aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/DocBook/writing-an-alsa-driver.tmpl36
-rw-r--r--Documentation/devicetree/bindings/sound/soc/codecs/fsl-sgtl5000.txt11
-rw-r--r--Documentation/devicetree/bindings/sound/wm8510.txt18
-rw-r--r--Documentation/devicetree/bindings/sound/wm8523.txt16
-rw-r--r--Documentation/devicetree/bindings/sound/wm8580.txt16
-rw-r--r--Documentation/devicetree/bindings/sound/wm8711.txt18
-rw-r--r--Documentation/devicetree/bindings/sound/wm8728.txt18
-rw-r--r--Documentation/devicetree/bindings/sound/wm8731.txt18
-rw-r--r--Documentation/devicetree/bindings/sound/wm8737.txt18
-rw-r--r--Documentation/devicetree/bindings/sound/wm8741.txt18
-rw-r--r--Documentation/devicetree/bindings/sound/wm8750.txt18
-rw-r--r--Documentation/devicetree/bindings/sound/wm8753.txt18
-rw-r--r--Documentation/devicetree/bindings/sound/wm8770.txt16
-rw-r--r--Documentation/devicetree/bindings/sound/wm8776.txt18
-rw-r--r--Documentation/devicetree/bindings/sound/wm8804.txt18
-rw-r--r--Documentation/sound/alsa/ALSA-Configuration.txt6
-rw-r--r--Documentation/sound/alsa/HD-Audio-Controls.txt16
-rw-r--r--Documentation/sound/alsa/HD-Audio-Models.txt67
-rw-r--r--Documentation/sound/alsa/HD-Audio.txt55
-rw-r--r--MAINTAINERS4
-rw-r--r--arch/arm/mach-ep93xx/edb93xx.c6
-rw-r--r--arch/arm/mach-ep93xx/simone.c13
-rw-r--r--arch/arm/mach-ep93xx/snappercl15.c13
-rw-r--r--arch/arm/mach-omap2/board-rx51-peripherals.c1
-rw-r--r--arch/arm/mach-omap2/devices.c33
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_44xx_data.c2
-rw-r--r--arch/arm/plat-omap/devices.c36
-rw-r--r--arch/mips/alchemy/devboards/db1200/platform.c16
-rw-r--r--arch/mips/alchemy/devboards/db1x00/platform.c48
-rw-r--r--drivers/input/misc/twl6040-vibra.c21
-rw-r--r--drivers/mfd/twl6040-core.c67
-rw-r--r--drivers/mfd/wm8994-core.c27
-rw-r--r--drivers/regulator/core.c64
-rw-r--r--drivers/regulator/wm8994-regulator.c13
-rw-r--r--include/linux/input.h1
-rw-r--r--include/linux/mfd/twl6040.h46
-rw-r--r--include/linux/mfd/wm8994/core.h1
-rw-r--r--include/linux/mfd/wm8994/registers.h88
-rw-r--r--include/linux/regulator/consumer.h7
-rw-r--r--include/linux/regulator/driver.h3
-rw-r--r--include/linux/usb/ch9.h17
-rw-r--r--include/sound/adau1373.h34
-rw-r--r--include/sound/asound.h4
-rw-r--r--include/sound/initval.h2
-rw-r--r--include/sound/jack.h1
-rw-r--r--include/sound/mpu401.h7
-rw-r--r--include/sound/pcm.h4
-rw-r--r--include/sound/saif.h16
-rw-r--r--include/sound/soc-dai.h37
-rw-r--r--include/sound/soc-dapm.h16
-rw-r--r--include/sound/soc.h107
-rw-r--r--include/sound/tpa6130a2-plat.h6
-rw-r--r--include/sound/wm1250-ev1.h27
-rw-r--r--include/sound/wm5100.h59
-rw-r--r--include/trace/events/asoc.h25
-rw-r--r--sound/aoa/codecs/onyx.c4
-rw-r--r--sound/arm/aaci.c2
-rw-r--r--sound/arm/pxa2xx-ac97-lib.c2
-rw-r--r--sound/core/control.c84
-rw-r--r--sound/core/control_compat.c4
-rw-r--r--sound/core/jack.c1
-rw-r--r--sound/core/oss/mixer_oss.c2
-rw-r--r--sound/core/pcm_lib.c26
-rw-r--r--sound/core/pcm_native.c19
-rw-r--r--sound/drivers/aloop.c13
-rw-r--r--sound/drivers/ml403-ac97cr.c4
-rw-r--r--sound/drivers/mpu401/mpu401.c3
-rw-r--r--sound/drivers/mpu401/mpu401_uart.c20
-rw-r--r--sound/drivers/mtpav.c2
-rw-r--r--sound/drivers/serial-u16550.c2
-rw-r--r--sound/firewire/isight.c1
-rw-r--r--sound/firewire/speakers.c5
-rw-r--r--sound/isa/ad1816a/ad1816a.c2
-rw-r--r--sound/isa/ad1816a/ad1816a_lib.c2
-rw-r--r--sound/isa/als100.c1
-rw-r--r--sound/isa/azt2320.c3
-rw-r--r--sound/isa/cmi8330.c2
-rw-r--r--sound/isa/cs423x/cs4231.c1
-rw-r--r--sound/isa/cs423x/cs4236.c3
-rw-r--r--sound/isa/es1688/es1688.c2
-rw-r--r--sound/isa/es1688/es1688_lib.c2
-rw-r--r--sound/isa/es18xx.c6
-rw-r--r--sound/isa/galaxy/galaxy.c3
-rw-r--r--sound/isa/gus/gus_main.c2
-rw-r--r--sound/isa/gus/gusextreme.c3
-rw-r--r--sound/isa/gus/gusmax.c2
-rw-r--r--sound/isa/gus/interwave.c2
-rw-r--r--sound/isa/msnd/msnd_pinnacle.c2
-rw-r--r--sound/isa/opl3sa2.c7
-rw-r--r--sound/isa/opti9xx/miro.c3
-rw-r--r--sound/isa/opti9xx/opti92x-ad1848.c4
-rw-r--r--sound/isa/sb/jazz16.c1
-rw-r--r--sound/isa/sb/sb16.c5
-rw-r--r--sound/isa/sb/sb_common.c2
-rw-r--r--sound/isa/sc6000.c3
-rw-r--r--sound/isa/sscape.c3
-rw-r--r--sound/isa/wavefront/wavefront.c5
-rw-r--r--sound/isa/wss/wss_lib.c2
-rw-r--r--sound/mips/Kconfig5
-rw-r--r--sound/mips/au1x00.c4
-rw-r--r--sound/oss/sound_timer.c2
-rw-r--r--sound/pci/als4000.c5
-rw-r--r--sound/pci/au88x0/au88x0_mpu401.c6
-rw-r--r--sound/pci/azt3328.c5
-rw-r--r--sound/pci/cmipci.c5
-rw-r--r--sound/pci/ctxfi/ctpcm.c2
-rw-r--r--sound/pci/ctxfi/ctsrc.c2
-rw-r--r--sound/pci/ctxfi/ctvmem.h2
-rw-r--r--sound/pci/emu10k1/emupcm.c5
-rw-r--r--sound/pci/es1938.c5
-rw-r--r--sound/pci/es1968.c5
-rw-r--r--sound/pci/fm801.c20
-rw-r--r--sound/pci/hda/Makefile3
-rw-r--r--sound/pci/hda/alc260_quirks.c304
-rw-r--r--sound/pci/hda/alc262_quirks.c530
-rw-r--r--sound/pci/hda/alc268_quirks.c636
-rw-r--r--sound/pci/hda/alc269_quirks.c674
-rw-r--r--sound/pci/hda/alc662_quirks.c1408
-rw-r--r--sound/pci/hda/alc680_quirks.c222
-rw-r--r--sound/pci/hda/alc861_quirks.c725
-rw-r--r--sound/pci/hda/alc861vd_quirks.c605
-rw-r--r--sound/pci/hda/alc880_quirks.c17
-rw-r--r--sound/pci/hda/alc882_quirks.c85
-rw-r--r--sound/pci/hda/alc_quirks.c13
-rw-r--r--sound/pci/hda/hda_codec.c143
-rw-r--r--sound/pci/hda/hda_eld.c39
-rw-r--r--sound/pci/hda/hda_hwdep.c6
-rw-r--r--sound/pci/hda/hda_intel.c225
-rw-r--r--sound/pci/hda/hda_local.h32
-rw-r--r--sound/pci/hda/hda_proc.c12
-rw-r--r--sound/pci/hda/hda_trace.h117
-rw-r--r--sound/pci/hda/patch_analog.c176
-rw-r--r--sound/pci/hda/patch_conexant.c165
-rw-r--r--sound/pci/hda/patch_hdmi.c99
-rw-r--r--sound/pci/hda/patch_realtek.c1402
-rw-r--r--sound/pci/hda/patch_sigmatel.c50
-rw-r--r--sound/pci/hda/patch_via.c68
-rw-r--r--sound/pci/ice1712/ice1712.c10
-rw-r--r--sound/pci/maestro3.c4
-rw-r--r--sound/pci/oxygen/oxygen_lib.c6
-rw-r--r--sound/pci/oxygen/xonar_pcm179x.c1
-rw-r--r--sound/pci/riptide/riptide.c2
-rw-r--r--sound/pci/rme9652/hdspm.c153
-rw-r--r--sound/pci/sis7019.c4
-rw-r--r--sound/pci/sonicvibes.c7
-rw-r--r--sound/pci/trident/trident.c5
-rw-r--r--sound/pci/via82xx.c13
-rw-r--r--sound/pci/ymfpci/ymfpci.c5
-rw-r--r--sound/pci/ymfpci/ymfpci_main.c32
-rw-r--r--sound/ppc/keywest.c1
-rw-r--r--sound/ppc/snd_ps3.c2
-rw-r--r--sound/soc/Kconfig3
-rw-r--r--sound/soc/Makefile1
-rw-r--r--sound/soc/atmel/playpaq_wm8510.c6
-rw-r--r--sound/soc/atmel/sam9g20_wm8731.c2
-rw-r--r--sound/soc/atmel/snd-soc-afeb9260.c2
-rw-r--r--sound/soc/au1x/Kconfig28
-rw-r--r--sound/soc/au1x/Makefile10
-rw-r--r--sound/soc/au1x/ac97c.c366
-rw-r--r--sound/soc/au1x/db1000.c75
-rw-r--r--sound/soc/au1x/db1200.c64
-rw-r--r--sound/soc/au1x/dbdma2.c91
-rw-r--r--sound/soc/au1x/dma.c377
-rw-r--r--sound/soc/au1x/i2sc.c349
-rw-r--r--sound/soc/au1x/psc-ac97.c61
-rw-r--r--sound/soc/au1x/psc-i2s.c55
-rw-r--r--sound/soc/au1x/psc.h16
-rw-r--r--sound/soc/blackfin/Kconfig13
-rw-r--r--sound/soc/blackfin/Makefile2
-rw-r--r--sound/soc/blackfin/bf5xx-ac97-pcm.c2
-rw-r--r--sound/soc/blackfin/bf5xx-i2s-pcm.c2
-rw-r--r--sound/soc/blackfin/bfin-eval-adau1373.c202
-rw-r--r--sound/soc/codecs/88pm860x-codec.c14
-rw-r--r--sound/soc/codecs/Kconfig16
-rw-r--r--sound/soc/codecs/Makefile8
-rw-r--r--sound/soc/codecs/ad193x.c96
-rw-r--r--sound/soc/codecs/ad193x.h36
-rw-r--r--sound/soc/codecs/ad1980.c11
-rw-r--r--sound/soc/codecs/adau1373.c1414
-rw-r--r--sound/soc/codecs/adau1373.h29
-rw-r--r--sound/soc/codecs/adau1701.c3
-rw-r--r--sound/soc/codecs/adav80x.c3
-rw-r--r--sound/soc/codecs/ads117x.h13
-rw-r--r--sound/soc/codecs/ak4104.c2
-rw-r--r--sound/soc/codecs/ak4535.c110
-rw-r--r--sound/soc/codecs/ak4641.c3
-rw-r--r--sound/soc/codecs/ak4642.c104
-rw-r--r--sound/soc/codecs/ak4671.c22
-rw-r--r--sound/soc/codecs/alc5623.c8
-rw-r--r--sound/soc/codecs/cs4270.c14
-rw-r--r--sound/soc/codecs/cs4271.c5
-rw-r--r--sound/soc/codecs/cs42l51.c15
-rw-r--r--sound/soc/codecs/da7210.c649
-rw-r--r--sound/soc/codecs/lm4857.c2
-rw-r--r--sound/soc/codecs/max98088.c36
-rw-r--r--sound/soc/codecs/max98095.c47
-rw-r--r--sound/soc/codecs/rt5631.c1773
-rw-r--r--sound/soc/codecs/rt5631.h701
-rw-r--r--sound/soc/codecs/sgtl5000.c37
-rw-r--r--sound/soc/codecs/sgtl5000.h2
-rw-r--r--sound/soc/codecs/sn95031.c16
-rw-r--r--sound/soc/codecs/ssm2602.c107
-rw-r--r--sound/soc/codecs/ssm2602.h6
-rw-r--r--sound/soc/codecs/sta32x.c54
-rw-r--r--sound/soc/codecs/tlv320aic23.c181
-rw-r--r--sound/soc/codecs/tlv320aic32x4.c65
-rw-r--r--sound/soc/codecs/tlv320aic3x.c25
-rw-r--r--sound/soc/codecs/tlv320dac33.c31
-rw-r--r--sound/soc/codecs/tpa6130a2.c13
-rw-r--r--sound/soc/codecs/twl4030.c69
-rw-r--r--sound/soc/codecs/twl6040.c805
-rw-r--r--sound/soc/codecs/twl6040.h13
-rw-r--r--sound/soc/codecs/wl1273.c1
-rw-r--r--sound/soc/codecs/wm1250-ev1.c140
-rw-r--r--sound/soc/codecs/wm5100-tables.c1531
-rw-r--r--sound/soc/codecs/wm5100.c2809
-rw-r--r--sound/soc/codecs/wm5100.h5155
-rw-r--r--sound/soc/codecs/wm8350.c43
-rw-r--r--sound/soc/codecs/wm8400.c2
-rw-r--r--sound/soc/codecs/wm8510.c21
-rw-r--r--sound/soc/codecs/wm8523.c36
-rw-r--r--sound/soc/codecs/wm8580.c69
-rw-r--r--sound/soc/codecs/wm8711.c38
-rw-r--r--sound/soc/codecs/wm8728.c13
-rw-r--r--sound/soc/codecs/wm8731.c25
-rw-r--r--sound/soc/codecs/wm8737.c10
-rw-r--r--sound/soc/codecs/wm8741.c151
-rw-r--r--sound/soc/codecs/wm8750.c56
-rw-r--r--sound/soc/codecs/wm8753.c13
-rw-r--r--sound/soc/codecs/wm8770.c8
-rw-r--r--sound/soc/codecs/wm8776.c67
-rw-r--r--sound/soc/codecs/wm8782.c2
-rw-r--r--sound/soc/codecs/wm8804.c9
-rw-r--r--sound/soc/codecs/wm8900.c115
-rw-r--r--sound/soc/codecs/wm8904.c2
-rw-r--r--sound/soc/codecs/wm8940.c51
-rw-r--r--sound/soc/codecs/wm8960.c18
-rw-r--r--sound/soc/codecs/wm8961.c4
-rw-r--r--sound/soc/codecs/wm8962.c222
-rw-r--r--sound/soc/codecs/wm8971.c42
-rw-r--r--sound/soc/codecs/wm8974.c15
-rw-r--r--sound/soc/codecs/wm8978.c3
-rw-r--r--sound/soc/codecs/wm8983.c2
-rw-r--r--sound/soc/codecs/wm8988.c33
-rw-r--r--sound/soc/codecs/wm8990.c105
-rw-r--r--sound/soc/codecs/wm8991.c24
-rw-r--r--sound/soc/codecs/wm8993.c7
-rw-r--r--sound/soc/codecs/wm8994-tables.c16
-rw-r--r--sound/soc/codecs/wm8994.c376
-rw-r--r--sound/soc/codecs/wm8994.h2
-rw-r--r--sound/soc/codecs/wm8995.c22
-rw-r--r--sound/soc/codecs/wm8996.c321
-rw-r--r--sound/soc/codecs/wm9081.c14
-rw-r--r--sound/soc/codecs/wm9090.c7
-rw-r--r--sound/soc/codecs/wm_hubs.c68
-rw-r--r--sound/soc/codecs/wm_hubs.h3
-rw-r--r--sound/soc/davinci/davinci-evm.c2
-rw-r--r--sound/soc/davinci/davinci-i2s.c5
-rw-r--r--sound/soc/davinci/davinci-mcasp.c20
-rw-r--r--sound/soc/davinci/davinci-pcm.c123
-rw-r--r--sound/soc/ep93xx/edb93xx.c60
-rw-r--r--sound/soc/ep93xx/ep93xx-ac97.c2
-rw-r--r--sound/soc/ep93xx/ep93xx-pcm.c1
-rw-r--r--sound/soc/ep93xx/simone.c64
-rw-r--r--sound/soc/ep93xx/snappercl15.c53
-rw-r--r--sound/soc/fsl/fsl_dma.c1
-rw-r--r--sound/soc/fsl/fsl_ssi.c206
-rw-r--r--sound/soc/fsl/mpc8610_hpcd.c2
-rw-r--r--sound/soc/fsl/p1022_ds.c4
-rw-r--r--sound/soc/imx/Kconfig3
-rw-r--r--sound/soc/imx/imx-pcm-fiq.c12
-rw-r--r--sound/soc/imx/imx-ssi.c9
-rw-r--r--sound/soc/imx/imx-ssi.h6
-rw-r--r--sound/soc/jz4740/jz4740-pcm.c2
-rw-r--r--sound/soc/kirkwood/kirkwood-i2s.c2
-rw-r--r--sound/soc/kirkwood/kirkwood-t5325.c2
-rw-r--r--sound/soc/mid-x86/mfld_machine.c4
-rw-r--r--sound/soc/mid-x86/sst_platform.c19
-rw-r--r--sound/soc/mxs/Kconfig20
-rw-r--r--sound/soc/mxs/Makefile10
-rw-r--r--sound/soc/mxs/mxs-pcm.c359
-rw-r--r--sound/soc/mxs/mxs-pcm.h43
-rw-r--r--sound/soc/mxs/mxs-saif.c798
-rw-r--r--sound/soc/mxs/mxs-saif.h134
-rw-r--r--sound/soc/mxs/mxs-sgtl5000.c173
-rw-r--r--sound/soc/nuc900/nuc900-pcm.c5
-rw-r--r--sound/soc/omap/Makefile2
-rw-r--r--sound/soc/omap/am3517evm.c50
-rw-r--r--sound/soc/omap/ams-delta.c1
-rw-r--r--sound/soc/omap/igep0020.c23
-rw-r--r--sound/soc/omap/mcpdm.c470
-rw-r--r--sound/soc/omap/mcpdm.h153
-rw-r--r--sound/soc/omap/n810.c42
-rw-r--r--sound/soc/omap/omap-mcbsp.c27
-rw-r--r--sound/soc/omap/omap-mcpdm.c481
-rw-r--r--sound/soc/omap/omap-mcpdm.h107
-rw-r--r--sound/soc/omap/omap-pcm.c8
-rw-r--r--sound/soc/omap/omap3evm.c23
-rw-r--r--sound/soc/omap/omap3pandora.c28
-rw-r--r--sound/soc/omap/osk5912.c50
-rw-r--r--sound/soc/omap/overo.c23
-rw-r--r--sound/soc/omap/rx51.c22
-rw-r--r--sound/soc/omap/sdp3430.c88
-rw-r--r--sound/soc/omap/sdp4430.c47
-rw-r--r--sound/soc/omap/zoom2.c96
-rw-r--r--sound/soc/pxa/Kconfig2
-rw-r--r--sound/soc/pxa/corgi.c1
-rw-r--r--sound/soc/pxa/e740_wm9705.c2
-rw-r--r--sound/soc/pxa/e750_wm9705.c2
-rw-r--r--sound/soc/pxa/e800_wm9712.c1
-rw-r--r--sound/soc/pxa/magician.c4
-rw-r--r--sound/soc/pxa/mioa701_wm9713.c1
-rw-r--r--sound/soc/pxa/palm27x.c4
-rw-r--r--sound/soc/pxa/poodle.c1
-rw-r--r--sound/soc/pxa/raumfeld.c4
-rw-r--r--sound/soc/pxa/saarb.c4
-rw-r--r--sound/soc/pxa/spitz.c3
-rw-r--r--sound/soc/pxa/tavorevb3.c4
-rw-r--r--sound/soc/pxa/tosa.c1
-rw-r--r--sound/soc/pxa/z2.c6
-rw-r--r--sound/soc/pxa/zylonite.c1
-rw-r--r--sound/soc/s6000/s6000-pcm.c1
-rw-r--r--sound/soc/samsung/Kconfig12
-rw-r--r--sound/soc/samsung/ac97.c4
-rw-r--r--sound/soc/samsung/goni_wm8994.c15
-rw-r--r--sound/soc/samsung/h1940_uda1380.c19
-rw-r--r--sound/soc/samsung/i2s.c2
-rw-r--r--sound/soc/samsung/jive_wm8750.c19
-rw-r--r--sound/soc/samsung/neo1973_wm8753.c4
-rw-r--r--sound/soc/samsung/pcm.c2
-rw-r--r--sound/soc/samsung/rx1950_uda1380.c33
-rw-r--r--sound/soc/samsung/s3c-i2s-v2.c1
-rw-r--r--sound/soc/samsung/s3c2412-i2s.c6
-rw-r--r--sound/soc/samsung/s3c24xx-i2s.c6
-rw-r--r--sound/soc/samsung/s3c24xx_simtec.c2
-rw-r--r--sound/soc/samsung/s3c24xx_simtec_hermes.c11
-rw-r--r--sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c11
-rw-r--r--sound/soc/samsung/s3c24xx_uda134x.c8
-rw-r--r--sound/soc/samsung/smartq_wm8987.c27
-rw-r--r--sound/soc/samsung/smdk_wm8580.c51
-rw-r--r--sound/soc/samsung/smdk_wm8580pcm.c4
-rw-r--r--sound/soc/samsung/smdk_wm8994.c2
-rw-r--r--sound/soc/samsung/spdif.c4
-rw-r--r--sound/soc/samsung/speyside.c10
-rw-r--r--sound/soc/samsung/speyside_wm8962.c41
-rw-r--r--sound/soc/sh/fsi.c12
-rw-r--r--sound/soc/sh/sh7760-ac97.c7
-rw-r--r--sound/soc/sh/ssi.c2
-rw-r--r--sound/soc/soc-cache.c7
-rw-r--r--sound/soc/soc-core.c215
-rw-r--r--sound/soc/soc-dapm.c416
-rw-r--r--sound/soc/soc-io.c357
-rw-r--r--sound/soc/soc-jack.c2
-rw-r--r--sound/soc/soc-pcm.c57
-rw-r--r--sound/soc/tegra/tegra_das.c4
-rw-r--r--sound/soc/tegra/tegra_i2s.c2
-rw-r--r--sound/soc/tegra/tegra_pcm.c2
-rw-r--r--sound/soc/tegra/tegra_spdif.c5
-rw-r--r--sound/soc/tegra/tegra_wm8903.c2
-rw-r--r--sound/soc/tegra/trimslice.c2
-rw-r--r--sound/soc/txx9/txx9aclc-ac97.c2
-rw-r--r--sound/soc/txx9/txx9aclc-generic.c2
-rw-r--r--sound/sparc/amd7930.c2
-rw-r--r--sound/usb/6fire/firmware.c25
-rw-r--r--sound/usb/Kconfig2
-rw-r--r--sound/usb/Makefile12
-rw-r--r--sound/usb/caiaq/device.c8
-rw-r--r--sound/usb/caiaq/device.h1
-rw-r--r--sound/usb/caiaq/input.c155
-rw-r--r--sound/usb/card.c4
-rw-r--r--sound/usb/card.h2
-rw-r--r--sound/usb/clock.c12
-rw-r--r--sound/usb/endpoint.c1199
-rw-r--r--sound/usb/endpoint.h20
-rw-r--r--sound/usb/format.c4
-rw-r--r--sound/usb/helper.c4
-rw-r--r--sound/usb/helper.h2
-rw-r--r--sound/usb/midi.c27
-rw-r--r--sound/usb/mixer.c21
-rw-r--r--sound/usb/mixer_quirks.c10
-rw-r--r--sound/usb/pcm.c34
-rw-r--r--sound/usb/pcm.h3
-rw-r--r--sound/usb/quirks-table.h25
-rw-r--r--sound/usb/quirks.c16
-rw-r--r--sound/usb/stream.c452
-rw-r--r--sound/usb/stream.h12
-rw-r--r--sound/usb/urb.c941
-rw-r--r--sound/usb/urb.h21
-rw-r--r--sound/usb/usbaudio.h1
389 files changed, 25739 insertions, 12181 deletions
diff --git a/Documentation/DocBook/writing-an-alsa-driver.tmpl b/Documentation/DocBook/writing-an-alsa-driver.tmpl
index 598c22f3b3a..5de23c00707 100644
--- a/Documentation/DocBook/writing-an-alsa-driver.tmpl
+++ b/Documentation/DocBook/writing-an-alsa-driver.tmpl
@@ -4288,7 +4288,7 @@ struct _snd_pcm_runtime {
4288<![CDATA[ 4288<![CDATA[
4289 struct snd_rawmidi *rmidi; 4289 struct snd_rawmidi *rmidi;
4290 snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, port, info_flags, 4290 snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, port, info_flags,
4291 irq, irq_flags, &rmidi); 4291 irq, &rmidi);
4292]]> 4292]]>
4293 </programlisting> 4293 </programlisting>
4294 </informalexample> 4294 </informalexample>
@@ -4343,6 +4343,13 @@ struct _snd_pcm_runtime {
4343 by itself to start processing the output stream in the irq handler. 4343 by itself to start processing the output stream in the irq handler.
4344 </para> 4344 </para>
4345 4345
4346 <para>
4347 If the MPU-401 interface shares its interrupt with the other logical
4348 devices on the card, set <constant>MPU401_INFO_IRQ_HOOK</constant>
4349 (see <link linkend="midi-interface-interrupt-handler"><citetitle>
4350 below</citetitle></link>).
4351 </para>
4352
4346 <para> 4353 <para>
4347 Usually, the port address corresponds to the command port and 4354 Usually, the port address corresponds to the command port and
4348 port + 1 corresponds to the data port. If not, you may change 4355 port + 1 corresponds to the data port. If not, you may change
@@ -4375,14 +4382,12 @@ struct _snd_pcm_runtime {
4375 </para> 4382 </para>
4376 4383
4377 <para> 4384 <para>
4378 The 6th argument specifies the irq number for UART. If the irq 4385 The 6th argument specifies the ISA irq number that will be
4379 is already allocated, pass 0 to the 7th argument 4386 allocated. If no interrupt is to be allocated (because your
4380 (<parameter>irq_flags</parameter>). Otherwise, pass the flags 4387 code is already allocating a shared interrupt, or because the
4381 for irq allocation 4388 device does not use interrupts), pass -1 instead.
4382 (<constant>SA_XXX</constant> bits) to it, and the irq will be 4389 For a MPU-401 device without an interrupt, a polling timer
4383 reserved by the mpu401-uart layer. If the card doesn't generate 4390 will be used instead.
4384 UART interrupts, pass -1 as the irq number. Then a timer
4385 interrupt will be invoked for polling.
4386 </para> 4391 </para>
4387 </section> 4392 </section>
4388 4393
@@ -4390,12 +4395,13 @@ struct _snd_pcm_runtime {
4390 <title>Interrupt Handler</title> 4395 <title>Interrupt Handler</title>
4391 <para> 4396 <para>
4392 When the interrupt is allocated in 4397 When the interrupt is allocated in
4393 <function>snd_mpu401_uart_new()</function>, the private 4398 <function>snd_mpu401_uart_new()</function>, an exclusive ISA
4394 interrupt handler is used, hence you don't have anything else to do 4399 interrupt handler is automatically used, hence you don't have
4395 than creating the mpu401 stuff. Otherwise, you have to call 4400 anything else to do than creating the mpu401 stuff. Otherwise, you
4396 <function>snd_mpu401_uart_interrupt()</function> explicitly when 4401 have to set <constant>MPU401_INFO_IRQ_HOOK</constant>, and call
4397 a UART interrupt is invoked and checked in your own interrupt 4402 <function>snd_mpu401_uart_interrupt()</function> explicitly from your
4398 handler. 4403 own interrupt handler when it has determined that a UART interrupt
4404 has occurred.
4399 </para> 4405 </para>
4400 4406
4401 <para> 4407 <para>
diff --git a/Documentation/devicetree/bindings/sound/soc/codecs/fsl-sgtl5000.txt b/Documentation/devicetree/bindings/sound/soc/codecs/fsl-sgtl5000.txt
new file mode 100644
index 00000000000..2c3cd413f04
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/soc/codecs/fsl-sgtl5000.txt
@@ -0,0 +1,11 @@
1* Freescale SGTL5000 Stereo Codec
2
3Required properties:
4- compatible : "fsl,sgtl5000".
5
6Example:
7
8codec: sgtl5000@0a {
9 compatible = "fsl,sgtl5000";
10 reg = <0x0a>;
11};
diff --git a/Documentation/devicetree/bindings/sound/wm8510.txt b/Documentation/devicetree/bindings/sound/wm8510.txt
new file mode 100644
index 00000000000..fa1a32b8557
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/wm8510.txt
@@ -0,0 +1,18 @@
1WM8510 audio CODEC
2
3This device supports both I2C and SPI (configured with pin strapping
4on the board).
5
6Required properties:
7
8 - compatible : "wlf,wm8510"
9
10 - reg : the I2C address of the device for I2C, the chip select
11 number for SPI.
12
13Example:
14
15codec: wm8510@1a {
16 compatible = "wlf,wm8510";
17 reg = <0x1a>;
18};
diff --git a/Documentation/devicetree/bindings/sound/wm8523.txt b/Documentation/devicetree/bindings/sound/wm8523.txt
new file mode 100644
index 00000000000..04746186b28
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/wm8523.txt
@@ -0,0 +1,16 @@
1WM8523 audio CODEC
2
3This device supports I2C only.
4
5Required properties:
6
7 - compatible : "wlf,wm8523"
8
9 - reg : the I2C address of the device.
10
11Example:
12
13codec: wm8523@1a {
14 compatible = "wlf,wm8523";
15 reg = <0x1a>;
16};
diff --git a/Documentation/devicetree/bindings/sound/wm8580.txt b/Documentation/devicetree/bindings/sound/wm8580.txt
new file mode 100644
index 00000000000..7d9821f348d
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/wm8580.txt
@@ -0,0 +1,16 @@
1WM8580 audio CODEC
2
3This device supports I2C only.
4
5Required properties:
6
7 - compatible : "wlf,wm8580"
8
9 - reg : the I2C address of the device.
10
11Example:
12
13codec: wm8580@1a {
14 compatible = "wlf,wm8580";
15 reg = <0x1a>;
16};
diff --git a/Documentation/devicetree/bindings/sound/wm8711.txt b/Documentation/devicetree/bindings/sound/wm8711.txt
new file mode 100644
index 00000000000..8ed9998cd23
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/wm8711.txt
@@ -0,0 +1,18 @@
1WM8711 audio CODEC
2
3This device supports both I2C and SPI (configured with pin strapping
4on the board).
5
6Required properties:
7
8 - compatible : "wlf,wm8711"
9
10 - reg : the I2C address of the device for I2C, the chip select
11 number for SPI.
12
13Example:
14
15codec: wm8711@1a {
16 compatible = "wlf,wm8711";
17 reg = <0x1a>;
18};
diff --git a/Documentation/devicetree/bindings/sound/wm8728.txt b/Documentation/devicetree/bindings/sound/wm8728.txt
new file mode 100644
index 00000000000..a8b5c3668e6
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/wm8728.txt
@@ -0,0 +1,18 @@
1WM8728 audio CODEC
2
3This device supports both I2C and SPI (configured with pin strapping
4on the board).
5
6Required properties:
7
8 - compatible : "wlf,wm8728"
9
10 - reg : the I2C address of the device for I2C, the chip select
11 number for SPI.
12
13Example:
14
15codec: wm8728@1a {
16 compatible = "wlf,wm8728";
17 reg = <0x1a>;
18};
diff --git a/Documentation/devicetree/bindings/sound/wm8731.txt b/Documentation/devicetree/bindings/sound/wm8731.txt
new file mode 100644
index 00000000000..15f70048469
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/wm8731.txt
@@ -0,0 +1,18 @@
1WM8731 audio CODEC
2
3This device supports both I2C and SPI (configured with pin strapping
4on the board).
5
6Required properties:
7
8 - compatible : "wlf,wm8731"
9
10 - reg : the I2C address of the device for I2C, the chip select
11 number for SPI.
12
13Example:
14
15codec: wm8731@1a {
16 compatible = "wlf,wm8731";
17 reg = <0x1a>;
18};
diff --git a/Documentation/devicetree/bindings/sound/wm8737.txt b/Documentation/devicetree/bindings/sound/wm8737.txt
new file mode 100644
index 00000000000..4bc2cea3b14
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/wm8737.txt
@@ -0,0 +1,18 @@
1WM8737 audio CODEC
2
3This device supports both I2C and SPI (configured with pin strapping
4on the board).
5
6Required properties:
7
8 - compatible : "wlf,wm8737"
9
10 - reg : the I2C address of the device for I2C, the chip select
11 number for SPI.
12
13Example:
14
15codec: wm8737@1a {
16 compatible = "wlf,wm8737";
17 reg = <0x1a>;
18};
diff --git a/Documentation/devicetree/bindings/sound/wm8741.txt b/Documentation/devicetree/bindings/sound/wm8741.txt
new file mode 100644
index 00000000000..74bda58c1bc
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/wm8741.txt
@@ -0,0 +1,18 @@
1WM8741 audio CODEC
2
3This device supports both I2C and SPI (configured with pin strapping
4on the board).
5
6Required properties:
7
8 - compatible : "wlf,wm8741"
9
10 - reg : the I2C address of the device for I2C, the chip select
11 number for SPI.
12
13Example:
14
15codec: wm8741@1a {
16 compatible = "wlf,wm8741";
17 reg = <0x1a>;
18};
diff --git a/Documentation/devicetree/bindings/sound/wm8750.txt b/Documentation/devicetree/bindings/sound/wm8750.txt
new file mode 100644
index 00000000000..8db239fd5ec
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/wm8750.txt
@@ -0,0 +1,18 @@
1WM8750 and WM8987 audio CODECs
2
3These devices support both I2C and SPI (configured with pin strapping
4on the board).
5
6Required properties:
7
8 - compatible : "wlf,wm8750" or "wlf,wm8987"
9
10 - reg : the I2C address of the device for I2C, the chip select
11 number for SPI.
12
13Example:
14
15codec: wm8750@1a {
16 compatible = "wlf,wm8750";
17 reg = <0x1a>;
18};
diff --git a/Documentation/devicetree/bindings/sound/wm8753.txt b/Documentation/devicetree/bindings/sound/wm8753.txt
new file mode 100644
index 00000000000..e65277a0fb6
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/wm8753.txt
@@ -0,0 +1,18 @@
1WM8753 audio CODEC
2
3This device supports both I2C and SPI (configured with pin strapping
4on the board).
5
6Required properties:
7
8 - compatible : "wlf,wm8753"
9
10 - reg : the I2C address of the device for I2C, the chip select
11 number for SPI.
12
13Example:
14
15codec: wm8737@1a {
16 compatible = "wlf,wm8753";
17 reg = <0x1a>;
18};
diff --git a/Documentation/devicetree/bindings/sound/wm8770.txt b/Documentation/devicetree/bindings/sound/wm8770.txt
new file mode 100644
index 00000000000..866e00ca150
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/wm8770.txt
@@ -0,0 +1,16 @@
1WM8770 audio CODEC
2
3This device supports SPI.
4
5Required properties:
6
7 - compatible : "wlf,wm8770"
8
9 - reg : the chip select number.
10
11Example:
12
13codec: wm8770@1 {
14 compatible = "wlf,wm8770";
15 reg = <1>;
16};
diff --git a/Documentation/devicetree/bindings/sound/wm8776.txt b/Documentation/devicetree/bindings/sound/wm8776.txt
new file mode 100644
index 00000000000..3b9ca49abc2
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/wm8776.txt
@@ -0,0 +1,18 @@
1WM8776 audio CODEC
2
3This device supports both I2C and SPI (configured with pin strapping
4on the board).
5
6Required properties:
7
8 - compatible : "wlf,wm8776"
9
10 - reg : the I2C address of the device for I2C, the chip select
11 number for SPI.
12
13Example:
14
15codec: wm8776@1a {
16 compatible = "wlf,wm8776";
17 reg = <0x1a>;
18};
diff --git a/Documentation/devicetree/bindings/sound/wm8804.txt b/Documentation/devicetree/bindings/sound/wm8804.txt
new file mode 100644
index 00000000000..4d3a56f38ad
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/wm8804.txt
@@ -0,0 +1,18 @@
1WM8804 audio CODEC
2
3This device supports both I2C and SPI (configured with pin strapping
4on the board).
5
6Required properties:
7
8 - compatible : "wlf,wm8804"
9
10 - reg : the I2C address of the device for I2C, the chip select
11 number for SPI.
12
13Example:
14
15codec: wm8804@1a {
16 compatible = "wlf,wm8804";
17 reg = <0x1a>;
18};
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
index 89757012c7f..936699e4f04 100644
--- a/Documentation/sound/alsa/ALSA-Configuration.txt
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt
@@ -886,6 +886,12 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
886 disable) 886 disable)
887 power_save_controller - Reset HD-audio controller in power-saving mode 887 power_save_controller - Reset HD-audio controller in power-saving mode
888 (default = on) 888 (default = on)
889 align_buffer_size - Force rounding of buffer/period sizes to multiples
890 of 128 bytes. This is more efficient in terms of memory
891 access but isn't required by the HDA spec and prevents
892 users from specifying exact period/buffer sizes.
893 (default = on)
894 snoop - Enable/disable snooping (default = on)
889 895
890 This module supports multiple cards and autoprobe. 896 This module supports multiple cards and autoprobe.
891 897
diff --git a/Documentation/sound/alsa/HD-Audio-Controls.txt b/Documentation/sound/alsa/HD-Audio-Controls.txt
index 1482035243e..e9621e349e1 100644
--- a/Documentation/sound/alsa/HD-Audio-Controls.txt
+++ b/Documentation/sound/alsa/HD-Audio-Controls.txt
@@ -98,3 +98,19 @@ Conexant codecs
98 98
99* Auto-Mute Mode 99* Auto-Mute Mode
100 See Reatek codecs. 100 See Reatek codecs.
101
102
103Analog codecs
104--------------
105
106* Channel Mode
107 This is an enum control to change the surround-channel setup,
108 appears only when the surround channels are available.
109 It gives the number of channels to be used, "2ch", "4ch" and "6ch".
110 According to the configuration, this also controls the
111 jack-retasking of multi-I/O jacks.
112
113* Independent HP
114 When this enum control is enabled, the headphone output is routed
115 from an individual stream (the third PCM such as hw:0,2) instead of
116 the primary stream.
diff --git a/Documentation/sound/alsa/HD-Audio-Models.txt b/Documentation/sound/alsa/HD-Audio-Models.txt
index d70c93bdcad..4f3443230d8 100644
--- a/Documentation/sound/alsa/HD-Audio-Models.txt
+++ b/Documentation/sound/alsa/HD-Audio-Models.txt
@@ -29,9 +29,6 @@ ALC880
29 29
30ALC260 30ALC260
31====== 31======
32 hp HP machines
33 hp-3013 HP machines (3013-variant)
34 hp-dc7600 HP DC7600
35 fujitsu Fujitsu S7020 32 fujitsu Fujitsu S7020
36 acer Acer TravelMate 33 acer Acer TravelMate
37 will Will laptops (PB V7900) 34 will Will laptops (PB V7900)
@@ -46,15 +43,10 @@ ALC260
46ALC262 43ALC262
47====== 44======
48 fujitsu Fujitsu Laptop 45 fujitsu Fujitsu Laptop
49 hp-bpc HP xw4400/6400/8400/9400 laptops
50 hp-bpc-d7000 HP BPC D7000
51 hp-tc-t5735 HP Thin Client T5735
52 hp-rp5700 HP RP5700
53 benq Benq ED8 46 benq Benq ED8
54 benq-t31 Benq T31 47 benq-t31 Benq T31
55 hippo Hippo (ATI) with jack detection, Sony UX-90s 48 hippo Hippo (ATI) with jack detection, Sony UX-90s
56 hippo_1 Hippo (Benq) with jack detection 49 hippo_1 Hippo (Benq) with jack detection
57 sony-assamd Sony ASSAMD
58 toshiba-s06 Toshiba S06 50 toshiba-s06 Toshiba S06
59 toshiba-rx1 Toshiba RX1 51 toshiba-rx1 Toshiba RX1
60 tyan Tyan Thunder n6650W (S2915-E) 52 tyan Tyan Thunder n6650W (S2915-E)
@@ -66,43 +58,15 @@ ALC262
66 58
67ALC267/268 59ALC267/268
68========== 60==========
69 quanta-il1 Quanta IL1 mini-notebook 61 N/A
70 3stack 3-stack model
71 toshiba Toshiba A205
72 acer Acer laptops
73 acer-dmic Acer laptops with digital-mic
74 acer-aspire Acer Aspire One
75 dell Dell OEM laptops (Vostro 1200)
76 zepto Zepto laptops
77 test for testing/debugging purpose, almost all controls can
78 adjusted. Appearing only when compiled with
79 $CONFIG_SND_DEBUG=y
80 auto auto-config reading BIOS (default)
81 62
82ALC269 63ALC269
83====== 64======
84 basic Basic preset
85 quanta Quanta FL1
86 laptop-amic Laptops with analog-mic input 65 laptop-amic Laptops with analog-mic input
87 laptop-dmic Laptops with digital-mic input 66 laptop-dmic Laptops with digital-mic input
88 fujitsu FSC Amilo
89 lifebook Fujitsu Lifebook S6420
90 auto auto-config reading BIOS (default)
91 67
92ALC662/663/272 68ALC662/663/272
93============== 69==============
94 3stack-dig 3-stack (2-channel) with SPDIF
95 3stack-6ch 3-stack (6-channel)
96 3stack-6ch-dig 3-stack (6-channel) with SPDIF
97 5stack-dig 5-stack with SPDIF
98 lenovo-101e Lenovo laptop
99 eeepc-p701 ASUS Eeepc P701
100 eeepc-ep20 ASUS Eeepc EP20
101 ecs ECS/Foxconn mobo
102 m51va ASUS M51VA
103 g71v ASUS G71V
104 h13 ASUS H13
105 g50v ASUS G50V
106 asus-mode1 ASUS 70 asus-mode1 ASUS
107 asus-mode2 ASUS 71 asus-mode2 ASUS
108 asus-mode3 ASUS 72 asus-mode3 ASUS
@@ -111,15 +75,10 @@ ALC662/663/272
111 asus-mode6 ASUS 75 asus-mode6 ASUS
112 asus-mode7 ASUS 76 asus-mode7 ASUS
113 asus-mode8 ASUS 77 asus-mode8 ASUS
114 dell Dell with ALC272
115 dell-zm1 Dell ZM1 with ALC272
116 samsung-nc10 Samsung NC10 mini notebook
117 auto auto-config reading BIOS (default)
118 78
119ALC680 79ALC680
120====== 80======
121 base Base model (ASUS NX90) 81 N/A
122 auto auto-config reading BIOS (default)
123 82
124ALC882/883/885/888/889 83ALC882/883/885/888/889
125====================== 84======================
@@ -175,28 +134,11 @@ ALC882/883/885/888/889
175 134
176ALC861/660 135ALC861/660
177========== 136==========
178 3stack 3-jack 137 N/A
179 3stack-dig 3-jack with SPDIF I/O
180 6stack-dig 6-jack with SPDIF I/O
181 3stack-660 3-jack (for ALC660)
182 uniwill-m31 Uniwill M31 laptop
183 toshiba Toshiba laptop support
184 asus Asus laptop support
185 asus-laptop ASUS F2/F3 laptops
186 auto auto-config reading BIOS (default)
187 138
188ALC861VD/660VD 139ALC861VD/660VD
189============== 140==============
190 3stack 3-jack 141 N/A
191 3stack-dig 3-jack with SPDIF OUT
192 6stack-dig 6-jack with SPDIF OUT
193 3stack-660 3-jack (for ALC660VD)
194 3stack-660-digout 3-jack with SPDIF OUT (for ALC660VD)
195 lenovo Lenovo 3000 C200
196 dallas Dallas laptops
197 hp HP TX1000
198 asus-v1s ASUS V1Sn
199 auto auto-config reading BIOS (default)
200 142
201CMI9880 143CMI9880
202======= 144=======
@@ -289,7 +231,6 @@ Conexant 5051
289 hp-dv6736 HP dv6736 231 hp-dv6736 HP dv6736
290 hp-f700 HP Compaq Presario F700 232 hp-f700 HP Compaq Presario F700
291 ideapad Lenovo IdeaPad laptop 233 ideapad Lenovo IdeaPad laptop
292 lenovo-x200 Lenovo X200 laptop
293 toshiba Toshiba Satellite M300 234 toshiba Toshiba Satellite M300
294 235
295Conexant 5066 236Conexant 5066
diff --git a/Documentation/sound/alsa/HD-Audio.txt b/Documentation/sound/alsa/HD-Audio.txt
index c82beb00763..03e2771ddee 100644
--- a/Documentation/sound/alsa/HD-Audio.txt
+++ b/Documentation/sound/alsa/HD-Audio.txt
@@ -447,7 +447,10 @@ The file needs to have a line `[codec]`. The next line should contain
447three numbers indicating the codec vendor-id (0x12345678 in the 447three numbers indicating the codec vendor-id (0x12345678 in the
448example), the codec subsystem-id (0xabcd1234) and the address (2) of 448example), the codec subsystem-id (0xabcd1234) and the address (2) of
449the codec. The rest patch entries are applied to this specified codec 449the codec. The rest patch entries are applied to this specified codec
450until another codec entry is given. 450until another codec entry is given. Passing 0 or a negative number to
451the first or the second value will make the check of the corresponding
452field be skipped. It'll be useful for really broken devices that don't
453initialize SSID properly.
451 454
452The `[model]` line allows to change the model name of the each codec. 455The `[model]` line allows to change the model name of the each codec.
453In the example above, it will be changed to model=auto. 456In the example above, it will be changed to model=auto.
@@ -491,7 +494,7 @@ Also, the codec chip name can be rewritten via `[chip_name]` line.
491The hd-audio driver reads the file via request_firmware(). Thus, 494The hd-audio driver reads the file via request_firmware(). Thus,
492a patch file has to be located on the appropriate firmware path, 495a patch file has to be located on the appropriate firmware path,
493typically, /lib/firmware. For example, when you pass the option 496typically, /lib/firmware. For example, when you pass the option
494`patch=hda-init.fw`, the file /lib/firmware/hda-init-fw must be 497`patch=hda-init.fw`, the file /lib/firmware/hda-init.fw must be
495present. 498present.
496 499
497The patch module option is specific to each card instance, and you 500The patch module option is specific to each card instance, and you
@@ -524,6 +527,54 @@ power-saving. See /sys/module/snd_hda_intel/parameters/power_save to
524check the current value. If it's non-zero, the feature is turned on. 527check the current value. If it's non-zero, the feature is turned on.
525 528
526 529
530Tracepoints
531~~~~~~~~~~~
532The hd-audio driver gives a few basic tracepoints.
533`hda:hda_send_cmd` traces each CORB write while `hda:hda_get_response`
534traces the response from RIRB (only when read from the codec driver).
535`hda:hda_bus_reset` traces the bus-reset due to fatal error, etc,
536`hda:hda_unsol_event` traces the unsolicited events, and
537`hda:hda_power_down` and `hda:hda_power_up` trace the power down/up
538via power-saving behavior.
539
540Enabling all tracepoints can be done like
541------------------------------------------------------------------------
542 # echo 1 > /sys/kernel/debug/tracing/events/hda/enable
543------------------------------------------------------------------------
544then after some commands, you can traces from
545/sys/kernel/debug/tracing/trace file. For example, when you want to
546trace what codec command is sent, enable the tracepoint like:
547------------------------------------------------------------------------
548 # cat /sys/kernel/debug/tracing/trace
549 # tracer: nop
550 #
551 # TASK-PID CPU# TIMESTAMP FUNCTION
552 # | | | | |
553 <...>-7807 [002] 105147.774889: hda_send_cmd: [0:0] val=e3a019
554 <...>-7807 [002] 105147.774893: hda_send_cmd: [0:0] val=e39019
555 <...>-7807 [002] 105147.999542: hda_send_cmd: [0:0] val=e3a01a
556 <...>-7807 [002] 105147.999543: hda_send_cmd: [0:0] val=e3901a
557 <...>-26764 [001] 349222.837143: hda_send_cmd: [0:0] val=e3a019
558 <...>-26764 [001] 349222.837148: hda_send_cmd: [0:0] val=e39019
559 <...>-26764 [001] 349223.058539: hda_send_cmd: [0:0] val=e3a01a
560 <...>-26764 [001] 349223.058541: hda_send_cmd: [0:0] val=e3901a
561------------------------------------------------------------------------
562Here `[0:0]` indicates the card number and the codec address, and
563`val` shows the value sent to the codec, respectively. The value is
564a packed value, and you can decode it via hda-decode-verb program
565included in hda-emu package below. For example, the value e3a019 is
566to set the left output-amp value to 25.
567------------------------------------------------------------------------
568 % hda-decode-verb 0xe3a019
569 raw value = 0x00e3a019
570 cid = 0, nid = 0x0e, verb = 0x3a0, parm = 0x19
571 raw value: verb = 0x3a0, parm = 0x19
572 verbname = set_amp_gain_mute
573 amp raw val = 0xa019
574 output, left, idx=0, mute=0, val=25
575------------------------------------------------------------------------
576
577
527Development Tree 578Development Tree
528~~~~~~~~~~~~~~~~ 579~~~~~~~~~~~~~~~~
529The latest development codes for HD-audio are found on sound git tree: 580The latest development codes for HD-audio are found on sound git tree:
diff --git a/MAINTAINERS b/MAINTAINERS
index 506fe49a4c7..07e5dbd1427 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -529,6 +529,7 @@ S: Maintained
529F: drivers/infiniband/hw/amso1100/ 529F: drivers/infiniband/hw/amso1100/
530 530
531ANALOG DEVICES INC ASOC CODEC DRIVERS 531ANALOG DEVICES INC ASOC CODEC DRIVERS
532M: Lars-Peter Clausen <lars@metafoo.de>
532L: device-drivers-devel@blackfin.uclinux.org 533L: device-drivers-devel@blackfin.uclinux.org
533L: alsa-devel@alsa-project.org (moderated for non-subscribers) 534L: alsa-devel@alsa-project.org (moderated for non-subscribers)
534W: http://wiki.analog.com/ 535W: http://wiki.analog.com/
@@ -6038,7 +6039,7 @@ M: Jaroslav Kysela <perex@perex.cz>
6038M: Takashi Iwai <tiwai@suse.de> 6039M: Takashi Iwai <tiwai@suse.de>
6039L: alsa-devel@alsa-project.org (moderated for non-subscribers) 6040L: alsa-devel@alsa-project.org (moderated for non-subscribers)
6040W: http://www.alsa-project.org/ 6041W: http://www.alsa-project.org/
6041T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6.git 6042T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git
6042T: git git://git.alsa-project.org/alsa-kernel.git 6043T: git git://git.alsa-project.org/alsa-kernel.git
6043S: Maintained 6044S: Maintained
6044F: Documentation/sound/ 6045F: Documentation/sound/
@@ -7259,6 +7260,7 @@ T: git git://opensource.wolfsonmicro.com/linux-2.6-audioplus
7259W: http://opensource.wolfsonmicro.com/content/linux-drivers-wolfson-devices 7260W: http://opensource.wolfsonmicro.com/content/linux-drivers-wolfson-devices
7260S: Supported 7261S: Supported
7261F: Documentation/hwmon/wm83?? 7262F: Documentation/hwmon/wm83??
7263F: arch/arm/mach-s3c64xx/mach-crag6410*
7262F: drivers/leds/leds-wm83*.c 7264F: drivers/leds/leds-wm83*.c
7263F: drivers/input/misc/wm831x-on.c 7265F: drivers/input/misc/wm831x-on.c
7264F: drivers/input/touchscreen/wm831x-ts.c 7266F: drivers/input/touchscreen/wm831x-ts.c
diff --git a/arch/arm/mach-ep93xx/edb93xx.c b/arch/arm/mach-ep93xx/edb93xx.c
index c63a5ec1a8e..70ef8c527d2 100644
--- a/arch/arm/mach-ep93xx/edb93xx.c
+++ b/arch/arm/mach-ep93xx/edb93xx.c
@@ -160,6 +160,11 @@ static void __init edb93xx_register_spi(void)
160/************************************************************************* 160/*************************************************************************
161 * EDB93xx I2S 161 * EDB93xx I2S
162 *************************************************************************/ 162 *************************************************************************/
163static struct platform_device edb93xx_audio_device = {
164 .name = "edb93xx-audio",
165 .id = -1,
166};
167
163static int __init edb93xx_has_audio(void) 168static int __init edb93xx_has_audio(void)
164{ 169{
165 return (machine_is_edb9301() || machine_is_edb9302() || 170 return (machine_is_edb9301() || machine_is_edb9302() ||
@@ -171,6 +176,7 @@ static void __init edb93xx_register_i2s(void)
171{ 176{
172 if (edb93xx_has_audio()) { 177 if (edb93xx_has_audio()) {
173 ep93xx_register_i2s(); 178 ep93xx_register_i2s();
179 platform_device_register(&edb93xx_audio_device);
174 } 180 }
175} 181}
176 182
diff --git a/arch/arm/mach-ep93xx/simone.c b/arch/arm/mach-ep93xx/simone.c
index d6f286b4db9..52e090dc9d2 100644
--- a/arch/arm/mach-ep93xx/simone.c
+++ b/arch/arm/mach-ep93xx/simone.c
@@ -53,6 +53,17 @@ static struct i2c_board_info __initdata simone_i2c_board_info[] = {
53 }, 53 },
54}; 54};
55 55
56static struct platform_device simone_audio_device = {
57 .name = "simone-audio",
58 .id = -1,
59};
60
61static void __init simone_register_audio(void)
62{
63 ep93xx_register_ac97();
64 platform_device_register(&simone_audio_device);
65}
66
56static void __init simone_init_machine(void) 67static void __init simone_init_machine(void)
57{ 68{
58 ep93xx_init_devices(); 69 ep93xx_init_devices();
@@ -61,7 +72,7 @@ static void __init simone_init_machine(void)
61 ep93xx_register_fb(&simone_fb_info); 72 ep93xx_register_fb(&simone_fb_info);
62 ep93xx_register_i2c(&simone_i2c_gpio_data, simone_i2c_board_info, 73 ep93xx_register_i2c(&simone_i2c_gpio_data, simone_i2c_board_info,
63 ARRAY_SIZE(simone_i2c_board_info)); 74 ARRAY_SIZE(simone_i2c_board_info));
64 ep93xx_register_ac97(); 75 simone_register_audio();
65} 76}
66 77
67MACHINE_START(SIM_ONE, "Simplemachines Sim.One Board") 78MACHINE_START(SIM_ONE, "Simplemachines Sim.One Board")
diff --git a/arch/arm/mach-ep93xx/snappercl15.c b/arch/arm/mach-ep93xx/snappercl15.c
index 2b4d4b0201d..8121e3aedc0 100644
--- a/arch/arm/mach-ep93xx/snappercl15.c
+++ b/arch/arm/mach-ep93xx/snappercl15.c
@@ -150,6 +150,17 @@ static struct ep93xxfb_mach_info __initdata snappercl15_fb_info = {
150 .bpp = 16, 150 .bpp = 16,
151}; 151};
152 152
153static struct platform_device snappercl15_audio_device = {
154 .name = "snappercl15-audio",
155 .id = -1,
156};
157
158static void __init snappercl15_register_audio(void)
159{
160 ep93xx_register_i2s();
161 platform_device_register(&snappercl15_audio_device);
162}
163
153static void __init snappercl15_init_machine(void) 164static void __init snappercl15_init_machine(void)
154{ 165{
155 ep93xx_init_devices(); 166 ep93xx_init_devices();
@@ -157,7 +168,7 @@ static void __init snappercl15_init_machine(void)
157 ep93xx_register_i2c(&snappercl15_i2c_gpio_data, snappercl15_i2c_data, 168 ep93xx_register_i2c(&snappercl15_i2c_gpio_data, snappercl15_i2c_data,
158 ARRAY_SIZE(snappercl15_i2c_data)); 169 ARRAY_SIZE(snappercl15_i2c_data));
159 ep93xx_register_fb(&snappercl15_fb_info); 170 ep93xx_register_fb(&snappercl15_fb_info);
160 ep93xx_register_i2s(); 171 snappercl15_register_audio();
161 platform_device_register(&snappercl15_nand_device); 172 platform_device_register(&snappercl15_nand_device);
162} 173}
163 174
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
index 5a886cd2c59..ba1aa07bdb2 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -900,7 +900,6 @@ static struct twl4030_platform_data rx51_twldata __initdata = {
900}; 900};
901 901
902static struct tpa6130a2_platform_data rx51_tpa6130a2_data __initdata_or_module = { 902static struct tpa6130a2_platform_data rx51_tpa6130a2_data __initdata_or_module = {
903 .id = TPA6130A2,
904 .power_gpio = 98, 903 .power_gpio = 98,
905}; 904};
906 905
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 5391079c868..ae8ea5b3b1a 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -329,6 +329,38 @@ static void omap_init_audio(void)
329static inline void omap_init_audio(void) {} 329static inline void omap_init_audio(void) {}
330#endif 330#endif
331 331
332#if defined(CONFIG_SND_OMAP_SOC_MCPDM) || \
333 defined(CONFIG_SND_OMAP_SOC_MCPDM_MODULE)
334
335static struct omap_device_pm_latency omap_mcpdm_latency[] = {
336 {
337 .deactivate_func = omap_device_idle_hwmods,
338 .activate_func = omap_device_enable_hwmods,
339 .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
340 },
341};
342
343static void omap_init_mcpdm(void)
344{
345 struct omap_hwmod *oh;
346 struct omap_device *od;
347
348 oh = omap_hwmod_lookup("mcpdm");
349 if (!oh) {
350 printk(KERN_ERR "Could not look up mcpdm hw_mod\n");
351 return;
352 }
353
354 od = omap_device_build("omap-mcpdm", -1, oh, NULL, 0,
355 omap_mcpdm_latency,
356 ARRAY_SIZE(omap_mcpdm_latency), 0);
357 if (IS_ERR(od))
358 printk(KERN_ERR "Could not build omap_device for omap-mcpdm-dai\n");
359}
360#else
361static inline void omap_init_mcpdm(void) {}
362#endif
363
332#if defined(CONFIG_SPI_OMAP24XX) || defined(CONFIG_SPI_OMAP24XX_MODULE) 364#if defined(CONFIG_SPI_OMAP24XX) || defined(CONFIG_SPI_OMAP24XX_MODULE)
333 365
334#include <plat/mcspi.h> 366#include <plat/mcspi.h>
@@ -682,6 +714,7 @@ static int __init omap2_init_devices(void)
682 * in alphabetical order so they're easier to sort through. 714 * in alphabetical order so they're easier to sort through.
683 */ 715 */
684 omap_init_audio(); 716 omap_init_audio();
717 omap_init_mcpdm();
685 omap_init_camera(); 718 omap_init_camera();
686 omap_init_mbox(); 719 omap_init_mbox();
687 omap_init_mcspi(); 720 omap_init_mcspi();
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index 6201422c060..79325c65c23 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -5430,7 +5430,7 @@ static __initdata struct omap_hwmod *omap44xx_hwmods[] = {
5430 &omap44xx_mcbsp4_hwmod, 5430 &omap44xx_mcbsp4_hwmod,
5431 5431
5432 /* mcpdm class */ 5432 /* mcpdm class */
5433/* &omap44xx_mcpdm_hwmod, */ 5433 &omap44xx_mcpdm_hwmod,
5434 5434
5435 /* mcspi class */ 5435 /* mcspi class */
5436 &omap44xx_mcspi1_hwmod, 5436 &omap44xx_mcspi1_hwmod,
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
index 64c3bd4aa54..c46c47afa09 100644
--- a/arch/arm/plat-omap/devices.c
+++ b/arch/arm/plat-omap/devices.c
@@ -73,41 +73,6 @@ void omap_mcbsp_register_board_cfg(struct resource *res, int res_count,
73 73
74/*-------------------------------------------------------------------------*/ 74/*-------------------------------------------------------------------------*/
75 75
76#if defined(CONFIG_SND_OMAP_SOC_MCPDM) || \
77 defined(CONFIG_SND_OMAP_SOC_MCPDM_MODULE)
78
79static struct resource mcpdm_resources[] = {
80 {
81 .name = "mcpdm_mem",
82 .start = OMAP44XX_MCPDM_BASE,
83 .end = OMAP44XX_MCPDM_BASE + SZ_4K,
84 .flags = IORESOURCE_MEM,
85 },
86 {
87 .name = "mcpdm_irq",
88 .start = OMAP44XX_IRQ_MCPDM,
89 .end = OMAP44XX_IRQ_MCPDM,
90 .flags = IORESOURCE_IRQ,
91 },
92};
93
94static struct platform_device omap_mcpdm_device = {
95 .name = "omap-mcpdm",
96 .id = -1,
97 .num_resources = ARRAY_SIZE(mcpdm_resources),
98 .resource = mcpdm_resources,
99};
100
101static void omap_init_mcpdm(void)
102{
103 (void) platform_device_register(&omap_mcpdm_device);
104}
105#else
106static inline void omap_init_mcpdm(void) {}
107#endif
108
109/*-------------------------------------------------------------------------*/
110
111#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \ 76#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
112 defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE) 77 defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
113 78
@@ -290,7 +255,6 @@ static int __init omap_init_devices(void)
290 * in alphabetical order so they're easier to sort through. 255 * in alphabetical order so they're easier to sort through.
291 */ 256 */
292 omap_init_rng(); 257 omap_init_rng();
293 omap_init_mcpdm();
294 omap_init_uwire(); 258 omap_init_uwire();
295 return 0; 259 return 0;
296} 260}
diff --git a/arch/mips/alchemy/devboards/db1200/platform.c b/arch/mips/alchemy/devboards/db1200/platform.c
index fbb55935b99..dda090bf74e 100644
--- a/arch/mips/alchemy/devboards/db1200/platform.c
+++ b/arch/mips/alchemy/devboards/db1200/platform.c
@@ -422,6 +422,7 @@ static struct resource au1200_psc1_res[] = {
422 }, 422 },
423}; 423};
424 424
425/* AC97 or I2S device */
425static struct platform_device db1200_audio_dev = { 426static struct platform_device db1200_audio_dev = {
426 /* name assigned later based on switch setting */ 427 /* name assigned later based on switch setting */
427 .id = 1, /* PSC ID */ 428 .id = 1, /* PSC ID */
@@ -429,19 +430,32 @@ static struct platform_device db1200_audio_dev = {
429 .resource = au1200_psc1_res, 430 .resource = au1200_psc1_res,
430}; 431};
431 432
433/* DB1200 ASoC card device */
434static struct platform_device db1200_sound_dev = {
435 /* name assigned later based on switch setting */
436 .id = 1, /* PSC ID */
437};
438
432static struct platform_device db1200_stac_dev = { 439static struct platform_device db1200_stac_dev = {
433 .name = "ac97-codec", 440 .name = "ac97-codec",
434 .id = 1, /* on PSC1 */ 441 .id = 1, /* on PSC1 */
435}; 442};
436 443
444static struct platform_device db1200_audiodma_dev = {
445 .name = "au1xpsc-pcm",
446 .id = 1, /* PSC ID */
447};
448
437static struct platform_device *db1200_devs[] __initdata = { 449static struct platform_device *db1200_devs[] __initdata = {
438 NULL, /* PSC0, selected by S6.8 */ 450 NULL, /* PSC0, selected by S6.8 */
439 &db1200_ide_dev, 451 &db1200_ide_dev,
440 &db1200_eth_dev, 452 &db1200_eth_dev,
441 &db1200_rtc_dev, 453 &db1200_rtc_dev,
442 &db1200_nand_dev, 454 &db1200_nand_dev,
455 &db1200_audiodma_dev,
443 &db1200_audio_dev, 456 &db1200_audio_dev,
444 &db1200_stac_dev, 457 &db1200_stac_dev,
458 &db1200_sound_dev,
445}; 459};
446 460
447static int __init db1200_dev_init(void) 461static int __init db1200_dev_init(void)
@@ -501,10 +515,12 @@ static int __init db1200_dev_init(void)
501 if (sw == BCSR_SWITCHES_DIP_8) { 515 if (sw == BCSR_SWITCHES_DIP_8) {
502 bcsr_mod(BCSR_RESETS, 0, BCSR_RESETS_PSC1MUX); 516 bcsr_mod(BCSR_RESETS, 0, BCSR_RESETS_PSC1MUX);
503 db1200_audio_dev.name = "au1xpsc_i2s"; 517 db1200_audio_dev.name = "au1xpsc_i2s";
518 db1200_sound_dev.name = "db1200-i2s";
504 printk(KERN_INFO " S6.7 ON : PSC1 mode I2S\n"); 519 printk(KERN_INFO " S6.7 ON : PSC1 mode I2S\n");
505 } else { 520 } else {
506 bcsr_mod(BCSR_RESETS, BCSR_RESETS_PSC1MUX, 0); 521 bcsr_mod(BCSR_RESETS, BCSR_RESETS_PSC1MUX, 0);
507 db1200_audio_dev.name = "au1xpsc_ac97"; 522 db1200_audio_dev.name = "au1xpsc_ac97";
523 db1200_sound_dev.name = "db1200-ac97";
508 printk(KERN_INFO " S6.7 OFF: PSC1 mode AC97\n"); 524 printk(KERN_INFO " S6.7 OFF: PSC1 mode AC97\n");
509 } 525 }
510 526
diff --git a/arch/mips/alchemy/devboards/db1x00/platform.c b/arch/mips/alchemy/devboards/db1x00/platform.c
index 978d5ab3d67..7057d28f730 100644
--- a/arch/mips/alchemy/devboards/db1x00/platform.c
+++ b/arch/mips/alchemy/devboards/db1x00/platform.c
@@ -19,8 +19,11 @@
19 */ 19 */
20 20
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/interrupt.h>
22#include <linux/platform_device.h> 23#include <linux/platform_device.h>
23 24
25#include <asm/mach-au1x00/au1000.h>
26#include <asm/mach-au1x00/au1000_dma.h>
24#include <asm/mach-au1x00/au1xxx.h> 27#include <asm/mach-au1x00/au1xxx.h>
25#include <asm/mach-db1x00/bcsr.h> 28#include <asm/mach-db1x00/bcsr.h>
26#include "../platform.h" 29#include "../platform.h"
@@ -85,6 +88,45 @@
85#endif 88#endif
86#endif 89#endif
87 90
91static struct resource alchemy_ac97c_res[] = {
92 [0] = {
93 .start = AU1000_AC97_PHYS_ADDR,
94 .end = AU1000_AC97_PHYS_ADDR + 0xfff,
95 .flags = IORESOURCE_MEM,
96 },
97 [1] = {
98 .start = DMA_ID_AC97C_TX,
99 .end = DMA_ID_AC97C_TX,
100 .flags = IORESOURCE_DMA,
101 },
102 [2] = {
103 .start = DMA_ID_AC97C_RX,
104 .end = DMA_ID_AC97C_RX,
105 .flags = IORESOURCE_DMA,
106 },
107};
108
109static struct platform_device alchemy_ac97c_dev = {
110 .name = "alchemy-ac97c",
111 .id = -1,
112 .resource = alchemy_ac97c_res,
113 .num_resources = ARRAY_SIZE(alchemy_ac97c_res),
114};
115
116static struct platform_device alchemy_ac97c_dma_dev = {
117 .name = "alchemy-pcm-dma",
118 .id = 0,
119};
120
121static struct platform_device db1x00_codec_dev = {
122 .name = "ac97-codec",
123 .id = -1,
124};
125
126static struct platform_device db1x00_audio_dev = {
127 .name = "db1000-audio",
128};
129
88static int __init db1xxx_dev_init(void) 130static int __init db1xxx_dev_init(void)
89{ 131{
90#ifdef DB1XXX_HAS_PCMCIA 132#ifdef DB1XXX_HAS_PCMCIA
@@ -113,6 +155,12 @@ static int __init db1xxx_dev_init(void)
113 1); 155 1);
114#endif 156#endif
115 db1x_register_norflash(BOARD_FLASH_SIZE, BOARD_FLASH_WIDTH, F_SWAPPED); 157 db1x_register_norflash(BOARD_FLASH_SIZE, BOARD_FLASH_WIDTH, F_SWAPPED);
158
159 platform_device_register(&db1x00_codec_dev);
160 platform_device_register(&alchemy_ac97c_dma_dev);
161 platform_device_register(&alchemy_ac97c_dev);
162 platform_device_register(&db1x00_audio_dev);
163
116 return 0; 164 return 0;
117} 165}
118device_initcall(db1xxx_dev_init); 166device_initcall(db1xxx_dev_init);
diff --git a/drivers/input/misc/twl6040-vibra.c b/drivers/input/misc/twl6040-vibra.c
index 23855e12a30..ad153a417ee 100644
--- a/drivers/input/misc/twl6040-vibra.c
+++ b/drivers/input/misc/twl6040-vibra.c
@@ -74,12 +74,12 @@ static irqreturn_t twl6040_vib_irq_handler(int irq, void *data)
74 if (status & TWL6040_VIBLOCDET) { 74 if (status & TWL6040_VIBLOCDET) {
75 dev_warn(info->dev, "Left Vibrator overcurrent detected\n"); 75 dev_warn(info->dev, "Left Vibrator overcurrent detected\n");
76 twl6040_clear_bits(twl6040, TWL6040_REG_VIBCTLL, 76 twl6040_clear_bits(twl6040, TWL6040_REG_VIBCTLL,
77 TWL6040_VIBENAL); 77 TWL6040_VIBENA);
78 } 78 }
79 if (status & TWL6040_VIBROCDET) { 79 if (status & TWL6040_VIBROCDET) {
80 dev_warn(info->dev, "Right Vibrator overcurrent detected\n"); 80 dev_warn(info->dev, "Right Vibrator overcurrent detected\n");
81 twl6040_clear_bits(twl6040, TWL6040_REG_VIBCTLR, 81 twl6040_clear_bits(twl6040, TWL6040_REG_VIBCTLR,
82 TWL6040_VIBENAR); 82 TWL6040_VIBENA);
83 } 83 }
84 84
85 return IRQ_HANDLED; 85 return IRQ_HANDLED;
@@ -97,23 +97,23 @@ static void twl6040_vibra_enable(struct vibra_info *info)
97 } 97 }
98 98
99 twl6040_power(info->twl6040, 1); 99 twl6040_power(info->twl6040, 1);
100 if (twl6040->rev <= TWL6040_REV_ES1_1) { 100 if (twl6040_get_revid(twl6040) <= TWL6040_REV_ES1_1) {
101 /* 101 /*
102 * ERRATA: Disable overcurrent protection for at least 102 * ERRATA: Disable overcurrent protection for at least
103 * 3ms when enabling vibrator drivers to avoid false 103 * 3ms when enabling vibrator drivers to avoid false
104 * overcurrent detection 104 * overcurrent detection
105 */ 105 */
106 twl6040_reg_write(twl6040, TWL6040_REG_VIBCTLL, 106 twl6040_reg_write(twl6040, TWL6040_REG_VIBCTLL,
107 TWL6040_VIBENAL | TWL6040_VIBCTRLL); 107 TWL6040_VIBENA | TWL6040_VIBCTRL);
108 twl6040_reg_write(twl6040, TWL6040_REG_VIBCTLR, 108 twl6040_reg_write(twl6040, TWL6040_REG_VIBCTLR,
109 TWL6040_VIBENAR | TWL6040_VIBCTRLR); 109 TWL6040_VIBENA | TWL6040_VIBCTRL);
110 usleep_range(3000, 3500); 110 usleep_range(3000, 3500);
111 } 111 }
112 112
113 twl6040_reg_write(twl6040, TWL6040_REG_VIBCTLL, 113 twl6040_reg_write(twl6040, TWL6040_REG_VIBCTLL,
114 TWL6040_VIBENAL); 114 TWL6040_VIBENA);
115 twl6040_reg_write(twl6040, TWL6040_REG_VIBCTLR, 115 twl6040_reg_write(twl6040, TWL6040_REG_VIBCTLR,
116 TWL6040_VIBENAR); 116 TWL6040_VIBENA);
117 117
118 info->enabled = true; 118 info->enabled = true;
119} 119}
@@ -201,6 +201,13 @@ static int vibra_play(struct input_dev *input, void *data,
201 struct vibra_info *info = input_get_drvdata(input); 201 struct vibra_info *info = input_get_drvdata(input);
202 int ret; 202 int ret;
203 203
204 /* Do not allow effect, while the routing is set to use audio */
205 ret = twl6040_get_vibralr_status(info->twl6040);
206 if (ret & TWL6040_VIBSEL) {
207 dev_info(&input->dev, "Vibra is configured for audio\n");
208 return -EBUSY;
209 }
210
204 info->weak_speed = effect->u.rumble.weak_magnitude; 211 info->weak_speed = effect->u.rumble.weak_magnitude;
205 info->strong_speed = effect->u.rumble.strong_magnitude; 212 info->strong_speed = effect->u.rumble.strong_magnitude;
206 info->direction = effect->direction < EFFECT_DIR_180_DEG ? 1 : -1; 213 info->direction = effect->direction < EFFECT_DIR_180_DEG ? 1 : -1;
diff --git a/drivers/mfd/twl6040-core.c b/drivers/mfd/twl6040-core.c
index 24d436c2fe4..268f80fd043 100644
--- a/drivers/mfd/twl6040-core.c
+++ b/drivers/mfd/twl6040-core.c
@@ -34,7 +34,7 @@
34#include <linux/mfd/core.h> 34#include <linux/mfd/core.h>
35#include <linux/mfd/twl6040.h> 35#include <linux/mfd/twl6040.h>
36 36
37static struct platform_device *twl6040_dev; 37#define VIBRACTRL_MEMBER(reg) ((reg == TWL6040_REG_VIBCTLL) ? 0 : 1)
38 38
39int twl6040_reg_read(struct twl6040 *twl6040, unsigned int reg) 39int twl6040_reg_read(struct twl6040 *twl6040, unsigned int reg)
40{ 40{
@@ -42,10 +42,16 @@ int twl6040_reg_read(struct twl6040 *twl6040, unsigned int reg)
42 u8 val = 0; 42 u8 val = 0;
43 43
44 mutex_lock(&twl6040->io_mutex); 44 mutex_lock(&twl6040->io_mutex);
45 ret = twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &val, reg); 45 /* Vibra control registers from cache */
46 if (ret < 0) { 46 if (unlikely(reg == TWL6040_REG_VIBCTLL ||
47 mutex_unlock(&twl6040->io_mutex); 47 reg == TWL6040_REG_VIBCTLR)) {
48 return ret; 48 val = twl6040->vibra_ctrl_cache[VIBRACTRL_MEMBER(reg)];
49 } else {
50 ret = twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &val, reg);
51 if (ret < 0) {
52 mutex_unlock(&twl6040->io_mutex);
53 return ret;
54 }
49 } 55 }
50 mutex_unlock(&twl6040->io_mutex); 56 mutex_unlock(&twl6040->io_mutex);
51 57
@@ -59,6 +65,9 @@ int twl6040_reg_write(struct twl6040 *twl6040, unsigned int reg, u8 val)
59 65
60 mutex_lock(&twl6040->io_mutex); 66 mutex_lock(&twl6040->io_mutex);
61 ret = twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, val, reg); 67 ret = twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, val, reg);
68 /* Cache the vibra control registers */
69 if (reg == TWL6040_REG_VIBCTLL || reg == TWL6040_REG_VIBCTLR)
70 twl6040->vibra_ctrl_cache[VIBRACTRL_MEMBER(reg)] = val;
62 mutex_unlock(&twl6040->io_mutex); 71 mutex_unlock(&twl6040->io_mutex);
63 72
64 return ret; 73 return ret;
@@ -203,11 +212,11 @@ static irqreturn_t twl6040_naudint_handler(int irq, void *data)
203 if (intid & TWL6040_THINT) { 212 if (intid & TWL6040_THINT) {
204 status = twl6040_reg_read(twl6040, TWL6040_REG_STATUS); 213 status = twl6040_reg_read(twl6040, TWL6040_REG_STATUS);
205 if (status & TWL6040_TSHUTDET) { 214 if (status & TWL6040_TSHUTDET) {
206 dev_warn(&twl6040_dev->dev, 215 dev_warn(twl6040->dev,
207 "Thermal shutdown, powering-off"); 216 "Thermal shutdown, powering-off");
208 twl6040_power(twl6040, 0); 217 twl6040_power(twl6040, 0);
209 } else { 218 } else {
210 dev_warn(&twl6040_dev->dev, 219 dev_warn(twl6040->dev,
211 "Leaving thermal shutdown, powering-on"); 220 "Leaving thermal shutdown, powering-on");
212 twl6040_power(twl6040, 1); 221 twl6040_power(twl6040, 1);
213 } 222 }
@@ -227,7 +236,7 @@ static int twl6040_power_up_completion(struct twl6040 *twl6040,
227 if (!time_left) { 236 if (!time_left) {
228 intid = twl6040_reg_read(twl6040, TWL6040_REG_INTID); 237 intid = twl6040_reg_read(twl6040, TWL6040_REG_INTID);
229 if (!(intid & TWL6040_READYINT)) { 238 if (!(intid & TWL6040_READYINT)) {
230 dev_err(&twl6040_dev->dev, 239 dev_err(twl6040->dev,
231 "timeout waiting for READYINT\n"); 240 "timeout waiting for READYINT\n");
232 return -ETIMEDOUT; 241 return -ETIMEDOUT;
233 } 242 }
@@ -255,7 +264,7 @@ int twl6040_power(struct twl6040 *twl6040, int on)
255 /* wait for power-up completion */ 264 /* wait for power-up completion */
256 ret = twl6040_power_up_completion(twl6040, naudint); 265 ret = twl6040_power_up_completion(twl6040, naudint);
257 if (ret) { 266 if (ret) {
258 dev_err(&twl6040_dev->dev, 267 dev_err(twl6040->dev,
259 "automatic power-down failed\n"); 268 "automatic power-down failed\n");
260 twl6040->power_count = 0; 269 twl6040->power_count = 0;
261 goto out; 270 goto out;
@@ -264,7 +273,7 @@ int twl6040_power(struct twl6040 *twl6040, int on)
264 /* use manual power-up sequence */ 273 /* use manual power-up sequence */
265 ret = twl6040_power_up(twl6040); 274 ret = twl6040_power_up(twl6040);
266 if (ret) { 275 if (ret) {
267 dev_err(&twl6040_dev->dev, 276 dev_err(twl6040->dev,
268 "manual power-up failed\n"); 277 "manual power-up failed\n");
269 twl6040->power_count = 0; 278 twl6040->power_count = 0;
270 goto out; 279 goto out;
@@ -276,7 +285,7 @@ int twl6040_power(struct twl6040 *twl6040, int on)
276 } else { 285 } else {
277 /* already powered-down */ 286 /* already powered-down */
278 if (!twl6040->power_count) { 287 if (!twl6040->power_count) {
279 dev_err(&twl6040_dev->dev, 288 dev_err(twl6040->dev,
280 "device is already powered-off\n"); 289 "device is already powered-off\n");
281 ret = -EPERM; 290 ret = -EPERM;
282 goto out; 291 goto out;
@@ -326,7 +335,7 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id,
326 lppllctl &= ~TWL6040_LPLLFIN; 335 lppllctl &= ~TWL6040_LPLLFIN;
327 break; 336 break;
328 default: 337 default:
329 dev_err(&twl6040_dev->dev, 338 dev_err(twl6040->dev,
330 "freq_out %d not supported\n", freq_out); 339 "freq_out %d not supported\n", freq_out);
331 ret = -EINVAL; 340 ret = -EINVAL;
332 goto pll_out; 341 goto pll_out;
@@ -347,7 +356,7 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id,
347 hppllctl); 356 hppllctl);
348 break; 357 break;
349 default: 358 default:
350 dev_err(&twl6040_dev->dev, 359 dev_err(twl6040->dev,
351 "freq_in %d not supported\n", freq_in); 360 "freq_in %d not supported\n", freq_in);
352 ret = -EINVAL; 361 ret = -EINVAL;
353 goto pll_out; 362 goto pll_out;
@@ -356,7 +365,7 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id,
356 case TWL6040_SYSCLK_SEL_HPPLL: 365 case TWL6040_SYSCLK_SEL_HPPLL:
357 /* high-performance PLL can provide only 19.2 MHz */ 366 /* high-performance PLL can provide only 19.2 MHz */
358 if (freq_out != 19200000) { 367 if (freq_out != 19200000) {
359 dev_err(&twl6040_dev->dev, 368 dev_err(twl6040->dev,
360 "freq_out %d not supported\n", freq_out); 369 "freq_out %d not supported\n", freq_out);
361 ret = -EINVAL; 370 ret = -EINVAL;
362 goto pll_out; 371 goto pll_out;
@@ -389,7 +398,7 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id,
389 TWL6040_HPLLENA; 398 TWL6040_HPLLENA;
390 break; 399 break;
391 default: 400 default:
392 dev_err(&twl6040_dev->dev, 401 dev_err(twl6040->dev,
393 "freq_in %d not supported\n", freq_in); 402 "freq_in %d not supported\n", freq_in);
394 ret = -EINVAL; 403 ret = -EINVAL;
395 goto pll_out; 404 goto pll_out;
@@ -406,7 +415,7 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id,
406 twl6040_reg_write(twl6040, TWL6040_REG_LPPLLCTL, lppllctl); 415 twl6040_reg_write(twl6040, TWL6040_REG_LPPLLCTL, lppllctl);
407 break; 416 break;
408 default: 417 default:
409 dev_err(&twl6040_dev->dev, "unknown pll id %d\n", pll_id); 418 dev_err(twl6040->dev, "unknown pll id %d\n", pll_id);
410 ret = -EINVAL; 419 ret = -EINVAL;
411 goto pll_out; 420 goto pll_out;
412 } 421 }
@@ -435,6 +444,18 @@ unsigned int twl6040_get_sysclk(struct twl6040 *twl6040)
435} 444}
436EXPORT_SYMBOL(twl6040_get_sysclk); 445EXPORT_SYMBOL(twl6040_get_sysclk);
437 446
447/* Get the combined status of the vibra control register */
448int twl6040_get_vibralr_status(struct twl6040 *twl6040)
449{
450 u8 status;
451
452 status = twl6040->vibra_ctrl_cache[0] | twl6040->vibra_ctrl_cache[1];
453 status &= (TWL6040_VIBENA | TWL6040_VIBSEL);
454
455 return status;
456}
457EXPORT_SYMBOL(twl6040_get_vibralr_status);
458
438static struct resource twl6040_vibra_rsrc[] = { 459static struct resource twl6040_vibra_rsrc[] = {
439 { 460 {
440 .flags = IORESOURCE_IRQ, 461 .flags = IORESOURCE_IRQ,
@@ -471,9 +492,7 @@ static int __devinit twl6040_probe(struct platform_device *pdev)
471 492
472 platform_set_drvdata(pdev, twl6040); 493 platform_set_drvdata(pdev, twl6040);
473 494
474 twl6040_dev = pdev;
475 twl6040->dev = &pdev->dev; 495 twl6040->dev = &pdev->dev;
476 twl6040->audpwron = pdata->audpwron_gpio;
477 twl6040->irq = pdata->naudint_irq; 496 twl6040->irq = pdata->naudint_irq;
478 twl6040->irq_base = pdata->irq_base; 497 twl6040->irq_base = pdata->irq_base;
479 498
@@ -483,6 +502,12 @@ static int __devinit twl6040_probe(struct platform_device *pdev)
483 502
484 twl6040->rev = twl6040_reg_read(twl6040, TWL6040_REG_ASICREV); 503 twl6040->rev = twl6040_reg_read(twl6040, TWL6040_REG_ASICREV);
485 504
505 /* ERRATA: Automatic power-up is not possible in ES1.0 */
506 if (twl6040_get_revid(twl6040) > TWL6040_REV_ES1_0)
507 twl6040->audpwron = pdata->audpwron_gpio;
508 else
509 twl6040->audpwron = -EINVAL;
510
486 if (gpio_is_valid(twl6040->audpwron)) { 511 if (gpio_is_valid(twl6040->audpwron)) {
487 ret = gpio_request(twl6040->audpwron, "audpwron"); 512 ret = gpio_request(twl6040->audpwron, "audpwron");
488 if (ret) 513 if (ret)
@@ -493,10 +518,6 @@ static int __devinit twl6040_probe(struct platform_device *pdev)
493 goto gpio2_err; 518 goto gpio2_err;
494 } 519 }
495 520
496 /* ERRATA: Automatic power-up is not possible in ES1.0 */
497 if (twl6040->rev == TWL6040_REV_ES1_0)
498 twl6040->audpwron = -EINVAL;
499
500 /* codec interrupt */ 521 /* codec interrupt */
501 ret = twl6040_irq_init(twl6040); 522 ret = twl6040_irq_init(twl6040);
502 if (ret) 523 if (ret)
@@ -566,7 +587,6 @@ gpio2_err:
566gpio1_err: 587gpio1_err:
567 platform_set_drvdata(pdev, NULL); 588 platform_set_drvdata(pdev, NULL);
568 kfree(twl6040); 589 kfree(twl6040);
569 twl6040_dev = NULL;
570 return ret; 590 return ret;
571} 591}
572 592
@@ -586,7 +606,6 @@ static int __devexit twl6040_remove(struct platform_device *pdev)
586 mfd_remove_devices(&pdev->dev); 606 mfd_remove_devices(&pdev->dev);
587 platform_set_drvdata(pdev, NULL); 607 platform_set_drvdata(pdev, NULL);
588 kfree(twl6040); 608 kfree(twl6040);
589 twl6040_dev = NULL;
590 609
591 return 0; 610 return 0;
592} 611}
diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c
index bfde4e8ec63..b03be1d4e0c 100644
--- a/drivers/mfd/wm8994-core.c
+++ b/drivers/mfd/wm8994-core.c
@@ -167,6 +167,18 @@ static struct mfd_cell wm8994_devs[] = {
167 * and should be handled via the standard regulator API supply 167 * and should be handled via the standard regulator API supply
168 * management. 168 * management.
169 */ 169 */
170static const char *wm1811_main_supplies[] = {
171 "DBVDD1",
172 "DBVDD2",
173 "DBVDD3",
174 "DCVDD",
175 "AVDD1",
176 "AVDD2",
177 "CPVDD",
178 "SPKVDD1",
179 "SPKVDD2",
180};
181
170static const char *wm8994_main_supplies[] = { 182static const char *wm8994_main_supplies[] = {
171 "DBVDD", 183 "DBVDD",
172 "DCVDD", 184 "DCVDD",
@@ -329,6 +341,9 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
329 } 341 }
330 342
331 switch (wm8994->type) { 343 switch (wm8994->type) {
344 case WM1811:
345 wm8994->num_supplies = ARRAY_SIZE(wm1811_main_supplies);
346 break;
332 case WM8994: 347 case WM8994:
333 wm8994->num_supplies = ARRAY_SIZE(wm8994_main_supplies); 348 wm8994->num_supplies = ARRAY_SIZE(wm8994_main_supplies);
334 break; 349 break;
@@ -349,6 +364,10 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
349 } 364 }
350 365
351 switch (wm8994->type) { 366 switch (wm8994->type) {
367 case WM1811:
368 for (i = 0; i < ARRAY_SIZE(wm1811_main_supplies); i++)
369 wm8994->supplies[i].supply = wm1811_main_supplies[i];
370 break;
352 case WM8994: 371 case WM8994:
353 for (i = 0; i < ARRAY_SIZE(wm8994_main_supplies); i++) 372 for (i = 0; i < ARRAY_SIZE(wm8994_main_supplies); i++)
354 wm8994->supplies[i].supply = wm8994_main_supplies[i]; 373 wm8994->supplies[i].supply = wm8994_main_supplies[i];
@@ -382,6 +401,13 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
382 goto err_enable; 401 goto err_enable;
383 } 402 }
384 switch (ret) { 403 switch (ret) {
404 case 0x1811:
405 devname = "WM1811";
406 if (wm8994->type != WM1811)
407 dev_warn(wm8994->dev, "Device registered as type %d\n",
408 wm8994->type);
409 wm8994->type = WM1811;
410 break;
385 case 0x8994: 411 case 0x8994:
386 devname = "WM8994"; 412 devname = "WM8994";
387 if (wm8994->type != WM8994) 413 if (wm8994->type != WM8994)
@@ -539,6 +565,7 @@ static int wm8994_i2c_remove(struct i2c_client *i2c)
539} 565}
540 566
541static const struct i2c_device_id wm8994_i2c_id[] = { 567static const struct i2c_device_id wm8994_i2c_id[] = {
568 { "wm1811", WM1811 },
542 { "wm8994", WM8994 }, 569 { "wm8994", WM8994 },
543 { "wm8958", WM8958 }, 570 { "wm8958", WM8958 },
544 { } 571 { }
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index d8e6a429e8b..9e4c123c402 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -1552,6 +1552,68 @@ int regulator_force_disable(struct regulator *regulator)
1552} 1552}
1553EXPORT_SYMBOL_GPL(regulator_force_disable); 1553EXPORT_SYMBOL_GPL(regulator_force_disable);
1554 1554
1555static void regulator_disable_work(struct work_struct *work)
1556{
1557 struct regulator_dev *rdev = container_of(work, struct regulator_dev,
1558 disable_work.work);
1559 int count, i, ret;
1560
1561 mutex_lock(&rdev->mutex);
1562
1563 BUG_ON(!rdev->deferred_disables);
1564
1565 count = rdev->deferred_disables;
1566 rdev->deferred_disables = 0;
1567
1568 for (i = 0; i < count; i++) {
1569 ret = _regulator_disable(rdev);
1570 if (ret != 0)
1571 rdev_err(rdev, "Deferred disable failed: %d\n", ret);
1572 }
1573
1574 mutex_unlock(&rdev->mutex);
1575
1576 if (rdev->supply) {
1577 for (i = 0; i < count; i++) {
1578 ret = regulator_disable(rdev->supply);
1579 if (ret != 0) {
1580 rdev_err(rdev,
1581 "Supply disable failed: %d\n", ret);
1582 }
1583 }
1584 }
1585}
1586
1587/**
1588 * regulator_disable_deferred - disable regulator output with delay
1589 * @regulator: regulator source
1590 * @ms: miliseconds until the regulator is disabled
1591 *
1592 * Execute regulator_disable() on the regulator after a delay. This
1593 * is intended for use with devices that require some time to quiesce.
1594 *
1595 * NOTE: this will only disable the regulator output if no other consumer
1596 * devices have it enabled, the regulator device supports disabling and
1597 * machine constraints permit this operation.
1598 */
1599int regulator_disable_deferred(struct regulator *regulator, int ms)
1600{
1601 struct regulator_dev *rdev = regulator->rdev;
1602 int ret;
1603
1604 mutex_lock(&rdev->mutex);
1605 rdev->deferred_disables++;
1606 mutex_unlock(&rdev->mutex);
1607
1608 ret = schedule_delayed_work(&rdev->disable_work,
1609 msecs_to_jiffies(ms));
1610 if (ret < 0)
1611 return ret;
1612 else
1613 return 0;
1614}
1615EXPORT_SYMBOL_GPL(regulator_disable_deferred);
1616
1555static int _regulator_is_enabled(struct regulator_dev *rdev) 1617static int _regulator_is_enabled(struct regulator_dev *rdev)
1556{ 1618{
1557 /* If we don't know then assume that the regulator is always on */ 1619 /* If we don't know then assume that the regulator is always on */
@@ -2622,6 +2684,7 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
2622 INIT_LIST_HEAD(&rdev->consumer_list); 2684 INIT_LIST_HEAD(&rdev->consumer_list);
2623 INIT_LIST_HEAD(&rdev->list); 2685 INIT_LIST_HEAD(&rdev->list);
2624 BLOCKING_INIT_NOTIFIER_HEAD(&rdev->notifier); 2686 BLOCKING_INIT_NOTIFIER_HEAD(&rdev->notifier);
2687 INIT_DELAYED_WORK(&rdev->disable_work, regulator_disable_work);
2625 2688
2626 /* preform any regulator specific init */ 2689 /* preform any regulator specific init */
2627 if (init_data->regulator_init) { 2690 if (init_data->regulator_init) {
@@ -2729,6 +2792,7 @@ void regulator_unregister(struct regulator_dev *rdev)
2729#ifdef CONFIG_DEBUG_FS 2792#ifdef CONFIG_DEBUG_FS
2730 debugfs_remove_recursive(rdev->debugfs); 2793 debugfs_remove_recursive(rdev->debugfs);
2731#endif 2794#endif
2795 flush_work_sync(&rdev->disable_work.work);
2732 WARN_ON(rdev->open_count); 2796 WARN_ON(rdev->open_count);
2733 unset_regulator_supplies(rdev); 2797 unset_regulator_supplies(rdev);
2734 list_del(&rdev->list); 2798 list_del(&rdev->list);
diff --git a/drivers/regulator/wm8994-regulator.c b/drivers/regulator/wm8994-regulator.c
index 1a6a690f24d..b87bf5c841f 100644
--- a/drivers/regulator/wm8994-regulator.c
+++ b/drivers/regulator/wm8994-regulator.c
@@ -140,6 +140,14 @@ static int wm8994_ldo2_list_voltage(struct regulator_dev *rdev,
140 return (selector * 100000) + 900000; 140 return (selector * 100000) + 900000;
141 case WM8958: 141 case WM8958:
142 return (selector * 100000) + 1000000; 142 return (selector * 100000) + 1000000;
143 case WM1811:
144 switch (selector) {
145 case 0:
146 return -EINVAL;
147 default:
148 return (selector * 100000) + 950000;
149 }
150 break;
143 default: 151 default:
144 return -EINVAL; 152 return -EINVAL;
145 } 153 }
@@ -170,6 +178,11 @@ static int wm8994_ldo2_set_voltage(struct regulator_dev *rdev,
170 case WM8958: 178 case WM8958:
171 selector = (min_uV - 1000000) / 100000; 179 selector = (min_uV - 1000000) / 100000;
172 break; 180 break;
181 case WM1811:
182 selector = (min_uV - 950000) / 100000;
183 if (selector == 0)
184 selector = 1;
185 break;
173 default: 186 default:
174 return -EINVAL; 187 return -EINVAL;
175 } 188 }
diff --git a/include/linux/input.h b/include/linux/input.h
index 6d5eddb18c8..3862e32c4ee 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -815,6 +815,7 @@ struct input_keymap_entry {
815#define SW_KEYPAD_SLIDE 0x0a /* set = keypad slide out */ 815#define SW_KEYPAD_SLIDE 0x0a /* set = keypad slide out */
816#define SW_FRONT_PROXIMITY 0x0b /* set = front proximity sensor active */ 816#define SW_FRONT_PROXIMITY 0x0b /* set = front proximity sensor active */
817#define SW_ROTATE_LOCK 0x0c /* set = rotate locked/disabled */ 817#define SW_ROTATE_LOCK 0x0c /* set = rotate locked/disabled */
818#define SW_LINEIN_INSERT 0x0d /* set = inserted */
818#define SW_MAX 0x0f 819#define SW_MAX 0x0f
819#define SW_CNT (SW_MAX+1) 820#define SW_CNT (SW_MAX+1)
820 821
diff --git a/include/linux/mfd/twl6040.h b/include/linux/mfd/twl6040.h
index 4c806f6d663..2463c261959 100644
--- a/include/linux/mfd/twl6040.h
+++ b/include/linux/mfd/twl6040.h
@@ -68,11 +68,6 @@
68#define TWL6040_REG_ACCCTL 0x2D 68#define TWL6040_REG_ACCCTL 0x2D
69#define TWL6040_REG_STATUS 0x2E 69#define TWL6040_REG_STATUS 0x2E
70 70
71#define TWL6040_CACHEREGNUM (TWL6040_REG_STATUS + 1)
72
73#define TWL6040_VIOREGNUM 18
74#define TWL6040_VDDREGNUM 21
75
76/* INTID (0x03) fields */ 71/* INTID (0x03) fields */
77 72
78#define TWL6040_THINT 0x01 73#define TWL6040_THINT 0x01
@@ -125,34 +120,24 @@
125#define TWL6040_LPLLFIN 0x08 120#define TWL6040_LPLLFIN 0x08
126#define TWL6040_HPLLSEL 0x10 121#define TWL6040_HPLLSEL 0x10
127 122
128/* HSLCTL (0x10) fields */ 123/* HSLCTL/R (0x10/0x11) fields */
129
130#define TWL6040_HSDACMODEL 0x02
131#define TWL6040_HSDRVMODEL 0x08
132
133/* HSRCTL (0x11) fields */
134 124
135#define TWL6040_HSDACMODER 0x02 125#define TWL6040_HSDACENA (1 << 0)
136#define TWL6040_HSDRVMODER 0x08 126#define TWL6040_HSDACMODE (1 << 1)
127#define TWL6040_HSDRVMODE (1 << 3)
137 128
138/* VIBCTLL (0x18) fields */ 129/* VIBCTLL/R (0x18/0x1A) fields */
139 130
140#define TWL6040_VIBENAL 0x01 131#define TWL6040_VIBENA (1 << 0)
141#define TWL6040_VIBCTRLL 0x04 132#define TWL6040_VIBSEL (1 << 1)
142#define TWL6040_VIBCTRLLP 0x08 133#define TWL6040_VIBCTRL (1 << 2)
143#define TWL6040_VIBCTRLLN 0x10 134#define TWL6040_VIBCTRL_P (1 << 3)
135#define TWL6040_VIBCTRL_N (1 << 4)
144 136
145/* VIBDATL (0x19) fields */ 137/* VIBDATL/R (0x19/0x1B) fields */
146 138
147#define TWL6040_VIBDAT_MAX 0x64 139#define TWL6040_VIBDAT_MAX 0x64
148 140
149/* VIBCTLR (0x1A) fields */
150
151#define TWL6040_VIBENAR 0x01
152#define TWL6040_VIBCTRLR 0x04
153#define TWL6040_VIBCTRLRP 0x08
154#define TWL6040_VIBCTRLRN 0x10
155
156/* GPOCTL (0x1E) fields */ 141/* GPOCTL (0x1E) fields */
157 142
158#define TWL6040_GPO1 0x01 143#define TWL6040_GPO1 0x01
@@ -200,6 +185,7 @@ struct twl6040 {
200 int audpwron; 185 int audpwron;
201 int power_count; 186 int power_count;
202 int rev; 187 int rev;
188 u8 vibra_ctrl_cache[2];
203 189
204 int pll; 190 int pll;
205 unsigned int sysclk; 191 unsigned int sysclk;
@@ -224,5 +210,13 @@ int twl6040_get_pll(struct twl6040 *twl6040);
224unsigned int twl6040_get_sysclk(struct twl6040 *twl6040); 210unsigned int twl6040_get_sysclk(struct twl6040 *twl6040);
225int twl6040_irq_init(struct twl6040 *twl6040); 211int twl6040_irq_init(struct twl6040 *twl6040);
226void twl6040_irq_exit(struct twl6040 *twl6040); 212void twl6040_irq_exit(struct twl6040 *twl6040);
213/* Get the combined status of the vibra control register */
214int twl6040_get_vibralr_status(struct twl6040 *twl6040);
215
216static inline int twl6040_get_revid(struct twl6040 *twl6040)
217{
218 return twl6040->rev;
219}
220
227 221
228#endif /* End of __TWL6040_CODEC_H__ */ 222#endif /* End of __TWL6040_CODEC_H__ */
diff --git a/include/linux/mfd/wm8994/core.h b/include/linux/mfd/wm8994/core.h
index 45df450d869..62680914762 100644
--- a/include/linux/mfd/wm8994/core.h
+++ b/include/linux/mfd/wm8994/core.h
@@ -20,6 +20,7 @@
20enum wm8994_type { 20enum wm8994_type {
21 WM8994 = 0, 21 WM8994 = 0,
22 WM8958 = 1, 22 WM8958 = 1,
23 WM1811 = 2,
23}; 24};
24 25
25struct regulator_dev; 26struct regulator_dev;
diff --git a/include/linux/mfd/wm8994/registers.h b/include/linux/mfd/wm8994/registers.h
index f3ee8428467..fae295048a8 100644
--- a/include/linux/mfd/wm8994/registers.h
+++ b/include/linux/mfd/wm8994/registers.h
@@ -72,6 +72,7 @@
72#define WM8994_DC_SERVO_2 0x55 72#define WM8994_DC_SERVO_2 0x55
73#define WM8994_DC_SERVO_4 0x57 73#define WM8994_DC_SERVO_4 0x57
74#define WM8994_DC_SERVO_READBACK 0x58 74#define WM8994_DC_SERVO_READBACK 0x58
75#define WM8994_DC_SERVO_4E 0x59
75#define WM8994_ANALOGUE_HP_1 0x60 76#define WM8994_ANALOGUE_HP_1 0x60
76#define WM8958_MIC_DETECT_1 0xD0 77#define WM8958_MIC_DETECT_1 0xD0
77#define WM8958_MIC_DETECT_2 0xD1 78#define WM8958_MIC_DETECT_2 0xD1
@@ -133,6 +134,8 @@
133#define WM8994_AIF1_DAC1_FILTERS_2 0x421 134#define WM8994_AIF1_DAC1_FILTERS_2 0x421
134#define WM8994_AIF1_DAC2_FILTERS_1 0x422 135#define WM8994_AIF1_DAC2_FILTERS_1 0x422
135#define WM8994_AIF1_DAC2_FILTERS_2 0x423 136#define WM8994_AIF1_DAC2_FILTERS_2 0x423
137#define WM8958_AIF1_DAC1_NOISE_GATE 0x430
138#define WM8958_AIF1_DAC2_NOISE_GATE 0x431
136#define WM8994_AIF1_DRC1_1 0x440 139#define WM8994_AIF1_DRC1_1 0x440
137#define WM8994_AIF1_DRC1_2 0x441 140#define WM8994_AIF1_DRC1_2 0x441
138#define WM8994_AIF1_DRC1_3 0x442 141#define WM8994_AIF1_DRC1_3 0x442
@@ -190,6 +193,7 @@
190#define WM8994_AIF2_ADC_FILTERS 0x510 193#define WM8994_AIF2_ADC_FILTERS 0x510
191#define WM8994_AIF2_DAC_FILTERS_1 0x520 194#define WM8994_AIF2_DAC_FILTERS_1 0x520
192#define WM8994_AIF2_DAC_FILTERS_2 0x521 195#define WM8994_AIF2_DAC_FILTERS_2 0x521
196#define WM8958_AIF2_DAC_NOISE_GATE 0x530
193#define WM8994_AIF2_DRC_1 0x540 197#define WM8994_AIF2_DRC_1 0x540
194#define WM8994_AIF2_DRC_2 0x541 198#define WM8994_AIF2_DRC_2 0x541
195#define WM8994_AIF2_DRC_3 0x542 199#define WM8994_AIF2_DRC_3 0x542
@@ -1921,6 +1925,44 @@
1921#define WM8994_LDO2_DISCH_WIDTH 1 /* LDO2_DISCH */ 1925#define WM8994_LDO2_DISCH_WIDTH 1 /* LDO2_DISCH */
1922 1926
1923/* 1927/*
1928 * R61 (0x3D) - MICBIAS1
1929 */
1930#define WM8958_MICB1_RATE 0x0020 /* MICB1_RATE */
1931#define WM8958_MICB1_RATE_MASK 0x0020 /* MICB1_RATE */
1932#define WM8958_MICB1_RATE_SHIFT 5 /* MICB1_RATE */
1933#define WM8958_MICB1_RATE_WIDTH 1 /* MICB1_RATE */
1934#define WM8958_MICB1_MODE 0x0010 /* MICB1_MODE */
1935#define WM8958_MICB1_MODE_MASK 0x0010 /* MICB1_MODE */
1936#define WM8958_MICB1_MODE_SHIFT 4 /* MICB1_MODE */
1937#define WM8958_MICB1_MODE_WIDTH 1 /* MICB1_MODE */
1938#define WM8958_MICB1_LVL_MASK 0x000E /* MICB1_LVL - [3:1] */
1939#define WM8958_MICB1_LVL_SHIFT 1 /* MICB1_LVL - [3:1] */
1940#define WM8958_MICB1_LVL_WIDTH 3 /* MICB1_LVL - [3:1] */
1941#define WM8958_MICB1_DISCH 0x0001 /* MICB1_DISCH */
1942#define WM8958_MICB1_DISCH_MASK 0x0001 /* MICB1_DISCH */
1943#define WM8958_MICB1_DISCH_SHIFT 0 /* MICB1_DISCH */
1944#define WM8958_MICB1_DISCH_WIDTH 1 /* MICB1_DISCH */
1945
1946/*
1947 * R62 (0x3E) - MICBIAS2
1948 */
1949#define WM8958_MICB2_RATE 0x0020 /* MICB2_RATE */
1950#define WM8958_MICB2_RATE_MASK 0x0020 /* MICB2_RATE */
1951#define WM8958_MICB2_RATE_SHIFT 5 /* MICB2_RATE */
1952#define WM8958_MICB2_RATE_WIDTH 1 /* MICB2_RATE */
1953#define WM8958_MICB2_MODE 0x0010 /* MICB2_MODE */
1954#define WM8958_MICB2_MODE_MASK 0x0010 /* MICB2_MODE */
1955#define WM8958_MICB2_MODE_SHIFT 4 /* MICB2_MODE */
1956#define WM8958_MICB2_MODE_WIDTH 1 /* MICB2_MODE */
1957#define WM8958_MICB2_LVL_MASK 0x000E /* MICB2_LVL - [3:1] */
1958#define WM8958_MICB2_LVL_SHIFT 1 /* MICB2_LVL - [3:1] */
1959#define WM8958_MICB2_LVL_WIDTH 3 /* MICB2_LVL - [3:1] */
1960#define WM8958_MICB2_DISCH 0x0001 /* MICB2_DISCH */
1961#define WM8958_MICB2_DISCH_MASK 0x0001 /* MICB2_DISCH */
1962#define WM8958_MICB2_DISCH_SHIFT 0 /* MICB2_DISCH */
1963#define WM8958_MICB2_DISCH_WIDTH 1 /* MICB2_DISCH */
1964
1965/*
1924 * R76 (0x4C) - Charge Pump (1) 1966 * R76 (0x4C) - Charge Pump (1)
1925 */ 1967 */
1926#define WM8994_CP_ENA 0x8000 /* CP_ENA */ 1968#define WM8994_CP_ENA 0x8000 /* CP_ENA */
@@ -2027,6 +2069,10 @@
2027/* 2069/*
2028 * R96 (0x60) - Analogue HP (1) 2070 * R96 (0x60) - Analogue HP (1)
2029 */ 2071 */
2072#define WM1811_HPOUT1_ATTN 0x0100 /* HPOUT1_ATTN */
2073#define WM1811_HPOUT1_ATTN_MASK 0x0100 /* HPOUT1_ATTN */
2074#define WM1811_HPOUT1_ATTN_SHIFT 8 /* HPOUT1_ATTN */
2075#define WM1811_HPOUT1_ATTN_WIDTH 1 /* HPOUT1_ATTN */
2030#define WM8994_HPOUT1L_RMV_SHORT 0x0080 /* HPOUT1L_RMV_SHORT */ 2076#define WM8994_HPOUT1L_RMV_SHORT 0x0080 /* HPOUT1L_RMV_SHORT */
2031#define WM8994_HPOUT1L_RMV_SHORT_MASK 0x0080 /* HPOUT1L_RMV_SHORT */ 2077#define WM8994_HPOUT1L_RMV_SHORT_MASK 0x0080 /* HPOUT1L_RMV_SHORT */
2032#define WM8994_HPOUT1L_RMV_SHORT_SHIFT 7 /* HPOUT1L_RMV_SHORT */ 2078#define WM8994_HPOUT1L_RMV_SHORT_SHIFT 7 /* HPOUT1L_RMV_SHORT */
@@ -2949,6 +2995,34 @@
2949#define WM8994_AIF1DAC2_3D_ENA_WIDTH 1 /* AIF1DAC2_3D_ENA */ 2995#define WM8994_AIF1DAC2_3D_ENA_WIDTH 1 /* AIF1DAC2_3D_ENA */
2950 2996
2951/* 2997/*
2998 * R1072 (0x430) - AIF1 DAC1 Noise Gate
2999 */
3000#define WM8958_AIF1DAC1_NG_HLD_MASK 0x0060 /* AIF1DAC1_NG_HLD - [6:5] */
3001#define WM8958_AIF1DAC1_NG_HLD_SHIFT 5 /* AIF1DAC1_NG_HLD - [6:5] */
3002#define WM8958_AIF1DAC1_NG_HLD_WIDTH 2 /* AIF1DAC1_NG_HLD - [6:5] */
3003#define WM8958_AIF1DAC1_NG_THR_MASK 0x000E /* AIF1DAC1_NG_THR - [3:1] */
3004#define WM8958_AIF1DAC1_NG_THR_SHIFT 1 /* AIF1DAC1_NG_THR - [3:1] */
3005#define WM8958_AIF1DAC1_NG_THR_WIDTH 3 /* AIF1DAC1_NG_THR - [3:1] */
3006#define WM8958_AIF1DAC1_NG_ENA 0x0001 /* AIF1DAC1_NG_ENA */
3007#define WM8958_AIF1DAC1_NG_ENA_MASK 0x0001 /* AIF1DAC1_NG_ENA */
3008#define WM8958_AIF1DAC1_NG_ENA_SHIFT 0 /* AIF1DAC1_NG_ENA */
3009#define WM8958_AIF1DAC1_NG_ENA_WIDTH 1 /* AIF1DAC1_NG_ENA */
3010
3011/*
3012 * R1073 (0x431) - AIF1 DAC2 Noise Gate
3013 */
3014#define WM8958_AIF1DAC2_NG_HLD_MASK 0x0060 /* AIF1DAC2_NG_HLD - [6:5] */
3015#define WM8958_AIF1DAC2_NG_HLD_SHIFT 5 /* AIF1DAC2_NG_HLD - [6:5] */
3016#define WM8958_AIF1DAC2_NG_HLD_WIDTH 2 /* AIF1DAC2_NG_HLD - [6:5] */
3017#define WM8958_AIF1DAC2_NG_THR_MASK 0x000E /* AIF1DAC2_NG_THR - [3:1] */
3018#define WM8958_AIF1DAC2_NG_THR_SHIFT 1 /* AIF1DAC2_NG_THR - [3:1] */
3019#define WM8958_AIF1DAC2_NG_THR_WIDTH 3 /* AIF1DAC2_NG_THR - [3:1] */
3020#define WM8958_AIF1DAC2_NG_ENA 0x0001 /* AIF1DAC2_NG_ENA */
3021#define WM8958_AIF1DAC2_NG_ENA_MASK 0x0001 /* AIF1DAC2_NG_ENA */
3022#define WM8958_AIF1DAC2_NG_ENA_SHIFT 0 /* AIF1DAC2_NG_ENA */
3023#define WM8958_AIF1DAC2_NG_ENA_WIDTH 1 /* AIF1DAC2_NG_ENA */
3024
3025/*
2952 * R1088 (0x440) - AIF1 DRC1 (1) 3026 * R1088 (0x440) - AIF1 DRC1 (1)
2953 */ 3027 */
2954#define WM8994_AIF1DRC1_SIG_DET_RMS_MASK 0xF800 /* AIF1DRC1_SIG_DET_RMS - [15:11] */ 3028#define WM8994_AIF1DRC1_SIG_DET_RMS_MASK 0xF800 /* AIF1DRC1_SIG_DET_RMS - [15:11] */
@@ -3560,6 +3634,20 @@
3560#define WM8994_AIF2DAC_3D_ENA_WIDTH 1 /* AIF2DAC_3D_ENA */ 3634#define WM8994_AIF2DAC_3D_ENA_WIDTH 1 /* AIF2DAC_3D_ENA */
3561 3635
3562/* 3636/*
3637 * R1328 (0x530) - AIF2 DAC Noise Gate
3638 */
3639#define WM8958_AIF2DAC_NG_HLD_MASK 0x0060 /* AIF2DAC_NG_HLD - [6:5] */
3640#define WM8958_AIF2DAC_NG_HLD_SHIFT 5 /* AIF2DAC_NG_HLD - [6:5] */
3641#define WM8958_AIF2DAC_NG_HLD_WIDTH 2 /* AIF2DAC_NG_HLD - [6:5] */
3642#define WM8958_AIF2DAC_NG_THR_MASK 0x000E /* AIF2DAC_NG_THR - [3:1] */
3643#define WM8958_AIF2DAC_NG_THR_SHIFT 1 /* AIF2DAC_NG_THR - [3:1] */
3644#define WM8958_AIF2DAC_NG_THR_WIDTH 3 /* AIF2DAC_NG_THR - [3:1] */
3645#define WM8958_AIF2DAC_NG_ENA 0x0001 /* AIF2DAC_NG_ENA */
3646#define WM8958_AIF2DAC_NG_ENA_MASK 0x0001 /* AIF2DAC_NG_ENA */
3647#define WM8958_AIF2DAC_NG_ENA_SHIFT 0 /* AIF2DAC_NG_ENA */
3648#define WM8958_AIF2DAC_NG_ENA_WIDTH 1 /* AIF2DAC_NG_ENA */
3649
3650/*
3563 * R1344 (0x540) - AIF2 DRC (1) 3651 * R1344 (0x540) - AIF2 DRC (1)
3564 */ 3652 */
3565#define WM8994_AIF2DRC_SIG_DET_RMS_MASK 0xF800 /* AIF2DRC_SIG_DET_RMS - [15:11] */ 3653#define WM8994_AIF2DRC_SIG_DET_RMS_MASK 0xF800 /* AIF2DRC_SIG_DET_RMS - [15:11] */
diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h
index b47771aa571..f7756d146c6 100644
--- a/include/linux/regulator/consumer.h
+++ b/include/linux/regulator/consumer.h
@@ -141,6 +141,7 @@ int regulator_enable(struct regulator *regulator);
141int regulator_disable(struct regulator *regulator); 141int regulator_disable(struct regulator *regulator);
142int regulator_force_disable(struct regulator *regulator); 142int regulator_force_disable(struct regulator *regulator);
143int regulator_is_enabled(struct regulator *regulator); 143int regulator_is_enabled(struct regulator *regulator);
144int regulator_disable_deferred(struct regulator *regulator, int ms);
144 145
145int regulator_bulk_get(struct device *dev, int num_consumers, 146int regulator_bulk_get(struct device *dev, int num_consumers,
146 struct regulator_bulk_data *consumers); 147 struct regulator_bulk_data *consumers);
@@ -211,6 +212,12 @@ static inline int regulator_disable(struct regulator *regulator)
211 return 0; 212 return 0;
212} 213}
213 214
215static inline int regulator_disable_deferred(struct regulator *regulator,
216 int ms)
217{
218 return 0;
219}
220
214static inline int regulator_is_enabled(struct regulator *regulator) 221static inline int regulator_is_enabled(struct regulator *regulator)
215{ 222{
216 return 1; 223 return 1;
diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h
index 1a80bc77517..12a1aa04b72 100644
--- a/include/linux/regulator/driver.h
+++ b/include/linux/regulator/driver.h
@@ -199,6 +199,9 @@ struct regulator_dev {
199 struct regulation_constraints *constraints; 199 struct regulation_constraints *constraints;
200 struct regulator *supply; /* for tree */ 200 struct regulator *supply; /* for tree */
201 201
202 struct delayed_work disable_work;
203 int deferred_disables;
204
202 void *reg_data; /* regulator_dev data */ 205 void *reg_data; /* regulator_dev data */
203 206
204#ifdef CONFIG_DEBUG_FS 207#ifdef CONFIG_DEBUG_FS
diff --git a/include/linux/usb/ch9.h b/include/linux/usb/ch9.h
index f32a64e57f9..d5da6c68c25 100644
--- a/include/linux/usb/ch9.h
+++ b/include/linux/usb/ch9.h
@@ -383,12 +383,6 @@ struct usb_endpoint_descriptor {
383#define USB_ENDPOINT_NUMBER_MASK 0x0f /* in bEndpointAddress */ 383#define USB_ENDPOINT_NUMBER_MASK 0x0f /* in bEndpointAddress */
384#define USB_ENDPOINT_DIR_MASK 0x80 384#define USB_ENDPOINT_DIR_MASK 0x80
385 385
386#define USB_ENDPOINT_SYNCTYPE 0x0c
387#define USB_ENDPOINT_SYNC_NONE (0 << 2)
388#define USB_ENDPOINT_SYNC_ASYNC (1 << 2)
389#define USB_ENDPOINT_SYNC_ADAPTIVE (2 << 2)
390#define USB_ENDPOINT_SYNC_SYNC (3 << 2)
391
392#define USB_ENDPOINT_XFERTYPE_MASK 0x03 /* in bmAttributes */ 386#define USB_ENDPOINT_XFERTYPE_MASK 0x03 /* in bmAttributes */
393#define USB_ENDPOINT_XFER_CONTROL 0 387#define USB_ENDPOINT_XFER_CONTROL 0
394#define USB_ENDPOINT_XFER_ISOC 1 388#define USB_ENDPOINT_XFER_ISOC 1
@@ -396,6 +390,17 @@ struct usb_endpoint_descriptor {
396#define USB_ENDPOINT_XFER_INT 3 390#define USB_ENDPOINT_XFER_INT 3
397#define USB_ENDPOINT_MAX_ADJUSTABLE 0x80 391#define USB_ENDPOINT_MAX_ADJUSTABLE 0x80
398 392
393#define USB_ENDPOINT_SYNCTYPE 0x0c
394#define USB_ENDPOINT_SYNC_NONE (0 << 2)
395#define USB_ENDPOINT_SYNC_ASYNC (1 << 2)
396#define USB_ENDPOINT_SYNC_ADAPTIVE (2 << 2)
397#define USB_ENDPOINT_SYNC_SYNC (3 << 2)
398
399#define USB_ENDPOINT_USAGE_MASK 0x30
400#define USB_ENDPOINT_USAGE_DATA 0x00
401#define USB_ENDPOINT_USAGE_FEEDBACK 0x10
402#define USB_ENDPOINT_USAGE_IMPLICIT_FB 0x20 /* Implicit feedback Data endpoint */
403
399/*-------------------------------------------------------------------------*/ 404/*-------------------------------------------------------------------------*/
400 405
401/** 406/**
diff --git a/include/sound/adau1373.h b/include/sound/adau1373.h
new file mode 100644
index 00000000000..1b19c766657
--- /dev/null
+++ b/include/sound/adau1373.h
@@ -0,0 +1,34 @@
1/*
2 * Analog Devices ADAU1373 Audio Codec drive
3 *
4 * Copyright 2011 Analog Devices Inc.
5 * Author: Lars-Peter Clausen <lars@metafoo.de>
6 *
7 * Licensed under the GPL-2 or later.
8 */
9
10#ifndef __SOUND_ADAU1373_H__
11#define __SOUND_ADAU1373_H__
12
13enum adau1373_micbias_voltage {
14 ADAU1373_MICBIAS_2_9V = 0,
15 ADAU1373_MICBIAS_2_2V = 1,
16 ADAU1373_MICBIAS_2_6V = 2,
17 ADAU1373_MICBIAS_1_8V = 3,
18};
19
20#define ADAU1373_DRC_SIZE 13
21
22struct adau1373_platform_data {
23 bool input_differential[4];
24 bool lineout_differential;
25 bool lineout_ground_sense;
26
27 unsigned int num_drc;
28 uint8_t drc_setting[3][ADAU1373_DRC_SIZE];
29
30 enum adau1373_micbias_voltage micbias1;
31 enum adau1373_micbias_voltage micbias2;
32};
33
34#endif
diff --git a/include/sound/asound.h b/include/sound/asound.h
index 5d6074faa27..a2e4ff5ba9e 100644
--- a/include/sound/asound.h
+++ b/include/sound/asound.h
@@ -706,7 +706,7 @@ struct snd_timer_tread {
706 * * 706 * *
707 ****************************************************************************/ 707 ****************************************************************************/
708 708
709#define SNDRV_CTL_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 6) 709#define SNDRV_CTL_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 7)
710 710
711struct snd_ctl_card_info { 711struct snd_ctl_card_info {
712 int card; /* card number */ 712 int card; /* card number */
@@ -803,6 +803,8 @@ struct snd_ctl_elem_info {
803 unsigned int items; /* R: number of items */ 803 unsigned int items; /* R: number of items */
804 unsigned int item; /* W: item number */ 804 unsigned int item; /* W: item number */
805 char name[64]; /* R: value name */ 805 char name[64]; /* R: value name */
806 __u64 names_ptr; /* W: names list (ELEM_ADD only) */
807 unsigned int names_length;
806 } enumerated; 808 } enumerated;
807 unsigned char reserved[128]; 809 unsigned char reserved[128];
808 } value; 810 } value;
diff --git a/include/sound/initval.h b/include/sound/initval.h
index 1daa6dff829..f99a0d2ddfe 100644
--- a/include/sound/initval.h
+++ b/include/sound/initval.h
@@ -62,7 +62,7 @@ static int snd_legacy_find_free_irq(int *irq_table)
62{ 62{
63 while (*irq_table != -1) { 63 while (*irq_table != -1) {
64 if (!request_irq(*irq_table, snd_legacy_empty_irq_handler, 64 if (!request_irq(*irq_table, snd_legacy_empty_irq_handler,
65 IRQF_DISABLED | IRQF_PROBE_SHARED, "ALSA Test IRQ", 65 IRQF_PROBE_SHARED, "ALSA Test IRQ",
66 (void *) irq_table)) { 66 (void *) irq_table)) {
67 free_irq(*irq_table, (void *) irq_table); 67 free_irq(*irq_table, (void *) irq_table);
68 return *irq_table; 68 return *irq_table;
diff --git a/include/sound/jack.h b/include/sound/jack.h
index c140fc7cbd3..63c790742db 100644
--- a/include/sound/jack.h
+++ b/include/sound/jack.h
@@ -42,6 +42,7 @@ enum snd_jack_types {
42 SND_JACK_MECHANICAL = 0x0008, /* If detected separately */ 42 SND_JACK_MECHANICAL = 0x0008, /* If detected separately */
43 SND_JACK_VIDEOOUT = 0x0010, 43 SND_JACK_VIDEOOUT = 0x0010,
44 SND_JACK_AVOUT = SND_JACK_LINEOUT | SND_JACK_VIDEOOUT, 44 SND_JACK_AVOUT = SND_JACK_LINEOUT | SND_JACK_VIDEOOUT,
45 SND_JACK_LINEIN = 0x0020,
45 46
46 /* Kept separate from switches to facilitate implementation */ 47 /* Kept separate from switches to facilitate implementation */
47 SND_JACK_BTN_0 = 0x4000, 48 SND_JACK_BTN_0 = 0x4000,
diff --git a/include/sound/mpu401.h b/include/sound/mpu401.h
index 1f1d53f8830..20230db00ef 100644
--- a/include/sound/mpu401.h
+++ b/include/sound/mpu401.h
@@ -50,7 +50,10 @@
50#define MPU401_INFO_INTEGRATED (1 << 2) /* integrated h/w port */ 50#define MPU401_INFO_INTEGRATED (1 << 2) /* integrated h/w port */
51#define MPU401_INFO_MMIO (1 << 3) /* MMIO access */ 51#define MPU401_INFO_MMIO (1 << 3) /* MMIO access */
52#define MPU401_INFO_TX_IRQ (1 << 4) /* independent TX irq */ 52#define MPU401_INFO_TX_IRQ (1 << 4) /* independent TX irq */
53#define MPU401_INFO_IRQ_HOOK (1 << 5) /* mpu401 irq handler is called
54 from driver irq handler */
53#define MPU401_INFO_NO_ACK (1 << 6) /* No ACK cmd needed */ 55#define MPU401_INFO_NO_ACK (1 << 6) /* No ACK cmd needed */
56#define MPU401_INFO_USE_TIMER (1 << 15) /* internal */
54 57
55#define MPU401_MODE_BIT_INPUT 0 58#define MPU401_MODE_BIT_INPUT 0
56#define MPU401_MODE_BIT_OUTPUT 1 59#define MPU401_MODE_BIT_OUTPUT 1
@@ -73,8 +76,7 @@ struct snd_mpu401 {
73 unsigned long port; /* base port of MPU-401 chip */ 76 unsigned long port; /* base port of MPU-401 chip */
74 unsigned long cport; /* port + 1 (usually) */ 77 unsigned long cport; /* port + 1 (usually) */
75 struct resource *res; /* port resource */ 78 struct resource *res; /* port resource */
76 int irq; /* IRQ number of MPU-401 chip (-1 = poll) */ 79 int irq; /* IRQ number of MPU-401 chip */
77 int irq_flags;
78 80
79 unsigned long mode; /* MPU401_MODE_XXXX */ 81 unsigned long mode; /* MPU401_MODE_XXXX */
80 int timer_invoked; 82 int timer_invoked;
@@ -131,7 +133,6 @@ int snd_mpu401_uart_new(struct snd_card *card,
131 unsigned long port, 133 unsigned long port,
132 unsigned int info_flags, 134 unsigned int info_flags,
133 int irq, 135 int irq,
134 int irq_flags,
135 struct snd_rawmidi ** rrawmidi); 136 struct snd_rawmidi ** rrawmidi);
136 137
137#endif /* __SOUND_MPU401_H */ 138#endif /* __SOUND_MPU401_H */
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index 54cb079b7bf..0cf91b2f08c 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -825,6 +825,8 @@ int snd_pcm_hw_constraint_step(struct snd_pcm_runtime *runtime,
825int snd_pcm_hw_constraint_pow2(struct snd_pcm_runtime *runtime, 825int snd_pcm_hw_constraint_pow2(struct snd_pcm_runtime *runtime,
826 unsigned int cond, 826 unsigned int cond,
827 snd_pcm_hw_param_t var); 827 snd_pcm_hw_param_t var);
828int snd_pcm_hw_rule_noresample(struct snd_pcm_runtime *runtime,
829 unsigned int base_rate);
828int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, 830int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime,
829 unsigned int cond, 831 unsigned int cond,
830 int var, 832 int var,
@@ -1035,6 +1037,8 @@ static inline void snd_pcm_mmap_data_close(struct vm_area_struct *area)
1035 atomic_dec(&substream->mmap_count); 1037 atomic_dec(&substream->mmap_count);
1036} 1038}
1037 1039
1040int snd_pcm_lib_default_mmap(struct snd_pcm_substream *substream,
1041 struct vm_area_struct *area);
1038/* mmap for io-memory area */ 1042/* mmap for io-memory area */
1039#if defined(CONFIG_X86) || defined(CONFIG_PPC) || defined(CONFIG_ALPHA) 1043#if defined(CONFIG_X86) || defined(CONFIG_PPC) || defined(CONFIG_ALPHA)
1040#define SNDRV_PCM_INFO_MMAP_IOMEM SNDRV_PCM_INFO_MMAP 1044#define SNDRV_PCM_INFO_MMAP_IOMEM SNDRV_PCM_INFO_MMAP
diff --git a/include/sound/saif.h b/include/sound/saif.h
new file mode 100644
index 00000000000..d0e0de7984e
--- /dev/null
+++ b/include/sound/saif.h
@@ -0,0 +1,16 @@
1/*
2 * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
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 __SOUND_SAIF_H__
10#define __SOUND_SAIF_H__
11
12struct mxs_saif_platform_data {
13 int (*init) (void);
14 int (*get_master_id) (unsigned int saif_id);
15};
16#endif
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index 5ad5f3a50c6..2413acc5488 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -24,13 +24,13 @@ struct snd_pcm_substream;
24 * Describes the physical PCM data formating and clocking. Add new formats 24 * Describes the physical PCM data formating and clocking. Add new formats
25 * to the end. 25 * to the end.
26 */ 26 */
27#define SND_SOC_DAIFMT_I2S 0 /* I2S mode */ 27#define SND_SOC_DAIFMT_I2S 1 /* I2S mode */
28#define SND_SOC_DAIFMT_RIGHT_J 1 /* Right Justified mode */ 28#define SND_SOC_DAIFMT_RIGHT_J 2 /* Right Justified mode */
29#define SND_SOC_DAIFMT_LEFT_J 2 /* Left Justified mode */ 29#define SND_SOC_DAIFMT_LEFT_J 3 /* Left Justified mode */
30#define SND_SOC_DAIFMT_DSP_A 3 /* L data MSB after FRM LRC */ 30#define SND_SOC_DAIFMT_DSP_A 4 /* L data MSB after FRM LRC */
31#define SND_SOC_DAIFMT_DSP_B 4 /* L data MSB during FRM LRC */ 31#define SND_SOC_DAIFMT_DSP_B 5 /* L data MSB during FRM LRC */
32#define SND_SOC_DAIFMT_AC97 5 /* AC97 */ 32#define SND_SOC_DAIFMT_AC97 6 /* AC97 */
33#define SND_SOC_DAIFMT_PDM 6 /* Pulse density modulation */ 33#define SND_SOC_DAIFMT_PDM 7 /* Pulse density modulation */
34 34
35/* left and right justified also known as MSB and LSB respectively */ 35/* left and right justified also known as MSB and LSB respectively */
36#define SND_SOC_DAIFMT_MSB SND_SOC_DAIFMT_LEFT_J 36#define SND_SOC_DAIFMT_MSB SND_SOC_DAIFMT_LEFT_J
@@ -42,8 +42,8 @@ struct snd_pcm_substream;
42 * DAI bit clocks can be be gated (disabled) when the DAI is not 42 * DAI bit clocks can be be gated (disabled) when the DAI is not
43 * sending or receiving PCM data in a frame. This can be used to save power. 43 * sending or receiving PCM data in a frame. This can be used to save power.
44 */ 44 */
45#define SND_SOC_DAIFMT_CONT (0 << 4) /* continuous clock */ 45#define SND_SOC_DAIFMT_CONT (1 << 4) /* continuous clock */
46#define SND_SOC_DAIFMT_GATED (1 << 4) /* clock is gated */ 46#define SND_SOC_DAIFMT_GATED (2 << 4) /* clock is gated */
47 47
48/* 48/*
49 * DAI hardware signal inversions. 49 * DAI hardware signal inversions.
@@ -51,10 +51,10 @@ struct snd_pcm_substream;
51 * Specifies whether the DAI can also support inverted clocks for the specified 51 * Specifies whether the DAI can also support inverted clocks for the specified
52 * format. 52 * format.
53 */ 53 */
54#define SND_SOC_DAIFMT_NB_NF (0 << 8) /* normal bit clock + frame */ 54#define SND_SOC_DAIFMT_NB_NF (1 << 8) /* normal bit clock + frame */
55#define SND_SOC_DAIFMT_NB_IF (1 << 8) /* normal BCLK + inv FRM */ 55#define SND_SOC_DAIFMT_NB_IF (2 << 8) /* normal BCLK + inv FRM */
56#define SND_SOC_DAIFMT_IB_NF (2 << 8) /* invert BCLK + nor FRM */ 56#define SND_SOC_DAIFMT_IB_NF (3 << 8) /* invert BCLK + nor FRM */
57#define SND_SOC_DAIFMT_IB_IF (3 << 8) /* invert BCLK + FRM */ 57#define SND_SOC_DAIFMT_IB_IF (4 << 8) /* invert BCLK + FRM */
58 58
59/* 59/*
60 * DAI hardware clock masters. 60 * DAI hardware clock masters.
@@ -63,10 +63,10 @@ struct snd_pcm_substream;
63 * i.e. if the codec is clk and FRM master then the interface is 63 * i.e. if the codec is clk and FRM master then the interface is
64 * clk and frame slave. 64 * clk and frame slave.
65 */ 65 */
66#define SND_SOC_DAIFMT_CBM_CFM (0 << 12) /* codec clk & FRM master */ 66#define SND_SOC_DAIFMT_CBM_CFM (1 << 12) /* codec clk & FRM master */
67#define SND_SOC_DAIFMT_CBS_CFM (1 << 12) /* codec clk slave & FRM master */ 67#define SND_SOC_DAIFMT_CBS_CFM (2 << 12) /* codec clk slave & FRM master */
68#define SND_SOC_DAIFMT_CBM_CFS (2 << 12) /* codec clk master & frame slave */ 68#define SND_SOC_DAIFMT_CBM_CFS (3 << 12) /* codec clk master & frame slave */
69#define SND_SOC_DAIFMT_CBS_CFS (3 << 12) /* codec clk & FRM slave */ 69#define SND_SOC_DAIFMT_CBS_CFS (4 << 12) /* codec clk & FRM slave */
70 70
71#define SND_SOC_DAIFMT_FORMAT_MASK 0x000f 71#define SND_SOC_DAIFMT_FORMAT_MASK 0x000f
72#define SND_SOC_DAIFMT_CLOCK_MASK 0x00f0 72#define SND_SOC_DAIFMT_CLOCK_MASK 0x00f0
@@ -242,6 +242,9 @@ struct snd_soc_dai {
242 void *playback_dma_data; 242 void *playback_dma_data;
243 void *capture_dma_data; 243 void *capture_dma_data;
244 244
245 /* Symmetry data - only valid if symmetry is being enforced */
246 unsigned int rate;
247
245 /* parent platform/codec */ 248 /* parent platform/codec */
246 union { 249 union {
247 struct snd_soc_platform *platform; 250 struct snd_soc_platform *platform;
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index e0583b7769c..17a4c17f19f 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -381,6 +381,9 @@ int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm,
381int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm, 381int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm,
382 const char *pin); 382 const char *pin);
383 383
384/* Mostly internal - should not normally be used */
385void dapm_mark_dirty(struct snd_soc_dapm_widget *w, const char *reason);
386
384/* dapm widget types */ 387/* dapm widget types */
385enum snd_soc_dapm_type { 388enum snd_soc_dapm_type {
386 snd_soc_dapm_input = 0, /* input pin */ 389 snd_soc_dapm_input = 0, /* input pin */
@@ -473,6 +476,8 @@ struct snd_soc_dapm_widget {
473 unsigned char ext:1; /* has external widgets */ 476 unsigned char ext:1; /* has external widgets */
474 unsigned char force:1; /* force state */ 477 unsigned char force:1; /* force state */
475 unsigned char ignore_suspend:1; /* kept enabled over suspend */ 478 unsigned char ignore_suspend:1; /* kept enabled over suspend */
479 unsigned char new_power:1; /* power from this run */
480 unsigned char power_checked:1; /* power checked this run */
476 int subseq; /* sort within widget type */ 481 int subseq; /* sort within widget type */
477 482
478 int (*power_check)(struct snd_soc_dapm_widget *w); 483 int (*power_check)(struct snd_soc_dapm_widget *w);
@@ -492,6 +497,9 @@ struct snd_soc_dapm_widget {
492 497
493 /* used during DAPM updates */ 498 /* used during DAPM updates */
494 struct list_head power_list; 499 struct list_head power_list;
500 struct list_head dirty;
501 int inputs;
502 int outputs;
495}; 503};
496 504
497struct snd_soc_dapm_update { 505struct snd_soc_dapm_update {
@@ -524,6 +532,8 @@ struct snd_soc_dapm_context {
524 enum snd_soc_bias_level target_bias_level; 532 enum snd_soc_bias_level target_bias_level;
525 struct list_head list; 533 struct list_head list;
526 534
535 int (*stream_event)(struct snd_soc_dapm_context *dapm, int event);
536
527#ifdef CONFIG_DEBUG_FS 537#ifdef CONFIG_DEBUG_FS
528 struct dentry *debugfs_dapm; 538 struct dentry *debugfs_dapm;
529#endif 539#endif
@@ -535,4 +545,10 @@ struct snd_soc_dapm_widget_list {
535 struct snd_soc_dapm_widget *widgets[0]; 545 struct snd_soc_dapm_widget *widgets[0];
536}; 546};
537 547
548struct snd_soc_dapm_stats {
549 int power_checks;
550 int path_checks;
551 int neighbour_checks;
552};
553
538#endif 554#endif
diff --git a/include/sound/soc.h b/include/sound/soc.h
index aa19f5a32ba..11cfb5953e0 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -19,6 +19,7 @@
19#include <linux/workqueue.h> 19#include <linux/workqueue.h>
20#include <linux/interrupt.h> 20#include <linux/interrupt.h>
21#include <linux/kernel.h> 21#include <linux/kernel.h>
22#include <linux/regmap.h>
22#include <sound/core.h> 23#include <sound/core.h>
23#include <sound/pcm.h> 24#include <sound/pcm.h>
24#include <sound/control.h> 25#include <sound/control.h>
@@ -27,13 +28,20 @@
27/* 28/*
28 * Convenience kcontrol builders 29 * Convenience kcontrol builders
29 */ 30 */
30#define SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) \ 31#define SOC_DOUBLE_VALUE(xreg, shift_left, shift_right, xmax, xinvert) \
31 ((unsigned long)&(struct soc_mixer_control) \ 32 ((unsigned long)&(struct soc_mixer_control) \
32 {.reg = xreg, .shift = xshift, .rshift = xshift, .max = xmax, \ 33 {.reg = xreg, .rreg = xreg, .shift = shift_left, \
33 .platform_max = xmax, .invert = xinvert}) 34 .rshift = shift_right, .max = xmax, .platform_max = xmax, \
35 .invert = xinvert})
36#define SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) \
37 SOC_DOUBLE_VALUE(xreg, xshift, xshift, xmax, xinvert)
34#define SOC_SINGLE_VALUE_EXT(xreg, xmax, xinvert) \ 38#define SOC_SINGLE_VALUE_EXT(xreg, xmax, xinvert) \
35 ((unsigned long)&(struct soc_mixer_control) \ 39 ((unsigned long)&(struct soc_mixer_control) \
36 {.reg = xreg, .max = xmax, .platform_max = xmax, .invert = xinvert}) 40 {.reg = xreg, .max = xmax, .platform_max = xmax, .invert = xinvert})
41#define SOC_DOUBLE_R_VALUE(xlreg, xrreg, xshift, xmax, xinvert) \
42 ((unsigned long)&(struct soc_mixer_control) \
43 {.reg = xlreg, .rreg = xrreg, .shift = xshift, .rshift = xshift, \
44 .max = xmax, .platform_max = xmax, .invert = xinvert})
37#define SOC_SINGLE(xname, reg, shift, max, invert) \ 45#define SOC_SINGLE(xname, reg, shift, max, invert) \
38{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 46{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
39 .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\ 47 .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\
@@ -47,40 +55,36 @@
47 .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\ 55 .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\
48 .put = snd_soc_put_volsw, \ 56 .put = snd_soc_put_volsw, \
49 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) } 57 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
50#define SOC_DOUBLE(xname, xreg, shift_left, shift_right, xmax, xinvert) \ 58#define SOC_DOUBLE(xname, reg, shift_left, shift_right, max, invert) \
51{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ 59{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
52 .info = snd_soc_info_volsw, .get = snd_soc_get_volsw, \ 60 .info = snd_soc_info_volsw, .get = snd_soc_get_volsw, \
53 .put = snd_soc_put_volsw, \ 61 .put = snd_soc_put_volsw, \
54 .private_value = (unsigned long)&(struct soc_mixer_control) \ 62 .private_value = SOC_DOUBLE_VALUE(reg, shift_left, shift_right, \
55 {.reg = xreg, .shift = shift_left, .rshift = shift_right, \ 63 max, invert) }
56 .max = xmax, .platform_max = xmax, .invert = xinvert} }
57#define SOC_DOUBLE_R(xname, reg_left, reg_right, xshift, xmax, xinvert) \ 64#define SOC_DOUBLE_R(xname, reg_left, reg_right, xshift, xmax, xinvert) \
58{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ 65{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
59 .info = snd_soc_info_volsw_2r, \ 66 .info = snd_soc_info_volsw, \
60 .get = snd_soc_get_volsw_2r, .put = snd_soc_put_volsw_2r, \ 67 .get = snd_soc_get_volsw, .put = snd_soc_put_volsw, \
61 .private_value = (unsigned long)&(struct soc_mixer_control) \ 68 .private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, xshift, \
62 {.reg = reg_left, .rreg = reg_right, .shift = xshift, \ 69 xmax, xinvert) }
63 .max = xmax, .platform_max = xmax, .invert = xinvert} } 70#define SOC_DOUBLE_TLV(xname, reg, shift_left, shift_right, max, invert, tlv_array) \
64#define SOC_DOUBLE_TLV(xname, xreg, shift_left, shift_right, xmax, xinvert, tlv_array) \
65{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ 71{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
66 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ 72 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
67 SNDRV_CTL_ELEM_ACCESS_READWRITE,\ 73 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
68 .tlv.p = (tlv_array), \ 74 .tlv.p = (tlv_array), \
69 .info = snd_soc_info_volsw, .get = snd_soc_get_volsw, \ 75 .info = snd_soc_info_volsw, .get = snd_soc_get_volsw, \
70 .put = snd_soc_put_volsw, \ 76 .put = snd_soc_put_volsw, \
71 .private_value = (unsigned long)&(struct soc_mixer_control) \ 77 .private_value = SOC_DOUBLE_VALUE(reg, shift_left, shift_right, \
72 {.reg = xreg, .shift = shift_left, .rshift = shift_right,\ 78 max, invert) }
73 .max = xmax, .platform_max = xmax, .invert = xinvert} }
74#define SOC_DOUBLE_R_TLV(xname, reg_left, reg_right, xshift, xmax, xinvert, tlv_array) \ 79#define SOC_DOUBLE_R_TLV(xname, reg_left, reg_right, xshift, xmax, xinvert, tlv_array) \
75{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ 80{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
76 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ 81 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
77 SNDRV_CTL_ELEM_ACCESS_READWRITE,\ 82 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
78 .tlv.p = (tlv_array), \ 83 .tlv.p = (tlv_array), \
79 .info = snd_soc_info_volsw_2r, \ 84 .info = snd_soc_info_volsw, \
80 .get = snd_soc_get_volsw_2r, .put = snd_soc_put_volsw_2r, \ 85 .get = snd_soc_get_volsw, .put = snd_soc_put_volsw, \
81 .private_value = (unsigned long)&(struct soc_mixer_control) \ 86 .private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, xshift, \
82 {.reg = reg_left, .rreg = reg_right, .shift = xshift, \ 87 xmax, xinvert) }
83 .max = xmax, .platform_max = xmax, .invert = xinvert} }
84#define SOC_DOUBLE_S8_TLV(xname, xreg, xmin, xmax, tlv_array) \ 88#define SOC_DOUBLE_S8_TLV(xname, xreg, xmin, xmax, tlv_array) \
85{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ 89{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
86 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ 90 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
@@ -120,14 +124,13 @@
120 .info = snd_soc_info_volsw, \ 124 .info = snd_soc_info_volsw, \
121 .get = xhandler_get, .put = xhandler_put, \ 125 .get = xhandler_get, .put = xhandler_put, \
122 .private_value = SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) } 126 .private_value = SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) }
123#define SOC_DOUBLE_EXT(xname, xreg, shift_left, shift_right, xmax, xinvert,\ 127#define SOC_DOUBLE_EXT(xname, reg, shift_left, shift_right, max, invert,\
124 xhandler_get, xhandler_put) \ 128 xhandler_get, xhandler_put) \
125{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ 129{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
126 .info = snd_soc_info_volsw, \ 130 .info = snd_soc_info_volsw, \
127 .get = xhandler_get, .put = xhandler_put, \ 131 .get = xhandler_get, .put = xhandler_put, \
128 .private_value = (unsigned long)&(struct soc_mixer_control) \ 132 .private_value = \
129 {.reg = xreg, .shift = shift_left, .rshift = shift_right, \ 133 SOC_DOUBLE_VALUE(reg, shift_left, shift_right, max, invert) }
130 .max = xmax, .platform_max = xmax, .invert = xinvert} }
131#define SOC_SINGLE_EXT_TLV(xname, xreg, xshift, xmax, xinvert,\ 134#define SOC_SINGLE_EXT_TLV(xname, xreg, xshift, xmax, xinvert,\
132 xhandler_get, xhandler_put, tlv_array) \ 135 xhandler_get, xhandler_put, tlv_array) \
133{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 136{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
@@ -145,20 +148,18 @@
145 .tlv.p = (tlv_array), \ 148 .tlv.p = (tlv_array), \
146 .info = snd_soc_info_volsw, \ 149 .info = snd_soc_info_volsw, \
147 .get = xhandler_get, .put = xhandler_put, \ 150 .get = xhandler_get, .put = xhandler_put, \
148 .private_value = (unsigned long)&(struct soc_mixer_control) \ 151 .private_value = SOC_DOUBLE_VALUE(xreg, shift_left, shift_right, \
149 {.reg = xreg, .shift = shift_left, .rshift = shift_right, \ 152 xmax, xinvert) }
150 .max = xmax, .platform_max = xmax, .invert = xinvert} }
151#define SOC_DOUBLE_R_EXT_TLV(xname, reg_left, reg_right, xshift, xmax, xinvert,\ 153#define SOC_DOUBLE_R_EXT_TLV(xname, reg_left, reg_right, xshift, xmax, xinvert,\
152 xhandler_get, xhandler_put, tlv_array) \ 154 xhandler_get, xhandler_put, tlv_array) \
153{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ 155{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
154 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ 156 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
155 SNDRV_CTL_ELEM_ACCESS_READWRITE, \ 157 SNDRV_CTL_ELEM_ACCESS_READWRITE, \
156 .tlv.p = (tlv_array), \ 158 .tlv.p = (tlv_array), \
157 .info = snd_soc_info_volsw_2r, \ 159 .info = snd_soc_info_volsw, \
158 .get = xhandler_get, .put = xhandler_put, \ 160 .get = xhandler_get, .put = xhandler_put, \
159 .private_value = (unsigned long)&(struct soc_mixer_control) \ 161 .private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, xshift, \
160 {.reg = reg_left, .rreg = reg_right, .shift = xshift, \ 162 xmax, xinvert) }
161 .max = xmax, .platform_max = xmax, .invert = xinvert} }
162#define SOC_SINGLE_BOOL_EXT(xname, xdata, xhandler_get, xhandler_put) \ 163#define SOC_SINGLE_BOOL_EXT(xname, xdata, xhandler_get, xhandler_put) \
163{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 164{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
164 .info = snd_soc_info_bool_ext, \ 165 .info = snd_soc_info_bool_ext, \
@@ -260,6 +261,7 @@ extern struct snd_ac97_bus_ops soc_ac97_ops;
260enum snd_soc_control_type { 261enum snd_soc_control_type {
261 SND_SOC_I2C = 1, 262 SND_SOC_I2C = 1,
262 SND_SOC_SPI, 263 SND_SOC_SPI,
264 SND_SOC_REGMAP,
263}; 265};
264 266
265enum snd_soc_compress_type { 267enum snd_soc_compress_type {
@@ -274,7 +276,7 @@ enum snd_soc_pcm_subclass {
274}; 276};
275 277
276int snd_soc_codec_set_sysclk(struct snd_soc_codec *codec, int clk_id, 278int snd_soc_codec_set_sysclk(struct snd_soc_codec *codec, int clk_id,
277 unsigned int freq, int dir); 279 int source, unsigned int freq, int dir);
278int snd_soc_codec_set_pll(struct snd_soc_codec *codec, int pll_id, int source, 280int snd_soc_codec_set_pll(struct snd_soc_codec *codec, int pll_id, int source,
279 unsigned int freq_in, unsigned int freq_out); 281 unsigned int freq_in, unsigned int freq_out);
280 282
@@ -391,12 +393,8 @@ int snd_soc_get_volsw(struct snd_kcontrol *kcontrol,
391 struct snd_ctl_elem_value *ucontrol); 393 struct snd_ctl_elem_value *ucontrol);
392int snd_soc_put_volsw(struct snd_kcontrol *kcontrol, 394int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
393 struct snd_ctl_elem_value *ucontrol); 395 struct snd_ctl_elem_value *ucontrol);
394int snd_soc_info_volsw_2r(struct snd_kcontrol *kcontrol, 396#define snd_soc_get_volsw_2r snd_soc_get_volsw
395 struct snd_ctl_elem_info *uinfo); 397#define snd_soc_put_volsw_2r snd_soc_put_volsw
396int snd_soc_get_volsw_2r(struct snd_kcontrol *kcontrol,
397 struct snd_ctl_elem_value *ucontrol);
398int snd_soc_put_volsw_2r(struct snd_kcontrol *kcontrol,
399 struct snd_ctl_elem_value *ucontrol);
400int snd_soc_info_volsw_s8(struct snd_kcontrol *kcontrol, 398int snd_soc_info_volsw_s8(struct snd_kcontrol *kcontrol,
401 struct snd_ctl_elem_info *uinfo); 399 struct snd_ctl_elem_info *uinfo);
402int snd_soc_get_volsw_s8(struct snd_kcontrol *kcontrol, 400int snd_soc_get_volsw_s8(struct snd_kcontrol *kcontrol,
@@ -576,9 +574,11 @@ struct snd_soc_codec {
576 const void *reg_def_copy; 574 const void *reg_def_copy;
577 const struct snd_soc_cache_ops *cache_ops; 575 const struct snd_soc_cache_ops *cache_ops;
578 struct mutex cache_rw_mutex; 576 struct mutex cache_rw_mutex;
577 int val_bytes;
579 578
580 /* dapm */ 579 /* dapm */
581 struct snd_soc_dapm_context dapm; 580 struct snd_soc_dapm_context dapm;
581 unsigned int ignore_pmdown_time:1; /* pmdown_time is ignored at stop */
582 582
583#ifdef CONFIG_DEBUG_FS 583#ifdef CONFIG_DEBUG_FS
584 struct dentry *debugfs_codec_root; 584 struct dentry *debugfs_codec_root;
@@ -607,7 +607,7 @@ struct snd_soc_codec_driver {
607 607
608 /* codec wide operations */ 608 /* codec wide operations */
609 int (*set_sysclk)(struct snd_soc_codec *codec, 609 int (*set_sysclk)(struct snd_soc_codec *codec,
610 int clk_id, unsigned int freq, int dir); 610 int clk_id, int source, unsigned int freq, int dir);
611 int (*set_pll)(struct snd_soc_codec *codec, int pll_id, int source, 611 int (*set_pll)(struct snd_soc_codec *codec, int pll_id, int source,
612 unsigned int freq_in, unsigned int freq_out); 612 unsigned int freq_in, unsigned int freq_out);
613 613
@@ -619,7 +619,7 @@ struct snd_soc_codec_driver {
619 int (*volatile_register)(struct snd_soc_codec *, unsigned int); 619 int (*volatile_register)(struct snd_soc_codec *, unsigned int);
620 int (*readable_register)(struct snd_soc_codec *, unsigned int); 620 int (*readable_register)(struct snd_soc_codec *, unsigned int);
621 int (*writable_register)(struct snd_soc_codec *, unsigned int); 621 int (*writable_register)(struct snd_soc_codec *, unsigned int);
622 short reg_cache_size; 622 unsigned int reg_cache_size;
623 short reg_cache_step; 623 short reg_cache_step;
624 short reg_word_size; 624 short reg_word_size;
625 const void *reg_cache_default; 625 const void *reg_cache_default;
@@ -630,10 +630,14 @@ struct snd_soc_codec_driver {
630 /* codec bias level */ 630 /* codec bias level */
631 int (*set_bias_level)(struct snd_soc_codec *, 631 int (*set_bias_level)(struct snd_soc_codec *,
632 enum snd_soc_bias_level level); 632 enum snd_soc_bias_level level);
633 bool idle_bias_off;
633 634
634 void (*seq_notifier)(struct snd_soc_dapm_context *, 635 void (*seq_notifier)(struct snd_soc_dapm_context *,
635 enum snd_soc_dapm_type, int); 636 enum snd_soc_dapm_type, int);
636 637
638 /* codec stream completion event */
639 int (*stream_event)(struct snd_soc_dapm_context *dapm, int event);
640
637 /* probe ordering - for components with runtime dependencies */ 641 /* probe ordering - for components with runtime dependencies */
638 int probe_order; 642 int probe_order;
639 int remove_order; 643 int remove_order;
@@ -669,6 +673,9 @@ struct snd_soc_platform_driver {
669 /* platform stream ops */ 673 /* platform stream ops */
670 struct snd_pcm_ops *ops; 674 struct snd_pcm_ops *ops;
671 675
676 /* platform stream completion event */
677 int (*stream_event)(struct snd_soc_dapm_context *dapm, int event);
678
672 /* probe ordering - for components with runtime dependencies */ 679 /* probe ordering - for components with runtime dependencies */
673 int probe_order; 680 int probe_order;
674 int remove_order; 681 int remove_order;
@@ -703,6 +710,8 @@ struct snd_soc_dai_link {
703 const char *cpu_dai_name; 710 const char *cpu_dai_name;
704 const char *codec_dai_name; 711 const char *codec_dai_name;
705 712
713 unsigned int dai_fmt; /* format to set on init */
714
706 /* Keep DAI active over suspend */ 715 /* Keep DAI active over suspend */
707 unsigned int ignore_suspend:1; 716 unsigned int ignore_suspend:1;
708 717
@@ -815,9 +824,11 @@ struct snd_soc_card {
815 struct list_head widgets; 824 struct list_head widgets;
816 struct list_head paths; 825 struct list_head paths;
817 struct list_head dapm_list; 826 struct list_head dapm_list;
827 struct list_head dapm_dirty;
818 828
819 /* Generic DAPM context for the card */ 829 /* Generic DAPM context for the card */
820 struct snd_soc_dapm_context dapm; 830 struct snd_soc_dapm_context dapm;
831 struct snd_soc_dapm_stats dapm_stats;
821 832
822#ifdef CONFIG_DEBUG_FS 833#ifdef CONFIG_DEBUG_FS
823 struct dentry *debugfs_card_root; 834 struct dentry *debugfs_card_root;
@@ -840,8 +851,6 @@ struct snd_soc_pcm_runtime {
840 unsigned int complete:1; 851 unsigned int complete:1;
841 unsigned int dev_registered:1; 852 unsigned int dev_registered:1;
842 853
843 /* Symmetry data - only valid if symmetry is being enforced */
844 unsigned int rate;
845 long pmdown_time; 854 long pmdown_time;
846 855
847 /* runtime devices */ 856 /* runtime devices */
@@ -936,6 +945,18 @@ static inline void snd_soc_initialize_card_lists(struct snd_soc_card *card)
936 INIT_LIST_HEAD(&card->dapm_list); 945 INIT_LIST_HEAD(&card->dapm_list);
937} 946}
938 947
948static inline bool snd_soc_volsw_is_stereo(struct soc_mixer_control *mc)
949{
950 if (mc->reg == mc->rreg && mc->shift == mc->rshift)
951 return 0;
952 /*
953 * mc->reg == mc->rreg && mc->shift != mc->rshift, or
954 * mc->reg != mc->rreg means that the control is
955 * stereo (bits in one register or in two registers)
956 */
957 return 1;
958}
959
939int snd_soc_util_init(void); 960int snd_soc_util_init(void);
940void snd_soc_util_exit(void); 961void snd_soc_util_exit(void);
941 962
diff --git a/include/sound/tpa6130a2-plat.h b/include/sound/tpa6130a2-plat.h
index 89beccb57ed..4cc1093844c 100644
--- a/include/sound/tpa6130a2-plat.h
+++ b/include/sound/tpa6130a2-plat.h
@@ -23,13 +23,7 @@
23#ifndef TPA6130A2_PLAT_H 23#ifndef TPA6130A2_PLAT_H
24#define TPA6130A2_PLAT_H 24#define TPA6130A2_PLAT_H
25 25
26enum tpa_model {
27 TPA6130A2,
28 TPA6140A2,
29};
30
31struct tpa6130a2_platform_data { 26struct tpa6130a2_platform_data {
32 enum tpa_model id;
33 int power_gpio; 27 int power_gpio;
34}; 28};
35 29
diff --git a/include/sound/wm1250-ev1.h b/include/sound/wm1250-ev1.h
new file mode 100644
index 00000000000..7dff8283412
--- /dev/null
+++ b/include/sound/wm1250-ev1.h
@@ -0,0 +1,27 @@
1/*
2 * linux/sound/wm1250-ev1.h - Platform data for WM1250-EV1
3 *
4 * Copyright 2011 Wolfson Microelectronics. PLC.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef __LINUX_SND_WM1250_EV1_H
12#define __LINUX_SND_WM1250_EV1_H
13
14#define WM1250_EV1_NUM_GPIOS 5
15
16#define WM1250_EV1_GPIO_CLK_ENA 0
17#define WM1250_EV1_GPIO_CLK_SEL0 1
18#define WM1250_EV1_GPIO_CLK_SEL1 2
19#define WM1250_EV1_GPIO_OSR 3
20#define WM1250_EV1_GPIO_MASTER 4
21
22
23struct wm1250_ev1_pdata {
24 int gpios[WM1250_EV1_NUM_GPIOS];
25};
26
27#endif
diff --git a/include/sound/wm5100.h b/include/sound/wm5100.h
new file mode 100644
index 00000000000..617d0c4a159
--- /dev/null
+++ b/include/sound/wm5100.h
@@ -0,0 +1,59 @@
1/*
2 * linux/sound/wm5100.h -- Platform data for WM5100
3 *
4 * Copyright 2011 Wolfson Microelectronics. PLC.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef __LINUX_SND_WM5100_H
12#define __LINUX_SND_WM5100_H
13
14enum wm5100_in_mode {
15 WM5100_IN_SE = 0,
16 WM5100_IN_DIFF = 1,
17 WM5100_IN_DMIC = 2,
18};
19
20enum wm5100_dmic_sup {
21 WM5100_DMIC_SUP_MICVDD = 0,
22 WM5100_DMIC_SUP_MICBIAS1 = 1,
23 WM5100_DMIC_SUP_MICBIAS2 = 2,
24 WM5100_DMIC_SUP_MICBIAS3 = 3,
25};
26
27enum wm5100_micdet_bias {
28 WM5100_MICDET_MICBIAS1 = 0,
29 WM5100_MICDET_MICBIAS2 = 1,
30 WM5100_MICDET_MICBIAS3 = 2,
31};
32
33struct wm5100_jack_mode {
34 enum wm5100_micdet_bias bias;
35 int hp_pol;
36 int micd_src;
37};
38
39#define WM5100_GPIO_SET 0x10000
40
41struct wm5100_pdata {
42 int reset; /** GPIO controlling /RESET, if any */
43 int ldo_ena; /** GPIO controlling LODENA, if any */
44 int hp_pol; /** GPIO controlling headset polarity, if any */
45 int irq_flags;
46 int gpio_base;
47
48 struct wm5100_jack_mode jack_modes[2];
49
50 /* Input pin mode selection */
51 enum wm5100_in_mode in_mode[4];
52
53 /* DMIC supply selection */
54 enum wm5100_dmic_sup dmic_sup[4];
55
56 int gpio_defaults[6];
57};
58
59#endif
diff --git a/include/trace/events/asoc.h b/include/trace/events/asoc.h
index 603f5a0f036..ab26f8aa3c7 100644
--- a/include/trace/events/asoc.h
+++ b/include/trace/events/asoc.h
@@ -216,6 +216,31 @@ DEFINE_EVENT(snd_soc_dapm_widget, snd_soc_dapm_widget_event_done,
216 216
217); 217);
218 218
219TRACE_EVENT(snd_soc_dapm_walk_done,
220
221 TP_PROTO(struct snd_soc_card *card),
222
223 TP_ARGS(card),
224
225 TP_STRUCT__entry(
226 __string( name, card->name )
227 __field( int, power_checks )
228 __field( int, path_checks )
229 __field( int, neighbour_checks )
230 ),
231
232 TP_fast_assign(
233 __assign_str(name, card->name);
234 __entry->power_checks = card->dapm_stats.power_checks;
235 __entry->path_checks = card->dapm_stats.path_checks;
236 __entry->neighbour_checks = card->dapm_stats.neighbour_checks;
237 ),
238
239 TP_printk("%s: checks %d power, %d path, %d neighbour",
240 __get_str(name), (int)__entry->power_checks,
241 (int)__entry->path_checks, (int)__entry->neighbour_checks)
242);
243
219TRACE_EVENT(snd_soc_jack_irq, 244TRACE_EVENT(snd_soc_jack_irq,
220 245
221 TP_PROTO(const char *name), 246 TP_PROTO(const char *name),
diff --git a/sound/aoa/codecs/onyx.c b/sound/aoa/codecs/onyx.c
index 3687a6cc988..762af68c899 100644
--- a/sound/aoa/codecs/onyx.c
+++ b/sound/aoa/codecs/onyx.c
@@ -1067,7 +1067,6 @@ static int onyx_i2c_probe(struct i2c_client *client,
1067 printk(KERN_DEBUG PFX "created and attached onyx instance\n"); 1067 printk(KERN_DEBUG PFX "created and attached onyx instance\n");
1068 return 0; 1068 return 0;
1069 fail: 1069 fail:
1070 i2c_set_clientdata(client, NULL);
1071 kfree(onyx); 1070 kfree(onyx);
1072 return -ENODEV; 1071 return -ENODEV;
1073} 1072}
@@ -1112,8 +1111,7 @@ static int onyx_i2c_remove(struct i2c_client *client)
1112 1111
1113 aoa_codec_unregister(&onyx->codec); 1112 aoa_codec_unregister(&onyx->codec);
1114 of_node_put(onyx->codec.node); 1113 of_node_put(onyx->codec.node);
1115 if (onyx->codec_info) 1114 kfree(onyx->codec_info);
1116 kfree(onyx->codec_info);
1117 kfree(onyx); 1115 kfree(onyx);
1118 return 0; 1116 return 0;
1119} 1117}
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c
index d0cead38d5f..e518d38b1c7 100644
--- a/sound/arm/aaci.c
+++ b/sound/arm/aaci.c
@@ -443,7 +443,7 @@ static int aaci_pcm_open(struct snd_pcm_substream *substream)
443 mutex_lock(&aaci->irq_lock); 443 mutex_lock(&aaci->irq_lock);
444 if (!aaci->users++) { 444 if (!aaci->users++) {
445 ret = request_irq(aaci->dev->irq[0], aaci_irq, 445 ret = request_irq(aaci->dev->irq[0], aaci_irq,
446 IRQF_SHARED | IRQF_DISABLED, DRIVER_NAME, aaci); 446 IRQF_SHARED, DRIVER_NAME, aaci);
447 if (ret != 0) 447 if (ret != 0)
448 aaci->users--; 448 aaci->users--;
449 } 449 }
diff --git a/sound/arm/pxa2xx-ac97-lib.c b/sound/arm/pxa2xx-ac97-lib.c
index 88eec3847df..8ad65352bf9 100644
--- a/sound/arm/pxa2xx-ac97-lib.c
+++ b/sound/arm/pxa2xx-ac97-lib.c
@@ -359,7 +359,7 @@ int __devinit pxa2xx_ac97_hw_probe(struct platform_device *dev)
359 if (ret) 359 if (ret)
360 goto err_clk2; 360 goto err_clk2;
361 361
362 ret = request_irq(IRQ_AC97, pxa2xx_ac97_irq, IRQF_DISABLED, "AC97", NULL); 362 ret = request_irq(IRQ_AC97, pxa2xx_ac97_irq, 0, "AC97", NULL);
363 if (ret < 0) 363 if (ret < 0)
364 goto err_irq; 364 goto err_irq;
365 365
diff --git a/sound/core/control.c b/sound/core/control.c
index f8c5be46451..978fe1a8e9f 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -989,7 +989,6 @@ struct user_element {
989 void *tlv_data; /* TLV data */ 989 void *tlv_data; /* TLV data */
990 unsigned long tlv_data_size; /* TLV data size */ 990 unsigned long tlv_data_size; /* TLV data size */
991 void *priv_data; /* private data (like strings for enumerated type) */ 991 void *priv_data; /* private data (like strings for enumerated type) */
992 unsigned long priv_data_size; /* size of private data in bytes */
993}; 992};
994 993
995static int snd_ctl_elem_user_info(struct snd_kcontrol *kcontrol, 994static int snd_ctl_elem_user_info(struct snd_kcontrol *kcontrol,
@@ -1001,6 +1000,28 @@ static int snd_ctl_elem_user_info(struct snd_kcontrol *kcontrol,
1001 return 0; 1000 return 0;
1002} 1001}
1003 1002
1003static int snd_ctl_elem_user_enum_info(struct snd_kcontrol *kcontrol,
1004 struct snd_ctl_elem_info *uinfo)
1005{
1006 struct user_element *ue = kcontrol->private_data;
1007 const char *names;
1008 unsigned int item;
1009
1010 item = uinfo->value.enumerated.item;
1011
1012 *uinfo = ue->info;
1013
1014 item = min(item, uinfo->value.enumerated.items - 1);
1015 uinfo->value.enumerated.item = item;
1016
1017 names = ue->priv_data;
1018 for (; item > 0; --item)
1019 names += strlen(names) + 1;
1020 strcpy(uinfo->value.enumerated.name, names);
1021
1022 return 0;
1023}
1024
1004static int snd_ctl_elem_user_get(struct snd_kcontrol *kcontrol, 1025static int snd_ctl_elem_user_get(struct snd_kcontrol *kcontrol,
1005 struct snd_ctl_elem_value *ucontrol) 1026 struct snd_ctl_elem_value *ucontrol)
1006{ 1027{
@@ -1055,11 +1076,46 @@ static int snd_ctl_elem_user_tlv(struct snd_kcontrol *kcontrol,
1055 return change; 1076 return change;
1056} 1077}
1057 1078
1079static int snd_ctl_elem_init_enum_names(struct user_element *ue)
1080{
1081 char *names, *p;
1082 size_t buf_len, name_len;
1083 unsigned int i;
1084
1085 if (ue->info.value.enumerated.names_length > 64 * 1024)
1086 return -EINVAL;
1087
1088 names = memdup_user(
1089 (const void __user *)ue->info.value.enumerated.names_ptr,
1090 ue->info.value.enumerated.names_length);
1091 if (IS_ERR(names))
1092 return PTR_ERR(names);
1093
1094 /* check that there are enough valid names */
1095 buf_len = ue->info.value.enumerated.names_length;
1096 p = names;
1097 for (i = 0; i < ue->info.value.enumerated.items; ++i) {
1098 name_len = strnlen(p, buf_len);
1099 if (name_len == 0 || name_len >= 64 || name_len == buf_len) {
1100 kfree(names);
1101 return -EINVAL;
1102 }
1103 p += name_len + 1;
1104 buf_len -= name_len + 1;
1105 }
1106
1107 ue->priv_data = names;
1108 ue->info.value.enumerated.names_ptr = 0;
1109
1110 return 0;
1111}
1112
1058static void snd_ctl_elem_user_free(struct snd_kcontrol *kcontrol) 1113static void snd_ctl_elem_user_free(struct snd_kcontrol *kcontrol)
1059{ 1114{
1060 struct user_element *ue = kcontrol->private_data; 1115 struct user_element *ue = kcontrol->private_data;
1061 if (ue->tlv_data) 1116
1062 kfree(ue->tlv_data); 1117 kfree(ue->tlv_data);
1118 kfree(ue->priv_data);
1063 kfree(ue); 1119 kfree(ue);
1064} 1120}
1065 1121
@@ -1072,8 +1128,8 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
1072 long private_size; 1128 long private_size;
1073 struct user_element *ue; 1129 struct user_element *ue;
1074 int idx, err; 1130 int idx, err;
1075 1131
1076 if (card->user_ctl_count >= MAX_USER_CONTROLS) 1132 if (!replace && card->user_ctl_count >= MAX_USER_CONTROLS)
1077 return -ENOMEM; 1133 return -ENOMEM;
1078 if (info->count < 1) 1134 if (info->count < 1)
1079 return -EINVAL; 1135 return -EINVAL;
@@ -1101,7 +1157,10 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
1101 memcpy(&kctl.id, &info->id, sizeof(info->id)); 1157 memcpy(&kctl.id, &info->id, sizeof(info->id));
1102 kctl.count = info->owner ? info->owner : 1; 1158 kctl.count = info->owner ? info->owner : 1;
1103 access |= SNDRV_CTL_ELEM_ACCESS_USER; 1159 access |= SNDRV_CTL_ELEM_ACCESS_USER;
1104 kctl.info = snd_ctl_elem_user_info; 1160 if (info->type == SNDRV_CTL_ELEM_TYPE_ENUMERATED)
1161 kctl.info = snd_ctl_elem_user_enum_info;
1162 else
1163 kctl.info = snd_ctl_elem_user_info;
1105 if (access & SNDRV_CTL_ELEM_ACCESS_READ) 1164 if (access & SNDRV_CTL_ELEM_ACCESS_READ)
1106 kctl.get = snd_ctl_elem_user_get; 1165 kctl.get = snd_ctl_elem_user_get;
1107 if (access & SNDRV_CTL_ELEM_ACCESS_WRITE) 1166 if (access & SNDRV_CTL_ELEM_ACCESS_WRITE)
@@ -1122,6 +1181,11 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
1122 if (info->count > 64) 1181 if (info->count > 64)
1123 return -EINVAL; 1182 return -EINVAL;
1124 break; 1183 break;
1184 case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
1185 private_size = sizeof(unsigned int);
1186 if (info->count > 128 || info->value.enumerated.items == 0)
1187 return -EINVAL;
1188 break;
1125 case SNDRV_CTL_ELEM_TYPE_BYTES: 1189 case SNDRV_CTL_ELEM_TYPE_BYTES:
1126 private_size = sizeof(unsigned char); 1190 private_size = sizeof(unsigned char);
1127 if (info->count > 512) 1191 if (info->count > 512)
@@ -1143,9 +1207,17 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
1143 ue->info.access = 0; 1207 ue->info.access = 0;
1144 ue->elem_data = (char *)ue + sizeof(*ue); 1208 ue->elem_data = (char *)ue + sizeof(*ue);
1145 ue->elem_data_size = private_size; 1209 ue->elem_data_size = private_size;
1210 if (ue->info.type == SNDRV_CTL_ELEM_TYPE_ENUMERATED) {
1211 err = snd_ctl_elem_init_enum_names(ue);
1212 if (err < 0) {
1213 kfree(ue);
1214 return err;
1215 }
1216 }
1146 kctl.private_free = snd_ctl_elem_user_free; 1217 kctl.private_free = snd_ctl_elem_user_free;
1147 _kctl = snd_ctl_new(&kctl, access); 1218 _kctl = snd_ctl_new(&kctl, access);
1148 if (_kctl == NULL) { 1219 if (_kctl == NULL) {
1220 kfree(ue->priv_data);
1149 kfree(ue); 1221 kfree(ue);
1150 return -ENOMEM; 1222 return -ENOMEM;
1151 } 1223 }
diff --git a/sound/core/control_compat.c b/sound/core/control_compat.c
index 426874429a5..2bb95a7a880 100644
--- a/sound/core/control_compat.c
+++ b/sound/core/control_compat.c
@@ -83,6 +83,8 @@ struct snd_ctl_elem_info32 {
83 u32 items; 83 u32 items;
84 u32 item; 84 u32 item;
85 char name[64]; 85 char name[64];
86 u64 names_ptr;
87 u32 names_length;
86 } enumerated; 88 } enumerated;
87 unsigned char reserved[128]; 89 unsigned char reserved[128];
88 } value; 90 } value;
@@ -372,6 +374,8 @@ static int snd_ctl_elem_add_compat(struct snd_ctl_file *file,
372 &data32->value.enumerated, 374 &data32->value.enumerated,
373 sizeof(data->value.enumerated))) 375 sizeof(data->value.enumerated)))
374 goto error; 376 goto error;
377 data->value.enumerated.names_ptr =
378 (uintptr_t)compat_ptr(data->value.enumerated.names_ptr);
375 break; 379 break;
376 default: 380 default:
377 break; 381 break;
diff --git a/sound/core/jack.c b/sound/core/jack.c
index 53b53e97c89..240a3e13470 100644
--- a/sound/core/jack.c
+++ b/sound/core/jack.c
@@ -30,6 +30,7 @@ static int jack_switch_types[] = {
30 SW_LINEOUT_INSERT, 30 SW_LINEOUT_INSERT,
31 SW_JACK_PHYSICAL_INSERT, 31 SW_JACK_PHYSICAL_INSERT,
32 SW_VIDEOOUT_INSERT, 32 SW_VIDEOOUT_INSERT,
33 SW_LINEIN_INSERT,
33}; 34};
34 35
35static int snd_jack_dev_free(struct snd_device *device) 36static int snd_jack_dev_free(struct snd_device *device)
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
index d8359cfeca1..1b5e0c49a0a 100644
--- a/sound/core/oss/mixer_oss.c
+++ b/sound/core/oss/mixer_oss.c
@@ -499,7 +499,7 @@ static struct snd_kcontrol *snd_mixer_oss_test_id(struct snd_mixer_oss *mixer, c
499 499
500 memset(&id, 0, sizeof(id)); 500 memset(&id, 0, sizeof(id));
501 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; 501 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
502 strcpy(id.name, name); 502 strlcpy(id.name, name, sizeof(id.name));
503 id.index = index; 503 id.index = index;
504 return snd_ctl_find_id(card, &id); 504 return snd_ctl_find_id(card, &id);
505} 505}
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 62e90b862a0..95d1e789715 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -1399,6 +1399,32 @@ int snd_pcm_hw_constraint_pow2(struct snd_pcm_runtime *runtime,
1399 1399
1400EXPORT_SYMBOL(snd_pcm_hw_constraint_pow2); 1400EXPORT_SYMBOL(snd_pcm_hw_constraint_pow2);
1401 1401
1402static int snd_pcm_hw_rule_noresample_func(struct snd_pcm_hw_params *params,
1403 struct snd_pcm_hw_rule *rule)
1404{
1405 unsigned int base_rate = (unsigned int)(uintptr_t)rule->private;
1406 struct snd_interval *rate;
1407
1408 rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
1409 return snd_interval_list(rate, 1, &base_rate, 0);
1410}
1411
1412/**
1413 * snd_pcm_hw_rule_noresample - add a rule to allow disabling hw resampling
1414 * @runtime: PCM runtime instance
1415 * @base_rate: the rate at which the hardware does not resample
1416 */
1417int snd_pcm_hw_rule_noresample(struct snd_pcm_runtime *runtime,
1418 unsigned int base_rate)
1419{
1420 return snd_pcm_hw_rule_add(runtime, SNDRV_PCM_HW_PARAMS_NORESAMPLE,
1421 SNDRV_PCM_HW_PARAM_RATE,
1422 snd_pcm_hw_rule_noresample_func,
1423 (void *)(uintptr_t)base_rate,
1424 SNDRV_PCM_HW_PARAM_RATE, -1);
1425}
1426EXPORT_SYMBOL(snd_pcm_hw_rule_noresample);
1427
1402static void _snd_pcm_hw_param_any(struct snd_pcm_hw_params *params, 1428static void _snd_pcm_hw_param_any(struct snd_pcm_hw_params *params,
1403 snd_pcm_hw_param_t var) 1429 snd_pcm_hw_param_t var)
1404{ 1430{
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index c74e228731e..d7d2179c036 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -2058,16 +2058,12 @@ EXPORT_SYMBOL(snd_pcm_open_substream);
2058 2058
2059static int snd_pcm_open_file(struct file *file, 2059static int snd_pcm_open_file(struct file *file,
2060 struct snd_pcm *pcm, 2060 struct snd_pcm *pcm,
2061 int stream, 2061 int stream)
2062 struct snd_pcm_file **rpcm_file)
2063{ 2062{
2064 struct snd_pcm_file *pcm_file; 2063 struct snd_pcm_file *pcm_file;
2065 struct snd_pcm_substream *substream; 2064 struct snd_pcm_substream *substream;
2066 int err; 2065 int err;
2067 2066
2068 if (rpcm_file)
2069 *rpcm_file = NULL;
2070
2071 err = snd_pcm_open_substream(pcm, stream, file, &substream); 2067 err = snd_pcm_open_substream(pcm, stream, file, &substream);
2072 if (err < 0) 2068 if (err < 0)
2073 return err; 2069 return err;
@@ -2083,8 +2079,7 @@ static int snd_pcm_open_file(struct file *file,
2083 substream->pcm_release = pcm_release_private; 2079 substream->pcm_release = pcm_release_private;
2084 } 2080 }
2085 file->private_data = pcm_file; 2081 file->private_data = pcm_file;
2086 if (rpcm_file) 2082
2087 *rpcm_file = pcm_file;
2088 return 0; 2083 return 0;
2089} 2084}
2090 2085
@@ -2113,7 +2108,6 @@ static int snd_pcm_capture_open(struct inode *inode, struct file *file)
2113static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream) 2108static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream)
2114{ 2109{
2115 int err; 2110 int err;
2116 struct snd_pcm_file *pcm_file;
2117 wait_queue_t wait; 2111 wait_queue_t wait;
2118 2112
2119 if (pcm == NULL) { 2113 if (pcm == NULL) {
@@ -2131,7 +2125,7 @@ static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream)
2131 add_wait_queue(&pcm->open_wait, &wait); 2125 add_wait_queue(&pcm->open_wait, &wait);
2132 mutex_lock(&pcm->open_mutex); 2126 mutex_lock(&pcm->open_mutex);
2133 while (1) { 2127 while (1) {
2134 err = snd_pcm_open_file(file, pcm, stream, &pcm_file); 2128 err = snd_pcm_open_file(file, pcm, stream);
2135 if (err >= 0) 2129 if (err >= 0)
2136 break; 2130 break;
2137 if (err == -EAGAIN) { 2131 if (err == -EAGAIN) {
@@ -3156,8 +3150,8 @@ static const struct vm_operations_struct snd_pcm_vm_ops_data_fault = {
3156/* 3150/*
3157 * mmap the DMA buffer on RAM 3151 * mmap the DMA buffer on RAM
3158 */ 3152 */
3159static int snd_pcm_default_mmap(struct snd_pcm_substream *substream, 3153int snd_pcm_lib_default_mmap(struct snd_pcm_substream *substream,
3160 struct vm_area_struct *area) 3154 struct vm_area_struct *area)
3161{ 3155{
3162 area->vm_flags |= VM_RESERVED; 3156 area->vm_flags |= VM_RESERVED;
3163#ifdef ARCH_HAS_DMA_MMAP_COHERENT 3157#ifdef ARCH_HAS_DMA_MMAP_COHERENT
@@ -3177,6 +3171,7 @@ static int snd_pcm_default_mmap(struct snd_pcm_substream *substream,
3177 area->vm_ops = &snd_pcm_vm_ops_data_fault; 3171 area->vm_ops = &snd_pcm_vm_ops_data_fault;
3178 return 0; 3172 return 0;
3179} 3173}
3174EXPORT_SYMBOL_GPL(snd_pcm_lib_default_mmap);
3180 3175
3181/* 3176/*
3182 * mmap the DMA buffer on I/O memory area 3177 * mmap the DMA buffer on I/O memory area
@@ -3242,7 +3237,7 @@ int snd_pcm_mmap_data(struct snd_pcm_substream *substream, struct file *file,
3242 if (substream->ops->mmap) 3237 if (substream->ops->mmap)
3243 err = substream->ops->mmap(substream, area); 3238 err = substream->ops->mmap(substream, area);
3244 else 3239 else
3245 err = snd_pcm_default_mmap(substream, area); 3240 err = snd_pcm_lib_default_mmap(substream, area);
3246 if (!err) 3241 if (!err)
3247 atomic_inc(&substream->mmap_count); 3242 atomic_inc(&substream->mmap_count);
3248 return err; 3243 return err;
diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c
index a0da7755fce..4067f154894 100644
--- a/sound/drivers/aloop.c
+++ b/sound/drivers/aloop.c
@@ -575,7 +575,8 @@ static void loopback_runtime_free(struct snd_pcm_runtime *runtime)
575static int loopback_hw_params(struct snd_pcm_substream *substream, 575static int loopback_hw_params(struct snd_pcm_substream *substream,
576 struct snd_pcm_hw_params *params) 576 struct snd_pcm_hw_params *params)
577{ 577{
578 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); 578 return snd_pcm_lib_alloc_vmalloc_buffer(substream,
579 params_buffer_bytes(params));
579} 580}
580 581
581static int loopback_hw_free(struct snd_pcm_substream *substream) 582static int loopback_hw_free(struct snd_pcm_substream *substream)
@@ -587,7 +588,7 @@ static int loopback_hw_free(struct snd_pcm_substream *substream)
587 mutex_lock(&dpcm->loopback->cable_lock); 588 mutex_lock(&dpcm->loopback->cable_lock);
588 cable->valid &= ~(1 << substream->stream); 589 cable->valid &= ~(1 << substream->stream);
589 mutex_unlock(&dpcm->loopback->cable_lock); 590 mutex_unlock(&dpcm->loopback->cable_lock);
590 return snd_pcm_lib_free_pages(substream); 591 return snd_pcm_lib_free_vmalloc_buffer(substream);
591} 592}
592 593
593static unsigned int get_cable_index(struct snd_pcm_substream *substream) 594static unsigned int get_cable_index(struct snd_pcm_substream *substream)
@@ -740,6 +741,8 @@ static struct snd_pcm_ops loopback_playback_ops = {
740 .prepare = loopback_prepare, 741 .prepare = loopback_prepare,
741 .trigger = loopback_trigger, 742 .trigger = loopback_trigger,
742 .pointer = loopback_pointer, 743 .pointer = loopback_pointer,
744 .page = snd_pcm_lib_get_vmalloc_page,
745 .mmap = snd_pcm_lib_mmap_vmalloc,
743}; 746};
744 747
745static struct snd_pcm_ops loopback_capture_ops = { 748static struct snd_pcm_ops loopback_capture_ops = {
@@ -751,6 +754,8 @@ static struct snd_pcm_ops loopback_capture_ops = {
751 .prepare = loopback_prepare, 754 .prepare = loopback_prepare,
752 .trigger = loopback_trigger, 755 .trigger = loopback_trigger,
753 .pointer = loopback_pointer, 756 .pointer = loopback_pointer,
757 .page = snd_pcm_lib_get_vmalloc_page,
758 .mmap = snd_pcm_lib_mmap_vmalloc,
754}; 759};
755 760
756static int __devinit loopback_pcm_new(struct loopback *loopback, 761static int __devinit loopback_pcm_new(struct loopback *loopback,
@@ -771,10 +776,6 @@ static int __devinit loopback_pcm_new(struct loopback *loopback,
771 strcpy(pcm->name, "Loopback PCM"); 776 strcpy(pcm->name, "Loopback PCM");
772 777
773 loopback->pcm[device] = pcm; 778 loopback->pcm[device] = pcm;
774
775 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
776 snd_dma_continuous_data(GFP_KERNEL),
777 0, 2 * 1024 * 1024);
778 return 0; 779 return 0;
779} 780}
780 781
diff --git a/sound/drivers/ml403-ac97cr.c b/sound/drivers/ml403-ac97cr.c
index 5cfcb908c43..2c7a7636f47 100644
--- a/sound/drivers/ml403-ac97cr.c
+++ b/sound/drivers/ml403-ac97cr.c
@@ -1153,7 +1153,7 @@ snd_ml403_ac97cr_create(struct snd_card *card, struct platform_device *pfdev,
1153 "0x%x done\n", (unsigned int)ml403_ac97cr->port); 1153 "0x%x done\n", (unsigned int)ml403_ac97cr->port);
1154 /* get irq */ 1154 /* get irq */
1155 irq = platform_get_irq(pfdev, 0); 1155 irq = platform_get_irq(pfdev, 0);
1156 if (request_irq(irq, snd_ml403_ac97cr_irq, IRQF_DISABLED, 1156 if (request_irq(irq, snd_ml403_ac97cr_irq, 0,
1157 dev_name(&pfdev->dev), (void *)ml403_ac97cr)) { 1157 dev_name(&pfdev->dev), (void *)ml403_ac97cr)) {
1158 snd_printk(KERN_ERR SND_ML403_AC97CR_DRIVER ": " 1158 snd_printk(KERN_ERR SND_ML403_AC97CR_DRIVER ": "
1159 "unable to grab IRQ %d\n", 1159 "unable to grab IRQ %d\n",
@@ -1166,7 +1166,7 @@ snd_ml403_ac97cr_create(struct snd_card *card, struct platform_device *pfdev,
1166 "request (playback) irq %d done\n", 1166 "request (playback) irq %d done\n",
1167 ml403_ac97cr->irq); 1167 ml403_ac97cr->irq);
1168 irq = platform_get_irq(pfdev, 1); 1168 irq = platform_get_irq(pfdev, 1);
1169 if (request_irq(irq, snd_ml403_ac97cr_irq, IRQF_DISABLED, 1169 if (request_irq(irq, snd_ml403_ac97cr_irq, 0,
1170 dev_name(&pfdev->dev), (void *)ml403_ac97cr)) { 1170 dev_name(&pfdev->dev), (void *)ml403_ac97cr)) {
1171 snd_printk(KERN_ERR SND_ML403_AC97CR_DRIVER ": " 1171 snd_printk(KERN_ERR SND_ML403_AC97CR_DRIVER ": "
1172 "unable to grab IRQ %d\n", 1172 "unable to grab IRQ %d\n",
diff --git a/sound/drivers/mpu401/mpu401.c b/sound/drivers/mpu401/mpu401.c
index 149d05a8202..1c02852acee 100644
--- a/sound/drivers/mpu401/mpu401.c
+++ b/sound/drivers/mpu401/mpu401.c
@@ -86,8 +86,7 @@ static int snd_mpu401_create(int dev, struct snd_card **rcard)
86 } 86 }
87 87
88 err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, port[dev], 0, 88 err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, port[dev], 0,
89 irq[dev], irq[dev] >= 0 ? IRQF_DISABLED : 0, 89 irq[dev], NULL);
90 NULL);
91 if (err < 0) { 90 if (err < 0) {
92 printk(KERN_ERR "MPU401 not detected at 0x%lx\n", port[dev]); 91 printk(KERN_ERR "MPU401 not detected at 0x%lx\n", port[dev]);
93 goto _err; 92 goto _err;
diff --git a/sound/drivers/mpu401/mpu401_uart.c b/sound/drivers/mpu401/mpu401_uart.c
index 2af09996a3d..e91698a634b 100644
--- a/sound/drivers/mpu401/mpu401_uart.c
+++ b/sound/drivers/mpu401/mpu401_uart.c
@@ -3,7 +3,7 @@
3 * Routines for control of MPU-401 in UART mode 3 * Routines for control of MPU-401 in UART mode
4 * 4 *
5 * MPU-401 supports UART mode which is not capable generate transmit 5 * MPU-401 supports UART mode which is not capable generate transmit
6 * interrupts thus output is done via polling. Also, if irq < 0, then 6 * interrupts thus output is done via polling. Without interrupt,
7 * input is done also via polling. Do not expect good performance. 7 * input is done also via polling. Do not expect good performance.
8 * 8 *
9 * 9 *
@@ -374,7 +374,7 @@ snd_mpu401_uart_input_trigger(struct snd_rawmidi_substream *substream, int up)
374 /* first time - flush FIFO */ 374 /* first time - flush FIFO */
375 while (max-- > 0) 375 while (max-- > 0)
376 mpu->read(mpu, MPU401D(mpu)); 376 mpu->read(mpu, MPU401D(mpu));
377 if (mpu->irq < 0) 377 if (mpu->info_flags & MPU401_INFO_USE_TIMER)
378 snd_mpu401_uart_add_timer(mpu, 1); 378 snd_mpu401_uart_add_timer(mpu, 1);
379 } 379 }
380 380
@@ -383,7 +383,7 @@ snd_mpu401_uart_input_trigger(struct snd_rawmidi_substream *substream, int up)
383 snd_mpu401_uart_input_read(mpu); 383 snd_mpu401_uart_input_read(mpu);
384 spin_unlock_irqrestore(&mpu->input_lock, flags); 384 spin_unlock_irqrestore(&mpu->input_lock, flags);
385 } else { 385 } else {
386 if (mpu->irq < 0) 386 if (mpu->info_flags & MPU401_INFO_USE_TIMER)
387 snd_mpu401_uart_remove_timer(mpu, 1); 387 snd_mpu401_uart_remove_timer(mpu, 1);
388 clear_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode); 388 clear_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode);
389 } 389 }
@@ -496,7 +496,7 @@ static struct snd_rawmidi_ops snd_mpu401_uart_input =
496static void snd_mpu401_uart_free(struct snd_rawmidi *rmidi) 496static void snd_mpu401_uart_free(struct snd_rawmidi *rmidi)
497{ 497{
498 struct snd_mpu401 *mpu = rmidi->private_data; 498 struct snd_mpu401 *mpu = rmidi->private_data;
499 if (mpu->irq_flags && mpu->irq >= 0) 499 if (mpu->irq >= 0)
500 free_irq(mpu->irq, (void *) mpu); 500 free_irq(mpu->irq, (void *) mpu);
501 release_and_free_resource(mpu->res); 501 release_and_free_resource(mpu->res);
502 kfree(mpu); 502 kfree(mpu);
@@ -509,8 +509,7 @@ static void snd_mpu401_uart_free(struct snd_rawmidi *rmidi)
509 * @hardware: the hardware type, MPU401_HW_XXXX 509 * @hardware: the hardware type, MPU401_HW_XXXX
510 * @port: the base address of MPU401 port 510 * @port: the base address of MPU401 port
511 * @info_flags: bitflags MPU401_INFO_XXX 511 * @info_flags: bitflags MPU401_INFO_XXX
512 * @irq: the irq number, -1 if no interrupt for mpu 512 * @irq: the ISA irq number, -1 if not to be allocated
513 * @irq_flags: the irq request flags (SA_XXX), 0 if irq was already reserved.
514 * @rrawmidi: the pointer to store the new rawmidi instance 513 * @rrawmidi: the pointer to store the new rawmidi instance
515 * 514 *
516 * Creates a new MPU-401 instance. 515 * Creates a new MPU-401 instance.
@@ -525,7 +524,7 @@ int snd_mpu401_uart_new(struct snd_card *card, int device,
525 unsigned short hardware, 524 unsigned short hardware,
526 unsigned long port, 525 unsigned long port,
527 unsigned int info_flags, 526 unsigned int info_flags,
528 int irq, int irq_flags, 527 int irq,
529 struct snd_rawmidi ** rrawmidi) 528 struct snd_rawmidi ** rrawmidi)
530{ 529{
531 struct snd_mpu401 *mpu; 530 struct snd_mpu401 *mpu;
@@ -577,8 +576,8 @@ int snd_mpu401_uart_new(struct snd_card *card, int device,
577 mpu->cport = port + 2; 576 mpu->cport = port + 2;
578 else 577 else
579 mpu->cport = port + 1; 578 mpu->cport = port + 1;
580 if (irq >= 0 && irq_flags) { 579 if (irq >= 0) {
581 if (request_irq(irq, snd_mpu401_uart_interrupt, irq_flags, 580 if (request_irq(irq, snd_mpu401_uart_interrupt, 0,
582 "MPU401 UART", (void *) mpu)) { 581 "MPU401 UART", (void *) mpu)) {
583 snd_printk(KERN_ERR "mpu401_uart: " 582 snd_printk(KERN_ERR "mpu401_uart: "
584 "unable to grab IRQ %d\n", irq); 583 "unable to grab IRQ %d\n", irq);
@@ -586,9 +585,10 @@ int snd_mpu401_uart_new(struct snd_card *card, int device,
586 return -EBUSY; 585 return -EBUSY;
587 } 586 }
588 } 587 }
588 if (irq < 0 && !(info_flags & MPU401_INFO_IRQ_HOOK))
589 info_flags |= MPU401_INFO_USE_TIMER;
589 mpu->info_flags = info_flags; 590 mpu->info_flags = info_flags;
590 mpu->irq = irq; 591 mpu->irq = irq;
591 mpu->irq_flags = irq_flags;
592 if (card->shortname[0]) 592 if (card->shortname[0])
593 snprintf(rmidi->name, sizeof(rmidi->name), "%s MIDI", 593 snprintf(rmidi->name, sizeof(rmidi->name), "%s MIDI",
594 card->shortname); 594 card->shortname);
diff --git a/sound/drivers/mtpav.c b/sound/drivers/mtpav.c
index 5c426df8767..1eef4ccebe4 100644
--- a/sound/drivers/mtpav.c
+++ b/sound/drivers/mtpav.c
@@ -589,7 +589,7 @@ static int __devinit snd_mtpav_get_ISA(struct mtpav * mcard)
589 return -EBUSY; 589 return -EBUSY;
590 } 590 }
591 mcard->port = port; 591 mcard->port = port;
592 if (request_irq(irq, snd_mtpav_irqh, IRQF_DISABLED, "MOTU MTPAV", mcard)) { 592 if (request_irq(irq, snd_mtpav_irqh, 0, "MOTU MTPAV", mcard)) {
593 snd_printk(KERN_ERR "MTVAP IRQ %d busy\n", irq); 593 snd_printk(KERN_ERR "MTVAP IRQ %d busy\n", irq);
594 return -EBUSY; 594 return -EBUSY;
595 } 595 }
diff --git a/sound/drivers/serial-u16550.c b/sound/drivers/serial-u16550.c
index a25fb7b1f44..fc1d822802c 100644
--- a/sound/drivers/serial-u16550.c
+++ b/sound/drivers/serial-u16550.c
@@ -816,7 +816,7 @@ static int __devinit snd_uart16550_create(struct snd_card *card,
816 816
817 if (irq >= 0 && irq != SNDRV_AUTO_IRQ) { 817 if (irq >= 0 && irq != SNDRV_AUTO_IRQ) {
818 if (request_irq(irq, snd_uart16550_interrupt, 818 if (request_irq(irq, snd_uart16550_interrupt,
819 IRQF_DISABLED, "Serial MIDI", uart)) { 819 0, "Serial MIDI", uart)) {
820 snd_printk(KERN_WARNING 820 snd_printk(KERN_WARNING
821 "irq %d busy. Using Polling.\n", irq); 821 "irq %d busy. Using Polling.\n", irq);
822 } else { 822 } else {
diff --git a/sound/firewire/isight.c b/sound/firewire/isight.c
index 440030818db..cd094ecaca3 100644
--- a/sound/firewire/isight.c
+++ b/sound/firewire/isight.c
@@ -51,7 +51,6 @@ struct isight {
51 struct fw_unit *unit; 51 struct fw_unit *unit;
52 struct fw_device *device; 52 struct fw_device *device;
53 u64 audio_base; 53 u64 audio_base;
54 struct fw_address_handler iris_handler;
55 struct snd_pcm_substream *pcm; 54 struct snd_pcm_substream *pcm;
56 struct mutex mutex; 55 struct mutex mutex;
57 struct iso_packets_buffer buffer; 56 struct iso_packets_buffer buffer;
diff --git a/sound/firewire/speakers.c b/sound/firewire/speakers.c
index 3fc257da180..cbe6bb9e53b 100644
--- a/sound/firewire/speakers.c
+++ b/sound/firewire/speakers.c
@@ -778,9 +778,10 @@ static int __devexit fwspk_remove(struct device *dev)
778{ 778{
779 struct fwspk *fwspk = dev_get_drvdata(dev); 779 struct fwspk *fwspk = dev_get_drvdata(dev);
780 780
781 mutex_lock(&fwspk->mutex);
782 amdtp_out_stream_pcm_abort(&fwspk->stream); 781 amdtp_out_stream_pcm_abort(&fwspk->stream);
783 snd_card_disconnect(fwspk->card); 782 snd_card_disconnect(fwspk->card);
783
784 mutex_lock(&fwspk->mutex);
784 fwspk_stop_stream(fwspk); 785 fwspk_stop_stream(fwspk);
785 mutex_unlock(&fwspk->mutex); 786 mutex_unlock(&fwspk->mutex);
786 787
@@ -796,8 +797,8 @@ static void fwspk_bus_reset(struct fw_unit *unit)
796 fcp_bus_reset(fwspk->unit); 797 fcp_bus_reset(fwspk->unit);
797 798
798 if (cmp_connection_update(&fwspk->connection) < 0) { 799 if (cmp_connection_update(&fwspk->connection) < 0) {
799 mutex_lock(&fwspk->mutex);
800 amdtp_out_stream_pcm_abort(&fwspk->stream); 800 amdtp_out_stream_pcm_abort(&fwspk->stream);
801 mutex_lock(&fwspk->mutex);
801 fwspk_stop_stream(fwspk); 802 fwspk_stop_stream(fwspk);
802 mutex_unlock(&fwspk->mutex); 803 mutex_unlock(&fwspk->mutex);
803 return; 804 return;
diff --git a/sound/isa/ad1816a/ad1816a.c b/sound/isa/ad1816a/ad1816a.c
index 3cb75bc9769..a87a2b566e1 100644
--- a/sound/isa/ad1816a/ad1816a.c
+++ b/sound/isa/ad1816a/ad1816a.c
@@ -204,7 +204,7 @@ static int __devinit snd_card_ad1816a_probe(int dev, struct pnp_card_link *pcard
204 204
205 if (mpu_port[dev] > 0) { 205 if (mpu_port[dev] > 0) {
206 if (snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, 206 if (snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
207 mpu_port[dev], 0, mpu_irq[dev], IRQF_DISABLED, 207 mpu_port[dev], 0, mpu_irq[dev],
208 NULL) < 0) 208 NULL) < 0)
209 printk(KERN_ERR PFX "no MPU-401 device at 0x%lx.\n", mpu_port[dev]); 209 printk(KERN_ERR PFX "no MPU-401 device at 0x%lx.\n", mpu_port[dev]);
210 } 210 }
diff --git a/sound/isa/ad1816a/ad1816a_lib.c b/sound/isa/ad1816a/ad1816a_lib.c
index 05aef8b97e9..177eed3271b 100644
--- a/sound/isa/ad1816a/ad1816a_lib.c
+++ b/sound/isa/ad1816a/ad1816a_lib.c
@@ -595,7 +595,7 @@ int __devinit snd_ad1816a_create(struct snd_card *card,
595 snd_ad1816a_free(chip); 595 snd_ad1816a_free(chip);
596 return -EBUSY; 596 return -EBUSY;
597 } 597 }
598 if (request_irq(irq, snd_ad1816a_interrupt, IRQF_DISABLED, "AD1816A", (void *) chip)) { 598 if (request_irq(irq, snd_ad1816a_interrupt, 0, "AD1816A", (void *) chip)) {
599 snd_printk(KERN_ERR "ad1816a: can't grab IRQ %d\n", irq); 599 snd_printk(KERN_ERR "ad1816a: can't grab IRQ %d\n", irq);
600 snd_ad1816a_free(chip); 600 snd_ad1816a_free(chip);
601 return -EBUSY; 601 return -EBUSY;
diff --git a/sound/isa/als100.c b/sound/isa/als100.c
index 20becc89f6f..706effd6b3c 100644
--- a/sound/isa/als100.c
+++ b/sound/isa/als100.c
@@ -256,7 +256,6 @@ static int __devinit snd_card_als100_probe(int dev,
256 mpu_type, 256 mpu_type,
257 mpu_port[dev], 0, 257 mpu_port[dev], 0,
258 mpu_irq[dev], 258 mpu_irq[dev],
259 mpu_irq[dev] >= 0 ? IRQF_DISABLED : 0,
260 NULL) < 0) 259 NULL) < 0)
261 snd_printk(KERN_ERR PFX "no MPU-401 device at 0x%lx\n", mpu_port[dev]); 260 snd_printk(KERN_ERR PFX "no MPU-401 device at 0x%lx\n", mpu_port[dev]);
262 } 261 }
diff --git a/sound/isa/azt2320.c b/sound/isa/azt2320.c
index aac8dc15c2f..b7bdbf30774 100644
--- a/sound/isa/azt2320.c
+++ b/sound/isa/azt2320.c
@@ -234,8 +234,7 @@ static int __devinit snd_card_azt2320_probe(int dev,
234 if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) { 234 if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) {
235 if (snd_mpu401_uart_new(card, 0, MPU401_HW_AZT2320, 235 if (snd_mpu401_uart_new(card, 0, MPU401_HW_AZT2320,
236 mpu_port[dev], 0, 236 mpu_port[dev], 0,
237 mpu_irq[dev], IRQF_DISABLED, 237 mpu_irq[dev], NULL) < 0)
238 NULL) < 0)
239 snd_printk(KERN_ERR PFX "no MPU-401 device at 0x%lx\n", mpu_port[dev]); 238 snd_printk(KERN_ERR PFX "no MPU-401 device at 0x%lx\n", mpu_port[dev]);
240 } 239 }
241 240
diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c
index fe79a169acb..dca69f80305 100644
--- a/sound/isa/cmi8330.c
+++ b/sound/isa/cmi8330.c
@@ -597,7 +597,7 @@ static int __devinit snd_cmi8330_probe(struct snd_card *card, int dev)
597 if (mpuport[dev] != SNDRV_AUTO_PORT) { 597 if (mpuport[dev] != SNDRV_AUTO_PORT) {
598 if (snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, 598 if (snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
599 mpuport[dev], 0, mpuirq[dev], 599 mpuport[dev], 0, mpuirq[dev],
600 IRQF_DISABLED, NULL) < 0) 600 NULL) < 0)
601 printk(KERN_ERR PFX "no MPU-401 device at 0x%lx.\n", 601 printk(KERN_ERR PFX "no MPU-401 device at 0x%lx.\n",
602 mpuport[dev]); 602 mpuport[dev]);
603 } 603 }
diff --git a/sound/isa/cs423x/cs4231.c b/sound/isa/cs423x/cs4231.c
index cb9153e75b8..409fa0ad784 100644
--- a/sound/isa/cs423x/cs4231.c
+++ b/sound/isa/cs423x/cs4231.c
@@ -131,7 +131,6 @@ static int __devinit snd_cs4231_probe(struct device *dev, unsigned int n)
131 mpu_irq[n] = -1; 131 mpu_irq[n] = -1;
132 if (snd_mpu401_uart_new(card, 0, MPU401_HW_CS4232, 132 if (snd_mpu401_uart_new(card, 0, MPU401_HW_CS4232,
133 mpu_port[n], 0, mpu_irq[n], 133 mpu_port[n], 0, mpu_irq[n],
134 mpu_irq[n] >= 0 ? IRQF_DISABLED : 0,
135 NULL) < 0) 134 NULL) < 0)
136 dev_warn(dev, "MPU401 not detected\n"); 135 dev_warn(dev, "MPU401 not detected\n");
137 } 136 }
diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c
index 999dc1e0fdb..0dbde461e6c 100644
--- a/sound/isa/cs423x/cs4236.c
+++ b/sound/isa/cs423x/cs4236.c
@@ -449,8 +449,7 @@ static int __devinit snd_cs423x_probe(struct snd_card *card, int dev)
449 mpu_irq[dev] = -1; 449 mpu_irq[dev] = -1;
450 if (snd_mpu401_uart_new(card, 0, MPU401_HW_CS4232, 450 if (snd_mpu401_uart_new(card, 0, MPU401_HW_CS4232,
451 mpu_port[dev], 0, 451 mpu_port[dev], 0,
452 mpu_irq[dev], 452 mpu_irq[dev], NULL) < 0)
453 mpu_irq[dev] >= 0 ? IRQF_DISABLED : 0, NULL) < 0)
454 printk(KERN_WARNING IDENT ": MPU401 not detected\n"); 453 printk(KERN_WARNING IDENT ": MPU401 not detected\n");
455 } 454 }
456 455
diff --git a/sound/isa/es1688/es1688.c b/sound/isa/es1688/es1688.c
index 0cde8131a57..5493e9e4bcd 100644
--- a/sound/isa/es1688/es1688.c
+++ b/sound/isa/es1688/es1688.c
@@ -174,7 +174,7 @@ static int __devinit snd_es1688_probe(struct snd_card *card, unsigned int n)
174 chip->mpu_port > 0) { 174 chip->mpu_port > 0) {
175 error = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688, 175 error = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688,
176 chip->mpu_port, 0, 176 chip->mpu_port, 0,
177 mpu_irq[n], IRQF_DISABLED, NULL); 177 mpu_irq[n], NULL);
178 if (error < 0) 178 if (error < 0)
179 return error; 179 return error;
180 } 180 }
diff --git a/sound/isa/es1688/es1688_lib.c b/sound/isa/es1688/es1688_lib.c
index 07676200496..d3eab6fb086 100644
--- a/sound/isa/es1688/es1688_lib.c
+++ b/sound/isa/es1688/es1688_lib.c
@@ -661,7 +661,7 @@ int snd_es1688_create(struct snd_card *card,
661 snd_printk(KERN_ERR "es1688: can't grab port 0x%lx\n", port + 4); 661 snd_printk(KERN_ERR "es1688: can't grab port 0x%lx\n", port + 4);
662 return -EBUSY; 662 return -EBUSY;
663 } 663 }
664 if (request_irq(irq, snd_es1688_interrupt, IRQF_DISABLED, "ES1688", (void *) chip)) { 664 if (request_irq(irq, snd_es1688_interrupt, 0, "ES1688", (void *) chip)) {
665 snd_printk(KERN_ERR "es1688: can't grab IRQ %d\n", irq); 665 snd_printk(KERN_ERR "es1688: can't grab IRQ %d\n", irq);
666 return -EBUSY; 666 return -EBUSY;
667 } 667 }
diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c
index fb4d6b34bbc..bf6ad0bf51c 100644
--- a/sound/isa/es18xx.c
+++ b/sound/isa/es18xx.c
@@ -1805,7 +1805,7 @@ static int __devinit snd_es18xx_new_device(struct snd_card *card,
1805 return -EBUSY; 1805 return -EBUSY;
1806 } 1806 }
1807 1807
1808 if (request_irq(irq, snd_es18xx_interrupt, IRQF_DISABLED, "ES18xx", 1808 if (request_irq(irq, snd_es18xx_interrupt, 0, "ES18xx",
1809 (void *) card)) { 1809 (void *) card)) {
1810 snd_es18xx_free(card); 1810 snd_es18xx_free(card);
1811 snd_printk(KERN_ERR PFX "unable to grap IRQ %d\n", irq); 1811 snd_printk(KERN_ERR PFX "unable to grap IRQ %d\n", irq);
@@ -2160,8 +2160,8 @@ static int __devinit snd_audiodrive_probe(struct snd_card *card, int dev)
2160 2160
2161 if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) { 2161 if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) {
2162 err = snd_mpu401_uart_new(card, 0, MPU401_HW_ES18XX, 2162 err = snd_mpu401_uart_new(card, 0, MPU401_HW_ES18XX,
2163 mpu_port[dev], 0, 2163 mpu_port[dev], MPU401_INFO_IRQ_HOOK,
2164 irq[dev], 0, &chip->rmidi); 2164 -1, &chip->rmidi);
2165 if (err < 0) 2165 if (err < 0)
2166 return err; 2166 return err;
2167 } 2167 }
diff --git a/sound/isa/galaxy/galaxy.c b/sound/isa/galaxy/galaxy.c
index ee54df082b9..e51d3244742 100644
--- a/sound/isa/galaxy/galaxy.c
+++ b/sound/isa/galaxy/galaxy.c
@@ -585,8 +585,7 @@ static int __devinit snd_galaxy_probe(struct device *dev, unsigned int n)
585 585
586 if (mpu_port[n] >= 0) { 586 if (mpu_port[n] >= 0) {
587 err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, 587 err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
588 mpu_port[n], 0, mpu_irq[n], 588 mpu_port[n], 0, mpu_irq[n], NULL);
589 IRQF_DISABLED, NULL);
590 if (err < 0) 589 if (err < 0)
591 goto error; 590 goto error;
592 } 591 }
diff --git a/sound/isa/gus/gus_main.c b/sound/isa/gus/gus_main.c
index 12eb98f2f93..3167e5ac369 100644
--- a/sound/isa/gus/gus_main.c
+++ b/sound/isa/gus/gus_main.c
@@ -180,7 +180,7 @@ int snd_gus_create(struct snd_card *card,
180 snd_gus_free(gus); 180 snd_gus_free(gus);
181 return -EBUSY; 181 return -EBUSY;
182 } 182 }
183 if (irq >= 0 && request_irq(irq, snd_gus_interrupt, IRQF_DISABLED, "GUS GF1", (void *) gus)) { 183 if (irq >= 0 && request_irq(irq, snd_gus_interrupt, 0, "GUS GF1", (void *) gus)) {
184 snd_printk(KERN_ERR "gus: can't grab irq %d\n", irq); 184 snd_printk(KERN_ERR "gus: can't grab irq %d\n", irq);
185 snd_gus_free(gus); 185 snd_gus_free(gus);
186 return -EBUSY; 186 return -EBUSY;
diff --git a/sound/isa/gus/gusextreme.c b/sound/isa/gus/gusextreme.c
index 008e8e5bfa3..c4733c08b60 100644
--- a/sound/isa/gus/gusextreme.c
+++ b/sound/isa/gus/gusextreme.c
@@ -317,8 +317,7 @@ static int __devinit snd_gusextreme_probe(struct device *dev, unsigned int n)
317 317
318 if (es1688->mpu_port >= 0x300) { 318 if (es1688->mpu_port >= 0x300) {
319 error = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688, 319 error = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688,
320 es1688->mpu_port, 0, 320 es1688->mpu_port, 0, mpu_irq[n], NULL);
321 mpu_irq[n], IRQF_DISABLED, NULL);
322 if (error < 0) 321 if (error < 0)
323 goto out; 322 goto out;
324 } 323 }
diff --git a/sound/isa/gus/gusmax.c b/sound/isa/gus/gusmax.c
index 3e4a58b7291..c43faa057ff 100644
--- a/sound/isa/gus/gusmax.c
+++ b/sound/isa/gus/gusmax.c
@@ -291,7 +291,7 @@ static int __devinit snd_gusmax_probe(struct device *pdev, unsigned int dev)
291 goto _err; 291 goto _err;
292 } 292 }
293 293
294 if (request_irq(xirq, snd_gusmax_interrupt, IRQF_DISABLED, "GUS MAX", (void *)maxcard)) { 294 if (request_irq(xirq, snd_gusmax_interrupt, 0, "GUS MAX", (void *)maxcard)) {
295 snd_printk(KERN_ERR PFX "unable to grab IRQ %d\n", xirq); 295 snd_printk(KERN_ERR PFX "unable to grab IRQ %d\n", xirq);
296 err = -EBUSY; 296 err = -EBUSY;
297 goto _err; 297 goto _err;
diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c
index c7b80e4730f..5f869a32b48 100644
--- a/sound/isa/gus/interwave.c
+++ b/sound/isa/gus/interwave.c
@@ -684,7 +684,7 @@ static int __devinit snd_interwave_probe(struct snd_card *card, int dev)
684 if ((err = snd_gus_initialize(gus)) < 0) 684 if ((err = snd_gus_initialize(gus)) < 0)
685 return err; 685 return err;
686 686
687 if (request_irq(xirq, snd_interwave_interrupt, IRQF_DISABLED, 687 if (request_irq(xirq, snd_interwave_interrupt, 0,
688 "InterWave", iwcard)) { 688 "InterWave", iwcard)) {
689 snd_printk(KERN_ERR PFX "unable to grab IRQ %d\n", xirq); 689 snd_printk(KERN_ERR PFX "unable to grab IRQ %d\n", xirq);
690 return -EBUSY; 690 return -EBUSY;
diff --git a/sound/isa/msnd/msnd_pinnacle.c b/sound/isa/msnd/msnd_pinnacle.c
index 91d6023a63e..0961e2cf20c 100644
--- a/sound/isa/msnd/msnd_pinnacle.c
+++ b/sound/isa/msnd/msnd_pinnacle.c
@@ -600,7 +600,7 @@ static int __devinit snd_msnd_attach(struct snd_card *card)
600 mpu_io[0], 600 mpu_io[0],
601 MPU401_MODE_INPUT | 601 MPU401_MODE_INPUT |
602 MPU401_MODE_OUTPUT, 602 MPU401_MODE_OUTPUT,
603 mpu_irq[0], IRQF_DISABLED, 603 mpu_irq[0],
604 &chip->rmidi); 604 &chip->rmidi);
605 if (err < 0) { 605 if (err < 0) {
606 printk(KERN_ERR LOGNAME 606 printk(KERN_ERR LOGNAME
diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c
index 9b915e27b5b..bbafb0b543e 100644
--- a/sound/isa/opl3sa2.c
+++ b/sound/isa/opl3sa2.c
@@ -667,7 +667,7 @@ static int __devinit snd_opl3sa2_probe(struct snd_card *card, int dev)
667 err = snd_opl3sa2_detect(card); 667 err = snd_opl3sa2_detect(card);
668 if (err < 0) 668 if (err < 0)
669 return err; 669 return err;
670 err = request_irq(xirq, snd_opl3sa2_interrupt, IRQF_DISABLED, 670 err = request_irq(xirq, snd_opl3sa2_interrupt, 0,
671 "OPL3-SA2", card); 671 "OPL3-SA2", card);
672 if (err) { 672 if (err) {
673 snd_printk(KERN_ERR PFX "can't grab IRQ %d\n", xirq); 673 snd_printk(KERN_ERR PFX "can't grab IRQ %d\n", xirq);
@@ -707,8 +707,9 @@ static int __devinit snd_opl3sa2_probe(struct snd_card *card, int dev)
707 } 707 }
708 if (midi_port[dev] >= 0x300 && midi_port[dev] < 0x340) { 708 if (midi_port[dev] >= 0x300 && midi_port[dev] < 0x340) {
709 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_OPL3SA2, 709 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_OPL3SA2,
710 midi_port[dev], 0, 710 midi_port[dev],
711 xirq, 0, &chip->rmidi)) < 0) 711 MPU401_INFO_IRQ_HOOK, -1,
712 &chip->rmidi)) < 0)
712 return err; 713 return err;
713 } 714 }
714 sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d", 715 sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d",
diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c
index 8c24102d0d9..d94d0f35cb7 100644
--- a/sound/isa/opti9xx/miro.c
+++ b/sound/isa/opti9xx/miro.c
@@ -1377,8 +1377,7 @@ static int __devinit snd_miro_probe(struct snd_card *card)
1377 rmidi = NULL; 1377 rmidi = NULL;
1378 else { 1378 else {
1379 error = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, 1379 error = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
1380 mpu_port, 0, miro->mpu_irq, IRQF_DISABLED, 1380 mpu_port, 0, miro->mpu_irq, &rmidi);
1381 &rmidi);
1382 if (error < 0) 1381 if (error < 0)
1383 snd_printk(KERN_WARNING "no MPU-401 device at 0x%lx?\n", 1382 snd_printk(KERN_WARNING "no MPU-401 device at 0x%lx?\n",
1384 mpu_port); 1383 mpu_port);
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c
index c35dc68930d..6dbbfa76b44 100644
--- a/sound/isa/opti9xx/opti92x-ad1848.c
+++ b/sound/isa/opti9xx/opti92x-ad1848.c
@@ -892,7 +892,7 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card)
892#endif 892#endif
893#ifdef OPTi93X 893#ifdef OPTi93X
894 error = request_irq(irq, snd_opti93x_interrupt, 894 error = request_irq(irq, snd_opti93x_interrupt,
895 IRQF_DISABLED, DEV_NAME" - WSS", chip); 895 0, DEV_NAME" - WSS", chip);
896 if (error < 0) { 896 if (error < 0) {
897 snd_printk(KERN_ERR "opti9xx: can't grab IRQ %d\n", irq); 897 snd_printk(KERN_ERR "opti9xx: can't grab IRQ %d\n", irq);
898 return error; 898 return error;
@@ -914,7 +914,7 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card)
914 rmidi = NULL; 914 rmidi = NULL;
915 else { 915 else {
916 error = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, 916 error = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
917 mpu_port, 0, mpu_irq, IRQF_DISABLED, &rmidi); 917 mpu_port, 0, mpu_irq, &rmidi);
918 if (error) 918 if (error)
919 snd_printk(KERN_WARNING "no MPU-401 device at 0x%lx?\n", 919 snd_printk(KERN_WARNING "no MPU-401 device at 0x%lx?\n",
920 mpu_port); 920 mpu_port);
diff --git a/sound/isa/sb/jazz16.c b/sound/isa/sb/jazz16.c
index 8ccbcddf08e..54e3c2c1806 100644
--- a/sound/isa/sb/jazz16.c
+++ b/sound/isa/sb/jazz16.c
@@ -322,7 +322,6 @@ static int __devinit snd_jazz16_probe(struct device *devptr, unsigned int dev)
322 MPU401_HW_MPU401, 322 MPU401_HW_MPU401,
323 mpu_port[dev], 0, 323 mpu_port[dev], 0,
324 mpu_irq[dev], 324 mpu_irq[dev],
325 mpu_irq[dev] >= 0 ? IRQF_DISABLED : 0,
326 NULL) < 0) 325 NULL) < 0)
327 snd_printk(KERN_ERR "no MPU-401 device at 0x%lx\n", 326 snd_printk(KERN_ERR "no MPU-401 device at 0x%lx\n",
328 mpu_port[dev]); 327 mpu_port[dev]);
diff --git a/sound/isa/sb/sb16.c b/sound/isa/sb/sb16.c
index 4d1c5a300ff..237f8bd7fbe 100644
--- a/sound/isa/sb/sb16.c
+++ b/sound/isa/sb/sb16.c
@@ -394,8 +394,9 @@ static int __devinit snd_sb16_probe(struct snd_card *card, int dev)
394 394
395 if (chip->mpu_port > 0 && chip->mpu_port != SNDRV_AUTO_PORT) { 395 if (chip->mpu_port > 0 && chip->mpu_port != SNDRV_AUTO_PORT) {
396 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_SB, 396 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_SB,
397 chip->mpu_port, 0, 397 chip->mpu_port,
398 xirq, 0, &chip->rmidi)) < 0) 398 MPU401_INFO_IRQ_HOOK, -1,
399 &chip->rmidi)) < 0)
399 return err; 400 return err;
400 chip->rmidi_callback = snd_mpu401_uart_interrupt; 401 chip->rmidi_callback = snd_mpu401_uart_interrupt;
401 } 402 }
diff --git a/sound/isa/sb/sb_common.c b/sound/isa/sb/sb_common.c
index eae6c1c0eff..d2e19215813 100644
--- a/sound/isa/sb/sb_common.c
+++ b/sound/isa/sb/sb_common.c
@@ -240,7 +240,7 @@ int snd_sbdsp_create(struct snd_card *card,
240 if (request_irq(irq, irq_handler, 240 if (request_irq(irq, irq_handler,
241 (hardware == SB_HW_ALS4000 || 241 (hardware == SB_HW_ALS4000 ||
242 hardware == SB_HW_CS5530) ? 242 hardware == SB_HW_CS5530) ?
243 IRQF_SHARED : IRQF_DISABLED, 243 IRQF_SHARED : 0,
244 "SoundBlaster", (void *) chip)) { 244 "SoundBlaster", (void *) chip)) {
245 snd_printk(KERN_ERR "sb: can't grab irq %d\n", irq); 245 snd_printk(KERN_ERR "sb: can't grab irq %d\n", irq);
246 snd_sbdsp_free(chip); 246 snd_sbdsp_free(chip);
diff --git a/sound/isa/sc6000.c b/sound/isa/sc6000.c
index 9a8bbf6dd62..207c161f100 100644
--- a/sound/isa/sc6000.c
+++ b/sound/isa/sc6000.c
@@ -658,8 +658,7 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev)
658 if (snd_mpu401_uart_new(card, 0, 658 if (snd_mpu401_uart_new(card, 0,
659 MPU401_HW_MPU401, 659 MPU401_HW_MPU401,
660 mpu_port[dev], 0, 660 mpu_port[dev], 0,
661 mpu_irq[dev], IRQF_DISABLED, 661 mpu_irq[dev], NULL) < 0)
662 NULL) < 0)
663 snd_printk(KERN_ERR "no MPU-401 device at 0x%lx ?\n", 662 snd_printk(KERN_ERR "no MPU-401 device at 0x%lx ?\n",
664 mpu_port[dev]); 663 mpu_port[dev]);
665 } 664 }
diff --git a/sound/isa/sscape.c b/sound/isa/sscape.c
index e2d5d2d3ed9..f2379e102b6 100644
--- a/sound/isa/sscape.c
+++ b/sound/isa/sscape.c
@@ -825,8 +825,7 @@ static int __devinit create_mpu401(struct snd_card *card, int devnum,
825 int err; 825 int err;
826 826
827 err = snd_mpu401_uart_new(card, devnum, MPU401_HW_MPU401, port, 827 err = snd_mpu401_uart_new(card, devnum, MPU401_HW_MPU401, port,
828 MPU401_INFO_INTEGRATED, irq, IRQF_DISABLED, 828 MPU401_INFO_INTEGRATED, irq, &rawmidi);
829 &rawmidi);
830 if (err == 0) { 829 if (err == 0) {
831 struct snd_mpu401 *mpu = rawmidi->private_data; 830 struct snd_mpu401 *mpu = rawmidi->private_data;
832 mpu->open_input = mpu401_open; 831 mpu->open_input = mpu401_open;
diff --git a/sound/isa/wavefront/wavefront.c b/sound/isa/wavefront/wavefront.c
index 711670e4a42..87142977335 100644
--- a/sound/isa/wavefront/wavefront.c
+++ b/sound/isa/wavefront/wavefront.c
@@ -418,7 +418,7 @@ snd_wavefront_probe (struct snd_card *card, int dev)
418 return -EBUSY; 418 return -EBUSY;
419 } 419 }
420 if (request_irq(ics2115_irq[dev], snd_wavefront_ics2115_interrupt, 420 if (request_irq(ics2115_irq[dev], snd_wavefront_ics2115_interrupt,
421 IRQF_DISABLED, "ICS2115", acard)) { 421 0, "ICS2115", acard)) {
422 snd_printk(KERN_ERR "unable to use ICS2115 IRQ %d\n", ics2115_irq[dev]); 422 snd_printk(KERN_ERR "unable to use ICS2115 IRQ %d\n", ics2115_irq[dev]);
423 return -EBUSY; 423 return -EBUSY;
424 } 424 }
@@ -449,8 +449,7 @@ snd_wavefront_probe (struct snd_card *card, int dev)
449 if (cs4232_mpu_port[dev] > 0 && cs4232_mpu_port[dev] != SNDRV_AUTO_PORT) { 449 if (cs4232_mpu_port[dev] > 0 && cs4232_mpu_port[dev] != SNDRV_AUTO_PORT) {
450 err = snd_mpu401_uart_new(card, midi_dev, MPU401_HW_CS4232, 450 err = snd_mpu401_uart_new(card, midi_dev, MPU401_HW_CS4232,
451 cs4232_mpu_port[dev], 0, 451 cs4232_mpu_port[dev], 0,
452 cs4232_mpu_irq[dev], IRQF_DISABLED, 452 cs4232_mpu_irq[dev], NULL);
453 NULL);
454 if (err < 0) { 453 if (err < 0) {
455 snd_printk (KERN_ERR "can't allocate CS4232 MPU-401 device\n"); 454 snd_printk (KERN_ERR "can't allocate CS4232 MPU-401 device\n");
456 return err; 455 return err;
diff --git a/sound/isa/wss/wss_lib.c b/sound/isa/wss/wss_lib.c
index 2a42cc37795..7277c5b7df6 100644
--- a/sound/isa/wss/wss_lib.c
+++ b/sound/isa/wss/wss_lib.c
@@ -1833,7 +1833,7 @@ int snd_wss_create(struct snd_card *card,
1833 } 1833 }
1834 chip->cport = cport; 1834 chip->cport = cport;
1835 if (!(hwshare & WSS_HWSHARE_IRQ)) 1835 if (!(hwshare & WSS_HWSHARE_IRQ))
1836 if (request_irq(irq, snd_wss_interrupt, IRQF_DISABLED, 1836 if (request_irq(irq, snd_wss_interrupt, 0,
1837 "WSS", (void *) chip)) { 1837 "WSS", (void *) chip)) {
1838 snd_printk(KERN_ERR "wss: can't grab IRQ %d\n", irq); 1838 snd_printk(KERN_ERR "wss: can't grab IRQ %d\n", irq);
1839 snd_wss_free(chip); 1839 snd_wss_free(chip);
diff --git a/sound/mips/Kconfig b/sound/mips/Kconfig
index a9823fad85c..77dd0a13aec 100644
--- a/sound/mips/Kconfig
+++ b/sound/mips/Kconfig
@@ -23,12 +23,15 @@ config SND_SGI_HAL2
23 23
24 24
25config SND_AU1X00 25config SND_AU1X00
26 tristate "Au1x00 AC97 Port Driver" 26 tristate "Au1x00 AC97 Port Driver (DEPRECATED)"
27 depends on SOC_AU1000 || SOC_AU1100 || SOC_AU1500 27 depends on SOC_AU1000 || SOC_AU1100 || SOC_AU1500
28 select SND_PCM 28 select SND_PCM
29 select SND_AC97_CODEC 29 select SND_AC97_CODEC
30 help 30 help
31 ALSA Sound driver for the Au1x00's AC97 port. 31 ALSA Sound driver for the Au1x00's AC97 port.
32 32
33 Newer drivers for ASoC are available, please do not use
34 this driver as it will be removed in the future.
35
33endif # SND_MIPS 36endif # SND_MIPS
34 37
diff --git a/sound/mips/au1x00.c b/sound/mips/au1x00.c
index 446cf974866..7567ebd7191 100644
--- a/sound/mips/au1x00.c
+++ b/sound/mips/au1x00.c
@@ -465,13 +465,13 @@ snd_au1000_pcm_new(struct snd_au1000 *au1000)
465 465
466 flags = claim_dma_lock(); 466 flags = claim_dma_lock();
467 if ((au1000->stream[PLAYBACK]->dma = request_au1000_dma(DMA_ID_AC97C_TX, 467 if ((au1000->stream[PLAYBACK]->dma = request_au1000_dma(DMA_ID_AC97C_TX,
468 "AC97 TX", au1000_dma_interrupt, IRQF_DISABLED, 468 "AC97 TX", au1000_dma_interrupt, 0,
469 au1000->stream[PLAYBACK])) < 0) { 469 au1000->stream[PLAYBACK])) < 0) {
470 release_dma_lock(flags); 470 release_dma_lock(flags);
471 return -EBUSY; 471 return -EBUSY;
472 } 472 }
473 if ((au1000->stream[CAPTURE]->dma = request_au1000_dma(DMA_ID_AC97C_RX, 473 if ((au1000->stream[CAPTURE]->dma = request_au1000_dma(DMA_ID_AC97C_RX,
474 "AC97 RX", au1000_dma_interrupt, IRQF_DISABLED, 474 "AC97 RX", au1000_dma_interrupt, 0,
475 au1000->stream[CAPTURE])) < 0){ 475 au1000->stream[CAPTURE])) < 0){
476 release_dma_lock(flags); 476 release_dma_lock(flags);
477 return -EBUSY; 477 return -EBUSY;
diff --git a/sound/oss/sound_timer.c b/sound/oss/sound_timer.c
index 48cda6c4c25..8021c85f076 100644
--- a/sound/oss/sound_timer.c
+++ b/sound/oss/sound_timer.c
@@ -320,7 +320,7 @@ void sound_timer_init(struct sound_lowlev_timer *t, char *name)
320 n = sound_alloc_timerdev(); 320 n = sound_alloc_timerdev();
321 if (n == -1) 321 if (n == -1)
322 n = 0; /* Overwrite the system timer */ 322 n = 0; /* Overwrite the system timer */
323 strcpy(sound_timer.info.name, name); 323 strlcpy(sound_timer.info.name, name, sizeof(sound_timer.info.name));
324 sound_timer_devs[n] = &sound_timer; 324 sound_timer_devs[n] = &sound_timer;
325} 325}
326EXPORT_SYMBOL(sound_timer_init); 326EXPORT_SYMBOL(sound_timer_init);
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c
index a9c1af33f27..04628696eb0 100644
--- a/sound/pci/als4000.c
+++ b/sound/pci/als4000.c
@@ -931,8 +931,9 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci,
931 931
932 if ((err = snd_mpu401_uart_new( card, 0, MPU401_HW_ALS4000, 932 if ((err = snd_mpu401_uart_new( card, 0, MPU401_HW_ALS4000,
933 iobase + ALS4K_IOB_30_MIDI_DATA, 933 iobase + ALS4K_IOB_30_MIDI_DATA,
934 MPU401_INFO_INTEGRATED, 934 MPU401_INFO_INTEGRATED |
935 pci->irq, 0, &chip->rmidi)) < 0) { 935 MPU401_INFO_IRQ_HOOK,
936 -1, &chip->rmidi)) < 0) {
936 printk(KERN_ERR "als4000: no MPU-401 device at 0x%lx?\n", 937 printk(KERN_ERR "als4000: no MPU-401 device at 0x%lx?\n",
937 iobase + ALS4K_IOB_30_MIDI_DATA); 938 iobase + ALS4K_IOB_30_MIDI_DATA);
938 goto out_err; 939 goto out_err;
diff --git a/sound/pci/au88x0/au88x0_mpu401.c b/sound/pci/au88x0/au88x0_mpu401.c
index 0dc8d259d1e..e6c6a0febb7 100644
--- a/sound/pci/au88x0/au88x0_mpu401.c
+++ b/sound/pci/au88x0/au88x0_mpu401.c
@@ -84,7 +84,7 @@ static int __devinit snd_vortex_midi(vortex_t * vortex)
84#ifdef VORTEX_MPU401_LEGACY 84#ifdef VORTEX_MPU401_LEGACY
85 if ((temp = 85 if ((temp =
86 snd_mpu401_uart_new(vortex->card, 0, MPU401_HW_MPU401, 0x330, 86 snd_mpu401_uart_new(vortex->card, 0, MPU401_HW_MPU401, 0x330,
87 0, 0, 0, &rmidi)) != 0) { 87 MPU401_INFO_IRQ_HOOK, -1, &rmidi)) != 0) {
88 hwwrite(vortex->mmio, VORTEX_CTRL, 88 hwwrite(vortex->mmio, VORTEX_CTRL,
89 (hwread(vortex->mmio, VORTEX_CTRL) & 89 (hwread(vortex->mmio, VORTEX_CTRL) &
90 ~CTRL_MIDI_PORT) & ~CTRL_MIDI_EN); 90 ~CTRL_MIDI_PORT) & ~CTRL_MIDI_EN);
@@ -94,8 +94,8 @@ static int __devinit snd_vortex_midi(vortex_t * vortex)
94 port = (unsigned long)(vortex->mmio + VORTEX_MIDI_DATA); 94 port = (unsigned long)(vortex->mmio + VORTEX_MIDI_DATA);
95 if ((temp = 95 if ((temp =
96 snd_mpu401_uart_new(vortex->card, 0, MPU401_HW_AUREAL, port, 96 snd_mpu401_uart_new(vortex->card, 0, MPU401_HW_AUREAL, port,
97 MPU401_INFO_INTEGRATED | MPU401_INFO_MMIO, 97 MPU401_INFO_INTEGRATED | MPU401_INFO_MMIO |
98 0, 0, &rmidi)) != 0) { 98 MPU401_INFO_IRQ_HOOK, -1, &rmidi)) != 0) {
99 hwwrite(vortex->mmio, VORTEX_CTRL, 99 hwwrite(vortex->mmio, VORTEX_CTRL,
100 (hwread(vortex->mmio, VORTEX_CTRL) & 100 (hwread(vortex->mmio, VORTEX_CTRL) &
101 ~CTRL_MIDI_PORT) & ~CTRL_MIDI_EN); 101 ~CTRL_MIDI_PORT) & ~CTRL_MIDI_EN);
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index 579fc0dce12..d24fe425e87 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -2652,8 +2652,9 @@ snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
2652 since our hardware ought to be similar, thus use same ID. */ 2652 since our hardware ought to be similar, thus use same ID. */
2653 err = snd_mpu401_uart_new( 2653 err = snd_mpu401_uart_new(
2654 card, 0, 2654 card, 0,
2655 MPU401_HW_AZT2320, chip->mpu_io, MPU401_INFO_INTEGRATED, 2655 MPU401_HW_AZT2320, chip->mpu_io,
2656 pci->irq, 0, &chip->rmidi 2656 MPU401_INFO_INTEGRATED | MPU401_INFO_IRQ_HOOK,
2657 -1, &chip->rmidi
2657 ); 2658 );
2658 if (err < 0) { 2659 if (err < 0) {
2659 snd_printk(KERN_ERR "azf3328: no MPU-401 device at 0x%lx?\n", 2660 snd_printk(KERN_ERR "azf3328: no MPU-401 device at 0x%lx?\n",
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
index 9cf99fb7eb9..da9c73211ec 100644
--- a/sound/pci/cmipci.c
+++ b/sound/pci/cmipci.c
@@ -3228,8 +3228,9 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc
3228 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_CMIPCI, 3228 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_CMIPCI,
3229 iomidi, 3229 iomidi,
3230 (integrated_midi ? 3230 (integrated_midi ?
3231 MPU401_INFO_INTEGRATED : 0), 3231 MPU401_INFO_INTEGRATED : 0) |
3232 cm->irq, 0, &cm->rmidi)) < 0) { 3232 MPU401_INFO_IRQ_HOOK,
3233 -1, &cm->rmidi)) < 0) {
3233 printk(KERN_ERR "cmipci: no UART401 device at 0x%lx\n", iomidi); 3234 printk(KERN_ERR "cmipci: no UART401 device at 0x%lx\n", iomidi);
3234 } 3235 }
3235 } 3236 }
diff --git a/sound/pci/ctxfi/ctpcm.c b/sound/pci/ctxfi/ctpcm.c
index 457d21189b0..2c8622617c8 100644
--- a/sound/pci/ctxfi/ctpcm.c
+++ b/sound/pci/ctxfi/ctpcm.c
@@ -404,7 +404,7 @@ int ct_alsa_pcm_create(struct ct_atc *atc,
404 int err; 404 int err;
405 int playback_count, capture_count; 405 int playback_count, capture_count;
406 406
407 playback_count = (IEC958 == device) ? 1 : 8; 407 playback_count = (IEC958 == device) ? 1 : 256;
408 capture_count = (FRONT == device) ? 1 : 0; 408 capture_count = (FRONT == device) ? 1 : 0;
409 err = snd_pcm_new(atc->card, "ctxfi", device, 409 err = snd_pcm_new(atc->card, "ctxfi", device,
410 playback_count, capture_count, &pcm); 410 playback_count, capture_count, &pcm);
diff --git a/sound/pci/ctxfi/ctsrc.c b/sound/pci/ctxfi/ctsrc.c
index c749fa72088..e134b3a5780 100644
--- a/sound/pci/ctxfi/ctsrc.c
+++ b/sound/pci/ctxfi/ctsrc.c
@@ -20,7 +20,7 @@
20#include "cthardware.h" 20#include "cthardware.h"
21#include <linux/slab.h> 21#include <linux/slab.h>
22 22
23#define SRC_RESOURCE_NUM 64 23#define SRC_RESOURCE_NUM 256
24#define SRCIMP_RESOURCE_NUM 256 24#define SRCIMP_RESOURCE_NUM 256
25 25
26static unsigned int conj_mask; 26static unsigned int conj_mask;
diff --git a/sound/pci/ctxfi/ctvmem.h b/sound/pci/ctxfi/ctvmem.h
index b23adfca4de..e6da60eb19c 100644
--- a/sound/pci/ctxfi/ctvmem.h
+++ b/sound/pci/ctxfi/ctvmem.h
@@ -18,7 +18,7 @@
18#ifndef CTVMEM_H 18#ifndef CTVMEM_H
19#define CTVMEM_H 19#define CTVMEM_H
20 20
21#define CT_PTP_NUM 1 /* num of device page table pages */ 21#define CT_PTP_NUM 4 /* num of device page table pages */
22 22
23#include <linux/mutex.h> 23#include <linux/mutex.h>
24#include <linux/list.h> 24#include <linux/list.h>
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c
index 622bace148e..e22b8e2bbd8 100644
--- a/sound/pci/emu10k1/emupcm.c
+++ b/sound/pci/emu10k1/emupcm.c
@@ -1146,6 +1146,11 @@ static int snd_emu10k1_playback_open(struct snd_pcm_substream *substream)
1146 kfree(epcm); 1146 kfree(epcm);
1147 return err; 1147 return err;
1148 } 1148 }
1149 err = snd_pcm_hw_rule_noresample(runtime, 48000);
1150 if (err < 0) {
1151 kfree(epcm);
1152 return err;
1153 }
1149 mix = &emu->pcm_mixer[substream->number]; 1154 mix = &emu->pcm_mixer[substream->number];
1150 for (i = 0; i < 4; i++) 1155 for (i = 0; i < 4; i++)
1151 mix->send_routing[0][i] = mix->send_routing[1][i] = mix->send_routing[2][i] = i; 1156 mix->send_routing[0][i] = mix->send_routing[1][i] = mix->send_routing[2][i] = i;
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c
index 26a5a2f25d4..718a2643474 100644
--- a/sound/pci/es1938.c
+++ b/sound/pci/es1938.c
@@ -1854,8 +1854,9 @@ static int __devinit snd_es1938_probe(struct pci_dev *pci,
1854 } 1854 }
1855 } 1855 }
1856 if (snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, 1856 if (snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
1857 chip->mpu_port, MPU401_INFO_INTEGRATED, 1857 chip->mpu_port,
1858 chip->irq, 0, &chip->rmidi) < 0) { 1858 MPU401_INFO_INTEGRATED | MPU401_INFO_IRQ_HOOK,
1859 -1, &chip->rmidi) < 0) {
1859 printk(KERN_ERR "es1938: unable to initialize MPU-401\n"); 1860 printk(KERN_ERR "es1938: unable to initialize MPU-401\n");
1860 } else { 1861 } else {
1861 // this line is vital for MIDI interrupt handling on ess-solo1 1862 // this line is vital for MIDI interrupt handling on ess-solo1
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index 99ea9320c6b..407e4abc435 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -2843,8 +2843,9 @@ static int __devinit snd_es1968_probe(struct pci_dev *pci,
2843 if (enable_mpu[dev]) { 2843 if (enable_mpu[dev]) {
2844 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, 2844 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
2845 chip->io_port + ESM_MPU401_PORT, 2845 chip->io_port + ESM_MPU401_PORT,
2846 MPU401_INFO_INTEGRATED, 2846 MPU401_INFO_INTEGRATED |
2847 chip->irq, 0, &chip->rmidi)) < 0) { 2847 MPU401_INFO_IRQ_HOOK,
2848 -1, &chip->rmidi)) < 0) {
2848 printk(KERN_WARNING "es1968: skipping MPU-401 MIDI support..\n"); 2849 printk(KERN_WARNING "es1968: skipping MPU-401 MIDI support..\n");
2849 } 2850 }
2850 } 2851 }
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
index 32b02d90670..136f7232bb7 100644
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -729,11 +729,14 @@ static struct snd_fm801_tea575x_gpio snd_fm801_tea575x_gpios[] = {
729 { .data = 2, .clk = 0, .wren = 1, .most = 3, .name = "SF64-PCR" }, 729 { .data = 2, .clk = 0, .wren = 1, .most = 3, .name = "SF64-PCR" },
730}; 730};
731 731
732#define get_tea575x_gpio(chip) \
733 (&snd_fm801_tea575x_gpios[((chip)->tea575x_tuner & TUNER_TYPE_MASK) - 1])
734
732static void snd_fm801_tea575x_set_pins(struct snd_tea575x *tea, u8 pins) 735static void snd_fm801_tea575x_set_pins(struct snd_tea575x *tea, u8 pins)
733{ 736{
734 struct fm801 *chip = tea->private_data; 737 struct fm801 *chip = tea->private_data;
735 unsigned short reg = inw(FM801_REG(chip, GPIO_CTRL)); 738 unsigned short reg = inw(FM801_REG(chip, GPIO_CTRL));
736 struct snd_fm801_tea575x_gpio gpio = snd_fm801_tea575x_gpios[(chip->tea575x_tuner & TUNER_TYPE_MASK) - 1]; 739 struct snd_fm801_tea575x_gpio gpio = *get_tea575x_gpio(chip);
737 740
738 reg &= ~(FM801_GPIO_GP(gpio.data) | 741 reg &= ~(FM801_GPIO_GP(gpio.data) |
739 FM801_GPIO_GP(gpio.clk) | 742 FM801_GPIO_GP(gpio.clk) |
@@ -751,7 +754,7 @@ static u8 snd_fm801_tea575x_get_pins(struct snd_tea575x *tea)
751{ 754{
752 struct fm801 *chip = tea->private_data; 755 struct fm801 *chip = tea->private_data;
753 unsigned short reg = inw(FM801_REG(chip, GPIO_CTRL)); 756 unsigned short reg = inw(FM801_REG(chip, GPIO_CTRL));
754 struct snd_fm801_tea575x_gpio gpio = snd_fm801_tea575x_gpios[(chip->tea575x_tuner & TUNER_TYPE_MASK) - 1]; 757 struct snd_fm801_tea575x_gpio gpio = *get_tea575x_gpio(chip);
755 758
756 return (reg & FM801_GPIO_GP(gpio.data)) ? TEA575X_DATA : 0 | 759 return (reg & FM801_GPIO_GP(gpio.data)) ? TEA575X_DATA : 0 |
757 (reg & FM801_GPIO_GP(gpio.most)) ? TEA575X_MOST : 0; 760 (reg & FM801_GPIO_GP(gpio.most)) ? TEA575X_MOST : 0;
@@ -761,7 +764,7 @@ static void snd_fm801_tea575x_set_direction(struct snd_tea575x *tea, bool output
761{ 764{
762 struct fm801 *chip = tea->private_data; 765 struct fm801 *chip = tea->private_data;
763 unsigned short reg = inw(FM801_REG(chip, GPIO_CTRL)); 766 unsigned short reg = inw(FM801_REG(chip, GPIO_CTRL));
764 struct snd_fm801_tea575x_gpio gpio = snd_fm801_tea575x_gpios[(chip->tea575x_tuner & TUNER_TYPE_MASK) - 1]; 767 struct snd_fm801_tea575x_gpio gpio = *get_tea575x_gpio(chip);
765 768
766 /* use GPIO lines and set write enable bit */ 769 /* use GPIO lines and set write enable bit */
767 reg |= FM801_GPIO_GS(gpio.data) | 770 reg |= FM801_GPIO_GS(gpio.data) |
@@ -1246,7 +1249,7 @@ static int __devinit snd_fm801_create(struct snd_card *card,
1246 chip->tea575x_tuner = tea575x_tuner; 1249 chip->tea575x_tuner = tea575x_tuner;
1247 if (!snd_tea575x_init(&chip->tea)) { 1250 if (!snd_tea575x_init(&chip->tea)) {
1248 snd_printk(KERN_INFO "detected TEA575x radio type %s\n", 1251 snd_printk(KERN_INFO "detected TEA575x radio type %s\n",
1249 snd_fm801_tea575x_gpios[tea575x_tuner - 1].name); 1252 get_tea575x_gpio(chip)->name);
1250 break; 1253 break;
1251 } 1254 }
1252 } 1255 }
@@ -1256,9 +1259,7 @@ static int __devinit snd_fm801_create(struct snd_card *card,
1256 } 1259 }
1257 } 1260 }
1258 if (!(chip->tea575x_tuner & TUNER_DISABLED)) { 1261 if (!(chip->tea575x_tuner & TUNER_DISABLED)) {
1259 strlcpy(chip->tea.card, 1262 strlcpy(chip->tea.card, get_tea575x_gpio(chip)->name,
1260 snd_fm801_tea575x_gpios[(tea575x_tuner &
1261 TUNER_TYPE_MASK) - 1].name,
1262 sizeof(chip->tea.card)); 1263 sizeof(chip->tea.card));
1263 } 1264 }
1264#endif 1265#endif
@@ -1311,8 +1312,9 @@ static int __devinit snd_card_fm801_probe(struct pci_dev *pci,
1311 } 1312 }
1312 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_FM801, 1313 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_FM801,
1313 FM801_REG(chip, MPU401_DATA), 1314 FM801_REG(chip, MPU401_DATA),
1314 MPU401_INFO_INTEGRATED, 1315 MPU401_INFO_INTEGRATED |
1315 chip->irq, 0, &chip->rmidi)) < 0) { 1316 MPU401_INFO_IRQ_HOOK,
1317 -1, &chip->rmidi)) < 0) {
1316 snd_card_free(card); 1318 snd_card_free(card);
1317 return err; 1319 return err;
1318 } 1320 }
diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile
index 87365d5ea2a..f928d663472 100644
--- a/sound/pci/hda/Makefile
+++ b/sound/pci/hda/Makefile
@@ -6,6 +6,9 @@ snd-hda-codec-$(CONFIG_PROC_FS) += hda_proc.o
6snd-hda-codec-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o 6snd-hda-codec-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o
7snd-hda-codec-$(CONFIG_SND_HDA_INPUT_BEEP) += hda_beep.o 7snd-hda-codec-$(CONFIG_SND_HDA_INPUT_BEEP) += hda_beep.o
8 8
9# for trace-points
10CFLAGS_hda_codec.o := -I$(src)
11
9snd-hda-codec-realtek-objs := patch_realtek.o 12snd-hda-codec-realtek-objs := patch_realtek.o
10snd-hda-codec-cmedia-objs := patch_cmedia.o 13snd-hda-codec-cmedia-objs := patch_cmedia.o
11snd-hda-codec-analog-objs := patch_analog.o 14snd-hda-codec-analog-objs := patch_analog.o
diff --git a/sound/pci/hda/alc260_quirks.c b/sound/pci/hda/alc260_quirks.c
index 21ec2cb100b..3b5170b9700 100644
--- a/sound/pci/hda/alc260_quirks.c
+++ b/sound/pci/hda/alc260_quirks.c
@@ -7,9 +7,6 @@
7enum { 7enum {
8 ALC260_AUTO, 8 ALC260_AUTO,
9 ALC260_BASIC, 9 ALC260_BASIC,
10 ALC260_HP,
11 ALC260_HP_DC7600,
12 ALC260_HP_3013,
13 ALC260_FUJITSU_S702X, 10 ALC260_FUJITSU_S702X,
14 ALC260_ACER, 11 ALC260_ACER,
15 ALC260_WILL, 12 ALC260_WILL,
@@ -142,8 +139,6 @@ static const struct hda_channel_mode alc260_modes[1] = {
142/* Mixer combinations 139/* Mixer combinations
143 * 140 *
144 * basic: base_output + input + pc_beep + capture 141 * basic: base_output + input + pc_beep + capture
145 * HP: base_output + input + capture_alt
146 * HP_3013: hp_3013 + input + capture
147 * fujitsu: fujitsu + capture 142 * fujitsu: fujitsu + capture
148 * acer: acer + capture 143 * acer: acer + capture
149 */ 144 */
@@ -170,145 +165,6 @@ static const struct snd_kcontrol_new alc260_input_mixer[] = {
170 { } /* end */ 165 { } /* end */
171}; 166};
172 167
173/* update HP, line and mono out pins according to the master switch */
174static void alc260_hp_master_update(struct hda_codec *codec)
175{
176 update_speakers(codec);
177}
178
179static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
180 struct snd_ctl_elem_value *ucontrol)
181{
182 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
183 struct alc_spec *spec = codec->spec;
184 *ucontrol->value.integer.value = !spec->master_mute;
185 return 0;
186}
187
188static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
189 struct snd_ctl_elem_value *ucontrol)
190{
191 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
192 struct alc_spec *spec = codec->spec;
193 int val = !*ucontrol->value.integer.value;
194
195 if (val == spec->master_mute)
196 return 0;
197 spec->master_mute = val;
198 alc260_hp_master_update(codec);
199 return 1;
200}
201
202static const struct snd_kcontrol_new alc260_hp_output_mixer[] = {
203 {
204 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
205 .name = "Master Playback Switch",
206 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
207 .info = snd_ctl_boolean_mono_info,
208 .get = alc260_hp_master_sw_get,
209 .put = alc260_hp_master_sw_put,
210 },
211 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
212 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
213 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
214 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
215 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
216 HDA_OUTPUT),
217 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
218 { } /* end */
219};
220
221static const struct hda_verb alc260_hp_unsol_verbs[] = {
222 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
223 {},
224};
225
226static void alc260_hp_setup(struct hda_codec *codec)
227{
228 struct alc_spec *spec = codec->spec;
229
230 spec->autocfg.hp_pins[0] = 0x0f;
231 spec->autocfg.speaker_pins[0] = 0x10;
232 spec->autocfg.speaker_pins[1] = 0x11;
233 spec->automute = 1;
234 spec->automute_mode = ALC_AUTOMUTE_PIN;
235}
236
237static const struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
238 {
239 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
240 .name = "Master Playback Switch",
241 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
242 .info = snd_ctl_boolean_mono_info,
243 .get = alc260_hp_master_sw_get,
244 .put = alc260_hp_master_sw_put,
245 },
246 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
247 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
248 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
249 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
250 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
251 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
252 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
253 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
254 { } /* end */
255};
256
257static void alc260_hp_3013_setup(struct hda_codec *codec)
258{
259 struct alc_spec *spec = codec->spec;
260
261 spec->autocfg.hp_pins[0] = 0x15;
262 spec->autocfg.speaker_pins[0] = 0x10;
263 spec->autocfg.speaker_pins[1] = 0x11;
264 spec->automute = 1;
265 spec->automute_mode = ALC_AUTOMUTE_PIN;
266}
267
268static const struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
269 .ops = &snd_hda_bind_vol,
270 .values = {
271 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
272 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
273 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
274 0
275 },
276};
277
278static const struct hda_bind_ctls alc260_dc7600_bind_switch = {
279 .ops = &snd_hda_bind_sw,
280 .values = {
281 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
282 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
283 0
284 },
285};
286
287static const struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
288 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
289 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
290 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
291 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
292 { } /* end */
293};
294
295static const struct hda_verb alc260_hp_3013_unsol_verbs[] = {
296 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
297 {},
298};
299
300static void alc260_hp_3012_setup(struct hda_codec *codec)
301{
302 struct alc_spec *spec = codec->spec;
303
304 spec->autocfg.hp_pins[0] = 0x10;
305 spec->autocfg.speaker_pins[0] = 0x0f;
306 spec->autocfg.speaker_pins[1] = 0x11;
307 spec->autocfg.speaker_pins[2] = 0x15;
308 spec->automute = 1;
309 spec->automute_mode = ALC_AUTOMUTE_PIN;
310}
311
312/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12, 168/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
313 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10. 169 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
314 */ 170 */
@@ -480,106 +336,6 @@ static const struct hda_verb alc260_init_verbs[] = {
480 { } 336 { }
481}; 337};
482 338
483#if 0 /* should be identical with alc260_init_verbs? */
484static const struct hda_verb alc260_hp_init_verbs[] = {
485 /* Headphone and output */
486 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
487 /* mono output */
488 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
489 /* Mic1 (rear panel) pin widget for input and vref at 80% */
490 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
491 /* Mic2 (front panel) pin widget for input and vref at 80% */
492 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
493 /* Line In pin widget for input */
494 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
495 /* Line-2 pin widget for output */
496 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
497 /* CD pin widget for input */
498 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
499 /* unmute amp left and right */
500 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
501 /* set connection select to line in (default select for this ADC) */
502 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
503 /* unmute Line-Out mixer amp left and right (volume = 0) */
504 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
505 /* mute pin widget amp left and right (no gain on this amp) */
506 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
507 /* unmute HP mixer amp left and right (volume = 0) */
508 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
509 /* mute pin widget amp left and right (no gain on this amp) */
510 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
511 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
512 * Line In 2 = 0x03
513 */
514 /* mute analog inputs */
515 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
516 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
517 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
518 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
519 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
520 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
521 /* Unmute Front out path */
522 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
523 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
524 /* Unmute Headphone out path */
525 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
526 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
527 /* Unmute Mono out path */
528 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
529 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
530 { }
531};
532#endif
533
534static const struct hda_verb alc260_hp_3013_init_verbs[] = {
535 /* Line out and output */
536 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
537 /* mono output */
538 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
539 /* Mic1 (rear panel) pin widget for input and vref at 80% */
540 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
541 /* Mic2 (front panel) pin widget for input and vref at 80% */
542 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
543 /* Line In pin widget for input */
544 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
545 /* Headphone pin widget for output */
546 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
547 /* CD pin widget for input */
548 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
549 /* unmute amp left and right */
550 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
551 /* set connection select to line in (default select for this ADC) */
552 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
553 /* unmute Line-Out mixer amp left and right (volume = 0) */
554 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
555 /* mute pin widget amp left and right (no gain on this amp) */
556 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
557 /* unmute HP mixer amp left and right (volume = 0) */
558 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
559 /* mute pin widget amp left and right (no gain on this amp) */
560 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
561 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
562 * Line In 2 = 0x03
563 */
564 /* mute analog inputs */
565 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
566 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
567 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
568 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
569 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
570 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
571 /* Unmute Front out path */
572 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
573 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
574 /* Unmute Headphone out path */
575 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
576 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
577 /* Unmute Mono out path */
578 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
579 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
580 { }
581};
582
583/* Initialisation sequence for ALC260 as configured in Fujitsu S702x 339/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
584 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD 340 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
585 * audio = 0x16, internal speaker = 0x10. 341 * audio = 0x16, internal speaker = 0x10.
@@ -1093,9 +849,6 @@ static const struct hda_verb alc260_test_init_verbs[] = {
1093 */ 849 */
1094static const char * const alc260_models[ALC260_MODEL_LAST] = { 850static const char * const alc260_models[ALC260_MODEL_LAST] = {
1095 [ALC260_BASIC] = "basic", 851 [ALC260_BASIC] = "basic",
1096 [ALC260_HP] = "hp",
1097 [ALC260_HP_3013] = "hp-3013",
1098 [ALC260_HP_DC7600] = "hp-dc7600",
1099 [ALC260_FUJITSU_S702X] = "fujitsu", 852 [ALC260_FUJITSU_S702X] = "fujitsu",
1100 [ALC260_ACER] = "acer", 853 [ALC260_ACER] = "acer",
1101 [ALC260_WILL] = "will", 854 [ALC260_WILL] = "will",
@@ -1112,15 +865,6 @@ static const struct snd_pci_quirk alc260_cfg_tbl[] = {
1112 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL), 865 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
1113 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER), 866 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
1114 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100), 867 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
1115 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
1116 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
1117 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
1118 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
1119 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
1120 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
1121 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
1122 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
1123 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
1124 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC), 868 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
1125 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC), 869 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
1126 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC), 870 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
@@ -1144,54 +888,6 @@ static const struct alc_config_preset alc260_presets[] = {
1144 .channel_mode = alc260_modes, 888 .channel_mode = alc260_modes,
1145 .input_mux = &alc260_capture_source, 889 .input_mux = &alc260_capture_source,
1146 }, 890 },
1147 [ALC260_HP] = {
1148 .mixers = { alc260_hp_output_mixer,
1149 alc260_input_mixer },
1150 .init_verbs = { alc260_init_verbs,
1151 alc260_hp_unsol_verbs },
1152 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
1153 .dac_nids = alc260_dac_nids,
1154 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
1155 .adc_nids = alc260_adc_nids_alt,
1156 .num_channel_mode = ARRAY_SIZE(alc260_modes),
1157 .channel_mode = alc260_modes,
1158 .input_mux = &alc260_capture_source,
1159 .unsol_event = alc_sku_unsol_event,
1160 .setup = alc260_hp_setup,
1161 .init_hook = alc_inithook,
1162 },
1163 [ALC260_HP_DC7600] = {
1164 .mixers = { alc260_hp_dc7600_mixer,
1165 alc260_input_mixer },
1166 .init_verbs = { alc260_init_verbs,
1167 alc260_hp_dc7600_verbs },
1168 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
1169 .dac_nids = alc260_dac_nids,
1170 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
1171 .adc_nids = alc260_adc_nids_alt,
1172 .num_channel_mode = ARRAY_SIZE(alc260_modes),
1173 .channel_mode = alc260_modes,
1174 .input_mux = &alc260_capture_source,
1175 .unsol_event = alc_sku_unsol_event,
1176 .setup = alc260_hp_3012_setup,
1177 .init_hook = alc_inithook,
1178 },
1179 [ALC260_HP_3013] = {
1180 .mixers = { alc260_hp_3013_mixer,
1181 alc260_input_mixer },
1182 .init_verbs = { alc260_hp_3013_init_verbs,
1183 alc260_hp_3013_unsol_verbs },
1184 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
1185 .dac_nids = alc260_dac_nids,
1186 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
1187 .adc_nids = alc260_adc_nids_alt,
1188 .num_channel_mode = ARRAY_SIZE(alc260_modes),
1189 .channel_mode = alc260_modes,
1190 .input_mux = &alc260_capture_source,
1191 .unsol_event = alc_sku_unsol_event,
1192 .setup = alc260_hp_3013_setup,
1193 .init_hook = alc_inithook,
1194 },
1195 [ALC260_FUJITSU_S702X] = { 891 [ALC260_FUJITSU_S702X] = {
1196 .mixers = { alc260_fujitsu_mixer }, 892 .mixers = { alc260_fujitsu_mixer },
1197 .init_verbs = { alc260_fujitsu_init_verbs }, 893 .init_verbs = { alc260_fujitsu_init_verbs },
diff --git a/sound/pci/hda/alc262_quirks.c b/sound/pci/hda/alc262_quirks.c
index 8d2097d7764..7894b2b5aac 100644
--- a/sound/pci/hda/alc262_quirks.c
+++ b/sound/pci/hda/alc262_quirks.c
@@ -10,13 +10,7 @@ enum {
10 ALC262_HIPPO, 10 ALC262_HIPPO,
11 ALC262_HIPPO_1, 11 ALC262_HIPPO_1,
12 ALC262_FUJITSU, 12 ALC262_FUJITSU,
13 ALC262_HP_BPC,
14 ALC262_HP_BPC_D7000_WL,
15 ALC262_HP_BPC_D7000_WF,
16 ALC262_HP_TC_T5735,
17 ALC262_HP_RP5700,
18 ALC262_BENQ_ED8, 13 ALC262_BENQ_ED8,
19 ALC262_SONY_ASSAMD,
20 ALC262_BENQ_T31, 14 ALC262_BENQ_T31,
21 ALC262_ULTRA, 15 ALC262_ULTRA,
22 ALC262_LENOVO_3000, 16 ALC262_LENOVO_3000,
@@ -66,164 +60,31 @@ static const struct snd_kcontrol_new alc262_base_mixer[] = {
66 { } /* end */ 60 { } /* end */
67}; 61};
68 62
69/* update HP, line and mono-out pins according to the master switch */ 63/* bind hp and internal speaker mute (with plug check) as master switch */
70#define alc262_hp_master_update alc260_hp_master_update
71 64
72static void alc262_hp_bpc_setup(struct hda_codec *codec) 65static int alc262_hippo_master_sw_get(struct snd_kcontrol *kcontrol,
66 struct snd_ctl_elem_value *ucontrol)
73{ 67{
68 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
74 struct alc_spec *spec = codec->spec; 69 struct alc_spec *spec = codec->spec;
75 70 *ucontrol->value.integer.value = !spec->master_mute;
76 spec->autocfg.hp_pins[0] = 0x1b; 71 return 0;
77 spec->autocfg.speaker_pins[0] = 0x16;
78 spec->automute = 1;
79 spec->automute_mode = ALC_AUTOMUTE_PIN;
80} 72}
81 73
82static void alc262_hp_wildwest_setup(struct hda_codec *codec) 74static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
83{ 75 struct snd_ctl_elem_value *ucontrol)
84 struct alc_spec *spec = codec->spec;
85
86 spec->autocfg.hp_pins[0] = 0x15;
87 spec->autocfg.speaker_pins[0] = 0x16;
88 spec->automute = 1;
89 spec->automute_mode = ALC_AUTOMUTE_PIN;
90}
91
92#define alc262_hp_master_sw_get alc260_hp_master_sw_get
93#define alc262_hp_master_sw_put alc260_hp_master_sw_put
94
95#define ALC262_HP_MASTER_SWITCH \
96 { \
97 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
98 .name = "Master Playback Switch", \
99 .info = snd_ctl_boolean_mono_info, \
100 .get = alc262_hp_master_sw_get, \
101 .put = alc262_hp_master_sw_put, \
102 }, \
103 { \
104 .iface = NID_MAPPING, \
105 .name = "Master Playback Switch", \
106 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
107 }
108
109
110static const struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
111 ALC262_HP_MASTER_SWITCH,
112 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
113 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
114 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
115 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
116 HDA_OUTPUT),
117 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
118 HDA_OUTPUT),
119 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
120 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
121 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
122 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
123 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
124 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
125 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
126 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
127 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
128 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
129 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
130 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
131 { } /* end */
132};
133
134static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
135 ALC262_HP_MASTER_SWITCH,
136 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
137 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
138 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
139 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
140 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
141 HDA_OUTPUT),
142 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
143 HDA_OUTPUT),
144 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
145 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
146 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT),
147 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
148 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
149 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
150 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
151 { } /* end */
152};
153
154static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
155 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
156 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
157 HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT),
158 { } /* end */
159};
160
161/* mute/unmute internal speaker according to the hp jack and mute state */
162static void alc262_hp_t5735_setup(struct hda_codec *codec)
163{ 76{
77 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
164 struct alc_spec *spec = codec->spec; 78 struct alc_spec *spec = codec->spec;
79 int val = !*ucontrol->value.integer.value;
165 80
166 spec->autocfg.hp_pins[0] = 0x15; 81 if (val == spec->master_mute)
167 spec->autocfg.speaker_pins[0] = 0x14; 82 return 0;
168 spec->automute = 1; 83 spec->master_mute = val;
169 spec->automute_mode = ALC_AUTOMUTE_PIN; 84 update_outputs(codec);
85 return 1;
170} 86}
171 87
172static const struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
173 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
174 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
175 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
176 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
177 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
178 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
179 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
180 { } /* end */
181};
182
183static const struct hda_verb alc262_hp_t5735_verbs[] = {
184 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
185 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
186
187 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
188 { }
189};
190
191static const struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
192 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
193 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
194 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
195 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
196 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
197 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
198 { } /* end */
199};
200
201static const struct hda_verb alc262_hp_rp5700_verbs[] = {
202 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
203 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
204 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
205 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
206 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
207 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
208 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
209 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
210 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
211 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
212 {}
213};
214
215static const struct hda_input_mux alc262_hp_rp5700_capture_source = {
216 .num_items = 1,
217 .items = {
218 { "Line", 0x1 },
219 },
220};
221
222/* bind hp and internal speaker mute (with plug check) as master switch */
223#define alc262_hippo_master_update alc262_hp_master_update
224#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
225#define alc262_hippo_master_sw_put alc262_hp_master_sw_put
226
227#define ALC262_HIPPO_MASTER_SWITCH \ 88#define ALC262_HIPPO_MASTER_SWITCH \
228 { \ 89 { \
229 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 90 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
@@ -239,6 +100,9 @@ static const struct hda_input_mux alc262_hp_rp5700_capture_source = {
239 (SUBDEV_SPEAKER(0) << 16), \ 100 (SUBDEV_SPEAKER(0) << 16), \
240 } 101 }
241 102
103#define alc262_hp_master_sw_get alc262_hippo_master_sw_get
104#define alc262_hp_master_sw_put alc262_hippo_master_sw_put
105
242static const struct snd_kcontrol_new alc262_hippo_mixer[] = { 106static const struct snd_kcontrol_new alc262_hippo_mixer[] = {
243 ALC262_HIPPO_MASTER_SWITCH, 107 ALC262_HIPPO_MASTER_SWITCH,
244 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 108 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
@@ -279,8 +143,7 @@ static void alc262_hippo_setup(struct hda_codec *codec)
279 143
280 spec->autocfg.hp_pins[0] = 0x15; 144 spec->autocfg.hp_pins[0] = 0x15;
281 spec->autocfg.speaker_pins[0] = 0x14; 145 spec->autocfg.speaker_pins[0] = 0x14;
282 spec->automute = 1; 146 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
283 spec->automute_mode = ALC_AUTOMUTE_AMP;
284} 147}
285 148
286static void alc262_hippo1_setup(struct hda_codec *codec) 149static void alc262_hippo1_setup(struct hda_codec *codec)
@@ -289,8 +152,7 @@ static void alc262_hippo1_setup(struct hda_codec *codec)
289 152
290 spec->autocfg.hp_pins[0] = 0x1b; 153 spec->autocfg.hp_pins[0] = 0x1b;
291 spec->autocfg.speaker_pins[0] = 0x14; 154 spec->autocfg.speaker_pins[0] = 0x14;
292 spec->automute = 1; 155 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
293 spec->automute_mode = ALC_AUTOMUTE_AMP;
294} 156}
295 157
296 158
@@ -353,8 +215,7 @@ static void alc262_tyan_setup(struct hda_codec *codec)
353 215
354 spec->autocfg.hp_pins[0] = 0x1b; 216 spec->autocfg.hp_pins[0] = 0x1b;
355 spec->autocfg.speaker_pins[0] = 0x15; 217 spec->autocfg.speaker_pins[0] = 0x15;
356 spec->automute = 1; 218 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
357 spec->automute_mode = ALC_AUTOMUTE_AMP;
358} 219}
359 220
360 221
@@ -496,8 +357,7 @@ static void alc262_toshiba_s06_setup(struct hda_codec *codec)
496 spec->ext_mic_pin = 0x18; 357 spec->ext_mic_pin = 0x18;
497 spec->int_mic_pin = 0x12; 358 spec->int_mic_pin = 0x12;
498 spec->auto_mic = 1; 359 spec->auto_mic = 1;
499 spec->automute = 1; 360 alc_simple_setup_automute(spec, ALC_AUTOMUTE_PIN);
500 spec->automute_mode = ALC_AUTOMUTE_PIN;
501} 361}
502 362
503/* 363/*
@@ -571,27 +431,6 @@ static const struct hda_input_mux alc262_fujitsu_capture_source = {
571 }, 431 },
572}; 432};
573 433
574static const struct hda_input_mux alc262_HP_capture_source = {
575 .num_items = 5,
576 .items = {
577 { "Mic", 0x0 },
578 { "Front Mic", 0x1 },
579 { "Line", 0x2 },
580 { "CD", 0x4 },
581 { "AUX IN", 0x6 },
582 },
583};
584
585static const struct hda_input_mux alc262_HP_D7000_capture_source = {
586 .num_items = 4,
587 .items = {
588 { "Mic", 0x0 },
589 { "Front Mic", 0x2 },
590 { "Line", 0x1 },
591 { "CD", 0x4 },
592 },
593};
594
595static void alc262_fujitsu_setup(struct hda_codec *codec) 434static void alc262_fujitsu_setup(struct hda_codec *codec)
596{ 435{
597 struct alc_spec *spec = codec->spec; 436 struct alc_spec *spec = codec->spec;
@@ -599,8 +438,7 @@ static void alc262_fujitsu_setup(struct hda_codec *codec)
599 spec->autocfg.hp_pins[0] = 0x14; 438 spec->autocfg.hp_pins[0] = 0x14;
600 spec->autocfg.hp_pins[1] = 0x1b; 439 spec->autocfg.hp_pins[1] = 0x1b;
601 spec->autocfg.speaker_pins[0] = 0x15; 440 spec->autocfg.speaker_pins[0] = 0x15;
602 spec->automute = 1; 441 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
603 spec->automute_mode = ALC_AUTOMUTE_AMP;
604} 442}
605 443
606/* bind volumes of both NID 0x0c and 0x0d */ 444/* bind volumes of both NID 0x0c and 0x0d */
@@ -646,8 +484,7 @@ static void alc262_lenovo_3000_setup(struct hda_codec *codec)
646 spec->autocfg.hp_pins[0] = 0x1b; 484 spec->autocfg.hp_pins[0] = 0x1b;
647 spec->autocfg.speaker_pins[0] = 0x14; 485 spec->autocfg.speaker_pins[0] = 0x14;
648 spec->autocfg.speaker_pins[1] = 0x16; 486 spec->autocfg.speaker_pins[1] = 0x16;
649 spec->automute = 1; 487 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
650 spec->automute_mode = ALC_AUTOMUTE_AMP;
651} 488}
652 489
653static const struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = { 490static const struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
@@ -752,8 +589,8 @@ static void alc262_ultra_automute(struct hda_codec *codec)
752 mute = 0; 589 mute = 0;
753 /* auto-mute only when HP is used as HP */ 590 /* auto-mute only when HP is used as HP */
754 if (!spec->cur_mux[0]) { 591 if (!spec->cur_mux[0]) {
755 spec->jack_present = snd_hda_jack_detect(codec, 0x15); 592 spec->hp_jack_present = snd_hda_jack_detect(codec, 0x15);
756 if (spec->jack_present) 593 if (spec->hp_jack_present)
757 mute = HDA_AMP_MUTE; 594 mute = HDA_AMP_MUTE;
758 } 595 }
759 /* mute/unmute internal speaker */ 596 /* mute/unmute internal speaker */
@@ -817,206 +654,6 @@ static const struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
817 { } /* end */ 654 { } /* end */
818}; 655};
819 656
820static const struct hda_verb alc262_HP_BPC_init_verbs[] = {
821 /*
822 * Unmute ADC0-2 and set the default input to mic-in
823 */
824 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
825 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
826 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
827 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
828 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
829 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
830
831 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
832 * mixer widget
833 * Note: PASD motherboards uses the Line In 2 as the input for
834 * front panel mic (mic 2)
835 */
836 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
837 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
838 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
839 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
840 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
841 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
842 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
843 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
844
845 /*
846 * Set up output mixers (0x0c - 0x0e)
847 */
848 /* set vol=0 to output mixers */
849 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
850 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
851 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
852
853 /* set up input amps for analog loopback */
854 /* Amp Indices: DAC = 0, mixer = 1 */
855 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
856 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
857 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
858 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
859 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
860 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
861
862 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
863 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
864 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
865
866 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
867 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
868
869 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
870 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
871
872 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
873 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
874 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
875 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
876 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
877
878 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
879 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
880 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
881 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
882 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
883 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
884
885
886 /* FIXME: use matrix-type input source selection */
887 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
888 /* Input mixer1: only unmute Mic */
889 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
890 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
891 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
892 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
893 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
894 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
895 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
896 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
897 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
898 /* Input mixer2 */
899 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
900 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
901 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
902 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
903 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
904 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
905 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
906 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
907 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
908 /* Input mixer3 */
909 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
910 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
911 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
912 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
913 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
914 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
915 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
916 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
917 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
918
919 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
920
921 { }
922};
923
924static const struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
925 /*
926 * Unmute ADC0-2 and set the default input to mic-in
927 */
928 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
929 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
930 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
931 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
932 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
933 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
934
935 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
936 * mixer widget
937 * Note: PASD motherboards uses the Line In 2 as the input for front
938 * panel mic (mic 2)
939 */
940 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
941 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
942 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
943 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
944 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
945 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
946 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
947 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
948 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
949 /*
950 * Set up output mixers (0x0c - 0x0e)
951 */
952 /* set vol=0 to output mixers */
953 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
954 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
955 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
956
957 /* set up input amps for analog loopback */
958 /* Amp Indices: DAC = 0, mixer = 1 */
959 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
960 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
961 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
962 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
963 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
964 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
965
966
967 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
968 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
969 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
970 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
971 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
972 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
973 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
974
975 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
976 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
977
978 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
979 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
980
981 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
982 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
983 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
984 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
985 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
986 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
987
988 /* FIXME: use matrix-type input source selection */
989 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
990 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
991 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
992 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
993 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
994 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
995 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
996 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
997 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
998 /* Input mixer2 */
999 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1000 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1001 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
1002 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
1003 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
1004 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
1005 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
1006 /* Input mixer3 */
1007 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1008 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1009 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
1010 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
1011 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
1012 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
1013 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
1014
1015 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
1016
1017 { }
1018};
1019
1020static const struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = { 657static const struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
1021 658
1022 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */ 659 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
@@ -1042,13 +679,8 @@ static const char * const alc262_models[ALC262_MODEL_LAST] = {
1042 [ALC262_HIPPO] = "hippo", 679 [ALC262_HIPPO] = "hippo",
1043 [ALC262_HIPPO_1] = "hippo_1", 680 [ALC262_HIPPO_1] = "hippo_1",
1044 [ALC262_FUJITSU] = "fujitsu", 681 [ALC262_FUJITSU] = "fujitsu",
1045 [ALC262_HP_BPC] = "hp-bpc",
1046 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
1047 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
1048 [ALC262_HP_RP5700] = "hp-rp5700",
1049 [ALC262_BENQ_ED8] = "benq", 682 [ALC262_BENQ_ED8] = "benq",
1050 [ALC262_BENQ_T31] = "benq-t31", 683 [ALC262_BENQ_T31] = "benq-t31",
1051 [ALC262_SONY_ASSAMD] = "sony-assamd",
1052 [ALC262_TOSHIBA_S06] = "toshiba-s06", 684 [ALC262_TOSHIBA_S06] = "toshiba-s06",
1053 [ALC262_TOSHIBA_RX1] = "toshiba-rx1", 685 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
1054 [ALC262_ULTRA] = "ultra", 686 [ALC262_ULTRA] = "ultra",
@@ -1061,41 +693,6 @@ static const char * const alc262_models[ALC262_MODEL_LAST] = {
1061static const struct snd_pci_quirk alc262_cfg_tbl[] = { 693static const struct snd_pci_quirk alc262_cfg_tbl[] = {
1062 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO), 694 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
1063 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC), 695 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
1064 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
1065 ALC262_HP_BPC),
1066 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
1067 ALC262_HP_BPC),
1068 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1500, "HP z series",
1069 ALC262_HP_BPC),
1070 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200",
1071 ALC262_AUTO),
1072 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
1073 ALC262_HP_BPC),
1074 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
1075 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
1076 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
1077 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
1078 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
1079 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
1080 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
1081 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
1082 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
1083 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
1084 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
1085 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
1086 ALC262_HP_TC_T5735),
1087 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
1088 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
1089 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
1090 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
1091 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
1092 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
1093 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
1094 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
1095#if 0 /* disable the quirk since model=auto works better in recent versions */
1096 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
1097 ALC262_SONY_ASSAMD),
1098#endif
1099 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1", 696 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
1100 ALC262_TOSHIBA_RX1), 697 ALC262_TOSHIBA_RX1),
1101 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06), 698 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
@@ -1166,68 +763,6 @@ static const struct alc_config_preset alc262_presets[] = {
1166 .setup = alc262_fujitsu_setup, 763 .setup = alc262_fujitsu_setup,
1167 .init_hook = alc_inithook, 764 .init_hook = alc_inithook,
1168 }, 765 },
1169 [ALC262_HP_BPC] = {
1170 .mixers = { alc262_HP_BPC_mixer },
1171 .init_verbs = { alc262_HP_BPC_init_verbs },
1172 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1173 .dac_nids = alc262_dac_nids,
1174 .hp_nid = 0x03,
1175 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1176 .channel_mode = alc262_modes,
1177 .input_mux = &alc262_HP_capture_source,
1178 .unsol_event = alc_sku_unsol_event,
1179 .setup = alc262_hp_bpc_setup,
1180 .init_hook = alc_inithook,
1181 },
1182 [ALC262_HP_BPC_D7000_WF] = {
1183 .mixers = { alc262_HP_BPC_WildWest_mixer },
1184 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
1185 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1186 .dac_nids = alc262_dac_nids,
1187 .hp_nid = 0x03,
1188 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1189 .channel_mode = alc262_modes,
1190 .input_mux = &alc262_HP_D7000_capture_source,
1191 .unsol_event = alc_sku_unsol_event,
1192 .setup = alc262_hp_wildwest_setup,
1193 .init_hook = alc_inithook,
1194 },
1195 [ALC262_HP_BPC_D7000_WL] = {
1196 .mixers = { alc262_HP_BPC_WildWest_mixer,
1197 alc262_HP_BPC_WildWest_option_mixer },
1198 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
1199 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1200 .dac_nids = alc262_dac_nids,
1201 .hp_nid = 0x03,
1202 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1203 .channel_mode = alc262_modes,
1204 .input_mux = &alc262_HP_D7000_capture_source,
1205 .unsol_event = alc_sku_unsol_event,
1206 .setup = alc262_hp_wildwest_setup,
1207 .init_hook = alc_inithook,
1208 },
1209 [ALC262_HP_TC_T5735] = {
1210 .mixers = { alc262_hp_t5735_mixer },
1211 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
1212 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1213 .dac_nids = alc262_dac_nids,
1214 .hp_nid = 0x03,
1215 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1216 .channel_mode = alc262_modes,
1217 .input_mux = &alc262_capture_source,
1218 .unsol_event = alc_sku_unsol_event,
1219 .setup = alc262_hp_t5735_setup,
1220 .init_hook = alc_inithook,
1221 },
1222 [ALC262_HP_RP5700] = {
1223 .mixers = { alc262_hp_rp5700_mixer },
1224 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
1225 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1226 .dac_nids = alc262_dac_nids,
1227 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1228 .channel_mode = alc262_modes,
1229 .input_mux = &alc262_hp_rp5700_capture_source,
1230 },
1231 [ALC262_BENQ_ED8] = { 766 [ALC262_BENQ_ED8] = {
1232 .mixers = { alc262_base_mixer }, 767 .mixers = { alc262_base_mixer },
1233 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs }, 768 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
@@ -1238,19 +773,6 @@ static const struct alc_config_preset alc262_presets[] = {
1238 .channel_mode = alc262_modes, 773 .channel_mode = alc262_modes,
1239 .input_mux = &alc262_capture_source, 774 .input_mux = &alc262_capture_source,
1240 }, 775 },
1241 [ALC262_SONY_ASSAMD] = {
1242 .mixers = { alc262_sony_mixer },
1243 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
1244 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1245 .dac_nids = alc262_dac_nids,
1246 .hp_nid = 0x02,
1247 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1248 .channel_mode = alc262_modes,
1249 .input_mux = &alc262_capture_source,
1250 .unsol_event = alc_sku_unsol_event,
1251 .setup = alc262_hippo_setup,
1252 .init_hook = alc_inithook,
1253 },
1254 [ALC262_BENQ_T31] = { 776 [ALC262_BENQ_T31] = {
1255 .mixers = { alc262_benq_t31_mixer }, 777 .mixers = { alc262_benq_t31_mixer },
1256 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, 778 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
diff --git a/sound/pci/hda/alc268_quirks.c b/sound/pci/hda/alc268_quirks.c
deleted file mode 100644
index 2e5876ce71f..00000000000
--- a/sound/pci/hda/alc268_quirks.c
+++ /dev/null
@@ -1,636 +0,0 @@
1/*
2 * ALC267/ALC268 quirk models
3 * included by patch_realtek.c
4 */
5
6/* ALC268 models */
7enum {
8 ALC268_AUTO,
9 ALC267_QUANTA_IL1,
10 ALC268_3ST,
11 ALC268_TOSHIBA,
12 ALC268_ACER,
13 ALC268_ACER_DMIC,
14 ALC268_ACER_ASPIRE_ONE,
15 ALC268_DELL,
16 ALC268_ZEPTO,
17#ifdef CONFIG_SND_DEBUG
18 ALC268_TEST,
19#endif
20 ALC268_MODEL_LAST /* last tag */
21};
22
23/*
24 * ALC268 channel source setting (2 channel)
25 */
26#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
27#define alc268_modes alc260_modes
28
29static const hda_nid_t alc268_dac_nids[2] = {
30 /* front, hp */
31 0x02, 0x03
32};
33
34static const hda_nid_t alc268_adc_nids[2] = {
35 /* ADC0-1 */
36 0x08, 0x07
37};
38
39static const hda_nid_t alc268_adc_nids_alt[1] = {
40 /* ADC0 */
41 0x08
42};
43
44static const hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
45
46static const struct snd_kcontrol_new alc268_base_mixer[] = {
47 /* output mixer control */
48 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
49 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
50 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
51 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
52 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
53 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
54 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
55 { }
56};
57
58static const struct snd_kcontrol_new alc268_toshiba_mixer[] = {
59 /* output mixer control */
60 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
61 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
62 ALC262_HIPPO_MASTER_SWITCH,
63 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
64 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
65 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
66 { }
67};
68
69static const struct hda_verb alc268_eapd_verbs[] = {
70 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
71 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
72 { }
73};
74
75/* Toshiba specific */
76static const struct hda_verb alc268_toshiba_verbs[] = {
77 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
78 { } /* end */
79};
80
81/* Acer specific */
82/* bind volumes of both NID 0x02 and 0x03 */
83static const struct hda_bind_ctls alc268_acer_bind_master_vol = {
84 .ops = &snd_hda_bind_vol,
85 .values = {
86 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
87 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
88 0
89 },
90};
91
92static void alc268_acer_setup(struct hda_codec *codec)
93{
94 struct alc_spec *spec = codec->spec;
95
96 spec->autocfg.hp_pins[0] = 0x14;
97 spec->autocfg.speaker_pins[0] = 0x15;
98 spec->automute = 1;
99 spec->automute_mode = ALC_AUTOMUTE_AMP;
100}
101
102#define alc268_acer_master_sw_get alc262_hp_master_sw_get
103#define alc268_acer_master_sw_put alc262_hp_master_sw_put
104
105static const struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
106 /* output mixer control */
107 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
108 {
109 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
110 .name = "Master Playback Switch",
111 .subdevice = HDA_SUBDEV_NID_FLAG | 0x15,
112 .info = snd_ctl_boolean_mono_info,
113 .get = alc268_acer_master_sw_get,
114 .put = alc268_acer_master_sw_put,
115 },
116 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
117 { }
118};
119
120static const struct snd_kcontrol_new alc268_acer_mixer[] = {
121 /* output mixer control */
122 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
123 {
124 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
125 .name = "Master Playback Switch",
126 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
127 .info = snd_ctl_boolean_mono_info,
128 .get = alc268_acer_master_sw_get,
129 .put = alc268_acer_master_sw_put,
130 },
131 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
132 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
133 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
134 { }
135};
136
137static const struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
138 /* output mixer control */
139 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
140 {
141 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
142 .name = "Master Playback Switch",
143 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
144 .info = snd_ctl_boolean_mono_info,
145 .get = alc268_acer_master_sw_get,
146 .put = alc268_acer_master_sw_put,
147 },
148 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
149 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
150 { }
151};
152
153static const struct hda_verb alc268_acer_aspire_one_verbs[] = {
154 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
155 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
156 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
157 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
158 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
159 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
160 { }
161};
162
163static const struct hda_verb alc268_acer_verbs[] = {
164 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
165 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
166 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
167 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
168 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
169 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
170 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
171 { }
172};
173
174/* unsolicited event for HP jack sensing */
175#define alc268_toshiba_setup alc262_hippo_setup
176
177static void alc268_acer_lc_setup(struct hda_codec *codec)
178{
179 struct alc_spec *spec = codec->spec;
180 spec->autocfg.hp_pins[0] = 0x15;
181 spec->autocfg.speaker_pins[0] = 0x14;
182 spec->automute = 1;
183 spec->automute_mode = ALC_AUTOMUTE_AMP;
184 spec->ext_mic_pin = 0x18;
185 spec->int_mic_pin = 0x12;
186 spec->auto_mic = 1;
187}
188
189static const struct snd_kcontrol_new alc268_dell_mixer[] = {
190 /* output mixer control */
191 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
192 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
193 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
194 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
195 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
196 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
197 { }
198};
199
200static const struct hda_verb alc268_dell_verbs[] = {
201 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
202 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
203 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
204 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_MIC_EVENT | AC_USRSP_EN},
205 { }
206};
207
208/* mute/unmute internal speaker according to the hp jack and mute state */
209static void alc268_dell_setup(struct hda_codec *codec)
210{
211 struct alc_spec *spec = codec->spec;
212
213 spec->autocfg.hp_pins[0] = 0x15;
214 spec->autocfg.speaker_pins[0] = 0x14;
215 spec->ext_mic_pin = 0x18;
216 spec->int_mic_pin = 0x19;
217 spec->auto_mic = 1;
218 spec->automute = 1;
219 spec->automute_mode = ALC_AUTOMUTE_PIN;
220}
221
222static const struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
223 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
224 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
225 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
226 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
227 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
228 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
229 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
230 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
231 { }
232};
233
234static const struct hda_verb alc267_quanta_il1_verbs[] = {
235 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
236 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_MIC_EVENT | AC_USRSP_EN},
237 { }
238};
239
240static void alc267_quanta_il1_setup(struct hda_codec *codec)
241{
242 struct alc_spec *spec = codec->spec;
243 spec->autocfg.hp_pins[0] = 0x15;
244 spec->autocfg.speaker_pins[0] = 0x14;
245 spec->ext_mic_pin = 0x18;
246 spec->int_mic_pin = 0x19;
247 spec->auto_mic = 1;
248 spec->automute = 1;
249 spec->automute_mode = ALC_AUTOMUTE_PIN;
250}
251
252/*
253 * generic initialization of ADC, input mixers and output mixers
254 */
255static const struct hda_verb alc268_base_init_verbs[] = {
256 /* Unmute DAC0-1 and set vol = 0 */
257 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
258 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
259
260 /*
261 * Set up output mixers (0x0c - 0x0e)
262 */
263 /* set vol=0 to output mixers */
264 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
265 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
266
267 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
268 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
269
270 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
271 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
272 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
273 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
274 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
275 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
276 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
277 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
278
279 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
280 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
281 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
282 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
283 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
284
285 /* set PCBEEP vol = 0, mute connections */
286 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
287 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
288 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
289
290 /* Unmute Selector 23h,24h and set the default input to mic-in */
291
292 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
293 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
294 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
295 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
296
297 { }
298};
299
300/* only for model=test */
301#ifdef CONFIG_SND_DEBUG
302/*
303 * generic initialization of ADC, input mixers and output mixers
304 */
305static const struct hda_verb alc268_volume_init_verbs[] = {
306 /* set output DAC */
307 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
308 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
309
310 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
311 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
312 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
313 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
314 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
315
316 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
317 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
318 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
319
320 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
321 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
322 { }
323};
324#endif /* CONFIG_SND_DEBUG */
325
326static const struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
327 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
328 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
329 { } /* end */
330};
331
332static const struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
333 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
334 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
335 _DEFINE_CAPSRC(1),
336 { } /* end */
337};
338
339static const struct snd_kcontrol_new alc268_capture_mixer[] = {
340 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
341 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
342 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
343 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
344 _DEFINE_CAPSRC(2),
345 { } /* end */
346};
347
348static const struct hda_input_mux alc268_capture_source = {
349 .num_items = 4,
350 .items = {
351 { "Mic", 0x0 },
352 { "Front Mic", 0x1 },
353 { "Line", 0x2 },
354 { "CD", 0x3 },
355 },
356};
357
358static const struct hda_input_mux alc268_acer_capture_source = {
359 .num_items = 3,
360 .items = {
361 { "Mic", 0x0 },
362 { "Internal Mic", 0x1 },
363 { "Line", 0x2 },
364 },
365};
366
367static const struct hda_input_mux alc268_acer_dmic_capture_source = {
368 .num_items = 3,
369 .items = {
370 { "Mic", 0x0 },
371 { "Internal Mic", 0x6 },
372 { "Line", 0x2 },
373 },
374};
375
376#ifdef CONFIG_SND_DEBUG
377static const struct snd_kcontrol_new alc268_test_mixer[] = {
378 /* Volume widgets */
379 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
380 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
381 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
382 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
383 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
384 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
385 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
386 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
387 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
388 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
389 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
390 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
391 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
392 /* The below appears problematic on some hardwares */
393 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
394 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
395 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
396 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
397 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
398
399 /* Modes for retasking pin widgets */
400 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
401 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
402 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
403 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
404
405 /* Controls for GPIO pins, assuming they are configured as outputs */
406 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
407 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
408 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
409 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
410
411 /* Switches to allow the digital SPDIF output pin to be enabled.
412 * The ALC268 does not have an SPDIF input.
413 */
414 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
415
416 /* A switch allowing EAPD to be enabled. Some laptops seem to use
417 * this output to turn on an external amplifier.
418 */
419 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
420 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
421
422 { } /* end */
423};
424#endif
425
426/*
427 * configuration and preset
428 */
429static const char * const alc268_models[ALC268_MODEL_LAST] = {
430 [ALC267_QUANTA_IL1] = "quanta-il1",
431 [ALC268_3ST] = "3stack",
432 [ALC268_TOSHIBA] = "toshiba",
433 [ALC268_ACER] = "acer",
434 [ALC268_ACER_DMIC] = "acer-dmic",
435 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
436 [ALC268_DELL] = "dell",
437 [ALC268_ZEPTO] = "zepto",
438#ifdef CONFIG_SND_DEBUG
439 [ALC268_TEST] = "test",
440#endif
441 [ALC268_AUTO] = "auto",
442};
443
444static const struct snd_pci_quirk alc268_cfg_tbl[] = {
445 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
446 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
447 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
448 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
449 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
450 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
451 ALC268_ACER_ASPIRE_ONE),
452 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
453 SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron 910", ALC268_AUTO),
454 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
455 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
456 /* almost compatible with toshiba but with optional digital outs;
457 * auto-probing seems working fine
458 */
459 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
460 ALC268_AUTO),
461 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
462 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
463 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
464 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
465 {}
466};
467
468/* Toshiba laptops have no unique PCI SSID but only codec SSID */
469static const struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
470 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
471 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
472 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
473 ALC268_TOSHIBA),
474 {}
475};
476
477static const struct alc_config_preset alc268_presets[] = {
478 [ALC267_QUANTA_IL1] = {
479 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer },
480 .cap_mixer = alc268_capture_nosrc_mixer,
481 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
482 alc267_quanta_il1_verbs },
483 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
484 .dac_nids = alc268_dac_nids,
485 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
486 .adc_nids = alc268_adc_nids_alt,
487 .hp_nid = 0x03,
488 .num_channel_mode = ARRAY_SIZE(alc268_modes),
489 .channel_mode = alc268_modes,
490 .unsol_event = alc_sku_unsol_event,
491 .setup = alc267_quanta_il1_setup,
492 .init_hook = alc_inithook,
493 },
494 [ALC268_3ST] = {
495 .mixers = { alc268_base_mixer, alc268_beep_mixer },
496 .cap_mixer = alc268_capture_alt_mixer,
497 .init_verbs = { alc268_base_init_verbs },
498 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
499 .dac_nids = alc268_dac_nids,
500 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
501 .adc_nids = alc268_adc_nids_alt,
502 .capsrc_nids = alc268_capsrc_nids,
503 .hp_nid = 0x03,
504 .dig_out_nid = ALC268_DIGOUT_NID,
505 .num_channel_mode = ARRAY_SIZE(alc268_modes),
506 .channel_mode = alc268_modes,
507 .input_mux = &alc268_capture_source,
508 },
509 [ALC268_TOSHIBA] = {
510 .mixers = { alc268_toshiba_mixer, alc268_beep_mixer },
511 .cap_mixer = alc268_capture_alt_mixer,
512 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
513 alc268_toshiba_verbs },
514 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
515 .dac_nids = alc268_dac_nids,
516 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
517 .adc_nids = alc268_adc_nids_alt,
518 .capsrc_nids = alc268_capsrc_nids,
519 .hp_nid = 0x03,
520 .num_channel_mode = ARRAY_SIZE(alc268_modes),
521 .channel_mode = alc268_modes,
522 .input_mux = &alc268_capture_source,
523 .unsol_event = alc_sku_unsol_event,
524 .setup = alc268_toshiba_setup,
525 .init_hook = alc_inithook,
526 },
527 [ALC268_ACER] = {
528 .mixers = { alc268_acer_mixer, alc268_beep_mixer },
529 .cap_mixer = alc268_capture_alt_mixer,
530 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
531 alc268_acer_verbs },
532 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
533 .dac_nids = alc268_dac_nids,
534 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
535 .adc_nids = alc268_adc_nids_alt,
536 .capsrc_nids = alc268_capsrc_nids,
537 .hp_nid = 0x02,
538 .num_channel_mode = ARRAY_SIZE(alc268_modes),
539 .channel_mode = alc268_modes,
540 .input_mux = &alc268_acer_capture_source,
541 .unsol_event = alc_sku_unsol_event,
542 .setup = alc268_acer_setup,
543 .init_hook = alc_inithook,
544 },
545 [ALC268_ACER_DMIC] = {
546 .mixers = { alc268_acer_dmic_mixer, alc268_beep_mixer },
547 .cap_mixer = alc268_capture_alt_mixer,
548 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
549 alc268_acer_verbs },
550 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
551 .dac_nids = alc268_dac_nids,
552 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
553 .adc_nids = alc268_adc_nids_alt,
554 .capsrc_nids = alc268_capsrc_nids,
555 .hp_nid = 0x02,
556 .num_channel_mode = ARRAY_SIZE(alc268_modes),
557 .channel_mode = alc268_modes,
558 .input_mux = &alc268_acer_dmic_capture_source,
559 .unsol_event = alc_sku_unsol_event,
560 .setup = alc268_acer_setup,
561 .init_hook = alc_inithook,
562 },
563 [ALC268_ACER_ASPIRE_ONE] = {
564 .mixers = { alc268_acer_aspire_one_mixer, alc268_beep_mixer},
565 .cap_mixer = alc268_capture_nosrc_mixer,
566 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
567 alc268_acer_aspire_one_verbs },
568 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
569 .dac_nids = alc268_dac_nids,
570 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
571 .adc_nids = alc268_adc_nids_alt,
572 .capsrc_nids = alc268_capsrc_nids,
573 .hp_nid = 0x03,
574 .num_channel_mode = ARRAY_SIZE(alc268_modes),
575 .channel_mode = alc268_modes,
576 .unsol_event = alc_sku_unsol_event,
577 .setup = alc268_acer_lc_setup,
578 .init_hook = alc_inithook,
579 },
580 [ALC268_DELL] = {
581 .mixers = { alc268_dell_mixer, alc268_beep_mixer},
582 .cap_mixer = alc268_capture_nosrc_mixer,
583 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
584 alc268_dell_verbs },
585 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
586 .dac_nids = alc268_dac_nids,
587 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
588 .adc_nids = alc268_adc_nids_alt,
589 .capsrc_nids = alc268_capsrc_nids,
590 .hp_nid = 0x02,
591 .num_channel_mode = ARRAY_SIZE(alc268_modes),
592 .channel_mode = alc268_modes,
593 .unsol_event = alc_sku_unsol_event,
594 .setup = alc268_dell_setup,
595 .init_hook = alc_inithook,
596 },
597 [ALC268_ZEPTO] = {
598 .mixers = { alc268_base_mixer, alc268_beep_mixer },
599 .cap_mixer = alc268_capture_alt_mixer,
600 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
601 alc268_toshiba_verbs },
602 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
603 .dac_nids = alc268_dac_nids,
604 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
605 .adc_nids = alc268_adc_nids_alt,
606 .capsrc_nids = alc268_capsrc_nids,
607 .hp_nid = 0x03,
608 .dig_out_nid = ALC268_DIGOUT_NID,
609 .num_channel_mode = ARRAY_SIZE(alc268_modes),
610 .channel_mode = alc268_modes,
611 .input_mux = &alc268_capture_source,
612 .unsol_event = alc_sku_unsol_event,
613 .setup = alc268_toshiba_setup,
614 .init_hook = alc_inithook,
615 },
616#ifdef CONFIG_SND_DEBUG
617 [ALC268_TEST] = {
618 .mixers = { alc268_test_mixer },
619 .cap_mixer = alc268_capture_mixer,
620 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
621 alc268_volume_init_verbs,
622 alc268_beep_init_verbs },
623 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
624 .dac_nids = alc268_dac_nids,
625 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
626 .adc_nids = alc268_adc_nids_alt,
627 .capsrc_nids = alc268_capsrc_nids,
628 .hp_nid = 0x03,
629 .dig_out_nid = ALC268_DIGOUT_NID,
630 .num_channel_mode = ARRAY_SIZE(alc268_modes),
631 .channel_mode = alc268_modes,
632 .input_mux = &alc268_capture_source,
633 },
634#endif
635};
636
diff --git a/sound/pci/hda/alc269_quirks.c b/sound/pci/hda/alc269_quirks.c
deleted file mode 100644
index 5ac0e2162a4..00000000000
--- a/sound/pci/hda/alc269_quirks.c
+++ /dev/null
@@ -1,674 +0,0 @@
1/*
2 * ALC269/ALC270/ALC275/ALC276 quirk models
3 * included by patch_realtek.c
4 */
5
6/* ALC269 models */
7enum {
8 ALC269_AUTO,
9 ALC269_BASIC,
10 ALC269_QUANTA_FL1,
11 ALC269_AMIC,
12 ALC269_DMIC,
13 ALC269VB_AMIC,
14 ALC269VB_DMIC,
15 ALC269_FUJITSU,
16 ALC269_LIFEBOOK,
17 ALC271_ACER,
18 ALC269_MODEL_LAST /* last tag */
19};
20
21/*
22 * ALC269 channel source setting (2 channel)
23 */
24#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
25
26#define alc269_dac_nids alc260_dac_nids
27
28static const hda_nid_t alc269_adc_nids[1] = {
29 /* ADC1 */
30 0x08,
31};
32
33static const hda_nid_t alc269_capsrc_nids[1] = {
34 0x23,
35};
36
37static const hda_nid_t alc269vb_adc_nids[1] = {
38 /* ADC1 */
39 0x09,
40};
41
42static const hda_nid_t alc269vb_capsrc_nids[1] = {
43 0x22,
44};
45
46#define alc269_modes alc260_modes
47#define alc269_capture_source alc880_lg_lw_capture_source
48
49static const struct snd_kcontrol_new alc269_base_mixer[] = {
50 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
51 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
52 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
53 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
54 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
55 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
56 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
57 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
58 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
59 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
60 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
61 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
62 { } /* end */
63};
64
65static const struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
66 /* output mixer control */
67 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
68 {
69 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
70 .name = "Master Playback Switch",
71 .subdevice = HDA_SUBDEV_AMP_FLAG,
72 .info = snd_hda_mixer_amp_switch_info,
73 .get = snd_hda_mixer_amp_switch_get,
74 .put = alc268_acer_master_sw_put,
75 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
76 },
77 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
78 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
79 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
80 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
81 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
82 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
83 { }
84};
85
86static const struct snd_kcontrol_new alc269_lifebook_mixer[] = {
87 /* output mixer control */
88 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
89 {
90 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
91 .name = "Master Playback Switch",
92 .subdevice = HDA_SUBDEV_AMP_FLAG,
93 .info = snd_hda_mixer_amp_switch_info,
94 .get = snd_hda_mixer_amp_switch_get,
95 .put = alc268_acer_master_sw_put,
96 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
97 },
98 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
99 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
100 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
101 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
102 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
103 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
104 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
105 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
106 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT),
107 { }
108};
109
110static const struct snd_kcontrol_new alc269_laptop_mixer[] = {
111 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
112 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
113 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
114 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
115 { } /* end */
116};
117
118static const struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
119 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
120 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
121 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
122 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
123 { } /* end */
124};
125
126static const struct snd_kcontrol_new alc269_asus_mixer[] = {
127 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
128 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
129 { } /* end */
130};
131
132/* capture mixer elements */
133static const struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
134 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
135 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
136 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
137 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
138 { } /* end */
139};
140
141static const struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
142 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
143 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
144 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
145 { } /* end */
146};
147
148static const struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
149 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
150 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
151 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
152 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
153 { } /* end */
154};
155
156static const struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
157 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
158 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
159 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
160 { } /* end */
161};
162
163/* FSC amilo */
164#define alc269_fujitsu_mixer alc269_laptop_mixer
165
166static const struct hda_verb alc269_quanta_fl1_verbs[] = {
167 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
168 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
169 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
170 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
171 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
172 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
173 { }
174};
175
176static const struct hda_verb alc269_lifebook_verbs[] = {
177 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
178 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
179 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
180 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
181 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
182 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
183 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
184 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
185 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
186 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
187 { }
188};
189
190/* toggle speaker-output according to the hp-jack state */
191static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
192{
193 alc_hp_automute(codec);
194
195 snd_hda_codec_write(codec, 0x20, 0,
196 AC_VERB_SET_COEF_INDEX, 0x0c);
197 snd_hda_codec_write(codec, 0x20, 0,
198 AC_VERB_SET_PROC_COEF, 0x680);
199
200 snd_hda_codec_write(codec, 0x20, 0,
201 AC_VERB_SET_COEF_INDEX, 0x0c);
202 snd_hda_codec_write(codec, 0x20, 0,
203 AC_VERB_SET_PROC_COEF, 0x480);
204}
205
206#define alc269_lifebook_speaker_automute \
207 alc269_quanta_fl1_speaker_automute
208
209static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
210{
211 unsigned int present_laptop;
212 unsigned int present_dock;
213
214 present_laptop = snd_hda_jack_detect(codec, 0x18);
215 present_dock = snd_hda_jack_detect(codec, 0x1b);
216
217 /* Laptop mic port overrides dock mic port, design decision */
218 if (present_dock)
219 snd_hda_codec_write(codec, 0x23, 0,
220 AC_VERB_SET_CONNECT_SEL, 0x3);
221 if (present_laptop)
222 snd_hda_codec_write(codec, 0x23, 0,
223 AC_VERB_SET_CONNECT_SEL, 0x0);
224 if (!present_dock && !present_laptop)
225 snd_hda_codec_write(codec, 0x23, 0,
226 AC_VERB_SET_CONNECT_SEL, 0x1);
227}
228
229static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
230 unsigned int res)
231{
232 switch (res >> 26) {
233 case ALC_HP_EVENT:
234 alc269_quanta_fl1_speaker_automute(codec);
235 break;
236 case ALC_MIC_EVENT:
237 alc_mic_automute(codec);
238 break;
239 }
240}
241
242static void alc269_lifebook_unsol_event(struct hda_codec *codec,
243 unsigned int res)
244{
245 if ((res >> 26) == ALC_HP_EVENT)
246 alc269_lifebook_speaker_automute(codec);
247 if ((res >> 26) == ALC_MIC_EVENT)
248 alc269_lifebook_mic_autoswitch(codec);
249}
250
251static void alc269_quanta_fl1_setup(struct hda_codec *codec)
252{
253 struct alc_spec *spec = codec->spec;
254 spec->autocfg.hp_pins[0] = 0x15;
255 spec->autocfg.speaker_pins[0] = 0x14;
256 spec->automute_mixer_nid[0] = 0x0c;
257 spec->automute = 1;
258 spec->automute_mode = ALC_AUTOMUTE_MIXER;
259 spec->ext_mic_pin = 0x18;
260 spec->int_mic_pin = 0x19;
261 spec->auto_mic = 1;
262}
263
264static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
265{
266 alc269_quanta_fl1_speaker_automute(codec);
267 alc_mic_automute(codec);
268}
269
270static void alc269_lifebook_setup(struct hda_codec *codec)
271{
272 struct alc_spec *spec = codec->spec;
273 spec->autocfg.hp_pins[0] = 0x15;
274 spec->autocfg.hp_pins[1] = 0x1a;
275 spec->autocfg.speaker_pins[0] = 0x14;
276 spec->automute_mixer_nid[0] = 0x0c;
277 spec->automute = 1;
278 spec->automute_mode = ALC_AUTOMUTE_MIXER;
279}
280
281static void alc269_lifebook_init_hook(struct hda_codec *codec)
282{
283 alc269_lifebook_speaker_automute(codec);
284 alc269_lifebook_mic_autoswitch(codec);
285}
286
287static const struct hda_verb alc269_laptop_dmic_init_verbs[] = {
288 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
289 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
290 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
291 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
292 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
293 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
294 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
295 {}
296};
297
298static const struct hda_verb alc269_laptop_amic_init_verbs[] = {
299 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
300 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
301 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
302 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
303 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
304 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
305 {}
306};
307
308static const struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
309 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
310 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
311 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
312 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
313 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
314 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
315 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
316 {}
317};
318
319static const struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
320 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
321 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
322 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
323 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
324 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
325 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
326 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
327 {}
328};
329
330static const struct hda_verb alc271_acer_dmic_verbs[] = {
331 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
332 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
333 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
334 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
335 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
336 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
337 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},
338 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
339 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
340 {0x22, AC_VERB_SET_CONNECT_SEL, 6},
341 { }
342};
343
344static void alc269_laptop_amic_setup(struct hda_codec *codec)
345{
346 struct alc_spec *spec = codec->spec;
347 spec->autocfg.hp_pins[0] = 0x15;
348 spec->autocfg.speaker_pins[0] = 0x14;
349 spec->automute_mixer_nid[0] = 0x0c;
350 spec->automute = 1;
351 spec->automute_mode = ALC_AUTOMUTE_MIXER;
352 spec->ext_mic_pin = 0x18;
353 spec->int_mic_pin = 0x19;
354 spec->auto_mic = 1;
355}
356
357static void alc269_laptop_dmic_setup(struct hda_codec *codec)
358{
359 struct alc_spec *spec = codec->spec;
360 spec->autocfg.hp_pins[0] = 0x15;
361 spec->autocfg.speaker_pins[0] = 0x14;
362 spec->automute_mixer_nid[0] = 0x0c;
363 spec->automute = 1;
364 spec->automute_mode = ALC_AUTOMUTE_MIXER;
365 spec->ext_mic_pin = 0x18;
366 spec->int_mic_pin = 0x12;
367 spec->auto_mic = 1;
368}
369
370static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
371{
372 struct alc_spec *spec = codec->spec;
373 spec->autocfg.hp_pins[0] = 0x21;
374 spec->autocfg.speaker_pins[0] = 0x14;
375 spec->automute_mixer_nid[0] = 0x0c;
376 spec->automute = 1;
377 spec->automute_mode = ALC_AUTOMUTE_MIXER;
378 spec->ext_mic_pin = 0x18;
379 spec->int_mic_pin = 0x19;
380 spec->auto_mic = 1;
381}
382
383static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
384{
385 struct alc_spec *spec = codec->spec;
386 spec->autocfg.hp_pins[0] = 0x21;
387 spec->autocfg.speaker_pins[0] = 0x14;
388 spec->automute_mixer_nid[0] = 0x0c;
389 spec->automute = 1;
390 spec->automute_mode = ALC_AUTOMUTE_MIXER;
391 spec->ext_mic_pin = 0x18;
392 spec->int_mic_pin = 0x12;
393 spec->auto_mic = 1;
394}
395
396/*
397 * generic initialization of ADC, input mixers and output mixers
398 */
399static const struct hda_verb alc269_init_verbs[] = {
400 /*
401 * Unmute ADC0 and set the default input to mic-in
402 */
403 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
404
405 /*
406 * Set up output mixers (0x02 - 0x03)
407 */
408 /* set vol=0 to output mixers */
409 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
410 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
411
412 /* set up input amps for analog loopback */
413 /* Amp Indices: DAC = 0, mixer = 1 */
414 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
415 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
416 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
417 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
418 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
419 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
420
421 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
422 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
423 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
424 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
425 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
426 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
427 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
428
429 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
430 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
431
432 /* FIXME: use Mux-type input source selection */
433 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
434 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
435 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
436
437 /* set EAPD */
438 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
439 { }
440};
441
442static const struct hda_verb alc269vb_init_verbs[] = {
443 /*
444 * Unmute ADC0 and set the default input to mic-in
445 */
446 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
447
448 /*
449 * Set up output mixers (0x02 - 0x03)
450 */
451 /* set vol=0 to output mixers */
452 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
453 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
454
455 /* set up input amps for analog loopback */
456 /* Amp Indices: DAC = 0, mixer = 1 */
457 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
458 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
459 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
460 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
461 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
462 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
463
464 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
465 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
466 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
467 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
468 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
469 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
470 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
471
472 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
473 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
474
475 /* FIXME: use Mux-type input source selection */
476 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
477 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
478 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
479
480 /* set EAPD */
481 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
482 { }
483};
484
485/*
486 * configuration and preset
487 */
488static const char * const alc269_models[ALC269_MODEL_LAST] = {
489 [ALC269_BASIC] = "basic",
490 [ALC269_QUANTA_FL1] = "quanta",
491 [ALC269_AMIC] = "laptop-amic",
492 [ALC269_DMIC] = "laptop-dmic",
493 [ALC269_FUJITSU] = "fujitsu",
494 [ALC269_LIFEBOOK] = "lifebook",
495 [ALC269_AUTO] = "auto",
496};
497
498static const struct snd_pci_quirk alc269_cfg_tbl[] = {
499 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
500 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
501 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
502 ALC269_AMIC),
503 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
504 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
505 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
506 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
507 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
508 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
509 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
510 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
511 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
512 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269VB_AMIC),
513 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
514 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
515 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
516 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
517 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
518 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
519 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
520 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
521 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
522 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
523 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
524 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
525 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
526 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
527 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
528 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
529 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
530 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
531 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
532 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
533 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
534 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
535 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
536 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
537 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
538 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
539 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
540 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
541 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
542 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
543 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
544 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
545 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
546 {}
547};
548
549static const struct alc_config_preset alc269_presets[] = {
550 [ALC269_BASIC] = {
551 .mixers = { alc269_base_mixer },
552 .init_verbs = { alc269_init_verbs },
553 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
554 .dac_nids = alc269_dac_nids,
555 .hp_nid = 0x03,
556 .num_channel_mode = ARRAY_SIZE(alc269_modes),
557 .channel_mode = alc269_modes,
558 .input_mux = &alc269_capture_source,
559 },
560 [ALC269_QUANTA_FL1] = {
561 .mixers = { alc269_quanta_fl1_mixer },
562 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
563 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
564 .dac_nids = alc269_dac_nids,
565 .hp_nid = 0x03,
566 .num_channel_mode = ARRAY_SIZE(alc269_modes),
567 .channel_mode = alc269_modes,
568 .input_mux = &alc269_capture_source,
569 .unsol_event = alc269_quanta_fl1_unsol_event,
570 .setup = alc269_quanta_fl1_setup,
571 .init_hook = alc269_quanta_fl1_init_hook,
572 },
573 [ALC269_AMIC] = {
574 .mixers = { alc269_laptop_mixer },
575 .cap_mixer = alc269_laptop_analog_capture_mixer,
576 .init_verbs = { alc269_init_verbs,
577 alc269_laptop_amic_init_verbs },
578 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
579 .dac_nids = alc269_dac_nids,
580 .hp_nid = 0x03,
581 .num_channel_mode = ARRAY_SIZE(alc269_modes),
582 .channel_mode = alc269_modes,
583 .unsol_event = alc_sku_unsol_event,
584 .setup = alc269_laptop_amic_setup,
585 .init_hook = alc_inithook,
586 },
587 [ALC269_DMIC] = {
588 .mixers = { alc269_laptop_mixer },
589 .cap_mixer = alc269_laptop_digital_capture_mixer,
590 .init_verbs = { alc269_init_verbs,
591 alc269_laptop_dmic_init_verbs },
592 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
593 .dac_nids = alc269_dac_nids,
594 .hp_nid = 0x03,
595 .num_channel_mode = ARRAY_SIZE(alc269_modes),
596 .channel_mode = alc269_modes,
597 .unsol_event = alc_sku_unsol_event,
598 .setup = alc269_laptop_dmic_setup,
599 .init_hook = alc_inithook,
600 },
601 [ALC269VB_AMIC] = {
602 .mixers = { alc269vb_laptop_mixer },
603 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
604 .init_verbs = { alc269vb_init_verbs,
605 alc269vb_laptop_amic_init_verbs },
606 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
607 .dac_nids = alc269_dac_nids,
608 .hp_nid = 0x03,
609 .num_channel_mode = ARRAY_SIZE(alc269_modes),
610 .channel_mode = alc269_modes,
611 .unsol_event = alc_sku_unsol_event,
612 .setup = alc269vb_laptop_amic_setup,
613 .init_hook = alc_inithook,
614 },
615 [ALC269VB_DMIC] = {
616 .mixers = { alc269vb_laptop_mixer },
617 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
618 .init_verbs = { alc269vb_init_verbs,
619 alc269vb_laptop_dmic_init_verbs },
620 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
621 .dac_nids = alc269_dac_nids,
622 .hp_nid = 0x03,
623 .num_channel_mode = ARRAY_SIZE(alc269_modes),
624 .channel_mode = alc269_modes,
625 .unsol_event = alc_sku_unsol_event,
626 .setup = alc269vb_laptop_dmic_setup,
627 .init_hook = alc_inithook,
628 },
629 [ALC269_FUJITSU] = {
630 .mixers = { alc269_fujitsu_mixer },
631 .cap_mixer = alc269_laptop_digital_capture_mixer,
632 .init_verbs = { alc269_init_verbs,
633 alc269_laptop_dmic_init_verbs },
634 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
635 .dac_nids = alc269_dac_nids,
636 .hp_nid = 0x03,
637 .num_channel_mode = ARRAY_SIZE(alc269_modes),
638 .channel_mode = alc269_modes,
639 .unsol_event = alc_sku_unsol_event,
640 .setup = alc269_laptop_dmic_setup,
641 .init_hook = alc_inithook,
642 },
643 [ALC269_LIFEBOOK] = {
644 .mixers = { alc269_lifebook_mixer },
645 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
646 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
647 .dac_nids = alc269_dac_nids,
648 .hp_nid = 0x03,
649 .num_channel_mode = ARRAY_SIZE(alc269_modes),
650 .channel_mode = alc269_modes,
651 .input_mux = &alc269_capture_source,
652 .unsol_event = alc269_lifebook_unsol_event,
653 .setup = alc269_lifebook_setup,
654 .init_hook = alc269_lifebook_init_hook,
655 },
656 [ALC271_ACER] = {
657 .mixers = { alc269_asus_mixer },
658 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
659 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
660 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
661 .dac_nids = alc269_dac_nids,
662 .adc_nids = alc262_dmic_adc_nids,
663 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
664 .capsrc_nids = alc262_dmic_capsrc_nids,
665 .num_channel_mode = ARRAY_SIZE(alc269_modes),
666 .channel_mode = alc269_modes,
667 .input_mux = &alc269_capture_source,
668 .dig_out_nid = ALC880_DIGOUT_NID,
669 .unsol_event = alc_sku_unsol_event,
670 .setup = alc269vb_laptop_dmic_setup,
671 .init_hook = alc_inithook,
672 },
673};
674
diff --git a/sound/pci/hda/alc662_quirks.c b/sound/pci/hda/alc662_quirks.c
deleted file mode 100644
index e69a6ea3083..00000000000
--- a/sound/pci/hda/alc662_quirks.c
+++ /dev/null
@@ -1,1408 +0,0 @@
1/*
2 * ALC662/ALC663/ALC665/ALC670 quirk models
3 * included by patch_realtek.c
4 */
5
6/* ALC662 models */
7enum {
8 ALC662_AUTO,
9 ALC662_3ST_2ch_DIG,
10 ALC662_3ST_6ch_DIG,
11 ALC662_3ST_6ch,
12 ALC662_5ST_DIG,
13 ALC662_LENOVO_101E,
14 ALC662_ASUS_EEEPC_P701,
15 ALC662_ASUS_EEEPC_EP20,
16 ALC663_ASUS_M51VA,
17 ALC663_ASUS_G71V,
18 ALC663_ASUS_H13,
19 ALC663_ASUS_G50V,
20 ALC662_ECS,
21 ALC663_ASUS_MODE1,
22 ALC662_ASUS_MODE2,
23 ALC663_ASUS_MODE3,
24 ALC663_ASUS_MODE4,
25 ALC663_ASUS_MODE5,
26 ALC663_ASUS_MODE6,
27 ALC663_ASUS_MODE7,
28 ALC663_ASUS_MODE8,
29 ALC272_DELL,
30 ALC272_DELL_ZM1,
31 ALC272_SAMSUNG_NC10,
32 ALC662_MODEL_LAST,
33};
34
35#define ALC662_DIGOUT_NID 0x06
36#define ALC662_DIGIN_NID 0x0a
37
38static const hda_nid_t alc662_dac_nids[3] = {
39 /* front, rear, clfe */
40 0x02, 0x03, 0x04
41};
42
43static const hda_nid_t alc272_dac_nids[2] = {
44 0x02, 0x03
45};
46
47static const hda_nid_t alc662_adc_nids[2] = {
48 /* ADC1-2 */
49 0x09, 0x08
50};
51
52static const hda_nid_t alc272_adc_nids[1] = {
53 /* ADC1-2 */
54 0x08,
55};
56
57static const hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
58static const hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
59
60
61/* input MUX */
62/* FIXME: should be a matrix-type input source selection */
63static const struct hda_input_mux alc662_capture_source = {
64 .num_items = 4,
65 .items = {
66 { "Mic", 0x0 },
67 { "Front Mic", 0x1 },
68 { "Line", 0x2 },
69 { "CD", 0x4 },
70 },
71};
72
73static const struct hda_input_mux alc662_lenovo_101e_capture_source = {
74 .num_items = 2,
75 .items = {
76 { "Mic", 0x1 },
77 { "Line", 0x2 },
78 },
79};
80
81static const struct hda_input_mux alc663_capture_source = {
82 .num_items = 3,
83 .items = {
84 { "Mic", 0x0 },
85 { "Front Mic", 0x1 },
86 { "Line", 0x2 },
87 },
88};
89
90#if 0 /* set to 1 for testing other input sources below */
91static const struct hda_input_mux alc272_nc10_capture_source = {
92 .num_items = 16,
93 .items = {
94 { "Autoselect Mic", 0x0 },
95 { "Internal Mic", 0x1 },
96 { "In-0x02", 0x2 },
97 { "In-0x03", 0x3 },
98 { "In-0x04", 0x4 },
99 { "In-0x05", 0x5 },
100 { "In-0x06", 0x6 },
101 { "In-0x07", 0x7 },
102 { "In-0x08", 0x8 },
103 { "In-0x09", 0x9 },
104 { "In-0x0a", 0x0a },
105 { "In-0x0b", 0x0b },
106 { "In-0x0c", 0x0c },
107 { "In-0x0d", 0x0d },
108 { "In-0x0e", 0x0e },
109 { "In-0x0f", 0x0f },
110 },
111};
112#endif
113
114/*
115 * 2ch mode
116 */
117static const struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
118 { 2, NULL }
119};
120
121/*
122 * 2ch mode
123 */
124static const struct hda_verb alc662_3ST_ch2_init[] = {
125 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
126 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
127 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
128 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
129 { } /* end */
130};
131
132/*
133 * 6ch mode
134 */
135static const struct hda_verb alc662_3ST_ch6_init[] = {
136 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
137 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
138 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
139 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
140 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
141 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
142 { } /* end */
143};
144
145static const struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
146 { 2, alc662_3ST_ch2_init },
147 { 6, alc662_3ST_ch6_init },
148};
149
150/*
151 * 2ch mode
152 */
153static const struct hda_verb alc662_sixstack_ch6_init[] = {
154 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
155 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
156 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
157 { } /* end */
158};
159
160/*
161 * 6ch mode
162 */
163static const struct hda_verb alc662_sixstack_ch8_init[] = {
164 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
165 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
166 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
167 { } /* end */
168};
169
170static const struct hda_channel_mode alc662_5stack_modes[2] = {
171 { 2, alc662_sixstack_ch6_init },
172 { 6, alc662_sixstack_ch8_init },
173};
174
175/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
176 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
177 */
178
179static const struct snd_kcontrol_new alc662_base_mixer[] = {
180 /* output mixer control */
181 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
182 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
183 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
184 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
185 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
186 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
187 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
188 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
189 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
190
191 /*Input mixer control */
192 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
193 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
194 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
195 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
196 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
197 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
198 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
199 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
200 { } /* end */
201};
202
203static const struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
204 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
205 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
206 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
207 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
208 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
209 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
210 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
211 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
212 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
213 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
214 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
215 { } /* end */
216};
217
218static const struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
219 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
220 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
221 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
222 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
223 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
224 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
225 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
226 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
227 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
228 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
229 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
230 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
231 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
232 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
233 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
234 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
235 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
236 { } /* end */
237};
238
239static const struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
240 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
241 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
242 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
243 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
244 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
245 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
246 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
247 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
248 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
249 { } /* end */
250};
251
252static const struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
253 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
254 ALC262_HIPPO_MASTER_SWITCH,
255
256 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
257 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
258 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
259
260 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
261 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
262 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
263 { } /* end */
264};
265
266static const struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
267 ALC262_HIPPO_MASTER_SWITCH,
268 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
269 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
270 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
271 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
272 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
273 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
274 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
275 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
276 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
277 { } /* end */
278};
279
280static const struct hda_bind_ctls alc663_asus_bind_master_vol = {
281 .ops = &snd_hda_bind_vol,
282 .values = {
283 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
284 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
285 0
286 },
287};
288
289static const struct hda_bind_ctls alc663_asus_one_bind_switch = {
290 .ops = &snd_hda_bind_sw,
291 .values = {
292 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
293 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
294 0
295 },
296};
297
298static const struct snd_kcontrol_new alc663_m51va_mixer[] = {
299 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
300 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
301 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
302 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
303 { } /* end */
304};
305
306static const struct hda_bind_ctls alc663_asus_tree_bind_switch = {
307 .ops = &snd_hda_bind_sw,
308 .values = {
309 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
310 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
311 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
312 0
313 },
314};
315
316static const struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
317 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
318 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
319 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
320 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
321 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
322 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
323
324 { } /* end */
325};
326
327static const struct hda_bind_ctls alc663_asus_four_bind_switch = {
328 .ops = &snd_hda_bind_sw,
329 .values = {
330 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
331 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
332 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
333 0
334 },
335};
336
337static const struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
338 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
339 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
340 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
341 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
342 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
343 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
344 { } /* end */
345};
346
347static const struct snd_kcontrol_new alc662_1bjd_mixer[] = {
348 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
349 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
350 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
351 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
352 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
353 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
354 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
355 { } /* end */
356};
357
358static const struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
359 .ops = &snd_hda_bind_vol,
360 .values = {
361 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
362 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
363 0
364 },
365};
366
367static const struct hda_bind_ctls alc663_asus_two_bind_switch = {
368 .ops = &snd_hda_bind_sw,
369 .values = {
370 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
371 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
372 0
373 },
374};
375
376static const struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
377 HDA_BIND_VOL("Master Playback Volume",
378 &alc663_asus_two_bind_master_vol),
379 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
380 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
381 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
382 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
383 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
384 { } /* end */
385};
386
387static const struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
388 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
389 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
390 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
391 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
392 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
393 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
394 { } /* end */
395};
396
397static const struct snd_kcontrol_new alc663_g71v_mixer[] = {
398 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
399 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
400 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
401 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
402 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
403
404 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
405 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
406 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
407 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
408 { } /* end */
409};
410
411static const struct snd_kcontrol_new alc663_g50v_mixer[] = {
412 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
413 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
414 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
415
416 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
417 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
418 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
419 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
420 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
421 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
422 { } /* end */
423};
424
425static const struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
426 .ops = &snd_hda_bind_sw,
427 .values = {
428 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
429 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
430 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
431 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
432 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
433 0
434 },
435};
436
437static const struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
438 .ops = &snd_hda_bind_sw,
439 .values = {
440 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
441 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
442 0
443 },
444};
445
446static const struct snd_kcontrol_new alc663_mode7_mixer[] = {
447 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
448 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
449 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
450 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
451 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
452 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
453 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
454 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
455 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
456 { } /* end */
457};
458
459static const struct snd_kcontrol_new alc663_mode8_mixer[] = {
460 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
461 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
462 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
463 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
464 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
465 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
466 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
467 { } /* end */
468};
469
470
471static const struct snd_kcontrol_new alc662_chmode_mixer[] = {
472 {
473 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
474 .name = "Channel Mode",
475 .info = alc_ch_mode_info,
476 .get = alc_ch_mode_get,
477 .put = alc_ch_mode_put,
478 },
479 { } /* end */
480};
481
482static const struct hda_verb alc662_init_verbs[] = {
483 /* ADC: mute amp left and right */
484 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
485 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
486
487 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
488 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
489 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
490 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
491 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
492 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
493
494 /* Front Pin: output 0 (0x0c) */
495 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
496 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
497
498 /* Rear Pin: output 1 (0x0d) */
499 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
500 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
501
502 /* CLFE Pin: output 2 (0x0e) */
503 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
504 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
505
506 /* Mic (rear) pin: input vref at 80% */
507 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
508 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
509 /* Front Mic pin: input vref at 80% */
510 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
511 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
512 /* Line In pin: input */
513 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
514 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
515 /* Line-2 In: Headphone output (output 0 - 0x0c) */
516 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
517 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
518 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
519 /* CD pin widget for input */
520 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
521
522 /* FIXME: use matrix-type input source selection */
523 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
524 /* Input mixer */
525 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
526 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
527
528 { }
529};
530
531static const struct hda_verb alc662_eapd_init_verbs[] = {
532 /* always trun on EAPD */
533 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
534 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
535 { }
536};
537
538static const struct hda_verb alc662_sue_init_verbs[] = {
539 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC_FRONT_EVENT},
540 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC_HP_EVENT},
541 {}
542};
543
544static const struct hda_verb alc662_eeepc_sue_init_verbs[] = {
545 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
546 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
547 {}
548};
549
550/* Set Unsolicited Event*/
551static const struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
552 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
553 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
554 {}
555};
556
557static const struct hda_verb alc663_m51va_init_verbs[] = {
558 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
559 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
560 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
561 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
562 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
563 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
564 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
565 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
566 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
567 {}
568};
569
570static const struct hda_verb alc663_21jd_amic_init_verbs[] = {
571 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
572 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
573 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
574 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
575 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
576 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
577 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
578 {}
579};
580
581static const struct hda_verb alc662_1bjd_amic_init_verbs[] = {
582 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
583 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
584 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
585 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
586 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
587 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
588 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
589 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
590 {}
591};
592
593static const struct hda_verb alc663_15jd_amic_init_verbs[] = {
594 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
595 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
596 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
597 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
598 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
599 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
600 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
601 {}
602};
603
604static const struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
605 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
606 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
607 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
608 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
609 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
610 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
611 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
612 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
613 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
614 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
615 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
616 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
617 {}
618};
619
620static const struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
621 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
622 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
623 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
624 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
625 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
626 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
627 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
628 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
629 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
630 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
631 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
632 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
633 {}
634};
635
636static const struct hda_verb alc663_g71v_init_verbs[] = {
637 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
638 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
639 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
640
641 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
642 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
643 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
644
645 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC_FRONT_EVENT},
646 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC_MIC_EVENT},
647 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC_HP_EVENT},
648 {}
649};
650
651static const struct hda_verb alc663_g50v_init_verbs[] = {
652 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
653 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
654 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
655
656 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
657 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
658 {}
659};
660
661static const struct hda_verb alc662_ecs_init_verbs[] = {
662 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
663 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
664 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
665 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
666 {}
667};
668
669static const struct hda_verb alc272_dell_zm1_init_verbs[] = {
670 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
671 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
672 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
673 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
674 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
675 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
676 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
677 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
678 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
679 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
680 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
681 {}
682};
683
684static const struct hda_verb alc272_dell_init_verbs[] = {
685 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
686 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
687 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
688 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
689 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
690 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
691 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
692 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
693 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
694 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
695 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
696 {}
697};
698
699static const struct hda_verb alc663_mode7_init_verbs[] = {
700 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
701 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
702 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
703 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
704 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
705 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
706 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
707 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
708 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
709 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
710 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
711 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
712 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
713 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
714 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
715 {}
716};
717
718static const struct hda_verb alc663_mode8_init_verbs[] = {
719 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
720 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
721 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
722 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
723 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
724 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
725 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
726 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
727 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
728 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
729 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
730 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
731 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
732 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
733 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
734 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
735 {}
736};
737
738static const struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
739 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
740 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
741 { } /* end */
742};
743
744static const struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
745 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
746 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
747 { } /* end */
748};
749
750static void alc662_lenovo_101e_setup(struct hda_codec *codec)
751{
752 struct alc_spec *spec = codec->spec;
753
754 spec->autocfg.hp_pins[0] = 0x1b;
755 spec->autocfg.line_out_pins[0] = 0x14;
756 spec->autocfg.speaker_pins[0] = 0x15;
757 spec->automute = 1;
758 spec->detect_line = 1;
759 spec->automute_lines = 1;
760 spec->automute_mode = ALC_AUTOMUTE_AMP;
761}
762
763static void alc662_eeepc_setup(struct hda_codec *codec)
764{
765 struct alc_spec *spec = codec->spec;
766
767 alc262_hippo1_setup(codec);
768 spec->ext_mic_pin = 0x18;
769 spec->int_mic_pin = 0x19;
770 spec->auto_mic = 1;
771}
772
773static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
774{
775 struct alc_spec *spec = codec->spec;
776
777 spec->autocfg.hp_pins[0] = 0x14;
778 spec->autocfg.speaker_pins[0] = 0x1b;
779 spec->automute = 1;
780 spec->automute_mode = ALC_AUTOMUTE_AMP;
781}
782
783static void alc663_m51va_setup(struct hda_codec *codec)
784{
785 struct alc_spec *spec = codec->spec;
786 spec->autocfg.hp_pins[0] = 0x21;
787 spec->autocfg.speaker_pins[0] = 0x14;
788 spec->automute_mixer_nid[0] = 0x0c;
789 spec->automute = 1;
790 spec->automute_mode = ALC_AUTOMUTE_MIXER;
791 spec->ext_mic_pin = 0x18;
792 spec->int_mic_pin = 0x12;
793 spec->auto_mic = 1;
794}
795
796/* ***************** Mode1 ******************************/
797static void alc663_mode1_setup(struct hda_codec *codec)
798{
799 struct alc_spec *spec = codec->spec;
800 spec->autocfg.hp_pins[0] = 0x21;
801 spec->autocfg.speaker_pins[0] = 0x14;
802 spec->automute_mixer_nid[0] = 0x0c;
803 spec->automute = 1;
804 spec->automute_mode = ALC_AUTOMUTE_MIXER;
805 spec->ext_mic_pin = 0x18;
806 spec->int_mic_pin = 0x19;
807 spec->auto_mic = 1;
808}
809
810/* ***************** Mode2 ******************************/
811static void alc662_mode2_setup(struct hda_codec *codec)
812{
813 struct alc_spec *spec = codec->spec;
814 spec->autocfg.hp_pins[0] = 0x1b;
815 spec->autocfg.speaker_pins[0] = 0x14;
816 spec->automute = 1;
817 spec->automute_mode = ALC_AUTOMUTE_PIN;
818 spec->ext_mic_pin = 0x18;
819 spec->int_mic_pin = 0x19;
820 spec->auto_mic = 1;
821}
822
823/* ***************** Mode3 ******************************/
824static void alc663_mode3_setup(struct hda_codec *codec)
825{
826 struct alc_spec *spec = codec->spec;
827 spec->autocfg.hp_pins[0] = 0x21;
828 spec->autocfg.hp_pins[0] = 0x15;
829 spec->autocfg.speaker_pins[0] = 0x14;
830 spec->automute = 1;
831 spec->automute_mode = ALC_AUTOMUTE_PIN;
832 spec->ext_mic_pin = 0x18;
833 spec->int_mic_pin = 0x19;
834 spec->auto_mic = 1;
835}
836
837/* ***************** Mode4 ******************************/
838static void alc663_mode4_setup(struct hda_codec *codec)
839{
840 struct alc_spec *spec = codec->spec;
841 spec->autocfg.hp_pins[0] = 0x21;
842 spec->autocfg.speaker_pins[0] = 0x14;
843 spec->autocfg.speaker_pins[1] = 0x16;
844 spec->automute_mixer_nid[0] = 0x0c;
845 spec->automute_mixer_nid[1] = 0x0e;
846 spec->automute = 1;
847 spec->automute_mode = ALC_AUTOMUTE_MIXER;
848 spec->ext_mic_pin = 0x18;
849 spec->int_mic_pin = 0x19;
850 spec->auto_mic = 1;
851}
852
853/* ***************** Mode5 ******************************/
854static void alc663_mode5_setup(struct hda_codec *codec)
855{
856 struct alc_spec *spec = codec->spec;
857 spec->autocfg.hp_pins[0] = 0x15;
858 spec->autocfg.speaker_pins[0] = 0x14;
859 spec->autocfg.speaker_pins[1] = 0x16;
860 spec->automute_mixer_nid[0] = 0x0c;
861 spec->automute_mixer_nid[1] = 0x0e;
862 spec->automute = 1;
863 spec->automute_mode = ALC_AUTOMUTE_MIXER;
864 spec->ext_mic_pin = 0x18;
865 spec->int_mic_pin = 0x19;
866 spec->auto_mic = 1;
867}
868
869/* ***************** Mode6 ******************************/
870static void alc663_mode6_setup(struct hda_codec *codec)
871{
872 struct alc_spec *spec = codec->spec;
873 spec->autocfg.hp_pins[0] = 0x1b;
874 spec->autocfg.hp_pins[0] = 0x15;
875 spec->autocfg.speaker_pins[0] = 0x14;
876 spec->automute_mixer_nid[0] = 0x0c;
877 spec->automute = 1;
878 spec->automute_mode = ALC_AUTOMUTE_MIXER;
879 spec->ext_mic_pin = 0x18;
880 spec->int_mic_pin = 0x19;
881 spec->auto_mic = 1;
882}
883
884/* ***************** Mode7 ******************************/
885static void alc663_mode7_setup(struct hda_codec *codec)
886{
887 struct alc_spec *spec = codec->spec;
888 spec->autocfg.hp_pins[0] = 0x1b;
889 spec->autocfg.hp_pins[0] = 0x21;
890 spec->autocfg.speaker_pins[0] = 0x14;
891 spec->autocfg.speaker_pins[0] = 0x17;
892 spec->automute = 1;
893 spec->automute_mode = ALC_AUTOMUTE_PIN;
894 spec->ext_mic_pin = 0x18;
895 spec->int_mic_pin = 0x19;
896 spec->auto_mic = 1;
897}
898
899/* ***************** Mode8 ******************************/
900static void alc663_mode8_setup(struct hda_codec *codec)
901{
902 struct alc_spec *spec = codec->spec;
903 spec->autocfg.hp_pins[0] = 0x21;
904 spec->autocfg.hp_pins[1] = 0x15;
905 spec->autocfg.speaker_pins[0] = 0x14;
906 spec->autocfg.speaker_pins[0] = 0x17;
907 spec->automute = 1;
908 spec->automute_mode = ALC_AUTOMUTE_PIN;
909 spec->ext_mic_pin = 0x18;
910 spec->int_mic_pin = 0x12;
911 spec->auto_mic = 1;
912}
913
914static void alc663_g71v_setup(struct hda_codec *codec)
915{
916 struct alc_spec *spec = codec->spec;
917 spec->autocfg.hp_pins[0] = 0x21;
918 spec->autocfg.line_out_pins[0] = 0x15;
919 spec->autocfg.speaker_pins[0] = 0x14;
920 spec->automute = 1;
921 spec->automute_mode = ALC_AUTOMUTE_AMP;
922 spec->detect_line = 1;
923 spec->automute_lines = 1;
924 spec->ext_mic_pin = 0x18;
925 spec->int_mic_pin = 0x12;
926 spec->auto_mic = 1;
927}
928
929#define alc663_g50v_setup alc663_m51va_setup
930
931static const struct snd_kcontrol_new alc662_ecs_mixer[] = {
932 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
933 ALC262_HIPPO_MASTER_SWITCH,
934
935 HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT),
936 HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
937 HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
938
939 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
940 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
941 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
942 { } /* end */
943};
944
945static const struct snd_kcontrol_new alc272_nc10_mixer[] = {
946 /* Master Playback automatically created from Speaker and Headphone */
947 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
948 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
949 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
950 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
951
952 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
953 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
954 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
955
956 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
957 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
958 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
959 { } /* end */
960};
961
962
963/*
964 * configuration and preset
965 */
966static const char * const alc662_models[ALC662_MODEL_LAST] = {
967 [ALC662_3ST_2ch_DIG] = "3stack-dig",
968 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
969 [ALC662_3ST_6ch] = "3stack-6ch",
970 [ALC662_5ST_DIG] = "5stack-dig",
971 [ALC662_LENOVO_101E] = "lenovo-101e",
972 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
973 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
974 [ALC662_ECS] = "ecs",
975 [ALC663_ASUS_M51VA] = "m51va",
976 [ALC663_ASUS_G71V] = "g71v",
977 [ALC663_ASUS_H13] = "h13",
978 [ALC663_ASUS_G50V] = "g50v",
979 [ALC663_ASUS_MODE1] = "asus-mode1",
980 [ALC662_ASUS_MODE2] = "asus-mode2",
981 [ALC663_ASUS_MODE3] = "asus-mode3",
982 [ALC663_ASUS_MODE4] = "asus-mode4",
983 [ALC663_ASUS_MODE5] = "asus-mode5",
984 [ALC663_ASUS_MODE6] = "asus-mode6",
985 [ALC663_ASUS_MODE7] = "asus-mode7",
986 [ALC663_ASUS_MODE8] = "asus-mode8",
987 [ALC272_DELL] = "dell",
988 [ALC272_DELL_ZM1] = "dell-zm1",
989 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
990 [ALC662_AUTO] = "auto",
991};
992
993static const struct snd_pci_quirk alc662_cfg_tbl[] = {
994 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
995 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
996 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
997 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
998 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
999 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
1000 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
1001 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
1002 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
1003 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
1004 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
1005 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
1006 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
1007 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
1008 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
1009 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
1010 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
1011 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
1012 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
1013 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
1014 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
1015 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
1016 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
1017 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
1018 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
1019 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
1020 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
1021 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
1022 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
1023 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
1024 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
1025 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
1026 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
1027 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
1028 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
1029 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
1030 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
1031 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
1032 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
1033 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
1034 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
1035 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
1036 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
1037 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
1038 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
1039 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
1040 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
1041 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
1042 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
1043 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
1044 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
1045 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
1046 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
1047 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
1048 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
1049 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
1050 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
1051 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
1052 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
1053 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
1054 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
1055 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
1056 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
1057 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
1058 ALC662_3ST_6ch_DIG),
1059 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
1060 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
1061 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
1062 ALC662_3ST_6ch_DIG),
1063 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
1064 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
1065 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
1066 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
1067 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
1068 ALC662_3ST_6ch_DIG),
1069 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
1070 ALC663_ASUS_H13),
1071 SND_PCI_QUIRK(0x1991, 0x5628, "Ordissimo EVE", ALC662_LENOVO_101E),
1072 {}
1073};
1074
1075static const struct alc_config_preset alc662_presets[] = {
1076 [ALC662_3ST_2ch_DIG] = {
1077 .mixers = { alc662_3ST_2ch_mixer },
1078 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
1079 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1080 .dac_nids = alc662_dac_nids,
1081 .dig_out_nid = ALC662_DIGOUT_NID,
1082 .dig_in_nid = ALC662_DIGIN_NID,
1083 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1084 .channel_mode = alc662_3ST_2ch_modes,
1085 .input_mux = &alc662_capture_source,
1086 },
1087 [ALC662_3ST_6ch_DIG] = {
1088 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
1089 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
1090 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1091 .dac_nids = alc662_dac_nids,
1092 .dig_out_nid = ALC662_DIGOUT_NID,
1093 .dig_in_nid = ALC662_DIGIN_NID,
1094 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
1095 .channel_mode = alc662_3ST_6ch_modes,
1096 .need_dac_fix = 1,
1097 .input_mux = &alc662_capture_source,
1098 },
1099 [ALC662_3ST_6ch] = {
1100 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
1101 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
1102 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1103 .dac_nids = alc662_dac_nids,
1104 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
1105 .channel_mode = alc662_3ST_6ch_modes,
1106 .need_dac_fix = 1,
1107 .input_mux = &alc662_capture_source,
1108 },
1109 [ALC662_5ST_DIG] = {
1110 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
1111 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
1112 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1113 .dac_nids = alc662_dac_nids,
1114 .dig_out_nid = ALC662_DIGOUT_NID,
1115 .dig_in_nid = ALC662_DIGIN_NID,
1116 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
1117 .channel_mode = alc662_5stack_modes,
1118 .input_mux = &alc662_capture_source,
1119 },
1120 [ALC662_LENOVO_101E] = {
1121 .mixers = { alc662_lenovo_101e_mixer },
1122 .init_verbs = { alc662_init_verbs,
1123 alc662_eapd_init_verbs,
1124 alc662_sue_init_verbs },
1125 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1126 .dac_nids = alc662_dac_nids,
1127 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1128 .channel_mode = alc662_3ST_2ch_modes,
1129 .input_mux = &alc662_lenovo_101e_capture_source,
1130 .unsol_event = alc_sku_unsol_event,
1131 .setup = alc662_lenovo_101e_setup,
1132 .init_hook = alc_inithook,
1133 },
1134 [ALC662_ASUS_EEEPC_P701] = {
1135 .mixers = { alc662_eeepc_p701_mixer },
1136 .init_verbs = { alc662_init_verbs,
1137 alc662_eapd_init_verbs,
1138 alc662_eeepc_sue_init_verbs },
1139 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1140 .dac_nids = alc662_dac_nids,
1141 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1142 .channel_mode = alc662_3ST_2ch_modes,
1143 .unsol_event = alc_sku_unsol_event,
1144 .setup = alc662_eeepc_setup,
1145 .init_hook = alc_inithook,
1146 },
1147 [ALC662_ASUS_EEEPC_EP20] = {
1148 .mixers = { alc662_eeepc_ep20_mixer,
1149 alc662_chmode_mixer },
1150 .init_verbs = { alc662_init_verbs,
1151 alc662_eapd_init_verbs,
1152 alc662_eeepc_ep20_sue_init_verbs },
1153 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1154 .dac_nids = alc662_dac_nids,
1155 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
1156 .channel_mode = alc662_3ST_6ch_modes,
1157 .input_mux = &alc662_lenovo_101e_capture_source,
1158 .unsol_event = alc_sku_unsol_event,
1159 .setup = alc662_eeepc_ep20_setup,
1160 .init_hook = alc_inithook,
1161 },
1162 [ALC662_ECS] = {
1163 .mixers = { alc662_ecs_mixer },
1164 .init_verbs = { alc662_init_verbs,
1165 alc662_eapd_init_verbs,
1166 alc662_ecs_init_verbs },
1167 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1168 .dac_nids = alc662_dac_nids,
1169 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1170 .channel_mode = alc662_3ST_2ch_modes,
1171 .unsol_event = alc_sku_unsol_event,
1172 .setup = alc662_eeepc_setup,
1173 .init_hook = alc_inithook,
1174 },
1175 [ALC663_ASUS_M51VA] = {
1176 .mixers = { alc663_m51va_mixer },
1177 .init_verbs = { alc662_init_verbs,
1178 alc662_eapd_init_verbs,
1179 alc663_m51va_init_verbs },
1180 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1181 .dac_nids = alc662_dac_nids,
1182 .dig_out_nid = ALC662_DIGOUT_NID,
1183 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1184 .channel_mode = alc662_3ST_2ch_modes,
1185 .unsol_event = alc_sku_unsol_event,
1186 .setup = alc663_m51va_setup,
1187 .init_hook = alc_inithook,
1188 },
1189 [ALC663_ASUS_G71V] = {
1190 .mixers = { alc663_g71v_mixer },
1191 .init_verbs = { alc662_init_verbs,
1192 alc662_eapd_init_verbs,
1193 alc663_g71v_init_verbs },
1194 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1195 .dac_nids = alc662_dac_nids,
1196 .dig_out_nid = ALC662_DIGOUT_NID,
1197 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1198 .channel_mode = alc662_3ST_2ch_modes,
1199 .unsol_event = alc_sku_unsol_event,
1200 .setup = alc663_g71v_setup,
1201 .init_hook = alc_inithook,
1202 },
1203 [ALC663_ASUS_H13] = {
1204 .mixers = { alc663_m51va_mixer },
1205 .init_verbs = { alc662_init_verbs,
1206 alc662_eapd_init_verbs,
1207 alc663_m51va_init_verbs },
1208 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1209 .dac_nids = alc662_dac_nids,
1210 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1211 .channel_mode = alc662_3ST_2ch_modes,
1212 .setup = alc663_m51va_setup,
1213 .unsol_event = alc_sku_unsol_event,
1214 .init_hook = alc_inithook,
1215 },
1216 [ALC663_ASUS_G50V] = {
1217 .mixers = { alc663_g50v_mixer },
1218 .init_verbs = { alc662_init_verbs,
1219 alc662_eapd_init_verbs,
1220 alc663_g50v_init_verbs },
1221 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1222 .dac_nids = alc662_dac_nids,
1223 .dig_out_nid = ALC662_DIGOUT_NID,
1224 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
1225 .channel_mode = alc662_3ST_6ch_modes,
1226 .input_mux = &alc663_capture_source,
1227 .unsol_event = alc_sku_unsol_event,
1228 .setup = alc663_g50v_setup,
1229 .init_hook = alc_inithook,
1230 },
1231 [ALC663_ASUS_MODE1] = {
1232 .mixers = { alc663_m51va_mixer },
1233 .cap_mixer = alc662_auto_capture_mixer,
1234 .init_verbs = { alc662_init_verbs,
1235 alc662_eapd_init_verbs,
1236 alc663_21jd_amic_init_verbs },
1237 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1238 .hp_nid = 0x03,
1239 .dac_nids = alc662_dac_nids,
1240 .dig_out_nid = ALC662_DIGOUT_NID,
1241 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1242 .channel_mode = alc662_3ST_2ch_modes,
1243 .unsol_event = alc_sku_unsol_event,
1244 .setup = alc663_mode1_setup,
1245 .init_hook = alc_inithook,
1246 },
1247 [ALC662_ASUS_MODE2] = {
1248 .mixers = { alc662_1bjd_mixer },
1249 .cap_mixer = alc662_auto_capture_mixer,
1250 .init_verbs = { alc662_init_verbs,
1251 alc662_eapd_init_verbs,
1252 alc662_1bjd_amic_init_verbs },
1253 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1254 .dac_nids = alc662_dac_nids,
1255 .dig_out_nid = ALC662_DIGOUT_NID,
1256 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1257 .channel_mode = alc662_3ST_2ch_modes,
1258 .unsol_event = alc_sku_unsol_event,
1259 .setup = alc662_mode2_setup,
1260 .init_hook = alc_inithook,
1261 },
1262 [ALC663_ASUS_MODE3] = {
1263 .mixers = { alc663_two_hp_m1_mixer },
1264 .cap_mixer = alc662_auto_capture_mixer,
1265 .init_verbs = { alc662_init_verbs,
1266 alc662_eapd_init_verbs,
1267 alc663_two_hp_amic_m1_init_verbs },
1268 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1269 .hp_nid = 0x03,
1270 .dac_nids = alc662_dac_nids,
1271 .dig_out_nid = ALC662_DIGOUT_NID,
1272 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1273 .channel_mode = alc662_3ST_2ch_modes,
1274 .unsol_event = alc_sku_unsol_event,
1275 .setup = alc663_mode3_setup,
1276 .init_hook = alc_inithook,
1277 },
1278 [ALC663_ASUS_MODE4] = {
1279 .mixers = { alc663_asus_21jd_clfe_mixer },
1280 .cap_mixer = alc662_auto_capture_mixer,
1281 .init_verbs = { alc662_init_verbs,
1282 alc662_eapd_init_verbs,
1283 alc663_21jd_amic_init_verbs},
1284 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1285 .hp_nid = 0x03,
1286 .dac_nids = alc662_dac_nids,
1287 .dig_out_nid = ALC662_DIGOUT_NID,
1288 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1289 .channel_mode = alc662_3ST_2ch_modes,
1290 .unsol_event = alc_sku_unsol_event,
1291 .setup = alc663_mode4_setup,
1292 .init_hook = alc_inithook,
1293 },
1294 [ALC663_ASUS_MODE5] = {
1295 .mixers = { alc663_asus_15jd_clfe_mixer },
1296 .cap_mixer = alc662_auto_capture_mixer,
1297 .init_verbs = { alc662_init_verbs,
1298 alc662_eapd_init_verbs,
1299 alc663_15jd_amic_init_verbs },
1300 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1301 .hp_nid = 0x03,
1302 .dac_nids = alc662_dac_nids,
1303 .dig_out_nid = ALC662_DIGOUT_NID,
1304 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1305 .channel_mode = alc662_3ST_2ch_modes,
1306 .unsol_event = alc_sku_unsol_event,
1307 .setup = alc663_mode5_setup,
1308 .init_hook = alc_inithook,
1309 },
1310 [ALC663_ASUS_MODE6] = {
1311 .mixers = { alc663_two_hp_m2_mixer },
1312 .cap_mixer = alc662_auto_capture_mixer,
1313 .init_verbs = { alc662_init_verbs,
1314 alc662_eapd_init_verbs,
1315 alc663_two_hp_amic_m2_init_verbs },
1316 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1317 .hp_nid = 0x03,
1318 .dac_nids = alc662_dac_nids,
1319 .dig_out_nid = ALC662_DIGOUT_NID,
1320 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1321 .channel_mode = alc662_3ST_2ch_modes,
1322 .unsol_event = alc_sku_unsol_event,
1323 .setup = alc663_mode6_setup,
1324 .init_hook = alc_inithook,
1325 },
1326 [ALC663_ASUS_MODE7] = {
1327 .mixers = { alc663_mode7_mixer },
1328 .cap_mixer = alc662_auto_capture_mixer,
1329 .init_verbs = { alc662_init_verbs,
1330 alc662_eapd_init_verbs,
1331 alc663_mode7_init_verbs },
1332 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1333 .hp_nid = 0x03,
1334 .dac_nids = alc662_dac_nids,
1335 .dig_out_nid = ALC662_DIGOUT_NID,
1336 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1337 .channel_mode = alc662_3ST_2ch_modes,
1338 .unsol_event = alc_sku_unsol_event,
1339 .setup = alc663_mode7_setup,
1340 .init_hook = alc_inithook,
1341 },
1342 [ALC663_ASUS_MODE8] = {
1343 .mixers = { alc663_mode8_mixer },
1344 .cap_mixer = alc662_auto_capture_mixer,
1345 .init_verbs = { alc662_init_verbs,
1346 alc662_eapd_init_verbs,
1347 alc663_mode8_init_verbs },
1348 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1349 .hp_nid = 0x03,
1350 .dac_nids = alc662_dac_nids,
1351 .dig_out_nid = ALC662_DIGOUT_NID,
1352 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1353 .channel_mode = alc662_3ST_2ch_modes,
1354 .unsol_event = alc_sku_unsol_event,
1355 .setup = alc663_mode8_setup,
1356 .init_hook = alc_inithook,
1357 },
1358 [ALC272_DELL] = {
1359 .mixers = { alc663_m51va_mixer },
1360 .cap_mixer = alc272_auto_capture_mixer,
1361 .init_verbs = { alc662_init_verbs,
1362 alc662_eapd_init_verbs,
1363 alc272_dell_init_verbs },
1364 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
1365 .dac_nids = alc272_dac_nids,
1366 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1367 .adc_nids = alc272_adc_nids,
1368 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
1369 .capsrc_nids = alc272_capsrc_nids,
1370 .channel_mode = alc662_3ST_2ch_modes,
1371 .unsol_event = alc_sku_unsol_event,
1372 .setup = alc663_m51va_setup,
1373 .init_hook = alc_inithook,
1374 },
1375 [ALC272_DELL_ZM1] = {
1376 .mixers = { alc663_m51va_mixer },
1377 .cap_mixer = alc662_auto_capture_mixer,
1378 .init_verbs = { alc662_init_verbs,
1379 alc662_eapd_init_verbs,
1380 alc272_dell_zm1_init_verbs },
1381 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
1382 .dac_nids = alc272_dac_nids,
1383 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1384 .adc_nids = alc662_adc_nids,
1385 .num_adc_nids = 1,
1386 .capsrc_nids = alc662_capsrc_nids,
1387 .channel_mode = alc662_3ST_2ch_modes,
1388 .unsol_event = alc_sku_unsol_event,
1389 .setup = alc663_m51va_setup,
1390 .init_hook = alc_inithook,
1391 },
1392 [ALC272_SAMSUNG_NC10] = {
1393 .mixers = { alc272_nc10_mixer },
1394 .init_verbs = { alc662_init_verbs,
1395 alc662_eapd_init_verbs,
1396 alc663_21jd_amic_init_verbs },
1397 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
1398 .dac_nids = alc272_dac_nids,
1399 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1400 .channel_mode = alc662_3ST_2ch_modes,
1401 /*.input_mux = &alc272_nc10_capture_source,*/
1402 .unsol_event = alc_sku_unsol_event,
1403 .setup = alc663_mode4_setup,
1404 .init_hook = alc_inithook,
1405 },
1406};
1407
1408
diff --git a/sound/pci/hda/alc680_quirks.c b/sound/pci/hda/alc680_quirks.c
deleted file mode 100644
index 0eeb227c7bc..00000000000
--- a/sound/pci/hda/alc680_quirks.c
+++ /dev/null
@@ -1,222 +0,0 @@
1/*
2 * ALC680 quirk models
3 * included by patch_realtek.c
4 */
5
6/* ALC680 models */
7enum {
8 ALC680_AUTO,
9 ALC680_BASE,
10 ALC680_MODEL_LAST,
11};
12
13#define ALC680_DIGIN_NID ALC880_DIGIN_NID
14#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
15#define alc680_modes alc260_modes
16
17static const hda_nid_t alc680_dac_nids[3] = {
18 /* Lout1, Lout2, hp */
19 0x02, 0x03, 0x04
20};
21
22static const hda_nid_t alc680_adc_nids[3] = {
23 /* ADC0-2 */
24 /* DMIC, MIC, Line-in*/
25 0x07, 0x08, 0x09
26};
27
28/*
29 * Analog capture ADC cgange
30 */
31static hda_nid_t alc680_get_cur_adc(struct hda_codec *codec)
32{
33 static hda_nid_t pins[] = {0x18, 0x19};
34 static hda_nid_t adcs[] = {0x08, 0x09};
35 int i;
36
37 for (i = 0; i < ARRAY_SIZE(pins); i++) {
38 if (!is_jack_detectable(codec, pins[i]))
39 continue;
40 if (snd_hda_jack_detect(codec, pins[i]))
41 return adcs[i];
42 }
43 return 0x07;
44}
45
46static void alc680_rec_autoswitch(struct hda_codec *codec)
47{
48 struct alc_spec *spec = codec->spec;
49 hda_nid_t nid = alc680_get_cur_adc(codec);
50 if (spec->cur_adc && nid != spec->cur_adc) {
51 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
52 spec->cur_adc = nid;
53 snd_hda_codec_setup_stream(codec, nid,
54 spec->cur_adc_stream_tag, 0,
55 spec->cur_adc_format);
56 }
57}
58
59static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
60 struct hda_codec *codec,
61 unsigned int stream_tag,
62 unsigned int format,
63 struct snd_pcm_substream *substream)
64{
65 struct alc_spec *spec = codec->spec;
66 hda_nid_t nid = alc680_get_cur_adc(codec);
67
68 spec->cur_adc = nid;
69 spec->cur_adc_stream_tag = stream_tag;
70 spec->cur_adc_format = format;
71 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
72 return 0;
73}
74
75static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
76 struct hda_codec *codec,
77 struct snd_pcm_substream *substream)
78{
79 struct alc_spec *spec = codec->spec;
80 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
81 spec->cur_adc = 0;
82 return 0;
83}
84
85static const struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
86 .substreams = 1, /* can be overridden */
87 .channels_min = 2,
88 .channels_max = 2,
89 /* NID is set in alc_build_pcms */
90 .ops = {
91 .prepare = alc680_capture_pcm_prepare,
92 .cleanup = alc680_capture_pcm_cleanup
93 },
94};
95
96static const struct snd_kcontrol_new alc680_base_mixer[] = {
97 /* output mixer control */
98 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
99 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
100 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
101 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
102 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT),
103 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
104 HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT),
105 { }
106};
107
108static const struct hda_bind_ctls alc680_bind_cap_vol = {
109 .ops = &snd_hda_bind_vol,
110 .values = {
111 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
112 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
113 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
114 0
115 },
116};
117
118static const struct hda_bind_ctls alc680_bind_cap_switch = {
119 .ops = &snd_hda_bind_sw,
120 .values = {
121 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
122 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
123 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
124 0
125 },
126};
127
128static const struct snd_kcontrol_new alc680_master_capture_mixer[] = {
129 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
130 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
131 { } /* end */
132};
133
134/*
135 * generic initialization of ADC, input mixers and output mixers
136 */
137static const struct hda_verb alc680_init_verbs[] = {
138 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
139 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
140 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
141
142 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
143 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
144 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
145 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
146 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
147 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
148
149 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
150 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
151 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
152 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
153 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
154
155 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
156 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_MIC_EVENT | AC_USRSP_EN},
157 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_MIC_EVENT | AC_USRSP_EN},
158
159 { }
160};
161
162/* toggle speaker-output according to the hp-jack state */
163static void alc680_base_setup(struct hda_codec *codec)
164{
165 struct alc_spec *spec = codec->spec;
166
167 spec->autocfg.hp_pins[0] = 0x16;
168 spec->autocfg.speaker_pins[0] = 0x14;
169 spec->autocfg.speaker_pins[1] = 0x15;
170 spec->autocfg.num_inputs = 2;
171 spec->autocfg.inputs[0].pin = 0x18;
172 spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
173 spec->autocfg.inputs[1].pin = 0x19;
174 spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
175 spec->automute = 1;
176 spec->automute_mode = ALC_AUTOMUTE_AMP;
177}
178
179static void alc680_unsol_event(struct hda_codec *codec,
180 unsigned int res)
181{
182 if ((res >> 26) == ALC_HP_EVENT)
183 alc_hp_automute(codec);
184 if ((res >> 26) == ALC_MIC_EVENT)
185 alc680_rec_autoswitch(codec);
186}
187
188static void alc680_inithook(struct hda_codec *codec)
189{
190 alc_hp_automute(codec);
191 alc680_rec_autoswitch(codec);
192}
193
194/*
195 * configuration and preset
196 */
197static const char * const alc680_models[ALC680_MODEL_LAST] = {
198 [ALC680_BASE] = "base",
199 [ALC680_AUTO] = "auto",
200};
201
202static const struct snd_pci_quirk alc680_cfg_tbl[] = {
203 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
204 {}
205};
206
207static const struct alc_config_preset alc680_presets[] = {
208 [ALC680_BASE] = {
209 .mixers = { alc680_base_mixer },
210 .cap_mixer = alc680_master_capture_mixer,
211 .init_verbs = { alc680_init_verbs },
212 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
213 .dac_nids = alc680_dac_nids,
214 .dig_out_nid = ALC680_DIGOUT_NID,
215 .num_channel_mode = ARRAY_SIZE(alc680_modes),
216 .channel_mode = alc680_modes,
217 .unsol_event = alc680_unsol_event,
218 .setup = alc680_base_setup,
219 .init_hook = alc680_inithook,
220
221 },
222};
diff --git a/sound/pci/hda/alc861_quirks.c b/sound/pci/hda/alc861_quirks.c
deleted file mode 100644
index d719ec6350e..00000000000
--- a/sound/pci/hda/alc861_quirks.c
+++ /dev/null
@@ -1,725 +0,0 @@
1/*
2 * ALC660/ALC861 quirk models
3 * included by patch_realtek.c
4 */
5
6/* ALC861 models */
7enum {
8 ALC861_AUTO,
9 ALC861_3ST,
10 ALC660_3ST,
11 ALC861_3ST_DIG,
12 ALC861_6ST_DIG,
13 ALC861_UNIWILL_M31,
14 ALC861_TOSHIBA,
15 ALC861_ASUS,
16 ALC861_ASUS_LAPTOP,
17 ALC861_MODEL_LAST,
18};
19
20/*
21 * ALC861 channel source setting (2/6 channel selection for 3-stack)
22 */
23
24/*
25 * set the path ways for 2 channel output
26 * need to set the codec line out and mic 1 pin widgets to inputs
27 */
28static const struct hda_verb alc861_threestack_ch2_init[] = {
29 /* set pin widget 1Ah (line in) for input */
30 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
31 /* set pin widget 18h (mic1/2) for input, for mic also enable
32 * the vref
33 */
34 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
35
36 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
37#if 0
38 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
39 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
40#endif
41 { } /* end */
42};
43/*
44 * 6ch mode
45 * need to set the codec line out and mic 1 pin widgets to outputs
46 */
47static const struct hda_verb alc861_threestack_ch6_init[] = {
48 /* set pin widget 1Ah (line in) for output (Back Surround)*/
49 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
50 /* set pin widget 18h (mic1) for output (CLFE)*/
51 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
52
53 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
54 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
55
56 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
57#if 0
58 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
59 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
60#endif
61 { } /* end */
62};
63
64static const struct hda_channel_mode alc861_threestack_modes[2] = {
65 { 2, alc861_threestack_ch2_init },
66 { 6, alc861_threestack_ch6_init },
67};
68/* Set mic1 as input and unmute the mixer */
69static const struct hda_verb alc861_uniwill_m31_ch2_init[] = {
70 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
71 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
72 { } /* end */
73};
74/* Set mic1 as output and mute mixer */
75static const struct hda_verb alc861_uniwill_m31_ch4_init[] = {
76 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
77 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
78 { } /* end */
79};
80
81static const struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
82 { 2, alc861_uniwill_m31_ch2_init },
83 { 4, alc861_uniwill_m31_ch4_init },
84};
85
86/* Set mic1 and line-in as input and unmute the mixer */
87static const struct hda_verb alc861_asus_ch2_init[] = {
88 /* set pin widget 1Ah (line in) for input */
89 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
90 /* set pin widget 18h (mic1/2) for input, for mic also enable
91 * the vref
92 */
93 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
94
95 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
96#if 0
97 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
98 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
99#endif
100 { } /* end */
101};
102/* Set mic1 nad line-in as output and mute mixer */
103static const struct hda_verb alc861_asus_ch6_init[] = {
104 /* set pin widget 1Ah (line in) for output (Back Surround)*/
105 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
106 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
107 /* set pin widget 18h (mic1) for output (CLFE)*/
108 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
109 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
110 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
111 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
112
113 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
114#if 0
115 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
116 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
117#endif
118 { } /* end */
119};
120
121static const struct hda_channel_mode alc861_asus_modes[2] = {
122 { 2, alc861_asus_ch2_init },
123 { 6, alc861_asus_ch6_init },
124};
125
126/* patch-ALC861 */
127
128static const struct snd_kcontrol_new alc861_base_mixer[] = {
129 /* output mixer control */
130 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
131 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
132 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
133 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
134 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
135
136 /*Input mixer control */
137 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
138 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
139 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
140 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
141 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
142 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
143 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
144 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
145 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
146 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
147
148 { } /* end */
149};
150
151static const struct snd_kcontrol_new alc861_3ST_mixer[] = {
152 /* output mixer control */
153 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
154 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
155 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
156 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
157 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
158
159 /* Input mixer control */
160 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
161 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
162 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
163 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
164 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
165 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
166 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
167 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
168 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
169 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
170
171 {
172 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
173 .name = "Channel Mode",
174 .info = alc_ch_mode_info,
175 .get = alc_ch_mode_get,
176 .put = alc_ch_mode_put,
177 .private_value = ARRAY_SIZE(alc861_threestack_modes),
178 },
179 { } /* end */
180};
181
182static const struct snd_kcontrol_new alc861_toshiba_mixer[] = {
183 /* output mixer control */
184 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
185 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
186 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
187
188 { } /* end */
189};
190
191static const struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
192 /* output mixer control */
193 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
194 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
195 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
196 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
197 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
198
199 /* Input mixer control */
200 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
201 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
202 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
203 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
204 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
205 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
206 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
207 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
208 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
209 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
210
211 {
212 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
213 .name = "Channel Mode",
214 .info = alc_ch_mode_info,
215 .get = alc_ch_mode_get,
216 .put = alc_ch_mode_put,
217 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
218 },
219 { } /* end */
220};
221
222static const struct snd_kcontrol_new alc861_asus_mixer[] = {
223 /* output mixer control */
224 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
225 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
226 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
227 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
228 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
229
230 /* Input mixer control */
231 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
232 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
233 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
234 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
235 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
236 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
237 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
238 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
239 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
240 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
241
242 {
243 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
244 .name = "Channel Mode",
245 .info = alc_ch_mode_info,
246 .get = alc_ch_mode_get,
247 .put = alc_ch_mode_put,
248 .private_value = ARRAY_SIZE(alc861_asus_modes),
249 },
250 { }
251};
252
253/* additional mixer */
254static const struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
255 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
256 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
257 { }
258};
259
260/*
261 * generic initialization of ADC, input mixers and output mixers
262 */
263static const struct hda_verb alc861_base_init_verbs[] = {
264 /*
265 * Unmute ADC0 and set the default input to mic-in
266 */
267 /* port-A for surround (rear panel) */
268 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
269 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
270 /* port-B for mic-in (rear panel) with vref */
271 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
272 /* port-C for line-in (rear panel) */
273 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
274 /* port-D for Front */
275 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
276 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
277 /* port-E for HP out (front panel) */
278 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
279 /* route front PCM to HP */
280 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
281 /* port-F for mic-in (front panel) with vref */
282 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
283 /* port-G for CLFE (rear panel) */
284 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
285 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
286 /* port-H for side (rear panel) */
287 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
288 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
289 /* CD-in */
290 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
291 /* route front mic to ADC1*/
292 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
293 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
294
295 /* Unmute DAC0~3 & spdif out*/
296 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
297 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
298 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
299 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
300 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
301
302 /* Unmute Mixer 14 (mic) 1c (Line in)*/
303 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
304 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
305 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
306 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
307
308 /* Unmute Stereo Mixer 15 */
309 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
310 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
311 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
312 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
313
314 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
315 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
316 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
317 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
318 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
319 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
320 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
321 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
322 /* hp used DAC 3 (Front) */
323 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
324 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
325
326 { }
327};
328
329static const struct hda_verb alc861_threestack_init_verbs[] = {
330 /*
331 * Unmute ADC0 and set the default input to mic-in
332 */
333 /* port-A for surround (rear panel) */
334 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
335 /* port-B for mic-in (rear panel) with vref */
336 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
337 /* port-C for line-in (rear panel) */
338 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
339 /* port-D for Front */
340 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
341 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
342 /* port-E for HP out (front panel) */
343 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
344 /* route front PCM to HP */
345 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
346 /* port-F for mic-in (front panel) with vref */
347 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
348 /* port-G for CLFE (rear panel) */
349 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
350 /* port-H for side (rear panel) */
351 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
352 /* CD-in */
353 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
354 /* route front mic to ADC1*/
355 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
356 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
357 /* Unmute DAC0~3 & spdif out*/
358 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
359 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
360 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
361 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
362 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
363
364 /* Unmute Mixer 14 (mic) 1c (Line in)*/
365 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
366 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
367 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
368 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
369
370 /* Unmute Stereo Mixer 15 */
371 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
372 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
373 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
374 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
375
376 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
377 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
378 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
379 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
380 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
381 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
382 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
383 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
384 /* hp used DAC 3 (Front) */
385 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
386 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
387 { }
388};
389
390static const struct hda_verb alc861_uniwill_m31_init_verbs[] = {
391 /*
392 * Unmute ADC0 and set the default input to mic-in
393 */
394 /* port-A for surround (rear panel) */
395 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
396 /* port-B for mic-in (rear panel) with vref */
397 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
398 /* port-C for line-in (rear panel) */
399 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
400 /* port-D for Front */
401 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
402 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
403 /* port-E for HP out (front panel) */
404 /* this has to be set to VREF80 */
405 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
406 /* route front PCM to HP */
407 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
408 /* port-F for mic-in (front panel) with vref */
409 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
410 /* port-G for CLFE (rear panel) */
411 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
412 /* port-H for side (rear panel) */
413 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
414 /* CD-in */
415 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
416 /* route front mic to ADC1*/
417 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
418 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
419 /* Unmute DAC0~3 & spdif out*/
420 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
421 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
422 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
423 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
424 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
425
426 /* Unmute Mixer 14 (mic) 1c (Line in)*/
427 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
428 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
429 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
430 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
431
432 /* Unmute Stereo Mixer 15 */
433 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
434 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
435 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
436 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
437
438 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
439 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
440 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
441 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
442 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
443 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
444 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
445 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
446 /* hp used DAC 3 (Front) */
447 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
448 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
449 { }
450};
451
452static const struct hda_verb alc861_asus_init_verbs[] = {
453 /*
454 * Unmute ADC0 and set the default input to mic-in
455 */
456 /* port-A for surround (rear panel)
457 * according to codec#0 this is the HP jack
458 */
459 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
460 /* route front PCM to HP */
461 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
462 /* port-B for mic-in (rear panel) with vref */
463 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
464 /* port-C for line-in (rear panel) */
465 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
466 /* port-D for Front */
467 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
468 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
469 /* port-E for HP out (front panel) */
470 /* this has to be set to VREF80 */
471 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
472 /* route front PCM to HP */
473 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
474 /* port-F for mic-in (front panel) with vref */
475 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
476 /* port-G for CLFE (rear panel) */
477 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
478 /* port-H for side (rear panel) */
479 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
480 /* CD-in */
481 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
482 /* route front mic to ADC1*/
483 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
484 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
485 /* Unmute DAC0~3 & spdif out*/
486 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
487 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
488 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
489 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
490 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
491 /* Unmute Mixer 14 (mic) 1c (Line in)*/
492 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
493 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
494 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
495 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
496
497 /* Unmute Stereo Mixer 15 */
498 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
499 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
500 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
501 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
502
503 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
504 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
505 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
506 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
507 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
508 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
509 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
510 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
511 /* hp used DAC 3 (Front) */
512 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
513 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
514 { }
515};
516
517/* additional init verbs for ASUS laptops */
518static const struct hda_verb alc861_asus_laptop_init_verbs[] = {
519 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
520 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
521 { }
522};
523
524static const struct hda_verb alc861_toshiba_init_verbs[] = {
525 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
526
527 { }
528};
529
530/* toggle speaker-output according to the hp-jack state */
531static void alc861_toshiba_automute(struct hda_codec *codec)
532{
533 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
534
535 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
536 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
537 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
538 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
539}
540
541static void alc861_toshiba_unsol_event(struct hda_codec *codec,
542 unsigned int res)
543{
544 if ((res >> 26) == ALC_HP_EVENT)
545 alc861_toshiba_automute(codec);
546}
547
548#define ALC861_DIGOUT_NID 0x07
549
550static const struct hda_channel_mode alc861_8ch_modes[1] = {
551 { 8, NULL }
552};
553
554static const hda_nid_t alc861_dac_nids[4] = {
555 /* front, surround, clfe, side */
556 0x03, 0x06, 0x05, 0x04
557};
558
559static const hda_nid_t alc660_dac_nids[3] = {
560 /* front, clfe, surround */
561 0x03, 0x05, 0x06
562};
563
564static const hda_nid_t alc861_adc_nids[1] = {
565 /* ADC0-2 */
566 0x08,
567};
568
569static const struct hda_input_mux alc861_capture_source = {
570 .num_items = 5,
571 .items = {
572 { "Mic", 0x0 },
573 { "Front Mic", 0x3 },
574 { "Line", 0x1 },
575 { "CD", 0x4 },
576 { "Mixer", 0x5 },
577 },
578};
579
580/*
581 * configuration and preset
582 */
583static const char * const alc861_models[ALC861_MODEL_LAST] = {
584 [ALC861_3ST] = "3stack",
585 [ALC660_3ST] = "3stack-660",
586 [ALC861_3ST_DIG] = "3stack-dig",
587 [ALC861_6ST_DIG] = "6stack-dig",
588 [ALC861_UNIWILL_M31] = "uniwill-m31",
589 [ALC861_TOSHIBA] = "toshiba",
590 [ALC861_ASUS] = "asus",
591 [ALC861_ASUS_LAPTOP] = "asus-laptop",
592 [ALC861_AUTO] = "auto",
593};
594
595static const struct snd_pci_quirk alc861_cfg_tbl[] = {
596 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
597 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
598 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
599 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
600 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
601 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
602 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
603 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
604 * Any other models that need this preset?
605 */
606 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
607 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
608 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
609 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
610 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
611 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
612 /* FIXME: the below seems conflict */
613 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
614 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
615 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
616 {}
617};
618
619static const struct alc_config_preset alc861_presets[] = {
620 [ALC861_3ST] = {
621 .mixers = { alc861_3ST_mixer },
622 .init_verbs = { alc861_threestack_init_verbs },
623 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
624 .dac_nids = alc861_dac_nids,
625 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
626 .channel_mode = alc861_threestack_modes,
627 .need_dac_fix = 1,
628 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
629 .adc_nids = alc861_adc_nids,
630 .input_mux = &alc861_capture_source,
631 },
632 [ALC861_3ST_DIG] = {
633 .mixers = { alc861_base_mixer },
634 .init_verbs = { alc861_threestack_init_verbs },
635 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
636 .dac_nids = alc861_dac_nids,
637 .dig_out_nid = ALC861_DIGOUT_NID,
638 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
639 .channel_mode = alc861_threestack_modes,
640 .need_dac_fix = 1,
641 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
642 .adc_nids = alc861_adc_nids,
643 .input_mux = &alc861_capture_source,
644 },
645 [ALC861_6ST_DIG] = {
646 .mixers = { alc861_base_mixer },
647 .init_verbs = { alc861_base_init_verbs },
648 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
649 .dac_nids = alc861_dac_nids,
650 .dig_out_nid = ALC861_DIGOUT_NID,
651 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
652 .channel_mode = alc861_8ch_modes,
653 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
654 .adc_nids = alc861_adc_nids,
655 .input_mux = &alc861_capture_source,
656 },
657 [ALC660_3ST] = {
658 .mixers = { alc861_3ST_mixer },
659 .init_verbs = { alc861_threestack_init_verbs },
660 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
661 .dac_nids = alc660_dac_nids,
662 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
663 .channel_mode = alc861_threestack_modes,
664 .need_dac_fix = 1,
665 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
666 .adc_nids = alc861_adc_nids,
667 .input_mux = &alc861_capture_source,
668 },
669 [ALC861_UNIWILL_M31] = {
670 .mixers = { alc861_uniwill_m31_mixer },
671 .init_verbs = { alc861_uniwill_m31_init_verbs },
672 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
673 .dac_nids = alc861_dac_nids,
674 .dig_out_nid = ALC861_DIGOUT_NID,
675 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
676 .channel_mode = alc861_uniwill_m31_modes,
677 .need_dac_fix = 1,
678 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
679 .adc_nids = alc861_adc_nids,
680 .input_mux = &alc861_capture_source,
681 },
682 [ALC861_TOSHIBA] = {
683 .mixers = { alc861_toshiba_mixer },
684 .init_verbs = { alc861_base_init_verbs,
685 alc861_toshiba_init_verbs },
686 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
687 .dac_nids = alc861_dac_nids,
688 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
689 .channel_mode = alc883_3ST_2ch_modes,
690 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
691 .adc_nids = alc861_adc_nids,
692 .input_mux = &alc861_capture_source,
693 .unsol_event = alc861_toshiba_unsol_event,
694 .init_hook = alc861_toshiba_automute,
695 },
696 [ALC861_ASUS] = {
697 .mixers = { alc861_asus_mixer },
698 .init_verbs = { alc861_asus_init_verbs },
699 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
700 .dac_nids = alc861_dac_nids,
701 .dig_out_nid = ALC861_DIGOUT_NID,
702 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
703 .channel_mode = alc861_asus_modes,
704 .need_dac_fix = 1,
705 .hp_nid = 0x06,
706 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
707 .adc_nids = alc861_adc_nids,
708 .input_mux = &alc861_capture_source,
709 },
710 [ALC861_ASUS_LAPTOP] = {
711 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
712 .init_verbs = { alc861_asus_init_verbs,
713 alc861_asus_laptop_init_verbs },
714 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
715 .dac_nids = alc861_dac_nids,
716 .dig_out_nid = ALC861_DIGOUT_NID,
717 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
718 .channel_mode = alc883_3ST_2ch_modes,
719 .need_dac_fix = 1,
720 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
721 .adc_nids = alc861_adc_nids,
722 .input_mux = &alc861_capture_source,
723 },
724};
725
diff --git a/sound/pci/hda/alc861vd_quirks.c b/sound/pci/hda/alc861vd_quirks.c
deleted file mode 100644
index 8f28450f41f..00000000000
--- a/sound/pci/hda/alc861vd_quirks.c
+++ /dev/null
@@ -1,605 +0,0 @@
1/*
2 * ALC660-VD/ALC861-VD quirk models
3 * included by patch_realtek.c
4 */
5
6/* ALC861-VD models */
7enum {
8 ALC861VD_AUTO,
9 ALC660VD_3ST,
10 ALC660VD_3ST_DIG,
11 ALC660VD_ASUS_V1S,
12 ALC861VD_3ST,
13 ALC861VD_3ST_DIG,
14 ALC861VD_6ST_DIG,
15 ALC861VD_LENOVO,
16 ALC861VD_DALLAS,
17 ALC861VD_HP,
18 ALC861VD_MODEL_LAST,
19};
20
21#define ALC861VD_DIGOUT_NID 0x06
22
23static const hda_nid_t alc861vd_dac_nids[4] = {
24 /* front, surr, clfe, side surr */
25 0x02, 0x03, 0x04, 0x05
26};
27
28/* dac_nids for ALC660vd are in a different order - according to
29 * Realtek's driver.
30 * This should probably result in a different mixer for 6stack models
31 * of ALC660vd codecs, but for now there is only 3stack mixer
32 * - and it is the same as in 861vd.
33 * adc_nids in ALC660vd are (is) the same as in 861vd
34 */
35static const hda_nid_t alc660vd_dac_nids[3] = {
36 /* front, rear, clfe, rear_surr */
37 0x02, 0x04, 0x03
38};
39
40static const hda_nid_t alc861vd_adc_nids[1] = {
41 /* ADC0 */
42 0x09,
43};
44
45static const hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
46
47/* input MUX */
48/* FIXME: should be a matrix-type input source selection */
49static const struct hda_input_mux alc861vd_capture_source = {
50 .num_items = 4,
51 .items = {
52 { "Mic", 0x0 },
53 { "Front Mic", 0x1 },
54 { "Line", 0x2 },
55 { "CD", 0x4 },
56 },
57};
58
59static const struct hda_input_mux alc861vd_dallas_capture_source = {
60 .num_items = 2,
61 .items = {
62 { "Mic", 0x0 },
63 { "Internal Mic", 0x1 },
64 },
65};
66
67static const struct hda_input_mux alc861vd_hp_capture_source = {
68 .num_items = 2,
69 .items = {
70 { "Front Mic", 0x0 },
71 { "ATAPI Mic", 0x1 },
72 },
73};
74
75/*
76 * 2ch mode
77 */
78static const struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
79 { 2, NULL }
80};
81
82/*
83 * 6ch mode
84 */
85static const struct hda_verb alc861vd_6stack_ch6_init[] = {
86 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
87 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
88 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
89 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
90 { } /* end */
91};
92
93/*
94 * 8ch mode
95 */
96static const struct hda_verb alc861vd_6stack_ch8_init[] = {
97 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
98 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
99 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
100 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
101 { } /* end */
102};
103
104static const struct hda_channel_mode alc861vd_6stack_modes[2] = {
105 { 6, alc861vd_6stack_ch6_init },
106 { 8, alc861vd_6stack_ch8_init },
107};
108
109static const struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
110 {
111 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
112 .name = "Channel Mode",
113 .info = alc_ch_mode_info,
114 .get = alc_ch_mode_get,
115 .put = alc_ch_mode_put,
116 },
117 { } /* end */
118};
119
120/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
121 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
122 */
123static const struct snd_kcontrol_new alc861vd_6st_mixer[] = {
124 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
125 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
126
127 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
128 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
129
130 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
131 HDA_OUTPUT),
132 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
133 HDA_OUTPUT),
134 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
135 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
136
137 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
138 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
139
140 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
141
142 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
143 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
144 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
145
146 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
147 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
148 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
149
150 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
151 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
152
153 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
154 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
155
156 { } /* end */
157};
158
159static const struct snd_kcontrol_new alc861vd_3st_mixer[] = {
160 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
161 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
162
163 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
164
165 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
166 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
167 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
168
169 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
170 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
171 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
172
173 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
174 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
175
176 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
177 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
178
179 { } /* end */
180};
181
182static const struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
183 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
184 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
185 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
186
187 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
188
189 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
190 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
191 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
192
193 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
194 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
195 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
196
197 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
198 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
199
200 { } /* end */
201};
202
203/* Pin assignment: Speaker=0x14, HP = 0x15,
204 * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
205 */
206static const struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
207 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
208 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
209 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
210 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
211 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
212 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
213 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
214 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
215 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
216 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
217 { } /* end */
218};
219
220/* Pin assignment: Speaker=0x14, Line-out = 0x15,
221 * Front Mic=0x18, ATAPI Mic = 0x19,
222 */
223static const struct snd_kcontrol_new alc861vd_hp_mixer[] = {
224 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
225 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
226 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
227 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
228 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
229 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
230 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
231 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
232
233 { } /* end */
234};
235
236/*
237 * generic initialization of ADC, input mixers and output mixers
238 */
239static const struct hda_verb alc861vd_volume_init_verbs[] = {
240 /*
241 * Unmute ADC0 and set the default input to mic-in
242 */
243 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
244 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
245
246 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
247 * the analog-loopback mixer widget
248 */
249 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
250 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
251 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
252 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
253 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
254 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
255
256 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
257 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
258 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
259 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
260 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
261
262 /*
263 * Set up output mixers (0x02 - 0x05)
264 */
265 /* set vol=0 to output mixers */
266 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
267 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
268 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
269 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
270
271 /* set up input amps for analog loopback */
272 /* Amp Indices: DAC = 0, mixer = 1 */
273 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
274 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
275 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
276 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
277 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
278 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
279 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
280 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
281
282 { }
283};
284
285/*
286 * 3-stack pin configuration:
287 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
288 */
289static const struct hda_verb alc861vd_3stack_init_verbs[] = {
290 /*
291 * Set pin mode and muting
292 */
293 /* set front pin widgets 0x14 for output */
294 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
295 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
296 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
297
298 /* Mic (rear) pin: input vref at 80% */
299 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
300 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
301 /* Front Mic pin: input vref at 80% */
302 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
303 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
304 /* Line In pin: input */
305 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
306 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
307 /* Line-2 In: Headphone output (output 0 - 0x0c) */
308 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
309 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
310 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
311 /* CD pin widget for input */
312 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
313
314 { }
315};
316
317/*
318 * 6-stack pin configuration:
319 */
320static const struct hda_verb alc861vd_6stack_init_verbs[] = {
321 /*
322 * Set pin mode and muting
323 */
324 /* set front pin widgets 0x14 for output */
325 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
326 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
327 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
328
329 /* Rear Pin: output 1 (0x0d) */
330 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
331 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
332 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
333 /* CLFE Pin: output 2 (0x0e) */
334 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
335 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
336 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
337 /* Side Pin: output 3 (0x0f) */
338 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
339 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
340 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
341
342 /* Mic (rear) pin: input vref at 80% */
343 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
344 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
345 /* Front Mic pin: input vref at 80% */
346 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
347 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
348 /* Line In pin: input */
349 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
350 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
351 /* Line-2 In: Headphone output (output 0 - 0x0c) */
352 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
353 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
354 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
355 /* CD pin widget for input */
356 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
357
358 { }
359};
360
361static const struct hda_verb alc861vd_eapd_verbs[] = {
362 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
363 { }
364};
365
366static const struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
367 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
368 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
369 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
370 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
371 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
372 {}
373};
374
375static void alc861vd_lenovo_setup(struct hda_codec *codec)
376{
377 struct alc_spec *spec = codec->spec;
378 spec->autocfg.hp_pins[0] = 0x1b;
379 spec->autocfg.speaker_pins[0] = 0x14;
380 spec->automute = 1;
381 spec->automute_mode = ALC_AUTOMUTE_AMP;
382}
383
384static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
385{
386 alc_hp_automute(codec);
387 alc88x_simple_mic_automute(codec);
388}
389
390static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
391 unsigned int res)
392{
393 switch (res >> 26) {
394 case ALC_MIC_EVENT:
395 alc88x_simple_mic_automute(codec);
396 break;
397 default:
398 alc_sku_unsol_event(codec, res);
399 break;
400 }
401}
402
403static const struct hda_verb alc861vd_dallas_verbs[] = {
404 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
405 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
406 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
407 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
408
409 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
410 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
411 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
412 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
413 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
414 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
415 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
416 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
417
418 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
419 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
420 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
421 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
422 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
423 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
424 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
425 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
426
427 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
428 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
429 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
430 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
431 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
432 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
433 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
434 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
435
436 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
437 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
438 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
439 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
440
441 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
442 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
443 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
444
445 { } /* end */
446};
447
448/* toggle speaker-output according to the hp-jack state */
449static void alc861vd_dallas_setup(struct hda_codec *codec)
450{
451 struct alc_spec *spec = codec->spec;
452
453 spec->autocfg.hp_pins[0] = 0x15;
454 spec->autocfg.speaker_pins[0] = 0x14;
455 spec->automute = 1;
456 spec->automute_mode = ALC_AUTOMUTE_AMP;
457}
458
459/*
460 * configuration and preset
461 */
462static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = {
463 [ALC660VD_3ST] = "3stack-660",
464 [ALC660VD_3ST_DIG] = "3stack-660-digout",
465 [ALC660VD_ASUS_V1S] = "asus-v1s",
466 [ALC861VD_3ST] = "3stack",
467 [ALC861VD_3ST_DIG] = "3stack-digout",
468 [ALC861VD_6ST_DIG] = "6stack-digout",
469 [ALC861VD_LENOVO] = "lenovo",
470 [ALC861VD_DALLAS] = "dallas",
471 [ALC861VD_HP] = "hp",
472 [ALC861VD_AUTO] = "auto",
473};
474
475static const struct snd_pci_quirk alc861vd_cfg_tbl[] = {
476 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
477 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
478 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
479 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
480 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
481 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
482 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
483 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
484 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
485 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
486 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
487 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
488 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
489 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
490 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
491 {}
492};
493
494static const struct alc_config_preset alc861vd_presets[] = {
495 [ALC660VD_3ST] = {
496 .mixers = { alc861vd_3st_mixer },
497 .init_verbs = { alc861vd_volume_init_verbs,
498 alc861vd_3stack_init_verbs },
499 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
500 .dac_nids = alc660vd_dac_nids,
501 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
502 .channel_mode = alc861vd_3stack_2ch_modes,
503 .input_mux = &alc861vd_capture_source,
504 },
505 [ALC660VD_3ST_DIG] = {
506 .mixers = { alc861vd_3st_mixer },
507 .init_verbs = { alc861vd_volume_init_verbs,
508 alc861vd_3stack_init_verbs },
509 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
510 .dac_nids = alc660vd_dac_nids,
511 .dig_out_nid = ALC861VD_DIGOUT_NID,
512 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
513 .channel_mode = alc861vd_3stack_2ch_modes,
514 .input_mux = &alc861vd_capture_source,
515 },
516 [ALC861VD_3ST] = {
517 .mixers = { alc861vd_3st_mixer },
518 .init_verbs = { alc861vd_volume_init_verbs,
519 alc861vd_3stack_init_verbs },
520 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
521 .dac_nids = alc861vd_dac_nids,
522 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
523 .channel_mode = alc861vd_3stack_2ch_modes,
524 .input_mux = &alc861vd_capture_source,
525 },
526 [ALC861VD_3ST_DIG] = {
527 .mixers = { alc861vd_3st_mixer },
528 .init_verbs = { alc861vd_volume_init_verbs,
529 alc861vd_3stack_init_verbs },
530 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
531 .dac_nids = alc861vd_dac_nids,
532 .dig_out_nid = ALC861VD_DIGOUT_NID,
533 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
534 .channel_mode = alc861vd_3stack_2ch_modes,
535 .input_mux = &alc861vd_capture_source,
536 },
537 [ALC861VD_6ST_DIG] = {
538 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
539 .init_verbs = { alc861vd_volume_init_verbs,
540 alc861vd_6stack_init_verbs },
541 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
542 .dac_nids = alc861vd_dac_nids,
543 .dig_out_nid = ALC861VD_DIGOUT_NID,
544 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
545 .channel_mode = alc861vd_6stack_modes,
546 .input_mux = &alc861vd_capture_source,
547 },
548 [ALC861VD_LENOVO] = {
549 .mixers = { alc861vd_lenovo_mixer },
550 .init_verbs = { alc861vd_volume_init_verbs,
551 alc861vd_3stack_init_verbs,
552 alc861vd_eapd_verbs,
553 alc861vd_lenovo_unsol_verbs },
554 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
555 .dac_nids = alc660vd_dac_nids,
556 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
557 .channel_mode = alc861vd_3stack_2ch_modes,
558 .input_mux = &alc861vd_capture_source,
559 .unsol_event = alc861vd_lenovo_unsol_event,
560 .setup = alc861vd_lenovo_setup,
561 .init_hook = alc861vd_lenovo_init_hook,
562 },
563 [ALC861VD_DALLAS] = {
564 .mixers = { alc861vd_dallas_mixer },
565 .init_verbs = { alc861vd_dallas_verbs },
566 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
567 .dac_nids = alc861vd_dac_nids,
568 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
569 .channel_mode = alc861vd_3stack_2ch_modes,
570 .input_mux = &alc861vd_dallas_capture_source,
571 .unsol_event = alc_sku_unsol_event,
572 .setup = alc861vd_dallas_setup,
573 .init_hook = alc_hp_automute,
574 },
575 [ALC861VD_HP] = {
576 .mixers = { alc861vd_hp_mixer },
577 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
578 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
579 .dac_nids = alc861vd_dac_nids,
580 .dig_out_nid = ALC861VD_DIGOUT_NID,
581 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
582 .channel_mode = alc861vd_3stack_2ch_modes,
583 .input_mux = &alc861vd_hp_capture_source,
584 .unsol_event = alc_sku_unsol_event,
585 .setup = alc861vd_dallas_setup,
586 .init_hook = alc_hp_automute,
587 },
588 [ALC660VD_ASUS_V1S] = {
589 .mixers = { alc861vd_lenovo_mixer },
590 .init_verbs = { alc861vd_volume_init_verbs,
591 alc861vd_3stack_init_verbs,
592 alc861vd_eapd_verbs,
593 alc861vd_lenovo_unsol_verbs },
594 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
595 .dac_nids = alc660vd_dac_nids,
596 .dig_out_nid = ALC861VD_DIGOUT_NID,
597 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
598 .channel_mode = alc861vd_3stack_2ch_modes,
599 .input_mux = &alc861vd_capture_source,
600 .unsol_event = alc861vd_lenovo_unsol_event,
601 .setup = alc861vd_lenovo_setup,
602 .init_hook = alc861vd_lenovo_init_hook,
603 },
604};
605
diff --git a/sound/pci/hda/alc880_quirks.c b/sound/pci/hda/alc880_quirks.c
index c844d2b5998..bea22edcfd8 100644
--- a/sound/pci/hda/alc880_quirks.c
+++ b/sound/pci/hda/alc880_quirks.c
@@ -749,8 +749,7 @@ static void alc880_uniwill_setup(struct hda_codec *codec)
749 spec->autocfg.hp_pins[0] = 0x14; 749 spec->autocfg.hp_pins[0] = 0x14;
750 spec->autocfg.speaker_pins[0] = 0x15; 750 spec->autocfg.speaker_pins[0] = 0x15;
751 spec->autocfg.speaker_pins[0] = 0x16; 751 spec->autocfg.speaker_pins[0] = 0x16;
752 spec->automute = 1; 752 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
753 spec->automute_mode = ALC_AUTOMUTE_AMP;
754} 753}
755 754
756static void alc880_uniwill_init_hook(struct hda_codec *codec) 755static void alc880_uniwill_init_hook(struct hda_codec *codec)
@@ -781,8 +780,7 @@ static void alc880_uniwill_p53_setup(struct hda_codec *codec)
781 780
782 spec->autocfg.hp_pins[0] = 0x14; 781 spec->autocfg.hp_pins[0] = 0x14;
783 spec->autocfg.speaker_pins[0] = 0x15; 782 spec->autocfg.speaker_pins[0] = 0x15;
784 spec->automute = 1; 783 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
785 spec->automute_mode = ALC_AUTOMUTE_AMP;
786} 784}
787 785
788static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec) 786static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
@@ -1051,8 +1049,7 @@ static void alc880_lg_setup(struct hda_codec *codec)
1051 1049
1052 spec->autocfg.hp_pins[0] = 0x1b; 1050 spec->autocfg.hp_pins[0] = 0x1b;
1053 spec->autocfg.speaker_pins[0] = 0x17; 1051 spec->autocfg.speaker_pins[0] = 0x17;
1054 spec->automute = 1; 1052 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
1055 spec->automute_mode = ALC_AUTOMUTE_AMP;
1056} 1053}
1057 1054
1058/* 1055/*
@@ -1137,8 +1134,7 @@ static void alc880_lg_lw_setup(struct hda_codec *codec)
1137 1134
1138 spec->autocfg.hp_pins[0] = 0x1b; 1135 spec->autocfg.hp_pins[0] = 0x1b;
1139 spec->autocfg.speaker_pins[0] = 0x14; 1136 spec->autocfg.speaker_pins[0] = 0x14;
1140 spec->automute = 1; 1137 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
1141 spec->automute_mode = ALC_AUTOMUTE_AMP;
1142} 1138}
1143 1139
1144static const struct snd_kcontrol_new alc880_medion_rim_mixer[] = { 1140static const struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
@@ -1188,7 +1184,7 @@ static void alc880_medion_rim_automute(struct hda_codec *codec)
1188 struct alc_spec *spec = codec->spec; 1184 struct alc_spec *spec = codec->spec;
1189 alc_hp_automute(codec); 1185 alc_hp_automute(codec);
1190 /* toggle EAPD */ 1186 /* toggle EAPD */
1191 if (spec->jack_present) 1187 if (spec->hp_jack_present)
1192 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0); 1188 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
1193 else 1189 else
1194 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2); 1190 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
@@ -1210,8 +1206,7 @@ static void alc880_medion_rim_setup(struct hda_codec *codec)
1210 1206
1211 spec->autocfg.hp_pins[0] = 0x14; 1207 spec->autocfg.hp_pins[0] = 0x14;
1212 spec->autocfg.speaker_pins[0] = 0x1b; 1208 spec->autocfg.speaker_pins[0] = 0x1b;
1213 spec->automute = 1; 1209 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
1214 spec->automute_mode = ALC_AUTOMUTE_AMP;
1215} 1210}
1216 1211
1217#ifdef CONFIG_SND_HDA_POWER_SAVE 1212#ifdef CONFIG_SND_HDA_POWER_SAVE
diff --git a/sound/pci/hda/alc882_quirks.c b/sound/pci/hda/alc882_quirks.c
index 617d04723b8..e251514a26a 100644
--- a/sound/pci/hda/alc882_quirks.c
+++ b/sound/pci/hda/alc882_quirks.c
@@ -173,8 +173,7 @@ static void alc889_automute_setup(struct hda_codec *codec)
173 spec->autocfg.speaker_pins[2] = 0x17; 173 spec->autocfg.speaker_pins[2] = 0x17;
174 spec->autocfg.speaker_pins[3] = 0x19; 174 spec->autocfg.speaker_pins[3] = 0x19;
175 spec->autocfg.speaker_pins[4] = 0x1a; 175 spec->autocfg.speaker_pins[4] = 0x1a;
176 spec->automute = 1; 176 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
177 spec->automute_mode = ALC_AUTOMUTE_AMP;
178} 177}
179 178
180static void alc889_intel_init_hook(struct hda_codec *codec) 179static void alc889_intel_init_hook(struct hda_codec *codec)
@@ -191,8 +190,7 @@ static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
191 spec->autocfg.hp_pins[1] = 0x1b; /* hp */ 190 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
192 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */ 191 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
193 spec->autocfg.speaker_pins[1] = 0x15; /* bass */ 192 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
194 spec->automute = 1; 193 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
195 spec->automute_mode = ALC_AUTOMUTE_AMP;
196} 194}
197 195
198/* 196/*
@@ -475,8 +473,7 @@ static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
475 spec->autocfg.speaker_pins[0] = 0x14; 473 spec->autocfg.speaker_pins[0] = 0x14;
476 spec->autocfg.speaker_pins[1] = 0x16; 474 spec->autocfg.speaker_pins[1] = 0x16;
477 spec->autocfg.speaker_pins[2] = 0x17; 475 spec->autocfg.speaker_pins[2] = 0x17;
478 spec->automute = 1; 476 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
479 spec->automute_mode = ALC_AUTOMUTE_AMP;
480} 477}
481 478
482static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec) 479static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
@@ -487,8 +484,7 @@ static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
487 spec->autocfg.speaker_pins[0] = 0x14; 484 spec->autocfg.speaker_pins[0] = 0x14;
488 spec->autocfg.speaker_pins[1] = 0x16; 485 spec->autocfg.speaker_pins[1] = 0x16;
489 spec->autocfg.speaker_pins[2] = 0x17; 486 spec->autocfg.speaker_pins[2] = 0x17;
490 spec->automute = 1; 487 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
491 spec->automute_mode = ALC_AUTOMUTE_AMP;
492} 488}
493 489
494static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec) 490static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec)
@@ -499,8 +495,7 @@ static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec)
499 spec->autocfg.speaker_pins[0] = 0x14; 495 spec->autocfg.speaker_pins[0] = 0x14;
500 spec->autocfg.speaker_pins[1] = 0x16; 496 spec->autocfg.speaker_pins[1] = 0x16;
501 spec->autocfg.speaker_pins[2] = 0x17; 497 spec->autocfg.speaker_pins[2] = 0x17;
502 spec->automute = 1; 498 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
503 spec->automute_mode = ALC_AUTOMUTE_AMP;
504} 499}
505 500
506static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec) 501static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
@@ -511,8 +506,7 @@ static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
511 spec->autocfg.speaker_pins[0] = 0x14; 506 spec->autocfg.speaker_pins[0] = 0x14;
512 spec->autocfg.speaker_pins[1] = 0x16; 507 spec->autocfg.speaker_pins[1] = 0x16;
513 spec->autocfg.speaker_pins[2] = 0x1b; 508 spec->autocfg.speaker_pins[2] = 0x1b;
514 spec->automute = 1; 509 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
515 spec->automute_mode = ALC_AUTOMUTE_AMP;
516} 510}
517 511
518#define ALC882_DIGOUT_NID 0x06 512#define ALC882_DIGOUT_NID 0x06
@@ -1711,8 +1705,7 @@ static void alc885_imac24_setup(struct hda_codec *codec)
1711 spec->autocfg.hp_pins[0] = 0x14; 1705 spec->autocfg.hp_pins[0] = 0x14;
1712 spec->autocfg.speaker_pins[0] = 0x18; 1706 spec->autocfg.speaker_pins[0] = 0x18;
1713 spec->autocfg.speaker_pins[1] = 0x1a; 1707 spec->autocfg.speaker_pins[1] = 0x1a;
1714 spec->automute = 1; 1708 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
1715 spec->automute_mode = ALC_AUTOMUTE_AMP;
1716} 1709}
1717 1710
1718#define alc885_mb5_setup alc885_imac24_setup 1711#define alc885_mb5_setup alc885_imac24_setup
@@ -1721,12 +1714,11 @@ static void alc885_imac24_setup(struct hda_codec *codec)
1721/* Macbook Air 2,1 */ 1714/* Macbook Air 2,1 */
1722static void alc885_mba21_setup(struct hda_codec *codec) 1715static void alc885_mba21_setup(struct hda_codec *codec)
1723{ 1716{
1724 struct alc_spec *spec = codec->spec; 1717 struct alc_spec *spec = codec->spec;
1725 1718
1726 spec->autocfg.hp_pins[0] = 0x14; 1719 spec->autocfg.hp_pins[0] = 0x14;
1727 spec->autocfg.speaker_pins[0] = 0x18; 1720 spec->autocfg.speaker_pins[0] = 0x18;
1728 spec->automute = 1; 1721 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
1729 spec->automute_mode = ALC_AUTOMUTE_AMP;
1730} 1722}
1731 1723
1732 1724
@@ -1737,8 +1729,7 @@ static void alc885_mbp3_setup(struct hda_codec *codec)
1737 1729
1738 spec->autocfg.hp_pins[0] = 0x15; 1730 spec->autocfg.hp_pins[0] = 0x15;
1739 spec->autocfg.speaker_pins[0] = 0x14; 1731 spec->autocfg.speaker_pins[0] = 0x14;
1740 spec->automute = 1; 1732 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
1741 spec->automute_mode = ALC_AUTOMUTE_AMP;
1742} 1733}
1743 1734
1744static void alc885_imac91_setup(struct hda_codec *codec) 1735static void alc885_imac91_setup(struct hda_codec *codec)
@@ -1748,8 +1739,7 @@ static void alc885_imac91_setup(struct hda_codec *codec)
1748 spec->autocfg.hp_pins[0] = 0x14; 1739 spec->autocfg.hp_pins[0] = 0x14;
1749 spec->autocfg.speaker_pins[0] = 0x18; 1740 spec->autocfg.speaker_pins[0] = 0x18;
1750 spec->autocfg.speaker_pins[1] = 0x1a; 1741 spec->autocfg.speaker_pins[1] = 0x1a;
1751 spec->automute = 1; 1742 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
1752 spec->automute_mode = ALC_AUTOMUTE_AMP;
1753} 1743}
1754 1744
1755static const struct hda_verb alc882_targa_verbs[] = { 1745static const struct hda_verb alc882_targa_verbs[] = {
@@ -1773,7 +1763,7 @@ static void alc882_targa_automute(struct hda_codec *codec)
1773 struct alc_spec *spec = codec->spec; 1763 struct alc_spec *spec = codec->spec;
1774 alc_hp_automute(codec); 1764 alc_hp_automute(codec);
1775 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA, 1765 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
1776 spec->jack_present ? 1 : 3); 1766 spec->hp_jack_present ? 1 : 3);
1777} 1767}
1778 1768
1779static void alc882_targa_setup(struct hda_codec *codec) 1769static void alc882_targa_setup(struct hda_codec *codec)
@@ -1782,8 +1772,7 @@ static void alc882_targa_setup(struct hda_codec *codec)
1782 1772
1783 spec->autocfg.hp_pins[0] = 0x14; 1773 spec->autocfg.hp_pins[0] = 0x14;
1784 spec->autocfg.speaker_pins[0] = 0x1b; 1774 spec->autocfg.speaker_pins[0] = 0x1b;
1785 spec->automute = 1; 1775 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
1786 spec->automute_mode = ALC_AUTOMUTE_AMP;
1787} 1776}
1788 1777
1789static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res) 1778static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
@@ -2187,8 +2176,7 @@ static void alc883_medion_wim2160_setup(struct hda_codec *codec)
2187 2176
2188 spec->autocfg.hp_pins[0] = 0x1a; 2177 spec->autocfg.hp_pins[0] = 0x1a;
2189 spec->autocfg.speaker_pins[0] = 0x15; 2178 spec->autocfg.speaker_pins[0] = 0x15;
2190 spec->automute = 1; 2179 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
2191 spec->automute_mode = ALC_AUTOMUTE_AMP;
2192} 2180}
2193 2181
2194static const struct snd_kcontrol_new alc883_acer_aspire_mixer[] = { 2182static const struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
@@ -2341,8 +2329,7 @@ static void alc883_mitac_setup(struct hda_codec *codec)
2341 spec->autocfg.hp_pins[0] = 0x15; 2329 spec->autocfg.hp_pins[0] = 0x15;
2342 spec->autocfg.speaker_pins[0] = 0x14; 2330 spec->autocfg.speaker_pins[0] = 0x14;
2343 spec->autocfg.speaker_pins[1] = 0x17; 2331 spec->autocfg.speaker_pins[1] = 0x17;
2344 spec->automute = 1; 2332 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
2345 spec->automute_mode = ALC_AUTOMUTE_AMP;
2346} 2333}
2347 2334
2348static const struct hda_verb alc883_mitac_verbs[] = { 2335static const struct hda_verb alc883_mitac_verbs[] = {
@@ -2507,8 +2494,7 @@ static void alc888_3st_hp_setup(struct hda_codec *codec)
2507 spec->autocfg.speaker_pins[0] = 0x14; 2494 spec->autocfg.speaker_pins[0] = 0x14;
2508 spec->autocfg.speaker_pins[1] = 0x16; 2495 spec->autocfg.speaker_pins[1] = 0x16;
2509 spec->autocfg.speaker_pins[2] = 0x18; 2496 spec->autocfg.speaker_pins[2] = 0x18;
2510 spec->automute = 1; 2497 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
2511 spec->automute_mode = ALC_AUTOMUTE_AMP;
2512} 2498}
2513 2499
2514static const struct hda_verb alc888_3st_hp_verbs[] = { 2500static const struct hda_verb alc888_3st_hp_verbs[] = {
@@ -2568,8 +2554,7 @@ static void alc888_lenovo_ms7195_setup(struct hda_codec *codec)
2568 spec->autocfg.hp_pins[0] = 0x1b; 2554 spec->autocfg.hp_pins[0] = 0x1b;
2569 spec->autocfg.line_out_pins[0] = 0x14; 2555 spec->autocfg.line_out_pins[0] = 0x14;
2570 spec->autocfg.speaker_pins[0] = 0x15; 2556 spec->autocfg.speaker_pins[0] = 0x15;
2571 spec->automute = 1; 2557 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
2572 spec->automute_mode = ALC_AUTOMUTE_AMP;
2573} 2558}
2574 2559
2575/* toggle speaker-output according to the hp-jack state */ 2560/* toggle speaker-output according to the hp-jack state */
@@ -2579,8 +2564,7 @@ static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)
2579 2564
2580 spec->autocfg.hp_pins[0] = 0x14; 2565 spec->autocfg.hp_pins[0] = 0x14;
2581 spec->autocfg.speaker_pins[0] = 0x15; 2566 spec->autocfg.speaker_pins[0] = 0x15;
2582 spec->automute = 1; 2567 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
2583 spec->automute_mode = ALC_AUTOMUTE_AMP;
2584} 2568}
2585 2569
2586/* toggle speaker-output according to the hp-jack state */ 2570/* toggle speaker-output according to the hp-jack state */
@@ -2593,8 +2577,7 @@ static void alc883_clevo_m720_setup(struct hda_codec *codec)
2593 2577
2594 spec->autocfg.hp_pins[0] = 0x15; 2578 spec->autocfg.hp_pins[0] = 0x15;
2595 spec->autocfg.speaker_pins[0] = 0x14; 2579 spec->autocfg.speaker_pins[0] = 0x14;
2596 spec->automute = 1; 2580 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
2597 spec->automute_mode = ALC_AUTOMUTE_AMP;
2598} 2581}
2599 2582
2600static void alc883_clevo_m720_init_hook(struct hda_codec *codec) 2583static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
@@ -2623,8 +2606,7 @@ static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
2623 2606
2624 spec->autocfg.hp_pins[0] = 0x14; 2607 spec->autocfg.hp_pins[0] = 0x14;
2625 spec->autocfg.speaker_pins[0] = 0x15; 2608 spec->autocfg.speaker_pins[0] = 0x15;
2626 spec->automute = 1; 2609 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
2627 spec->automute_mode = ALC_AUTOMUTE_AMP;
2628} 2610}
2629 2611
2630static void alc883_haier_w66_setup(struct hda_codec *codec) 2612static void alc883_haier_w66_setup(struct hda_codec *codec)
@@ -2633,8 +2615,7 @@ static void alc883_haier_w66_setup(struct hda_codec *codec)
2633 2615
2634 spec->autocfg.hp_pins[0] = 0x1b; 2616 spec->autocfg.hp_pins[0] = 0x1b;
2635 spec->autocfg.speaker_pins[0] = 0x14; 2617 spec->autocfg.speaker_pins[0] = 0x14;
2636 spec->automute = 1; 2618 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
2637 spec->automute_mode = ALC_AUTOMUTE_AMP;
2638} 2619}
2639 2620
2640static void alc883_lenovo_101e_setup(struct hda_codec *codec) 2621static void alc883_lenovo_101e_setup(struct hda_codec *codec)
@@ -2644,10 +2625,7 @@ static void alc883_lenovo_101e_setup(struct hda_codec *codec)
2644 spec->autocfg.hp_pins[0] = 0x1b; 2625 spec->autocfg.hp_pins[0] = 0x1b;
2645 spec->autocfg.line_out_pins[0] = 0x14; 2626 spec->autocfg.line_out_pins[0] = 0x14;
2646 spec->autocfg.speaker_pins[0] = 0x15; 2627 spec->autocfg.speaker_pins[0] = 0x15;
2647 spec->automute = 1; 2628 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
2648 spec->detect_line = 1;
2649 spec->automute_lines = 1;
2650 spec->automute_mode = ALC_AUTOMUTE_AMP;
2651} 2629}
2652 2630
2653/* toggle speaker-output according to the hp-jack state */ 2631/* toggle speaker-output according to the hp-jack state */
@@ -2658,8 +2636,7 @@ static void alc883_acer_aspire_setup(struct hda_codec *codec)
2658 spec->autocfg.hp_pins[0] = 0x14; 2636 spec->autocfg.hp_pins[0] = 0x14;
2659 spec->autocfg.speaker_pins[0] = 0x15; 2637 spec->autocfg.speaker_pins[0] = 0x15;
2660 spec->autocfg.speaker_pins[1] = 0x16; 2638 spec->autocfg.speaker_pins[1] = 0x16;
2661 spec->automute = 1; 2639 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
2662 spec->automute_mode = ALC_AUTOMUTE_AMP;
2663} 2640}
2664 2641
2665static const struct hda_verb alc883_acer_eapd_verbs[] = { 2642static const struct hda_verb alc883_acer_eapd_verbs[] = {
@@ -2689,8 +2666,7 @@ static void alc888_6st_dell_setup(struct hda_codec *codec)
2689 spec->autocfg.speaker_pins[1] = 0x15; 2666 spec->autocfg.speaker_pins[1] = 0x15;
2690 spec->autocfg.speaker_pins[2] = 0x16; 2667 spec->autocfg.speaker_pins[2] = 0x16;
2691 spec->autocfg.speaker_pins[3] = 0x17; 2668 spec->autocfg.speaker_pins[3] = 0x17;
2692 spec->automute = 1; 2669 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
2693 spec->automute_mode = ALC_AUTOMUTE_AMP;
2694} 2670}
2695 2671
2696static void alc888_lenovo_sky_setup(struct hda_codec *codec) 2672static void alc888_lenovo_sky_setup(struct hda_codec *codec)
@@ -2703,8 +2679,7 @@ static void alc888_lenovo_sky_setup(struct hda_codec *codec)
2703 spec->autocfg.speaker_pins[2] = 0x16; 2679 spec->autocfg.speaker_pins[2] = 0x16;
2704 spec->autocfg.speaker_pins[3] = 0x17; 2680 spec->autocfg.speaker_pins[3] = 0x17;
2705 spec->autocfg.speaker_pins[4] = 0x1a; 2681 spec->autocfg.speaker_pins[4] = 0x1a;
2706 spec->automute = 1; 2682 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
2707 spec->automute_mode = ALC_AUTOMUTE_AMP;
2708} 2683}
2709 2684
2710static void alc883_vaiott_setup(struct hda_codec *codec) 2685static void alc883_vaiott_setup(struct hda_codec *codec)
@@ -2714,8 +2689,7 @@ static void alc883_vaiott_setup(struct hda_codec *codec)
2714 spec->autocfg.hp_pins[0] = 0x15; 2689 spec->autocfg.hp_pins[0] = 0x15;
2715 spec->autocfg.speaker_pins[0] = 0x14; 2690 spec->autocfg.speaker_pins[0] = 0x14;
2716 spec->autocfg.speaker_pins[1] = 0x17; 2691 spec->autocfg.speaker_pins[1] = 0x17;
2717 spec->automute = 1; 2692 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
2718 spec->automute_mode = ALC_AUTOMUTE_AMP;
2719} 2693}
2720 2694
2721static const struct hda_verb alc888_asus_m90v_verbs[] = { 2695static const struct hda_verb alc888_asus_m90v_verbs[] = {
@@ -2739,8 +2713,7 @@ static void alc883_mode2_setup(struct hda_codec *codec)
2739 spec->ext_mic_pin = 0x18; 2713 spec->ext_mic_pin = 0x18;
2740 spec->int_mic_pin = 0x19; 2714 spec->int_mic_pin = 0x19;
2741 spec->auto_mic = 1; 2715 spec->auto_mic = 1;
2742 spec->automute = 1; 2716 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
2743 spec->automute_mode = ALC_AUTOMUTE_AMP;
2744} 2717}
2745 2718
2746static const struct hda_verb alc888_asus_eee1601_verbs[] = { 2719static const struct hda_verb alc888_asus_eee1601_verbs[] = {
diff --git a/sound/pci/hda/alc_quirks.c b/sound/pci/hda/alc_quirks.c
index 2be1129cf45..a18952ed431 100644
--- a/sound/pci/hda/alc_quirks.c
+++ b/sound/pci/hda/alc_quirks.c
@@ -453,6 +453,19 @@ static void setup_preset(struct hda_codec *codec,
453 alc_fixup_autocfg_pin_nums(codec); 453 alc_fixup_autocfg_pin_nums(codec);
454} 454}
455 455
456static void alc_simple_setup_automute(struct alc_spec *spec, int mode)
457{
458 int lo_pin = spec->autocfg.line_out_pins[0];
459
460 if (lo_pin == spec->autocfg.speaker_pins[0] ||
461 lo_pin == spec->autocfg.hp_pins[0])
462 lo_pin = 0;
463 spec->automute_mode = mode;
464 spec->detect_hp = !!spec->autocfg.hp_pins[0];
465 spec->detect_lo = !!lo_pin;
466 spec->automute_lo = spec->automute_lo_possible = !!lo_pin;
467 spec->automute_speaker = spec->automute_speaker_possible = !!spec->autocfg.speaker_pins[0];
468}
456 469
457/* auto-toggle front mic */ 470/* auto-toggle front mic */
458static void alc88x_simple_mic_automute(struct hda_codec *codec) 471static void alc88x_simple_mic_automute(struct hda_codec *codec)
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index f3aefef3721..1715e8b24ff 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -34,6 +34,9 @@
34#include "hda_beep.h" 34#include "hda_beep.h"
35#include <sound/hda_hwdep.h> 35#include <sound/hda_hwdep.h>
36 36
37#define CREATE_TRACE_POINTS
38#include "hda_trace.h"
39
37/* 40/*
38 * vendor / preset table 41 * vendor / preset table
39 */ 42 */
@@ -208,15 +211,19 @@ static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd,
208 again: 211 again:
209 snd_hda_power_up(codec); 212 snd_hda_power_up(codec);
210 mutex_lock(&bus->cmd_mutex); 213 mutex_lock(&bus->cmd_mutex);
214 trace_hda_send_cmd(codec, cmd);
211 err = bus->ops.command(bus, cmd); 215 err = bus->ops.command(bus, cmd);
212 if (!err && res) 216 if (!err && res) {
213 *res = bus->ops.get_response(bus, codec->addr); 217 *res = bus->ops.get_response(bus, codec->addr);
218 trace_hda_get_response(codec, *res);
219 }
214 mutex_unlock(&bus->cmd_mutex); 220 mutex_unlock(&bus->cmd_mutex);
215 snd_hda_power_down(codec); 221 snd_hda_power_down(codec);
216 if (res && *res == -1 && bus->rirb_error) { 222 if (res && *res == -1 && bus->rirb_error) {
217 if (bus->response_reset) { 223 if (bus->response_reset) {
218 snd_printd("hda_codec: resetting BUS due to " 224 snd_printd("hda_codec: resetting BUS due to "
219 "fatal communication error\n"); 225 "fatal communication error\n");
226 trace_hda_bus_reset(bus);
220 bus->ops.bus_reset(bus); 227 bus->ops.bus_reset(bus);
221 } 228 }
222 goto again; 229 goto again;
@@ -607,6 +614,7 @@ int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex)
607 struct hda_bus_unsolicited *unsol; 614 struct hda_bus_unsolicited *unsol;
608 unsigned int wp; 615 unsigned int wp;
609 616
617 trace_hda_unsol_event(bus, res, res_ex);
610 unsol = bus->unsol; 618 unsol = bus->unsol;
611 if (!unsol) 619 if (!unsol)
612 return 0; 620 return 0;
@@ -1483,8 +1491,11 @@ static void really_cleanup_stream(struct hda_codec *codec,
1483 struct hda_cvt_setup *q) 1491 struct hda_cvt_setup *q)
1484{ 1492{
1485 hda_nid_t nid = q->nid; 1493 hda_nid_t nid = q->nid;
1486 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CHANNEL_STREAMID, 0); 1494 if (q->stream_tag || q->channel_id)
1487 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, 0); 1495 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CHANNEL_STREAMID, 0);
1496 if (q->format_id)
1497 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, 0
1498);
1488 memset(q, 0, sizeof(*q)); 1499 memset(q, 0, sizeof(*q));
1489 q->nid = nid; 1500 q->nid = nid;
1490} 1501}
@@ -1689,6 +1700,29 @@ u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid)
1689EXPORT_SYMBOL_HDA(snd_hda_query_pin_caps); 1700EXPORT_SYMBOL_HDA(snd_hda_query_pin_caps);
1690 1701
1691/** 1702/**
1703 * snd_hda_override_pin_caps - Override the pin capabilities
1704 * @codec: the CODEC
1705 * @nid: the NID to override
1706 * @caps: the capability bits to set
1707 *
1708 * Override the cached PIN capabilitiy bits value by the given one.
1709 *
1710 * Returns zero if successful or a negative error code.
1711 */
1712int snd_hda_override_pin_caps(struct hda_codec *codec, hda_nid_t nid,
1713 unsigned int caps)
1714{
1715 struct hda_amp_info *info;
1716 info = get_alloc_amp_hash(codec, HDA_HASH_PINCAP_KEY(nid));
1717 if (!info)
1718 return -ENOMEM;
1719 info->amp_caps = caps;
1720 info->head.val |= INFO_AMP_CAPS;
1721 return 0;
1722}
1723EXPORT_SYMBOL_HDA(snd_hda_override_pin_caps);
1724
1725/**
1692 * snd_hda_pin_sense - execute pin sense measurement 1726 * snd_hda_pin_sense - execute pin sense measurement
1693 * @codec: the CODEC to sense 1727 * @codec: the CODEC to sense
1694 * @nid: the pin NID to sense 1728 * @nid: the pin NID to sense
@@ -4087,6 +4121,7 @@ static void hda_power_work(struct work_struct *work)
4087 return; 4121 return;
4088 } 4122 }
4089 4123
4124 trace_hda_power_down(codec);
4090 hda_call_codec_suspend(codec); 4125 hda_call_codec_suspend(codec);
4091 if (bus->ops.pm_notify) 4126 if (bus->ops.pm_notify)
4092 bus->ops.pm_notify(bus); 4127 bus->ops.pm_notify(bus);
@@ -4125,6 +4160,7 @@ void snd_hda_power_up(struct hda_codec *codec)
4125 if (codec->power_on || codec->power_transition) 4160 if (codec->power_on || codec->power_transition)
4126 return; 4161 return;
4127 4162
4163 trace_hda_power_up(codec);
4128 snd_hda_update_power_acct(codec); 4164 snd_hda_update_power_acct(codec);
4129 codec->power_on = 1; 4165 codec->power_on = 1;
4130 codec->power_jiffies = jiffies; 4166 codec->power_jiffies = jiffies;
@@ -4537,6 +4573,11 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec,
4537 snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag, 4573 snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag,
4538 0, format); 4574 0, format);
4539 /* extra outputs copied from front */ 4575 /* extra outputs copied from front */
4576 for (i = 0; i < ARRAY_SIZE(mout->hp_out_nid); i++)
4577 if (!mout->no_share_stream && mout->hp_out_nid[i])
4578 snd_hda_codec_setup_stream(codec,
4579 mout->hp_out_nid[i],
4580 stream_tag, 0, format);
4540 for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++) 4581 for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
4541 if (!mout->no_share_stream && mout->extra_out_nid[i]) 4582 if (!mout->no_share_stream && mout->extra_out_nid[i])
4542 snd_hda_codec_setup_stream(codec, 4583 snd_hda_codec_setup_stream(codec,
@@ -4569,6 +4610,10 @@ int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec,
4569 snd_hda_codec_cleanup_stream(codec, nids[i]); 4610 snd_hda_codec_cleanup_stream(codec, nids[i]);
4570 if (mout->hp_nid) 4611 if (mout->hp_nid)
4571 snd_hda_codec_cleanup_stream(codec, mout->hp_nid); 4612 snd_hda_codec_cleanup_stream(codec, mout->hp_nid);
4613 for (i = 0; i < ARRAY_SIZE(mout->hp_out_nid); i++)
4614 if (mout->hp_out_nid[i])
4615 snd_hda_codec_cleanup_stream(codec,
4616 mout->hp_out_nid[i]);
4572 for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++) 4617 for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
4573 if (mout->extra_out_nid[i]) 4618 if (mout->extra_out_nid[i])
4574 snd_hda_codec_cleanup_stream(codec, 4619 snd_hda_codec_cleanup_stream(codec,
@@ -4649,6 +4694,27 @@ static void sort_autocfg_input_pins(struct auto_pin_cfg *cfg)
4649 } 4694 }
4650} 4695}
4651 4696
4697/* Reorder the surround channels
4698 * ALSA sequence is front/surr/clfe/side
4699 * HDA sequence is:
4700 * 4-ch: front/surr => OK as it is
4701 * 6-ch: front/clfe/surr
4702 * 8-ch: front/clfe/rear/side|fc
4703 */
4704static void reorder_outputs(unsigned int nums, hda_nid_t *pins)
4705{
4706 hda_nid_t nid;
4707
4708 switch (nums) {
4709 case 3:
4710 case 4:
4711 nid = pins[1];
4712 pins[1] = pins[2];
4713 pins[2] = nid;
4714 break;
4715 }
4716}
4717
4652/* 4718/*
4653 * Parse all pin widgets and store the useful pin nids to cfg 4719 * Parse all pin widgets and store the useful pin nids to cfg
4654 * 4720 *
@@ -4666,12 +4732,13 @@ static void sort_autocfg_input_pins(struct auto_pin_cfg *cfg)
4666 * The digital input/output pins are assigned to dig_in_pin and dig_out_pin, 4732 * The digital input/output pins are assigned to dig_in_pin and dig_out_pin,
4667 * respectively. 4733 * respectively.
4668 */ 4734 */
4669int snd_hda_parse_pin_def_config(struct hda_codec *codec, 4735int snd_hda_parse_pin_defcfg(struct hda_codec *codec,
4670 struct auto_pin_cfg *cfg, 4736 struct auto_pin_cfg *cfg,
4671 const hda_nid_t *ignore_nids) 4737 const hda_nid_t *ignore_nids,
4738 unsigned int cond_flags)
4672{ 4739{
4673 hda_nid_t nid, end_nid; 4740 hda_nid_t nid, end_nid;
4674 short seq, assoc_line_out, assoc_speaker; 4741 short seq, assoc_line_out;
4675 short sequences_line_out[ARRAY_SIZE(cfg->line_out_pins)]; 4742 short sequences_line_out[ARRAY_SIZE(cfg->line_out_pins)];
4676 short sequences_speaker[ARRAY_SIZE(cfg->speaker_pins)]; 4743 short sequences_speaker[ARRAY_SIZE(cfg->speaker_pins)];
4677 short sequences_hp[ARRAY_SIZE(cfg->hp_pins)]; 4744 short sequences_hp[ARRAY_SIZE(cfg->hp_pins)];
@@ -4682,7 +4749,7 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
4682 memset(sequences_line_out, 0, sizeof(sequences_line_out)); 4749 memset(sequences_line_out, 0, sizeof(sequences_line_out));
4683 memset(sequences_speaker, 0, sizeof(sequences_speaker)); 4750 memset(sequences_speaker, 0, sizeof(sequences_speaker));
4684 memset(sequences_hp, 0, sizeof(sequences_hp)); 4751 memset(sequences_hp, 0, sizeof(sequences_hp));
4685 assoc_line_out = assoc_speaker = 0; 4752 assoc_line_out = 0;
4686 4753
4687 end_nid = codec->start_nid + codec->num_nodes; 4754 end_nid = codec->start_nid + codec->num_nodes;
4688 for (nid = codec->start_nid; nid < end_nid; nid++) { 4755 for (nid = codec->start_nid; nid < end_nid; nid++) {
@@ -4734,16 +4801,10 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
4734 case AC_JACK_SPEAKER: 4801 case AC_JACK_SPEAKER:
4735 seq = get_defcfg_sequence(def_conf); 4802 seq = get_defcfg_sequence(def_conf);
4736 assoc = get_defcfg_association(def_conf); 4803 assoc = get_defcfg_association(def_conf);
4737 if (!assoc)
4738 continue;
4739 if (!assoc_speaker)
4740 assoc_speaker = assoc;
4741 else if (assoc_speaker != assoc)
4742 continue;
4743 if (cfg->speaker_outs >= ARRAY_SIZE(cfg->speaker_pins)) 4804 if (cfg->speaker_outs >= ARRAY_SIZE(cfg->speaker_pins))
4744 continue; 4805 continue;
4745 cfg->speaker_pins[cfg->speaker_outs] = nid; 4806 cfg->speaker_pins[cfg->speaker_outs] = nid;
4746 sequences_speaker[cfg->speaker_outs] = seq; 4807 sequences_speaker[cfg->speaker_outs] = (assoc << 4) | seq;
4747 cfg->speaker_outs++; 4808 cfg->speaker_outs++;
4748 break; 4809 break;
4749 case AC_JACK_HP_OUT: 4810 case AC_JACK_HP_OUT:
@@ -4792,7 +4853,8 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
4792 * If no line-out is defined but multiple HPs are found, 4853 * If no line-out is defined but multiple HPs are found,
4793 * some of them might be the real line-outs. 4854 * some of them might be the real line-outs.
4794 */ 4855 */
4795 if (!cfg->line_outs && cfg->hp_outs > 1) { 4856 if (!cfg->line_outs && cfg->hp_outs > 1 &&
4857 !(cond_flags & HDA_PINCFG_NO_HP_FIXUP)) {
4796 int i = 0; 4858 int i = 0;
4797 while (i < cfg->hp_outs) { 4859 while (i < cfg->hp_outs) {
4798 /* The real HPs should have the sequence 0x0f */ 4860 /* The real HPs should have the sequence 0x0f */
@@ -4829,7 +4891,8 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
4829 * FIX-UP: if no line-outs are detected, try to use speaker or HP pin 4891 * FIX-UP: if no line-outs are detected, try to use speaker or HP pin
4830 * as a primary output 4892 * as a primary output
4831 */ 4893 */
4832 if (!cfg->line_outs) { 4894 if (!cfg->line_outs &&
4895 !(cond_flags & HDA_PINCFG_NO_LO_FIXUP)) {
4833 if (cfg->speaker_outs) { 4896 if (cfg->speaker_outs) {
4834 cfg->line_outs = cfg->speaker_outs; 4897 cfg->line_outs = cfg->speaker_outs;
4835 memcpy(cfg->line_out_pins, cfg->speaker_pins, 4898 memcpy(cfg->line_out_pins, cfg->speaker_pins,
@@ -4847,21 +4910,9 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
4847 } 4910 }
4848 } 4911 }
4849 4912
4850 /* Reorder the surround channels 4913 reorder_outputs(cfg->line_outs, cfg->line_out_pins);
4851 * ALSA sequence is front/surr/clfe/side 4914 reorder_outputs(cfg->hp_outs, cfg->hp_pins);
4852 * HDA sequence is: 4915 reorder_outputs(cfg->speaker_outs, cfg->speaker_pins);
4853 * 4-ch: front/surr => OK as it is
4854 * 6-ch: front/clfe/surr
4855 * 8-ch: front/clfe/rear/side|fc
4856 */
4857 switch (cfg->line_outs) {
4858 case 3:
4859 case 4:
4860 nid = cfg->line_out_pins[1];
4861 cfg->line_out_pins[1] = cfg->line_out_pins[2];
4862 cfg->line_out_pins[2] = nid;
4863 break;
4864 }
4865 4916
4866 sort_autocfg_input_pins(cfg); 4917 sort_autocfg_input_pins(cfg);
4867 4918
@@ -4899,7 +4950,7 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
4899 4950
4900 return 0; 4951 return 0;
4901} 4952}
4902EXPORT_SYMBOL_HDA(snd_hda_parse_pin_def_config); 4953EXPORT_SYMBOL_HDA(snd_hda_parse_pin_defcfg);
4903 4954
4904int snd_hda_get_input_pin_attr(unsigned int def_conf) 4955int snd_hda_get_input_pin_attr(unsigned int def_conf)
4905{ 4956{
@@ -5158,30 +5209,6 @@ void snd_array_free(struct snd_array *array)
5158EXPORT_SYMBOL_HDA(snd_array_free); 5209EXPORT_SYMBOL_HDA(snd_array_free);
5159 5210
5160/** 5211/**
5161 * snd_print_pcm_rates - Print the supported PCM rates to the string buffer
5162 * @pcm: PCM caps bits
5163 * @buf: the string buffer to write
5164 * @buflen: the max buffer length
5165 *
5166 * used by hda_proc.c and hda_eld.c
5167 */
5168void snd_print_pcm_rates(int pcm, char *buf, int buflen)
5169{
5170 static unsigned int rates[] = {
5171 8000, 11025, 16000, 22050, 32000, 44100, 48000, 88200,
5172 96000, 176400, 192000, 384000
5173 };
5174 int i, j;
5175
5176 for (i = 0, j = 0; i < ARRAY_SIZE(rates); i++)
5177 if (pcm & (1 << i))
5178 j += snprintf(buf + j, buflen - j, " %d", rates[i]);
5179
5180 buf[j] = '\0'; /* necessary when j == 0 */
5181}
5182EXPORT_SYMBOL_HDA(snd_print_pcm_rates);
5183
5184/**
5185 * snd_print_pcm_bits - Print the supported PCM fmt bits to the string buffer 5212 * snd_print_pcm_bits - Print the supported PCM fmt bits to the string buffer
5186 * @pcm: PCM caps bits 5213 * @pcm: PCM caps bits
5187 * @buf: the string buffer to write 5214 * @buf: the string buffer to write
@@ -5222,6 +5249,8 @@ static const char *get_jack_default_name(struct hda_codec *codec, hda_nid_t nid,
5222 return "Mic"; 5249 return "Mic";
5223 case SND_JACK_LINEOUT: 5250 case SND_JACK_LINEOUT:
5224 return "Line-out"; 5251 return "Line-out";
5252 case SND_JACK_LINEIN:
5253 return "Line-in";
5225 case SND_JACK_HEADSET: 5254 case SND_JACK_HEADSET:
5226 return "Headset"; 5255 return "Headset";
5227 case SND_JACK_VIDEOOUT: 5256 case SND_JACK_VIDEOOUT:
diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c
index c34f730f481..1c8ddf547a2 100644
--- a/sound/pci/hda/hda_eld.c
+++ b/sound/pci/hda/hda_eld.c
@@ -318,6 +318,11 @@ int snd_hdmi_get_eld(struct hdmi_eld *eld,
318 int size; 318 int size;
319 unsigned char *buf; 319 unsigned char *buf;
320 320
321 /*
322 * ELD size is initialized to zero in caller function. If no errors and
323 * ELD is valid, actual eld_size is assigned in hdmi_update_eld()
324 */
325
321 if (!eld->eld_valid) 326 if (!eld->eld_valid)
322 return -ENOENT; 327 return -ENOENT;
323 328
@@ -327,14 +332,13 @@ int snd_hdmi_get_eld(struct hdmi_eld *eld,
327 snd_printd(KERN_INFO "HDMI: ELD buf size is 0, force 128\n"); 332 snd_printd(KERN_INFO "HDMI: ELD buf size is 0, force 128\n");
328 size = 128; 333 size = 128;
329 } 334 }
330 if (size < ELD_FIXED_BYTES || size > PAGE_SIZE) { 335 if (size < ELD_FIXED_BYTES || size > ELD_MAX_SIZE) {
331 snd_printd(KERN_INFO "HDMI: invalid ELD buf size %d\n", size); 336 snd_printd(KERN_INFO "HDMI: invalid ELD buf size %d\n", size);
332 return -ERANGE; 337 return -ERANGE;
333 } 338 }
334 339
335 buf = kmalloc(size, GFP_KERNEL); 340 /* set ELD buffer */
336 if (!buf) 341 buf = eld->eld_buffer;
337 return -ENOMEM;
338 342
339 for (i = 0; i < size; i++) { 343 for (i = 0; i < size; i++) {
340 unsigned int val = hdmi_get_eld_data(codec, nid, i); 344 unsigned int val = hdmi_get_eld_data(codec, nid, i);
@@ -356,10 +360,31 @@ int snd_hdmi_get_eld(struct hdmi_eld *eld,
356 ret = hdmi_update_eld(eld, buf, size); 360 ret = hdmi_update_eld(eld, buf, size);
357 361
358error: 362error:
359 kfree(buf);
360 return ret; 363 return ret;
361} 364}
362 365
366/**
367 * SNDRV_PCM_RATE_* and AC_PAR_PCM values don't match, print correct rates with
368 * hdmi-specific routine.
369 */
370static void hdmi_print_pcm_rates(int pcm, char *buf, int buflen)
371{
372 static unsigned int alsa_rates[] = {
373 5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000, 88200,
374 96000, 176400, 192000, 384000
375 };
376 int i, j;
377
378 for (i = 0, j = 0; i < ARRAY_SIZE(alsa_rates); i++)
379 if (pcm & (1 << i))
380 j += snprintf(buf + j, buflen - j, " %d",
381 alsa_rates[i]);
382
383 buf[j] = '\0'; /* necessary when j == 0 */
384}
385
386#define SND_PRINT_RATES_ADVISED_BUFSIZE 80
387
363static void hdmi_show_short_audio_desc(struct cea_sad *a) 388static void hdmi_show_short_audio_desc(struct cea_sad *a)
364{ 389{
365 char buf[SND_PRINT_RATES_ADVISED_BUFSIZE]; 390 char buf[SND_PRINT_RATES_ADVISED_BUFSIZE];
@@ -368,7 +393,7 @@ static void hdmi_show_short_audio_desc(struct cea_sad *a)
368 if (!a->format) 393 if (!a->format)
369 return; 394 return;
370 395
371 snd_print_pcm_rates(a->rates, buf, sizeof(buf)); 396 hdmi_print_pcm_rates(a->rates, buf, sizeof(buf));
372 397
373 if (a->format == AUDIO_CODING_TYPE_LPCM) 398 if (a->format == AUDIO_CODING_TYPE_LPCM)
374 snd_print_pcm_bits(a->sample_bits, buf2 + 8, sizeof(buf2) - 8); 399 snd_print_pcm_bits(a->sample_bits, buf2 + 8, sizeof(buf2) - 8);
@@ -427,7 +452,7 @@ static void hdmi_print_sad_info(int i, struct cea_sad *a,
427 i, a->format, cea_audio_coding_type_names[a->format]); 452 i, a->format, cea_audio_coding_type_names[a->format]);
428 snd_iprintf(buffer, "sad%d_channels\t\t%d\n", i, a->channels); 453 snd_iprintf(buffer, "sad%d_channels\t\t%d\n", i, a->channels);
429 454
430 snd_print_pcm_rates(a->rates, buf, sizeof(buf)); 455 hdmi_print_pcm_rates(a->rates, buf, sizeof(buf));
431 snd_iprintf(buffer, "sad%d_rates\t\t[0x%x]%s\n", i, a->rates, buf); 456 snd_iprintf(buffer, "sad%d_rates\t\t[0x%x]%s\n", i, a->rates, buf);
432 457
433 if (a->format == AUDIO_CODING_TYPE_LPCM) { 458 if (a->format == AUDIO_CODING_TYPE_LPCM) {
diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c
index bf3ced51e0f..72e5885007c 100644
--- a/sound/pci/hda/hda_hwdep.c
+++ b/sound/pci/hda/hda_hwdep.c
@@ -643,14 +643,14 @@ static inline int strmatch(const char *a, const char *b)
643static void parse_codec_mode(char *buf, struct hda_bus *bus, 643static void parse_codec_mode(char *buf, struct hda_bus *bus,
644 struct hda_codec **codecp) 644 struct hda_codec **codecp)
645{ 645{
646 unsigned int vendorid, subid, caddr; 646 int vendorid, subid, caddr;
647 struct hda_codec *codec; 647 struct hda_codec *codec;
648 648
649 *codecp = NULL; 649 *codecp = NULL;
650 if (sscanf(buf, "%i %i %i", &vendorid, &subid, &caddr) == 3) { 650 if (sscanf(buf, "%i %i %i", &vendorid, &subid, &caddr) == 3) {
651 list_for_each_entry(codec, &bus->codec_list, list) { 651 list_for_each_entry(codec, &bus->codec_list, list) {
652 if (codec->vendor_id == vendorid && 652 if ((vendorid <= 0 || codec->vendor_id == vendorid) &&
653 codec->subsystem_id == subid && 653 (subid <= 0 || codec->subsystem_id == subid) &&
654 codec->addr == caddr) { 654 codec->addr == caddr) {
655 *codecp = codec; 655 *codecp = codec;
656 break; 656 break;
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 191284a1c0a..bd7fc99af18 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -34,7 +34,6 @@
34 * 34 *
35 */ 35 */
36 36
37#include <asm/io.h>
38#include <linux/delay.h> 37#include <linux/delay.h>
39#include <linux/interrupt.h> 38#include <linux/interrupt.h>
40#include <linux/kernel.h> 39#include <linux/kernel.h>
@@ -46,6 +45,12 @@
46#include <linux/pci.h> 45#include <linux/pci.h>
47#include <linux/mutex.h> 46#include <linux/mutex.h>
48#include <linux/reboot.h> 47#include <linux/reboot.h>
48#include <linux/io.h>
49#ifdef CONFIG_X86
50/* for snoop control */
51#include <asm/pgtable.h>
52#include <asm/cacheflush.h>
53#endif
49#include <sound/core.h> 54#include <sound/core.h>
50#include <sound/initval.h> 55#include <sound/initval.h>
51#include "hda_codec.h" 56#include "hda_codec.h"
@@ -116,6 +121,22 @@ module_param(power_save_controller, bool, 0644);
116MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode."); 121MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode.");
117#endif 122#endif
118 123
124static int align_buffer_size = 1;
125module_param(align_buffer_size, bool, 0644);
126MODULE_PARM_DESC(align_buffer_size,
127 "Force buffer and period sizes to be multiple of 128 bytes.");
128
129#ifdef CONFIG_X86
130static bool hda_snoop = true;
131module_param_named(snoop, hda_snoop, bool, 0444);
132MODULE_PARM_DESC(snoop, "Enable/disable snooping");
133#define azx_snoop(chip) (chip)->snoop
134#else
135#define hda_snoop true
136#define azx_snoop(chip) true
137#endif
138
139
119MODULE_LICENSE("GPL"); 140MODULE_LICENSE("GPL");
120MODULE_SUPPORTED_DEVICE("{{Intel, ICH6}," 141MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
121 "{Intel, ICH6M}," 142 "{Intel, ICH6M},"
@@ -360,7 +381,7 @@ struct azx_dev {
360 */ 381 */
361 unsigned char stream_tag; /* assigned stream */ 382 unsigned char stream_tag; /* assigned stream */
362 unsigned char index; /* stream index */ 383 unsigned char index; /* stream index */
363 int device; /* last device number assigned to */ 384 int assigned_key; /* last device# key assigned to */
364 385
365 unsigned int opened :1; 386 unsigned int opened :1;
366 unsigned int running :1; 387 unsigned int running :1;
@@ -371,6 +392,7 @@ struct azx_dev {
371 * when link position is not greater than FIFO size 392 * when link position is not greater than FIFO size
372 */ 393 */
373 unsigned int insufficient :1; 394 unsigned int insufficient :1;
395 unsigned int wc_marked:1;
374}; 396};
375 397
376/* CORB/RIRB */ 398/* CORB/RIRB */
@@ -438,6 +460,7 @@ struct azx {
438 unsigned int msi :1; 460 unsigned int msi :1;
439 unsigned int irq_pending_warned :1; 461 unsigned int irq_pending_warned :1;
440 unsigned int probing :1; /* codec probing phase */ 462 unsigned int probing :1; /* codec probing phase */
463 unsigned int snoop:1;
441 464
442 /* for debugging */ 465 /* for debugging */
443 unsigned int last_cmd[AZX_MAX_CODECS]; 466 unsigned int last_cmd[AZX_MAX_CODECS];
@@ -481,6 +504,7 @@ enum {
481#define AZX_DCAPS_NO_64BIT (1 << 18) /* No 64bit address */ 504#define AZX_DCAPS_NO_64BIT (1 << 18) /* No 64bit address */
482#define AZX_DCAPS_SYNC_WRITE (1 << 19) /* sync each cmd write */ 505#define AZX_DCAPS_SYNC_WRITE (1 << 19) /* sync each cmd write */
483#define AZX_DCAPS_OLD_SSYNC (1 << 20) /* Old SSYNC reg for ICH */ 506#define AZX_DCAPS_OLD_SSYNC (1 << 20) /* Old SSYNC reg for ICH */
507#define AZX_DCAPS_BUFSIZE (1 << 21) /* no buffer size alignment */
484 508
485/* quirks for ATI SB / AMD Hudson */ 509/* quirks for ATI SB / AMD Hudson */
486#define AZX_DCAPS_PRESET_ATI_SB \ 510#define AZX_DCAPS_PRESET_ATI_SB \
@@ -542,6 +566,45 @@ static char *driver_short_names[] __devinitdata = {
542/* for pcm support */ 566/* for pcm support */
543#define get_azx_dev(substream) (substream->runtime->private_data) 567#define get_azx_dev(substream) (substream->runtime->private_data)
544 568
569#ifdef CONFIG_X86
570static void __mark_pages_wc(struct azx *chip, void *addr, size_t size, bool on)
571{
572 if (azx_snoop(chip))
573 return;
574 if (addr && size) {
575 int pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
576 if (on)
577 set_memory_wc((unsigned long)addr, pages);
578 else
579 set_memory_wb((unsigned long)addr, pages);
580 }
581}
582
583static inline void mark_pages_wc(struct azx *chip, struct snd_dma_buffer *buf,
584 bool on)
585{
586 __mark_pages_wc(chip, buf->area, buf->bytes, on);
587}
588static inline void mark_runtime_wc(struct azx *chip, struct azx_dev *azx_dev,
589 struct snd_pcm_runtime *runtime, bool on)
590{
591 if (azx_dev->wc_marked != on) {
592 __mark_pages_wc(chip, runtime->dma_area, runtime->dma_bytes, on);
593 azx_dev->wc_marked = on;
594 }
595}
596#else
597/* NOP for other archs */
598static inline void mark_pages_wc(struct azx *chip, struct snd_dma_buffer *buf,
599 bool on)
600{
601}
602static inline void mark_runtime_wc(struct azx *chip, struct azx_dev *azx_dev,
603 struct snd_pcm_runtime *runtime, bool on)
604{
605}
606#endif
607
545static int azx_acquire_irq(struct azx *chip, int do_disconnect); 608static int azx_acquire_irq(struct azx *chip, int do_disconnect);
546static int azx_send_cmd(struct hda_bus *bus, unsigned int val); 609static int azx_send_cmd(struct hda_bus *bus, unsigned int val);
547/* 610/*
@@ -563,6 +626,7 @@ static int azx_alloc_cmd_io(struct azx *chip)
563 snd_printk(KERN_ERR SFX "cannot allocate CORB/RIRB\n"); 626 snd_printk(KERN_ERR SFX "cannot allocate CORB/RIRB\n");
564 return err; 627 return err;
565 } 628 }
629 mark_pages_wc(chip, &chip->rb, true);
566 return 0; 630 return 0;
567} 631}
568 632
@@ -1079,7 +1143,15 @@ static void update_pci_byte(struct pci_dev *pci, unsigned int reg,
1079 1143
1080static void azx_init_pci(struct azx *chip) 1144static void azx_init_pci(struct azx *chip)
1081{ 1145{
1082 unsigned short snoop; 1146 /* force to non-snoop mode for a new VIA controller when BIOS is set */
1147 if (chip->snoop && chip->driver_type == AZX_DRIVER_VIA) {
1148 u8 snoop;
1149 pci_read_config_byte(chip->pci, 0x42, &snoop);
1150 if (!(snoop & 0x80) && chip->pci->revision == 0x30) {
1151 chip->snoop = 0;
1152 snd_printdd(SFX "Force to non-snoop mode\n");
1153 }
1154 }
1083 1155
1084 /* Clear bits 0-2 of PCI register TCSEL (at offset 0x44) 1156 /* Clear bits 0-2 of PCI register TCSEL (at offset 0x44)
1085 * TCSEL == Traffic Class Select Register, which sets PCI express QOS 1157 * TCSEL == Traffic Class Select Register, which sets PCI express QOS
@@ -1096,15 +1168,15 @@ static void azx_init_pci(struct azx *chip)
1096 * we need to enable snoop. 1168 * we need to enable snoop.
1097 */ 1169 */
1098 if (chip->driver_caps & AZX_DCAPS_ATI_SNOOP) { 1170 if (chip->driver_caps & AZX_DCAPS_ATI_SNOOP) {
1099 snd_printdd(SFX "Enabling ATI snoop\n"); 1171 snd_printdd(SFX "Setting ATI snoop: %d\n", azx_snoop(chip));
1100 update_pci_byte(chip->pci, 1172 update_pci_byte(chip->pci,
1101 ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, 1173 ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, 0x07,
1102 0x07, ATI_SB450_HDAUDIO_ENABLE_SNOOP); 1174 azx_snoop(chip) ? ATI_SB450_HDAUDIO_ENABLE_SNOOP : 0);
1103 } 1175 }
1104 1176
1105 /* For NVIDIA HDA, enable snoop */ 1177 /* For NVIDIA HDA, enable snoop */
1106 if (chip->driver_caps & AZX_DCAPS_NVIDIA_SNOOP) { 1178 if (chip->driver_caps & AZX_DCAPS_NVIDIA_SNOOP) {
1107 snd_printdd(SFX "Enabling Nvidia snoop\n"); 1179 snd_printdd(SFX "Setting Nvidia snoop: %d\n", azx_snoop(chip));
1108 update_pci_byte(chip->pci, 1180 update_pci_byte(chip->pci,
1109 NVIDIA_HDA_TRANSREG_ADDR, 1181 NVIDIA_HDA_TRANSREG_ADDR,
1110 0x0f, NVIDIA_HDA_ENABLE_COHBITS); 1182 0x0f, NVIDIA_HDA_ENABLE_COHBITS);
@@ -1118,16 +1190,20 @@ static void azx_init_pci(struct azx *chip)
1118 1190
1119 /* Enable SCH/PCH snoop if needed */ 1191 /* Enable SCH/PCH snoop if needed */
1120 if (chip->driver_caps & AZX_DCAPS_SCH_SNOOP) { 1192 if (chip->driver_caps & AZX_DCAPS_SCH_SNOOP) {
1193 unsigned short snoop;
1121 pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop); 1194 pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop);
1122 if (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) { 1195 if ((!azx_snoop(chip) && !(snoop & INTEL_SCH_HDA_DEVC_NOSNOOP)) ||
1123 pci_write_config_word(chip->pci, INTEL_SCH_HDA_DEVC, 1196 (azx_snoop(chip) && (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP))) {
1124 snoop & (~INTEL_SCH_HDA_DEVC_NOSNOOP)); 1197 snoop &= ~INTEL_SCH_HDA_DEVC_NOSNOOP;
1198 if (!azx_snoop(chip))
1199 snoop |= INTEL_SCH_HDA_DEVC_NOSNOOP;
1200 pci_write_config_word(chip->pci, INTEL_SCH_HDA_DEVC, snoop);
1125 pci_read_config_word(chip->pci, 1201 pci_read_config_word(chip->pci,
1126 INTEL_SCH_HDA_DEVC, &snoop); 1202 INTEL_SCH_HDA_DEVC, &snoop);
1127 snd_printdd(SFX "HDA snoop disabled, enabling ... %s\n",
1128 (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP)
1129 ? "Failed" : "OK");
1130 } 1203 }
1204 snd_printdd(SFX "SCH snoop: %s\n",
1205 (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP)
1206 ? "Disabled" : "Enabled");
1131 } 1207 }
1132} 1208}
1133 1209
@@ -1334,12 +1410,16 @@ static void azx_stream_reset(struct azx *chip, struct azx_dev *azx_dev)
1334 */ 1410 */
1335static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev) 1411static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev)
1336{ 1412{
1413 unsigned int val;
1337 /* make sure the run bit is zero for SD */ 1414 /* make sure the run bit is zero for SD */
1338 azx_stream_clear(chip, azx_dev); 1415 azx_stream_clear(chip, azx_dev);
1339 /* program the stream_tag */ 1416 /* program the stream_tag */
1340 azx_sd_writel(azx_dev, SD_CTL, 1417 val = azx_sd_readl(azx_dev, SD_CTL);
1341 (azx_sd_readl(azx_dev, SD_CTL) & ~SD_CTL_STREAM_TAG_MASK)| 1418 val = (val & ~SD_CTL_STREAM_TAG_MASK) |
1342 (azx_dev->stream_tag << SD_CTL_STREAM_TAG_SHIFT)); 1419 (azx_dev->stream_tag << SD_CTL_STREAM_TAG_SHIFT);
1420 if (!azx_snoop(chip))
1421 val |= SD_CTL_TRAFFIC_PRIO;
1422 azx_sd_writel(azx_dev, SD_CTL, val);
1343 1423
1344 /* program the length of samples in cyclic buffer */ 1424 /* program the length of samples in cyclic buffer */
1345 azx_sd_writel(azx_dev, SD_CBL, azx_dev->bufsize); 1425 azx_sd_writel(azx_dev, SD_CBL, azx_dev->bufsize);
@@ -1533,6 +1613,9 @@ azx_assign_device(struct azx *chip, struct snd_pcm_substream *substream)
1533{ 1613{
1534 int dev, i, nums; 1614 int dev, i, nums;
1535 struct azx_dev *res = NULL; 1615 struct azx_dev *res = NULL;
1616 /* make a non-zero unique key for the substream */
1617 int key = (substream->pcm->device << 16) | (substream->number << 2) |
1618 (substream->stream + 1);
1536 1619
1537 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 1620 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1538 dev = chip->playback_index_offset; 1621 dev = chip->playback_index_offset;
@@ -1544,12 +1627,12 @@ azx_assign_device(struct azx *chip, struct snd_pcm_substream *substream)
1544 for (i = 0; i < nums; i++, dev++) 1627 for (i = 0; i < nums; i++, dev++)
1545 if (!chip->azx_dev[dev].opened) { 1628 if (!chip->azx_dev[dev].opened) {
1546 res = &chip->azx_dev[dev]; 1629 res = &chip->azx_dev[dev];
1547 if (res->device == substream->pcm->device) 1630 if (res->assigned_key == key)
1548 break; 1631 break;
1549 } 1632 }
1550 if (res) { 1633 if (res) {
1551 res->opened = 1; 1634 res->opened = 1;
1552 res->device = substream->pcm->device; 1635 res->assigned_key = key;
1553 } 1636 }
1554 return res; 1637 return res;
1555} 1638}
@@ -1599,6 +1682,7 @@ static int azx_pcm_open(struct snd_pcm_substream *substream)
1599 struct snd_pcm_runtime *runtime = substream->runtime; 1682 struct snd_pcm_runtime *runtime = substream->runtime;
1600 unsigned long flags; 1683 unsigned long flags;
1601 int err; 1684 int err;
1685 int buff_step;
1602 1686
1603 mutex_lock(&chip->open_mutex); 1687 mutex_lock(&chip->open_mutex);
1604 azx_dev = azx_assign_device(chip, substream); 1688 azx_dev = azx_assign_device(chip, substream);
@@ -1613,10 +1697,25 @@ static int azx_pcm_open(struct snd_pcm_substream *substream)
1613 runtime->hw.rates = hinfo->rates; 1697 runtime->hw.rates = hinfo->rates;
1614 snd_pcm_limit_hw_rates(runtime); 1698 snd_pcm_limit_hw_rates(runtime);
1615 snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); 1699 snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
1700 if (align_buffer_size)
1701 /* constrain buffer sizes to be multiple of 128
1702 bytes. This is more efficient in terms of memory
1703 access but isn't required by the HDA spec and
1704 prevents users from specifying exact period/buffer
1705 sizes. For example for 44.1kHz, a period size set
1706 to 20ms will be rounded to 19.59ms. */
1707 buff_step = 128;
1708 else
1709 /* Don't enforce steps on buffer sizes, still need to
1710 be multiple of 4 bytes (HDA spec). Tested on Intel
1711 HDA controllers, may not work on all devices where
1712 option needs to be disabled */
1713 buff_step = 4;
1714
1616 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 1715 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
1617 128); 1716 buff_step);
1618 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 1717 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
1619 128); 1718 buff_step);
1620 snd_hda_power_up(apcm->codec); 1719 snd_hda_power_up(apcm->codec);
1621 err = hinfo->ops.open(hinfo, apcm->codec, substream); 1720 err = hinfo->ops.open(hinfo, apcm->codec, substream);
1622 if (err < 0) { 1721 if (err < 0) {
@@ -1671,19 +1770,30 @@ static int azx_pcm_close(struct snd_pcm_substream *substream)
1671static int azx_pcm_hw_params(struct snd_pcm_substream *substream, 1770static int azx_pcm_hw_params(struct snd_pcm_substream *substream,
1672 struct snd_pcm_hw_params *hw_params) 1771 struct snd_pcm_hw_params *hw_params)
1673{ 1772{
1773 struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
1774 struct azx *chip = apcm->chip;
1775 struct snd_pcm_runtime *runtime = substream->runtime;
1674 struct azx_dev *azx_dev = get_azx_dev(substream); 1776 struct azx_dev *azx_dev = get_azx_dev(substream);
1777 int ret;
1675 1778
1779 mark_runtime_wc(chip, azx_dev, runtime, false);
1676 azx_dev->bufsize = 0; 1780 azx_dev->bufsize = 0;
1677 azx_dev->period_bytes = 0; 1781 azx_dev->period_bytes = 0;
1678 azx_dev->format_val = 0; 1782 azx_dev->format_val = 0;
1679 return snd_pcm_lib_malloc_pages(substream, 1783 ret = snd_pcm_lib_malloc_pages(substream,
1680 params_buffer_bytes(hw_params)); 1784 params_buffer_bytes(hw_params));
1785 if (ret < 0)
1786 return ret;
1787 mark_runtime_wc(chip, azx_dev, runtime, true);
1788 return ret;
1681} 1789}
1682 1790
1683static int azx_pcm_hw_free(struct snd_pcm_substream *substream) 1791static int azx_pcm_hw_free(struct snd_pcm_substream *substream)
1684{ 1792{
1685 struct azx_pcm *apcm = snd_pcm_substream_chip(substream); 1793 struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
1686 struct azx_dev *azx_dev = get_azx_dev(substream); 1794 struct azx_dev *azx_dev = get_azx_dev(substream);
1795 struct azx *chip = apcm->chip;
1796 struct snd_pcm_runtime *runtime = substream->runtime;
1687 struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream]; 1797 struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream];
1688 1798
1689 /* reset BDL address */ 1799 /* reset BDL address */
@@ -1696,6 +1806,7 @@ static int azx_pcm_hw_free(struct snd_pcm_substream *substream)
1696 1806
1697 snd_hda_codec_cleanup(apcm->codec, hinfo, substream); 1807 snd_hda_codec_cleanup(apcm->codec, hinfo, substream);
1698 1808
1809 mark_runtime_wc(chip, azx_dev, runtime, false);
1699 return snd_pcm_lib_free_pages(substream); 1810 return snd_pcm_lib_free_pages(substream);
1700} 1811}
1701 1812
@@ -2055,6 +2166,20 @@ static void azx_clear_irq_pending(struct azx *chip)
2055 spin_unlock_irq(&chip->reg_lock); 2166 spin_unlock_irq(&chip->reg_lock);
2056} 2167}
2057 2168
2169#ifdef CONFIG_X86
2170static int azx_pcm_mmap(struct snd_pcm_substream *substream,
2171 struct vm_area_struct *area)
2172{
2173 struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
2174 struct azx *chip = apcm->chip;
2175 if (!azx_snoop(chip))
2176 area->vm_page_prot = pgprot_writecombine(area->vm_page_prot);
2177 return snd_pcm_lib_default_mmap(substream, area);
2178}
2179#else
2180#define azx_pcm_mmap NULL
2181#endif
2182
2058static struct snd_pcm_ops azx_pcm_ops = { 2183static struct snd_pcm_ops azx_pcm_ops = {
2059 .open = azx_pcm_open, 2184 .open = azx_pcm_open,
2060 .close = azx_pcm_close, 2185 .close = azx_pcm_close,
@@ -2064,6 +2189,7 @@ static struct snd_pcm_ops azx_pcm_ops = {
2064 .prepare = azx_pcm_prepare, 2189 .prepare = azx_pcm_prepare,
2065 .trigger = azx_pcm_trigger, 2190 .trigger = azx_pcm_trigger,
2066 .pointer = azx_pcm_pointer, 2191 .pointer = azx_pcm_pointer,
2192 .mmap = azx_pcm_mmap,
2067 .page = snd_pcm_sgbuf_ops_page, 2193 .page = snd_pcm_sgbuf_ops_page,
2068}; 2194};
2069 2195
@@ -2344,13 +2470,19 @@ static int azx_free(struct azx *chip)
2344 2470
2345 if (chip->azx_dev) { 2471 if (chip->azx_dev) {
2346 for (i = 0; i < chip->num_streams; i++) 2472 for (i = 0; i < chip->num_streams; i++)
2347 if (chip->azx_dev[i].bdl.area) 2473 if (chip->azx_dev[i].bdl.area) {
2474 mark_pages_wc(chip, &chip->azx_dev[i].bdl, false);
2348 snd_dma_free_pages(&chip->azx_dev[i].bdl); 2475 snd_dma_free_pages(&chip->azx_dev[i].bdl);
2476 }
2349 } 2477 }
2350 if (chip->rb.area) 2478 if (chip->rb.area) {
2479 mark_pages_wc(chip, &chip->rb, false);
2351 snd_dma_free_pages(&chip->rb); 2480 snd_dma_free_pages(&chip->rb);
2352 if (chip->posbuf.area) 2481 }
2482 if (chip->posbuf.area) {
2483 mark_pages_wc(chip, &chip->posbuf, false);
2353 snd_dma_free_pages(&chip->posbuf); 2484 snd_dma_free_pages(&chip->posbuf);
2485 }
2354 pci_release_regions(chip->pci); 2486 pci_release_regions(chip->pci);
2355 pci_disable_device(chip->pci); 2487 pci_disable_device(chip->pci);
2356 kfree(chip->azx_dev); 2488 kfree(chip->azx_dev);
@@ -2546,6 +2678,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
2546 check_probe_mask(chip, dev); 2678 check_probe_mask(chip, dev);
2547 2679
2548 chip->single_cmd = single_cmd; 2680 chip->single_cmd = single_cmd;
2681 chip->snoop = hda_snoop;
2549 2682
2550 if (bdl_pos_adj[dev] < 0) { 2683 if (bdl_pos_adj[dev] < 0) {
2551 switch (chip->driver_type) { 2684 switch (chip->driver_type) {
@@ -2618,6 +2751,10 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
2618 gcap &= ~ICH6_GCAP_64OK; 2751 gcap &= ~ICH6_GCAP_64OK;
2619 } 2752 }
2620 2753
2754 /* disable buffer size rounding to 128-byte multiples if supported */
2755 if (chip->driver_caps & AZX_DCAPS_BUFSIZE)
2756 align_buffer_size = 0;
2757
2621 /* allow 64bit DMA address if supported by H/W */ 2758 /* allow 64bit DMA address if supported by H/W */
2622 if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64))) 2759 if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64)))
2623 pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(64)); 2760 pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(64));
@@ -2669,6 +2806,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
2669 snd_printk(KERN_ERR SFX "cannot allocate BDL\n"); 2806 snd_printk(KERN_ERR SFX "cannot allocate BDL\n");
2670 goto errout; 2807 goto errout;
2671 } 2808 }
2809 mark_pages_wc(chip, &chip->azx_dev[i].bdl, true);
2672 } 2810 }
2673 /* allocate memory for the position buffer */ 2811 /* allocate memory for the position buffer */
2674 err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, 2812 err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
@@ -2678,6 +2816,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
2678 snd_printk(KERN_ERR SFX "cannot allocate posbuf\n"); 2816 snd_printk(KERN_ERR SFX "cannot allocate posbuf\n");
2679 goto errout; 2817 goto errout;
2680 } 2818 }
2819 mark_pages_wc(chip, &chip->posbuf, true);
2681 /* allocate CORB/RIRB */ 2820 /* allocate CORB/RIRB */
2682 err = azx_alloc_cmd_io(chip); 2821 err = azx_alloc_cmd_io(chip);
2683 if (err < 0) 2822 if (err < 0)
@@ -2819,37 +2958,49 @@ static void __devexit azx_remove(struct pci_dev *pci)
2819static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { 2958static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
2820 /* CPT */ 2959 /* CPT */
2821 { PCI_DEVICE(0x8086, 0x1c20), 2960 { PCI_DEVICE(0x8086, 0x1c20),
2822 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP }, 2961 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
2962 AZX_DCAPS_BUFSIZE },
2823 /* PBG */ 2963 /* PBG */
2824 { PCI_DEVICE(0x8086, 0x1d20), 2964 { PCI_DEVICE(0x8086, 0x1d20),
2825 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP }, 2965 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
2966 AZX_DCAPS_BUFSIZE},
2826 /* Panther Point */ 2967 /* Panther Point */
2827 { PCI_DEVICE(0x8086, 0x1e20), 2968 { PCI_DEVICE(0x8086, 0x1e20),
2828 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP }, 2969 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
2970 AZX_DCAPS_BUFSIZE},
2829 /* SCH */ 2971 /* SCH */
2830 { PCI_DEVICE(0x8086, 0x811b), 2972 { PCI_DEVICE(0x8086, 0x811b),
2831 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP }, 2973 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
2974 AZX_DCAPS_BUFSIZE},
2832 { PCI_DEVICE(0x8086, 0x2668), 2975 { PCI_DEVICE(0x8086, 0x2668),
2833 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH6 */ 2976 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
2977 AZX_DCAPS_BUFSIZE }, /* ICH6 */
2834 { PCI_DEVICE(0x8086, 0x27d8), 2978 { PCI_DEVICE(0x8086, 0x27d8),
2835 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH7 */ 2979 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
2980 AZX_DCAPS_BUFSIZE }, /* ICH7 */
2836 { PCI_DEVICE(0x8086, 0x269a), 2981 { PCI_DEVICE(0x8086, 0x269a),
2837 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ESB2 */ 2982 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
2983 AZX_DCAPS_BUFSIZE }, /* ESB2 */
2838 { PCI_DEVICE(0x8086, 0x284b), 2984 { PCI_DEVICE(0x8086, 0x284b),
2839 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH8 */ 2985 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
2986 AZX_DCAPS_BUFSIZE }, /* ICH8 */
2840 { PCI_DEVICE(0x8086, 0x293e), 2987 { PCI_DEVICE(0x8086, 0x293e),
2841 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH9 */ 2988 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
2989 AZX_DCAPS_BUFSIZE }, /* ICH9 */
2842 { PCI_DEVICE(0x8086, 0x293f), 2990 { PCI_DEVICE(0x8086, 0x293f),
2843 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH9 */ 2991 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
2992 AZX_DCAPS_BUFSIZE }, /* ICH9 */
2844 { PCI_DEVICE(0x8086, 0x3a3e), 2993 { PCI_DEVICE(0x8086, 0x3a3e),
2845 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH10 */ 2994 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
2995 AZX_DCAPS_BUFSIZE }, /* ICH10 */
2846 { PCI_DEVICE(0x8086, 0x3a6e), 2996 { PCI_DEVICE(0x8086, 0x3a6e),
2847 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH10 */ 2997 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
2998 AZX_DCAPS_BUFSIZE }, /* ICH10 */
2848 /* Generic Intel */ 2999 /* Generic Intel */
2849 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_ANY_ID), 3000 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_ANY_ID),
2850 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, 3001 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
2851 .class_mask = 0xffffff, 3002 .class_mask = 0xffffff,
2852 .driver_data = AZX_DRIVER_ICH }, 3003 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_BUFSIZE },
2853 /* ATI SB 450/600/700/800/900 */ 3004 /* ATI SB 450/600/700/800/900 */
2854 { PCI_DEVICE(0x1002, 0x437b), 3005 { PCI_DEVICE(0x1002, 0x437b),
2855 .driver_data = AZX_DRIVER_ATI | AZX_DCAPS_PRESET_ATI_SB }, 3006 .driver_data = AZX_DRIVER_ATI | AZX_DCAPS_PRESET_ATI_SB },
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 2e7ac31afa8..81e12c0ed0a 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -267,11 +267,14 @@ int snd_hda_ch_mode_put(struct hda_codec *codec,
267enum { HDA_FRONT, HDA_REAR, HDA_CLFE, HDA_SIDE }; /* index for dac_nidx */ 267enum { HDA_FRONT, HDA_REAR, HDA_CLFE, HDA_SIDE }; /* index for dac_nidx */
268enum { HDA_DIG_NONE, HDA_DIG_EXCLUSIVE, HDA_DIG_ANALOG_DUP }; /* dig_out_used */ 268enum { HDA_DIG_NONE, HDA_DIG_EXCLUSIVE, HDA_DIG_ANALOG_DUP }; /* dig_out_used */
269 269
270#define HDA_MAX_OUTS 5
271
270struct hda_multi_out { 272struct hda_multi_out {
271 int num_dacs; /* # of DACs, must be more than 1 */ 273 int num_dacs; /* # of DACs, must be more than 1 */
272 const hda_nid_t *dac_nids; /* DAC list */ 274 const hda_nid_t *dac_nids; /* DAC list */
273 hda_nid_t hp_nid; /* optional DAC for HP, 0 when not exists */ 275 hda_nid_t hp_nid; /* optional DAC for HP, 0 when not exists */
274 hda_nid_t extra_out_nid[3]; /* optional DACs, 0 when not exists */ 276 hda_nid_t hp_out_nid[HDA_MAX_OUTS]; /* DACs for multiple HPs */
277 hda_nid_t extra_out_nid[HDA_MAX_OUTS]; /* other (e.g. speaker) DACs */
275 hda_nid_t dig_out_nid; /* digital out audio widget */ 278 hda_nid_t dig_out_nid; /* digital out audio widget */
276 const hda_nid_t *slave_dig_outs; 279 const hda_nid_t *slave_dig_outs;
277 int max_channels; /* currently supported analog channels */ 280 int max_channels; /* currently supported analog channels */
@@ -333,9 +336,6 @@ int snd_hda_codec_proc_new(struct hda_codec *codec);
333static inline int snd_hda_codec_proc_new(struct hda_codec *codec) { return 0; } 336static inline int snd_hda_codec_proc_new(struct hda_codec *codec) { return 0; }
334#endif 337#endif
335 338
336#define SND_PRINT_RATES_ADVISED_BUFSIZE 80
337void snd_print_pcm_rates(int pcm, char *buf, int buflen);
338
339#define SND_PRINT_BITS_ADVISED_BUFSIZE 16 339#define SND_PRINT_BITS_ADVISED_BUFSIZE 16
340void snd_print_pcm_bits(int pcm, char *buf, int buflen); 340void snd_print_pcm_bits(int pcm, char *buf, int buflen);
341 341
@@ -385,7 +385,7 @@ enum {
385 AUTO_PIN_HP_OUT 385 AUTO_PIN_HP_OUT
386}; 386};
387 387
388#define AUTO_CFG_MAX_OUTS 5 388#define AUTO_CFG_MAX_OUTS HDA_MAX_OUTS
389#define AUTO_CFG_MAX_INS 8 389#define AUTO_CFG_MAX_INS 8
390 390
391struct auto_pin_cfg_item { 391struct auto_pin_cfg_item {
@@ -443,9 +443,18 @@ struct auto_pin_cfg {
443#define get_defcfg_device(cfg) \ 443#define get_defcfg_device(cfg) \
444 ((cfg & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT) 444 ((cfg & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT)
445 445
446int snd_hda_parse_pin_def_config(struct hda_codec *codec, 446/* bit-flags for snd_hda_parse_pin_def_config() behavior */
447 struct auto_pin_cfg *cfg, 447#define HDA_PINCFG_NO_HP_FIXUP (1 << 0) /* no HP-split */
448 const hda_nid_t *ignore_nids); 448#define HDA_PINCFG_NO_LO_FIXUP (1 << 1) /* don't take other outs as LO */
449
450int snd_hda_parse_pin_defcfg(struct hda_codec *codec,
451 struct auto_pin_cfg *cfg,
452 const hda_nid_t *ignore_nids,
453 unsigned int cond_flags);
454
455/* older function */
456#define snd_hda_parse_pin_def_config(codec, cfg, ignore) \
457 snd_hda_parse_pin_defcfg(codec, cfg, ignore, 0)
449 458
450/* amp values */ 459/* amp values */
451#define AMP_IN_MUTE(idx) (0x7080 | ((idx)<<8)) 460#define AMP_IN_MUTE(idx) (0x7080 | ((idx)<<8))
@@ -492,6 +501,8 @@ u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction);
492int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, 501int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
493 unsigned int caps); 502 unsigned int caps);
494u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid); 503u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid);
504int snd_hda_override_pin_caps(struct hda_codec *codec, hda_nid_t nid,
505 unsigned int caps);
495u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid); 506u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid);
496int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid); 507int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid);
497 508
@@ -589,7 +600,8 @@ int snd_hda_check_amp_list_power(struct hda_codec *codec,
589#define get_amp_nid_(pv) ((pv) & 0xffff) 600#define get_amp_nid_(pv) ((pv) & 0xffff)
590#define get_amp_nid(kc) get_amp_nid_((kc)->private_value) 601#define get_amp_nid(kc) get_amp_nid_((kc)->private_value)
591#define get_amp_channels(kc) (((kc)->private_value >> 16) & 0x3) 602#define get_amp_channels(kc) (((kc)->private_value >> 16) & 0x3)
592#define get_amp_direction(kc) (((kc)->private_value >> 18) & 0x1) 603#define get_amp_direction_(pv) (((pv) >> 18) & 0x1)
604#define get_amp_direction(kc) get_amp_direction_((kc)->private_value)
593#define get_amp_index(kc) (((kc)->private_value >> 19) & 0xf) 605#define get_amp_index(kc) (((kc)->private_value >> 19) & 0xf)
594#define get_amp_offset(kc) (((kc)->private_value >> 23) & 0x3f) 606#define get_amp_offset(kc) (((kc)->private_value >> 23) & 0x3f)
595#define get_amp_min_mute(kc) (((kc)->private_value >> 29) & 0x1) 607#define get_amp_min_mute(kc) (((kc)->private_value >> 29) & 0x1)
@@ -607,6 +619,7 @@ struct cea_sad {
607}; 619};
608 620
609#define ELD_FIXED_BYTES 20 621#define ELD_FIXED_BYTES 20
622#define ELD_MAX_SIZE 256
610#define ELD_MAX_MNL 16 623#define ELD_MAX_MNL 16
611#define ELD_MAX_SAD 16 624#define ELD_MAX_SAD 16
612 625
@@ -631,6 +644,7 @@ struct hdmi_eld {
631 int spk_alloc; 644 int spk_alloc;
632 int sad_count; 645 int sad_count;
633 struct cea_sad sad[ELD_MAX_SAD]; 646 struct cea_sad sad[ELD_MAX_SAD];
647 char eld_buffer[ELD_MAX_SIZE];
634#ifdef CONFIG_PROC_FS 648#ifdef CONFIG_PROC_FS
635 struct snd_info_entry *proc_entry; 649 struct snd_info_entry *proc_entry;
636#endif 650#endif
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
index 2be57b051aa..2c981b55940 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -152,12 +152,18 @@ static void print_amp_vals(struct snd_info_buffer *buffer,
152 152
153static void print_pcm_rates(struct snd_info_buffer *buffer, unsigned int pcm) 153static void print_pcm_rates(struct snd_info_buffer *buffer, unsigned int pcm)
154{ 154{
155 char buf[SND_PRINT_RATES_ADVISED_BUFSIZE]; 155 static unsigned int rates[] = {
156 8000, 11025, 16000, 22050, 32000, 44100, 48000, 88200,
157 96000, 176400, 192000, 384000
158 };
159 int i;
156 160
157 pcm &= AC_SUPPCM_RATES; 161 pcm &= AC_SUPPCM_RATES;
158 snd_iprintf(buffer, " rates [0x%x]:", pcm); 162 snd_iprintf(buffer, " rates [0x%x]:", pcm);
159 snd_print_pcm_rates(pcm, buf, sizeof(buf)); 163 for (i = 0; i < ARRAY_SIZE(rates); i++)
160 snd_iprintf(buffer, "%s\n", buf); 164 if (pcm & (1 << i))
165 snd_iprintf(buffer, " %d", rates[i]);
166 snd_iprintf(buffer, "\n");
161} 167}
162 168
163static void print_pcm_bits(struct snd_info_buffer *buffer, unsigned int pcm) 169static void print_pcm_bits(struct snd_info_buffer *buffer, unsigned int pcm)
diff --git a/sound/pci/hda/hda_trace.h b/sound/pci/hda/hda_trace.h
new file mode 100644
index 00000000000..9884871ddb0
--- /dev/null
+++ b/sound/pci/hda/hda_trace.h
@@ -0,0 +1,117 @@
1#undef TRACE_SYSTEM
2#define TRACE_SYSTEM hda
3#define TRACE_INCLUDE_FILE hda_trace
4
5#if !defined(_TRACE_HDA_H) || defined(TRACE_HEADER_MULTI_READ)
6#define _TRACE_HDA_H
7
8#include <linux/tracepoint.h>
9
10struct hda_bus;
11struct hda_codec;
12
13DECLARE_EVENT_CLASS(hda_cmd,
14
15 TP_PROTO(struct hda_codec *codec, unsigned int val),
16
17 TP_ARGS(codec, val),
18
19 TP_STRUCT__entry(
20 __field( unsigned int, card )
21 __field( unsigned int, addr )
22 __field( unsigned int, val )
23 ),
24
25 TP_fast_assign(
26 __entry->card = (codec)->bus->card->number;
27 __entry->addr = (codec)->addr;
28 __entry->val = (val);
29 ),
30
31 TP_printk("[%d:%d] val=%x", __entry->card, __entry->addr, __entry->val)
32);
33
34DEFINE_EVENT(hda_cmd, hda_send_cmd,
35 TP_PROTO(struct hda_codec *codec, unsigned int val),
36 TP_ARGS(codec, val)
37);
38
39DEFINE_EVENT(hda_cmd, hda_get_response,
40 TP_PROTO(struct hda_codec *codec, unsigned int val),
41 TP_ARGS(codec, val)
42);
43
44TRACE_EVENT(hda_bus_reset,
45
46 TP_PROTO(struct hda_bus *bus),
47
48 TP_ARGS(bus),
49
50 TP_STRUCT__entry(
51 __field( unsigned int, card )
52 ),
53
54 TP_fast_assign(
55 __entry->card = (bus)->card->number;
56 ),
57
58 TP_printk("[%d]", __entry->card)
59);
60
61DECLARE_EVENT_CLASS(hda_power,
62
63 TP_PROTO(struct hda_codec *codec),
64
65 TP_ARGS(codec),
66
67 TP_STRUCT__entry(
68 __field( unsigned int, card )
69 __field( unsigned int, addr )
70 ),
71
72 TP_fast_assign(
73 __entry->card = (codec)->bus->card->number;
74 __entry->addr = (codec)->addr;
75 ),
76
77 TP_printk("[%d:%d]", __entry->card, __entry->addr)
78);
79
80DEFINE_EVENT(hda_power, hda_power_down,
81 TP_PROTO(struct hda_codec *codec),
82 TP_ARGS(codec)
83);
84
85DEFINE_EVENT(hda_power, hda_power_up,
86 TP_PROTO(struct hda_codec *codec),
87 TP_ARGS(codec)
88);
89
90TRACE_EVENT(hda_unsol_event,
91
92 TP_PROTO(struct hda_bus *bus, u32 res, u32 res_ex),
93
94 TP_ARGS(bus, res, res_ex),
95
96 TP_STRUCT__entry(
97 __field( unsigned int, card )
98 __field( u32, res )
99 __field( u32, res_ex )
100 ),
101
102 TP_fast_assign(
103 __entry->card = (bus)->card->number;
104 __entry->res = res;
105 __entry->res_ex = res_ex;
106 ),
107
108 TP_printk("[%d] res=%x, res_ex=%x", __entry->card,
109 __entry->res, __entry->res_ex)
110);
111
112#endif /* _TRACE_HDA_H */
113
114/* This part must be outside protection */
115#undef TRACE_INCLUDE_PATH
116#define TRACE_INCLUDE_PATH .
117#include <trace/define_trace.h>
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 8648917acff..d8aac588f23 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -48,6 +48,8 @@ struct ad198x_spec {
48 48
49 const hda_nid_t *alt_dac_nid; 49 const hda_nid_t *alt_dac_nid;
50 const struct hda_pcm_stream *stream_analog_alt_playback; 50 const struct hda_pcm_stream *stream_analog_alt_playback;
51 int independent_hp;
52 int num_active_streams;
51 53
52 /* capture */ 54 /* capture */
53 unsigned int num_adc_nids; 55 unsigned int num_adc_nids;
@@ -302,6 +304,72 @@ static int ad198x_check_power_status(struct hda_codec *codec, hda_nid_t nid)
302} 304}
303#endif 305#endif
304 306
307static void activate_ctl(struct hda_codec *codec, const char *name, int active)
308{
309 struct snd_kcontrol *ctl = snd_hda_find_mixer_ctl(codec, name);
310 if (ctl) {
311 ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
312 ctl->vd[0].access |= active ? 0 :
313 SNDRV_CTL_ELEM_ACCESS_INACTIVE;
314 ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_WRITE;
315 ctl->vd[0].access |= active ?
316 SNDRV_CTL_ELEM_ACCESS_WRITE : 0;
317 snd_ctl_notify(codec->bus->card,
318 SNDRV_CTL_EVENT_MASK_INFO, &ctl->id);
319 }
320}
321
322static void set_stream_active(struct hda_codec *codec, bool active)
323{
324 struct ad198x_spec *spec = codec->spec;
325 if (active)
326 spec->num_active_streams++;
327 else
328 spec->num_active_streams--;
329 activate_ctl(codec, "Independent HP", spec->num_active_streams == 0);
330}
331
332static int ad1988_independent_hp_info(struct snd_kcontrol *kcontrol,
333 struct snd_ctl_elem_info *uinfo)
334{
335 static const char * const texts[] = { "OFF", "ON", NULL};
336 int index;
337 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
338 uinfo->count = 1;
339 uinfo->value.enumerated.items = 2;
340 index = uinfo->value.enumerated.item;
341 if (index >= 2)
342 index = 1;
343 strcpy(uinfo->value.enumerated.name, texts[index]);
344 return 0;
345}
346
347static int ad1988_independent_hp_get(struct snd_kcontrol *kcontrol,
348 struct snd_ctl_elem_value *ucontrol)
349{
350 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
351 struct ad198x_spec *spec = codec->spec;
352 ucontrol->value.enumerated.item[0] = spec->independent_hp;
353 return 0;
354}
355
356static int ad1988_independent_hp_put(struct snd_kcontrol *kcontrol,
357 struct snd_ctl_elem_value *ucontrol)
358{
359 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
360 struct ad198x_spec *spec = codec->spec;
361 unsigned int select = ucontrol->value.enumerated.item[0];
362 if (spec->independent_hp != select) {
363 spec->independent_hp = select;
364 if (spec->independent_hp)
365 spec->multiout.hp_nid = 0;
366 else
367 spec->multiout.hp_nid = spec->alt_dac_nid[0];
368 return 1;
369 }
370 return 0;
371}
372
305/* 373/*
306 * Analog playback callbacks 374 * Analog playback callbacks
307 */ 375 */
@@ -310,8 +378,15 @@ static int ad198x_playback_pcm_open(struct hda_pcm_stream *hinfo,
310 struct snd_pcm_substream *substream) 378 struct snd_pcm_substream *substream)
311{ 379{
312 struct ad198x_spec *spec = codec->spec; 380 struct ad198x_spec *spec = codec->spec;
313 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, 381 int err;
382 set_stream_active(codec, true);
383 err = snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
314 hinfo); 384 hinfo);
385 if (err < 0) {
386 set_stream_active(codec, false);
387 return err;
388 }
389 return 0;
315} 390}
316 391
317static int ad198x_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 392static int ad198x_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
@@ -333,11 +408,41 @@ static int ad198x_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
333 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); 408 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
334} 409}
335 410
411static int ad198x_playback_pcm_close(struct hda_pcm_stream *hinfo,
412 struct hda_codec *codec,
413 struct snd_pcm_substream *substream)
414{
415 set_stream_active(codec, false);
416 return 0;
417}
418
419static int ad1988_alt_playback_pcm_open(struct hda_pcm_stream *hinfo,
420 struct hda_codec *codec,
421 struct snd_pcm_substream *substream)
422{
423 struct ad198x_spec *spec = codec->spec;
424 if (!spec->independent_hp)
425 return -EBUSY;
426 set_stream_active(codec, true);
427 return 0;
428}
429
430static int ad1988_alt_playback_pcm_close(struct hda_pcm_stream *hinfo,
431 struct hda_codec *codec,
432 struct snd_pcm_substream *substream)
433{
434 set_stream_active(codec, false);
435 return 0;
436}
437
336static const struct hda_pcm_stream ad198x_pcm_analog_alt_playback = { 438static const struct hda_pcm_stream ad198x_pcm_analog_alt_playback = {
337 .substreams = 1, 439 .substreams = 1,
338 .channels_min = 2, 440 .channels_min = 2,
339 .channels_max = 2, 441 .channels_max = 2,
340 /* NID is set in ad198x_build_pcms */ 442 .ops = {
443 .open = ad1988_alt_playback_pcm_open,
444 .close = ad1988_alt_playback_pcm_close
445 },
341}; 446};
342 447
343/* 448/*
@@ -402,7 +507,6 @@ static int ad198x_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
402 return 0; 507 return 0;
403} 508}
404 509
405
406/* 510/*
407 */ 511 */
408static const struct hda_pcm_stream ad198x_pcm_analog_playback = { 512static const struct hda_pcm_stream ad198x_pcm_analog_playback = {
@@ -413,7 +517,8 @@ static const struct hda_pcm_stream ad198x_pcm_analog_playback = {
413 .ops = { 517 .ops = {
414 .open = ad198x_playback_pcm_open, 518 .open = ad198x_playback_pcm_open,
415 .prepare = ad198x_playback_pcm_prepare, 519 .prepare = ad198x_playback_pcm_prepare,
416 .cleanup = ad198x_playback_pcm_cleanup 520 .cleanup = ad198x_playback_pcm_cleanup,
521 .close = ad198x_playback_pcm_close
417 }, 522 },
418}; 523};
419 524
@@ -2058,7 +2163,6 @@ static int patch_ad1981(struct hda_codec *codec)
2058enum { 2163enum {
2059 AD1988_6STACK, 2164 AD1988_6STACK,
2060 AD1988_6STACK_DIG, 2165 AD1988_6STACK_DIG,
2061 AD1988_6STACK_DIG_FP,
2062 AD1988_3STACK, 2166 AD1988_3STACK,
2063 AD1988_3STACK_DIG, 2167 AD1988_3STACK_DIG,
2064 AD1988_LAPTOP, 2168 AD1988_LAPTOP,
@@ -2168,6 +2272,17 @@ static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol,
2168 return err; 2272 return err;
2169} 2273}
2170 2274
2275static const struct snd_kcontrol_new ad1988_hp_mixers[] = {
2276 {
2277 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2278 .name = "Independent HP",
2279 .info = ad1988_independent_hp_info,
2280 .get = ad1988_independent_hp_get,
2281 .put = ad1988_independent_hp_put,
2282 },
2283 { } /* end */
2284};
2285
2171/* 6-stack mode */ 2286/* 6-stack mode */
2172static const struct snd_kcontrol_new ad1988_6stack_mixers1[] = { 2287static const struct snd_kcontrol_new ad1988_6stack_mixers1[] = {
2173 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), 2288 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
@@ -2188,6 +2303,7 @@ static const struct snd_kcontrol_new ad1988_6stack_mixers1_rev2[] = {
2188}; 2303};
2189 2304
2190static const struct snd_kcontrol_new ad1988_6stack_mixers2[] = { 2305static const struct snd_kcontrol_new ad1988_6stack_mixers2[] = {
2306 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
2191 HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT), 2307 HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT),
2192 HDA_BIND_MUTE("Surround Playback Switch", 0x2a, 2, HDA_INPUT), 2308 HDA_BIND_MUTE("Surround Playback Switch", 0x2a, 2, HDA_INPUT),
2193 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x27, 1, 2, HDA_INPUT), 2309 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x27, 1, 2, HDA_INPUT),
@@ -2210,13 +2326,6 @@ static const struct snd_kcontrol_new ad1988_6stack_mixers2[] = {
2210 2326
2211 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT), 2327 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT),
2212 HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT), 2328 HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT),
2213
2214 { } /* end */
2215};
2216
2217static const struct snd_kcontrol_new ad1988_6stack_fp_mixers[] = {
2218 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
2219
2220 { } /* end */ 2329 { } /* end */
2221}; 2330};
2222 2331
@@ -2238,6 +2347,7 @@ static const struct snd_kcontrol_new ad1988_3stack_mixers1_rev2[] = {
2238}; 2347};
2239 2348
2240static const struct snd_kcontrol_new ad1988_3stack_mixers2[] = { 2349static const struct snd_kcontrol_new ad1988_3stack_mixers2[] = {
2350 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
2241 HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT), 2351 HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT),
2242 HDA_BIND_MUTE("Surround Playback Switch", 0x2c, 2, HDA_INPUT), 2352 HDA_BIND_MUTE("Surround Playback Switch", 0x2c, 2, HDA_INPUT),
2243 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x26, 1, 2, HDA_INPUT), 2353 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x26, 1, 2, HDA_INPUT),
@@ -2272,6 +2382,7 @@ static const struct snd_kcontrol_new ad1988_3stack_mixers2[] = {
2272 2382
2273/* laptop mode */ 2383/* laptop mode */
2274static const struct snd_kcontrol_new ad1988_laptop_mixers[] = { 2384static const struct snd_kcontrol_new ad1988_laptop_mixers[] = {
2385 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
2275 HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT), 2386 HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2276 HDA_CODEC_MUTE("PCM Playback Switch", 0x29, 0x0, HDA_INPUT), 2387 HDA_CODEC_MUTE("PCM Playback Switch", 0x29, 0x0, HDA_INPUT),
2277 HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT), 2388 HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
@@ -2446,7 +2557,7 @@ static const struct hda_verb ad1988_6stack_init_verbs[] = {
2446 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2557 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2447 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2558 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2448 /* Port-A front headphon path */ 2559 /* Port-A front headphon path */
2449 {0x37, AC_VERB_SET_CONNECT_SEL, 0x01}, /* DAC1:04h */ 2560 {0x37, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC0:03h */
2450 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2561 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2451 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2562 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2452 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2563 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
@@ -2594,7 +2705,7 @@ static const struct hda_verb ad1988_3stack_init_verbs[] = {
2594 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2705 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2595 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2706 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2596 /* Port-A front headphon path */ 2707 /* Port-A front headphon path */
2597 {0x37, AC_VERB_SET_CONNECT_SEL, 0x01}, /* DAC1:04h */ 2708 {0x37, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC0:03h */
2598 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2709 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2599 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2710 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2600 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2711 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
@@ -2669,7 +2780,7 @@ static const struct hda_verb ad1988_laptop_init_verbs[] = {
2669 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2780 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2670 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2781 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2671 /* Port-A front headphon path */ 2782 /* Port-A front headphon path */
2672 {0x37, AC_VERB_SET_CONNECT_SEL, 0x01}, /* DAC1:04h */ 2783 {0x37, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC0:03h */
2673 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2784 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2674 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2785 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2675 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2786 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
@@ -2782,11 +2893,11 @@ static inline hda_nid_t ad1988_idx_to_dac(struct hda_codec *codec, int idx)
2782{ 2893{
2783 static const hda_nid_t idx_to_dac[8] = { 2894 static const hda_nid_t idx_to_dac[8] = {
2784 /* A B C D E F G H */ 2895 /* A B C D E F G H */
2785 0x04, 0x06, 0x05, 0x04, 0x0a, 0x06, 0x05, 0x0a 2896 0x03, 0x06, 0x05, 0x04, 0x0a, 0x06, 0x05, 0x0a
2786 }; 2897 };
2787 static const hda_nid_t idx_to_dac_rev2[8] = { 2898 static const hda_nid_t idx_to_dac_rev2[8] = {
2788 /* A B C D E F G H */ 2899 /* A B C D E F G H */
2789 0x04, 0x05, 0x0a, 0x04, 0x06, 0x05, 0x0a, 0x06 2900 0x03, 0x05, 0x0a, 0x04, 0x06, 0x05, 0x0a, 0x06
2790 }; 2901 };
2791 if (is_rev2(codec)) 2902 if (is_rev2(codec))
2792 return idx_to_dac_rev2[idx]; 2903 return idx_to_dac_rev2[idx];
@@ -3023,8 +3134,8 @@ static void ad1988_auto_set_output_and_unmute(struct hda_codec *codec,
3023 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); 3134 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
3024 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); 3135 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
3025 switch (nid) { 3136 switch (nid) {
3026 case 0x11: /* port-A - DAC 04 */ 3137 case 0x11: /* port-A - DAC 03 */
3027 snd_hda_codec_write(codec, 0x37, 0, AC_VERB_SET_CONNECT_SEL, 0x01); 3138 snd_hda_codec_write(codec, 0x37, 0, AC_VERB_SET_CONNECT_SEL, 0x00);
3028 break; 3139 break;
3029 case 0x14: /* port-B - DAC 06 */ 3140 case 0x14: /* port-B - DAC 06 */
3030 snd_hda_codec_write(codec, 0x30, 0, AC_VERB_SET_CONNECT_SEL, 0x02); 3141 snd_hda_codec_write(codec, 0x30, 0, AC_VERB_SET_CONNECT_SEL, 0x02);
@@ -3150,7 +3261,6 @@ static int ad1988_auto_init(struct hda_codec *codec)
3150static const char * const ad1988_models[AD1988_MODEL_LAST] = { 3261static const char * const ad1988_models[AD1988_MODEL_LAST] = {
3151 [AD1988_6STACK] = "6stack", 3262 [AD1988_6STACK] = "6stack",
3152 [AD1988_6STACK_DIG] = "6stack-dig", 3263 [AD1988_6STACK_DIG] = "6stack-dig",
3153 [AD1988_6STACK_DIG_FP] = "6stack-dig-fp",
3154 [AD1988_3STACK] = "3stack", 3264 [AD1988_3STACK] = "3stack",
3155 [AD1988_3STACK_DIG] = "3stack-dig", 3265 [AD1988_3STACK_DIG] = "3stack-dig",
3156 [AD1988_LAPTOP] = "laptop", 3266 [AD1988_LAPTOP] = "laptop",
@@ -3208,10 +3318,11 @@ static int patch_ad1988(struct hda_codec *codec)
3208 } 3318 }
3209 set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); 3319 set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
3210 3320
3321 if (!spec->multiout.hp_nid)
3322 spec->multiout.hp_nid = ad1988_alt_dac_nid[0];
3211 switch (board_config) { 3323 switch (board_config) {
3212 case AD1988_6STACK: 3324 case AD1988_6STACK:
3213 case AD1988_6STACK_DIG: 3325 case AD1988_6STACK_DIG:
3214 case AD1988_6STACK_DIG_FP:
3215 spec->multiout.max_channels = 8; 3326 spec->multiout.max_channels = 8;
3216 spec->multiout.num_dacs = 4; 3327 spec->multiout.num_dacs = 4;
3217 if (is_rev2(codec)) 3328 if (is_rev2(codec))
@@ -3227,19 +3338,7 @@ static int patch_ad1988(struct hda_codec *codec)
3227 spec->mixers[1] = ad1988_6stack_mixers2; 3338 spec->mixers[1] = ad1988_6stack_mixers2;
3228 spec->num_init_verbs = 1; 3339 spec->num_init_verbs = 1;
3229 spec->init_verbs[0] = ad1988_6stack_init_verbs; 3340 spec->init_verbs[0] = ad1988_6stack_init_verbs;
3230 if (board_config == AD1988_6STACK_DIG_FP) { 3341 if (board_config == AD1988_6STACK_DIG) {
3231 spec->num_mixers++;
3232 spec->mixers[2] = ad1988_6stack_fp_mixers;
3233 spec->num_init_verbs++;
3234 spec->init_verbs[1] = ad1988_6stack_fp_init_verbs;
3235 spec->slave_vols = ad1988_6stack_fp_slave_vols;
3236 spec->slave_sws = ad1988_6stack_fp_slave_sws;
3237 spec->alt_dac_nid = ad1988_alt_dac_nid;
3238 spec->stream_analog_alt_playback =
3239 &ad198x_pcm_analog_alt_playback;
3240 }
3241 if ((board_config == AD1988_6STACK_DIG) ||
3242 (board_config == AD1988_6STACK_DIG_FP)) {
3243 spec->multiout.dig_out_nid = AD1988_SPDIF_OUT; 3342 spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
3244 spec->dig_in_nid = AD1988_SPDIF_IN; 3343 spec->dig_in_nid = AD1988_SPDIF_IN;
3245 } 3344 }
@@ -3282,6 +3381,15 @@ static int patch_ad1988(struct hda_codec *codec)
3282 break; 3381 break;
3283 } 3382 }
3284 3383
3384 if (spec->autocfg.hp_pins[0]) {
3385 spec->mixers[spec->num_mixers++] = ad1988_hp_mixers;
3386 spec->slave_vols = ad1988_6stack_fp_slave_vols;
3387 spec->slave_sws = ad1988_6stack_fp_slave_sws;
3388 spec->alt_dac_nid = ad1988_alt_dac_nid;
3389 spec->stream_analog_alt_playback =
3390 &ad198x_pcm_analog_alt_playback;
3391 }
3392
3285 spec->num_adc_nids = ARRAY_SIZE(ad1988_adc_nids); 3393 spec->num_adc_nids = ARRAY_SIZE(ad1988_adc_nids);
3286 spec->adc_nids = ad1988_adc_nids; 3394 spec->adc_nids = ad1988_adc_nids;
3287 spec->capsrc_nids = ad1988_capsrc_nids; 3395 spec->capsrc_nids = ad1988_capsrc_nids;
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 76752d8ea73..0c8b5a1993e 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -136,6 +136,8 @@ struct conexant_spec {
136 unsigned int thinkpad:1; 136 unsigned int thinkpad:1;
137 unsigned int hp_laptop:1; 137 unsigned int hp_laptop:1;
138 unsigned int asus:1; 138 unsigned int asus:1;
139 unsigned int pin_eapd_ctrls:1;
140 unsigned int single_adc_amp:1;
139 141
140 unsigned int adc_switching:1; 142 unsigned int adc_switching:1;
141 143
@@ -1867,39 +1869,6 @@ static const struct hda_verb cxt5051_hp_dv6736_init_verbs[] = {
1867 { } /* end */ 1869 { } /* end */
1868}; 1870};
1869 1871
1870static const struct hda_verb cxt5051_lenovo_x200_init_verbs[] = {
1871 /* Line in, Mic */
1872 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1873 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1874 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1875 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1876 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1877 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1878 /* SPK */
1879 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1880 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
1881 /* HP, Amp */
1882 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1883 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
1884 /* Docking HP */
1885 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1886 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00},
1887 /* DAC1 */
1888 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1889 /* Record selector: Internal mic */
1890 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
1891 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1892 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
1893 /* SPDIF route: PCM */
1894 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* needed for W500 Advanced Mini Dock 250410 */
1895 {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0},
1896 /* EAPD */
1897 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
1898 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1899 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1900 { } /* end */
1901};
1902
1903static const struct hda_verb cxt5051_f700_init_verbs[] = { 1872static const struct hda_verb cxt5051_f700_init_verbs[] = {
1904 /* Line in, Mic */ 1873 /* Line in, Mic */
1905 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, 1874 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
@@ -1968,7 +1937,6 @@ enum {
1968 CXT5051_LAPTOP, /* Laptops w/ EAPD support */ 1937 CXT5051_LAPTOP, /* Laptops w/ EAPD support */
1969 CXT5051_HP, /* no docking */ 1938 CXT5051_HP, /* no docking */
1970 CXT5051_HP_DV6736, /* HP without mic switch */ 1939 CXT5051_HP_DV6736, /* HP without mic switch */
1971 CXT5051_LENOVO_X200, /* Lenovo X200 laptop, also used for Advanced Mini Dock 250410 */
1972 CXT5051_F700, /* HP Compaq Presario F700 */ 1940 CXT5051_F700, /* HP Compaq Presario F700 */
1973 CXT5051_TOSHIBA, /* Toshiba M300 & co */ 1941 CXT5051_TOSHIBA, /* Toshiba M300 & co */
1974 CXT5051_IDEAPAD, /* Lenovo IdeaPad Y430 */ 1942 CXT5051_IDEAPAD, /* Lenovo IdeaPad Y430 */
@@ -1980,7 +1948,6 @@ static const char *const cxt5051_models[CXT5051_MODELS] = {
1980 [CXT5051_LAPTOP] = "laptop", 1948 [CXT5051_LAPTOP] = "laptop",
1981 [CXT5051_HP] = "hp", 1949 [CXT5051_HP] = "hp",
1982 [CXT5051_HP_DV6736] = "hp-dv6736", 1950 [CXT5051_HP_DV6736] = "hp-dv6736",
1983 [CXT5051_LENOVO_X200] = "lenovo-x200",
1984 [CXT5051_F700] = "hp-700", 1951 [CXT5051_F700] = "hp-700",
1985 [CXT5051_TOSHIBA] = "toshiba", 1952 [CXT5051_TOSHIBA] = "toshiba",
1986 [CXT5051_IDEAPAD] = "ideapad", 1953 [CXT5051_IDEAPAD] = "ideapad",
@@ -1995,7 +1962,6 @@ static const struct snd_pci_quirk cxt5051_cfg_tbl[] = {
1995 SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board", 1962 SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board",
1996 CXT5051_LAPTOP), 1963 CXT5051_LAPTOP),
1997 SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP), 1964 SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP),
1998 SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT5051_LENOVO_X200),
1999 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo IdeaPad", CXT5051_IDEAPAD), 1965 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo IdeaPad", CXT5051_IDEAPAD),
2000 {} 1966 {}
2001}; 1967};
@@ -2053,13 +2019,6 @@ static int patch_cxt5051(struct hda_codec *codec)
2053 spec->mixers[0] = cxt5051_hp_dv6736_mixers; 2019 spec->mixers[0] = cxt5051_hp_dv6736_mixers;
2054 spec->auto_mic = 0; 2020 spec->auto_mic = 0;
2055 break; 2021 break;
2056 case CXT5051_LENOVO_X200:
2057 spec->init_verbs[0] = cxt5051_lenovo_x200_init_verbs;
2058 /* Thinkpad X301 does not have S/PDIF wired and no ability
2059 to use a docking station. */
2060 if (codec->subsystem_id == 0x17aa211f)
2061 spec->multiout.dig_out_nid = 0;
2062 break;
2063 case CXT5051_F700: 2022 case CXT5051_F700:
2064 spec->init_verbs[0] = cxt5051_f700_init_verbs; 2023 spec->init_verbs[0] = cxt5051_f700_init_verbs;
2065 spec->mixers[0] = cxt5051_f700_mixers; 2024 spec->mixers[0] = cxt5051_f700_mixers;
@@ -3473,12 +3432,14 @@ static void cx_auto_turn_eapd(struct hda_codec *codec, int num_pins,
3473static void do_automute(struct hda_codec *codec, int num_pins, 3432static void do_automute(struct hda_codec *codec, int num_pins,
3474 hda_nid_t *pins, bool on) 3433 hda_nid_t *pins, bool on)
3475{ 3434{
3435 struct conexant_spec *spec = codec->spec;
3476 int i; 3436 int i;
3477 for (i = 0; i < num_pins; i++) 3437 for (i = 0; i < num_pins; i++)
3478 snd_hda_codec_write(codec, pins[i], 0, 3438 snd_hda_codec_write(codec, pins[i], 0,
3479 AC_VERB_SET_PIN_WIDGET_CONTROL, 3439 AC_VERB_SET_PIN_WIDGET_CONTROL,
3480 on ? PIN_OUT : 0); 3440 on ? PIN_OUT : 0);
3481 cx_auto_turn_eapd(codec, num_pins, pins, on); 3441 if (spec->pin_eapd_ctrls)
3442 cx_auto_turn_eapd(codec, num_pins, pins, on);
3482} 3443}
3483 3444
3484static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins) 3445static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
@@ -3503,9 +3464,12 @@ static void cx_auto_update_speakers(struct hda_codec *codec)
3503 int on = 1; 3464 int on = 1;
3504 3465
3505 /* turn on HP EAPD when HP jacks are present */ 3466 /* turn on HP EAPD when HP jacks are present */
3506 if (spec->auto_mute) 3467 if (spec->pin_eapd_ctrls) {
3507 on = spec->hp_present; 3468 if (spec->auto_mute)
3508 cx_auto_turn_eapd(codec, cfg->hp_outs, cfg->hp_pins, on); 3469 on = spec->hp_present;
3470 cx_auto_turn_eapd(codec, cfg->hp_outs, cfg->hp_pins, on);
3471 }
3472
3509 /* mute speakers in auto-mode if HP or LO jacks are plugged */ 3473 /* mute speakers in auto-mode if HP or LO jacks are plugged */
3510 if (spec->auto_mute) 3474 if (spec->auto_mute)
3511 on = !(spec->hp_present || 3475 on = !(spec->hp_present ||
@@ -3932,20 +3896,10 @@ static void cx_auto_parse_beep(struct hda_codec *codec)
3932#define cx_auto_parse_beep(codec) 3896#define cx_auto_parse_beep(codec)
3933#endif 3897#endif
3934 3898
3935static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums) 3899/* parse EAPDs */
3936{
3937 int i;
3938 for (i = 0; i < nums; i++)
3939 if (list[i] == nid)
3940 return true;
3941 return false;
3942}
3943
3944/* parse extra-EAPD that aren't assigned to any pins */
3945static void cx_auto_parse_eapd(struct hda_codec *codec) 3900static void cx_auto_parse_eapd(struct hda_codec *codec)
3946{ 3901{
3947 struct conexant_spec *spec = codec->spec; 3902 struct conexant_spec *spec = codec->spec;
3948 struct auto_pin_cfg *cfg = &spec->autocfg;
3949 hda_nid_t nid, end_nid; 3903 hda_nid_t nid, end_nid;
3950 3904
3951 end_nid = codec->start_nid + codec->num_nodes; 3905 end_nid = codec->start_nid + codec->num_nodes;
@@ -3954,14 +3908,18 @@ static void cx_auto_parse_eapd(struct hda_codec *codec)
3954 continue; 3908 continue;
3955 if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)) 3909 if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD))
3956 continue; 3910 continue;
3957 if (found_in_nid_list(nid, cfg->line_out_pins, cfg->line_outs) ||
3958 found_in_nid_list(nid, cfg->hp_pins, cfg->hp_outs) ||
3959 found_in_nid_list(nid, cfg->speaker_pins, cfg->speaker_outs))
3960 continue;
3961 spec->eapds[spec->num_eapds++] = nid; 3911 spec->eapds[spec->num_eapds++] = nid;
3962 if (spec->num_eapds >= ARRAY_SIZE(spec->eapds)) 3912 if (spec->num_eapds >= ARRAY_SIZE(spec->eapds))
3963 break; 3913 break;
3964 } 3914 }
3915
3916 /* NOTE: below is a wild guess; if we have more than two EAPDs,
3917 * it's a new chip, where EAPDs are supposed to be associated to
3918 * pins, and we can control EAPD per pin.
3919 * OTOH, if only one or two EAPDs are found, it's an old chip,
3920 * thus it might control over all pins.
3921 */
3922 spec->pin_eapd_ctrls = spec->num_eapds > 2;
3965} 3923}
3966 3924
3967static int cx_auto_parse_auto_config(struct hda_codec *codec) 3925static int cx_auto_parse_auto_config(struct hda_codec *codec)
@@ -4067,8 +4025,9 @@ static void cx_auto_init_output(struct hda_codec *codec)
4067 } 4025 }
4068 } 4026 }
4069 cx_auto_update_speakers(codec); 4027 cx_auto_update_speakers(codec);
4070 /* turn on/off extra EAPDs, too */ 4028 /* turn on all EAPDs if no individual EAPD control is available */
4071 cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true); 4029 if (!spec->pin_eapd_ctrls)
4030 cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true);
4072} 4031}
4073 4032
4074static void cx_auto_init_input(struct hda_codec *codec) 4033static void cx_auto_init_input(struct hda_codec *codec)
@@ -4255,6 +4214,8 @@ static int cx_auto_add_capture_volume(struct hda_codec *codec, hda_nid_t nid,
4255 int idx = get_input_connection(codec, adc_nid, nid); 4214 int idx = get_input_connection(codec, adc_nid, nid);
4256 if (idx < 0) 4215 if (idx < 0)
4257 continue; 4216 continue;
4217 if (spec->single_adc_amp)
4218 idx = 0;
4258 return cx_auto_add_volume_idx(codec, label, pfx, 4219 return cx_auto_add_volume_idx(codec, label, pfx,
4259 cidx, adc_nid, HDA_INPUT, idx); 4220 cidx, adc_nid, HDA_INPUT, idx);
4260 } 4221 }
@@ -4295,14 +4256,21 @@ static int cx_auto_build_input_controls(struct hda_codec *codec)
4295 struct hda_input_mux *imux = &spec->private_imux; 4256 struct hda_input_mux *imux = &spec->private_imux;
4296 const char *prev_label; 4257 const char *prev_label;
4297 int input_conn[HDA_MAX_NUM_INPUTS]; 4258 int input_conn[HDA_MAX_NUM_INPUTS];
4298 int i, err, cidx; 4259 int i, j, err, cidx;
4299 int multi_connection; 4260 int multi_connection;
4300 4261
4262 if (!imux->num_items)
4263 return 0;
4264
4301 multi_connection = 0; 4265 multi_connection = 0;
4302 for (i = 0; i < imux->num_items; i++) { 4266 for (i = 0; i < imux->num_items; i++) {
4303 cidx = get_input_connection(codec, spec->imux_info[i].adc, 4267 cidx = get_input_connection(codec, spec->imux_info[i].adc,
4304 spec->imux_info[i].pin); 4268 spec->imux_info[i].pin);
4305 input_conn[i] = (spec->imux_info[i].adc << 8) | cidx; 4269 if (cidx < 0)
4270 continue;
4271 input_conn[i] = spec->imux_info[i].adc;
4272 if (!spec->single_adc_amp)
4273 input_conn[i] |= cidx << 8;
4306 if (i > 0 && input_conn[i] != input_conn[0]) 4274 if (i > 0 && input_conn[i] != input_conn[0])
4307 multi_connection = 1; 4275 multi_connection = 1;
4308 } 4276 }
@@ -4331,6 +4299,15 @@ static int cx_auto_build_input_controls(struct hda_codec *codec)
4331 err = cx_auto_add_capture_volume(codec, nid, 4299 err = cx_auto_add_capture_volume(codec, nid,
4332 "Capture", "", cidx); 4300 "Capture", "", cidx);
4333 } else { 4301 } else {
4302 bool dup_found = false;
4303 for (j = 0; j < i; j++) {
4304 if (input_conn[j] == input_conn[i]) {
4305 dup_found = true;
4306 break;
4307 }
4308 }
4309 if (dup_found)
4310 continue;
4334 err = cx_auto_add_capture_volume(codec, nid, 4311 err = cx_auto_add_capture_volume(codec, nid,
4335 label, " Capture", cidx); 4312 label, " Capture", cidx);
4336 } 4313 }
@@ -4394,6 +4371,53 @@ static const struct hda_codec_ops cx_auto_patch_ops = {
4394 .reboot_notify = snd_hda_shutup_pins, 4371 .reboot_notify = snd_hda_shutup_pins,
4395}; 4372};
4396 4373
4374/*
4375 * pin fix-up
4376 */
4377struct cxt_pincfg {
4378 hda_nid_t nid;
4379 u32 val;
4380};
4381
4382static void apply_pincfg(struct hda_codec *codec, const struct cxt_pincfg *cfg)
4383{
4384 for (; cfg->nid; cfg++)
4385 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
4386
4387}
4388
4389static void apply_pin_fixup(struct hda_codec *codec,
4390 const struct snd_pci_quirk *quirk,
4391 const struct cxt_pincfg **table)
4392{
4393 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
4394 if (quirk) {
4395 snd_printdd(KERN_INFO "hda_codec: applying pincfg for %s\n",
4396 quirk->name);
4397 apply_pincfg(codec, table[quirk->value]);
4398 }
4399}
4400
4401enum {
4402 CXT_PINCFG_LENOVO_X200,
4403};
4404
4405static const struct cxt_pincfg cxt_pincfg_lenovo_x200[] = {
4406 { 0x16, 0x042140ff }, /* HP (seq# overridden) */
4407 { 0x17, 0x21a11000 }, /* dock-mic */
4408 { 0x19, 0x2121103f }, /* dock-HP */
4409 {}
4410};
4411
4412static const struct cxt_pincfg *cxt_pincfg_tbl[] = {
4413 [CXT_PINCFG_LENOVO_X200] = cxt_pincfg_lenovo_x200,
4414};
4415
4416static const struct snd_pci_quirk cxt_fixups[] = {
4417 SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT_PINCFG_LENOVO_X200),
4418 {}
4419};
4420
4397static int patch_conexant_auto(struct hda_codec *codec) 4421static int patch_conexant_auto(struct hda_codec *codec)
4398{ 4422{
4399 struct conexant_spec *spec; 4423 struct conexant_spec *spec;
@@ -4407,6 +4431,15 @@ static int patch_conexant_auto(struct hda_codec *codec)
4407 return -ENOMEM; 4431 return -ENOMEM;
4408 codec->spec = spec; 4432 codec->spec = spec;
4409 codec->pin_amp_workaround = 1; 4433 codec->pin_amp_workaround = 1;
4434
4435 switch (codec->vendor_id) {
4436 case 0x14f15045:
4437 spec->single_adc_amp = 1;
4438 break;
4439 }
4440
4441 apply_pin_fixup(codec, cxt_fixups, cxt_pincfg_tbl);
4442
4410 err = cx_auto_search_adcs(codec); 4443 err = cx_auto_search_adcs(codec);
4411 if (err < 0) 4444 if (err < 0)
4412 return err; 4445 return err;
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 19cb72db9c3..342540128fb 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -324,6 +324,66 @@ static int cvt_nid_to_cvt_index(struct hdmi_spec *spec, hda_nid_t cvt_nid)
324 return -EINVAL; 324 return -EINVAL;
325} 325}
326 326
327static int hdmi_eld_ctl_info(struct snd_kcontrol *kcontrol,
328 struct snd_ctl_elem_info *uinfo)
329{
330 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
331 struct hdmi_spec *spec;
332 int pin_idx;
333
334 spec = codec->spec;
335 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
336
337 pin_idx = kcontrol->private_value;
338 uinfo->count = spec->pins[pin_idx].sink_eld.eld_size;
339
340 return 0;
341}
342
343static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol,
344 struct snd_ctl_elem_value *ucontrol)
345{
346 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
347 struct hdmi_spec *spec;
348 int pin_idx;
349
350 spec = codec->spec;
351 pin_idx = kcontrol->private_value;
352
353 memcpy(ucontrol->value.bytes.data,
354 spec->pins[pin_idx].sink_eld.eld_buffer, ELD_MAX_SIZE);
355
356 return 0;
357}
358
359static struct snd_kcontrol_new eld_bytes_ctl = {
360 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
361 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
362 .name = "ELD",
363 .info = hdmi_eld_ctl_info,
364 .get = hdmi_eld_ctl_get,
365};
366
367static int hdmi_create_eld_ctl(struct hda_codec *codec, int pin_idx,
368 int device)
369{
370 struct snd_kcontrol *kctl;
371 struct hdmi_spec *spec = codec->spec;
372 int err;
373
374 kctl = snd_ctl_new1(&eld_bytes_ctl, codec);
375 if (!kctl)
376 return -ENOMEM;
377 kctl->private_value = pin_idx;
378 kctl->id.device = device;
379
380 err = snd_hda_ctl_add(codec, spec->pins[pin_idx].pin_nid, kctl);
381 if (err < 0)
382 return err;
383
384 return 0;
385}
386
327#ifdef BE_PARANOID 387#ifdef BE_PARANOID
328static void hdmi_get_dip_index(struct hda_codec *codec, hda_nid_t pin_nid, 388static void hdmi_get_dip_index(struct hda_codec *codec, hda_nid_t pin_nid,
329 int *packet_index, int *byte_index) 389 int *packet_index, int *byte_index)
@@ -967,19 +1027,12 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
967 1027
968 per_pin->pin_nid = pin_nid; 1028 per_pin->pin_nid = pin_nid;
969 1029
970 err = snd_hda_input_jack_add(codec, pin_nid,
971 SND_JACK_VIDEOOUT, NULL);
972 if (err < 0)
973 return err;
974
975 err = hdmi_read_pin_conn(codec, pin_idx); 1030 err = hdmi_read_pin_conn(codec, pin_idx);
976 if (err < 0) 1031 if (err < 0)
977 return err; 1032 return err;
978 1033
979 spec->num_pins++; 1034 spec->num_pins++;
980 1035
981 hdmi_present_sense(codec, pin_nid, eld);
982
983 return 0; 1036 return 0;
984} 1037}
985 1038
@@ -1162,6 +1215,25 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec)
1162 return 0; 1215 return 0;
1163} 1216}
1164 1217
1218static int generic_hdmi_build_jack(struct hda_codec *codec, int pin_idx)
1219{
1220 int err;
1221 char hdmi_str[32];
1222 struct hdmi_spec *spec = codec->spec;
1223 struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
1224 int pcmdev = spec->pcm_rec[pin_idx].device;
1225
1226 snprintf(hdmi_str, sizeof(hdmi_str), "HDMI/DP,pcm=%d", pcmdev);
1227
1228 err = snd_hda_input_jack_add(codec, per_pin->pin_nid,
1229 SND_JACK_VIDEOOUT, pcmdev > 0 ? hdmi_str : NULL);
1230 if (err < 0)
1231 return err;
1232
1233 hdmi_present_sense(codec, per_pin->pin_nid, &per_pin->sink_eld);
1234 return 0;
1235}
1236
1165static int generic_hdmi_build_controls(struct hda_codec *codec) 1237static int generic_hdmi_build_controls(struct hda_codec *codec)
1166{ 1238{
1167 struct hdmi_spec *spec = codec->spec; 1239 struct hdmi_spec *spec = codec->spec;
@@ -1170,12 +1242,25 @@ static int generic_hdmi_build_controls(struct hda_codec *codec)
1170 1242
1171 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { 1243 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
1172 struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; 1244 struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
1245
1246 err = generic_hdmi_build_jack(codec, pin_idx);
1247 if (err < 0)
1248 return err;
1249
1173 err = snd_hda_create_spdif_out_ctls(codec, 1250 err = snd_hda_create_spdif_out_ctls(codec,
1174 per_pin->pin_nid, 1251 per_pin->pin_nid,
1175 per_pin->mux_nids[0]); 1252 per_pin->mux_nids[0]);
1176 if (err < 0) 1253 if (err < 0)
1177 return err; 1254 return err;
1178 snd_hda_spdif_ctls_unassign(codec, pin_idx); 1255 snd_hda_spdif_ctls_unassign(codec, pin_idx);
1256
1257 /* add control for ELD Bytes */
1258 err = hdmi_create_eld_ctl(codec,
1259 pin_idx,
1260 spec->pcm_rec[pin_idx].device);
1261
1262 if (err < 0)
1263 return err;
1179 } 1264 }
1180 1265
1181 return 0; 1266 return 0;
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 7a73621a890..8f93b97559a 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -116,6 +116,8 @@ struct alc_spec {
116 const hda_nid_t *capsrc_nids; 116 const hda_nid_t *capsrc_nids;
117 hda_nid_t dig_in_nid; /* digital-in NID; optional */ 117 hda_nid_t dig_in_nid; /* digital-in NID; optional */
118 hda_nid_t mixer_nid; /* analog-mixer NID */ 118 hda_nid_t mixer_nid; /* analog-mixer NID */
119 DECLARE_BITMAP(vol_ctls, 0x20 << 1);
120 DECLARE_BITMAP(sw_ctls, 0x20 << 1);
119 121
120 /* capture setup for dynamic dual-adc switch */ 122 /* capture setup for dynamic dual-adc switch */
121 hda_nid_t cur_adc; 123 hda_nid_t cur_adc;
@@ -159,23 +161,27 @@ struct alc_spec {
159 void (*power_hook)(struct hda_codec *codec); 161 void (*power_hook)(struct hda_codec *codec);
160#endif 162#endif
161 void (*shutup)(struct hda_codec *codec); 163 void (*shutup)(struct hda_codec *codec);
164 void (*automute_hook)(struct hda_codec *codec);
162 165
163 /* for pin sensing */ 166 /* for pin sensing */
164 unsigned int jack_present: 1; 167 unsigned int hp_jack_present:1;
165 unsigned int line_jack_present:1; 168 unsigned int line_jack_present:1;
166 unsigned int master_mute:1; 169 unsigned int master_mute:1;
167 unsigned int auto_mic:1; 170 unsigned int auto_mic:1;
168 unsigned int auto_mic_valid_imux:1; /* valid imux for auto-mic */ 171 unsigned int auto_mic_valid_imux:1; /* valid imux for auto-mic */
169 unsigned int automute:1; /* HP automute enabled */ 172 unsigned int automute_speaker:1; /* automute speaker outputs */
170 unsigned int detect_line:1; /* Line-out detection enabled */ 173 unsigned int automute_lo:1; /* automute LO outputs */
171 unsigned int automute_lines:1; /* automute line-out as well; NOP when automute_hp_lo isn't set */ 174 unsigned int detect_hp:1; /* Headphone detection enabled */
172 unsigned int automute_hp_lo:1; /* both HP and LO available */ 175 unsigned int detect_lo:1; /* Line-out detection enabled */
176 unsigned int automute_speaker_possible:1; /* there are speakers and either LO or HP */
177 unsigned int automute_lo_possible:1; /* there are line outs and HP */
173 178
174 /* other flags */ 179 /* other flags */
175 unsigned int no_analog :1; /* digital I/O only */ 180 unsigned int no_analog :1; /* digital I/O only */
176 unsigned int dyn_adc_switch:1; /* switch ADCs (for ALC275) */ 181 unsigned int dyn_adc_switch:1; /* switch ADCs (for ALC275) */
177 unsigned int single_input_src:1; 182 unsigned int single_input_src:1;
178 unsigned int vol_in_capsrc:1; /* use capsrc volume (ADC has no vol) */ 183 unsigned int vol_in_capsrc:1; /* use capsrc volume (ADC has no vol) */
184 unsigned int parse_flags; /* passed to snd_hda_parse_pin_defcfg() */
179 185
180 /* auto-mute control */ 186 /* auto-mute control */
181 int automute_mode; 187 int automute_mode;
@@ -193,6 +199,7 @@ struct alc_spec {
193 /* for PLL fix */ 199 /* for PLL fix */
194 hda_nid_t pll_nid; 200 hda_nid_t pll_nid;
195 unsigned int pll_coef_idx, pll_coef_bit; 201 unsigned int pll_coef_idx, pll_coef_bit;
202 unsigned int coef0;
196 203
197 /* fix-up list */ 204 /* fix-up list */
198 int fixup_id; 205 int fixup_id;
@@ -202,6 +209,9 @@ struct alc_spec {
202 /* multi-io */ 209 /* multi-io */
203 int multi_ios; 210 int multi_ios;
204 struct alc_multi_io multi_io[4]; 211 struct alc_multi_io multi_io[4];
212
213 /* bind volumes */
214 struct snd_array bind_ctls;
205}; 215};
206 216
207#define ALC_MODEL_AUTO 0 /* common for all chips */ 217#define ALC_MODEL_AUTO 0 /* common for all chips */
@@ -525,8 +535,8 @@ static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
525 } 535 }
526} 536}
527 537
528/* Toggle internal speakers muting */ 538/* Toggle outputs muting */
529static void update_speakers(struct hda_codec *codec) 539static void update_outputs(struct hda_codec *codec)
530{ 540{
531 struct alc_spec *spec = codec->spec; 541 struct alc_spec *spec = codec->spec;
532 int on; 542 int on;
@@ -538,10 +548,10 @@ static void update_speakers(struct hda_codec *codec)
538 do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins), 548 do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
539 spec->autocfg.hp_pins, spec->master_mute, true); 549 spec->autocfg.hp_pins, spec->master_mute, true);
540 550
541 if (!spec->automute) 551 if (!spec->automute_speaker)
542 on = 0; 552 on = 0;
543 else 553 else
544 on = spec->jack_present | spec->line_jack_present; 554 on = spec->hp_jack_present | spec->line_jack_present;
545 on |= spec->master_mute; 555 on |= spec->master_mute;
546 do_automute(codec, ARRAY_SIZE(spec->autocfg.speaker_pins), 556 do_automute(codec, ARRAY_SIZE(spec->autocfg.speaker_pins),
547 spec->autocfg.speaker_pins, on, false); 557 spec->autocfg.speaker_pins, on, false);
@@ -551,26 +561,35 @@ static void update_speakers(struct hda_codec *codec)
551 if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0] || 561 if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0] ||
552 spec->autocfg.line_out_pins[0] == spec->autocfg.speaker_pins[0]) 562 spec->autocfg.line_out_pins[0] == spec->autocfg.speaker_pins[0])
553 return; 563 return;
554 if (!spec->automute || (spec->automute_hp_lo && !spec->automute_lines)) 564 if (!spec->automute_lo)
555 on = 0; 565 on = 0;
556 else 566 else
557 on = spec->jack_present; 567 on = spec->hp_jack_present;
558 on |= spec->master_mute; 568 on |= spec->master_mute;
559 do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins), 569 do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
560 spec->autocfg.line_out_pins, on, false); 570 spec->autocfg.line_out_pins, on, false);
561} 571}
562 572
573static void call_update_outputs(struct hda_codec *codec)
574{
575 struct alc_spec *spec = codec->spec;
576 if (spec->automute_hook)
577 spec->automute_hook(codec);
578 else
579 update_outputs(codec);
580}
581
563/* standard HP-automute helper */ 582/* standard HP-automute helper */
564static void alc_hp_automute(struct hda_codec *codec) 583static void alc_hp_automute(struct hda_codec *codec)
565{ 584{
566 struct alc_spec *spec = codec->spec; 585 struct alc_spec *spec = codec->spec;
567 586
568 spec->jack_present = 587 spec->hp_jack_present =
569 detect_jacks(codec, ARRAY_SIZE(spec->autocfg.hp_pins), 588 detect_jacks(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
570 spec->autocfg.hp_pins); 589 spec->autocfg.hp_pins);
571 if (!spec->automute) 590 if (!spec->detect_hp || (!spec->automute_speaker && !spec->automute_lo))
572 return; 591 return;
573 update_speakers(codec); 592 call_update_outputs(codec);
574} 593}
575 594
576/* standard line-out-automute helper */ 595/* standard line-out-automute helper */
@@ -585,9 +604,9 @@ static void alc_line_automute(struct hda_codec *codec)
585 spec->line_jack_present = 604 spec->line_jack_present =
586 detect_jacks(codec, ARRAY_SIZE(spec->autocfg.line_out_pins), 605 detect_jacks(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
587 spec->autocfg.line_out_pins); 606 spec->autocfg.line_out_pins);
588 if (!spec->automute || !spec->detect_line) 607 if (!spec->automute_speaker || !spec->detect_lo)
589 return; 608 return;
590 update_speakers(codec); 609 call_update_outputs(codec);
591} 610}
592 611
593#define get_connection_index(codec, mux, nid) \ 612#define get_connection_index(codec, mux, nid) \
@@ -785,7 +804,7 @@ static int alc_automute_mode_info(struct snd_kcontrol *kcontrol,
785 804
786 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 805 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
787 uinfo->count = 1; 806 uinfo->count = 1;
788 if (spec->automute_hp_lo) { 807 if (spec->automute_speaker_possible && spec->automute_lo_possible) {
789 uinfo->value.enumerated.items = 3; 808 uinfo->value.enumerated.items = 3;
790 texts = texts3; 809 texts = texts3;
791 } else { 810 } else {
@@ -804,13 +823,12 @@ static int alc_automute_mode_get(struct snd_kcontrol *kcontrol,
804{ 823{
805 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 824 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
806 struct alc_spec *spec = codec->spec; 825 struct alc_spec *spec = codec->spec;
807 unsigned int val; 826 unsigned int val = 0;
808 if (!spec->automute) 827 if (spec->automute_speaker)
809 val = 0; 828 val++;
810 else if (!spec->automute_hp_lo || !spec->automute_lines) 829 if (spec->automute_lo)
811 val = 1; 830 val++;
812 else 831
813 val = 2;
814 ucontrol->value.enumerated.item[0] = val; 832 ucontrol->value.enumerated.item[0] = val;
815 return 0; 833 return 0;
816} 834}
@@ -823,29 +841,36 @@ static int alc_automute_mode_put(struct snd_kcontrol *kcontrol,
823 841
824 switch (ucontrol->value.enumerated.item[0]) { 842 switch (ucontrol->value.enumerated.item[0]) {
825 case 0: 843 case 0:
826 if (!spec->automute) 844 if (!spec->automute_speaker && !spec->automute_lo)
827 return 0; 845 return 0;
828 spec->automute = 0; 846 spec->automute_speaker = 0;
847 spec->automute_lo = 0;
829 break; 848 break;
830 case 1: 849 case 1:
831 if (spec->automute && 850 if (spec->automute_speaker_possible) {
832 (!spec->automute_hp_lo || !spec->automute_lines)) 851 if (!spec->automute_lo && spec->automute_speaker)
833 return 0; 852 return 0;
834 spec->automute = 1; 853 spec->automute_speaker = 1;
835 spec->automute_lines = 0; 854 spec->automute_lo = 0;
855 } else if (spec->automute_lo_possible) {
856 if (spec->automute_lo)
857 return 0;
858 spec->automute_lo = 1;
859 } else
860 return -EINVAL;
836 break; 861 break;
837 case 2: 862 case 2:
838 if (!spec->automute_hp_lo) 863 if (!spec->automute_lo_possible || !spec->automute_speaker_possible)
839 return -EINVAL; 864 return -EINVAL;
840 if (spec->automute && spec->automute_lines) 865 if (spec->automute_speaker && spec->automute_lo)
841 return 0; 866 return 0;
842 spec->automute = 1; 867 spec->automute_speaker = 1;
843 spec->automute_lines = 1; 868 spec->automute_lo = 1;
844 break; 869 break;
845 default: 870 default:
846 return -EINVAL; 871 return -EINVAL;
847 } 872 }
848 update_speakers(codec); 873 call_update_outputs(codec);
849 return 1; 874 return 1;
850} 875}
851 876
@@ -882,7 +907,7 @@ static int alc_add_automute_mode_enum(struct hda_codec *codec)
882 * Check the availability of HP/line-out auto-mute; 907 * Check the availability of HP/line-out auto-mute;
883 * Set up appropriately if really supported 908 * Set up appropriately if really supported
884 */ 909 */
885static void alc_init_auto_hp(struct hda_codec *codec) 910static void alc_init_automute(struct hda_codec *codec)
886{ 911{
887 struct alc_spec *spec = codec->spec; 912 struct alc_spec *spec = codec->spec;
888 struct auto_pin_cfg *cfg = &spec->autocfg; 913 struct auto_pin_cfg *cfg = &spec->autocfg;
@@ -897,8 +922,6 @@ static void alc_init_auto_hp(struct hda_codec *codec)
897 present++; 922 present++;
898 if (present < 2) /* need two different output types */ 923 if (present < 2) /* need two different output types */
899 return; 924 return;
900 if (present == 3)
901 spec->automute_hp_lo = 1; /* both HP and LO automute */
902 925
903 if (!cfg->speaker_pins[0] && 926 if (!cfg->speaker_pins[0] &&
904 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) { 927 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
@@ -914,6 +937,8 @@ static void alc_init_auto_hp(struct hda_codec *codec)
914 cfg->hp_outs = cfg->line_outs; 937 cfg->hp_outs = cfg->line_outs;
915 } 938 }
916 939
940 spec->automute_mode = ALC_AUTOMUTE_PIN;
941
917 for (i = 0; i < cfg->hp_outs; i++) { 942 for (i = 0; i < cfg->hp_outs; i++) {
918 hda_nid_t nid = cfg->hp_pins[i]; 943 hda_nid_t nid = cfg->hp_pins[i];
919 if (!is_jack_detectable(codec, nid)) 944 if (!is_jack_detectable(codec, nid))
@@ -923,28 +948,32 @@ static void alc_init_auto_hp(struct hda_codec *codec)
923 snd_hda_codec_write_cache(codec, nid, 0, 948 snd_hda_codec_write_cache(codec, nid, 0,
924 AC_VERB_SET_UNSOLICITED_ENABLE, 949 AC_VERB_SET_UNSOLICITED_ENABLE,
925 AC_USRSP_EN | ALC_HP_EVENT); 950 AC_USRSP_EN | ALC_HP_EVENT);
926 spec->automute = 1; 951 spec->detect_hp = 1;
927 spec->automute_mode = ALC_AUTOMUTE_PIN; 952 }
928 } 953
929 if (spec->automute && cfg->line_out_pins[0] && 954 if (cfg->line_out_type == AUTO_PIN_LINE_OUT && cfg->line_outs) {
930 cfg->speaker_pins[0] && 955 if (cfg->speaker_outs)
931 cfg->line_out_pins[0] != cfg->hp_pins[0] && 956 for (i = 0; i < cfg->line_outs; i++) {
932 cfg->line_out_pins[0] != cfg->speaker_pins[0]) { 957 hda_nid_t nid = cfg->line_out_pins[i];
933 for (i = 0; i < cfg->line_outs; i++) { 958 if (!is_jack_detectable(codec, nid))
934 hda_nid_t nid = cfg->line_out_pins[i]; 959 continue;
935 if (!is_jack_detectable(codec, nid)) 960 snd_printdd("realtek: Enable Line-Out "
936 continue; 961 "auto-muting on NID 0x%x\n", nid);
937 snd_printdd("realtek: Enable Line-Out auto-muting " 962 snd_hda_codec_write_cache(codec, nid, 0,
938 "on NID 0x%x\n", nid); 963 AC_VERB_SET_UNSOLICITED_ENABLE,
939 snd_hda_codec_write_cache(codec, nid, 0, 964 AC_USRSP_EN | ALC_FRONT_EVENT);
940 AC_VERB_SET_UNSOLICITED_ENABLE, 965 spec->detect_lo = 1;
941 AC_USRSP_EN | ALC_FRONT_EVENT);
942 spec->detect_line = 1;
943 } 966 }
944 spec->automute_lines = spec->detect_line; 967 spec->automute_lo_possible = spec->detect_hp;
945 } 968 }
946 969
947 if (spec->automute) { 970 spec->automute_speaker_possible = cfg->speaker_outs &&
971 (spec->detect_hp || spec->detect_lo);
972
973 spec->automute_lo = spec->automute_lo_possible;
974 spec->automute_speaker = spec->automute_speaker_possible;
975
976 if (spec->automute_speaker_possible || spec->automute_lo_possible) {
948 /* create a control for automute mode */ 977 /* create a control for automute mode */
949 alc_add_automute_mode_enum(codec); 978 alc_add_automute_mode_enum(codec);
950 spec->unsol_event = alc_sku_unsol_event; 979 spec->unsol_event = alc_sku_unsol_event;
@@ -1145,7 +1174,7 @@ static void alc_init_auto_mic(struct hda_codec *codec)
1145/* check the availabilities of auto-mute and auto-mic switches */ 1174/* check the availabilities of auto-mute and auto-mic switches */
1146static void alc_auto_check_switches(struct hda_codec *codec) 1175static void alc_auto_check_switches(struct hda_codec *codec)
1147{ 1176{
1148 alc_init_auto_hp(codec); 1177 alc_init_automute(codec);
1149 alc_init_auto_mic(codec); 1178 alc_init_auto_mic(codec);
1150} 1179}
1151 1180
@@ -1528,6 +1557,15 @@ static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx,
1528 coef_val); 1557 coef_val);
1529} 1558}
1530 1559
1560/* a special bypass for COEF 0; read the cached value at the second time */
1561static unsigned int alc_get_coef0(struct hda_codec *codec)
1562{
1563 struct alc_spec *spec = codec->spec;
1564 if (!spec->coef0)
1565 spec->coef0 = alc_read_coef_idx(codec, 0);
1566 return spec->coef0;
1567}
1568
1531/* 1569/*
1532 * Digital I/O handling 1570 * Digital I/O handling
1533 */ 1571 */
@@ -2368,6 +2406,18 @@ static void alc_free_kctls(struct hda_codec *codec)
2368 snd_array_free(&spec->kctls); 2406 snd_array_free(&spec->kctls);
2369} 2407}
2370 2408
2409static void alc_free_bind_ctls(struct hda_codec *codec)
2410{
2411 struct alc_spec *spec = codec->spec;
2412 if (spec->bind_ctls.list) {
2413 struct hda_bind_ctls **ctl = spec->bind_ctls.list;
2414 int i;
2415 for (i = 0; i < spec->bind_ctls.used; i++)
2416 kfree(ctl[i]);
2417 }
2418 snd_array_free(&spec->bind_ctls);
2419}
2420
2371static void alc_free(struct hda_codec *codec) 2421static void alc_free(struct hda_codec *codec)
2372{ 2422{
2373 struct alc_spec *spec = codec->spec; 2423 struct alc_spec *spec = codec->spec;
@@ -2378,6 +2428,7 @@ static void alc_free(struct hda_codec *codec)
2378 alc_shutup(codec); 2428 alc_shutup(codec);
2379 snd_hda_input_jack_free(codec); 2429 snd_hda_input_jack_free(codec);
2380 alc_free_kctls(codec); 2430 alc_free_kctls(codec);
2431 alc_free_bind_ctls(codec);
2381 kfree(spec); 2432 kfree(spec);
2382 snd_hda_detach_beep_device(codec); 2433 snd_hda_detach_beep_device(codec);
2383} 2434}
@@ -2441,6 +2492,47 @@ static int alc_codec_rename(struct hda_codec *codec, const char *name)
2441} 2492}
2442 2493
2443/* 2494/*
2495 * Rename codecs appropriately from COEF value
2496 */
2497struct alc_codec_rename_table {
2498 unsigned int vendor_id;
2499 unsigned short coef_mask;
2500 unsigned short coef_bits;
2501 const char *name;
2502};
2503
2504static struct alc_codec_rename_table rename_tbl[] = {
2505 { 0x10ec0269, 0xfff0, 0x3010, "ALC277" },
2506 { 0x10ec0269, 0xf0f0, 0x2010, "ALC259" },
2507 { 0x10ec0269, 0xf0f0, 0x3010, "ALC258" },
2508 { 0x10ec0269, 0x00f0, 0x0010, "ALC269VB" },
2509 { 0x10ec0269, 0xffff, 0xa023, "ALC259" },
2510 { 0x10ec0269, 0xffff, 0x6023, "ALC281X" },
2511 { 0x10ec0269, 0x00f0, 0x0020, "ALC269VC" },
2512 { 0x10ec0887, 0x00f0, 0x0030, "ALC887-VD" },
2513 { 0x10ec0888, 0x00f0, 0x0030, "ALC888-VD" },
2514 { 0x10ec0888, 0xf0f0, 0x3020, "ALC886" },
2515 { 0x10ec0899, 0x2000, 0x2000, "ALC899" },
2516 { 0x10ec0892, 0xffff, 0x8020, "ALC661" },
2517 { 0x10ec0892, 0xffff, 0x8011, "ALC661" },
2518 { 0x10ec0892, 0xffff, 0x4011, "ALC656" },
2519 { } /* terminator */
2520};
2521
2522static int alc_codec_rename_from_preset(struct hda_codec *codec)
2523{
2524 const struct alc_codec_rename_table *p;
2525
2526 for (p = rename_tbl; p->vendor_id; p++) {
2527 if (p->vendor_id != codec->vendor_id)
2528 continue;
2529 if ((alc_get_coef0(codec) & p->coef_mask) == p->coef_bits)
2530 return alc_codec_rename(codec, p->name);
2531 }
2532 return 0;
2533}
2534
2535/*
2444 * Automatic parse of I/O pins from the BIOS configuration 2536 * Automatic parse of I/O pins from the BIOS configuration
2445 */ 2537 */
2446 2538
@@ -2448,11 +2540,15 @@ enum {
2448 ALC_CTL_WIDGET_VOL, 2540 ALC_CTL_WIDGET_VOL,
2449 ALC_CTL_WIDGET_MUTE, 2541 ALC_CTL_WIDGET_MUTE,
2450 ALC_CTL_BIND_MUTE, 2542 ALC_CTL_BIND_MUTE,
2543 ALC_CTL_BIND_VOL,
2544 ALC_CTL_BIND_SW,
2451}; 2545};
2452static const struct snd_kcontrol_new alc_control_templates[] = { 2546static const struct snd_kcontrol_new alc_control_templates[] = {
2453 HDA_CODEC_VOLUME(NULL, 0, 0, 0), 2547 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
2454 HDA_CODEC_MUTE(NULL, 0, 0, 0), 2548 HDA_CODEC_MUTE(NULL, 0, 0, 0),
2455 HDA_BIND_MUTE(NULL, 0, 0, 0), 2549 HDA_BIND_MUTE(NULL, 0, 0, 0),
2550 HDA_BIND_VOL(NULL, 0),
2551 HDA_BIND_SW(NULL, 0),
2456}; 2552};
2457 2553
2458/* add dynamic controls */ 2554/* add dynamic controls */
@@ -2493,13 +2589,14 @@ static int add_control_with_pfx(struct alc_spec *spec, int type,
2493#define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \ 2589#define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \
2494 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val) 2590 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val)
2495 2591
2592static const char * const channel_name[4] = {
2593 "Front", "Surround", "CLFE", "Side"
2594};
2595
2496static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch, 2596static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch,
2497 bool can_be_master, int *index) 2597 bool can_be_master, int *index)
2498{ 2598{
2499 struct auto_pin_cfg *cfg = &spec->autocfg; 2599 struct auto_pin_cfg *cfg = &spec->autocfg;
2500 static const char * const chname[4] = {
2501 "Front", "Surround", NULL /*CLFE*/, "Side"
2502 };
2503 2600
2504 *index = 0; 2601 *index = 0;
2505 if (cfg->line_outs == 1 && !spec->multi_ios && 2602 if (cfg->line_outs == 1 && !spec->multi_ios &&
@@ -2522,7 +2619,10 @@ static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch,
2522 return "PCM"; 2619 return "PCM";
2523 break; 2620 break;
2524 } 2621 }
2525 return chname[ch]; 2622 if (snd_BUG_ON(ch >= ARRAY_SIZE(channel_name)))
2623 return "PCM";
2624
2625 return channel_name[ch];
2526} 2626}
2527 2627
2528/* create input playback/capture controls for the given pin */ 2628/* create input playback/capture controls for the given pin */
@@ -2786,8 +2886,9 @@ static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
2786 if (found_in_nid_list(nid, spec->multiout.dac_nids, 2886 if (found_in_nid_list(nid, spec->multiout.dac_nids,
2787 spec->multiout.num_dacs)) 2887 spec->multiout.num_dacs))
2788 continue; 2888 continue;
2789 if (spec->multiout.hp_nid == nid) 2889 if (found_in_nid_list(nid, spec->multiout.hp_out_nid,
2790 continue; 2890 ARRAY_SIZE(spec->multiout.hp_out_nid)))
2891 continue;
2791 if (found_in_nid_list(nid, spec->multiout.extra_out_nid, 2892 if (found_in_nid_list(nid, spec->multiout.extra_out_nid,
2792 ARRAY_SIZE(spec->multiout.extra_out_nid))) 2893 ARRAY_SIZE(spec->multiout.extra_out_nid)))
2793 continue; 2894 continue;
@@ -2804,6 +2905,29 @@ static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin)
2804 return 0; 2905 return 0;
2805} 2906}
2806 2907
2908static int alc_auto_fill_extra_dacs(struct hda_codec *codec, int num_outs,
2909 const hda_nid_t *pins, hda_nid_t *dacs)
2910{
2911 int i;
2912
2913 if (num_outs && !dacs[0]) {
2914 dacs[0] = alc_auto_look_for_dac(codec, pins[0]);
2915 if (!dacs[0])
2916 return 0;
2917 }
2918
2919 for (i = 1; i < num_outs; i++)
2920 dacs[i] = get_dac_if_single(codec, pins[i]);
2921 for (i = 1; i < num_outs; i++) {
2922 if (!dacs[i])
2923 dacs[i] = alc_auto_look_for_dac(codec, pins[i]);
2924 }
2925 return 0;
2926}
2927
2928static int alc_auto_fill_multi_ios(struct hda_codec *codec,
2929 unsigned int location);
2930
2807/* fill in the dac_nids table from the parsed pin configuration */ 2931/* fill in the dac_nids table from the parsed pin configuration */
2808static int alc_auto_fill_dac_nids(struct hda_codec *codec) 2932static int alc_auto_fill_dac_nids(struct hda_codec *codec)
2809{ 2933{
@@ -2815,7 +2939,7 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec)
2815 again: 2939 again:
2816 /* set num_dacs once to full for alc_auto_look_for_dac() */ 2940 /* set num_dacs once to full for alc_auto_look_for_dac() */
2817 spec->multiout.num_dacs = cfg->line_outs; 2941 spec->multiout.num_dacs = cfg->line_outs;
2818 spec->multiout.hp_nid = 0; 2942 spec->multiout.hp_out_nid[0] = 0;
2819 spec->multiout.extra_out_nid[0] = 0; 2943 spec->multiout.extra_out_nid[0] = 0;
2820 memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids)); 2944 memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids));
2821 spec->multiout.dac_nids = spec->private_dac_nids; 2945 spec->multiout.dac_nids = spec->private_dac_nids;
@@ -2826,7 +2950,7 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec)
2826 spec->private_dac_nids[i] = 2950 spec->private_dac_nids[i] =
2827 get_dac_if_single(codec, cfg->line_out_pins[i]); 2951 get_dac_if_single(codec, cfg->line_out_pins[i]);
2828 if (cfg->hp_outs) 2952 if (cfg->hp_outs)
2829 spec->multiout.hp_nid = 2953 spec->multiout.hp_out_nid[0] =
2830 get_dac_if_single(codec, cfg->hp_pins[0]); 2954 get_dac_if_single(codec, cfg->hp_pins[0]);
2831 if (cfg->speaker_outs) 2955 if (cfg->speaker_outs)
2832 spec->multiout.extra_out_nid[0] = 2956 spec->multiout.extra_out_nid[0] =
@@ -2858,24 +2982,58 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec)
2858 sizeof(hda_nid_t) * (cfg->line_outs - i - 1)); 2982 sizeof(hda_nid_t) * (cfg->line_outs - i - 1));
2859 } 2983 }
2860 2984
2861 if (cfg->hp_outs && !spec->multiout.hp_nid) 2985 if (cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
2862 spec->multiout.hp_nid = 2986 /* try to fill multi-io first */
2863 alc_auto_look_for_dac(codec, cfg->hp_pins[0]); 2987 unsigned int location, defcfg;
2864 if (cfg->speaker_outs && !spec->multiout.extra_out_nid[0]) 2988 int num_pins;
2865 spec->multiout.extra_out_nid[0] = 2989
2866 alc_auto_look_for_dac(codec, cfg->speaker_pins[0]); 2990 defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]);
2991 location = get_defcfg_location(defcfg);
2992
2993 num_pins = alc_auto_fill_multi_ios(codec, location);
2994 if (num_pins > 0) {
2995 spec->multi_ios = num_pins;
2996 spec->ext_channel_count = 2;
2997 spec->multiout.num_dacs = num_pins + 1;
2998 }
2999 }
3000
3001 if (cfg->line_out_type != AUTO_PIN_HP_OUT)
3002 alc_auto_fill_extra_dacs(codec, cfg->hp_outs, cfg->hp_pins,
3003 spec->multiout.hp_out_nid);
3004 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT)
3005 alc_auto_fill_extra_dacs(codec, cfg->speaker_outs, cfg->speaker_pins,
3006 spec->multiout.extra_out_nid);
2867 3007
2868 return 0; 3008 return 0;
2869} 3009}
2870 3010
3011static inline unsigned int get_ctl_pos(unsigned int data)
3012{
3013 hda_nid_t nid = get_amp_nid_(data);
3014 unsigned int dir = get_amp_direction_(data);
3015 return (nid << 1) | dir;
3016}
3017
3018#define is_ctl_used(bits, data) \
3019 test_bit(get_ctl_pos(data), bits)
3020#define mark_ctl_usage(bits, data) \
3021 set_bit(get_ctl_pos(data), bits)
3022
2871static int alc_auto_add_vol_ctl(struct hda_codec *codec, 3023static int alc_auto_add_vol_ctl(struct hda_codec *codec,
2872 const char *pfx, int cidx, 3024 const char *pfx, int cidx,
2873 hda_nid_t nid, unsigned int chs) 3025 hda_nid_t nid, unsigned int chs)
2874{ 3026{
3027 struct alc_spec *spec = codec->spec;
3028 unsigned int val;
2875 if (!nid) 3029 if (!nid)
2876 return 0; 3030 return 0;
3031 val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT);
3032 if (is_ctl_used(spec->vol_ctls, val) && chs != 2) /* exclude LFE */
3033 return 0;
3034 mark_ctl_usage(spec->vol_ctls, val);
2877 return __add_pb_vol_ctrl(codec->spec, ALC_CTL_WIDGET_VOL, pfx, cidx, 3035 return __add_pb_vol_ctrl(codec->spec, ALC_CTL_WIDGET_VOL, pfx, cidx,
2878 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); 3036 val);
2879} 3037}
2880 3038
2881#define alc_auto_add_stereo_vol(codec, pfx, cidx, nid) \ 3039#define alc_auto_add_stereo_vol(codec, pfx, cidx, nid) \
@@ -2888,6 +3046,7 @@ static int alc_auto_add_sw_ctl(struct hda_codec *codec,
2888 const char *pfx, int cidx, 3046 const char *pfx, int cidx,
2889 hda_nid_t nid, unsigned int chs) 3047 hda_nid_t nid, unsigned int chs)
2890{ 3048{
3049 struct alc_spec *spec = codec->spec;
2891 int wid_type; 3050 int wid_type;
2892 int type; 3051 int type;
2893 unsigned long val; 3052 unsigned long val;
@@ -2904,6 +3063,9 @@ static int alc_auto_add_sw_ctl(struct hda_codec *codec,
2904 type = ALC_CTL_BIND_MUTE; 3063 type = ALC_CTL_BIND_MUTE;
2905 val = HDA_COMPOSE_AMP_VAL(nid, chs, 2, HDA_INPUT); 3064 val = HDA_COMPOSE_AMP_VAL(nid, chs, 2, HDA_INPUT);
2906 } 3065 }
3066 if (is_ctl_used(spec->sw_ctls, val) && chs != 2) /* exclude LFE */
3067 return 0;
3068 mark_ctl_usage(spec->sw_ctls, val);
2907 return __add_pb_sw_ctrl(codec->spec, type, pfx, cidx, val); 3069 return __add_pb_sw_ctrl(codec->spec, type, pfx, cidx, val);
2908} 3070}
2909 3071
@@ -2964,7 +3126,7 @@ static int alc_auto_create_multi_out_ctls(struct hda_codec *codec,
2964 sw = alc_look_for_out_mute_nid(codec, pin, dac); 3126 sw = alc_look_for_out_mute_nid(codec, pin, dac);
2965 vol = alc_look_for_out_vol_nid(codec, pin, dac); 3127 vol = alc_look_for_out_vol_nid(codec, pin, dac);
2966 name = alc_get_line_out_pfx(spec, i, true, &index); 3128 name = alc_get_line_out_pfx(spec, i, true, &index);
2967 if (!name) { 3129 if (!name || !strcmp(name, "CLFE")) {
2968 /* Center/LFE */ 3130 /* Center/LFE */
2969 err = alc_auto_add_vol_ctl(codec, "Center", 0, vol, 1); 3131 err = alc_auto_add_vol_ctl(codec, "Center", 0, vol, 1);
2970 if (err < 0) 3132 if (err < 0)
@@ -2990,23 +3152,24 @@ static int alc_auto_create_multi_out_ctls(struct hda_codec *codec,
2990 return 0; 3152 return 0;
2991} 3153}
2992 3154
2993/* add playback controls for speaker and HP outputs */
2994static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, 3155static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
2995 hda_nid_t dac, const char *pfx) 3156 hda_nid_t dac, const char *pfx)
2996{ 3157{
2997 struct alc_spec *spec = codec->spec; 3158 struct alc_spec *spec = codec->spec;
2998 hda_nid_t sw, vol; 3159 hda_nid_t sw, vol;
2999 int err; 3160 int err;
3000 3161
3001 if (!pin)
3002 return 0;
3003 if (!dac) { 3162 if (!dac) {
3163 unsigned int val;
3004 /* the corresponding DAC is already occupied */ 3164 /* the corresponding DAC is already occupied */
3005 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP)) 3165 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
3006 return 0; /* no way */ 3166 return 0; /* no way */
3007 /* create a switch only */ 3167 /* create a switch only */
3008 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, 3168 val = HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT);
3009 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 3169 if (is_ctl_used(spec->sw_ctls, val))
3170 return 0; /* already created */
3171 mark_ctl_usage(spec->sw_ctls, val);
3172 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, val);
3010 } 3173 }
3011 3174
3012 sw = alc_look_for_out_mute_nid(codec, pin, dac); 3175 sw = alc_look_for_out_mute_nid(codec, pin, dac);
@@ -3020,20 +3183,112 @@ static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
3020 return 0; 3183 return 0;
3021} 3184}
3022 3185
3186static struct hda_bind_ctls *new_bind_ctl(struct hda_codec *codec,
3187 unsigned int nums,
3188 struct hda_ctl_ops *ops)
3189{
3190 struct alc_spec *spec = codec->spec;
3191 struct hda_bind_ctls **ctlp, *ctl;
3192 snd_array_init(&spec->bind_ctls, sizeof(ctl), 8);
3193 ctlp = snd_array_new(&spec->bind_ctls);
3194 if (!ctlp)
3195 return NULL;
3196 ctl = kzalloc(sizeof(*ctl) + sizeof(long) * (nums + 1), GFP_KERNEL);
3197 *ctlp = ctl;
3198 if (ctl)
3199 ctl->ops = ops;
3200 return ctl;
3201}
3202
3203/* add playback controls for speaker and HP outputs */
3204static int alc_auto_create_extra_outs(struct hda_codec *codec, int num_pins,
3205 const hda_nid_t *pins,
3206 const hda_nid_t *dacs,
3207 const char *pfx)
3208{
3209 struct alc_spec *spec = codec->spec;
3210 struct hda_bind_ctls *ctl;
3211 char name[32];
3212 int i, n, err;
3213
3214 if (!num_pins || !pins[0])
3215 return 0;
3216
3217 if (num_pins == 1) {
3218 hda_nid_t dac = *dacs;
3219 if (!dac)
3220 dac = spec->multiout.dac_nids[0];
3221 return alc_auto_create_extra_out(codec, *pins, dac, pfx);
3222 }
3223
3224 if (dacs[num_pins - 1]) {
3225 /* OK, we have a multi-output system with individual volumes */
3226 for (i = 0; i < num_pins; i++) {
3227 snprintf(name, sizeof(name), "%s %s",
3228 pfx, channel_name[i]);
3229 err = alc_auto_create_extra_out(codec, pins[i], dacs[i],
3230 name);
3231 if (err < 0)
3232 return err;
3233 }
3234 return 0;
3235 }
3236
3237 /* Let's create a bind-controls */
3238 ctl = new_bind_ctl(codec, num_pins, &snd_hda_bind_sw);
3239 if (!ctl)
3240 return -ENOMEM;
3241 n = 0;
3242 for (i = 0; i < num_pins; i++) {
3243 if (get_wcaps(codec, pins[i]) & AC_WCAP_OUT_AMP)
3244 ctl->values[n++] =
3245 HDA_COMPOSE_AMP_VAL(pins[i], 3, 0, HDA_OUTPUT);
3246 }
3247 if (n) {
3248 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
3249 err = add_control(spec, ALC_CTL_BIND_SW, name, 0, (long)ctl);
3250 if (err < 0)
3251 return err;
3252 }
3253
3254 ctl = new_bind_ctl(codec, num_pins, &snd_hda_bind_vol);
3255 if (!ctl)
3256 return -ENOMEM;
3257 n = 0;
3258 for (i = 0; i < num_pins; i++) {
3259 hda_nid_t vol;
3260 if (!pins[i] || !dacs[i])
3261 continue;
3262 vol = alc_look_for_out_vol_nid(codec, pins[i], dacs[i]);
3263 if (vol)
3264 ctl->values[n++] =
3265 HDA_COMPOSE_AMP_VAL(vol, 3, 0, HDA_OUTPUT);
3266 }
3267 if (n) {
3268 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
3269 err = add_control(spec, ALC_CTL_BIND_VOL, name, 0, (long)ctl);
3270 if (err < 0)
3271 return err;
3272 }
3273 return 0;
3274}
3275
3023static int alc_auto_create_hp_out(struct hda_codec *codec) 3276static int alc_auto_create_hp_out(struct hda_codec *codec)
3024{ 3277{
3025 struct alc_spec *spec = codec->spec; 3278 struct alc_spec *spec = codec->spec;
3026 return alc_auto_create_extra_out(codec, spec->autocfg.hp_pins[0], 3279 return alc_auto_create_extra_outs(codec, spec->autocfg.hp_outs,
3027 spec->multiout.hp_nid, 3280 spec->autocfg.hp_pins,
3028 "Headphone"); 3281 spec->multiout.hp_out_nid,
3282 "Headphone");
3029} 3283}
3030 3284
3031static int alc_auto_create_speaker_out(struct hda_codec *codec) 3285static int alc_auto_create_speaker_out(struct hda_codec *codec)
3032{ 3286{
3033 struct alc_spec *spec = codec->spec; 3287 struct alc_spec *spec = codec->spec;
3034 return alc_auto_create_extra_out(codec, spec->autocfg.speaker_pins[0], 3288 return alc_auto_create_extra_outs(codec, spec->autocfg.speaker_outs,
3035 spec->multiout.extra_out_nid[0], 3289 spec->autocfg.speaker_pins,
3036 "Speaker"); 3290 spec->multiout.extra_out_nid,
3291 "Speaker");
3037} 3292}
3038 3293
3039static void alc_auto_set_output_and_unmute(struct hda_codec *codec, 3294static void alc_auto_set_output_and_unmute(struct hda_codec *codec,
@@ -3090,20 +3345,37 @@ static void alc_auto_init_multi_out(struct hda_codec *codec)
3090static void alc_auto_init_extra_out(struct hda_codec *codec) 3345static void alc_auto_init_extra_out(struct hda_codec *codec)
3091{ 3346{
3092 struct alc_spec *spec = codec->spec; 3347 struct alc_spec *spec = codec->spec;
3348 int i;
3093 hda_nid_t pin, dac; 3349 hda_nid_t pin, dac;
3094 3350
3095 pin = spec->autocfg.hp_pins[0]; 3351 for (i = 0; i < spec->autocfg.hp_outs; i++) {
3096 if (pin) { 3352 if (spec->autocfg.line_out_type == AUTO_PIN_HP_OUT)
3097 dac = spec->multiout.hp_nid; 3353 break;
3098 if (!dac) 3354 pin = spec->autocfg.hp_pins[i];
3099 dac = spec->multiout.dac_nids[0]; 3355 if (!pin)
3356 break;
3357 dac = spec->multiout.hp_out_nid[i];
3358 if (!dac) {
3359 if (i > 0 && spec->multiout.hp_out_nid[0])
3360 dac = spec->multiout.hp_out_nid[0];
3361 else
3362 dac = spec->multiout.dac_nids[0];
3363 }
3100 alc_auto_set_output_and_unmute(codec, pin, PIN_HP, dac); 3364 alc_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
3101 } 3365 }
3102 pin = spec->autocfg.speaker_pins[0]; 3366 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
3103 if (pin) { 3367 if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
3104 dac = spec->multiout.extra_out_nid[0]; 3368 break;
3105 if (!dac) 3369 pin = spec->autocfg.speaker_pins[i];
3106 dac = spec->multiout.dac_nids[0]; 3370 if (!pin)
3371 break;
3372 dac = spec->multiout.extra_out_nid[i];
3373 if (!dac) {
3374 if (i > 0 && spec->multiout.extra_out_nid[0])
3375 dac = spec->multiout.extra_out_nid[0];
3376 else
3377 dac = spec->multiout.dac_nids[0];
3378 }
3107 alc_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac); 3379 alc_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
3108 } 3380 }
3109} 3381}
@@ -3116,6 +3388,7 @@ static int alc_auto_fill_multi_ios(struct hda_codec *codec,
3116{ 3388{
3117 struct alc_spec *spec = codec->spec; 3389 struct alc_spec *spec = codec->spec;
3118 struct auto_pin_cfg *cfg = &spec->autocfg; 3390 struct auto_pin_cfg *cfg = &spec->autocfg;
3391 hda_nid_t prime_dac = spec->private_dac_nids[0];
3119 int type, i, num_pins = 0; 3392 int type, i, num_pins = 0;
3120 3393
3121 for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) { 3394 for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) {
@@ -3143,8 +3416,13 @@ static int alc_auto_fill_multi_ios(struct hda_codec *codec,
3143 } 3416 }
3144 } 3417 }
3145 spec->multiout.num_dacs = 1; 3418 spec->multiout.num_dacs = 1;
3146 if (num_pins < 2) 3419 if (num_pins < 2) {
3420 /* clear up again */
3421 memset(spec->private_dac_nids, 0,
3422 sizeof(spec->private_dac_nids));
3423 spec->private_dac_nids[0] = prime_dac;
3147 return 0; 3424 return 0;
3425 }
3148 return num_pins; 3426 return num_pins;
3149} 3427}
3150 3428
@@ -3230,36 +3508,11 @@ static const struct snd_kcontrol_new alc_auto_channel_mode_enum = {
3230 .put = alc_auto_ch_mode_put, 3508 .put = alc_auto_ch_mode_put,
3231}; 3509};
3232 3510
3233static int alc_auto_add_multi_channel_mode(struct hda_codec *codec, 3511static int alc_auto_add_multi_channel_mode(struct hda_codec *codec)
3234 int (*fill_dac)(struct hda_codec *))
3235{ 3512{
3236 struct alc_spec *spec = codec->spec; 3513 struct alc_spec *spec = codec->spec;
3237 struct auto_pin_cfg *cfg = &spec->autocfg;
3238 unsigned int location, defcfg;
3239 int num_pins;
3240
3241 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT && cfg->hp_outs == 1) {
3242 /* use HP as primary out */
3243 cfg->speaker_outs = cfg->line_outs;
3244 memcpy(cfg->speaker_pins, cfg->line_out_pins,
3245 sizeof(cfg->speaker_pins));
3246 cfg->line_outs = cfg->hp_outs;
3247 memcpy(cfg->line_out_pins, cfg->hp_pins, sizeof(cfg->hp_pins));
3248 cfg->hp_outs = 0;
3249 memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins));
3250 cfg->line_out_type = AUTO_PIN_HP_OUT;
3251 if (fill_dac)
3252 fill_dac(codec);
3253 }
3254 if (cfg->line_outs != 1 ||
3255 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
3256 return 0;
3257 3514
3258 defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]); 3515 if (spec->multi_ios > 0) {
3259 location = get_defcfg_location(defcfg);
3260
3261 num_pins = alc_auto_fill_multi_ios(codec, location);
3262 if (num_pins > 0) {
3263 struct snd_kcontrol_new *knew; 3516 struct snd_kcontrol_new *knew;
3264 3517
3265 knew = alc_kcontrol_new(spec); 3518 knew = alc_kcontrol_new(spec);
@@ -3269,10 +3522,6 @@ static int alc_auto_add_multi_channel_mode(struct hda_codec *codec,
3269 knew->name = kstrdup("Channel Mode", GFP_KERNEL); 3522 knew->name = kstrdup("Channel Mode", GFP_KERNEL);
3270 if (!knew->name) 3523 if (!knew->name)
3271 return -ENOMEM; 3524 return -ENOMEM;
3272
3273 spec->multi_ios = num_pins;
3274 spec->ext_channel_count = 2;
3275 spec->multiout.num_dacs = num_pins + 1;
3276 } 3525 }
3277 return 0; 3526 return 0;
3278} 3527}
@@ -3555,27 +3804,42 @@ static int alc_parse_auto_config(struct hda_codec *codec,
3555 const hda_nid_t *ssid_nids) 3804 const hda_nid_t *ssid_nids)
3556{ 3805{
3557 struct alc_spec *spec = codec->spec; 3806 struct alc_spec *spec = codec->spec;
3807 struct auto_pin_cfg *cfg = &spec->autocfg;
3558 int err; 3808 int err;
3559 3809
3560 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 3810 err = snd_hda_parse_pin_defcfg(codec, cfg, ignore_nids,
3561 ignore_nids); 3811 spec->parse_flags);
3562 if (err < 0) 3812 if (err < 0)
3563 return err; 3813 return err;
3564 if (!spec->autocfg.line_outs) { 3814 if (!cfg->line_outs) {
3565 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) { 3815 if (cfg->dig_outs || cfg->dig_in_pin) {
3566 spec->multiout.max_channels = 2; 3816 spec->multiout.max_channels = 2;
3567 spec->no_analog = 1; 3817 spec->no_analog = 1;
3568 goto dig_only; 3818 goto dig_only;
3569 } 3819 }
3570 return 0; /* can't find valid BIOS pin config */ 3820 return 0; /* can't find valid BIOS pin config */
3571 } 3821 }
3822
3823 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT &&
3824 cfg->line_outs <= cfg->hp_outs) {
3825 /* use HP as primary out */
3826 cfg->speaker_outs = cfg->line_outs;
3827 memcpy(cfg->speaker_pins, cfg->line_out_pins,
3828 sizeof(cfg->speaker_pins));
3829 cfg->line_outs = cfg->hp_outs;
3830 memcpy(cfg->line_out_pins, cfg->hp_pins, sizeof(cfg->hp_pins));
3831 cfg->hp_outs = 0;
3832 memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins));
3833 cfg->line_out_type = AUTO_PIN_HP_OUT;
3834 }
3835
3572 err = alc_auto_fill_dac_nids(codec); 3836 err = alc_auto_fill_dac_nids(codec);
3573 if (err < 0) 3837 if (err < 0)
3574 return err; 3838 return err;
3575 err = alc_auto_add_multi_channel_mode(codec, alc_auto_fill_dac_nids); 3839 err = alc_auto_add_multi_channel_mode(codec);
3576 if (err < 0) 3840 if (err < 0)
3577 return err; 3841 return err;
3578 err = alc_auto_create_multi_out_ctls(codec, &spec->autocfg); 3842 err = alc_auto_create_multi_out_ctls(codec, cfg);
3579 if (err < 0) 3843 if (err < 0)
3580 return err; 3844 return err;
3581 err = alc_auto_create_hp_out(codec); 3845 err = alc_auto_create_hp_out(codec);
@@ -3678,10 +3942,8 @@ static int patch_alc880(struct hda_codec *codec)
3678 if (board_config == ALC_MODEL_AUTO) { 3942 if (board_config == ALC_MODEL_AUTO) {
3679 /* automatic parse from the BIOS config */ 3943 /* automatic parse from the BIOS config */
3680 err = alc880_parse_auto_config(codec); 3944 err = alc880_parse_auto_config(codec);
3681 if (err < 0) { 3945 if (err < 0)
3682 alc_free(codec); 3946 goto error;
3683 return err;
3684 }
3685#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS 3947#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
3686 else if (!err) { 3948 else if (!err) {
3687 printk(KERN_INFO 3949 printk(KERN_INFO
@@ -3706,10 +3968,8 @@ static int patch_alc880(struct hda_codec *codec)
3706 3968
3707 if (!spec->no_analog) { 3969 if (!spec->no_analog) {
3708 err = snd_hda_attach_beep_device(codec, 0x1); 3970 err = snd_hda_attach_beep_device(codec, 0x1);
3709 if (err < 0) { 3971 if (err < 0)
3710 alc_free(codec); 3972 goto error;
3711 return err;
3712 }
3713 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 3973 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
3714 } 3974 }
3715 3975
@@ -3724,6 +3984,10 @@ static int patch_alc880(struct hda_codec *codec)
3724#endif 3984#endif
3725 3985
3726 return 0; 3986 return 0;
3987
3988 error:
3989 alc_free(codec);
3990 return err;
3727} 3991}
3728 3992
3729 3993
@@ -3805,10 +4069,8 @@ static int patch_alc260(struct hda_codec *codec)
3805 if (board_config == ALC_MODEL_AUTO) { 4069 if (board_config == ALC_MODEL_AUTO) {
3806 /* automatic parse from the BIOS config */ 4070 /* automatic parse from the BIOS config */
3807 err = alc260_parse_auto_config(codec); 4071 err = alc260_parse_auto_config(codec);
3808 if (err < 0) { 4072 if (err < 0)
3809 alc_free(codec); 4073 goto error;
3810 return err;
3811 }
3812#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS 4074#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
3813 else if (!err) { 4075 else if (!err) {
3814 printk(KERN_INFO 4076 printk(KERN_INFO
@@ -3833,10 +4095,8 @@ static int patch_alc260(struct hda_codec *codec)
3833 4095
3834 if (!spec->no_analog) { 4096 if (!spec->no_analog) {
3835 err = snd_hda_attach_beep_device(codec, 0x1); 4097 err = snd_hda_attach_beep_device(codec, 0x1);
3836 if (err < 0) { 4098 if (err < 0)
3837 alc_free(codec); 4099 goto error;
3838 return err;
3839 }
3840 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT); 4100 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
3841 } 4101 }
3842 4102
@@ -3854,6 +4114,10 @@ static int patch_alc260(struct hda_codec *codec)
3854#endif 4114#endif
3855 4115
3856 return 0; 4116 return 0;
4117
4118 error:
4119 alc_free(codec);
4120 return err;
3857} 4121}
3858 4122
3859 4123
@@ -3880,6 +4144,7 @@ enum {
3880 PINFIX_LENOVO_Y530, 4144 PINFIX_LENOVO_Y530,
3881 PINFIX_PB_M5210, 4145 PINFIX_PB_M5210,
3882 PINFIX_ACER_ASPIRE_7736, 4146 PINFIX_ACER_ASPIRE_7736,
4147 PINFIX_ASUS_W90V,
3883}; 4148};
3884 4149
3885static const struct alc_fixup alc882_fixups[] = { 4150static const struct alc_fixup alc882_fixups[] = {
@@ -3911,10 +4176,18 @@ static const struct alc_fixup alc882_fixups[] = {
3911 .type = ALC_FIXUP_SKU, 4176 .type = ALC_FIXUP_SKU,
3912 .v.sku = ALC_FIXUP_SKU_IGNORE, 4177 .v.sku = ALC_FIXUP_SKU_IGNORE,
3913 }, 4178 },
4179 [PINFIX_ASUS_W90V] = {
4180 .type = ALC_FIXUP_PINS,
4181 .v.pins = (const struct alc_pincfg[]) {
4182 { 0x16, 0x99130110 }, /* fix sequence for CLFE */
4183 { }
4184 }
4185 },
3914}; 4186};
3915 4187
3916static const struct snd_pci_quirk alc882_fixup_tbl[] = { 4188static const struct snd_pci_quirk alc882_fixup_tbl[] = {
3917 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210), 4189 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
4190 SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", PINFIX_ASUS_W90V),
3918 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530), 4191 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530),
3919 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX), 4192 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
3920 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736), 4193 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736),
@@ -3961,6 +4234,10 @@ static int patch_alc882(struct hda_codec *codec)
3961 break; 4234 break;
3962 } 4235 }
3963 4236
4237 err = alc_codec_rename_from_preset(codec);
4238 if (err < 0)
4239 goto error;
4240
3964 board_config = alc_board_config(codec, ALC882_MODEL_LAST, 4241 board_config = alc_board_config(codec, ALC882_MODEL_LAST,
3965 alc882_models, alc882_cfg_tbl); 4242 alc882_models, alc882_cfg_tbl);
3966 4243
@@ -3984,10 +4261,8 @@ static int patch_alc882(struct hda_codec *codec)
3984 if (board_config == ALC_MODEL_AUTO) { 4261 if (board_config == ALC_MODEL_AUTO) {
3985 /* automatic parse from the BIOS config */ 4262 /* automatic parse from the BIOS config */
3986 err = alc882_parse_auto_config(codec); 4263 err = alc882_parse_auto_config(codec);
3987 if (err < 0) { 4264 if (err < 0)
3988 alc_free(codec); 4265 goto error;
3989 return err;
3990 }
3991#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS 4266#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
3992 else if (!err) { 4267 else if (!err) {
3993 printk(KERN_INFO 4268 printk(KERN_INFO
@@ -4012,10 +4287,8 @@ static int patch_alc882(struct hda_codec *codec)
4012 4287
4013 if (!spec->no_analog && has_cdefine_beep(codec)) { 4288 if (!spec->no_analog && has_cdefine_beep(codec)) {
4014 err = snd_hda_attach_beep_device(codec, 0x1); 4289 err = snd_hda_attach_beep_device(codec, 0x1);
4015 if (err < 0) { 4290 if (err < 0)
4016 alc_free(codec); 4291 goto error;
4017 return err;
4018 }
4019 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 4292 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
4020 } 4293 }
4021 4294
@@ -4034,6 +4307,10 @@ static int patch_alc882(struct hda_codec *codec)
4034#endif 4307#endif
4035 4308
4036 return 0; 4309 return 0;
4310
4311 error:
4312 alc_free(codec);
4313 return err;
4037} 4314}
4038 4315
4039 4316
@@ -4138,10 +4415,8 @@ static int patch_alc262(struct hda_codec *codec)
4138 if (board_config == ALC_MODEL_AUTO) { 4415 if (board_config == ALC_MODEL_AUTO) {
4139 /* automatic parse from the BIOS config */ 4416 /* automatic parse from the BIOS config */
4140 err = alc262_parse_auto_config(codec); 4417 err = alc262_parse_auto_config(codec);
4141 if (err < 0) { 4418 if (err < 0)
4142 alc_free(codec); 4419 goto error;
4143 return err;
4144 }
4145#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS 4420#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4146 else if (!err) { 4421 else if (!err) {
4147 printk(KERN_INFO 4422 printk(KERN_INFO
@@ -4166,10 +4441,8 @@ static int patch_alc262(struct hda_codec *codec)
4166 4441
4167 if (!spec->no_analog && has_cdefine_beep(codec)) { 4442 if (!spec->no_analog && has_cdefine_beep(codec)) {
4168 err = snd_hda_attach_beep_device(codec, 0x1); 4443 err = snd_hda_attach_beep_device(codec, 0x1);
4169 if (err < 0) { 4444 if (err < 0)
4170 alc_free(codec); 4445 goto error;
4171 return err;
4172 }
4173 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 4446 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
4174 } 4447 }
4175 4448
@@ -4189,6 +4462,10 @@ static int patch_alc262(struct hda_codec *codec)
4189#endif 4462#endif
4190 4463
4191 return 0; 4464 return 0;
4465
4466 error:
4467 alc_free(codec);
4468 return err;
4192} 4469}
4193 4470
4194/* 4471/*
@@ -4237,14 +4514,9 @@ static int alc268_parse_auto_config(struct hda_codec *codec)
4237 4514
4238/* 4515/*
4239 */ 4516 */
4240#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4241#include "alc268_quirks.c"
4242#endif
4243
4244static int patch_alc268(struct hda_codec *codec) 4517static int patch_alc268(struct hda_codec *codec)
4245{ 4518{
4246 struct alc_spec *spec; 4519 struct alc_spec *spec;
4247 int board_config;
4248 int i, has_beep, err; 4520 int i, has_beep, err;
4249 4521
4250 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 4522 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
@@ -4255,38 +4527,10 @@ static int patch_alc268(struct hda_codec *codec)
4255 4527
4256 /* ALC268 has no aa-loopback mixer */ 4528 /* ALC268 has no aa-loopback mixer */
4257 4529
4258 board_config = alc_board_config(codec, ALC268_MODEL_LAST, 4530 /* automatic parse from the BIOS config */
4259 alc268_models, alc268_cfg_tbl); 4531 err = alc268_parse_auto_config(codec);
4260 4532 if (err < 0)
4261 if (board_config < 0) 4533 goto error;
4262 board_config = alc_board_codec_sid_config(codec,
4263 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
4264
4265 if (board_config < 0) {
4266 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4267 codec->chip_name);
4268 board_config = ALC_MODEL_AUTO;
4269 }
4270
4271 if (board_config == ALC_MODEL_AUTO) {
4272 /* automatic parse from the BIOS config */
4273 err = alc268_parse_auto_config(codec);
4274 if (err < 0) {
4275 alc_free(codec);
4276 return err;
4277 }
4278#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4279 else if (!err) {
4280 printk(KERN_INFO
4281 "hda_codec: Cannot set up configuration "
4282 "from BIOS. Using base mode...\n");
4283 board_config = ALC268_3ST;
4284 }
4285#endif
4286 }
4287
4288 if (board_config != ALC_MODEL_AUTO)
4289 setup_preset(codec, &alc268_presets[board_config]);
4290 4534
4291 has_beep = 0; 4535 has_beep = 0;
4292 for (i = 0; i < spec->num_mixers; i++) { 4536 for (i = 0; i < spec->num_mixers; i++) {
@@ -4298,10 +4542,8 @@ static int patch_alc268(struct hda_codec *codec)
4298 4542
4299 if (has_beep) { 4543 if (has_beep) {
4300 err = snd_hda_attach_beep_device(codec, 0x1); 4544 err = snd_hda_attach_beep_device(codec, 0x1);
4301 if (err < 0) { 4545 if (err < 0)
4302 alc_free(codec); 4546 goto error;
4303 return err;
4304 }
4305 if (!query_amp_caps(codec, 0x1d, HDA_INPUT)) 4547 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
4306 /* override the amp caps for beep generator */ 4548 /* override the amp caps for beep generator */
4307 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT, 4549 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
@@ -4323,13 +4565,16 @@ static int patch_alc268(struct hda_codec *codec)
4323 spec->vmaster_nid = 0x02; 4565 spec->vmaster_nid = 0x02;
4324 4566
4325 codec->patch_ops = alc_patch_ops; 4567 codec->patch_ops = alc_patch_ops;
4326 if (board_config == ALC_MODEL_AUTO) 4568 spec->init_hook = alc_auto_init_std;
4327 spec->init_hook = alc_auto_init_std;
4328 spec->shutup = alc_eapd_shutup; 4569 spec->shutup = alc_eapd_shutup;
4329 4570
4330 alc_init_jacks(codec); 4571 alc_init_jacks(codec);
4331 4572
4332 return 0; 4573 return 0;
4574
4575 error:
4576 alc_free(codec);
4577 return err;
4333} 4578}
4334 4579
4335/* 4580/*
@@ -4423,9 +4668,9 @@ static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)
4423 4668
4424static void alc269_shutup(struct hda_codec *codec) 4669static void alc269_shutup(struct hda_codec *codec)
4425{ 4670{
4426 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) 4671 if ((alc_get_coef0(codec) & 0x00ff) == 0x017)
4427 alc269_toggle_power_output(codec, 0); 4672 alc269_toggle_power_output(codec, 0);
4428 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) { 4673 if ((alc_get_coef0(codec) & 0x00ff) == 0x018) {
4429 alc269_toggle_power_output(codec, 0); 4674 alc269_toggle_power_output(codec, 0);
4430 msleep(150); 4675 msleep(150);
4431 } 4676 }
@@ -4434,19 +4679,19 @@ static void alc269_shutup(struct hda_codec *codec)
4434#ifdef CONFIG_PM 4679#ifdef CONFIG_PM
4435static int alc269_resume(struct hda_codec *codec) 4680static int alc269_resume(struct hda_codec *codec)
4436{ 4681{
4437 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) { 4682 if ((alc_get_coef0(codec) & 0x00ff) == 0x018) {
4438 alc269_toggle_power_output(codec, 0); 4683 alc269_toggle_power_output(codec, 0);
4439 msleep(150); 4684 msleep(150);
4440 } 4685 }
4441 4686
4442 codec->patch_ops.init(codec); 4687 codec->patch_ops.init(codec);
4443 4688
4444 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) { 4689 if ((alc_get_coef0(codec) & 0x00ff) == 0x017) {
4445 alc269_toggle_power_output(codec, 1); 4690 alc269_toggle_power_output(codec, 1);
4446 msleep(200); 4691 msleep(200);
4447 } 4692 }
4448 4693
4449 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) 4694 if ((alc_get_coef0(codec) & 0x00ff) == 0x018)
4450 alc269_toggle_power_output(codec, 1); 4695 alc269_toggle_power_output(codec, 1);
4451 4696
4452 snd_hda_codec_resume_amp(codec); 4697 snd_hda_codec_resume_amp(codec);
@@ -4515,6 +4760,30 @@ static void alc269_fixup_stereo_dmic(struct hda_codec *codec,
4515 alc_write_coef_idx(codec, 0x07, coef | 0x80); 4760 alc_write_coef_idx(codec, 0x07, coef | 0x80);
4516} 4761}
4517 4762
4763static void alc269_quanta_automute(struct hda_codec *codec)
4764{
4765 update_outputs(codec);
4766
4767 snd_hda_codec_write(codec, 0x20, 0,
4768 AC_VERB_SET_COEF_INDEX, 0x0c);
4769 snd_hda_codec_write(codec, 0x20, 0,
4770 AC_VERB_SET_PROC_COEF, 0x680);
4771
4772 snd_hda_codec_write(codec, 0x20, 0,
4773 AC_VERB_SET_COEF_INDEX, 0x0c);
4774 snd_hda_codec_write(codec, 0x20, 0,
4775 AC_VERB_SET_PROC_COEF, 0x480);
4776}
4777
4778static void alc269_fixup_quanta_mute(struct hda_codec *codec,
4779 const struct alc_fixup *fix, int action)
4780{
4781 struct alc_spec *spec = codec->spec;
4782 if (action != ALC_FIXUP_ACT_PROBE)
4783 return;
4784 spec->automute_hook = alc269_quanta_automute;
4785}
4786
4518enum { 4787enum {
4519 ALC269_FIXUP_SONY_VAIO, 4788 ALC269_FIXUP_SONY_VAIO,
4520 ALC275_FIXUP_SONY_VAIO_GPIO2, 4789 ALC275_FIXUP_SONY_VAIO_GPIO2,
@@ -4526,6 +4795,12 @@ enum {
4526 ALC271_FIXUP_DMIC, 4795 ALC271_FIXUP_DMIC,
4527 ALC269_FIXUP_PCM_44K, 4796 ALC269_FIXUP_PCM_44K,
4528 ALC269_FIXUP_STEREO_DMIC, 4797 ALC269_FIXUP_STEREO_DMIC,
4798 ALC269_FIXUP_QUANTA_MUTE,
4799 ALC269_FIXUP_LIFEBOOK,
4800 ALC269_FIXUP_AMIC,
4801 ALC269_FIXUP_DMIC,
4802 ALC269VB_FIXUP_AMIC,
4803 ALC269VB_FIXUP_DMIC,
4529}; 4804};
4530 4805
4531static const struct alc_fixup alc269_fixups[] = { 4806static const struct alc_fixup alc269_fixups[] = {
@@ -4592,6 +4867,60 @@ static const struct alc_fixup alc269_fixups[] = {
4592 .type = ALC_FIXUP_FUNC, 4867 .type = ALC_FIXUP_FUNC,
4593 .v.func = alc269_fixup_stereo_dmic, 4868 .v.func = alc269_fixup_stereo_dmic,
4594 }, 4869 },
4870 [ALC269_FIXUP_QUANTA_MUTE] = {
4871 .type = ALC_FIXUP_FUNC,
4872 .v.func = alc269_fixup_quanta_mute,
4873 },
4874 [ALC269_FIXUP_LIFEBOOK] = {
4875 .type = ALC_FIXUP_PINS,
4876 .v.pins = (const struct alc_pincfg[]) {
4877 { 0x1a, 0x2101103f }, /* dock line-out */
4878 { 0x1b, 0x23a11040 }, /* dock mic-in */
4879 { }
4880 },
4881 .chained = true,
4882 .chain_id = ALC269_FIXUP_QUANTA_MUTE
4883 },
4884 [ALC269_FIXUP_AMIC] = {
4885 .type = ALC_FIXUP_PINS,
4886 .v.pins = (const struct alc_pincfg[]) {
4887 { 0x14, 0x99130110 }, /* speaker */
4888 { 0x15, 0x0121401f }, /* HP out */
4889 { 0x18, 0x01a19c20 }, /* mic */
4890 { 0x19, 0x99a3092f }, /* int-mic */
4891 { }
4892 },
4893 },
4894 [ALC269_FIXUP_DMIC] = {
4895 .type = ALC_FIXUP_PINS,
4896 .v.pins = (const struct alc_pincfg[]) {
4897 { 0x12, 0x99a3092f }, /* int-mic */
4898 { 0x14, 0x99130110 }, /* speaker */
4899 { 0x15, 0x0121401f }, /* HP out */
4900 { 0x18, 0x01a19c20 }, /* mic */
4901 { }
4902 },
4903 },
4904 [ALC269VB_FIXUP_AMIC] = {
4905 .type = ALC_FIXUP_PINS,
4906 .v.pins = (const struct alc_pincfg[]) {
4907 { 0x14, 0x99130110 }, /* speaker */
4908 { 0x18, 0x01a19c20 }, /* mic */
4909 { 0x19, 0x99a3092f }, /* int-mic */
4910 { 0x21, 0x0121401f }, /* HP out */
4911 { }
4912 },
4913 },
4914 [ALC269_FIXUP_DMIC] = {
4915 .type = ALC_FIXUP_PINS,
4916 .v.pins = (const struct alc_pincfg[]) {
4917 { 0x12, 0x99a3092f }, /* int-mic */
4918 { 0x14, 0x99130110 }, /* speaker */
4919 { 0x18, 0x01a19c20 }, /* mic */
4920 { 0x21, 0x0121401f }, /* HP out */
4921 { }
4922 },
4923 },
4595}; 4924};
4596 4925
4597static const struct snd_pci_quirk alc269_fixup_tbl[] = { 4926static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -4607,13 +4936,71 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
4607 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), 4936 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
4608 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), 4937 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
4609 SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC), 4938 SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
4939 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK),
4610 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), 4940 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
4611 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE), 4941 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
4612 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), 4942 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
4613 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE), 4943 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
4614 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE), 4944 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
4945 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_QUANTA_MUTE),
4615 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Lenovo Ideapd", ALC269_FIXUP_PCM_44K), 4946 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Lenovo Ideapd", ALC269_FIXUP_PCM_44K),
4616 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), 4947 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
4948
4949#if 1
4950 /* Below is a quirk table taken from the old code.
4951 * Basically the device should work as is without the fixup table.
4952 * If BIOS doesn't give a proper info, enable the corresponding
4953 * fixup entry.
4954 */
4955 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
4956 ALC269_FIXUP_AMIC),
4957 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC),
4958 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269_FIXUP_AMIC),
4959 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC),
4960 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC),
4961 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC),
4962 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269_FIXUP_AMIC),
4963 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269_FIXUP_AMIC),
4964 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269_FIXUP_AMIC),
4965 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_FIXUP_AMIC),
4966 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269_FIXUP_AMIC),
4967 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_FIXUP_AMIC),
4968 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_FIXUP_AMIC),
4969 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_FIXUP_AMIC),
4970 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_FIXUP_AMIC),
4971 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_FIXUP_AMIC),
4972 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_FIXUP_AMIC),
4973 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_FIXUP_AMIC),
4974 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_FIXUP_AMIC),
4975 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_FIXUP_AMIC),
4976 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_FIXUP_AMIC),
4977 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_FIXUP_AMIC),
4978 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_FIXUP_AMIC),
4979 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_FIXUP_AMIC),
4980 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_FIXUP_AMIC),
4981 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_FIXUP_AMIC),
4982 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_FIXUP_AMIC),
4983 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_FIXUP_AMIC),
4984 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_FIXUP_AMIC),
4985 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_FIXUP_AMIC),
4986 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_FIXUP_AMIC),
4987 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_FIXUP_AMIC),
4988 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_FIXUP_AMIC),
4989 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_FIXUP_AMIC),
4990 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_FIXUP_AMIC),
4991 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_FIXUP_AMIC),
4992 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_FIXUP_DMIC),
4993 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_FIXUP_AMIC),
4994 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_AMIC),
4995 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_FIXUP_DMIC),
4996 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_FIXUP_DMIC),
4997#endif
4998 {}
4999};
5000
5001static const struct alc_model_fixup alc269_fixup_models[] = {
5002 {.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"},
5003 {.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"},
4617 {} 5004 {}
4618}; 5005};
4619 5006
@@ -4622,23 +5009,23 @@ static int alc269_fill_coef(struct hda_codec *codec)
4622{ 5009{
4623 int val; 5010 int val;
4624 5011
4625 if ((alc_read_coef_idx(codec, 0) & 0x00ff) < 0x015) { 5012 if ((alc_get_coef0(codec) & 0x00ff) < 0x015) {
4626 alc_write_coef_idx(codec, 0xf, 0x960b); 5013 alc_write_coef_idx(codec, 0xf, 0x960b);
4627 alc_write_coef_idx(codec, 0xe, 0x8817); 5014 alc_write_coef_idx(codec, 0xe, 0x8817);
4628 } 5015 }
4629 5016
4630 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x016) { 5017 if ((alc_get_coef0(codec) & 0x00ff) == 0x016) {
4631 alc_write_coef_idx(codec, 0xf, 0x960b); 5018 alc_write_coef_idx(codec, 0xf, 0x960b);
4632 alc_write_coef_idx(codec, 0xe, 0x8814); 5019 alc_write_coef_idx(codec, 0xe, 0x8814);
4633 } 5020 }
4634 5021
4635 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) { 5022 if ((alc_get_coef0(codec) & 0x00ff) == 0x017) {
4636 val = alc_read_coef_idx(codec, 0x04); 5023 val = alc_read_coef_idx(codec, 0x04);
4637 /* Power up output pin */ 5024 /* Power up output pin */
4638 alc_write_coef_idx(codec, 0x04, val | (1<<11)); 5025 alc_write_coef_idx(codec, 0x04, val | (1<<11));
4639 } 5026 }
4640 5027
4641 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) { 5028 if ((alc_get_coef0(codec) & 0x00ff) == 0x018) {
4642 val = alc_read_coef_idx(codec, 0xd); 5029 val = alc_read_coef_idx(codec, 0xd);
4643 if ((val & 0x0c00) >> 10 != 0x1) { 5030 if ((val & 0x0c00) >> 10 != 0x1) {
4644 /* Capless ramp up clock control */ 5031 /* Capless ramp up clock control */
@@ -4662,15 +5049,10 @@ static int alc269_fill_coef(struct hda_codec *codec)
4662 5049
4663/* 5050/*
4664 */ 5051 */
4665#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4666#include "alc269_quirks.c"
4667#endif
4668
4669static int patch_alc269(struct hda_codec *codec) 5052static int patch_alc269(struct hda_codec *codec)
4670{ 5053{
4671 struct alc_spec *spec; 5054 struct alc_spec *spec;
4672 int board_config, coef; 5055 int err = 0;
4673 int err;
4674 5056
4675 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 5057 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4676 if (spec == NULL) 5058 if (spec == NULL)
@@ -4682,72 +5064,41 @@ static int patch_alc269(struct hda_codec *codec)
4682 5064
4683 alc_auto_parse_customize_define(codec); 5065 alc_auto_parse_customize_define(codec);
4684 5066
5067 err = alc_codec_rename_from_preset(codec);
5068 if (err < 0)
5069 goto error;
5070
4685 if (codec->vendor_id == 0x10ec0269) { 5071 if (codec->vendor_id == 0x10ec0269) {
4686 spec->codec_variant = ALC269_TYPE_ALC269VA; 5072 spec->codec_variant = ALC269_TYPE_ALC269VA;
4687 coef = alc_read_coef_idx(codec, 0); 5073 switch (alc_get_coef0(codec) & 0x00f0) {
4688 if ((coef & 0x00f0) == 0x0010) { 5074 case 0x0010:
4689 if (codec->bus->pci->subsystem_vendor == 0x1025 && 5075 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
4690 spec->cdefine.platform_type == 1) { 5076 spec->cdefine.platform_type == 1)
4691 alc_codec_rename(codec, "ALC271X"); 5077 err = alc_codec_rename(codec, "ALC271X");
4692 } else if ((coef & 0xf000) == 0x2000) {
4693 alc_codec_rename(codec, "ALC259");
4694 } else if ((coef & 0xf000) == 0x3000) {
4695 alc_codec_rename(codec, "ALC258");
4696 } else if ((coef & 0xfff0) == 0x3010) {
4697 alc_codec_rename(codec, "ALC277");
4698 } else {
4699 alc_codec_rename(codec, "ALC269VB");
4700 }
4701 spec->codec_variant = ALC269_TYPE_ALC269VB; 5078 spec->codec_variant = ALC269_TYPE_ALC269VB;
4702 } else if ((coef & 0x00f0) == 0x0020) { 5079 break;
4703 if (coef == 0xa023) 5080 case 0x0020:
4704 alc_codec_rename(codec, "ALC259"); 5081 if (codec->bus->pci->subsystem_vendor == 0x17aa &&
4705 else if (coef == 0x6023) 5082 codec->bus->pci->subsystem_device == 0x21f3)
4706 alc_codec_rename(codec, "ALC281X"); 5083 err = alc_codec_rename(codec, "ALC3202");
4707 else if (codec->bus->pci->subsystem_vendor == 0x17aa &&
4708 codec->bus->pci->subsystem_device == 0x21f3)
4709 alc_codec_rename(codec, "ALC3202");
4710 else
4711 alc_codec_rename(codec, "ALC269VC");
4712 spec->codec_variant = ALC269_TYPE_ALC269VC; 5084 spec->codec_variant = ALC269_TYPE_ALC269VC;
4713 } else 5085 break;
5086 default:
4714 alc_fix_pll_init(codec, 0x20, 0x04, 15); 5087 alc_fix_pll_init(codec, 0x20, 0x04, 15);
5088 }
5089 if (err < 0)
5090 goto error;
4715 alc269_fill_coef(codec); 5091 alc269_fill_coef(codec);
4716 } 5092 }
4717 5093
4718 board_config = alc_board_config(codec, ALC269_MODEL_LAST, 5094 alc_pick_fixup(codec, alc269_fixup_models,
4719 alc269_models, alc269_cfg_tbl); 5095 alc269_fixup_tbl, alc269_fixups);
4720 5096 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
4721 if (board_config < 0) {
4722 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4723 codec->chip_name);
4724 board_config = ALC_MODEL_AUTO;
4725 }
4726
4727 if (board_config == ALC_MODEL_AUTO) {
4728 alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups);
4729 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
4730 }
4731 5097
4732 if (board_config == ALC_MODEL_AUTO) { 5098 /* automatic parse from the BIOS config */
4733 /* automatic parse from the BIOS config */ 5099 err = alc269_parse_auto_config(codec);
4734 err = alc269_parse_auto_config(codec); 5100 if (err < 0)
4735 if (err < 0) { 5101 goto error;
4736 alc_free(codec);
4737 return err;
4738 }
4739#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4740 else if (!err) {
4741 printk(KERN_INFO
4742 "hda_codec: Cannot set up configuration "
4743 "from BIOS. Using base mode...\n");
4744 board_config = ALC269_BASIC;
4745 }
4746#endif
4747 }
4748
4749 if (board_config != ALC_MODEL_AUTO)
4750 setup_preset(codec, &alc269_presets[board_config]);
4751 5102
4752 if (!spec->no_analog && !spec->adc_nids) { 5103 if (!spec->no_analog && !spec->adc_nids) {
4753 alc_auto_fill_adc_caps(codec); 5104 alc_auto_fill_adc_caps(codec);
@@ -4760,10 +5111,8 @@ static int patch_alc269(struct hda_codec *codec)
4760 5111
4761 if (!spec->no_analog && has_cdefine_beep(codec)) { 5112 if (!spec->no_analog && has_cdefine_beep(codec)) {
4762 err = snd_hda_attach_beep_device(codec, 0x1); 5113 err = snd_hda_attach_beep_device(codec, 0x1);
4763 if (err < 0) { 5114 if (err < 0)
4764 alc_free(codec); 5115 goto error;
4765 return err;
4766 }
4767 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 5116 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
4768 } 5117 }
4769 5118
@@ -4775,8 +5124,7 @@ static int patch_alc269(struct hda_codec *codec)
4775#ifdef CONFIG_PM 5124#ifdef CONFIG_PM
4776 codec->patch_ops.resume = alc269_resume; 5125 codec->patch_ops.resume = alc269_resume;
4777#endif 5126#endif
4778 if (board_config == ALC_MODEL_AUTO) 5127 spec->init_hook = alc_auto_init_std;
4779 spec->init_hook = alc_auto_init_std;
4780 spec->shutup = alc269_shutup; 5128 spec->shutup = alc269_shutup;
4781 5129
4782 alc_init_jacks(codec); 5130 alc_init_jacks(codec);
@@ -4788,6 +5136,10 @@ static int patch_alc269(struct hda_codec *codec)
4788#endif 5136#endif
4789 5137
4790 return 0; 5138 return 0;
5139
5140 error:
5141 alc_free(codec);
5142 return err;
4791} 5143}
4792 5144
4793/* 5145/*
@@ -4835,14 +5187,9 @@ static const struct snd_pci_quirk alc861_fixup_tbl[] = {
4835 5187
4836/* 5188/*
4837 */ 5189 */
4838#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4839#include "alc861_quirks.c"
4840#endif
4841
4842static int patch_alc861(struct hda_codec *codec) 5190static int patch_alc861(struct hda_codec *codec)
4843{ 5191{
4844 struct alc_spec *spec; 5192 struct alc_spec *spec;
4845 int board_config;
4846 int err; 5193 int err;
4847 5194
4848 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 5195 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
@@ -4853,39 +5200,13 @@ static int patch_alc861(struct hda_codec *codec)
4853 5200
4854 spec->mixer_nid = 0x15; 5201 spec->mixer_nid = 0x15;
4855 5202
4856 board_config = alc_board_config(codec, ALC861_MODEL_LAST, 5203 alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
4857 alc861_models, alc861_cfg_tbl); 5204 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
4858
4859 if (board_config < 0) {
4860 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4861 codec->chip_name);
4862 board_config = ALC_MODEL_AUTO;
4863 }
4864
4865 if (board_config == ALC_MODEL_AUTO) {
4866 alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
4867 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
4868 }
4869
4870 if (board_config == ALC_MODEL_AUTO) {
4871 /* automatic parse from the BIOS config */
4872 err = alc861_parse_auto_config(codec);
4873 if (err < 0) {
4874 alc_free(codec);
4875 return err;
4876 }
4877#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4878 else if (!err) {
4879 printk(KERN_INFO
4880 "hda_codec: Cannot set up configuration "
4881 "from BIOS. Using base mode...\n");
4882 board_config = ALC861_3ST_DIG;
4883 }
4884#endif
4885 }
4886 5205
4887 if (board_config != ALC_MODEL_AUTO) 5206 /* automatic parse from the BIOS config */
4888 setup_preset(codec, &alc861_presets[board_config]); 5207 err = alc861_parse_auto_config(codec);
5208 if (err < 0)
5209 goto error;
4889 5210
4890 if (!spec->no_analog && !spec->adc_nids) { 5211 if (!spec->no_analog && !spec->adc_nids) {
4891 alc_auto_fill_adc_caps(codec); 5212 alc_auto_fill_adc_caps(codec);
@@ -4898,10 +5219,8 @@ static int patch_alc861(struct hda_codec *codec)
4898 5219
4899 if (!spec->no_analog) { 5220 if (!spec->no_analog) {
4900 err = snd_hda_attach_beep_device(codec, 0x23); 5221 err = snd_hda_attach_beep_device(codec, 0x23);
4901 if (err < 0) { 5222 if (err < 0)
4902 alc_free(codec); 5223 goto error;
4903 return err;
4904 }
4905 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT); 5224 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
4906 } 5225 }
4907 5226
@@ -4910,18 +5229,18 @@ static int patch_alc861(struct hda_codec *codec)
4910 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); 5229 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
4911 5230
4912 codec->patch_ops = alc_patch_ops; 5231 codec->patch_ops = alc_patch_ops;
4913 if (board_config == ALC_MODEL_AUTO) { 5232 spec->init_hook = alc_auto_init_std;
4914 spec->init_hook = alc_auto_init_std;
4915#ifdef CONFIG_SND_HDA_POWER_SAVE
4916 spec->power_hook = alc_power_eapd;
4917#endif
4918 }
4919#ifdef CONFIG_SND_HDA_POWER_SAVE 5233#ifdef CONFIG_SND_HDA_POWER_SAVE
5234 spec->power_hook = alc_power_eapd;
4920 if (!spec->loopback.amplist) 5235 if (!spec->loopback.amplist)
4921 spec->loopback.amplist = alc861_loopbacks; 5236 spec->loopback.amplist = alc861_loopbacks;
4922#endif 5237#endif
4923 5238
4924 return 0; 5239 return 0;
5240
5241 error:
5242 alc_free(codec);
5243 return err;
4925} 5244}
4926 5245
4927/* 5246/*
@@ -4943,24 +5262,41 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec)
4943} 5262}
4944 5263
4945enum { 5264enum {
4946 ALC660VD_FIX_ASUS_GPIO1 5265 ALC660VD_FIX_ASUS_GPIO1,
5266 ALC861VD_FIX_DALLAS,
4947}; 5267};
4948 5268
4949/* reset GPIO1 */ 5269/* exclude VREF80 */
5270static void alc861vd_fixup_dallas(struct hda_codec *codec,
5271 const struct alc_fixup *fix, int action)
5272{
5273 if (action == ALC_FIXUP_ACT_PRE_PROBE) {
5274 snd_hda_override_pin_caps(codec, 0x18, 0x00001714);
5275 snd_hda_override_pin_caps(codec, 0x19, 0x0000171c);
5276 }
5277}
5278
4950static const struct alc_fixup alc861vd_fixups[] = { 5279static const struct alc_fixup alc861vd_fixups[] = {
4951 [ALC660VD_FIX_ASUS_GPIO1] = { 5280 [ALC660VD_FIX_ASUS_GPIO1] = {
4952 .type = ALC_FIXUP_VERBS, 5281 .type = ALC_FIXUP_VERBS,
4953 .v.verbs = (const struct hda_verb[]) { 5282 .v.verbs = (const struct hda_verb[]) {
5283 /* reset GPIO1 */
4954 {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, 5284 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
4955 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 5285 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4956 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 5286 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
4957 { } 5287 { }
4958 } 5288 }
4959 }, 5289 },
5290 [ALC861VD_FIX_DALLAS] = {
5291 .type = ALC_FIXUP_FUNC,
5292 .v.func = alc861vd_fixup_dallas,
5293 },
4960}; 5294};
4961 5295
4962static const struct snd_pci_quirk alc861vd_fixup_tbl[] = { 5296static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
5297 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_FIX_DALLAS),
4963 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1), 5298 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
5299 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_FIX_DALLAS),
4964 {} 5300 {}
4965}; 5301};
4966 5302
@@ -4972,14 +5308,10 @@ static const struct hda_verb alc660vd_eapd_verbs[] = {
4972 5308
4973/* 5309/*
4974 */ 5310 */
4975#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4976#include "alc861vd_quirks.c"
4977#endif
4978
4979static int patch_alc861vd(struct hda_codec *codec) 5311static int patch_alc861vd(struct hda_codec *codec)
4980{ 5312{
4981 struct alc_spec *spec; 5313 struct alc_spec *spec;
4982 int err, board_config; 5314 int err;
4983 5315
4984 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 5316 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4985 if (spec == NULL) 5317 if (spec == NULL)
@@ -4989,39 +5321,13 @@ static int patch_alc861vd(struct hda_codec *codec)
4989 5321
4990 spec->mixer_nid = 0x0b; 5322 spec->mixer_nid = 0x0b;
4991 5323
4992 board_config = alc_board_config(codec, ALC861VD_MODEL_LAST, 5324 alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
4993 alc861vd_models, alc861vd_cfg_tbl); 5325 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
4994 5326
4995 if (board_config < 0) { 5327 /* automatic parse from the BIOS config */
4996 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 5328 err = alc861vd_parse_auto_config(codec);
4997 codec->chip_name); 5329 if (err < 0)
4998 board_config = ALC_MODEL_AUTO; 5330 goto error;
4999 }
5000
5001 if (board_config == ALC_MODEL_AUTO) {
5002 alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
5003 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
5004 }
5005
5006 if (board_config == ALC_MODEL_AUTO) {
5007 /* automatic parse from the BIOS config */
5008 err = alc861vd_parse_auto_config(codec);
5009 if (err < 0) {
5010 alc_free(codec);
5011 return err;
5012 }
5013#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
5014 else if (!err) {
5015 printk(KERN_INFO
5016 "hda_codec: Cannot set up configuration "
5017 "from BIOS. Using base mode...\n");
5018 board_config = ALC861VD_3ST;
5019 }
5020#endif
5021 }
5022
5023 if (board_config != ALC_MODEL_AUTO)
5024 setup_preset(codec, &alc861vd_presets[board_config]);
5025 5331
5026 if (codec->vendor_id == 0x10ec0660) { 5332 if (codec->vendor_id == 0x10ec0660) {
5027 /* always turn on EAPD */ 5333 /* always turn on EAPD */
@@ -5039,10 +5345,8 @@ static int patch_alc861vd(struct hda_codec *codec)
5039 5345
5040 if (!spec->no_analog) { 5346 if (!spec->no_analog) {
5041 err = snd_hda_attach_beep_device(codec, 0x23); 5347 err = snd_hda_attach_beep_device(codec, 0x23);
5042 if (err < 0) { 5348 if (err < 0)
5043 alc_free(codec); 5349 goto error;
5044 return err;
5045 }
5046 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 5350 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
5047 } 5351 }
5048 5352
@@ -5052,8 +5356,7 @@ static int patch_alc861vd(struct hda_codec *codec)
5052 5356
5053 codec->patch_ops = alc_patch_ops; 5357 codec->patch_ops = alc_patch_ops;
5054 5358
5055 if (board_config == ALC_MODEL_AUTO) 5359 spec->init_hook = alc_auto_init_std;
5056 spec->init_hook = alc_auto_init_std;
5057 spec->shutup = alc_eapd_shutup; 5360 spec->shutup = alc_eapd_shutup;
5058#ifdef CONFIG_SND_HDA_POWER_SAVE 5361#ifdef CONFIG_SND_HDA_POWER_SAVE
5059 if (!spec->loopback.amplist) 5362 if (!spec->loopback.amplist)
@@ -5061,6 +5364,10 @@ static int patch_alc861vd(struct hda_codec *codec)
5061#endif 5364#endif
5062 5365
5063 return 0; 5366 return 0;
5367
5368 error:
5369 alc_free(codec);
5370 return err;
5064} 5371}
5065 5372
5066/* 5373/*
@@ -5118,6 +5425,14 @@ enum {
5118 ALC662_FIXUP_CZC_P10T, 5425 ALC662_FIXUP_CZC_P10T,
5119 ALC662_FIXUP_SKU_IGNORE, 5426 ALC662_FIXUP_SKU_IGNORE,
5120 ALC662_FIXUP_HP_RP5800, 5427 ALC662_FIXUP_HP_RP5800,
5428 ALC662_FIXUP_ASUS_MODE1,
5429 ALC662_FIXUP_ASUS_MODE2,
5430 ALC662_FIXUP_ASUS_MODE3,
5431 ALC662_FIXUP_ASUS_MODE4,
5432 ALC662_FIXUP_ASUS_MODE5,
5433 ALC662_FIXUP_ASUS_MODE6,
5434 ALC662_FIXUP_ASUS_MODE7,
5435 ALC662_FIXUP_ASUS_MODE8,
5121}; 5436};
5122 5437
5123static const struct alc_fixup alc662_fixups[] = { 5438static const struct alc_fixup alc662_fixups[] = {
@@ -5159,37 +5474,204 @@ static const struct alc_fixup alc662_fixups[] = {
5159 .chained = true, 5474 .chained = true,
5160 .chain_id = ALC662_FIXUP_SKU_IGNORE 5475 .chain_id = ALC662_FIXUP_SKU_IGNORE
5161 }, 5476 },
5477 [ALC662_FIXUP_ASUS_MODE1] = {
5478 .type = ALC_FIXUP_PINS,
5479 .v.pins = (const struct alc_pincfg[]) {
5480 { 0x14, 0x99130110 }, /* speaker */
5481 { 0x18, 0x01a19c20 }, /* mic */
5482 { 0x19, 0x99a3092f }, /* int-mic */
5483 { 0x21, 0x0121401f }, /* HP out */
5484 { }
5485 },
5486 .chained = true,
5487 .chain_id = ALC662_FIXUP_SKU_IGNORE
5488 },
5489 [ALC662_FIXUP_ASUS_MODE2] = {
5490 .type = ALC_FIXUP_PINS,
5491 .v.pins = (const struct alc_pincfg[]) {
5492 { 0x14, 0x99130110 }, /* speaker */
5493 { 0x18, 0x01a19820 }, /* mic */
5494 { 0x19, 0x99a3092f }, /* int-mic */
5495 { 0x1b, 0x0121401f }, /* HP out */
5496 { }
5497 },
5498 .chained = true,
5499 .chain_id = ALC662_FIXUP_SKU_IGNORE
5500 },
5501 [ALC662_FIXUP_ASUS_MODE3] = {
5502 .type = ALC_FIXUP_PINS,
5503 .v.pins = (const struct alc_pincfg[]) {
5504 { 0x14, 0x99130110 }, /* speaker */
5505 { 0x15, 0x0121441f }, /* HP */
5506 { 0x18, 0x01a19840 }, /* mic */
5507 { 0x19, 0x99a3094f }, /* int-mic */
5508 { 0x21, 0x01211420 }, /* HP2 */
5509 { }
5510 },
5511 .chained = true,
5512 .chain_id = ALC662_FIXUP_SKU_IGNORE
5513 },
5514 [ALC662_FIXUP_ASUS_MODE4] = {
5515 .type = ALC_FIXUP_PINS,
5516 .v.pins = (const struct alc_pincfg[]) {
5517 { 0x14, 0x99130110 }, /* speaker */
5518 { 0x16, 0x99130111 }, /* speaker */
5519 { 0x18, 0x01a19840 }, /* mic */
5520 { 0x19, 0x99a3094f }, /* int-mic */
5521 { 0x21, 0x0121441f }, /* HP */
5522 { }
5523 },
5524 .chained = true,
5525 .chain_id = ALC662_FIXUP_SKU_IGNORE
5526 },
5527 [ALC662_FIXUP_ASUS_MODE5] = {
5528 .type = ALC_FIXUP_PINS,
5529 .v.pins = (const struct alc_pincfg[]) {
5530 { 0x14, 0x99130110 }, /* speaker */
5531 { 0x15, 0x0121441f }, /* HP */
5532 { 0x16, 0x99130111 }, /* speaker */
5533 { 0x18, 0x01a19840 }, /* mic */
5534 { 0x19, 0x99a3094f }, /* int-mic */
5535 { }
5536 },
5537 .chained = true,
5538 .chain_id = ALC662_FIXUP_SKU_IGNORE
5539 },
5540 [ALC662_FIXUP_ASUS_MODE6] = {
5541 .type = ALC_FIXUP_PINS,
5542 .v.pins = (const struct alc_pincfg[]) {
5543 { 0x14, 0x99130110 }, /* speaker */
5544 { 0x15, 0x01211420 }, /* HP2 */
5545 { 0x18, 0x01a19840 }, /* mic */
5546 { 0x19, 0x99a3094f }, /* int-mic */
5547 { 0x1b, 0x0121441f }, /* HP */
5548 { }
5549 },
5550 .chained = true,
5551 .chain_id = ALC662_FIXUP_SKU_IGNORE
5552 },
5553 [ALC662_FIXUP_ASUS_MODE7] = {
5554 .type = ALC_FIXUP_PINS,
5555 .v.pins = (const struct alc_pincfg[]) {
5556 { 0x14, 0x99130110 }, /* speaker */
5557 { 0x17, 0x99130111 }, /* speaker */
5558 { 0x18, 0x01a19840 }, /* mic */
5559 { 0x19, 0x99a3094f }, /* int-mic */
5560 { 0x1b, 0x01214020 }, /* HP */
5561 { 0x21, 0x0121401f }, /* HP */
5562 { }
5563 },
5564 .chained = true,
5565 .chain_id = ALC662_FIXUP_SKU_IGNORE
5566 },
5567 [ALC662_FIXUP_ASUS_MODE8] = {
5568 .type = ALC_FIXUP_PINS,
5569 .v.pins = (const struct alc_pincfg[]) {
5570 { 0x14, 0x99130110 }, /* speaker */
5571 { 0x12, 0x99a30970 }, /* int-mic */
5572 { 0x15, 0x01214020 }, /* HP */
5573 { 0x17, 0x99130111 }, /* speaker */
5574 { 0x18, 0x01a19840 }, /* mic */
5575 { 0x21, 0x0121401f }, /* HP */
5576 { }
5577 },
5578 .chained = true,
5579 .chain_id = ALC662_FIXUP_SKU_IGNORE
5580 },
5162}; 5581};
5163 5582
5164static const struct snd_pci_quirk alc662_fixup_tbl[] = { 5583static const struct snd_pci_quirk alc662_fixup_tbl[] = {
5584 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2),
5165 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE), 5585 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
5166 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE), 5586 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
5167 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), 5587 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
5168 SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), 5588 SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
5589 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2),
5169 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), 5590 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
5170 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), 5591 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
5171 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD), 5592 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
5172 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T), 5593 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
5594
5595#if 0
5596 /* Below is a quirk table taken from the old code.
5597 * Basically the device should work as is without the fixup table.
5598 * If BIOS doesn't give a proper info, enable the corresponding
5599 * fixup entry.
5600 */
5601 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC662_FIXUP_ASUS_MODE1),
5602 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC662_FIXUP_ASUS_MODE3),
5603 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC662_FIXUP_ASUS_MODE1),
5604 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC662_FIXUP_ASUS_MODE3),
5605 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
5606 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
5607 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
5608 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC662_FIXUP_ASUS_MODE1),
5609 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC662_FIXUP_ASUS_MODE1),
5610 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
5611 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC662_FIXUP_ASUS_MODE7),
5612 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC662_FIXUP_ASUS_MODE7),
5613 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC662_FIXUP_ASUS_MODE8),
5614 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC662_FIXUP_ASUS_MODE3),
5615 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC662_FIXUP_ASUS_MODE1),
5616 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
5617 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_FIXUP_ASUS_MODE2),
5618 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC662_FIXUP_ASUS_MODE1),
5619 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
5620 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
5621 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
5622 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
5623 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC662_FIXUP_ASUS_MODE1),
5624 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC662_FIXUP_ASUS_MODE3),
5625 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_FIXUP_ASUS_MODE2),
5626 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
5627 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC662_FIXUP_ASUS_MODE5),
5628 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
5629 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
5630 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC662_FIXUP_ASUS_MODE1),
5631 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
5632 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
5633 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC662_FIXUP_ASUS_MODE3),
5634 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC662_FIXUP_ASUS_MODE3),
5635 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC662_FIXUP_ASUS_MODE1),
5636 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC662_FIXUP_ASUS_MODE1),
5637 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC662_FIXUP_ASUS_MODE1),
5638 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC662_FIXUP_ASUS_MODE1),
5639 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC662_FIXUP_ASUS_MODE1),
5640 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
5641 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_FIXUP_ASUS_MODE2),
5642 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC662_FIXUP_ASUS_MODE1),
5643 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
5644 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC662_FIXUP_ASUS_MODE3),
5645 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC662_FIXUP_ASUS_MODE1),
5646 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC662_FIXUP_ASUS_MODE1),
5647 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC662_FIXUP_ASUS_MODE1),
5648 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_FIXUP_ASUS_MODE2),
5649 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
5650 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE4),
5651#endif
5173 {} 5652 {}
5174}; 5653};
5175 5654
5176static const struct alc_model_fixup alc662_fixup_models[] = { 5655static const struct alc_model_fixup alc662_fixup_models[] = {
5177 {.id = ALC272_FIXUP_MARIO, .name = "mario"}, 5656 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
5657 {.id = ALC662_FIXUP_ASUS_MODE1, .name = "asus-mode1"},
5658 {.id = ALC662_FIXUP_ASUS_MODE2, .name = "asus-mode2"},
5659 {.id = ALC662_FIXUP_ASUS_MODE3, .name = "asus-mode3"},
5660 {.id = ALC662_FIXUP_ASUS_MODE4, .name = "asus-mode4"},
5661 {.id = ALC662_FIXUP_ASUS_MODE5, .name = "asus-mode5"},
5662 {.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"},
5663 {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"},
5664 {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"},
5178 {} 5665 {}
5179}; 5666};
5180 5667
5181 5668
5182/* 5669/*
5183 */ 5670 */
5184#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
5185#include "alc662_quirks.c"
5186#endif
5187
5188static int patch_alc662(struct hda_codec *codec) 5671static int patch_alc662(struct hda_codec *codec)
5189{ 5672{
5190 struct alc_spec *spec; 5673 struct alc_spec *spec;
5191 int err, board_config; 5674 int err = 0;
5192 int coef;
5193 5675
5194 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 5676 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5195 if (!spec) 5677 if (!spec)
@@ -5199,50 +5681,31 @@ static int patch_alc662(struct hda_codec *codec)
5199 5681
5200 spec->mixer_nid = 0x0b; 5682 spec->mixer_nid = 0x0b;
5201 5683
5684 /* handle multiple HPs as is */
5685 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
5686
5202 alc_auto_parse_customize_define(codec); 5687 alc_auto_parse_customize_define(codec);
5203 5688
5204 alc_fix_pll_init(codec, 0x20, 0x04, 15); 5689 alc_fix_pll_init(codec, 0x20, 0x04, 15);
5205 5690
5206 coef = alc_read_coef_idx(codec, 0); 5691 err = alc_codec_rename_from_preset(codec);
5207 if (coef == 0x8020 || coef == 0x8011) 5692 if (err < 0)
5208 alc_codec_rename(codec, "ALC661"); 5693 goto error;
5209 else if (coef & (1 << 14) &&
5210 codec->bus->pci->subsystem_vendor == 0x1025 &&
5211 spec->cdefine.platform_type == 1)
5212 alc_codec_rename(codec, "ALC272X");
5213 else if (coef == 0x4011)
5214 alc_codec_rename(codec, "ALC656");
5215
5216 board_config = alc_board_config(codec, ALC662_MODEL_LAST,
5217 alc662_models, alc662_cfg_tbl);
5218 if (board_config < 0) {
5219 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5220 codec->chip_name);
5221 board_config = ALC_MODEL_AUTO;
5222 }
5223 5694
5224 if (board_config == ALC_MODEL_AUTO) { 5695 if ((alc_get_coef0(codec) & (1 << 14)) &&
5225 alc_pick_fixup(codec, alc662_fixup_models, 5696 codec->bus->pci->subsystem_vendor == 0x1025 &&
5226 alc662_fixup_tbl, alc662_fixups); 5697 spec->cdefine.platform_type == 1) {
5227 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 5698 if (alc_codec_rename(codec, "ALC272X") < 0)
5228 /* automatic parse from the BIOS config */ 5699 goto error;
5229 err = alc662_parse_auto_config(codec);
5230 if (err < 0) {
5231 alc_free(codec);
5232 return err;
5233 }
5234#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
5235 else if (!err) {
5236 printk(KERN_INFO
5237 "hda_codec: Cannot set up configuration "
5238 "from BIOS. Using base mode...\n");
5239 board_config = ALC662_3ST_2ch_DIG;
5240 }
5241#endif
5242 } 5700 }
5243 5701
5244 if (board_config != ALC_MODEL_AUTO) 5702 alc_pick_fixup(codec, alc662_fixup_models,
5245 setup_preset(codec, &alc662_presets[board_config]); 5703 alc662_fixup_tbl, alc662_fixups);
5704 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
5705 /* automatic parse from the BIOS config */
5706 err = alc662_parse_auto_config(codec);
5707 if (err < 0)
5708 goto error;
5246 5709
5247 if (!spec->no_analog && !spec->adc_nids) { 5710 if (!spec->no_analog && !spec->adc_nids) {
5248 alc_auto_fill_adc_caps(codec); 5711 alc_auto_fill_adc_caps(codec);
@@ -5255,10 +5718,8 @@ static int patch_alc662(struct hda_codec *codec)
5255 5718
5256 if (!spec->no_analog && has_cdefine_beep(codec)) { 5719 if (!spec->no_analog && has_cdefine_beep(codec)) {
5257 err = snd_hda_attach_beep_device(codec, 0x1); 5720 err = snd_hda_attach_beep_device(codec, 0x1);
5258 if (err < 0) { 5721 if (err < 0)
5259 alc_free(codec); 5722 goto error;
5260 return err;
5261 }
5262 switch (codec->vendor_id) { 5723 switch (codec->vendor_id) {
5263 case 0x10ec0662: 5724 case 0x10ec0662:
5264 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 5725 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
@@ -5278,8 +5739,7 @@ static int patch_alc662(struct hda_codec *codec)
5278 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); 5739 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
5279 5740
5280 codec->patch_ops = alc_patch_ops; 5741 codec->patch_ops = alc_patch_ops;
5281 if (board_config == ALC_MODEL_AUTO) 5742 spec->init_hook = alc_auto_init_std;
5282 spec->init_hook = alc_auto_init_std;
5283 spec->shutup = alc_eapd_shutup; 5743 spec->shutup = alc_eapd_shutup;
5284 5744
5285 alc_init_jacks(codec); 5745 alc_init_jacks(codec);
@@ -5290,32 +5750,10 @@ static int patch_alc662(struct hda_codec *codec)
5290#endif 5750#endif
5291 5751
5292 return 0; 5752 return 0;
5293}
5294 5753
5295static int patch_alc888(struct hda_codec *codec) 5754 error:
5296{ 5755 alc_free(codec);
5297 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){ 5756 return err;
5298 kfree(codec->chip_name);
5299 if (codec->vendor_id == 0x10ec0887)
5300 codec->chip_name = kstrdup("ALC887-VD", GFP_KERNEL);
5301 else
5302 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
5303 if (!codec->chip_name) {
5304 alc_free(codec);
5305 return -ENOMEM;
5306 }
5307 return patch_alc662(codec);
5308 }
5309 return patch_alc882(codec);
5310}
5311
5312static int patch_alc899(struct hda_codec *codec)
5313{
5314 if ((alc_read_coef_idx(codec, 0) & 0x2000) != 0x2000) {
5315 kfree(codec->chip_name);
5316 codec->chip_name = kstrdup("ALC898", GFP_KERNEL);
5317 }
5318 return patch_alc882(codec);
5319} 5757}
5320 5758
5321/* 5759/*
@@ -5329,14 +5767,9 @@ static int alc680_parse_auto_config(struct hda_codec *codec)
5329 5767
5330/* 5768/*
5331 */ 5769 */
5332#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
5333#include "alc680_quirks.c"
5334#endif
5335
5336static int patch_alc680(struct hda_codec *codec) 5770static int patch_alc680(struct hda_codec *codec)
5337{ 5771{
5338 struct alc_spec *spec; 5772 struct alc_spec *spec;
5339 int board_config;
5340 int err; 5773 int err;
5341 5774
5342 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 5775 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
@@ -5347,43 +5780,11 @@ static int patch_alc680(struct hda_codec *codec)
5347 5780
5348 /* ALC680 has no aa-loopback mixer */ 5781 /* ALC680 has no aa-loopback mixer */
5349 5782
5350 board_config = alc_board_config(codec, ALC680_MODEL_LAST, 5783 /* automatic parse from the BIOS config */
5351 alc680_models, alc680_cfg_tbl); 5784 err = alc680_parse_auto_config(codec);
5352 5785 if (err < 0) {
5353 if (board_config < 0) { 5786 alc_free(codec);
5354 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 5787 return err;
5355 codec->chip_name);
5356 board_config = ALC_MODEL_AUTO;
5357 }
5358
5359 if (board_config == ALC_MODEL_AUTO) {
5360 /* automatic parse from the BIOS config */
5361 err = alc680_parse_auto_config(codec);
5362 if (err < 0) {
5363 alc_free(codec);
5364 return err;
5365 }
5366#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
5367 else if (!err) {
5368 printk(KERN_INFO
5369 "hda_codec: Cannot set up configuration "
5370 "from BIOS. Using base mode...\n");
5371 board_config = ALC680_BASE;
5372 }
5373#endif
5374 }
5375
5376 if (board_config != ALC_MODEL_AUTO) {
5377 setup_preset(codec, &alc680_presets[board_config]);
5378#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
5379 spec->stream_analog_capture = &alc680_pcm_analog_auto_capture;
5380#endif
5381 }
5382
5383 if (!spec->no_analog && !spec->adc_nids) {
5384 alc_auto_fill_adc_caps(codec);
5385 alc_rebuild_imux_for_auto_mic(codec);
5386 alc_remove_invalid_adc_nids(codec);
5387 } 5788 }
5388 5789
5389 if (!spec->no_analog && !spec->cap_mixer) 5790 if (!spec->no_analog && !spec->cap_mixer)
@@ -5392,8 +5793,7 @@ static int patch_alc680(struct hda_codec *codec)
5392 spec->vmaster_nid = 0x02; 5793 spec->vmaster_nid = 0x02;
5393 5794
5394 codec->patch_ops = alc_patch_ops; 5795 codec->patch_ops = alc_patch_ops;
5395 if (board_config == ALC_MODEL_AUTO) 5796 spec->init_hook = alc_auto_init_std;
5396 spec->init_hook = alc_auto_init_std;
5397 5797
5398 return 0; 5798 return 0;
5399} 5799}
@@ -5421,6 +5821,8 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = {
5421 .patch = patch_alc882 }, 5821 .patch = patch_alc882 },
5422 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1", 5822 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
5423 .patch = patch_alc662 }, 5823 .patch = patch_alc662 },
5824 { .id = 0x10ec0662, .rev = 0x100300, .name = "ALC662 rev3",
5825 .patch = patch_alc662 },
5424 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, 5826 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
5425 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 }, 5827 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
5426 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 }, 5828 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
@@ -5433,13 +5835,13 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = {
5433 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A", 5835 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
5434 .patch = patch_alc882 }, 5836 .patch = patch_alc882 },
5435 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, 5837 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
5436 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc888 }, 5838 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 },
5437 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200", 5839 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
5438 .patch = patch_alc882 }, 5840 .patch = patch_alc882 },
5439 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 }, 5841 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc882 },
5440 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 }, 5842 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
5441 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 }, 5843 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
5442 { .id = 0x10ec0899, .name = "ALC899", .patch = patch_alc899 }, 5844 { .id = 0x10ec0899, .name = "ALC898", .patch = patch_alc882 },
5443 {} /* terminator */ 5845 {} /* terminator */
5444}; 5846};
5445 5847
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 987e3cf71a0..59a52a430f2 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -2972,8 +2972,9 @@ static int check_all_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
2972static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t nid) 2972static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t nid)
2973{ 2973{
2974 struct sigmatel_spec *spec = codec->spec; 2974 struct sigmatel_spec *spec = codec->spec;
2975 struct auto_pin_cfg *cfg = &spec->autocfg;
2975 int j, conn_len; 2976 int j, conn_len;
2976 hda_nid_t conn[HDA_MAX_CONNECTIONS]; 2977 hda_nid_t conn[HDA_MAX_CONNECTIONS], fallback_dac;
2977 unsigned int wcaps, wtype; 2978 unsigned int wcaps, wtype;
2978 2979
2979 conn_len = snd_hda_get_connections(codec, nid, conn, 2980 conn_len = snd_hda_get_connections(codec, nid, conn,
@@ -3001,10 +3002,21 @@ static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t nid)
3001 return conn[j]; 3002 return conn[j];
3002 } 3003 }
3003 } 3004 }
3004 /* if all DACs are already assigned, connect to the primary DAC */ 3005
3006 /* if all DACs are already assigned, connect to the primary DAC,
3007 unless we're assigning a secondary headphone */
3008 fallback_dac = spec->multiout.dac_nids[0];
3009 if (spec->multiout.hp_nid) {
3010 for (j = 0; j < cfg->hp_outs; j++)
3011 if (cfg->hp_pins[j] == nid) {
3012 fallback_dac = spec->multiout.hp_nid;
3013 break;
3014 }
3015 }
3016
3005 if (conn_len > 1) { 3017 if (conn_len > 1) {
3006 for (j = 0; j < conn_len; j++) { 3018 for (j = 0; j < conn_len; j++) {
3007 if (conn[j] == spec->multiout.dac_nids[0]) { 3019 if (conn[j] == fallback_dac) {
3008 snd_hda_codec_write_cache(codec, nid, 0, 3020 snd_hda_codec_write_cache(codec, nid, 0,
3009 AC_VERB_SET_CONNECT_SEL, j); 3021 AC_VERB_SET_CONNECT_SEL, j);
3010 break; 3022 break;
@@ -4130,22 +4142,14 @@ static int stac92xx_add_jack(struct hda_codec *codec,
4130#ifdef CONFIG_SND_HDA_INPUT_JACK 4142#ifdef CONFIG_SND_HDA_INPUT_JACK
4131 int def_conf = snd_hda_codec_get_pincfg(codec, nid); 4143 int def_conf = snd_hda_codec_get_pincfg(codec, nid);
4132 int connectivity = get_defcfg_connect(def_conf); 4144 int connectivity = get_defcfg_connect(def_conf);
4133 char name[32];
4134 int err;
4135 4145
4136 if (connectivity && connectivity != AC_JACK_PORT_FIXED) 4146 if (connectivity && connectivity != AC_JACK_PORT_FIXED)
4137 return 0; 4147 return 0;
4138 4148
4139 snprintf(name, sizeof(name), "%s at %s %s Jack", 4149 return snd_hda_input_jack_add(codec, nid, type, NULL);
4140 snd_hda_get_jack_type(def_conf), 4150#else
4141 snd_hda_get_jack_connectivity(def_conf),
4142 snd_hda_get_jack_location(def_conf));
4143
4144 err = snd_hda_input_jack_add(codec, nid, type, name);
4145 if (err < 0)
4146 return err;
4147#endif /* CONFIG_SND_HDA_INPUT_JACK */
4148 return 0; 4151 return 0;
4152#endif /* CONFIG_SND_HDA_INPUT_JACK */
4149} 4153}
4150 4154
4151static int stac_add_event(struct sigmatel_spec *spec, hda_nid_t nid, 4155static int stac_add_event(struct sigmatel_spec *spec, hda_nid_t nid,
@@ -5585,9 +5589,7 @@ static void stac92hd8x_fill_auto_spec(struct hda_codec *codec)
5585static int patch_stac92hd83xxx(struct hda_codec *codec) 5589static int patch_stac92hd83xxx(struct hda_codec *codec)
5586{ 5590{
5587 struct sigmatel_spec *spec; 5591 struct sigmatel_spec *spec;
5588 hda_nid_t conn[STAC92HD83_DAC_COUNT + 1];
5589 int err; 5592 int err;
5590 int num_dacs;
5591 5593
5592 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 5594 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5593 if (spec == NULL) 5595 if (spec == NULL)
@@ -5689,22 +5691,6 @@ again:
5689 return err; 5691 return err;
5690 } 5692 }
5691 5693
5692 /* docking output support */
5693 num_dacs = snd_hda_get_connections(codec, 0xF,
5694 conn, STAC92HD83_DAC_COUNT + 1) - 1;
5695 /* skip non-DAC connections */
5696 while (num_dacs >= 0 &&
5697 (get_wcaps_type(get_wcaps(codec, conn[num_dacs]))
5698 != AC_WID_AUD_OUT))
5699 num_dacs--;
5700 /* set port E and F to select the last DAC */
5701 if (num_dacs >= 0) {
5702 snd_hda_codec_write_cache(codec, 0xE, 0,
5703 AC_VERB_SET_CONNECT_SEL, num_dacs);
5704 snd_hda_codec_write_cache(codec, 0xF, 0,
5705 AC_VERB_SET_CONNECT_SEL, num_dacs);
5706 }
5707
5708 codec->proc_widget_hook = stac92hd_proc_hook; 5694 codec->proc_widget_hook = stac92hd_proc_hook;
5709 5695
5710 return 0; 5696 return 0;
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index 4ebfbd874c9..417d62ad3b9 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -1506,39 +1506,49 @@ static int via_build_pcms(struct hda_codec *codec)
1506 struct via_spec *spec = codec->spec; 1506 struct via_spec *spec = codec->spec;
1507 struct hda_pcm *info = spec->pcm_rec; 1507 struct hda_pcm *info = spec->pcm_rec;
1508 1508
1509 codec->num_pcms = 1; 1509 codec->num_pcms = 0;
1510 codec->pcm_info = info; 1510 codec->pcm_info = info;
1511 1511
1512 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog), 1512 if (spec->multiout.num_dacs || spec->num_adc_nids) {
1513 "%s Analog", codec->chip_name); 1513 snprintf(spec->stream_name_analog,
1514 info->name = spec->stream_name_analog; 1514 sizeof(spec->stream_name_analog),
1515 "%s Analog", codec->chip_name);
1516 info->name = spec->stream_name_analog;
1515 1517
1516 if (!spec->stream_analog_playback) 1518 if (spec->multiout.num_dacs) {
1517 spec->stream_analog_playback = &via_pcm_analog_playback; 1519 if (!spec->stream_analog_playback)
1518 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = 1520 spec->stream_analog_playback =
1519 *spec->stream_analog_playback; 1521 &via_pcm_analog_playback;
1520 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 1522 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
1521 spec->multiout.dac_nids[0]; 1523 *spec->stream_analog_playback;
1522 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 1524 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
1523 spec->multiout.max_channels; 1525 spec->multiout.dac_nids[0];
1526 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
1527 spec->multiout.max_channels;
1528 }
1524 1529
1525 if (!spec->stream_analog_capture) { 1530 if (!spec->stream_analog_capture) {
1526 if (spec->dyn_adc_switch) 1531 if (spec->dyn_adc_switch)
1527 spec->stream_analog_capture = 1532 spec->stream_analog_capture =
1528 &via_pcm_dyn_adc_analog_capture; 1533 &via_pcm_dyn_adc_analog_capture;
1529 else 1534 else
1530 spec->stream_analog_capture = &via_pcm_analog_capture; 1535 spec->stream_analog_capture =
1536 &via_pcm_analog_capture;
1537 }
1538 if (spec->num_adc_nids) {
1539 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
1540 *spec->stream_analog_capture;
1541 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
1542 spec->adc_nids[0];
1543 if (!spec->dyn_adc_switch)
1544 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
1545 spec->num_adc_nids;
1546 }
1547 codec->num_pcms++;
1548 info++;
1531 } 1549 }
1532 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
1533 *spec->stream_analog_capture;
1534 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
1535 if (!spec->dyn_adc_switch)
1536 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
1537 spec->num_adc_nids;
1538 1550
1539 if (spec->multiout.dig_out_nid || spec->dig_in_nid) { 1551 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
1540 codec->num_pcms++;
1541 info++;
1542 snprintf(spec->stream_name_digital, 1552 snprintf(spec->stream_name_digital,
1543 sizeof(spec->stream_name_digital), 1553 sizeof(spec->stream_name_digital),
1544 "%s Digital", codec->chip_name); 1554 "%s Digital", codec->chip_name);
@@ -1562,17 +1572,19 @@ static int via_build_pcms(struct hda_codec *codec)
1562 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 1572 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
1563 spec->dig_in_nid; 1573 spec->dig_in_nid;
1564 } 1574 }
1575 codec->num_pcms++;
1576 info++;
1565 } 1577 }
1566 1578
1567 if (spec->hp_dac_nid) { 1579 if (spec->hp_dac_nid) {
1568 codec->num_pcms++;
1569 info++;
1570 snprintf(spec->stream_name_hp, sizeof(spec->stream_name_hp), 1580 snprintf(spec->stream_name_hp, sizeof(spec->stream_name_hp),
1571 "%s HP", codec->chip_name); 1581 "%s HP", codec->chip_name);
1572 info->name = spec->stream_name_hp; 1582 info->name = spec->stream_name_hp;
1573 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = via_pcm_hp_playback; 1583 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = via_pcm_hp_playback;
1574 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 1584 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
1575 spec->hp_dac_nid; 1585 spec->hp_dac_nid;
1586 codec->num_pcms++;
1587 info++;
1576 } 1588 }
1577 return 0; 1589 return 0;
1578} 1590}
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
index 0ccc0eb7577..8531b983f3a 100644
--- a/sound/pci/ice1712/ice1712.c
+++ b/sound/pci/ice1712/ice1712.c
@@ -2748,8 +2748,9 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci,
2748 if (!c->no_mpu401) { 2748 if (!c->no_mpu401) {
2749 err = snd_mpu401_uart_new(card, 0, MPU401_HW_ICE1712, 2749 err = snd_mpu401_uart_new(card, 0, MPU401_HW_ICE1712,
2750 ICEREG(ice, MPU1_CTRL), 2750 ICEREG(ice, MPU1_CTRL),
2751 (c->mpu401_1_info_flags | MPU401_INFO_INTEGRATED), 2751 c->mpu401_1_info_flags |
2752 ice->irq, 0, &ice->rmidi[0]); 2752 MPU401_INFO_INTEGRATED | MPU401_INFO_IRQ_HOOK,
2753 -1, &ice->rmidi[0]);
2753 if (err < 0) { 2754 if (err < 0) {
2754 snd_card_free(card); 2755 snd_card_free(card);
2755 return err; 2756 return err;
@@ -2764,8 +2765,9 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci,
2764 /* 2nd port used */ 2765 /* 2nd port used */
2765 err = snd_mpu401_uart_new(card, 1, MPU401_HW_ICE1712, 2766 err = snd_mpu401_uart_new(card, 1, MPU401_HW_ICE1712,
2766 ICEREG(ice, MPU2_CTRL), 2767 ICEREG(ice, MPU2_CTRL),
2767 (c->mpu401_2_info_flags | MPU401_INFO_INTEGRATED), 2768 c->mpu401_2_info_flags |
2768 ice->irq, 0, &ice->rmidi[1]); 2769 MPU401_INFO_INTEGRATED | MPU401_INFO_IRQ_HOOK,
2770 -1, &ice->rmidi[1]);
2769 2771
2770 if (err < 0) { 2772 if (err < 0) {
2771 snd_card_free(card); 2773 snd_card_free(card);
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index 0378126e627..2fd4bf2d665 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -2820,8 +2820,8 @@ snd_m3_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
2820 /* TODO enable MIDI IRQ and I/O */ 2820 /* TODO enable MIDI IRQ and I/O */
2821 err = snd_mpu401_uart_new(chip->card, 0, MPU401_HW_MPU401, 2821 err = snd_mpu401_uart_new(chip->card, 0, MPU401_HW_MPU401,
2822 chip->iobase + MPU401_DATA_PORT, 2822 chip->iobase + MPU401_DATA_PORT,
2823 MPU401_INFO_INTEGRATED, 2823 MPU401_INFO_INTEGRATED | MPU401_INFO_IRQ_HOOK,
2824 chip->irq, 0, &chip->rmidi); 2824 -1, &chip->rmidi);
2825 if (err < 0) 2825 if (err < 0)
2826 printk(KERN_WARNING "maestro3: no MIDI support.\n"); 2826 printk(KERN_WARNING "maestro3: no MIDI support.\n");
2827#endif 2827#endif
diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c
index 82311fcb86f..53e5508abcb 100644
--- a/sound/pci/oxygen/oxygen_lib.c
+++ b/sound/pci/oxygen/oxygen_lib.c
@@ -678,15 +678,15 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
678 goto err_card; 678 goto err_card;
679 679
680 if (chip->model.device_config & (MIDI_OUTPUT | MIDI_INPUT)) { 680 if (chip->model.device_config & (MIDI_OUTPUT | MIDI_INPUT)) {
681 unsigned int info_flags = MPU401_INFO_INTEGRATED; 681 unsigned int info_flags =
682 MPU401_INFO_INTEGRATED | MPU401_INFO_IRQ_HOOK;
682 if (chip->model.device_config & MIDI_OUTPUT) 683 if (chip->model.device_config & MIDI_OUTPUT)
683 info_flags |= MPU401_INFO_OUTPUT; 684 info_flags |= MPU401_INFO_OUTPUT;
684 if (chip->model.device_config & MIDI_INPUT) 685 if (chip->model.device_config & MIDI_INPUT)
685 info_flags |= MPU401_INFO_INPUT; 686 info_flags |= MPU401_INFO_INPUT;
686 err = snd_mpu401_uart_new(card, 0, MPU401_HW_CMIPCI, 687 err = snd_mpu401_uart_new(card, 0, MPU401_HW_CMIPCI,
687 chip->addr + OXYGEN_MPU401, 688 chip->addr + OXYGEN_MPU401,
688 info_flags, 0, 0, 689 info_flags, -1, &chip->midi);
689 &chip->midi);
690 if (err < 0) 690 if (err < 0)
691 goto err_card; 691 goto err_card;
692 } 692 }
diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c
index 32d096c98f5..8433aa7c3d7 100644
--- a/sound/pci/oxygen/xonar_pcm179x.c
+++ b/sound/pci/oxygen/xonar_pcm179x.c
@@ -1074,6 +1074,7 @@ static const struct oxygen_model model_xonar_st = {
1074 .device_config = PLAYBACK_0_TO_I2S | 1074 .device_config = PLAYBACK_0_TO_I2S |
1075 PLAYBACK_1_TO_SPDIF | 1075 PLAYBACK_1_TO_SPDIF |
1076 CAPTURE_0_FROM_I2S_2 | 1076 CAPTURE_0_FROM_I2S_2 |
1077 CAPTURE_1_FROM_SPDIF |
1077 AC97_FMIC_SWITCH, 1078 AC97_FMIC_SWITCH,
1078 .dac_channels_pcm = 2, 1079 .dac_channels_pcm = 2,
1079 .dac_channels_mixer = 2, 1080 .dac_channels_mixer = 2,
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c
index e34ae14908b..88cc776aa38 100644
--- a/sound/pci/riptide/riptide.c
+++ b/sound/pci/riptide/riptide.c
@@ -2109,7 +2109,7 @@ snd_card_riptide_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
2109 val = mpu_port[dev]; 2109 val = mpu_port[dev];
2110 pci_write_config_word(chip->pci, PCI_EXT_MPU_Base, val); 2110 pci_write_config_word(chip->pci, PCI_EXT_MPU_Base, val);
2111 err = snd_mpu401_uart_new(card, 0, MPU401_HW_RIPTIDE, 2111 err = snd_mpu401_uart_new(card, 0, MPU401_HW_RIPTIDE,
2112 val, 0, chip->irq, 0, 2112 val, MPU401_INFO_IRQ_HOOK, -1,
2113 &chip->rmidi); 2113 &chip->rmidi);
2114 if (err < 0) 2114 if (err < 0)
2115 snd_printk(KERN_WARNING 2115 snd_printk(KERN_WARNING
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index 493e3946756..6e2f7ef7ddb 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -1241,10 +1241,30 @@ static int hdspm_external_sample_rate(struct hdspm *hdspm)
1241 return rate; 1241 return rate;
1242} 1242}
1243 1243
1244/* return latency in samples per period */
1245static int hdspm_get_latency(struct hdspm *hdspm)
1246{
1247 int n;
1248
1249 n = hdspm_decode_latency(hdspm->control_register);
1250
1251 /* Special case for new RME cards with 32 samples period size.
1252 * The three latency bits in the control register
1253 * (HDSP_LatencyMask) encode latency values of 64 samples as
1254 * 0, 128 samples as 1 ... 4096 samples as 6. For old cards, 7
1255 * denotes 8192 samples, but on new cards like RayDAT or AIO,
1256 * it corresponds to 32 samples.
1257 */
1258 if ((7 == n) && (RayDAT == hdspm->io_type || AIO == hdspm->io_type))
1259 n = -1;
1260
1261 return 1 << (n + 6);
1262}
1263
1244/* Latency function */ 1264/* Latency function */
1245static inline void hdspm_compute_period_size(struct hdspm *hdspm) 1265static inline void hdspm_compute_period_size(struct hdspm *hdspm)
1246{ 1266{
1247 hdspm->period_bytes = 1 << ((hdspm_decode_latency(hdspm->control_register) + 8)); 1267 hdspm->period_bytes = 4 * hdspm_get_latency(hdspm);
1248} 1268}
1249 1269
1250 1270
@@ -1303,12 +1323,27 @@ static int hdspm_set_interrupt_interval(struct hdspm *s, unsigned int frames)
1303 1323
1304 spin_lock_irq(&s->lock); 1324 spin_lock_irq(&s->lock);
1305 1325
1306 frames >>= 7; 1326 if (32 == frames) {
1307 n = 0; 1327 /* Special case for new RME cards like RayDAT/AIO which
1308 while (frames) { 1328 * support period sizes of 32 samples. Since latency is
1309 n++; 1329 * encoded in the three bits of HDSP_LatencyMask, we can only
1310 frames >>= 1; 1330 * have values from 0 .. 7. While 0 still means 64 samples and
1331 * 6 represents 4096 samples on all cards, 7 represents 8192
1332 * on older cards and 32 samples on new cards.
1333 *
1334 * In other words, period size in samples is calculated by
1335 * 2^(n+6) with n ranging from 0 .. 7.
1336 */
1337 n = 7;
1338 } else {
1339 frames >>= 7;
1340 n = 0;
1341 while (frames) {
1342 n++;
1343 frames >>= 1;
1344 }
1311 } 1345 }
1346
1312 s->control_register &= ~HDSPM_LatencyMask; 1347 s->control_register &= ~HDSPM_LatencyMask;
1313 s->control_register |= hdspm_encode_latency(n); 1348 s->control_register |= hdspm_encode_latency(n);
1314 1349
@@ -4801,8 +4836,7 @@ snd_hdspm_proc_read_madi(struct snd_info_entry * entry,
4801 4836
4802 snd_iprintf(buffer, "--- Settings ---\n"); 4837 snd_iprintf(buffer, "--- Settings ---\n");
4803 4838
4804 x = 1 << (6 + hdspm_decode_latency(hdspm->control_register & 4839 x = hdspm_get_latency(hdspm);
4805 HDSPM_LatencyMask));
4806 4840
4807 snd_iprintf(buffer, 4841 snd_iprintf(buffer,
4808 "Size (Latency): %d samples (2 periods of %lu bytes)\n", 4842 "Size (Latency): %d samples (2 periods of %lu bytes)\n",
@@ -4965,8 +4999,7 @@ snd_hdspm_proc_read_aes32(struct snd_info_entry * entry,
4965 4999
4966 snd_iprintf(buffer, "--- Settings ---\n"); 5000 snd_iprintf(buffer, "--- Settings ---\n");
4967 5001
4968 x = 1 << (6 + hdspm_decode_latency(hdspm->control_register & 5002 x = hdspm_get_latency(hdspm);
4969 HDSPM_LatencyMask));
4970 5003
4971 snd_iprintf(buffer, 5004 snd_iprintf(buffer,
4972 "Size (Latency): %d samples (2 periods of %lu bytes)\n", 5005 "Size (Latency): %d samples (2 periods of %lu bytes)\n",
@@ -5672,19 +5705,6 @@ static int snd_hdspm_prepare(struct snd_pcm_substream *substream)
5672 return 0; 5705 return 0;
5673} 5706}
5674 5707
5675static unsigned int period_sizes_old[] = {
5676 64, 128, 256, 512, 1024, 2048, 4096
5677};
5678
5679static unsigned int period_sizes_new[] = {
5680 32, 64, 128, 256, 512, 1024, 2048, 4096
5681};
5682
5683/* RayDAT and AIO always have a buffer of 16384 samples per channel */
5684static unsigned int raydat_aio_buffer_sizes[] = {
5685 16384
5686};
5687
5688static struct snd_pcm_hardware snd_hdspm_playback_subinfo = { 5708static struct snd_pcm_hardware snd_hdspm_playback_subinfo = {
5689 .info = (SNDRV_PCM_INFO_MMAP | 5709 .info = (SNDRV_PCM_INFO_MMAP |
5690 SNDRV_PCM_INFO_MMAP_VALID | 5710 SNDRV_PCM_INFO_MMAP_VALID |
@@ -5703,8 +5723,8 @@ static struct snd_pcm_hardware snd_hdspm_playback_subinfo = {
5703 .channels_max = HDSPM_MAX_CHANNELS, 5723 .channels_max = HDSPM_MAX_CHANNELS,
5704 .buffer_bytes_max = 5724 .buffer_bytes_max =
5705 HDSPM_CHANNEL_BUFFER_BYTES * HDSPM_MAX_CHANNELS, 5725 HDSPM_CHANNEL_BUFFER_BYTES * HDSPM_MAX_CHANNELS,
5706 .period_bytes_min = (64 * 4), 5726 .period_bytes_min = (32 * 4),
5707 .period_bytes_max = (4096 * 4) * HDSPM_MAX_CHANNELS, 5727 .period_bytes_max = (8192 * 4) * HDSPM_MAX_CHANNELS,
5708 .periods_min = 2, 5728 .periods_min = 2,
5709 .periods_max = 512, 5729 .periods_max = 512,
5710 .fifo_size = 0 5730 .fifo_size = 0
@@ -5728,31 +5748,13 @@ static struct snd_pcm_hardware snd_hdspm_capture_subinfo = {
5728 .channels_max = HDSPM_MAX_CHANNELS, 5748 .channels_max = HDSPM_MAX_CHANNELS,
5729 .buffer_bytes_max = 5749 .buffer_bytes_max =
5730 HDSPM_CHANNEL_BUFFER_BYTES * HDSPM_MAX_CHANNELS, 5750 HDSPM_CHANNEL_BUFFER_BYTES * HDSPM_MAX_CHANNELS,
5731 .period_bytes_min = (64 * 4), 5751 .period_bytes_min = (32 * 4),
5732 .period_bytes_max = (4096 * 4) * HDSPM_MAX_CHANNELS, 5752 .period_bytes_max = (8192 * 4) * HDSPM_MAX_CHANNELS,
5733 .periods_min = 2, 5753 .periods_min = 2,
5734 .periods_max = 512, 5754 .periods_max = 512,
5735 .fifo_size = 0 5755 .fifo_size = 0
5736}; 5756};
5737 5757
5738static struct snd_pcm_hw_constraint_list hw_constraints_period_sizes_old = {
5739 .count = ARRAY_SIZE(period_sizes_old),
5740 .list = period_sizes_old,
5741 .mask = 0
5742};
5743
5744static struct snd_pcm_hw_constraint_list hw_constraints_period_sizes_new = {
5745 .count = ARRAY_SIZE(period_sizes_new),
5746 .list = period_sizes_new,
5747 .mask = 0
5748};
5749
5750static struct snd_pcm_hw_constraint_list hw_constraints_raydat_io_buffer = {
5751 .count = ARRAY_SIZE(raydat_aio_buffer_sizes),
5752 .list = raydat_aio_buffer_sizes,
5753 .mask = 0
5754};
5755
5756static int snd_hdspm_hw_rule_in_channels_rate(struct snd_pcm_hw_params *params, 5758static int snd_hdspm_hw_rule_in_channels_rate(struct snd_pcm_hw_params *params,
5757 struct snd_pcm_hw_rule *rule) 5759 struct snd_pcm_hw_rule *rule)
5758{ 5760{
@@ -5953,26 +5955,29 @@ static int snd_hdspm_playback_open(struct snd_pcm_substream *substream)
5953 spin_unlock_irq(&hdspm->lock); 5955 spin_unlock_irq(&hdspm->lock);
5954 5956
5955 snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); 5957 snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
5958 snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
5956 5959
5957 switch (hdspm->io_type) { 5960 switch (hdspm->io_type) {
5958 case AIO: 5961 case AIO:
5959 case RayDAT: 5962 case RayDAT:
5960 snd_pcm_hw_constraint_list(runtime, 0, 5963 snd_pcm_hw_constraint_minmax(runtime,
5961 SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 5964 SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
5962 &hw_constraints_period_sizes_new); 5965 32, 4096);
5963 snd_pcm_hw_constraint_list(runtime, 0, 5966 /* RayDAT & AIO have a fixed buffer of 16384 samples per channel */
5964 SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 5967 snd_pcm_hw_constraint_minmax(runtime,
5965 &hw_constraints_raydat_io_buffer); 5968 SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
5966 5969 16384, 16384);
5967 break; 5970 break;
5968 5971
5969 default: 5972 default:
5970 snd_pcm_hw_constraint_list(runtime, 0, 5973 snd_pcm_hw_constraint_minmax(runtime,
5971 SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 5974 SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
5972 &hw_constraints_period_sizes_old); 5975 64, 8192);
5976 break;
5973 } 5977 }
5974 5978
5975 if (AES32 == hdspm->io_type) { 5979 if (AES32 == hdspm->io_type) {
5980 runtime->hw.rates |= SNDRV_PCM_RATE_KNOT;
5976 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 5981 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
5977 &hdspm_hw_constraints_aes32_sample_rates); 5982 &hdspm_hw_constraints_aes32_sample_rates);
5978 } else { 5983 } else {
@@ -6025,24 +6030,28 @@ static int snd_hdspm_capture_open(struct snd_pcm_substream *substream)
6025 spin_unlock_irq(&hdspm->lock); 6030 spin_unlock_irq(&hdspm->lock);
6026 6031
6027 snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); 6032 snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
6033 snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
6034
6028 switch (hdspm->io_type) { 6035 switch (hdspm->io_type) {
6029 case AIO: 6036 case AIO:
6030 case RayDAT: 6037 case RayDAT:
6031 snd_pcm_hw_constraint_list(runtime, 0, 6038 snd_pcm_hw_constraint_minmax(runtime,
6032 SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 6039 SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
6033 &hw_constraints_period_sizes_new); 6040 32, 4096);
6034 snd_pcm_hw_constraint_list(runtime, 0, 6041 snd_pcm_hw_constraint_minmax(runtime,
6035 SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 6042 SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
6036 &hw_constraints_raydat_io_buffer); 6043 16384, 16384);
6037 break; 6044 break;
6038 6045
6039 default: 6046 default:
6040 snd_pcm_hw_constraint_list(runtime, 0, 6047 snd_pcm_hw_constraint_minmax(runtime,
6041 SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 6048 SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
6042 &hw_constraints_period_sizes_old); 6049 64, 8192);
6050 break;
6043 } 6051 }
6044 6052
6045 if (AES32 == hdspm->io_type) { 6053 if (AES32 == hdspm->io_type) {
6054 runtime->hw.rates |= SNDRV_PCM_RATE_KNOT;
6046 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 6055 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
6047 &hdspm_hw_constraints_aes32_sample_rates); 6056 &hdspm_hw_constraints_aes32_sample_rates);
6048 } else { 6057 } else {
@@ -6088,7 +6097,7 @@ static inline int copy_u32_le(void __user *dest, void __iomem *src)
6088} 6097}
6089 6098
6090static int snd_hdspm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, 6099static int snd_hdspm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
6091 unsigned int cmd, unsigned long __user arg) 6100 unsigned int cmd, unsigned long arg)
6092{ 6101{
6093 void __user *argp = (void __user *)arg; 6102 void __user *argp = (void __user *)arg;
6094 struct hdspm *hdspm = hw->private_data; 6103 struct hdspm *hdspm = hw->private_data;
@@ -6213,11 +6222,13 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
6213 info.line_out = hdspm_line_out(hdspm); 6222 info.line_out = hdspm_line_out(hdspm);
6214 info.passthru = 0; 6223 info.passthru = 0;
6215 spin_unlock_irq(&hdspm->lock); 6224 spin_unlock_irq(&hdspm->lock);
6216 if (copy_to_user((void __user *) arg, &info, sizeof(info))) 6225 if (copy_to_user(argp, &info, sizeof(info)))
6217 return -EFAULT; 6226 return -EFAULT;
6218 break; 6227 break;
6219 6228
6220 case SNDRV_HDSPM_IOCTL_GET_STATUS: 6229 case SNDRV_HDSPM_IOCTL_GET_STATUS:
6230 memset(&status, 0, sizeof(status));
6231
6221 status.card_type = hdspm->io_type; 6232 status.card_type = hdspm->io_type;
6222 6233
6223 status.autosync_source = hdspm_autosync_ref(hdspm); 6234 status.autosync_source = hdspm_autosync_ref(hdspm);
@@ -6250,13 +6261,15 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
6250 break; 6261 break;
6251 } 6262 }
6252 6263
6253 if (copy_to_user((void __user *) arg, &status, sizeof(status))) 6264 if (copy_to_user(argp, &status, sizeof(status)))
6254 return -EFAULT; 6265 return -EFAULT;
6255 6266
6256 6267
6257 break; 6268 break;
6258 6269
6259 case SNDRV_HDSPM_IOCTL_GET_VERSION: 6270 case SNDRV_HDSPM_IOCTL_GET_VERSION:
6271 memset(&hdspm_version, 0, sizeof(hdspm_version));
6272
6260 hdspm_version.card_type = hdspm->io_type; 6273 hdspm_version.card_type = hdspm->io_type;
6261 strncpy(hdspm_version.cardname, hdspm->card_name, 6274 strncpy(hdspm_version.cardname, hdspm->card_name,
6262 sizeof(hdspm_version.cardname)); 6275 sizeof(hdspm_version.cardname));
@@ -6267,13 +6280,13 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
6267 if (hdspm->tco) 6280 if (hdspm->tco)
6268 hdspm_version.addons |= HDSPM_ADDON_TCO; 6281 hdspm_version.addons |= HDSPM_ADDON_TCO;
6269 6282
6270 if (copy_to_user((void __user *) arg, &hdspm_version, 6283 if (copy_to_user(argp, &hdspm_version,
6271 sizeof(hdspm_version))) 6284 sizeof(hdspm_version)))
6272 return -EFAULT; 6285 return -EFAULT;
6273 break; 6286 break;
6274 6287
6275 case SNDRV_HDSPM_IOCTL_GET_MIXER: 6288 case SNDRV_HDSPM_IOCTL_GET_MIXER:
6276 if (copy_from_user(&mixer, (void __user *)arg, sizeof(mixer))) 6289 if (copy_from_user(&mixer, argp, sizeof(mixer)))
6277 return -EFAULT; 6290 return -EFAULT;
6278 if (copy_to_user((void __user *)mixer.mixer, hdspm->mixer, 6291 if (copy_to_user((void __user *)mixer.mixer, hdspm->mixer,
6279 sizeof(struct hdspm_mixer))) 6292 sizeof(struct hdspm_mixer)))
diff --git a/sound/pci/sis7019.c b/sound/pci/sis7019.c
index bcf61524a13..5ffb20b1878 100644
--- a/sound/pci/sis7019.c
+++ b/sound/pci/sis7019.c
@@ -1234,7 +1234,7 @@ static int sis_resume(struct pci_dev *pci)
1234 goto error; 1234 goto error;
1235 } 1235 }
1236 1236
1237 if (request_irq(pci->irq, sis_interrupt, IRQF_DISABLED|IRQF_SHARED, 1237 if (request_irq(pci->irq, sis_interrupt, IRQF_SHARED,
1238 KBUILD_MODNAME, sis)) { 1238 KBUILD_MODNAME, sis)) {
1239 printk(KERN_ERR "sis7019: unable to regain IRQ %d\n", pci->irq); 1239 printk(KERN_ERR "sis7019: unable to regain IRQ %d\n", pci->irq);
1240 goto error; 1240 goto error;
@@ -1340,7 +1340,7 @@ static int __devinit sis_chip_create(struct snd_card *card,
1340 if (rc) 1340 if (rc)
1341 goto error_out_cleanup; 1341 goto error_out_cleanup;
1342 1342
1343 if (request_irq(pci->irq, sis_interrupt, IRQF_DISABLED|IRQF_SHARED, 1343 if (request_irq(pci->irq, sis_interrupt, IRQF_SHARED,
1344 KBUILD_MODNAME, sis)) { 1344 KBUILD_MODNAME, sis)) {
1345 printk(KERN_ERR "unable to allocate irq %d\n", sis->irq); 1345 printk(KERN_ERR "unable to allocate irq %d\n", sis->irq);
1346 goto error_out_cleanup; 1346 goto error_out_cleanup;
diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c
index 2571a67b389..c5008166cf1 100644
--- a/sound/pci/sonicvibes.c
+++ b/sound/pci/sonicvibes.c
@@ -1493,9 +1493,10 @@ static int __devinit snd_sonic_probe(struct pci_dev *pci,
1493 return err; 1493 return err;
1494 } 1494 }
1495 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_SONICVIBES, 1495 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_SONICVIBES,
1496 sonic->midi_port, MPU401_INFO_INTEGRATED, 1496 sonic->midi_port,
1497 sonic->irq, 0, 1497 MPU401_INFO_INTEGRATED |
1498 &midi_uart)) < 0) { 1498 MPU401_INFO_IRQ_HOOK,
1499 -1, &midi_uart)) < 0) {
1499 snd_card_free(card); 1500 snd_card_free(card);
1500 return err; 1501 return err;
1501 } 1502 }
diff --git a/sound/pci/trident/trident.c b/sound/pci/trident/trident.c
index d8a128f6fc0..5e707effdc7 100644
--- a/sound/pci/trident/trident.c
+++ b/sound/pci/trident/trident.c
@@ -148,8 +148,9 @@ static int __devinit snd_trident_probe(struct pci_dev *pci,
148 if (trident->device != TRIDENT_DEVICE_ID_SI7018 && 148 if (trident->device != TRIDENT_DEVICE_ID_SI7018 &&
149 (err = snd_mpu401_uart_new(card, 0, MPU401_HW_TRID4DWAVE, 149 (err = snd_mpu401_uart_new(card, 0, MPU401_HW_TRID4DWAVE,
150 trident->midi_port, 150 trident->midi_port,
151 MPU401_INFO_INTEGRATED, 151 MPU401_INFO_INTEGRATED |
152 trident->irq, 0, &trident->rmidi)) < 0) { 152 MPU401_INFO_IRQ_HOOK,
153 -1, &trident->rmidi)) < 0) {
153 snd_card_free(card); 154 snd_card_free(card);
154 return err; 155 return err;
155 } 156 }
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index f03fd620a2a..c3656fffdb5 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -1175,6 +1175,7 @@ static int snd_via82xx_pcm_open(struct via82xx *chip, struct viadev *viadev,
1175 struct snd_pcm_runtime *runtime = substream->runtime; 1175 struct snd_pcm_runtime *runtime = substream->runtime;
1176 int err; 1176 int err;
1177 struct via_rate_lock *ratep; 1177 struct via_rate_lock *ratep;
1178 bool use_src = false;
1178 1179
1179 runtime->hw = snd_via82xx_hw; 1180 runtime->hw = snd_via82xx_hw;
1180 1181
@@ -1196,6 +1197,7 @@ static int snd_via82xx_pcm_open(struct via82xx *chip, struct viadev *viadev,
1196 SNDRV_PCM_RATE_8000_48000); 1197 SNDRV_PCM_RATE_8000_48000);
1197 runtime->hw.rate_min = 8000; 1198 runtime->hw.rate_min = 8000;
1198 runtime->hw.rate_max = 48000; 1199 runtime->hw.rate_max = 48000;
1200 use_src = true;
1199 } else if (! ratep->rate) { 1201 } else if (! ratep->rate) {
1200 int idx = viadev->direction ? AC97_RATES_ADC : AC97_RATES_FRONT_DAC; 1202 int idx = viadev->direction ? AC97_RATES_ADC : AC97_RATES_FRONT_DAC;
1201 runtime->hw.rates = chip->ac97->rates[idx]; 1203 runtime->hw.rates = chip->ac97->rates[idx];
@@ -1212,6 +1214,12 @@ static int snd_via82xx_pcm_open(struct via82xx *chip, struct viadev *viadev,
1212 if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0) 1214 if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
1213 return err; 1215 return err;
1214 1216
1217 if (use_src) {
1218 err = snd_pcm_hw_rule_noresample(runtime, 48000);
1219 if (err < 0)
1220 return err;
1221 }
1222
1215 runtime->private_data = viadev; 1223 runtime->private_data = viadev;
1216 viadev->substream = substream; 1224 viadev->substream = substream;
1217 1225
@@ -2068,8 +2076,9 @@ static int __devinit snd_via686_init_misc(struct via82xx *chip)
2068 pci_write_config_byte(chip->pci, VIA_PNP_CONTROL, legacy_cfg); 2076 pci_write_config_byte(chip->pci, VIA_PNP_CONTROL, legacy_cfg);
2069 if (chip->mpu_res) { 2077 if (chip->mpu_res) {
2070 if (snd_mpu401_uart_new(chip->card, 0, MPU401_HW_VIA686A, 2078 if (snd_mpu401_uart_new(chip->card, 0, MPU401_HW_VIA686A,
2071 mpu_port, MPU401_INFO_INTEGRATED, 2079 mpu_port, MPU401_INFO_INTEGRATED |
2072 chip->irq, 0, &chip->rmidi) < 0) { 2080 MPU401_INFO_IRQ_HOOK, -1,
2081 &chip->rmidi) < 0) {
2073 printk(KERN_WARNING "unable to initialize MPU-401" 2082 printk(KERN_WARNING "unable to initialize MPU-401"
2074 " at 0x%lx, skipping\n", mpu_port); 2083 " at 0x%lx, skipping\n", mpu_port);
2075 legacy &= ~VIA_FUNC_ENABLE_MIDI; 2084 legacy &= ~VIA_FUNC_ENABLE_MIDI;
diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c
index 511d5765312..3253b04da18 100644
--- a/sound/pci/ymfpci/ymfpci.c
+++ b/sound/pci/ymfpci/ymfpci.c
@@ -305,8 +305,9 @@ static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci,
305 if (chip->mpu_res) { 305 if (chip->mpu_res) {
306 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_YMFPCI, 306 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_YMFPCI,
307 mpu_port[dev], 307 mpu_port[dev],
308 MPU401_INFO_INTEGRATED, 308 MPU401_INFO_INTEGRATED |
309 pci->irq, 0, &chip->rawmidi)) < 0) { 309 MPU401_INFO_IRQ_HOOK,
310 -1, &chip->rawmidi)) < 0) {
310 printk(KERN_WARNING "ymfpci: cannot initialize MPU401 at 0x%lx, skipping...\n", mpu_port[dev]); 311 printk(KERN_WARNING "ymfpci: cannot initialize MPU401 at 0x%lx, skipping...\n", mpu_port[dev]);
311 legacy_ctrl &= ~YMFPCI_LEGACY_MIEN; /* disable MPU401 irq */ 312 legacy_ctrl &= ~YMFPCI_LEGACY_MIEN; /* disable MPU401 irq */
312 pci_write_config_word(pci, PCIR_DSXG_LEGACY, legacy_ctrl); 313 pci_write_config_word(pci, PCIR_DSXG_LEGACY, legacy_ctrl);
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
index f3260e658b8..66ea71b2a70 100644
--- a/sound/pci/ymfpci/ymfpci_main.c
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -897,6 +897,18 @@ static int snd_ymfpci_playback_open_1(struct snd_pcm_substream *substream)
897 struct snd_ymfpci *chip = snd_pcm_substream_chip(substream); 897 struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);
898 struct snd_pcm_runtime *runtime = substream->runtime; 898 struct snd_pcm_runtime *runtime = substream->runtime;
899 struct snd_ymfpci_pcm *ypcm; 899 struct snd_ymfpci_pcm *ypcm;
900 int err;
901
902 runtime->hw = snd_ymfpci_playback;
903 /* FIXME? True value is 256/48 = 5.33333 ms */
904 err = snd_pcm_hw_constraint_minmax(runtime,
905 SNDRV_PCM_HW_PARAM_PERIOD_TIME,
906 5334, UINT_MAX);
907 if (err < 0)
908 return err;
909 err = snd_pcm_hw_rule_noresample(runtime, 48000);
910 if (err < 0)
911 return err;
900 912
901 ypcm = kzalloc(sizeof(*ypcm), GFP_KERNEL); 913 ypcm = kzalloc(sizeof(*ypcm), GFP_KERNEL);
902 if (ypcm == NULL) 914 if (ypcm == NULL)
@@ -904,11 +916,8 @@ static int snd_ymfpci_playback_open_1(struct snd_pcm_substream *substream)
904 ypcm->chip = chip; 916 ypcm->chip = chip;
905 ypcm->type = PLAYBACK_VOICE; 917 ypcm->type = PLAYBACK_VOICE;
906 ypcm->substream = substream; 918 ypcm->substream = substream;
907 runtime->hw = snd_ymfpci_playback;
908 runtime->private_data = ypcm; 919 runtime->private_data = ypcm;
909 runtime->private_free = snd_ymfpci_pcm_free_substream; 920 runtime->private_free = snd_ymfpci_pcm_free_substream;
910 /* FIXME? True value is 256/48 = 5.33333 ms */
911 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, 5333, UINT_MAX);
912 return 0; 921 return 0;
913} 922}
914 923
@@ -1013,6 +1022,18 @@ static int snd_ymfpci_capture_open(struct snd_pcm_substream *substream,
1013 struct snd_ymfpci *chip = snd_pcm_substream_chip(substream); 1022 struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);
1014 struct snd_pcm_runtime *runtime = substream->runtime; 1023 struct snd_pcm_runtime *runtime = substream->runtime;
1015 struct snd_ymfpci_pcm *ypcm; 1024 struct snd_ymfpci_pcm *ypcm;
1025 int err;
1026
1027 runtime->hw = snd_ymfpci_capture;
1028 /* FIXME? True value is 256/48 = 5.33333 ms */
1029 err = snd_pcm_hw_constraint_minmax(runtime,
1030 SNDRV_PCM_HW_PARAM_PERIOD_TIME,
1031 5334, UINT_MAX);
1032 if (err < 0)
1033 return err;
1034 err = snd_pcm_hw_rule_noresample(runtime, 48000);
1035 if (err < 0)
1036 return err;
1016 1037
1017 ypcm = kzalloc(sizeof(*ypcm), GFP_KERNEL); 1038 ypcm = kzalloc(sizeof(*ypcm), GFP_KERNEL);
1018 if (ypcm == NULL) 1039 if (ypcm == NULL)
@@ -1022,9 +1043,6 @@ static int snd_ymfpci_capture_open(struct snd_pcm_substream *substream,
1022 ypcm->substream = substream; 1043 ypcm->substream = substream;
1023 ypcm->capture_bank_number = capture_bank_number; 1044 ypcm->capture_bank_number = capture_bank_number;
1024 chip->capture_substream[capture_bank_number] = substream; 1045 chip->capture_substream[capture_bank_number] = substream;
1025 runtime->hw = snd_ymfpci_capture;
1026 /* FIXME? True value is 256/48 = 5.33333 ms */
1027 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, 5333, UINT_MAX);
1028 runtime->private_data = ypcm; 1046 runtime->private_data = ypcm;
1029 runtime->private_free = snd_ymfpci_pcm_free_substream; 1047 runtime->private_free = snd_ymfpci_pcm_free_substream;
1030 snd_ymfpci_hw_start(chip); 1048 snd_ymfpci_hw_start(chip);
@@ -1615,7 +1633,7 @@ YMFPCI_DOUBLE("ADC Playback Volume", 0, YDSXGR_PRIADCOUTVOL),
1615YMFPCI_DOUBLE("ADC Capture Volume", 0, YDSXGR_PRIADCLOOPVOL), 1633YMFPCI_DOUBLE("ADC Capture Volume", 0, YDSXGR_PRIADCLOOPVOL),
1616YMFPCI_DOUBLE("ADC Playback Volume", 1, YDSXGR_SECADCOUTVOL), 1634YMFPCI_DOUBLE("ADC Playback Volume", 1, YDSXGR_SECADCOUTVOL),
1617YMFPCI_DOUBLE("ADC Capture Volume", 1, YDSXGR_SECADCLOOPVOL), 1635YMFPCI_DOUBLE("ADC Capture Volume", 1, YDSXGR_SECADCLOOPVOL),
1618YMFPCI_DOUBLE("FM Legacy Volume", 0, YDSXGR_LEGACYOUTVOL), 1636YMFPCI_DOUBLE("FM Legacy Playback Volume", 0, YDSXGR_LEGACYOUTVOL),
1619YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("AC97 ", PLAYBACK,VOLUME), 0, YDSXGR_ZVOUTVOL), 1637YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("AC97 ", PLAYBACK,VOLUME), 0, YDSXGR_ZVOUTVOL),
1620YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("", CAPTURE,VOLUME), 0, YDSXGR_ZVLOOPVOL), 1638YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("", CAPTURE,VOLUME), 0, YDSXGR_ZVLOOPVOL),
1621YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("AC97 ",PLAYBACK,VOLUME), 1, YDSXGR_SPDIFOUTVOL), 1639YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("AC97 ",PLAYBACK,VOLUME), 1, YDSXGR_SPDIFOUTVOL),
diff --git a/sound/ppc/keywest.c b/sound/ppc/keywest.c
index 8f064c7ce74..4080becf4ce 100644
--- a/sound/ppc/keywest.c
+++ b/sound/ppc/keywest.c
@@ -82,7 +82,6 @@ static int keywest_attach_adapter(struct i2c_adapter *adapter)
82 82
83static int keywest_remove(struct i2c_client *client) 83static int keywest_remove(struct i2c_client *client)
84{ 84{
85 i2c_set_clientdata(client, NULL);
86 if (! keywest_ctx) 85 if (! keywest_ctx)
87 return 0; 86 return 0;
88 if (client == keywest_ctx->client) 87 if (client == keywest_ctx->client)
diff --git a/sound/ppc/snd_ps3.c b/sound/ppc/snd_ps3.c
index bc823a54755..775bd95d4be 100644
--- a/sound/ppc/snd_ps3.c
+++ b/sound/ppc/snd_ps3.c
@@ -845,7 +845,7 @@ static int __devinit snd_ps3_allocate_irq(void)
845 return ret; 845 return ret;
846 } 846 }
847 847
848 ret = request_irq(the_card.irq_no, snd_ps3_interrupt, IRQF_DISABLED, 848 ret = request_irq(the_card.irq_no, snd_ps3_interrupt, 0,
849 SND_PS3_DRIVER_NAME, &the_card); 849 SND_PS3_DRIVER_NAME, &the_card);
850 if (ret) { 850 if (ret) {
851 pr_info("%s: request_irq failed (%d)\n", __func__, ret); 851 pr_info("%s: request_irq failed (%d)\n", __func__, ret);
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index 8224db5f043..1381db853ef 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -7,6 +7,8 @@ menuconfig SND_SOC
7 select SND_PCM 7 select SND_PCM
8 select AC97_BUS if SND_SOC_AC97_BUS 8 select AC97_BUS if SND_SOC_AC97_BUS
9 select SND_JACK if INPUT=y || INPUT=SND 9 select SND_JACK if INPUT=y || INPUT=SND
10 select REGMAP_I2C if I2C
11 select REGMAP_SPI if SPI_MASTER
10 ---help--- 12 ---help---
11 13
12 If you want ASoC support, you should say Y here and also to the 14 If you want ASoC support, you should say Y here and also to the
@@ -51,6 +53,7 @@ source "sound/soc/nuc900/Kconfig"
51source "sound/soc/omap/Kconfig" 53source "sound/soc/omap/Kconfig"
52source "sound/soc/kirkwood/Kconfig" 54source "sound/soc/kirkwood/Kconfig"
53source "sound/soc/mid-x86/Kconfig" 55source "sound/soc/mid-x86/Kconfig"
56source "sound/soc/mxs/Kconfig"
54source "sound/soc/pxa/Kconfig" 57source "sound/soc/pxa/Kconfig"
55source "sound/soc/samsung/Kconfig" 58source "sound/soc/samsung/Kconfig"
56source "sound/soc/s6000/Kconfig" 59source "sound/soc/s6000/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 4f913876f33..9ea8ac827ad 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_SND_SOC) += fsl/
12obj-$(CONFIG_SND_SOC) += imx/ 12obj-$(CONFIG_SND_SOC) += imx/
13obj-$(CONFIG_SND_SOC) += jz4740/ 13obj-$(CONFIG_SND_SOC) += jz4740/
14obj-$(CONFIG_SND_SOC) += mid-x86/ 14obj-$(CONFIG_SND_SOC) += mid-x86/
15obj-$(CONFIG_SND_SOC) += mxs/
15obj-$(CONFIG_SND_SOC) += nuc900/ 16obj-$(CONFIG_SND_SOC) += nuc900/
16obj-$(CONFIG_SND_SOC) += omap/ 17obj-$(CONFIG_SND_SOC) += omap/
17obj-$(CONFIG_SND_SOC) += kirkwood/ 18obj-$(CONFIG_SND_SOC) += kirkwood/
diff --git a/sound/soc/atmel/playpaq_wm8510.c b/sound/soc/atmel/playpaq_wm8510.c
index 1aac2f4dbcf..73ae99ad457 100644
--- a/sound/soc/atmel/playpaq_wm8510.c
+++ b/sound/soc/atmel/playpaq_wm8510.c
@@ -338,7 +338,6 @@ static int playpaq_wm8510_init(struct snd_soc_pcm_runtime *rtd)
338 /* always connected pins */ 338 /* always connected pins */
339 snd_soc_dapm_enable_pin(dapm, "Int Mic"); 339 snd_soc_dapm_enable_pin(dapm, "Int Mic");
340 snd_soc_dapm_enable_pin(dapm, "Ext Spk"); 340 snd_soc_dapm_enable_pin(dapm, "Ext Spk");
341 snd_soc_dapm_sync(dapm);
342 341
343 342
344 343
@@ -383,14 +382,17 @@ static int __init playpaq_asoc_init(void)
383 _gclk0 = clk_get(NULL, "gclk0"); 382 _gclk0 = clk_get(NULL, "gclk0");
384 if (IS_ERR(_gclk0)) { 383 if (IS_ERR(_gclk0)) {
385 _gclk0 = NULL; 384 _gclk0 = NULL;
385 ret = PTR_ERR(_gclk0);
386 goto err_gclk0; 386 goto err_gclk0;
387 } 387 }
388 _pll0 = clk_get(NULL, "pll0"); 388 _pll0 = clk_get(NULL, "pll0");
389 if (IS_ERR(_pll0)) { 389 if (IS_ERR(_pll0)) {
390 _pll0 = NULL; 390 _pll0 = NULL;
391 ret = PTR_ERR(_pll0);
391 goto err_pll0; 392 goto err_pll0;
392 } 393 }
393 if (clk_set_parent(_gclk0, _pll0)) { 394 ret = clk_set_parent(_gclk0, _pll0);
395 if (ret) {
394 pr_warning("snd-soc-playpaq: " 396 pr_warning("snd-soc-playpaq: "
395 "Failed to set PLL0 as parent for DAC clock\n"); 397 "Failed to set PLL0 as parent for DAC clock\n");
396 goto err_set_clk; 398 goto err_set_clk;
diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c
index bad3aa14d5b..0377c5451ae 100644
--- a/sound/soc/atmel/sam9g20_wm8731.c
+++ b/sound/soc/atmel/sam9g20_wm8731.c
@@ -173,8 +173,6 @@ static int at91sam9g20ek_wm8731_init(struct snd_soc_pcm_runtime *rtd)
173 /* always connected */ 173 /* always connected */
174 snd_soc_dapm_enable_pin(dapm, "Ext Spk"); 174 snd_soc_dapm_enable_pin(dapm, "Ext Spk");
175 175
176 snd_soc_dapm_sync(dapm);
177
178 return 0; 176 return 0;
179} 177}
180 178
diff --git a/sound/soc/atmel/snd-soc-afeb9260.c b/sound/soc/atmel/snd-soc-afeb9260.c
index 5e4d499d843..d427e9217ce 100644
--- a/sound/soc/atmel/snd-soc-afeb9260.c
+++ b/sound/soc/atmel/snd-soc-afeb9260.c
@@ -117,8 +117,6 @@ static int afeb9260_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd)
117 snd_soc_dapm_enable_pin(dapm, "Line In"); 117 snd_soc_dapm_enable_pin(dapm, "Line In");
118 snd_soc_dapm_enable_pin(dapm, "Mic Jack"); 118 snd_soc_dapm_enable_pin(dapm, "Mic Jack");
119 119
120 snd_soc_dapm_sync(dapm);
121
122 return 0; 120 return 0;
123} 121}
124 122
diff --git a/sound/soc/au1x/Kconfig b/sound/soc/au1x/Kconfig
index 4b67140fdec..6d592546e8f 100644
--- a/sound/soc/au1x/Kconfig
+++ b/sound/soc/au1x/Kconfig
@@ -18,10 +18,38 @@ config SND_SOC_AU1XPSC_AC97
18 select SND_AC97_CODEC 18 select SND_AC97_CODEC
19 select SND_SOC_AC97_BUS 19 select SND_SOC_AC97_BUS
20 20
21##
22## Au1000/1500/1100 DMA + AC97C/I2SC
23##
24config SND_SOC_AU1XAUDIO
25 tristate "SoC Audio for Au1000/Au1500/Au1100"
26 depends on MIPS_ALCHEMY
27 help
28 This is a driver set for the AC97 unit and the
29 old DMA controller as found on the Au1000/Au1500/Au1100 chips.
30
31config SND_SOC_AU1XAC97C
32 tristate
33 select AC97_BUS
34 select SND_AC97_CODEC
35 select SND_SOC_AC97_BUS
36
37config SND_SOC_AU1XI2SC
38 tristate
39
21 40
22## 41##
23## Boards 42## Boards
24## 43##
44config SND_SOC_DB1000
45 tristate "DB1000 Audio support"
46 depends on SND_SOC_AU1XAUDIO
47 select SND_SOC_AU1XAC97C
48 select SND_SOC_AC97_CODEC
49 help
50 Select this option to enable AC97 audio on the early DB1x00 series
51 of boards (DB1000/DB1500/DB1100).
52
25config SND_SOC_DB1200 53config SND_SOC_DB1200
26 tristate "DB1200 AC97+I2S audio support" 54 tristate "DB1200 AC97+I2S audio support"
27 depends on SND_SOC_AU1XPSC 55 depends on SND_SOC_AU1XPSC
diff --git a/sound/soc/au1x/Makefile b/sound/soc/au1x/Makefile
index 16873076e8c..920710514ea 100644
--- a/sound/soc/au1x/Makefile
+++ b/sound/soc/au1x/Makefile
@@ -3,11 +3,21 @@ snd-soc-au1xpsc-dbdma-objs := dbdma2.o
3snd-soc-au1xpsc-i2s-objs := psc-i2s.o 3snd-soc-au1xpsc-i2s-objs := psc-i2s.o
4snd-soc-au1xpsc-ac97-objs := psc-ac97.o 4snd-soc-au1xpsc-ac97-objs := psc-ac97.o
5 5
6# Au1000/1500/1100 Audio units
7snd-soc-au1x-dma-objs := dma.o
8snd-soc-au1x-ac97c-objs := ac97c.o
9snd-soc-au1x-i2sc-objs := i2sc.o
10
6obj-$(CONFIG_SND_SOC_AU1XPSC) += snd-soc-au1xpsc-dbdma.o 11obj-$(CONFIG_SND_SOC_AU1XPSC) += snd-soc-au1xpsc-dbdma.o
7obj-$(CONFIG_SND_SOC_AU1XPSC_I2S) += snd-soc-au1xpsc-i2s.o 12obj-$(CONFIG_SND_SOC_AU1XPSC_I2S) += snd-soc-au1xpsc-i2s.o
8obj-$(CONFIG_SND_SOC_AU1XPSC_AC97) += snd-soc-au1xpsc-ac97.o 13obj-$(CONFIG_SND_SOC_AU1XPSC_AC97) += snd-soc-au1xpsc-ac97.o
14obj-$(CONFIG_SND_SOC_AU1XAUDIO) += snd-soc-au1x-dma.o
15obj-$(CONFIG_SND_SOC_AU1XAC97C) += snd-soc-au1x-ac97c.o
16obj-$(CONFIG_SND_SOC_AU1XI2SC) += snd-soc-au1x-i2sc.o
9 17
10# Boards 18# Boards
19snd-soc-db1000-objs := db1000.o
11snd-soc-db1200-objs := db1200.o 20snd-soc-db1200-objs := db1200.o
12 21
22obj-$(CONFIG_SND_SOC_DB1000) += snd-soc-db1000.o
13obj-$(CONFIG_SND_SOC_DB1200) += snd-soc-db1200.o 23obj-$(CONFIG_SND_SOC_DB1200) += snd-soc-db1200.o
diff --git a/sound/soc/au1x/ac97c.c b/sound/soc/au1x/ac97c.c
new file mode 100644
index 00000000000..726bd651a10
--- /dev/null
+++ b/sound/soc/au1x/ac97c.c
@@ -0,0 +1,366 @@
1/*
2 * Au1000/Au1500/Au1100 AC97C controller driver for ASoC
3 *
4 * (c) 2011 Manuel Lauss <manuel.lauss@googlemail.com>
5 *
6 * based on the old ALSA driver originally written by
7 * Charles Eidsness <charles@cooper-street.com>
8 */
9
10#include <linux/init.h>
11#include <linux/module.h>
12#include <linux/slab.h>
13#include <linux/device.h>
14#include <linux/delay.h>
15#include <linux/mutex.h>
16#include <linux/platform_device.h>
17#include <linux/suspend.h>
18#include <sound/core.h>
19#include <sound/pcm.h>
20#include <sound/initval.h>
21#include <sound/soc.h>
22#include <asm/mach-au1x00/au1000.h>
23
24#include "psc.h"
25
26/* register offsets and bits */
27#define AC97_CONFIG 0x00
28#define AC97_STATUS 0x04
29#define AC97_DATA 0x08
30#define AC97_CMDRESP 0x0c
31#define AC97_ENABLE 0x10
32
33#define CFG_RC(x) (((x) & 0x3ff) << 13) /* valid rx slots mask */
34#define CFG_XS(x) (((x) & 0x3ff) << 3) /* valid tx slots mask */
35#define CFG_SG (1 << 2) /* sync gate */
36#define CFG_SN (1 << 1) /* sync control */
37#define CFG_RS (1 << 0) /* acrst# control */
38#define STAT_XU (1 << 11) /* tx underflow */
39#define STAT_XO (1 << 10) /* tx overflow */
40#define STAT_RU (1 << 9) /* rx underflow */
41#define STAT_RO (1 << 8) /* rx overflow */
42#define STAT_RD (1 << 7) /* codec ready */
43#define STAT_CP (1 << 6) /* command pending */
44#define STAT_TE (1 << 4) /* tx fifo empty */
45#define STAT_TF (1 << 3) /* tx fifo full */
46#define STAT_RE (1 << 1) /* rx fifo empty */
47#define STAT_RF (1 << 0) /* rx fifo full */
48#define CMD_SET_DATA(x) (((x) & 0xffff) << 16)
49#define CMD_GET_DATA(x) ((x) & 0xffff)
50#define CMD_READ (1 << 7)
51#define CMD_WRITE (0 << 7)
52#define CMD_IDX(x) ((x) & 0x7f)
53#define EN_D (1 << 1) /* DISable bit */
54#define EN_CE (1 << 0) /* clock enable bit */
55
56/* how often to retry failed codec register reads/writes */
57#define AC97_RW_RETRIES 5
58
59#define AC97_RATES \
60 SNDRV_PCM_RATE_CONTINUOUS
61
62#define AC97_FMTS \
63 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE)
64
65/* instance data. There can be only one, MacLeod!!!!, fortunately there IS only
66 * once AC97C on early Alchemy chips. The newer ones aren't so lucky.
67 */
68static struct au1xpsc_audio_data *ac97c_workdata;
69#define ac97_to_ctx(x) ac97c_workdata
70
71static inline unsigned long RD(struct au1xpsc_audio_data *ctx, int reg)
72{
73 return __raw_readl(ctx->mmio + reg);
74}
75
76static inline void WR(struct au1xpsc_audio_data *ctx, int reg, unsigned long v)
77{
78 __raw_writel(v, ctx->mmio + reg);
79 wmb();
80}
81
82static unsigned short au1xac97c_ac97_read(struct snd_ac97 *ac97,
83 unsigned short r)
84{
85 struct au1xpsc_audio_data *ctx = ac97_to_ctx(ac97);
86 unsigned int tmo, retry;
87 unsigned long data;
88
89 data = ~0;
90 retry = AC97_RW_RETRIES;
91 do {
92 mutex_lock(&ctx->lock);
93
94 tmo = 5;
95 while ((RD(ctx, AC97_STATUS) & STAT_CP) && tmo--)
96 udelay(21); /* wait an ac97 frame time */
97 if (!tmo) {
98 pr_debug("ac97rd timeout #1\n");
99 goto next;
100 }
101
102 WR(ctx, AC97_CMDRESP, CMD_IDX(r) | CMD_READ);
103
104 /* stupid errata: data is only valid for 21us, so
105 * poll, Forrest, poll...
106 */
107 tmo = 0x10000;
108 while ((RD(ctx, AC97_STATUS) & STAT_CP) && tmo--)
109 asm volatile ("nop");
110 data = RD(ctx, AC97_CMDRESP);
111
112 if (!tmo)
113 pr_debug("ac97rd timeout #2\n");
114
115next:
116 mutex_unlock(&ctx->lock);
117 } while (--retry && !tmo);
118
119 pr_debug("AC97RD %04x %04lx %d\n", r, data, retry);
120
121 return retry ? data & 0xffff : 0xffff;
122}
123
124static void au1xac97c_ac97_write(struct snd_ac97 *ac97, unsigned short r,
125 unsigned short v)
126{
127 struct au1xpsc_audio_data *ctx = ac97_to_ctx(ac97);
128 unsigned int tmo, retry;
129
130 retry = AC97_RW_RETRIES;
131 do {
132 mutex_lock(&ctx->lock);
133
134 for (tmo = 5; (RD(ctx, AC97_STATUS) & STAT_CP) && tmo; tmo--)
135 udelay(21);
136 if (!tmo) {
137 pr_debug("ac97wr timeout #1\n");
138 goto next;
139 }
140
141 WR(ctx, AC97_CMDRESP, CMD_WRITE | CMD_IDX(r) | CMD_SET_DATA(v));
142
143 for (tmo = 10; (RD(ctx, AC97_STATUS) & STAT_CP) && tmo; tmo--)
144 udelay(21);
145 if (!tmo)
146 pr_debug("ac97wr timeout #2\n");
147next:
148 mutex_unlock(&ctx->lock);
149 } while (--retry && !tmo);
150
151 pr_debug("AC97WR %04x %04x %d\n", r, v, retry);
152}
153
154static void au1xac97c_ac97_warm_reset(struct snd_ac97 *ac97)
155{
156 struct au1xpsc_audio_data *ctx = ac97_to_ctx(ac97);
157
158 WR(ctx, AC97_CONFIG, ctx->cfg | CFG_SG | CFG_SN);
159 msleep(20);
160 WR(ctx, AC97_CONFIG, ctx->cfg | CFG_SG);
161 WR(ctx, AC97_CONFIG, ctx->cfg);
162}
163
164static void au1xac97c_ac97_cold_reset(struct snd_ac97 *ac97)
165{
166 struct au1xpsc_audio_data *ctx = ac97_to_ctx(ac97);
167 int i;
168
169 WR(ctx, AC97_CONFIG, ctx->cfg | CFG_RS);
170 msleep(500);
171 WR(ctx, AC97_CONFIG, ctx->cfg);
172
173 /* wait for codec ready */
174 i = 50;
175 while (((RD(ctx, AC97_STATUS) & STAT_RD) == 0) && --i)
176 msleep(20);
177 if (!i)
178 printk(KERN_ERR "ac97c: codec not ready after cold reset\n");
179}
180
181/* AC97 controller operations */
182struct snd_ac97_bus_ops soc_ac97_ops = {
183 .read = au1xac97c_ac97_read,
184 .write = au1xac97c_ac97_write,
185 .reset = au1xac97c_ac97_cold_reset,
186 .warm_reset = au1xac97c_ac97_warm_reset,
187};
188EXPORT_SYMBOL_GPL(soc_ac97_ops); /* globals be gone! */
189
190static int alchemy_ac97c_startup(struct snd_pcm_substream *substream,
191 struct snd_soc_dai *dai)
192{
193 struct au1xpsc_audio_data *ctx = snd_soc_dai_get_drvdata(dai);
194 snd_soc_dai_set_dma_data(dai, substream, &ctx->dmaids[0]);
195 return 0;
196}
197
198static struct snd_soc_dai_ops alchemy_ac97c_ops = {
199 .startup = alchemy_ac97c_startup,
200};
201
202static int au1xac97c_dai_probe(struct snd_soc_dai *dai)
203{
204 return ac97c_workdata ? 0 : -ENODEV;
205}
206
207static struct snd_soc_dai_driver au1xac97c_dai_driver = {
208 .name = "alchemy-ac97c",
209 .ac97_control = 1,
210 .probe = au1xac97c_dai_probe,
211 .playback = {
212 .rates = AC97_RATES,
213 .formats = AC97_FMTS,
214 .channels_min = 2,
215 .channels_max = 2,
216 },
217 .capture = {
218 .rates = AC97_RATES,
219 .formats = AC97_FMTS,
220 .channels_min = 2,
221 .channels_max = 2,
222 },
223 .ops = &alchemy_ac97c_ops,
224};
225
226static int __devinit au1xac97c_drvprobe(struct platform_device *pdev)
227{
228 int ret;
229 struct resource *iores, *dmares;
230 struct au1xpsc_audio_data *ctx;
231
232 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
233 if (!ctx)
234 return -ENOMEM;
235
236 mutex_init(&ctx->lock);
237
238 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
239 if (!iores) {
240 ret = -ENODEV;
241 goto out0;
242 }
243
244 ret = -EBUSY;
245 if (!request_mem_region(iores->start, resource_size(iores),
246 pdev->name))
247 goto out0;
248
249 ctx->mmio = ioremap_nocache(iores->start, resource_size(iores));
250 if (!ctx->mmio)
251 goto out1;
252
253 dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
254 if (!dmares)
255 goto out2;
256 ctx->dmaids[SNDRV_PCM_STREAM_PLAYBACK] = dmares->start;
257
258 dmares = platform_get_resource(pdev, IORESOURCE_DMA, 1);
259 if (!dmares)
260 goto out2;
261 ctx->dmaids[SNDRV_PCM_STREAM_CAPTURE] = dmares->start;
262
263 /* switch it on */
264 WR(ctx, AC97_ENABLE, EN_D | EN_CE);
265 WR(ctx, AC97_ENABLE, EN_CE);
266
267 ctx->cfg = CFG_RC(3) | CFG_XS(3);
268 WR(ctx, AC97_CONFIG, ctx->cfg);
269
270 platform_set_drvdata(pdev, ctx);
271
272 ret = snd_soc_register_dai(&pdev->dev, &au1xac97c_dai_driver);
273 if (ret)
274 goto out2;
275
276 ac97c_workdata = ctx;
277 return 0;
278
279out2:
280 iounmap(ctx->mmio);
281out1:
282 release_mem_region(iores->start, resource_size(iores));
283out0:
284 kfree(ctx);
285 return ret;
286}
287
288static int __devexit au1xac97c_drvremove(struct platform_device *pdev)
289{
290 struct au1xpsc_audio_data *ctx = platform_get_drvdata(pdev);
291 struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
292
293 snd_soc_unregister_dai(&pdev->dev);
294
295 WR(ctx, AC97_ENABLE, EN_D); /* clock off, disable */
296
297 iounmap(ctx->mmio);
298 release_mem_region(r->start, resource_size(r));
299 kfree(ctx);
300
301 ac97c_workdata = NULL; /* MDEV */
302
303 return 0;
304}
305
306#ifdef CONFIG_PM
307static int au1xac97c_drvsuspend(struct device *dev)
308{
309 struct au1xpsc_audio_data *ctx = dev_get_drvdata(dev);
310
311 WR(ctx, AC97_ENABLE, EN_D); /* clock off, disable */
312
313 return 0;
314}
315
316static int au1xac97c_drvresume(struct device *dev)
317{
318 struct au1xpsc_audio_data *ctx = dev_get_drvdata(dev);
319
320 WR(ctx, AC97_ENABLE, EN_D | EN_CE);
321 WR(ctx, AC97_ENABLE, EN_CE);
322 WR(ctx, AC97_CONFIG, ctx->cfg);
323
324 return 0;
325}
326
327static const struct dev_pm_ops au1xpscac97_pmops = {
328 .suspend = au1xac97c_drvsuspend,
329 .resume = au1xac97c_drvresume,
330};
331
332#define AU1XPSCAC97_PMOPS (&au1xpscac97_pmops)
333
334#else
335
336#define AU1XPSCAC97_PMOPS NULL
337
338#endif
339
340static struct platform_driver au1xac97c_driver = {
341 .driver = {
342 .name = "alchemy-ac97c",
343 .owner = THIS_MODULE,
344 .pm = AU1XPSCAC97_PMOPS,
345 },
346 .probe = au1xac97c_drvprobe,
347 .remove = __devexit_p(au1xac97c_drvremove),
348};
349
350static int __init au1xac97c_load(void)
351{
352 ac97c_workdata = NULL;
353 return platform_driver_register(&au1xac97c_driver);
354}
355
356static void __exit au1xac97c_unload(void)
357{
358 platform_driver_unregister(&au1xac97c_driver);
359}
360
361module_init(au1xac97c_load);
362module_exit(au1xac97c_unload);
363
364MODULE_LICENSE("GPL");
365MODULE_DESCRIPTION("Au1000/1500/1100 AC97C ASoC driver");
366MODULE_AUTHOR("Manuel Lauss");
diff --git a/sound/soc/au1x/db1000.c b/sound/soc/au1x/db1000.c
new file mode 100644
index 00000000000..127477a5e0c
--- /dev/null
+++ b/sound/soc/au1x/db1000.c
@@ -0,0 +1,75 @@
1/*
2 * DB1000/DB1500/DB1100 ASoC audio fabric support code.
3 *
4 * (c) 2011 Manuel Lauss <manuel.lauss@googlemail.com>
5 *
6 */
7
8#include <linux/module.h>
9#include <linux/moduleparam.h>
10#include <linux/timer.h>
11#include <linux/interrupt.h>
12#include <linux/platform_device.h>
13#include <sound/core.h>
14#include <sound/pcm.h>
15#include <sound/soc.h>
16#include <asm/mach-au1x00/au1000.h>
17#include <asm/mach-db1x00/bcsr.h>
18
19#include "psc.h"
20
21static struct snd_soc_dai_link db1000_ac97_dai = {
22 .name = "AC97",
23 .stream_name = "AC97 HiFi",
24 .codec_dai_name = "ac97-hifi",
25 .cpu_dai_name = "alchemy-ac97c",
26 .platform_name = "alchemy-pcm-dma.0",
27 .codec_name = "ac97-codec",
28};
29
30static struct snd_soc_card db1000_ac97 = {
31 .name = "DB1000_AC97",
32 .dai_link = &db1000_ac97_dai,
33 .num_links = 1,
34};
35
36static int __devinit db1000_audio_probe(struct platform_device *pdev)
37{
38 struct snd_soc_card *card = &db1000_ac97;
39 card->dev = &pdev->dev;
40 return snd_soc_register_card(card);
41}
42
43static int __devexit db1000_audio_remove(struct platform_device *pdev)
44{
45 struct snd_soc_card *card = platform_get_drvdata(pdev);
46 snd_soc_unregister_card(card);
47 return 0;
48}
49
50static struct platform_driver db1000_audio_driver = {
51 .driver = {
52 .name = "db1000-audio",
53 .owner = THIS_MODULE,
54 .pm = &snd_soc_pm_ops,
55 },
56 .probe = db1000_audio_probe,
57 .remove = __devexit_p(db1000_audio_remove),
58};
59
60static int __init db1000_audio_load(void)
61{
62 return platform_driver_register(&db1000_audio_driver);
63}
64
65static void __exit db1000_audio_unload(void)
66{
67 platform_driver_unregister(&db1000_audio_driver);
68}
69
70module_init(db1000_audio_load);
71module_exit(db1000_audio_unload);
72
73MODULE_LICENSE("GPL");
74MODULE_DESCRIPTION("DB1000/DB1500/DB1100 ASoC audio");
75MODULE_AUTHOR("Manuel Lauss");
diff --git a/sound/soc/au1x/db1200.c b/sound/soc/au1x/db1200.c
index 1d3e258c9ea..289312c14b9 100644
--- a/sound/soc/au1x/db1200.c
+++ b/sound/soc/au1x/db1200.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * DB1200 ASoC audio fabric support code. 2 * DB1200 ASoC audio fabric support code.
3 * 3 *
4 * (c) 2008-9 Manuel Lauss <manuel.lauss@gmail.com> 4 * (c) 2008-2011 Manuel Lauss <manuel.lauss@googlemail.com>
5 * 5 *
6 */ 6 */
7 7
@@ -21,6 +21,17 @@
21#include "../codecs/wm8731.h" 21#include "../codecs/wm8731.h"
22#include "psc.h" 22#include "psc.h"
23 23
24static struct platform_device_id db1200_pids[] = {
25 {
26 .name = "db1200-ac97",
27 .driver_data = 0,
28 }, {
29 .name = "db1200-i2s",
30 .driver_data = 1,
31 },
32 {},
33};
34
24/*------------------------- AC97 PART ---------------------------*/ 35/*------------------------- AC97 PART ---------------------------*/
25 36
26static struct snd_soc_dai_link db1200_ac97_dai = { 37static struct snd_soc_dai_link db1200_ac97_dai = {
@@ -89,36 +100,47 @@ static struct snd_soc_card db1200_i2s_machine = {
89 100
90/*------------------------- COMMON PART ---------------------------*/ 101/*------------------------- COMMON PART ---------------------------*/
91 102
92static struct platform_device *db1200_asoc_dev; 103static struct snd_soc_card *db1200_cards[] __devinitdata = {
104 &db1200_ac97_machine,
105 &db1200_i2s_machine,
106};
93 107
94static int __init db1200_audio_load(void) 108static int __devinit db1200_audio_probe(struct platform_device *pdev)
95{ 109{
96 int ret; 110 const struct platform_device_id *pid = platform_get_device_id(pdev);
111 struct snd_soc_card *card;
97 112
98 ret = -ENOMEM; 113 card = db1200_cards[pid->driver_data];
99 db1200_asoc_dev = platform_device_alloc("soc-audio", 1); /* PSC1 */ 114 card->dev = &pdev->dev;
100 if (!db1200_asoc_dev) 115 return snd_soc_register_card(card);
101 goto out; 116}
102 117
103 /* DB1200 board setup set PSC1MUX to preferred audio device */ 118static int __devexit db1200_audio_remove(struct platform_device *pdev)
104 if (bcsr_read(BCSR_RESETS) & BCSR_RESETS_PSC1MUX) 119{
105 platform_set_drvdata(db1200_asoc_dev, &db1200_i2s_machine); 120 struct snd_soc_card *card = platform_get_drvdata(pdev);
106 else 121 snd_soc_unregister_card(card);
107 platform_set_drvdata(db1200_asoc_dev, &db1200_ac97_machine); 122 return 0;
123}
108 124
109 ret = platform_device_add(db1200_asoc_dev); 125static struct platform_driver db1200_audio_driver = {
126 .driver = {
127 .name = "db1200-ac97",
128 .owner = THIS_MODULE,
129 .pm = &snd_soc_pm_ops,
130 },
131 .id_table = db1200_pids,
132 .probe = db1200_audio_probe,
133 .remove = __devexit_p(db1200_audio_remove),
134};
110 135
111 if (ret) { 136static int __init db1200_audio_load(void)
112 platform_device_put(db1200_asoc_dev); 137{
113 db1200_asoc_dev = NULL; 138 return platform_driver_register(&db1200_audio_driver);
114 }
115out:
116 return ret;
117} 139}
118 140
119static void __exit db1200_audio_unload(void) 141static void __exit db1200_audio_unload(void)
120{ 142{
121 platform_device_unregister(db1200_asoc_dev); 143 platform_driver_unregister(&db1200_audio_driver);
122} 144}
123 145
124module_init(db1200_audio_load); 146module_init(db1200_audio_load);
diff --git a/sound/soc/au1x/dbdma2.c b/sound/soc/au1x/dbdma2.c
index 20bb53a837b..d7d04e26eee 100644
--- a/sound/soc/au1x/dbdma2.c
+++ b/sound/soc/au1x/dbdma2.c
@@ -169,7 +169,7 @@ static int au1x_pcm_dbdma_realloc(struct au1xpsc_audio_dmadata *pcd,
169 169
170 au1x_pcm_dbdma_free(pcd); 170 au1x_pcm_dbdma_free(pcd);
171 171
172 if (stype == PCM_RX) 172 if (stype == SNDRV_PCM_STREAM_CAPTURE)
173 pcd->ddma_chan = au1xxx_dbdma_chan_alloc(pcd->ddma_id, 173 pcd->ddma_chan = au1xxx_dbdma_chan_alloc(pcd->ddma_id,
174 DSCR_CMD0_ALWAYS, 174 DSCR_CMD0_ALWAYS,
175 au1x_pcm_dmarx_cb, (void *)pcd); 175 au1x_pcm_dmarx_cb, (void *)pcd);
@@ -198,7 +198,7 @@ static inline struct au1xpsc_audio_dmadata *to_dmadata(struct snd_pcm_substream
198 struct snd_soc_pcm_runtime *rtd = ss->private_data; 198 struct snd_soc_pcm_runtime *rtd = ss->private_data;
199 struct au1xpsc_audio_dmadata *pcd = 199 struct au1xpsc_audio_dmadata *pcd =
200 snd_soc_platform_get_drvdata(rtd->platform); 200 snd_soc_platform_get_drvdata(rtd->platform);
201 return &pcd[SUBSTREAM_TYPE(ss)]; 201 return &pcd[ss->stream];
202} 202}
203 203
204static int au1xpsc_pcm_hw_params(struct snd_pcm_substream *substream, 204static int au1xpsc_pcm_hw_params(struct snd_pcm_substream *substream,
@@ -212,7 +212,7 @@ static int au1xpsc_pcm_hw_params(struct snd_pcm_substream *substream,
212 if (ret < 0) 212 if (ret < 0)
213 goto out; 213 goto out;
214 214
215 stype = SUBSTREAM_TYPE(substream); 215 stype = substream->stream;
216 pcd = to_dmadata(substream); 216 pcd = to_dmadata(substream);
217 217
218 DBG("runtime->dma_area = 0x%08lx dma_addr_t = 0x%08lx dma_size = %d " 218 DBG("runtime->dma_area = 0x%08lx dma_addr_t = 0x%08lx dma_size = %d "
@@ -255,7 +255,7 @@ static int au1xpsc_pcm_prepare(struct snd_pcm_substream *substream)
255 255
256 au1xxx_dbdma_reset(pcd->ddma_chan); 256 au1xxx_dbdma_reset(pcd->ddma_chan);
257 257
258 if (SUBSTREAM_TYPE(substream) == PCM_RX) { 258 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
259 au1x_pcm_queue_rx(pcd); 259 au1x_pcm_queue_rx(pcd);
260 au1x_pcm_queue_rx(pcd); 260 au1x_pcm_queue_rx(pcd);
261 } else { 261 } else {
@@ -293,6 +293,16 @@ au1xpsc_pcm_pointer(struct snd_pcm_substream *substream)
293 293
294static int au1xpsc_pcm_open(struct snd_pcm_substream *substream) 294static int au1xpsc_pcm_open(struct snd_pcm_substream *substream)
295{ 295{
296 struct au1xpsc_audio_dmadata *pcd = to_dmadata(substream);
297 struct snd_soc_pcm_runtime *rtd = substream->private_data;
298 int stype = substream->stream, *dmaids;
299
300 dmaids = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
301 if (!dmaids)
302 return -ENODEV; /* whoa, has ordering changed? */
303
304 pcd->ddma_id = dmaids[stype];
305
296 snd_soc_set_runtime_hwparams(substream, &au1xpsc_pcm_hardware); 306 snd_soc_set_runtime_hwparams(substream, &au1xpsc_pcm_hardware);
297 return 0; 307 return 0;
298} 308}
@@ -340,36 +350,18 @@ struct snd_soc_platform_driver au1xpsc_soc_platform = {
340static int __devinit au1xpsc_pcm_drvprobe(struct platform_device *pdev) 350static int __devinit au1xpsc_pcm_drvprobe(struct platform_device *pdev)
341{ 351{
342 struct au1xpsc_audio_dmadata *dmadata; 352 struct au1xpsc_audio_dmadata *dmadata;
343 struct resource *r;
344 int ret; 353 int ret;
345 354
346 dmadata = kzalloc(2 * sizeof(struct au1xpsc_audio_dmadata), GFP_KERNEL); 355 dmadata = kzalloc(2 * sizeof(struct au1xpsc_audio_dmadata), GFP_KERNEL);
347 if (!dmadata) 356 if (!dmadata)
348 return -ENOMEM; 357 return -ENOMEM;
349 358
350 r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
351 if (!r) {
352 ret = -ENODEV;
353 goto out1;
354 }
355 dmadata[PCM_TX].ddma_id = r->start;
356
357 /* RX DMA */
358 r = platform_get_resource(pdev, IORESOURCE_DMA, 1);
359 if (!r) {
360 ret = -ENODEV;
361 goto out1;
362 }
363 dmadata[PCM_RX].ddma_id = r->start;
364
365 platform_set_drvdata(pdev, dmadata); 359 platform_set_drvdata(pdev, dmadata);
366 360
367 ret = snd_soc_register_platform(&pdev->dev, &au1xpsc_soc_platform); 361 ret = snd_soc_register_platform(&pdev->dev, &au1xpsc_soc_platform);
368 if (!ret) 362 if (ret)
369 return ret; 363 kfree(dmadata);
370 364
371out1:
372 kfree(dmadata);
373 return ret; 365 return ret;
374} 366}
375 367
@@ -405,57 +397,6 @@ static void __exit au1xpsc_audio_dbdma_unload(void)
405module_init(au1xpsc_audio_dbdma_load); 397module_init(au1xpsc_audio_dbdma_load);
406module_exit(au1xpsc_audio_dbdma_unload); 398module_exit(au1xpsc_audio_dbdma_unload);
407 399
408
409struct platform_device *au1xpsc_pcm_add(struct platform_device *pdev)
410{
411 struct resource *res, *r;
412 struct platform_device *pd;
413 int id[2];
414 int ret;
415
416 r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
417 if (!r)
418 return NULL;
419 id[0] = r->start;
420
421 r = platform_get_resource(pdev, IORESOURCE_DMA, 1);
422 if (!r)
423 return NULL;
424 id[1] = r->start;
425
426 res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL);
427 if (!res)
428 return NULL;
429
430 res[0].start = res[0].end = id[0];
431 res[1].start = res[1].end = id[1];
432 res[0].flags = res[1].flags = IORESOURCE_DMA;
433
434 pd = platform_device_alloc("au1xpsc-pcm", pdev->id);
435 if (!pd)
436 goto out;
437
438 pd->resource = res;
439 pd->num_resources = 2;
440
441 ret = platform_device_add(pd);
442 if (!ret)
443 return pd;
444
445 platform_device_put(pd);
446out:
447 kfree(res);
448 return NULL;
449}
450EXPORT_SYMBOL_GPL(au1xpsc_pcm_add);
451
452void au1xpsc_pcm_destroy(struct platform_device *dmapd)
453{
454 if (dmapd)
455 platform_device_unregister(dmapd);
456}
457EXPORT_SYMBOL_GPL(au1xpsc_pcm_destroy);
458
459MODULE_LICENSE("GPL"); 400MODULE_LICENSE("GPL");
460MODULE_DESCRIPTION("Au12x0/Au1550 PSC Audio DMA driver"); 401MODULE_DESCRIPTION("Au12x0/Au1550 PSC Audio DMA driver");
461MODULE_AUTHOR("Manuel Lauss"); 402MODULE_AUTHOR("Manuel Lauss");
diff --git a/sound/soc/au1x/dma.c b/sound/soc/au1x/dma.c
new file mode 100644
index 00000000000..177f7137a9c
--- /dev/null
+++ b/sound/soc/au1x/dma.c
@@ -0,0 +1,377 @@
1/*
2 * Au1000/Au1500/Au1100 Audio DMA support.
3 *
4 * (c) 2011 Manuel Lauss <manuel.lauss@googlemail.com>
5 *
6 * copied almost verbatim from the old ALSA driver, written by
7 * Charles Eidsness <charles@cooper-street.com>
8 */
9
10#include <linux/module.h>
11#include <linux/init.h>
12#include <linux/platform_device.h>
13#include <linux/slab.h>
14#include <linux/dma-mapping.h>
15#include <sound/core.h>
16#include <sound/pcm.h>
17#include <sound/pcm_params.h>
18#include <sound/soc.h>
19#include <asm/mach-au1x00/au1000.h>
20#include <asm/mach-au1x00/au1000_dma.h>
21
22#include "psc.h"
23
24#define ALCHEMY_PCM_FMTS \
25 (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 | \
26 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \
27 SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_U16_BE | \
28 SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE | \
29 SNDRV_PCM_FMTBIT_U32_LE | SNDRV_PCM_FMTBIT_U32_BE | \
30 0)
31
32struct pcm_period {
33 u32 start;
34 u32 relative_end; /* relative to start of buffer */
35 struct pcm_period *next;
36};
37
38struct audio_stream {
39 struct snd_pcm_substream *substream;
40 int dma;
41 struct pcm_period *buffer;
42 unsigned int period_size;
43 unsigned int periods;
44};
45
46struct alchemy_pcm_ctx {
47 struct audio_stream stream[2]; /* playback & capture */
48};
49
50static void au1000_release_dma_link(struct audio_stream *stream)
51{
52 struct pcm_period *pointer;
53 struct pcm_period *pointer_next;
54
55 stream->period_size = 0;
56 stream->periods = 0;
57 pointer = stream->buffer;
58 if (!pointer)
59 return;
60 do {
61 pointer_next = pointer->next;
62 kfree(pointer);
63 pointer = pointer_next;
64 } while (pointer != stream->buffer);
65 stream->buffer = NULL;
66}
67
68static int au1000_setup_dma_link(struct audio_stream *stream,
69 unsigned int period_bytes,
70 unsigned int periods)
71{
72 struct snd_pcm_substream *substream = stream->substream;
73 struct snd_pcm_runtime *runtime = substream->runtime;
74 struct pcm_period *pointer;
75 unsigned long dma_start;
76 int i;
77
78 dma_start = virt_to_phys(runtime->dma_area);
79
80 if (stream->period_size == period_bytes &&
81 stream->periods == periods)
82 return 0; /* not changed */
83
84 au1000_release_dma_link(stream);
85
86 stream->period_size = period_bytes;
87 stream->periods = periods;
88
89 stream->buffer = kmalloc(sizeof(struct pcm_period), GFP_KERNEL);
90 if (!stream->buffer)
91 return -ENOMEM;
92 pointer = stream->buffer;
93 for (i = 0; i < periods; i++) {
94 pointer->start = (u32)(dma_start + (i * period_bytes));
95 pointer->relative_end = (u32) (((i+1) * period_bytes) - 0x1);
96 if (i < periods - 1) {
97 pointer->next = kmalloc(sizeof(struct pcm_period),
98 GFP_KERNEL);
99 if (!pointer->next) {
100 au1000_release_dma_link(stream);
101 return -ENOMEM;
102 }
103 pointer = pointer->next;
104 }
105 }
106 pointer->next = stream->buffer;
107 return 0;
108}
109
110static void au1000_dma_stop(struct audio_stream *stream)
111{
112 if (stream->buffer)
113 disable_dma(stream->dma);
114}
115
116static void au1000_dma_start(struct audio_stream *stream)
117{
118 if (!stream->buffer)
119 return;
120
121 init_dma(stream->dma);
122 if (get_dma_active_buffer(stream->dma) == 0) {
123 clear_dma_done0(stream->dma);
124 set_dma_addr0(stream->dma, stream->buffer->start);
125 set_dma_count0(stream->dma, stream->period_size >> 1);
126 set_dma_addr1(stream->dma, stream->buffer->next->start);
127 set_dma_count1(stream->dma, stream->period_size >> 1);
128 } else {
129 clear_dma_done1(stream->dma);
130 set_dma_addr1(stream->dma, stream->buffer->start);
131 set_dma_count1(stream->dma, stream->period_size >> 1);
132 set_dma_addr0(stream->dma, stream->buffer->next->start);
133 set_dma_count0(stream->dma, stream->period_size >> 1);
134 }
135 enable_dma_buffers(stream->dma);
136 start_dma(stream->dma);
137}
138
139static irqreturn_t au1000_dma_interrupt(int irq, void *ptr)
140{
141 struct audio_stream *stream = (struct audio_stream *)ptr;
142 struct snd_pcm_substream *substream = stream->substream;
143
144 switch (get_dma_buffer_done(stream->dma)) {
145 case DMA_D0:
146 stream->buffer = stream->buffer->next;
147 clear_dma_done0(stream->dma);
148 set_dma_addr0(stream->dma, stream->buffer->next->start);
149 set_dma_count0(stream->dma, stream->period_size >> 1);
150 enable_dma_buffer0(stream->dma);
151 break;
152 case DMA_D1:
153 stream->buffer = stream->buffer->next;
154 clear_dma_done1(stream->dma);
155 set_dma_addr1(stream->dma, stream->buffer->next->start);
156 set_dma_count1(stream->dma, stream->period_size >> 1);
157 enable_dma_buffer1(stream->dma);
158 break;
159 case (DMA_D0 | DMA_D1):
160 pr_debug("DMA %d missed interrupt.\n", stream->dma);
161 au1000_dma_stop(stream);
162 au1000_dma_start(stream);
163 break;
164 case (~DMA_D0 & ~DMA_D1):
165 pr_debug("DMA %d empty irq.\n", stream->dma);
166 }
167 snd_pcm_period_elapsed(substream);
168 return IRQ_HANDLED;
169}
170
171static const struct snd_pcm_hardware alchemy_pcm_hardware = {
172 .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
173 SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BATCH,
174 .formats = ALCHEMY_PCM_FMTS,
175 .rates = SNDRV_PCM_RATE_8000_192000,
176 .rate_min = SNDRV_PCM_RATE_8000,
177 .rate_max = SNDRV_PCM_RATE_192000,
178 .channels_min = 2,
179 .channels_max = 2,
180 .period_bytes_min = 1024,
181 .period_bytes_max = 16 * 1024 - 1,
182 .periods_min = 4,
183 .periods_max = 255,
184 .buffer_bytes_max = 128 * 1024,
185 .fifo_size = 16,
186};
187
188static inline struct alchemy_pcm_ctx *ss_to_ctx(struct snd_pcm_substream *ss)
189{
190 struct snd_soc_pcm_runtime *rtd = ss->private_data;
191 return snd_soc_platform_get_drvdata(rtd->platform);
192}
193
194static inline struct audio_stream *ss_to_as(struct snd_pcm_substream *ss)
195{
196 struct alchemy_pcm_ctx *ctx = ss_to_ctx(ss);
197 return &(ctx->stream[ss->stream]);
198}
199
200static int alchemy_pcm_open(struct snd_pcm_substream *substream)
201{
202 struct alchemy_pcm_ctx *ctx = ss_to_ctx(substream);
203 struct snd_soc_pcm_runtime *rtd = substream->private_data;
204 int *dmaids, s = substream->stream;
205 char *name;
206
207 dmaids = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
208 if (!dmaids)
209 return -ENODEV; /* whoa, has ordering changed? */
210
211 /* DMA setup */
212 name = (s == SNDRV_PCM_STREAM_PLAYBACK) ? "audio-tx" : "audio-rx";
213 ctx->stream[s].dma = request_au1000_dma(dmaids[s], name,
214 au1000_dma_interrupt, 0,
215 &ctx->stream[s]);
216 set_dma_mode(ctx->stream[s].dma,
217 get_dma_mode(ctx->stream[s].dma) & ~DMA_NC);
218
219 ctx->stream[s].substream = substream;
220 ctx->stream[s].buffer = NULL;
221 snd_soc_set_runtime_hwparams(substream, &alchemy_pcm_hardware);
222
223 return 0;
224}
225
226static int alchemy_pcm_close(struct snd_pcm_substream *substream)
227{
228 struct alchemy_pcm_ctx *ctx = ss_to_ctx(substream);
229 int stype = substream->stream;
230
231 ctx->stream[stype].substream = NULL;
232 free_au1000_dma(ctx->stream[stype].dma);
233
234 return 0;
235}
236
237static int alchemy_pcm_hw_params(struct snd_pcm_substream *substream,
238 struct snd_pcm_hw_params *hw_params)
239{
240 struct audio_stream *stream = ss_to_as(substream);
241 int err;
242
243 err = snd_pcm_lib_malloc_pages(substream,
244 params_buffer_bytes(hw_params));
245 if (err < 0)
246 return err;
247 err = au1000_setup_dma_link(stream,
248 params_period_bytes(hw_params),
249 params_periods(hw_params));
250 if (err)
251 snd_pcm_lib_free_pages(substream);
252
253 return err;
254}
255
256static int alchemy_pcm_hw_free(struct snd_pcm_substream *substream)
257{
258 struct audio_stream *stream = ss_to_as(substream);
259 au1000_release_dma_link(stream);
260 return snd_pcm_lib_free_pages(substream);
261}
262
263static int alchemy_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
264{
265 struct audio_stream *stream = ss_to_as(substream);
266 int err = 0;
267
268 switch (cmd) {
269 case SNDRV_PCM_TRIGGER_START:
270 au1000_dma_start(stream);
271 break;
272 case SNDRV_PCM_TRIGGER_STOP:
273 au1000_dma_stop(stream);
274 break;
275 default:
276 err = -EINVAL;
277 break;
278 }
279 return err;
280}
281
282static snd_pcm_uframes_t alchemy_pcm_pointer(struct snd_pcm_substream *ss)
283{
284 struct audio_stream *stream = ss_to_as(ss);
285 long location;
286
287 location = get_dma_residue(stream->dma);
288 location = stream->buffer->relative_end - location;
289 if (location == -1)
290 location = 0;
291 return bytes_to_frames(ss->runtime, location);
292}
293
294static struct snd_pcm_ops alchemy_pcm_ops = {
295 .open = alchemy_pcm_open,
296 .close = alchemy_pcm_close,
297 .ioctl = snd_pcm_lib_ioctl,
298 .hw_params = alchemy_pcm_hw_params,
299 .hw_free = alchemy_pcm_hw_free,
300 .trigger = alchemy_pcm_trigger,
301 .pointer = alchemy_pcm_pointer,
302};
303
304static void alchemy_pcm_free_dma_buffers(struct snd_pcm *pcm)
305{
306 snd_pcm_lib_preallocate_free_for_all(pcm);
307}
308
309static int alchemy_pcm_new(struct snd_soc_pcm_runtime *rtd)
310{
311 struct snd_pcm *pcm = rtd->pcm;
312
313 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
314 snd_dma_continuous_data(GFP_KERNEL), 65536, (4096 * 1024) - 1);
315
316 return 0;
317}
318
319struct snd_soc_platform_driver alchemy_pcm_soc_platform = {
320 .ops = &alchemy_pcm_ops,
321 .pcm_new = alchemy_pcm_new,
322 .pcm_free = alchemy_pcm_free_dma_buffers,
323};
324
325static int __devinit alchemy_pcm_drvprobe(struct platform_device *pdev)
326{
327 struct alchemy_pcm_ctx *ctx;
328 int ret;
329
330 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
331 if (!ctx)
332 return -ENOMEM;
333
334 platform_set_drvdata(pdev, ctx);
335
336 ret = snd_soc_register_platform(&pdev->dev, &alchemy_pcm_soc_platform);
337 if (ret)
338 kfree(ctx);
339
340 return ret;
341}
342
343static int __devexit alchemy_pcm_drvremove(struct platform_device *pdev)
344{
345 struct alchemy_pcm_ctx *ctx = platform_get_drvdata(pdev);
346
347 snd_soc_unregister_platform(&pdev->dev);
348 kfree(ctx);
349
350 return 0;
351}
352
353static struct platform_driver alchemy_pcmdma_driver = {
354 .driver = {
355 .name = "alchemy-pcm-dma",
356 .owner = THIS_MODULE,
357 },
358 .probe = alchemy_pcm_drvprobe,
359 .remove = __devexit_p(alchemy_pcm_drvremove),
360};
361
362static int __init alchemy_pcmdma_load(void)
363{
364 return platform_driver_register(&alchemy_pcmdma_driver);
365}
366
367static void __exit alchemy_pcmdma_unload(void)
368{
369 platform_driver_unregister(&alchemy_pcmdma_driver);
370}
371
372module_init(alchemy_pcmdma_load);
373module_exit(alchemy_pcmdma_unload);
374
375MODULE_LICENSE("GPL");
376MODULE_DESCRIPTION("Au1000/Au1500/Au1100 Audio DMA driver");
377MODULE_AUTHOR("Manuel Lauss");
diff --git a/sound/soc/au1x/i2sc.c b/sound/soc/au1x/i2sc.c
new file mode 100644
index 00000000000..6bcf48f5884
--- /dev/null
+++ b/sound/soc/au1x/i2sc.c
@@ -0,0 +1,349 @@
1/*
2 * Au1000/Au1500/Au1100 I2S controller driver for ASoC
3 *
4 * (c) 2011 Manuel Lauss <manuel.lauss@googlemail.com>
5 *
6 * Note: clock supplied to the I2S controller must be 256x samplerate.
7 */
8
9#include <linux/init.h>
10#include <linux/module.h>
11#include <linux/slab.h>
12#include <linux/suspend.h>
13#include <sound/core.h>
14#include <sound/pcm.h>
15#include <sound/initval.h>
16#include <sound/soc.h>
17#include <asm/mach-au1x00/au1000.h>
18
19#include "psc.h"
20
21#define I2S_RXTX 0x00
22#define I2S_CFG 0x04
23#define I2S_ENABLE 0x08
24
25#define CFG_XU (1 << 25) /* tx underflow */
26#define CFG_XO (1 << 24)
27#define CFG_RU (1 << 23)
28#define CFG_RO (1 << 22)
29#define CFG_TR (1 << 21)
30#define CFG_TE (1 << 20)
31#define CFG_TF (1 << 19)
32#define CFG_RR (1 << 18)
33#define CFG_RF (1 << 17)
34#define CFG_ICK (1 << 12) /* clock invert */
35#define CFG_PD (1 << 11) /* set to make I2SDIO INPUT */
36#define CFG_LB (1 << 10) /* loopback */
37#define CFG_IC (1 << 9) /* word select invert */
38#define CFG_FM_I2S (0 << 7) /* I2S format */
39#define CFG_FM_LJ (1 << 7) /* left-justified */
40#define CFG_FM_RJ (2 << 7) /* right-justified */
41#define CFG_FM_MASK (3 << 7)
42#define CFG_TN (1 << 6) /* tx fifo en */
43#define CFG_RN (1 << 5) /* rx fifo en */
44#define CFG_SZ_8 (0x08)
45#define CFG_SZ_16 (0x10)
46#define CFG_SZ_18 (0x12)
47#define CFG_SZ_20 (0x14)
48#define CFG_SZ_24 (0x18)
49#define CFG_SZ_MASK (0x1f)
50#define EN_D (1 << 1) /* DISable */
51#define EN_CE (1 << 0) /* clock enable */
52
53/* only limited by clock generator and board design */
54#define AU1XI2SC_RATES \
55 SNDRV_PCM_RATE_CONTINUOUS
56
57#define AU1XI2SC_FMTS \
58 (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 | \
59 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \
60 SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_U16_BE | \
61 SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_U18_3LE | \
62 SNDRV_PCM_FMTBIT_S18_3BE | SNDRV_PCM_FMTBIT_U18_3BE | \
63 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_U20_3LE | \
64 SNDRV_PCM_FMTBIT_S20_3BE | SNDRV_PCM_FMTBIT_U20_3BE | \
65 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE | \
66 SNDRV_PCM_FMTBIT_U24_LE | SNDRV_PCM_FMTBIT_U24_BE | \
67 0)
68
69static inline unsigned long RD(struct au1xpsc_audio_data *ctx, int reg)
70{
71 return __raw_readl(ctx->mmio + reg);
72}
73
74static inline void WR(struct au1xpsc_audio_data *ctx, int reg, unsigned long v)
75{
76 __raw_writel(v, ctx->mmio + reg);
77 wmb();
78}
79
80static int au1xi2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
81{
82 struct au1xpsc_audio_data *ctx = snd_soc_dai_get_drvdata(cpu_dai);
83 unsigned long c;
84 int ret;
85
86 ret = -EINVAL;
87 c = ctx->cfg;
88
89 c &= ~CFG_FM_MASK;
90 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
91 case SND_SOC_DAIFMT_I2S:
92 c |= CFG_FM_I2S;
93 break;
94 case SND_SOC_DAIFMT_MSB:
95 c |= CFG_FM_RJ;
96 break;
97 case SND_SOC_DAIFMT_LSB:
98 c |= CFG_FM_LJ;
99 break;
100 default:
101 goto out;
102 }
103
104 c &= ~(CFG_IC | CFG_ICK); /* IB-IF */
105 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
106 case SND_SOC_DAIFMT_NB_NF:
107 c |= CFG_IC | CFG_ICK;
108 break;
109 case SND_SOC_DAIFMT_NB_IF:
110 c |= CFG_IC;
111 break;
112 case SND_SOC_DAIFMT_IB_NF:
113 c |= CFG_ICK;
114 break;
115 case SND_SOC_DAIFMT_IB_IF:
116 break;
117 default:
118 goto out;
119 }
120
121 /* I2S controller only supports master */
122 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
123 case SND_SOC_DAIFMT_CBS_CFS: /* CODEC slave */
124 break;
125 default:
126 goto out;
127 }
128
129 ret = 0;
130 ctx->cfg = c;
131out:
132 return ret;
133}
134
135static int au1xi2s_trigger(struct snd_pcm_substream *substream,
136 int cmd, struct snd_soc_dai *dai)
137{
138 struct au1xpsc_audio_data *ctx = snd_soc_dai_get_drvdata(dai);
139 int stype = SUBSTREAM_TYPE(substream);
140
141 switch (cmd) {
142 case SNDRV_PCM_TRIGGER_START:
143 case SNDRV_PCM_TRIGGER_RESUME:
144 /* power up */
145 WR(ctx, I2S_ENABLE, EN_D | EN_CE);
146 WR(ctx, I2S_ENABLE, EN_CE);
147 ctx->cfg |= (stype == PCM_TX) ? CFG_TN : CFG_RN;
148 WR(ctx, I2S_CFG, ctx->cfg);
149 break;
150 case SNDRV_PCM_TRIGGER_STOP:
151 case SNDRV_PCM_TRIGGER_SUSPEND:
152 ctx->cfg &= ~((stype == PCM_TX) ? CFG_TN : CFG_RN);
153 WR(ctx, I2S_CFG, ctx->cfg);
154 WR(ctx, I2S_ENABLE, EN_D); /* power off */
155 break;
156 default:
157 return -EINVAL;
158 }
159
160 return 0;
161}
162
163static unsigned long msbits_to_reg(int msbits)
164{
165 switch (msbits) {
166 case 8:
167 return CFG_SZ_8;
168 case 16:
169 return CFG_SZ_16;
170 case 18:
171 return CFG_SZ_18;
172 case 20:
173 return CFG_SZ_20;
174 case 24:
175 return CFG_SZ_24;
176 }
177 return 0;
178}
179
180static int au1xi2s_hw_params(struct snd_pcm_substream *substream,
181 struct snd_pcm_hw_params *params,
182 struct snd_soc_dai *dai)
183{
184 struct au1xpsc_audio_data *ctx = snd_soc_dai_get_drvdata(dai);
185 unsigned long v;
186
187 v = msbits_to_reg(params->msbits);
188 if (!v)
189 return -EINVAL;
190
191 ctx->cfg &= ~CFG_SZ_MASK;
192 ctx->cfg |= v;
193 return 0;
194}
195
196static int au1xi2s_startup(struct snd_pcm_substream *substream,
197 struct snd_soc_dai *dai)
198{
199 struct au1xpsc_audio_data *ctx = snd_soc_dai_get_drvdata(dai);
200 snd_soc_dai_set_dma_data(dai, substream, &ctx->dmaids[0]);
201 return 0;
202}
203
204static const struct snd_soc_dai_ops au1xi2s_dai_ops = {
205 .startup = au1xi2s_startup,
206 .trigger = au1xi2s_trigger,
207 .hw_params = au1xi2s_hw_params,
208 .set_fmt = au1xi2s_set_fmt,
209};
210
211static struct snd_soc_dai_driver au1xi2s_dai_driver = {
212 .symmetric_rates = 1,
213 .playback = {
214 .rates = AU1XI2SC_RATES,
215 .formats = AU1XI2SC_FMTS,
216 .channels_min = 2,
217 .channels_max = 2,
218 },
219 .capture = {
220 .rates = AU1XI2SC_RATES,
221 .formats = AU1XI2SC_FMTS,
222 .channels_min = 2,
223 .channels_max = 2,
224 },
225 .ops = &au1xi2s_dai_ops,
226};
227
228static int __devinit au1xi2s_drvprobe(struct platform_device *pdev)
229{
230 int ret;
231 struct resource *iores, *dmares;
232 struct au1xpsc_audio_data *ctx;
233
234 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
235 if (!ctx)
236 return -ENOMEM;
237
238 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
239 if (!iores) {
240 ret = -ENODEV;
241 goto out0;
242 }
243
244 ret = -EBUSY;
245 if (!request_mem_region(iores->start, resource_size(iores),
246 pdev->name))
247 goto out0;
248
249 ctx->mmio = ioremap_nocache(iores->start, resource_size(iores));
250 if (!ctx->mmio)
251 goto out1;
252
253 dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
254 if (!dmares)
255 goto out2;
256 ctx->dmaids[SNDRV_PCM_STREAM_PLAYBACK] = dmares->start;
257
258 dmares = platform_get_resource(pdev, IORESOURCE_DMA, 1);
259 if (!dmares)
260 goto out2;
261 ctx->dmaids[SNDRV_PCM_STREAM_CAPTURE] = dmares->start;
262
263 platform_set_drvdata(pdev, ctx);
264
265 ret = snd_soc_register_dai(&pdev->dev, &au1xi2s_dai_driver);
266 if (ret)
267 goto out2;
268
269 return 0;
270
271out2:
272 iounmap(ctx->mmio);
273out1:
274 release_mem_region(iores->start, resource_size(iores));
275out0:
276 kfree(ctx);
277 return ret;
278}
279
280static int __devexit au1xi2s_drvremove(struct platform_device *pdev)
281{
282 struct au1xpsc_audio_data *ctx = platform_get_drvdata(pdev);
283 struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
284
285 snd_soc_unregister_dai(&pdev->dev);
286
287 WR(ctx, I2S_ENABLE, EN_D); /* clock off, disable */
288
289 iounmap(ctx->mmio);
290 release_mem_region(r->start, resource_size(r));
291 kfree(ctx);
292
293 return 0;
294}
295
296#ifdef CONFIG_PM
297static int au1xi2s_drvsuspend(struct device *dev)
298{
299 struct au1xpsc_audio_data *ctx = dev_get_drvdata(dev);
300
301 WR(ctx, I2S_ENABLE, EN_D); /* clock off, disable */
302
303 return 0;
304}
305
306static int au1xi2s_drvresume(struct device *dev)
307{
308 return 0;
309}
310
311static const struct dev_pm_ops au1xi2sc_pmops = {
312 .suspend = au1xi2s_drvsuspend,
313 .resume = au1xi2s_drvresume,
314};
315
316#define AU1XI2SC_PMOPS (&au1xi2sc_pmops)
317
318#else
319
320#define AU1XI2SC_PMOPS NULL
321
322#endif
323
324static struct platform_driver au1xi2s_driver = {
325 .driver = {
326 .name = "alchemy-i2sc",
327 .owner = THIS_MODULE,
328 .pm = AU1XI2SC_PMOPS,
329 },
330 .probe = au1xi2s_drvprobe,
331 .remove = __devexit_p(au1xi2s_drvremove),
332};
333
334static int __init au1xi2s_load(void)
335{
336 return platform_driver_register(&au1xi2s_driver);
337}
338
339static void __exit au1xi2s_unload(void)
340{
341 platform_driver_unregister(&au1xi2s_driver);
342}
343
344module_init(au1xi2s_load);
345module_exit(au1xi2s_unload);
346
347MODULE_LICENSE("GPL");
348MODULE_DESCRIPTION("Au1000/1500/1100 I2S ASoC driver");
349MODULE_AUTHOR("Manuel Lauss");
diff --git a/sound/soc/au1x/psc-ac97.c b/sound/soc/au1x/psc-ac97.c
index d0db66f24a0..0c6acd54714 100644
--- a/sound/soc/au1x/psc-ac97.c
+++ b/sound/soc/au1x/psc-ac97.c
@@ -41,14 +41,14 @@
41 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3BE) 41 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3BE)
42 42
43#define AC97PCR_START(stype) \ 43#define AC97PCR_START(stype) \
44 ((stype) == PCM_TX ? PSC_AC97PCR_TS : PSC_AC97PCR_RS) 44 ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_AC97PCR_TS : PSC_AC97PCR_RS)
45#define AC97PCR_STOP(stype) \ 45#define AC97PCR_STOP(stype) \
46 ((stype) == PCM_TX ? PSC_AC97PCR_TP : PSC_AC97PCR_RP) 46 ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_AC97PCR_TP : PSC_AC97PCR_RP)
47#define AC97PCR_CLRFIFO(stype) \ 47#define AC97PCR_CLRFIFO(stype) \
48 ((stype) == PCM_TX ? PSC_AC97PCR_TC : PSC_AC97PCR_RC) 48 ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_AC97PCR_TC : PSC_AC97PCR_RC)
49 49
50#define AC97STAT_BUSY(stype) \ 50#define AC97STAT_BUSY(stype) \
51 ((stype) == PCM_TX ? PSC_AC97STAT_TB : PSC_AC97STAT_RB) 51 ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_AC97STAT_TB : PSC_AC97STAT_RB)
52 52
53/* instance data. There can be only one, MacLeod!!!! */ 53/* instance data. There can be only one, MacLeod!!!! */
54static struct au1xpsc_audio_data *au1xpsc_ac97_workdata; 54static struct au1xpsc_audio_data *au1xpsc_ac97_workdata;
@@ -215,7 +215,7 @@ static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream,
215{ 215{
216 struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai); 216 struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai);
217 unsigned long r, ro, stat; 217 unsigned long r, ro, stat;
218 int chans, t, stype = SUBSTREAM_TYPE(substream); 218 int chans, t, stype = substream->stream;
219 219
220 chans = params_channels(params); 220 chans = params_channels(params);
221 221
@@ -235,7 +235,7 @@ static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream,
235 r |= PSC_AC97CFG_SET_LEN(params->msbits); 235 r |= PSC_AC97CFG_SET_LEN(params->msbits);
236 236
237 /* channels: enable slots for front L/R channel */ 237 /* channels: enable slots for front L/R channel */
238 if (stype == PCM_TX) { 238 if (stype == SNDRV_PCM_STREAM_PLAYBACK) {
239 r &= ~PSC_AC97CFG_TXSLOT_MASK; 239 r &= ~PSC_AC97CFG_TXSLOT_MASK;
240 r |= PSC_AC97CFG_TXSLOT_ENA(3); 240 r |= PSC_AC97CFG_TXSLOT_ENA(3);
241 r |= PSC_AC97CFG_TXSLOT_ENA(4); 241 r |= PSC_AC97CFG_TXSLOT_ENA(4);
@@ -294,7 +294,7 @@ static int au1xpsc_ac97_trigger(struct snd_pcm_substream *substream,
294 int cmd, struct snd_soc_dai *dai) 294 int cmd, struct snd_soc_dai *dai)
295{ 295{
296 struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai); 296 struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai);
297 int ret, stype = SUBSTREAM_TYPE(substream); 297 int ret, stype = substream->stream;
298 298
299 ret = 0; 299 ret = 0;
300 300
@@ -324,12 +324,21 @@ static int au1xpsc_ac97_trigger(struct snd_pcm_substream *substream,
324 return ret; 324 return ret;
325} 325}
326 326
327static int au1xpsc_ac97_startup(struct snd_pcm_substream *substream,
328 struct snd_soc_dai *dai)
329{
330 struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai);
331 snd_soc_dai_set_dma_data(dai, substream, &pscdata->dmaids[0]);
332 return 0;
333}
334
327static int au1xpsc_ac97_probe(struct snd_soc_dai *dai) 335static int au1xpsc_ac97_probe(struct snd_soc_dai *dai)
328{ 336{
329 return au1xpsc_ac97_workdata ? 0 : -ENODEV; 337 return au1xpsc_ac97_workdata ? 0 : -ENODEV;
330} 338}
331 339
332static struct snd_soc_dai_ops au1xpsc_ac97_dai_ops = { 340static struct snd_soc_dai_ops au1xpsc_ac97_dai_ops = {
341 .startup = au1xpsc_ac97_startup,
333 .trigger = au1xpsc_ac97_trigger, 342 .trigger = au1xpsc_ac97_trigger,
334 .hw_params = au1xpsc_ac97_hw_params, 343 .hw_params = au1xpsc_ac97_hw_params,
335}; 344};
@@ -355,7 +364,7 @@ static const struct snd_soc_dai_driver au1xpsc_ac97_dai_template = {
355static int __devinit au1xpsc_ac97_drvprobe(struct platform_device *pdev) 364static int __devinit au1xpsc_ac97_drvprobe(struct platform_device *pdev)
356{ 365{
357 int ret; 366 int ret;
358 struct resource *r; 367 struct resource *iores, *dmares;
359 unsigned long sel; 368 unsigned long sel;
360 struct au1xpsc_audio_data *wd; 369 struct au1xpsc_audio_data *wd;
361 370
@@ -365,20 +374,31 @@ static int __devinit au1xpsc_ac97_drvprobe(struct platform_device *pdev)
365 374
366 mutex_init(&wd->lock); 375 mutex_init(&wd->lock);
367 376
368 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 377 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
369 if (!r) { 378 if (!iores) {
370 ret = -ENODEV; 379 ret = -ENODEV;
371 goto out0; 380 goto out0;
372 } 381 }
373 382
374 ret = -EBUSY; 383 ret = -EBUSY;
375 if (!request_mem_region(r->start, resource_size(r), pdev->name)) 384 if (!request_mem_region(iores->start, resource_size(iores),
385 pdev->name))
376 goto out0; 386 goto out0;
377 387
378 wd->mmio = ioremap(r->start, resource_size(r)); 388 wd->mmio = ioremap(iores->start, resource_size(iores));
379 if (!wd->mmio) 389 if (!wd->mmio)
380 goto out1; 390 goto out1;
381 391
392 dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
393 if (!dmares)
394 goto out2;
395 wd->dmaids[SNDRV_PCM_STREAM_PLAYBACK] = dmares->start;
396
397 dmares = platform_get_resource(pdev, IORESOURCE_DMA, 1);
398 if (!dmares)
399 goto out2;
400 wd->dmaids[SNDRV_PCM_STREAM_CAPTURE] = dmares->start;
401
382 /* configuration: max dma trigger threshold, enable ac97 */ 402 /* configuration: max dma trigger threshold, enable ac97 */
383 wd->cfg = PSC_AC97CFG_RT_FIFO8 | PSC_AC97CFG_TT_FIFO8 | 403 wd->cfg = PSC_AC97CFG_RT_FIFO8 | PSC_AC97CFG_TT_FIFO8 |
384 PSC_AC97CFG_DE_ENABLE; 404 PSC_AC97CFG_DE_ENABLE;
@@ -401,17 +421,15 @@ static int __devinit au1xpsc_ac97_drvprobe(struct platform_device *pdev)
401 421
402 ret = snd_soc_register_dai(&pdev->dev, &wd->dai_drv); 422 ret = snd_soc_register_dai(&pdev->dev, &wd->dai_drv);
403 if (ret) 423 if (ret)
404 goto out1; 424 goto out2;
405 425
406 wd->dmapd = au1xpsc_pcm_add(pdev); 426 au1xpsc_ac97_workdata = wd;
407 if (wd->dmapd) { 427 return 0;
408 au1xpsc_ac97_workdata = wd;
409 return 0;
410 }
411 428
412 snd_soc_unregister_dai(&pdev->dev); 429out2:
430 iounmap(wd->mmio);
413out1: 431out1:
414 release_mem_region(r->start, resource_size(r)); 432 release_mem_region(iores->start, resource_size(iores));
415out0: 433out0:
416 kfree(wd); 434 kfree(wd);
417 return ret; 435 return ret;
@@ -422,9 +440,6 @@ static int __devexit au1xpsc_ac97_drvremove(struct platform_device *pdev)
422 struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev); 440 struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev);
423 struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 441 struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
424 442
425 if (wd->dmapd)
426 au1xpsc_pcm_destroy(wd->dmapd);
427
428 snd_soc_unregister_dai(&pdev->dev); 443 snd_soc_unregister_dai(&pdev->dev);
429 444
430 /* disable PSC completely */ 445 /* disable PSC completely */
diff --git a/sound/soc/au1x/psc-i2s.c b/sound/soc/au1x/psc-i2s.c
index fca09127632..e03c5ce01b3 100644
--- a/sound/soc/au1x/psc-i2s.c
+++ b/sound/soc/au1x/psc-i2s.c
@@ -42,13 +42,13 @@
42 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) 42 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE)
43 43
44#define I2SSTAT_BUSY(stype) \ 44#define I2SSTAT_BUSY(stype) \
45 ((stype) == PCM_TX ? PSC_I2SSTAT_TB : PSC_I2SSTAT_RB) 45 ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_I2SSTAT_TB : PSC_I2SSTAT_RB)
46#define I2SPCR_START(stype) \ 46#define I2SPCR_START(stype) \
47 ((stype) == PCM_TX ? PSC_I2SPCR_TS : PSC_I2SPCR_RS) 47 ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_I2SPCR_TS : PSC_I2SPCR_RS)
48#define I2SPCR_STOP(stype) \ 48#define I2SPCR_STOP(stype) \
49 ((stype) == PCM_TX ? PSC_I2SPCR_TP : PSC_I2SPCR_RP) 49 ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_I2SPCR_TP : PSC_I2SPCR_RP)
50#define I2SPCR_CLRFIFO(stype) \ 50#define I2SPCR_CLRFIFO(stype) \
51 ((stype) == PCM_TX ? PSC_I2SPCR_TC : PSC_I2SPCR_RC) 51 ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_I2SPCR_TC : PSC_I2SPCR_RC)
52 52
53 53
54static int au1xpsc_i2s_set_fmt(struct snd_soc_dai *cpu_dai, 54static int au1xpsc_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
@@ -240,7 +240,7 @@ static int au1xpsc_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
240 struct snd_soc_dai *dai) 240 struct snd_soc_dai *dai)
241{ 241{
242 struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai); 242 struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai);
243 int ret, stype = SUBSTREAM_TYPE(substream); 243 int ret, stype = substream->stream;
244 244
245 switch (cmd) { 245 switch (cmd) {
246 case SNDRV_PCM_TRIGGER_START: 246 case SNDRV_PCM_TRIGGER_START:
@@ -257,7 +257,16 @@ static int au1xpsc_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
257 return ret; 257 return ret;
258} 258}
259 259
260static int au1xpsc_i2s_startup(struct snd_pcm_substream *substream,
261 struct snd_soc_dai *dai)
262{
263 struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai);
264 snd_soc_dai_set_dma_data(dai, substream, &pscdata->dmaids[0]);
265 return 0;
266}
267
260static struct snd_soc_dai_ops au1xpsc_i2s_dai_ops = { 268static struct snd_soc_dai_ops au1xpsc_i2s_dai_ops = {
269 .startup = au1xpsc_i2s_startup,
261 .trigger = au1xpsc_i2s_trigger, 270 .trigger = au1xpsc_i2s_trigger,
262 .hw_params = au1xpsc_i2s_hw_params, 271 .hw_params = au1xpsc_i2s_hw_params,
263 .set_fmt = au1xpsc_i2s_set_fmt, 272 .set_fmt = au1xpsc_i2s_set_fmt,
@@ -281,7 +290,7 @@ static const struct snd_soc_dai_driver au1xpsc_i2s_dai_template = {
281 290
282static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev) 291static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev)
283{ 292{
284 struct resource *r; 293 struct resource *iores, *dmares;
285 unsigned long sel; 294 unsigned long sel;
286 int ret; 295 int ret;
287 struct au1xpsc_audio_data *wd; 296 struct au1xpsc_audio_data *wd;
@@ -290,20 +299,31 @@ static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev)
290 if (!wd) 299 if (!wd)
291 return -ENOMEM; 300 return -ENOMEM;
292 301
293 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 302 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
294 if (!r) { 303 if (!iores) {
295 ret = -ENODEV; 304 ret = -ENODEV;
296 goto out0; 305 goto out0;
297 } 306 }
298 307
299 ret = -EBUSY; 308 ret = -EBUSY;
300 if (!request_mem_region(r->start, resource_size(r), pdev->name)) 309 if (!request_mem_region(iores->start, resource_size(iores),
310 pdev->name))
301 goto out0; 311 goto out0;
302 312
303 wd->mmio = ioremap(r->start, resource_size(r)); 313 wd->mmio = ioremap(iores->start, resource_size(iores));
304 if (!wd->mmio) 314 if (!wd->mmio)
305 goto out1; 315 goto out1;
306 316
317 dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
318 if (!dmares)
319 goto out2;
320 wd->dmaids[SNDRV_PCM_STREAM_PLAYBACK] = dmares->start;
321
322 dmares = platform_get_resource(pdev, IORESOURCE_DMA, 1);
323 if (!dmares)
324 goto out2;
325 wd->dmaids[SNDRV_PCM_STREAM_CAPTURE] = dmares->start;
326
307 /* preserve PSC clock source set up by platform (dev.platform_data 327 /* preserve PSC clock source set up by platform (dev.platform_data
308 * is already occupied by soc layer) 328 * is already occupied by soc layer)
309 */ 329 */
@@ -330,17 +350,13 @@ static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev)
330 platform_set_drvdata(pdev, wd); 350 platform_set_drvdata(pdev, wd);
331 351
332 ret = snd_soc_register_dai(&pdev->dev, &wd->dai_drv); 352 ret = snd_soc_register_dai(&pdev->dev, &wd->dai_drv);
333 if (ret) 353 if (!ret)
334 goto out1;
335
336 /* finally add the DMA device for this PSC */
337 wd->dmapd = au1xpsc_pcm_add(pdev);
338 if (wd->dmapd)
339 return 0; 354 return 0;
340 355
341 snd_soc_unregister_dai(&pdev->dev); 356out2:
357 iounmap(wd->mmio);
342out1: 358out1:
343 release_mem_region(r->start, resource_size(r)); 359 release_mem_region(iores->start, resource_size(iores));
344out0: 360out0:
345 kfree(wd); 361 kfree(wd);
346 return ret; 362 return ret;
@@ -351,9 +367,6 @@ static int __devexit au1xpsc_i2s_drvremove(struct platform_device *pdev)
351 struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev); 367 struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev);
352 struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 368 struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
353 369
354 if (wd->dmapd)
355 au1xpsc_pcm_destroy(wd->dmapd);
356
357 snd_soc_unregister_dai(&pdev->dev); 370 snd_soc_unregister_dai(&pdev->dev);
358 371
359 au_writel(0, I2S_CFG(wd)); 372 au_writel(0, I2S_CFG(wd));
diff --git a/sound/soc/au1x/psc.h b/sound/soc/au1x/psc.h
index b30eadd422a..b16b2e02e0c 100644
--- a/sound/soc/au1x/psc.h
+++ b/sound/soc/au1x/psc.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Au12x0/Au1550 PSC ALSA ASoC audio support. 2 * Alchemy ALSA ASoC audio support.
3 * 3 *
4 * (c) 2007-2008 MSC Vertriebsges.m.b.H., 4 * (c) 2007-2011 MSC Vertriebsges.m.b.H.,
5 * Manuel Lauss <manuel.lauss@gmail.com> 5 * Manuel Lauss <manuel.lauss@gmail.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
@@ -13,10 +13,6 @@
13#ifndef _AU1X_PCM_H 13#ifndef _AU1X_PCM_H
14#define _AU1X_PCM_H 14#define _AU1X_PCM_H
15 15
16/* DBDMA helpers */
17extern struct platform_device *au1xpsc_pcm_add(struct platform_device *pdev);
18extern void au1xpsc_pcm_destroy(struct platform_device *dmapd);
19
20struct au1xpsc_audio_data { 16struct au1xpsc_audio_data {
21 void __iomem *mmio; 17 void __iomem *mmio;
22 18
@@ -27,15 +23,9 @@ struct au1xpsc_audio_data {
27 23
28 unsigned long pm[2]; 24 unsigned long pm[2];
29 struct mutex lock; 25 struct mutex lock;
30 struct platform_device *dmapd; 26 int dmaids[2];
31}; 27};
32 28
33#define PCM_TX 0
34#define PCM_RX 1
35
36#define SUBSTREAM_TYPE(substream) \
37 ((substream)->stream == SNDRV_PCM_STREAM_PLAYBACK ? PCM_TX : PCM_RX)
38
39/* easy access macros */ 29/* easy access macros */
40#define PSC_CTRL(x) ((unsigned long)((x)->mmio) + PSC_CTRL_OFFSET) 30#define PSC_CTRL(x) ((unsigned long)((x)->mmio) + PSC_CTRL_OFFSET)
41#define PSC_SEL(x) ((unsigned long)((x)->mmio) + PSC_SEL_OFFSET) 31#define PSC_SEL(x) ((unsigned long)((x)->mmio) + PSC_SEL_OFFSET)
diff --git a/sound/soc/blackfin/Kconfig b/sound/soc/blackfin/Kconfig
index fe9d548a683..9f6bc55fc39 100644
--- a/sound/soc/blackfin/Kconfig
+++ b/sound/soc/blackfin/Kconfig
@@ -27,6 +27,19 @@ config SND_SOC_BFIN_EVAL_ADAU1701
27 board connected to one of the Blackfin evaluation boards like the 27 board connected to one of the Blackfin evaluation boards like the
28 BF5XX-STAMP or BF5XX-EZKIT. 28 BF5XX-STAMP or BF5XX-EZKIT.
29 29
30config SND_SOC_BFIN_EVAL_ADAU1373
31 tristate "Support for the EVAL-ADAU1373 board on Blackfin eval boards"
32 depends on SND_BF5XX_I2S && I2C
33 select SND_BF5XX_SOC_I2S
34 select SND_SOC_ADAU1373
35 help
36 Say Y if you want to add support for the Analog Devices EVAL-ADAU1373
37 board connected to one of the Blackfin evaluation boards like the
38 BF5XX-STAMP or BF5XX-EZKIT.
39
40 Note: This driver assumes that first ADAU1373 DAI is connected to the
41 first SPORT port on the BF5XX board.
42
30config SND_SOC_BFIN_EVAL_ADAV80X 43config SND_SOC_BFIN_EVAL_ADAV80X
31 tristate "Support for the EVAL-ADAV80X boards on Blackfin eval boards" 44 tristate "Support for the EVAL-ADAV80X boards on Blackfin eval boards"
32 depends on SND_BF5XX_I2S && (SPI_MASTER || I2C) 45 depends on SND_BF5XX_I2S && (SPI_MASTER || I2C)
diff --git a/sound/soc/blackfin/Makefile b/sound/soc/blackfin/Makefile
index 6018bf52a23..1bf86ccaa8d 100644
--- a/sound/soc/blackfin/Makefile
+++ b/sound/soc/blackfin/Makefile
@@ -21,6 +21,7 @@ snd-ad1980-objs := bf5xx-ad1980.o
21snd-ssm2602-objs := bf5xx-ssm2602.o 21snd-ssm2602-objs := bf5xx-ssm2602.o
22snd-ad73311-objs := bf5xx-ad73311.o 22snd-ad73311-objs := bf5xx-ad73311.o
23snd-ad193x-objs := bf5xx-ad193x.o 23snd-ad193x-objs := bf5xx-ad193x.o
24snd-soc-bfin-eval-adau1373-objs := bfin-eval-adau1373.o
24snd-soc-bfin-eval-adau1701-objs := bfin-eval-adau1701.o 25snd-soc-bfin-eval-adau1701-objs := bfin-eval-adau1701.o
25snd-soc-bfin-eval-adav80x-objs := bfin-eval-adav80x.o 26snd-soc-bfin-eval-adav80x-objs := bfin-eval-adav80x.o
26 27
@@ -29,5 +30,6 @@ obj-$(CONFIG_SND_BF5XX_SOC_AD1980) += snd-ad1980.o
29obj-$(CONFIG_SND_BF5XX_SOC_SSM2602) += snd-ssm2602.o 30obj-$(CONFIG_SND_BF5XX_SOC_SSM2602) += snd-ssm2602.o
30obj-$(CONFIG_SND_BF5XX_SOC_AD73311) += snd-ad73311.o 31obj-$(CONFIG_SND_BF5XX_SOC_AD73311) += snd-ad73311.o
31obj-$(CONFIG_SND_BF5XX_SOC_AD193X) += snd-ad193x.o 32obj-$(CONFIG_SND_BF5XX_SOC_AD193X) += snd-ad193x.o
33obj-$(CONFIG_SND_SOC_BFIN_EVAL_ADAU1373) += snd-soc-bfin-eval-adau1373.o
32obj-$(CONFIG_SND_SOC_BFIN_EVAL_ADAU1701) += snd-soc-bfin-eval-adau1701.o 34obj-$(CONFIG_SND_SOC_BFIN_EVAL_ADAU1701) += snd-soc-bfin-eval-adau1701.o
33obj-$(CONFIG_SND_SOC_BFIN_EVAL_ADAV80X) += snd-soc-bfin-eval-adav80x.o 35obj-$(CONFIG_SND_SOC_BFIN_EVAL_ADAV80X) += snd-soc-bfin-eval-adav80x.o
diff --git a/sound/soc/blackfin/bf5xx-ac97-pcm.c b/sound/soc/blackfin/bf5xx-ac97-pcm.c
index 9e59f680bc1..56815c1d47b 100644
--- a/sound/soc/blackfin/bf5xx-ac97-pcm.c
+++ b/sound/soc/blackfin/bf5xx-ac97-pcm.c
@@ -418,7 +418,7 @@ static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
418 418
419static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32); 419static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32);
420 420
421int bf5xx_pcm_ac97_new(struct snd_soc_pcm_runtime *rtd) 421static int bf5xx_pcm_ac97_new(struct snd_soc_pcm_runtime *rtd)
422{ 422{
423 struct snd_card *card = rtd->card->snd_card; 423 struct snd_card *card = rtd->card->snd_card;
424 struct snd_soc_dai *dai = rtd->cpu_dai; 424 struct snd_soc_dai *dai = rtd->cpu_dai;
diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.c b/sound/soc/blackfin/bf5xx-i2s-pcm.c
index 61ddf942fd4..7565e1576ff 100644
--- a/sound/soc/blackfin/bf5xx-i2s-pcm.c
+++ b/sound/soc/blackfin/bf5xx-i2s-pcm.c
@@ -257,7 +257,7 @@ static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
257 257
258static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32); 258static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32);
259 259
260int bf5xx_pcm_i2s_new(struct snd_soc_pcm_runtime *rtd) 260static int bf5xx_pcm_i2s_new(struct snd_soc_pcm_runtime *rtd)
261{ 261{
262 struct snd_card *card = rtd->card->snd_card; 262 struct snd_card *card = rtd->card->snd_card;
263 struct snd_soc_dai *dai = rtd->cpu_dai; 263 struct snd_soc_dai *dai = rtd->cpu_dai;
diff --git a/sound/soc/blackfin/bfin-eval-adau1373.c b/sound/soc/blackfin/bfin-eval-adau1373.c
new file mode 100644
index 00000000000..8df2a3b0cb3
--- /dev/null
+++ b/sound/soc/blackfin/bfin-eval-adau1373.c
@@ -0,0 +1,202 @@
1/*
2 * Machine driver for EVAL-ADAU1373 on Analog Devices bfin
3 * evaluation boards.
4 *
5 * Copyright 2011 Analog Devices Inc.
6 * Author: Lars-Peter Clausen <lars@metafoo.de>
7 *
8 * Licensed under the GPL-2 or later.
9 */
10
11#include <linux/module.h>
12#include <linux/device.h>
13#include <sound/core.h>
14#include <sound/pcm.h>
15#include <sound/soc.h>
16#include <sound/pcm_params.h>
17
18#include "../codecs/adau1373.h"
19
20static const struct snd_soc_dapm_widget bfin_eval_adau1373_dapm_widgets[] = {
21 SND_SOC_DAPM_LINE("Line In1", NULL),
22 SND_SOC_DAPM_LINE("Line In2", NULL),
23 SND_SOC_DAPM_LINE("Line In3", NULL),
24 SND_SOC_DAPM_LINE("Line In4", NULL),
25
26 SND_SOC_DAPM_LINE("Line Out1", NULL),
27 SND_SOC_DAPM_LINE("Line Out2", NULL),
28 SND_SOC_DAPM_LINE("Stereo Out", NULL),
29 SND_SOC_DAPM_HP("Headphone", NULL),
30 SND_SOC_DAPM_HP("Earpiece", NULL),
31 SND_SOC_DAPM_SPK("Speaker", NULL),
32};
33
34static const struct snd_soc_dapm_route bfin_eval_adau1373_dapm_routes[] = {
35 { "AIN1L", NULL, "Line In1" },
36 { "AIN1R", NULL, "Line In1" },
37 { "AIN2L", NULL, "Line In2" },
38 { "AIN2R", NULL, "Line In2" },
39 { "AIN3L", NULL, "Line In3" },
40 { "AIN3R", NULL, "Line In3" },
41 { "AIN4L", NULL, "Line In4" },
42 { "AIN4R", NULL, "Line In4" },
43
44 /* MICBIAS can be connected via a jumper to the line-in jack, since w
45 don't know which one is going to be used, just power both. */
46 { "Line In1", NULL, "MICBIAS1" },
47 { "Line In2", NULL, "MICBIAS1" },
48 { "Line In3", NULL, "MICBIAS1" },
49 { "Line In4", NULL, "MICBIAS1" },
50 { "Line In1", NULL, "MICBIAS2" },
51 { "Line In2", NULL, "MICBIAS2" },
52 { "Line In3", NULL, "MICBIAS2" },
53 { "Line In4", NULL, "MICBIAS2" },
54
55 { "Line Out1", NULL, "LOUT1L" },
56 { "Line Out1", NULL, "LOUT1R" },
57 { "Line Out2", NULL, "LOUT2L" },
58 { "Line Out2", NULL, "LOUT2R" },
59 { "Headphone", NULL, "HPL" },
60 { "Headphone", NULL, "HPR" },
61 { "Earpiece", NULL, "EP" },
62 { "Speaker", NULL, "SPKL" },
63 { "Stereo Out", NULL, "SPKR" },
64};
65
66static int bfin_eval_adau1373_hw_params(struct snd_pcm_substream *substream,
67 struct snd_pcm_hw_params *params)
68{
69 struct snd_soc_pcm_runtime *rtd = substream->private_data;
70 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
71 struct snd_soc_dai *codec_dai = rtd->codec_dai;
72 int ret;
73 int pll_rate;
74
75 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
76 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
77 if (ret)
78 return ret;
79
80 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
81 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
82 if (ret)
83 return ret;
84
85 switch (params_rate(params)) {
86 case 48000:
87 case 8000:
88 case 12000:
89 case 16000:
90 case 24000:
91 case 32000:
92 pll_rate = 48000 * 1024;
93 break;
94 case 44100:
95 case 7350:
96 case 11025:
97 case 14700:
98 case 22050:
99 case 29400:
100 pll_rate = 44100 * 1024;
101 break;
102 default:
103 return -EINVAL;
104 }
105
106 ret = snd_soc_dai_set_pll(codec_dai, ADAU1373_PLL1,
107 ADAU1373_PLL_SRC_MCLK1, 12288000, pll_rate);
108 if (ret)
109 return ret;
110
111 ret = snd_soc_dai_set_sysclk(codec_dai, ADAU1373_CLK_SRC_PLL1, pll_rate,
112 SND_SOC_CLOCK_IN);
113
114 return ret;
115}
116
117static int bfin_eval_adau1373_codec_init(struct snd_soc_pcm_runtime *rtd)
118{
119 struct snd_soc_dai *codec_dai = rtd->codec_dai;
120 unsigned int pll_rate = 48000 * 1024;
121 int ret;
122
123 ret = snd_soc_dai_set_pll(codec_dai, ADAU1373_PLL1,
124 ADAU1373_PLL_SRC_MCLK1, 12288000, pll_rate);
125 if (ret)
126 return ret;
127
128 ret = snd_soc_dai_set_sysclk(codec_dai, ADAU1373_CLK_SRC_PLL1, pll_rate,
129 SND_SOC_CLOCK_IN);
130
131 return ret;
132}
133static struct snd_soc_ops bfin_eval_adau1373_ops = {
134 .hw_params = bfin_eval_adau1373_hw_params,
135};
136
137static struct snd_soc_dai_link bfin_eval_adau1373_dai = {
138 .name = "adau1373",
139 .stream_name = "adau1373",
140 .cpu_dai_name = "bfin-i2s.0",
141 .codec_dai_name = "adau1373-aif1",
142 .platform_name = "bfin-i2s-pcm-audio",
143 .codec_name = "adau1373.0-001a",
144 .ops = &bfin_eval_adau1373_ops,
145 .init = bfin_eval_adau1373_codec_init,
146};
147
148static struct snd_soc_card bfin_eval_adau1373 = {
149 .name = "bfin-eval-adau1373",
150 .dai_link = &bfin_eval_adau1373_dai,
151 .num_links = 1,
152
153 .dapm_widgets = bfin_eval_adau1373_dapm_widgets,
154 .num_dapm_widgets = ARRAY_SIZE(bfin_eval_adau1373_dapm_widgets),
155 .dapm_routes = bfin_eval_adau1373_dapm_routes,
156 .num_dapm_routes = ARRAY_SIZE(bfin_eval_adau1373_dapm_routes),
157};
158
159static int bfin_eval_adau1373_probe(struct platform_device *pdev)
160{
161 struct snd_soc_card *card = &bfin_eval_adau1373;
162
163 card->dev = &pdev->dev;
164
165 return snd_soc_register_card(&bfin_eval_adau1373);
166}
167
168static int __devexit bfin_eval_adau1373_remove(struct platform_device *pdev)
169{
170 struct snd_soc_card *card = platform_get_drvdata(pdev);
171
172 snd_soc_unregister_card(card);
173
174 return 0;
175}
176
177static struct platform_driver bfin_eval_adau1373_driver = {
178 .driver = {
179 .name = "bfin-eval-adau1373",
180 .owner = THIS_MODULE,
181 .pm = &snd_soc_pm_ops,
182 },
183 .probe = bfin_eval_adau1373_probe,
184 .remove = __devexit_p(bfin_eval_adau1373_remove),
185};
186
187static int __init bfin_eval_adau1373_init(void)
188{
189 return platform_driver_register(&bfin_eval_adau1373_driver);
190}
191module_init(bfin_eval_adau1373_init);
192
193static void __exit bfin_eval_adau1373_exit(void)
194{
195 platform_driver_unregister(&bfin_eval_adau1373_driver);
196}
197module_exit(bfin_eval_adau1373_exit);
198
199MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
200MODULE_DESCRIPTION("ALSA SoC bfin adau1373 driver");
201MODULE_LICENSE("GPL");
202MODULE_ALIAS("platform:bfin-eval-adau1373");
diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c
index 19241576b6b..5ca122e5118 100644
--- a/sound/soc/codecs/88pm860x-codec.c
+++ b/sound/soc/codecs/88pm860x-codec.c
@@ -15,6 +15,7 @@
15#include <linux/platform_device.h> 15#include <linux/platform_device.h>
16#include <linux/mfd/88pm860x.h> 16#include <linux/mfd/88pm860x.h>
17#include <linux/slab.h> 17#include <linux/slab.h>
18#include <linux/delay.h>
18#include <sound/core.h> 19#include <sound/core.h>
19#include <sound/pcm.h> 20#include <sound/pcm.h>
20#include <sound/pcm_params.h> 21#include <sound/pcm_params.h>
@@ -772,11 +773,12 @@ static const struct snd_soc_dapm_widget pm860x_dapm_widgets[] = {
772 773
773 774
774 SND_SOC_DAPM_AIF_IN("I2S DIN", "I2S Playback", 0, 775 SND_SOC_DAPM_AIF_IN("I2S DIN", "I2S Playback", 0,
775 PM860X_DAC_EN_2, 0, 0), 776 SND_SOC_NOPM, 0, 0),
776 SND_SOC_DAPM_AIF_IN("I2S DIN1", "I2S Playback", 0, 777 SND_SOC_DAPM_AIF_IN("I2S DIN1", "I2S Playback", 0,
777 PM860X_DAC_EN_2, 0, 0), 778 SND_SOC_NOPM, 0, 0),
778 SND_SOC_DAPM_AIF_OUT("I2S DOUT", "I2S Capture", 0, 779 SND_SOC_DAPM_AIF_OUT("I2S DOUT", "I2S Capture", 0,
779 PM860X_I2S_IFACE_3, 5, 1), 780 PM860X_I2S_IFACE_3, 5, 1),
781 SND_SOC_DAPM_SUPPLY("I2S CLK", PM860X_DAC_EN_2, 0, 0, NULL, 0),
780 SND_SOC_DAPM_MUX("I2S Mic Mux", SND_SOC_NOPM, 0, 0, &i2s_mic_mux), 782 SND_SOC_DAPM_MUX("I2S Mic Mux", SND_SOC_NOPM, 0, 0, &i2s_mic_mux),
781 SND_SOC_DAPM_MUX("ADC Left Mux", SND_SOC_NOPM, 0, 0, &adcl_mux), 783 SND_SOC_DAPM_MUX("ADC Left Mux", SND_SOC_NOPM, 0, 0, &adcl_mux),
782 SND_SOC_DAPM_MUX("ADC Right Mux", SND_SOC_NOPM, 0, 0, &adcr_mux), 784 SND_SOC_DAPM_MUX("ADC Right Mux", SND_SOC_NOPM, 0, 0, &adcr_mux),
@@ -868,6 +870,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
868 {"Left ADC", NULL, "Left ADC MOD"}, 870 {"Left ADC", NULL, "Left ADC MOD"},
869 {"Right ADC", NULL, "Right ADC MOD"}, 871 {"Right ADC", NULL, "Right ADC MOD"},
870 872
873 /* I2S Clock */
874 {"I2S DIN", NULL, "I2S CLK"},
875 {"I2S DIN1", NULL, "I2S CLK"},
876 {"I2S DOUT", NULL, "I2S CLK"},
877
871 /* PCM/AIF1 Inputs */ 878 /* PCM/AIF1 Inputs */
872 {"PCM SDO", NULL, "ADC Left Mux"}, 879 {"PCM SDO", NULL, "ADC Left Mux"},
873 {"PCM SDO", NULL, "ADCR EC Mux"}, 880 {"PCM SDO", NULL, "ADCR EC Mux"},
@@ -1173,6 +1180,9 @@ static int pm860x_set_bias_level(struct snd_soc_codec *codec,
1173 case SND_SOC_BIAS_STANDBY: 1180 case SND_SOC_BIAS_STANDBY:
1174 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { 1181 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1175 /* Enable Audio PLL & Audio section */ 1182 /* Enable Audio PLL & Audio section */
1183 data = AUDIO_PLL | AUDIO_SECTION_ON;
1184 pm860x_reg_write(codec->control_data, REG_MISC2, data);
1185 udelay(300);
1176 data = AUDIO_PLL | AUDIO_SECTION_RESET 1186 data = AUDIO_PLL | AUDIO_SECTION_RESET
1177 | AUDIO_SECTION_ON; 1187 | AUDIO_SECTION_ON;
1178 pm860x_reg_write(codec->control_data, REG_MISC2, data); 1188 pm860x_reg_write(codec->control_data, REG_MISC2, data);
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 665d9240c4a..4584514d93d 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -17,6 +17,7 @@ config SND_SOC_ALL_CODECS
17 select SND_SOC_AD193X if SND_SOC_I2C_AND_SPI 17 select SND_SOC_AD193X if SND_SOC_I2C_AND_SPI
18 select SND_SOC_AD1980 if SND_SOC_AC97_BUS 18 select SND_SOC_AD1980 if SND_SOC_AC97_BUS
19 select SND_SOC_AD73311 19 select SND_SOC_AD73311
20 select SND_SOC_ADAU1373 if I2C
20 select SND_SOC_ADAV80X 21 select SND_SOC_ADAV80X
21 select SND_SOC_ADS117X 22 select SND_SOC_ADS117X
22 select SND_SOC_AK4104 if SPI_MASTER 23 select SND_SOC_AK4104 if SPI_MASTER
@@ -39,6 +40,7 @@ config SND_SOC_ALL_CODECS
39 select SND_SOC_MAX9850 if I2C 40 select SND_SOC_MAX9850 if I2C
40 select SND_SOC_MAX9877 if I2C 41 select SND_SOC_MAX9877 if I2C
41 select SND_SOC_PCM3008 42 select SND_SOC_PCM3008
43 select SND_SOC_RT5631 if I2C
42 select SND_SOC_SGTL5000 if I2C 44 select SND_SOC_SGTL5000 if I2C
43 select SND_SOC_SN95031 if INTEL_SCU_IPC 45 select SND_SOC_SN95031 if INTEL_SCU_IPC
44 select SND_SOC_SPDIF 46 select SND_SOC_SPDIF
@@ -47,7 +49,7 @@ config SND_SOC_ALL_CODECS
47 select SND_SOC_STAC9766 if SND_SOC_AC97_BUS 49 select SND_SOC_STAC9766 if SND_SOC_AC97_BUS
48 select SND_SOC_TLV320AIC23 if I2C 50 select SND_SOC_TLV320AIC23 if I2C
49 select SND_SOC_TLV320AIC26 if SPI_MASTER 51 select SND_SOC_TLV320AIC26 if SPI_MASTER
50 select SND_SOC_TVL320AIC32X4 if I2C 52 select SND_SOC_TLV320AIC32X4 if I2C
51 select SND_SOC_TLV320AIC3X if I2C 53 select SND_SOC_TLV320AIC3X if I2C
52 select SND_SOC_TPA6130A2 if I2C 54 select SND_SOC_TPA6130A2 if I2C
53 select SND_SOC_TLV320DAC33 if I2C 55 select SND_SOC_TLV320DAC33 if I2C
@@ -58,6 +60,7 @@ config SND_SOC_ALL_CODECS
58 select SND_SOC_WL1273 if MFD_WL1273_CORE 60 select SND_SOC_WL1273 if MFD_WL1273_CORE
59 select SND_SOC_WM1250_EV1 if I2C 61 select SND_SOC_WM1250_EV1 if I2C
60 select SND_SOC_WM2000 if I2C 62 select SND_SOC_WM2000 if I2C
63 select SND_SOC_WM5100 if I2C
61 select SND_SOC_WM8350 if MFD_WM8350 64 select SND_SOC_WM8350 if MFD_WM8350
62 select SND_SOC_WM8400 if MFD_WM8400 65 select SND_SOC_WM8400 if MFD_WM8400
63 select SND_SOC_WM8510 if SND_SOC_I2C_AND_SPI 66 select SND_SOC_WM8510 if SND_SOC_I2C_AND_SPI
@@ -139,6 +142,9 @@ config SND_SOC_ADAU1701
139 select SIGMA 142 select SIGMA
140 tristate 143 tristate
141 144
145config SND_SOC_ADAU1373
146 tristate
147
142config SND_SOC_ADAV80X 148config SND_SOC_ADAV80X
143 tristate 149 tristate
144 150
@@ -214,6 +220,9 @@ config SND_SOC_MAX9850
214config SND_SOC_PCM3008 220config SND_SOC_PCM3008
215 tristate 221 tristate
216 222
223config SND_SOC_RT5631
224 tristate
225
217#Freescale sgtl5000 codec 226#Freescale sgtl5000 codec
218config SND_SOC_SGTL5000 227config SND_SOC_SGTL5000
219 tristate 228 tristate
@@ -240,7 +249,7 @@ config SND_SOC_TLV320AIC26
240 tristate "TI TLV320AIC26 Codec support" if SND_SOC_OF_SIMPLE 249 tristate "TI TLV320AIC26 Codec support" if SND_SOC_OF_SIMPLE
241 depends on SPI 250 depends on SPI
242 251
243config SND_SOC_TVL320AIC32X4 252config SND_SOC_TLV320AIC32X4
244 tristate 253 tristate
245 254
246config SND_SOC_TLV320AIC3X 255config SND_SOC_TLV320AIC3X
@@ -269,6 +278,9 @@ config SND_SOC_WL1273
269config SND_SOC_WM1250_EV1 278config SND_SOC_WM1250_EV1
270 tristate 279 tristate
271 280
281config SND_SOC_WM5100
282 tristate
283
272config SND_SOC_WM8350 284config SND_SOC_WM8350
273 tristate 285 tristate
274 286
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 5119a7e2c1a..a2c7842e357 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -5,6 +5,7 @@ snd-soc-ad193x-objs := ad193x.o
5snd-soc-ad1980-objs := ad1980.o 5snd-soc-ad1980-objs := ad1980.o
6snd-soc-ad73311-objs := ad73311.o 6snd-soc-ad73311-objs := ad73311.o
7snd-soc-adau1701-objs := adau1701.o 7snd-soc-adau1701-objs := adau1701.o
8snd-soc-adau1373-objs := adau1373.o
8snd-soc-adav80x-objs := adav80x.o 9snd-soc-adav80x-objs := adav80x.o
9snd-soc-ads117x-objs := ads117x.o 10snd-soc-ads117x-objs := ads117x.o
10snd-soc-ak4104-objs := ak4104.o 11snd-soc-ak4104-objs := ak4104.o
@@ -25,6 +26,7 @@ snd-soc-max98088-objs := max98088.o
25snd-soc-max98095-objs := max98095.o 26snd-soc-max98095-objs := max98095.o
26snd-soc-max9850-objs := max9850.o 27snd-soc-max9850-objs := max9850.o
27snd-soc-pcm3008-objs := pcm3008.o 28snd-soc-pcm3008-objs := pcm3008.o
29snd-soc-rt5631-objs := rt5631.o
28snd-soc-sgtl5000-objs := sgtl5000.o 30snd-soc-sgtl5000-objs := sgtl5000.o
29snd-soc-alc5623-objs := alc5623.o 31snd-soc-alc5623-objs := alc5623.o
30snd-soc-sn95031-objs := sn95031.o 32snd-soc-sn95031-objs := sn95031.o
@@ -43,6 +45,7 @@ snd-soc-uda134x-objs := uda134x.o
43snd-soc-uda1380-objs := uda1380.o 45snd-soc-uda1380-objs := uda1380.o
44snd-soc-wl1273-objs := wl1273.o 46snd-soc-wl1273-objs := wl1273.o
45snd-soc-wm1250-ev1-objs := wm1250-ev1.o 47snd-soc-wm1250-ev1-objs := wm1250-ev1.o
48snd-soc-wm5100-objs := wm5100.o wm5100-tables.o
46snd-soc-wm8350-objs := wm8350.o 49snd-soc-wm8350-objs := wm8350.o
47snd-soc-wm8400-objs := wm8400.o 50snd-soc-wm8400-objs := wm8400.o
48snd-soc-wm8510-objs := wm8510.o 51snd-soc-wm8510-objs := wm8510.o
@@ -100,6 +103,7 @@ obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o
100obj-$(CONFIG_SND_SOC_AD193X) += snd-soc-ad193x.o 103obj-$(CONFIG_SND_SOC_AD193X) += snd-soc-ad193x.o
101obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o 104obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o
102obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o 105obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o
106obj-$(CONFIG_SND_SOC_ADAU1373) += snd-soc-adau1373.o
103obj-$(CONFIG_SND_SOC_ADAU1701) += snd-soc-adau1701.o 107obj-$(CONFIG_SND_SOC_ADAU1701) += snd-soc-adau1701.o
104obj-$(CONFIG_SND_SOC_ADAV80X) += snd-soc-adav80x.o 108obj-$(CONFIG_SND_SOC_ADAV80X) += snd-soc-adav80x.o
105obj-$(CONFIG_SND_SOC_ADS117X) += snd-soc-ads117x.o 109obj-$(CONFIG_SND_SOC_ADS117X) += snd-soc-ads117x.o
@@ -123,6 +127,7 @@ obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o
123obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o 127obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o
124obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o 128obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o
125obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o 129obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o
130obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o
126obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o 131obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o
127obj-$(CONFIG_SND_SOC_SN95031) +=snd-soc-sn95031.o 132obj-$(CONFIG_SND_SOC_SN95031) +=snd-soc-sn95031.o
128obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o 133obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o
@@ -132,7 +137,7 @@ obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o
132obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o 137obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o
133obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o 138obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o
134obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o 139obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o
135obj-$(CONFIG_SND_SOC_TVL320AIC32X4) += snd-soc-tlv320aic32x4.o 140obj-$(CONFIG_SND_SOC_TLV320AIC32X4) += snd-soc-tlv320aic32x4.o
136obj-$(CONFIG_SND_SOC_TLV320DAC33) += snd-soc-tlv320dac33.o 141obj-$(CONFIG_SND_SOC_TLV320DAC33) += snd-soc-tlv320dac33.o
137obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o 142obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o
138obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o 143obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o
@@ -140,6 +145,7 @@ obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o
140obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o 145obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o
141obj-$(CONFIG_SND_SOC_WL1273) += snd-soc-wl1273.o 146obj-$(CONFIG_SND_SOC_WL1273) += snd-soc-wl1273.o
142obj-$(CONFIG_SND_SOC_WM1250_EV1) += snd-soc-wm1250-ev1.o 147obj-$(CONFIG_SND_SOC_WM1250_EV1) += snd-soc-wm1250-ev1.o
148obj-$(CONFIG_SND_SOC_WM5100) += snd-soc-wm5100.o
143obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o 149obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o
144obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o 150obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o
145obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o 151obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c
index eedb6f5e582..120602130b5 100644
--- a/sound/soc/codecs/ad193x.c
+++ b/sound/soc/codecs/ad193x.c
@@ -23,7 +23,7 @@
23 23
24/* codec private data */ 24/* codec private data */
25struct ad193x_priv { 25struct ad193x_priv {
26 enum snd_soc_control_type control_type; 26 struct regmap *regmap;
27 int sysclk; 27 int sysclk;
28}; 28};
29 29
@@ -103,12 +103,14 @@ static const struct snd_soc_dapm_route audio_paths[] = {
103static int ad193x_mute(struct snd_soc_dai *dai, int mute) 103static int ad193x_mute(struct snd_soc_dai *dai, int mute)
104{ 104{
105 struct snd_soc_codec *codec = dai->codec; 105 struct snd_soc_codec *codec = dai->codec;
106 int reg;
107 106
108 reg = snd_soc_read(codec, AD193X_DAC_CTRL2); 107 if (mute)
109 reg = (mute > 0) ? reg | AD193X_DAC_MASTER_MUTE : reg & 108 snd_soc_update_bits(codec, AD193X_DAC_CTRL2,
110 (~AD193X_DAC_MASTER_MUTE); 109 AD193X_DAC_MASTER_MUTE,
111 snd_soc_write(codec, AD193X_DAC_CTRL2, reg); 110 AD193X_DAC_MASTER_MUTE);
111 else
112 snd_soc_update_bits(codec, AD193X_DAC_CTRL2,
113 AD193X_DAC_MASTER_MUTE, 0);
112 114
113 return 0; 115 return 0;
114} 116}
@@ -262,7 +264,7 @@ static int ad193x_hw_params(struct snd_pcm_substream *substream,
262 struct snd_pcm_hw_params *params, 264 struct snd_pcm_hw_params *params,
263 struct snd_soc_dai *dai) 265 struct snd_soc_dai *dai)
264{ 266{
265 int word_len = 0, reg = 0, master_rate = 0; 267 int word_len = 0, master_rate = 0;
266 268
267 struct snd_soc_pcm_runtime *rtd = substream->private_data; 269 struct snd_soc_pcm_runtime *rtd = substream->private_data;
268 struct snd_soc_codec *codec = rtd->codec; 270 struct snd_soc_codec *codec = rtd->codec;
@@ -297,18 +299,15 @@ static int ad193x_hw_params(struct snd_pcm_substream *substream,
297 break; 299 break;
298 } 300 }
299 301
300 reg = snd_soc_read(codec, AD193X_PLL_CLK_CTRL0); 302 snd_soc_update_bits(codec, AD193X_PLL_CLK_CTRL0,
301 reg = (reg & AD193X_PLL_INPUT_MASK) | master_rate; 303 AD193X_PLL_INPUT_MASK, master_rate);
302 snd_soc_write(codec, AD193X_PLL_CLK_CTRL0, reg);
303 304
304 reg = snd_soc_read(codec, AD193X_DAC_CTRL2); 305 snd_soc_update_bits(codec, AD193X_DAC_CTRL2,
305 reg = (reg & (~AD193X_DAC_WORD_LEN_MASK)) 306 AD193X_DAC_WORD_LEN_MASK,
306 | (word_len << AD193X_DAC_WORD_LEN_SHFT); 307 word_len << AD193X_DAC_WORD_LEN_SHFT);
307 snd_soc_write(codec, AD193X_DAC_CTRL2, reg);
308 308
309 reg = snd_soc_read(codec, AD193X_ADC_CTRL1); 309 snd_soc_update_bits(codec, AD193X_ADC_CTRL1,
310 reg = (reg & (~AD193X_ADC_WORD_LEN_MASK)) | word_len; 310 AD193X_ADC_WORD_LEN_MASK, word_len);
311 snd_soc_write(codec, AD193X_ADC_CTRL1, reg);
312 311
313 return 0; 312 return 0;
314} 313}
@@ -349,10 +348,8 @@ static int ad193x_probe(struct snd_soc_codec *codec)
349 struct snd_soc_dapm_context *dapm = &codec->dapm; 348 struct snd_soc_dapm_context *dapm = &codec->dapm;
350 int ret; 349 int ret;
351 350
352 if (ad193x->control_type == SND_SOC_I2C) 351 codec->control_data = ad193x->regmap;
353 ret = snd_soc_codec_set_cache_io(codec, 8, 8, ad193x->control_type); 352 ret = snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP);
354 else
355 ret = snd_soc_codec_set_cache_io(codec, 16, 8, ad193x->control_type);
356 if (ret < 0) { 353 if (ret < 0) {
357 dev_err(codec->dev, "failed to set cache I/O: %d\n", ret); 354 dev_err(codec->dev, "failed to set cache I/O: %d\n", ret);
358 return ret; 355 return ret;
@@ -388,6 +385,14 @@ static struct snd_soc_codec_driver soc_codec_dev_ad193x = {
388}; 385};
389 386
390#if defined(CONFIG_SPI_MASTER) 387#if defined(CONFIG_SPI_MASTER)
388
389static const struct regmap_config ad193x_spi_regmap_config = {
390 .val_bits = 8,
391 .reg_bits = 16,
392 .read_flag_mask = 0x09,
393 .write_flag_mask = 0x08,
394};
395
391static int __devinit ad193x_spi_probe(struct spi_device *spi) 396static int __devinit ad193x_spi_probe(struct spi_device *spi)
392{ 397{
393 struct ad193x_priv *ad193x; 398 struct ad193x_priv *ad193x;
@@ -397,20 +402,36 @@ static int __devinit ad193x_spi_probe(struct spi_device *spi)
397 if (ad193x == NULL) 402 if (ad193x == NULL)
398 return -ENOMEM; 403 return -ENOMEM;
399 404
405 ad193x->regmap = regmap_init_spi(spi, &ad193x_spi_regmap_config);
406 if (IS_ERR(ad193x->regmap)) {
407 ret = PTR_ERR(ad193x->regmap);
408 goto err_free;
409 }
410
400 spi_set_drvdata(spi, ad193x); 411 spi_set_drvdata(spi, ad193x);
401 ad193x->control_type = SND_SOC_SPI;
402 412
403 ret = snd_soc_register_codec(&spi->dev, 413 ret = snd_soc_register_codec(&spi->dev,
404 &soc_codec_dev_ad193x, &ad193x_dai, 1); 414 &soc_codec_dev_ad193x, &ad193x_dai, 1);
405 if (ret < 0) 415 if (ret < 0)
406 kfree(ad193x); 416 goto err_regmap_exit;
417
418 return 0;
419
420err_regmap_exit:
421 regmap_exit(ad193x->regmap);
422err_free:
423 kfree(ad193x);
424
407 return ret; 425 return ret;
408} 426}
409 427
410static int __devexit ad193x_spi_remove(struct spi_device *spi) 428static int __devexit ad193x_spi_remove(struct spi_device *spi)
411{ 429{
430 struct ad193x_priv *ad193x = spi_get_drvdata(spi);
431
412 snd_soc_unregister_codec(&spi->dev); 432 snd_soc_unregister_codec(&spi->dev);
413 kfree(spi_get_drvdata(spi)); 433 regmap_exit(ad193x->regmap);
434 kfree(ad193x);
414 return 0; 435 return 0;
415} 436}
416 437
@@ -425,6 +446,12 @@ static struct spi_driver ad193x_spi_driver = {
425#endif 446#endif
426 447
427#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 448#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
449
450static const struct regmap_config ad193x_i2c_regmap_config = {
451 .val_bits = 8,
452 .reg_bits = 8,
453};
454
428static const struct i2c_device_id ad193x_id[] = { 455static const struct i2c_device_id ad193x_id[] = {
429 { "ad1936", 0 }, 456 { "ad1936", 0 },
430 { "ad1937", 0 }, 457 { "ad1937", 0 },
@@ -442,20 +469,35 @@ static int __devinit ad193x_i2c_probe(struct i2c_client *client,
442 if (ad193x == NULL) 469 if (ad193x == NULL)
443 return -ENOMEM; 470 return -ENOMEM;
444 471
472 ad193x->regmap = regmap_init_i2c(client, &ad193x_i2c_regmap_config);
473 if (IS_ERR(ad193x->regmap)) {
474 ret = PTR_ERR(ad193x->regmap);
475 goto err_free;
476 }
477
445 i2c_set_clientdata(client, ad193x); 478 i2c_set_clientdata(client, ad193x);
446 ad193x->control_type = SND_SOC_I2C;
447 479
448 ret = snd_soc_register_codec(&client->dev, 480 ret = snd_soc_register_codec(&client->dev,
449 &soc_codec_dev_ad193x, &ad193x_dai, 1); 481 &soc_codec_dev_ad193x, &ad193x_dai, 1);
450 if (ret < 0) 482 if (ret < 0)
451 kfree(ad193x); 483 goto err_regmap_exit;
484
485 return 0;
486
487err_regmap_exit:
488 regmap_exit(ad193x->regmap);
489err_free:
490 kfree(ad193x);
452 return ret; 491 return ret;
453} 492}
454 493
455static int __devexit ad193x_i2c_remove(struct i2c_client *client) 494static int __devexit ad193x_i2c_remove(struct i2c_client *client)
456{ 495{
496 struct ad193x_priv *ad193x = i2c_get_clientdata(client);
497
457 snd_soc_unregister_codec(&client->dev); 498 snd_soc_unregister_codec(&client->dev);
458 kfree(i2c_get_clientdata(client)); 499 regmap_exit(ad193x->regmap);
500 kfree(ad193x);
459 return 0; 501 return 0;
460} 502}
461 503
diff --git a/sound/soc/codecs/ad193x.h b/sound/soc/codecs/ad193x.h
index cccc2e8e5fb..1507eaa425a 100644
--- a/sound/soc/codecs/ad193x.h
+++ b/sound/soc/codecs/ad193x.h
@@ -9,20 +9,20 @@
9#ifndef __AD193X_H__ 9#ifndef __AD193X_H__
10#define __AD193X_H__ 10#define __AD193X_H__
11 11
12#define AD193X_PLL_CLK_CTRL0 0x800 12#define AD193X_PLL_CLK_CTRL0 0x00
13#define AD193X_PLL_POWERDOWN 0x01 13#define AD193X_PLL_POWERDOWN 0x01
14#define AD193X_PLL_INPUT_MASK (~0x6) 14#define AD193X_PLL_INPUT_MASK 0x6
15#define AD193X_PLL_INPUT_256 (0 << 1) 15#define AD193X_PLL_INPUT_256 (0 << 1)
16#define AD193X_PLL_INPUT_384 (1 << 1) 16#define AD193X_PLL_INPUT_384 (1 << 1)
17#define AD193X_PLL_INPUT_512 (2 << 1) 17#define AD193X_PLL_INPUT_512 (2 << 1)
18#define AD193X_PLL_INPUT_768 (3 << 1) 18#define AD193X_PLL_INPUT_768 (3 << 1)
19#define AD193X_PLL_CLK_CTRL1 0x801 19#define AD193X_PLL_CLK_CTRL1 0x01
20#define AD193X_DAC_CTRL0 0x802 20#define AD193X_DAC_CTRL0 0x02
21#define AD193X_DAC_POWERDOWN 0x01 21#define AD193X_DAC_POWERDOWN 0x01
22#define AD193X_DAC_SERFMT_MASK 0xC0 22#define AD193X_DAC_SERFMT_MASK 0xC0
23#define AD193X_DAC_SERFMT_STEREO (0 << 6) 23#define AD193X_DAC_SERFMT_STEREO (0 << 6)
24#define AD193X_DAC_SERFMT_TDM (1 << 6) 24#define AD193X_DAC_SERFMT_TDM (1 << 6)
25#define AD193X_DAC_CTRL1 0x803 25#define AD193X_DAC_CTRL1 0x03
26#define AD193X_DAC_2_CHANNELS 0 26#define AD193X_DAC_2_CHANNELS 0
27#define AD193X_DAC_4_CHANNELS 1 27#define AD193X_DAC_4_CHANNELS 1
28#define AD193X_DAC_8_CHANNELS 2 28#define AD193X_DAC_8_CHANNELS 2
@@ -33,11 +33,11 @@
33#define AD193X_DAC_BCLK_MASTER (1 << 5) 33#define AD193X_DAC_BCLK_MASTER (1 << 5)
34#define AD193X_DAC_LEFT_HIGH (1 << 3) 34#define AD193X_DAC_LEFT_HIGH (1 << 3)
35#define AD193X_DAC_BCLK_INV (1 << 7) 35#define AD193X_DAC_BCLK_INV (1 << 7)
36#define AD193X_DAC_CTRL2 0x804 36#define AD193X_DAC_CTRL2 0x04
37#define AD193X_DAC_WORD_LEN_SHFT 3 37#define AD193X_DAC_WORD_LEN_SHFT 3
38#define AD193X_DAC_WORD_LEN_MASK 0x18 38#define AD193X_DAC_WORD_LEN_MASK 0x18
39#define AD193X_DAC_MASTER_MUTE 1 39#define AD193X_DAC_MASTER_MUTE 1
40#define AD193X_DAC_CHNL_MUTE 0x805 40#define AD193X_DAC_CHNL_MUTE 0x05
41#define AD193X_DACL1_MUTE 0 41#define AD193X_DACL1_MUTE 0
42#define AD193X_DACR1_MUTE 1 42#define AD193X_DACR1_MUTE 1
43#define AD193X_DACL2_MUTE 2 43#define AD193X_DACL2_MUTE 2
@@ -46,28 +46,28 @@
46#define AD193X_DACR3_MUTE 5 46#define AD193X_DACR3_MUTE 5
47#define AD193X_DACL4_MUTE 6 47#define AD193X_DACL4_MUTE 6
48#define AD193X_DACR4_MUTE 7 48#define AD193X_DACR4_MUTE 7
49#define AD193X_DAC_L1_VOL 0x806 49#define AD193X_DAC_L1_VOL 0x06
50#define AD193X_DAC_R1_VOL 0x807 50#define AD193X_DAC_R1_VOL 0x07
51#define AD193X_DAC_L2_VOL 0x808 51#define AD193X_DAC_L2_VOL 0x08
52#define AD193X_DAC_R2_VOL 0x809 52#define AD193X_DAC_R2_VOL 0x09
53#define AD193X_DAC_L3_VOL 0x80a 53#define AD193X_DAC_L3_VOL 0x0a
54#define AD193X_DAC_R3_VOL 0x80b 54#define AD193X_DAC_R3_VOL 0x0b
55#define AD193X_DAC_L4_VOL 0x80c 55#define AD193X_DAC_L4_VOL 0x0c
56#define AD193X_DAC_R4_VOL 0x80d 56#define AD193X_DAC_R4_VOL 0x0d
57#define AD193X_ADC_CTRL0 0x80e 57#define AD193X_ADC_CTRL0 0x0e
58#define AD193X_ADC_POWERDOWN 0x01 58#define AD193X_ADC_POWERDOWN 0x01
59#define AD193X_ADC_HIGHPASS_FILTER 1 59#define AD193X_ADC_HIGHPASS_FILTER 1
60#define AD193X_ADCL1_MUTE 2 60#define AD193X_ADCL1_MUTE 2
61#define AD193X_ADCR1_MUTE 3 61#define AD193X_ADCR1_MUTE 3
62#define AD193X_ADCL2_MUTE 4 62#define AD193X_ADCL2_MUTE 4
63#define AD193X_ADCR2_MUTE 5 63#define AD193X_ADCR2_MUTE 5
64#define AD193X_ADC_CTRL1 0x80f 64#define AD193X_ADC_CTRL1 0x0f
65#define AD193X_ADC_SERFMT_MASK 0x60 65#define AD193X_ADC_SERFMT_MASK 0x60
66#define AD193X_ADC_SERFMT_STEREO (0 << 5) 66#define AD193X_ADC_SERFMT_STEREO (0 << 5)
67#define AD193X_ADC_SERFMT_TDM (1 << 5) 67#define AD193X_ADC_SERFMT_TDM (1 << 5)
68#define AD193X_ADC_SERFMT_AUX (2 << 5) 68#define AD193X_ADC_SERFMT_AUX (2 << 5)
69#define AD193X_ADC_WORD_LEN_MASK 0x3 69#define AD193X_ADC_WORD_LEN_MASK 0x3
70#define AD193X_ADC_CTRL2 0x810 70#define AD193X_ADC_CTRL2 0x10
71#define AD193X_ADC_2_CHANNELS 0 71#define AD193X_ADC_2_CHANNELS 0
72#define AD193X_ADC_4_CHANNELS 1 72#define AD193X_ADC_4_CHANNELS 1
73#define AD193X_ADC_8_CHANNELS 2 73#define AD193X_ADC_8_CHANNELS 2
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index 923b364a3e4..e3931cc5e66 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -148,7 +148,6 @@ static struct snd_soc_dai_driver ad1980_dai = {
148 .rates = SNDRV_PCM_RATE_48000, 148 .rates = SNDRV_PCM_RATE_48000,
149 .formats = SND_SOC_STD_AC97_FMTS, }, 149 .formats = SND_SOC_STD_AC97_FMTS, },
150}; 150};
151EXPORT_SYMBOL_GPL(ad1980_dai);
152 151
153static int ad1980_reset(struct snd_soc_codec *codec, int try_warm) 152static int ad1980_reset(struct snd_soc_codec *codec, int try_warm)
154{ 153{
@@ -200,18 +199,22 @@ static int ad1980_soc_probe(struct snd_soc_codec *codec)
200 } 199 }
201 200
202 /* Read out vendor ID to make sure it is ad1980 */ 201 /* Read out vendor ID to make sure it is ad1980 */
203 if (ac97_read(codec, AC97_VENDOR_ID1) != 0x4144) 202 if (ac97_read(codec, AC97_VENDOR_ID1) != 0x4144) {
203 ret = -ENODEV;
204 goto reset_err; 204 goto reset_err;
205 }
205 206
206 vendor_id2 = ac97_read(codec, AC97_VENDOR_ID2); 207 vendor_id2 = ac97_read(codec, AC97_VENDOR_ID2);
207 208
208 if (vendor_id2 != 0x5370) { 209 if (vendor_id2 != 0x5370) {
209 if (vendor_id2 != 0x5374) 210 if (vendor_id2 != 0x5374) {
211 ret = -ENODEV;
210 goto reset_err; 212 goto reset_err;
211 else 213 } else {
212 printk(KERN_WARNING "ad1980: " 214 printk(KERN_WARNING "ad1980: "
213 "Found AD1981 - only 2/2 IN/OUT Channels " 215 "Found AD1981 - only 2/2 IN/OUT Channels "
214 "supported\n"); 216 "supported\n");
217 }
215 } 218 }
216 219
217 /* unmute captures and playbacks volume */ 220 /* unmute captures and playbacks volume */
diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c
new file mode 100644
index 00000000000..1ccf8dd4757
--- /dev/null
+++ b/sound/soc/codecs/adau1373.c
@@ -0,0 +1,1414 @@
1/*
2 * Analog Devices ADAU1373 Audio Codec drive
3 *
4 * Copyright 2011 Analog Devices Inc.
5 * Author: Lars-Peter Clausen <lars@metafoo.de>
6 *
7 * Licensed under the GPL-2 or later.
8 */
9
10#include <linux/module.h>
11#include <linux/init.h>
12#include <linux/delay.h>
13#include <linux/pm.h>
14#include <linux/i2c.h>
15#include <linux/slab.h>
16#include <linux/gcd.h>
17
18#include <sound/core.h>
19#include <sound/pcm.h>
20#include <sound/pcm_params.h>
21#include <sound/tlv.h>
22#include <sound/soc.h>
23#include <sound/adau1373.h>
24
25#include "adau1373.h"
26
27struct adau1373_dai {
28 unsigned int clk_src;
29 unsigned int sysclk;
30 bool enable_src;
31 bool master;
32};
33
34struct adau1373 {
35 struct adau1373_dai dais[3];
36};
37
38#define ADAU1373_INPUT_MODE 0x00
39#define ADAU1373_AINL_CTRL(x) (0x01 + (x) * 2)
40#define ADAU1373_AINR_CTRL(x) (0x02 + (x) * 2)
41#define ADAU1373_LLINE_OUT(x) (0x9 + (x) * 2)
42#define ADAU1373_RLINE_OUT(x) (0xa + (x) * 2)
43#define ADAU1373_LSPK_OUT 0x0d
44#define ADAU1373_RSPK_OUT 0x0e
45#define ADAU1373_LHP_OUT 0x0f
46#define ADAU1373_RHP_OUT 0x10
47#define ADAU1373_ADC_GAIN 0x11
48#define ADAU1373_LADC_MIXER 0x12
49#define ADAU1373_RADC_MIXER 0x13
50#define ADAU1373_LLINE1_MIX 0x14
51#define ADAU1373_RLINE1_MIX 0x15
52#define ADAU1373_LLINE2_MIX 0x16
53#define ADAU1373_RLINE2_MIX 0x17
54#define ADAU1373_LSPK_MIX 0x18
55#define ADAU1373_RSPK_MIX 0x19
56#define ADAU1373_LHP_MIX 0x1a
57#define ADAU1373_RHP_MIX 0x1b
58#define ADAU1373_EP_MIX 0x1c
59#define ADAU1373_HP_CTRL 0x1d
60#define ADAU1373_HP_CTRL2 0x1e
61#define ADAU1373_LS_CTRL 0x1f
62#define ADAU1373_EP_CTRL 0x21
63#define ADAU1373_MICBIAS_CTRL1 0x22
64#define ADAU1373_MICBIAS_CTRL2 0x23
65#define ADAU1373_OUTPUT_CTRL 0x24
66#define ADAU1373_PWDN_CTRL1 0x25
67#define ADAU1373_PWDN_CTRL2 0x26
68#define ADAU1373_PWDN_CTRL3 0x27
69#define ADAU1373_DPLL_CTRL(x) (0x28 + (x) * 7)
70#define ADAU1373_PLL_CTRL1(x) (0x29 + (x) * 7)
71#define ADAU1373_PLL_CTRL2(x) (0x2a + (x) * 7)
72#define ADAU1373_PLL_CTRL3(x) (0x2b + (x) * 7)
73#define ADAU1373_PLL_CTRL4(x) (0x2c + (x) * 7)
74#define ADAU1373_PLL_CTRL5(x) (0x2d + (x) * 7)
75#define ADAU1373_PLL_CTRL6(x) (0x2e + (x) * 7)
76#define ADAU1373_PLL_CTRL7(x) (0x2f + (x) * 7)
77#define ADAU1373_HEADDECT 0x36
78#define ADAU1373_ADC_DAC_STATUS 0x37
79#define ADAU1373_ADC_CTRL 0x3c
80#define ADAU1373_DAI(x) (0x44 + (x))
81#define ADAU1373_CLK_SRC_DIV(x) (0x40 + (x) * 2)
82#define ADAU1373_BCLKDIV(x) (0x47 + (x))
83#define ADAU1373_SRC_RATIOA(x) (0x4a + (x) * 2)
84#define ADAU1373_SRC_RATIOB(x) (0x4b + (x) * 2)
85#define ADAU1373_DEEMP_CTRL 0x50
86#define ADAU1373_SRC_DAI_CTRL(x) (0x51 + (x))
87#define ADAU1373_DIN_MIX_CTRL(x) (0x56 + (x))
88#define ADAU1373_DOUT_MIX_CTRL(x) (0x5b + (x))
89#define ADAU1373_DAI_PBL_VOL(x) (0x62 + (x) * 2)
90#define ADAU1373_DAI_PBR_VOL(x) (0x63 + (x) * 2)
91#define ADAU1373_DAI_RECL_VOL(x) (0x68 + (x) * 2)
92#define ADAU1373_DAI_RECR_VOL(x) (0x69 + (x) * 2)
93#define ADAU1373_DAC1_PBL_VOL 0x6e
94#define ADAU1373_DAC1_PBR_VOL 0x6f
95#define ADAU1373_DAC2_PBL_VOL 0x70
96#define ADAU1373_DAC2_PBR_VOL 0x71
97#define ADAU1373_ADC_RECL_VOL 0x72
98#define ADAU1373_ADC_RECR_VOL 0x73
99#define ADAU1373_DMIC_RECL_VOL 0x74
100#define ADAU1373_DMIC_RECR_VOL 0x75
101#define ADAU1373_VOL_GAIN1 0x76
102#define ADAU1373_VOL_GAIN2 0x77
103#define ADAU1373_VOL_GAIN3 0x78
104#define ADAU1373_HPF_CTRL 0x7d
105#define ADAU1373_BASS1 0x7e
106#define ADAU1373_BASS2 0x7f
107#define ADAU1373_DRC(x) (0x80 + (x) * 0x10)
108#define ADAU1373_3D_CTRL1 0xc0
109#define ADAU1373_3D_CTRL2 0xc1
110#define ADAU1373_FDSP_SEL1 0xdc
111#define ADAU1373_FDSP_SEL2 0xdd
112#define ADAU1373_FDSP_SEL3 0xde
113#define ADAU1373_FDSP_SEL4 0xdf
114#define ADAU1373_DIGMICCTRL 0xe2
115#define ADAU1373_DIGEN 0xeb
116#define ADAU1373_SOFT_RESET 0xff
117
118
119#define ADAU1373_PLL_CTRL6_DPLL_BYPASS BIT(1)
120#define ADAU1373_PLL_CTRL6_PLL_EN BIT(0)
121
122#define ADAU1373_DAI_INVERT_BCLK BIT(7)
123#define ADAU1373_DAI_MASTER BIT(6)
124#define ADAU1373_DAI_INVERT_LRCLK BIT(4)
125#define ADAU1373_DAI_WLEN_16 0x0
126#define ADAU1373_DAI_WLEN_20 0x4
127#define ADAU1373_DAI_WLEN_24 0x8
128#define ADAU1373_DAI_WLEN_32 0xc
129#define ADAU1373_DAI_WLEN_MASK 0xc
130#define ADAU1373_DAI_FORMAT_RIGHT_J 0x0
131#define ADAU1373_DAI_FORMAT_LEFT_J 0x1
132#define ADAU1373_DAI_FORMAT_I2S 0x2
133#define ADAU1373_DAI_FORMAT_DSP 0x3
134
135#define ADAU1373_BCLKDIV_SOURCE BIT(5)
136#define ADAU1373_BCLKDIV_32 0x03
137#define ADAU1373_BCLKDIV_64 0x02
138#define ADAU1373_BCLKDIV_128 0x01
139#define ADAU1373_BCLKDIV_256 0x00
140
141#define ADAU1373_ADC_CTRL_PEAK_DETECT BIT(0)
142#define ADAU1373_ADC_CTRL_RESET BIT(1)
143#define ADAU1373_ADC_CTRL_RESET_FORCE BIT(2)
144
145#define ADAU1373_OUTPUT_CTRL_LDIFF BIT(3)
146#define ADAU1373_OUTPUT_CTRL_LNFBEN BIT(2)
147
148#define ADAU1373_PWDN_CTRL3_PWR_EN BIT(0)
149
150#define ADAU1373_EP_CTRL_MICBIAS1_OFFSET 4
151#define ADAU1373_EP_CTRL_MICBIAS2_OFFSET 2
152
153static const uint8_t adau1373_default_regs[] = {
154 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00 */
155 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
156 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10 */
157 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
158 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20 */
159 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
160 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* 0x30 */
161 0x00, 0x00, 0x00, 0x80, 0x00, 0x01, 0x00, 0x00,
162 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a, 0x0a, 0x00, /* 0x40 */
163 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
164 0x00, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, /* 0x50 */
165 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
166 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60 */
167 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
168 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70 */
169 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
170 0x78, 0x18, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, /* 0x80 */
171 0x00, 0xc0, 0x88, 0x7a, 0xdf, 0x20, 0x00, 0x00,
172 0x78, 0x18, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, /* 0x90 */
173 0x00, 0xc0, 0x88, 0x7a, 0xdf, 0x20, 0x00, 0x00,
174 0x78, 0x18, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, /* 0xa0 */
175 0x00, 0xc0, 0x88, 0x7a, 0xdf, 0x20, 0x00, 0x00,
176 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xb0 */
177 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00,
178 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0 */
179 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
180 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0 */
181 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
182 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* 0xe0 */
183 0x00, 0x1f, 0x0f, 0x00, 0x00,
184};
185
186static const unsigned int adau1373_out_tlv[] = {
187 TLV_DB_RANGE_HEAD(4),
188 0, 7, TLV_DB_SCALE_ITEM(-7900, 400, 1),
189 8, 15, TLV_DB_SCALE_ITEM(-4700, 300, 0),
190 16, 23, TLV_DB_SCALE_ITEM(-2300, 200, 0),
191 24, 31, TLV_DB_SCALE_ITEM(-700, 100, 0),
192};
193
194static const DECLARE_TLV_DB_MINMAX(adau1373_digital_tlv, -9563, 0);
195static const DECLARE_TLV_DB_SCALE(adau1373_in_pga_tlv, -1300, 100, 1);
196static const DECLARE_TLV_DB_SCALE(adau1373_ep_tlv, -600, 600, 1);
197
198static const DECLARE_TLV_DB_SCALE(adau1373_input_boost_tlv, 0, 2000, 0);
199static const DECLARE_TLV_DB_SCALE(adau1373_gain_boost_tlv, 0, 600, 0);
200static const DECLARE_TLV_DB_SCALE(adau1373_speaker_boost_tlv, 1200, 600, 0);
201
202static const char *adau1373_fdsp_sel_text[] = {
203 "None",
204 "Channel 1",
205 "Channel 2",
206 "Channel 3",
207 "Channel 4",
208 "Channel 5",
209};
210
211static const SOC_ENUM_SINGLE_DECL(adau1373_drc1_channel_enum,
212 ADAU1373_FDSP_SEL1, 4, adau1373_fdsp_sel_text);
213static const SOC_ENUM_SINGLE_DECL(adau1373_drc2_channel_enum,
214 ADAU1373_FDSP_SEL1, 0, adau1373_fdsp_sel_text);
215static const SOC_ENUM_SINGLE_DECL(adau1373_drc3_channel_enum,
216 ADAU1373_FDSP_SEL2, 0, adau1373_fdsp_sel_text);
217static const SOC_ENUM_SINGLE_DECL(adau1373_hpf_channel_enum,
218 ADAU1373_FDSP_SEL3, 0, adau1373_fdsp_sel_text);
219static const SOC_ENUM_SINGLE_DECL(adau1373_bass_channel_enum,
220 ADAU1373_FDSP_SEL4, 4, adau1373_fdsp_sel_text);
221
222static const char *adau1373_hpf_cutoff_text[] = {
223 "3.7Hz", "50Hz", "100Hz", "150Hz", "200Hz", "250Hz", "300Hz", "350Hz",
224 "400Hz", "450Hz", "500Hz", "550Hz", "600Hz", "650Hz", "700Hz", "750Hz",
225 "800Hz",
226};
227
228static const SOC_ENUM_SINGLE_DECL(adau1373_hpf_cutoff_enum,
229 ADAU1373_HPF_CTRL, 3, adau1373_hpf_cutoff_text);
230
231static const char *adau1373_bass_lpf_cutoff_text[] = {
232 "801Hz", "1001Hz",
233};
234
235static const char *adau1373_bass_clip_level_text[] = {
236 "0.125", "0.250", "0.370", "0.500", "0.625", "0.750", "0.875",
237};
238
239static const unsigned int adau1373_bass_clip_level_values[] = {
240 1, 2, 3, 4, 5, 6, 7,
241};
242
243static const char *adau1373_bass_hpf_cutoff_text[] = {
244 "158Hz", "232Hz", "347Hz", "520Hz",
245};
246
247static const unsigned int adau1373_bass_tlv[] = {
248 TLV_DB_RANGE_HEAD(4),
249 0, 2, TLV_DB_SCALE_ITEM(-600, 600, 1),
250 3, 4, TLV_DB_SCALE_ITEM(950, 250, 0),
251 5, 7, TLV_DB_SCALE_ITEM(1400, 150, 0),
252};
253
254static const SOC_ENUM_SINGLE_DECL(adau1373_bass_lpf_cutoff_enum,
255 ADAU1373_BASS1, 5, adau1373_bass_lpf_cutoff_text);
256
257static const SOC_VALUE_ENUM_SINGLE_DECL(adau1373_bass_clip_level_enum,
258 ADAU1373_BASS1, 2, 7, adau1373_bass_clip_level_text,
259 adau1373_bass_clip_level_values);
260
261static const SOC_ENUM_SINGLE_DECL(adau1373_bass_hpf_cutoff_enum,
262 ADAU1373_BASS1, 0, adau1373_bass_hpf_cutoff_text);
263
264static const char *adau1373_3d_level_text[] = {
265 "0%", "6.67%", "13.33%", "20%", "26.67%", "33.33%",
266 "40%", "46.67%", "53.33%", "60%", "66.67%", "73.33%",
267 "80%", "86.67", "99.33%", "100%"
268};
269
270static const char *adau1373_3d_cutoff_text[] = {
271 "No 3D", "0.03125 fs", "0.04583 fs", "0.075 fs", "0.11458 fs",
272 "0.16875 fs", "0.27083 fs"
273};
274
275static const SOC_ENUM_SINGLE_DECL(adau1373_3d_level_enum,
276 ADAU1373_3D_CTRL1, 4, adau1373_3d_level_text);
277static const SOC_ENUM_SINGLE_DECL(adau1373_3d_cutoff_enum,
278 ADAU1373_3D_CTRL1, 0, adau1373_3d_cutoff_text);
279
280static const unsigned int adau1373_3d_tlv[] = {
281 TLV_DB_RANGE_HEAD(2),
282 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
283 1, 7, TLV_DB_LINEAR_ITEM(-1800, -120),
284};
285
286static const char *adau1373_lr_mux_text[] = {
287 "Mute",
288 "Right Channel (L+R)",
289 "Left Channel (L+R)",
290 "Stereo",
291};
292
293static const SOC_ENUM_SINGLE_DECL(adau1373_lineout1_lr_mux_enum,
294 ADAU1373_OUTPUT_CTRL, 4, adau1373_lr_mux_text);
295static const SOC_ENUM_SINGLE_DECL(adau1373_lineout2_lr_mux_enum,
296 ADAU1373_OUTPUT_CTRL, 6, adau1373_lr_mux_text);
297static const SOC_ENUM_SINGLE_DECL(adau1373_speaker_lr_mux_enum,
298 ADAU1373_LS_CTRL, 4, adau1373_lr_mux_text);
299
300static const struct snd_kcontrol_new adau1373_controls[] = {
301 SOC_DOUBLE_R_TLV("AIF1 Capture Volume", ADAU1373_DAI_RECL_VOL(0),
302 ADAU1373_DAI_RECR_VOL(0), 0, 0xff, 1, adau1373_digital_tlv),
303 SOC_DOUBLE_R_TLV("AIF2 Capture Volume", ADAU1373_DAI_RECL_VOL(1),
304 ADAU1373_DAI_RECR_VOL(1), 0, 0xff, 1, adau1373_digital_tlv),
305 SOC_DOUBLE_R_TLV("AIF3 Capture Volume", ADAU1373_DAI_RECL_VOL(2),
306 ADAU1373_DAI_RECR_VOL(2), 0, 0xff, 1, adau1373_digital_tlv),
307
308 SOC_DOUBLE_R_TLV("ADC Capture Volume", ADAU1373_ADC_RECL_VOL,
309 ADAU1373_ADC_RECR_VOL, 0, 0xff, 1, adau1373_digital_tlv),
310 SOC_DOUBLE_R_TLV("DMIC Capture Volume", ADAU1373_DMIC_RECL_VOL,
311 ADAU1373_DMIC_RECR_VOL, 0, 0xff, 1, adau1373_digital_tlv),
312
313 SOC_DOUBLE_R_TLV("AIF1 Playback Volume", ADAU1373_DAI_PBL_VOL(0),
314 ADAU1373_DAI_PBR_VOL(0), 0, 0xff, 1, adau1373_digital_tlv),
315 SOC_DOUBLE_R_TLV("AIF2 Playback Volume", ADAU1373_DAI_PBL_VOL(1),
316 ADAU1373_DAI_PBR_VOL(1), 0, 0xff, 1, adau1373_digital_tlv),
317 SOC_DOUBLE_R_TLV("AIF3 Playback Volume", ADAU1373_DAI_PBL_VOL(2),
318 ADAU1373_DAI_PBR_VOL(2), 0, 0xff, 1, adau1373_digital_tlv),
319
320 SOC_DOUBLE_R_TLV("DAC1 Playback Volume", ADAU1373_DAC1_PBL_VOL,
321 ADAU1373_DAC1_PBR_VOL, 0, 0xff, 1, adau1373_digital_tlv),
322 SOC_DOUBLE_R_TLV("DAC2 Playback Volume", ADAU1373_DAC2_PBL_VOL,
323 ADAU1373_DAC2_PBR_VOL, 0, 0xff, 1, adau1373_digital_tlv),
324
325 SOC_DOUBLE_R_TLV("Lineout1 Playback Volume", ADAU1373_LLINE_OUT(0),
326 ADAU1373_RLINE_OUT(0), 0, 0x1f, 0, adau1373_out_tlv),
327 SOC_DOUBLE_R_TLV("Speaker Playback Volume", ADAU1373_LSPK_OUT,
328 ADAU1373_RSPK_OUT, 0, 0x1f, 0, adau1373_out_tlv),
329 SOC_DOUBLE_R_TLV("Headphone Playback Volume", ADAU1373_LHP_OUT,
330 ADAU1373_RHP_OUT, 0, 0x1f, 0, adau1373_out_tlv),
331
332 SOC_DOUBLE_R_TLV("Input 1 Capture Volume", ADAU1373_AINL_CTRL(0),
333 ADAU1373_AINR_CTRL(0), 0, 0x1f, 0, adau1373_in_pga_tlv),
334 SOC_DOUBLE_R_TLV("Input 2 Capture Volume", ADAU1373_AINL_CTRL(1),
335 ADAU1373_AINR_CTRL(1), 0, 0x1f, 0, adau1373_in_pga_tlv),
336 SOC_DOUBLE_R_TLV("Input 3 Capture Volume", ADAU1373_AINL_CTRL(2),
337 ADAU1373_AINR_CTRL(2), 0, 0x1f, 0, adau1373_in_pga_tlv),
338 SOC_DOUBLE_R_TLV("Input 4 Capture Volume", ADAU1373_AINL_CTRL(3),
339 ADAU1373_AINR_CTRL(3), 0, 0x1f, 0, adau1373_in_pga_tlv),
340
341 SOC_SINGLE_TLV("Earpiece Playback Volume", ADAU1373_EP_CTRL, 0, 3, 0,
342 adau1373_ep_tlv),
343
344 SOC_DOUBLE_TLV("AIF3 Boost Playback Volume", ADAU1373_VOL_GAIN1, 4, 5,
345 1, 0, adau1373_gain_boost_tlv),
346 SOC_DOUBLE_TLV("AIF2 Boost Playback Volume", ADAU1373_VOL_GAIN1, 2, 3,
347 1, 0, adau1373_gain_boost_tlv),
348 SOC_DOUBLE_TLV("AIF1 Boost Playback Volume", ADAU1373_VOL_GAIN1, 0, 1,
349 1, 0, adau1373_gain_boost_tlv),
350 SOC_DOUBLE_TLV("AIF3 Boost Capture Volume", ADAU1373_VOL_GAIN2, 4, 5,
351 1, 0, adau1373_gain_boost_tlv),
352 SOC_DOUBLE_TLV("AIF2 Boost Capture Volume", ADAU1373_VOL_GAIN2, 2, 3,
353 1, 0, adau1373_gain_boost_tlv),
354 SOC_DOUBLE_TLV("AIF1 Boost Capture Volume", ADAU1373_VOL_GAIN2, 0, 1,
355 1, 0, adau1373_gain_boost_tlv),
356 SOC_DOUBLE_TLV("DMIC Boost Capture Volume", ADAU1373_VOL_GAIN3, 6, 7,
357 1, 0, adau1373_gain_boost_tlv),
358 SOC_DOUBLE_TLV("ADC Boost Capture Volume", ADAU1373_VOL_GAIN3, 4, 5,
359 1, 0, adau1373_gain_boost_tlv),
360 SOC_DOUBLE_TLV("DAC2 Boost Playback Volume", ADAU1373_VOL_GAIN3, 2, 3,
361 1, 0, adau1373_gain_boost_tlv),
362 SOC_DOUBLE_TLV("DAC1 Boost Playback Volume", ADAU1373_VOL_GAIN3, 0, 1,
363 1, 0, adau1373_gain_boost_tlv),
364
365 SOC_DOUBLE_TLV("Input 1 Boost Capture Volume", ADAU1373_ADC_GAIN, 0, 4,
366 1, 0, adau1373_input_boost_tlv),
367 SOC_DOUBLE_TLV("Input 2 Boost Capture Volume", ADAU1373_ADC_GAIN, 1, 5,
368 1, 0, adau1373_input_boost_tlv),
369 SOC_DOUBLE_TLV("Input 3 Boost Capture Volume", ADAU1373_ADC_GAIN, 2, 6,
370 1, 0, adau1373_input_boost_tlv),
371 SOC_DOUBLE_TLV("Input 4 Boost Capture Volume", ADAU1373_ADC_GAIN, 3, 7,
372 1, 0, adau1373_input_boost_tlv),
373
374 SOC_DOUBLE_TLV("Speaker Boost Playback Volume", ADAU1373_LS_CTRL, 2, 3,
375 1, 0, adau1373_speaker_boost_tlv),
376
377 SOC_ENUM("Lineout1 LR Mux", adau1373_lineout1_lr_mux_enum),
378 SOC_ENUM("Speaker LR Mux", adau1373_speaker_lr_mux_enum),
379
380 SOC_ENUM("HPF Cutoff", adau1373_hpf_cutoff_enum),
381 SOC_DOUBLE("HPF Switch", ADAU1373_HPF_CTRL, 1, 0, 1, 0),
382 SOC_ENUM("HPF Channel", adau1373_hpf_channel_enum),
383
384 SOC_ENUM("Bass HPF Cutoff", adau1373_bass_hpf_cutoff_enum),
385 SOC_VALUE_ENUM("Bass Clip Level Threshold",
386 adau1373_bass_clip_level_enum),
387 SOC_ENUM("Bass LPF Cutoff", adau1373_bass_lpf_cutoff_enum),
388 SOC_DOUBLE("Bass Playback Switch", ADAU1373_BASS2, 0, 1, 1, 0),
389 SOC_SINGLE_TLV("Bass Playback Volume", ADAU1373_BASS2, 2, 7, 0,
390 adau1373_bass_tlv),
391 SOC_ENUM("Bass Channel", adau1373_bass_channel_enum),
392
393 SOC_ENUM("3D Freq", adau1373_3d_cutoff_enum),
394 SOC_ENUM("3D Level", adau1373_3d_level_enum),
395 SOC_SINGLE("3D Playback Switch", ADAU1373_3D_CTRL2, 0, 1, 0),
396 SOC_SINGLE_TLV("3D Playback Volume", ADAU1373_3D_CTRL2, 2, 7, 0,
397 adau1373_3d_tlv),
398 SOC_ENUM("3D Channel", adau1373_bass_channel_enum),
399
400 SOC_SINGLE("Zero Cross Switch", ADAU1373_PWDN_CTRL3, 7, 1, 0),
401};
402
403static const struct snd_kcontrol_new adau1373_lineout2_controls[] = {
404 SOC_DOUBLE_R_TLV("Lineout2 Playback Volume", ADAU1373_LLINE_OUT(1),
405 ADAU1373_RLINE_OUT(1), 0, 0x1f, 0, adau1373_out_tlv),
406 SOC_ENUM("Lineout2 LR Mux", adau1373_lineout2_lr_mux_enum),
407};
408
409static const struct snd_kcontrol_new adau1373_drc_controls[] = {
410 SOC_ENUM("DRC1 Channel", adau1373_drc1_channel_enum),
411 SOC_ENUM("DRC2 Channel", adau1373_drc2_channel_enum),
412 SOC_ENUM("DRC3 Channel", adau1373_drc3_channel_enum),
413};
414
415static int adau1373_pll_event(struct snd_soc_dapm_widget *w,
416 struct snd_kcontrol *kcontrol, int event)
417{
418 struct snd_soc_codec *codec = w->codec;
419 unsigned int pll_id = w->name[3] - '1';
420 unsigned int val;
421
422 if (SND_SOC_DAPM_EVENT_ON(event))
423 val = ADAU1373_PLL_CTRL6_PLL_EN;
424 else
425 val = 0;
426
427 snd_soc_update_bits(codec, ADAU1373_PLL_CTRL6(pll_id),
428 ADAU1373_PLL_CTRL6_PLL_EN, val);
429
430 if (SND_SOC_DAPM_EVENT_ON(event))
431 mdelay(5);
432
433 return 0;
434}
435
436static const char *adau1373_decimator_text[] = {
437 "ADC",
438 "DMIC1",
439};
440
441static const struct soc_enum adau1373_decimator_enum =
442 SOC_ENUM_SINGLE(0, 0, 2, adau1373_decimator_text);
443
444static const struct snd_kcontrol_new adau1373_decimator_mux =
445 SOC_DAPM_ENUM_VIRT("Decimator Mux", adau1373_decimator_enum);
446
447static const struct snd_kcontrol_new adau1373_left_adc_mixer_controls[] = {
448 SOC_DAPM_SINGLE("DAC1 Switch", ADAU1373_LADC_MIXER, 4, 1, 0),
449 SOC_DAPM_SINGLE("Input 4 Switch", ADAU1373_LADC_MIXER, 3, 1, 0),
450 SOC_DAPM_SINGLE("Input 3 Switch", ADAU1373_LADC_MIXER, 2, 1, 0),
451 SOC_DAPM_SINGLE("Input 2 Switch", ADAU1373_LADC_MIXER, 1, 1, 0),
452 SOC_DAPM_SINGLE("Input 1 Switch", ADAU1373_LADC_MIXER, 0, 1, 0),
453};
454
455static const struct snd_kcontrol_new adau1373_right_adc_mixer_controls[] = {
456 SOC_DAPM_SINGLE("DAC1 Switch", ADAU1373_RADC_MIXER, 4, 1, 0),
457 SOC_DAPM_SINGLE("Input 4 Switch", ADAU1373_RADC_MIXER, 3, 1, 0),
458 SOC_DAPM_SINGLE("Input 3 Switch", ADAU1373_RADC_MIXER, 2, 1, 0),
459 SOC_DAPM_SINGLE("Input 2 Switch", ADAU1373_RADC_MIXER, 1, 1, 0),
460 SOC_DAPM_SINGLE("Input 1 Switch", ADAU1373_RADC_MIXER, 0, 1, 0),
461};
462
463#define DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(_name, _reg) \
464const struct snd_kcontrol_new _name[] = { \
465 SOC_DAPM_SINGLE("Left DAC2 Switch", _reg, 7, 1, 0), \
466 SOC_DAPM_SINGLE("Right DAC2 Switch", _reg, 6, 1, 0), \
467 SOC_DAPM_SINGLE("Left DAC1 Switch", _reg, 5, 1, 0), \
468 SOC_DAPM_SINGLE("Right DAC1 Switch", _reg, 4, 1, 0), \
469 SOC_DAPM_SINGLE("Input 4 Bypass Switch", _reg, 3, 1, 0), \
470 SOC_DAPM_SINGLE("Input 3 Bypass Switch", _reg, 2, 1, 0), \
471 SOC_DAPM_SINGLE("Input 2 Bypass Switch", _reg, 1, 1, 0), \
472 SOC_DAPM_SINGLE("Input 1 Bypass Switch", _reg, 0, 1, 0), \
473}
474
475static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_left_line1_mixer_controls,
476 ADAU1373_LLINE1_MIX);
477static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_right_line1_mixer_controls,
478 ADAU1373_RLINE1_MIX);
479static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_left_line2_mixer_controls,
480 ADAU1373_LLINE2_MIX);
481static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_right_line2_mixer_controls,
482 ADAU1373_RLINE2_MIX);
483static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_left_spk_mixer_controls,
484 ADAU1373_LSPK_MIX);
485static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_right_spk_mixer_controls,
486 ADAU1373_RSPK_MIX);
487static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_ep_mixer_controls,
488 ADAU1373_EP_MIX);
489
490static const struct snd_kcontrol_new adau1373_left_hp_mixer_controls[] = {
491 SOC_DAPM_SINGLE("Left DAC1 Switch", ADAU1373_LHP_MIX, 5, 1, 0),
492 SOC_DAPM_SINGLE("Left DAC2 Switch", ADAU1373_LHP_MIX, 4, 1, 0),
493 SOC_DAPM_SINGLE("Input 4 Bypass Switch", ADAU1373_LHP_MIX, 3, 1, 0),
494 SOC_DAPM_SINGLE("Input 3 Bypass Switch", ADAU1373_LHP_MIX, 2, 1, 0),
495 SOC_DAPM_SINGLE("Input 2 Bypass Switch", ADAU1373_LHP_MIX, 1, 1, 0),
496 SOC_DAPM_SINGLE("Input 1 Bypass Switch", ADAU1373_LHP_MIX, 0, 1, 0),
497};
498
499static const struct snd_kcontrol_new adau1373_right_hp_mixer_controls[] = {
500 SOC_DAPM_SINGLE("Right DAC1 Switch", ADAU1373_RHP_MIX, 5, 1, 0),
501 SOC_DAPM_SINGLE("Right DAC2 Switch", ADAU1373_RHP_MIX, 4, 1, 0),
502 SOC_DAPM_SINGLE("Input 4 Bypass Switch", ADAU1373_RHP_MIX, 3, 1, 0),
503 SOC_DAPM_SINGLE("Input 3 Bypass Switch", ADAU1373_RHP_MIX, 2, 1, 0),
504 SOC_DAPM_SINGLE("Input 2 Bypass Switch", ADAU1373_RHP_MIX, 1, 1, 0),
505 SOC_DAPM_SINGLE("Input 1 Bypass Switch", ADAU1373_RHP_MIX, 0, 1, 0),
506};
507
508#define DECLARE_ADAU1373_DSP_CHANNEL_MIXER_CTRLS(_name, _reg) \
509const struct snd_kcontrol_new _name[] = { \
510 SOC_DAPM_SINGLE("DMIC2 Swapped Switch", _reg, 6, 1, 0), \
511 SOC_DAPM_SINGLE("DMIC2 Switch", _reg, 5, 1, 0), \
512 SOC_DAPM_SINGLE("ADC/DMIC1 Swapped Switch", _reg, 4, 1, 0), \
513 SOC_DAPM_SINGLE("ADC/DMIC1 Switch", _reg, 3, 1, 0), \
514 SOC_DAPM_SINGLE("AIF3 Switch", _reg, 2, 1, 0), \
515 SOC_DAPM_SINGLE("AIF2 Switch", _reg, 1, 1, 0), \
516 SOC_DAPM_SINGLE("AIF1 Switch", _reg, 0, 1, 0), \
517}
518
519static DECLARE_ADAU1373_DSP_CHANNEL_MIXER_CTRLS(adau1373_dsp_channel1_mixer_controls,
520 ADAU1373_DIN_MIX_CTRL(0));
521static DECLARE_ADAU1373_DSP_CHANNEL_MIXER_CTRLS(adau1373_dsp_channel2_mixer_controls,
522 ADAU1373_DIN_MIX_CTRL(1));
523static DECLARE_ADAU1373_DSP_CHANNEL_MIXER_CTRLS(adau1373_dsp_channel3_mixer_controls,
524 ADAU1373_DIN_MIX_CTRL(2));
525static DECLARE_ADAU1373_DSP_CHANNEL_MIXER_CTRLS(adau1373_dsp_channel4_mixer_controls,
526 ADAU1373_DIN_MIX_CTRL(3));
527static DECLARE_ADAU1373_DSP_CHANNEL_MIXER_CTRLS(adau1373_dsp_channel5_mixer_controls,
528 ADAU1373_DIN_MIX_CTRL(4));
529
530#define DECLARE_ADAU1373_DSP_OUTPUT_MIXER_CTRLS(_name, _reg) \
531const struct snd_kcontrol_new _name[] = { \
532 SOC_DAPM_SINGLE("DSP Channel5 Switch", _reg, 4, 1, 0), \
533 SOC_DAPM_SINGLE("DSP Channel4 Switch", _reg, 3, 1, 0), \
534 SOC_DAPM_SINGLE("DSP Channel3 Switch", _reg, 2, 1, 0), \
535 SOC_DAPM_SINGLE("DSP Channel2 Switch", _reg, 1, 1, 0), \
536 SOC_DAPM_SINGLE("DSP Channel1 Switch", _reg, 0, 1, 0), \
537}
538
539static DECLARE_ADAU1373_DSP_OUTPUT_MIXER_CTRLS(adau1373_aif1_mixer_controls,
540 ADAU1373_DOUT_MIX_CTRL(0));
541static DECLARE_ADAU1373_DSP_OUTPUT_MIXER_CTRLS(adau1373_aif2_mixer_controls,
542 ADAU1373_DOUT_MIX_CTRL(1));
543static DECLARE_ADAU1373_DSP_OUTPUT_MIXER_CTRLS(adau1373_aif3_mixer_controls,
544 ADAU1373_DOUT_MIX_CTRL(2));
545static DECLARE_ADAU1373_DSP_OUTPUT_MIXER_CTRLS(adau1373_dac1_mixer_controls,
546 ADAU1373_DOUT_MIX_CTRL(3));
547static DECLARE_ADAU1373_DSP_OUTPUT_MIXER_CTRLS(adau1373_dac2_mixer_controls,
548 ADAU1373_DOUT_MIX_CTRL(4));
549
550static const struct snd_soc_dapm_widget adau1373_dapm_widgets[] = {
551 /* Datasheet claims Left ADC is bit 6 and Right ADC is bit 7, but that
552 * doesn't seem to be the case. */
553 SND_SOC_DAPM_ADC("Left ADC", NULL, ADAU1373_PWDN_CTRL1, 7, 0),
554 SND_SOC_DAPM_ADC("Right ADC", NULL, ADAU1373_PWDN_CTRL1, 6, 0),
555
556 SND_SOC_DAPM_ADC("DMIC1", NULL, ADAU1373_DIGMICCTRL, 0, 0),
557 SND_SOC_DAPM_ADC("DMIC2", NULL, ADAU1373_DIGMICCTRL, 2, 0),
558
559 SND_SOC_DAPM_VIRT_MUX("Decimator Mux", SND_SOC_NOPM, 0, 0,
560 &adau1373_decimator_mux),
561
562 SND_SOC_DAPM_SUPPLY("MICBIAS2", ADAU1373_PWDN_CTRL1, 5, 0, NULL, 0),
563 SND_SOC_DAPM_SUPPLY("MICBIAS1", ADAU1373_PWDN_CTRL1, 4, 0, NULL, 0),
564
565 SND_SOC_DAPM_PGA("IN4PGA", ADAU1373_PWDN_CTRL1, 3, 0, NULL, 0),
566 SND_SOC_DAPM_PGA("IN3PGA", ADAU1373_PWDN_CTRL1, 2, 0, NULL, 0),
567 SND_SOC_DAPM_PGA("IN2PGA", ADAU1373_PWDN_CTRL1, 1, 0, NULL, 0),
568 SND_SOC_DAPM_PGA("IN1PGA", ADAU1373_PWDN_CTRL1, 0, 0, NULL, 0),
569
570 SND_SOC_DAPM_DAC("Left DAC2", NULL, ADAU1373_PWDN_CTRL2, 7, 0),
571 SND_SOC_DAPM_DAC("Right DAC2", NULL, ADAU1373_PWDN_CTRL2, 6, 0),
572 SND_SOC_DAPM_DAC("Left DAC1", NULL, ADAU1373_PWDN_CTRL2, 5, 0),
573 SND_SOC_DAPM_DAC("Right DAC1", NULL, ADAU1373_PWDN_CTRL2, 4, 0),
574
575 SOC_MIXER_ARRAY("Left ADC Mixer", SND_SOC_NOPM, 0, 0,
576 adau1373_left_adc_mixer_controls),
577 SOC_MIXER_ARRAY("Right ADC Mixer", SND_SOC_NOPM, 0, 0,
578 adau1373_right_adc_mixer_controls),
579
580 SOC_MIXER_ARRAY("Left Lineout2 Mixer", ADAU1373_PWDN_CTRL2, 3, 0,
581 adau1373_left_line2_mixer_controls),
582 SOC_MIXER_ARRAY("Right Lineout2 Mixer", ADAU1373_PWDN_CTRL2, 2, 0,
583 adau1373_right_line2_mixer_controls),
584 SOC_MIXER_ARRAY("Left Lineout1 Mixer", ADAU1373_PWDN_CTRL2, 1, 0,
585 adau1373_left_line1_mixer_controls),
586 SOC_MIXER_ARRAY("Right Lineout1 Mixer", ADAU1373_PWDN_CTRL2, 0, 0,
587 adau1373_right_line1_mixer_controls),
588
589 SOC_MIXER_ARRAY("Earpiece Mixer", ADAU1373_PWDN_CTRL3, 4, 0,
590 adau1373_ep_mixer_controls),
591 SOC_MIXER_ARRAY("Left Speaker Mixer", ADAU1373_PWDN_CTRL3, 3, 0,
592 adau1373_left_spk_mixer_controls),
593 SOC_MIXER_ARRAY("Right Speaker Mixer", ADAU1373_PWDN_CTRL3, 2, 0,
594 adau1373_right_spk_mixer_controls),
595 SOC_MIXER_ARRAY("Left Headphone Mixer", SND_SOC_NOPM, 0, 0,
596 adau1373_left_hp_mixer_controls),
597 SOC_MIXER_ARRAY("Right Headphone Mixer", SND_SOC_NOPM, 0, 0,
598 adau1373_right_hp_mixer_controls),
599 SND_SOC_DAPM_SUPPLY("Headphone Enable", ADAU1373_PWDN_CTRL3, 1, 0,
600 NULL, 0),
601
602 SND_SOC_DAPM_SUPPLY("AIF1 CLK", ADAU1373_SRC_DAI_CTRL(0), 0, 0,
603 NULL, 0),
604 SND_SOC_DAPM_SUPPLY("AIF2 CLK", ADAU1373_SRC_DAI_CTRL(1), 0, 0,
605 NULL, 0),
606 SND_SOC_DAPM_SUPPLY("AIF3 CLK", ADAU1373_SRC_DAI_CTRL(2), 0, 0,
607 NULL, 0),
608 SND_SOC_DAPM_SUPPLY("AIF1 IN SRC", ADAU1373_SRC_DAI_CTRL(0), 2, 0,
609 NULL, 0),
610 SND_SOC_DAPM_SUPPLY("AIF1 OUT SRC", ADAU1373_SRC_DAI_CTRL(0), 1, 0,
611 NULL, 0),
612 SND_SOC_DAPM_SUPPLY("AIF2 IN SRC", ADAU1373_SRC_DAI_CTRL(1), 2, 0,
613 NULL, 0),
614 SND_SOC_DAPM_SUPPLY("AIF2 OUT SRC", ADAU1373_SRC_DAI_CTRL(1), 1, 0,
615 NULL, 0),
616 SND_SOC_DAPM_SUPPLY("AIF3 IN SRC", ADAU1373_SRC_DAI_CTRL(2), 2, 0,
617 NULL, 0),
618 SND_SOC_DAPM_SUPPLY("AIF3 OUT SRC", ADAU1373_SRC_DAI_CTRL(2), 1, 0,
619 NULL, 0),
620
621 SND_SOC_DAPM_AIF_IN("AIF1 IN", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
622 SND_SOC_DAPM_AIF_OUT("AIF1 OUT", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0),
623 SND_SOC_DAPM_AIF_IN("AIF2 IN", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0),
624 SND_SOC_DAPM_AIF_OUT("AIF2 OUT", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0),
625 SND_SOC_DAPM_AIF_IN("AIF3 IN", "AIF3 Playback", 0, SND_SOC_NOPM, 0, 0),
626 SND_SOC_DAPM_AIF_OUT("AIF3 OUT", "AIF3 Capture", 0, SND_SOC_NOPM, 0, 0),
627
628 SOC_MIXER_ARRAY("DSP Channel1 Mixer", SND_SOC_NOPM, 0, 0,
629 adau1373_dsp_channel1_mixer_controls),
630 SOC_MIXER_ARRAY("DSP Channel2 Mixer", SND_SOC_NOPM, 0, 0,
631 adau1373_dsp_channel2_mixer_controls),
632 SOC_MIXER_ARRAY("DSP Channel3 Mixer", SND_SOC_NOPM, 0, 0,
633 adau1373_dsp_channel3_mixer_controls),
634 SOC_MIXER_ARRAY("DSP Channel4 Mixer", SND_SOC_NOPM, 0, 0,
635 adau1373_dsp_channel4_mixer_controls),
636 SOC_MIXER_ARRAY("DSP Channel5 Mixer", SND_SOC_NOPM, 0, 0,
637 adau1373_dsp_channel5_mixer_controls),
638
639 SOC_MIXER_ARRAY("AIF1 Mixer", SND_SOC_NOPM, 0, 0,
640 adau1373_aif1_mixer_controls),
641 SOC_MIXER_ARRAY("AIF2 Mixer", SND_SOC_NOPM, 0, 0,
642 adau1373_aif2_mixer_controls),
643 SOC_MIXER_ARRAY("AIF3 Mixer", SND_SOC_NOPM, 0, 0,
644 adau1373_aif3_mixer_controls),
645 SOC_MIXER_ARRAY("DAC1 Mixer", SND_SOC_NOPM, 0, 0,
646 adau1373_dac1_mixer_controls),
647 SOC_MIXER_ARRAY("DAC2 Mixer", SND_SOC_NOPM, 0, 0,
648 adau1373_dac2_mixer_controls),
649
650 SND_SOC_DAPM_SUPPLY("DSP", ADAU1373_DIGEN, 4, 0, NULL, 0),
651 SND_SOC_DAPM_SUPPLY("Recording Engine B", ADAU1373_DIGEN, 3, 0, NULL, 0),
652 SND_SOC_DAPM_SUPPLY("Recording Engine A", ADAU1373_DIGEN, 2, 0, NULL, 0),
653 SND_SOC_DAPM_SUPPLY("Playback Engine B", ADAU1373_DIGEN, 1, 0, NULL, 0),
654 SND_SOC_DAPM_SUPPLY("Playback Engine A", ADAU1373_DIGEN, 0, 0, NULL, 0),
655
656 SND_SOC_DAPM_SUPPLY("PLL1", SND_SOC_NOPM, 0, 0, adau1373_pll_event,
657 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
658 SND_SOC_DAPM_SUPPLY("PLL2", SND_SOC_NOPM, 0, 0, adau1373_pll_event,
659 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
660 SND_SOC_DAPM_SUPPLY("SYSCLK1", ADAU1373_CLK_SRC_DIV(0), 7, 0, NULL, 0),
661 SND_SOC_DAPM_SUPPLY("SYSCLK2", ADAU1373_CLK_SRC_DIV(1), 7, 0, NULL, 0),
662
663 SND_SOC_DAPM_INPUT("AIN1L"),
664 SND_SOC_DAPM_INPUT("AIN1R"),
665 SND_SOC_DAPM_INPUT("AIN2L"),
666 SND_SOC_DAPM_INPUT("AIN2R"),
667 SND_SOC_DAPM_INPUT("AIN3L"),
668 SND_SOC_DAPM_INPUT("AIN3R"),
669 SND_SOC_DAPM_INPUT("AIN4L"),
670 SND_SOC_DAPM_INPUT("AIN4R"),
671
672 SND_SOC_DAPM_INPUT("DMIC1DAT"),
673 SND_SOC_DAPM_INPUT("DMIC2DAT"),
674
675 SND_SOC_DAPM_OUTPUT("LOUT1L"),
676 SND_SOC_DAPM_OUTPUT("LOUT1R"),
677 SND_SOC_DAPM_OUTPUT("LOUT2L"),
678 SND_SOC_DAPM_OUTPUT("LOUT2R"),
679 SND_SOC_DAPM_OUTPUT("HPL"),
680 SND_SOC_DAPM_OUTPUT("HPR"),
681 SND_SOC_DAPM_OUTPUT("SPKL"),
682 SND_SOC_DAPM_OUTPUT("SPKR"),
683 SND_SOC_DAPM_OUTPUT("EP"),
684};
685
686static int adau1373_check_aif_clk(struct snd_soc_dapm_widget *source,
687 struct snd_soc_dapm_widget *sink)
688{
689 struct snd_soc_codec *codec = source->codec;
690 struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
691 unsigned int dai;
692 const char *clk;
693
694 dai = sink->name[3] - '1';
695
696 if (!adau1373->dais[dai].master)
697 return 0;
698
699 if (adau1373->dais[dai].clk_src == ADAU1373_CLK_SRC_PLL1)
700 clk = "SYSCLK1";
701 else
702 clk = "SYSCLK2";
703
704 return strcmp(source->name, clk) == 0;
705}
706
707static int adau1373_check_src(struct snd_soc_dapm_widget *source,
708 struct snd_soc_dapm_widget *sink)
709{
710 struct snd_soc_codec *codec = source->codec;
711 struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
712 unsigned int dai;
713
714 dai = sink->name[3] - '1';
715
716 return adau1373->dais[dai].enable_src;
717}
718
719#define DSP_CHANNEL_MIXER_ROUTES(_sink) \
720 { _sink, "DMIC2 Swapped Switch", "DMIC2" }, \
721 { _sink, "DMIC2 Switch", "DMIC2" }, \
722 { _sink, "ADC/DMIC1 Swapped Switch", "Decimator Mux" }, \
723 { _sink, "ADC/DMIC1 Switch", "Decimator Mux" }, \
724 { _sink, "AIF1 Switch", "AIF1 IN" }, \
725 { _sink, "AIF2 Switch", "AIF2 IN" }, \
726 { _sink, "AIF3 Switch", "AIF3 IN" }
727
728#define DSP_OUTPUT_MIXER_ROUTES(_sink) \
729 { _sink, "DSP Channel1 Switch", "DSP Channel1 Mixer" }, \
730 { _sink, "DSP Channel2 Switch", "DSP Channel2 Mixer" }, \
731 { _sink, "DSP Channel3 Switch", "DSP Channel3 Mixer" }, \
732 { _sink, "DSP Channel4 Switch", "DSP Channel4 Mixer" }, \
733 { _sink, "DSP Channel5 Switch", "DSP Channel5 Mixer" }
734
735#define LEFT_OUTPUT_MIXER_ROUTES(_sink) \
736 { _sink, "Right DAC2 Switch", "Right DAC2" }, \
737 { _sink, "Left DAC2 Switch", "Left DAC2" }, \
738 { _sink, "Right DAC1 Switch", "Right DAC1" }, \
739 { _sink, "Left DAC1 Switch", "Left DAC1" }, \
740 { _sink, "Input 1 Bypass Switch", "IN1PGA" }, \
741 { _sink, "Input 2 Bypass Switch", "IN2PGA" }, \
742 { _sink, "Input 3 Bypass Switch", "IN3PGA" }, \
743 { _sink, "Input 4 Bypass Switch", "IN4PGA" }
744
745#define RIGHT_OUTPUT_MIXER_ROUTES(_sink) \
746 { _sink, "Right DAC2 Switch", "Right DAC2" }, \
747 { _sink, "Left DAC2 Switch", "Left DAC2" }, \
748 { _sink, "Right DAC1 Switch", "Right DAC1" }, \
749 { _sink, "Left DAC1 Switch", "Left DAC1" }, \
750 { _sink, "Input 1 Bypass Switch", "IN1PGA" }, \
751 { _sink, "Input 2 Bypass Switch", "IN2PGA" }, \
752 { _sink, "Input 3 Bypass Switch", "IN3PGA" }, \
753 { _sink, "Input 4 Bypass Switch", "IN4PGA" }
754
755static const struct snd_soc_dapm_route adau1373_dapm_routes[] = {
756 { "Left ADC Mixer", "DAC1 Switch", "Left DAC1" },
757 { "Left ADC Mixer", "Input 1 Switch", "IN1PGA" },
758 { "Left ADC Mixer", "Input 2 Switch", "IN2PGA" },
759 { "Left ADC Mixer", "Input 3 Switch", "IN3PGA" },
760 { "Left ADC Mixer", "Input 4 Switch", "IN4PGA" },
761
762 { "Right ADC Mixer", "DAC1 Switch", "Right DAC1" },
763 { "Right ADC Mixer", "Input 1 Switch", "IN1PGA" },
764 { "Right ADC Mixer", "Input 2 Switch", "IN2PGA" },
765 { "Right ADC Mixer", "Input 3 Switch", "IN3PGA" },
766 { "Right ADC Mixer", "Input 4 Switch", "IN4PGA" },
767
768 { "Left ADC", NULL, "Left ADC Mixer" },
769 { "Right ADC", NULL, "Right ADC Mixer" },
770
771 { "Decimator Mux", "ADC", "Left ADC" },
772 { "Decimator Mux", "ADC", "Right ADC" },
773 { "Decimator Mux", "DMIC1", "DMIC1" },
774
775 DSP_CHANNEL_MIXER_ROUTES("DSP Channel1 Mixer"),
776 DSP_CHANNEL_MIXER_ROUTES("DSP Channel2 Mixer"),
777 DSP_CHANNEL_MIXER_ROUTES("DSP Channel3 Mixer"),
778 DSP_CHANNEL_MIXER_ROUTES("DSP Channel4 Mixer"),
779 DSP_CHANNEL_MIXER_ROUTES("DSP Channel5 Mixer"),
780
781 DSP_OUTPUT_MIXER_ROUTES("AIF1 Mixer"),
782 DSP_OUTPUT_MIXER_ROUTES("AIF2 Mixer"),
783 DSP_OUTPUT_MIXER_ROUTES("AIF3 Mixer"),
784 DSP_OUTPUT_MIXER_ROUTES("DAC1 Mixer"),
785 DSP_OUTPUT_MIXER_ROUTES("DAC2 Mixer"),
786
787 { "AIF1 OUT", NULL, "AIF1 Mixer" },
788 { "AIF2 OUT", NULL, "AIF2 Mixer" },
789 { "AIF3 OUT", NULL, "AIF3 Mixer" },
790 { "Left DAC1", NULL, "DAC1 Mixer" },
791 { "Right DAC1", NULL, "DAC1 Mixer" },
792 { "Left DAC2", NULL, "DAC2 Mixer" },
793 { "Right DAC2", NULL, "DAC2 Mixer" },
794
795 LEFT_OUTPUT_MIXER_ROUTES("Left Lineout1 Mixer"),
796 RIGHT_OUTPUT_MIXER_ROUTES("Right Lineout1 Mixer"),
797 LEFT_OUTPUT_MIXER_ROUTES("Left Lineout2 Mixer"),
798 RIGHT_OUTPUT_MIXER_ROUTES("Right Lineout2 Mixer"),
799 LEFT_OUTPUT_MIXER_ROUTES("Left Speaker Mixer"),
800 RIGHT_OUTPUT_MIXER_ROUTES("Right Speaker Mixer"),
801
802 { "Left Headphone Mixer", "Left DAC2 Switch", "Left DAC2" },
803 { "Left Headphone Mixer", "Left DAC1 Switch", "Left DAC1" },
804 { "Left Headphone Mixer", "Input 1 Bypass Switch", "IN1PGA" },
805 { "Left Headphone Mixer", "Input 2 Bypass Switch", "IN2PGA" },
806 { "Left Headphone Mixer", "Input 3 Bypass Switch", "IN3PGA" },
807 { "Left Headphone Mixer", "Input 4 Bypass Switch", "IN4PGA" },
808 { "Right Headphone Mixer", "Right DAC2 Switch", "Right DAC2" },
809 { "Right Headphone Mixer", "Right DAC1 Switch", "Right DAC1" },
810 { "Right Headphone Mixer", "Input 1 Bypass Switch", "IN1PGA" },
811 { "Right Headphone Mixer", "Input 2 Bypass Switch", "IN2PGA" },
812 { "Right Headphone Mixer", "Input 3 Bypass Switch", "IN3PGA" },
813 { "Right Headphone Mixer", "Input 4 Bypass Switch", "IN4PGA" },
814
815 { "Left Headphone Mixer", NULL, "Headphone Enable" },
816 { "Right Headphone Mixer", NULL, "Headphone Enable" },
817
818 { "Earpiece Mixer", "Right DAC2 Switch", "Right DAC2" },
819 { "Earpiece Mixer", "Left DAC2 Switch", "Left DAC2" },
820 { "Earpiece Mixer", "Right DAC1 Switch", "Right DAC1" },
821 { "Earpiece Mixer", "Left DAC1 Switch", "Left DAC1" },
822 { "Earpiece Mixer", "Input 1 Bypass Switch", "IN1PGA" },
823 { "Earpiece Mixer", "Input 2 Bypass Switch", "IN2PGA" },
824 { "Earpiece Mixer", "Input 3 Bypass Switch", "IN3PGA" },
825 { "Earpiece Mixer", "Input 4 Bypass Switch", "IN4PGA" },
826
827 { "LOUT1L", NULL, "Left Lineout1 Mixer" },
828 { "LOUT1R", NULL, "Right Lineout1 Mixer" },
829 { "LOUT2L", NULL, "Left Lineout2 Mixer" },
830 { "LOUT2R", NULL, "Right Lineout2 Mixer" },
831 { "SPKL", NULL, "Left Speaker Mixer" },
832 { "SPKR", NULL, "Right Speaker Mixer" },
833 { "HPL", NULL, "Left Headphone Mixer" },
834 { "HPR", NULL, "Right Headphone Mixer" },
835 { "EP", NULL, "Earpiece Mixer" },
836
837 { "IN1PGA", NULL, "AIN1L" },
838 { "IN2PGA", NULL, "AIN2L" },
839 { "IN3PGA", NULL, "AIN3L" },
840 { "IN4PGA", NULL, "AIN4L" },
841 { "IN1PGA", NULL, "AIN1R" },
842 { "IN2PGA", NULL, "AIN2R" },
843 { "IN3PGA", NULL, "AIN3R" },
844 { "IN4PGA", NULL, "AIN4R" },
845
846 { "SYSCLK1", NULL, "PLL1" },
847 { "SYSCLK2", NULL, "PLL2" },
848
849 { "Left DAC1", NULL, "SYSCLK1" },
850 { "Right DAC1", NULL, "SYSCLK1" },
851 { "Left DAC2", NULL, "SYSCLK1" },
852 { "Right DAC2", NULL, "SYSCLK1" },
853 { "Left ADC", NULL, "SYSCLK1" },
854 { "Right ADC", NULL, "SYSCLK1" },
855
856 { "DSP", NULL, "SYSCLK1" },
857
858 { "AIF1 Mixer", NULL, "DSP" },
859 { "AIF2 Mixer", NULL, "DSP" },
860 { "AIF3 Mixer", NULL, "DSP" },
861 { "DAC1 Mixer", NULL, "DSP" },
862 { "DAC2 Mixer", NULL, "DSP" },
863 { "DAC1 Mixer", NULL, "Playback Engine A" },
864 { "DAC2 Mixer", NULL, "Playback Engine B" },
865 { "Left ADC Mixer", NULL, "Recording Engine A" },
866 { "Right ADC Mixer", NULL, "Recording Engine A" },
867
868 { "AIF1 CLK", NULL, "SYSCLK1", adau1373_check_aif_clk },
869 { "AIF2 CLK", NULL, "SYSCLK1", adau1373_check_aif_clk },
870 { "AIF3 CLK", NULL, "SYSCLK1", adau1373_check_aif_clk },
871 { "AIF1 CLK", NULL, "SYSCLK2", adau1373_check_aif_clk },
872 { "AIF2 CLK", NULL, "SYSCLK2", adau1373_check_aif_clk },
873 { "AIF3 CLK", NULL, "SYSCLK2", adau1373_check_aif_clk },
874
875 { "AIF1 IN", NULL, "AIF1 CLK" },
876 { "AIF1 OUT", NULL, "AIF1 CLK" },
877 { "AIF2 IN", NULL, "AIF2 CLK" },
878 { "AIF2 OUT", NULL, "AIF2 CLK" },
879 { "AIF3 IN", NULL, "AIF3 CLK" },
880 { "AIF3 OUT", NULL, "AIF3 CLK" },
881 { "AIF1 IN", NULL, "AIF1 IN SRC", adau1373_check_src },
882 { "AIF1 OUT", NULL, "AIF1 OUT SRC", adau1373_check_src },
883 { "AIF2 IN", NULL, "AIF2 IN SRC", adau1373_check_src },
884 { "AIF2 OUT", NULL, "AIF2 OUT SRC", adau1373_check_src },
885 { "AIF3 IN", NULL, "AIF3 IN SRC", adau1373_check_src },
886 { "AIF3 OUT", NULL, "AIF3 OUT SRC", adau1373_check_src },
887
888 { "DMIC1", NULL, "DMIC1DAT" },
889 { "DMIC1", NULL, "SYSCLK1" },
890 { "DMIC1", NULL, "Recording Engine A" },
891 { "DMIC2", NULL, "DMIC2DAT" },
892 { "DMIC2", NULL, "SYSCLK1" },
893 { "DMIC2", NULL, "Recording Engine B" },
894};
895
896static int adau1373_hw_params(struct snd_pcm_substream *substream,
897 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
898{
899 struct snd_soc_codec *codec = dai->codec;
900 struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
901 struct adau1373_dai *adau1373_dai = &adau1373->dais[dai->id];
902 unsigned int div;
903 unsigned int freq;
904 unsigned int ctrl;
905
906 freq = adau1373_dai->sysclk;
907
908 if (freq % params_rate(params) != 0)
909 return -EINVAL;
910
911 switch (freq / params_rate(params)) {
912 case 1024: /* sysclk / 256 */
913 div = 0;
914 break;
915 case 1536: /* 2/3 sysclk / 256 */
916 div = 1;
917 break;
918 case 2048: /* 1/2 sysclk / 256 */
919 div = 2;
920 break;
921 case 3072: /* 1/3 sysclk / 256 */
922 div = 3;
923 break;
924 case 4096: /* 1/4 sysclk / 256 */
925 div = 4;
926 break;
927 case 6144: /* 1/6 sysclk / 256 */
928 div = 5;
929 break;
930 case 5632: /* 2/11 sysclk / 256 */
931 div = 6;
932 break;
933 default:
934 return -EINVAL;
935 }
936
937 adau1373_dai->enable_src = (div != 0);
938
939 snd_soc_update_bits(codec, ADAU1373_BCLKDIV(dai->id),
940 ~ADAU1373_BCLKDIV_SOURCE, (div << 2) | ADAU1373_BCLKDIV_64);
941
942 switch (params_format(params)) {
943 case SNDRV_PCM_FORMAT_S16_LE:
944 ctrl = ADAU1373_DAI_WLEN_16;
945 break;
946 case SNDRV_PCM_FORMAT_S20_3LE:
947 ctrl = ADAU1373_DAI_WLEN_20;
948 break;
949 case SNDRV_PCM_FORMAT_S24_LE:
950 ctrl = ADAU1373_DAI_WLEN_24;
951 break;
952 case SNDRV_PCM_FORMAT_S32_LE:
953 ctrl = ADAU1373_DAI_WLEN_32;
954 break;
955 default:
956 return -EINVAL;
957 }
958
959 return snd_soc_update_bits(codec, ADAU1373_DAI(dai->id),
960 ADAU1373_DAI_WLEN_MASK, ctrl);
961}
962
963static int adau1373_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
964{
965 struct snd_soc_codec *codec = dai->codec;
966 struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
967 struct adau1373_dai *adau1373_dai = &adau1373->dais[dai->id];
968 unsigned int ctrl;
969
970 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
971 case SND_SOC_DAIFMT_CBM_CFM:
972 ctrl = ADAU1373_DAI_MASTER;
973 adau1373_dai->master = true;
974 break;
975 case SND_SOC_DAIFMT_CBS_CFS:
976 ctrl = 0;
977 adau1373_dai->master = false;
978 break;
979 default:
980 return -EINVAL;
981 }
982
983 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
984 case SND_SOC_DAIFMT_I2S:
985 ctrl |= ADAU1373_DAI_FORMAT_I2S;
986 break;
987 case SND_SOC_DAIFMT_LEFT_J:
988 ctrl |= ADAU1373_DAI_FORMAT_LEFT_J;
989 break;
990 case SND_SOC_DAIFMT_RIGHT_J:
991 ctrl |= ADAU1373_DAI_FORMAT_RIGHT_J;
992 break;
993 case SND_SOC_DAIFMT_DSP_B:
994 ctrl |= ADAU1373_DAI_FORMAT_DSP;
995 break;
996 default:
997 return -EINVAL;
998 }
999
1000 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1001 case SND_SOC_DAIFMT_NB_NF:
1002 break;
1003 case SND_SOC_DAIFMT_IB_NF:
1004 ctrl |= ADAU1373_DAI_INVERT_BCLK;
1005 break;
1006 case SND_SOC_DAIFMT_NB_IF:
1007 ctrl |= ADAU1373_DAI_INVERT_LRCLK;
1008 break;
1009 case SND_SOC_DAIFMT_IB_IF:
1010 ctrl |= ADAU1373_DAI_INVERT_LRCLK | ADAU1373_DAI_INVERT_BCLK;
1011 break;
1012 default:
1013 return -EINVAL;
1014 }
1015
1016 snd_soc_update_bits(codec, ADAU1373_DAI(dai->id),
1017 ~ADAU1373_DAI_WLEN_MASK, ctrl);
1018
1019 return 0;
1020}
1021
1022static int adau1373_set_dai_sysclk(struct snd_soc_dai *dai,
1023 int clk_id, unsigned int freq, int dir)
1024{
1025 struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(dai->codec);
1026 struct adau1373_dai *adau1373_dai = &adau1373->dais[dai->id];
1027
1028 switch (clk_id) {
1029 case ADAU1373_CLK_SRC_PLL1:
1030 case ADAU1373_CLK_SRC_PLL2:
1031 break;
1032 default:
1033 return -EINVAL;
1034 }
1035
1036 adau1373_dai->sysclk = freq;
1037 adau1373_dai->clk_src = clk_id;
1038
1039 snd_soc_update_bits(dai->codec, ADAU1373_BCLKDIV(dai->id),
1040 ADAU1373_BCLKDIV_SOURCE, clk_id << 5);
1041
1042 return 0;
1043}
1044
1045static const struct snd_soc_dai_ops adau1373_dai_ops = {
1046 .hw_params = adau1373_hw_params,
1047 .set_sysclk = adau1373_set_dai_sysclk,
1048 .set_fmt = adau1373_set_dai_fmt,
1049};
1050
1051#define ADAU1373_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
1052 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
1053
1054static struct snd_soc_dai_driver adau1373_dai_driver[] = {
1055 {
1056 .id = 0,
1057 .name = "adau1373-aif1",
1058 .playback = {
1059 .stream_name = "AIF1 Playback",
1060 .channels_min = 2,
1061 .channels_max = 2,
1062 .rates = SNDRV_PCM_RATE_8000_48000,
1063 .formats = ADAU1373_FORMATS,
1064 },
1065 .capture = {
1066 .stream_name = "AIF1 Capture",
1067 .channels_min = 2,
1068 .channels_max = 2,
1069 .rates = SNDRV_PCM_RATE_8000_48000,
1070 .formats = ADAU1373_FORMATS,
1071 },
1072 .ops = &adau1373_dai_ops,
1073 .symmetric_rates = 1,
1074 },
1075 {
1076 .id = 1,
1077 .name = "adau1373-aif2",
1078 .playback = {
1079 .stream_name = "AIF2 Playback",
1080 .channels_min = 2,
1081 .channels_max = 2,
1082 .rates = SNDRV_PCM_RATE_8000_48000,
1083 .formats = ADAU1373_FORMATS,
1084 },
1085 .capture = {
1086 .stream_name = "AIF2 Capture",
1087 .channels_min = 2,
1088 .channels_max = 2,
1089 .rates = SNDRV_PCM_RATE_8000_48000,
1090 .formats = ADAU1373_FORMATS,
1091 },
1092 .ops = &adau1373_dai_ops,
1093 .symmetric_rates = 1,
1094 },
1095 {
1096 .id = 2,
1097 .name = "adau1373-aif3",
1098 .playback = {
1099 .stream_name = "AIF3 Playback",
1100 .channels_min = 2,
1101 .channels_max = 2,
1102 .rates = SNDRV_PCM_RATE_8000_48000,
1103 .formats = ADAU1373_FORMATS,
1104 },
1105 .capture = {
1106 .stream_name = "AIF3 Capture",
1107 .channels_min = 2,
1108 .channels_max = 2,
1109 .rates = SNDRV_PCM_RATE_8000_48000,
1110 .formats = ADAU1373_FORMATS,
1111 },
1112 .ops = &adau1373_dai_ops,
1113 .symmetric_rates = 1,
1114 },
1115};
1116
1117static int adau1373_set_pll(struct snd_soc_codec *codec, int pll_id,
1118 int source, unsigned int freq_in, unsigned int freq_out)
1119{
1120 unsigned int dpll_div = 0;
1121 unsigned int x, r, n, m, i, j, mode;
1122
1123 switch (pll_id) {
1124 case ADAU1373_PLL1:
1125 case ADAU1373_PLL2:
1126 break;
1127 default:
1128 return -EINVAL;
1129 }
1130
1131 switch (source) {
1132 case ADAU1373_PLL_SRC_BCLK1:
1133 case ADAU1373_PLL_SRC_BCLK2:
1134 case ADAU1373_PLL_SRC_BCLK3:
1135 case ADAU1373_PLL_SRC_LRCLK1:
1136 case ADAU1373_PLL_SRC_LRCLK2:
1137 case ADAU1373_PLL_SRC_LRCLK3:
1138 case ADAU1373_PLL_SRC_MCLK1:
1139 case ADAU1373_PLL_SRC_MCLK2:
1140 case ADAU1373_PLL_SRC_GPIO1:
1141 case ADAU1373_PLL_SRC_GPIO2:
1142 case ADAU1373_PLL_SRC_GPIO3:
1143 case ADAU1373_PLL_SRC_GPIO4:
1144 break;
1145 default:
1146 return -EINVAL;
1147 }
1148
1149 if (freq_in < 7813 || freq_in > 27000000)
1150 return -EINVAL;
1151
1152 if (freq_out < 45158000 || freq_out > 49152000)
1153 return -EINVAL;
1154
1155 /* APLL input needs to be >= 8Mhz, so in case freq_in is less we use the
1156 * DPLL to get it there. DPLL_out = (DPLL_in / div) * 1024 */
1157 while (freq_in < 8000000) {
1158 freq_in *= 2;
1159 dpll_div++;
1160 }
1161
1162 if (freq_out % freq_in != 0) {
1163 /* fout = fin * (r + (n/m)) / x */
1164 x = DIV_ROUND_UP(freq_in, 13500000);
1165 freq_in /= x;
1166 r = freq_out / freq_in;
1167 i = freq_out % freq_in;
1168 j = gcd(i, freq_in);
1169 n = i / j;
1170 m = freq_in / j;
1171 x--;
1172 mode = 1;
1173 } else {
1174 /* fout = fin / r */
1175 r = freq_out / freq_in;
1176 n = 0;
1177 m = 0;
1178 x = 0;
1179 mode = 0;
1180 }
1181
1182 if (r < 2 || r > 8 || x > 3 || m > 0xffff || n > 0xffff)
1183 return -EINVAL;
1184
1185 if (dpll_div) {
1186 dpll_div = 11 - dpll_div;
1187 snd_soc_update_bits(codec, ADAU1373_PLL_CTRL6(pll_id),
1188 ADAU1373_PLL_CTRL6_DPLL_BYPASS, 0);
1189 } else {
1190 snd_soc_update_bits(codec, ADAU1373_PLL_CTRL6(pll_id),
1191 ADAU1373_PLL_CTRL6_DPLL_BYPASS,
1192 ADAU1373_PLL_CTRL6_DPLL_BYPASS);
1193 }
1194
1195 snd_soc_write(codec, ADAU1373_DPLL_CTRL(pll_id),
1196 (source << 4) | dpll_div);
1197 snd_soc_write(codec, ADAU1373_PLL_CTRL1(pll_id), (m >> 8) & 0xff);
1198 snd_soc_write(codec, ADAU1373_PLL_CTRL2(pll_id), m & 0xff);
1199 snd_soc_write(codec, ADAU1373_PLL_CTRL3(pll_id), (n >> 8) & 0xff);
1200 snd_soc_write(codec, ADAU1373_PLL_CTRL4(pll_id), n & 0xff);
1201 snd_soc_write(codec, ADAU1373_PLL_CTRL5(pll_id),
1202 (r << 3) | (x << 1) | mode);
1203
1204 /* Set sysclk to pll_rate / 4 */
1205 snd_soc_update_bits(codec, ADAU1373_CLK_SRC_DIV(pll_id), 0x3f, 0x09);
1206
1207 return 0;
1208}
1209
1210static void adau1373_load_drc_settings(struct snd_soc_codec *codec,
1211 unsigned int nr, uint8_t *drc)
1212{
1213 unsigned int i;
1214
1215 for (i = 0; i < ADAU1373_DRC_SIZE; ++i)
1216 snd_soc_write(codec, ADAU1373_DRC(nr) + i, drc[i]);
1217}
1218
1219static bool adau1373_valid_micbias(enum adau1373_micbias_voltage micbias)
1220{
1221 switch (micbias) {
1222 case ADAU1373_MICBIAS_2_9V:
1223 case ADAU1373_MICBIAS_2_2V:
1224 case ADAU1373_MICBIAS_2_6V:
1225 case ADAU1373_MICBIAS_1_8V:
1226 return true;
1227 default:
1228 break;
1229 }
1230 return false;
1231}
1232
1233static int adau1373_probe(struct snd_soc_codec *codec)
1234{
1235 struct adau1373_platform_data *pdata = codec->dev->platform_data;
1236 bool lineout_differential = false;
1237 unsigned int val;
1238 int ret;
1239 int i;
1240
1241 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
1242 if (ret) {
1243 dev_err(codec->dev, "failed to set cache I/O: %d\n", ret);
1244 return ret;
1245 }
1246
1247 codec->dapm.idle_bias_off = true;
1248
1249 if (pdata) {
1250 if (pdata->num_drc > ARRAY_SIZE(pdata->drc_setting))
1251 return -EINVAL;
1252
1253 if (!adau1373_valid_micbias(pdata->micbias1) ||
1254 !adau1373_valid_micbias(pdata->micbias2))
1255 return -EINVAL;
1256
1257 for (i = 0; i < pdata->num_drc; ++i) {
1258 adau1373_load_drc_settings(codec, i,
1259 pdata->drc_setting[i]);
1260 }
1261
1262 snd_soc_add_controls(codec, adau1373_drc_controls,
1263 pdata->num_drc);
1264
1265 val = 0;
1266 for (i = 0; i < 4; ++i) {
1267 if (pdata->input_differential[i])
1268 val |= BIT(i);
1269 }
1270 snd_soc_write(codec, ADAU1373_INPUT_MODE, val);
1271
1272 val = 0;
1273 if (pdata->lineout_differential)
1274 val |= ADAU1373_OUTPUT_CTRL_LDIFF;
1275 if (pdata->lineout_ground_sense)
1276 val |= ADAU1373_OUTPUT_CTRL_LNFBEN;
1277 snd_soc_write(codec, ADAU1373_OUTPUT_CTRL, val);
1278
1279 lineout_differential = pdata->lineout_differential;
1280
1281 snd_soc_write(codec, ADAU1373_EP_CTRL,
1282 (pdata->micbias1 << ADAU1373_EP_CTRL_MICBIAS1_OFFSET) |
1283 (pdata->micbias2 << ADAU1373_EP_CTRL_MICBIAS2_OFFSET));
1284 }
1285
1286 if (!lineout_differential) {
1287 snd_soc_add_controls(codec, adau1373_lineout2_controls,
1288 ARRAY_SIZE(adau1373_lineout2_controls));
1289 }
1290
1291 snd_soc_write(codec, ADAU1373_ADC_CTRL,
1292 ADAU1373_ADC_CTRL_RESET_FORCE | ADAU1373_ADC_CTRL_PEAK_DETECT);
1293
1294 return 0;
1295}
1296
1297static int adau1373_set_bias_level(struct snd_soc_codec *codec,
1298 enum snd_soc_bias_level level)
1299{
1300 switch (level) {
1301 case SND_SOC_BIAS_ON:
1302 break;
1303 case SND_SOC_BIAS_PREPARE:
1304 break;
1305 case SND_SOC_BIAS_STANDBY:
1306 snd_soc_update_bits(codec, ADAU1373_PWDN_CTRL3,
1307 ADAU1373_PWDN_CTRL3_PWR_EN, ADAU1373_PWDN_CTRL3_PWR_EN);
1308 break;
1309 case SND_SOC_BIAS_OFF:
1310 snd_soc_update_bits(codec, ADAU1373_PWDN_CTRL3,
1311 ADAU1373_PWDN_CTRL3_PWR_EN, 0);
1312 break;
1313 }
1314 codec->dapm.bias_level = level;
1315 return 0;
1316}
1317
1318static int adau1373_remove(struct snd_soc_codec *codec)
1319{
1320 adau1373_set_bias_level(codec, SND_SOC_BIAS_OFF);
1321 return 0;
1322}
1323
1324static int adau1373_suspend(struct snd_soc_codec *codec, pm_message_t state)
1325{
1326 return adau1373_set_bias_level(codec, SND_SOC_BIAS_OFF);
1327}
1328
1329static int adau1373_resume(struct snd_soc_codec *codec)
1330{
1331 adau1373_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1332 snd_soc_cache_sync(codec);
1333
1334 return 0;
1335}
1336
1337static struct snd_soc_codec_driver adau1373_codec_driver = {
1338 .probe = adau1373_probe,
1339 .remove = adau1373_remove,
1340 .suspend = adau1373_suspend,
1341 .resume = adau1373_resume,
1342 .set_bias_level = adau1373_set_bias_level,
1343 .reg_cache_size = ARRAY_SIZE(adau1373_default_regs),
1344 .reg_cache_default = adau1373_default_regs,
1345 .reg_word_size = sizeof(uint8_t),
1346
1347 .set_pll = adau1373_set_pll,
1348
1349 .controls = adau1373_controls,
1350 .num_controls = ARRAY_SIZE(adau1373_controls),
1351 .dapm_widgets = adau1373_dapm_widgets,
1352 .num_dapm_widgets = ARRAY_SIZE(adau1373_dapm_widgets),
1353 .dapm_routes = adau1373_dapm_routes,
1354 .num_dapm_routes = ARRAY_SIZE(adau1373_dapm_routes),
1355};
1356
1357static int __devinit adau1373_i2c_probe(struct i2c_client *client,
1358 const struct i2c_device_id *id)
1359{
1360 struct adau1373 *adau1373;
1361 int ret;
1362
1363 adau1373 = kzalloc(sizeof(*adau1373), GFP_KERNEL);
1364 if (!adau1373)
1365 return -ENOMEM;
1366
1367 dev_set_drvdata(&client->dev, adau1373);
1368
1369 ret = snd_soc_register_codec(&client->dev, &adau1373_codec_driver,
1370 adau1373_dai_driver, ARRAY_SIZE(adau1373_dai_driver));
1371 if (ret < 0)
1372 kfree(adau1373);
1373
1374 return ret;
1375}
1376
1377static int __devexit adau1373_i2c_remove(struct i2c_client *client)
1378{
1379 snd_soc_unregister_codec(&client->dev);
1380 kfree(dev_get_drvdata(&client->dev));
1381 return 0;
1382}
1383
1384static const struct i2c_device_id adau1373_i2c_id[] = {
1385 { "adau1373", 0 },
1386 { }
1387};
1388MODULE_DEVICE_TABLE(i2c, adau1373_i2c_id);
1389
1390static struct i2c_driver adau1373_i2c_driver = {
1391 .driver = {
1392 .name = "adau1373",
1393 .owner = THIS_MODULE,
1394 },
1395 .probe = adau1373_i2c_probe,
1396 .remove = __devexit_p(adau1373_i2c_remove),
1397 .id_table = adau1373_i2c_id,
1398};
1399
1400static int __init adau1373_init(void)
1401{
1402 return i2c_add_driver(&adau1373_i2c_driver);
1403}
1404module_init(adau1373_init);
1405
1406static void __exit adau1373_exit(void)
1407{
1408 i2c_del_driver(&adau1373_i2c_driver);
1409}
1410module_exit(adau1373_exit);
1411
1412MODULE_DESCRIPTION("ASoC ADAU1373 driver");
1413MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
1414MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/adau1373.h b/sound/soc/codecs/adau1373.h
new file mode 100644
index 00000000000..c6ab5530760
--- /dev/null
+++ b/sound/soc/codecs/adau1373.h
@@ -0,0 +1,29 @@
1#ifndef __ADAU1373_H__
2#define __ADAU1373_H__
3
4enum adau1373_pll_src {
5 ADAU1373_PLL_SRC_MCLK1 = 0,
6 ADAU1373_PLL_SRC_BCLK1 = 1,
7 ADAU1373_PLL_SRC_BCLK2 = 2,
8 ADAU1373_PLL_SRC_BCLK3 = 3,
9 ADAU1373_PLL_SRC_LRCLK1 = 4,
10 ADAU1373_PLL_SRC_LRCLK2 = 5,
11 ADAU1373_PLL_SRC_LRCLK3 = 6,
12 ADAU1373_PLL_SRC_GPIO1 = 7,
13 ADAU1373_PLL_SRC_GPIO2 = 8,
14 ADAU1373_PLL_SRC_GPIO3 = 9,
15 ADAU1373_PLL_SRC_GPIO4 = 10,
16 ADAU1373_PLL_SRC_MCLK2 = 11,
17};
18
19enum adau1373_pll {
20 ADAU1373_PLL1 = 0,
21 ADAU1373_PLL2 = 1,
22};
23
24enum adau1373_clk_src {
25 ADAU1373_CLK_SRC_PLL1 = 0,
26 ADAU1373_CLK_SRC_PLL2 = 1,
27};
28
29#endif
diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c
index 2758d5fc60d..8b7e1c50d6e 100644
--- a/sound/soc/codecs/adau1701.c
+++ b/sound/soc/codecs/adau1701.c
@@ -401,7 +401,7 @@ static int adau1701_digital_mute(struct snd_soc_dai *dai, int mute)
401} 401}
402 402
403static int adau1701_set_sysclk(struct snd_soc_codec *codec, int clk_id, 403static int adau1701_set_sysclk(struct snd_soc_codec *codec, int clk_id,
404 unsigned int freq, int dir) 404 int source, unsigned int freq, int dir)
405{ 405{
406 unsigned int val; 406 unsigned int val;
407 407
@@ -458,6 +458,7 @@ static int adau1701_probe(struct snd_soc_codec *codec)
458 int ret; 458 int ret;
459 459
460 codec->dapm.idle_bias_off = 1; 460 codec->dapm.idle_bias_off = 1;
461 codec->control_data = to_i2c_client(codec->dev);
461 462
462 ret = adau1701_load_firmware(codec); 463 ret = adau1701_load_firmware(codec);
463 if (ret) 464 if (ret)
diff --git a/sound/soc/codecs/adav80x.c b/sound/soc/codecs/adav80x.c
index 300c04b70e7..f9f08948e5e 100644
--- a/sound/soc/codecs/adav80x.c
+++ b/sound/soc/codecs/adav80x.c
@@ -523,7 +523,8 @@ static int adav80x_hw_params(struct snd_pcm_substream *substream,
523} 523}
524 524
525static int adav80x_set_sysclk(struct snd_soc_codec *codec, 525static int adav80x_set_sysclk(struct snd_soc_codec *codec,
526 int clk_id, unsigned int freq, int dir) 526 int clk_id, int source,
527 unsigned int freq, int dir)
527{ 528{
528 struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); 529 struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
529 530
diff --git a/sound/soc/codecs/ads117x.h b/sound/soc/codecs/ads117x.h
deleted file mode 100644
index 3ce02861400..00000000000
--- a/sound/soc/codecs/ads117x.h
+++ /dev/null
@@ -1,13 +0,0 @@
1/*
2 * ads117x.h -- Driver for ads1174/8 ADC chips
3 *
4 * Copyright 2009 ShotSpotter Inc.
5 * Author: Graeme Gregory <gg@slimlogic.co.uk>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12extern struct snd_soc_dai_driver ads117x_dai;
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 cbf0b6d400b..d3b29dce6ed 100644
--- a/sound/soc/codecs/ak4104.c
+++ b/sound/soc/codecs/ak4104.c
@@ -247,7 +247,7 @@ static struct snd_soc_codec_driver soc_codec_device_ak4104 = {
247 .probe = ak4104_probe, 247 .probe = ak4104_probe,
248 .remove = ak4104_remove, 248 .remove = ak4104_remove,
249 .reg_cache_size = AK4104_NUM_REGS, 249 .reg_cache_size = AK4104_NUM_REGS,
250 .reg_word_size = sizeof(u16), 250 .reg_word_size = sizeof(u8),
251}; 251};
252 252
253static int ak4104_spi_probe(struct spi_device *spi) 253static int ak4104_spi_probe(struct spi_device *spi)
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
index e1a214ee757..95d782d86e7 100644
--- a/sound/soc/codecs/ak4535.c
+++ b/sound/soc/codecs/ak4535.c
@@ -34,74 +34,16 @@
34struct ak4535_priv { 34struct ak4535_priv {
35 unsigned int sysclk; 35 unsigned int sysclk;
36 enum snd_soc_control_type control_type; 36 enum snd_soc_control_type control_type;
37 void *control_data;
38}; 37};
39 38
40/* 39/*
41 * ak4535 register cache 40 * ak4535 register cache
42 */ 41 */
43static const u16 ak4535_reg[AK4535_CACHEREGNUM] = { 42static const u8 ak4535_reg[AK4535_CACHEREGNUM] = {
44 0x0000, 0x0080, 0x0000, 0x0003, 43 0x00, 0x80, 0x00, 0x03,
45 0x0002, 0x0000, 0x0011, 0x0001, 44 0x02, 0x00, 0x11, 0x01,
46 0x0000, 0x0040, 0x0036, 0x0010, 45 0x00, 0x40, 0x36, 0x10,
47 0x0000, 0x0000, 0x0057, 0x0000, 46 0x00, 0x00, 0x57, 0x00,
48};
49
50/*
51 * read ak4535 register cache
52 */
53static inline unsigned int ak4535_read_reg_cache(struct snd_soc_codec *codec,
54 unsigned int reg)
55{
56 u16 *cache = codec->reg_cache;
57 if (reg >= AK4535_CACHEREGNUM)
58 return -1;
59 return cache[reg];
60}
61
62/*
63 * write ak4535 register cache
64 */
65static inline void ak4535_write_reg_cache(struct snd_soc_codec *codec,
66 u16 reg, unsigned int value)
67{
68 u16 *cache = codec->reg_cache;
69 if (reg >= AK4535_CACHEREGNUM)
70 return;
71 cache[reg] = value;
72}
73
74/*
75 * write to the AK4535 register space
76 */
77static int ak4535_write(struct snd_soc_codec *codec, unsigned int reg,
78 unsigned int value)
79{
80 u8 data[2];
81
82 /* data is
83 * D15..D8 AK4535 register offset
84 * D7...D0 register data
85 */
86 data[0] = reg & 0xff;
87 data[1] = value & 0xff;
88
89 ak4535_write_reg_cache(codec, reg, value);
90 if (codec->hw_write(codec->control_data, data, 2) == 2)
91 return 0;
92 else
93 return -EIO;
94}
95
96static int ak4535_sync(struct snd_soc_codec *codec)
97{
98 u16 *cache = codec->reg_cache;
99 int i, r = 0;
100
101 for (i = 0; i < AK4535_CACHEREGNUM; i++)
102 r |= ak4535_write(codec, i, cache[i]);
103
104 return r;
105}; 47};
106 48
107static const char *ak4535_mono_gain[] = {"+6dB", "-17dB"}; 49static const char *ak4535_mono_gain[] = {"+6dB", "-17dB"};
@@ -304,7 +246,7 @@ static int ak4535_hw_params(struct snd_pcm_substream *substream,
304 struct snd_soc_pcm_runtime *rtd = substream->private_data; 246 struct snd_soc_pcm_runtime *rtd = substream->private_data;
305 struct snd_soc_codec *codec = rtd->codec; 247 struct snd_soc_codec *codec = rtd->codec;
306 struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec); 248 struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec);
307 u8 mode2 = ak4535_read_reg_cache(codec, AK4535_MODE2) & ~(0x3 << 5); 249 u8 mode2 = snd_soc_read(codec, AK4535_MODE2) & ~(0x3 << 5);
308 int rate = params_rate(params), fs = 256; 250 int rate = params_rate(params), fs = 256;
309 251
310 if (rate) 252 if (rate)
@@ -323,7 +265,7 @@ static int ak4535_hw_params(struct snd_pcm_substream *substream,
323 } 265 }
324 266
325 /* set rate */ 267 /* set rate */
326 ak4535_write(codec, AK4535_MODE2, mode2); 268 snd_soc_write(codec, AK4535_MODE2, mode2);
327 return 0; 269 return 0;
328} 270}
329 271
@@ -348,44 +290,37 @@ static int ak4535_set_dai_fmt(struct snd_soc_dai *codec_dai,
348 /* use 32 fs for BCLK to save power */ 290 /* use 32 fs for BCLK to save power */
349 mode1 |= 0x4; 291 mode1 |= 0x4;
350 292
351 ak4535_write(codec, AK4535_MODE1, mode1); 293 snd_soc_write(codec, AK4535_MODE1, mode1);
352 return 0; 294 return 0;
353} 295}
354 296
355static int ak4535_mute(struct snd_soc_dai *dai, int mute) 297static int ak4535_mute(struct snd_soc_dai *dai, int mute)
356{ 298{
357 struct snd_soc_codec *codec = dai->codec; 299 struct snd_soc_codec *codec = dai->codec;
358 u16 mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC); 300 u16 mute_reg = snd_soc_read(codec, AK4535_DAC);
359 if (!mute) 301 if (!mute)
360 ak4535_write(codec, AK4535_DAC, mute_reg & ~0x20); 302 snd_soc_write(codec, AK4535_DAC, mute_reg & ~0x20);
361 else 303 else
362 ak4535_write(codec, AK4535_DAC, mute_reg | 0x20); 304 snd_soc_write(codec, AK4535_DAC, mute_reg | 0x20);
363 return 0; 305 return 0;
364} 306}
365 307
366static int ak4535_set_bias_level(struct snd_soc_codec *codec, 308static int ak4535_set_bias_level(struct snd_soc_codec *codec,
367 enum snd_soc_bias_level level) 309 enum snd_soc_bias_level level)
368{ 310{
369 u16 i, mute_reg;
370
371 switch (level) { 311 switch (level) {
372 case SND_SOC_BIAS_ON: 312 case SND_SOC_BIAS_ON:
373 mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC); 313 snd_soc_update_bits(codec, AK4535_DAC, 0x20, 0);
374 ak4535_write(codec, AK4535_DAC, mute_reg & ~0x20);
375 break; 314 break;
376 case SND_SOC_BIAS_PREPARE: 315 case SND_SOC_BIAS_PREPARE:
377 mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC); 316 snd_soc_update_bits(codec, AK4535_DAC, 0x20, 0x20);
378 ak4535_write(codec, AK4535_DAC, mute_reg | 0x20);
379 break; 317 break;
380 case SND_SOC_BIAS_STANDBY: 318 case SND_SOC_BIAS_STANDBY:
381 i = ak4535_read_reg_cache(codec, AK4535_PM1); 319 snd_soc_update_bits(codec, AK4535_PM1, 0x80, 0x80);
382 ak4535_write(codec, AK4535_PM1, i | 0x80); 320 snd_soc_update_bits(codec, AK4535_PM2, 0x80, 0);
383 i = ak4535_read_reg_cache(codec, AK4535_PM2);
384 ak4535_write(codec, AK4535_PM2, i & (~0x80));
385 break; 321 break;
386 case SND_SOC_BIAS_OFF: 322 case SND_SOC_BIAS_OFF:
387 i = ak4535_read_reg_cache(codec, AK4535_PM1); 323 snd_soc_update_bits(codec, AK4535_PM1, 0x80, 0);
388 ak4535_write(codec, AK4535_PM1, i & (~0x80));
389 break; 324 break;
390 } 325 }
391 codec->dapm.bias_level = level; 326 codec->dapm.bias_level = level;
@@ -428,7 +363,7 @@ static int ak4535_suspend(struct snd_soc_codec *codec, pm_message_t state)
428 363
429static int ak4535_resume(struct snd_soc_codec *codec) 364static int ak4535_resume(struct snd_soc_codec *codec)
430{ 365{
431 ak4535_sync(codec); 366 snd_soc_cache_sync(codec);
432 ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 367 ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
433 return 0; 368 return 0;
434} 369}
@@ -436,11 +371,15 @@ static int ak4535_resume(struct snd_soc_codec *codec)
436static int ak4535_probe(struct snd_soc_codec *codec) 371static int ak4535_probe(struct snd_soc_codec *codec)
437{ 372{
438 struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec); 373 struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec);
374 int ret;
439 375
440 printk(KERN_INFO "AK4535 Audio Codec %s", AK4535_VERSION); 376 printk(KERN_INFO "AK4535 Audio Codec %s", AK4535_VERSION);
441 377
442 codec->control_data = ak4535->control_data; 378 ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4535->control_type);
443 379 if (ret < 0) {
380 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
381 return ret;
382 }
444 /* power on device */ 383 /* power on device */
445 ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 384 ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
446 385
@@ -461,8 +400,6 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4535 = {
461 .remove = ak4535_remove, 400 .remove = ak4535_remove,
462 .suspend = ak4535_suspend, 401 .suspend = ak4535_suspend,
463 .resume = ak4535_resume, 402 .resume = ak4535_resume,
464 .read = ak4535_read_reg_cache,
465 .write = ak4535_write,
466 .set_bias_level = ak4535_set_bias_level, 403 .set_bias_level = ak4535_set_bias_level,
467 .reg_cache_size = ARRAY_SIZE(ak4535_reg), 404 .reg_cache_size = ARRAY_SIZE(ak4535_reg),
468 .reg_word_size = sizeof(u8), 405 .reg_word_size = sizeof(u8),
@@ -485,7 +422,6 @@ static __devinit int ak4535_i2c_probe(struct i2c_client *i2c,
485 return -ENOMEM; 422 return -ENOMEM;
486 423
487 i2c_set_clientdata(i2c, ak4535); 424 i2c_set_clientdata(i2c, ak4535);
488 ak4535->control_data = i2c;
489 ak4535->control_type = SND_SOC_I2C; 425 ak4535->control_type = SND_SOC_I2C;
490 426
491 ret = snd_soc_register_codec(&i2c->dev, 427 ret = snd_soc_register_codec(&i2c->dev,
diff --git a/sound/soc/codecs/ak4641.c b/sound/soc/codecs/ak4641.c
index 7a64e58cddc..77838586f35 100644
--- a/sound/soc/codecs/ak4641.c
+++ b/sound/soc/codecs/ak4641.c
@@ -31,7 +31,6 @@
31 31
32/* codec private data */ 32/* codec private data */
33struct ak4641_priv { 33struct ak4641_priv {
34 struct snd_soc_codec *codec;
35 unsigned int sysclk; 34 unsigned int sysclk;
36 int deemph; 35 int deemph;
37 int playback_fs; 36 int playback_fs;
@@ -226,7 +225,7 @@ static const struct snd_soc_dapm_widget ak4641_dapm_widgets[] = {
226 SND_SOC_DAPM_PGA("Mono Out 2", AK4641_PM2, 3, 0, NULL, 0), 225 SND_SOC_DAPM_PGA("Mono Out 2", AK4641_PM2, 3, 0, NULL, 0),
227 226
228 SND_SOC_DAPM_ADC("Voice ADC", "Voice Capture", AK4641_BTIF, 0, 0), 227 SND_SOC_DAPM_ADC("Voice ADC", "Voice Capture", AK4641_BTIF, 0, 0),
229 SND_SOC_DAPM_ADC("Voice DAC", "Voice Playback", AK4641_BTIF, 1, 0), 228 SND_SOC_DAPM_DAC("Voice DAC", "Voice Playback", AK4641_BTIF, 1, 0),
230 229
231 SND_SOC_DAPM_MICBIAS("Mic Int Bias", AK4641_MIC, 3, 0), 230 SND_SOC_DAPM_MICBIAS("Mic Int Bias", AK4641_MIC, 3, 0),
232 SND_SOC_DAPM_MICBIAS("Mic Ext Bias", AK4641_MIC, 4, 0), 231 SND_SOC_DAPM_MICBIAS("Mic Ext Bias", AK4641_MIC, 4, 0),
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
index 65f46047b1c..d8fc04486ab 100644
--- a/sound/soc/codecs/ak4642.c
+++ b/sound/soc/codecs/ak4642.c
@@ -156,81 +156,22 @@ static const struct snd_kcontrol_new ak4642_snd_controls[] = {
156struct ak4642_priv { 156struct ak4642_priv {
157 unsigned int sysclk; 157 unsigned int sysclk;
158 enum snd_soc_control_type control_type; 158 enum snd_soc_control_type control_type;
159 void *control_data;
160}; 159};
161 160
162/* 161/*
163 * ak4642 register cache 162 * ak4642 register cache
164 */ 163 */
165static const u16 ak4642_reg[AK4642_CACHEREGNUM] = { 164static const u8 ak4642_reg[AK4642_CACHEREGNUM] = {
166 0x0000, 0x0000, 0x0001, 0x0000, 165 0x00, 0x00, 0x01, 0x00,
167 0x0002, 0x0000, 0x0000, 0x0000, 166 0x02, 0x00, 0x00, 0x00,
168 0x00e1, 0x00e1, 0x0018, 0x0000, 167 0xe1, 0xe1, 0x18, 0x00,
169 0x00e1, 0x0018, 0x0011, 0x0008, 168 0xe1, 0x18, 0x11, 0x08,
170 0x0000, 0x0000, 0x0000, 0x0000, 169 0x00, 0x00, 0x00, 0x00,
171 0x0000, 0x0000, 0x0000, 0x0000, 170 0x00, 0x00, 0x00, 0x00,
172 0x0000, 0x0000, 0x0000, 0x0000, 171 0x00, 0x00, 0x00, 0x00,
173 0x0000, 0x0000, 0x0000, 0x0000, 172 0x00, 0x00, 0x00, 0x00,
174 0x0000, 0x0000, 0x0000, 0x0000, 173 0x00, 0x00, 0x00, 0x00,
175 0x0000, 174 0x00,
176};
177
178/*
179 * read ak4642 register cache
180 */
181static inline unsigned int ak4642_read_reg_cache(struct snd_soc_codec *codec,
182 unsigned int reg)
183{
184 u16 *cache = codec->reg_cache;
185 if (reg >= AK4642_CACHEREGNUM)
186 return -1;
187 return cache[reg];
188}
189
190/*
191 * write ak4642 register cache
192 */
193static inline void ak4642_write_reg_cache(struct snd_soc_codec *codec,
194 u16 reg, unsigned int value)
195{
196 u16 *cache = codec->reg_cache;
197 if (reg >= AK4642_CACHEREGNUM)
198 return;
199
200 cache[reg] = value;
201}
202
203/*
204 * write to the AK4642 register space
205 */
206static int ak4642_write(struct snd_soc_codec *codec, unsigned int reg,
207 unsigned int value)
208{
209 u8 data[2];
210
211 /* data is
212 * D15..D8 AK4642 register offset
213 * D7...D0 register data
214 */
215 data[0] = reg & 0xff;
216 data[1] = value & 0xff;
217
218 if (codec->hw_write(codec->control_data, data, 2) == 2) {
219 ak4642_write_reg_cache(codec, reg, value);
220 return 0;
221 } else
222 return -EIO;
223}
224
225static int ak4642_sync(struct snd_soc_codec *codec)
226{
227 u16 *cache = codec->reg_cache;
228 int i, r = 0;
229
230 for (i = 0; i < AK4642_CACHEREGNUM; i++)
231 r |= ak4642_write(codec, i, cache[i]);
232
233 return r;
234}; 175};
235 176
236static int ak4642_dai_startup(struct snd_pcm_substream *substream, 177static int ak4642_dai_startup(struct snd_pcm_substream *substream,
@@ -252,8 +193,8 @@ static int ak4642_dai_startup(struct snd_pcm_substream *substream,
252 */ 193 */
253 snd_soc_update_bits(codec, MD_CTL4, DACH, DACH); 194 snd_soc_update_bits(codec, MD_CTL4, DACH, DACH);
254 snd_soc_update_bits(codec, MD_CTL3, BST1, BST1); 195 snd_soc_update_bits(codec, MD_CTL3, BST1, BST1);
255 ak4642_write(codec, L_IVC, 0x91); /* volume */ 196 snd_soc_write(codec, L_IVC, 0x91); /* volume */
256 ak4642_write(codec, R_IVC, 0x91); /* volume */ 197 snd_soc_write(codec, R_IVC, 0x91); /* volume */
257 snd_soc_update_bits(codec, PW_MGMT1, PMVCM | PMMIN | PMDAC, 198 snd_soc_update_bits(codec, PW_MGMT1, PMVCM | PMMIN | PMDAC,
258 PMVCM | PMMIN | PMDAC); 199 PMVCM | PMMIN | PMDAC);
259 snd_soc_update_bits(codec, PW_MGMT2, PMHP_MASK, PMHP); 200 snd_soc_update_bits(codec, PW_MGMT2, PMHP_MASK, PMHP);
@@ -272,9 +213,9 @@ static int ak4642_dai_startup(struct snd_pcm_substream *substream,
272 * This operation came from example code of 213 * This operation came from example code of
273 * "ASAHI KASEI AK4642" (japanese) manual p94. 214 * "ASAHI KASEI AK4642" (japanese) manual p94.
274 */ 215 */
275 ak4642_write(codec, SG_SL1, PMMP | MGAIN0); 216 snd_soc_write(codec, SG_SL1, PMMP | MGAIN0);
276 ak4642_write(codec, TIMER, ZTM(0x3) | WTM(0x3)); 217 snd_soc_write(codec, TIMER, ZTM(0x3) | WTM(0x3));
277 ak4642_write(codec, ALC_CTL1, ALC | LMTH0); 218 snd_soc_write(codec, ALC_CTL1, ALC | LMTH0);
278 snd_soc_update_bits(codec, PW_MGMT1, PMVCM | PMADL, 219 snd_soc_update_bits(codec, PW_MGMT1, PMVCM | PMADL,
279 PMVCM | PMADL); 220 PMVCM | PMADL);
280 snd_soc_update_bits(codec, PW_MGMT3, PMADR, PMADR); 221 snd_soc_update_bits(codec, PW_MGMT3, PMADR, PMADR);
@@ -462,7 +403,7 @@ static struct snd_soc_dai_driver ak4642_dai = {
462 403
463static int ak4642_resume(struct snd_soc_codec *codec) 404static int ak4642_resume(struct snd_soc_codec *codec)
464{ 405{
465 ak4642_sync(codec); 406 snd_soc_cache_sync(codec);
466 return 0; 407 return 0;
467} 408}
468 409
@@ -470,11 +411,15 @@ static int ak4642_resume(struct snd_soc_codec *codec)
470static int ak4642_probe(struct snd_soc_codec *codec) 411static int ak4642_probe(struct snd_soc_codec *codec)
471{ 412{
472 struct ak4642_priv *ak4642 = snd_soc_codec_get_drvdata(codec); 413 struct ak4642_priv *ak4642 = snd_soc_codec_get_drvdata(codec);
414 int ret;
473 415
474 dev_info(codec->dev, "AK4642 Audio Codec %s", AK4642_VERSION); 416 dev_info(codec->dev, "AK4642 Audio Codec %s", AK4642_VERSION);
475 417
476 codec->hw_write = (hw_write_t)i2c_master_send; 418 ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4642->control_type);
477 codec->control_data = ak4642->control_data; 419 if (ret < 0) {
420 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
421 return ret;
422 }
478 423
479 snd_soc_add_controls(codec, ak4642_snd_controls, 424 snd_soc_add_controls(codec, ak4642_snd_controls,
480 ARRAY_SIZE(ak4642_snd_controls)); 425 ARRAY_SIZE(ak4642_snd_controls));
@@ -485,8 +430,6 @@ static int ak4642_probe(struct snd_soc_codec *codec)
485static struct snd_soc_codec_driver soc_codec_dev_ak4642 = { 430static struct snd_soc_codec_driver soc_codec_dev_ak4642 = {
486 .probe = ak4642_probe, 431 .probe = ak4642_probe,
487 .resume = ak4642_resume, 432 .resume = ak4642_resume,
488 .read = ak4642_read_reg_cache,
489 .write = ak4642_write,
490 .reg_cache_size = ARRAY_SIZE(ak4642_reg), 433 .reg_cache_size = ARRAY_SIZE(ak4642_reg),
491 .reg_word_size = sizeof(u8), 434 .reg_word_size = sizeof(u8),
492 .reg_cache_default = ak4642_reg, 435 .reg_cache_default = ak4642_reg,
@@ -504,7 +447,6 @@ static __devinit int ak4642_i2c_probe(struct i2c_client *i2c,
504 return -ENOMEM; 447 return -ENOMEM;
505 448
506 i2c_set_clientdata(i2c, ak4642); 449 i2c_set_clientdata(i2c, ak4642);
507 ak4642->control_data = i2c;
508 ak4642->control_type = SND_SOC_I2C; 450 ak4642->control_type = SND_SOC_I2C;
509 451
510 ret = snd_soc_register_codec(&i2c->dev, 452 ret = snd_soc_register_codec(&i2c->dev,
diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c
index 88b29f8c748..de9ff66d372 100644
--- a/sound/soc/codecs/ak4671.c
+++ b/sound/soc/codecs/ak4671.c
@@ -26,7 +26,6 @@
26/* codec private data */ 26/* codec private data */
27struct ak4671_priv { 27struct ak4671_priv {
28 enum snd_soc_control_type control_type; 28 enum snd_soc_control_type control_type;
29 void *control_data;
30}; 29};
31 30
32/* ak4671 register cache & default register settings */ 31/* ak4671 register cache & default register settings */
@@ -169,18 +168,15 @@ static int ak4671_out2_event(struct snd_soc_dapm_widget *w,
169 struct snd_kcontrol *kcontrol, int event) 168 struct snd_kcontrol *kcontrol, int event)
170{ 169{
171 struct snd_soc_codec *codec = w->codec; 170 struct snd_soc_codec *codec = w->codec;
172 u8 reg;
173 171
174 switch (event) { 172 switch (event) {
175 case SND_SOC_DAPM_POST_PMU: 173 case SND_SOC_DAPM_POST_PMU:
176 reg = snd_soc_read(codec, AK4671_LOUT2_POWER_MANAGERMENT); 174 snd_soc_update_bits(codec, AK4671_LOUT2_POWER_MANAGERMENT,
177 reg |= AK4671_MUTEN; 175 AK4671_MUTEN, AK4671_MUTEN);
178 snd_soc_write(codec, AK4671_LOUT2_POWER_MANAGERMENT, reg);
179 break; 176 break;
180 case SND_SOC_DAPM_PRE_PMD: 177 case SND_SOC_DAPM_PRE_PMD:
181 reg = snd_soc_read(codec, AK4671_LOUT2_POWER_MANAGERMENT); 178 snd_soc_update_bits(codec, AK4671_LOUT2_POWER_MANAGERMENT,
182 reg &= ~AK4671_MUTEN; 179 AK4671_MUTEN, 0);
183 snd_soc_write(codec, AK4671_LOUT2_POWER_MANAGERMENT, reg);
184 break; 180 break;
185 } 181 }
186 182
@@ -576,15 +572,12 @@ static int ak4671_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
576static int ak4671_set_bias_level(struct snd_soc_codec *codec, 572static int ak4671_set_bias_level(struct snd_soc_codec *codec,
577 enum snd_soc_bias_level level) 573 enum snd_soc_bias_level level)
578{ 574{
579 u8 reg;
580
581 switch (level) { 575 switch (level) {
582 case SND_SOC_BIAS_ON: 576 case SND_SOC_BIAS_ON:
583 case SND_SOC_BIAS_PREPARE: 577 case SND_SOC_BIAS_PREPARE:
584 case SND_SOC_BIAS_STANDBY: 578 case SND_SOC_BIAS_STANDBY:
585 reg = snd_soc_read(codec, AK4671_AD_DA_POWER_MANAGEMENT); 579 snd_soc_update_bits(codec, AK4671_AD_DA_POWER_MANAGEMENT,
586 snd_soc_write(codec, AK4671_AD_DA_POWER_MANAGEMENT, 580 AK4671_PMVCM, AK4671_PMVCM);
587 reg | AK4671_PMVCM);
588 break; 581 break;
589 case SND_SOC_BIAS_OFF: 582 case SND_SOC_BIAS_OFF:
590 snd_soc_write(codec, AK4671_AD_DA_POWER_MANAGEMENT, 0x00); 583 snd_soc_write(codec, AK4671_AD_DA_POWER_MANAGEMENT, 0x00);
@@ -629,8 +622,6 @@ static int ak4671_probe(struct snd_soc_codec *codec)
629 struct ak4671_priv *ak4671 = snd_soc_codec_get_drvdata(codec); 622 struct ak4671_priv *ak4671 = snd_soc_codec_get_drvdata(codec);
630 int ret; 623 int ret;
631 624
632 codec->hw_write = (hw_write_t)i2c_master_send;
633
634 ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4671->control_type); 625 ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4671->control_type);
635 if (ret < 0) { 626 if (ret < 0) {
636 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 627 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
@@ -675,7 +666,6 @@ static int __devinit ak4671_i2c_probe(struct i2c_client *client,
675 return -ENOMEM; 666 return -ENOMEM;
676 667
677 i2c_set_clientdata(client, ak4671); 668 i2c_set_clientdata(client, ak4671);
678 ak4671->control_data = client;
679 ak4671->control_type = SND_SOC_I2C; 669 ak4671->control_type = SND_SOC_I2C;
680 670
681 ret = snd_soc_register_codec(&client->dev, 671 ret = snd_soc_register_codec(&client->dev,
diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c
index eecffb54894..984b14bcb60 100644
--- a/sound/soc/codecs/alc5623.c
+++ b/sound/soc/codecs/alc5623.c
@@ -40,8 +40,6 @@ MODULE_PARM_DESC(caps_charge, "ALC5623 cap charge time (msecs)");
40/* codec private data */ 40/* codec private data */
41struct alc5623_priv { 41struct alc5623_priv {
42 enum snd_soc_control_type control_type; 42 enum snd_soc_control_type control_type;
43 void *control_data;
44 struct mutex mutex;
45 u8 id; 43 u8 id;
46 unsigned int sysclk; 44 unsigned int sysclk;
47 u16 reg_cache[ALC5623_VENDOR_ID2+2]; 45 u16 reg_cache[ALC5623_VENDOR_ID2+2];
@@ -55,8 +53,10 @@ static void alc5623_fill_cache(struct snd_soc_codec *codec)
55 u16 *cache = codec->reg_cache; 53 u16 *cache = codec->reg_cache;
56 54
57 /* not really efficient ... */ 55 /* not really efficient ... */
56 codec->cache_bypass = 1;
58 for (i = 0 ; i < codec->driver->reg_cache_size ; i += step) 57 for (i = 0 ; i < codec->driver->reg_cache_size ; i += step)
59 cache[i] = codec->hw_read(codec, i); 58 cache[i] = snd_soc_read(codec, i);
59 codec->cache_bypass = 0;
60} 60}
61 61
62static inline int alc5623_reset(struct snd_soc_codec *codec) 62static inline int alc5623_reset(struct snd_soc_codec *codec)
@@ -1050,9 +1050,7 @@ static int alc5623_i2c_probe(struct i2c_client *client,
1050 } 1050 }
1051 1051
1052 i2c_set_clientdata(client, alc5623); 1052 i2c_set_clientdata(client, alc5623);
1053 alc5623->control_data = client;
1054 alc5623->control_type = SND_SOC_I2C; 1053 alc5623->control_type = SND_SOC_I2C;
1055 mutex_init(&alc5623->mutex);
1056 1054
1057 ret = snd_soc_register_codec(&client->dev, 1055 ret = snd_soc_register_codec(&client->dev,
1058 &soc_codec_device_alc5623, &alc5623_dai, 1); 1056 &soc_codec_device_alc5623, &alc5623_dai, 1);
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index 6cc8678f49f..f1f237ecec2 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -128,7 +128,6 @@ static const char *supply_names[] = {
128/* Private data for the CS4270 */ 128/* Private data for the CS4270 */
129struct cs4270_private { 129struct cs4270_private {
130 enum snd_soc_control_type control_type; 130 enum snd_soc_control_type control_type;
131 void *control_data;
132 unsigned int mclk; /* Input frequency of the MCLK pin */ 131 unsigned int mclk; /* Input frequency of the MCLK pin */
133 unsigned int mode; /* The mode (I2S or left-justified) */ 132 unsigned int mode; /* The mode (I2S or left-justified) */
134 unsigned int slave_mode; 133 unsigned int slave_mode;
@@ -262,7 +261,6 @@ static int cs4270_set_dai_fmt(struct snd_soc_dai *codec_dai,
262{ 261{
263 struct snd_soc_codec *codec = codec_dai->codec; 262 struct snd_soc_codec *codec = codec_dai->codec;
264 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); 263 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
265 int ret = 0;
266 264
267 /* set DAI format */ 265 /* set DAI format */
268 switch (format & SND_SOC_DAIFMT_FORMAT_MASK) { 266 switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -272,7 +270,7 @@ static int cs4270_set_dai_fmt(struct snd_soc_dai *codec_dai,
272 break; 270 break;
273 default: 271 default:
274 dev_err(codec->dev, "invalid dai format\n"); 272 dev_err(codec->dev, "invalid dai format\n");
275 ret = -EINVAL; 273 return -EINVAL;
276 } 274 }
277 275
278 /* set master/slave audio interface */ 276 /* set master/slave audio interface */
@@ -285,10 +283,11 @@ static int cs4270_set_dai_fmt(struct snd_soc_dai *codec_dai,
285 break; 283 break;
286 default: 284 default:
287 /* all other modes are unsupported by the hardware */ 285 /* all other modes are unsupported by the hardware */
288 ret = -EINVAL; 286 dev_err(codec->dev, "Unknown master/slave configuration\n");
287 return -EINVAL;
289 } 288 }
290 289
291 return ret; 290 return 0;
292} 291}
293 292
294/** 293/**
@@ -490,8 +489,6 @@ static int cs4270_probe(struct snd_soc_codec *codec)
490 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); 489 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
491 int i, ret; 490 int i, ret;
492 491
493 codec->control_data = cs4270->control_data;
494
495 /* Tell ASoC what kind of I/O to use to read the registers. ASoC will 492 /* Tell ASoC what kind of I/O to use to read the registers. ASoC will
496 * then do the I2C transactions itself. 493 * then do the I2C transactions itself.
497 */ 494 */
@@ -604,7 +601,7 @@ static int cs4270_soc_suspend(struct snd_soc_codec *codec, pm_message_t mesg)
604static int cs4270_soc_resume(struct snd_soc_codec *codec) 601static int cs4270_soc_resume(struct snd_soc_codec *codec)
605{ 602{
606 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); 603 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
607 struct i2c_client *i2c_client = codec->control_data; 604 struct i2c_client *i2c_client = to_i2c_client(codec->dev);
608 int reg; 605 int reg;
609 606
610 regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies), 607 regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies),
@@ -690,7 +687,6 @@ static int cs4270_i2c_probe(struct i2c_client *i2c_client,
690 } 687 }
691 688
692 i2c_set_clientdata(i2c_client, cs4270); 689 i2c_set_clientdata(i2c_client, cs4270);
693 cs4270->control_data = i2c_client;
694 cs4270->control_type = SND_SOC_I2C; 690 cs4270->control_type = SND_SOC_I2C;
695 691
696 ret = snd_soc_register_codec(&i2c_client->dev, 692 ret = snd_soc_register_codec(&i2c_client->dev,
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c
index 083aab96ca8..23d1bd5dadd 100644
--- a/sound/soc/codecs/cs4271.c
+++ b/sound/soc/codecs/cs4271.c
@@ -156,7 +156,6 @@ static const u8 cs4271_dflt_reg[CS4271_NR_REGS] = {
156struct cs4271_private { 156struct cs4271_private {
157 /* SND_SOC_I2C or SND_SOC_SPI */ 157 /* SND_SOC_I2C or SND_SOC_SPI */
158 enum snd_soc_control_type bus_type; 158 enum snd_soc_control_type bus_type;
159 void *control_data;
160 unsigned int mclk; 159 unsigned int mclk;
161 bool master; 160 bool master;
162 bool deemph; 161 bool deemph;
@@ -466,8 +465,6 @@ static int cs4271_probe(struct snd_soc_codec *codec)
466 int ret; 465 int ret;
467 int gpio_nreset = -EINVAL; 466 int gpio_nreset = -EINVAL;
468 467
469 codec->control_data = cs4271->control_data;
470
471 if (cs4271plat && gpio_is_valid(cs4271plat->gpio_nreset)) 468 if (cs4271plat && gpio_is_valid(cs4271plat->gpio_nreset))
472 gpio_nreset = cs4271plat->gpio_nreset; 469 gpio_nreset = cs4271plat->gpio_nreset;
473 470
@@ -555,7 +552,6 @@ static int __devinit cs4271_spi_probe(struct spi_device *spi)
555 return -ENOMEM; 552 return -ENOMEM;
556 553
557 spi_set_drvdata(spi, cs4271); 554 spi_set_drvdata(spi, cs4271);
558 cs4271->control_data = spi;
559 cs4271->bus_type = SND_SOC_SPI; 555 cs4271->bus_type = SND_SOC_SPI;
560 556
561 return snd_soc_register_codec(&spi->dev, &soc_codec_dev_cs4271, 557 return snd_soc_register_codec(&spi->dev, &soc_codec_dev_cs4271,
@@ -595,7 +591,6 @@ static int __devinit cs4271_i2c_probe(struct i2c_client *client,
595 return -ENOMEM; 591 return -ENOMEM;
596 592
597 i2c_set_clientdata(client, cs4271); 593 i2c_set_clientdata(client, cs4271);
598 cs4271->control_data = client;
599 cs4271->bus_type = SND_SOC_I2C; 594 cs4271->bus_type = SND_SOC_I2C;
600 595
601 return snd_soc_register_codec(&client->dev, &soc_codec_dev_cs4271, 596 return snd_soc_register_codec(&client->dev, &soc_codec_dev_cs4271,
diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c
index 8fb7070108d..8c3c8205d19 100644
--- a/sound/soc/codecs/cs42l51.c
+++ b/sound/soc/codecs/cs42l51.c
@@ -42,7 +42,6 @@ enum master_slave_mode {
42 42
43struct cs42l51_private { 43struct cs42l51_private {
44 enum snd_soc_control_type control_type; 44 enum snd_soc_control_type control_type;
45 void *control_data;
46 unsigned int mclk; 45 unsigned int mclk;
47 unsigned int audio_mode; /* The mode (I2S or left-justified) */ 46 unsigned int audio_mode; /* The mode (I2S or left-justified) */
48 enum master_slave_mode func; 47 enum master_slave_mode func;
@@ -57,7 +56,7 @@ struct cs42l51_private {
57static int cs42l51_fill_cache(struct snd_soc_codec *codec) 56static int cs42l51_fill_cache(struct snd_soc_codec *codec)
58{ 57{
59 u8 *cache = codec->reg_cache + 1; 58 u8 *cache = codec->reg_cache + 1;
60 struct i2c_client *i2c_client = codec->control_data; 59 struct i2c_client *i2c_client = to_i2c_client(codec->dev);
61 s32 length; 60 s32 length;
62 61
63 length = i2c_smbus_read_i2c_block_data(i2c_client, 62 length = i2c_smbus_read_i2c_block_data(i2c_client,
@@ -289,7 +288,6 @@ static int cs42l51_set_dai_fmt(struct snd_soc_dai *codec_dai,
289{ 288{
290 struct snd_soc_codec *codec = codec_dai->codec; 289 struct snd_soc_codec *codec = codec_dai->codec;
291 struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec); 290 struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
292 int ret = 0;
293 291
294 switch (format & SND_SOC_DAIFMT_FORMAT_MASK) { 292 switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
295 case SND_SOC_DAIFMT_I2S: 293 case SND_SOC_DAIFMT_I2S:
@@ -299,7 +297,7 @@ static int cs42l51_set_dai_fmt(struct snd_soc_dai *codec_dai,
299 break; 297 break;
300 default: 298 default:
301 dev_err(codec->dev, "invalid DAI format\n"); 299 dev_err(codec->dev, "invalid DAI format\n");
302 ret = -EINVAL; 300 return -EINVAL;
303 } 301 }
304 302
305 switch (format & SND_SOC_DAIFMT_MASTER_MASK) { 303 switch (format & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -310,11 +308,11 @@ static int cs42l51_set_dai_fmt(struct snd_soc_dai *codec_dai,
310 cs42l51->func = MODE_SLAVE_AUTO; 308 cs42l51->func = MODE_SLAVE_AUTO;
311 break; 309 break;
312 default: 310 default:
313 ret = -EINVAL; 311 dev_err(codec->dev, "Unknown master/slave configuration\n");
314 break; 312 return -EINVAL;
315 } 313 }
316 314
317 return ret; 315 return 0;
318} 316}
319 317
320struct cs42l51_ratios { 318struct cs42l51_ratios {
@@ -520,8 +518,6 @@ static int cs42l51_probe(struct snd_soc_codec *codec)
520 struct snd_soc_dapm_context *dapm = &codec->dapm; 518 struct snd_soc_dapm_context *dapm = &codec->dapm;
521 int ret, reg; 519 int ret, reg;
522 520
523 codec->control_data = cs42l51->control_data;
524
525 ret = cs42l51_fill_cache(codec); 521 ret = cs42l51_fill_cache(codec);
526 if (ret < 0) { 522 if (ret < 0) {
527 dev_err(codec->dev, "failed to fill register cache\n"); 523 dev_err(codec->dev, "failed to fill register cache\n");
@@ -593,7 +589,6 @@ static int cs42l51_i2c_probe(struct i2c_client *i2c_client,
593 } 589 }
594 590
595 i2c_set_clientdata(i2c_client, cs42l51); 591 i2c_set_clientdata(i2c_client, cs42l51);
596 cs42l51->control_data = i2c_client;
597 cs42l51->control_type = SND_SOC_I2C; 592 cs42l51->control_type = SND_SOC_I2C;
598 593
599 ret = snd_soc_register_codec(&i2c_client->dev, 594 ret = snd_soc_register_codec(&i2c_client->dev,
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c
index 92fd9d7a922..0ebcbd53449 100644
--- a/sound/soc/codecs/da7210.c
+++ b/sound/soc/codecs/da7210.c
@@ -26,23 +26,41 @@
26#include <sound/tlv.h> 26#include <sound/tlv.h>
27 27
28/* DA7210 register space */ 28/* DA7210 register space */
29#define DA7210_CONTROL 0x01
29#define DA7210_STATUS 0x02 30#define DA7210_STATUS 0x02
30#define DA7210_STARTUP1 0x03 31#define DA7210_STARTUP1 0x03
32#define DA7210_STARTUP2 0x04
33#define DA7210_STARTUP3 0x05
31#define DA7210_MIC_L 0x07 34#define DA7210_MIC_L 0x07
32#define DA7210_MIC_R 0x08 35#define DA7210_MIC_R 0x08
36#define DA7210_AUX1_L 0x09
37#define DA7210_AUX1_R 0x0A
38#define DA7210_AUX2 0x0B
39#define DA7210_IN_GAIN 0x0C
33#define DA7210_INMIX_L 0x0D 40#define DA7210_INMIX_L 0x0D
34#define DA7210_INMIX_R 0x0E 41#define DA7210_INMIX_R 0x0E
35#define DA7210_ADC_HPF 0x0F 42#define DA7210_ADC_HPF 0x0F
36#define DA7210_ADC 0x10 43#define DA7210_ADC 0x10
44#define DA7210_ADC_EQ1_2 0X11
45#define DA7210_ADC_EQ3_4 0x12
46#define DA7210_ADC_EQ5 0x13
37#define DA7210_DAC_HPF 0x14 47#define DA7210_DAC_HPF 0x14
38#define DA7210_DAC_L 0x15 48#define DA7210_DAC_L 0x15
39#define DA7210_DAC_R 0x16 49#define DA7210_DAC_R 0x16
40#define DA7210_DAC_SEL 0x17 50#define DA7210_DAC_SEL 0x17
51#define DA7210_SOFTMUTE 0x18
52#define DA7210_DAC_EQ1_2 0x19
53#define DA7210_DAC_EQ3_4 0x1A
54#define DA7210_DAC_EQ5 0x1B
41#define DA7210_OUTMIX_L 0x1C 55#define DA7210_OUTMIX_L 0x1C
42#define DA7210_OUTMIX_R 0x1D 56#define DA7210_OUTMIX_R 0x1D
57#define DA7210_OUT1_L 0x1E
58#define DA7210_OUT1_R 0x1F
59#define DA7210_OUT2 0x20
43#define DA7210_HP_L_VOL 0x21 60#define DA7210_HP_L_VOL 0x21
44#define DA7210_HP_R_VOL 0x22 61#define DA7210_HP_R_VOL 0x22
45#define DA7210_HP_CFG 0x23 62#define DA7210_HP_CFG 0x23
63#define DA7210_ZERO_CROSS 0x24
46#define DA7210_DAI_SRC_SEL 0x25 64#define DA7210_DAI_SRC_SEL 0x25
47#define DA7210_DAI_CFG1 0x26 65#define DA7210_DAI_CFG1 0x26
48#define DA7210_DAI_CFG3 0x28 66#define DA7210_DAI_CFG3 0x28
@@ -50,6 +68,12 @@
50#define DA7210_PLL_DIV2 0x2A 68#define DA7210_PLL_DIV2 0x2A
51#define DA7210_PLL_DIV3 0x2B 69#define DA7210_PLL_DIV3 0x2B
52#define DA7210_PLL 0x2C 70#define DA7210_PLL 0x2C
71#define DA7210_ALC_MAX 0x83
72#define DA7210_ALC_MIN 0x84
73#define DA7210_ALC_NOIS 0x85
74#define DA7210_ALC_ATT 0x86
75#define DA7210_ALC_REL 0x87
76#define DA7210_ALC_DEL 0x88
53#define DA7210_A_HID_UNLOCK 0x8A 77#define DA7210_A_HID_UNLOCK 0x8A
54#define DA7210_A_TEST_UNLOCK 0x8B 78#define DA7210_A_TEST_UNLOCK 0x8B
55#define DA7210_A_PLL1 0x90 79#define DA7210_A_PLL1 0x90
@@ -72,6 +96,7 @@
72#define DA7210_IN_R_EN (1 << 7) 96#define DA7210_IN_R_EN (1 << 7)
73 97
74/* ADC bit fields */ 98/* ADC bit fields */
99#define DA7210_ADC_ALC_EN (1 << 0)
75#define DA7210_ADC_L_EN (1 << 3) 100#define DA7210_ADC_L_EN (1 << 3)
76#define DA7210_ADC_R_EN (1 << 7) 101#define DA7210_ADC_R_EN (1 << 7)
77 102
@@ -105,12 +130,17 @@
105 130
106/* DAI_CFG1 bit fields */ 131/* DAI_CFG1 bit fields */
107#define DA7210_DAI_WORD_S16_LE (0 << 0) 132#define DA7210_DAI_WORD_S16_LE (0 << 0)
133#define DA7210_DAI_WORD_S20_3LE (1 << 0)
108#define DA7210_DAI_WORD_S24_LE (2 << 0) 134#define DA7210_DAI_WORD_S24_LE (2 << 0)
135#define DA7210_DAI_WORD_S32_LE (3 << 0)
109#define DA7210_DAI_FLEN_64BIT (1 << 2) 136#define DA7210_DAI_FLEN_64BIT (1 << 2)
137#define DA7210_DAI_MODE_SLAVE (0 << 7)
110#define DA7210_DAI_MODE_MASTER (1 << 7) 138#define DA7210_DAI_MODE_MASTER (1 << 7)
111 139
112/* DAI_CFG3 bit fields */ 140/* DAI_CFG3 bit fields */
113#define DA7210_DAI_FORMAT_I2SMODE (0 << 0) 141#define DA7210_DAI_FORMAT_I2SMODE (0 << 0)
142#define DA7210_DAI_FORMAT_LEFT_J (1 << 0)
143#define DA7210_DAI_FORMAT_RIGHT_J (2 << 0)
114#define DA7210_DAI_OE (1 << 3) 144#define DA7210_DAI_OE (1 << 3)
115#define DA7210_DAI_EN (1 << 7) 145#define DA7210_DAI_EN (1 << 7)
116 146
@@ -133,6 +163,43 @@
133#define DA7210_PLL_FS_96000 (0xF << 0) 163#define DA7210_PLL_FS_96000 (0xF << 0)
134#define DA7210_PLL_EN (0x1 << 7) 164#define DA7210_PLL_EN (0x1 << 7)
135 165
166/* SOFTMUTE bit fields */
167#define DA7210_RAMP_EN (1 << 6)
168
169/* CONTROL bit fields */
170#define DA7210_NOISE_SUP_EN (1 << 3)
171
172/* IN_GAIN bit fields */
173#define DA7210_INPGA_L_VOL (0x0F << 0)
174#define DA7210_INPGA_R_VOL (0xF0 << 0)
175
176/* ZERO_CROSS bit fields */
177#define DA7210_AUX1_L_ZC (1 << 0)
178#define DA7210_AUX1_R_ZC (1 << 1)
179#define DA7210_HP_L_ZC (1 << 6)
180#define DA7210_HP_R_ZC (1 << 7)
181
182/* AUX1_L bit fields */
183#define DA7210_AUX1_L_VOL (0x3F << 0)
184
185/* AUX1_R bit fields */
186#define DA7210_AUX1_R_VOL (0x3F << 0)
187
188/* Minimum INPGA and AUX1 volume to enable noise suppression */
189#define DA7210_INPGA_MIN_VOL_NS 0x0A /* 10.5dB */
190#define DA7210_AUX1_MIN_VOL_NS 0x35 /* 6dB */
191
192/* OUT1_L bit fields */
193#define DA7210_OUT1_L_EN (1 << 7)
194
195/* OUT1_R bit fields */
196#define DA7210_OUT1_R_EN (1 << 7)
197
198/* OUT2 bit fields */
199#define DA7210_OUT2_OUTMIX_R (1 << 5)
200#define DA7210_OUT2_OUTMIX_L (1 << 6)
201#define DA7210_OUT2_EN (1 << 7)
202
136#define DA7210_VERSION "0.0.1" 203#define DA7210_VERSION "0.0.1"
137 204
138/* 205/*
@@ -144,24 +211,351 @@
144 * mute : 0x10 211 * mute : 0x10
145 * reserved : 0x00 - 0x0F 212 * reserved : 0x00 - 0x0F
146 * 213 *
147 * ** FIXME **
148 *
149 * Reserved area are considered as "mute". 214 * Reserved area are considered as "mute".
150 * -> min = -79.5 dB
151 */ 215 */
152static const DECLARE_TLV_DB_SCALE(hp_out_tlv, -7950, 150, 1); 216static const unsigned int hp_out_tlv[] = {
217 TLV_DB_RANGE_HEAD(2),
218 0x0, 0x10, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1),
219 /* -54 dB to +15 dB */
220 0x11, 0x3f, TLV_DB_SCALE_ITEM(-5400, 150, 0),
221};
222
223static const unsigned int lineout_vol_tlv[] = {
224 TLV_DB_RANGE_HEAD(2),
225 0x0, 0x10, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1),
226 /* -54dB to 15dB */
227 0x11, 0x3f, TLV_DB_SCALE_ITEM(-5400, 150, 0)
228};
229
230static const unsigned int mono_vol_tlv[] = {
231 TLV_DB_RANGE_HEAD(2),
232 0x0, 0x2, TLV_DB_SCALE_ITEM(-1800, 0, 1),
233 /* -18dB to 6dB */
234 0x3, 0x7, TLV_DB_SCALE_ITEM(-1800, 600, 0)
235};
236
237static const DECLARE_TLV_DB_SCALE(eq_gain_tlv, -1050, 150, 0);
238static const DECLARE_TLV_DB_SCALE(adc_eq_master_gain_tlv, -1800, 600, 1);
239static const DECLARE_TLV_DB_SCALE(dac_gain_tlv, -7725, 75, 0);
240
241/* ADC and DAC high pass filter f0 value */
242static const char const *da7210_hpf_cutoff_txt[] = {
243 "Fs/8192*pi", "Fs/4096*pi", "Fs/2048*pi", "Fs/1024*pi"
244};
245
246static const struct soc_enum da7210_dac_hpf_cutoff =
247 SOC_ENUM_SINGLE(DA7210_DAC_HPF, 0, 4, da7210_hpf_cutoff_txt);
248
249static const struct soc_enum da7210_adc_hpf_cutoff =
250 SOC_ENUM_SINGLE(DA7210_ADC_HPF, 0, 4, da7210_hpf_cutoff_txt);
251
252/* ADC and DAC voice (8kHz) high pass cutoff value */
253static const char const *da7210_vf_cutoff_txt[] = {
254 "2.5Hz", "25Hz", "50Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz"
255};
256
257static const struct soc_enum da7210_dac_vf_cutoff =
258 SOC_ENUM_SINGLE(DA7210_DAC_HPF, 4, 8, da7210_vf_cutoff_txt);
259
260static const struct soc_enum da7210_adc_vf_cutoff =
261 SOC_ENUM_SINGLE(DA7210_ADC_HPF, 4, 8, da7210_vf_cutoff_txt);
262
263static const char *da7210_hp_mode_txt[] = {
264 "Class H", "Class G"
265};
266
267static const struct soc_enum da7210_hp_mode_sel =
268 SOC_ENUM_SINGLE(DA7210_HP_CFG, 0, 2, da7210_hp_mode_txt);
269
270/* ALC can be enabled only if noise suppression is disabled */
271static int da7210_put_alc_sw(struct snd_kcontrol *kcontrol,
272 struct snd_ctl_elem_value *ucontrol)
273{
274 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
275
276 if (ucontrol->value.integer.value[0]) {
277 /* Check if noise suppression is enabled */
278 if (snd_soc_read(codec, DA7210_CONTROL) & DA7210_NOISE_SUP_EN) {
279 dev_dbg(codec->dev,
280 "Disable noise suppression to enable ALC\n");
281 return -EINVAL;
282 }
283 }
284 /* If all conditions are met or we are actually disabling ALC */
285 return snd_soc_put_volsw(kcontrol, ucontrol);
286}
287
288/* Noise suppression can be enabled only if following conditions are met
289 * ALC disabled
290 * ZC enabled for HP and AUX1 PGA
291 * INPGA_L_VOL and INPGA_R_VOL >= 10.5 dB
292 * AUX1_L_VOL and AUX1_R_VOL >= 6 dB
293 */
294static int da7210_put_noise_sup_sw(struct snd_kcontrol *kcontrol,
295 struct snd_ctl_elem_value *ucontrol)
296{
297 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
298 u8 val;
299
300 if (ucontrol->value.integer.value[0]) {
301 /* Check if ALC is enabled */
302 if (snd_soc_read(codec, DA7210_ADC) & DA7210_ADC_ALC_EN)
303 goto err;
304
305 /* Check ZC for HP and AUX1 PGA */
306 if ((snd_soc_read(codec, DA7210_ZERO_CROSS) &
307 (DA7210_AUX1_L_ZC | DA7210_AUX1_R_ZC | DA7210_HP_L_ZC |
308 DA7210_HP_R_ZC)) != (DA7210_AUX1_L_ZC |
309 DA7210_AUX1_R_ZC | DA7210_HP_L_ZC | DA7210_HP_R_ZC))
310 goto err;
311
312 /* Check INPGA_L_VOL and INPGA_R_VOL */
313 val = snd_soc_read(codec, DA7210_IN_GAIN);
314 if (((val & DA7210_INPGA_L_VOL) < DA7210_INPGA_MIN_VOL_NS) ||
315 (((val & DA7210_INPGA_R_VOL) >> 4) <
316 DA7210_INPGA_MIN_VOL_NS))
317 goto err;
318
319 /* Check AUX1_L_VOL and AUX1_R_VOL */
320 if (((snd_soc_read(codec, DA7210_AUX1_L) & DA7210_AUX1_L_VOL) <
321 DA7210_AUX1_MIN_VOL_NS) ||
322 ((snd_soc_read(codec, DA7210_AUX1_R) & DA7210_AUX1_R_VOL) <
323 DA7210_AUX1_MIN_VOL_NS))
324 goto err;
325 }
326 /* If all conditions are met or we are actually disabling Noise sup */
327 return snd_soc_put_volsw(kcontrol, ucontrol);
328
329err:
330 return -EINVAL;
331}
153 332
154static const struct snd_kcontrol_new da7210_snd_controls[] = { 333static const struct snd_kcontrol_new da7210_snd_controls[] = {
155 334
156 SOC_DOUBLE_R_TLV("HeadPhone Playback Volume", 335 SOC_DOUBLE_R_TLV("HeadPhone Playback Volume",
157 DA7210_HP_L_VOL, DA7210_HP_R_VOL, 336 DA7210_HP_L_VOL, DA7210_HP_R_VOL,
158 0, 0x3F, 0, hp_out_tlv), 337 0, 0x3F, 0, hp_out_tlv),
338 SOC_DOUBLE_R_TLV("Digital Playback Volume",
339 DA7210_DAC_L, DA7210_DAC_R,
340 0, 0x77, 1, dac_gain_tlv),
341 SOC_DOUBLE_R_TLV("Lineout Playback Volume",
342 DA7210_OUT1_L, DA7210_OUT1_R,
343 0, 0x3f, 0, lineout_vol_tlv),
344 SOC_SINGLE_TLV("Mono Playback Volume", DA7210_OUT2, 0, 0x7, 0,
345 mono_vol_tlv),
346
347 /* DAC Equalizer controls */
348 SOC_SINGLE("DAC EQ Switch", DA7210_DAC_EQ5, 7, 1, 0),
349 SOC_SINGLE_TLV("DAC EQ1 Volume", DA7210_DAC_EQ1_2, 0, 0xf, 1,
350 eq_gain_tlv),
351 SOC_SINGLE_TLV("DAC EQ2 Volume", DA7210_DAC_EQ1_2, 4, 0xf, 1,
352 eq_gain_tlv),
353 SOC_SINGLE_TLV("DAC EQ3 Volume", DA7210_DAC_EQ3_4, 0, 0xf, 1,
354 eq_gain_tlv),
355 SOC_SINGLE_TLV("DAC EQ4 Volume", DA7210_DAC_EQ3_4, 4, 0xf, 1,
356 eq_gain_tlv),
357 SOC_SINGLE_TLV("DAC EQ5 Volume", DA7210_DAC_EQ5, 0, 0xf, 1,
358 eq_gain_tlv),
359
360 /* ADC Equalizer controls */
361 SOC_SINGLE("ADC EQ Switch", DA7210_ADC_EQ5, 7, 1, 0),
362 SOC_SINGLE_TLV("ADC EQ Master Volume", DA7210_ADC_EQ5, 4, 0x3,
363 1, adc_eq_master_gain_tlv),
364 SOC_SINGLE_TLV("ADC EQ1 Volume", DA7210_ADC_EQ1_2, 0, 0xf, 1,
365 eq_gain_tlv),
366 SOC_SINGLE_TLV("ADC EQ2 Volume", DA7210_ADC_EQ1_2, 4, 0xf, 1,
367 eq_gain_tlv),
368 SOC_SINGLE_TLV("ADC EQ3 Volume", DA7210_ADC_EQ3_4, 0, 0xf, 1,
369 eq_gain_tlv),
370 SOC_SINGLE_TLV("ADC EQ4 Volume", DA7210_ADC_EQ3_4, 4, 0xf, 1,
371 eq_gain_tlv),
372 SOC_SINGLE_TLV("ADC EQ5 Volume", DA7210_ADC_EQ5, 0, 0xf, 1,
373 eq_gain_tlv),
374
375 SOC_SINGLE("DAC HPF Switch", DA7210_DAC_HPF, 3, 1, 0),
376 SOC_ENUM("DAC HPF Cutoff", da7210_dac_hpf_cutoff),
377 SOC_SINGLE("DAC Voice Mode Switch", DA7210_DAC_HPF, 7, 1, 0),
378 SOC_ENUM("DAC Voice Cutoff", da7210_dac_vf_cutoff),
379
380 SOC_SINGLE("ADC HPF Switch", DA7210_ADC_HPF, 3, 1, 0),
381 SOC_ENUM("ADC HPF Cutoff", da7210_adc_hpf_cutoff),
382 SOC_SINGLE("ADC Voice Mode Switch", DA7210_ADC_HPF, 7, 1, 0),
383 SOC_ENUM("ADC Voice Cutoff", da7210_adc_vf_cutoff),
384
385 /* Mute controls */
386 SOC_DOUBLE_R("Mic Capture Switch", DA7210_MIC_L, DA7210_MIC_R, 3, 1, 0),
387 SOC_SINGLE("Aux2 Capture Switch", DA7210_AUX2, 2, 1, 0),
388 SOC_DOUBLE("ADC Capture Switch", DA7210_ADC, 2, 6, 1, 0),
389 SOC_SINGLE("Digital Soft Mute Switch", DA7210_SOFTMUTE, 7, 1, 0),
390 SOC_SINGLE("Digital Soft Mute Rate", DA7210_SOFTMUTE, 0, 0x7, 0),
391
392 /* Zero cross controls */
393 SOC_DOUBLE("Aux1 ZC Switch", DA7210_ZERO_CROSS, 0, 1, 1, 0),
394 SOC_DOUBLE("In PGA ZC Switch", DA7210_ZERO_CROSS, 2, 3, 1, 0),
395 SOC_DOUBLE("Lineout ZC Switch", DA7210_ZERO_CROSS, 4, 5, 1, 0),
396 SOC_DOUBLE("Headphone ZC Switch", DA7210_ZERO_CROSS, 6, 7, 1, 0),
397
398 SOC_ENUM("Headphone Class", da7210_hp_mode_sel),
399
400 /* ALC controls */
401 SOC_SINGLE_EXT("ALC Enable Switch", DA7210_ADC, 0, 1, 0,
402 snd_soc_get_volsw, da7210_put_alc_sw),
403 SOC_SINGLE("ALC Capture Max Volume", DA7210_ALC_MAX, 0, 0x3F, 0),
404 SOC_SINGLE("ALC Capture Min Volume", DA7210_ALC_MIN, 0, 0x3F, 0),
405 SOC_SINGLE("ALC Capture Noise Volume", DA7210_ALC_NOIS, 0, 0x3F, 0),
406 SOC_SINGLE("ALC Capture Attack Rate", DA7210_ALC_ATT, 0, 0xFF, 0),
407 SOC_SINGLE("ALC Capture Release Rate", DA7210_ALC_REL, 0, 0xFF, 0),
408 SOC_SINGLE("ALC Capture Release Delay", DA7210_ALC_DEL, 0, 0xFF, 0),
409
410 SOC_SINGLE_EXT("Noise Suppression Enable Switch", DA7210_CONTROL, 3, 1,
411 0, snd_soc_get_volsw, da7210_put_noise_sup_sw),
412};
413
414/*
415 * DAPM Controls
416 *
417 * Current DAPM implementation covers almost all codec components e.g. IOs,
418 * mixers, PGAs,ADC and DAC.
419 */
420/* In Mixer Left */
421static const struct snd_kcontrol_new da7210_dapm_inmixl_controls[] = {
422 SOC_DAPM_SINGLE("Mic Left Switch", DA7210_INMIX_L, 0, 1, 0),
423 SOC_DAPM_SINGLE("Mic Right Switch", DA7210_INMIX_L, 1, 1, 0),
424};
425
426/* In Mixer Right */
427static const struct snd_kcontrol_new da7210_dapm_inmixr_controls[] = {
428 SOC_DAPM_SINGLE("Mic Right Switch", DA7210_INMIX_R, 0, 1, 0),
429 SOC_DAPM_SINGLE("Mic Left Switch", DA7210_INMIX_R, 1, 1, 0),
430};
431
432/* Out Mixer Left */
433static const struct snd_kcontrol_new da7210_dapm_outmixl_controls[] = {
434 SOC_DAPM_SINGLE("DAC Left Switch", DA7210_OUTMIX_L, 4, 1, 0),
435};
436
437/* Out Mixer Right */
438static const struct snd_kcontrol_new da7210_dapm_outmixr_controls[] = {
439 SOC_DAPM_SINGLE("DAC Right Switch", DA7210_OUTMIX_R, 4, 1, 0),
440};
441
442/* Mono Mixer */
443static const struct snd_kcontrol_new da7210_dapm_monomix_controls[] = {
444 SOC_DAPM_SINGLE("Outmix Right Switch", DA7210_OUT2, 5, 1, 0),
445 SOC_DAPM_SINGLE("Outmix Left Switch", DA7210_OUT2, 6, 1, 0),
446};
447
448/* DAPM widgets */
449static const struct snd_soc_dapm_widget da7210_dapm_widgets[] = {
450 /* Input Side */
451 /* Input Lines */
452 SND_SOC_DAPM_INPUT("MICL"),
453 SND_SOC_DAPM_INPUT("MICR"),
454
455 /* Input PGAs */
456 SND_SOC_DAPM_PGA("Mic Left", DA7210_STARTUP3, 0, 1, NULL, 0),
457 SND_SOC_DAPM_PGA("Mic Right", DA7210_STARTUP3, 1, 1, NULL, 0),
458
459 SND_SOC_DAPM_PGA("INPGA Left", DA7210_INMIX_L, 7, 0, NULL, 0),
460 SND_SOC_DAPM_PGA("INPGA Right", DA7210_INMIX_R, 7, 0, NULL, 0),
461
462 /* Input Mixers */
463 SND_SOC_DAPM_MIXER("In Mixer Left", SND_SOC_NOPM, 0, 0,
464 &da7210_dapm_inmixl_controls[0],
465 ARRAY_SIZE(da7210_dapm_inmixl_controls)),
466
467 SND_SOC_DAPM_MIXER("In Mixer Right", SND_SOC_NOPM, 0, 0,
468 &da7210_dapm_inmixr_controls[0],
469 ARRAY_SIZE(da7210_dapm_inmixr_controls)),
470
471 /* ADCs */
472 SND_SOC_DAPM_ADC("ADC Left", "Capture", DA7210_STARTUP3, 5, 1),
473 SND_SOC_DAPM_ADC("ADC Right", "Capture", DA7210_STARTUP3, 6, 1),
474
475 /* Output Side */
476 /* DACs */
477 SND_SOC_DAPM_DAC("DAC Left", "Playback", DA7210_STARTUP2, 5, 1),
478 SND_SOC_DAPM_DAC("DAC Right", "Playback", DA7210_STARTUP2, 6, 1),
479
480 /* Output Mixers */
481 SND_SOC_DAPM_MIXER("Out Mixer Left", SND_SOC_NOPM, 0, 0,
482 &da7210_dapm_outmixl_controls[0],
483 ARRAY_SIZE(da7210_dapm_outmixl_controls)),
484
485 SND_SOC_DAPM_MIXER("Out Mixer Right", SND_SOC_NOPM, 0, 0,
486 &da7210_dapm_outmixr_controls[0],
487 ARRAY_SIZE(da7210_dapm_outmixr_controls)),
488
489 SND_SOC_DAPM_MIXER("Mono Mixer", SND_SOC_NOPM, 0, 0,
490 &da7210_dapm_monomix_controls[0],
491 ARRAY_SIZE(da7210_dapm_monomix_controls)),
492
493 /* Output PGAs */
494 SND_SOC_DAPM_PGA("OUTPGA Left Enable", DA7210_OUTMIX_L, 7, 0, NULL, 0),
495 SND_SOC_DAPM_PGA("OUTPGA Right Enable", DA7210_OUTMIX_R, 7, 0, NULL, 0),
496
497 SND_SOC_DAPM_PGA("Out1 Left", DA7210_STARTUP2, 0, 1, NULL, 0),
498 SND_SOC_DAPM_PGA("Out1 Right", DA7210_STARTUP2, 1, 1, NULL, 0),
499 SND_SOC_DAPM_PGA("Out2 Mono", DA7210_STARTUP2, 2, 1, NULL, 0),
500 SND_SOC_DAPM_PGA("Headphone Left", DA7210_STARTUP2, 3, 1, NULL, 0),
501 SND_SOC_DAPM_PGA("Headphone Right", DA7210_STARTUP2, 4, 1, NULL, 0),
502
503 /* Output Lines */
504 SND_SOC_DAPM_OUTPUT("OUT1L"),
505 SND_SOC_DAPM_OUTPUT("OUT1R"),
506 SND_SOC_DAPM_OUTPUT("HPL"),
507 SND_SOC_DAPM_OUTPUT("HPR"),
508 SND_SOC_DAPM_OUTPUT("OUT2"),
509};
510
511/* DAPM audio route definition */
512static const struct snd_soc_dapm_route da7210_audio_map[] = {
513 /* Dest Connecting Widget source */
514 /* Input path */
515 {"Mic Left", NULL, "MICL"},
516 {"Mic Right", NULL, "MICR"},
517
518 {"In Mixer Left", "Mic Left Switch", "Mic Left"},
519 {"In Mixer Left", "Mic Right Switch", "Mic Right"},
520
521 {"In Mixer Right", "Mic Right Switch", "Mic Right"},
522 {"In Mixer Right", "Mic Left Switch", "Mic Left"},
523
524 {"INPGA Left", NULL, "In Mixer Left"},
525 {"ADC Left", NULL, "INPGA Left"},
526
527 {"INPGA Right", NULL, "In Mixer Right"},
528 {"ADC Right", NULL, "INPGA Right"},
529
530 /* Output path */
531 {"Out Mixer Left", "DAC Left Switch", "DAC Left"},
532 {"Out Mixer Right", "DAC Right Switch", "DAC Right"},
533
534 {"Mono Mixer", "Outmix Right Switch", "Out Mixer Right"},
535 {"Mono Mixer", "Outmix Left Switch", "Out Mixer Left"},
536
537 {"OUTPGA Left Enable", NULL, "Out Mixer Left"},
538 {"OUTPGA Right Enable", NULL, "Out Mixer Right"},
539
540 {"Out1 Left", NULL, "OUTPGA Left Enable"},
541 {"OUT1L", NULL, "Out1 Left"},
542
543 {"Out1 Right", NULL, "OUTPGA Right Enable"},
544 {"OUT1R", NULL, "Out1 Right"},
545
546 {"Headphone Left", NULL, "OUTPGA Left Enable"},
547 {"HPL", NULL, "Headphone Left"},
548
549 {"Headphone Right", NULL, "OUTPGA Right Enable"},
550 {"HPR", NULL, "Headphone Right"},
551
552 {"Out2 Mono", NULL, "Mono Mixer"},
553 {"OUT2", NULL, "Out2 Mono"},
159}; 554};
160 555
161/* Codec private data */ 556/* Codec private data */
162struct da7210_priv { 557struct da7210_priv {
163 enum snd_soc_control_type control_type; 558 enum snd_soc_control_type control_type;
164 void *control_data;
165}; 559};
166 560
167/* 561/*
@@ -188,72 +582,15 @@ static const u8 da7210_reg[] = {
188 0x00, /* R88 */ 582 0x00, /* R88 */
189}; 583};
190 584
191/* 585static int da7210_volatile_register(struct snd_soc_codec *codec,
192 * Read da7210 register cache 586 unsigned int reg)
193 */
194static inline u32 da7210_read_reg_cache(struct snd_soc_codec *codec, u32 reg)
195{
196 u8 *cache = codec->reg_cache;
197 BUG_ON(reg >= ARRAY_SIZE(da7210_reg));
198 return cache[reg];
199}
200
201/*
202 * Write to the da7210 register space
203 */
204static int da7210_write(struct snd_soc_codec *codec, u32 reg, u32 value)
205{ 587{
206 u8 *cache = codec->reg_cache; 588 switch (reg) {
207 u8 data[2]; 589 case DA7210_STATUS:
208 590 return 1;
209 BUG_ON(codec->driver->volatile_register); 591 default:
210 592 return 0;
211 data[0] = reg & 0xff;
212 data[1] = value & 0xff;
213
214 if (reg >= codec->driver->reg_cache_size)
215 return -EIO;
216
217 if (2 != codec->hw_write(codec->control_data, data, 2))
218 return -EIO;
219
220 cache[reg] = value;
221 return 0;
222}
223
224/*
225 * Read from the da7210 register space.
226 */
227static inline u32 da7210_read(struct snd_soc_codec *codec, u32 reg)
228{
229 if (DA7210_STATUS == reg)
230 return i2c_smbus_read_byte_data(codec->control_data, reg);
231
232 return da7210_read_reg_cache(codec, reg);
233}
234
235static int da7210_startup(struct snd_pcm_substream *substream,
236 struct snd_soc_dai *dai)
237{
238 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
239 struct snd_soc_codec *codec = dai->codec;
240
241 if (is_play) {
242 /* Enable Out */
243 snd_soc_update_bits(codec, DA7210_OUTMIX_L, 0x1F, 0x10);
244 snd_soc_update_bits(codec, DA7210_OUTMIX_R, 0x1F, 0x10);
245
246 } else {
247 /* Volume 7 */
248 snd_soc_update_bits(codec, DA7210_MIC_L, 0x7, 0x7);
249 snd_soc_update_bits(codec, DA7210_MIC_R, 0x7, 0x7);
250
251 /* Enable Mic */
252 snd_soc_update_bits(codec, DA7210_INMIX_L, 0x1F, 0x1);
253 snd_soc_update_bits(codec, DA7210_INMIX_R, 0x1F, 0x1);
254 } 593 }
255
256 return 0;
257} 594}
258 595
259/* 596/*
@@ -266,93 +603,75 @@ static int da7210_hw_params(struct snd_pcm_substream *substream,
266 struct snd_soc_pcm_runtime *rtd = substream->private_data; 603 struct snd_soc_pcm_runtime *rtd = substream->private_data;
267 struct snd_soc_codec *codec = rtd->codec; 604 struct snd_soc_codec *codec = rtd->codec;
268 u32 dai_cfg1; 605 u32 dai_cfg1;
269 u32 hpf_reg, hpf_mask, hpf_value;
270 u32 fs, bypass; 606 u32 fs, bypass;
271 607
272 /* set DAI source to Left and Right ADC */ 608 /* set DAI source to Left and Right ADC */
273 da7210_write(codec, DA7210_DAI_SRC_SEL, 609 snd_soc_write(codec, DA7210_DAI_SRC_SEL,
274 DA7210_DAI_OUT_R_SRC | DA7210_DAI_OUT_L_SRC); 610 DA7210_DAI_OUT_R_SRC | DA7210_DAI_OUT_L_SRC);
275 611
276 /* Enable DAI */ 612 /* Enable DAI */
277 da7210_write(codec, DA7210_DAI_CFG3, DA7210_DAI_OE | DA7210_DAI_EN); 613 snd_soc_write(codec, DA7210_DAI_CFG3, DA7210_DAI_OE | DA7210_DAI_EN);
278 614
279 dai_cfg1 = 0xFC & da7210_read(codec, DA7210_DAI_CFG1); 615 dai_cfg1 = 0xFC & snd_soc_read(codec, DA7210_DAI_CFG1);
280 616
281 switch (params_format(params)) { 617 switch (params_format(params)) {
282 case SNDRV_PCM_FORMAT_S16_LE: 618 case SNDRV_PCM_FORMAT_S16_LE:
283 dai_cfg1 |= DA7210_DAI_WORD_S16_LE; 619 dai_cfg1 |= DA7210_DAI_WORD_S16_LE;
284 break; 620 break;
621 case SNDRV_PCM_FORMAT_S20_3LE:
622 dai_cfg1 |= DA7210_DAI_WORD_S20_3LE;
623 break;
285 case SNDRV_PCM_FORMAT_S24_LE: 624 case SNDRV_PCM_FORMAT_S24_LE:
286 dai_cfg1 |= DA7210_DAI_WORD_S24_LE; 625 dai_cfg1 |= DA7210_DAI_WORD_S24_LE;
287 break; 626 break;
627 case SNDRV_PCM_FORMAT_S32_LE:
628 dai_cfg1 |= DA7210_DAI_WORD_S32_LE;
629 break;
288 default: 630 default:
289 return -EINVAL; 631 return -EINVAL;
290 } 632 }
291 633
292 da7210_write(codec, DA7210_DAI_CFG1, dai_cfg1); 634 snd_soc_write(codec, DA7210_DAI_CFG1, dai_cfg1);
293
294 hpf_reg = (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) ?
295 DA7210_DAC_HPF : DA7210_ADC_HPF;
296 635
297 switch (params_rate(params)) { 636 switch (params_rate(params)) {
298 case 8000: 637 case 8000:
299 fs = DA7210_PLL_FS_8000; 638 fs = DA7210_PLL_FS_8000;
300 hpf_mask = DA7210_VOICE_F0_MASK | DA7210_VOICE_EN;
301 hpf_value = DA7210_VOICE_F0_25 | DA7210_VOICE_EN;
302 bypass = DA7210_PLL_BYP; 639 bypass = DA7210_PLL_BYP;
303 break; 640 break;
304 case 11025: 641 case 11025:
305 fs = DA7210_PLL_FS_11025; 642 fs = DA7210_PLL_FS_11025;
306 hpf_mask = DA7210_VOICE_F0_MASK | DA7210_VOICE_EN;
307 hpf_value = DA7210_VOICE_F0_25 | DA7210_VOICE_EN;
308 bypass = 0; 643 bypass = 0;
309 break; 644 break;
310 case 12000: 645 case 12000:
311 fs = DA7210_PLL_FS_12000; 646 fs = DA7210_PLL_FS_12000;
312 hpf_mask = DA7210_VOICE_F0_MASK | DA7210_VOICE_EN;
313 hpf_value = DA7210_VOICE_F0_25 | DA7210_VOICE_EN;
314 bypass = DA7210_PLL_BYP; 647 bypass = DA7210_PLL_BYP;
315 break; 648 break;
316 case 16000: 649 case 16000:
317 fs = DA7210_PLL_FS_16000; 650 fs = DA7210_PLL_FS_16000;
318 hpf_mask = DA7210_VOICE_F0_MASK | DA7210_VOICE_EN;
319 hpf_value = DA7210_VOICE_F0_25 | DA7210_VOICE_EN;
320 bypass = DA7210_PLL_BYP; 651 bypass = DA7210_PLL_BYP;
321 break; 652 break;
322 case 22050: 653 case 22050:
323 fs = DA7210_PLL_FS_22050; 654 fs = DA7210_PLL_FS_22050;
324 hpf_mask = DA7210_VOICE_EN;
325 hpf_value = 0;
326 bypass = 0; 655 bypass = 0;
327 break; 656 break;
328 case 32000: 657 case 32000:
329 fs = DA7210_PLL_FS_32000; 658 fs = DA7210_PLL_FS_32000;
330 hpf_mask = DA7210_VOICE_EN;
331 hpf_value = 0;
332 bypass = DA7210_PLL_BYP; 659 bypass = DA7210_PLL_BYP;
333 break; 660 break;
334 case 44100: 661 case 44100:
335 fs = DA7210_PLL_FS_44100; 662 fs = DA7210_PLL_FS_44100;
336 hpf_mask = DA7210_VOICE_EN;
337 hpf_value = 0;
338 bypass = 0; 663 bypass = 0;
339 break; 664 break;
340 case 48000: 665 case 48000:
341 fs = DA7210_PLL_FS_48000; 666 fs = DA7210_PLL_FS_48000;
342 hpf_mask = DA7210_VOICE_EN;
343 hpf_value = 0;
344 bypass = DA7210_PLL_BYP; 667 bypass = DA7210_PLL_BYP;
345 break; 668 break;
346 case 88200: 669 case 88200:
347 fs = DA7210_PLL_FS_88200; 670 fs = DA7210_PLL_FS_88200;
348 hpf_mask = DA7210_VOICE_EN;
349 hpf_value = 0;
350 bypass = 0; 671 bypass = 0;
351 break; 672 break;
352 case 96000: 673 case 96000:
353 fs = DA7210_PLL_FS_96000; 674 fs = DA7210_PLL_FS_96000;
354 hpf_mask = DA7210_VOICE_EN;
355 hpf_value = 0;
356 bypass = DA7210_PLL_BYP; 675 bypass = DA7210_PLL_BYP;
357 break; 676 break;
358 default: 677 default:
@@ -362,7 +681,6 @@ static int da7210_hw_params(struct snd_pcm_substream *substream,
362 /* Disable active mode */ 681 /* Disable active mode */
363 snd_soc_update_bits(codec, DA7210_STARTUP1, DA7210_SC_MST_EN, 0); 682 snd_soc_update_bits(codec, DA7210_STARTUP1, DA7210_SC_MST_EN, 0);
364 683
365 snd_soc_update_bits(codec, hpf_reg, hpf_mask, hpf_value);
366 snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_FS_MASK, fs); 684 snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_FS_MASK, fs);
367 snd_soc_update_bits(codec, DA7210_PLL_DIV3, DA7210_PLL_BYP, bypass); 685 snd_soc_update_bits(codec, DA7210_PLL_DIV3, DA7210_PLL_BYP, bypass);
368 686
@@ -382,13 +700,16 @@ static int da7210_set_dai_fmt(struct snd_soc_dai *codec_dai, u32 fmt)
382 u32 dai_cfg1; 700 u32 dai_cfg1;
383 u32 dai_cfg3; 701 u32 dai_cfg3;
384 702
385 dai_cfg1 = 0x7f & da7210_read(codec, DA7210_DAI_CFG1); 703 dai_cfg1 = 0x7f & snd_soc_read(codec, DA7210_DAI_CFG1);
386 dai_cfg3 = 0xfc & da7210_read(codec, DA7210_DAI_CFG3); 704 dai_cfg3 = 0xfc & snd_soc_read(codec, DA7210_DAI_CFG3);
387 705
388 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 706 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
389 case SND_SOC_DAIFMT_CBM_CFM: 707 case SND_SOC_DAIFMT_CBM_CFM:
390 dai_cfg1 |= DA7210_DAI_MODE_MASTER; 708 dai_cfg1 |= DA7210_DAI_MODE_MASTER;
391 break; 709 break;
710 case SND_SOC_DAIFMT_CBS_CFS:
711 dai_cfg1 |= DA7210_DAI_MODE_SLAVE;
712 break;
392 default: 713 default:
393 return -EINVAL; 714 return -EINVAL;
394 } 715 }
@@ -401,6 +722,12 @@ static int da7210_set_dai_fmt(struct snd_soc_dai *codec_dai, u32 fmt)
401 case SND_SOC_DAIFMT_I2S: 722 case SND_SOC_DAIFMT_I2S:
402 dai_cfg3 |= DA7210_DAI_FORMAT_I2SMODE; 723 dai_cfg3 |= DA7210_DAI_FORMAT_I2SMODE;
403 break; 724 break;
725 case SND_SOC_DAIFMT_LEFT_J:
726 dai_cfg3 |= DA7210_DAI_FORMAT_LEFT_J;
727 break;
728 case SND_SOC_DAIFMT_RIGHT_J:
729 dai_cfg3 |= DA7210_DAI_FORMAT_RIGHT_J;
730 break;
404 default: 731 default:
405 return -EINVAL; 732 return -EINVAL;
406 } 733 }
@@ -411,19 +738,32 @@ static int da7210_set_dai_fmt(struct snd_soc_dai *codec_dai, u32 fmt)
411 */ 738 */
412 dai_cfg1 |= DA7210_DAI_FLEN_64BIT; 739 dai_cfg1 |= DA7210_DAI_FLEN_64BIT;
413 740
414 da7210_write(codec, DA7210_DAI_CFG1, dai_cfg1); 741 snd_soc_write(codec, DA7210_DAI_CFG1, dai_cfg1);
415 da7210_write(codec, DA7210_DAI_CFG3, dai_cfg3); 742 snd_soc_write(codec, DA7210_DAI_CFG3, dai_cfg3);
743
744 return 0;
745}
746
747static int da7210_mute(struct snd_soc_dai *dai, int mute)
748{
749 struct snd_soc_codec *codec = dai->codec;
750 u8 mute_reg = snd_soc_read(codec, DA7210_DAC_HPF) & 0xFB;
416 751
752 if (mute)
753 snd_soc_write(codec, DA7210_DAC_HPF, mute_reg | 0x4);
754 else
755 snd_soc_write(codec, DA7210_DAC_HPF, mute_reg);
417 return 0; 756 return 0;
418} 757}
419 758
420#define DA7210_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) 759#define DA7210_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
760 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
421 761
422/* DAI operations */ 762/* DAI operations */
423static struct snd_soc_dai_ops da7210_dai_ops = { 763static struct snd_soc_dai_ops da7210_dai_ops = {
424 .startup = da7210_startup,
425 .hw_params = da7210_hw_params, 764 .hw_params = da7210_hw_params,
426 .set_fmt = da7210_set_dai_fmt, 765 .set_fmt = da7210_set_dai_fmt,
766 .digital_mute = da7210_mute,
427}; 767};
428 768
429static struct snd_soc_dai_driver da7210_dai = { 769static struct snd_soc_dai_driver da7210_dai = {
@@ -451,11 +791,15 @@ static struct snd_soc_dai_driver da7210_dai = {
451static int da7210_probe(struct snd_soc_codec *codec) 791static int da7210_probe(struct snd_soc_codec *codec)
452{ 792{
453 struct da7210_priv *da7210 = snd_soc_codec_get_drvdata(codec); 793 struct da7210_priv *da7210 = snd_soc_codec_get_drvdata(codec);
794 int ret;
454 795
455 dev_info(codec->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION); 796 dev_info(codec->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
456 797
457 codec->control_data = da7210->control_data; 798 ret = snd_soc_codec_set_cache_io(codec, 8, 8, da7210->control_type);
458 codec->hw_write = (hw_write_t)i2c_master_send; 799 if (ret < 0) {
800 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
801 return ret;
802 }
459 803
460 /* FIXME 804 /* FIXME
461 * 805 *
@@ -472,8 +816,8 @@ static int da7210_probe(struct snd_soc_codec *codec)
472 /* 816 /*
473 * make sure that DA7210 use bypass mode before start up 817 * make sure that DA7210 use bypass mode before start up
474 */ 818 */
475 da7210_write(codec, DA7210_STARTUP1, 0); 819 snd_soc_write(codec, DA7210_STARTUP1, 0);
476 da7210_write(codec, DA7210_PLL_DIV3, 820 snd_soc_write(codec, DA7210_PLL_DIV3,
477 DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP); 821 DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP);
478 822
479 /* 823 /*
@@ -481,36 +825,70 @@ static int da7210_probe(struct snd_soc_codec *codec)
481 */ 825 */
482 826
483 /* Enable Left & Right MIC PGA and Mic Bias */ 827 /* Enable Left & Right MIC PGA and Mic Bias */
484 da7210_write(codec, DA7210_MIC_L, DA7210_MIC_L_EN | DA7210_MICBIAS_EN); 828 snd_soc_write(codec, DA7210_MIC_L, DA7210_MIC_L_EN | DA7210_MICBIAS_EN);
485 da7210_write(codec, DA7210_MIC_R, DA7210_MIC_R_EN); 829 snd_soc_write(codec, DA7210_MIC_R, DA7210_MIC_R_EN);
486 830
487 /* Enable Left and Right input PGA */ 831 /* Enable Left and Right input PGA */
488 da7210_write(codec, DA7210_INMIX_L, DA7210_IN_L_EN); 832 snd_soc_write(codec, DA7210_INMIX_L, DA7210_IN_L_EN);
489 da7210_write(codec, DA7210_INMIX_R, DA7210_IN_R_EN); 833 snd_soc_write(codec, DA7210_INMIX_R, DA7210_IN_R_EN);
490 834
491 /* Enable Left and Right ADC */ 835 /* Enable Left and Right ADC */
492 da7210_write(codec, DA7210_ADC, DA7210_ADC_L_EN | DA7210_ADC_R_EN); 836 snd_soc_write(codec, DA7210_ADC, DA7210_ADC_L_EN | DA7210_ADC_R_EN);
493 837
494 /* 838 /*
495 * DAC settings 839 * DAC settings
496 */ 840 */
497 841
498 /* Enable Left and Right DAC */ 842 /* Enable Left and Right DAC */
499 da7210_write(codec, DA7210_DAC_SEL, 843 snd_soc_write(codec, DA7210_DAC_SEL,
500 DA7210_DAC_L_SRC_DAI_L | DA7210_DAC_L_EN | 844 DA7210_DAC_L_SRC_DAI_L | DA7210_DAC_L_EN |
501 DA7210_DAC_R_SRC_DAI_R | DA7210_DAC_R_EN); 845 DA7210_DAC_R_SRC_DAI_R | DA7210_DAC_R_EN);
502 846
503 /* Enable Left and Right out PGA */ 847 /* Enable Left and Right out PGA */
504 da7210_write(codec, DA7210_OUTMIX_L, DA7210_OUT_L_EN); 848 snd_soc_write(codec, DA7210_OUTMIX_L, DA7210_OUT_L_EN);
505 da7210_write(codec, DA7210_OUTMIX_R, DA7210_OUT_R_EN); 849 snd_soc_write(codec, DA7210_OUTMIX_R, DA7210_OUT_R_EN);
506 850
507 /* Enable Left and Right HeadPhone PGA */ 851 /* Enable Left and Right HeadPhone PGA */
508 da7210_write(codec, DA7210_HP_CFG, 852 snd_soc_write(codec, DA7210_HP_CFG,
509 DA7210_HP_2CAP_MODE | DA7210_HP_SENSE_EN | 853 DA7210_HP_2CAP_MODE | DA7210_HP_SENSE_EN |
510 DA7210_HP_L_EN | DA7210_HP_MODE | DA7210_HP_R_EN); 854 DA7210_HP_L_EN | DA7210_HP_MODE | DA7210_HP_R_EN);
511 855
856 /* Enable ramp mode for DAC gain update */
857 snd_soc_write(codec, DA7210_SOFTMUTE, DA7210_RAMP_EN);
858
859 /*
860 * For DA7210 codec, there are two ways to enable/disable analog IOs
861 * and ADC/DAC,
862 * (1) Using "Enable Bit" of register associated with that IO
863 * (or ADC/DAC)
864 * e.g. Mic Left can be enabled using bit 7 of MIC_L(0x7) reg
865 *
866 * (2) Using "Standby Bit" of STARTUP2 or STARTUP3 register
867 * e.g. Mic left can be put to STANDBY using bit 0 of STARTUP3(0x5)
868 *
869 * Out of these two methods, the one using STANDBY bits is preferred
870 * way to enable/disable individual blocks. This is because STANDBY
871 * registers are part of system controller which allows system power
872 * up/down in a controlled, pop-free manner. Also, as per application
873 * note of DA7210, STANDBY register bits are only effective if a
874 * particular IO (or ADC/DAC) is already enabled using enable/disable
875 * register bits. Keeping these things in mind, current DAPM
876 * implementation manipulates only STANDBY bits.
877 *
878 * Overall implementation can be outlined as below,
879 *
880 * - "Enable bit" of an IO or ADC/DAC is used to enable it in probe()
881 * - "STANDBY bit" is controlled by DAPM
882 */
883
884 /* Enable Line out amplifiers */
885 snd_soc_write(codec, DA7210_OUT1_L, DA7210_OUT1_L_EN);
886 snd_soc_write(codec, DA7210_OUT1_R, DA7210_OUT1_R_EN);
887 snd_soc_write(codec, DA7210_OUT2, DA7210_OUT2_EN |
888 DA7210_OUT2_OUTMIX_L | DA7210_OUT2_OUTMIX_R);
889
512 /* Diable PLL and bypass it */ 890 /* Diable PLL and bypass it */
513 da7210_write(codec, DA7210_PLL, DA7210_PLL_FS_48000); 891 snd_soc_write(codec, DA7210_PLL, DA7210_PLL_FS_48000);
514 892
515 /* 893 /*
516 * If 48kHz sound came, it use bypass mode, 894 * If 48kHz sound came, it use bypass mode,
@@ -521,25 +899,22 @@ static int da7210_probe(struct snd_soc_codec *codec)
521 * DA7210_PLL_DIV3 :: DA7210_PLL_BYP bit. 899 * DA7210_PLL_DIV3 :: DA7210_PLL_BYP bit.
522 * see da7210_hw_params 900 * see da7210_hw_params
523 */ 901 */
524 da7210_write(codec, DA7210_PLL_DIV1, 0xE5); /* MCLK = 12.288MHz */ 902 snd_soc_write(codec, DA7210_PLL_DIV1, 0xE5); /* MCLK = 12.288MHz */
525 da7210_write(codec, DA7210_PLL_DIV2, 0x99); 903 snd_soc_write(codec, DA7210_PLL_DIV2, 0x99);
526 da7210_write(codec, DA7210_PLL_DIV3, 0x0A | 904 snd_soc_write(codec, DA7210_PLL_DIV3, 0x0A |
527 DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP); 905 DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP);
528 snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_EN, DA7210_PLL_EN); 906 snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_EN, DA7210_PLL_EN);
529 907
530 /* As suggested by Dialog */ 908 /* As suggested by Dialog */
531 da7210_write(codec, DA7210_A_HID_UNLOCK, 0x8B); /* unlock */ 909 snd_soc_write(codec, DA7210_A_HID_UNLOCK, 0x8B); /* unlock */
532 da7210_write(codec, DA7210_A_TEST_UNLOCK, 0xB4); 910 snd_soc_write(codec, DA7210_A_TEST_UNLOCK, 0xB4);
533 da7210_write(codec, DA7210_A_PLL1, 0x01); 911 snd_soc_write(codec, DA7210_A_PLL1, 0x01);
534 da7210_write(codec, DA7210_A_CP_MODE, 0x7C); 912 snd_soc_write(codec, DA7210_A_CP_MODE, 0x7C);
535 da7210_write(codec, DA7210_A_HID_UNLOCK, 0x00); /* re-lock */ 913 snd_soc_write(codec, DA7210_A_HID_UNLOCK, 0x00); /* re-lock */
536 da7210_write(codec, DA7210_A_TEST_UNLOCK, 0x00); 914 snd_soc_write(codec, DA7210_A_TEST_UNLOCK, 0x00);
537 915
538 /* Activate all enabled subsystem */ 916 /* Activate all enabled subsystem */
539 da7210_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN); 917 snd_soc_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN);
540
541 snd_soc_add_controls(codec, da7210_snd_controls,
542 ARRAY_SIZE(da7210_snd_controls));
543 918
544 dev_info(codec->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION); 919 dev_info(codec->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
545 920
@@ -548,11 +923,18 @@ static int da7210_probe(struct snd_soc_codec *codec)
548 923
549static struct snd_soc_codec_driver soc_codec_dev_da7210 = { 924static struct snd_soc_codec_driver soc_codec_dev_da7210 = {
550 .probe = da7210_probe, 925 .probe = da7210_probe,
551 .read = da7210_read,
552 .write = da7210_write,
553 .reg_cache_size = ARRAY_SIZE(da7210_reg), 926 .reg_cache_size = ARRAY_SIZE(da7210_reg),
554 .reg_word_size = sizeof(u8), 927 .reg_word_size = sizeof(u8),
555 .reg_cache_default = da7210_reg, 928 .reg_cache_default = da7210_reg,
929 .volatile_register = da7210_volatile_register,
930
931 .controls = da7210_snd_controls,
932 .num_controls = ARRAY_SIZE(da7210_snd_controls),
933
934 .dapm_widgets = da7210_dapm_widgets,
935 .num_dapm_widgets = ARRAY_SIZE(da7210_dapm_widgets),
936 .dapm_routes = da7210_audio_map,
937 .num_dapm_routes = ARRAY_SIZE(da7210_audio_map),
556}; 938};
557 939
558#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 940#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
@@ -567,7 +949,6 @@ static int __devinit da7210_i2c_probe(struct i2c_client *i2c,
567 return -ENOMEM; 949 return -ENOMEM;
568 950
569 i2c_set_clientdata(i2c, da7210); 951 i2c_set_clientdata(i2c, da7210);
570 da7210->control_data = i2c;
571 da7210->control_type = SND_SOC_I2C; 952 da7210->control_type = SND_SOC_I2C;
572 953
573 ret = snd_soc_register_codec(&i2c->dev, 954 ret = snd_soc_register_codec(&i2c->dev,
diff --git a/sound/soc/codecs/lm4857.c b/sound/soc/codecs/lm4857.c
index 2c2a681da0d..c387dafc6ab 100644
--- a/sound/soc/codecs/lm4857.c
+++ b/sound/soc/codecs/lm4857.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright 2007 Wolfson Microelectronics PLC. 4 * Copyright 2007 Wolfson Microelectronics PLC.
5 * Author: Graeme Gregory 5 * Author: Graeme Gregory
6 * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com 6 * graeme.gregory@wolfsonmicro.com
7 * Copyright 2011 Lars-Peter Clausen <lars@metafoo.de> 7 * Copyright 2011 Lars-Peter Clausen <lars@metafoo.de>
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify it 9 * This program is free software; you can redistribute it and/or modify it
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c
index ac65a2d3640..ebbf63c79c3 100644
--- a/sound/soc/codecs/max98088.c
+++ b/sound/soc/codecs/max98088.c
@@ -40,7 +40,6 @@ struct max98088_cdata {
40 40
41struct max98088_priv { 41struct max98088_priv {
42 enum max98088_type devtype; 42 enum max98088_type devtype;
43 void *control_data;
44 struct max98088_pdata *pdata; 43 struct max98088_pdata *pdata;
45 unsigned int sysclk; 44 unsigned int sysclk;
46 struct max98088_cdata dai[2]; 45 struct max98088_cdata dai[2];
@@ -1697,13 +1696,19 @@ static struct snd_soc_dai_driver max98088_dai[] = {
1697} 1696}
1698}; 1697};
1699 1698
1700static int max98088_get_channel(const char *name) 1699static const char *eq_mode_name[] = {"EQ1 Mode", "EQ2 Mode"};
1700
1701static int max98088_get_channel(struct snd_soc_codec *codec, const char *name)
1701{ 1702{
1702 if (strcmp(name, "EQ1 Mode") == 0) 1703 int i;
1703 return 0; 1704
1704 if (strcmp(name, "EQ2 Mode") == 0) 1705 for (i = 0; i < ARRAY_SIZE(eq_mode_name); i++)
1705 return 1; 1706 if (strcmp(name, eq_mode_name[i]) == 0)
1706 return -EINVAL; 1707 return i;
1708
1709 /* Shouldn't happen */
1710 dev_err(codec->dev, "Bad EQ channel name '%s'\n", name);
1711 return -EINVAL;
1707} 1712}
1708 1713
1709static void max98088_setup_eq1(struct snd_soc_codec *codec) 1714static void max98088_setup_eq1(struct snd_soc_codec *codec)
@@ -1807,10 +1812,13 @@ static int max98088_put_eq_enum(struct snd_kcontrol *kcontrol,
1807 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1812 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1808 struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); 1813 struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
1809 struct max98088_pdata *pdata = max98088->pdata; 1814 struct max98088_pdata *pdata = max98088->pdata;
1810 int channel = max98088_get_channel(kcontrol->id.name); 1815 int channel = max98088_get_channel(codec, kcontrol->id.name);
1811 struct max98088_cdata *cdata; 1816 struct max98088_cdata *cdata;
1812 int sel = ucontrol->value.integer.value[0]; 1817 int sel = ucontrol->value.integer.value[0];
1813 1818
1819 if (channel < 0)
1820 return channel;
1821
1814 cdata = &max98088->dai[channel]; 1822 cdata = &max98088->dai[channel];
1815 1823
1816 if (sel >= pdata->eq_cfgcnt) 1824 if (sel >= pdata->eq_cfgcnt)
@@ -1835,9 +1843,12 @@ static int max98088_get_eq_enum(struct snd_kcontrol *kcontrol,
1835{ 1843{
1836 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1844 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1837 struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); 1845 struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
1838 int channel = max98088_get_channel(kcontrol->id.name); 1846 int channel = max98088_get_channel(codec, kcontrol->id.name);
1839 struct max98088_cdata *cdata; 1847 struct max98088_cdata *cdata;
1840 1848
1849 if (channel < 0)
1850 return channel;
1851
1841 cdata = &max98088->dai[channel]; 1852 cdata = &max98088->dai[channel];
1842 ucontrol->value.enumerated.item[0] = cdata->eq_sel; 1853 ucontrol->value.enumerated.item[0] = cdata->eq_sel;
1843 return 0; 1854 return 0;
@@ -1852,17 +1863,17 @@ static void max98088_handle_eq_pdata(struct snd_soc_codec *codec)
1852 int i, j; 1863 int i, j;
1853 const char **t; 1864 const char **t;
1854 int ret; 1865 int ret;
1855
1856 struct snd_kcontrol_new controls[] = { 1866 struct snd_kcontrol_new controls[] = {
1857 SOC_ENUM_EXT("EQ1 Mode", 1867 SOC_ENUM_EXT((char *)eq_mode_name[0],
1858 max98088->eq_enum, 1868 max98088->eq_enum,
1859 max98088_get_eq_enum, 1869 max98088_get_eq_enum,
1860 max98088_put_eq_enum), 1870 max98088_put_eq_enum),
1861 SOC_ENUM_EXT("EQ2 Mode", 1871 SOC_ENUM_EXT((char *)eq_mode_name[1],
1862 max98088->eq_enum, 1872 max98088->eq_enum,
1863 max98088_get_eq_enum, 1873 max98088_get_eq_enum,
1864 max98088_put_eq_enum), 1874 max98088_put_eq_enum),
1865 }; 1875 };
1876 BUILD_BUG_ON(ARRAY_SIZE(controls) != ARRAY_SIZE(eq_mode_name));
1866 1877
1867 cfg = pdata->eq_cfg; 1878 cfg = pdata->eq_cfg;
1868 cfgcnt = pdata->eq_cfgcnt; 1879 cfgcnt = pdata->eq_cfgcnt;
@@ -2066,7 +2077,6 @@ static int max98088_i2c_probe(struct i2c_client *i2c,
2066 max98088->devtype = id->driver_data; 2077 max98088->devtype = id->driver_data;
2067 2078
2068 i2c_set_clientdata(i2c, max98088); 2079 i2c_set_clientdata(i2c, max98088);
2069 max98088->control_data = i2c;
2070 max98088->pdata = i2c->dev.platform_data; 2080 max98088->pdata = i2c->dev.platform_data;
2071 2081
2072 ret = snd_soc_register_codec(&i2c->dev, 2082 ret = snd_soc_register_codec(&i2c->dev,
diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c
index 668434d4430..26d7b089fb9 100644
--- a/sound/soc/codecs/max98095.c
+++ b/sound/soc/codecs/max98095.c
@@ -40,7 +40,6 @@ struct max98095_cdata {
40 40
41struct max98095_priv { 41struct max98095_priv {
42 enum max98095_type devtype; 42 enum max98095_type devtype;
43 void *control_data;
44 struct max98095_pdata *pdata; 43 struct max98095_pdata *pdata;
45 unsigned int sysclk; 44 unsigned int sysclk;
46 struct max98095_cdata dai[3]; 45 struct max98095_cdata dai[3];
@@ -618,14 +617,13 @@ static int max98095_volatile(struct snd_soc_codec *codec, unsigned int reg)
618static int max98095_hw_write(struct snd_soc_codec *codec, unsigned int reg, 617static int max98095_hw_write(struct snd_soc_codec *codec, unsigned int reg,
619 unsigned int value) 618 unsigned int value)
620{ 619{
621 u8 data[2]; 620 int ret;
622 621
623 data[0] = reg; 622 codec->cache_bypass = 1;
624 data[1] = value; 623 ret = snd_soc_write(codec, reg, value);
625 if (codec->hw_write(codec->control_data, data, 2) == 2) 624 codec->cache_bypass = 0;
626 return 0; 625
627 else 626 return ret ? -EIO : 0;
628 return -EIO;
629} 627}
630 628
631/* 629/*
@@ -1992,12 +1990,19 @@ static void max98095_handle_eq_pdata(struct snd_soc_codec *codec)
1992 dev_err(codec->dev, "Failed to add EQ control: %d\n", ret); 1990 dev_err(codec->dev, "Failed to add EQ control: %d\n", ret);
1993} 1991}
1994 1992
1995static int max98095_get_bq_channel(const char *name) 1993static const char *bq_mode_name[] = {"Biquad1 Mode", "Biquad2 Mode"};
1994
1995static int max98095_get_bq_channel(struct snd_soc_codec *codec,
1996 const char *name)
1996{ 1997{
1997 if (strcmp(name, "Biquad1 Mode") == 0) 1998 int i;
1998 return 0; 1999
1999 if (strcmp(name, "Biquad2 Mode") == 0) 2000 for (i = 0; i < ARRAY_SIZE(bq_mode_name); i++)
2000 return 1; 2001 if (strcmp(name, bq_mode_name[i]) == 0)
2002 return i;
2003
2004 /* Shouldn't happen */
2005 dev_err(codec->dev, "Bad biquad channel name '%s'\n", name);
2001 return -EINVAL; 2006 return -EINVAL;
2002} 2007}
2003 2008
@@ -2007,14 +2012,15 @@ static int max98095_put_bq_enum(struct snd_kcontrol *kcontrol,
2007 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 2012 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2008 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); 2013 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
2009 struct max98095_pdata *pdata = max98095->pdata; 2014 struct max98095_pdata *pdata = max98095->pdata;
2010 int channel = max98095_get_bq_channel(kcontrol->id.name); 2015 int channel = max98095_get_bq_channel(codec, kcontrol->id.name);
2011 struct max98095_cdata *cdata; 2016 struct max98095_cdata *cdata;
2012 int sel = ucontrol->value.integer.value[0]; 2017 int sel = ucontrol->value.integer.value[0];
2013 struct max98095_biquad_cfg *coef_set; 2018 struct max98095_biquad_cfg *coef_set;
2014 int fs, best, best_val, i; 2019 int fs, best, best_val, i;
2015 int regmask, regsave; 2020 int regmask, regsave;
2016 2021
2017 BUG_ON(channel > 1); 2022 if (channel < 0)
2023 return channel;
2018 2024
2019 if (!pdata || !max98095->bq_textcnt) 2025 if (!pdata || !max98095->bq_textcnt)
2020 return 0; 2026 return 0;
@@ -2066,9 +2072,12 @@ static int max98095_get_bq_enum(struct snd_kcontrol *kcontrol,
2066{ 2072{
2067 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 2073 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2068 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); 2074 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
2069 int channel = max98095_get_bq_channel(kcontrol->id.name); 2075 int channel = max98095_get_bq_channel(codec, kcontrol->id.name);
2070 struct max98095_cdata *cdata; 2076 struct max98095_cdata *cdata;
2071 2077
2078 if (channel < 0)
2079 return channel;
2080
2072 cdata = &max98095->dai[channel]; 2081 cdata = &max98095->dai[channel];
2073 ucontrol->value.enumerated.item[0] = cdata->bq_sel; 2082 ucontrol->value.enumerated.item[0] = cdata->bq_sel;
2074 2083
@@ -2086,15 +2095,16 @@ static void max98095_handle_bq_pdata(struct snd_soc_codec *codec)
2086 int ret; 2095 int ret;
2087 2096
2088 struct snd_kcontrol_new controls[] = { 2097 struct snd_kcontrol_new controls[] = {
2089 SOC_ENUM_EXT("Biquad1 Mode", 2098 SOC_ENUM_EXT((char *)bq_mode_name[0],
2090 max98095->bq_enum, 2099 max98095->bq_enum,
2091 max98095_get_bq_enum, 2100 max98095_get_bq_enum,
2092 max98095_put_bq_enum), 2101 max98095_put_bq_enum),
2093 SOC_ENUM_EXT("Biquad2 Mode", 2102 SOC_ENUM_EXT((char *)bq_mode_name[1],
2094 max98095->bq_enum, 2103 max98095->bq_enum,
2095 max98095_get_bq_enum, 2104 max98095_get_bq_enum,
2096 max98095_put_bq_enum), 2105 max98095_put_bq_enum),
2097 }; 2106 };
2107 BUILD_BUG_ON(ARRAY_SIZE(controls) != ARRAY_SIZE(bq_mode_name));
2098 2108
2099 cfg = pdata->bq_cfg; 2109 cfg = pdata->bq_cfg;
2100 cfgcnt = pdata->bq_cfgcnt; 2110 cfgcnt = pdata->bq_cfgcnt;
@@ -2337,7 +2347,6 @@ static int max98095_i2c_probe(struct i2c_client *i2c,
2337 2347
2338 max98095->devtype = id->driver_data; 2348 max98095->devtype = id->driver_data;
2339 i2c_set_clientdata(i2c, max98095); 2349 i2c_set_clientdata(i2c, max98095);
2340 max98095->control_data = i2c;
2341 max98095->pdata = i2c->dev.platform_data; 2350 max98095->pdata = i2c->dev.platform_data;
2342 2351
2343 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_max98095, 2352 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_max98095,
diff --git a/sound/soc/codecs/rt5631.c b/sound/soc/codecs/rt5631.c
new file mode 100644
index 00000000000..27a078cbb6e
--- /dev/null
+++ b/sound/soc/codecs/rt5631.c
@@ -0,0 +1,1773 @@
1/*
2 * rt5631.c -- RT5631 ALSA Soc Audio driver
3 *
4 * Copyright 2011 Realtek Microelectronics
5 *
6 * Author: flove <flove@realtek.com>
7 *
8 * Based on WM8753.c
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 */
15#include <linux/module.h>
16#include <linux/moduleparam.h>
17#include <linux/init.h>
18#include <linux/delay.h>
19#include <linux/pm.h>
20#include <linux/i2c.h>
21#include <linux/platform_device.h>
22#include <linux/spi/spi.h>
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/initval.h>
29#include <sound/tlv.h>
30
31#include "rt5631.h"
32
33struct rt5631_priv {
34 int codec_version;
35 int master;
36 int sysclk;
37 int rx_rate;
38 int bclk_rate;
39 int dmic_used_flag;
40};
41
42static const u16 rt5631_reg[RT5631_VENDOR_ID2 + 1] = {
43 [RT5631_SPK_OUT_VOL] = 0x8888,
44 [RT5631_HP_OUT_VOL] = 0x8080,
45 [RT5631_MONO_AXO_1_2_VOL] = 0xa080,
46 [RT5631_AUX_IN_VOL] = 0x0808,
47 [RT5631_ADC_REC_MIXER] = 0xf0f0,
48 [RT5631_VDAC_DIG_VOL] = 0x0010,
49 [RT5631_OUTMIXER_L_CTRL] = 0xffc0,
50 [RT5631_OUTMIXER_R_CTRL] = 0xffc0,
51 [RT5631_AXO1MIXER_CTRL] = 0x88c0,
52 [RT5631_AXO2MIXER_CTRL] = 0x88c0,
53 [RT5631_DIG_MIC_CTRL] = 0x3000,
54 [RT5631_MONO_INPUT_VOL] = 0x8808,
55 [RT5631_SPK_MIXER_CTRL] = 0xf8f8,
56 [RT5631_SPK_MONO_OUT_CTRL] = 0xfc00,
57 [RT5631_SPK_MONO_HP_OUT_CTRL] = 0x4440,
58 [RT5631_SDP_CTRL] = 0x8000,
59 [RT5631_MONO_SDP_CTRL] = 0x8000,
60 [RT5631_STEREO_AD_DA_CLK_CTRL] = 0x2010,
61 [RT5631_GEN_PUR_CTRL_REG] = 0x0e00,
62 [RT5631_INT_ST_IRQ_CTRL_2] = 0x071a,
63 [RT5631_MISC_CTRL] = 0x2040,
64 [RT5631_DEPOP_FUN_CTRL_2] = 0x8000,
65 [RT5631_SOFT_VOL_CTRL] = 0x07e0,
66 [RT5631_ALC_CTRL_1] = 0x0206,
67 [RT5631_ALC_CTRL_3] = 0x2000,
68 [RT5631_PSEUDO_SPATL_CTRL] = 0x0553,
69};
70
71/**
72 * rt5631_write_index - write index register of 2nd layer
73 */
74static void rt5631_write_index(struct snd_soc_codec *codec,
75 unsigned int reg, unsigned int value)
76{
77 snd_soc_write(codec, RT5631_INDEX_ADD, reg);
78 snd_soc_write(codec, RT5631_INDEX_DATA, value);
79}
80
81/**
82 * rt5631_read_index - read index register of 2nd layer
83 */
84static unsigned int rt5631_read_index(struct snd_soc_codec *codec,
85 unsigned int reg)
86{
87 unsigned int value;
88
89 snd_soc_write(codec, RT5631_INDEX_ADD, reg);
90 value = snd_soc_read(codec, RT5631_INDEX_DATA);
91
92 return value;
93}
94
95static int rt5631_reset(struct snd_soc_codec *codec)
96{
97 return snd_soc_write(codec, RT5631_RESET, 0);
98}
99
100static int rt5631_volatile_register(struct snd_soc_codec *codec,
101 unsigned int reg)
102{
103 switch (reg) {
104 case RT5631_RESET:
105 case RT5631_INT_ST_IRQ_CTRL_2:
106 case RT5631_INDEX_ADD:
107 case RT5631_INDEX_DATA:
108 case RT5631_EQ_CTRL:
109 return 1;
110 default:
111 return 0;
112 }
113}
114
115static int rt5631_readable_register(struct snd_soc_codec *codec,
116 unsigned int reg)
117{
118 switch (reg) {
119 case RT5631_RESET:
120 case RT5631_SPK_OUT_VOL:
121 case RT5631_HP_OUT_VOL:
122 case RT5631_MONO_AXO_1_2_VOL:
123 case RT5631_AUX_IN_VOL:
124 case RT5631_STEREO_DAC_VOL_1:
125 case RT5631_MIC_CTRL_1:
126 case RT5631_STEREO_DAC_VOL_2:
127 case RT5631_ADC_CTRL_1:
128 case RT5631_ADC_REC_MIXER:
129 case RT5631_ADC_CTRL_2:
130 case RT5631_VDAC_DIG_VOL:
131 case RT5631_OUTMIXER_L_CTRL:
132 case RT5631_OUTMIXER_R_CTRL:
133 case RT5631_AXO1MIXER_CTRL:
134 case RT5631_AXO2MIXER_CTRL:
135 case RT5631_MIC_CTRL_2:
136 case RT5631_DIG_MIC_CTRL:
137 case RT5631_MONO_INPUT_VOL:
138 case RT5631_SPK_MIXER_CTRL:
139 case RT5631_SPK_MONO_OUT_CTRL:
140 case RT5631_SPK_MONO_HP_OUT_CTRL:
141 case RT5631_SDP_CTRL:
142 case RT5631_MONO_SDP_CTRL:
143 case RT5631_STEREO_AD_DA_CLK_CTRL:
144 case RT5631_PWR_MANAG_ADD1:
145 case RT5631_PWR_MANAG_ADD2:
146 case RT5631_PWR_MANAG_ADD3:
147 case RT5631_PWR_MANAG_ADD4:
148 case RT5631_GEN_PUR_CTRL_REG:
149 case RT5631_GLOBAL_CLK_CTRL:
150 case RT5631_PLL_CTRL:
151 case RT5631_INT_ST_IRQ_CTRL_1:
152 case RT5631_INT_ST_IRQ_CTRL_2:
153 case RT5631_GPIO_CTRL:
154 case RT5631_MISC_CTRL:
155 case RT5631_DEPOP_FUN_CTRL_1:
156 case RT5631_DEPOP_FUN_CTRL_2:
157 case RT5631_JACK_DET_CTRL:
158 case RT5631_SOFT_VOL_CTRL:
159 case RT5631_ALC_CTRL_1:
160 case RT5631_ALC_CTRL_2:
161 case RT5631_ALC_CTRL_3:
162 case RT5631_PSEUDO_SPATL_CTRL:
163 case RT5631_INDEX_ADD:
164 case RT5631_INDEX_DATA:
165 case RT5631_EQ_CTRL:
166 case RT5631_VENDOR_ID:
167 case RT5631_VENDOR_ID1:
168 case RT5631_VENDOR_ID2:
169 return 1;
170 default:
171 return 0;
172 }
173}
174
175static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0);
176static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -95625, 375, 0);
177static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0);
178/* {0, +20, +24, +30, +35, +40, +44, +50, +52}dB */
179static unsigned int mic_bst_tlv[] = {
180 TLV_DB_RANGE_HEAD(6),
181 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
182 1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0),
183 2, 2, TLV_DB_SCALE_ITEM(2400, 0, 0),
184 3, 5, TLV_DB_SCALE_ITEM(3000, 500, 0),
185 6, 6, TLV_DB_SCALE_ITEM(4400, 0, 0),
186 7, 7, TLV_DB_SCALE_ITEM(5000, 0, 0),
187 8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0),
188};
189
190static int rt5631_dmic_get(struct snd_kcontrol *kcontrol,
191 struct snd_ctl_elem_value *ucontrol)
192{
193 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
194 struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
195
196 ucontrol->value.integer.value[0] = rt5631->dmic_used_flag;
197
198 return 0;
199}
200
201static int rt5631_dmic_put(struct snd_kcontrol *kcontrol,
202 struct snd_ctl_elem_value *ucontrol)
203{
204 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
205 struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
206
207 rt5631->dmic_used_flag = ucontrol->value.integer.value[0];
208 return 0;
209}
210
211/* MIC Input Type */
212static const char *rt5631_input_mode[] = {
213 "Single ended", "Differential"};
214
215static const SOC_ENUM_SINGLE_DECL(
216 rt5631_mic1_mode_enum, RT5631_MIC_CTRL_1,
217 RT5631_MIC1_DIFF_INPUT_SHIFT, rt5631_input_mode);
218
219static const SOC_ENUM_SINGLE_DECL(
220 rt5631_mic2_mode_enum, RT5631_MIC_CTRL_1,
221 RT5631_MIC2_DIFF_INPUT_SHIFT, rt5631_input_mode);
222
223/* MONO Input Type */
224static const SOC_ENUM_SINGLE_DECL(
225 rt5631_monoin_mode_enum, RT5631_MONO_INPUT_VOL,
226 RT5631_MONO_DIFF_INPUT_SHIFT, rt5631_input_mode);
227
228/* SPK Ratio Gain Control */
229static const char *rt5631_spk_ratio[] = {"1.00x", "1.09x", "1.27x", "1.44x",
230 "1.56x", "1.68x", "1.99x", "2.34x"};
231
232static const SOC_ENUM_SINGLE_DECL(
233 rt5631_spk_ratio_enum, RT5631_GEN_PUR_CTRL_REG,
234 RT5631_SPK_AMP_RATIO_CTRL_SHIFT, rt5631_spk_ratio);
235
236static const struct snd_kcontrol_new rt5631_snd_controls[] = {
237 /* MIC */
238 SOC_ENUM("MIC1 Mode Control", rt5631_mic1_mode_enum),
239 SOC_SINGLE_TLV("MIC1 Boost", RT5631_MIC_CTRL_2,
240 RT5631_MIC1_BOOST_SHIFT, 8, 0, mic_bst_tlv),
241 SOC_ENUM("MIC2 Mode Control", rt5631_mic2_mode_enum),
242 SOC_SINGLE_TLV("MIC2 Boost", RT5631_MIC_CTRL_2,
243 RT5631_MIC2_BOOST_SHIFT, 8, 0, mic_bst_tlv),
244 /* MONO IN */
245 SOC_ENUM("MONOIN Mode Control", rt5631_monoin_mode_enum),
246 SOC_DOUBLE_TLV("MONOIN_RX Capture Volume", RT5631_MONO_INPUT_VOL,
247 RT5631_L_VOL_SHIFT, RT5631_R_VOL_SHIFT,
248 RT5631_VOL_MASK, 1, in_vol_tlv),
249 /* AXI */
250 SOC_DOUBLE_TLV("AXI Capture Volume", RT5631_AUX_IN_VOL,
251 RT5631_L_VOL_SHIFT, RT5631_R_VOL_SHIFT,
252 RT5631_VOL_MASK, 1, in_vol_tlv),
253 /* DAC */
254 SOC_DOUBLE_TLV("PCM Playback Volume", RT5631_STEREO_DAC_VOL_2,
255 RT5631_L_VOL_SHIFT, RT5631_R_VOL_SHIFT,
256 RT5631_DAC_VOL_MASK, 1, dac_vol_tlv),
257 SOC_DOUBLE("PCM Playback Switch", RT5631_STEREO_DAC_VOL_1,
258 RT5631_L_MUTE_SHIFT, RT5631_R_MUTE_SHIFT, 1, 1),
259 /* AXO */
260 SOC_SINGLE("AXO1 Playback Switch", RT5631_MONO_AXO_1_2_VOL,
261 RT5631_L_MUTE_SHIFT, 1, 1),
262 SOC_SINGLE("AXO2 Playback Switch", RT5631_MONO_AXO_1_2_VOL,
263 RT5631_R_VOL_SHIFT, 1, 1),
264 /* OUTVOL */
265 SOC_DOUBLE("OUTVOL Channel Switch", RT5631_SPK_OUT_VOL,
266 RT5631_L_EN_SHIFT, RT5631_R_EN_SHIFT, 1, 0),
267
268 /* SPK */
269 SOC_DOUBLE("Speaker Playback Switch", RT5631_SPK_OUT_VOL,
270 RT5631_L_MUTE_SHIFT, RT5631_R_MUTE_SHIFT, 1, 1),
271 SOC_DOUBLE_TLV("Speaker Playback Volume", RT5631_SPK_OUT_VOL,
272 RT5631_L_VOL_SHIFT, RT5631_R_VOL_SHIFT, 39, 1, out_vol_tlv),
273 /* MONO OUT */
274 SOC_SINGLE("MONO Playback Switch", RT5631_MONO_AXO_1_2_VOL,
275 RT5631_MUTE_MONO_SHIFT, 1, 1),
276 /* HP */
277 SOC_DOUBLE("HP Playback Switch", RT5631_HP_OUT_VOL,
278 RT5631_L_MUTE_SHIFT, RT5631_R_MUTE_SHIFT, 1, 1),
279 SOC_DOUBLE_TLV("HP Playback Volume", RT5631_HP_OUT_VOL,
280 RT5631_L_VOL_SHIFT, RT5631_R_VOL_SHIFT,
281 RT5631_VOL_MASK, 1, out_vol_tlv),
282 /* DMIC */
283 SOC_SINGLE_EXT("DMIC Switch", 0, 0, 1, 0,
284 rt5631_dmic_get, rt5631_dmic_put),
285 SOC_DOUBLE("DMIC Capture Switch", RT5631_DIG_MIC_CTRL,
286 RT5631_DMIC_L_CH_MUTE_SHIFT,
287 RT5631_DMIC_R_CH_MUTE_SHIFT, 1, 1),
288
289 /* SPK Ratio Gain Control */
290 SOC_ENUM("SPK Ratio Control", rt5631_spk_ratio_enum),
291};
292
293static int check_sysclk1_source(struct snd_soc_dapm_widget *source,
294 struct snd_soc_dapm_widget *sink)
295{
296 unsigned int reg;
297
298 reg = snd_soc_read(source->codec, RT5631_GLOBAL_CLK_CTRL);
299 return reg & RT5631_SYSCLK_SOUR_SEL_PLL;
300}
301
302static int check_dmic_used(struct snd_soc_dapm_widget *source,
303 struct snd_soc_dapm_widget *sink)
304{
305 struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(source->codec);
306 return rt5631->dmic_used_flag;
307}
308
309static int check_dacl_to_outmixl(struct snd_soc_dapm_widget *source,
310 struct snd_soc_dapm_widget *sink)
311{
312 unsigned int reg;
313
314 reg = snd_soc_read(source->codec, RT5631_OUTMIXER_L_CTRL);
315 return !(reg & RT5631_M_DAC_L_TO_OUTMIXER_L);
316}
317
318static int check_dacr_to_outmixr(struct snd_soc_dapm_widget *source,
319 struct snd_soc_dapm_widget *sink)
320{
321 unsigned int reg;
322
323 reg = snd_soc_read(source->codec, RT5631_OUTMIXER_R_CTRL);
324 return !(reg & RT5631_M_DAC_R_TO_OUTMIXER_R);
325}
326
327static int check_dacl_to_spkmixl(struct snd_soc_dapm_widget *source,
328 struct snd_soc_dapm_widget *sink)
329{
330 unsigned int reg;
331
332 reg = snd_soc_read(source->codec, RT5631_SPK_MIXER_CTRL);
333 return !(reg & RT5631_M_DAC_L_TO_SPKMIXER_L);
334}
335
336static int check_dacr_to_spkmixr(struct snd_soc_dapm_widget *source,
337 struct snd_soc_dapm_widget *sink)
338{
339 unsigned int reg;
340
341 reg = snd_soc_read(source->codec, RT5631_SPK_MIXER_CTRL);
342 return !(reg & RT5631_M_DAC_R_TO_SPKMIXER_R);
343}
344
345static int check_adcl_select(struct snd_soc_dapm_widget *source,
346 struct snd_soc_dapm_widget *sink)
347{
348 unsigned int reg;
349
350 reg = snd_soc_read(source->codec, RT5631_ADC_REC_MIXER);
351 return !(reg & RT5631_M_MIC1_TO_RECMIXER_L);
352}
353
354static int check_adcr_select(struct snd_soc_dapm_widget *source,
355 struct snd_soc_dapm_widget *sink)
356{
357 unsigned int reg;
358
359 reg = snd_soc_read(source->codec, RT5631_ADC_REC_MIXER);
360 return !(reg & RT5631_M_MIC2_TO_RECMIXER_R);
361}
362
363/**
364 * onebit_depop_power_stage - auto depop in power stage.
365 * @enable: power on/off
366 *
367 * When power on/off headphone, the depop sequence is done by hardware.
368 */
369static void onebit_depop_power_stage(struct snd_soc_codec *codec, int enable)
370{
371 unsigned int soft_vol, hp_zc;
372
373 /* enable one-bit depop function */
374 snd_soc_update_bits(codec, RT5631_DEPOP_FUN_CTRL_2,
375 RT5631_EN_ONE_BIT_DEPOP, 0);
376
377 /* keep soft volume and zero crossing setting */
378 soft_vol = snd_soc_read(codec, RT5631_SOFT_VOL_CTRL);
379 snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, 0);
380 hp_zc = snd_soc_read(codec, RT5631_INT_ST_IRQ_CTRL_2);
381 snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc & 0xf7ff);
382 if (enable) {
383 /* config one-bit depop parameter */
384 rt5631_write_index(codec, RT5631_TEST_MODE_CTRL, 0x84c0);
385 rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x309f);
386 rt5631_write_index(codec, RT5631_CP_INTL_REG2, 0x6530);
387 /* power on capless block */
388 snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_2,
389 RT5631_EN_CAP_FREE_DEPOP);
390 } else {
391 /* power off capless block */
392 snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_2, 0);
393 msleep(100);
394 }
395
396 /* recover soft volume and zero crossing setting */
397 snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, soft_vol);
398 snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc);
399}
400
401/**
402 * onebit_depop_mute_stage - auto depop in mute stage.
403 * @enable: mute/unmute
404 *
405 * When mute/unmute headphone, the depop sequence is done by hardware.
406 */
407static void onebit_depop_mute_stage(struct snd_soc_codec *codec, int enable)
408{
409 unsigned int soft_vol, hp_zc;
410
411 /* enable one-bit depop function */
412 snd_soc_update_bits(codec, RT5631_DEPOP_FUN_CTRL_2,
413 RT5631_EN_ONE_BIT_DEPOP, 0);
414
415 /* keep soft volume and zero crossing setting */
416 soft_vol = snd_soc_read(codec, RT5631_SOFT_VOL_CTRL);
417 snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, 0);
418 hp_zc = snd_soc_read(codec, RT5631_INT_ST_IRQ_CTRL_2);
419 snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc & 0xf7ff);
420 if (enable) {
421 schedule_timeout_uninterruptible(msecs_to_jiffies(10));
422 /* config one-bit depop parameter */
423 rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x307f);
424 snd_soc_update_bits(codec, RT5631_HP_OUT_VOL,
425 RT5631_L_MUTE | RT5631_R_MUTE, 0);
426 msleep(300);
427 } else {
428 snd_soc_update_bits(codec, RT5631_HP_OUT_VOL,
429 RT5631_L_MUTE | RT5631_R_MUTE,
430 RT5631_L_MUTE | RT5631_R_MUTE);
431 msleep(100);
432 }
433
434 /* recover soft volume and zero crossing setting */
435 snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, soft_vol);
436 snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc);
437}
438
439/**
440 * onebit_depop_power_stage - step by step depop sequence in power stage.
441 * @enable: power on/off
442 *
443 * When power on/off headphone, the depop sequence is done in step by step.
444 */
445static void depop_seq_power_stage(struct snd_soc_codec *codec, int enable)
446{
447 unsigned int soft_vol, hp_zc;
448
449 /* depop control by register */
450 snd_soc_update_bits(codec, RT5631_DEPOP_FUN_CTRL_2,
451 RT5631_EN_ONE_BIT_DEPOP, RT5631_EN_ONE_BIT_DEPOP);
452
453 /* keep soft volume and zero crossing setting */
454 soft_vol = snd_soc_read(codec, RT5631_SOFT_VOL_CTRL);
455 snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, 0);
456 hp_zc = snd_soc_read(codec, RT5631_INT_ST_IRQ_CTRL_2);
457 snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc & 0xf7ff);
458 if (enable) {
459 /* config depop sequence parameter */
460 rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x303e);
461
462 /* power on headphone and charge pump */
463 snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
464 RT5631_PWR_CHARGE_PUMP | RT5631_PWR_HP_L_AMP |
465 RT5631_PWR_HP_R_AMP,
466 RT5631_PWR_CHARGE_PUMP | RT5631_PWR_HP_L_AMP |
467 RT5631_PWR_HP_R_AMP);
468
469 /* power on soft generator and depop mode2 */
470 snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1,
471 RT5631_POW_ON_SOFT_GEN | RT5631_EN_DEPOP2_FOR_HP);
472 msleep(100);
473
474 /* stop depop mode */
475 snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
476 RT5631_PWR_HP_DEPOP_DIS, RT5631_PWR_HP_DEPOP_DIS);
477 } else {
478 /* config depop sequence parameter */
479 rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x303F);
480 snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1,
481 RT5631_POW_ON_SOFT_GEN | RT5631_EN_MUTE_UNMUTE_DEPOP |
482 RT5631_PD_HPAMP_L_ST_UP | RT5631_PD_HPAMP_R_ST_UP);
483 msleep(75);
484 snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1,
485 RT5631_POW_ON_SOFT_GEN | RT5631_PD_HPAMP_L_ST_UP |
486 RT5631_PD_HPAMP_R_ST_UP);
487
488 /* start depop mode */
489 snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
490 RT5631_PWR_HP_DEPOP_DIS, 0);
491
492 /* config depop sequence parameter */
493 snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1,
494 RT5631_POW_ON_SOFT_GEN | RT5631_EN_DEPOP2_FOR_HP |
495 RT5631_PD_HPAMP_L_ST_UP | RT5631_PD_HPAMP_R_ST_UP);
496 msleep(80);
497 snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1,
498 RT5631_POW_ON_SOFT_GEN);
499
500 /* power down headphone and charge pump */
501 snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
502 RT5631_PWR_CHARGE_PUMP | RT5631_PWR_HP_L_AMP |
503 RT5631_PWR_HP_R_AMP, 0);
504 }
505
506 /* recover soft volume and zero crossing setting */
507 snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, soft_vol);
508 snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc);
509}
510
511/**
512 * depop_seq_mute_stage - step by step depop sequence in mute stage.
513 * @enable: mute/unmute
514 *
515 * When mute/unmute headphone, the depop sequence is done in step by step.
516 */
517static void depop_seq_mute_stage(struct snd_soc_codec *codec, int enable)
518{
519 unsigned int soft_vol, hp_zc;
520
521 /* depop control by register */
522 snd_soc_update_bits(codec, RT5631_DEPOP_FUN_CTRL_2,
523 RT5631_EN_ONE_BIT_DEPOP, RT5631_EN_ONE_BIT_DEPOP);
524
525 /* keep soft volume and zero crossing setting */
526 soft_vol = snd_soc_read(codec, RT5631_SOFT_VOL_CTRL);
527 snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, 0);
528 hp_zc = snd_soc_read(codec, RT5631_INT_ST_IRQ_CTRL_2);
529 snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc & 0xf7ff);
530 if (enable) {
531 schedule_timeout_uninterruptible(msecs_to_jiffies(10));
532
533 /* config depop sequence parameter */
534 rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x302f);
535 snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1,
536 RT5631_POW_ON_SOFT_GEN | RT5631_EN_MUTE_UNMUTE_DEPOP |
537 RT5631_EN_HP_R_M_UN_MUTE_DEPOP |
538 RT5631_EN_HP_L_M_UN_MUTE_DEPOP);
539
540 snd_soc_update_bits(codec, RT5631_HP_OUT_VOL,
541 RT5631_L_MUTE | RT5631_R_MUTE, 0);
542 msleep(160);
543 } else {
544 /* config depop sequence parameter */
545 rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x302f);
546 snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1,
547 RT5631_POW_ON_SOFT_GEN | RT5631_EN_MUTE_UNMUTE_DEPOP |
548 RT5631_EN_HP_R_M_UN_MUTE_DEPOP |
549 RT5631_EN_HP_L_M_UN_MUTE_DEPOP);
550
551 snd_soc_update_bits(codec, RT5631_HP_OUT_VOL,
552 RT5631_L_MUTE | RT5631_R_MUTE,
553 RT5631_L_MUTE | RT5631_R_MUTE);
554 msleep(150);
555 }
556
557 /* recover soft volume and zero crossing setting */
558 snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, soft_vol);
559 snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc);
560}
561
562static int hp_event(struct snd_soc_dapm_widget *w,
563 struct snd_kcontrol *kcontrol, int event)
564{
565 struct snd_soc_codec *codec = w->codec;
566 struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
567
568 switch (event) {
569 case SND_SOC_DAPM_PRE_PMD:
570 if (rt5631->codec_version) {
571 onebit_depop_mute_stage(codec, 0);
572 onebit_depop_power_stage(codec, 0);
573 } else {
574 depop_seq_mute_stage(codec, 0);
575 depop_seq_power_stage(codec, 0);
576 }
577 break;
578
579 case SND_SOC_DAPM_POST_PMU:
580 if (rt5631->codec_version) {
581 onebit_depop_power_stage(codec, 1);
582 onebit_depop_mute_stage(codec, 1);
583 } else {
584 depop_seq_power_stage(codec, 1);
585 depop_seq_mute_stage(codec, 1);
586 }
587 break;
588
589 default:
590 break;
591 }
592
593 return 0;
594}
595
596static int set_dmic_params(struct snd_soc_dapm_widget *w,
597 struct snd_kcontrol *kcontrol, int event)
598{
599 struct snd_soc_codec *codec = w->codec;
600 struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
601
602 switch (rt5631->rx_rate) {
603 case 44100:
604 case 48000:
605 snd_soc_update_bits(codec, RT5631_DIG_MIC_CTRL,
606 RT5631_DMIC_CLK_CTRL_MASK,
607 RT5631_DMIC_CLK_CTRL_TO_32FS);
608 break;
609
610 case 32000:
611 case 22050:
612 snd_soc_update_bits(codec, RT5631_DIG_MIC_CTRL,
613 RT5631_DMIC_CLK_CTRL_MASK,
614 RT5631_DMIC_CLK_CTRL_TO_64FS);
615 break;
616
617 case 16000:
618 case 11025:
619 case 8000:
620 snd_soc_update_bits(codec, RT5631_DIG_MIC_CTRL,
621 RT5631_DMIC_CLK_CTRL_MASK,
622 RT5631_DMIC_CLK_CTRL_TO_128FS);
623 break;
624
625 default:
626 return -EINVAL;
627 }
628
629 return 0;
630}
631
632static const struct snd_kcontrol_new rt5631_recmixl_mixer_controls[] = {
633 SOC_DAPM_SINGLE("OUTMIXL Capture Switch", RT5631_ADC_REC_MIXER,
634 RT5631_M_OUTMIXL_RECMIXL_BIT, 1, 1),
635 SOC_DAPM_SINGLE("MIC1_BST1 Capture Switch", RT5631_ADC_REC_MIXER,
636 RT5631_M_MIC1_RECMIXL_BIT, 1, 1),
637 SOC_DAPM_SINGLE("AXILVOL Capture Switch", RT5631_ADC_REC_MIXER,
638 RT5631_M_AXIL_RECMIXL_BIT, 1, 1),
639 SOC_DAPM_SINGLE("MONOIN_RX Capture Switch", RT5631_ADC_REC_MIXER,
640 RT5631_M_MONO_IN_RECMIXL_BIT, 1, 1),
641};
642
643static const struct snd_kcontrol_new rt5631_recmixr_mixer_controls[] = {
644 SOC_DAPM_SINGLE("MONOIN_RX Capture Switch", RT5631_ADC_REC_MIXER,
645 RT5631_M_MONO_IN_RECMIXR_BIT, 1, 1),
646 SOC_DAPM_SINGLE("AXIRVOL Capture Switch", RT5631_ADC_REC_MIXER,
647 RT5631_M_AXIR_RECMIXR_BIT, 1, 1),
648 SOC_DAPM_SINGLE("MIC2_BST2 Capture Switch", RT5631_ADC_REC_MIXER,
649 RT5631_M_MIC2_RECMIXR_BIT, 1, 1),
650 SOC_DAPM_SINGLE("OUTMIXR Capture Switch", RT5631_ADC_REC_MIXER,
651 RT5631_M_OUTMIXR_RECMIXR_BIT, 1, 1),
652};
653
654static const struct snd_kcontrol_new rt5631_spkmixl_mixer_controls[] = {
655 SOC_DAPM_SINGLE("RECMIXL Playback Switch", RT5631_SPK_MIXER_CTRL,
656 RT5631_M_RECMIXL_SPKMIXL_BIT, 1, 1),
657 SOC_DAPM_SINGLE("MIC1_P Playback Switch", RT5631_SPK_MIXER_CTRL,
658 RT5631_M_MIC1P_SPKMIXL_BIT, 1, 1),
659 SOC_DAPM_SINGLE("DACL Playback Switch", RT5631_SPK_MIXER_CTRL,
660 RT5631_M_DACL_SPKMIXL_BIT, 1, 1),
661 SOC_DAPM_SINGLE("OUTMIXL Playback Switch", RT5631_SPK_MIXER_CTRL,
662 RT5631_M_OUTMIXL_SPKMIXL_BIT, 1, 1),
663};
664
665static const struct snd_kcontrol_new rt5631_spkmixr_mixer_controls[] = {
666 SOC_DAPM_SINGLE("OUTMIXR Playback Switch", RT5631_SPK_MIXER_CTRL,
667 RT5631_M_OUTMIXR_SPKMIXR_BIT, 1, 1),
668 SOC_DAPM_SINGLE("DACR Playback Switch", RT5631_SPK_MIXER_CTRL,
669 RT5631_M_DACR_SPKMIXR_BIT, 1, 1),
670 SOC_DAPM_SINGLE("MIC2_P Playback Switch", RT5631_SPK_MIXER_CTRL,
671 RT5631_M_MIC2P_SPKMIXR_BIT, 1, 1),
672 SOC_DAPM_SINGLE("RECMIXR Playback Switch", RT5631_SPK_MIXER_CTRL,
673 RT5631_M_RECMIXR_SPKMIXR_BIT, 1, 1),
674};
675
676static const struct snd_kcontrol_new rt5631_outmixl_mixer_controls[] = {
677 SOC_DAPM_SINGLE("RECMIXL Playback Switch", RT5631_OUTMIXER_L_CTRL,
678 RT5631_M_RECMIXL_OUTMIXL_BIT, 1, 1),
679 SOC_DAPM_SINGLE("RECMIXR Playback Switch", RT5631_OUTMIXER_L_CTRL,
680 RT5631_M_RECMIXR_OUTMIXL_BIT, 1, 1),
681 SOC_DAPM_SINGLE("DACL Playback Switch", RT5631_OUTMIXER_L_CTRL,
682 RT5631_M_DACL_OUTMIXL_BIT, 1, 1),
683 SOC_DAPM_SINGLE("MIC1_BST1 Playback Switch", RT5631_OUTMIXER_L_CTRL,
684 RT5631_M_MIC1_OUTMIXL_BIT, 1, 1),
685 SOC_DAPM_SINGLE("MIC2_BST2 Playback Switch", RT5631_OUTMIXER_L_CTRL,
686 RT5631_M_MIC2_OUTMIXL_BIT, 1, 1),
687 SOC_DAPM_SINGLE("MONOIN_RXP Playback Switch", RT5631_OUTMIXER_L_CTRL,
688 RT5631_M_MONO_INP_OUTMIXL_BIT, 1, 1),
689 SOC_DAPM_SINGLE("AXILVOL Playback Switch", RT5631_OUTMIXER_L_CTRL,
690 RT5631_M_AXIL_OUTMIXL_BIT, 1, 1),
691 SOC_DAPM_SINGLE("AXIRVOL Playback Switch", RT5631_OUTMIXER_L_CTRL,
692 RT5631_M_AXIR_OUTMIXL_BIT, 1, 1),
693 SOC_DAPM_SINGLE("VDAC Playback Switch", RT5631_OUTMIXER_L_CTRL,
694 RT5631_M_VDAC_OUTMIXL_BIT, 1, 1),
695};
696
697static const struct snd_kcontrol_new rt5631_outmixr_mixer_controls[] = {
698 SOC_DAPM_SINGLE("VDAC Playback Switch", RT5631_OUTMIXER_R_CTRL,
699 RT5631_M_VDAC_OUTMIXR_BIT, 1, 1),
700 SOC_DAPM_SINGLE("AXIRVOL Playback Switch", RT5631_OUTMIXER_R_CTRL,
701 RT5631_M_AXIR_OUTMIXR_BIT, 1, 1),
702 SOC_DAPM_SINGLE("AXILVOL Playback Switch", RT5631_OUTMIXER_R_CTRL,
703 RT5631_M_AXIL_OUTMIXR_BIT, 1, 1),
704 SOC_DAPM_SINGLE("MONOIN_RXN Playback Switch", RT5631_OUTMIXER_R_CTRL,
705 RT5631_M_MONO_INN_OUTMIXR_BIT, 1, 1),
706 SOC_DAPM_SINGLE("MIC2_BST2 Playback Switch", RT5631_OUTMIXER_R_CTRL,
707 RT5631_M_MIC2_OUTMIXR_BIT, 1, 1),
708 SOC_DAPM_SINGLE("MIC1_BST1 Playback Switch", RT5631_OUTMIXER_R_CTRL,
709 RT5631_M_MIC1_OUTMIXR_BIT, 1, 1),
710 SOC_DAPM_SINGLE("DACR Playback Switch", RT5631_OUTMIXER_R_CTRL,
711 RT5631_M_DACR_OUTMIXR_BIT, 1, 1),
712 SOC_DAPM_SINGLE("RECMIXR Playback Switch", RT5631_OUTMIXER_R_CTRL,
713 RT5631_M_RECMIXR_OUTMIXR_BIT, 1, 1),
714 SOC_DAPM_SINGLE("RECMIXL Playback Switch", RT5631_OUTMIXER_R_CTRL,
715 RT5631_M_RECMIXL_OUTMIXR_BIT, 1, 1),
716};
717
718static const struct snd_kcontrol_new rt5631_AXO1MIX_mixer_controls[] = {
719 SOC_DAPM_SINGLE("MIC1_BST1 Playback Switch", RT5631_AXO1MIXER_CTRL,
720 RT5631_M_MIC1_AXO1MIX_BIT , 1, 1),
721 SOC_DAPM_SINGLE("MIC2_BST2 Playback Switch", RT5631_AXO1MIXER_CTRL,
722 RT5631_M_MIC2_AXO1MIX_BIT, 1, 1),
723 SOC_DAPM_SINGLE("OUTVOLL Playback Switch", RT5631_AXO1MIXER_CTRL,
724 RT5631_M_OUTMIXL_AXO1MIX_BIT , 1 , 1),
725 SOC_DAPM_SINGLE("OUTVOLR Playback Switch", RT5631_AXO1MIXER_CTRL,
726 RT5631_M_OUTMIXR_AXO1MIX_BIT, 1, 1),
727};
728
729static const struct snd_kcontrol_new rt5631_AXO2MIX_mixer_controls[] = {
730 SOC_DAPM_SINGLE("MIC1_BST1 Playback Switch", RT5631_AXO2MIXER_CTRL,
731 RT5631_M_MIC1_AXO2MIX_BIT, 1, 1),
732 SOC_DAPM_SINGLE("MIC2_BST2 Playback Switch", RT5631_AXO2MIXER_CTRL,
733 RT5631_M_MIC2_AXO2MIX_BIT, 1, 1),
734 SOC_DAPM_SINGLE("OUTVOLL Playback Switch", RT5631_AXO2MIXER_CTRL,
735 RT5631_M_OUTMIXL_AXO2MIX_BIT, 1, 1),
736 SOC_DAPM_SINGLE("OUTVOLR Playback Switch", RT5631_AXO2MIXER_CTRL,
737 RT5631_M_OUTMIXR_AXO2MIX_BIT, 1 , 1),
738};
739
740static const struct snd_kcontrol_new rt5631_spolmix_mixer_controls[] = {
741 SOC_DAPM_SINGLE("SPKVOLL Playback Switch", RT5631_SPK_MONO_OUT_CTRL,
742 RT5631_M_SPKVOLL_SPOLMIX_BIT, 1, 1),
743 SOC_DAPM_SINGLE("SPKVOLR Playback Switch", RT5631_SPK_MONO_OUT_CTRL,
744 RT5631_M_SPKVOLR_SPOLMIX_BIT, 1, 1),
745};
746
747static const struct snd_kcontrol_new rt5631_spormix_mixer_controls[] = {
748 SOC_DAPM_SINGLE("SPKVOLL Playback Switch", RT5631_SPK_MONO_OUT_CTRL,
749 RT5631_M_SPKVOLL_SPORMIX_BIT, 1, 1),
750 SOC_DAPM_SINGLE("SPKVOLR Playback Switch", RT5631_SPK_MONO_OUT_CTRL,
751 RT5631_M_SPKVOLR_SPORMIX_BIT, 1, 1),
752};
753
754static const struct snd_kcontrol_new rt5631_monomix_mixer_controls[] = {
755 SOC_DAPM_SINGLE("OUTVOLL Playback Switch", RT5631_SPK_MONO_OUT_CTRL,
756 RT5631_M_OUTVOLL_MONOMIX_BIT, 1, 1),
757 SOC_DAPM_SINGLE("OUTVOLR Playback Switch", RT5631_SPK_MONO_OUT_CTRL,
758 RT5631_M_OUTVOLR_MONOMIX_BIT, 1, 1),
759};
760
761/* Left SPK Volume Input */
762static const char *rt5631_spkvoll_sel[] = {"Vmid", "SPKMIXL"};
763
764static const SOC_ENUM_SINGLE_DECL(
765 rt5631_spkvoll_enum, RT5631_SPK_OUT_VOL,
766 RT5631_L_EN_SHIFT, rt5631_spkvoll_sel);
767
768static const struct snd_kcontrol_new rt5631_spkvoll_mux_control =
769 SOC_DAPM_ENUM("Left SPKVOL SRC", rt5631_spkvoll_enum);
770
771/* Left HP Volume Input */
772static const char *rt5631_hpvoll_sel[] = {"Vmid", "OUTMIXL"};
773
774static const SOC_ENUM_SINGLE_DECL(
775 rt5631_hpvoll_enum, RT5631_HP_OUT_VOL,
776 RT5631_L_EN_SHIFT, rt5631_hpvoll_sel);
777
778static const struct snd_kcontrol_new rt5631_hpvoll_mux_control =
779 SOC_DAPM_ENUM("Left HPVOL SRC", rt5631_hpvoll_enum);
780
781/* Left Out Volume Input */
782static const char *rt5631_outvoll_sel[] = {"Vmid", "OUTMIXL"};
783
784static const SOC_ENUM_SINGLE_DECL(
785 rt5631_outvoll_enum, RT5631_MONO_AXO_1_2_VOL,
786 RT5631_L_EN_SHIFT, rt5631_outvoll_sel);
787
788static const struct snd_kcontrol_new rt5631_outvoll_mux_control =
789 SOC_DAPM_ENUM("Left OUTVOL SRC", rt5631_outvoll_enum);
790
791/* Right Out Volume Input */
792static const char *rt5631_outvolr_sel[] = {"Vmid", "OUTMIXR"};
793
794static const SOC_ENUM_SINGLE_DECL(
795 rt5631_outvolr_enum, RT5631_MONO_AXO_1_2_VOL,
796 RT5631_R_EN_SHIFT, rt5631_outvolr_sel);
797
798static const struct snd_kcontrol_new rt5631_outvolr_mux_control =
799 SOC_DAPM_ENUM("Right OUTVOL SRC", rt5631_outvolr_enum);
800
801/* Right HP Volume Input */
802static const char *rt5631_hpvolr_sel[] = {"Vmid", "OUTMIXR"};
803
804static const SOC_ENUM_SINGLE_DECL(
805 rt5631_hpvolr_enum, RT5631_HP_OUT_VOL,
806 RT5631_R_EN_SHIFT, rt5631_hpvolr_sel);
807
808static const struct snd_kcontrol_new rt5631_hpvolr_mux_control =
809 SOC_DAPM_ENUM("Right HPVOL SRC", rt5631_hpvolr_enum);
810
811/* Right SPK Volume Input */
812static const char *rt5631_spkvolr_sel[] = {"Vmid", "SPKMIXR"};
813
814static const SOC_ENUM_SINGLE_DECL(
815 rt5631_spkvolr_enum, RT5631_SPK_OUT_VOL,
816 RT5631_R_EN_SHIFT, rt5631_spkvolr_sel);
817
818static const struct snd_kcontrol_new rt5631_spkvolr_mux_control =
819 SOC_DAPM_ENUM("Right SPKVOL SRC", rt5631_spkvolr_enum);
820
821/* SPO Left Channel Input */
822static const char *rt5631_spol_src_sel[] = {
823 "SPOLMIX", "MONOIN_RX", "VDAC", "DACL"};
824
825static const SOC_ENUM_SINGLE_DECL(
826 rt5631_spol_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL,
827 RT5631_SPK_L_MUX_SEL_SHIFT, rt5631_spol_src_sel);
828
829static const struct snd_kcontrol_new rt5631_spol_mux_control =
830 SOC_DAPM_ENUM("SPOL SRC", rt5631_spol_src_enum);
831
832/* SPO Right Channel Input */
833static const char *rt5631_spor_src_sel[] = {
834 "SPORMIX", "MONOIN_RX", "VDAC", "DACR"};
835
836static const SOC_ENUM_SINGLE_DECL(
837 rt5631_spor_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL,
838 RT5631_SPK_R_MUX_SEL_SHIFT, rt5631_spor_src_sel);
839
840static const struct snd_kcontrol_new rt5631_spor_mux_control =
841 SOC_DAPM_ENUM("SPOR SRC", rt5631_spor_src_enum);
842
843/* MONO Input */
844static const char *rt5631_mono_src_sel[] = {"MONOMIX", "MONOIN_RX", "VDAC"};
845
846static const SOC_ENUM_SINGLE_DECL(
847 rt5631_mono_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL,
848 RT5631_MONO_MUX_SEL_SHIFT, rt5631_mono_src_sel);
849
850static const struct snd_kcontrol_new rt5631_mono_mux_control =
851 SOC_DAPM_ENUM("MONO SRC", rt5631_mono_src_enum);
852
853/* Left HPO Input */
854static const char *rt5631_hpl_src_sel[] = {"Left HPVOL", "Left DAC"};
855
856static const SOC_ENUM_SINGLE_DECL(
857 rt5631_hpl_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL,
858 RT5631_HP_L_MUX_SEL_SHIFT, rt5631_hpl_src_sel);
859
860static const struct snd_kcontrol_new rt5631_hpl_mux_control =
861 SOC_DAPM_ENUM("HPL SRC", rt5631_hpl_src_enum);
862
863/* Right HPO Input */
864static const char *rt5631_hpr_src_sel[] = {"Right HPVOL", "Right DAC"};
865
866static const SOC_ENUM_SINGLE_DECL(
867 rt5631_hpr_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL,
868 RT5631_HP_R_MUX_SEL_SHIFT, rt5631_hpr_src_sel);
869
870static const struct snd_kcontrol_new rt5631_hpr_mux_control =
871 SOC_DAPM_ENUM("HPR SRC", rt5631_hpr_src_enum);
872
873static const struct snd_soc_dapm_widget rt5631_dapm_widgets[] = {
874 /* Vmid */
875 SND_SOC_DAPM_VMID("Vmid"),
876 /* PLL1 */
877 SND_SOC_DAPM_SUPPLY("PLL1", RT5631_PWR_MANAG_ADD2,
878 RT5631_PWR_PLL1_BIT, 0, NULL, 0),
879
880 /* Input Side */
881 /* Input Lines */
882 SND_SOC_DAPM_INPUT("MIC1"),
883 SND_SOC_DAPM_INPUT("MIC2"),
884 SND_SOC_DAPM_INPUT("AXIL"),
885 SND_SOC_DAPM_INPUT("AXIR"),
886 SND_SOC_DAPM_INPUT("MONOIN_RXN"),
887 SND_SOC_DAPM_INPUT("MONOIN_RXP"),
888 SND_SOC_DAPM_INPUT("DMIC"),
889
890 /* MICBIAS */
891 SND_SOC_DAPM_MICBIAS("MIC Bias1", RT5631_PWR_MANAG_ADD2,
892 RT5631_PWR_MICBIAS1_VOL_BIT, 0),
893 SND_SOC_DAPM_MICBIAS("MIC Bias2", RT5631_PWR_MANAG_ADD2,
894 RT5631_PWR_MICBIAS2_VOL_BIT, 0),
895
896 /* Boost */
897 SND_SOC_DAPM_PGA("MIC1 Boost", RT5631_PWR_MANAG_ADD2,
898 RT5631_PWR_MIC1_BOOT_GAIN_BIT, 0, NULL, 0),
899 SND_SOC_DAPM_PGA("MIC2 Boost", RT5631_PWR_MANAG_ADD2,
900 RT5631_PWR_MIC2_BOOT_GAIN_BIT, 0, NULL, 0),
901 SND_SOC_DAPM_PGA("MONOIN_RXP Boost", RT5631_PWR_MANAG_ADD4,
902 RT5631_PWR_MONO_IN_P_VOL_BIT, 0, NULL, 0),
903 SND_SOC_DAPM_PGA("MONOIN_RXN Boost", RT5631_PWR_MANAG_ADD4,
904 RT5631_PWR_MONO_IN_N_VOL_BIT, 0, NULL, 0),
905 SND_SOC_DAPM_PGA("AXIL Boost", RT5631_PWR_MANAG_ADD4,
906 RT5631_PWR_AXIL_IN_VOL_BIT, 0, NULL, 0),
907 SND_SOC_DAPM_PGA("AXIR Boost", RT5631_PWR_MANAG_ADD4,
908 RT5631_PWR_AXIR_IN_VOL_BIT, 0, NULL, 0),
909
910 /* MONO In */
911 SND_SOC_DAPM_MIXER("MONO_IN", SND_SOC_NOPM, 0, 0, NULL, 0),
912
913 /* REC Mixer */
914 SND_SOC_DAPM_MIXER("RECMIXL Mixer", RT5631_PWR_MANAG_ADD2,
915 RT5631_PWR_RECMIXER_L_BIT, 0,
916 &rt5631_recmixl_mixer_controls[0],
917 ARRAY_SIZE(rt5631_recmixl_mixer_controls)),
918 SND_SOC_DAPM_MIXER("RECMIXR Mixer", RT5631_PWR_MANAG_ADD2,
919 RT5631_PWR_RECMIXER_R_BIT, 0,
920 &rt5631_recmixr_mixer_controls[0],
921 ARRAY_SIZE(rt5631_recmixr_mixer_controls)),
922 /* Because of record duplication for L/R channel,
923 * L/R ADCs need power up at the same time */
924 SND_SOC_DAPM_MIXER("ADC Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
925
926 /* DMIC */
927 SND_SOC_DAPM_SUPPLY("DMIC Supply", RT5631_DIG_MIC_CTRL,
928 RT5631_DMIC_ENA_SHIFT, 0,
929 set_dmic_params, SND_SOC_DAPM_PRE_PMU),
930 /* ADC Data Srouce */
931 SND_SOC_DAPM_SUPPLY("Left ADC Select", RT5631_INT_ST_IRQ_CTRL_2,
932 RT5631_ADC_DATA_SEL_MIC1_SHIFT, 0, NULL, 0),
933 SND_SOC_DAPM_SUPPLY("Right ADC Select", RT5631_INT_ST_IRQ_CTRL_2,
934 RT5631_ADC_DATA_SEL_MIC2_SHIFT, 0, NULL, 0),
935
936 /* ADCs */
937 SND_SOC_DAPM_ADC("Left ADC", "HIFI Capture",
938 RT5631_PWR_MANAG_ADD1, RT5631_PWR_ADC_L_CLK_BIT, 0),
939 SND_SOC_DAPM_ADC("Right ADC", "HIFI Capture",
940 RT5631_PWR_MANAG_ADD1, RT5631_PWR_ADC_R_CLK_BIT, 0),
941
942 /* DAC and ADC supply power */
943 SND_SOC_DAPM_SUPPLY("I2S", RT5631_PWR_MANAG_ADD1,
944 RT5631_PWR_MAIN_I2S_BIT, 0, NULL, 0),
945 SND_SOC_DAPM_SUPPLY("DAC REF", RT5631_PWR_MANAG_ADD1,
946 RT5631_PWR_DAC_REF_BIT, 0, NULL, 0),
947
948 /* Output Side */
949 /* DACs */
950 SND_SOC_DAPM_DAC("Left DAC", "HIFI Playback",
951 RT5631_PWR_MANAG_ADD1, RT5631_PWR_DAC_L_CLK_BIT, 0),
952 SND_SOC_DAPM_DAC("Right DAC", "HIFI Playback",
953 RT5631_PWR_MANAG_ADD1, RT5631_PWR_DAC_R_CLK_BIT, 0),
954 SND_SOC_DAPM_DAC("Voice DAC", "Voice DAC Mono Playback",
955 SND_SOC_NOPM, 0, 0),
956 SND_SOC_DAPM_PGA("Voice DAC Boost", SND_SOC_NOPM, 0, 0, NULL, 0),
957 /* DAC supply power */
958 SND_SOC_DAPM_SUPPLY("Left DAC To Mixer", RT5631_PWR_MANAG_ADD1,
959 RT5631_PWR_DAC_L_TO_MIXER_BIT, 0, NULL, 0),
960 SND_SOC_DAPM_SUPPLY("Right DAC To Mixer", RT5631_PWR_MANAG_ADD1,
961 RT5631_PWR_DAC_R_TO_MIXER_BIT, 0, NULL, 0),
962
963 /* Left SPK Mixer */
964 SND_SOC_DAPM_MIXER("SPKMIXL Mixer", RT5631_PWR_MANAG_ADD2,
965 RT5631_PWR_SPKMIXER_L_BIT, 0,
966 &rt5631_spkmixl_mixer_controls[0],
967 ARRAY_SIZE(rt5631_spkmixl_mixer_controls)),
968 /* Left Out Mixer */
969 SND_SOC_DAPM_MIXER("OUTMIXL Mixer", RT5631_PWR_MANAG_ADD2,
970 RT5631_PWR_OUTMIXER_L_BIT, 0,
971 &rt5631_outmixl_mixer_controls[0],
972 ARRAY_SIZE(rt5631_outmixl_mixer_controls)),
973 /* Right Out Mixer */
974 SND_SOC_DAPM_MIXER("OUTMIXR Mixer", RT5631_PWR_MANAG_ADD2,
975 RT5631_PWR_OUTMIXER_R_BIT, 0,
976 &rt5631_outmixr_mixer_controls[0],
977 ARRAY_SIZE(rt5631_outmixr_mixer_controls)),
978 /* Right SPK Mixer */
979 SND_SOC_DAPM_MIXER("SPKMIXR Mixer", RT5631_PWR_MANAG_ADD2,
980 RT5631_PWR_SPKMIXER_R_BIT, 0,
981 &rt5631_spkmixr_mixer_controls[0],
982 ARRAY_SIZE(rt5631_spkmixr_mixer_controls)),
983
984 /* Volume Mux */
985 SND_SOC_DAPM_MUX("Left SPKVOL Mux", RT5631_PWR_MANAG_ADD4,
986 RT5631_PWR_SPK_L_VOL_BIT, 0,
987 &rt5631_spkvoll_mux_control),
988 SND_SOC_DAPM_MUX("Left HPVOL Mux", RT5631_PWR_MANAG_ADD4,
989 RT5631_PWR_HP_L_OUT_VOL_BIT, 0,
990 &rt5631_hpvoll_mux_control),
991 SND_SOC_DAPM_MUX("Left OUTVOL Mux", RT5631_PWR_MANAG_ADD4,
992 RT5631_PWR_LOUT_VOL_BIT, 0,
993 &rt5631_outvoll_mux_control),
994 SND_SOC_DAPM_MUX("Right OUTVOL Mux", RT5631_PWR_MANAG_ADD4,
995 RT5631_PWR_ROUT_VOL_BIT, 0,
996 &rt5631_outvolr_mux_control),
997 SND_SOC_DAPM_MUX("Right HPVOL Mux", RT5631_PWR_MANAG_ADD4,
998 RT5631_PWR_HP_R_OUT_VOL_BIT, 0,
999 &rt5631_hpvolr_mux_control),
1000 SND_SOC_DAPM_MUX("Right SPKVOL Mux", RT5631_PWR_MANAG_ADD4,
1001 RT5631_PWR_SPK_R_VOL_BIT, 0,
1002 &rt5631_spkvolr_mux_control),
1003
1004 /* DAC To HP */
1005 SND_SOC_DAPM_PGA_S("Left DAC_HP", 0, SND_SOC_NOPM, 0, 0, NULL, 0),
1006 SND_SOC_DAPM_PGA_S("Right DAC_HP", 0, SND_SOC_NOPM, 0, 0, NULL, 0),
1007
1008 /* HP Depop */
1009 SND_SOC_DAPM_PGA_S("HP Depop", 1, SND_SOC_NOPM, 0, 0,
1010 hp_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
1011
1012 /* AXO1 Mixer */
1013 SND_SOC_DAPM_MIXER("AXO1MIX Mixer", RT5631_PWR_MANAG_ADD3,
1014 RT5631_PWR_AXO1MIXER_BIT, 0,
1015 &rt5631_AXO1MIX_mixer_controls[0],
1016 ARRAY_SIZE(rt5631_AXO1MIX_mixer_controls)),
1017 /* SPOL Mixer */
1018 SND_SOC_DAPM_MIXER("SPOLMIX Mixer", SND_SOC_NOPM, 0, 0,
1019 &rt5631_spolmix_mixer_controls[0],
1020 ARRAY_SIZE(rt5631_spolmix_mixer_controls)),
1021 /* MONO Mixer */
1022 SND_SOC_DAPM_MIXER("MONOMIX Mixer", RT5631_PWR_MANAG_ADD3,
1023 RT5631_PWR_MONOMIXER_BIT, 0,
1024 &rt5631_monomix_mixer_controls[0],
1025 ARRAY_SIZE(rt5631_monomix_mixer_controls)),
1026 /* SPOR Mixer */
1027 SND_SOC_DAPM_MIXER("SPORMIX Mixer", SND_SOC_NOPM, 0, 0,
1028 &rt5631_spormix_mixer_controls[0],
1029 ARRAY_SIZE(rt5631_spormix_mixer_controls)),
1030 /* AXO2 Mixer */
1031 SND_SOC_DAPM_MIXER("AXO2MIX Mixer", RT5631_PWR_MANAG_ADD3,
1032 RT5631_PWR_AXO2MIXER_BIT, 0,
1033 &rt5631_AXO2MIX_mixer_controls[0],
1034 ARRAY_SIZE(rt5631_AXO2MIX_mixer_controls)),
1035
1036 /* Mux */
1037 SND_SOC_DAPM_MUX("SPOL Mux", SND_SOC_NOPM, 0, 0,
1038 &rt5631_spol_mux_control),
1039 SND_SOC_DAPM_MUX("SPOR Mux", SND_SOC_NOPM, 0, 0,
1040 &rt5631_spor_mux_control),
1041 SND_SOC_DAPM_MUX("MONO Mux", SND_SOC_NOPM, 0, 0,
1042 &rt5631_mono_mux_control),
1043 SND_SOC_DAPM_MUX("HPL Mux", SND_SOC_NOPM, 0, 0,
1044 &rt5631_hpl_mux_control),
1045 SND_SOC_DAPM_MUX("HPR Mux", SND_SOC_NOPM, 0, 0,
1046 &rt5631_hpr_mux_control),
1047
1048 /* AMP supply */
1049 SND_SOC_DAPM_SUPPLY("MONO Depop", RT5631_PWR_MANAG_ADD3,
1050 RT5631_PWR_MONO_DEPOP_DIS_BIT, 0, NULL, 0),
1051 SND_SOC_DAPM_SUPPLY("Class D", RT5631_PWR_MANAG_ADD1,
1052 RT5631_PWR_CLASS_D_BIT, 0, NULL, 0),
1053
1054 /* Output Lines */
1055 SND_SOC_DAPM_OUTPUT("AUXO1"),
1056 SND_SOC_DAPM_OUTPUT("AUXO2"),
1057 SND_SOC_DAPM_OUTPUT("SPOL"),
1058 SND_SOC_DAPM_OUTPUT("SPOR"),
1059 SND_SOC_DAPM_OUTPUT("HPOL"),
1060 SND_SOC_DAPM_OUTPUT("HPOR"),
1061 SND_SOC_DAPM_OUTPUT("MONO"),
1062};
1063
1064static const struct snd_soc_dapm_route rt5631_dapm_routes[] = {
1065 {"MIC1 Boost", NULL, "MIC1"},
1066 {"MIC2 Boost", NULL, "MIC2"},
1067 {"MONOIN_RXP Boost", NULL, "MONOIN_RXP"},
1068 {"MONOIN_RXN Boost", NULL, "MONOIN_RXN"},
1069 {"AXIL Boost", NULL, "AXIL"},
1070 {"AXIR Boost", NULL, "AXIR"},
1071
1072 {"MONO_IN", NULL, "MONOIN_RXP Boost"},
1073 {"MONO_IN", NULL, "MONOIN_RXN Boost"},
1074
1075 {"RECMIXL Mixer", "OUTMIXL Capture Switch", "OUTMIXL Mixer"},
1076 {"RECMIXL Mixer", "MIC1_BST1 Capture Switch", "MIC1 Boost"},
1077 {"RECMIXL Mixer", "AXILVOL Capture Switch", "AXIL Boost"},
1078 {"RECMIXL Mixer", "MONOIN_RX Capture Switch", "MONO_IN"},
1079
1080 {"RECMIXR Mixer", "OUTMIXR Capture Switch", "OUTMIXR Mixer"},
1081 {"RECMIXR Mixer", "MIC2_BST2 Capture Switch", "MIC2 Boost"},
1082 {"RECMIXR Mixer", "AXIRVOL Capture Switch", "AXIR Boost"},
1083 {"RECMIXR Mixer", "MONOIN_RX Capture Switch", "MONO_IN"},
1084
1085 {"ADC Mixer", NULL, "RECMIXL Mixer"},
1086 {"ADC Mixer", NULL, "RECMIXR Mixer"},
1087
1088 {"Left ADC", NULL, "ADC Mixer"},
1089 {"Left ADC", NULL, "Left ADC Select", check_adcl_select},
1090 {"Left ADC", NULL, "PLL1", check_sysclk1_source},
1091 {"Left ADC", NULL, "I2S"},
1092 {"Left ADC", NULL, "DAC REF"},
1093
1094 {"Right ADC", NULL, "ADC Mixer"},
1095 {"Right ADC", NULL, "Right ADC Select", check_adcr_select},
1096 {"Right ADC", NULL, "PLL1", check_sysclk1_source},
1097 {"Right ADC", NULL, "I2S"},
1098 {"Right ADC", NULL, "DAC REF"},
1099
1100 {"DMIC", NULL, "DMIC Supply", check_dmic_used},
1101 {"Left ADC", NULL, "DMIC"},
1102 {"Right ADC", NULL, "DMIC"},
1103
1104 {"Left DAC", NULL, "PLL1", check_sysclk1_source},
1105 {"Left DAC", NULL, "I2S"},
1106 {"Left DAC", NULL, "DAC REF"},
1107 {"Right DAC", NULL, "PLL1", check_sysclk1_source},
1108 {"Right DAC", NULL, "I2S"},
1109 {"Right DAC", NULL, "DAC REF"},
1110
1111 {"Voice DAC Boost", NULL, "Voice DAC"},
1112
1113 {"SPKMIXL Mixer", NULL, "Left DAC To Mixer", check_dacl_to_spkmixl},
1114 {"SPKMIXL Mixer", "RECMIXL Playback Switch", "RECMIXL Mixer"},
1115 {"SPKMIXL Mixer", "MIC1_P Playback Switch", "MIC1"},
1116 {"SPKMIXL Mixer", "DACL Playback Switch", "Left DAC"},
1117 {"SPKMIXL Mixer", "OUTMIXL Playback Switch", "OUTMIXL Mixer"},
1118
1119 {"SPKMIXR Mixer", NULL, "Right DAC To Mixer", check_dacr_to_spkmixr},
1120 {"SPKMIXR Mixer", "OUTMIXR Playback Switch", "OUTMIXR Mixer"},
1121 {"SPKMIXR Mixer", "DACR Playback Switch", "Right DAC"},
1122 {"SPKMIXR Mixer", "MIC2_P Playback Switch", "MIC2"},
1123 {"SPKMIXR Mixer", "RECMIXR Playback Switch", "RECMIXR Mixer"},
1124
1125 {"OUTMIXL Mixer", NULL, "Left DAC To Mixer", check_dacl_to_outmixl},
1126 {"OUTMIXL Mixer", "RECMIXL Playback Switch", "RECMIXL Mixer"},
1127 {"OUTMIXL Mixer", "RECMIXR Playback Switch", "RECMIXR Mixer"},
1128 {"OUTMIXL Mixer", "DACL Playback Switch", "Left DAC"},
1129 {"OUTMIXL Mixer", "MIC1_BST1 Playback Switch", "MIC1 Boost"},
1130 {"OUTMIXL Mixer", "MIC2_BST2 Playback Switch", "MIC2 Boost"},
1131 {"OUTMIXL Mixer", "MONOIN_RXP Playback Switch", "MONOIN_RXP Boost"},
1132 {"OUTMIXL Mixer", "AXILVOL Playback Switch", "AXIL Boost"},
1133 {"OUTMIXL Mixer", "AXIRVOL Playback Switch", "AXIR Boost"},
1134 {"OUTMIXL Mixer", "VDAC Playback Switch", "Voice DAC Boost"},
1135
1136 {"OUTMIXR Mixer", NULL, "Right DAC To Mixer", check_dacr_to_outmixr},
1137 {"OUTMIXR Mixer", "RECMIXL Playback Switch", "RECMIXL Mixer"},
1138 {"OUTMIXR Mixer", "RECMIXR Playback Switch", "RECMIXR Mixer"},
1139 {"OUTMIXR Mixer", "DACR Playback Switch", "Right DAC"},
1140 {"OUTMIXR Mixer", "MIC1_BST1 Playback Switch", "MIC1 Boost"},
1141 {"OUTMIXR Mixer", "MIC2_BST2 Playback Switch", "MIC2 Boost"},
1142 {"OUTMIXR Mixer", "MONOIN_RXN Playback Switch", "MONOIN_RXN Boost"},
1143 {"OUTMIXR Mixer", "AXILVOL Playback Switch", "AXIL Boost"},
1144 {"OUTMIXR Mixer", "AXIRVOL Playback Switch", "AXIR Boost"},
1145 {"OUTMIXR Mixer", "VDAC Playback Switch", "Voice DAC Boost"},
1146
1147 {"Left SPKVOL Mux", "SPKMIXL", "SPKMIXL Mixer"},
1148 {"Left SPKVOL Mux", "Vmid", "Vmid"},
1149 {"Left HPVOL Mux", "OUTMIXL", "OUTMIXL Mixer"},
1150 {"Left HPVOL Mux", "Vmid", "Vmid"},
1151 {"Left OUTVOL Mux", "OUTMIXL", "OUTMIXL Mixer"},
1152 {"Left OUTVOL Mux", "Vmid", "Vmid"},
1153 {"Right OUTVOL Mux", "OUTMIXR", "OUTMIXR Mixer"},
1154 {"Right OUTVOL Mux", "Vmid", "Vmid"},
1155 {"Right HPVOL Mux", "OUTMIXR", "OUTMIXR Mixer"},
1156 {"Right HPVOL Mux", "Vmid", "Vmid"},
1157 {"Right SPKVOL Mux", "SPKMIXR", "SPKMIXR Mixer"},
1158 {"Right SPKVOL Mux", "Vmid", "Vmid"},
1159
1160 {"AXO1MIX Mixer", "MIC1_BST1 Playback Switch", "MIC1 Boost"},
1161 {"AXO1MIX Mixer", "OUTVOLL Playback Switch", "Left OUTVOL Mux"},
1162 {"AXO1MIX Mixer", "OUTVOLR Playback Switch", "Right OUTVOL Mux"},
1163 {"AXO1MIX Mixer", "MIC2_BST2 Playback Switch", "MIC2 Boost"},
1164
1165 {"AXO2MIX Mixer", "MIC1_BST1 Playback Switch", "MIC1 Boost"},
1166 {"AXO2MIX Mixer", "OUTVOLL Playback Switch", "Left OUTVOL Mux"},
1167 {"AXO2MIX Mixer", "OUTVOLR Playback Switch", "Right OUTVOL Mux"},
1168 {"AXO2MIX Mixer", "MIC2_BST2 Playback Switch", "MIC2 Boost"},
1169
1170 {"SPOLMIX Mixer", "SPKVOLL Playback Switch", "Left SPKVOL Mux"},
1171 {"SPOLMIX Mixer", "SPKVOLR Playback Switch", "Right SPKVOL Mux"},
1172
1173 {"SPORMIX Mixer", "SPKVOLL Playback Switch", "Left SPKVOL Mux"},
1174 {"SPORMIX Mixer", "SPKVOLR Playback Switch", "Right SPKVOL Mux"},
1175
1176 {"MONOMIX Mixer", "OUTVOLL Playback Switch", "Left OUTVOL Mux"},
1177 {"MONOMIX Mixer", "OUTVOLR Playback Switch", "Right OUTVOL Mux"},
1178
1179 {"SPOL Mux", "SPOLMIX", "SPOLMIX Mixer"},
1180 {"SPOL Mux", "MONOIN_RX", "MONO_IN"},
1181 {"SPOL Mux", "VDAC", "Voice DAC Boost"},
1182 {"SPOL Mux", "DACL", "Left DAC"},
1183
1184 {"SPOR Mux", "SPORMIX", "SPORMIX Mixer"},
1185 {"SPOR Mux", "MONOIN_RX", "MONO_IN"},
1186 {"SPOR Mux", "VDAC", "Voice DAC Boost"},
1187 {"SPOR Mux", "DACR", "Right DAC"},
1188
1189 {"MONO Mux", "MONOMIX", "MONOMIX Mixer"},
1190 {"MONO Mux", "MONOIN_RX", "MONO_IN"},
1191 {"MONO Mux", "VDAC", "Voice DAC Boost"},
1192
1193 {"Right DAC_HP", NULL, "Right DAC"},
1194 {"Left DAC_HP", NULL, "Left DAC"},
1195
1196 {"HPL Mux", "Left HPVOL", "Left HPVOL Mux"},
1197 {"HPL Mux", "Left DAC", "Left DAC_HP"},
1198 {"HPR Mux", "Right HPVOL", "Right HPVOL Mux"},
1199 {"HPR Mux", "Right DAC", "Right DAC_HP"},
1200
1201 {"HP Depop", NULL, "HPL Mux"},
1202 {"HP Depop", NULL, "HPR Mux"},
1203
1204 {"AUXO1", NULL, "AXO1MIX Mixer"},
1205 {"AUXO2", NULL, "AXO2MIX Mixer"},
1206
1207 {"SPOL", NULL, "Class D"},
1208 {"SPOL", NULL, "SPOL Mux"},
1209 {"SPOR", NULL, "Class D"},
1210 {"SPOR", NULL, "SPOR Mux"},
1211
1212 {"HPOL", NULL, "HP Depop"},
1213 {"HPOR", NULL, "HP Depop"},
1214
1215 {"MONO", NULL, "MONO Depop"},
1216 {"MONO", NULL, "MONO Mux"},
1217};
1218
1219struct coeff_clk_div {
1220 u32 mclk;
1221 u32 bclk;
1222 u32 rate;
1223 u16 reg_val;
1224};
1225
1226/* PLL divisors */
1227struct pll_div {
1228 u32 pll_in;
1229 u32 pll_out;
1230 u16 reg_val;
1231};
1232
1233static const struct pll_div codec_master_pll_div[] = {
1234 {2048000, 8192000, 0x0ea0},
1235 {3686400, 8192000, 0x4e27},
1236 {12000000, 8192000, 0x456b},
1237 {13000000, 8192000, 0x495f},
1238 {13100000, 8192000, 0x0320},
1239 {2048000, 11289600, 0xf637},
1240 {3686400, 11289600, 0x2f22},
1241 {12000000, 11289600, 0x3e2f},
1242 {13000000, 11289600, 0x4d5b},
1243 {13100000, 11289600, 0x363b},
1244 {2048000, 16384000, 0x1ea0},
1245 {3686400, 16384000, 0x9e27},
1246 {12000000, 16384000, 0x452b},
1247 {13000000, 16384000, 0x542f},
1248 {13100000, 16384000, 0x03a0},
1249 {2048000, 16934400, 0xe625},
1250 {3686400, 16934400, 0x9126},
1251 {12000000, 16934400, 0x4d2c},
1252 {13000000, 16934400, 0x742f},
1253 {13100000, 16934400, 0x3c27},
1254 {2048000, 22579200, 0x2aa0},
1255 {3686400, 22579200, 0x2f20},
1256 {12000000, 22579200, 0x7e2f},
1257 {13000000, 22579200, 0x742f},
1258 {13100000, 22579200, 0x3c27},
1259 {2048000, 24576000, 0x2ea0},
1260 {3686400, 24576000, 0xee27},
1261 {12000000, 24576000, 0x2915},
1262 {13000000, 24576000, 0x772e},
1263 {13100000, 24576000, 0x0d20},
1264 {26000000, 24576000, 0x2027},
1265 {26000000, 22579200, 0x392f},
1266 {24576000, 22579200, 0x0921},
1267 {24576000, 24576000, 0x02a0},
1268};
1269
1270static const struct pll_div codec_slave_pll_div[] = {
1271 {256000, 2048000, 0x46f0},
1272 {256000, 4096000, 0x3ea0},
1273 {352800, 5644800, 0x3ea0},
1274 {512000, 8192000, 0x3ea0},
1275 {1024000, 8192000, 0x46f0},
1276 {705600, 11289600, 0x3ea0},
1277 {1024000, 16384000, 0x3ea0},
1278 {1411200, 22579200, 0x3ea0},
1279 {1536000, 24576000, 0x3ea0},
1280 {2048000, 16384000, 0x1ea0},
1281 {2822400, 22579200, 0x1ea0},
1282 {2822400, 45158400, 0x5ec0},
1283 {5644800, 45158400, 0x46f0},
1284 {3072000, 24576000, 0x1ea0},
1285 {3072000, 49152000, 0x5ec0},
1286 {6144000, 49152000, 0x46f0},
1287 {705600, 11289600, 0x3ea0},
1288 {705600, 8467200, 0x3ab0},
1289 {24576000, 24576000, 0x02a0},
1290 {1411200, 11289600, 0x1690},
1291 {2822400, 11289600, 0x0a90},
1292 {1536000, 12288000, 0x1690},
1293 {3072000, 12288000, 0x0a90},
1294};
1295
1296static struct coeff_clk_div coeff_div[] = {
1297 /* sysclk is 256fs */
1298 {2048000, 8000 * 32, 8000, 0x1000},
1299 {2048000, 8000 * 64, 8000, 0x0000},
1300 {2822400, 11025 * 32, 11025, 0x1000},
1301 {2822400, 11025 * 64, 11025, 0x0000},
1302 {4096000, 16000 * 32, 16000, 0x1000},
1303 {4096000, 16000 * 64, 16000, 0x0000},
1304 {5644800, 22050 * 32, 22050, 0x1000},
1305 {5644800, 22050 * 64, 22050, 0x0000},
1306 {8192000, 32000 * 32, 32000, 0x1000},
1307 {8192000, 32000 * 64, 32000, 0x0000},
1308 {11289600, 44100 * 32, 44100, 0x1000},
1309 {11289600, 44100 * 64, 44100, 0x0000},
1310 {12288000, 48000 * 32, 48000, 0x1000},
1311 {12288000, 48000 * 64, 48000, 0x0000},
1312 {22579200, 88200 * 32, 88200, 0x1000},
1313 {22579200, 88200 * 64, 88200, 0x0000},
1314 {24576000, 96000 * 32, 96000, 0x1000},
1315 {24576000, 96000 * 64, 96000, 0x0000},
1316 /* sysclk is 512fs */
1317 {4096000, 8000 * 32, 8000, 0x3000},
1318 {4096000, 8000 * 64, 8000, 0x2000},
1319 {5644800, 11025 * 32, 11025, 0x3000},
1320 {5644800, 11025 * 64, 11025, 0x2000},
1321 {8192000, 16000 * 32, 16000, 0x3000},
1322 {8192000, 16000 * 64, 16000, 0x2000},
1323 {11289600, 22050 * 32, 22050, 0x3000},
1324 {11289600, 22050 * 64, 22050, 0x2000},
1325 {16384000, 32000 * 32, 32000, 0x3000},
1326 {16384000, 32000 * 64, 32000, 0x2000},
1327 {22579200, 44100 * 32, 44100, 0x3000},
1328 {22579200, 44100 * 64, 44100, 0x2000},
1329 {24576000, 48000 * 32, 48000, 0x3000},
1330 {24576000, 48000 * 64, 48000, 0x2000},
1331 {45158400, 88200 * 32, 88200, 0x3000},
1332 {45158400, 88200 * 64, 88200, 0x2000},
1333 {49152000, 96000 * 32, 96000, 0x3000},
1334 {49152000, 96000 * 64, 96000, 0x2000},
1335 /* sysclk is 24.576Mhz or 22.5792Mhz */
1336 {24576000, 8000 * 32, 8000, 0x7080},
1337 {24576000, 8000 * 64, 8000, 0x6080},
1338 {24576000, 16000 * 32, 16000, 0x5080},
1339 {24576000, 16000 * 64, 16000, 0x4080},
1340 {24576000, 24000 * 32, 24000, 0x5000},
1341 {24576000, 24000 * 64, 24000, 0x4000},
1342 {24576000, 32000 * 32, 32000, 0x3080},
1343 {24576000, 32000 * 64, 32000, 0x2080},
1344 {22579200, 11025 * 32, 11025, 0x7000},
1345 {22579200, 11025 * 64, 11025, 0x6000},
1346 {22579200, 22050 * 32, 22050, 0x5000},
1347 {22579200, 22050 * 64, 22050, 0x4000},
1348};
1349
1350static int get_coeff(int mclk, int rate, int timesofbclk)
1351{
1352 int i;
1353
1354 for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
1355 if (coeff_div[i].mclk == mclk && coeff_div[i].rate == rate &&
1356 (coeff_div[i].bclk / coeff_div[i].rate) == timesofbclk)
1357 return i;
1358 }
1359 return -EINVAL;
1360}
1361
1362static int rt5631_hifi_pcm_params(struct snd_pcm_substream *substream,
1363 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
1364{
1365 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1366 struct snd_soc_codec *codec = rtd->codec;
1367 struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
1368 int timesofbclk = 32, coeff;
1369 unsigned int iface = 0;
1370
1371 dev_dbg(codec->dev, "enter %s\n", __func__);
1372
1373 rt5631->bclk_rate = snd_soc_params_to_bclk(params);
1374 if (rt5631->bclk_rate < 0) {
1375 dev_err(codec->dev, "Fail to get BCLK rate\n");
1376 return rt5631->bclk_rate;
1377 }
1378 rt5631->rx_rate = params_rate(params);
1379
1380 if (rt5631->master)
1381 coeff = get_coeff(rt5631->sysclk, rt5631->rx_rate,
1382 rt5631->bclk_rate / rt5631->rx_rate);
1383 else
1384 coeff = get_coeff(rt5631->sysclk, rt5631->rx_rate,
1385 timesofbclk);
1386 if (coeff < 0) {
1387 dev_err(codec->dev, "Fail to get coeff\n");
1388 return -EINVAL;
1389 }
1390
1391 switch (params_format(params)) {
1392 case SNDRV_PCM_FORMAT_S16_LE:
1393 break;
1394 case SNDRV_PCM_FORMAT_S20_3LE:
1395 iface |= RT5631_SDP_I2S_DL_20;
1396 break;
1397 case SNDRV_PCM_FORMAT_S24_LE:
1398 iface |= RT5631_SDP_I2S_DL_24;
1399 break;
1400 case SNDRV_PCM_FORMAT_S8:
1401 iface |= RT5631_SDP_I2S_DL_8;
1402 break;
1403 default:
1404 return -EINVAL;
1405 }
1406
1407 snd_soc_update_bits(codec, RT5631_SDP_CTRL,
1408 RT5631_SDP_I2S_DL_MASK, iface);
1409 snd_soc_write(codec, RT5631_STEREO_AD_DA_CLK_CTRL,
1410 coeff_div[coeff].reg_val);
1411
1412 return 0;
1413}
1414
1415static int rt5631_hifi_codec_set_dai_fmt(struct snd_soc_dai *codec_dai,
1416 unsigned int fmt)
1417{
1418 struct snd_soc_codec *codec = codec_dai->codec;
1419 struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
1420 unsigned int iface = 0;
1421
1422 dev_dbg(codec->dev, "enter %s\n", __func__);
1423
1424 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1425 case SND_SOC_DAIFMT_CBM_CFM:
1426 rt5631->master = 1;
1427 break;
1428 case SND_SOC_DAIFMT_CBS_CFS:
1429 iface |= RT5631_SDP_MODE_SEL_SLAVE;
1430 rt5631->master = 0;
1431 break;
1432 default:
1433 return -EINVAL;
1434 }
1435
1436 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1437 case SND_SOC_DAIFMT_I2S:
1438 break;
1439 case SND_SOC_DAIFMT_LEFT_J:
1440 iface |= RT5631_SDP_I2S_DF_LEFT;
1441 break;
1442 case SND_SOC_DAIFMT_DSP_A:
1443 iface |= RT5631_SDP_I2S_DF_PCM_A;
1444 break;
1445 case SND_SOC_DAIFMT_DSP_B:
1446 iface |= RT5631_SDP_I2S_DF_PCM_B;
1447 break;
1448 default:
1449 return -EINVAL;
1450 }
1451
1452 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1453 case SND_SOC_DAIFMT_NB_NF:
1454 break;
1455 case SND_SOC_DAIFMT_IB_NF:
1456 iface |= RT5631_SDP_I2S_BCLK_POL_CTRL;
1457 break;
1458 default:
1459 return -EINVAL;
1460 }
1461
1462 snd_soc_write(codec, RT5631_SDP_CTRL, iface);
1463
1464 return 0;
1465}
1466
1467static int rt5631_hifi_codec_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1468 int clk_id, unsigned int freq, int dir)
1469{
1470 struct snd_soc_codec *codec = codec_dai->codec;
1471 struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
1472
1473 dev_dbg(codec->dev, "enter %s, syclk=%d\n", __func__, freq);
1474
1475 if ((freq >= (256 * 8000)) && (freq <= (512 * 96000))) {
1476 rt5631->sysclk = freq;
1477 return 0;
1478 }
1479
1480 return -EINVAL;
1481}
1482
1483static int rt5631_codec_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
1484 int source, unsigned int freq_in, unsigned int freq_out)
1485{
1486 struct snd_soc_codec *codec = codec_dai->codec;
1487 struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
1488 int i, ret = -EINVAL;
1489
1490 dev_dbg(codec->dev, "enter %s\n", __func__);
1491
1492 if (!freq_in || !freq_out) {
1493 dev_dbg(codec->dev, "PLL disabled\n");
1494
1495 snd_soc_update_bits(codec, RT5631_GLOBAL_CLK_CTRL,
1496 RT5631_SYSCLK_SOUR_SEL_MASK,
1497 RT5631_SYSCLK_SOUR_SEL_MCLK);
1498
1499 return 0;
1500 }
1501
1502 if (rt5631->master) {
1503 for (i = 0; i < ARRAY_SIZE(codec_master_pll_div); i++)
1504 if (freq_in == codec_master_pll_div[i].pll_in &&
1505 freq_out == codec_master_pll_div[i].pll_out) {
1506 dev_info(codec->dev,
1507 "change PLL in master mode\n");
1508 snd_soc_write(codec, RT5631_PLL_CTRL,
1509 codec_master_pll_div[i].reg_val);
1510 schedule_timeout_uninterruptible(
1511 msecs_to_jiffies(20));
1512 snd_soc_update_bits(codec,
1513 RT5631_GLOBAL_CLK_CTRL,
1514 RT5631_SYSCLK_SOUR_SEL_MASK |
1515 RT5631_PLLCLK_SOUR_SEL_MASK,
1516 RT5631_SYSCLK_SOUR_SEL_PLL |
1517 RT5631_PLLCLK_SOUR_SEL_MCLK);
1518 ret = 0;
1519 break;
1520 }
1521 } else {
1522 for (i = 0; i < ARRAY_SIZE(codec_slave_pll_div); i++)
1523 if (freq_in == codec_slave_pll_div[i].pll_in &&
1524 freq_out == codec_slave_pll_div[i].pll_out) {
1525 dev_info(codec->dev,
1526 "change PLL in slave mode\n");
1527 snd_soc_write(codec, RT5631_PLL_CTRL,
1528 codec_slave_pll_div[i].reg_val);
1529 schedule_timeout_uninterruptible(
1530 msecs_to_jiffies(20));
1531 snd_soc_update_bits(codec,
1532 RT5631_GLOBAL_CLK_CTRL,
1533 RT5631_SYSCLK_SOUR_SEL_MASK |
1534 RT5631_PLLCLK_SOUR_SEL_MASK,
1535 RT5631_SYSCLK_SOUR_SEL_PLL |
1536 RT5631_PLLCLK_SOUR_SEL_BCLK);
1537 ret = 0;
1538 break;
1539 }
1540 }
1541
1542 return ret;
1543}
1544
1545static int rt5631_set_bias_level(struct snd_soc_codec *codec,
1546 enum snd_soc_bias_level level)
1547{
1548 switch (level) {
1549 case SND_SOC_BIAS_ON:
1550 case SND_SOC_BIAS_PREPARE:
1551 snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD2,
1552 RT5631_PWR_MICBIAS1_VOL | RT5631_PWR_MICBIAS2_VOL,
1553 RT5631_PWR_MICBIAS1_VOL | RT5631_PWR_MICBIAS2_VOL);
1554 break;
1555
1556 case SND_SOC_BIAS_STANDBY:
1557 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1558 snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
1559 RT5631_PWR_VREF | RT5631_PWR_MAIN_BIAS,
1560 RT5631_PWR_VREF | RT5631_PWR_MAIN_BIAS);
1561 msleep(80);
1562 snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
1563 RT5631_PWR_FAST_VREF_CTRL,
1564 RT5631_PWR_FAST_VREF_CTRL);
1565 codec->cache_only = false;
1566 snd_soc_cache_sync(codec);
1567 }
1568 break;
1569
1570 case SND_SOC_BIAS_OFF:
1571 snd_soc_write(codec, RT5631_PWR_MANAG_ADD1, 0x0000);
1572 snd_soc_write(codec, RT5631_PWR_MANAG_ADD2, 0x0000);
1573 snd_soc_write(codec, RT5631_PWR_MANAG_ADD3, 0x0000);
1574 snd_soc_write(codec, RT5631_PWR_MANAG_ADD4, 0x0000);
1575 break;
1576
1577 default:
1578 break;
1579 }
1580 codec->dapm.bias_level = level;
1581
1582 return 0;
1583}
1584
1585static int rt5631_probe(struct snd_soc_codec *codec)
1586{
1587 struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
1588 unsigned int val;
1589 int ret;
1590
1591 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
1592 if (ret != 0) {
1593 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1594 return ret;
1595 }
1596
1597 val = rt5631_read_index(codec, RT5631_ADDA_MIXER_INTL_REG3);
1598 if (val & 0x0002)
1599 rt5631->codec_version = 1;
1600 else
1601 rt5631->codec_version = 0;
1602
1603 rt5631_reset(codec);
1604 snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
1605 RT5631_PWR_VREF | RT5631_PWR_MAIN_BIAS,
1606 RT5631_PWR_VREF | RT5631_PWR_MAIN_BIAS);
1607 msleep(80);
1608 snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
1609 RT5631_PWR_FAST_VREF_CTRL, RT5631_PWR_FAST_VREF_CTRL);
1610 /* enable HP zero cross */
1611 snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, 0x0f18);
1612 /* power off ClassD auto Recovery */
1613 if (rt5631->codec_version)
1614 snd_soc_update_bits(codec, RT5631_INT_ST_IRQ_CTRL_2,
1615 0x2000, 0x2000);
1616 else
1617 snd_soc_update_bits(codec, RT5631_INT_ST_IRQ_CTRL_2,
1618 0x2000, 0);
1619 /* DMIC */
1620 if (rt5631->dmic_used_flag) {
1621 snd_soc_update_bits(codec, RT5631_GPIO_CTRL,
1622 RT5631_GPIO_PIN_FUN_SEL_MASK |
1623 RT5631_GPIO_DMIC_FUN_SEL_MASK,
1624 RT5631_GPIO_PIN_FUN_SEL_GPIO_DIMC |
1625 RT5631_GPIO_DMIC_FUN_SEL_DIMC);
1626 snd_soc_update_bits(codec, RT5631_DIG_MIC_CTRL,
1627 RT5631_DMIC_L_CH_LATCH_MASK |
1628 RT5631_DMIC_R_CH_LATCH_MASK,
1629 RT5631_DMIC_L_CH_LATCH_FALLING |
1630 RT5631_DMIC_R_CH_LATCH_RISING);
1631 }
1632
1633 codec->dapm.bias_level = SND_SOC_BIAS_STANDBY;
1634
1635 return 0;
1636}
1637
1638static int rt5631_remove(struct snd_soc_codec *codec)
1639{
1640 rt5631_set_bias_level(codec, SND_SOC_BIAS_OFF);
1641 return 0;
1642}
1643
1644#ifdef CONFIG_PM
1645static int rt5631_suspend(struct snd_soc_codec *codec, pm_message_t state)
1646{
1647 rt5631_set_bias_level(codec, SND_SOC_BIAS_OFF);
1648 return 0;
1649}
1650
1651static int rt5631_resume(struct snd_soc_codec *codec)
1652{
1653 rt5631_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1654 return 0;
1655}
1656#else
1657#define rt5631_suspend NULL
1658#define rt5631_resume NULL
1659#endif
1660
1661#define RT5631_STEREO_RATES SNDRV_PCM_RATE_8000_96000
1662#define RT5631_FORMAT (SNDRV_PCM_FMTBIT_S16_LE | \
1663 SNDRV_PCM_FMTBIT_S20_3LE | \
1664 SNDRV_PCM_FMTBIT_S24_LE | \
1665 SNDRV_PCM_FMTBIT_S8)
1666
1667static struct snd_soc_dai_ops rt5631_ops = {
1668 .hw_params = rt5631_hifi_pcm_params,
1669 .set_fmt = rt5631_hifi_codec_set_dai_fmt,
1670 .set_sysclk = rt5631_hifi_codec_set_dai_sysclk,
1671 .set_pll = rt5631_codec_set_dai_pll,
1672};
1673
1674static struct snd_soc_dai_driver rt5631_dai[] = {
1675 {
1676 .name = "rt5631-hifi",
1677 .id = 1,
1678 .playback = {
1679 .stream_name = "HIFI Playback",
1680 .channels_min = 1,
1681 .channels_max = 2,
1682 .rates = RT5631_STEREO_RATES,
1683 .formats = RT5631_FORMAT,
1684 },
1685 .capture = {
1686 .stream_name = "HIFI Capture",
1687 .channels_min = 1,
1688 .channels_max = 2,
1689 .rates = RT5631_STEREO_RATES,
1690 .formats = RT5631_FORMAT,
1691 },
1692 .ops = &rt5631_ops,
1693 },
1694};
1695
1696static struct snd_soc_codec_driver soc_codec_dev_rt5631 = {
1697 .probe = rt5631_probe,
1698 .remove = rt5631_remove,
1699 .suspend = rt5631_suspend,
1700 .resume = rt5631_resume,
1701 .set_bias_level = rt5631_set_bias_level,
1702 .reg_cache_size = RT5631_VENDOR_ID2 + 1,
1703 .reg_word_size = sizeof(u16),
1704 .reg_cache_default = rt5631_reg,
1705 .volatile_register = rt5631_volatile_register,
1706 .readable_register = rt5631_readable_register,
1707 .reg_cache_step = 1,
1708 .controls = rt5631_snd_controls,
1709 .num_controls = ARRAY_SIZE(rt5631_snd_controls),
1710 .dapm_widgets = rt5631_dapm_widgets,
1711 .num_dapm_widgets = ARRAY_SIZE(rt5631_dapm_widgets),
1712 .dapm_routes = rt5631_dapm_routes,
1713 .num_dapm_routes = ARRAY_SIZE(rt5631_dapm_routes),
1714};
1715
1716static const struct i2c_device_id rt5631_i2c_id[] = {
1717 { "rt5631", 0 },
1718 { }
1719};
1720MODULE_DEVICE_TABLE(i2c, rt5631_i2c_id);
1721
1722static int rt5631_i2c_probe(struct i2c_client *i2c,
1723 const struct i2c_device_id *id)
1724{
1725 struct rt5631_priv *rt5631;
1726 int ret;
1727
1728 rt5631 = kzalloc(sizeof(struct rt5631_priv), GFP_KERNEL);
1729 if (NULL == rt5631)
1730 return -ENOMEM;
1731
1732 i2c_set_clientdata(i2c, rt5631);
1733
1734 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5631,
1735 rt5631_dai, ARRAY_SIZE(rt5631_dai));
1736 if (ret < 0)
1737 kfree(rt5631);
1738
1739 return ret;
1740}
1741
1742static __devexit int rt5631_i2c_remove(struct i2c_client *client)
1743{
1744 snd_soc_unregister_codec(&client->dev);
1745 kfree(i2c_get_clientdata(client));
1746 return 0;
1747}
1748
1749static struct i2c_driver rt5631_i2c_driver = {
1750 .driver = {
1751 .name = "rt5631",
1752 .owner = THIS_MODULE,
1753 },
1754 .probe = rt5631_i2c_probe,
1755 .remove = __devexit_p(rt5631_i2c_remove),
1756 .id_table = rt5631_i2c_id,
1757};
1758
1759static int __init rt5631_modinit(void)
1760{
1761 return i2c_add_driver(&rt5631_i2c_driver);
1762}
1763module_init(rt5631_modinit);
1764
1765static void __exit rt5631_modexit(void)
1766{
1767 i2c_del_driver(&rt5631_i2c_driver);
1768}
1769module_exit(rt5631_modexit);
1770
1771MODULE_DESCRIPTION("ASoC RT5631 driver");
1772MODULE_AUTHOR("flove <flove@realtek.com>");
1773MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/rt5631.h b/sound/soc/codecs/rt5631.h
new file mode 100644
index 00000000000..13401581b0d
--- /dev/null
+++ b/sound/soc/codecs/rt5631.h
@@ -0,0 +1,701 @@
1#ifndef __RTCODEC5631_H__
2#define __RTCODEC5631_H__
3
4
5#define RT5631_RESET 0x00
6#define RT5631_SPK_OUT_VOL 0x02
7#define RT5631_HP_OUT_VOL 0x04
8#define RT5631_MONO_AXO_1_2_VOL 0x06
9#define RT5631_AUX_IN_VOL 0x0A
10#define RT5631_STEREO_DAC_VOL_1 0x0C
11#define RT5631_MIC_CTRL_1 0x0E
12#define RT5631_STEREO_DAC_VOL_2 0x10
13#define RT5631_ADC_CTRL_1 0x12
14#define RT5631_ADC_REC_MIXER 0x14
15#define RT5631_ADC_CTRL_2 0x16
16#define RT5631_VDAC_DIG_VOL 0x18
17#define RT5631_OUTMIXER_L_CTRL 0x1A
18#define RT5631_OUTMIXER_R_CTRL 0x1C
19#define RT5631_AXO1MIXER_CTRL 0x1E
20#define RT5631_AXO2MIXER_CTRL 0x20
21#define RT5631_MIC_CTRL_2 0x22
22#define RT5631_DIG_MIC_CTRL 0x24
23#define RT5631_MONO_INPUT_VOL 0x26
24#define RT5631_SPK_MIXER_CTRL 0x28
25#define RT5631_SPK_MONO_OUT_CTRL 0x2A
26#define RT5631_SPK_MONO_HP_OUT_CTRL 0x2C
27#define RT5631_SDP_CTRL 0x34
28#define RT5631_MONO_SDP_CTRL 0x36
29#define RT5631_STEREO_AD_DA_CLK_CTRL 0x38
30#define RT5631_PWR_MANAG_ADD1 0x3A
31#define RT5631_PWR_MANAG_ADD2 0x3B
32#define RT5631_PWR_MANAG_ADD3 0x3C
33#define RT5631_PWR_MANAG_ADD4 0x3E
34#define RT5631_GEN_PUR_CTRL_REG 0x40
35#define RT5631_GLOBAL_CLK_CTRL 0x42
36#define RT5631_PLL_CTRL 0x44
37#define RT5631_INT_ST_IRQ_CTRL_1 0x48
38#define RT5631_INT_ST_IRQ_CTRL_2 0x4A
39#define RT5631_GPIO_CTRL 0x4C
40#define RT5631_MISC_CTRL 0x52
41#define RT5631_DEPOP_FUN_CTRL_1 0x54
42#define RT5631_DEPOP_FUN_CTRL_2 0x56
43#define RT5631_JACK_DET_CTRL 0x5A
44#define RT5631_SOFT_VOL_CTRL 0x5C
45#define RT5631_ALC_CTRL_1 0x64
46#define RT5631_ALC_CTRL_2 0x65
47#define RT5631_ALC_CTRL_3 0x66
48#define RT5631_PSEUDO_SPATL_CTRL 0x68
49#define RT5631_INDEX_ADD 0x6A
50#define RT5631_INDEX_DATA 0x6C
51#define RT5631_EQ_CTRL 0x6E
52#define RT5631_VENDOR_ID 0x7A
53#define RT5631_VENDOR_ID1 0x7C
54#define RT5631_VENDOR_ID2 0x7E
55
56/* Index of Codec Private Register definition */
57#define RT5631_EQ_BW_LOP 0x00
58#define RT5631_EQ_GAIN_LOP 0x01
59#define RT5631_EQ_FC_BP1 0x02
60#define RT5631_EQ_BW_BP1 0x03
61#define RT5631_EQ_GAIN_BP1 0x04
62#define RT5631_EQ_FC_BP2 0x05
63#define RT5631_EQ_BW_BP2 0x06
64#define RT5631_EQ_GAIN_BP2 0x07
65#define RT5631_EQ_FC_BP3 0x08
66#define RT5631_EQ_BW_BP3 0x09
67#define RT5631_EQ_GAIN_BP3 0x0a
68#define RT5631_EQ_BW_HIP 0x0b
69#define RT5631_EQ_GAIN_HIP 0x0c
70#define RT5631_EQ_HPF_A1 0x0d
71#define RT5631_EQ_HPF_A2 0x0e
72#define RT5631_EQ_HPF_GAIN 0x0f
73#define RT5631_EQ_PRE_VOL_CTRL 0x11
74#define RT5631_EQ_POST_VOL_CTRL 0x12
75#define RT5631_TEST_MODE_CTRL 0x39
76#define RT5631_CP_INTL_REG2 0x45
77#define RT5631_ADDA_MIXER_INTL_REG3 0x52
78#define RT5631_SPK_INTL_CTRL 0x56
79
80
81/* global definition */
82#define RT5631_L_MUTE (0x1 << 15)
83#define RT5631_L_MUTE_SHIFT 15
84#define RT5631_L_EN (0x1 << 14)
85#define RT5631_L_EN_SHIFT 14
86#define RT5631_R_MUTE (0x1 << 7)
87#define RT5631_R_MUTE_SHIFT 7
88#define RT5631_R_EN (0x1 << 6)
89#define RT5631_R_EN_SHIFT 6
90#define RT5631_VOL_MASK 0x1f
91#define RT5631_L_VOL_SHIFT 8
92#define RT5631_R_VOL_SHIFT 0
93
94/* Speaker Output Control(0x02) */
95#define RT5631_SPK_L_VOL_SEL_MASK (0x1 << 14)
96#define RT5631_SPK_L_VOL_SEL_VMID (0x0 << 14)
97#define RT5631_SPK_L_VOL_SEL_SPKMIX_L (0x1 << 14)
98#define RT5631_SPK_R_VOL_SEL_MASK (0x1 << 6)
99#define RT5631_SPK_R_VOL_SEL_VMID (0x0 << 6)
100#define RT5631_SPK_R_VOL_SEL_SPKMIX_R (0x1 << 6)
101
102/* Headphone Output Control(0x04) */
103#define RT5631_HP_L_VOL_SEL_MASK (0x1 << 14)
104#define RT5631_HP_L_VOL_SEL_VMID (0x0 << 14)
105#define RT5631_HP_L_VOL_SEL_OUTMIX_L (0x1 << 14)
106#define RT5631_HP_R_VOL_SEL_MASK (0x1 << 6)
107#define RT5631_HP_R_VOL_SEL_VMID (0x0 << 6)
108#define RT5631_HP_R_VOL_SEL_OUTMIX_R (0x1 << 6)
109
110/* Output Control for AUXOUT/MONO(0x06) */
111#define RT5631_AUXOUT_1_VOL_SEL_MASK (0x1 << 14)
112#define RT5631_AUXOUT_1_VOL_SEL_VMID (0x0 << 14)
113#define RT5631_AUXOUT_1_VOL_SEL_OUTMIX_L (0x1 << 14)
114#define RT5631_MUTE_MONO (0x1 << 13)
115#define RT5631_MUTE_MONO_SHIFT 13
116#define RT5631_AUXOUT_2_VOL_SEL_MASK (0x1 << 6)
117#define RT5631_AUXOUT_2_VOL_SEL_VMID (0x0 << 6)
118#define RT5631_AUXOUT_2_VOL_SEL_OUTMIX_R (0x1 << 6)
119
120/* Microphone Input Control 1(0x0E) */
121#define RT5631_MIC1_DIFF_INPUT_CTRL (0x1 << 15)
122#define RT5631_MIC1_DIFF_INPUT_SHIFT 15
123#define RT5631_MIC2_DIFF_INPUT_CTRL (0x1 << 7)
124#define RT5631_MIC2_DIFF_INPUT_SHIFT 7
125
126/* Stereo DAC Digital Volume2(0x10) */
127#define RT5631_DAC_VOL_MASK 0xff
128
129/* ADC Recording Mixer Control(0x14) */
130#define RT5631_M_OUTMIXER_L_TO_RECMIXER_L (0x1 << 15)
131#define RT5631_M_OUTMIXL_RECMIXL_BIT 15
132#define RT5631_M_MIC1_TO_RECMIXER_L (0x1 << 14)
133#define RT5631_M_MIC1_RECMIXL_BIT 14
134#define RT5631_M_AXIL_TO_RECMIXER_L (0x1 << 13)
135#define RT5631_M_AXIL_RECMIXL_BIT 13
136#define RT5631_M_MONO_IN_TO_RECMIXER_L (0x1 << 12)
137#define RT5631_M_MONO_IN_RECMIXL_BIT 12
138#define RT5631_M_OUTMIXER_R_TO_RECMIXER_R (0x1 << 7)
139#define RT5631_M_OUTMIXR_RECMIXR_BIT 7
140#define RT5631_M_MIC2_TO_RECMIXER_R (0x1 << 6)
141#define RT5631_M_MIC2_RECMIXR_BIT 6
142#define RT5631_M_AXIR_TO_RECMIXER_R (0x1 << 5)
143#define RT5631_M_AXIR_RECMIXR_BIT 5
144#define RT5631_M_MONO_IN_TO_RECMIXER_R (0x1 << 4)
145#define RT5631_M_MONO_IN_RECMIXR_BIT 4
146
147/* Left Output Mixer Control(0x1A) */
148#define RT5631_M_RECMIXER_L_TO_OUTMIXER_L (0x1 << 15)
149#define RT5631_M_RECMIXL_OUTMIXL_BIT 15
150#define RT5631_M_RECMIXER_R_TO_OUTMIXER_L (0x1 << 14)
151#define RT5631_M_RECMIXR_OUTMIXL_BIT 14
152#define RT5631_M_DAC_L_TO_OUTMIXER_L (0x1 << 13)
153#define RT5631_M_DACL_OUTMIXL_BIT 13
154#define RT5631_M_MIC1_TO_OUTMIXER_L (0x1 << 12)
155#define RT5631_M_MIC1_OUTMIXL_BIT 12
156#define RT5631_M_MIC2_TO_OUTMIXER_L (0x1 << 11)
157#define RT5631_M_MIC2_OUTMIXL_BIT 11
158#define RT5631_M_MONO_IN_P_TO_OUTMIXER_L (0x1 << 10)
159#define RT5631_M_MONO_INP_OUTMIXL_BIT 10
160#define RT5631_M_AXIL_TO_OUTMIXER_L (0x1 << 9)
161#define RT5631_M_AXIL_OUTMIXL_BIT 9
162#define RT5631_M_AXIR_TO_OUTMIXER_L (0x1 << 8)
163#define RT5631_M_AXIR_OUTMIXL_BIT 8
164#define RT5631_M_VDAC_TO_OUTMIXER_L (0x1 << 7)
165#define RT5631_M_VDAC_OUTMIXL_BIT 7
166
167/* Right Output Mixer Control(0x1C) */
168#define RT5631_M_RECMIXER_L_TO_OUTMIXER_R (0x1 << 15)
169#define RT5631_M_RECMIXL_OUTMIXR_BIT 15
170#define RT5631_M_RECMIXER_R_TO_OUTMIXER_R (0x1 << 14)
171#define RT5631_M_RECMIXR_OUTMIXR_BIT 14
172#define RT5631_M_DAC_R_TO_OUTMIXER_R (0x1 << 13)
173#define RT5631_M_DACR_OUTMIXR_BIT 13
174#define RT5631_M_MIC1_TO_OUTMIXER_R (0x1 << 12)
175#define RT5631_M_MIC1_OUTMIXR_BIT 12
176#define RT5631_M_MIC2_TO_OUTMIXER_R (0x1 << 11)
177#define RT5631_M_MIC2_OUTMIXR_BIT 11
178#define RT5631_M_MONO_IN_N_TO_OUTMIXER_R (0x1 << 10)
179#define RT5631_M_MONO_INN_OUTMIXR_BIT 10
180#define RT5631_M_AXIL_TO_OUTMIXER_R (0x1 << 9)
181#define RT5631_M_AXIL_OUTMIXR_BIT 9
182#define RT5631_M_AXIR_TO_OUTMIXER_R (0x1 << 8)
183#define RT5631_M_AXIR_OUTMIXR_BIT 8
184#define RT5631_M_VDAC_TO_OUTMIXER_R (0x1 << 7)
185#define RT5631_M_VDAC_OUTMIXR_BIT 7
186
187/* Lout Mixer Control(0x1E) */
188#define RT5631_M_MIC1_TO_AXO1MIXER (0x1 << 15)
189#define RT5631_M_MIC1_AXO1MIX_BIT 15
190#define RT5631_M_MIC2_TO_AXO1MIXER (0x1 << 11)
191#define RT5631_M_MIC2_AXO1MIX_BIT 11
192#define RT5631_M_OUTMIXER_L_TO_AXO1MIXER (0x1 << 7)
193#define RT5631_M_OUTMIXL_AXO1MIX_BIT 7
194#define RT5631_M_OUTMIXER_R_TO_AXO1MIXER (0x1 << 6)
195#define RT5631_M_OUTMIXR_AXO1MIX_BIT 6
196
197/* Rout Mixer Control(0x20) */
198#define RT5631_M_MIC1_TO_AXO2MIXER (0x1 << 15)
199#define RT5631_M_MIC1_AXO2MIX_BIT 15
200#define RT5631_M_MIC2_TO_AXO2MIXER (0x1 << 11)
201#define RT5631_M_MIC2_AXO2MIX_BIT 11
202#define RT5631_M_OUTMIXER_L_TO_AXO2MIXER (0x1 << 7)
203#define RT5631_M_OUTMIXL_AXO2MIX_BIT 7
204#define RT5631_M_OUTMIXER_R_TO_AXO2MIXER (0x1 << 6)
205#define RT5631_M_OUTMIXR_AXO2MIX_BIT 6
206
207/* Micphone Input Control 2(0x22) */
208#define RT5631_MIC_BIAS_90_PRECNET_AVDD 1
209#define RT5631_MIC_BIAS_75_PRECNET_AVDD 2
210
211#define RT5631_MIC1_BOOST_CTRL_MASK (0xf << 12)
212#define RT5631_MIC1_BOOST_CTRL_BYPASS (0x0 << 12)
213#define RT5631_MIC1_BOOST_CTRL_20DB (0x1 << 12)
214#define RT5631_MIC1_BOOST_CTRL_24DB (0x2 << 12)
215#define RT5631_MIC1_BOOST_CTRL_30DB (0x3 << 12)
216#define RT5631_MIC1_BOOST_CTRL_35DB (0x4 << 12)
217#define RT5631_MIC1_BOOST_CTRL_40DB (0x5 << 12)
218#define RT5631_MIC1_BOOST_CTRL_34DB (0x6 << 12)
219#define RT5631_MIC1_BOOST_CTRL_50DB (0x7 << 12)
220#define RT5631_MIC1_BOOST_CTRL_52DB (0x8 << 12)
221#define RT5631_MIC1_BOOST_SHIFT 12
222
223#define RT5631_MIC2_BOOST_CTRL_MASK (0xf << 8)
224#define RT5631_MIC2_BOOST_CTRL_BYPASS (0x0 << 8)
225#define RT5631_MIC2_BOOST_CTRL_20DB (0x1 << 8)
226#define RT5631_MIC2_BOOST_CTRL_24DB (0x2 << 8)
227#define RT5631_MIC2_BOOST_CTRL_30DB (0x3 << 8)
228#define RT5631_MIC2_BOOST_CTRL_35DB (0x4 << 8)
229#define RT5631_MIC2_BOOST_CTRL_40DB (0x5 << 8)
230#define RT5631_MIC2_BOOST_CTRL_34DB (0x6 << 8)
231#define RT5631_MIC2_BOOST_CTRL_50DB (0x7 << 8)
232#define RT5631_MIC2_BOOST_CTRL_52DB (0x8 << 8)
233#define RT5631_MIC2_BOOST_SHIFT 8
234
235#define RT5631_MICBIAS1_VOLT_CTRL_MASK (0x1 << 7)
236#define RT5631_MICBIAS1_VOLT_CTRL_90P (0x0 << 7)
237#define RT5631_MICBIAS1_VOLT_CTRL_75P (0x1 << 7)
238
239#define RT5631_MICBIAS1_S_C_DET_MASK (0x1 << 6)
240#define RT5631_MICBIAS1_S_C_DET_DIS (0x0 << 6)
241#define RT5631_MICBIAS1_S_C_DET_ENA (0x1 << 6)
242
243#define RT5631_MICBIAS1_SHORT_CURR_DET_MASK (0x3 << 4)
244#define RT5631_MICBIAS1_SHORT_CURR_DET_600UA (0x0 << 4)
245#define RT5631_MICBIAS1_SHORT_CURR_DET_1500UA (0x1 << 4)
246#define RT5631_MICBIAS1_SHORT_CURR_DET_2000UA (0x2 << 4)
247
248#define RT5631_MICBIAS2_VOLT_CTRL_MASK (0x1 << 3)
249#define RT5631_MICBIAS2_VOLT_CTRL_90P (0x0 << 3)
250#define RT5631_MICBIAS2_VOLT_CTRL_75P (0x1 << 3)
251
252#define RT5631_MICBIAS2_S_C_DET_MASK (0x1 << 2)
253#define RT5631_MICBIAS2_S_C_DET_DIS (0x0 << 2)
254#define RT5631_MICBIAS2_S_C_DET_ENA (0x1 << 2)
255
256#define RT5631_MICBIAS2_SHORT_CURR_DET_MASK (0x3)
257#define RT5631_MICBIAS2_SHORT_CURR_DET_600UA (0x0)
258#define RT5631_MICBIAS2_SHORT_CURR_DET_1500UA (0x1)
259#define RT5631_MICBIAS2_SHORT_CURR_DET_2000UA (0x2)
260
261
262/* Digital Microphone Control(0x24) */
263#define RT5631_DMIC_ENA_MASK (0x1 << 15)
264#define RT5631_DMIC_ENA_SHIFT 15
265/* DMIC_ENA: DMIC to ADC Digital filter */
266#define RT5631_DMIC_ENA (0x1 << 15)
267/* DMIC_DIS: ADC mixer to ADC Digital filter */
268#define RT5631_DMIC_DIS (0x0 << 15)
269#define RT5631_DMIC_L_CH_MUTE (0x1 << 13)
270#define RT5631_DMIC_L_CH_MUTE_SHIFT 13
271#define RT5631_DMIC_R_CH_MUTE (0x1 << 12)
272#define RT5631_DMIC_R_CH_MUTE_SHIFT 12
273#define RT5631_DMIC_L_CH_LATCH_MASK (0x1 << 9)
274#define RT5631_DMIC_L_CH_LATCH_RISING (0x1 << 9)
275#define RT5631_DMIC_L_CH_LATCH_FALLING (0x0 << 9)
276#define RT5631_DMIC_R_CH_LATCH_MASK (0x1 << 8)
277#define RT5631_DMIC_R_CH_LATCH_RISING (0x1 << 8)
278#define RT5631_DMIC_R_CH_LATCH_FALLING (0x0 << 8)
279#define RT5631_DMIC_CLK_CTRL_MASK (0x3 << 4)
280#define RT5631_DMIC_CLK_CTRL_TO_128FS (0x0 << 4)
281#define RT5631_DMIC_CLK_CTRL_TO_64FS (0x1 << 4)
282#define RT5631_DMIC_CLK_CTRL_TO_32FS (0x2 << 4)
283
284/* Microphone Input Volume(0x26) */
285#define RT5631_MONO_DIFF_INPUT_SHIFT 15
286
287/* Speaker Mixer Control(0x28) */
288#define RT5631_M_RECMIXER_L_TO_SPKMIXER_L (0x1 << 15)
289#define RT5631_M_RECMIXL_SPKMIXL_BIT 15
290#define RT5631_M_MIC1_P_TO_SPKMIXER_L (0x1 << 14)
291#define RT5631_M_MIC1P_SPKMIXL_BIT 14
292#define RT5631_M_DAC_L_TO_SPKMIXER_L (0x1 << 13)
293#define RT5631_M_DACL_SPKMIXL_BIT 13
294#define RT5631_M_OUTMIXER_L_TO_SPKMIXER_L (0x1 << 12)
295#define RT5631_M_OUTMIXL_SPKMIXL_BIT 12
296
297#define RT5631_M_RECMIXER_R_TO_SPKMIXER_R (0x1 << 7)
298#define RT5631_M_RECMIXR_SPKMIXR_BIT 7
299#define RT5631_M_MIC2_P_TO_SPKMIXER_R (0x1 << 6)
300#define RT5631_M_MIC2P_SPKMIXR_BIT 6
301#define RT5631_M_DAC_R_TO_SPKMIXER_R (0x1 << 5)
302#define RT5631_M_DACR_SPKMIXR_BIT 5
303#define RT5631_M_OUTMIXER_R_TO_SPKMIXER_R (0x1 << 4)
304#define RT5631_M_OUTMIXR_SPKMIXR_BIT 4
305
306/* Speaker/Mono Output Control(0x2A) */
307#define RT5631_M_SPKVOL_L_TO_SPOL_MIXER (0x1 << 15)
308#define RT5631_M_SPKVOLL_SPOLMIX_BIT 15
309#define RT5631_M_SPKVOL_R_TO_SPOL_MIXER (0x1 << 14)
310#define RT5631_M_SPKVOLR_SPOLMIX_BIT 14
311#define RT5631_M_SPKVOL_L_TO_SPOR_MIXER (0x1 << 13)
312#define RT5631_M_SPKVOLL_SPORMIX_BIT 13
313#define RT5631_M_SPKVOL_R_TO_SPOR_MIXER (0x1 << 12)
314#define RT5631_M_SPKVOLR_SPORMIX_BIT 12
315#define RT5631_M_OUTVOL_L_TO_MONOMIXER (0x1 << 11)
316#define RT5631_M_OUTVOLL_MONOMIX_BIT 11
317#define RT5631_M_OUTVOL_R_TO_MONOMIXER (0x1 << 10)
318#define RT5631_M_OUTVOLR_MONOMIX_BIT 10
319
320/* Speaker/Mono/HP Output Control(0x2C) */
321#define RT5631_SPK_L_MUX_SEL_MASK (0x3 << 14)
322#define RT5631_SPK_L_MUX_SEL_SPKMIXER_L (0x0 << 14)
323#define RT5631_SPK_L_MUX_SEL_MONO_IN (0x1 << 14)
324#define RT5631_SPK_L_MUX_SEL_DAC_L (0x3 << 14)
325#define RT5631_SPK_L_MUX_SEL_SHIFT 14
326
327#define RT5631_SPK_R_MUX_SEL_MASK (0x3 << 10)
328#define RT5631_SPK_R_MUX_SEL_SPKMIXER_R (0x0 << 10)
329#define RT5631_SPK_R_MUX_SEL_MONO_IN (0x1 << 10)
330#define RT5631_SPK_R_MUX_SEL_DAC_R (0x3 << 10)
331#define RT5631_SPK_R_MUX_SEL_SHIFT 10
332
333#define RT5631_MONO_MUX_SEL_MASK (0x3 << 6)
334#define RT5631_MONO_MUX_SEL_MONOMIXER (0x0 << 6)
335#define RT5631_MONO_MUX_SEL_MONO_IN (0x1 << 6)
336#define RT5631_MONO_MUX_SEL_SHIFT 6
337
338#define RT5631_HP_L_MUX_SEL_MASK (0x1 << 3)
339#define RT5631_HP_L_MUX_SEL_HPVOL_L (0x0 << 3)
340#define RT5631_HP_L_MUX_SEL_DAC_L (0x1 << 3)
341#define RT5631_HP_L_MUX_SEL_SHIFT 3
342
343#define RT5631_HP_R_MUX_SEL_MASK (0x1 << 2)
344#define RT5631_HP_R_MUX_SEL_HPVOL_R (0x0 << 2)
345#define RT5631_HP_R_MUX_SEL_DAC_R (0x1 << 2)
346#define RT5631_HP_R_MUX_SEL_SHIFT 2
347
348/* Stereo I2S Serial Data Port Control(0x34) */
349#define RT5631_SDP_MODE_SEL_MASK (0x1 << 15)
350#define RT5631_SDP_MODE_SEL_MASTER (0x0 << 15)
351#define RT5631_SDP_MODE_SEL_SLAVE (0x1 << 15)
352
353#define RT5631_SDP_ADC_CPS_SEL_MASK (0x3 << 10)
354#define RT5631_SDP_ADC_CPS_SEL_OFF (0x0 << 10)
355#define RT5631_SDP_ADC_CPS_SEL_U_LAW (0x1 << 10)
356#define RT5631_SDP_ADC_CPS_SEL_A_LAW (0x2 << 10)
357
358#define RT5631_SDP_DAC_CPS_SEL_MASK (0x3 << 8)
359#define RT5631_SDP_DAC_CPS_SEL_OFF (0x0 << 8)
360#define RT5631_SDP_DAC_CPS_SEL_U_LAW (0x1 << 8)
361#define RT5631_SDP_DAC_CPS_SEL_A_LAW (0x2 << 8)
362/* 0:Normal 1:Invert */
363#define RT5631_SDP_I2S_BCLK_POL_CTRL (0x1 << 7)
364/* 0:Normal 1:Invert */
365#define RT5631_SDP_DAC_R_INV (0x1 << 6)
366/* 0:ADC data appear at left phase of LRCK
367 * 1:ADC data appear at right phase of LRCK
368 */
369#define RT5631_SDP_ADC_DATA_L_R_SWAP (0x1 << 5)
370/* 0:DAC data appear at left phase of LRCK
371 * 1:DAC data appear at right phase of LRCK
372 */
373#define RT5631_SDP_DAC_DATA_L_R_SWAP (0x1 << 4)
374
375/* Data Length Slection */
376#define RT5631_SDP_I2S_DL_MASK (0x3 << 2)
377#define RT5631_SDP_I2S_DL_16 (0x0 << 2)
378#define RT5631_SDP_I2S_DL_20 (0x1 << 2)
379#define RT5631_SDP_I2S_DL_24 (0x2 << 2)
380#define RT5631_SDP_I2S_DL_8 (0x3 << 2)
381
382/* PCM Data Format Selection */
383#define RT5631_SDP_I2S_DF_MASK (0x3)
384#define RT5631_SDP_I2S_DF_I2S (0x0)
385#define RT5631_SDP_I2S_DF_LEFT (0x1)
386#define RT5631_SDP_I2S_DF_PCM_A (0x2)
387#define RT5631_SDP_I2S_DF_PCM_B (0x3)
388
389/* Stereo AD/DA Clock Control(0x38h) */
390#define RT5631_I2S_PRE_DIV_MASK (0x7 << 13)
391#define RT5631_I2S_PRE_DIV_1 (0x0 << 13)
392#define RT5631_I2S_PRE_DIV_2 (0x1 << 13)
393#define RT5631_I2S_PRE_DIV_4 (0x2 << 13)
394#define RT5631_I2S_PRE_DIV_8 (0x3 << 13)
395#define RT5631_I2S_PRE_DIV_16 (0x4 << 13)
396#define RT5631_I2S_PRE_DIV_32 (0x5 << 13)
397/* CLOCK RELATIVE OF BCLK AND LCRK */
398#define RT5631_I2S_LRCK_SEL_N_BCLK_MASK (0x1 << 12)
399#define RT5631_I2S_LRCK_SEL_64_BCLK (0x0 << 12) /* 64FS */
400#define RT5631_I2S_LRCK_SEL_32_BCLK (0x1 << 12) /* 32FS */
401
402#define RT5631_DAC_OSR_SEL_MASK (0x3 << 10)
403#define RT5631_DAC_OSR_SEL_128FS (0x3 << 10)
404#define RT5631_DAC_OSR_SEL_64FS (0x3 << 10)
405#define RT5631_DAC_OSR_SEL_32FS (0x3 << 10)
406#define RT5631_DAC_OSR_SEL_16FS (0x3 << 10)
407
408#define RT5631_ADC_OSR_SEL_MASK (0x3 << 8)
409#define RT5631_ADC_OSR_SEL_128FS (0x3 << 8)
410#define RT5631_ADC_OSR_SEL_64FS (0x3 << 8)
411#define RT5631_ADC_OSR_SEL_32FS (0x3 << 8)
412#define RT5631_ADC_OSR_SEL_16FS (0x3 << 8)
413
414#define RT5631_ADDA_FILTER_CLK_SEL_256FS (0 << 7) /* 256FS */
415#define RT5631_ADDA_FILTER_CLK_SEL_384FS (1 << 7) /* 384FS */
416
417/* Power managment addition 1 (0x3A) */
418#define RT5631_PWR_MAIN_I2S_EN (0x1 << 15)
419#define RT5631_PWR_MAIN_I2S_BIT 15
420#define RT5631_PWR_CLASS_D (0x1 << 12)
421#define RT5631_PWR_CLASS_D_BIT 12
422#define RT5631_PWR_ADC_L_CLK (0x1 << 11)
423#define RT5631_PWR_ADC_L_CLK_BIT 11
424#define RT5631_PWR_ADC_R_CLK (0x1 << 10)
425#define RT5631_PWR_ADC_R_CLK_BIT 10
426#define RT5631_PWR_DAC_L_CLK (0x1 << 9)
427#define RT5631_PWR_DAC_L_CLK_BIT 9
428#define RT5631_PWR_DAC_R_CLK (0x1 << 8)
429#define RT5631_PWR_DAC_R_CLK_BIT 8
430#define RT5631_PWR_DAC_REF (0x1 << 7)
431#define RT5631_PWR_DAC_REF_BIT 7
432#define RT5631_PWR_DAC_L_TO_MIXER (0x1 << 6)
433#define RT5631_PWR_DAC_L_TO_MIXER_BIT 6
434#define RT5631_PWR_DAC_R_TO_MIXER (0x1 << 5)
435#define RT5631_PWR_DAC_R_TO_MIXER_BIT 5
436
437/* Power managment addition 2 (0x3B) */
438#define RT5631_PWR_OUTMIXER_L (0x1 << 15)
439#define RT5631_PWR_OUTMIXER_L_BIT 15
440#define RT5631_PWR_OUTMIXER_R (0x1 << 14)
441#define RT5631_PWR_OUTMIXER_R_BIT 14
442#define RT5631_PWR_SPKMIXER_L (0x1 << 13)
443#define RT5631_PWR_SPKMIXER_L_BIT 13
444#define RT5631_PWR_SPKMIXER_R (0x1 << 12)
445#define RT5631_PWR_SPKMIXER_R_BIT 12
446#define RT5631_PWR_RECMIXER_L (0x1 << 11)
447#define RT5631_PWR_RECMIXER_L_BIT 11
448#define RT5631_PWR_RECMIXER_R (0x1 << 10)
449#define RT5631_PWR_RECMIXER_R_BIT 10
450#define RT5631_PWR_MIC1_BOOT_GAIN (0x1 << 5)
451#define RT5631_PWR_MIC1_BOOT_GAIN_BIT 5
452#define RT5631_PWR_MIC2_BOOT_GAIN (0x1 << 4)
453#define RT5631_PWR_MIC2_BOOT_GAIN_BIT 4
454#define RT5631_PWR_MICBIAS1_VOL (0x1 << 3)
455#define RT5631_PWR_MICBIAS1_VOL_BIT 3
456#define RT5631_PWR_MICBIAS2_VOL (0x1 << 2)
457#define RT5631_PWR_MICBIAS2_VOL_BIT 2
458#define RT5631_PWR_PLL1 (0x1 << 1)
459#define RT5631_PWR_PLL1_BIT 1
460#define RT5631_PWR_PLL2 (0x1 << 0)
461#define RT5631_PWR_PLL2_BIT 0
462
463/* Power managment addition 3(0x3C) */
464#define RT5631_PWR_VREF (0x1 << 15)
465#define RT5631_PWR_VREF_BIT 15
466#define RT5631_PWR_FAST_VREF_CTRL (0x1 << 14)
467#define RT5631_PWR_FAST_VREF_CTRL_BIT 14
468#define RT5631_PWR_MAIN_BIAS (0x1 << 13)
469#define RT5631_PWR_MAIN_BIAS_BIT 13
470#define RT5631_PWR_AXO1MIXER (0x1 << 11)
471#define RT5631_PWR_AXO1MIXER_BIT 11
472#define RT5631_PWR_AXO2MIXER (0x1 << 10)
473#define RT5631_PWR_AXO2MIXER_BIT 10
474#define RT5631_PWR_MONOMIXER (0x1 << 9)
475#define RT5631_PWR_MONOMIXER_BIT 9
476#define RT5631_PWR_MONO_DEPOP_DIS (0x1 << 8)
477#define RT5631_PWR_MONO_DEPOP_DIS_BIT 8
478#define RT5631_PWR_MONO_AMP_EN (0x1 << 7)
479#define RT5631_PWR_MONO_AMP_EN_BIT 7
480#define RT5631_PWR_CHARGE_PUMP (0x1 << 4)
481#define RT5631_PWR_CHARGE_PUMP_BIT 4
482#define RT5631_PWR_HP_L_AMP (0x1 << 3)
483#define RT5631_PWR_HP_L_AMP_BIT 3
484#define RT5631_PWR_HP_R_AMP (0x1 << 2)
485#define RT5631_PWR_HP_R_AMP_BIT 2
486#define RT5631_PWR_HP_DEPOP_DIS (0x1 << 1)
487#define RT5631_PWR_HP_DEPOP_DIS_BIT 1
488#define RT5631_PWR_HP_AMP_DRIVING (0x1 << 0)
489#define RT5631_PWR_HP_AMP_DRIVING_BIT 0
490
491/* Power managment addition 4(0x3E) */
492#define RT5631_PWR_SPK_L_VOL (0x1 << 15)
493#define RT5631_PWR_SPK_L_VOL_BIT 15
494#define RT5631_PWR_SPK_R_VOL (0x1 << 14)
495#define RT5631_PWR_SPK_R_VOL_BIT 14
496#define RT5631_PWR_LOUT_VOL (0x1 << 13)
497#define RT5631_PWR_LOUT_VOL_BIT 13
498#define RT5631_PWR_ROUT_VOL (0x1 << 12)
499#define RT5631_PWR_ROUT_VOL_BIT 12
500#define RT5631_PWR_HP_L_OUT_VOL (0x1 << 11)
501#define RT5631_PWR_HP_L_OUT_VOL_BIT 11
502#define RT5631_PWR_HP_R_OUT_VOL (0x1 << 10)
503#define RT5631_PWR_HP_R_OUT_VOL_BIT 10
504#define RT5631_PWR_AXIL_IN_VOL (0x1 << 9)
505#define RT5631_PWR_AXIL_IN_VOL_BIT 9
506#define RT5631_PWR_AXIR_IN_VOL (0x1 << 8)
507#define RT5631_PWR_AXIR_IN_VOL_BIT 8
508#define RT5631_PWR_MONO_IN_P_VOL (0x1 << 7)
509#define RT5631_PWR_MONO_IN_P_VOL_BIT 7
510#define RT5631_PWR_MONO_IN_N_VOL (0x1 << 6)
511#define RT5631_PWR_MONO_IN_N_VOL_BIT 6
512
513/* General Purpose Control Register(0x40) */
514#define RT5631_SPK_AMP_AUTO_RATIO_EN (0x1 << 15)
515
516#define RT5631_SPK_AMP_RATIO_CTRL_MASK (0x7 << 12)
517#define RT5631_SPK_AMP_RATIO_CTRL_2_34 (0x0 << 12) /* 7.40DB */
518#define RT5631_SPK_AMP_RATIO_CTRL_1_99 (0x1 << 12) /* 5.99DB */
519#define RT5631_SPK_AMP_RATIO_CTRL_1_68 (0x2 << 12) /* 4.50DB */
520#define RT5631_SPK_AMP_RATIO_CTRL_1_56 (0x3 << 12) /* 3.86DB */
521#define RT5631_SPK_AMP_RATIO_CTRL_1_44 (0x4 << 12) /* 3.16DB */
522#define RT5631_SPK_AMP_RATIO_CTRL_1_27 (0x5 << 12) /* 2.10DB */
523#define RT5631_SPK_AMP_RATIO_CTRL_1_09 (0x6 << 12) /* 0.80DB */
524#define RT5631_SPK_AMP_RATIO_CTRL_1_00 (0x7 << 12) /* 0.00DB */
525#define RT5631_SPK_AMP_RATIO_CTRL_SHIFT 12
526
527#define RT5631_STEREO_DAC_HI_PASS_FILT_EN (0x1 << 11)
528#define RT5631_STEREO_ADC_HI_PASS_FILT_EN (0x1 << 10)
529/* Select ADC Wind Filter Clock type */
530#define RT5631_ADC_WIND_FILT_MASK (0x3 << 4)
531#define RT5631_ADC_WIND_FILT_8_16_32K (0x0 << 4) /*8/16/32k*/
532#define RT5631_ADC_WIND_FILT_11_22_44K (0x1 << 4) /*11/22/44k*/
533#define RT5631_ADC_WIND_FILT_12_24_48K (0x2 << 4) /*12/24/48k*/
534#define RT5631_ADC_WIND_FILT_EN (0x1 << 3)
535/* SelectADC Wind Filter Corner Frequency */
536#define RT5631_ADC_WIND_CNR_FREQ_MASK (0x7 << 0)
537#define RT5631_ADC_WIND_CNR_FREQ_82_113_122 (0x0 << 0) /* 82/113/122 Hz */
538#define RT5631_ADC_WIND_CNR_FREQ_102_141_153 (0x1 << 0) /* 102/141/153 Hz */
539#define RT5631_ADC_WIND_CNR_FREQ_131_180_156 (0x2 << 0) /* 131/180/156 Hz */
540#define RT5631_ADC_WIND_CNR_FREQ_163_225_245 (0x3 << 0) /* 163/225/245 Hz */
541#define RT5631_ADC_WIND_CNR_FREQ_204_281_306 (0x4 << 0) /* 204/281/306 Hz */
542#define RT5631_ADC_WIND_CNR_FREQ_261_360_392 (0x5 << 0) /* 261/360/392 Hz */
543#define RT5631_ADC_WIND_CNR_FREQ_327_450_490 (0x6 << 0) /* 327/450/490 Hz */
544#define RT5631_ADC_WIND_CNR_FREQ_408_563_612 (0x7 << 0) /* 408/563/612 Hz */
545
546/* Global Clock Control Register(0x42) */
547#define RT5631_SYSCLK_SOUR_SEL_MASK (0x3 << 14)
548#define RT5631_SYSCLK_SOUR_SEL_MCLK (0x0 << 14)
549#define RT5631_SYSCLK_SOUR_SEL_PLL (0x1 << 14)
550#define RT5631_SYSCLK_SOUR_SEL_PLL_TCK (0x2 << 14)
551
552#define RT5631_PLLCLK_SOUR_SEL_MASK (0x3 << 12)
553#define RT5631_PLLCLK_SOUR_SEL_MCLK (0x0 << 12)
554#define RT5631_PLLCLK_SOUR_SEL_BCLK (0x1 << 12)
555#define RT5631_PLLCLK_SOUR_SEL_VBCLK (0x2 << 12)
556
557#define RT5631_PLLCLK_PRE_DIV1 (0x0 << 11)
558#define RT5631_PLLCLK_PRE_DIV2 (0x1 << 11)
559
560/* PLL Control(0x44) */
561#define RT5631_PLL_CTRL_M_VAL(m) ((m)&0xf)
562#define RT5631_PLL_CTRL_K_VAL(k) (((k)&0x7) << 4)
563#define RT5631_PLL_CTRL_N_VAL(n) (((n)&0xff) << 8)
564
565/* Internal Status and IRQ Control2(0x4A) */
566#define RT5631_ADC_DATA_SEL_MASK (0x3 << 14)
567#define RT5631_ADC_DATA_SEL_Disable (0x0 << 14)
568#define RT5631_ADC_DATA_SEL_MIC1 (0x1 << 14)
569#define RT5631_ADC_DATA_SEL_MIC1_SHIFT 14
570#define RT5631_ADC_DATA_SEL_MIC2 (0x2 << 14)
571#define RT5631_ADC_DATA_SEL_MIC2_SHIFT 15
572#define RT5631_ADC_DATA_SEL_STO (0x3 << 14)
573#define RT5631_ADC_DATA_SEL_SHIFT 14
574
575/* GPIO Pin Configuration(0x4C) */
576#define RT5631_GPIO_PIN_FUN_SEL_MASK (0x1 << 15)
577#define RT5631_GPIO_PIN_FUN_SEL_IRQ (0x1 << 15)
578#define RT5631_GPIO_PIN_FUN_SEL_GPIO_DIMC (0x0 << 15)
579
580#define RT5631_GPIO_DMIC_FUN_SEL_MASK (0x1 << 3)
581#define RT5631_GPIO_DMIC_FUN_SEL_DIMC (0x1 << 3)
582#define RT5631_GPIO_DMIC_FUN_SEL_GPIO (0x0 << 3)
583
584#define RT5631_GPIO_PIN_CON_MASK (0x1 << 2)
585#define RT5631_GPIO_PIN_SET_INPUT (0x0 << 2)
586#define RT5631_GPIO_PIN_SET_OUTPUT (0x1 << 2)
587
588/* De-POP function Control 1(0x54) */
589#define RT5631_POW_ON_SOFT_GEN (0x1 << 15)
590#define RT5631_EN_MUTE_UNMUTE_DEPOP (0x1 << 14)
591#define RT5631_EN_DEPOP2_FOR_HP (0x1 << 7)
592/* Power Down HPAMP_L Starts Up Signal */
593#define RT5631_PD_HPAMP_L_ST_UP (0x1 << 5)
594/* Power Down HPAMP_R Starts Up Signal */
595#define RT5631_PD_HPAMP_R_ST_UP (0x1 << 4)
596/* Enable left HP mute/unmute depop */
597#define RT5631_EN_HP_L_M_UN_MUTE_DEPOP (0x1 << 1)
598/* Enable right HP mute/unmute depop */
599#define RT5631_EN_HP_R_M_UN_MUTE_DEPOP (0x1 << 0)
600
601/* De-POP Fnction Control(0x56) */
602#define RT5631_EN_ONE_BIT_DEPOP (0x1 << 15)
603#define RT5631_EN_CAP_FREE_DEPOP (0x1 << 14)
604
605/* Jack Detect Control Register(0x5A) */
606#define RT5631_JD_USE_MASK (0x3 << 14)
607#define RT5631_JD_USE_JD2 (0x3 << 14)
608#define RT5631_JD_USE_JD1 (0x2 << 14)
609#define RT5631_JD_USE_GPIO (0x1 << 14)
610#define RT5631_JD_OFF (0x0 << 14)
611/* JD trigger enable for HP */
612#define RT5631_JD_HP_EN (0x1 << 11)
613#define RT5631_JD_HP_TRI_MASK (0x1 << 10)
614#define RT5631_JD_HP_TRI_HI (0x1 << 10)
615#define RT5631_JD_HP_TRI_LO (0x1 << 10)
616/* JD trigger enable for speaker LP/LN */
617#define RT5631_JD_SPK_L_EN (0x1 << 9)
618#define RT5631_JD_SPK_L_TRI_MASK (0x1 << 8)
619#define RT5631_JD_SPK_L_TRI_HI (0x1 << 8)
620#define RT5631_JD_SPK_L_TRI_LO (0x0 << 8)
621/* JD trigger enable for speaker RP/RN */
622#define RT5631_JD_SPK_R_EN (0x1 << 7)
623#define RT5631_JD_SPK_R_TRI_MASK (0x1 << 6)
624#define RT5631_JD_SPK_R_TRI_HI (0x1 << 6)
625#define RT5631_JD_SPK_R_TRI_LO (0x0 << 6)
626/* JD trigger enable for monoout */
627#define RT5631_JD_MONO_EN (0x1 << 5)
628#define RT5631_JD_MONO_TRI_MASK (0x1 << 4)
629#define RT5631_JD_MONO_TRI_HI (0x1 << 4)
630#define RT5631_JD_MONO_TRI_LO (0x0 << 4)
631/* JD trigger enable for Lout */
632#define RT5631_JD_AUX_1_EN (0x1 << 3)
633#define RT5631_JD_AUX_1_MASK (0x1 << 2)
634#define RT5631_JD_AUX_1_TRI_HI (0x1 << 2)
635#define RT5631_JD_AUX_1_TRI_LO (0x0 << 2)
636/* JD trigger enable for Rout */
637#define RT5631_JD_AUX_2_EN (0x1 << 1)
638#define RT5631_JD_AUX_2_MASK (0x1 << 0)
639#define RT5631_JD_AUX_2_TRI_HI (0x1 << 0)
640#define RT5631_JD_AUX_2_TRI_LO (0x0 << 0)
641
642/* ALC CONTROL 1(0x64) */
643#define RT5631_ALC_ATTACK_RATE_MASK (0x1F << 8)
644#define RT5631_ALC_RECOVERY_RATE_MASK (0x1F << 0)
645
646/* ALC CONTROL 2(0x65) */
647/* select Compensation gain for Noise gate function */
648#define RT5631_ALC_COM_NOISE_GATE_MASK (0xF << 0)
649
650/* ALC CONTROL 3(0x66) */
651#define RT5631_ALC_FUN_MASK (0x3 << 14)
652#define RT5631_ALC_FUN_DIS (0x0 << 14)
653#define RT5631_ALC_ENA_DAC_PATH (0x1 << 14)
654#define RT5631_ALC_ENA_ADC_PATH (0x3 << 14)
655#define RT5631_ALC_PARA_UPDATE (0x1 << 13)
656#define RT5631_ALC_LIMIT_LEVEL_MASK (0x1F << 8)
657#define RT5631_ALC_NOISE_GATE_FUN_MASK (0x1 << 7)
658#define RT5631_ALC_NOISE_GATE_FUN_DIS (0x0 << 7)
659#define RT5631_ALC_NOISE_GATE_FUN_ENA (0x1 << 7)
660/* ALC noise gate hold data function */
661#define RT5631_ALC_NOISE_GATE_H_D_MASK (0x1 << 6)
662#define RT5631_ALC_NOISE_GATE_H_D_DIS (0x0 << 6)
663#define RT5631_ALC_NOISE_GATE_H_D_ENA (0x1 << 6)
664
665/* Psedueo Stereo & Spatial Effect Block Control(0x68) */
666#define RT5631_SPATIAL_CTRL_EN (0x1 << 15)
667#define RT5631_ALL_PASS_FILTER_EN (0x1 << 14)
668#define RT5631_PSEUDO_STEREO_EN (0x1 << 13)
669#define RT5631_STEREO_EXPENSION_EN (0x1 << 12)
670/* 3D gain parameter */
671#define RT5631_GAIN_3D_PARA_MASK (0x3 << 6)
672#define RT5631_GAIN_3D_PARA_1_00 (0x0 << 6) /* 3D gain 1.0 */
673#define RT5631_GAIN_3D_PARA_1_50 (0x1 << 6) /* 3D gain 1.5 */
674#define RT5631_GAIN_3D_PARA_2_00 (0x2 << 6) /* 3D gain 2.0 */
675/* 3D ratio parameter */
676#define RT5631_RATIO_3D_MASK (0x3 << 4)
677#define RT5631_RATIO_3D_0_0 (0x0 << 4) /* 3D ratio 0.0 */
678#define RT5631_RATIO_3D_0_66 (0x1 << 4) /* 3D ratio 0.66 */
679#define RT5631_RATIO_3D_1_0 (0x2 << 4) /* 3D ratio 1.0 */
680/* select samplerate for all pass filter */
681#define RT5631_APF_FUN_SLE_MASK (0x3 << 0)
682#define RT5631_APF_FUN_SEL_48K (0x3 << 0)
683#define RT5631_APF_FUN_SEL_44_1K (0x2 << 0)
684#define RT5631_APF_FUN_SEL_32K (0x1 << 0)
685#define RT5631_APF_FUN_DIS (0x0 << 0)
686
687/* EQ CONTROL 1(0x6E) */
688#define RT5631_HW_EQ_PATH_SEL_MASK (0x1 << 15)
689#define RT5631_HW_EQ_PATH_SEL_DAC (0x0 << 15)
690#define RT5631_HW_EQ_PATH_SEL_ADC (0x1 << 15)
691#define RT5631_HW_EQ_UPDATE_CTRL (0x1 << 14)
692
693#define RT5631_EN_HW_EQ_HPF2 (0x1 << 5)
694#define RT5631_EN_HW_EQ_HPF1 (0x1 << 4)
695#define RT5631_EN_HW_EQ_BP3 (0x1 << 3)
696#define RT5631_EN_HW_EQ_BP2 (0x1 << 2)
697#define RT5631_EN_HW_EQ_BP1 (0x1 << 1)
698#define RT5631_EN_HW_EQ_LPF (0x1 << 0)
699
700
701#endif /* __RTCODEC5631_H__ */
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
index 7e4066e131e..d15695d1c27 100644
--- a/sound/soc/codecs/sgtl5000.c
+++ b/sound/soc/codecs/sgtl5000.c
@@ -20,6 +20,7 @@
20#include <linux/regulator/driver.h> 20#include <linux/regulator/driver.h>
21#include <linux/regulator/machine.h> 21#include <linux/regulator/machine.h>
22#include <linux/regulator/consumer.h> 22#include <linux/regulator/consumer.h>
23#include <linux/of_device.h>
23#include <sound/core.h> 24#include <sound/core.h>
24#include <sound/tlv.h> 25#include <sound/tlv.h>
25#include <sound/pcm.h> 26#include <sound/pcm.h>
@@ -130,16 +131,13 @@ static int mic_bias_event(struct snd_soc_dapm_widget *w,
130 case SND_SOC_DAPM_POST_PMU: 131 case SND_SOC_DAPM_POST_PMU:
131 /* change mic bias resistor to 4Kohm */ 132 /* change mic bias resistor to 4Kohm */
132 snd_soc_update_bits(w->codec, SGTL5000_CHIP_MIC_CTRL, 133 snd_soc_update_bits(w->codec, SGTL5000_CHIP_MIC_CTRL,
133 SGTL5000_BIAS_R_4k, SGTL5000_BIAS_R_4k); 134 SGTL5000_BIAS_R_MASK,
135 SGTL5000_BIAS_R_4k << SGTL5000_BIAS_R_SHIFT);
134 break; 136 break;
135 137
136 case SND_SOC_DAPM_PRE_PMD: 138 case SND_SOC_DAPM_PRE_PMD:
137 /*
138 * SGTL5000_BIAS_R_8k as mask to clean the two bits
139 * of mic bias and output impedance
140 */
141 snd_soc_update_bits(w->codec, SGTL5000_CHIP_MIC_CTRL, 139 snd_soc_update_bits(w->codec, SGTL5000_CHIP_MIC_CTRL,
142 SGTL5000_BIAS_R_8k, 0); 140 SGTL5000_BIAS_R_MASK, 0);
143 break; 141 break;
144 } 142 }
145 return 0; 143 return 0;
@@ -725,7 +723,9 @@ static int sgtl5000_pcm_hw_params(struct snd_pcm_substream *substream,
725 return -EINVAL; 723 return -EINVAL;
726 } 724 }
727 725
728 snd_soc_update_bits(codec, SGTL5000_CHIP_I2S_CTRL, i2s_ctl, i2s_ctl); 726 snd_soc_update_bits(codec, SGTL5000_CHIP_I2S_CTRL,
727 SGTL5000_I2S_DLEN_MASK | SGTL5000_I2S_SCLKFREQ_MASK,
728 i2s_ctl);
729 729
730 return 0; 730 return 0;
731} 731}
@@ -756,7 +756,7 @@ static int ldo_regulator_enable(struct regulator_dev *dev)
756 756
757 /* set voltage to register */ 757 /* set voltage to register */
758 snd_soc_update_bits(codec, SGTL5000_CHIP_LINREG_CTRL, 758 snd_soc_update_bits(codec, SGTL5000_CHIP_LINREG_CTRL,
759 (0x1 << 4) - 1, reg); 759 SGTL5000_LINREG_VDDD_MASK, reg);
760 760
761 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER, 761 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
762 SGTL5000_LINEREG_D_POWERUP, 762 SGTL5000_LINEREG_D_POWERUP,
@@ -782,7 +782,7 @@ static int ldo_regulator_disable(struct regulator_dev *dev)
782 782
783 /* clear voltage info */ 783 /* clear voltage info */
784 snd_soc_update_bits(codec, SGTL5000_CHIP_LINREG_CTRL, 784 snd_soc_update_bits(codec, SGTL5000_CHIP_LINREG_CTRL,
785 (0x1 << 4) - 1, 0); 785 SGTL5000_LINREG_VDDD_MASK, 0);
786 786
787 ldo->enabled = 0; 787 ldo->enabled = 0;
788 788
@@ -808,6 +808,7 @@ static int ldo_regulator_register(struct snd_soc_codec *codec,
808 int voltage) 808 int voltage)
809{ 809{
810 struct ldo_regulator *ldo; 810 struct ldo_regulator *ldo;
811 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
811 812
812 ldo = kzalloc(sizeof(struct ldo_regulator), GFP_KERNEL); 813 ldo = kzalloc(sizeof(struct ldo_regulator), GFP_KERNEL);
813 814
@@ -842,6 +843,7 @@ static int ldo_regulator_register(struct snd_soc_codec *codec,
842 843
843 return ret; 844 return ret;
844 } 845 }
846 sgtl5000->ldo = ldo;
845 847
846 return 0; 848 return 0;
847} 849}
@@ -1115,7 +1117,7 @@ static int sgtl5000_set_power_regs(struct snd_soc_codec *codec)
1115 1117
1116 /* set voltage to register */ 1118 /* set voltage to register */
1117 snd_soc_update_bits(codec, SGTL5000_CHIP_LINREG_CTRL, 1119 snd_soc_update_bits(codec, SGTL5000_CHIP_LINREG_CTRL,
1118 (0x1 << 4) - 1, 0x8); 1120 SGTL5000_LINREG_VDDD_MASK, 0x8);
1119 1121
1120 /* 1122 /*
1121 * if vddd linear reg has been enabled, 1123 * if vddd linear reg has been enabled,
@@ -1146,8 +1148,7 @@ static int sgtl5000_set_power_regs(struct snd_soc_codec *codec)
1146 vag = (vag - SGTL5000_ANA_GND_BASE) / SGTL5000_ANA_GND_STP; 1148 vag = (vag - SGTL5000_ANA_GND_BASE) / SGTL5000_ANA_GND_STP;
1147 1149
1148 snd_soc_update_bits(codec, SGTL5000_CHIP_REF_CTRL, 1150 snd_soc_update_bits(codec, SGTL5000_CHIP_REF_CTRL,
1149 vag << SGTL5000_ANA_GND_SHIFT, 1151 SGTL5000_ANA_GND_MASK, vag << SGTL5000_ANA_GND_SHIFT);
1150 vag << SGTL5000_ANA_GND_SHIFT);
1151 1152
1152 /* set line out VAG to vddio / 2, in range (0.8v, 1.675v) */ 1153 /* set line out VAG to vddio / 2, in range (0.8v, 1.675v) */
1153 vag = vddio / 2; 1154 vag = vddio / 2;
@@ -1161,9 +1162,8 @@ static int sgtl5000_set_power_regs(struct snd_soc_codec *codec)
1161 SGTL5000_LINE_OUT_GND_STP; 1162 SGTL5000_LINE_OUT_GND_STP;
1162 1163
1163 snd_soc_update_bits(codec, SGTL5000_CHIP_LINE_OUT_CTRL, 1164 snd_soc_update_bits(codec, SGTL5000_CHIP_LINE_OUT_CTRL,
1164 vag << SGTL5000_LINE_OUT_GND_SHIFT | 1165 SGTL5000_LINE_OUT_CURRENT_MASK |
1165 SGTL5000_LINE_OUT_CURRENT_360u << 1166 SGTL5000_LINE_OUT_GND_MASK,
1166 SGTL5000_LINE_OUT_CURRENT_SHIFT,
1167 vag << SGTL5000_LINE_OUT_GND_SHIFT | 1167 vag << SGTL5000_LINE_OUT_GND_SHIFT |
1168 SGTL5000_LINE_OUT_CURRENT_360u << 1168 SGTL5000_LINE_OUT_CURRENT_360u <<
1169 SGTL5000_LINE_OUT_CURRENT_SHIFT); 1169 SGTL5000_LINE_OUT_CURRENT_SHIFT);
@@ -1436,10 +1436,17 @@ static const struct i2c_device_id sgtl5000_id[] = {
1436 1436
1437MODULE_DEVICE_TABLE(i2c, sgtl5000_id); 1437MODULE_DEVICE_TABLE(i2c, sgtl5000_id);
1438 1438
1439static const struct of_device_id sgtl5000_dt_ids[] = {
1440 { .compatible = "fsl,sgtl5000", },
1441 { /* sentinel */ }
1442};
1443MODULE_DEVICE_TABLE(of, sgtl5000_dt_ids);
1444
1439static struct i2c_driver sgtl5000_i2c_driver = { 1445static struct i2c_driver sgtl5000_i2c_driver = {
1440 .driver = { 1446 .driver = {
1441 .name = "sgtl5000", 1447 .name = "sgtl5000",
1442 .owner = THIS_MODULE, 1448 .owner = THIS_MODULE,
1449 .of_match_table = sgtl5000_dt_ids,
1443 }, 1450 },
1444 .probe = sgtl5000_i2c_probe, 1451 .probe = sgtl5000_i2c_probe,
1445 .remove = __devexit_p(sgtl5000_i2c_remove), 1452 .remove = __devexit_p(sgtl5000_i2c_remove),
diff --git a/sound/soc/codecs/sgtl5000.h b/sound/soc/codecs/sgtl5000.h
index eec3ab368f3..8a9f43534b7 100644
--- a/sound/soc/codecs/sgtl5000.h
+++ b/sound/soc/codecs/sgtl5000.h
@@ -280,7 +280,7 @@
280/* 280/*
281 * SGTL5000_CHIP_MIC_CTRL 281 * SGTL5000_CHIP_MIC_CTRL
282 */ 282 */
283#define SGTL5000_BIAS_R_MASK 0x0200 283#define SGTL5000_BIAS_R_MASK 0x0300
284#define SGTL5000_BIAS_R_SHIFT 8 284#define SGTL5000_BIAS_R_SHIFT 8
285#define SGTL5000_BIAS_R_WIDTH 2 285#define SGTL5000_BIAS_R_WIDTH 2
286#define SGTL5000_BIAS_R_off 0x0 286#define SGTL5000_BIAS_R_off 0x0
diff --git a/sound/soc/codecs/sn95031.c b/sound/soc/codecs/sn95031.c
index 84ffdebb8a8..f681e41fc12 100644
--- a/sound/soc/codecs/sn95031.c
+++ b/sound/soc/codecs/sn95031.c
@@ -79,7 +79,7 @@ static void configure_adc(struct snd_soc_codec *sn95031_codec, int val)
79 */ 79 */
80static int find_free_channel(struct snd_soc_codec *sn95031_codec) 80static int find_free_channel(struct snd_soc_codec *sn95031_codec)
81{ 81{
82 int ret = 0, i, value; 82 int i, value;
83 83
84 /* check whether ADC is enabled */ 84 /* check whether ADC is enabled */
85 value = snd_soc_read(sn95031_codec, SN95031_ADC1CNTL1); 85 value = snd_soc_read(sn95031_codec, SN95031_ADC1CNTL1);
@@ -91,12 +91,10 @@ static int find_free_channel(struct snd_soc_codec *sn95031_codec)
91 for (i = 0; i < SN95031_ADC_CHANLS_MAX; i++) { 91 for (i = 0; i < SN95031_ADC_CHANLS_MAX; i++) {
92 value = snd_soc_read(sn95031_codec, 92 value = snd_soc_read(sn95031_codec,
93 SN95031_ADC_CHNL_START_ADDR + i); 93 SN95031_ADC_CHNL_START_ADDR + i);
94 if (value & SN95031_STOPBIT_MASK) { 94 if (value & SN95031_STOPBIT_MASK)
95 ret = i;
96 break; 95 break;
97 }
98 } 96 }
99 return (ret > SN95031_ADC_LOOP_MAX) ? (-EINVAL) : ret; 97 return (i == SN95031_ADC_CHANLS_MAX) ? (-EINVAL) : i;
100} 98}
101 99
102/* Initialize the ADC for reading micbias values. Can sleep. */ 100/* Initialize the ADC for reading micbias values. Can sleep. */
@@ -104,7 +102,7 @@ static int sn95031_initialize_adc(struct snd_soc_codec *sn95031_codec)
104{ 102{
105 int base_addr, chnl_addr; 103 int base_addr, chnl_addr;
106 int value; 104 int value;
107 static int channel_index; 105 int channel_index;
108 106
109 /* Index of the first channel in which the stop bit is set */ 107 /* Index of the first channel in which the stop bit is set */
110 channel_index = find_free_channel(sn95031_codec); 108 channel_index = find_free_channel(sn95031_codec);
@@ -163,7 +161,6 @@ static unsigned int sn95031_get_mic_bias(struct snd_soc_codec *codec)
163 pr_debug("mic bias = %dmV\n", mic_bias); 161 pr_debug("mic bias = %dmV\n", mic_bias);
164 return mic_bias; 162 return mic_bias;
165} 163}
166EXPORT_SYMBOL_GPL(sn95031_get_mic_bias);
167/*end - adc helper functions */ 164/*end - adc helper functions */
168 165
169static inline unsigned int sn95031_read(struct snd_soc_codec *codec, 166static inline unsigned int sn95031_read(struct snd_soc_codec *codec,
@@ -660,7 +657,7 @@ static int sn95031_pcm_spkr_mute(struct snd_soc_dai *dai, int mute)
660 return 0; 657 return 0;
661} 658}
662 659
663int sn95031_pcm_hw_params(struct snd_pcm_substream *substream, 660static int sn95031_pcm_hw_params(struct snd_pcm_substream *substream,
664 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) 661 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
665{ 662{
666 unsigned int format, rate; 663 unsigned int format, rate;
@@ -718,7 +715,7 @@ static struct snd_soc_dai_ops sn95031_vib2_dai_ops = {
718 .hw_params = sn95031_pcm_hw_params, 715 .hw_params = sn95031_pcm_hw_params,
719}; 716};
720 717
721struct snd_soc_dai_driver sn95031_dais[] = { 718static struct snd_soc_dai_driver sn95031_dais[] = {
722{ 719{
723 .name = "SN95031 Headset", 720 .name = "SN95031 Headset",
724 .playback = { 721 .playback = {
@@ -829,7 +826,6 @@ static int sn95031_codec_probe(struct snd_soc_codec *codec)
829{ 826{
830 pr_debug("codec_probe called\n"); 827 pr_debug("codec_probe called\n");
831 828
832 codec->dapm.bias_level = SND_SOC_BIAS_OFF;
833 codec->dapm.idle_bias_off = 1; 829 codec->dapm.idle_bias_off = 1;
834 830
835 /* PCM interface config 831 /* PCM interface config
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
index 9801cd7cfcb..3cb3271c5fe 100644
--- a/sound/soc/codecs/ssm2602.c
+++ b/sound/soc/codecs/ssm2602.c
@@ -59,6 +59,7 @@ struct ssm2602_priv {
59 struct snd_pcm_substream *slave_substream; 59 struct snd_pcm_substream *slave_substream;
60 60
61 enum ssm2602_type type; 61 enum ssm2602_type type;
62 unsigned int clk_out_pwr;
62}; 63};
63 64
64/* 65/*
@@ -294,7 +295,6 @@ static int ssm2602_startup(struct snd_pcm_substream *substream,
294 struct snd_soc_pcm_runtime *rtd = substream->private_data; 295 struct snd_soc_pcm_runtime *rtd = substream->private_data;
295 struct snd_soc_codec *codec = rtd->codec; 296 struct snd_soc_codec *codec = rtd->codec;
296 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); 297 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
297 struct i2c_client *i2c = codec->control_data;
298 struct snd_pcm_runtime *master_runtime; 298 struct snd_pcm_runtime *master_runtime;
299 299
300 /* The DAI has shared clocks so if we already have a playback or 300 /* The DAI has shared clocks so if we already have a playback or
@@ -303,7 +303,7 @@ static int ssm2602_startup(struct snd_pcm_substream *substream,
303 */ 303 */
304 if (ssm2602->master_substream) { 304 if (ssm2602->master_substream) {
305 master_runtime = ssm2602->master_substream->runtime; 305 master_runtime = ssm2602->master_substream->runtime;
306 dev_dbg(&i2c->dev, "Constraining to %d bits at %dHz\n", 306 dev_dbg(codec->dev, "Constraining to %d bits at %dHz\n",
307 master_runtime->sample_bits, 307 master_runtime->sample_bits,
308 master_runtime->rate); 308 master_runtime->rate);
309 309
@@ -343,12 +343,14 @@ static void ssm2602_shutdown(struct snd_pcm_substream *substream,
343static int ssm2602_mute(struct snd_soc_dai *dai, int mute) 343static int ssm2602_mute(struct snd_soc_dai *dai, int mute)
344{ 344{
345 struct snd_soc_codec *codec = dai->codec; 345 struct snd_soc_codec *codec = dai->codec;
346 u16 mute_reg = snd_soc_read(codec, SSM2602_APDIGI) & ~APDIGI_ENABLE_DAC_MUTE; 346
347 if (mute) 347 if (mute)
348 snd_soc_write(codec, SSM2602_APDIGI, 348 snd_soc_update_bits(codec, SSM2602_APDIGI,
349 mute_reg | APDIGI_ENABLE_DAC_MUTE); 349 APDIGI_ENABLE_DAC_MUTE,
350 APDIGI_ENABLE_DAC_MUTE);
350 else 351 else
351 snd_soc_write(codec, SSM2602_APDIGI, mute_reg); 352 snd_soc_update_bits(codec, SSM2602_APDIGI,
353 APDIGI_ENABLE_DAC_MUTE, 0);
352 return 0; 354 return 0;
353} 355}
354 356
@@ -357,16 +359,46 @@ static int ssm2602_set_dai_sysclk(struct snd_soc_dai *codec_dai,
357{ 359{
358 struct snd_soc_codec *codec = codec_dai->codec; 360 struct snd_soc_codec *codec = codec_dai->codec;
359 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); 361 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
360 switch (freq) { 362
361 case 11289600: 363 if (dir == SND_SOC_CLOCK_IN) {
362 case 12000000: 364 if (clk_id != SSM2602_SYSCLK)
363 case 12288000: 365 return -EINVAL;
364 case 16934400: 366
365 case 18432000: 367 switch (freq) {
366 ssm2602->sysclk = freq; 368 case 11289600:
367 return 0; 369 case 12000000:
370 case 12288000:
371 case 16934400:
372 case 18432000:
373 ssm2602->sysclk = freq;
374 break;
375 default:
376 return -EINVAL;
377 }
378 } else {
379 unsigned int mask;
380
381 switch (clk_id) {
382 case SSM2602_CLK_CLKOUT:
383 mask = PWR_CLK_OUT_PDN;
384 break;
385 case SSM2602_CLK_XTO:
386 mask = PWR_OSC_PDN;
387 break;
388 default:
389 return -EINVAL;
390 }
391
392 if (freq == 0)
393 ssm2602->clk_out_pwr |= mask;
394 else
395 ssm2602->clk_out_pwr &= ~mask;
396
397 snd_soc_update_bits(codec, SSM2602_PWR,
398 PWR_CLK_OUT_PDN | PWR_OSC_PDN, ssm2602->clk_out_pwr);
368 } 399 }
369 return -EINVAL; 400
401 return 0;
370} 402}
371 403
372static int ssm2602_set_dai_fmt(struct snd_soc_dai *codec_dai, 404static int ssm2602_set_dai_fmt(struct snd_soc_dai *codec_dai,
@@ -431,23 +463,27 @@ static int ssm2602_set_dai_fmt(struct snd_soc_dai *codec_dai,
431static int ssm2602_set_bias_level(struct snd_soc_codec *codec, 463static int ssm2602_set_bias_level(struct snd_soc_codec *codec,
432 enum snd_soc_bias_level level) 464 enum snd_soc_bias_level level)
433{ 465{
434 u16 reg = snd_soc_read(codec, SSM2602_PWR); 466 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
435 reg &= ~(PWR_POWER_OFF | PWR_OSC_PDN);
436 467
437 switch (level) { 468 switch (level) {
438 case SND_SOC_BIAS_ON: 469 case SND_SOC_BIAS_ON:
439 /* vref/mid, osc on, dac unmute */ 470 /* vref/mid on, osc and clkout on if enabled */
440 snd_soc_write(codec, SSM2602_PWR, reg); 471 snd_soc_update_bits(codec, SSM2602_PWR,
472 PWR_POWER_OFF | PWR_CLK_OUT_PDN | PWR_OSC_PDN,
473 ssm2602->clk_out_pwr);
441 break; 474 break;
442 case SND_SOC_BIAS_PREPARE: 475 case SND_SOC_BIAS_PREPARE:
443 break; 476 break;
444 case SND_SOC_BIAS_STANDBY: 477 case SND_SOC_BIAS_STANDBY:
445 /* everything off except vref/vmid, */ 478 /* everything off except vref/vmid, */
446 snd_soc_write(codec, SSM2602_PWR, reg | PWR_CLK_OUT_PDN); 479 snd_soc_update_bits(codec, SSM2602_PWR,
480 PWR_POWER_OFF | PWR_CLK_OUT_PDN | PWR_OSC_PDN,
481 PWR_CLK_OUT_PDN | PWR_OSC_PDN);
447 break; 482 break;
448 case SND_SOC_BIAS_OFF: 483 case SND_SOC_BIAS_OFF:
449 /* everything off, dac mute, inactive */ 484 /* everything off */
450 snd_soc_write(codec, SSM2602_PWR, 0xffff); 485 snd_soc_update_bits(codec, SSM2602_PWR,
486 PWR_POWER_OFF, PWR_POWER_OFF);
451 break; 487 break;
452 488
453 } 489 }
@@ -506,12 +542,12 @@ static int ssm2602_resume(struct snd_soc_codec *codec)
506static int ssm2602_probe(struct snd_soc_codec *codec) 542static int ssm2602_probe(struct snd_soc_codec *codec)
507{ 543{
508 struct snd_soc_dapm_context *dapm = &codec->dapm; 544 struct snd_soc_dapm_context *dapm = &codec->dapm;
509 int ret, reg; 545 int ret;
510 546
511 reg = snd_soc_read(codec, SSM2602_LOUT1V); 547 snd_soc_update_bits(codec, SSM2602_LOUT1V,
512 snd_soc_write(codec, SSM2602_LOUT1V, reg | LOUT1V_LRHP_BOTH); 548 LOUT1V_LRHP_BOTH, LOUT1V_LRHP_BOTH);
513 reg = snd_soc_read(codec, SSM2602_ROUT1V); 549 snd_soc_update_bits(codec, SSM2602_ROUT1V,
514 snd_soc_write(codec, SSM2602_ROUT1V, reg | ROUT1V_RLHP_BOTH); 550 ROUT1V_RLHP_BOTH, ROUT1V_RLHP_BOTH);
515 551
516 ret = snd_soc_add_controls(codec, ssm2602_snd_controls, 552 ret = snd_soc_add_controls(codec, ssm2602_snd_controls,
517 ARRAY_SIZE(ssm2602_snd_controls)); 553 ARRAY_SIZE(ssm2602_snd_controls));
@@ -544,7 +580,7 @@ static int ssm2604_probe(struct snd_soc_codec *codec)
544static int ssm260x_probe(struct snd_soc_codec *codec) 580static int ssm260x_probe(struct snd_soc_codec *codec)
545{ 581{
546 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); 582 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
547 int ret, reg; 583 int ret;
548 584
549 pr_info("ssm2602 Audio Codec %s", SSM2602_VERSION); 585 pr_info("ssm2602 Audio Codec %s", SSM2602_VERSION);
550 586
@@ -561,10 +597,10 @@ static int ssm260x_probe(struct snd_soc_codec *codec)
561 } 597 }
562 598
563 /* set the update bits */ 599 /* set the update bits */
564 reg = snd_soc_read(codec, SSM2602_LINVOL); 600 snd_soc_update_bits(codec, SSM2602_LINVOL,
565 snd_soc_write(codec, SSM2602_LINVOL, reg | LINVOL_LRIN_BOTH); 601 LINVOL_LRIN_BOTH, LINVOL_LRIN_BOTH);
566 reg = snd_soc_read(codec, SSM2602_RINVOL); 602 snd_soc_update_bits(codec, SSM2602_RINVOL,
567 snd_soc_write(codec, SSM2602_RINVOL, reg | RINVOL_RLIN_BOTH); 603 RINVOL_RLIN_BOTH, RINVOL_RLIN_BOTH);
568 /*select Line in as default input*/ 604 /*select Line in as default input*/
569 snd_soc_write(codec, SSM2602_APANA, APANA_SELECT_DAC | 605 snd_soc_write(codec, SSM2602_APANA, APANA_SELECT_DAC |
570 APANA_ENABLE_MIC_BOOST); 606 APANA_ENABLE_MIC_BOOST);
@@ -578,7 +614,12 @@ static int ssm260x_probe(struct snd_soc_codec *codec)
578 break; 614 break;
579 } 615 }
580 616
581 return ret; 617 if (ret)
618 return ret;
619
620 ssm2602_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
621
622 return 0;
582} 623}
583 624
584/* remove everything here */ 625/* remove everything here */
diff --git a/sound/soc/codecs/ssm2602.h b/sound/soc/codecs/ssm2602.h
index b98c6916803..fbd07d7b73c 100644
--- a/sound/soc/codecs/ssm2602.h
+++ b/sound/soc/codecs/ssm2602.h
@@ -116,6 +116,10 @@
116 116
117#define SSM2602_CACHEREGNUM 10 117#define SSM2602_CACHEREGNUM 10
118 118
119#define SSM2602_SYSCLK 0 119enum ssm2602_clk {
120 SSM2602_SYSCLK,
121 SSM2602_CLK_CLKOUT,
122 SSM2602_CLK_XTO
123};
120 124
121#endif 125#endif
diff --git a/sound/soc/codecs/sta32x.c b/sound/soc/codecs/sta32x.c
index fbd7eb9e61c..bb82408ab8e 100644
--- a/sound/soc/codecs/sta32x.c
+++ b/sound/soc/codecs/sta32x.c
@@ -524,13 +524,17 @@ static int sta32x_hw_params(struct snd_pcm_substream *substream,
524 rate = params_rate(params); 524 rate = params_rate(params);
525 pr_debug("rate: %u\n", rate); 525 pr_debug("rate: %u\n", rate);
526 for (i = 0; i < ARRAY_SIZE(interpolation_ratios); i++) 526 for (i = 0; i < ARRAY_SIZE(interpolation_ratios); i++)
527 if (interpolation_ratios[i].fs == rate) 527 if (interpolation_ratios[i].fs == rate) {
528 ir = interpolation_ratios[i].ir; 528 ir = interpolation_ratios[i].ir;
529 break;
530 }
529 if (ir < 0) 531 if (ir < 0)
530 return -EINVAL; 532 return -EINVAL;
531 for (i = 0; mclk_ratios[ir][i].ratio; i++) 533 for (i = 0; mclk_ratios[ir][i].ratio; i++)
532 if (mclk_ratios[ir][i].ratio * rate == sta32x->mclk) 534 if (mclk_ratios[ir][i].ratio * rate == sta32x->mclk) {
533 mcs = mclk_ratios[ir][i].mcs; 535 mcs = mclk_ratios[ir][i].mcs;
536 break;
537 }
534 if (mcs < 0) 538 if (mcs < 0)
535 return -EINVAL; 539 return -EINVAL;
536 540
@@ -752,25 +756,19 @@ static int sta32x_probe(struct snd_soc_codec *codec)
752 return ret; 756 return ret;
753 } 757 }
754 758
755 /* read reg reset values into cache */ 759 /* Chip documentation explicitly requires that the reset values
756 for (i = 0; i < STA32X_REGISTER_COUNT; i++) 760 * of reserved register bits are left untouched.
757 snd_soc_cache_write(codec, i, sta32x_regs[i]); 761 * Write the register default value to cache for reserved registers,
758 762 * so the write to the these registers are suppressed by the cache
759 /* preserve reset values of reserved register bits */ 763 * restore code when it skips writes of default registers.
760 snd_soc_cache_write(codec, STA32X_CONFC, 764 */
761 codec->hw_read(codec, STA32X_CONFC)); 765 snd_soc_cache_write(codec, STA32X_CONFC, 0xc2);
762 snd_soc_cache_write(codec, STA32X_CONFE, 766 snd_soc_cache_write(codec, STA32X_CONFE, 0xc2);
763 codec->hw_read(codec, STA32X_CONFE)); 767 snd_soc_cache_write(codec, STA32X_CONFF, 0x5c);
764 snd_soc_cache_write(codec, STA32X_CONFF, 768 snd_soc_cache_write(codec, STA32X_MMUTE, 0x10);
765 codec->hw_read(codec, STA32X_CONFF)); 769 snd_soc_cache_write(codec, STA32X_AUTO1, 0x60);
766 snd_soc_cache_write(codec, STA32X_MMUTE, 770 snd_soc_cache_write(codec, STA32X_AUTO3, 0x00);
767 codec->hw_read(codec, STA32X_MMUTE)); 771 snd_soc_cache_write(codec, STA32X_C3CFG, 0x40);
768 snd_soc_cache_write(codec, STA32X_AUTO1,
769 codec->hw_read(codec, STA32X_AUTO1));
770 snd_soc_cache_write(codec, STA32X_AUTO3,
771 codec->hw_read(codec, STA32X_AUTO3));
772 snd_soc_cache_write(codec, STA32X_C3CFG,
773 codec->hw_read(codec, STA32X_C3CFG));
774 772
775 /* FIXME enable thermal warning adjustment and recovery */ 773 /* FIXME enable thermal warning adjustment and recovery */
776 snd_soc_update_bits(codec, STA32X_CONFA, 774 snd_soc_update_bits(codec, STA32X_CONFA,
@@ -808,6 +806,7 @@ static int sta32x_remove(struct snd_soc_codec *codec)
808{ 806{
809 struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec); 807 struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
810 808
809 sta32x_set_bias_level(codec, SND_SOC_BIAS_OFF);
811 regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies); 810 regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
812 regulator_bulk_free(ARRAY_SIZE(sta32x->supplies), sta32x->supplies); 811 regulator_bulk_free(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
813 812
@@ -832,6 +831,7 @@ static const struct snd_soc_codec_driver sta32x_codec = {
832 .resume = sta32x_resume, 831 .resume = sta32x_resume,
833 .reg_cache_size = STA32X_REGISTER_COUNT, 832 .reg_cache_size = STA32X_REGISTER_COUNT,
834 .reg_word_size = sizeof(u8), 833 .reg_word_size = sizeof(u8),
834 .reg_cache_default = sta32x_regs,
835 .volatile_register = sta32x_reg_is_volatile, 835 .volatile_register = sta32x_reg_is_volatile,
836 .set_bias_level = sta32x_set_bias_level, 836 .set_bias_level = sta32x_set_bias_level,
837 .controls = sta32x_snd_controls, 837 .controls = sta32x_snd_controls,
@@ -867,18 +867,8 @@ static __devinit int sta32x_i2c_probe(struct i2c_client *i2c,
867static __devexit int sta32x_i2c_remove(struct i2c_client *client) 867static __devexit int sta32x_i2c_remove(struct i2c_client *client)
868{ 868{
869 struct sta32x_priv *sta32x = i2c_get_clientdata(client); 869 struct sta32x_priv *sta32x = i2c_get_clientdata(client);
870 struct snd_soc_codec *codec = sta32x->codec;
871
872 if (codec)
873 sta32x_set_bias_level(codec, SND_SOC_BIAS_OFF);
874
875 regulator_bulk_free(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
876
877 if (codec) {
878 snd_soc_unregister_codec(&client->dev);
879 snd_soc_codec_set_drvdata(codec, NULL);
880 }
881 870
871 snd_soc_unregister_codec(&client->dev);
882 kfree(sta32x); 872 kfree(sta32x);
883 return 0; 873 return 0;
884} 874}
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index 33bb52f3f68..ab27dbcd126 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -47,63 +47,6 @@ static const u16 tlv320aic23_reg[] = {
47 0x0000, 0x0000, 0x0000, 0x0000, /* 12 */ 47 0x0000, 0x0000, 0x0000, 0x0000, /* 12 */
48}; 48};
49 49
50/*
51 * read tlv320aic23 register cache
52 */
53static inline unsigned int tlv320aic23_read_reg_cache(struct snd_soc_codec
54 *codec, unsigned int reg)
55{
56 u16 *cache = codec->reg_cache;
57 if (reg >= ARRAY_SIZE(tlv320aic23_reg))
58 return -1;
59 return cache[reg];
60}
61
62/*
63 * write tlv320aic23 register cache
64 */
65static inline void tlv320aic23_write_reg_cache(struct snd_soc_codec *codec,
66 u8 reg, u16 value)
67{
68 u16 *cache = codec->reg_cache;
69 if (reg >= ARRAY_SIZE(tlv320aic23_reg))
70 return;
71 cache[reg] = value;
72}
73
74/*
75 * write to the tlv320aic23 register space
76 */
77static int tlv320aic23_write(struct snd_soc_codec *codec, unsigned int reg,
78 unsigned int value)
79{
80
81 u8 data[2];
82
83 /* TLV320AIC23 has 7 bit address and 9 bits of data
84 * so we need to switch one data bit into reg and rest
85 * of data into val
86 */
87
88 if (reg > 9 && reg != 15) {
89 printk(KERN_WARNING "%s Invalid register R%u\n", __func__, reg);
90 return -1;
91 }
92
93 data[0] = (reg << 1) | (value >> 8 & 0x01);
94 data[1] = value & 0xff;
95
96 tlv320aic23_write_reg_cache(codec, reg, value);
97
98 if (codec->hw_write(codec->control_data, data, 2) == 2)
99 return 0;
100
101 printk(KERN_ERR "%s cannot write %03x to register R%u\n", __func__,
102 value, reg);
103
104 return -EIO;
105}
106
107static const char *rec_src_text[] = { "Line", "Mic" }; 50static const char *rec_src_text[] = { "Line", "Mic" };
108static const char *deemph_text[] = {"None", "32Khz", "44.1Khz", "48Khz"}; 51static const char *deemph_text[] = {"None", "32Khz", "44.1Khz", "48Khz"};
109 52
@@ -139,8 +82,8 @@ static int snd_soc_tlv320aic23_put_volsw(struct snd_kcontrol *kcontrol,
139 */ 82 */
140 val = (val >= 4) ? 4 : (3 - val); 83 val = (val >= 4) ? 4 : (3 - val);
141 84
142 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_ANLG) & (~0x1C0); 85 reg = snd_soc_read(codec, TLV320AIC23_ANLG) & (~0x1C0);
143 tlv320aic23_write(codec, TLV320AIC23_ANLG, reg | (val << 6)); 86 snd_soc_write(codec, TLV320AIC23_ANLG, reg | (val << 6));
144 87
145 return 0; 88 return 0;
146} 89}
@@ -151,7 +94,7 @@ static int snd_soc_tlv320aic23_get_volsw(struct snd_kcontrol *kcontrol,
151 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 94 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
152 u16 val; 95 u16 val;
153 96
154 val = tlv320aic23_read_reg_cache(codec, TLV320AIC23_ANLG) & (0x1C0); 97 val = snd_soc_read(codec, TLV320AIC23_ANLG) & (0x1C0);
155 val = val >> 6; 98 val = val >> 6;
156 val = (val >= 4) ? 4 : (3 - val); 99 val = (val >= 4) ? 4 : (3 - val);
157 ucontrol->value.integer.value[0] = val; 100 ucontrol->value.integer.value[0] = val;
@@ -159,15 +102,6 @@ static int snd_soc_tlv320aic23_get_volsw(struct snd_kcontrol *kcontrol,
159 102
160} 103}
161 104
162#define SOC_TLV320AIC23_SINGLE_TLV(xname, reg, shift, max, invert, tlv_array) \
163{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
164 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
165 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
166 .tlv.p = (tlv_array), \
167 .info = snd_soc_info_volsw, .get = snd_soc_tlv320aic23_get_volsw,\
168 .put = snd_soc_tlv320aic23_put_volsw, \
169 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
170
171static const struct snd_kcontrol_new tlv320aic23_snd_controls[] = { 105static const struct snd_kcontrol_new tlv320aic23_snd_controls[] = {
172 SOC_DOUBLE_R_TLV("Digital Playback Volume", TLV320AIC23_LCHNVOL, 106 SOC_DOUBLE_R_TLV("Digital Playback Volume", TLV320AIC23_LCHNVOL,
173 TLV320AIC23_RCHNVOL, 0, 127, 0, out_gain_tlv), 107 TLV320AIC23_RCHNVOL, 0, 127, 0, out_gain_tlv),
@@ -178,8 +112,9 @@ static const struct snd_kcontrol_new tlv320aic23_snd_controls[] = {
178 TLV320AIC23_RINVOL, 0, 31, 0, input_gain_tlv), 112 TLV320AIC23_RINVOL, 0, 31, 0, input_gain_tlv),
179 SOC_SINGLE("Mic Input Switch", TLV320AIC23_ANLG, 1, 1, 1), 113 SOC_SINGLE("Mic Input Switch", TLV320AIC23_ANLG, 1, 1, 1),
180 SOC_SINGLE("Mic Booster Switch", TLV320AIC23_ANLG, 0, 1, 0), 114 SOC_SINGLE("Mic Booster Switch", TLV320AIC23_ANLG, 0, 1, 0),
181 SOC_TLV320AIC23_SINGLE_TLV("Sidetone Volume", TLV320AIC23_ANLG, 115 SOC_SINGLE_EXT_TLV("Sidetone Volume", TLV320AIC23_ANLG, 6, 4, 0,
182 6, 4, 0, sidetone_vol_tlv), 116 snd_soc_tlv320aic23_get_volsw,
117 snd_soc_tlv320aic23_put_volsw, sidetone_vol_tlv),
183 SOC_ENUM("Playback De-emphasis", tlv320aic23_deemph), 118 SOC_ENUM("Playback De-emphasis", tlv320aic23_deemph),
184}; 119};
185 120
@@ -240,7 +175,6 @@ static const struct snd_soc_dapm_route tlv320aic23_intercon[] = {
240/* AIC23 driver data */ 175/* AIC23 driver data */
241struct aic23 { 176struct aic23 {
242 enum snd_soc_control_type control_type; 177 enum snd_soc_control_type control_type;
243 void *control_data;
244 int mclk; 178 int mclk;
245 int requested_adc; 179 int requested_adc;
246 int requested_dac; 180 int requested_dac;
@@ -352,7 +286,7 @@ static int find_rate(int mclk, u32 need_adc, u32 need_dac)
352static void get_current_sample_rates(struct snd_soc_codec *codec, int mclk, 286static void get_current_sample_rates(struct snd_soc_codec *codec, int mclk,
353 u32 *sample_rate_adc, u32 *sample_rate_dac) 287 u32 *sample_rate_adc, u32 *sample_rate_dac)
354{ 288{
355 int src = tlv320aic23_read_reg_cache(codec, TLV320AIC23_SRATE); 289 int src = snd_soc_read(codec, TLV320AIC23_SRATE);
356 int sr = (src >> 2) & 0x0f; 290 int sr = (src >> 2) & 0x0f;
357 int val = (mclk / bosr_usb_divisor_table[src & 3]); 291 int val = (mclk / bosr_usb_divisor_table[src & 3]);
358 int adc = (val * sr_adc_mult_table[sr]) / SR_MULT; 292 int adc = (val * sr_adc_mult_table[sr]) / SR_MULT;
@@ -376,7 +310,7 @@ static int set_sample_rate_control(struct snd_soc_codec *codec, int mclk,
376 __func__, sample_rate_adc, sample_rate_dac); 310 __func__, sample_rate_adc, sample_rate_dac);
377 return -EINVAL; 311 return -EINVAL;
378 } 312 }
379 tlv320aic23_write(codec, TLV320AIC23_SRATE, data); 313 snd_soc_write(codec, TLV320AIC23_SRATE, data);
380#ifdef DEBUG 314#ifdef DEBUG
381 { 315 {
382 u32 adc, dac; 316 u32 adc, dac;
@@ -415,9 +349,8 @@ static int tlv320aic23_hw_params(struct snd_pcm_substream *substream,
415 if (ret < 0) 349 if (ret < 0)
416 return ret; 350 return ret;
417 351
418 iface_reg = 352 iface_reg = snd_soc_read(codec, TLV320AIC23_DIGT_FMT) & ~(0x03 << 2);
419 tlv320aic23_read_reg_cache(codec, 353
420 TLV320AIC23_DIGT_FMT) & ~(0x03 << 2);
421 switch (params_format(params)) { 354 switch (params_format(params)) {
422 case SNDRV_PCM_FORMAT_S16_LE: 355 case SNDRV_PCM_FORMAT_S16_LE:
423 break; 356 break;
@@ -431,7 +364,7 @@ static int tlv320aic23_hw_params(struct snd_pcm_substream *substream,
431 iface_reg |= (0x03 << 2); 364 iface_reg |= (0x03 << 2);
432 break; 365 break;
433 } 366 }
434 tlv320aic23_write(codec, TLV320AIC23_DIGT_FMT, iface_reg); 367 snd_soc_write(codec, TLV320AIC23_DIGT_FMT, iface_reg);
435 368
436 return 0; 369 return 0;
437} 370}
@@ -443,7 +376,7 @@ static int tlv320aic23_pcm_prepare(struct snd_pcm_substream *substream,
443 struct snd_soc_codec *codec = rtd->codec; 376 struct snd_soc_codec *codec = rtd->codec;
444 377
445 /* set active */ 378 /* set active */
446 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0001); 379 snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x0001);
447 380
448 return 0; 381 return 0;
449} 382}
@@ -458,7 +391,7 @@ static void tlv320aic23_shutdown(struct snd_pcm_substream *substream,
458 /* deactivate */ 391 /* deactivate */
459 if (!codec->active) { 392 if (!codec->active) {
460 udelay(50); 393 udelay(50);
461 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0); 394 snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x0);
462 } 395 }
463 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 396 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
464 aic23->requested_dac = 0; 397 aic23->requested_dac = 0;
@@ -471,14 +404,14 @@ static int tlv320aic23_mute(struct snd_soc_dai *dai, int mute)
471 struct snd_soc_codec *codec = dai->codec; 404 struct snd_soc_codec *codec = dai->codec;
472 u16 reg; 405 u16 reg;
473 406
474 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_DIGT); 407 reg = snd_soc_read(codec, TLV320AIC23_DIGT);
475 if (mute) 408 if (mute)
476 reg |= TLV320AIC23_DACM_MUTE; 409 reg |= TLV320AIC23_DACM_MUTE;
477 410
478 else 411 else
479 reg &= ~TLV320AIC23_DACM_MUTE; 412 reg &= ~TLV320AIC23_DACM_MUTE;
480 413
481 tlv320aic23_write(codec, TLV320AIC23_DIGT, reg); 414 snd_soc_write(codec, TLV320AIC23_DIGT, reg);
482 415
483 return 0; 416 return 0;
484} 417}
@@ -489,8 +422,7 @@ static int tlv320aic23_set_dai_fmt(struct snd_soc_dai *codec_dai,
489 struct snd_soc_codec *codec = codec_dai->codec; 422 struct snd_soc_codec *codec = codec_dai->codec;
490 u16 iface_reg; 423 u16 iface_reg;
491 424
492 iface_reg = 425 iface_reg = snd_soc_read(codec, TLV320AIC23_DIGT_FMT) & (~0x03);
493 tlv320aic23_read_reg_cache(codec, TLV320AIC23_DIGT_FMT) & (~0x03);
494 426
495 /* set master/slave audio interface */ 427 /* set master/slave audio interface */
496 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 428 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -524,7 +456,7 @@ static int tlv320aic23_set_dai_fmt(struct snd_soc_dai *codec_dai,
524 456
525 } 457 }
526 458
527 tlv320aic23_write(codec, TLV320AIC23_DIGT_FMT, iface_reg); 459 snd_soc_write(codec, TLV320AIC23_DIGT_FMT, iface_reg);
528 460
529 return 0; 461 return 0;
530} 462}
@@ -540,26 +472,26 @@ static int tlv320aic23_set_dai_sysclk(struct snd_soc_dai *codec_dai,
540static int tlv320aic23_set_bias_level(struct snd_soc_codec *codec, 472static int tlv320aic23_set_bias_level(struct snd_soc_codec *codec,
541 enum snd_soc_bias_level level) 473 enum snd_soc_bias_level level)
542{ 474{
543 u16 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_PWR) & 0xff7f; 475 u16 reg = snd_soc_read(codec, TLV320AIC23_PWR) & 0xff7f;
544 476
545 switch (level) { 477 switch (level) {
546 case SND_SOC_BIAS_ON: 478 case SND_SOC_BIAS_ON:
547 /* vref/mid, osc on, dac unmute */ 479 /* vref/mid, osc on, dac unmute */
548 reg &= ~(TLV320AIC23_DEVICE_PWR_OFF | TLV320AIC23_OSC_OFF | \ 480 reg &= ~(TLV320AIC23_DEVICE_PWR_OFF | TLV320AIC23_OSC_OFF | \
549 TLV320AIC23_DAC_OFF); 481 TLV320AIC23_DAC_OFF);
550 tlv320aic23_write(codec, TLV320AIC23_PWR, reg); 482 snd_soc_write(codec, TLV320AIC23_PWR, reg);
551 break; 483 break;
552 case SND_SOC_BIAS_PREPARE: 484 case SND_SOC_BIAS_PREPARE:
553 break; 485 break;
554 case SND_SOC_BIAS_STANDBY: 486 case SND_SOC_BIAS_STANDBY:
555 /* everything off except vref/vmid, */ 487 /* everything off except vref/vmid, */
556 tlv320aic23_write(codec, TLV320AIC23_PWR, reg | \ 488 snd_soc_write(codec, TLV320AIC23_PWR,
557 TLV320AIC23_CLK_OFF); 489 reg | TLV320AIC23_CLK_OFF);
558 break; 490 break;
559 case SND_SOC_BIAS_OFF: 491 case SND_SOC_BIAS_OFF:
560 /* everything off, dac mute, inactive */ 492 /* everything off, dac mute, inactive */
561 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0); 493 snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x0);
562 tlv320aic23_write(codec, TLV320AIC23_PWR, 0xffff); 494 snd_soc_write(codec, TLV320AIC23_PWR, 0xffff);
563 break; 495 break;
564 } 496 }
565 codec->dapm.bias_level = level; 497 codec->dapm.bias_level = level;
@@ -606,13 +538,7 @@ static int tlv320aic23_suspend(struct snd_soc_codec *codec,
606 538
607static int tlv320aic23_resume(struct snd_soc_codec *codec) 539static int tlv320aic23_resume(struct snd_soc_codec *codec)
608{ 540{
609 u16 reg; 541 snd_soc_cache_sync(codec);
610
611 /* Sync reg_cache with the hardware */
612 for (reg = 0; reg <= TLV320AIC23_ACTIVE; reg++) {
613 u16 val = tlv320aic23_read_reg_cache(codec, reg);
614 tlv320aic23_write(codec, reg, val);
615 }
616 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 542 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
617 543
618 return 0; 544 return 0;
@@ -621,46 +547,52 @@ static int tlv320aic23_resume(struct snd_soc_codec *codec)
621static int tlv320aic23_probe(struct snd_soc_codec *codec) 547static int tlv320aic23_probe(struct snd_soc_codec *codec)
622{ 548{
623 struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec); 549 struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec);
624 int reg; 550 int ret;
625 551
626 printk(KERN_INFO "AIC23 Audio Codec %s\n", AIC23_VERSION); 552 printk(KERN_INFO "AIC23 Audio Codec %s\n", AIC23_VERSION);
627 codec->control_data = aic23->control_data; 553
628 codec->hw_write = (hw_write_t)i2c_master_send; 554 ret = snd_soc_codec_set_cache_io(codec, 7, 9, aic23->control_type);
629 codec->hw_read = NULL; 555 if (ret < 0) {
556 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
557 return ret;
558 }
630 559
631 /* Reset codec */ 560 /* Reset codec */
632 tlv320aic23_write(codec, TLV320AIC23_RESET, 0); 561 snd_soc_write(codec, TLV320AIC23_RESET, 0);
562
563 /* Write the register default value to cache for reserved registers,
564 * so the write to the these registers are suppressed by the cache
565 * restore code when it skips writes of default registers.
566 */
567 snd_soc_cache_write(codec, 0x0A, 0);
568 snd_soc_cache_write(codec, 0x0B, 0);
569 snd_soc_cache_write(codec, 0x0C, 0);
570 snd_soc_cache_write(codec, 0x0D, 0);
571 snd_soc_cache_write(codec, 0x0E, 0);
633 572
634 /* power on device */ 573 /* power on device */
635 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 574 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
636 575
637 tlv320aic23_write(codec, TLV320AIC23_DIGT, TLV320AIC23_DEEMP_44K); 576 snd_soc_write(codec, TLV320AIC23_DIGT, TLV320AIC23_DEEMP_44K);
638 577
639 /* Unmute input */ 578 /* Unmute input */
640 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_LINVOL); 579 snd_soc_update_bits(codec, TLV320AIC23_LINVOL,
641 tlv320aic23_write(codec, TLV320AIC23_LINVOL, 580 TLV320AIC23_LIM_MUTED, TLV320AIC23_LRS_ENABLED);
642 (reg & (~TLV320AIC23_LIM_MUTED)) |
643 (TLV320AIC23_LRS_ENABLED));
644 581
645 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_RINVOL); 582 snd_soc_update_bits(codec, TLV320AIC23_RINVOL,
646 tlv320aic23_write(codec, TLV320AIC23_RINVOL, 583 TLV320AIC23_LIM_MUTED, TLV320AIC23_LRS_ENABLED);
647 (reg & (~TLV320AIC23_LIM_MUTED)) |
648 TLV320AIC23_LRS_ENABLED);
649 584
650 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_ANLG); 585 snd_soc_update_bits(codec, TLV320AIC23_ANLG,
651 tlv320aic23_write(codec, TLV320AIC23_ANLG, 586 TLV320AIC23_BYPASS_ON | TLV320AIC23_MICM_MUTED,
652 (reg) & (~TLV320AIC23_BYPASS_ON) & 587 0);
653 (~TLV320AIC23_MICM_MUTED));
654 588
655 /* Default output volume */ 589 /* Default output volume */
656 tlv320aic23_write(codec, TLV320AIC23_LCHNVOL, 590 snd_soc_write(codec, TLV320AIC23_LCHNVOL,
657 TLV320AIC23_DEFAULT_OUT_VOL & 591 TLV320AIC23_DEFAULT_OUT_VOL & TLV320AIC23_OUT_VOL_MASK);
658 TLV320AIC23_OUT_VOL_MASK); 592 snd_soc_write(codec, TLV320AIC23_RCHNVOL,
659 tlv320aic23_write(codec, TLV320AIC23_RCHNVOL, 593 TLV320AIC23_DEFAULT_OUT_VOL & TLV320AIC23_OUT_VOL_MASK);
660 TLV320AIC23_DEFAULT_OUT_VOL &
661 TLV320AIC23_OUT_VOL_MASK);
662 594
663 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x1); 595 snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x1);
664 596
665 snd_soc_add_controls(codec, tlv320aic23_snd_controls, 597 snd_soc_add_controls(codec, tlv320aic23_snd_controls,
666 ARRAY_SIZE(tlv320aic23_snd_controls)); 598 ARRAY_SIZE(tlv320aic23_snd_controls));
@@ -682,8 +614,6 @@ static struct snd_soc_codec_driver soc_codec_dev_tlv320aic23 = {
682 .remove = tlv320aic23_remove, 614 .remove = tlv320aic23_remove,
683 .suspend = tlv320aic23_suspend, 615 .suspend = tlv320aic23_suspend,
684 .resume = tlv320aic23_resume, 616 .resume = tlv320aic23_resume,
685 .read = tlv320aic23_read_reg_cache,
686 .write = tlv320aic23_write,
687 .set_bias_level = tlv320aic23_set_bias_level, 617 .set_bias_level = tlv320aic23_set_bias_level,
688 .dapm_widgets = tlv320aic23_dapm_widgets, 618 .dapm_widgets = tlv320aic23_dapm_widgets,
689 .num_dapm_widgets = ARRAY_SIZE(tlv320aic23_dapm_widgets), 619 .num_dapm_widgets = ARRAY_SIZE(tlv320aic23_dapm_widgets),
@@ -710,7 +640,6 @@ static int tlv320aic23_codec_probe(struct i2c_client *i2c,
710 return -ENOMEM; 640 return -ENOMEM;
711 641
712 i2c_set_clientdata(i2c, aic23); 642 i2c_set_clientdata(i2c, aic23);
713 aic23->control_data = i2c;
714 aic23->control_type = SND_SOC_I2C; 643 aic23->control_type = SND_SOC_I2C;
715 644
716 ret = snd_soc_register_codec(&i2c->dev, 645 ret = snd_soc_register_codec(&i2c->dev,
diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c
index e93b9d1ae1d..b21c610051c 100644
--- a/sound/soc/codecs/tlv320aic32x4.c
+++ b/sound/soc/codecs/tlv320aic32x4.c
@@ -528,40 +528,33 @@ static int aic32x4_set_bias_level(struct snd_soc_codec *codec,
528 enum snd_soc_bias_level level) 528 enum snd_soc_bias_level level)
529{ 529{
530 struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec); 530 struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
531 u8 value;
532 531
533 switch (level) { 532 switch (level) {
534 case SND_SOC_BIAS_ON: 533 case SND_SOC_BIAS_ON:
535 if (aic32x4->master) { 534 if (aic32x4->master) {
536 /* Switch on PLL */ 535 /* Switch on PLL */
537 value = snd_soc_read(codec, AIC32X4_PLLPR); 536 snd_soc_update_bits(codec, AIC32X4_PLLPR,
538 snd_soc_write(codec, AIC32X4_PLLPR, 537 AIC32X4_PLLEN, AIC32X4_PLLEN);
539 (value | AIC32X4_PLLEN));
540 538
541 /* Switch on NDAC Divider */ 539 /* Switch on NDAC Divider */
542 value = snd_soc_read(codec, AIC32X4_NDAC); 540 snd_soc_update_bits(codec, AIC32X4_NDAC,
543 snd_soc_write(codec, AIC32X4_NDAC, 541 AIC32X4_NDACEN, AIC32X4_NDACEN);
544 value | AIC32X4_NDACEN);
545 542
546 /* Switch on MDAC Divider */ 543 /* Switch on MDAC Divider */
547 value = snd_soc_read(codec, AIC32X4_MDAC); 544 snd_soc_update_bits(codec, AIC32X4_MDAC,
548 snd_soc_write(codec, AIC32X4_MDAC, 545 AIC32X4_MDACEN, AIC32X4_MDACEN);
549 value | AIC32X4_MDACEN);
550 546
551 /* Switch on NADC Divider */ 547 /* Switch on NADC Divider */
552 value = snd_soc_read(codec, AIC32X4_NADC); 548 snd_soc_update_bits(codec, AIC32X4_NADC,
553 snd_soc_write(codec, AIC32X4_NADC, 549 AIC32X4_NADCEN, AIC32X4_NADCEN);
554 value | AIC32X4_MDACEN);
555 550
556 /* Switch on MADC Divider */ 551 /* Switch on MADC Divider */
557 value = snd_soc_read(codec, AIC32X4_MADC); 552 snd_soc_update_bits(codec, AIC32X4_MADC,
558 snd_soc_write(codec, AIC32X4_MADC, 553 AIC32X4_MADCEN, AIC32X4_MADCEN);
559 value | AIC32X4_MDACEN);
560 554
561 /* Switch on BCLK_N Divider */ 555 /* Switch on BCLK_N Divider */
562 value = snd_soc_read(codec, AIC32X4_BCLKN); 556 snd_soc_update_bits(codec, AIC32X4_BCLKN,
563 snd_soc_write(codec, AIC32X4_BCLKN, 557 AIC32X4_BCLKEN, AIC32X4_BCLKEN);
564 value | AIC32X4_BCLKEN);
565 } 558 }
566 break; 559 break;
567 case SND_SOC_BIAS_PREPARE: 560 case SND_SOC_BIAS_PREPARE:
@@ -569,34 +562,28 @@ static int aic32x4_set_bias_level(struct snd_soc_codec *codec,
569 case SND_SOC_BIAS_STANDBY: 562 case SND_SOC_BIAS_STANDBY:
570 if (aic32x4->master) { 563 if (aic32x4->master) {
571 /* Switch off PLL */ 564 /* Switch off PLL */
572 value = snd_soc_read(codec, AIC32X4_PLLPR); 565 snd_soc_update_bits(codec, AIC32X4_PLLPR,
573 snd_soc_write(codec, AIC32X4_PLLPR, 566 AIC32X4_PLLEN, 0);
574 (value & ~AIC32X4_PLLEN));
575 567
576 /* Switch off NDAC Divider */ 568 /* Switch off NDAC Divider */
577 value = snd_soc_read(codec, AIC32X4_NDAC); 569 snd_soc_update_bits(codec, AIC32X4_NDAC,
578 snd_soc_write(codec, AIC32X4_NDAC, 570 AIC32X4_NDACEN, 0);
579 value & ~AIC32X4_NDACEN);
580 571
581 /* Switch off MDAC Divider */ 572 /* Switch off MDAC Divider */
582 value = snd_soc_read(codec, AIC32X4_MDAC); 573 snd_soc_update_bits(codec, AIC32X4_MDAC,
583 snd_soc_write(codec, AIC32X4_MDAC, 574 AIC32X4_MDACEN, 0);
584 value & ~AIC32X4_MDACEN);
585 575
586 /* Switch off NADC Divider */ 576 /* Switch off NADC Divider */
587 value = snd_soc_read(codec, AIC32X4_NADC); 577 snd_soc_update_bits(codec, AIC32X4_NADC,
588 snd_soc_write(codec, AIC32X4_NADC, 578 AIC32X4_NADCEN, 0);
589 value & ~AIC32X4_NDACEN);
590 579
591 /* Switch off MADC Divider */ 580 /* Switch off MADC Divider */
592 value = snd_soc_read(codec, AIC32X4_MADC); 581 snd_soc_update_bits(codec, AIC32X4_MADC,
593 snd_soc_write(codec, AIC32X4_MADC, 582 AIC32X4_MADCEN, 0);
594 value & ~AIC32X4_MDACEN);
595 value = snd_soc_read(codec, AIC32X4_BCLKN);
596 583
597 /* Switch off BCLK_N Divider */ 584 /* Switch off BCLK_N Divider */
598 snd_soc_write(codec, AIC32X4_BCLKN, 585 snd_soc_update_bits(codec, AIC32X4_BCLKN,
599 value & ~AIC32X4_BCLKEN); 586 AIC32X4_BCLKEN, 0);
600 } 587 }
601 break; 588 break;
602 case SND_SOC_BIAS_OFF: 589 case SND_SOC_BIAS_OFF:
@@ -685,10 +672,10 @@ static int aic32x4_probe(struct snd_soc_codec *codec)
685 } 672 }
686 673
687 /* Mic PGA routing */ 674 /* Mic PGA routing */
688 if (aic32x4->micpga_routing | AIC32X4_MICPGA_ROUTE_LMIC_IN2R_10K) { 675 if (aic32x4->micpga_routing & AIC32X4_MICPGA_ROUTE_LMIC_IN2R_10K) {
689 snd_soc_write(codec, AIC32X4_LMICPGANIN, AIC32X4_LMICPGANIN_IN2R_10K); 676 snd_soc_write(codec, AIC32X4_LMICPGANIN, AIC32X4_LMICPGANIN_IN2R_10K);
690 } 677 }
691 if (aic32x4->micpga_routing | AIC32X4_MICPGA_ROUTE_RMIC_IN1L_10K) { 678 if (aic32x4->micpga_routing & AIC32X4_MICPGA_ROUTE_RMIC_IN1L_10K) {
692 snd_soc_write(codec, AIC32X4_RMICPGANIN, AIC32X4_RMICPGANIN_IN1L_10K); 679 snd_soc_write(codec, AIC32X4_RMICPGANIN, AIC32X4_RMICPGANIN_IN1L_10K);
693 } 680 }
694 681
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 0963c4c7a83..7a49390bc30 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -76,7 +76,6 @@ struct aic3x_priv {
76 struct aic3x_disable_nb disable_nb[AIC3X_NUM_SUPPLIES]; 76 struct aic3x_disable_nb disable_nb[AIC3X_NUM_SUPPLIES];
77 enum snd_soc_control_type control_type; 77 enum snd_soc_control_type control_type;
78 struct aic3x_setup_data *setup; 78 struct aic3x_setup_data *setup;
79 void *control_data;
80 unsigned int sysclk; 79 unsigned int sysclk;
81 struct list_head list; 80 struct list_head list;
82 int master; 81 int master;
@@ -138,7 +137,10 @@ static int aic3x_read(struct snd_soc_codec *codec, unsigned int reg,
138 if (reg >= AIC3X_CACHEREGNUM) 137 if (reg >= AIC3X_CACHEREGNUM)
139 return -1; 138 return -1;
140 139
141 *value = codec->hw_read(codec, reg); 140 codec->cache_bypass = 1;
141 *value = snd_soc_read(codec, reg);
142 codec->cache_bypass = 0;
143
142 cache[reg] = *value; 144 cache[reg] = *value;
143 145
144 return 0; 146 return 0;
@@ -198,6 +200,10 @@ static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol,
198 else 200 else
199 /* old connection must be powered down */ 201 /* old connection must be powered down */
200 path->connect = invert ? 1 : 0; 202 path->connect = invert ? 1 : 0;
203
204 dapm_mark_dirty(path->source, "tlv320aic3x source");
205 dapm_mark_dirty(path->sink, "tlv320aic3x sink");
206
201 break; 207 break;
202 } 208 }
203 209
@@ -1383,7 +1389,6 @@ static int aic3x_probe(struct snd_soc_codec *codec)
1383 int ret, i; 1389 int ret, i;
1384 1390
1385 INIT_LIST_HEAD(&aic3x->list); 1391 INIT_LIST_HEAD(&aic3x->list);
1386 codec->control_data = aic3x->control_data;
1387 aic3x->codec = codec; 1392 aic3x->codec = codec;
1388 codec->dapm.idle_bias_off = 1; 1393 codec->dapm.idle_bias_off = 1;
1389 1394
@@ -1495,9 +1500,9 @@ static struct snd_soc_codec_driver soc_codec_dev_aic3x = {
1495 */ 1500 */
1496 1501
1497static const struct i2c_device_id aic3x_i2c_id[] = { 1502static const struct i2c_device_id aic3x_i2c_id[] = {
1498 [AIC3X_MODEL_3X] = { "tlv320aic3x", 0 }, 1503 { "tlv320aic3x", AIC3X_MODEL_3X },
1499 [AIC3X_MODEL_33] = { "tlv320aic33", 0 }, 1504 { "tlv320aic33", AIC3X_MODEL_33 },
1500 [AIC3X_MODEL_3007] = { "tlv320aic3007", 0 }, 1505 { "tlv320aic3007", AIC3X_MODEL_3007 },
1501 { } 1506 { }
1502}; 1507};
1503MODULE_DEVICE_TABLE(i2c, aic3x_i2c_id); 1508MODULE_DEVICE_TABLE(i2c, aic3x_i2c_id);
@@ -1512,7 +1517,6 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
1512 struct aic3x_pdata *pdata = i2c->dev.platform_data; 1517 struct aic3x_pdata *pdata = i2c->dev.platform_data;
1513 struct aic3x_priv *aic3x; 1518 struct aic3x_priv *aic3x;
1514 int ret; 1519 int ret;
1515 const struct i2c_device_id *tbl;
1516 1520
1517 aic3x = kzalloc(sizeof(struct aic3x_priv), GFP_KERNEL); 1521 aic3x = kzalloc(sizeof(struct aic3x_priv), GFP_KERNEL);
1518 if (aic3x == NULL) { 1522 if (aic3x == NULL) {
@@ -1520,7 +1524,6 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
1520 return -ENOMEM; 1524 return -ENOMEM;
1521 } 1525 }
1522 1526
1523 aic3x->control_data = i2c;
1524 aic3x->control_type = SND_SOC_I2C; 1527 aic3x->control_type = SND_SOC_I2C;
1525 1528
1526 i2c_set_clientdata(i2c, aic3x); 1529 i2c_set_clientdata(i2c, aic3x);
@@ -1531,11 +1534,7 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
1531 aic3x->gpio_reset = -1; 1534 aic3x->gpio_reset = -1;
1532 } 1535 }
1533 1536
1534 for (tbl = aic3x_i2c_id; tbl->name[0]; tbl++) { 1537 aic3x->model = id->driver_data;
1535 if (!strcmp(tbl->name, id->name))
1536 break;
1537 }
1538 aic3x->model = tbl - aic3x_i2c_id;
1539 1538
1540 ret = snd_soc_register_codec(&i2c->dev, 1539 ret = snd_soc_register_codec(&i2c->dev,
1541 &soc_codec_dev_aic3x, &aic3x_dai, 1); 1540 &soc_codec_dev_aic3x, &aic3x_dai, 1);
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index faa5e9fb147..dc8a2b2bdc1 100644
--- a/sound/soc/codecs/tlv320dac33.c
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -55,13 +55,13 @@
55#define BURST_BASEFREQ_HZ 49152000 55#define BURST_BASEFREQ_HZ 49152000
56 56
57#define SAMPLES_TO_US(rate, samples) \ 57#define SAMPLES_TO_US(rate, samples) \
58 (1000000000 / ((rate * 1000) / samples)) 58 (1000000000 / (((rate) * 1000) / (samples)))
59 59
60#define US_TO_SAMPLES(rate, us) \ 60#define US_TO_SAMPLES(rate, us) \
61 (rate / (1000000 / (us < 1000000 ? us : 1000000))) 61 ((rate) / (1000000 / ((us) < 1000000 ? (us) : 1000000)))
62 62
63#define UTHR_FROM_PERIOD_SIZE(samples, playrate, burstrate) \ 63#define UTHR_FROM_PERIOD_SIZE(samples, playrate, burstrate) \
64 ((samples * 5000) / ((burstrate * 5000) / (burstrate - playrate))) 64 (((samples)*5000) / (((burstrate)*5000) / ((burstrate) - (playrate))))
65 65
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);
@@ -627,18 +627,6 @@ static const struct snd_soc_dapm_route audio_map[] = {
627 {"RIGHT_LO", NULL, "Codec Power"}, 627 {"RIGHT_LO", NULL, "Codec Power"},
628}; 628};
629 629
630static int dac33_add_widgets(struct snd_soc_codec *codec)
631{
632 struct snd_soc_dapm_context *dapm = &codec->dapm;
633
634 snd_soc_dapm_new_controls(dapm, dac33_dapm_widgets,
635 ARRAY_SIZE(dac33_dapm_widgets));
636 /* set up audio path interconnects */
637 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
638
639 return 0;
640}
641
642static int dac33_set_bias_level(struct snd_soc_codec *codec, 630static int dac33_set_bias_level(struct snd_soc_codec *codec,
643 enum snd_soc_bias_level level) 631 enum snd_soc_bias_level level)
644{ 632{
@@ -1431,7 +1419,7 @@ static int dac33_soc_probe(struct snd_soc_codec *codec)
1431 /* Check if the IRQ number is valid and request it */ 1419 /* Check if the IRQ number is valid and request it */
1432 if (dac33->irq >= 0) { 1420 if (dac33->irq >= 0) {
1433 ret = request_irq(dac33->irq, dac33_interrupt_handler, 1421 ret = request_irq(dac33->irq, dac33_interrupt_handler,
1434 IRQF_TRIGGER_RISING | IRQF_DISABLED, 1422 IRQF_TRIGGER_RISING,
1435 codec->name, codec); 1423 codec->name, codec);
1436 if (ret < 0) { 1424 if (ret < 0) {
1437 dev_err(codec->dev, "Could not request IRQ%d (%d)\n", 1425 dev_err(codec->dev, "Could not request IRQ%d (%d)\n",
@@ -1451,15 +1439,11 @@ static int dac33_soc_probe(struct snd_soc_codec *codec)
1451 } 1439 }
1452 } 1440 }
1453 1441
1454 snd_soc_add_controls(codec, dac33_snd_controls,
1455 ARRAY_SIZE(dac33_snd_controls));
1456 /* Only add the FIFO controls, if we have valid IRQ number */ 1442 /* Only add the FIFO controls, if we have valid IRQ number */
1457 if (dac33->irq >= 0) 1443 if (dac33->irq >= 0)
1458 snd_soc_add_controls(codec, dac33_mode_snd_controls, 1444 snd_soc_add_controls(codec, dac33_mode_snd_controls,
1459 ARRAY_SIZE(dac33_mode_snd_controls)); 1445 ARRAY_SIZE(dac33_mode_snd_controls));
1460 1446
1461 dac33_add_widgets(codec);
1462
1463err_power: 1447err_power:
1464 return ret; 1448 return ret;
1465} 1449}
@@ -1502,6 +1486,13 @@ static struct snd_soc_codec_driver soc_codec_dev_tlv320dac33 = {
1502 .remove = dac33_soc_remove, 1486 .remove = dac33_soc_remove,
1503 .suspend = dac33_soc_suspend, 1487 .suspend = dac33_soc_suspend,
1504 .resume = dac33_soc_resume, 1488 .resume = dac33_soc_resume,
1489
1490 .controls = dac33_snd_controls,
1491 .num_controls = ARRAY_SIZE(dac33_snd_controls),
1492 .dapm_widgets = dac33_dapm_widgets,
1493 .num_dapm_widgets = ARRAY_SIZE(dac33_dapm_widgets),
1494 .dapm_routes = audio_map,
1495 .num_dapm_routes = ARRAY_SIZE(audio_map),
1505}; 1496};
1506 1497
1507#define DAC33_RATES (SNDRV_PCM_RATE_44100 | \ 1498#define DAC33_RATES (SNDRV_PCM_RATE_44100 | \
diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
index 239e0c46106..7eeca79d738 100644
--- a/sound/soc/codecs/tpa6130a2.c
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -33,6 +33,11 @@
33 33
34#include "tpa6130a2.h" 34#include "tpa6130a2.h"
35 35
36enum tpa_model {
37 TPA6130A2,
38 TPA6140A2,
39};
40
36static struct i2c_client *tpa6130a2_client; 41static struct i2c_client *tpa6130a2_client;
37 42
38/* This struct is used to save the context */ 43/* This struct is used to save the context */
@@ -383,7 +388,7 @@ static int __devinit tpa6130a2_probe(struct i2c_client *client,
383 388
384 pdata = client->dev.platform_data; 389 pdata = client->dev.platform_data;
385 data->power_gpio = pdata->power_gpio; 390 data->power_gpio = pdata->power_gpio;
386 data->id = pdata->id; 391 data->id = id->driver_data;
387 392
388 mutex_init(&data->mutex); 393 mutex_init(&data->mutex);
389 394
@@ -405,7 +410,7 @@ static int __devinit tpa6130a2_probe(struct i2c_client *client,
405 switch (data->id) { 410 switch (data->id) {
406 default: 411 default:
407 dev_warn(dev, "Unknown TPA model (%d). Assuming 6130A2\n", 412 dev_warn(dev, "Unknown TPA model (%d). Assuming 6130A2\n",
408 pdata->id); 413 data->id);
409 case TPA6130A2: 414 case TPA6130A2:
410 regulator = "Vdd"; 415 regulator = "Vdd";
411 break; 416 break;
@@ -446,7 +451,6 @@ err_regulator:
446 gpio_free(data->power_gpio); 451 gpio_free(data->power_gpio);
447err_gpio: 452err_gpio:
448 kfree(data); 453 kfree(data);
449 i2c_set_clientdata(tpa6130a2_client, NULL);
450 tpa6130a2_client = NULL; 454 tpa6130a2_client = NULL;
451 455
452 return ret; 456 return ret;
@@ -470,7 +474,8 @@ static int __devexit tpa6130a2_remove(struct i2c_client *client)
470} 474}
471 475
472static const struct i2c_device_id tpa6130a2_id[] = { 476static const struct i2c_device_id tpa6130a2_id[] = {
473 { "tpa6130a2", 0 }, 477 { "tpa6130a2", TPA6130A2 },
478 { "tpa6140a2", TPA6140A2 },
474 { } 479 { }
475}; 480};
476MODULE_DEVICE_TABLE(i2c, tpa6130a2_id); 481MODULE_DEVICE_TABLE(i2c, tpa6130a2_id);
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index 71674bec960..f798247ac1b 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -863,34 +863,6 @@ static int digimic_event(struct snd_soc_dapm_widget *w,
863 * Inverting not going to help with these. 863 * Inverting not going to help with these.
864 * Custom volsw and volsw_2r get/put functions to handle these gain bits. 864 * Custom volsw and volsw_2r get/put functions to handle these gain bits.
865 */ 865 */
866#define SOC_DOUBLE_TLV_TWL4030(xname, xreg, shift_left, shift_right, xmax,\
867 xinvert, tlv_array) \
868{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
869 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
870 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
871 .tlv.p = (tlv_array), \
872 .info = snd_soc_info_volsw, \
873 .get = snd_soc_get_volsw_twl4030, \
874 .put = snd_soc_put_volsw_twl4030, \
875 .private_value = (unsigned long)&(struct soc_mixer_control) \
876 {.reg = xreg, .shift = shift_left, .rshift = shift_right,\
877 .max = xmax, .invert = xinvert} }
878#define SOC_DOUBLE_R_TLV_TWL4030(xname, reg_left, reg_right, xshift, xmax,\
879 xinvert, tlv_array) \
880{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
881 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
882 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
883 .tlv.p = (tlv_array), \
884 .info = snd_soc_info_volsw_2r, \
885 .get = snd_soc_get_volsw_r2_twl4030,\
886 .put = snd_soc_put_volsw_r2_twl4030, \
887 .private_value = (unsigned long)&(struct soc_mixer_control) \
888 {.reg = reg_left, .rreg = reg_right, .shift = xshift, \
889 .rshift = xshift, .max = xmax, .invert = xinvert} }
890#define SOC_SINGLE_TLV_TWL4030(xname, xreg, xshift, xmax, xinvert, tlv_array) \
891 SOC_DOUBLE_TLV_TWL4030(xname, xreg, xshift, xshift, xmax, \
892 xinvert, tlv_array)
893
894static int snd_soc_get_volsw_twl4030(struct snd_kcontrol *kcontrol, 866static int snd_soc_get_volsw_twl4030(struct snd_kcontrol *kcontrol,
895 struct snd_ctl_elem_value *ucontrol) 867 struct snd_ctl_elem_value *ucontrol)
896{ 868{
@@ -1197,19 +1169,23 @@ static const struct snd_kcontrol_new twl4030_snd_controls[] = {
1197 TWL4030_REG_VDL_APGA_CTL, 1, 1, 0), 1169 TWL4030_REG_VDL_APGA_CTL, 1, 1, 0),
1198 1170
1199 /* Separate output gain controls */ 1171 /* Separate output gain controls */
1200 SOC_DOUBLE_R_TLV_TWL4030("PreDriv Playback Volume", 1172 SOC_DOUBLE_R_EXT_TLV("PreDriv Playback Volume",
1201 TWL4030_REG_PREDL_CTL, TWL4030_REG_PREDR_CTL, 1173 TWL4030_REG_PREDL_CTL, TWL4030_REG_PREDR_CTL,
1202 4, 3, 0, output_tvl), 1174 4, 3, 0, snd_soc_get_volsw_r2_twl4030,
1175 snd_soc_put_volsw_r2_twl4030, output_tvl),
1203 1176
1204 SOC_DOUBLE_TLV_TWL4030("Headset Playback Volume", 1177 SOC_DOUBLE_EXT_TLV("Headset Playback Volume",
1205 TWL4030_REG_HS_GAIN_SET, 0, 2, 3, 0, output_tvl), 1178 TWL4030_REG_HS_GAIN_SET, 0, 2, 3, 0, snd_soc_get_volsw_twl4030,
1179 snd_soc_put_volsw_twl4030, output_tvl),
1206 1180
1207 SOC_DOUBLE_R_TLV_TWL4030("Carkit Playback Volume", 1181 SOC_DOUBLE_R_EXT_TLV("Carkit Playback Volume",
1208 TWL4030_REG_PRECKL_CTL, TWL4030_REG_PRECKR_CTL, 1182 TWL4030_REG_PRECKL_CTL, TWL4030_REG_PRECKR_CTL,
1209 4, 3, 0, output_tvl), 1183 4, 3, 0, snd_soc_get_volsw_r2_twl4030,
1184 snd_soc_put_volsw_r2_twl4030, output_tvl),
1210 1185
1211 SOC_SINGLE_TLV_TWL4030("Earpiece Playback Volume", 1186 SOC_SINGLE_EXT_TLV("Earpiece Playback Volume",
1212 TWL4030_REG_EAR_CTL, 4, 3, 0, output_ear_tvl), 1187 TWL4030_REG_EAR_CTL, 4, 3, 0, snd_soc_get_volsw_twl4030,
1188 snd_soc_put_volsw_twl4030, output_ear_tvl),
1213 1189
1214 /* Common capture gain controls */ 1190 /* Common capture gain controls */
1215 SOC_DOUBLE_R_TLV("TX1 Digital Capture Volume", 1191 SOC_DOUBLE_R_TLV("TX1 Digital Capture Volume",
@@ -1633,17 +1609,6 @@ static const struct snd_soc_dapm_route intercon[] = {
1633 1609
1634}; 1610};
1635 1611
1636static int twl4030_add_widgets(struct snd_soc_codec *codec)
1637{
1638 struct snd_soc_dapm_context *dapm = &codec->dapm;
1639
1640 snd_soc_dapm_new_controls(dapm, twl4030_dapm_widgets,
1641 ARRAY_SIZE(twl4030_dapm_widgets));
1642 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
1643
1644 return 0;
1645}
1646
1647static int twl4030_set_bias_level(struct snd_soc_codec *codec, 1612static int twl4030_set_bias_level(struct snd_soc_codec *codec,
1648 enum snd_soc_bias_level level) 1613 enum snd_soc_bias_level level)
1649{ 1614{
@@ -2265,9 +2230,6 @@ static int twl4030_soc_probe(struct snd_soc_codec *codec)
2265 2230
2266 twl4030_init_chip(codec); 2231 twl4030_init_chip(codec);
2267 2232
2268 snd_soc_add_controls(codec, twl4030_snd_controls,
2269 ARRAY_SIZE(twl4030_snd_controls));
2270 twl4030_add_widgets(codec);
2271 return 0; 2233 return 0;
2272} 2234}
2273 2235
@@ -2293,6 +2255,13 @@ static struct snd_soc_codec_driver soc_codec_dev_twl4030 = {
2293 .reg_cache_size = sizeof(twl4030_reg), 2255 .reg_cache_size = sizeof(twl4030_reg),
2294 .reg_word_size = sizeof(u8), 2256 .reg_word_size = sizeof(u8),
2295 .reg_cache_default = twl4030_reg, 2257 .reg_cache_default = twl4030_reg,
2258
2259 .controls = twl4030_snd_controls,
2260 .num_controls = ARRAY_SIZE(twl4030_snd_controls),
2261 .dapm_widgets = twl4030_dapm_widgets,
2262 .num_dapm_widgets = ARRAY_SIZE(twl4030_dapm_widgets),
2263 .dapm_routes = intercon,
2264 .num_dapm_routes = ARRAY_SIZE(intercon),
2296}; 2265};
2297 2266
2298static int __devinit twl4030_codec_probe(struct platform_device *pdev) 2267static int __devinit twl4030_codec_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index 443032b3b32..73e11f022de 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -57,6 +57,13 @@
57#define TWL6040_HF_VOL_MASK 0x1F 57#define TWL6040_HF_VOL_MASK 0x1F
58#define TWL6040_HF_VOL_SHIFT 0 58#define TWL6040_HF_VOL_SHIFT 0
59 59
60/* Shadow register used by the driver */
61#define TWL6040_REG_SW_SHADOW 0x2F
62#define TWL6040_CACHEREGNUM (TWL6040_REG_SW_SHADOW + 1)
63
64/* TWL6040_REG_SW_SHADOW (0x2F) fields */
65#define TWL6040_EAR_PATH_ENABLE 0x01
66
60struct twl6040_output { 67struct twl6040_output {
61 u16 active; 68 u16 active;
62 u16 left_vol; 69 u16 left_vol;
@@ -65,12 +72,13 @@ struct twl6040_output {
65 u16 right_step; 72 u16 right_step;
66 unsigned int step_delay; 73 unsigned int step_delay;
67 u16 ramp; 74 u16 ramp;
68 u16 mute; 75 struct delayed_work work;
69 struct completion ramp_done; 76 struct completion ramp_done;
70}; 77};
71 78
72struct twl6040_jack_data { 79struct twl6040_jack_data {
73 struct snd_soc_jack *jack; 80 struct snd_soc_jack *jack;
81 struct delayed_work work;
74 int report; 82 int report;
75}; 83};
76 84
@@ -79,7 +87,6 @@ struct twl6040_data {
79 int plug_irq; 87 int plug_irq;
80 int codec_powered; 88 int codec_powered;
81 int pll; 89 int pll;
82 int non_lp;
83 int pll_power_mode; 90 int pll_power_mode;
84 int hs_power_mode; 91 int hs_power_mode;
85 int hs_power_mode_locked; 92 int hs_power_mode_locked;
@@ -92,104 +99,68 @@ struct twl6040_data {
92 struct twl6040_jack_data hs_jack; 99 struct twl6040_jack_data hs_jack;
93 struct snd_soc_codec *codec; 100 struct snd_soc_codec *codec;
94 struct workqueue_struct *workqueue; 101 struct workqueue_struct *workqueue;
95 struct delayed_work delayed_work;
96 struct mutex mutex; 102 struct mutex mutex;
97 struct twl6040_output headset; 103 struct twl6040_output headset;
98 struct twl6040_output handsfree; 104 struct twl6040_output handsfree;
99 struct workqueue_struct *hf_workqueue;
100 struct workqueue_struct *hs_workqueue;
101 struct delayed_work hs_delayed_work;
102 struct delayed_work hf_delayed_work;
103}; 105};
104 106
105/* 107/*
106 * twl6040 register cache & default register settings 108 * twl6040 register cache & default register settings
107 */ 109 */
108static const u8 twl6040_reg[TWL6040_CACHEREGNUM] = { 110static const u8 twl6040_reg[TWL6040_CACHEREGNUM] = {
109 0x00, /* not used 0x00 */ 111 0x00, /* not used 0x00 */
110 0x4B, /* TWL6040_ASICID (ro) 0x01 */ 112 0x4B, /* REG_ASICID 0x01 (ro) */
111 0x00, /* TWL6040_ASICREV (ro) 0x02 */ 113 0x00, /* REG_ASICREV 0x02 (ro) */
112 0x00, /* TWL6040_INTID 0x03 */ 114 0x00, /* REG_INTID 0x03 */
113 0x00, /* TWL6040_INTMR 0x04 */ 115 0x00, /* REG_INTMR 0x04 */
114 0x00, /* TWL6040_NCPCTRL 0x05 */ 116 0x00, /* REG_NCPCTRL 0x05 */
115 0x00, /* TWL6040_LDOCTL 0x06 */ 117 0x00, /* REG_LDOCTL 0x06 */
116 0x60, /* TWL6040_HPPLLCTL 0x07 */ 118 0x60, /* REG_HPPLLCTL 0x07 */
117 0x00, /* TWL6040_LPPLLCTL 0x08 */ 119 0x00, /* REG_LPPLLCTL 0x08 */
118 0x4A, /* TWL6040_LPPLLDIV 0x09 */ 120 0x4A, /* REG_LPPLLDIV 0x09 */
119 0x00, /* TWL6040_AMICBCTL 0x0A */ 121 0x00, /* REG_AMICBCTL 0x0A */
120 0x00, /* TWL6040_DMICBCTL 0x0B */ 122 0x00, /* REG_DMICBCTL 0x0B */
121 0x18, /* TWL6040_MICLCTL 0x0C - No input selected on Left Mic */ 123 0x00, /* REG_MICLCTL 0x0C */
122 0x18, /* TWL6040_MICRCTL 0x0D - No input selected on Right Mic */ 124 0x00, /* REG_MICRCTL 0x0D */
123 0x00, /* TWL6040_MICGAIN 0x0E */ 125 0x00, /* REG_MICGAIN 0x0E */
124 0x1B, /* TWL6040_LINEGAIN 0x0F */ 126 0x1B, /* REG_LINEGAIN 0x0F */
125 0x00, /* TWL6040_HSLCTL 0x10 */ 127 0x00, /* REG_HSLCTL 0x10 */
126 0x00, /* TWL6040_HSRCTL 0x11 */ 128 0x00, /* REG_HSRCTL 0x11 */
127 0x00, /* TWL6040_HSGAIN 0x12 */ 129 0x00, /* REG_HSGAIN 0x12 */
128 0x00, /* TWL6040_EARCTL 0x13 */ 130 0x00, /* REG_EARCTL 0x13 */
129 0x00, /* TWL6040_HFLCTL 0x14 */ 131 0x00, /* REG_HFLCTL 0x14 */
130 0x00, /* TWL6040_HFLGAIN 0x15 */ 132 0x00, /* REG_HFLGAIN 0x15 */
131 0x00, /* TWL6040_HFRCTL 0x16 */ 133 0x00, /* REG_HFRCTL 0x16 */
132 0x00, /* TWL6040_HFRGAIN 0x17 */ 134 0x00, /* REG_HFRGAIN 0x17 */
133 0x00, /* TWL6040_VIBCTLL 0x18 */ 135 0x00, /* REG_VIBCTLL 0x18 */
134 0x00, /* TWL6040_VIBDATL 0x19 */ 136 0x00, /* REG_VIBDATL 0x19 */
135 0x00, /* TWL6040_VIBCTLR 0x1A */ 137 0x00, /* REG_VIBCTLR 0x1A */
136 0x00, /* TWL6040_VIBDATR 0x1B */ 138 0x00, /* REG_VIBDATR 0x1B */
137 0x00, /* TWL6040_HKCTL1 0x1C */ 139 0x00, /* REG_HKCTL1 0x1C */
138 0x00, /* TWL6040_HKCTL2 0x1D */ 140 0x00, /* REG_HKCTL2 0x1D */
139 0x00, /* TWL6040_GPOCTL 0x1E */ 141 0x00, /* REG_GPOCTL 0x1E */
140 0x00, /* TWL6040_ALB 0x1F */ 142 0x00, /* REG_ALB 0x1F */
141 0x00, /* TWL6040_DLB 0x20 */ 143 0x00, /* REG_DLB 0x20 */
142 0x00, /* not used 0x21 */ 144 0x00, /* not used 0x21 */
143 0x00, /* not used 0x22 */ 145 0x00, /* not used 0x22 */
144 0x00, /* not used 0x23 */ 146 0x00, /* not used 0x23 */
145 0x00, /* not used 0x24 */ 147 0x00, /* not used 0x24 */
146 0x00, /* not used 0x25 */ 148 0x00, /* not used 0x25 */
147 0x00, /* not used 0x26 */ 149 0x00, /* not used 0x26 */
148 0x00, /* not used 0x27 */ 150 0x00, /* not used 0x27 */
149 0x00, /* TWL6040_TRIM1 0x28 */ 151 0x00, /* REG_TRIM1 0x28 */
150 0x00, /* TWL6040_TRIM2 0x29 */ 152 0x00, /* REG_TRIM2 0x29 */
151 0x00, /* TWL6040_TRIM3 0x2A */ 153 0x00, /* REG_TRIM3 0x2A */
152 0x00, /* TWL6040_HSOTRIM 0x2B */ 154 0x00, /* REG_HSOTRIM 0x2B */
153 0x00, /* TWL6040_HFOTRIM 0x2C */ 155 0x00, /* REG_HFOTRIM 0x2C */
154 0x09, /* TWL6040_ACCCTL 0x2D */ 156 0x09, /* REG_ACCCTL 0x2D */
155 0x00, /* TWL6040_STATUS (ro) 0x2E */ 157 0x00, /* REG_STATUS 0x2E (ro) */
156}; 158
157 159 0x00, /* REG_SW_SHADOW 0x2F - Shadow, non HW register */
158/*
159 * twl6040 vio/gnd registers:
160 * registers under vio/gnd supply can be accessed
161 * before the power-up sequence, after NRESPWRON goes high
162 */
163static const int twl6040_vio_reg[TWL6040_VIOREGNUM] = {
164 TWL6040_REG_ASICID,
165 TWL6040_REG_ASICREV,
166 TWL6040_REG_INTID,
167 TWL6040_REG_INTMR,
168 TWL6040_REG_NCPCTL,
169 TWL6040_REG_LDOCTL,
170 TWL6040_REG_AMICBCTL,
171 TWL6040_REG_DMICBCTL,
172 TWL6040_REG_HKCTL1,
173 TWL6040_REG_HKCTL2,
174 TWL6040_REG_GPOCTL,
175 TWL6040_REG_TRIM1,
176 TWL6040_REG_TRIM2,
177 TWL6040_REG_TRIM3,
178 TWL6040_REG_HSOTRIM,
179 TWL6040_REG_HFOTRIM,
180 TWL6040_REG_ACCCTL,
181 TWL6040_REG_STATUS,
182}; 160};
183 161
184/* 162/* List of registers to be restored after power up */
185 * twl6040 vdd/vss registers: 163static const int twl6040_restore_list[] = {
186 * registers under vdd/vss supplies can only be accessed
187 * after the power-up sequence
188 */
189static const int twl6040_vdd_reg[TWL6040_VDDREGNUM] = {
190 TWL6040_REG_HPPLLCTL,
191 TWL6040_REG_LPPLLCTL,
192 TWL6040_REG_LPPLLDIV,
193 TWL6040_REG_MICLCTL, 164 TWL6040_REG_MICLCTL,
194 TWL6040_REG_MICRCTL, 165 TWL6040_REG_MICRCTL,
195 TWL6040_REG_MICGAIN, 166 TWL6040_REG_MICGAIN,
@@ -202,12 +173,6 @@ static const int twl6040_vdd_reg[TWL6040_VDDREGNUM] = {
202 TWL6040_REG_HFLGAIN, 173 TWL6040_REG_HFLGAIN,
203 TWL6040_REG_HFRCTL, 174 TWL6040_REG_HFRCTL,
204 TWL6040_REG_HFRGAIN, 175 TWL6040_REG_HFRGAIN,
205 TWL6040_REG_VIBCTLL,
206 TWL6040_REG_VIBDATL,
207 TWL6040_REG_VIBCTLR,
208 TWL6040_REG_VIBDATR,
209 TWL6040_REG_ALB,
210 TWL6040_REG_DLB,
211}; 176};
212 177
213/* set of rates for each pll: low-power and high-performance */ 178/* set of rates for each pll: low-power and high-performance */
@@ -275,8 +240,12 @@ static int twl6040_read_reg_volatile(struct snd_soc_codec *codec,
275 if (reg >= TWL6040_CACHEREGNUM) 240 if (reg >= TWL6040_CACHEREGNUM)
276 return -EIO; 241 return -EIO;
277 242
278 value = twl6040_reg_read(twl6040, reg); 243 if (likely(reg < TWL6040_REG_SW_SHADOW)) {
279 twl6040_write_reg_cache(codec, reg, value); 244 value = twl6040_reg_read(twl6040, reg);
245 twl6040_write_reg_cache(codec, reg, value);
246 } else {
247 value = twl6040_read_reg_cache(codec, reg);
248 }
280 249
281 return value; 250 return value;
282} 251}
@@ -293,59 +262,51 @@ static int twl6040_write(struct snd_soc_codec *codec,
293 return -EIO; 262 return -EIO;
294 263
295 twl6040_write_reg_cache(codec, reg, value); 264 twl6040_write_reg_cache(codec, reg, value);
296 return twl6040_reg_write(twl6040, reg, value); 265 if (likely(reg < TWL6040_REG_SW_SHADOW))
266 return twl6040_reg_write(twl6040, reg, value);
267 else
268 return 0;
297} 269}
298 270
299static void twl6040_init_vio_regs(struct snd_soc_codec *codec) 271static void twl6040_init_chip(struct snd_soc_codec *codec)
300{ 272{
301 u8 *cache = codec->reg_cache; 273 struct twl6040 *twl6040 = codec->control_data;
302 int reg, i; 274 u8 val;
303 275
304 for (i = 0; i < TWL6040_VIOREGNUM; i++) { 276 /* Update reg_cache: ASICREV, and TRIM values */
305 reg = twl6040_vio_reg[i]; 277 val = twl6040_get_revid(twl6040);
306 /* 278 twl6040_write_reg_cache(codec, TWL6040_REG_ASICREV, val);
307 * skip read-only registers (ASICID, ASICREV, STATUS) 279
308 * and registers shared among MFD children 280 twl6040_read_reg_volatile(codec, TWL6040_REG_TRIM1);
309 */ 281 twl6040_read_reg_volatile(codec, TWL6040_REG_TRIM2);
310 switch (reg) { 282 twl6040_read_reg_volatile(codec, TWL6040_REG_TRIM3);
311 case TWL6040_REG_ASICID: 283 twl6040_read_reg_volatile(codec, TWL6040_REG_HSOTRIM);
312 case TWL6040_REG_ASICREV: 284 twl6040_read_reg_volatile(codec, TWL6040_REG_HFOTRIM);
313 case TWL6040_REG_INTID: 285
314 case TWL6040_REG_INTMR: 286 /* Change chip defaults */
315 case TWL6040_REG_NCPCTL: 287 /* No imput selected for microphone amplifiers */
316 case TWL6040_REG_LDOCTL: 288 twl6040_write_reg_cache(codec, TWL6040_REG_MICLCTL, 0x18);
317 case TWL6040_REG_GPOCTL: 289 twl6040_write_reg_cache(codec, TWL6040_REG_MICRCTL, 0x18);
318 case TWL6040_REG_ACCCTL: 290
319 case TWL6040_REG_STATUS: 291 /*
320 continue; 292 * We need to lower the default gain values, so the ramp code
321 default: 293 * can work correctly for the first playback.
322 break; 294 * This reduces the pop noise heard at the first playback.
323 } 295 */
324 twl6040_write(codec, reg, cache[reg]); 296 twl6040_write_reg_cache(codec, TWL6040_REG_HSGAIN, 0xff);
325 } 297 twl6040_write_reg_cache(codec, TWL6040_REG_EARCTL, 0x1e);
298 twl6040_write_reg_cache(codec, TWL6040_REG_HFLGAIN, 0x1d);
299 twl6040_write_reg_cache(codec, TWL6040_REG_HFRGAIN, 0x1d);
300 twl6040_write_reg_cache(codec, TWL6040_REG_LINEGAIN, 0);
326} 301}
327 302
328static void twl6040_init_vdd_regs(struct snd_soc_codec *codec) 303static void twl6040_restore_regs(struct snd_soc_codec *codec)
329{ 304{
330 u8 *cache = codec->reg_cache; 305 u8 *cache = codec->reg_cache;
331 int reg, i; 306 int reg, i;
332 307
333 for (i = 0; i < TWL6040_VDDREGNUM; i++) { 308 for (i = 0; i < ARRAY_SIZE(twl6040_restore_list); i++) {
334 reg = twl6040_vdd_reg[i]; 309 reg = twl6040_restore_list[i];
335 /* skip vibra and PLL registers */
336 switch (reg) {
337 case TWL6040_REG_VIBCTLL:
338 case TWL6040_REG_VIBDATL:
339 case TWL6040_REG_VIBCTLR:
340 case TWL6040_REG_VIBDATR:
341 case TWL6040_REG_HPPLLCTL:
342 case TWL6040_REG_LPPLLCTL:
343 case TWL6040_REG_LPPLLDIV:
344 continue;
345 default:
346 break;
347 }
348
349 twl6040_write(codec, reg, cache[reg]); 310 twl6040_write(codec, reg, cache[reg]);
350 } 311 }
351} 312}
@@ -524,18 +485,17 @@ static inline int twl6040_hf_ramp_step(struct snd_soc_codec *codec,
524static void twl6040_pga_hs_work(struct work_struct *work) 485static void twl6040_pga_hs_work(struct work_struct *work)
525{ 486{
526 struct twl6040_data *priv = 487 struct twl6040_data *priv =
527 container_of(work, struct twl6040_data, hs_delayed_work.work); 488 container_of(work, struct twl6040_data, headset.work.work);
528 struct snd_soc_codec *codec = priv->codec; 489 struct snd_soc_codec *codec = priv->codec;
529 struct twl6040_output *headset = &priv->headset; 490 struct twl6040_output *headset = &priv->headset;
530 unsigned int delay = headset->step_delay;
531 int i, headset_complete; 491 int i, headset_complete;
532 492
533 /* do we need to ramp at all ? */ 493 /* do we need to ramp at all ? */
534 if (headset->ramp == TWL6040_RAMP_NONE) 494 if (headset->ramp == TWL6040_RAMP_NONE)
535 return; 495 return;
536 496
537 /* HS PGA volumes have 4 bits of resolution to ramp */ 497 /* HS PGA gain range: 0x0 - 0xf (0 - 15) */
538 for (i = 0; i <= 16; i++) { 498 for (i = 0; i < 16; i++) {
539 headset_complete = twl6040_hs_ramp_step(codec, 499 headset_complete = twl6040_hs_ramp_step(codec,
540 headset->left_step, 500 headset->left_step,
541 headset->right_step); 501 headset->right_step);
@@ -544,15 +504,8 @@ static void twl6040_pga_hs_work(struct work_struct *work)
544 if (headset_complete) 504 if (headset_complete)
545 break; 505 break;
546 506
547 /* 507 schedule_timeout_interruptible(
548 * TODO: tune: delay is longer over 0dB 508 msecs_to_jiffies(headset->step_delay));
549 * as increases are larger.
550 */
551 if (i >= 8)
552 schedule_timeout_interruptible(msecs_to_jiffies(delay +
553 (delay >> 1)));
554 else
555 schedule_timeout_interruptible(msecs_to_jiffies(delay));
556 } 509 }
557 510
558 if (headset->ramp == TWL6040_RAMP_DOWN) { 511 if (headset->ramp == TWL6040_RAMP_DOWN) {
@@ -567,18 +520,18 @@ static void twl6040_pga_hs_work(struct work_struct *work)
567static void twl6040_pga_hf_work(struct work_struct *work) 520static void twl6040_pga_hf_work(struct work_struct *work)
568{ 521{
569 struct twl6040_data *priv = 522 struct twl6040_data *priv =
570 container_of(work, struct twl6040_data, hf_delayed_work.work); 523 container_of(work, struct twl6040_data, handsfree.work.work);
571 struct snd_soc_codec *codec = priv->codec; 524 struct snd_soc_codec *codec = priv->codec;
572 struct twl6040_output *handsfree = &priv->handsfree; 525 struct twl6040_output *handsfree = &priv->handsfree;
573 unsigned int delay = handsfree->step_delay;
574 int i, handsfree_complete; 526 int i, handsfree_complete;
575 527
576 /* do we need to ramp at all ? */ 528 /* do we need to ramp at all ? */
577 if (handsfree->ramp == TWL6040_RAMP_NONE) 529 if (handsfree->ramp == TWL6040_RAMP_NONE)
578 return; 530 return;
579 531
580 /* HF PGA volumes have 5 bits of resolution to ramp */ 532 /*
581 for (i = 0; i <= 32; i++) { 533 * HF PGA gain range: 0x00 - 0x1d (0 - 29) */
534 for (i = 0; i < 30; i++) {
582 handsfree_complete = twl6040_hf_ramp_step(codec, 535 handsfree_complete = twl6040_hf_ramp_step(codec,
583 handsfree->left_step, 536 handsfree->left_step,
584 handsfree->right_step); 537 handsfree->right_step);
@@ -587,15 +540,8 @@ static void twl6040_pga_hf_work(struct work_struct *work)
587 if (handsfree_complete) 540 if (handsfree_complete)
588 break; 541 break;
589 542
590 /* 543 schedule_timeout_interruptible(
591 * TODO: tune: delay is longer over 0dB 544 msecs_to_jiffies(handsfree->step_delay));
592 * as increases are larger.
593 */
594 if (i >= 16)
595 schedule_timeout_interruptible(msecs_to_jiffies(delay +
596 (delay >> 1)));
597 else
598 schedule_timeout_interruptible(msecs_to_jiffies(delay));
599 } 545 }
600 546
601 547
@@ -607,36 +553,40 @@ static void twl6040_pga_hf_work(struct work_struct *work)
607 handsfree->ramp = TWL6040_RAMP_NONE; 553 handsfree->ramp = TWL6040_RAMP_NONE;
608} 554}
609 555
610static int pga_event(struct snd_soc_dapm_widget *w, 556static int out_drv_event(struct snd_soc_dapm_widget *w,
611 struct snd_kcontrol *kcontrol, int event) 557 struct snd_kcontrol *kcontrol, int event)
612{ 558{
613 struct snd_soc_codec *codec = w->codec; 559 struct snd_soc_codec *codec = w->codec;
614 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); 560 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
615 struct twl6040_output *out; 561 struct twl6040_output *out;
616 struct delayed_work *work; 562 struct delayed_work *work;
617 struct workqueue_struct *queue;
618 563
619 switch (w->shift) { 564 switch (w->shift) {
620 case 2: 565 case 2: /* Headset output driver */
621 case 3:
622 out = &priv->headset; 566 out = &priv->headset;
623 work = &priv->hs_delayed_work; 567 work = &out->work;
624 queue = priv->hs_workqueue; 568 /*
569 * Make sure, that we do not mess up variables for already
570 * executing work.
571 */
572 cancel_delayed_work_sync(work);
573
625 out->left_step = priv->hs_left_step; 574 out->left_step = priv->hs_left_step;
626 out->right_step = priv->hs_right_step; 575 out->right_step = priv->hs_right_step;
627 out->step_delay = 5; /* 5 ms between volume ramp steps */ 576 out->step_delay = 5; /* 5 ms between volume ramp steps */
628 break; 577 break;
629 case 4: 578 case 4: /* Handsfree output driver */
630 out = &priv->handsfree; 579 out = &priv->handsfree;
631 work = &priv->hf_delayed_work; 580 work = &out->work;
632 queue = priv->hf_workqueue; 581 /*
582 * Make sure, that we do not mess up variables for already
583 * executing work.
584 */
585 cancel_delayed_work_sync(work);
586
633 out->left_step = priv->hf_left_step; 587 out->left_step = priv->hf_left_step;
634 out->right_step = priv->hf_right_step; 588 out->right_step = priv->hf_right_step;
635 out->step_delay = 5; /* 5 ms between volume ramp steps */ 589 out->step_delay = 5; /* 5 ms between volume ramp steps */
636 if (SND_SOC_DAPM_EVENT_ON(event))
637 priv->non_lp++;
638 else
639 priv->non_lp--;
640 break; 590 break;
641 default: 591 default:
642 return -1; 592 return -1;
@@ -648,31 +598,25 @@ static int pga_event(struct snd_soc_dapm_widget *w,
648 break; 598 break;
649 599
650 /* don't use volume ramp for power-up */ 600 /* don't use volume ramp for power-up */
601 out->ramp = TWL6040_RAMP_UP;
651 out->left_step = out->left_vol; 602 out->left_step = out->left_vol;
652 out->right_step = out->right_vol; 603 out->right_step = out->right_vol;
653 604
654 if (!delayed_work_pending(work)) { 605 queue_delayed_work(priv->workqueue, work, msecs_to_jiffies(1));
655 out->ramp = TWL6040_RAMP_UP;
656 queue_delayed_work(queue, work,
657 msecs_to_jiffies(1));
658 }
659 break; 606 break;
660 607
661 case SND_SOC_DAPM_PRE_PMD: 608 case SND_SOC_DAPM_PRE_PMD:
662 if (!out->active) 609 if (!out->active)
663 break; 610 break;
664 611
665 if (!delayed_work_pending(work)) { 612 /* use volume ramp for power-down */
666 /* use volume ramp for power-down */ 613 out->ramp = TWL6040_RAMP_DOWN;
667 out->ramp = TWL6040_RAMP_DOWN; 614 INIT_COMPLETION(out->ramp_done);
668 INIT_COMPLETION(out->ramp_done);
669 615
670 queue_delayed_work(queue, work, 616 queue_delayed_work(priv->workqueue, work, msecs_to_jiffies(1));
671 msecs_to_jiffies(1));
672 617
673 wait_for_completion_timeout(&out->ramp_done, 618 wait_for_completion_timeout(&out->ramp_done,
674 msecs_to_jiffies(2000)); 619 msecs_to_jiffies(2000));
675 }
676 break; 620 break;
677 } 621 }
678 622
@@ -683,7 +627,7 @@ static int pga_event(struct snd_soc_dapm_widget *w,
683static int headset_power_mode(struct snd_soc_codec *codec, int high_perf) 627static int headset_power_mode(struct snd_soc_codec *codec, int high_perf)
684{ 628{
685 int hslctl, hsrctl; 629 int hslctl, hsrctl;
686 int mask = TWL6040_HSDRVMODEL | TWL6040_HSDACMODEL; 630 int mask = TWL6040_HSDRVMODE | TWL6040_HSDACMODE;
687 631
688 hslctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSLCTL); 632 hslctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSLCTL);
689 hsrctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSRCTL); 633 hsrctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSRCTL);
@@ -705,11 +649,31 @@ static int headset_power_mode(struct snd_soc_codec *codec, int high_perf)
705static int twl6040_hs_dac_event(struct snd_soc_dapm_widget *w, 649static int twl6040_hs_dac_event(struct snd_soc_dapm_widget *w,
706 struct snd_kcontrol *kcontrol, int event) 650 struct snd_kcontrol *kcontrol, int event)
707{ 651{
652 struct snd_soc_codec *codec = w->codec;
653 u8 hslctl, hsrctl;
654
655 /*
656 * Workaround for Headset DC offset caused pop noise:
657 * Both HS DAC need to be turned on (before the HS driver) and off at
658 * the same time.
659 */
660 hslctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSLCTL);
661 hsrctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSRCTL);
662 if (SND_SOC_DAPM_EVENT_ON(event)) {
663 hslctl |= TWL6040_HSDACENA;
664 hsrctl |= TWL6040_HSDACENA;
665 } else {
666 hslctl &= ~TWL6040_HSDACENA;
667 hsrctl &= ~TWL6040_HSDACENA;
668 }
669 twl6040_write(codec, TWL6040_REG_HSLCTL, hslctl);
670 twl6040_write(codec, TWL6040_REG_HSRCTL, hsrctl);
671
708 msleep(1); 672 msleep(1);
709 return 0; 673 return 0;
710} 674}
711 675
712static int twl6040_power_mode_event(struct snd_soc_dapm_widget *w, 676static int twl6040_ep_drv_event(struct snd_soc_dapm_widget *w,
713 struct snd_kcontrol *kcontrol, int event) 677 struct snd_kcontrol *kcontrol, int event)
714{ 678{
715 struct snd_soc_codec *codec = w->codec; 679 struct snd_soc_codec *codec = w->codec;
@@ -717,18 +681,12 @@ static int twl6040_power_mode_event(struct snd_soc_dapm_widget *w,
717 int ret = 0; 681 int ret = 0;
718 682
719 if (SND_SOC_DAPM_EVENT_ON(event)) { 683 if (SND_SOC_DAPM_EVENT_ON(event)) {
720 priv->non_lp++; 684 /* Earphone doesn't support low power mode */
721 if (!strcmp(w->name, "Earphone Driver")) { 685 priv->hs_power_mode_locked = 1;
722 /* Earphone doesn't support low power mode */ 686 ret = headset_power_mode(codec, 1);
723 priv->hs_power_mode_locked = 1;
724 ret = headset_power_mode(codec, 1);
725 }
726 } else { 687 } else {
727 priv->non_lp--; 688 priv->hs_power_mode_locked = 0;
728 if (!strcmp(w->name, "Earphone Driver")) { 689 ret = headset_power_mode(codec, priv->hs_power_mode);
729 priv->hs_power_mode_locked = 0;
730 ret = headset_power_mode(codec, priv->hs_power_mode);
731 }
732 } 690 }
733 691
734 msleep(1); 692 msleep(1);
@@ -770,7 +728,7 @@ EXPORT_SYMBOL_GPL(twl6040_hs_jack_detect);
770static void twl6040_accessory_work(struct work_struct *work) 728static void twl6040_accessory_work(struct work_struct *work)
771{ 729{
772 struct twl6040_data *priv = container_of(work, 730 struct twl6040_data *priv = container_of(work,
773 struct twl6040_data, delayed_work.work); 731 struct twl6040_data, hs_jack.work.work);
774 struct snd_soc_codec *codec = priv->codec; 732 struct snd_soc_codec *codec = priv->codec;
775 struct twl6040_jack_data *hs_jack = &priv->hs_jack; 733 struct twl6040_jack_data *hs_jack = &priv->hs_jack;
776 734
@@ -781,15 +739,10 @@ static void twl6040_accessory_work(struct work_struct *work)
781static irqreturn_t twl6040_audio_handler(int irq, void *data) 739static irqreturn_t twl6040_audio_handler(int irq, void *data)
782{ 740{
783 struct snd_soc_codec *codec = data; 741 struct snd_soc_codec *codec = data;
784 struct twl6040 *twl6040 = codec->control_data;
785 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); 742 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
786 u8 intid;
787
788 intid = twl6040_reg_read(twl6040, TWL6040_REG_INTID);
789 743
790 if ((intid & TWL6040_PLUGINT) || (intid & TWL6040_UNPLUGINT)) 744 queue_delayed_work(priv->workqueue, &priv->hs_jack.work,
791 queue_delayed_work(priv->workqueue, &priv->delayed_work, 745 msecs_to_jiffies(200));
792 msecs_to_jiffies(200));
793 746
794 return IRQ_HANDLED; 747 return IRQ_HANDLED;
795} 748}
@@ -803,25 +756,27 @@ static int twl6040_put_volsw(struct snd_kcontrol *kcontrol,
803 struct soc_mixer_control *mc = 756 struct soc_mixer_control *mc =
804 (struct soc_mixer_control *)kcontrol->private_value; 757 (struct soc_mixer_control *)kcontrol->private_value;
805 int ret; 758 int ret;
806 unsigned int reg = mc->reg;
807 759
808 /* For HS and HF we shadow the values and only actually write 760 /* For HS and HF we shadow the values and only actually write
809 * them out when active in order to ensure the amplifier comes on 761 * them out when active in order to ensure the amplifier comes on
810 * as quietly as possible. */ 762 * as quietly as possible. */
811 switch (reg) { 763 switch (mc->reg) {
812 case TWL6040_REG_HSGAIN: 764 case TWL6040_REG_HSGAIN:
813 out = &twl6040_priv->headset; 765 out = &twl6040_priv->headset;
814 break; 766 break;
815 default: 767 case TWL6040_REG_HFLGAIN:
768 out = &twl6040_priv->handsfree;
816 break; 769 break;
770 default:
771 dev_warn(codec->dev, "%s: Unexpected register: 0x%02x\n",
772 __func__, mc->reg);
773 return -EINVAL;
817 } 774 }
818 775
819 if (out) { 776 out->left_vol = ucontrol->value.integer.value[0];
820 out->left_vol = ucontrol->value.integer.value[0]; 777 out->right_vol = ucontrol->value.integer.value[1];
821 out->right_vol = ucontrol->value.integer.value[1]; 778 if (!out->active)
822 if (!out->active) 779 return 1;
823 return 1;
824 }
825 780
826 ret = snd_soc_put_volsw(kcontrol, ucontrol); 781 ret = snd_soc_put_volsw(kcontrol, ucontrol);
827 if (ret < 0) 782 if (ret < 0)
@@ -838,112 +793,42 @@ static int twl6040_get_volsw(struct snd_kcontrol *kcontrol,
838 struct twl6040_output *out = &twl6040_priv->headset; 793 struct twl6040_output *out = &twl6040_priv->headset;
839 struct soc_mixer_control *mc = 794 struct soc_mixer_control *mc =
840 (struct soc_mixer_control *)kcontrol->private_value; 795 (struct soc_mixer_control *)kcontrol->private_value;
841 unsigned int reg = mc->reg;
842 796
843 switch (reg) { 797 switch (mc->reg) {
844 case TWL6040_REG_HSGAIN: 798 case TWL6040_REG_HSGAIN:
845 out = &twl6040_priv->headset; 799 out = &twl6040_priv->headset;
846 ucontrol->value.integer.value[0] = out->left_vol;
847 ucontrol->value.integer.value[1] = out->right_vol;
848 return 0;
849
850 default:
851 break; 800 break;
852 }
853
854 return snd_soc_get_volsw(kcontrol, ucontrol);
855}
856
857static int twl6040_put_volsw_2r_vu(struct snd_kcontrol *kcontrol,
858 struct snd_ctl_elem_value *ucontrol)
859{
860 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
861 struct twl6040_data *twl6040_priv = snd_soc_codec_get_drvdata(codec);
862 struct twl6040_output *out = NULL;
863 struct soc_mixer_control *mc =
864 (struct soc_mixer_control *)kcontrol->private_value;
865 int ret;
866 unsigned int reg = mc->reg;
867
868 /* For HS and HF we shadow the values and only actually write
869 * them out when active in order to ensure the amplifier comes on
870 * as quietly as possible. */
871 switch (reg) {
872 case TWL6040_REG_HFLGAIN: 801 case TWL6040_REG_HFLGAIN:
873 case TWL6040_REG_HFRGAIN:
874 out = &twl6040_priv->handsfree; 802 out = &twl6040_priv->handsfree;
875 break; 803 break;
876 default: 804 default:
877 break; 805 dev_warn(codec->dev, "%s: Unexpected register: 0x%02x\n",
878 } 806 __func__, mc->reg);
879 807 return -EINVAL;
880 if (out) {
881 out->left_vol = ucontrol->value.integer.value[0];
882 out->right_vol = ucontrol->value.integer.value[1];
883 if (!out->active)
884 return 1;
885 } 808 }
886 809
887 ret = snd_soc_put_volsw_2r(kcontrol, ucontrol); 810 ucontrol->value.integer.value[0] = out->left_vol;
888 if (ret < 0) 811 ucontrol->value.integer.value[1] = out->right_vol;
889 return ret; 812 return 0;
890
891 return 1;
892} 813}
893 814
894static int twl6040_get_volsw_2r(struct snd_kcontrol *kcontrol, 815static int twl6040_soc_dapm_put_vibra_enum(struct snd_kcontrol *kcontrol,
895 struct snd_ctl_elem_value *ucontrol) 816 struct snd_ctl_elem_value *ucontrol)
896{ 817{
897 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 818 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
898 struct twl6040_data *twl6040_priv = snd_soc_codec_get_drvdata(codec); 819 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
899 struct twl6040_output *out = &twl6040_priv->handsfree; 820 struct snd_soc_codec *codec = widget->codec;
900 struct soc_mixer_control *mc = 821 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
901 (struct soc_mixer_control *)kcontrol->private_value; 822 unsigned int val;
902 unsigned int reg = mc->reg; 823
903 824 /* Do not allow changes while Input/FF efect is running */
904 /* If these are cached registers use the cache */ 825 val = twl6040_read_reg_volatile(codec, e->reg);
905 switch (reg) { 826 if (val & TWL6040_VIBENA && !(val & TWL6040_VIBSEL))
906 case TWL6040_REG_HFLGAIN: 827 return -EBUSY;
907 case TWL6040_REG_HFRGAIN: 828
908 out = &twl6040_priv->handsfree; 829 return snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
909 ucontrol->value.integer.value[0] = out->left_vol;
910 ucontrol->value.integer.value[1] = out->right_vol;
911 return 0;
912
913 default:
914 break;
915 }
916
917 return snd_soc_get_volsw_2r(kcontrol, ucontrol);
918} 830}
919 831
920/* double control with volume update */
921#define SOC_TWL6040_DOUBLE_TLV(xname, xreg, shift_left, shift_right, xmax,\
922 xinvert, tlv_array)\
923{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
924 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
925 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
926 .tlv.p = (tlv_array), \
927 .info = snd_soc_info_volsw, .get = twl6040_get_volsw, \
928 .put = twl6040_put_volsw, \
929 .private_value = (unsigned long)&(struct soc_mixer_control) \
930 {.reg = xreg, .shift = shift_left, .rshift = shift_right,\
931 .max = xmax, .platform_max = xmax, .invert = xinvert} }
932
933/* double control with volume update */
934#define SOC_TWL6040_DOUBLE_R_TLV(xname, reg_left, reg_right, xshift, xmax,\
935 xinvert, tlv_array)\
936{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
937 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
938 SNDRV_CTL_ELEM_ACCESS_READWRITE | \
939 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
940 .tlv.p = (tlv_array), \
941 .info = snd_soc_info_volsw_2r, \
942 .get = twl6040_get_volsw_2r, .put = twl6040_put_volsw_2r_vu, \
943 .private_value = (unsigned long)&(struct soc_mixer_control) \
944 {.reg = reg_left, .rreg = reg_right, .shift = xshift, \
945 .rshift = xshift, .max = xmax, .invert = xinvert}, }
946
947/* 832/*
948 * MICATT volume control: 833 * MICATT volume control:
949 * from -6 to 0 dB in 6 dB steps 834 * from -6 to 0 dB in 6 dB steps
@@ -1015,6 +900,19 @@ static const struct soc_enum twl6040_hf_enum[] = {
1015 twl6040_hf_texts), 900 twl6040_hf_texts),
1016}; 901};
1017 902
903static const char *twl6040_vibrapath_texts[] = {
904 "Input FF", "Audio PDM"
905};
906
907static const struct soc_enum twl6040_vibra_enum[] = {
908 SOC_ENUM_SINGLE(TWL6040_REG_VIBCTLL, 1,
909 ARRAY_SIZE(twl6040_vibrapath_texts),
910 twl6040_vibrapath_texts),
911 SOC_ENUM_SINGLE(TWL6040_REG_VIBCTLR, 1,
912 ARRAY_SIZE(twl6040_vibrapath_texts),
913 twl6040_vibrapath_texts),
914};
915
1018static const struct snd_kcontrol_new amicl_control = 916static const struct snd_kcontrol_new amicl_control =
1019 SOC_DAPM_ENUM("Route", twl6040_enum[0]); 917 SOC_DAPM_ENUM("Route", twl6040_enum[0]);
1020 918
@@ -1035,8 +933,25 @@ static const struct snd_kcontrol_new hfl_mux_controls =
1035static const struct snd_kcontrol_new hfr_mux_controls = 933static const struct snd_kcontrol_new hfr_mux_controls =
1036 SOC_DAPM_ENUM("Route", twl6040_hf_enum[1]); 934 SOC_DAPM_ENUM("Route", twl6040_hf_enum[1]);
1037 935
1038static const struct snd_kcontrol_new ep_driver_switch_controls = 936static const struct snd_kcontrol_new ep_path_enable_control =
1039 SOC_DAPM_SINGLE("Switch", TWL6040_REG_EARCTL, 0, 1, 0); 937 SOC_DAPM_SINGLE("Switch", TWL6040_REG_SW_SHADOW, 0, 1, 0);
938
939static const struct snd_kcontrol_new auxl_switch_control =
940 SOC_DAPM_SINGLE("Switch", TWL6040_REG_HFLCTL, 6, 1, 0);
941
942static const struct snd_kcontrol_new auxr_switch_control =
943 SOC_DAPM_SINGLE("Switch", TWL6040_REG_HFRCTL, 6, 1, 0);
944
945/* Vibra playback switches */
946static const struct snd_kcontrol_new vibral_mux_controls =
947 SOC_DAPM_ENUM_EXT("Route", twl6040_vibra_enum[0],
948 snd_soc_dapm_get_enum_double,
949 twl6040_soc_dapm_put_vibra_enum);
950
951static const struct snd_kcontrol_new vibrar_mux_controls =
952 SOC_DAPM_ENUM_EXT("Route", twl6040_vibra_enum[1],
953 snd_soc_dapm_get_enum_double,
954 twl6040_soc_dapm_put_vibra_enum);
1040 955
1041/* Headset power mode */ 956/* Headset power mode */
1042static const char *twl6040_power_mode_texts[] = { 957static const char *twl6040_power_mode_texts[] = {
@@ -1105,6 +1020,15 @@ int twl6040_get_clk_id(struct snd_soc_codec *codec)
1105} 1020}
1106EXPORT_SYMBOL_GPL(twl6040_get_clk_id); 1021EXPORT_SYMBOL_GPL(twl6040_get_clk_id);
1107 1022
1023int twl6040_get_trim_value(struct snd_soc_codec *codec, enum twl6040_trim trim)
1024{
1025 if (unlikely(trim >= TWL6040_TRIM_INVAL))
1026 return -EINVAL;
1027
1028 return twl6040_read_reg_cache(codec, TWL6040_REG_TRIM1 + trim);
1029}
1030EXPORT_SYMBOL_GPL(twl6040_get_trim_value);
1031
1108static const struct snd_kcontrol_new twl6040_snd_controls[] = { 1032static const struct snd_kcontrol_new twl6040_snd_controls[] = {
1109 /* Capture gains */ 1033 /* Capture gains */
1110 SOC_DOUBLE_TLV("Capture Preamplifier Volume", 1034 SOC_DOUBLE_TLV("Capture Preamplifier Volume",
@@ -1117,10 +1041,12 @@ static const struct snd_kcontrol_new twl6040_snd_controls[] = {
1117 TWL6040_REG_LINEGAIN, 0, 3, 7, 0, afm_amp_tlv), 1041 TWL6040_REG_LINEGAIN, 0, 3, 7, 0, afm_amp_tlv),
1118 1042
1119 /* Playback gains */ 1043 /* Playback gains */
1120 SOC_TWL6040_DOUBLE_TLV("Headset Playback Volume", 1044 SOC_DOUBLE_EXT_TLV("Headset Playback Volume",
1121 TWL6040_REG_HSGAIN, 0, 4, 0xF, 1, hs_tlv), 1045 TWL6040_REG_HSGAIN, 0, 4, 0xF, 1, twl6040_get_volsw,
1122 SOC_TWL6040_DOUBLE_R_TLV("Handsfree Playback Volume", 1046 twl6040_put_volsw, hs_tlv),
1123 TWL6040_REG_HFLGAIN, TWL6040_REG_HFRGAIN, 0, 0x1D, 1, hf_tlv), 1047 SOC_DOUBLE_R_EXT_TLV("Handsfree Playback Volume",
1048 TWL6040_REG_HFLGAIN, TWL6040_REG_HFRGAIN, 0, 0x1D, 1,
1049 twl6040_get_volsw, twl6040_put_volsw, hf_tlv),
1124 SOC_SINGLE_TLV("Earphone Playback Volume", 1050 SOC_SINGLE_TLV("Earphone Playback Volume",
1125 TWL6040_REG_EARCTL, 1, 0xF, 1, ep_tlv), 1051 TWL6040_REG_EARCTL, 1, 0xF, 1, ep_tlv),
1126 1052
@@ -1146,6 +1072,10 @@ static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = {
1146 SND_SOC_DAPM_OUTPUT("HFL"), 1072 SND_SOC_DAPM_OUTPUT("HFL"),
1147 SND_SOC_DAPM_OUTPUT("HFR"), 1073 SND_SOC_DAPM_OUTPUT("HFR"),
1148 SND_SOC_DAPM_OUTPUT("EP"), 1074 SND_SOC_DAPM_OUTPUT("EP"),
1075 SND_SOC_DAPM_OUTPUT("AUXL"),
1076 SND_SOC_DAPM_OUTPUT("AUXR"),
1077 SND_SOC_DAPM_OUTPUT("VIBRAL"),
1078 SND_SOC_DAPM_OUTPUT("VIBRAR"),
1149 1079
1150 /* Analog input muxes for the capture amplifiers */ 1080 /* Analog input muxes for the capture amplifiers */
1151 SND_SOC_DAPM_MUX("Analog Left Capture Route", 1081 SND_SOC_DAPM_MUX("Analog Left Capture Route",
@@ -1182,59 +1112,76 @@ static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = {
1182 TWL6040_REG_DMICBCTL, 4, 0), 1112 TWL6040_REG_DMICBCTL, 4, 0),
1183 1113
1184 /* DACs */ 1114 /* DACs */
1185 SND_SOC_DAPM_DAC_E("HSDAC Left", "Headset Playback", 1115 SND_SOC_DAPM_DAC("HSDAC Left", "Headset Playback", SND_SOC_NOPM, 0, 0),
1186 TWL6040_REG_HSLCTL, 0, 0, 1116 SND_SOC_DAPM_DAC("HSDAC Right", "Headset Playback", SND_SOC_NOPM, 0, 0),
1187 twl6040_hs_dac_event, 1117 SND_SOC_DAPM_DAC("HFDAC Left", "Handsfree Playback",
1188 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 1118 TWL6040_REG_HFLCTL, 0, 0),
1189 SND_SOC_DAPM_DAC_E("HSDAC Right", "Headset Playback", 1119 SND_SOC_DAPM_DAC("HFDAC Right", "Handsfree Playback",
1190 TWL6040_REG_HSRCTL, 0, 0, 1120 TWL6040_REG_HFRCTL, 0, 0),
1191 twl6040_hs_dac_event, 1121 /* Virtual DAC for vibra path (DL4 channel) */
1192 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 1122 SND_SOC_DAPM_DAC("VIBRA DAC", "Vibra Playback",
1193 SND_SOC_DAPM_DAC_E("HFDAC Left", "Handsfree Playback", 1123 SND_SOC_NOPM, 0, 0),
1194 TWL6040_REG_HFLCTL, 0, 0, 1124
1195 twl6040_power_mode_event, 1125 SND_SOC_DAPM_MUX("Handsfree Left Playback",
1196 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1197 SND_SOC_DAPM_DAC_E("HFDAC Right", "Handsfree Playback",
1198 TWL6040_REG_HFRCTL, 0, 0,
1199 twl6040_power_mode_event,
1200 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1201
1202 SND_SOC_DAPM_MUX("HF Left Playback",
1203 SND_SOC_NOPM, 0, 0, &hfl_mux_controls), 1126 SND_SOC_NOPM, 0, 0, &hfl_mux_controls),
1204 SND_SOC_DAPM_MUX("HF Right Playback", 1127 SND_SOC_DAPM_MUX("Handsfree Right Playback",
1205 SND_SOC_NOPM, 0, 0, &hfr_mux_controls), 1128 SND_SOC_NOPM, 0, 0, &hfr_mux_controls),
1206 /* Analog playback Muxes */ 1129 /* Analog playback Muxes */
1207 SND_SOC_DAPM_MUX("HS Left Playback", 1130 SND_SOC_DAPM_MUX("Headset Left Playback",
1208 SND_SOC_NOPM, 0, 0, &hsl_mux_controls), 1131 SND_SOC_NOPM, 0, 0, &hsl_mux_controls),
1209 SND_SOC_DAPM_MUX("HS Right Playback", 1132 SND_SOC_DAPM_MUX("Headset Right Playback",
1210 SND_SOC_NOPM, 0, 0, &hsr_mux_controls), 1133 SND_SOC_NOPM, 0, 0, &hsr_mux_controls),
1211 1134
1135 SND_SOC_DAPM_MUX("Vibra Left Playback", SND_SOC_NOPM, 0, 0,
1136 &vibral_mux_controls),
1137 SND_SOC_DAPM_MUX("Vibra Right Playback", SND_SOC_NOPM, 0, 0,
1138 &vibrar_mux_controls),
1139
1140 SND_SOC_DAPM_SWITCH("Earphone Playback", SND_SOC_NOPM, 0, 0,
1141 &ep_path_enable_control),
1142 SND_SOC_DAPM_SWITCH("AUXL Playback", SND_SOC_NOPM, 0, 0,
1143 &auxl_switch_control),
1144 SND_SOC_DAPM_SWITCH("AUXR Playback", SND_SOC_NOPM, 0, 0,
1145 &auxr_switch_control),
1146
1212 /* Analog playback drivers */ 1147 /* Analog playback drivers */
1213 SND_SOC_DAPM_OUT_DRV_E("Handsfree Left Driver", 1148 SND_SOC_DAPM_OUT_DRV_E("HF Left Driver",
1214 TWL6040_REG_HFLCTL, 4, 0, NULL, 0, 1149 TWL6040_REG_HFLCTL, 4, 0, NULL, 0,
1215 pga_event, 1150 out_drv_event,
1216 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 1151 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1217 SND_SOC_DAPM_OUT_DRV_E("Handsfree Right Driver", 1152 SND_SOC_DAPM_OUT_DRV_E("HF Right Driver",
1218 TWL6040_REG_HFRCTL, 4, 0, NULL, 0, 1153 TWL6040_REG_HFRCTL, 4, 0, NULL, 0,
1219 pga_event, 1154 out_drv_event,
1220 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 1155 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1221 SND_SOC_DAPM_OUT_DRV_E("Headset Left Driver", 1156 SND_SOC_DAPM_OUT_DRV_E("HS Left Driver",
1222 TWL6040_REG_HSLCTL, 2, 0, NULL, 0, 1157 TWL6040_REG_HSLCTL, 2, 0, NULL, 0,
1223 pga_event, 1158 out_drv_event,
1224 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 1159 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1225 SND_SOC_DAPM_OUT_DRV_E("Headset Right Driver", 1160 SND_SOC_DAPM_OUT_DRV_E("HS Right Driver",
1226 TWL6040_REG_HSRCTL, 2, 0, NULL, 0, 1161 TWL6040_REG_HSRCTL, 2, 0, NULL, 0,
1227 pga_event, 1162 out_drv_event,
1228 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 1163 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1229 SND_SOC_DAPM_SWITCH_E("Earphone Driver", 1164 SND_SOC_DAPM_OUT_DRV_E("Earphone Driver",
1230 SND_SOC_NOPM, 0, 0, &ep_driver_switch_controls, 1165 TWL6040_REG_EARCTL, 0, 0, NULL, 0,
1231 twl6040_power_mode_event, 1166 twl6040_ep_drv_event,
1232 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 1167 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1168 SND_SOC_DAPM_OUT_DRV("Vibra Left Driver",
1169 TWL6040_REG_VIBCTLL, 0, 0, NULL, 0),
1170 SND_SOC_DAPM_OUT_DRV("Vibra Right Driver",
1171 TWL6040_REG_VIBCTLR, 0, 0, NULL, 0),
1172
1173 SND_SOC_DAPM_SUPPLY("Vibra Left Control", TWL6040_REG_VIBCTLL, 2, 0,
1174 NULL, 0),
1175 SND_SOC_DAPM_SUPPLY("Vibra Right Control", TWL6040_REG_VIBCTLR, 2, 0,
1176 NULL, 0),
1177 SND_SOC_DAPM_SUPPLY_S("HSDAC Power", 1, SND_SOC_NOPM, 0, 0,
1178 twl6040_hs_dac_event,
1179 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1233 1180
1234 /* Analog playback PGAs */ 1181 /* Analog playback PGAs */
1235 SND_SOC_DAPM_PGA("HFDAC Left PGA", 1182 SND_SOC_DAPM_PGA("HF Left PGA",
1236 TWL6040_REG_HFLCTL, 1, 0, NULL, 0), 1183 TWL6040_REG_HFLCTL, 1, 0, NULL, 0),
1237 SND_SOC_DAPM_PGA("HFDAC Right PGA", 1184 SND_SOC_DAPM_PGA("HF Right PGA",
1238 TWL6040_REG_HFRCTL, 1, 0, NULL, 0), 1185 TWL6040_REG_HFRCTL, 1, 0, NULL, 0),
1239 1186
1240}; 1187};
@@ -1256,52 +1203,62 @@ static const struct snd_soc_dapm_route intercon[] = {
1256 {"ADC Right", NULL, "MicAmpR"}, 1203 {"ADC Right", NULL, "MicAmpR"},
1257 1204
1258 /* AFM path */ 1205 /* AFM path */
1259 {"AFMAmpL", "NULL", "AFML"}, 1206 {"AFMAmpL", NULL, "AFML"},
1260 {"AFMAmpR", "NULL", "AFMR"}, 1207 {"AFMAmpR", NULL, "AFMR"},
1208
1209 {"HSDAC Left", NULL, "HSDAC Power"},
1210 {"HSDAC Right", NULL, "HSDAC Power"},
1261 1211
1262 {"HS Left Playback", "HS DAC", "HSDAC Left"}, 1212 {"Headset Left Playback", "HS DAC", "HSDAC Left"},
1263 {"HS Left Playback", "Line-In amp", "AFMAmpL"}, 1213 {"Headset Left Playback", "Line-In amp", "AFMAmpL"},
1264 1214
1265 {"HS Right Playback", "HS DAC", "HSDAC Right"}, 1215 {"Headset Right Playback", "HS DAC", "HSDAC Right"},
1266 {"HS Right Playback", "Line-In amp", "AFMAmpR"}, 1216 {"Headset Right Playback", "Line-In amp", "AFMAmpR"},
1267 1217
1268 {"Headset Left Driver", "NULL", "HS Left Playback"}, 1218 {"HS Left Driver", NULL, "Headset Left Playback"},
1269 {"Headset Right Driver", "NULL", "HS Right Playback"}, 1219 {"HS Right Driver", NULL, "Headset Right Playback"},
1270 1220
1271 {"HSOL", NULL, "Headset Left Driver"}, 1221 {"HSOL", NULL, "HS Left Driver"},
1272 {"HSOR", NULL, "Headset Right Driver"}, 1222 {"HSOR", NULL, "HS Right Driver"},
1273 1223
1274 /* Earphone playback path */ 1224 /* Earphone playback path */
1275 {"Earphone Driver", "Switch", "HSDAC Left"}, 1225 {"Earphone Playback", "Switch", "HSDAC Left"},
1226 {"Earphone Driver", NULL, "Earphone Playback"},
1276 {"EP", NULL, "Earphone Driver"}, 1227 {"EP", NULL, "Earphone Driver"},
1277 1228
1278 {"HF Left Playback", "HF DAC", "HFDAC Left"}, 1229 {"Handsfree Left Playback", "HF DAC", "HFDAC Left"},
1279 {"HF Left Playback", "Line-In amp", "AFMAmpL"}, 1230 {"Handsfree Left Playback", "Line-In amp", "AFMAmpL"},
1280 1231
1281 {"HF Right Playback", "HF DAC", "HFDAC Right"}, 1232 {"Handsfree Right Playback", "HF DAC", "HFDAC Right"},
1282 {"HF Right Playback", "Line-In amp", "AFMAmpR"}, 1233 {"Handsfree Right Playback", "Line-In amp", "AFMAmpR"},
1283 1234
1284 {"HFDAC Left PGA", NULL, "HF Left Playback"}, 1235 {"HF Left PGA", NULL, "Handsfree Left Playback"},
1285 {"HFDAC Right PGA", NULL, "HF Right Playback"}, 1236 {"HF Right PGA", NULL, "Handsfree Right Playback"},
1286 1237
1287 {"Handsfree Left Driver", "Switch", "HFDAC Left PGA"}, 1238 {"HF Left Driver", NULL, "HF Left PGA"},
1288 {"Handsfree Right Driver", "Switch", "HFDAC Right PGA"}, 1239 {"HF Right Driver", NULL, "HF Right PGA"},
1289 1240
1290 {"HFL", NULL, "Handsfree Left Driver"}, 1241 {"HFL", NULL, "HF Left Driver"},
1291 {"HFR", NULL, "Handsfree Right Driver"}, 1242 {"HFR", NULL, "HF Right Driver"},
1292};
1293 1243
1294static int twl6040_add_widgets(struct snd_soc_codec *codec) 1244 {"AUXL Playback", "Switch", "HF Left PGA"},
1295{ 1245 {"AUXR Playback", "Switch", "HF Right PGA"},
1296 struct snd_soc_dapm_context *dapm = &codec->dapm;
1297 1246
1298 snd_soc_dapm_new_controls(dapm, twl6040_dapm_widgets, 1247 {"AUXL", NULL, "AUXL Playback"},
1299 ARRAY_SIZE(twl6040_dapm_widgets)); 1248 {"AUXR", NULL, "AUXR Playback"},
1300 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
1301 snd_soc_dapm_new_widgets(dapm);
1302 1249
1303 return 0; 1250 /* Vibrator paths */
1304} 1251 {"Vibra Left Playback", "Audio PDM", "VIBRA DAC"},
1252 {"Vibra Right Playback", "Audio PDM", "VIBRA DAC"},
1253
1254 {"Vibra Left Driver", NULL, "Vibra Left Playback"},
1255 {"Vibra Right Driver", NULL, "Vibra Right Playback"},
1256 {"Vibra Left Driver", NULL, "Vibra Left Control"},
1257 {"Vibra Right Driver", NULL, "Vibra Right Control"},
1258
1259 {"VIBRAL", NULL, "Vibra Left Driver"},
1260 {"VIBRAR", NULL, "Vibra Right Driver"},
1261};
1305 1262
1306static int twl6040_set_bias_level(struct snd_soc_codec *codec, 1263static int twl6040_set_bias_level(struct snd_soc_codec *codec,
1307 enum snd_soc_bias_level level) 1264 enum snd_soc_bias_level level)
@@ -1325,8 +1282,7 @@ static int twl6040_set_bias_level(struct snd_soc_codec *codec,
1325 1282
1326 priv->codec_powered = 1; 1283 priv->codec_powered = 1;
1327 1284
1328 /* initialize vdd/vss registers with reg_cache */ 1285 twl6040_restore_regs(codec);
1329 twl6040_init_vdd_regs(codec);
1330 1286
1331 /* Set external boost GPO */ 1287 /* Set external boost GPO */
1332 twl6040_write(codec, TWL6040_REG_GPOCTL, 0x02); 1288 twl6040_write(codec, TWL6040_REG_GPOCTL, 0x02);
@@ -1380,13 +1336,6 @@ static int twl6040_hw_params(struct snd_pcm_substream *substream,
1380 rate); 1336 rate);
1381 return -EINVAL; 1337 return -EINVAL;
1382 } 1338 }
1383 /* Capture is not supported with 17.64MHz sysclk */
1384 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
1385 dev_err(codec->dev,
1386 "capture mode is not supported at %dHz\n",
1387 rate);
1388 return -EINVAL;
1389 }
1390 priv->sysclk = 17640000; 1339 priv->sysclk = 17640000;
1391 break; 1340 break;
1392 case 8000: 1341 case 8000:
@@ -1419,13 +1368,6 @@ static int twl6040_prepare(struct snd_pcm_substream *substream,
1419 return -EINVAL; 1368 return -EINVAL;
1420 } 1369 }
1421 1370
1422 if ((priv->sysclk == 17640000) && priv->non_lp) {
1423 dev_err(codec->dev,
1424 "some enabled paths aren't supported at %dHz\n",
1425 priv->sysclk);
1426 return -EPERM;
1427 }
1428
1429 ret = twl6040_set_pll(twl6040, priv->pll, priv->clk_in, priv->sysclk); 1371 ret = twl6040_set_pll(twl6040, priv->pll, priv->clk_in, priv->sysclk);
1430 if (ret) { 1372 if (ret) {
1431 dev_err(codec->dev, "Can not set PLL (%d)\n", ret); 1373 dev_err(codec->dev, "Can not set PLL (%d)\n", ret);
@@ -1464,11 +1406,11 @@ static struct snd_soc_dai_ops twl6040_dai_ops = {
1464 1406
1465static struct snd_soc_dai_driver twl6040_dai[] = { 1407static struct snd_soc_dai_driver twl6040_dai[] = {
1466{ 1408{
1467 .name = "twl6040-hifi", 1409 .name = "twl6040-legacy",
1468 .playback = { 1410 .playback = {
1469 .stream_name = "Playback", 1411 .stream_name = "Playback",
1470 .channels_min = 1, 1412 .channels_min = 1,
1471 .channels_max = 2, 1413 .channels_max = 5,
1472 .rates = TWL6040_RATES, 1414 .rates = TWL6040_RATES,
1473 .formats = TWL6040_FORMATS, 1415 .formats = TWL6040_FORMATS,
1474 }, 1416 },
@@ -1518,8 +1460,8 @@ static struct snd_soc_dai_driver twl6040_dai[] = {
1518 .name = "twl6040-vib", 1460 .name = "twl6040-vib",
1519 .playback = { 1461 .playback = {
1520 .stream_name = "Vibra Playback", 1462 .stream_name = "Vibra Playback",
1521 .channels_min = 2, 1463 .channels_min = 1,
1522 .channels_max = 2, 1464 .channels_max = 1,
1523 .rates = SNDRV_PCM_RATE_CONTINUOUS, 1465 .rates = SNDRV_PCM_RATE_CONTINUOUS,
1524 .formats = TWL6040_FORMATS, 1466 .formats = TWL6040_FORMATS,
1525 }, 1467 },
@@ -1562,6 +1504,7 @@ static int twl6040_probe(struct snd_soc_codec *codec)
1562 1504
1563 priv->codec = codec; 1505 priv->codec = codec;
1564 codec->control_data = dev_get_drvdata(codec->dev->parent); 1506 codec->control_data = dev_get_drvdata(codec->dev->parent);
1507 codec->ignore_pmdown_time = 1;
1565 1508
1566 if (pdata && pdata->hs_left_step && pdata->hs_right_step) { 1509 if (pdata && pdata->hs_left_step && pdata->hs_right_step) {
1567 priv->hs_left_step = pdata->hs_left_step; 1510 priv->hs_left_step = pdata->hs_left_step;
@@ -1586,33 +1529,21 @@ static int twl6040_probe(struct snd_soc_codec *codec)
1586 goto work_err; 1529 goto work_err;
1587 } 1530 }
1588 1531
1589 priv->workqueue = create_singlethread_workqueue("twl6040-codec"); 1532 priv->workqueue = alloc_workqueue("twl6040-codec", 0, 0);
1590 if (!priv->workqueue) { 1533 if (!priv->workqueue) {
1591 ret = -ENOMEM; 1534 ret = -ENOMEM;
1592 goto work_err; 1535 goto work_err;
1593 } 1536 }
1594 1537
1595 INIT_DELAYED_WORK(&priv->delayed_work, twl6040_accessory_work); 1538 INIT_DELAYED_WORK(&priv->hs_jack.work, twl6040_accessory_work);
1539 INIT_DELAYED_WORK(&priv->headset.work, twl6040_pga_hs_work);
1540 INIT_DELAYED_WORK(&priv->handsfree.work, twl6040_pga_hf_work);
1596 1541
1597 mutex_init(&priv->mutex); 1542 mutex_init(&priv->mutex);
1598 1543
1599 init_completion(&priv->headset.ramp_done); 1544 init_completion(&priv->headset.ramp_done);
1600 init_completion(&priv->handsfree.ramp_done); 1545 init_completion(&priv->handsfree.ramp_done);
1601 1546
1602 priv->hf_workqueue = create_singlethread_workqueue("twl6040-hf");
1603 if (priv->hf_workqueue == NULL) {
1604 ret = -ENOMEM;
1605 goto hfwq_err;
1606 }
1607 priv->hs_workqueue = create_singlethread_workqueue("twl6040-hs");
1608 if (priv->hs_workqueue == NULL) {
1609 ret = -ENOMEM;
1610 goto hswq_err;
1611 }
1612
1613 INIT_DELAYED_WORK(&priv->hs_delayed_work, twl6040_pga_hs_work);
1614 INIT_DELAYED_WORK(&priv->hf_delayed_work, twl6040_pga_hf_work);
1615
1616 ret = request_threaded_irq(priv->plug_irq, NULL, twl6040_audio_handler, 1547 ret = request_threaded_irq(priv->plug_irq, NULL, twl6040_audio_handler,
1617 0, "twl6040_irq_plug", codec); 1548 0, "twl6040_irq_plug", codec);
1618 if (ret) { 1549 if (ret) {
@@ -1620,27 +1551,16 @@ static int twl6040_probe(struct snd_soc_codec *codec)
1620 goto plugirq_err; 1551 goto plugirq_err;
1621 } 1552 }
1622 1553
1623 /* init vio registers */ 1554 twl6040_init_chip(codec);
1624 twl6040_init_vio_regs(codec);
1625 1555
1626 /* power on device */ 1556 /* power on device */
1627 ret = twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1557 ret = twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1628 if (ret) 1558 if (!ret)
1629 goto bias_err; 1559 return 0;
1630
1631 snd_soc_add_controls(codec, twl6040_snd_controls,
1632 ARRAY_SIZE(twl6040_snd_controls));
1633 twl6040_add_widgets(codec);
1634
1635 return 0;
1636 1560
1637bias_err: 1561 /* Error path */
1638 free_irq(priv->plug_irq, codec); 1562 free_irq(priv->plug_irq, codec);
1639plugirq_err: 1563plugirq_err:
1640 destroy_workqueue(priv->hs_workqueue);
1641hswq_err:
1642 destroy_workqueue(priv->hf_workqueue);
1643hfwq_err:
1644 destroy_workqueue(priv->workqueue); 1564 destroy_workqueue(priv->workqueue);
1645work_err: 1565work_err:
1646 kfree(priv); 1566 kfree(priv);
@@ -1654,8 +1574,6 @@ static int twl6040_remove(struct snd_soc_codec *codec)
1654 twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF); 1574 twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF);
1655 free_irq(priv->plug_irq, codec); 1575 free_irq(priv->plug_irq, codec);
1656 destroy_workqueue(priv->workqueue); 1576 destroy_workqueue(priv->workqueue);
1657 destroy_workqueue(priv->hf_workqueue);
1658 destroy_workqueue(priv->hs_workqueue);
1659 kfree(priv); 1577 kfree(priv);
1660 1578
1661 return 0; 1579 return 0;
@@ -1672,6 +1590,13 @@ static struct snd_soc_codec_driver soc_codec_dev_twl6040 = {
1672 .reg_cache_size = ARRAY_SIZE(twl6040_reg), 1590 .reg_cache_size = ARRAY_SIZE(twl6040_reg),
1673 .reg_word_size = sizeof(u8), 1591 .reg_word_size = sizeof(u8),
1674 .reg_cache_default = twl6040_reg, 1592 .reg_cache_default = twl6040_reg,
1593
1594 .controls = twl6040_snd_controls,
1595 .num_controls = ARRAY_SIZE(twl6040_snd_controls),
1596 .dapm_widgets = twl6040_dapm_widgets,
1597 .num_dapm_widgets = ARRAY_SIZE(twl6040_dapm_widgets),
1598 .dapm_routes = intercon,
1599 .num_dapm_routes = ARRAY_SIZE(intercon),
1675}; 1600};
1676 1601
1677static int __devinit twl6040_codec_probe(struct platform_device *pdev) 1602static int __devinit twl6040_codec_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/twl6040.h b/sound/soc/codecs/twl6040.h
index d8de67869dd..a83277bdb85 100644
--- a/sound/soc/codecs/twl6040.h
+++ b/sound/soc/codecs/twl6040.h
@@ -22,8 +22,21 @@
22#ifndef __TWL6040_H__ 22#ifndef __TWL6040_H__
23#define __TWL6040_H__ 23#define __TWL6040_H__
24 24
25enum twl6040_trim {
26 TWL6040_TRIM_TRIM1 = 0,
27 TWL6040_TRIM_TRIM2,
28 TWL6040_TRIM_TRIM3,
29 TWL6040_TRIM_HSOTRIM,
30 TWL6040_TRIM_HFOTRIM,
31 TWL6040_TRIM_INVAL,
32};
33
34#define TWL6040_HSF_TRIM_LEFT(x) (x & 0x0f)
35#define TWL6040_HSF_TRIM_RIGHT(x) ((x >> 4) & 0x0f)
36
25void twl6040_hs_jack_detect(struct snd_soc_codec *codec, 37void twl6040_hs_jack_detect(struct snd_soc_codec *codec,
26 struct snd_soc_jack *jack, int report); 38 struct snd_soc_jack *jack, int report);
27int twl6040_get_clk_id(struct snd_soc_codec *codec); 39int twl6040_get_clk_id(struct snd_soc_codec *codec);
40int twl6040_get_trim_value(struct snd_soc_codec *codec, enum twl6040_trim trim);
28 41
29#endif /* End of __TWL6040_H__ */ 42#endif /* End of __TWL6040_H__ */
diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c
index 5836201834d..9fa14299cf2 100644
--- a/sound/soc/codecs/wl1273.c
+++ b/sound/soc/codecs/wl1273.c
@@ -462,7 +462,6 @@ static int wl1273_probe(struct snd_soc_codec *codec)
462 wl1273->core = *core; 462 wl1273->core = *core;
463 463
464 snd_soc_codec_set_drvdata(codec, wl1273); 464 snd_soc_codec_set_drvdata(codec, wl1273);
465 mutex_init(&codec->mutex);
466 465
467 r = snd_soc_add_controls(codec, wl1273_controls, 466 r = snd_soc_add_controls(codec, wl1273_controls,
468 ARRAY_SIZE(wl1273_controls)); 467 ARRAY_SIZE(wl1273_controls));
diff --git a/sound/soc/codecs/wm1250-ev1.c b/sound/soc/codecs/wm1250-ev1.c
index bcc20896791..cd0ec0fd1db 100644
--- a/sound/soc/codecs/wm1250-ev1.c
+++ b/sound/soc/codecs/wm1250-ev1.c
@@ -12,10 +12,59 @@
12 12
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/slab.h>
15#include <linux/i2c.h> 16#include <linux/i2c.h>
17#include <linux/gpio.h>
16 18
17#include <sound/soc.h> 19#include <sound/soc.h>
18#include <sound/soc-dapm.h> 20#include <sound/soc-dapm.h>
21#include <sound/wm1250-ev1.h>
22
23static const char *wm1250_gpio_names[WM1250_EV1_NUM_GPIOS] = {
24 "WM1250 CLK_ENA",
25 "WM1250 CLK_SEL0",
26 "WM1250 CLK_SEL1",
27 "WM1250 OSR",
28 "WM1250 MASTER",
29};
30
31struct wm1250_priv {
32 struct gpio gpios[WM1250_EV1_NUM_GPIOS];
33};
34
35static int wm1250_ev1_set_bias_level(struct snd_soc_codec *codec,
36 enum snd_soc_bias_level level)
37{
38 struct wm1250_priv *wm1250 = dev_get_drvdata(codec->dev);
39 int ena;
40
41 if (wm1250)
42 ena = wm1250->gpios[WM1250_EV1_GPIO_CLK_ENA].gpio;
43 else
44 ena = -1;
45
46 switch (level) {
47 case SND_SOC_BIAS_ON:
48 break;
49
50 case SND_SOC_BIAS_PREPARE:
51 break;
52
53 case SND_SOC_BIAS_STANDBY:
54 if (ena >= 0)
55 gpio_set_value_cansleep(ena, 1);
56 break;
57
58 case SND_SOC_BIAS_OFF:
59 if (ena >= 0)
60 gpio_set_value_cansleep(ena, 0);
61 break;
62 }
63
64 codec->dapm.bias_level = level;
65
66 return 0;
67}
19 68
20static const struct snd_soc_dapm_widget wm1250_ev1_dapm_widgets[] = { 69static const struct snd_soc_dapm_widget wm1250_ev1_dapm_widgets[] = {
21SND_SOC_DAPM_ADC("ADC", "wm1250-ev1 Capture", SND_SOC_NOPM, 0, 0), 70SND_SOC_DAPM_ADC("ADC", "wm1250-ev1 Capture", SND_SOC_NOPM, 0, 0),
@@ -53,18 +102,103 @@ static struct snd_soc_codec_driver soc_codec_dev_wm1250_ev1 = {
53 .num_dapm_widgets = ARRAY_SIZE(wm1250_ev1_dapm_widgets), 102 .num_dapm_widgets = ARRAY_SIZE(wm1250_ev1_dapm_widgets),
54 .dapm_routes = wm1250_ev1_dapm_routes, 103 .dapm_routes = wm1250_ev1_dapm_routes,
55 .num_dapm_routes = ARRAY_SIZE(wm1250_ev1_dapm_routes), 104 .num_dapm_routes = ARRAY_SIZE(wm1250_ev1_dapm_routes),
105
106 .set_bias_level = wm1250_ev1_set_bias_level,
107 .idle_bias_off = true,
56}; 108};
57 109
110static int __devinit wm1250_ev1_pdata(struct i2c_client *i2c)
111{
112 struct wm1250_ev1_pdata *pdata = dev_get_platdata(&i2c->dev);
113 struct wm1250_priv *wm1250;
114 int i, ret;
115
116 if (!pdata)
117 return 0;
118
119 wm1250 = kzalloc(sizeof(*wm1250), GFP_KERNEL);
120 if (!wm1250) {
121 dev_err(&i2c->dev, "Unable to allocate private data\n");
122 ret = -ENOMEM;
123 goto err;
124 }
125
126 for (i = 0; i < ARRAY_SIZE(wm1250->gpios); i++) {
127 wm1250->gpios[i].gpio = pdata->gpios[i];
128 wm1250->gpios[i].label = wm1250_gpio_names[i];
129 wm1250->gpios[i].flags = GPIOF_OUT_INIT_LOW;
130 }
131 wm1250->gpios[WM1250_EV1_GPIO_CLK_SEL0].flags = GPIOF_OUT_INIT_HIGH;
132 wm1250->gpios[WM1250_EV1_GPIO_CLK_SEL1].flags = GPIOF_OUT_INIT_HIGH;
133
134 ret = gpio_request_array(wm1250->gpios, ARRAY_SIZE(wm1250->gpios));
135 if (ret != 0) {
136 dev_err(&i2c->dev, "Failed to get GPIOs: %d\n", ret);
137 goto err_alloc;
138 }
139
140 dev_set_drvdata(&i2c->dev, wm1250);
141
142 return ret;
143
144err_alloc:
145 kfree(wm1250);
146err:
147 return ret;
148}
149
150static void wm1250_ev1_free(struct i2c_client *i2c)
151{
152 struct wm1250_priv *wm1250 = dev_get_drvdata(&i2c->dev);
153
154 if (wm1250) {
155 gpio_free_array(wm1250->gpios, ARRAY_SIZE(wm1250->gpios));
156 kfree(wm1250);
157 }
158}
159
58static int __devinit wm1250_ev1_probe(struct i2c_client *i2c, 160static int __devinit wm1250_ev1_probe(struct i2c_client *i2c,
59 const struct i2c_device_id *id) 161 const struct i2c_device_id *i2c_id)
60{ 162{
61 return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm1250_ev1, 163 int id, board, rev, ret;
62 &wm1250_ev1_dai, 1); 164
165 dev_set_drvdata(&i2c->dev, NULL);
166
167 board = i2c_smbus_read_byte_data(i2c, 0);
168 if (board < 0) {
169 dev_err(&i2c->dev, "Failed to read ID: %d\n", board);
170 return board;
171 }
172
173 id = (board & 0xfe) >> 2;
174 rev = board & 0x3;
175
176 if (id != 1) {
177 dev_err(&i2c->dev, "Unknown board ID %d\n", id);
178 return -ENODEV;
179 }
180
181 dev_info(&i2c->dev, "revision %d\n", rev + 1);
182
183 ret = wm1250_ev1_pdata(i2c);
184 if (ret != 0)
185 return ret;
186
187 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm1250_ev1,
188 &wm1250_ev1_dai, 1);
189 if (ret != 0) {
190 dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
191 wm1250_ev1_free(i2c);
192 return ret;
193 }
194
195 return 0;
63} 196}
64 197
65static int __devexit wm1250_ev1_remove(struct i2c_client *i2c) 198static int __devexit wm1250_ev1_remove(struct i2c_client *i2c)
66{ 199{
67 snd_soc_unregister_codec(&i2c->dev); 200 snd_soc_unregister_codec(&i2c->dev);
201 wm1250_ev1_free(i2c);
68 202
69 return 0; 203 return 0;
70} 204}
diff --git a/sound/soc/codecs/wm5100-tables.c b/sound/soc/codecs/wm5100-tables.c
new file mode 100644
index 00000000000..e9ce81a57b8
--- /dev/null
+++ b/sound/soc/codecs/wm5100-tables.c
@@ -0,0 +1,1531 @@
1/*
2 * wm5100-tables.c -- WM5100 ALSA SoC Audio driver data
3 *
4 * Copyright 2011 Wolfson Microelectronics plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include "wm5100.h"
15
16int wm5100_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
17{
18 switch (reg) {
19 case WM5100_SOFTWARE_RESET:
20 case WM5100_DEVICE_REVISION:
21 case WM5100_FX_CTRL:
22 case WM5100_INTERRUPT_STATUS_1:
23 case WM5100_INTERRUPT_STATUS_2:
24 case WM5100_INTERRUPT_STATUS_3:
25 case WM5100_INTERRUPT_STATUS_4:
26 case WM5100_INTERRUPT_RAW_STATUS_2:
27 case WM5100_INTERRUPT_RAW_STATUS_3:
28 case WM5100_INTERRUPT_RAW_STATUS_4:
29 case WM5100_OUTPUT_STATUS_1:
30 case WM5100_OUTPUT_STATUS_2:
31 case WM5100_INPUT_ENABLES_STATUS:
32 case WM5100_MIC_DETECT_3:
33 return 1;
34 default:
35 return 0;
36 }
37}
38
39int wm5100_readable_register(struct snd_soc_codec *codec, unsigned int reg)
40{
41 switch (reg) {
42 case WM5100_SOFTWARE_RESET:
43 case WM5100_DEVICE_REVISION:
44 case WM5100_CTRL_IF_1:
45 case WM5100_TONE_GENERATOR_1:
46 case WM5100_PWM_DRIVE_1:
47 case WM5100_PWM_DRIVE_2:
48 case WM5100_PWM_DRIVE_3:
49 case WM5100_CLOCKING_1:
50 case WM5100_CLOCKING_3:
51 case WM5100_CLOCKING_4:
52 case WM5100_CLOCKING_5:
53 case WM5100_CLOCKING_6:
54 case WM5100_CLOCKING_7:
55 case WM5100_CLOCKING_8:
56 case WM5100_ASRC_ENABLE:
57 case WM5100_ASRC_STATUS:
58 case WM5100_ASRC_RATE1:
59 case WM5100_ISRC_1_CTRL_1:
60 case WM5100_ISRC_1_CTRL_2:
61 case WM5100_ISRC_2_CTRL1:
62 case WM5100_ISRC_2_CTRL_2:
63 case WM5100_FLL1_CONTROL_1:
64 case WM5100_FLL1_CONTROL_2:
65 case WM5100_FLL1_CONTROL_3:
66 case WM5100_FLL1_CONTROL_5:
67 case WM5100_FLL1_CONTROL_6:
68 case WM5100_FLL1_EFS_1:
69 case WM5100_FLL2_CONTROL_1:
70 case WM5100_FLL2_CONTROL_2:
71 case WM5100_FLL2_CONTROL_3:
72 case WM5100_FLL2_CONTROL_5:
73 case WM5100_FLL2_CONTROL_6:
74 case WM5100_FLL2_EFS_1:
75 case WM5100_MIC_CHARGE_PUMP_1:
76 case WM5100_MIC_CHARGE_PUMP_2:
77 case WM5100_HP_CHARGE_PUMP_1:
78 case WM5100_LDO1_CONTROL:
79 case WM5100_MIC_BIAS_CTRL_1:
80 case WM5100_MIC_BIAS_CTRL_2:
81 case WM5100_MIC_BIAS_CTRL_3:
82 case WM5100_ACCESSORY_DETECT_MODE_1:
83 case WM5100_HEADPHONE_DETECT_1:
84 case WM5100_HEADPHONE_DETECT_2:
85 case WM5100_MIC_DETECT_1:
86 case WM5100_MIC_DETECT_2:
87 case WM5100_MIC_DETECT_3:
88 case WM5100_INPUT_ENABLES:
89 case WM5100_INPUT_ENABLES_STATUS:
90 case WM5100_IN1L_CONTROL:
91 case WM5100_IN1R_CONTROL:
92 case WM5100_IN2L_CONTROL:
93 case WM5100_IN2R_CONTROL:
94 case WM5100_IN3L_CONTROL:
95 case WM5100_IN3R_CONTROL:
96 case WM5100_IN4L_CONTROL:
97 case WM5100_IN4R_CONTROL:
98 case WM5100_RXANC_SRC:
99 case WM5100_INPUT_VOLUME_RAMP:
100 case WM5100_ADC_DIGITAL_VOLUME_1L:
101 case WM5100_ADC_DIGITAL_VOLUME_1R:
102 case WM5100_ADC_DIGITAL_VOLUME_2L:
103 case WM5100_ADC_DIGITAL_VOLUME_2R:
104 case WM5100_ADC_DIGITAL_VOLUME_3L:
105 case WM5100_ADC_DIGITAL_VOLUME_3R:
106 case WM5100_ADC_DIGITAL_VOLUME_4L:
107 case WM5100_ADC_DIGITAL_VOLUME_4R:
108 case WM5100_OUTPUT_ENABLES_2:
109 case WM5100_OUTPUT_STATUS_1:
110 case WM5100_OUTPUT_STATUS_2:
111 case WM5100_CHANNEL_ENABLES_1:
112 case WM5100_OUT_VOLUME_1L:
113 case WM5100_OUT_VOLUME_1R:
114 case WM5100_DAC_VOLUME_LIMIT_1L:
115 case WM5100_DAC_VOLUME_LIMIT_1R:
116 case WM5100_OUT_VOLUME_2L:
117 case WM5100_OUT_VOLUME_2R:
118 case WM5100_DAC_VOLUME_LIMIT_2L:
119 case WM5100_DAC_VOLUME_LIMIT_2R:
120 case WM5100_OUT_VOLUME_3L:
121 case WM5100_OUT_VOLUME_3R:
122 case WM5100_DAC_VOLUME_LIMIT_3L:
123 case WM5100_DAC_VOLUME_LIMIT_3R:
124 case WM5100_OUT_VOLUME_4L:
125 case WM5100_OUT_VOLUME_4R:
126 case WM5100_DAC_VOLUME_LIMIT_5L:
127 case WM5100_DAC_VOLUME_LIMIT_5R:
128 case WM5100_DAC_VOLUME_LIMIT_6L:
129 case WM5100_DAC_VOLUME_LIMIT_6R:
130 case WM5100_DAC_AEC_CONTROL_1:
131 case WM5100_OUTPUT_VOLUME_RAMP:
132 case WM5100_DAC_DIGITAL_VOLUME_1L:
133 case WM5100_DAC_DIGITAL_VOLUME_1R:
134 case WM5100_DAC_DIGITAL_VOLUME_2L:
135 case WM5100_DAC_DIGITAL_VOLUME_2R:
136 case WM5100_DAC_DIGITAL_VOLUME_3L:
137 case WM5100_DAC_DIGITAL_VOLUME_3R:
138 case WM5100_DAC_DIGITAL_VOLUME_4L:
139 case WM5100_DAC_DIGITAL_VOLUME_4R:
140 case WM5100_DAC_DIGITAL_VOLUME_5L:
141 case WM5100_DAC_DIGITAL_VOLUME_5R:
142 case WM5100_DAC_DIGITAL_VOLUME_6L:
143 case WM5100_DAC_DIGITAL_VOLUME_6R:
144 case WM5100_PDM_SPK1_CTRL_1:
145 case WM5100_PDM_SPK1_CTRL_2:
146 case WM5100_PDM_SPK2_CTRL_1:
147 case WM5100_PDM_SPK2_CTRL_2:
148 case WM5100_AUDIO_IF_1_1:
149 case WM5100_AUDIO_IF_1_2:
150 case WM5100_AUDIO_IF_1_3:
151 case WM5100_AUDIO_IF_1_4:
152 case WM5100_AUDIO_IF_1_5:
153 case WM5100_AUDIO_IF_1_6:
154 case WM5100_AUDIO_IF_1_7:
155 case WM5100_AUDIO_IF_1_8:
156 case WM5100_AUDIO_IF_1_9:
157 case WM5100_AUDIO_IF_1_10:
158 case WM5100_AUDIO_IF_1_11:
159 case WM5100_AUDIO_IF_1_12:
160 case WM5100_AUDIO_IF_1_13:
161 case WM5100_AUDIO_IF_1_14:
162 case WM5100_AUDIO_IF_1_15:
163 case WM5100_AUDIO_IF_1_16:
164 case WM5100_AUDIO_IF_1_17:
165 case WM5100_AUDIO_IF_1_18:
166 case WM5100_AUDIO_IF_1_19:
167 case WM5100_AUDIO_IF_1_20:
168 case WM5100_AUDIO_IF_1_21:
169 case WM5100_AUDIO_IF_1_22:
170 case WM5100_AUDIO_IF_1_23:
171 case WM5100_AUDIO_IF_1_24:
172 case WM5100_AUDIO_IF_1_25:
173 case WM5100_AUDIO_IF_1_26:
174 case WM5100_AUDIO_IF_1_27:
175 case WM5100_AUDIO_IF_2_1:
176 case WM5100_AUDIO_IF_2_2:
177 case WM5100_AUDIO_IF_2_3:
178 case WM5100_AUDIO_IF_2_4:
179 case WM5100_AUDIO_IF_2_5:
180 case WM5100_AUDIO_IF_2_6:
181 case WM5100_AUDIO_IF_2_7:
182 case WM5100_AUDIO_IF_2_8:
183 case WM5100_AUDIO_IF_2_9:
184 case WM5100_AUDIO_IF_2_10:
185 case WM5100_AUDIO_IF_2_11:
186 case WM5100_AUDIO_IF_2_18:
187 case WM5100_AUDIO_IF_2_19:
188 case WM5100_AUDIO_IF_2_26:
189 case WM5100_AUDIO_IF_2_27:
190 case WM5100_AUDIO_IF_3_1:
191 case WM5100_AUDIO_IF_3_2:
192 case WM5100_AUDIO_IF_3_3:
193 case WM5100_AUDIO_IF_3_4:
194 case WM5100_AUDIO_IF_3_5:
195 case WM5100_AUDIO_IF_3_6:
196 case WM5100_AUDIO_IF_3_7:
197 case WM5100_AUDIO_IF_3_8:
198 case WM5100_AUDIO_IF_3_9:
199 case WM5100_AUDIO_IF_3_10:
200 case WM5100_AUDIO_IF_3_11:
201 case WM5100_AUDIO_IF_3_18:
202 case WM5100_AUDIO_IF_3_19:
203 case WM5100_AUDIO_IF_3_26:
204 case WM5100_AUDIO_IF_3_27:
205 case WM5100_PWM1MIX_INPUT_1_SOURCE:
206 case WM5100_PWM1MIX_INPUT_1_VOLUME:
207 case WM5100_PWM1MIX_INPUT_2_SOURCE:
208 case WM5100_PWM1MIX_INPUT_2_VOLUME:
209 case WM5100_PWM1MIX_INPUT_3_SOURCE:
210 case WM5100_PWM1MIX_INPUT_3_VOLUME:
211 case WM5100_PWM1MIX_INPUT_4_SOURCE:
212 case WM5100_PWM1MIX_INPUT_4_VOLUME:
213 case WM5100_PWM2MIX_INPUT_1_SOURCE:
214 case WM5100_PWM2MIX_INPUT_1_VOLUME:
215 case WM5100_PWM2MIX_INPUT_2_SOURCE:
216 case WM5100_PWM2MIX_INPUT_2_VOLUME:
217 case WM5100_PWM2MIX_INPUT_3_SOURCE:
218 case WM5100_PWM2MIX_INPUT_3_VOLUME:
219 case WM5100_PWM2MIX_INPUT_4_SOURCE:
220 case WM5100_PWM2MIX_INPUT_4_VOLUME:
221 case WM5100_OUT1LMIX_INPUT_1_SOURCE:
222 case WM5100_OUT1LMIX_INPUT_1_VOLUME:
223 case WM5100_OUT1LMIX_INPUT_2_SOURCE:
224 case WM5100_OUT1LMIX_INPUT_2_VOLUME:
225 case WM5100_OUT1LMIX_INPUT_3_SOURCE:
226 case WM5100_OUT1LMIX_INPUT_3_VOLUME:
227 case WM5100_OUT1LMIX_INPUT_4_SOURCE:
228 case WM5100_OUT1LMIX_INPUT_4_VOLUME:
229 case WM5100_OUT1RMIX_INPUT_1_SOURCE:
230 case WM5100_OUT1RMIX_INPUT_1_VOLUME:
231 case WM5100_OUT1RMIX_INPUT_2_SOURCE:
232 case WM5100_OUT1RMIX_INPUT_2_VOLUME:
233 case WM5100_OUT1RMIX_INPUT_3_SOURCE:
234 case WM5100_OUT1RMIX_INPUT_3_VOLUME:
235 case WM5100_OUT1RMIX_INPUT_4_SOURCE:
236 case WM5100_OUT1RMIX_INPUT_4_VOLUME:
237 case WM5100_OUT2LMIX_INPUT_1_SOURCE:
238 case WM5100_OUT2LMIX_INPUT_1_VOLUME:
239 case WM5100_OUT2LMIX_INPUT_2_SOURCE:
240 case WM5100_OUT2LMIX_INPUT_2_VOLUME:
241 case WM5100_OUT2LMIX_INPUT_3_SOURCE:
242 case WM5100_OUT2LMIX_INPUT_3_VOLUME:
243 case WM5100_OUT2LMIX_INPUT_4_SOURCE:
244 case WM5100_OUT2LMIX_INPUT_4_VOLUME:
245 case WM5100_OUT2RMIX_INPUT_1_SOURCE:
246 case WM5100_OUT2RMIX_INPUT_1_VOLUME:
247 case WM5100_OUT2RMIX_INPUT_2_SOURCE:
248 case WM5100_OUT2RMIX_INPUT_2_VOLUME:
249 case WM5100_OUT2RMIX_INPUT_3_SOURCE:
250 case WM5100_OUT2RMIX_INPUT_3_VOLUME:
251 case WM5100_OUT2RMIX_INPUT_4_SOURCE:
252 case WM5100_OUT2RMIX_INPUT_4_VOLUME:
253 case WM5100_OUT3LMIX_INPUT_1_SOURCE:
254 case WM5100_OUT3LMIX_INPUT_1_VOLUME:
255 case WM5100_OUT3LMIX_INPUT_2_SOURCE:
256 case WM5100_OUT3LMIX_INPUT_2_VOLUME:
257 case WM5100_OUT3LMIX_INPUT_3_SOURCE:
258 case WM5100_OUT3LMIX_INPUT_3_VOLUME:
259 case WM5100_OUT3LMIX_INPUT_4_SOURCE:
260 case WM5100_OUT3LMIX_INPUT_4_VOLUME:
261 case WM5100_OUT3RMIX_INPUT_1_SOURCE:
262 case WM5100_OUT3RMIX_INPUT_1_VOLUME:
263 case WM5100_OUT3RMIX_INPUT_2_SOURCE:
264 case WM5100_OUT3RMIX_INPUT_2_VOLUME:
265 case WM5100_OUT3RMIX_INPUT_3_SOURCE:
266 case WM5100_OUT3RMIX_INPUT_3_VOLUME:
267 case WM5100_OUT3RMIX_INPUT_4_SOURCE:
268 case WM5100_OUT3RMIX_INPUT_4_VOLUME:
269 case WM5100_OUT4LMIX_INPUT_1_SOURCE:
270 case WM5100_OUT4LMIX_INPUT_1_VOLUME:
271 case WM5100_OUT4LMIX_INPUT_2_SOURCE:
272 case WM5100_OUT4LMIX_INPUT_2_VOLUME:
273 case WM5100_OUT4LMIX_INPUT_3_SOURCE:
274 case WM5100_OUT4LMIX_INPUT_3_VOLUME:
275 case WM5100_OUT4LMIX_INPUT_4_SOURCE:
276 case WM5100_OUT4LMIX_INPUT_4_VOLUME:
277 case WM5100_OUT4RMIX_INPUT_1_SOURCE:
278 case WM5100_OUT4RMIX_INPUT_1_VOLUME:
279 case WM5100_OUT4RMIX_INPUT_2_SOURCE:
280 case WM5100_OUT4RMIX_INPUT_2_VOLUME:
281 case WM5100_OUT4RMIX_INPUT_3_SOURCE:
282 case WM5100_OUT4RMIX_INPUT_3_VOLUME:
283 case WM5100_OUT4RMIX_INPUT_4_SOURCE:
284 case WM5100_OUT4RMIX_INPUT_4_VOLUME:
285 case WM5100_OUT5LMIX_INPUT_1_SOURCE:
286 case WM5100_OUT5LMIX_INPUT_1_VOLUME:
287 case WM5100_OUT5LMIX_INPUT_2_SOURCE:
288 case WM5100_OUT5LMIX_INPUT_2_VOLUME:
289 case WM5100_OUT5LMIX_INPUT_3_SOURCE:
290 case WM5100_OUT5LMIX_INPUT_3_VOLUME:
291 case WM5100_OUT5LMIX_INPUT_4_SOURCE:
292 case WM5100_OUT5LMIX_INPUT_4_VOLUME:
293 case WM5100_OUT5RMIX_INPUT_1_SOURCE:
294 case WM5100_OUT5RMIX_INPUT_1_VOLUME:
295 case WM5100_OUT5RMIX_INPUT_2_SOURCE:
296 case WM5100_OUT5RMIX_INPUT_2_VOLUME:
297 case WM5100_OUT5RMIX_INPUT_3_SOURCE:
298 case WM5100_OUT5RMIX_INPUT_3_VOLUME:
299 case WM5100_OUT5RMIX_INPUT_4_SOURCE:
300 case WM5100_OUT5RMIX_INPUT_4_VOLUME:
301 case WM5100_OUT6LMIX_INPUT_1_SOURCE:
302 case WM5100_OUT6LMIX_INPUT_1_VOLUME:
303 case WM5100_OUT6LMIX_INPUT_2_SOURCE:
304 case WM5100_OUT6LMIX_INPUT_2_VOLUME:
305 case WM5100_OUT6LMIX_INPUT_3_SOURCE:
306 case WM5100_OUT6LMIX_INPUT_3_VOLUME:
307 case WM5100_OUT6LMIX_INPUT_4_SOURCE:
308 case WM5100_OUT6LMIX_INPUT_4_VOLUME:
309 case WM5100_OUT6RMIX_INPUT_1_SOURCE:
310 case WM5100_OUT6RMIX_INPUT_1_VOLUME:
311 case WM5100_OUT6RMIX_INPUT_2_SOURCE:
312 case WM5100_OUT6RMIX_INPUT_2_VOLUME:
313 case WM5100_OUT6RMIX_INPUT_3_SOURCE:
314 case WM5100_OUT6RMIX_INPUT_3_VOLUME:
315 case WM5100_OUT6RMIX_INPUT_4_SOURCE:
316 case WM5100_OUT6RMIX_INPUT_4_VOLUME:
317 case WM5100_AIF1TX1MIX_INPUT_1_SOURCE:
318 case WM5100_AIF1TX1MIX_INPUT_1_VOLUME:
319 case WM5100_AIF1TX1MIX_INPUT_2_SOURCE:
320 case WM5100_AIF1TX1MIX_INPUT_2_VOLUME:
321 case WM5100_AIF1TX1MIX_INPUT_3_SOURCE:
322 case WM5100_AIF1TX1MIX_INPUT_3_VOLUME:
323 case WM5100_AIF1TX1MIX_INPUT_4_SOURCE:
324 case WM5100_AIF1TX1MIX_INPUT_4_VOLUME:
325 case WM5100_AIF1TX2MIX_INPUT_1_SOURCE:
326 case WM5100_AIF1TX2MIX_INPUT_1_VOLUME:
327 case WM5100_AIF1TX2MIX_INPUT_2_SOURCE:
328 case WM5100_AIF1TX2MIX_INPUT_2_VOLUME:
329 case WM5100_AIF1TX2MIX_INPUT_3_SOURCE:
330 case WM5100_AIF1TX2MIX_INPUT_3_VOLUME:
331 case WM5100_AIF1TX2MIX_INPUT_4_SOURCE:
332 case WM5100_AIF1TX2MIX_INPUT_4_VOLUME:
333 case WM5100_AIF1TX3MIX_INPUT_1_SOURCE:
334 case WM5100_AIF1TX3MIX_INPUT_1_VOLUME:
335 case WM5100_AIF1TX3MIX_INPUT_2_SOURCE:
336 case WM5100_AIF1TX3MIX_INPUT_2_VOLUME:
337 case WM5100_AIF1TX3MIX_INPUT_3_SOURCE:
338 case WM5100_AIF1TX3MIX_INPUT_3_VOLUME:
339 case WM5100_AIF1TX3MIX_INPUT_4_SOURCE:
340 case WM5100_AIF1TX3MIX_INPUT_4_VOLUME:
341 case WM5100_AIF1TX4MIX_INPUT_1_SOURCE:
342 case WM5100_AIF1TX4MIX_INPUT_1_VOLUME:
343 case WM5100_AIF1TX4MIX_INPUT_2_SOURCE:
344 case WM5100_AIF1TX4MIX_INPUT_2_VOLUME:
345 case WM5100_AIF1TX4MIX_INPUT_3_SOURCE:
346 case WM5100_AIF1TX4MIX_INPUT_3_VOLUME:
347 case WM5100_AIF1TX4MIX_INPUT_4_SOURCE:
348 case WM5100_AIF1TX4MIX_INPUT_4_VOLUME:
349 case WM5100_AIF1TX5MIX_INPUT_1_SOURCE:
350 case WM5100_AIF1TX5MIX_INPUT_1_VOLUME:
351 case WM5100_AIF1TX5MIX_INPUT_2_SOURCE:
352 case WM5100_AIF1TX5MIX_INPUT_2_VOLUME:
353 case WM5100_AIF1TX5MIX_INPUT_3_SOURCE:
354 case WM5100_AIF1TX5MIX_INPUT_3_VOLUME:
355 case WM5100_AIF1TX5MIX_INPUT_4_SOURCE:
356 case WM5100_AIF1TX5MIX_INPUT_4_VOLUME:
357 case WM5100_AIF1TX6MIX_INPUT_1_SOURCE:
358 case WM5100_AIF1TX6MIX_INPUT_1_VOLUME:
359 case WM5100_AIF1TX6MIX_INPUT_2_SOURCE:
360 case WM5100_AIF1TX6MIX_INPUT_2_VOLUME:
361 case WM5100_AIF1TX6MIX_INPUT_3_SOURCE:
362 case WM5100_AIF1TX6MIX_INPUT_3_VOLUME:
363 case WM5100_AIF1TX6MIX_INPUT_4_SOURCE:
364 case WM5100_AIF1TX6MIX_INPUT_4_VOLUME:
365 case WM5100_AIF1TX7MIX_INPUT_1_SOURCE:
366 case WM5100_AIF1TX7MIX_INPUT_1_VOLUME:
367 case WM5100_AIF1TX7MIX_INPUT_2_SOURCE:
368 case WM5100_AIF1TX7MIX_INPUT_2_VOLUME:
369 case WM5100_AIF1TX7MIX_INPUT_3_SOURCE:
370 case WM5100_AIF1TX7MIX_INPUT_3_VOLUME:
371 case WM5100_AIF1TX7MIX_INPUT_4_SOURCE:
372 case WM5100_AIF1TX7MIX_INPUT_4_VOLUME:
373 case WM5100_AIF1TX8MIX_INPUT_1_SOURCE:
374 case WM5100_AIF1TX8MIX_INPUT_1_VOLUME:
375 case WM5100_AIF1TX8MIX_INPUT_2_SOURCE:
376 case WM5100_AIF1TX8MIX_INPUT_2_VOLUME:
377 case WM5100_AIF1TX8MIX_INPUT_3_SOURCE:
378 case WM5100_AIF1TX8MIX_INPUT_3_VOLUME:
379 case WM5100_AIF1TX8MIX_INPUT_4_SOURCE:
380 case WM5100_AIF1TX8MIX_INPUT_4_VOLUME:
381 case WM5100_AIF2TX1MIX_INPUT_1_SOURCE:
382 case WM5100_AIF2TX1MIX_INPUT_1_VOLUME:
383 case WM5100_AIF2TX1MIX_INPUT_2_SOURCE:
384 case WM5100_AIF2TX1MIX_INPUT_2_VOLUME:
385 case WM5100_AIF2TX1MIX_INPUT_3_SOURCE:
386 case WM5100_AIF2TX1MIX_INPUT_3_VOLUME:
387 case WM5100_AIF2TX1MIX_INPUT_4_SOURCE:
388 case WM5100_AIF2TX1MIX_INPUT_4_VOLUME:
389 case WM5100_AIF2TX2MIX_INPUT_1_SOURCE:
390 case WM5100_AIF2TX2MIX_INPUT_1_VOLUME:
391 case WM5100_AIF2TX2MIX_INPUT_2_SOURCE:
392 case WM5100_AIF2TX2MIX_INPUT_2_VOLUME:
393 case WM5100_AIF2TX2MIX_INPUT_3_SOURCE:
394 case WM5100_AIF2TX2MIX_INPUT_3_VOLUME:
395 case WM5100_AIF2TX2MIX_INPUT_4_SOURCE:
396 case WM5100_AIF2TX2MIX_INPUT_4_VOLUME:
397 case WM5100_AIF3TX1MIX_INPUT_1_SOURCE:
398 case WM5100_AIF3TX1MIX_INPUT_1_VOLUME:
399 case WM5100_AIF3TX1MIX_INPUT_2_SOURCE:
400 case WM5100_AIF3TX1MIX_INPUT_2_VOLUME:
401 case WM5100_AIF3TX1MIX_INPUT_3_SOURCE:
402 case WM5100_AIF3TX1MIX_INPUT_3_VOLUME:
403 case WM5100_AIF3TX1MIX_INPUT_4_SOURCE:
404 case WM5100_AIF3TX1MIX_INPUT_4_VOLUME:
405 case WM5100_AIF3TX2MIX_INPUT_1_SOURCE:
406 case WM5100_AIF3TX2MIX_INPUT_1_VOLUME:
407 case WM5100_AIF3TX2MIX_INPUT_2_SOURCE:
408 case WM5100_AIF3TX2MIX_INPUT_2_VOLUME:
409 case WM5100_AIF3TX2MIX_INPUT_3_SOURCE:
410 case WM5100_AIF3TX2MIX_INPUT_3_VOLUME:
411 case WM5100_AIF3TX2MIX_INPUT_4_SOURCE:
412 case WM5100_AIF3TX2MIX_INPUT_4_VOLUME:
413 case WM5100_EQ1MIX_INPUT_1_SOURCE:
414 case WM5100_EQ1MIX_INPUT_1_VOLUME:
415 case WM5100_EQ1MIX_INPUT_2_SOURCE:
416 case WM5100_EQ1MIX_INPUT_2_VOLUME:
417 case WM5100_EQ1MIX_INPUT_3_SOURCE:
418 case WM5100_EQ1MIX_INPUT_3_VOLUME:
419 case WM5100_EQ1MIX_INPUT_4_SOURCE:
420 case WM5100_EQ1MIX_INPUT_4_VOLUME:
421 case WM5100_EQ2MIX_INPUT_1_SOURCE:
422 case WM5100_EQ2MIX_INPUT_1_VOLUME:
423 case WM5100_EQ2MIX_INPUT_2_SOURCE:
424 case WM5100_EQ2MIX_INPUT_2_VOLUME:
425 case WM5100_EQ2MIX_INPUT_3_SOURCE:
426 case WM5100_EQ2MIX_INPUT_3_VOLUME:
427 case WM5100_EQ2MIX_INPUT_4_SOURCE:
428 case WM5100_EQ2MIX_INPUT_4_VOLUME:
429 case WM5100_EQ3MIX_INPUT_1_SOURCE:
430 case WM5100_EQ3MIX_INPUT_1_VOLUME:
431 case WM5100_EQ3MIX_INPUT_2_SOURCE:
432 case WM5100_EQ3MIX_INPUT_2_VOLUME:
433 case WM5100_EQ3MIX_INPUT_3_SOURCE:
434 case WM5100_EQ3MIX_INPUT_3_VOLUME:
435 case WM5100_EQ3MIX_INPUT_4_SOURCE:
436 case WM5100_EQ3MIX_INPUT_4_VOLUME:
437 case WM5100_EQ4MIX_INPUT_1_SOURCE:
438 case WM5100_EQ4MIX_INPUT_1_VOLUME:
439 case WM5100_EQ4MIX_INPUT_2_SOURCE:
440 case WM5100_EQ4MIX_INPUT_2_VOLUME:
441 case WM5100_EQ4MIX_INPUT_3_SOURCE:
442 case WM5100_EQ4MIX_INPUT_3_VOLUME:
443 case WM5100_EQ4MIX_INPUT_4_SOURCE:
444 case WM5100_EQ4MIX_INPUT_4_VOLUME:
445 case WM5100_DRC1LMIX_INPUT_1_SOURCE:
446 case WM5100_DRC1LMIX_INPUT_1_VOLUME:
447 case WM5100_DRC1LMIX_INPUT_2_SOURCE:
448 case WM5100_DRC1LMIX_INPUT_2_VOLUME:
449 case WM5100_DRC1LMIX_INPUT_3_SOURCE:
450 case WM5100_DRC1LMIX_INPUT_3_VOLUME:
451 case WM5100_DRC1LMIX_INPUT_4_SOURCE:
452 case WM5100_DRC1LMIX_INPUT_4_VOLUME:
453 case WM5100_DRC1RMIX_INPUT_1_SOURCE:
454 case WM5100_DRC1RMIX_INPUT_1_VOLUME:
455 case WM5100_DRC1RMIX_INPUT_2_SOURCE:
456 case WM5100_DRC1RMIX_INPUT_2_VOLUME:
457 case WM5100_DRC1RMIX_INPUT_3_SOURCE:
458 case WM5100_DRC1RMIX_INPUT_3_VOLUME:
459 case WM5100_DRC1RMIX_INPUT_4_SOURCE:
460 case WM5100_DRC1RMIX_INPUT_4_VOLUME:
461 case WM5100_HPLP1MIX_INPUT_1_SOURCE:
462 case WM5100_HPLP1MIX_INPUT_1_VOLUME:
463 case WM5100_HPLP1MIX_INPUT_2_SOURCE:
464 case WM5100_HPLP1MIX_INPUT_2_VOLUME:
465 case WM5100_HPLP1MIX_INPUT_3_SOURCE:
466 case WM5100_HPLP1MIX_INPUT_3_VOLUME:
467 case WM5100_HPLP1MIX_INPUT_4_SOURCE:
468 case WM5100_HPLP1MIX_INPUT_4_VOLUME:
469 case WM5100_HPLP2MIX_INPUT_1_SOURCE:
470 case WM5100_HPLP2MIX_INPUT_1_VOLUME:
471 case WM5100_HPLP2MIX_INPUT_2_SOURCE:
472 case WM5100_HPLP2MIX_INPUT_2_VOLUME:
473 case WM5100_HPLP2MIX_INPUT_3_SOURCE:
474 case WM5100_HPLP2MIX_INPUT_3_VOLUME:
475 case WM5100_HPLP2MIX_INPUT_4_SOURCE:
476 case WM5100_HPLP2MIX_INPUT_4_VOLUME:
477 case WM5100_HPLP3MIX_INPUT_1_SOURCE:
478 case WM5100_HPLP3MIX_INPUT_1_VOLUME:
479 case WM5100_HPLP3MIX_INPUT_2_SOURCE:
480 case WM5100_HPLP3MIX_INPUT_2_VOLUME:
481 case WM5100_HPLP3MIX_INPUT_3_SOURCE:
482 case WM5100_HPLP3MIX_INPUT_3_VOLUME:
483 case WM5100_HPLP3MIX_INPUT_4_SOURCE:
484 case WM5100_HPLP3MIX_INPUT_4_VOLUME:
485 case WM5100_HPLP4MIX_INPUT_1_SOURCE:
486 case WM5100_HPLP4MIX_INPUT_1_VOLUME:
487 case WM5100_HPLP4MIX_INPUT_2_SOURCE:
488 case WM5100_HPLP4MIX_INPUT_2_VOLUME:
489 case WM5100_HPLP4MIX_INPUT_3_SOURCE:
490 case WM5100_HPLP4MIX_INPUT_3_VOLUME:
491 case WM5100_HPLP4MIX_INPUT_4_SOURCE:
492 case WM5100_HPLP4MIX_INPUT_4_VOLUME:
493 case WM5100_DSP1LMIX_INPUT_1_SOURCE:
494 case WM5100_DSP1LMIX_INPUT_1_VOLUME:
495 case WM5100_DSP1LMIX_INPUT_2_SOURCE:
496 case WM5100_DSP1LMIX_INPUT_2_VOLUME:
497 case WM5100_DSP1LMIX_INPUT_3_SOURCE:
498 case WM5100_DSP1LMIX_INPUT_3_VOLUME:
499 case WM5100_DSP1LMIX_INPUT_4_SOURCE:
500 case WM5100_DSP1LMIX_INPUT_4_VOLUME:
501 case WM5100_DSP1RMIX_INPUT_1_SOURCE:
502 case WM5100_DSP1RMIX_INPUT_1_VOLUME:
503 case WM5100_DSP1RMIX_INPUT_2_SOURCE:
504 case WM5100_DSP1RMIX_INPUT_2_VOLUME:
505 case WM5100_DSP1RMIX_INPUT_3_SOURCE:
506 case WM5100_DSP1RMIX_INPUT_3_VOLUME:
507 case WM5100_DSP1RMIX_INPUT_4_SOURCE:
508 case WM5100_DSP1RMIX_INPUT_4_VOLUME:
509 case WM5100_DSP1AUX1MIX_INPUT_1_SOURCE:
510 case WM5100_DSP1AUX2MIX_INPUT_1_SOURCE:
511 case WM5100_DSP1AUX3MIX_INPUT_1_SOURCE:
512 case WM5100_DSP1AUX4MIX_INPUT_1_SOURCE:
513 case WM5100_DSP1AUX5MIX_INPUT_1_SOURCE:
514 case WM5100_DSP1AUX6MIX_INPUT_1_SOURCE:
515 case WM5100_DSP2LMIX_INPUT_1_SOURCE:
516 case WM5100_DSP2LMIX_INPUT_1_VOLUME:
517 case WM5100_DSP2LMIX_INPUT_2_SOURCE:
518 case WM5100_DSP2LMIX_INPUT_2_VOLUME:
519 case WM5100_DSP2LMIX_INPUT_3_SOURCE:
520 case WM5100_DSP2LMIX_INPUT_3_VOLUME:
521 case WM5100_DSP2LMIX_INPUT_4_SOURCE:
522 case WM5100_DSP2LMIX_INPUT_4_VOLUME:
523 case WM5100_DSP2RMIX_INPUT_1_SOURCE:
524 case WM5100_DSP2RMIX_INPUT_1_VOLUME:
525 case WM5100_DSP2RMIX_INPUT_2_SOURCE:
526 case WM5100_DSP2RMIX_INPUT_2_VOLUME:
527 case WM5100_DSP2RMIX_INPUT_3_SOURCE:
528 case WM5100_DSP2RMIX_INPUT_3_VOLUME:
529 case WM5100_DSP2RMIX_INPUT_4_SOURCE:
530 case WM5100_DSP2RMIX_INPUT_4_VOLUME:
531 case WM5100_DSP2AUX1MIX_INPUT_1_SOURCE:
532 case WM5100_DSP2AUX2MIX_INPUT_1_SOURCE:
533 case WM5100_DSP2AUX3MIX_INPUT_1_SOURCE:
534 case WM5100_DSP2AUX4MIX_INPUT_1_SOURCE:
535 case WM5100_DSP2AUX5MIX_INPUT_1_SOURCE:
536 case WM5100_DSP2AUX6MIX_INPUT_1_SOURCE:
537 case WM5100_DSP3LMIX_INPUT_1_SOURCE:
538 case WM5100_DSP3LMIX_INPUT_1_VOLUME:
539 case WM5100_DSP3LMIX_INPUT_2_SOURCE:
540 case WM5100_DSP3LMIX_INPUT_2_VOLUME:
541 case WM5100_DSP3LMIX_INPUT_3_SOURCE:
542 case WM5100_DSP3LMIX_INPUT_3_VOLUME:
543 case WM5100_DSP3LMIX_INPUT_4_SOURCE:
544 case WM5100_DSP3LMIX_INPUT_4_VOLUME:
545 case WM5100_DSP3RMIX_INPUT_1_SOURCE:
546 case WM5100_DSP3RMIX_INPUT_1_VOLUME:
547 case WM5100_DSP3RMIX_INPUT_2_SOURCE:
548 case WM5100_DSP3RMIX_INPUT_2_VOLUME:
549 case WM5100_DSP3RMIX_INPUT_3_SOURCE:
550 case WM5100_DSP3RMIX_INPUT_3_VOLUME:
551 case WM5100_DSP3RMIX_INPUT_4_SOURCE:
552 case WM5100_DSP3RMIX_INPUT_4_VOLUME:
553 case WM5100_DSP3AUX1MIX_INPUT_1_SOURCE:
554 case WM5100_DSP3AUX2MIX_INPUT_1_SOURCE:
555 case WM5100_DSP3AUX3MIX_INPUT_1_SOURCE:
556 case WM5100_DSP3AUX4MIX_INPUT_1_SOURCE:
557 case WM5100_DSP3AUX5MIX_INPUT_1_SOURCE:
558 case WM5100_DSP3AUX6MIX_INPUT_1_SOURCE:
559 case WM5100_ASRC1LMIX_INPUT_1_SOURCE:
560 case WM5100_ASRC1RMIX_INPUT_1_SOURCE:
561 case WM5100_ASRC2LMIX_INPUT_1_SOURCE:
562 case WM5100_ASRC2RMIX_INPUT_1_SOURCE:
563 case WM5100_ISRC1DEC1MIX_INPUT_1_SOURCE:
564 case WM5100_ISRC1DEC2MIX_INPUT_1_SOURCE:
565 case WM5100_ISRC1DEC3MIX_INPUT_1_SOURCE:
566 case WM5100_ISRC1DEC4MIX_INPUT_1_SOURCE:
567 case WM5100_ISRC1INT1MIX_INPUT_1_SOURCE:
568 case WM5100_ISRC1INT2MIX_INPUT_1_SOURCE:
569 case WM5100_ISRC1INT3MIX_INPUT_1_SOURCE:
570 case WM5100_ISRC1INT4MIX_INPUT_1_SOURCE:
571 case WM5100_ISRC2DEC1MIX_INPUT_1_SOURCE:
572 case WM5100_ISRC2DEC2MIX_INPUT_1_SOURCE:
573 case WM5100_ISRC2DEC3MIX_INPUT_1_SOURCE:
574 case WM5100_ISRC2DEC4MIX_INPUT_1_SOURCE:
575 case WM5100_ISRC2INT1MIX_INPUT_1_SOURCE:
576 case WM5100_ISRC2INT2MIX_INPUT_1_SOURCE:
577 case WM5100_ISRC2INT3MIX_INPUT_1_SOURCE:
578 case WM5100_ISRC2INT4MIX_INPUT_1_SOURCE:
579 case WM5100_GPIO_CTRL_1:
580 case WM5100_GPIO_CTRL_2:
581 case WM5100_GPIO_CTRL_3:
582 case WM5100_GPIO_CTRL_4:
583 case WM5100_GPIO_CTRL_5:
584 case WM5100_GPIO_CTRL_6:
585 case WM5100_MISC_PAD_CTRL_1:
586 case WM5100_MISC_PAD_CTRL_2:
587 case WM5100_MISC_PAD_CTRL_3:
588 case WM5100_MISC_PAD_CTRL_4:
589 case WM5100_MISC_PAD_CTRL_5:
590 case WM5100_MISC_GPIO_1:
591 case WM5100_INTERRUPT_STATUS_1:
592 case WM5100_INTERRUPT_STATUS_2:
593 case WM5100_INTERRUPT_STATUS_3:
594 case WM5100_INTERRUPT_STATUS_4:
595 case WM5100_INTERRUPT_RAW_STATUS_2:
596 case WM5100_INTERRUPT_RAW_STATUS_3:
597 case WM5100_INTERRUPT_RAW_STATUS_4:
598 case WM5100_INTERRUPT_STATUS_1_MASK:
599 case WM5100_INTERRUPT_STATUS_2_MASK:
600 case WM5100_INTERRUPT_STATUS_3_MASK:
601 case WM5100_INTERRUPT_STATUS_4_MASK:
602 case WM5100_INTERRUPT_CONTROL:
603 case WM5100_IRQ_DEBOUNCE_1:
604 case WM5100_IRQ_DEBOUNCE_2:
605 case WM5100_FX_CTRL:
606 case WM5100_EQ1_1:
607 case WM5100_EQ1_2:
608 case WM5100_EQ1_3:
609 case WM5100_EQ1_4:
610 case WM5100_EQ1_5:
611 case WM5100_EQ1_6:
612 case WM5100_EQ1_7:
613 case WM5100_EQ1_8:
614 case WM5100_EQ1_9:
615 case WM5100_EQ1_10:
616 case WM5100_EQ1_11:
617 case WM5100_EQ1_12:
618 case WM5100_EQ1_13:
619 case WM5100_EQ1_14:
620 case WM5100_EQ1_15:
621 case WM5100_EQ1_16:
622 case WM5100_EQ1_17:
623 case WM5100_EQ1_18:
624 case WM5100_EQ1_19:
625 case WM5100_EQ1_20:
626 case WM5100_EQ2_1:
627 case WM5100_EQ2_2:
628 case WM5100_EQ2_3:
629 case WM5100_EQ2_4:
630 case WM5100_EQ2_5:
631 case WM5100_EQ2_6:
632 case WM5100_EQ2_7:
633 case WM5100_EQ2_8:
634 case WM5100_EQ2_9:
635 case WM5100_EQ2_10:
636 case WM5100_EQ2_11:
637 case WM5100_EQ2_12:
638 case WM5100_EQ2_13:
639 case WM5100_EQ2_14:
640 case WM5100_EQ2_15:
641 case WM5100_EQ2_16:
642 case WM5100_EQ2_17:
643 case WM5100_EQ2_18:
644 case WM5100_EQ2_19:
645 case WM5100_EQ2_20:
646 case WM5100_EQ3_1:
647 case WM5100_EQ3_2:
648 case WM5100_EQ3_3:
649 case WM5100_EQ3_4:
650 case WM5100_EQ3_5:
651 case WM5100_EQ3_6:
652 case WM5100_EQ3_7:
653 case WM5100_EQ3_8:
654 case WM5100_EQ3_9:
655 case WM5100_EQ3_10:
656 case WM5100_EQ3_11:
657 case WM5100_EQ3_12:
658 case WM5100_EQ3_13:
659 case WM5100_EQ3_14:
660 case WM5100_EQ3_15:
661 case WM5100_EQ3_16:
662 case WM5100_EQ3_17:
663 case WM5100_EQ3_18:
664 case WM5100_EQ3_19:
665 case WM5100_EQ3_20:
666 case WM5100_EQ4_1:
667 case WM5100_EQ4_2:
668 case WM5100_EQ4_3:
669 case WM5100_EQ4_4:
670 case WM5100_EQ4_5:
671 case WM5100_EQ4_6:
672 case WM5100_EQ4_7:
673 case WM5100_EQ4_8:
674 case WM5100_EQ4_9:
675 case WM5100_EQ4_10:
676 case WM5100_EQ4_11:
677 case WM5100_EQ4_12:
678 case WM5100_EQ4_13:
679 case WM5100_EQ4_14:
680 case WM5100_EQ4_15:
681 case WM5100_EQ4_16:
682 case WM5100_EQ4_17:
683 case WM5100_EQ4_18:
684 case WM5100_EQ4_19:
685 case WM5100_EQ4_20:
686 case WM5100_DRC1_CTRL1:
687 case WM5100_DRC1_CTRL2:
688 case WM5100_DRC1_CTRL3:
689 case WM5100_DRC1_CTRL4:
690 case WM5100_DRC1_CTRL5:
691 case WM5100_HPLPF1_1:
692 case WM5100_HPLPF1_2:
693 case WM5100_HPLPF2_1:
694 case WM5100_HPLPF2_2:
695 case WM5100_HPLPF3_1:
696 case WM5100_HPLPF3_2:
697 case WM5100_HPLPF4_1:
698 case WM5100_HPLPF4_2:
699 case WM5100_DSP1_DM_0:
700 case WM5100_DSP1_DM_1:
701 case WM5100_DSP1_DM_2:
702 case WM5100_DSP1_DM_3:
703 case WM5100_DSP1_DM_508:
704 case WM5100_DSP1_DM_509:
705 case WM5100_DSP1_DM_510:
706 case WM5100_DSP1_DM_511:
707 case WM5100_DSP1_PM_0:
708 case WM5100_DSP1_PM_1:
709 case WM5100_DSP1_PM_2:
710 case WM5100_DSP1_PM_3:
711 case WM5100_DSP1_PM_4:
712 case WM5100_DSP1_PM_5:
713 case WM5100_DSP1_PM_1530:
714 case WM5100_DSP1_PM_1531:
715 case WM5100_DSP1_PM_1532:
716 case WM5100_DSP1_PM_1533:
717 case WM5100_DSP1_PM_1534:
718 case WM5100_DSP1_PM_1535:
719 case WM5100_DSP1_ZM_0:
720 case WM5100_DSP1_ZM_1:
721 case WM5100_DSP1_ZM_2:
722 case WM5100_DSP1_ZM_3:
723 case WM5100_DSP1_ZM_2044:
724 case WM5100_DSP1_ZM_2045:
725 case WM5100_DSP1_ZM_2046:
726 case WM5100_DSP1_ZM_2047:
727 case WM5100_DSP2_DM_0:
728 case WM5100_DSP2_DM_1:
729 case WM5100_DSP2_DM_2:
730 case WM5100_DSP2_DM_3:
731 case WM5100_DSP2_DM_508:
732 case WM5100_DSP2_DM_509:
733 case WM5100_DSP2_DM_510:
734 case WM5100_DSP2_DM_511:
735 case WM5100_DSP2_PM_0:
736 case WM5100_DSP2_PM_1:
737 case WM5100_DSP2_PM_2:
738 case WM5100_DSP2_PM_3:
739 case WM5100_DSP2_PM_4:
740 case WM5100_DSP2_PM_5:
741 case WM5100_DSP2_PM_1530:
742 case WM5100_DSP2_PM_1531:
743 case WM5100_DSP2_PM_1532:
744 case WM5100_DSP2_PM_1533:
745 case WM5100_DSP2_PM_1534:
746 case WM5100_DSP2_PM_1535:
747 case WM5100_DSP2_ZM_0:
748 case WM5100_DSP2_ZM_1:
749 case WM5100_DSP2_ZM_2:
750 case WM5100_DSP2_ZM_3:
751 case WM5100_DSP2_ZM_2044:
752 case WM5100_DSP2_ZM_2045:
753 case WM5100_DSP2_ZM_2046:
754 case WM5100_DSP2_ZM_2047:
755 case WM5100_DSP3_DM_0:
756 case WM5100_DSP3_DM_1:
757 case WM5100_DSP3_DM_2:
758 case WM5100_DSP3_DM_3:
759 case WM5100_DSP3_DM_508:
760 case WM5100_DSP3_DM_509:
761 case WM5100_DSP3_DM_510:
762 case WM5100_DSP3_DM_511:
763 case WM5100_DSP3_PM_0:
764 case WM5100_DSP3_PM_1:
765 case WM5100_DSP3_PM_2:
766 case WM5100_DSP3_PM_3:
767 case WM5100_DSP3_PM_4:
768 case WM5100_DSP3_PM_5:
769 case WM5100_DSP3_PM_1530:
770 case WM5100_DSP3_PM_1531:
771 case WM5100_DSP3_PM_1532:
772 case WM5100_DSP3_PM_1533:
773 case WM5100_DSP3_PM_1534:
774 case WM5100_DSP3_PM_1535:
775 case WM5100_DSP3_ZM_0:
776 case WM5100_DSP3_ZM_1:
777 case WM5100_DSP3_ZM_2:
778 case WM5100_DSP3_ZM_3:
779 case WM5100_DSP3_ZM_2044:
780 case WM5100_DSP3_ZM_2045:
781 case WM5100_DSP3_ZM_2046:
782 case WM5100_DSP3_ZM_2047:
783 return 1;
784 default:
785 return 0;
786 }
787}
788
789u16 wm5100_reg_defaults[WM5100_MAX_REGISTER + 1] = {
790 [0x0000] = 0x0000, /* R0 - software reset */
791 [0x0001] = 0x0000, /* R1 - Device Revision */
792 [0x0010] = 0x0801, /* R16 - Ctrl IF 1 */
793 [0x0020] = 0x0000, /* R32 - Tone Generator 1 */
794 [0x0030] = 0x0000, /* R48 - PWM Drive 1 */
795 [0x0031] = 0x0100, /* R49 - PWM Drive 2 */
796 [0x0032] = 0x0100, /* R50 - PWM Drive 3 */
797 [0x0100] = 0x0002, /* R256 - Clocking 1 */
798 [0x0101] = 0x0000, /* R257 - Clocking 3 */
799 [0x0102] = 0x0011, /* R258 - Clocking 4 */
800 [0x0103] = 0x0011, /* R259 - Clocking 5 */
801 [0x0104] = 0x0011, /* R260 - Clocking 6 */
802 [0x0107] = 0x0000, /* R263 - Clocking 7 */
803 [0x0108] = 0x0000, /* R264 - Clocking 8 */
804 [0x0120] = 0x0000, /* R288 - ASRC_ENABLE */
805 [0x0121] = 0x0000, /* R289 - ASRC_STATUS */
806 [0x0122] = 0x0000, /* R290 - ASRC_RATE1 */
807 [0x0141] = 0x8000, /* R321 - ISRC 1 CTRL 1 */
808 [0x0142] = 0x0000, /* R322 - ISRC 1 CTRL 2 */
809 [0x0143] = 0x8000, /* R323 - ISRC 2 CTRL1 */
810 [0x0144] = 0x0000, /* R324 - ISRC 2 CTRL 2 */
811 [0x0182] = 0x0000, /* R386 - FLL1 Control 1 */
812 [0x0183] = 0x0000, /* R387 - FLL1 Control 2 */
813 [0x0184] = 0x0000, /* R388 - FLL1 Control 3 */
814 [0x0186] = 0x0177, /* R390 - FLL1 Control 5 */
815 [0x0187] = 0x0001, /* R391 - FLL1 Control 6 */
816 [0x0188] = 0x0000, /* R392 - FLL1 EFS 1 */
817 [0x01A2] = 0x0000, /* R418 - FLL2 Control 1 */
818 [0x01A3] = 0x0000, /* R419 - FLL2 Control 2 */
819 [0x01A4] = 0x0000, /* R420 - FLL2 Control 3 */
820 [0x01A6] = 0x0177, /* R422 - FLL2 Control 5 */
821 [0x01A7] = 0x0001, /* R423 - FLL2 Control 6 */
822 [0x01A8] = 0x0000, /* R424 - FLL2 EFS 1 */
823 [0x0200] = 0x0020, /* R512 - Mic Charge Pump 1 */
824 [0x0201] = 0xB084, /* R513 - Mic Charge Pump 2 */
825 [0x0202] = 0xBBDE, /* R514 - HP Charge Pump 1 */
826 [0x0211] = 0x20D4, /* R529 - LDO1 Control */
827 [0x0215] = 0x0062, /* R533 - Mic Bias Ctrl 1 */
828 [0x0216] = 0x0062, /* R534 - Mic Bias Ctrl 2 */
829 [0x0217] = 0x0062, /* R535 - Mic Bias Ctrl 3 */
830 [0x0280] = 0x0004, /* R640 - Accessory Detect Mode 1 */
831 [0x0288] = 0x0020, /* R648 - Headphone Detect 1 */
832 [0x0289] = 0x0000, /* R649 - Headphone Detect 2 */
833 [0x0290] = 0x1100, /* R656 - Mic Detect 1 */
834 [0x0291] = 0x009F, /* R657 - Mic Detect 2 */
835 [0x0292] = 0x0000, /* R658 - Mic Detect 3 */
836 [0x0301] = 0x0000, /* R769 - Input Enables */
837 [0x0302] = 0x0000, /* R770 - Input Enables Status */
838 [0x0310] = 0x2280, /* R784 - Status */
839 [0x0311] = 0x0080, /* R785 - IN1R Control */
840 [0x0312] = 0x2280, /* R786 - IN2L Control */
841 [0x0313] = 0x0080, /* R787 - IN2R Control */
842 [0x0314] = 0x2280, /* R788 - IN3L Control */
843 [0x0315] = 0x0080, /* R789 - IN3R Control */
844 [0x0316] = 0x2280, /* R790 - IN4L Control */
845 [0x0317] = 0x0080, /* R791 - IN4R Control */
846 [0x0318] = 0x0000, /* R792 - RXANC_SRC */
847 [0x0319] = 0x0022, /* R793 - Input Volume Ramp */
848 [0x0320] = 0x0180, /* R800 - ADC Digital Volume 1L */
849 [0x0321] = 0x0180, /* R801 - ADC Digital Volume 1R */
850 [0x0322] = 0x0180, /* R802 - ADC Digital Volume 2L */
851 [0x0323] = 0x0180, /* R803 - ADC Digital Volume 2R */
852 [0x0324] = 0x0180, /* R804 - ADC Digital Volume 3L */
853 [0x0325] = 0x0180, /* R805 - ADC Digital Volume 3R */
854 [0x0326] = 0x0180, /* R806 - ADC Digital Volume 4L */
855 [0x0327] = 0x0180, /* R807 - ADC Digital Volume 4R */
856 [0x0401] = 0x0000, /* R1025 - Output Enables 2 */
857 [0x0402] = 0x0000, /* R1026 - Output Status 1 */
858 [0x0403] = 0x0000, /* R1027 - Output Status 2 */
859 [0x0408] = 0x0000, /* R1032 - Channel Enables 1 */
860 [0x0410] = 0x0080, /* R1040 - Out Volume 1L */
861 [0x0411] = 0x0080, /* R1041 - Out Volume 1R */
862 [0x0412] = 0x0080, /* R1042 - DAC Volume Limit 1L */
863 [0x0413] = 0x0080, /* R1043 - DAC Volume Limit 1R */
864 [0x0414] = 0x0080, /* R1044 - Out Volume 2L */
865 [0x0415] = 0x0080, /* R1045 - Out Volume 2R */
866 [0x0416] = 0x0080, /* R1046 - DAC Volume Limit 2L */
867 [0x0417] = 0x0080, /* R1047 - DAC Volume Limit 2R */
868 [0x0418] = 0x0080, /* R1048 - Out Volume 3L */
869 [0x0419] = 0x0080, /* R1049 - Out Volume 3R */
870 [0x041A] = 0x0080, /* R1050 - DAC Volume Limit 3L */
871 [0x041B] = 0x0080, /* R1051 - DAC Volume Limit 3R */
872 [0x041C] = 0x0080, /* R1052 - Out Volume 4L */
873 [0x041D] = 0x0080, /* R1053 - Out Volume 4R */
874 [0x041E] = 0x0080, /* R1054 - DAC Volume Limit 5L */
875 [0x041F] = 0x0080, /* R1055 - DAC Volume Limit 5R */
876 [0x0420] = 0x0080, /* R1056 - DAC Volume Limit 6L */
877 [0x0421] = 0x0080, /* R1057 - DAC Volume Limit 6R */
878 [0x0440] = 0x0000, /* R1088 - DAC AEC Control 1 */
879 [0x0441] = 0x0022, /* R1089 - Output Volume Ramp */
880 [0x0480] = 0x0180, /* R1152 - DAC Digital Volume 1L */
881 [0x0481] = 0x0180, /* R1153 - DAC Digital Volume 1R */
882 [0x0482] = 0x0180, /* R1154 - DAC Digital Volume 2L */
883 [0x0483] = 0x0180, /* R1155 - DAC Digital Volume 2R */
884 [0x0484] = 0x0180, /* R1156 - DAC Digital Volume 3L */
885 [0x0485] = 0x0180, /* R1157 - DAC Digital Volume 3R */
886 [0x0486] = 0x0180, /* R1158 - DAC Digital Volume 4L */
887 [0x0487] = 0x0180, /* R1159 - DAC Digital Volume 4R */
888 [0x0488] = 0x0180, /* R1160 - DAC Digital Volume 5L */
889 [0x0489] = 0x0180, /* R1161 - DAC Digital Volume 5R */
890 [0x048A] = 0x0180, /* R1162 - DAC Digital Volume 6L */
891 [0x048B] = 0x0180, /* R1163 - DAC Digital Volume 6R */
892 [0x04C0] = 0x0069, /* R1216 - PDM SPK1 CTRL 1 */
893 [0x04C1] = 0x0000, /* R1217 - PDM SPK1 CTRL 2 */
894 [0x04C2] = 0x0069, /* R1218 - PDM SPK2 CTRL 1 */
895 [0x04C3] = 0x0000, /* R1219 - PDM SPK2 CTRL 2 */
896 [0x0500] = 0x000C, /* R1280 - Audio IF 1_1 */
897 [0x0501] = 0x0008, /* R1281 - Audio IF 1_2 */
898 [0x0502] = 0x0000, /* R1282 - Audio IF 1_3 */
899 [0x0503] = 0x0000, /* R1283 - Audio IF 1_4 */
900 [0x0504] = 0x0000, /* R1284 - Audio IF 1_5 */
901 [0x0505] = 0x0300, /* R1285 - Audio IF 1_6 */
902 [0x0506] = 0x0300, /* R1286 - Audio IF 1_7 */
903 [0x0507] = 0x1820, /* R1287 - Audio IF 1_8 */
904 [0x0508] = 0x1820, /* R1288 - Audio IF 1_9 */
905 [0x0509] = 0x0000, /* R1289 - Audio IF 1_10 */
906 [0x050A] = 0x0001, /* R1290 - Audio IF 1_11 */
907 [0x050B] = 0x0002, /* R1291 - Audio IF 1_12 */
908 [0x050C] = 0x0003, /* R1292 - Audio IF 1_13 */
909 [0x050D] = 0x0004, /* R1293 - Audio IF 1_14 */
910 [0x050E] = 0x0005, /* R1294 - Audio IF 1_15 */
911 [0x050F] = 0x0006, /* R1295 - Audio IF 1_16 */
912 [0x0510] = 0x0007, /* R1296 - Audio IF 1_17 */
913 [0x0511] = 0x0000, /* R1297 - Audio IF 1_18 */
914 [0x0512] = 0x0001, /* R1298 - Audio IF 1_19 */
915 [0x0513] = 0x0002, /* R1299 - Audio IF 1_20 */
916 [0x0514] = 0x0003, /* R1300 - Audio IF 1_21 */
917 [0x0515] = 0x0004, /* R1301 - Audio IF 1_22 */
918 [0x0516] = 0x0005, /* R1302 - Audio IF 1_23 */
919 [0x0517] = 0x0006, /* R1303 - Audio IF 1_24 */
920 [0x0518] = 0x0007, /* R1304 - Audio IF 1_25 */
921 [0x0519] = 0x0000, /* R1305 - Audio IF 1_26 */
922 [0x051A] = 0x0000, /* R1306 - Audio IF 1_27 */
923 [0x0540] = 0x000C, /* R1344 - Audio IF 2_1 */
924 [0x0541] = 0x0008, /* R1345 - Audio IF 2_2 */
925 [0x0542] = 0x0000, /* R1346 - Audio IF 2_3 */
926 [0x0543] = 0x0000, /* R1347 - Audio IF 2_4 */
927 [0x0544] = 0x0000, /* R1348 - Audio IF 2_5 */
928 [0x0545] = 0x0300, /* R1349 - Audio IF 2_6 */
929 [0x0546] = 0x0300, /* R1350 - Audio IF 2_7 */
930 [0x0547] = 0x1820, /* R1351 - Audio IF 2_8 */
931 [0x0548] = 0x1820, /* R1352 - Audio IF 2_9 */
932 [0x0549] = 0x0000, /* R1353 - Audio IF 2_10 */
933 [0x054A] = 0x0001, /* R1354 - Audio IF 2_11 */
934 [0x0551] = 0x0000, /* R1361 - Audio IF 2_18 */
935 [0x0552] = 0x0001, /* R1362 - Audio IF 2_19 */
936 [0x0559] = 0x0000, /* R1369 - Audio IF 2_26 */
937 [0x055A] = 0x0000, /* R1370 - Audio IF 2_27 */
938 [0x0580] = 0x000C, /* R1408 - Audio IF 3_1 */
939 [0x0581] = 0x0008, /* R1409 - Audio IF 3_2 */
940 [0x0582] = 0x0000, /* R1410 - Audio IF 3_3 */
941 [0x0583] = 0x0000, /* R1411 - Audio IF 3_4 */
942 [0x0584] = 0x0000, /* R1412 - Audio IF 3_5 */
943 [0x0585] = 0x0300, /* R1413 - Audio IF 3_6 */
944 [0x0586] = 0x0300, /* R1414 - Audio IF 3_7 */
945 [0x0587] = 0x1820, /* R1415 - Audio IF 3_8 */
946 [0x0588] = 0x1820, /* R1416 - Audio IF 3_9 */
947 [0x0589] = 0x0000, /* R1417 - Audio IF 3_10 */
948 [0x058A] = 0x0001, /* R1418 - Audio IF 3_11 */
949 [0x0591] = 0x0000, /* R1425 - Audio IF 3_18 */
950 [0x0592] = 0x0001, /* R1426 - Audio IF 3_19 */
951 [0x0599] = 0x0000, /* R1433 - Audio IF 3_26 */
952 [0x059A] = 0x0000, /* R1434 - Audio IF 3_27 */
953 [0x0640] = 0x0000, /* R1600 - PWM1MIX Input 1 Source */
954 [0x0641] = 0x0080, /* R1601 - PWM1MIX Input 1 Volume */
955 [0x0642] = 0x0000, /* R1602 - PWM1MIX Input 2 Source */
956 [0x0643] = 0x0080, /* R1603 - PWM1MIX Input 2 Volume */
957 [0x0644] = 0x0000, /* R1604 - PWM1MIX Input 3 Source */
958 [0x0645] = 0x0080, /* R1605 - PWM1MIX Input 3 Volume */
959 [0x0646] = 0x0000, /* R1606 - PWM1MIX Input 4 Source */
960 [0x0647] = 0x0080, /* R1607 - PWM1MIX Input 4 Volume */
961 [0x0648] = 0x0000, /* R1608 - PWM2MIX Input 1 Source */
962 [0x0649] = 0x0080, /* R1609 - PWM2MIX Input 1 Volume */
963 [0x064A] = 0x0000, /* R1610 - PWM2MIX Input 2 Source */
964 [0x064B] = 0x0080, /* R1611 - PWM2MIX Input 2 Volume */
965 [0x064C] = 0x0000, /* R1612 - PWM2MIX Input 3 Source */
966 [0x064D] = 0x0080, /* R1613 - PWM2MIX Input 3 Volume */
967 [0x064E] = 0x0000, /* R1614 - PWM2MIX Input 4 Source */
968 [0x064F] = 0x0080, /* R1615 - PWM2MIX Input 4 Volume */
969 [0x0680] = 0x0000, /* R1664 - OUT1LMIX Input 1 Source */
970 [0x0681] = 0x0080, /* R1665 - OUT1LMIX Input 1 Volume */
971 [0x0682] = 0x0000, /* R1666 - OUT1LMIX Input 2 Source */
972 [0x0683] = 0x0080, /* R1667 - OUT1LMIX Input 2 Volume */
973 [0x0684] = 0x0000, /* R1668 - OUT1LMIX Input 3 Source */
974 [0x0685] = 0x0080, /* R1669 - OUT1LMIX Input 3 Volume */
975 [0x0686] = 0x0000, /* R1670 - OUT1LMIX Input 4 Source */
976 [0x0687] = 0x0080, /* R1671 - OUT1LMIX Input 4 Volume */
977 [0x0688] = 0x0000, /* R1672 - OUT1RMIX Input 1 Source */
978 [0x0689] = 0x0080, /* R1673 - OUT1RMIX Input 1 Volume */
979 [0x068A] = 0x0000, /* R1674 - OUT1RMIX Input 2 Source */
980 [0x068B] = 0x0080, /* R1675 - OUT1RMIX Input 2 Volume */
981 [0x068C] = 0x0000, /* R1676 - OUT1RMIX Input 3 Source */
982 [0x068D] = 0x0080, /* R1677 - OUT1RMIX Input 3 Volume */
983 [0x068E] = 0x0000, /* R1678 - OUT1RMIX Input 4 Source */
984 [0x068F] = 0x0080, /* R1679 - OUT1RMIX Input 4 Volume */
985 [0x0690] = 0x0000, /* R1680 - OUT2LMIX Input 1 Source */
986 [0x0691] = 0x0080, /* R1681 - OUT2LMIX Input 1 Volume */
987 [0x0692] = 0x0000, /* R1682 - OUT2LMIX Input 2 Source */
988 [0x0693] = 0x0080, /* R1683 - OUT2LMIX Input 2 Volume */
989 [0x0694] = 0x0000, /* R1684 - OUT2LMIX Input 3 Source */
990 [0x0695] = 0x0080, /* R1685 - OUT2LMIX Input 3 Volume */
991 [0x0696] = 0x0000, /* R1686 - OUT2LMIX Input 4 Source */
992 [0x0697] = 0x0080, /* R1687 - OUT2LMIX Input 4 Volume */
993 [0x0698] = 0x0000, /* R1688 - OUT2RMIX Input 1 Source */
994 [0x0699] = 0x0080, /* R1689 - OUT2RMIX Input 1 Volume */
995 [0x069A] = 0x0000, /* R1690 - OUT2RMIX Input 2 Source */
996 [0x069B] = 0x0080, /* R1691 - OUT2RMIX Input 2 Volume */
997 [0x069C] = 0x0000, /* R1692 - OUT2RMIX Input 3 Source */
998 [0x069D] = 0x0080, /* R1693 - OUT2RMIX Input 3 Volume */
999 [0x069E] = 0x0000, /* R1694 - OUT2RMIX Input 4 Source */
1000 [0x069F] = 0x0080, /* R1695 - OUT2RMIX Input 4 Volume */
1001 [0x06A0] = 0x0000, /* R1696 - OUT3LMIX Input 1 Source */
1002 [0x06A1] = 0x0080, /* R1697 - OUT3LMIX Input 1 Volume */
1003 [0x06A2] = 0x0000, /* R1698 - OUT3LMIX Input 2 Source */
1004 [0x06A3] = 0x0080, /* R1699 - OUT3LMIX Input 2 Volume */
1005 [0x06A4] = 0x0000, /* R1700 - OUT3LMIX Input 3 Source */
1006 [0x06A5] = 0x0080, /* R1701 - OUT3LMIX Input 3 Volume */
1007 [0x06A6] = 0x0000, /* R1702 - OUT3LMIX Input 4 Source */
1008 [0x06A7] = 0x0080, /* R1703 - OUT3LMIX Input 4 Volume */
1009 [0x06A8] = 0x0000, /* R1704 - OUT3RMIX Input 1 Source */
1010 [0x06A9] = 0x0080, /* R1705 - OUT3RMIX Input 1 Volume */
1011 [0x06AA] = 0x0000, /* R1706 - OUT3RMIX Input 2 Source */
1012 [0x06AB] = 0x0080, /* R1707 - OUT3RMIX Input 2 Volume */
1013 [0x06AC] = 0x0000, /* R1708 - OUT3RMIX Input 3 Source */
1014 [0x06AD] = 0x0080, /* R1709 - OUT3RMIX Input 3 Volume */
1015 [0x06AE] = 0x0000, /* R1710 - OUT3RMIX Input 4 Source */
1016 [0x06AF] = 0x0080, /* R1711 - OUT3RMIX Input 4 Volume */
1017 [0x06B0] = 0x0000, /* R1712 - OUT4LMIX Input 1 Source */
1018 [0x06B1] = 0x0080, /* R1713 - OUT4LMIX Input 1 Volume */
1019 [0x06B2] = 0x0000, /* R1714 - OUT4LMIX Input 2 Source */
1020 [0x06B3] = 0x0080, /* R1715 - OUT4LMIX Input 2 Volume */
1021 [0x06B4] = 0x0000, /* R1716 - OUT4LMIX Input 3 Source */
1022 [0x06B5] = 0x0080, /* R1717 - OUT4LMIX Input 3 Volume */
1023 [0x06B6] = 0x0000, /* R1718 - OUT4LMIX Input 4 Source */
1024 [0x06B7] = 0x0080, /* R1719 - OUT4LMIX Input 4 Volume */
1025 [0x06B8] = 0x0000, /* R1720 - OUT4RMIX Input 1 Source */
1026 [0x06B9] = 0x0080, /* R1721 - OUT4RMIX Input 1 Volume */
1027 [0x06BA] = 0x0000, /* R1722 - OUT4RMIX Input 2 Source */
1028 [0x06BB] = 0x0080, /* R1723 - OUT4RMIX Input 2 Volume */
1029 [0x06BC] = 0x0000, /* R1724 - OUT4RMIX Input 3 Source */
1030 [0x06BD] = 0x0080, /* R1725 - OUT4RMIX Input 3 Volume */
1031 [0x06BE] = 0x0000, /* R1726 - OUT4RMIX Input 4 Source */
1032 [0x06BF] = 0x0080, /* R1727 - OUT4RMIX Input 4 Volume */
1033 [0x06C0] = 0x0000, /* R1728 - OUT5LMIX Input 1 Source */
1034 [0x06C1] = 0x0080, /* R1729 - OUT5LMIX Input 1 Volume */
1035 [0x06C2] = 0x0000, /* R1730 - OUT5LMIX Input 2 Source */
1036 [0x06C3] = 0x0080, /* R1731 - OUT5LMIX Input 2 Volume */
1037 [0x06C4] = 0x0000, /* R1732 - OUT5LMIX Input 3 Source */
1038 [0x06C5] = 0x0080, /* R1733 - OUT5LMIX Input 3 Volume */
1039 [0x06C6] = 0x0000, /* R1734 - OUT5LMIX Input 4 Source */
1040 [0x06C7] = 0x0080, /* R1735 - OUT5LMIX Input 4 Volume */
1041 [0x06C8] = 0x0000, /* R1736 - OUT5RMIX Input 1 Source */
1042 [0x06C9] = 0x0080, /* R1737 - OUT5RMIX Input 1 Volume */
1043 [0x06CA] = 0x0000, /* R1738 - OUT5RMIX Input 2 Source */
1044 [0x06CB] = 0x0080, /* R1739 - OUT5RMIX Input 2 Volume */
1045 [0x06CC] = 0x0000, /* R1740 - OUT5RMIX Input 3 Source */
1046 [0x06CD] = 0x0080, /* R1741 - OUT5RMIX Input 3 Volume */
1047 [0x06CE] = 0x0000, /* R1742 - OUT5RMIX Input 4 Source */
1048 [0x06CF] = 0x0080, /* R1743 - OUT5RMIX Input 4 Volume */
1049 [0x06D0] = 0x0000, /* R1744 - OUT6LMIX Input 1 Source */
1050 [0x06D1] = 0x0080, /* R1745 - OUT6LMIX Input 1 Volume */
1051 [0x06D2] = 0x0000, /* R1746 - OUT6LMIX Input 2 Source */
1052 [0x06D3] = 0x0080, /* R1747 - OUT6LMIX Input 2 Volume */
1053 [0x06D4] = 0x0000, /* R1748 - OUT6LMIX Input 3 Source */
1054 [0x06D5] = 0x0080, /* R1749 - OUT6LMIX Input 3 Volume */
1055 [0x06D6] = 0x0000, /* R1750 - OUT6LMIX Input 4 Source */
1056 [0x06D7] = 0x0080, /* R1751 - OUT6LMIX Input 4 Volume */
1057 [0x06D8] = 0x0000, /* R1752 - OUT6RMIX Input 1 Source */
1058 [0x06D9] = 0x0080, /* R1753 - OUT6RMIX Input 1 Volume */
1059 [0x06DA] = 0x0000, /* R1754 - OUT6RMIX Input 2 Source */
1060 [0x06DB] = 0x0080, /* R1755 - OUT6RMIX Input 2 Volume */
1061 [0x06DC] = 0x0000, /* R1756 - OUT6RMIX Input 3 Source */
1062 [0x06DD] = 0x0080, /* R1757 - OUT6RMIX Input 3 Volume */
1063 [0x06DE] = 0x0000, /* R1758 - OUT6RMIX Input 4 Source */
1064 [0x06DF] = 0x0080, /* R1759 - OUT6RMIX Input 4 Volume */
1065 [0x0700] = 0x0000, /* R1792 - AIF1TX1MIX Input 1 Source */
1066 [0x0701] = 0x0080, /* R1793 - AIF1TX1MIX Input 1 Volume */
1067 [0x0702] = 0x0000, /* R1794 - AIF1TX1MIX Input 2 Source */
1068 [0x0703] = 0x0080, /* R1795 - AIF1TX1MIX Input 2 Volume */
1069 [0x0704] = 0x0000, /* R1796 - AIF1TX1MIX Input 3 Source */
1070 [0x0705] = 0x0080, /* R1797 - AIF1TX1MIX Input 3 Volume */
1071 [0x0706] = 0x0000, /* R1798 - AIF1TX1MIX Input 4 Source */
1072 [0x0707] = 0x0080, /* R1799 - AIF1TX1MIX Input 4 Volume */
1073 [0x0708] = 0x0000, /* R1800 - AIF1TX2MIX Input 1 Source */
1074 [0x0709] = 0x0080, /* R1801 - AIF1TX2MIX Input 1 Volume */
1075 [0x070A] = 0x0000, /* R1802 - AIF1TX2MIX Input 2 Source */
1076 [0x070B] = 0x0080, /* R1803 - AIF1TX2MIX Input 2 Volume */
1077 [0x070C] = 0x0000, /* R1804 - AIF1TX2MIX Input 3 Source */
1078 [0x070D] = 0x0080, /* R1805 - AIF1TX2MIX Input 3 Volume */
1079 [0x070E] = 0x0000, /* R1806 - AIF1TX2MIX Input 4 Source */
1080 [0x070F] = 0x0080, /* R1807 - AIF1TX2MIX Input 4 Volume */
1081 [0x0710] = 0x0000, /* R1808 - AIF1TX3MIX Input 1 Source */
1082 [0x0711] = 0x0080, /* R1809 - AIF1TX3MIX Input 1 Volume */
1083 [0x0712] = 0x0000, /* R1810 - AIF1TX3MIX Input 2 Source */
1084 [0x0713] = 0x0080, /* R1811 - AIF1TX3MIX Input 2 Volume */
1085 [0x0714] = 0x0000, /* R1812 - AIF1TX3MIX Input 3 Source */
1086 [0x0715] = 0x0080, /* R1813 - AIF1TX3MIX Input 3 Volume */
1087 [0x0716] = 0x0000, /* R1814 - AIF1TX3MIX Input 4 Source */
1088 [0x0717] = 0x0080, /* R1815 - AIF1TX3MIX Input 4 Volume */
1089 [0x0718] = 0x0000, /* R1816 - AIF1TX4MIX Input 1 Source */
1090 [0x0719] = 0x0080, /* R1817 - AIF1TX4MIX Input 1 Volume */
1091 [0x071A] = 0x0000, /* R1818 - AIF1TX4MIX Input 2 Source */
1092 [0x071B] = 0x0080, /* R1819 - AIF1TX4MIX Input 2 Volume */
1093 [0x071C] = 0x0000, /* R1820 - AIF1TX4MIX Input 3 Source */
1094 [0x071D] = 0x0080, /* R1821 - AIF1TX4MIX Input 3 Volume */
1095 [0x071E] = 0x0000, /* R1822 - AIF1TX4MIX Input 4 Source */
1096 [0x071F] = 0x0080, /* R1823 - AIF1TX4MIX Input 4 Volume */
1097 [0x0720] = 0x0000, /* R1824 - AIF1TX5MIX Input 1 Source */
1098 [0x0721] = 0x0080, /* R1825 - AIF1TX5MIX Input 1 Volume */
1099 [0x0722] = 0x0000, /* R1826 - AIF1TX5MIX Input 2 Source */
1100 [0x0723] = 0x0080, /* R1827 - AIF1TX5MIX Input 2 Volume */
1101 [0x0724] = 0x0000, /* R1828 - AIF1TX5MIX Input 3 Source */
1102 [0x0725] = 0x0080, /* R1829 - AIF1TX5MIX Input 3 Volume */
1103 [0x0726] = 0x0000, /* R1830 - AIF1TX5MIX Input 4 Source */
1104 [0x0727] = 0x0080, /* R1831 - AIF1TX5MIX Input 4 Volume */
1105 [0x0728] = 0x0000, /* R1832 - AIF1TX6MIX Input 1 Source */
1106 [0x0729] = 0x0080, /* R1833 - AIF1TX6MIX Input 1 Volume */
1107 [0x072A] = 0x0000, /* R1834 - AIF1TX6MIX Input 2 Source */
1108 [0x072B] = 0x0080, /* R1835 - AIF1TX6MIX Input 2 Volume */
1109 [0x072C] = 0x0000, /* R1836 - AIF1TX6MIX Input 3 Source */
1110 [0x072D] = 0x0080, /* R1837 - AIF1TX6MIX Input 3 Volume */
1111 [0x072E] = 0x0000, /* R1838 - AIF1TX6MIX Input 4 Source */
1112 [0x072F] = 0x0080, /* R1839 - AIF1TX6MIX Input 4 Volume */
1113 [0x0730] = 0x0000, /* R1840 - AIF1TX7MIX Input 1 Source */
1114 [0x0731] = 0x0080, /* R1841 - AIF1TX7MIX Input 1 Volume */
1115 [0x0732] = 0x0000, /* R1842 - AIF1TX7MIX Input 2 Source */
1116 [0x0733] = 0x0080, /* R1843 - AIF1TX7MIX Input 2 Volume */
1117 [0x0734] = 0x0000, /* R1844 - AIF1TX7MIX Input 3 Source */
1118 [0x0735] = 0x0080, /* R1845 - AIF1TX7MIX Input 3 Volume */
1119 [0x0736] = 0x0000, /* R1846 - AIF1TX7MIX Input 4 Source */
1120 [0x0737] = 0x0080, /* R1847 - AIF1TX7MIX Input 4 Volume */
1121 [0x0738] = 0x0000, /* R1848 - AIF1TX8MIX Input 1 Source */
1122 [0x0739] = 0x0080, /* R1849 - AIF1TX8MIX Input 1 Volume */
1123 [0x073A] = 0x0000, /* R1850 - AIF1TX8MIX Input 2 Source */
1124 [0x073B] = 0x0080, /* R1851 - AIF1TX8MIX Input 2 Volume */
1125 [0x073C] = 0x0000, /* R1852 - AIF1TX8MIX Input 3 Source */
1126 [0x073D] = 0x0080, /* R1853 - AIF1TX8MIX Input 3 Volume */
1127 [0x073E] = 0x0000, /* R1854 - AIF1TX8MIX Input 4 Source */
1128 [0x073F] = 0x0080, /* R1855 - AIF1TX8MIX Input 4 Volume */
1129 [0x0740] = 0x0000, /* R1856 - AIF2TX1MIX Input 1 Source */
1130 [0x0741] = 0x0080, /* R1857 - AIF2TX1MIX Input 1 Volume */
1131 [0x0742] = 0x0000, /* R1858 - AIF2TX1MIX Input 2 Source */
1132 [0x0743] = 0x0080, /* R1859 - AIF2TX1MIX Input 2 Volume */
1133 [0x0744] = 0x0000, /* R1860 - AIF2TX1MIX Input 3 Source */
1134 [0x0745] = 0x0080, /* R1861 - AIF2TX1MIX Input 3 Volume */
1135 [0x0746] = 0x0000, /* R1862 - AIF2TX1MIX Input 4 Source */
1136 [0x0747] = 0x0080, /* R1863 - AIF2TX1MIX Input 4 Volume */
1137 [0x0748] = 0x0000, /* R1864 - AIF2TX2MIX Input 1 Source */
1138 [0x0749] = 0x0080, /* R1865 - AIF2TX2MIX Input 1 Volume */
1139 [0x074A] = 0x0000, /* R1866 - AIF2TX2MIX Input 2 Source */
1140 [0x074B] = 0x0080, /* R1867 - AIF2TX2MIX Input 2 Volume */
1141 [0x074C] = 0x0000, /* R1868 - AIF2TX2MIX Input 3 Source */
1142 [0x074D] = 0x0080, /* R1869 - AIF2TX2MIX Input 3 Volume */
1143 [0x074E] = 0x0000, /* R1870 - AIF2TX2MIX Input 4 Source */
1144 [0x074F] = 0x0080, /* R1871 - AIF2TX2MIX Input 4 Volume */
1145 [0x0780] = 0x0000, /* R1920 - AIF3TX1MIX Input 1 Source */
1146 [0x0781] = 0x0080, /* R1921 - AIF3TX1MIX Input 1 Volume */
1147 [0x0782] = 0x0000, /* R1922 - AIF3TX1MIX Input 2 Source */
1148 [0x0783] = 0x0080, /* R1923 - AIF3TX1MIX Input 2 Volume */
1149 [0x0784] = 0x0000, /* R1924 - AIF3TX1MIX Input 3 Source */
1150 [0x0785] = 0x0080, /* R1925 - AIF3TX1MIX Input 3 Volume */
1151 [0x0786] = 0x0000, /* R1926 - AIF3TX1MIX Input 4 Source */
1152 [0x0787] = 0x0080, /* R1927 - AIF3TX1MIX Input 4 Volume */
1153 [0x0788] = 0x0000, /* R1928 - AIF3TX2MIX Input 1 Source */
1154 [0x0789] = 0x0080, /* R1929 - AIF3TX2MIX Input 1 Volume */
1155 [0x078A] = 0x0000, /* R1930 - AIF3TX2MIX Input 2 Source */
1156 [0x078B] = 0x0080, /* R1931 - AIF3TX2MIX Input 2 Volume */
1157 [0x078C] = 0x0000, /* R1932 - AIF3TX2MIX Input 3 Source */
1158 [0x078D] = 0x0080, /* R1933 - AIF3TX2MIX Input 3 Volume */
1159 [0x078E] = 0x0000, /* R1934 - AIF3TX2MIX Input 4 Source */
1160 [0x078F] = 0x0080, /* R1935 - AIF3TX2MIX Input 4 Volume */
1161 [0x0880] = 0x0000, /* R2176 - EQ1MIX Input 1 Source */
1162 [0x0881] = 0x0080, /* R2177 - EQ1MIX Input 1 Volume */
1163 [0x0882] = 0x0000, /* R2178 - EQ1MIX Input 2 Source */
1164 [0x0883] = 0x0080, /* R2179 - EQ1MIX Input 2 Volume */
1165 [0x0884] = 0x0000, /* R2180 - EQ1MIX Input 3 Source */
1166 [0x0885] = 0x0080, /* R2181 - EQ1MIX Input 3 Volume */
1167 [0x0886] = 0x0000, /* R2182 - EQ1MIX Input 4 Source */
1168 [0x0887] = 0x0080, /* R2183 - EQ1MIX Input 4 Volume */
1169 [0x0888] = 0x0000, /* R2184 - EQ2MIX Input 1 Source */
1170 [0x0889] = 0x0080, /* R2185 - EQ2MIX Input 1 Volume */
1171 [0x088A] = 0x0000, /* R2186 - EQ2MIX Input 2 Source */
1172 [0x088B] = 0x0080, /* R2187 - EQ2MIX Input 2 Volume */
1173 [0x088C] = 0x0000, /* R2188 - EQ2MIX Input 3 Source */
1174 [0x088D] = 0x0080, /* R2189 - EQ2MIX Input 3 Volume */
1175 [0x088E] = 0x0000, /* R2190 - EQ2MIX Input 4 Source */
1176 [0x088F] = 0x0080, /* R2191 - EQ2MIX Input 4 Volume */
1177 [0x0890] = 0x0000, /* R2192 - EQ3MIX Input 1 Source */
1178 [0x0891] = 0x0080, /* R2193 - EQ3MIX Input 1 Volume */
1179 [0x0892] = 0x0000, /* R2194 - EQ3MIX Input 2 Source */
1180 [0x0893] = 0x0080, /* R2195 - EQ3MIX Input 2 Volume */
1181 [0x0894] = 0x0000, /* R2196 - EQ3MIX Input 3 Source */
1182 [0x0895] = 0x0080, /* R2197 - EQ3MIX Input 3 Volume */
1183 [0x0896] = 0x0000, /* R2198 - EQ3MIX Input 4 Source */
1184 [0x0897] = 0x0080, /* R2199 - EQ3MIX Input 4 Volume */
1185 [0x0898] = 0x0000, /* R2200 - EQ4MIX Input 1 Source */
1186 [0x0899] = 0x0080, /* R2201 - EQ4MIX Input 1 Volume */
1187 [0x089A] = 0x0000, /* R2202 - EQ4MIX Input 2 Source */
1188 [0x089B] = 0x0080, /* R2203 - EQ4MIX Input 2 Volume */
1189 [0x089C] = 0x0000, /* R2204 - EQ4MIX Input 3 Source */
1190 [0x089D] = 0x0080, /* R2205 - EQ4MIX Input 3 Volume */
1191 [0x089E] = 0x0000, /* R2206 - EQ4MIX Input 4 Source */
1192 [0x089F] = 0x0080, /* R2207 - EQ4MIX Input 4 Volume */
1193 [0x08C0] = 0x0000, /* R2240 - DRC1LMIX Input 1 Source */
1194 [0x08C1] = 0x0080, /* R2241 - DRC1LMIX Input 1 Volume */
1195 [0x08C2] = 0x0000, /* R2242 - DRC1LMIX Input 2 Source */
1196 [0x08C3] = 0x0080, /* R2243 - DRC1LMIX Input 2 Volume */
1197 [0x08C4] = 0x0000, /* R2244 - DRC1LMIX Input 3 Source */
1198 [0x08C5] = 0x0080, /* R2245 - DRC1LMIX Input 3 Volume */
1199 [0x08C6] = 0x0000, /* R2246 - DRC1LMIX Input 4 Source */
1200 [0x08C7] = 0x0080, /* R2247 - DRC1LMIX Input 4 Volume */
1201 [0x08C8] = 0x0000, /* R2248 - DRC1RMIX Input 1 Source */
1202 [0x08C9] = 0x0080, /* R2249 - DRC1RMIX Input 1 Volume */
1203 [0x08CA] = 0x0000, /* R2250 - DRC1RMIX Input 2 Source */
1204 [0x08CB] = 0x0080, /* R2251 - DRC1RMIX Input 2 Volume */
1205 [0x08CC] = 0x0000, /* R2252 - DRC1RMIX Input 3 Source */
1206 [0x08CD] = 0x0080, /* R2253 - DRC1RMIX Input 3 Volume */
1207 [0x08CE] = 0x0000, /* R2254 - DRC1RMIX Input 4 Source */
1208 [0x08CF] = 0x0080, /* R2255 - DRC1RMIX Input 4 Volume */
1209 [0x0900] = 0x0000, /* R2304 - HPLP1MIX Input 1 Source */
1210 [0x0901] = 0x0080, /* R2305 - HPLP1MIX Input 1 Volume */
1211 [0x0902] = 0x0000, /* R2306 - HPLP1MIX Input 2 Source */
1212 [0x0903] = 0x0080, /* R2307 - HPLP1MIX Input 2 Volume */
1213 [0x0904] = 0x0000, /* R2308 - HPLP1MIX Input 3 Source */
1214 [0x0905] = 0x0080, /* R2309 - HPLP1MIX Input 3 Volume */
1215 [0x0906] = 0x0000, /* R2310 - HPLP1MIX Input 4 Source */
1216 [0x0907] = 0x0080, /* R2311 - HPLP1MIX Input 4 Volume */
1217 [0x0908] = 0x0000, /* R2312 - HPLP2MIX Input 1 Source */
1218 [0x0909] = 0x0080, /* R2313 - HPLP2MIX Input 1 Volume */
1219 [0x090A] = 0x0000, /* R2314 - HPLP2MIX Input 2 Source */
1220 [0x090B] = 0x0080, /* R2315 - HPLP2MIX Input 2 Volume */
1221 [0x090C] = 0x0000, /* R2316 - HPLP2MIX Input 3 Source */
1222 [0x090D] = 0x0080, /* R2317 - HPLP2MIX Input 3 Volume */
1223 [0x090E] = 0x0000, /* R2318 - HPLP2MIX Input 4 Source */
1224 [0x090F] = 0x0080, /* R2319 - HPLP2MIX Input 4 Volume */
1225 [0x0910] = 0x0000, /* R2320 - HPLP3MIX Input 1 Source */
1226 [0x0911] = 0x0080, /* R2321 - HPLP3MIX Input 1 Volume */
1227 [0x0912] = 0x0000, /* R2322 - HPLP3MIX Input 2 Source */
1228 [0x0913] = 0x0080, /* R2323 - HPLP3MIX Input 2 Volume */
1229 [0x0914] = 0x0000, /* R2324 - HPLP3MIX Input 3 Source */
1230 [0x0915] = 0x0080, /* R2325 - HPLP3MIX Input 3 Volume */
1231 [0x0916] = 0x0000, /* R2326 - HPLP3MIX Input 4 Source */
1232 [0x0917] = 0x0080, /* R2327 - HPLP3MIX Input 4 Volume */
1233 [0x0918] = 0x0000, /* R2328 - HPLP4MIX Input 1 Source */
1234 [0x0919] = 0x0080, /* R2329 - HPLP4MIX Input 1 Volume */
1235 [0x091A] = 0x0000, /* R2330 - HPLP4MIX Input 2 Source */
1236 [0x091B] = 0x0080, /* R2331 - HPLP4MIX Input 2 Volume */
1237 [0x091C] = 0x0000, /* R2332 - HPLP4MIX Input 3 Source */
1238 [0x091D] = 0x0080, /* R2333 - HPLP4MIX Input 3 Volume */
1239 [0x091E] = 0x0000, /* R2334 - HPLP4MIX Input 4 Source */
1240 [0x091F] = 0x0080, /* R2335 - HPLP4MIX Input 4 Volume */
1241 [0x0940] = 0x0000, /* R2368 - DSP1LMIX Input 1 Source */
1242 [0x0941] = 0x0080, /* R2369 - DSP1LMIX Input 1 Volume */
1243 [0x0942] = 0x0000, /* R2370 - DSP1LMIX Input 2 Source */
1244 [0x0943] = 0x0080, /* R2371 - DSP1LMIX Input 2 Volume */
1245 [0x0944] = 0x0000, /* R2372 - DSP1LMIX Input 3 Source */
1246 [0x0945] = 0x0080, /* R2373 - DSP1LMIX Input 3 Volume */
1247 [0x0946] = 0x0000, /* R2374 - DSP1LMIX Input 4 Source */
1248 [0x0947] = 0x0080, /* R2375 - DSP1LMIX Input 4 Volume */
1249 [0x0948] = 0x0000, /* R2376 - DSP1RMIX Input 1 Source */
1250 [0x0949] = 0x0080, /* R2377 - DSP1RMIX Input 1 Volume */
1251 [0x094A] = 0x0000, /* R2378 - DSP1RMIX Input 2 Source */
1252 [0x094B] = 0x0080, /* R2379 - DSP1RMIX Input 2 Volume */
1253 [0x094C] = 0x0000, /* R2380 - DSP1RMIX Input 3 Source */
1254 [0x094D] = 0x0080, /* R2381 - DSP1RMIX Input 3 Volume */
1255 [0x094E] = 0x0000, /* R2382 - DSP1RMIX Input 4 Source */
1256 [0x094F] = 0x0080, /* R2383 - DSP1RMIX Input 4 Volume */
1257 [0x0950] = 0x0000, /* R2384 - DSP1AUX1MIX Input 1 Source */
1258 [0x0958] = 0x0000, /* R2392 - DSP1AUX2MIX Input 1 Source */
1259 [0x0960] = 0x0000, /* R2400 - DSP1AUX3MIX Input 1 Source */
1260 [0x0968] = 0x0000, /* R2408 - DSP1AUX4MIX Input 1 Source */
1261 [0x0970] = 0x0000, /* R2416 - DSP1AUX5MIX Input 1 Source */
1262 [0x0978] = 0x0000, /* R2424 - DSP1AUX6MIX Input 1 Source */
1263 [0x0980] = 0x0000, /* R2432 - DSP2LMIX Input 1 Source */
1264 [0x0981] = 0x0080, /* R2433 - DSP2LMIX Input 1 Volume */
1265 [0x0982] = 0x0000, /* R2434 - DSP2LMIX Input 2 Source */
1266 [0x0983] = 0x0080, /* R2435 - DSP2LMIX Input 2 Volume */
1267 [0x0984] = 0x0000, /* R2436 - DSP2LMIX Input 3 Source */
1268 [0x0985] = 0x0080, /* R2437 - DSP2LMIX Input 3 Volume */
1269 [0x0986] = 0x0000, /* R2438 - DSP2LMIX Input 4 Source */
1270 [0x0987] = 0x0080, /* R2439 - DSP2LMIX Input 4 Volume */
1271 [0x0988] = 0x0000, /* R2440 - DSP2RMIX Input 1 Source */
1272 [0x0989] = 0x0080, /* R2441 - DSP2RMIX Input 1 Volume */
1273 [0x098A] = 0x0000, /* R2442 - DSP2RMIX Input 2 Source */
1274 [0x098B] = 0x0080, /* R2443 - DSP2RMIX Input 2 Volume */
1275 [0x098C] = 0x0000, /* R2444 - DSP2RMIX Input 3 Source */
1276 [0x098D] = 0x0080, /* R2445 - DSP2RMIX Input 3 Volume */
1277 [0x098E] = 0x0000, /* R2446 - DSP2RMIX Input 4 Source */
1278 [0x098F] = 0x0080, /* R2447 - DSP2RMIX Input 4 Volume */
1279 [0x0990] = 0x0000, /* R2448 - DSP2AUX1MIX Input 1 Source */
1280 [0x0998] = 0x0000, /* R2456 - DSP2AUX2MIX Input 1 Source */
1281 [0x09A0] = 0x0000, /* R2464 - DSP2AUX3MIX Input 1 Source */
1282 [0x09A8] = 0x0000, /* R2472 - DSP2AUX4MIX Input 1 Source */
1283 [0x09B0] = 0x0000, /* R2480 - DSP2AUX5MIX Input 1 Source */
1284 [0x09B8] = 0x0000, /* R2488 - DSP2AUX6MIX Input 1 Source */
1285 [0x09C0] = 0x0000, /* R2496 - DSP3LMIX Input 1 Source */
1286 [0x09C1] = 0x0080, /* R2497 - DSP3LMIX Input 1 Volume */
1287 [0x09C2] = 0x0000, /* R2498 - DSP3LMIX Input 2 Source */
1288 [0x09C3] = 0x0080, /* R2499 - DSP3LMIX Input 2 Volume */
1289 [0x09C4] = 0x0000, /* R2500 - DSP3LMIX Input 3 Source */
1290 [0x09C5] = 0x0080, /* R2501 - DSP3LMIX Input 3 Volume */
1291 [0x09C6] = 0x0000, /* R2502 - DSP3LMIX Input 4 Source */
1292 [0x09C7] = 0x0080, /* R2503 - DSP3LMIX Input 4 Volume */
1293 [0x09C8] = 0x0000, /* R2504 - DSP3RMIX Input 1 Source */
1294 [0x09C9] = 0x0080, /* R2505 - DSP3RMIX Input 1 Volume */
1295 [0x09CA] = 0x0000, /* R2506 - DSP3RMIX Input 2 Source */
1296 [0x09CB] = 0x0080, /* R2507 - DSP3RMIX Input 2 Volume */
1297 [0x09CC] = 0x0000, /* R2508 - DSP3RMIX Input 3 Source */
1298 [0x09CD] = 0x0080, /* R2509 - DSP3RMIX Input 3 Volume */
1299 [0x09CE] = 0x0000, /* R2510 - DSP3RMIX Input 4 Source */
1300 [0x09CF] = 0x0080, /* R2511 - DSP3RMIX Input 4 Volume */
1301 [0x09D0] = 0x0000, /* R2512 - DSP3AUX1MIX Input 1 Source */
1302 [0x09D8] = 0x0000, /* R2520 - DSP3AUX2MIX Input 1 Source */
1303 [0x09E0] = 0x0000, /* R2528 - DSP3AUX3MIX Input 1 Source */
1304 [0x09E8] = 0x0000, /* R2536 - DSP3AUX4MIX Input 1 Source */
1305 [0x09F0] = 0x0000, /* R2544 - DSP3AUX5MIX Input 1 Source */
1306 [0x09F8] = 0x0000, /* R2552 - DSP3AUX6MIX Input 1 Source */
1307 [0x0A80] = 0x0000, /* R2688 - ASRC1LMIX Input 1 Source */
1308 [0x0A88] = 0x0000, /* R2696 - ASRC1RMIX Input 1 Source */
1309 [0x0A90] = 0x0000, /* R2704 - ASRC2LMIX Input 1 Source */
1310 [0x0A98] = 0x0000, /* R2712 - ASRC2RMIX Input 1 Source */
1311 [0x0B00] = 0x0000, /* R2816 - ISRC1DEC1MIX Input 1 Source */
1312 [0x0B08] = 0x0000, /* R2824 - ISRC1DEC2MIX Input 1 Source */
1313 [0x0B10] = 0x0000, /* R2832 - ISRC1DEC3MIX Input 1 Source */
1314 [0x0B18] = 0x0000, /* R2840 - ISRC1DEC4MIX Input 1 Source */
1315 [0x0B20] = 0x0000, /* R2848 - ISRC1INT1MIX Input 1 Source */
1316 [0x0B28] = 0x0000, /* R2856 - ISRC1INT2MIX Input 1 Source */
1317 [0x0B30] = 0x0000, /* R2864 - ISRC1INT3MIX Input 1 Source */
1318 [0x0B38] = 0x0000, /* R2872 - ISRC1INT4MIX Input 1 Source */
1319 [0x0B40] = 0x0000, /* R2880 - ISRC2DEC1MIX Input 1 Source */
1320 [0x0B48] = 0x0000, /* R2888 - ISRC2DEC2MIX Input 1 Source */
1321 [0x0B50] = 0x0000, /* R2896 - ISRC2DEC3MIX Input 1 Source */
1322 [0x0B58] = 0x0000, /* R2904 - ISRC2DEC4MIX Input 1 Source */
1323 [0x0B60] = 0x0000, /* R2912 - ISRC2INT1MIX Input 1 Source */
1324 [0x0B68] = 0x0000, /* R2920 - ISRC2INT2MIX Input 1 Source */
1325 [0x0B70] = 0x0000, /* R2928 - ISRC2INT3MIX Input 1 Source */
1326 [0x0B78] = 0x0000, /* R2936 - ISRC2INT4MIX Input 1 Source */
1327 [0x0C00] = 0xA001, /* R3072 - GPIO CTRL 1 */
1328 [0x0C01] = 0xA001, /* R3073 - GPIO CTRL 2 */
1329 [0x0C02] = 0xA001, /* R3074 - GPIO CTRL 3 */
1330 [0x0C03] = 0xA001, /* R3075 - GPIO CTRL 4 */
1331 [0x0C04] = 0xA001, /* R3076 - GPIO CTRL 5 */
1332 [0x0C05] = 0xA001, /* R3077 - GPIO CTRL 6 */
1333 [0x0C23] = 0x4003, /* R3107 - Misc Pad Ctrl 1 */
1334 [0x0C24] = 0x0000, /* R3108 - Misc Pad Ctrl 2 */
1335 [0x0C25] = 0x0000, /* R3109 - Misc Pad Ctrl 3 */
1336 [0x0C26] = 0x0000, /* R3110 - Misc Pad Ctrl 4 */
1337 [0x0C27] = 0x0000, /* R3111 - Misc Pad Ctrl 5 */
1338 [0x0C28] = 0x0000, /* R3112 - Misc GPIO 1 */
1339 [0x0D00] = 0x0000, /* R3328 - Interrupt Status 1 */
1340 [0x0D01] = 0x0000, /* R3329 - Interrupt Status 2 */
1341 [0x0D02] = 0x0000, /* R3330 - Interrupt Status 3 */
1342 [0x0D03] = 0x0000, /* R3331 - Interrupt Status 4 */
1343 [0x0D04] = 0x0000, /* R3332 - Interrupt Raw Status 2 */
1344 [0x0D05] = 0x0000, /* R3333 - Interrupt Raw Status 3 */
1345 [0x0D06] = 0x0000, /* R3334 - Interrupt Raw Status 4 */
1346 [0x0D07] = 0xFFFF, /* R3335 - Interrupt Status 1 Mask */
1347 [0x0D08] = 0xFFFF, /* R3336 - Interrupt Status 2 Mask */
1348 [0x0D09] = 0xFFFF, /* R3337 - Interrupt Status 3 Mask */
1349 [0x0D0A] = 0xFFFF, /* R3338 - Interrupt Status 4 Mask */
1350 [0x0D1F] = 0x0000, /* R3359 - Interrupt Control */
1351 [0x0D20] = 0xFFFF, /* R3360 - IRQ Debounce 1 */
1352 [0x0D21] = 0xFFFF, /* R3361 - IRQ Debounce 2 */
1353 [0x0E00] = 0x0000, /* R3584 - FX_Ctrl */
1354 [0x0E10] = 0x6318, /* R3600 - EQ1_1 */
1355 [0x0E11] = 0x6300, /* R3601 - EQ1_2 */
1356 [0x0E12] = 0x0FC8, /* R3602 - EQ1_3 */
1357 [0x0E13] = 0x03FE, /* R3603 - EQ1_4 */
1358 [0x0E14] = 0x00E0, /* R3604 - EQ1_5 */
1359 [0x0E15] = 0x1EC4, /* R3605 - EQ1_6 */
1360 [0x0E16] = 0xF136, /* R3606 - EQ1_7 */
1361 [0x0E17] = 0x0409, /* R3607 - EQ1_8 */
1362 [0x0E18] = 0x04CC, /* R3608 - EQ1_9 */
1363 [0x0E19] = 0x1C9B, /* R3609 - EQ1_10 */
1364 [0x0E1A] = 0xF337, /* R3610 - EQ1_11 */
1365 [0x0E1B] = 0x040B, /* R3611 - EQ1_12 */
1366 [0x0E1C] = 0x0CBB, /* R3612 - EQ1_13 */
1367 [0x0E1D] = 0x16F8, /* R3613 - EQ1_14 */
1368 [0x0E1E] = 0xF7D9, /* R3614 - EQ1_15 */
1369 [0x0E1F] = 0x040A, /* R3615 - EQ1_16 */
1370 [0x0E20] = 0x1F14, /* R3616 - EQ1_17 */
1371 [0x0E21] = 0x058C, /* R3617 - EQ1_18 */
1372 [0x0E22] = 0x0563, /* R3618 - EQ1_19 */
1373 [0x0E23] = 0x4000, /* R3619 - EQ1_20 */
1374 [0x0E26] = 0x6318, /* R3622 - EQ2_1 */
1375 [0x0E27] = 0x6300, /* R3623 - EQ2_2 */
1376 [0x0E28] = 0x0FC8, /* R3624 - EQ2_3 */
1377 [0x0E29] = 0x03FE, /* R3625 - EQ2_4 */
1378 [0x0E2A] = 0x00E0, /* R3626 - EQ2_5 */
1379 [0x0E2B] = 0x1EC4, /* R3627 - EQ2_6 */
1380 [0x0E2C] = 0xF136, /* R3628 - EQ2_7 */
1381 [0x0E2D] = 0x0409, /* R3629 - EQ2_8 */
1382 [0x0E2E] = 0x04CC, /* R3630 - EQ2_9 */
1383 [0x0E2F] = 0x1C9B, /* R3631 - EQ2_10 */
1384 [0x0E30] = 0xF337, /* R3632 - EQ2_11 */
1385 [0x0E31] = 0x040B, /* R3633 - EQ2_12 */
1386 [0x0E32] = 0x0CBB, /* R3634 - EQ2_13 */
1387 [0x0E33] = 0x16F8, /* R3635 - EQ2_14 */
1388 [0x0E34] = 0xF7D9, /* R3636 - EQ2_15 */
1389 [0x0E35] = 0x040A, /* R3637 - EQ2_16 */
1390 [0x0E36] = 0x1F14, /* R3638 - EQ2_17 */
1391 [0x0E37] = 0x058C, /* R3639 - EQ2_18 */
1392 [0x0E38] = 0x0563, /* R3640 - EQ2_19 */
1393 [0x0E39] = 0x4000, /* R3641 - EQ2_20 */
1394 [0x0E3C] = 0x6318, /* R3644 - EQ3_1 */
1395 [0x0E3D] = 0x6300, /* R3645 - EQ3_2 */
1396 [0x0E3E] = 0x0FC8, /* R3646 - EQ3_3 */
1397 [0x0E3F] = 0x03FE, /* R3647 - EQ3_4 */
1398 [0x0E40] = 0x00E0, /* R3648 - EQ3_5 */
1399 [0x0E41] = 0x1EC4, /* R3649 - EQ3_6 */
1400 [0x0E42] = 0xF136, /* R3650 - EQ3_7 */
1401 [0x0E43] = 0x0409, /* R3651 - EQ3_8 */
1402 [0x0E44] = 0x04CC, /* R3652 - EQ3_9 */
1403 [0x0E45] = 0x1C9B, /* R3653 - EQ3_10 */
1404 [0x0E46] = 0xF337, /* R3654 - EQ3_11 */
1405 [0x0E47] = 0x040B, /* R3655 - EQ3_12 */
1406 [0x0E48] = 0x0CBB, /* R3656 - EQ3_13 */
1407 [0x0E49] = 0x16F8, /* R3657 - EQ3_14 */
1408 [0x0E4A] = 0xF7D9, /* R3658 - EQ3_15 */
1409 [0x0E4B] = 0x040A, /* R3659 - EQ3_16 */
1410 [0x0E4C] = 0x1F14, /* R3660 - EQ3_17 */
1411 [0x0E4D] = 0x058C, /* R3661 - EQ3_18 */
1412 [0x0E4E] = 0x0563, /* R3662 - EQ3_19 */
1413 [0x0E4F] = 0x4000, /* R3663 - EQ3_20 */
1414 [0x0E52] = 0x6318, /* R3666 - EQ4_1 */
1415 [0x0E53] = 0x6300, /* R3667 - EQ4_2 */
1416 [0x0E54] = 0x0FC8, /* R3668 - EQ4_3 */
1417 [0x0E55] = 0x03FE, /* R3669 - EQ4_4 */
1418 [0x0E56] = 0x00E0, /* R3670 - EQ4_5 */
1419 [0x0E57] = 0x1EC4, /* R3671 - EQ4_6 */
1420 [0x0E58] = 0xF136, /* R3672 - EQ4_7 */
1421 [0x0E59] = 0x0409, /* R3673 - EQ4_8 */
1422 [0x0E5A] = 0x04CC, /* R3674 - EQ4_9 */
1423 [0x0E5B] = 0x1C9B, /* R3675 - EQ4_10 */
1424 [0x0E5C] = 0xF337, /* R3676 - EQ4_11 */
1425 [0x0E5D] = 0x040B, /* R3677 - EQ4_12 */
1426 [0x0E5E] = 0x0CBB, /* R3678 - EQ4_13 */
1427 [0x0E5F] = 0x16F8, /* R3679 - EQ4_14 */
1428 [0x0E60] = 0xF7D9, /* R3680 - EQ4_15 */
1429 [0x0E61] = 0x040A, /* R3681 - EQ4_16 */
1430 [0x0E62] = 0x1F14, /* R3682 - EQ4_17 */
1431 [0x0E63] = 0x058C, /* R3683 - EQ4_18 */
1432 [0x0E64] = 0x0563, /* R3684 - EQ4_19 */
1433 [0x0E65] = 0x4000, /* R3685 - EQ4_20 */
1434 [0x0E80] = 0x0018, /* R3712 - DRC1 ctrl1 */
1435 [0x0E81] = 0x0933, /* R3713 - DRC1 ctrl2 */
1436 [0x0E82] = 0x0018, /* R3714 - DRC1 ctrl3 */
1437 [0x0E83] = 0x0000, /* R3715 - DRC1 ctrl4 */
1438 [0x0E84] = 0x0000, /* R3716 - DRC1 ctrl5 */
1439 [0x0EC0] = 0x0000, /* R3776 - HPLPF1_1 */
1440 [0x0EC1] = 0x0000, /* R3777 - HPLPF1_2 */
1441 [0x0EC4] = 0x0000, /* R3780 - HPLPF2_1 */
1442 [0x0EC5] = 0x0000, /* R3781 - HPLPF2_2 */
1443 [0x0EC8] = 0x0000, /* R3784 - HPLPF3_1 */
1444 [0x0EC9] = 0x0000, /* R3785 - HPLPF3_2 */
1445 [0x0ECC] = 0x0000, /* R3788 - HPLPF4_1 */
1446 [0x0ECD] = 0x0000, /* R3789 - HPLPF4_2 */
1447 [0x4000] = 0x0000, /* R16384 - DSP1 DM 0 */
1448 [0x4001] = 0x0000, /* R16385 - DSP1 DM 1 */
1449 [0x4002] = 0x0000, /* R16386 - DSP1 DM 2 */
1450 [0x4003] = 0x0000, /* R16387 - DSP1 DM 3 */
1451 [0x41FC] = 0x0000, /* R16892 - DSP1 DM 508 */
1452 [0x41FD] = 0x0000, /* R16893 - DSP1 DM 509 */
1453 [0x41FE] = 0x0000, /* R16894 - DSP1 DM 510 */
1454 [0x41FF] = 0x0000, /* R16895 - DSP1 DM 511 */
1455 [0x4800] = 0x0000, /* R18432 - DSP1 PM 0 */
1456 [0x4801] = 0x0000, /* R18433 - DSP1 PM 1 */
1457 [0x4802] = 0x0000, /* R18434 - DSP1 PM 2 */
1458 [0x4803] = 0x0000, /* R18435 - DSP1 PM 3 */
1459 [0x4804] = 0x0000, /* R18436 - DSP1 PM 4 */
1460 [0x4805] = 0x0000, /* R18437 - DSP1 PM 5 */
1461 [0x4DFA] = 0x0000, /* R19962 - DSP1 PM 1530 */
1462 [0x4DFB] = 0x0000, /* R19963 - DSP1 PM 1531 */
1463 [0x4DFC] = 0x0000, /* R19964 - DSP1 PM 1532 */
1464 [0x4DFD] = 0x0000, /* R19965 - DSP1 PM 1533 */
1465 [0x4DFE] = 0x0000, /* R19966 - DSP1 PM 1534 */
1466 [0x4DFF] = 0x0000, /* R19967 - DSP1 PM 1535 */
1467 [0x5000] = 0x0000, /* R20480 - DSP1 ZM 0 */
1468 [0x5001] = 0x0000, /* R20481 - DSP1 ZM 1 */
1469 [0x5002] = 0x0000, /* R20482 - DSP1 ZM 2 */
1470 [0x5003] = 0x0000, /* R20483 - DSP1 ZM 3 */
1471 [0x57FC] = 0x0000, /* R22524 - DSP1 ZM 2044 */
1472 [0x57FD] = 0x0000, /* R22525 - DSP1 ZM 2045 */
1473 [0x57FE] = 0x0000, /* R22526 - DSP1 ZM 2046 */
1474 [0x57FF] = 0x0000, /* R22527 - DSP1 ZM 2047 */
1475 [0x6000] = 0x0000, /* R24576 - DSP2 DM 0 */
1476 [0x6001] = 0x0000, /* R24577 - DSP2 DM 1 */
1477 [0x6002] = 0x0000, /* R24578 - DSP2 DM 2 */
1478 [0x6003] = 0x0000, /* R24579 - DSP2 DM 3 */
1479 [0x61FC] = 0x0000, /* R25084 - DSP2 DM 508 */
1480 [0x61FD] = 0x0000, /* R25085 - DSP2 DM 509 */
1481 [0x61FE] = 0x0000, /* R25086 - DSP2 DM 510 */
1482 [0x61FF] = 0x0000, /* R25087 - DSP2 DM 511 */
1483 [0x6800] = 0x0000, /* R26624 - DSP2 PM 0 */
1484 [0x6801] = 0x0000, /* R26625 - DSP2 PM 1 */
1485 [0x6802] = 0x0000, /* R26626 - DSP2 PM 2 */
1486 [0x6803] = 0x0000, /* R26627 - DSP2 PM 3 */
1487 [0x6804] = 0x0000, /* R26628 - DSP2 PM 4 */
1488 [0x6805] = 0x0000, /* R26629 - DSP2 PM 5 */
1489 [0x6DFA] = 0x0000, /* R28154 - DSP2 PM 1530 */
1490 [0x6DFB] = 0x0000, /* R28155 - DSP2 PM 1531 */
1491 [0x6DFC] = 0x0000, /* R28156 - DSP2 PM 1532 */
1492 [0x6DFD] = 0x0000, /* R28157 - DSP2 PM 1533 */
1493 [0x6DFE] = 0x0000, /* R28158 - DSP2 PM 1534 */
1494 [0x6DFF] = 0x0000, /* R28159 - DSP2 PM 1535 */
1495 [0x7000] = 0x0000, /* R28672 - DSP2 ZM 0 */
1496 [0x7001] = 0x0000, /* R28673 - DSP2 ZM 1 */
1497 [0x7002] = 0x0000, /* R28674 - DSP2 ZM 2 */
1498 [0x7003] = 0x0000, /* R28675 - DSP2 ZM 3 */
1499 [0x77FC] = 0x0000, /* R30716 - DSP2 ZM 2044 */
1500 [0x77FD] = 0x0000, /* R30717 - DSP2 ZM 2045 */
1501 [0x77FE] = 0x0000, /* R30718 - DSP2 ZM 2046 */
1502 [0x77FF] = 0x0000, /* R30719 - DSP2 ZM 2047 */
1503 [0x8000] = 0x0000, /* R32768 - DSP3 DM 0 */
1504 [0x8001] = 0x0000, /* R32769 - DSP3 DM 1 */
1505 [0x8002] = 0x0000, /* R32770 - DSP3 DM 2 */
1506 [0x8003] = 0x0000, /* R32771 - DSP3 DM 3 */
1507 [0x81FC] = 0x0000, /* R33276 - DSP3 DM 508 */
1508 [0x81FD] = 0x0000, /* R33277 - DSP3 DM 509 */
1509 [0x81FE] = 0x0000, /* R33278 - DSP3 DM 510 */
1510 [0x81FF] = 0x0000, /* R33279 - DSP3 DM 511 */
1511 [0x8800] = 0x0000, /* R34816 - DSP3 PM 0 */
1512 [0x8801] = 0x0000, /* R34817 - DSP3 PM 1 */
1513 [0x8802] = 0x0000, /* R34818 - DSP3 PM 2 */
1514 [0x8803] = 0x0000, /* R34819 - DSP3 PM 3 */
1515 [0x8804] = 0x0000, /* R34820 - DSP3 PM 4 */
1516 [0x8805] = 0x0000, /* R34821 - DSP3 PM 5 */
1517 [0x8DFA] = 0x0000, /* R36346 - DSP3 PM 1530 */
1518 [0x8DFB] = 0x0000, /* R36347 - DSP3 PM 1531 */
1519 [0x8DFC] = 0x0000, /* R36348 - DSP3 PM 1532 */
1520 [0x8DFD] = 0x0000, /* R36349 - DSP3 PM 1533 */
1521 [0x8DFE] = 0x0000, /* R36350 - DSP3 PM 1534 */
1522 [0x8DFF] = 0x0000, /* R36351 - DSP3 PM 1535 */
1523 [0x9000] = 0x0000, /* R36864 - DSP3 ZM 0 */
1524 [0x9001] = 0x0000, /* R36865 - DSP3 ZM 1 */
1525 [0x9002] = 0x0000, /* R36866 - DSP3 ZM 2 */
1526 [0x9003] = 0x0000, /* R36867 - DSP3 ZM 3 */
1527 [0x97FC] = 0x0000, /* R38908 - DSP3 ZM 2044 */
1528 [0x97FD] = 0x0000, /* R38909 - DSP3 ZM 2045 */
1529 [0x97FE] = 0x0000, /* R38910 - DSP3 ZM 2046 */
1530 [0x97FF] = 0x0000 /* R38911 - DSP3 ZM 2047 */
1531};
diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c
new file mode 100644
index 00000000000..5d88c99aaea
--- /dev/null
+++ b/sound/soc/codecs/wm5100.c
@@ -0,0 +1,2809 @@
1/*
2 * wm5100.c -- WM5100 ALSA SoC Audio driver
3 *
4 * Copyright 2011 Wolfson Microelectronics plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/pm.h>
18#include <linux/gcd.h>
19#include <linux/gpio.h>
20#include <linux/i2c.h>
21#include <linux/platform_device.h>
22#include <linux/regulator/consumer.h>
23#include <linux/regulator/fixed.h>
24#include <linux/slab.h>
25#include <sound/core.h>
26#include <sound/pcm.h>
27#include <sound/pcm_params.h>
28#include <sound/soc.h>
29#include <sound/jack.h>
30#include <sound/initval.h>
31#include <sound/tlv.h>
32#include <sound/wm5100.h>
33
34#include "wm5100.h"
35
36#define WM5100_NUM_CORE_SUPPLIES 2
37static const char *wm5100_core_supply_names[WM5100_NUM_CORE_SUPPLIES] = {
38 "DBVDD1",
39 "LDOVDD", /* If DCVDD is supplied externally specify as LDOVDD */
40};
41
42#define WM5100_AIFS 3
43#define WM5100_SYNC_SRS 3
44
45struct wm5100_fll {
46 int fref;
47 int fout;
48 int src;
49 struct completion lock;
50};
51
52/* codec private data */
53struct wm5100_priv {
54 struct snd_soc_codec *codec;
55
56 struct regulator_bulk_data core_supplies[WM5100_NUM_CORE_SUPPLIES];
57 struct regulator *cpvdd;
58 struct regulator *dbvdd2;
59 struct regulator *dbvdd3;
60
61 int rev;
62
63 int sysclk;
64 int asyncclk;
65
66 bool aif_async[WM5100_AIFS];
67 bool aif_symmetric[WM5100_AIFS];
68 int sr_ref[WM5100_SYNC_SRS];
69
70 bool out_ena[2];
71
72 struct snd_soc_jack *jack;
73 bool jack_detecting;
74 bool jack_mic;
75 int jack_mode;
76
77 struct wm5100_fll fll[2];
78
79 struct wm5100_pdata pdata;
80
81#ifdef CONFIG_GPIOLIB
82 struct gpio_chip gpio_chip;
83#endif
84};
85
86static int wm5100_sr_code[] = {
87 0,
88 12000,
89 24000,
90 48000,
91 96000,
92 192000,
93 384000,
94 768000,
95 0,
96 11025,
97 22050,
98 44100,
99 88200,
100 176400,
101 352800,
102 705600,
103 4000,
104 8000,
105 16000,
106 32000,
107 64000,
108 128000,
109 256000,
110 512000,
111};
112
113static int wm5100_sr_regs[WM5100_SYNC_SRS] = {
114 WM5100_CLOCKING_4,
115 WM5100_CLOCKING_5,
116 WM5100_CLOCKING_6,
117};
118
119static int wm5100_alloc_sr(struct snd_soc_codec *codec, int rate)
120{
121 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
122 int sr_code, sr_free, i;
123
124 for (i = 0; i < ARRAY_SIZE(wm5100_sr_code); i++)
125 if (wm5100_sr_code[i] == rate)
126 break;
127 if (i == ARRAY_SIZE(wm5100_sr_code)) {
128 dev_err(codec->dev, "Unsupported sample rate: %dHz\n", rate);
129 return -EINVAL;
130 }
131 sr_code = i;
132
133 if ((wm5100->sysclk % rate) == 0) {
134 /* Is this rate already in use? */
135 sr_free = -1;
136 for (i = 0; i < ARRAY_SIZE(wm5100_sr_regs); i++) {
137 if (!wm5100->sr_ref[i] && sr_free == -1) {
138 sr_free = i;
139 continue;
140 }
141 if ((snd_soc_read(codec, wm5100_sr_regs[i]) &
142 WM5100_SAMPLE_RATE_1_MASK) == sr_code)
143 break;
144 }
145
146 if (i < ARRAY_SIZE(wm5100_sr_regs)) {
147 wm5100->sr_ref[i]++;
148 dev_dbg(codec->dev, "SR %dHz, slot %d, ref %d\n",
149 rate, i, wm5100->sr_ref[i]);
150 return i;
151 }
152
153 if (sr_free == -1) {
154 dev_err(codec->dev, "All SR slots already in use\n");
155 return -EBUSY;
156 }
157
158 dev_dbg(codec->dev, "Allocating SR slot %d for %dHz\n",
159 sr_free, rate);
160 wm5100->sr_ref[sr_free]++;
161 snd_soc_update_bits(codec, wm5100_sr_regs[sr_free],
162 WM5100_SAMPLE_RATE_1_MASK,
163 sr_code);
164
165 return sr_free;
166
167 } else {
168 dev_err(codec->dev,
169 "SR %dHz incompatible with %dHz SYSCLK and %dHz ASYNCCLK\n",
170 rate, wm5100->sysclk, wm5100->asyncclk);
171 return -EINVAL;
172 }
173}
174
175static void wm5100_free_sr(struct snd_soc_codec *codec, int rate)
176{
177 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
178 int i, sr_code;
179
180 for (i = 0; i < ARRAY_SIZE(wm5100_sr_code); i++)
181 if (wm5100_sr_code[i] == rate)
182 break;
183 if (i == ARRAY_SIZE(wm5100_sr_code)) {
184 dev_err(codec->dev, "Unsupported sample rate: %dHz\n", rate);
185 return;
186 }
187 sr_code = wm5100_sr_code[i];
188
189 for (i = 0; i < ARRAY_SIZE(wm5100_sr_regs); i++) {
190 if (!wm5100->sr_ref[i])
191 continue;
192
193 if ((snd_soc_read(codec, wm5100_sr_regs[i]) &
194 WM5100_SAMPLE_RATE_1_MASK) == sr_code)
195 break;
196 }
197 if (i < ARRAY_SIZE(wm5100_sr_regs)) {
198 wm5100->sr_ref[i]--;
199 dev_dbg(codec->dev, "Dereference SR %dHz, count now %d\n",
200 rate, wm5100->sr_ref[i]);
201 } else {
202 dev_warn(codec->dev, "Freeing unreferenced sample rate %dHz\n",
203 rate);
204 }
205}
206
207static int wm5100_reset(struct snd_soc_codec *codec)
208{
209 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
210
211 if (wm5100->pdata.reset) {
212 gpio_set_value_cansleep(wm5100->pdata.reset, 0);
213 gpio_set_value_cansleep(wm5100->pdata.reset, 1);
214
215 return 0;
216 } else {
217 return snd_soc_write(codec, WM5100_SOFTWARE_RESET, 0);
218 }
219}
220
221static DECLARE_TLV_DB_SCALE(in_tlv, -6300, 100, 0);
222static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
223static DECLARE_TLV_DB_SCALE(mixer_tlv, -3200, 100, 0);
224static DECLARE_TLV_DB_SCALE(out_tlv, -6400, 100, 0);
225static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0);
226
227static const char *wm5100_mixer_texts[] = {
228 "None",
229 "Tone Generator 1",
230 "Tone Generator 2",
231 "AEC loopback",
232 "IN1L",
233 "IN1R",
234 "IN2L",
235 "IN2R",
236 "IN3L",
237 "IN3R",
238 "IN4L",
239 "IN4R",
240 "AIF1RX1",
241 "AIF1RX2",
242 "AIF1RX3",
243 "AIF1RX4",
244 "AIF1RX5",
245 "AIF1RX6",
246 "AIF1RX7",
247 "AIF1RX8",
248 "AIF2RX1",
249 "AIF2RX2",
250 "AIF3RX1",
251 "AIF3RX2",
252 "EQ1",
253 "EQ2",
254 "EQ3",
255 "EQ4",
256 "DRC1L",
257 "DRC1R",
258 "LHPF1",
259 "LHPF2",
260 "LHPF3",
261 "LHPF4",
262 "DSP1.1",
263 "DSP1.2",
264 "DSP1.3",
265 "DSP1.4",
266 "DSP1.5",
267 "DSP1.6",
268 "DSP2.1",
269 "DSP2.2",
270 "DSP2.3",
271 "DSP2.4",
272 "DSP2.5",
273 "DSP2.6",
274 "DSP3.1",
275 "DSP3.2",
276 "DSP3.3",
277 "DSP3.4",
278 "DSP3.5",
279 "DSP3.6",
280 "ASRC1L",
281 "ASRC1R",
282 "ASRC2L",
283 "ASRC2R",
284 "ISRC1INT1",
285 "ISRC1INT2",
286 "ISRC1INT3",
287 "ISRC1INT4",
288 "ISRC2INT1",
289 "ISRC2INT2",
290 "ISRC2INT3",
291 "ISRC2INT4",
292 "ISRC1DEC1",
293 "ISRC1DEC2",
294 "ISRC1DEC3",
295 "ISRC1DEC4",
296 "ISRC2DEC1",
297 "ISRC2DEC2",
298 "ISRC2DEC3",
299 "ISRC2DEC4",
300};
301
302static int wm5100_mixer_values[] = {
303 0x00,
304 0x04, /* Tone */
305 0x05,
306 0x08, /* AEC */
307 0x10, /* Input */
308 0x11,
309 0x12,
310 0x13,
311 0x14,
312 0x15,
313 0x16,
314 0x17,
315 0x20, /* AIF */
316 0x21,
317 0x22,
318 0x23,
319 0x24,
320 0x25,
321 0x26,
322 0x27,
323 0x28,
324 0x29,
325 0x30, /* AIF3 - check */
326 0x31,
327 0x50, /* EQ */
328 0x51,
329 0x52,
330 0x53,
331 0x54,
332 0x58, /* DRC */
333 0x59,
334 0x60, /* LHPF1 */
335 0x61, /* LHPF2 */
336 0x62, /* LHPF3 */
337 0x63, /* LHPF4 */
338 0x68, /* DSP1 */
339 0x69,
340 0x6a,
341 0x6b,
342 0x6c,
343 0x6d,
344 0x70, /* DSP2 */
345 0x71,
346 0x72,
347 0x73,
348 0x74,
349 0x75,
350 0x78, /* DSP3 */
351 0x79,
352 0x7a,
353 0x7b,
354 0x7c,
355 0x7d,
356 0x90, /* ASRC1 */
357 0x91,
358 0x92, /* ASRC2 */
359 0x93,
360 0xa0, /* ISRC1DEC1 */
361 0xa1,
362 0xa2,
363 0xa3,
364 0xa4, /* ISRC1INT1 */
365 0xa5,
366 0xa6,
367 0xa7,
368 0xa8, /* ISRC2DEC1 */
369 0xa9,
370 0xaa,
371 0xab,
372 0xac, /* ISRC2INT1 */
373 0xad,
374 0xae,
375 0xaf,
376};
377
378#define WM5100_MIXER_CONTROLS(name, base) \
379 SOC_SINGLE_TLV(name " Input 1 Volume", base + 1 , \
380 WM5100_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \
381 SOC_SINGLE_TLV(name " Input 2 Volume", base + 3 , \
382 WM5100_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \
383 SOC_SINGLE_TLV(name " Input 3 Volume", base + 5 , \
384 WM5100_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \
385 SOC_SINGLE_TLV(name " Input 4 Volume", base + 7 , \
386 WM5100_MIXER_VOL_SHIFT, 80, 0, mixer_tlv)
387
388#define WM5100_MUX_ENUM_DECL(name, reg) \
389 SOC_VALUE_ENUM_SINGLE_DECL(name, reg, 0, 0xff, \
390 wm5100_mixer_texts, wm5100_mixer_values)
391
392#define WM5100_MUX_CTL_DECL(name) \
393 const struct snd_kcontrol_new name##_mux = \
394 SOC_DAPM_VALUE_ENUM("Route", name##_enum)
395
396#define WM5100_MIXER_ENUMS(name, base_reg) \
397 static WM5100_MUX_ENUM_DECL(name##_in1_enum, base_reg); \
398 static WM5100_MUX_ENUM_DECL(name##_in2_enum, base_reg + 2); \
399 static WM5100_MUX_ENUM_DECL(name##_in3_enum, base_reg + 4); \
400 static WM5100_MUX_ENUM_DECL(name##_in4_enum, base_reg + 6); \
401 static WM5100_MUX_CTL_DECL(name##_in1); \
402 static WM5100_MUX_CTL_DECL(name##_in2); \
403 static WM5100_MUX_CTL_DECL(name##_in3); \
404 static WM5100_MUX_CTL_DECL(name##_in4)
405
406WM5100_MIXER_ENUMS(HPOUT1L, WM5100_OUT1LMIX_INPUT_1_SOURCE);
407WM5100_MIXER_ENUMS(HPOUT1R, WM5100_OUT1RMIX_INPUT_1_SOURCE);
408WM5100_MIXER_ENUMS(HPOUT2L, WM5100_OUT2LMIX_INPUT_1_SOURCE);
409WM5100_MIXER_ENUMS(HPOUT2R, WM5100_OUT2RMIX_INPUT_1_SOURCE);
410WM5100_MIXER_ENUMS(HPOUT3L, WM5100_OUT3LMIX_INPUT_1_SOURCE);
411WM5100_MIXER_ENUMS(HPOUT3R, WM5100_OUT3RMIX_INPUT_1_SOURCE);
412
413WM5100_MIXER_ENUMS(SPKOUTL, WM5100_OUT4LMIX_INPUT_1_SOURCE);
414WM5100_MIXER_ENUMS(SPKOUTR, WM5100_OUT4RMIX_INPUT_1_SOURCE);
415WM5100_MIXER_ENUMS(SPKDAT1L, WM5100_OUT5LMIX_INPUT_1_SOURCE);
416WM5100_MIXER_ENUMS(SPKDAT1R, WM5100_OUT5RMIX_INPUT_1_SOURCE);
417WM5100_MIXER_ENUMS(SPKDAT2L, WM5100_OUT6LMIX_INPUT_1_SOURCE);
418WM5100_MIXER_ENUMS(SPKDAT2R, WM5100_OUT6RMIX_INPUT_1_SOURCE);
419
420WM5100_MIXER_ENUMS(PWM1, WM5100_PWM1MIX_INPUT_1_SOURCE);
421WM5100_MIXER_ENUMS(PWM2, WM5100_PWM1MIX_INPUT_1_SOURCE);
422
423WM5100_MIXER_ENUMS(AIF1TX1, WM5100_AIF1TX1MIX_INPUT_1_SOURCE);
424WM5100_MIXER_ENUMS(AIF1TX2, WM5100_AIF1TX2MIX_INPUT_1_SOURCE);
425WM5100_MIXER_ENUMS(AIF1TX3, WM5100_AIF1TX3MIX_INPUT_1_SOURCE);
426WM5100_MIXER_ENUMS(AIF1TX4, WM5100_AIF1TX4MIX_INPUT_1_SOURCE);
427WM5100_MIXER_ENUMS(AIF1TX5, WM5100_AIF1TX5MIX_INPUT_1_SOURCE);
428WM5100_MIXER_ENUMS(AIF1TX6, WM5100_AIF1TX6MIX_INPUT_1_SOURCE);
429WM5100_MIXER_ENUMS(AIF1TX7, WM5100_AIF1TX7MIX_INPUT_1_SOURCE);
430WM5100_MIXER_ENUMS(AIF1TX8, WM5100_AIF1TX8MIX_INPUT_1_SOURCE);
431
432WM5100_MIXER_ENUMS(AIF2TX1, WM5100_AIF2TX1MIX_INPUT_1_SOURCE);
433WM5100_MIXER_ENUMS(AIF2TX2, WM5100_AIF2TX2MIX_INPUT_1_SOURCE);
434
435WM5100_MIXER_ENUMS(AIF3TX1, WM5100_AIF1TX1MIX_INPUT_1_SOURCE);
436WM5100_MIXER_ENUMS(AIF3TX2, WM5100_AIF1TX2MIX_INPUT_1_SOURCE);
437
438WM5100_MIXER_ENUMS(EQ1, WM5100_EQ1MIX_INPUT_1_SOURCE);
439WM5100_MIXER_ENUMS(EQ2, WM5100_EQ2MIX_INPUT_1_SOURCE);
440WM5100_MIXER_ENUMS(EQ3, WM5100_EQ3MIX_INPUT_1_SOURCE);
441WM5100_MIXER_ENUMS(EQ4, WM5100_EQ4MIX_INPUT_1_SOURCE);
442
443WM5100_MIXER_ENUMS(DRC1L, WM5100_DRC1LMIX_INPUT_1_SOURCE);
444WM5100_MIXER_ENUMS(DRC1R, WM5100_DRC1RMIX_INPUT_1_SOURCE);
445
446WM5100_MIXER_ENUMS(LHPF1, WM5100_HPLP1MIX_INPUT_1_SOURCE);
447WM5100_MIXER_ENUMS(LHPF2, WM5100_HPLP2MIX_INPUT_1_SOURCE);
448WM5100_MIXER_ENUMS(LHPF3, WM5100_HPLP3MIX_INPUT_1_SOURCE);
449WM5100_MIXER_ENUMS(LHPF4, WM5100_HPLP4MIX_INPUT_1_SOURCE);
450
451#define WM5100_MUX(name, ctrl) \
452 SND_SOC_DAPM_VALUE_MUX(name, SND_SOC_NOPM, 0, 0, ctrl)
453
454#define WM5100_MIXER_WIDGETS(name, name_str) \
455 WM5100_MUX(name_str " Input 1", &name##_in1_mux), \
456 WM5100_MUX(name_str " Input 2", &name##_in2_mux), \
457 WM5100_MUX(name_str " Input 3", &name##_in3_mux), \
458 WM5100_MUX(name_str " Input 4", &name##_in4_mux), \
459 SND_SOC_DAPM_MIXER(name_str " Mixer", SND_SOC_NOPM, 0, 0, NULL, 0)
460
461#define WM5100_MIXER_INPUT_ROUTES(name) \
462 { name, "Tone Generator 1", "Tone Generator 1" }, \
463 { name, "Tone Generator 2", "Tone Generator 2" }, \
464 { name, "IN1L", "IN1L PGA" }, \
465 { name, "IN1R", "IN1R PGA" }, \
466 { name, "IN2L", "IN2L PGA" }, \
467 { name, "IN2R", "IN2R PGA" }, \
468 { name, "IN3L", "IN3L PGA" }, \
469 { name, "IN3R", "IN3R PGA" }, \
470 { name, "IN4L", "IN4L PGA" }, \
471 { name, "IN4R", "IN4R PGA" }, \
472 { name, "AIF1RX1", "AIF1RX1" }, \
473 { name, "AIF1RX2", "AIF1RX2" }, \
474 { name, "AIF1RX3", "AIF1RX3" }, \
475 { name, "AIF1RX4", "AIF1RX4" }, \
476 { name, "AIF1RX5", "AIF1RX5" }, \
477 { name, "AIF1RX6", "AIF1RX6" }, \
478 { name, "AIF1RX7", "AIF1RX7" }, \
479 { name, "AIF1RX8", "AIF1RX8" }, \
480 { name, "AIF2RX1", "AIF2RX1" }, \
481 { name, "AIF2RX2", "AIF2RX2" }, \
482 { name, "AIF3RX1", "AIF3RX1" }, \
483 { name, "AIF3RX2", "AIF3RX2" }, \
484 { name, "EQ1", "EQ1" }, \
485 { name, "EQ2", "EQ2" }, \
486 { name, "EQ3", "EQ3" }, \
487 { name, "EQ4", "EQ4" }, \
488 { name, "DRC1L", "DRC1L" }, \
489 { name, "DRC1R", "DRC1R" }, \
490 { name, "LHPF1", "LHPF1" }, \
491 { name, "LHPF2", "LHPF2" }, \
492 { name, "LHPF3", "LHPF3" }, \
493 { name, "LHPF4", "LHPF4" }
494
495#define WM5100_MIXER_ROUTES(widget, name) \
496 { widget, NULL, name " Mixer" }, \
497 { name " Mixer", NULL, name " Input 1" }, \
498 { name " Mixer", NULL, name " Input 2" }, \
499 { name " Mixer", NULL, name " Input 3" }, \
500 { name " Mixer", NULL, name " Input 4" }, \
501 WM5100_MIXER_INPUT_ROUTES(name " Input 1"), \
502 WM5100_MIXER_INPUT_ROUTES(name " Input 2"), \
503 WM5100_MIXER_INPUT_ROUTES(name " Input 3"), \
504 WM5100_MIXER_INPUT_ROUTES(name " Input 4")
505
506static const char *wm5100_lhpf_mode_text[] = {
507 "Low-pass", "High-pass"
508};
509
510static const struct soc_enum wm5100_lhpf1_mode =
511 SOC_ENUM_SINGLE(WM5100_HPLPF1_1, WM5100_LHPF1_MODE_SHIFT, 2,
512 wm5100_lhpf_mode_text);
513
514static const struct soc_enum wm5100_lhpf2_mode =
515 SOC_ENUM_SINGLE(WM5100_HPLPF2_1, WM5100_LHPF2_MODE_SHIFT, 2,
516 wm5100_lhpf_mode_text);
517
518static const struct soc_enum wm5100_lhpf3_mode =
519 SOC_ENUM_SINGLE(WM5100_HPLPF3_1, WM5100_LHPF3_MODE_SHIFT, 2,
520 wm5100_lhpf_mode_text);
521
522static const struct soc_enum wm5100_lhpf4_mode =
523 SOC_ENUM_SINGLE(WM5100_HPLPF4_1, WM5100_LHPF4_MODE_SHIFT, 2,
524 wm5100_lhpf_mode_text);
525
526static const struct snd_kcontrol_new wm5100_snd_controls[] = {
527SOC_SINGLE("IN1 High Performance Switch", WM5100_IN1L_CONTROL,
528 WM5100_IN1_OSR_SHIFT, 1, 0),
529SOC_SINGLE("IN2 High Performance Switch", WM5100_IN2L_CONTROL,
530 WM5100_IN2_OSR_SHIFT, 1, 0),
531SOC_SINGLE("IN3 High Performance Switch", WM5100_IN3L_CONTROL,
532 WM5100_IN3_OSR_SHIFT, 1, 0),
533SOC_SINGLE("IN4 High Performance Switch", WM5100_IN4L_CONTROL,
534 WM5100_IN4_OSR_SHIFT, 1, 0),
535
536/* Only applicable for analogue inputs */
537SOC_DOUBLE_R_TLV("IN1 Volume", WM5100_IN1L_CONTROL, WM5100_IN1R_CONTROL,
538 WM5100_IN1L_PGA_VOL_SHIFT, 94, 0, in_tlv),
539SOC_DOUBLE_R_TLV("IN2 Volume", WM5100_IN2L_CONTROL, WM5100_IN2R_CONTROL,
540 WM5100_IN2L_PGA_VOL_SHIFT, 94, 0, in_tlv),
541SOC_DOUBLE_R_TLV("IN3 Volume", WM5100_IN3L_CONTROL, WM5100_IN3R_CONTROL,
542 WM5100_IN3L_PGA_VOL_SHIFT, 94, 0, in_tlv),
543SOC_DOUBLE_R_TLV("IN4 Volume", WM5100_IN4L_CONTROL, WM5100_IN4R_CONTROL,
544 WM5100_IN4L_PGA_VOL_SHIFT, 94, 0, in_tlv),
545
546SOC_DOUBLE_R_TLV("IN1 Digital Volume", WM5100_ADC_DIGITAL_VOLUME_1L,
547 WM5100_ADC_DIGITAL_VOLUME_1R, WM5100_IN1L_VOL_SHIFT, 191,
548 0, digital_tlv),
549SOC_DOUBLE_R_TLV("IN2 Digital Volume", WM5100_ADC_DIGITAL_VOLUME_2L,
550 WM5100_ADC_DIGITAL_VOLUME_2R, WM5100_IN2L_VOL_SHIFT, 191,
551 0, digital_tlv),
552SOC_DOUBLE_R_TLV("IN3 Digital Volume", WM5100_ADC_DIGITAL_VOLUME_3L,
553 WM5100_ADC_DIGITAL_VOLUME_3R, WM5100_IN3L_VOL_SHIFT, 191,
554 0, digital_tlv),
555SOC_DOUBLE_R_TLV("IN4 Digital Volume", WM5100_ADC_DIGITAL_VOLUME_4L,
556 WM5100_ADC_DIGITAL_VOLUME_4R, WM5100_IN4L_VOL_SHIFT, 191,
557 0, digital_tlv),
558
559SOC_DOUBLE_R("IN1 Switch", WM5100_ADC_DIGITAL_VOLUME_1L,
560 WM5100_ADC_DIGITAL_VOLUME_1R, WM5100_IN1L_MUTE_SHIFT, 1, 1),
561SOC_DOUBLE_R("IN2 Switch", WM5100_ADC_DIGITAL_VOLUME_2L,
562 WM5100_ADC_DIGITAL_VOLUME_2R, WM5100_IN2L_MUTE_SHIFT, 1, 1),
563SOC_DOUBLE_R("IN3 Switch", WM5100_ADC_DIGITAL_VOLUME_3L,
564 WM5100_ADC_DIGITAL_VOLUME_3R, WM5100_IN3L_MUTE_SHIFT, 1, 1),
565SOC_DOUBLE_R("IN4 Switch", WM5100_ADC_DIGITAL_VOLUME_4L,
566 WM5100_ADC_DIGITAL_VOLUME_4R, WM5100_IN4L_MUTE_SHIFT, 1, 1),
567
568SOC_SINGLE("HPOUT1 High Performance Switch", WM5100_OUT_VOLUME_1L,
569 WM5100_OUT1_OSR_SHIFT, 1, 0),
570SOC_SINGLE("HPOUT2 High Performance Switch", WM5100_OUT_VOLUME_2L,
571 WM5100_OUT2_OSR_SHIFT, 1, 0),
572SOC_SINGLE("HPOUT3 High Performance Switch", WM5100_OUT_VOLUME_3L,
573 WM5100_OUT3_OSR_SHIFT, 1, 0),
574SOC_SINGLE("SPKOUT High Performance Switch", WM5100_OUT_VOLUME_4L,
575 WM5100_OUT4_OSR_SHIFT, 1, 0),
576SOC_SINGLE("SPKDAT1 High Performance Switch", WM5100_DAC_VOLUME_LIMIT_5L,
577 WM5100_OUT5_OSR_SHIFT, 1, 0),
578SOC_SINGLE("SPKDAT2 High Performance Switch", WM5100_DAC_VOLUME_LIMIT_6L,
579 WM5100_OUT6_OSR_SHIFT, 1, 0),
580
581SOC_DOUBLE_R_TLV("HPOUT1 Digital Volume", WM5100_DAC_DIGITAL_VOLUME_1L,
582 WM5100_DAC_DIGITAL_VOLUME_1R, WM5100_OUT1L_VOL_SHIFT, 159, 0,
583 digital_tlv),
584SOC_DOUBLE_R_TLV("HPOUT2 Digital Volume", WM5100_DAC_DIGITAL_VOLUME_2L,
585 WM5100_DAC_DIGITAL_VOLUME_2R, WM5100_OUT2L_VOL_SHIFT, 159, 0,
586 digital_tlv),
587SOC_DOUBLE_R_TLV("HPOUT3 Digital Volume", WM5100_DAC_DIGITAL_VOLUME_3L,
588 WM5100_DAC_DIGITAL_VOLUME_3R, WM5100_OUT3L_VOL_SHIFT, 159, 0,
589 digital_tlv),
590SOC_DOUBLE_R_TLV("SPKOUT Digital Volume", WM5100_DAC_DIGITAL_VOLUME_4L,
591 WM5100_DAC_DIGITAL_VOLUME_4R, WM5100_OUT4L_VOL_SHIFT, 159, 0,
592 digital_tlv),
593SOC_DOUBLE_R_TLV("SPKDAT1 Digital Volume", WM5100_DAC_DIGITAL_VOLUME_5L,
594 WM5100_DAC_DIGITAL_VOLUME_5R, WM5100_OUT5L_VOL_SHIFT, 159, 0,
595 digital_tlv),
596SOC_DOUBLE_R_TLV("SPKDAT2 Digital Volume", WM5100_DAC_DIGITAL_VOLUME_6L,
597 WM5100_DAC_DIGITAL_VOLUME_6R, WM5100_OUT6L_VOL_SHIFT, 159, 0,
598 digital_tlv),
599
600SOC_DOUBLE_R("HPOUT1 Digital Switch", WM5100_DAC_DIGITAL_VOLUME_1L,
601 WM5100_DAC_DIGITAL_VOLUME_1R, WM5100_OUT1L_MUTE_SHIFT, 1, 1),
602SOC_DOUBLE_R("HPOUT2 Digital Switch", WM5100_DAC_DIGITAL_VOLUME_2L,
603 WM5100_DAC_DIGITAL_VOLUME_2R, WM5100_OUT2L_MUTE_SHIFT, 1, 1),
604SOC_DOUBLE_R("HPOUT3 Digital Switch", WM5100_DAC_DIGITAL_VOLUME_3L,
605 WM5100_DAC_DIGITAL_VOLUME_3R, WM5100_OUT3L_MUTE_SHIFT, 1, 1),
606SOC_DOUBLE_R("SPKOUT Digital Switch", WM5100_DAC_DIGITAL_VOLUME_4L,
607 WM5100_DAC_DIGITAL_VOLUME_4R, WM5100_OUT4L_MUTE_SHIFT, 1, 1),
608SOC_DOUBLE_R("SPKDAT1 Digital Switch", WM5100_DAC_DIGITAL_VOLUME_5L,
609 WM5100_DAC_DIGITAL_VOLUME_5R, WM5100_OUT5L_MUTE_SHIFT, 1, 1),
610SOC_DOUBLE_R("SPKDAT2 Digital Switch", WM5100_DAC_DIGITAL_VOLUME_6L,
611 WM5100_DAC_DIGITAL_VOLUME_6R, WM5100_OUT6L_MUTE_SHIFT, 1, 1),
612
613/* FIXME: Only valid from -12dB to 0dB (52-64) */
614SOC_DOUBLE_R_TLV("HPOUT1 Volume", WM5100_OUT_VOLUME_1L, WM5100_OUT_VOLUME_1R,
615 WM5100_OUT1L_PGA_VOL_SHIFT, 64, 0, out_tlv),
616SOC_DOUBLE_R_TLV("HPOUT2 Volume", WM5100_OUT_VOLUME_2L, WM5100_OUT_VOLUME_2R,
617 WM5100_OUT2L_PGA_VOL_SHIFT, 64, 0, out_tlv),
618SOC_DOUBLE_R_TLV("HPOUT3 Volume", WM5100_OUT_VOLUME_3L, WM5100_OUT_VOLUME_3R,
619 WM5100_OUT2L_PGA_VOL_SHIFT, 64, 0, out_tlv),
620
621SOC_DOUBLE("SPKDAT1 Switch", WM5100_PDM_SPK1_CTRL_1, WM5100_SPK1L_MUTE_SHIFT,
622 WM5100_SPK1R_MUTE_SHIFT, 1, 1),
623SOC_DOUBLE("SPKDAT2 Switch", WM5100_PDM_SPK2_CTRL_1, WM5100_SPK2L_MUTE_SHIFT,
624 WM5100_SPK2R_MUTE_SHIFT, 1, 1),
625
626SOC_SINGLE_TLV("EQ1 Band 1 Volume", WM5100_EQ1_1, WM5100_EQ1_B1_GAIN_SHIFT,
627 24, 0, eq_tlv),
628SOC_SINGLE_TLV("EQ1 Band 2 Volume", WM5100_EQ1_1, WM5100_EQ1_B2_GAIN_SHIFT,
629 24, 0, eq_tlv),
630SOC_SINGLE_TLV("EQ1 Band 3 Volume", WM5100_EQ1_1, WM5100_EQ1_B3_GAIN_SHIFT,
631 24, 0, eq_tlv),
632SOC_SINGLE_TLV("EQ1 Band 4 Volume", WM5100_EQ1_2, WM5100_EQ1_B4_GAIN_SHIFT,
633 24, 0, eq_tlv),
634SOC_SINGLE_TLV("EQ1 Band 5 Volume", WM5100_EQ1_2, WM5100_EQ1_B5_GAIN_SHIFT,
635 24, 0, eq_tlv),
636
637SOC_SINGLE_TLV("EQ2 Band 1 Volume", WM5100_EQ2_1, WM5100_EQ2_B1_GAIN_SHIFT,
638 24, 0, eq_tlv),
639SOC_SINGLE_TLV("EQ2 Band 2 Volume", WM5100_EQ2_1, WM5100_EQ2_B2_GAIN_SHIFT,
640 24, 0, eq_tlv),
641SOC_SINGLE_TLV("EQ2 Band 3 Volume", WM5100_EQ2_1, WM5100_EQ2_B3_GAIN_SHIFT,
642 24, 0, eq_tlv),
643SOC_SINGLE_TLV("EQ2 Band 4 Volume", WM5100_EQ2_2, WM5100_EQ2_B4_GAIN_SHIFT,
644 24, 0, eq_tlv),
645SOC_SINGLE_TLV("EQ2 Band 5 Volume", WM5100_EQ2_2, WM5100_EQ2_B5_GAIN_SHIFT,
646 24, 0, eq_tlv),
647
648SOC_SINGLE_TLV("EQ3 Band 1 Volume", WM5100_EQ1_1, WM5100_EQ3_B1_GAIN_SHIFT,
649 24, 0, eq_tlv),
650SOC_SINGLE_TLV("EQ3 Band 2 Volume", WM5100_EQ3_1, WM5100_EQ3_B2_GAIN_SHIFT,
651 24, 0, eq_tlv),
652SOC_SINGLE_TLV("EQ3 Band 3 Volume", WM5100_EQ3_1, WM5100_EQ3_B3_GAIN_SHIFT,
653 24, 0, eq_tlv),
654SOC_SINGLE_TLV("EQ3 Band 4 Volume", WM5100_EQ3_2, WM5100_EQ3_B4_GAIN_SHIFT,
655 24, 0, eq_tlv),
656SOC_SINGLE_TLV("EQ3 Band 5 Volume", WM5100_EQ3_2, WM5100_EQ3_B5_GAIN_SHIFT,
657 24, 0, eq_tlv),
658
659SOC_SINGLE_TLV("EQ4 Band 1 Volume", WM5100_EQ4_1, WM5100_EQ4_B1_GAIN_SHIFT,
660 24, 0, eq_tlv),
661SOC_SINGLE_TLV("EQ4 Band 2 Volume", WM5100_EQ4_1, WM5100_EQ4_B2_GAIN_SHIFT,
662 24, 0, eq_tlv),
663SOC_SINGLE_TLV("EQ4 Band 3 Volume", WM5100_EQ4_1, WM5100_EQ4_B3_GAIN_SHIFT,
664 24, 0, eq_tlv),
665SOC_SINGLE_TLV("EQ4 Band 4 Volume", WM5100_EQ4_2, WM5100_EQ4_B4_GAIN_SHIFT,
666 24, 0, eq_tlv),
667SOC_SINGLE_TLV("EQ4 Band 5 Volume", WM5100_EQ4_2, WM5100_EQ4_B5_GAIN_SHIFT,
668 24, 0, eq_tlv),
669
670SOC_ENUM("LHPF1 Mode", wm5100_lhpf1_mode),
671SOC_ENUM("LHPF2 Mode", wm5100_lhpf2_mode),
672SOC_ENUM("LHPF3 Mode", wm5100_lhpf3_mode),
673SOC_ENUM("LHPF4 Mode", wm5100_lhpf4_mode),
674
675WM5100_MIXER_CONTROLS("HPOUT1L", WM5100_OUT1LMIX_INPUT_1_SOURCE),
676WM5100_MIXER_CONTROLS("HPOUT1R", WM5100_OUT1RMIX_INPUT_1_SOURCE),
677WM5100_MIXER_CONTROLS("HPOUT2L", WM5100_OUT2LMIX_INPUT_1_SOURCE),
678WM5100_MIXER_CONTROLS("HPOUT2R", WM5100_OUT2RMIX_INPUT_1_SOURCE),
679WM5100_MIXER_CONTROLS("HPOUT3L", WM5100_OUT3LMIX_INPUT_1_SOURCE),
680WM5100_MIXER_CONTROLS("HPOUT3R", WM5100_OUT3RMIX_INPUT_1_SOURCE),
681
682WM5100_MIXER_CONTROLS("SPKOUTL", WM5100_OUT4LMIX_INPUT_1_SOURCE),
683WM5100_MIXER_CONTROLS("SPKOUTR", WM5100_OUT4RMIX_INPUT_1_SOURCE),
684WM5100_MIXER_CONTROLS("SPKDAT1L", WM5100_OUT5LMIX_INPUT_1_SOURCE),
685WM5100_MIXER_CONTROLS("SPKDAT1R", WM5100_OUT5RMIX_INPUT_1_SOURCE),
686WM5100_MIXER_CONTROLS("SPKDAT2L", WM5100_OUT6LMIX_INPUT_1_SOURCE),
687WM5100_MIXER_CONTROLS("SPKDAT2R", WM5100_OUT6RMIX_INPUT_1_SOURCE),
688
689WM5100_MIXER_CONTROLS("PWM1", WM5100_PWM1MIX_INPUT_1_SOURCE),
690WM5100_MIXER_CONTROLS("PWM2", WM5100_PWM2MIX_INPUT_1_SOURCE),
691
692WM5100_MIXER_CONTROLS("AIF1TX1", WM5100_AIF1TX1MIX_INPUT_1_SOURCE),
693WM5100_MIXER_CONTROLS("AIF1TX2", WM5100_AIF1TX2MIX_INPUT_1_SOURCE),
694WM5100_MIXER_CONTROLS("AIF1TX3", WM5100_AIF1TX3MIX_INPUT_1_SOURCE),
695WM5100_MIXER_CONTROLS("AIF1TX4", WM5100_AIF1TX4MIX_INPUT_1_SOURCE),
696WM5100_MIXER_CONTROLS("AIF1TX5", WM5100_AIF1TX5MIX_INPUT_1_SOURCE),
697WM5100_MIXER_CONTROLS("AIF1TX6", WM5100_AIF1TX6MIX_INPUT_1_SOURCE),
698WM5100_MIXER_CONTROLS("AIF1TX7", WM5100_AIF1TX7MIX_INPUT_1_SOURCE),
699WM5100_MIXER_CONTROLS("AIF1TX8", WM5100_AIF1TX8MIX_INPUT_1_SOURCE),
700
701WM5100_MIXER_CONTROLS("AIF2TX1", WM5100_AIF2TX1MIX_INPUT_1_SOURCE),
702WM5100_MIXER_CONTROLS("AIF2TX2", WM5100_AIF2TX2MIX_INPUT_1_SOURCE),
703
704WM5100_MIXER_CONTROLS("AIF3TX1", WM5100_AIF3TX1MIX_INPUT_1_SOURCE),
705WM5100_MIXER_CONTROLS("AIF3TX2", WM5100_AIF3TX2MIX_INPUT_1_SOURCE),
706
707WM5100_MIXER_CONTROLS("EQ1", WM5100_EQ1MIX_INPUT_1_SOURCE),
708WM5100_MIXER_CONTROLS("EQ2", WM5100_EQ2MIX_INPUT_1_SOURCE),
709WM5100_MIXER_CONTROLS("EQ3", WM5100_EQ3MIX_INPUT_1_SOURCE),
710WM5100_MIXER_CONTROLS("EQ4", WM5100_EQ4MIX_INPUT_1_SOURCE),
711
712WM5100_MIXER_CONTROLS("DRC1L", WM5100_DRC1LMIX_INPUT_1_SOURCE),
713WM5100_MIXER_CONTROLS("DRC1R", WM5100_DRC1RMIX_INPUT_1_SOURCE),
714
715WM5100_MIXER_CONTROLS("LHPF1", WM5100_HPLP1MIX_INPUT_1_SOURCE),
716WM5100_MIXER_CONTROLS("LHPF2", WM5100_HPLP2MIX_INPUT_1_SOURCE),
717WM5100_MIXER_CONTROLS("LHPF3", WM5100_HPLP3MIX_INPUT_1_SOURCE),
718WM5100_MIXER_CONTROLS("LHPF4", WM5100_HPLP4MIX_INPUT_1_SOURCE),
719};
720
721static void wm5100_seq_notifier(struct snd_soc_dapm_context *dapm,
722 enum snd_soc_dapm_type event, int subseq)
723{
724 struct snd_soc_codec *codec = container_of(dapm,
725 struct snd_soc_codec, dapm);
726 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
727 u16 val, expect, i;
728
729 /* Wait for the outputs to flag themselves as enabled */
730 if (wm5100->out_ena[0]) {
731 expect = snd_soc_read(codec, WM5100_CHANNEL_ENABLES_1);
732 for (i = 0; i < 200; i++) {
733 val = snd_soc_read(codec, WM5100_OUTPUT_STATUS_1);
734 if (val == expect) {
735 wm5100->out_ena[0] = false;
736 break;
737 }
738 }
739 if (i == 200) {
740 dev_err(codec->dev, "Timeout waiting for OUTPUT1 %x\n",
741 expect);
742 }
743 }
744
745 if (wm5100->out_ena[1]) {
746 expect = snd_soc_read(codec, WM5100_OUTPUT_ENABLES_2);
747 for (i = 0; i < 200; i++) {
748 val = snd_soc_read(codec, WM5100_OUTPUT_STATUS_2);
749 if (val == expect) {
750 wm5100->out_ena[1] = false;
751 break;
752 }
753 }
754 if (i == 200) {
755 dev_err(codec->dev, "Timeout waiting for OUTPUT2 %x\n",
756 expect);
757 }
758 }
759}
760
761static int wm5100_out_ev(struct snd_soc_dapm_widget *w,
762 struct snd_kcontrol *kcontrol,
763 int event)
764{
765 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(w->codec);
766
767 switch (w->reg) {
768 case WM5100_CHANNEL_ENABLES_1:
769 wm5100->out_ena[0] = true;
770 break;
771 case WM5100_OUTPUT_ENABLES_2:
772 wm5100->out_ena[0] = true;
773 break;
774 default:
775 break;
776 }
777
778 return 0;
779}
780
781static int wm5100_cp_ev(struct snd_soc_dapm_widget *w,
782 struct snd_kcontrol *kcontrol,
783 int event)
784{
785 struct snd_soc_codec *codec = w->codec;
786 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
787 int ret;
788
789 switch (event) {
790 case SND_SOC_DAPM_PRE_PMU:
791 ret = regulator_enable(wm5100->cpvdd);
792 if (ret != 0) {
793 dev_err(codec->dev, "Failed to enable CPVDD: %d\n",
794 ret);
795 return ret;
796 }
797 return ret;
798
799 case SND_SOC_DAPM_POST_PMD:
800 ret = regulator_disable_deferred(wm5100->cpvdd, 20);
801 if (ret != 0) {
802 dev_err(codec->dev, "Failed to disable CPVDD: %d\n",
803 ret);
804 return ret;
805 }
806 return ret;
807
808 default:
809 BUG();
810 return 0;
811 }
812}
813
814static int wm5100_dbvdd_ev(struct snd_soc_dapm_widget *w,
815 struct snd_kcontrol *kcontrol,
816 int event)
817{
818 struct snd_soc_codec *codec = w->codec;
819 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
820 struct regulator *regulator;
821 int ret;
822
823 switch (w->shift) {
824 case 2:
825 regulator = wm5100->dbvdd2;
826 break;
827 case 3:
828 regulator = wm5100->dbvdd3;
829 break;
830 default:
831 BUG();
832 return 0;
833 }
834
835 switch (event) {
836 case SND_SOC_DAPM_PRE_PMU:
837 ret = regulator_enable(regulator);
838 if (ret != 0) {
839 dev_err(codec->dev, "Failed to enable DBVDD%d: %d\n",
840 w->shift, ret);
841 return ret;
842 }
843 return ret;
844
845 case SND_SOC_DAPM_POST_PMD:
846 ret = regulator_disable(regulator);
847 if (ret != 0) {
848 dev_err(codec->dev, "Failed to enable DBVDD%d: %d\n",
849 w->shift, ret);
850 return ret;
851 }
852 return ret;
853
854 default:
855 BUG();
856 return 0;
857 }
858}
859
860static void wm5100_log_status3(struct snd_soc_codec *codec, int val)
861{
862 if (val & WM5100_SPK_SHUTDOWN_WARN_EINT)
863 dev_crit(codec->dev, "Speaker shutdown warning\n");
864 if (val & WM5100_SPK_SHUTDOWN_EINT)
865 dev_crit(codec->dev, "Speaker shutdown\n");
866 if (val & WM5100_CLKGEN_ERR_EINT)
867 dev_crit(codec->dev, "SYSCLK underclocked\n");
868 if (val & WM5100_CLKGEN_ERR_ASYNC_EINT)
869 dev_crit(codec->dev, "ASYNCCLK underclocked\n");
870}
871
872static void wm5100_log_status4(struct snd_soc_codec *codec, int val)
873{
874 if (val & WM5100_AIF3_ERR_EINT)
875 dev_err(codec->dev, "AIF3 configuration error\n");
876 if (val & WM5100_AIF2_ERR_EINT)
877 dev_err(codec->dev, "AIF2 configuration error\n");
878 if (val & WM5100_AIF1_ERR_EINT)
879 dev_err(codec->dev, "AIF1 configuration error\n");
880 if (val & WM5100_CTRLIF_ERR_EINT)
881 dev_err(codec->dev, "Control interface error\n");
882 if (val & WM5100_ISRC2_UNDERCLOCKED_EINT)
883 dev_err(codec->dev, "ISRC2 underclocked\n");
884 if (val & WM5100_ISRC1_UNDERCLOCKED_EINT)
885 dev_err(codec->dev, "ISRC1 underclocked\n");
886 if (val & WM5100_FX_UNDERCLOCKED_EINT)
887 dev_err(codec->dev, "FX underclocked\n");
888 if (val & WM5100_AIF3_UNDERCLOCKED_EINT)
889 dev_err(codec->dev, "AIF3 underclocked\n");
890 if (val & WM5100_AIF2_UNDERCLOCKED_EINT)
891 dev_err(codec->dev, "AIF2 underclocked\n");
892 if (val & WM5100_AIF1_UNDERCLOCKED_EINT)
893 dev_err(codec->dev, "AIF1 underclocked\n");
894 if (val & WM5100_ASRC_UNDERCLOCKED_EINT)
895 dev_err(codec->dev, "ASRC underclocked\n");
896 if (val & WM5100_DAC_UNDERCLOCKED_EINT)
897 dev_err(codec->dev, "DAC underclocked\n");
898 if (val & WM5100_ADC_UNDERCLOCKED_EINT)
899 dev_err(codec->dev, "ADC underclocked\n");
900 if (val & WM5100_MIXER_UNDERCLOCKED_EINT)
901 dev_err(codec->dev, "Mixer underclocked\n");
902}
903
904static int wm5100_post_ev(struct snd_soc_dapm_widget *w,
905 struct snd_kcontrol *kcontrol,
906 int event)
907{
908 struct snd_soc_codec *codec = w->codec;
909 int ret;
910
911 ret = snd_soc_read(codec, WM5100_INTERRUPT_RAW_STATUS_3);
912 ret &= WM5100_SPK_SHUTDOWN_WARN_STS |
913 WM5100_SPK_SHUTDOWN_STS | WM5100_CLKGEN_ERR_STS |
914 WM5100_CLKGEN_ERR_ASYNC_STS;
915 wm5100_log_status3(codec, ret);
916
917 ret = snd_soc_read(codec, WM5100_INTERRUPT_RAW_STATUS_4);
918 wm5100_log_status4(codec, ret);
919
920 return 0;
921}
922
923static const struct snd_soc_dapm_widget wm5100_dapm_widgets[] = {
924SND_SOC_DAPM_SUPPLY("SYSCLK", WM5100_CLOCKING_3, WM5100_SYSCLK_ENA_SHIFT, 0,
925 NULL, 0),
926SND_SOC_DAPM_SUPPLY("ASYNCCLK", WM5100_CLOCKING_6, WM5100_ASYNC_CLK_ENA_SHIFT,
927 0, NULL, 0),
928
929SND_SOC_DAPM_SUPPLY("CP1", WM5100_HP_CHARGE_PUMP_1, WM5100_CP1_ENA_SHIFT, 0,
930 wm5100_cp_ev,
931 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
932SND_SOC_DAPM_SUPPLY("CP2", WM5100_MIC_CHARGE_PUMP_1, WM5100_CP2_ENA_SHIFT, 0,
933 NULL, 0),
934SND_SOC_DAPM_SUPPLY("CP2 Active", WM5100_MIC_CHARGE_PUMP_1,
935 WM5100_CP2_BYPASS_SHIFT, 1, wm5100_cp_ev,
936 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
937SND_SOC_DAPM_SUPPLY("DBVDD2", SND_SOC_NOPM, 2, 0, wm5100_dbvdd_ev,
938 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
939SND_SOC_DAPM_SUPPLY("DBVDD3", SND_SOC_NOPM, 3, 0, wm5100_dbvdd_ev,
940 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
941
942SND_SOC_DAPM_SUPPLY("MICBIAS1", WM5100_MIC_BIAS_CTRL_1, WM5100_MICB1_ENA_SHIFT,
943 0, NULL, 0),
944SND_SOC_DAPM_SUPPLY("MICBIAS2", WM5100_MIC_BIAS_CTRL_2, WM5100_MICB2_ENA_SHIFT,
945 0, NULL, 0),
946SND_SOC_DAPM_SUPPLY("MICBIAS3", WM5100_MIC_BIAS_CTRL_3, WM5100_MICB3_ENA_SHIFT,
947 0, NULL, 0),
948
949SND_SOC_DAPM_INPUT("IN1L"),
950SND_SOC_DAPM_INPUT("IN1R"),
951SND_SOC_DAPM_INPUT("IN2L"),
952SND_SOC_DAPM_INPUT("IN2R"),
953SND_SOC_DAPM_INPUT("IN3L"),
954SND_SOC_DAPM_INPUT("IN3R"),
955SND_SOC_DAPM_INPUT("IN4L"),
956SND_SOC_DAPM_INPUT("IN4R"),
957SND_SOC_DAPM_INPUT("TONE"),
958
959SND_SOC_DAPM_PGA_E("IN1L PGA", WM5100_INPUT_ENABLES, WM5100_IN1L_ENA_SHIFT, 0,
960 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
961SND_SOC_DAPM_PGA_E("IN1R PGA", WM5100_INPUT_ENABLES, WM5100_IN1R_ENA_SHIFT, 0,
962 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
963SND_SOC_DAPM_PGA_E("IN2L PGA", WM5100_INPUT_ENABLES, WM5100_IN2L_ENA_SHIFT, 0,
964 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
965SND_SOC_DAPM_PGA_E("IN2R PGA", WM5100_INPUT_ENABLES, WM5100_IN2R_ENA_SHIFT, 0,
966 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
967SND_SOC_DAPM_PGA_E("IN3L PGA", WM5100_INPUT_ENABLES, WM5100_IN3L_ENA_SHIFT, 0,
968 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
969SND_SOC_DAPM_PGA_E("IN3R PGA", WM5100_INPUT_ENABLES, WM5100_IN3R_ENA_SHIFT, 0,
970 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
971SND_SOC_DAPM_PGA_E("IN4L PGA", WM5100_INPUT_ENABLES, WM5100_IN4L_ENA_SHIFT, 0,
972 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
973SND_SOC_DAPM_PGA_E("IN4R PGA", WM5100_INPUT_ENABLES, WM5100_IN4R_ENA_SHIFT, 0,
974 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
975
976SND_SOC_DAPM_PGA("Tone Generator 1", WM5100_TONE_GENERATOR_1,
977 WM5100_TONE1_ENA_SHIFT, 0, NULL, 0),
978SND_SOC_DAPM_PGA("Tone Generator 2", WM5100_TONE_GENERATOR_1,
979 WM5100_TONE2_ENA_SHIFT, 0, NULL, 0),
980
981SND_SOC_DAPM_AIF_IN("AIF1RX1", "AIF1 Playback", 0,
982 WM5100_AUDIO_IF_1_27, WM5100_AIF1RX1_ENA_SHIFT, 0),
983SND_SOC_DAPM_AIF_IN("AIF1RX2", "AIF1 Playback", 1,
984 WM5100_AUDIO_IF_1_27, WM5100_AIF1RX2_ENA_SHIFT, 0),
985SND_SOC_DAPM_AIF_IN("AIF1RX3", "AIF1 Playback", 2,
986 WM5100_AUDIO_IF_1_27, WM5100_AIF1RX3_ENA_SHIFT, 0),
987SND_SOC_DAPM_AIF_IN("AIF1RX4", "AIF1 Playback", 3,
988 WM5100_AUDIO_IF_1_27, WM5100_AIF1RX4_ENA_SHIFT, 0),
989SND_SOC_DAPM_AIF_IN("AIF1RX5", "AIF1 Playback", 4,
990 WM5100_AUDIO_IF_1_27, WM5100_AIF1RX5_ENA_SHIFT, 0),
991SND_SOC_DAPM_AIF_IN("AIF1RX6", "AIF1 Playback", 5,
992 WM5100_AUDIO_IF_1_27, WM5100_AIF1RX6_ENA_SHIFT, 0),
993SND_SOC_DAPM_AIF_IN("AIF1RX7", "AIF1 Playback", 6,
994 WM5100_AUDIO_IF_1_27, WM5100_AIF1RX7_ENA_SHIFT, 0),
995SND_SOC_DAPM_AIF_IN("AIF1RX8", "AIF1 Playback", 7,
996 WM5100_AUDIO_IF_1_27, WM5100_AIF1RX8_ENA_SHIFT, 0),
997
998SND_SOC_DAPM_AIF_IN("AIF2RX1", "AIF2 Playback", 0,
999 WM5100_AUDIO_IF_2_27, WM5100_AIF2RX1_ENA_SHIFT, 0),
1000SND_SOC_DAPM_AIF_IN("AIF2RX2", "AIF2 Playback", 1,
1001 WM5100_AUDIO_IF_2_27, WM5100_AIF2RX2_ENA_SHIFT, 0),
1002
1003SND_SOC_DAPM_AIF_IN("AIF3RX1", "AIF3 Playback", 0,
1004 WM5100_AUDIO_IF_3_27, WM5100_AIF3RX1_ENA_SHIFT, 0),
1005SND_SOC_DAPM_AIF_IN("AIF3RX2", "AIF3 Playback", 1,
1006 WM5100_AUDIO_IF_3_27, WM5100_AIF3RX2_ENA_SHIFT, 0),
1007
1008SND_SOC_DAPM_AIF_OUT("AIF1TX1", "AIF1 Capture", 0,
1009 WM5100_AUDIO_IF_1_26, WM5100_AIF1TX1_ENA_SHIFT, 0),
1010SND_SOC_DAPM_AIF_OUT("AIF1TX2", "AIF1 Capture", 1,
1011 WM5100_AUDIO_IF_1_26, WM5100_AIF1TX2_ENA_SHIFT, 0),
1012SND_SOC_DAPM_AIF_OUT("AIF1TX3", "AIF1 Capture", 2,
1013 WM5100_AUDIO_IF_1_26, WM5100_AIF1TX3_ENA_SHIFT, 0),
1014SND_SOC_DAPM_AIF_OUT("AIF1TX4", "AIF1 Capture", 3,
1015 WM5100_AUDIO_IF_1_26, WM5100_AIF1TX4_ENA_SHIFT, 0),
1016SND_SOC_DAPM_AIF_OUT("AIF1TX5", "AIF1 Capture", 4,
1017 WM5100_AUDIO_IF_1_26, WM5100_AIF1TX5_ENA_SHIFT, 0),
1018SND_SOC_DAPM_AIF_OUT("AIF1TX6", "AIF1 Capture", 5,
1019 WM5100_AUDIO_IF_1_26, WM5100_AIF1TX6_ENA_SHIFT, 0),
1020SND_SOC_DAPM_AIF_OUT("AIF1TX7", "AIF1 Capture", 6,
1021 WM5100_AUDIO_IF_1_26, WM5100_AIF1TX7_ENA_SHIFT, 0),
1022SND_SOC_DAPM_AIF_OUT("AIF1TX8", "AIF1 Capture", 7,
1023 WM5100_AUDIO_IF_1_26, WM5100_AIF1TX8_ENA_SHIFT, 0),
1024
1025SND_SOC_DAPM_AIF_OUT("AIF2TX1", "AIF2 Capture", 0,
1026 WM5100_AUDIO_IF_2_26, WM5100_AIF2TX1_ENA_SHIFT, 0),
1027SND_SOC_DAPM_AIF_OUT("AIF2TX2", "AIF2 Capture", 1,
1028 WM5100_AUDIO_IF_2_26, WM5100_AIF2TX2_ENA_SHIFT, 0),
1029
1030SND_SOC_DAPM_AIF_OUT("AIF3TX1", "AIF3 Capture", 0,
1031 WM5100_AUDIO_IF_3_26, WM5100_AIF3TX1_ENA_SHIFT, 0),
1032SND_SOC_DAPM_AIF_OUT("AIF3TX2", "AIF3 Capture", 1,
1033 WM5100_AUDIO_IF_3_26, WM5100_AIF3TX2_ENA_SHIFT, 0),
1034
1035SND_SOC_DAPM_PGA_E("OUT6L", WM5100_OUTPUT_ENABLES_2, WM5100_OUT6L_ENA_SHIFT, 0,
1036 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1037SND_SOC_DAPM_PGA_E("OUT6R", WM5100_OUTPUT_ENABLES_2, WM5100_OUT6R_ENA_SHIFT, 0,
1038 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1039SND_SOC_DAPM_PGA_E("OUT5L", WM5100_OUTPUT_ENABLES_2, WM5100_OUT5L_ENA_SHIFT, 0,
1040 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1041SND_SOC_DAPM_PGA_E("OUT5R", WM5100_OUTPUT_ENABLES_2, WM5100_OUT5R_ENA_SHIFT, 0,
1042 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1043SND_SOC_DAPM_PGA_E("OUT4L", WM5100_OUTPUT_ENABLES_2, WM5100_OUT4L_ENA_SHIFT, 0,
1044 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1045SND_SOC_DAPM_PGA_E("OUT4R", WM5100_OUTPUT_ENABLES_2, WM5100_OUT4R_ENA_SHIFT, 0,
1046 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1047SND_SOC_DAPM_PGA_E("OUT3L", WM5100_CHANNEL_ENABLES_1, WM5100_HP3L_ENA_SHIFT, 0,
1048 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1049SND_SOC_DAPM_PGA_E("OUT3R", WM5100_CHANNEL_ENABLES_1, WM5100_HP3R_ENA_SHIFT, 0,
1050 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1051SND_SOC_DAPM_PGA_E("OUT2L", WM5100_CHANNEL_ENABLES_1, WM5100_HP2L_ENA_SHIFT, 0,
1052 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1053SND_SOC_DAPM_PGA_E("OUT2R", WM5100_CHANNEL_ENABLES_1, WM5100_HP2R_ENA_SHIFT, 0,
1054 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1055SND_SOC_DAPM_PGA_E("OUT1L", WM5100_CHANNEL_ENABLES_1, WM5100_HP1L_ENA_SHIFT, 0,
1056 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1057SND_SOC_DAPM_PGA_E("OUT1R", WM5100_CHANNEL_ENABLES_1, WM5100_HP1R_ENA_SHIFT, 0,
1058 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1059SND_SOC_DAPM_PGA_E("PWM1 Driver", WM5100_PWM_DRIVE_1, WM5100_PWM1_ENA_SHIFT, 0,
1060 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1061SND_SOC_DAPM_PGA_E("PWM2 Driver", WM5100_PWM_DRIVE_1, WM5100_PWM2_ENA_SHIFT, 0,
1062 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1063
1064SND_SOC_DAPM_PGA("EQ1", WM5100_EQ1_1, WM5100_EQ1_ENA_SHIFT, 0, NULL, 0),
1065SND_SOC_DAPM_PGA("EQ2", WM5100_EQ2_1, WM5100_EQ2_ENA_SHIFT, 0, NULL, 0),
1066SND_SOC_DAPM_PGA("EQ3", WM5100_EQ3_1, WM5100_EQ3_ENA_SHIFT, 0, NULL, 0),
1067SND_SOC_DAPM_PGA("EQ4", WM5100_EQ4_1, WM5100_EQ4_ENA_SHIFT, 0, NULL, 0),
1068
1069SND_SOC_DAPM_PGA("DRC1L", WM5100_DRC1_CTRL1, WM5100_DRCL_ENA_SHIFT, 0,
1070 NULL, 0),
1071SND_SOC_DAPM_PGA("DRC1R", WM5100_DRC1_CTRL1, WM5100_DRCR_ENA_SHIFT, 0,
1072 NULL, 0),
1073
1074SND_SOC_DAPM_PGA("LHPF1", WM5100_HPLPF1_1, WM5100_LHPF1_ENA_SHIFT, 0,
1075 NULL, 0),
1076SND_SOC_DAPM_PGA("LHPF2", WM5100_HPLPF2_1, WM5100_LHPF2_ENA_SHIFT, 0,
1077 NULL, 0),
1078SND_SOC_DAPM_PGA("LHPF3", WM5100_HPLPF3_1, WM5100_LHPF3_ENA_SHIFT, 0,
1079 NULL, 0),
1080SND_SOC_DAPM_PGA("LHPF4", WM5100_HPLPF4_1, WM5100_LHPF4_ENA_SHIFT, 0,
1081 NULL, 0),
1082
1083WM5100_MIXER_WIDGETS(EQ1, "EQ1"),
1084WM5100_MIXER_WIDGETS(EQ2, "EQ2"),
1085WM5100_MIXER_WIDGETS(EQ3, "EQ3"),
1086WM5100_MIXER_WIDGETS(EQ4, "EQ4"),
1087
1088WM5100_MIXER_WIDGETS(DRC1L, "DRC1L"),
1089WM5100_MIXER_WIDGETS(DRC1R, "DRC1R"),
1090
1091WM5100_MIXER_WIDGETS(LHPF1, "LHPF1"),
1092WM5100_MIXER_WIDGETS(LHPF2, "LHPF2"),
1093WM5100_MIXER_WIDGETS(LHPF3, "LHPF3"),
1094WM5100_MIXER_WIDGETS(LHPF4, "LHPF4"),
1095
1096WM5100_MIXER_WIDGETS(AIF1TX1, "AIF1TX1"),
1097WM5100_MIXER_WIDGETS(AIF1TX2, "AIF1TX2"),
1098WM5100_MIXER_WIDGETS(AIF1TX3, "AIF1TX3"),
1099WM5100_MIXER_WIDGETS(AIF1TX4, "AIF1TX4"),
1100WM5100_MIXER_WIDGETS(AIF1TX5, "AIF1TX5"),
1101WM5100_MIXER_WIDGETS(AIF1TX6, "AIF1TX6"),
1102WM5100_MIXER_WIDGETS(AIF1TX7, "AIF1TX7"),
1103WM5100_MIXER_WIDGETS(AIF1TX8, "AIF1TX8"),
1104
1105WM5100_MIXER_WIDGETS(AIF2TX1, "AIF2TX1"),
1106WM5100_MIXER_WIDGETS(AIF2TX2, "AIF2TX2"),
1107
1108WM5100_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"),
1109WM5100_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"),
1110
1111WM5100_MIXER_WIDGETS(HPOUT1L, "HPOUT1L"),
1112WM5100_MIXER_WIDGETS(HPOUT1R, "HPOUT1R"),
1113WM5100_MIXER_WIDGETS(HPOUT2L, "HPOUT2L"),
1114WM5100_MIXER_WIDGETS(HPOUT2R, "HPOUT2R"),
1115WM5100_MIXER_WIDGETS(HPOUT3L, "HPOUT3L"),
1116WM5100_MIXER_WIDGETS(HPOUT3R, "HPOUT3R"),
1117
1118WM5100_MIXER_WIDGETS(SPKOUTL, "SPKOUTL"),
1119WM5100_MIXER_WIDGETS(SPKOUTR, "SPKOUTR"),
1120WM5100_MIXER_WIDGETS(SPKDAT1L, "SPKDAT1L"),
1121WM5100_MIXER_WIDGETS(SPKDAT1R, "SPKDAT1R"),
1122WM5100_MIXER_WIDGETS(SPKDAT2L, "SPKDAT2L"),
1123WM5100_MIXER_WIDGETS(SPKDAT2R, "SPKDAT2R"),
1124
1125WM5100_MIXER_WIDGETS(PWM1, "PWM1"),
1126WM5100_MIXER_WIDGETS(PWM2, "PWM2"),
1127
1128SND_SOC_DAPM_OUTPUT("HPOUT1L"),
1129SND_SOC_DAPM_OUTPUT("HPOUT1R"),
1130SND_SOC_DAPM_OUTPUT("HPOUT2L"),
1131SND_SOC_DAPM_OUTPUT("HPOUT2R"),
1132SND_SOC_DAPM_OUTPUT("HPOUT3L"),
1133SND_SOC_DAPM_OUTPUT("HPOUT3R"),
1134SND_SOC_DAPM_OUTPUT("SPKOUTL"),
1135SND_SOC_DAPM_OUTPUT("SPKOUTR"),
1136SND_SOC_DAPM_OUTPUT("SPKDAT1"),
1137SND_SOC_DAPM_OUTPUT("SPKDAT2"),
1138SND_SOC_DAPM_OUTPUT("PWM1"),
1139SND_SOC_DAPM_OUTPUT("PWM2"),
1140};
1141
1142/* We register a _POST event if we don't have IRQ support so we can
1143 * look at the error status from the CODEC - if we've got the IRQ
1144 * hooked up then we will get prompted to look by an interrupt.
1145 */
1146static const struct snd_soc_dapm_widget wm5100_dapm_widgets_noirq[] = {
1147SND_SOC_DAPM_POST("Post", wm5100_post_ev),
1148};
1149
1150static const struct snd_soc_dapm_route wm5100_dapm_routes[] = {
1151 { "IN1L", NULL, "SYSCLK" },
1152 { "IN1R", NULL, "SYSCLK" },
1153 { "IN2L", NULL, "SYSCLK" },
1154 { "IN2R", NULL, "SYSCLK" },
1155 { "IN3L", NULL, "SYSCLK" },
1156 { "IN3R", NULL, "SYSCLK" },
1157 { "IN4L", NULL, "SYSCLK" },
1158 { "IN4R", NULL, "SYSCLK" },
1159
1160 { "OUT1L", NULL, "SYSCLK" },
1161 { "OUT1R", NULL, "SYSCLK" },
1162 { "OUT2L", NULL, "SYSCLK" },
1163 { "OUT2R", NULL, "SYSCLK" },
1164 { "OUT3L", NULL, "SYSCLK" },
1165 { "OUT3R", NULL, "SYSCLK" },
1166 { "OUT4L", NULL, "SYSCLK" },
1167 { "OUT4R", NULL, "SYSCLK" },
1168 { "OUT5L", NULL, "SYSCLK" },
1169 { "OUT5R", NULL, "SYSCLK" },
1170 { "OUT6L", NULL, "SYSCLK" },
1171 { "OUT6R", NULL, "SYSCLK" },
1172
1173 { "AIF1RX1", NULL, "SYSCLK" },
1174 { "AIF1RX2", NULL, "SYSCLK" },
1175 { "AIF1RX3", NULL, "SYSCLK" },
1176 { "AIF1RX4", NULL, "SYSCLK" },
1177 { "AIF1RX5", NULL, "SYSCLK" },
1178 { "AIF1RX6", NULL, "SYSCLK" },
1179 { "AIF1RX7", NULL, "SYSCLK" },
1180 { "AIF1RX8", NULL, "SYSCLK" },
1181
1182 { "AIF2RX1", NULL, "SYSCLK" },
1183 { "AIF2RX1", NULL, "DBVDD2" },
1184 { "AIF2RX2", NULL, "SYSCLK" },
1185 { "AIF2RX2", NULL, "DBVDD2" },
1186
1187 { "AIF3RX1", NULL, "SYSCLK" },
1188 { "AIF3RX1", NULL, "DBVDD3" },
1189 { "AIF3RX2", NULL, "SYSCLK" },
1190 { "AIF3RX2", NULL, "DBVDD3" },
1191
1192 { "AIF1TX1", NULL, "SYSCLK" },
1193 { "AIF1TX2", NULL, "SYSCLK" },
1194 { "AIF1TX3", NULL, "SYSCLK" },
1195 { "AIF1TX4", NULL, "SYSCLK" },
1196 { "AIF1TX5", NULL, "SYSCLK" },
1197 { "AIF1TX6", NULL, "SYSCLK" },
1198 { "AIF1TX7", NULL, "SYSCLK" },
1199 { "AIF1TX8", NULL, "SYSCLK" },
1200
1201 { "AIF2TX1", NULL, "SYSCLK" },
1202 { "AIF2TX1", NULL, "DBVDD2" },
1203 { "AIF2TX2", NULL, "SYSCLK" },
1204 { "AIF2TX2", NULL, "DBVDD2" },
1205
1206 { "AIF3TX1", NULL, "SYSCLK" },
1207 { "AIF3TX1", NULL, "DBVDD3" },
1208 { "AIF3TX2", NULL, "SYSCLK" },
1209 { "AIF3TX2", NULL, "DBVDD3" },
1210
1211 { "MICBIAS1", NULL, "CP2" },
1212 { "MICBIAS2", NULL, "CP2" },
1213 { "MICBIAS3", NULL, "CP2" },
1214
1215 { "IN1L PGA", NULL, "CP2" },
1216 { "IN1R PGA", NULL, "CP2" },
1217 { "IN2L PGA", NULL, "CP2" },
1218 { "IN2R PGA", NULL, "CP2" },
1219 { "IN3L PGA", NULL, "CP2" },
1220 { "IN3R PGA", NULL, "CP2" },
1221 { "IN4L PGA", NULL, "CP2" },
1222 { "IN4R PGA", NULL, "CP2" },
1223
1224 { "IN1L PGA", NULL, "CP2 Active" },
1225 { "IN1R PGA", NULL, "CP2 Active" },
1226 { "IN2L PGA", NULL, "CP2 Active" },
1227 { "IN2R PGA", NULL, "CP2 Active" },
1228 { "IN3L PGA", NULL, "CP2 Active" },
1229 { "IN3R PGA", NULL, "CP2 Active" },
1230 { "IN4L PGA", NULL, "CP2 Active" },
1231 { "IN4R PGA", NULL, "CP2 Active" },
1232
1233 { "OUT1L", NULL, "CP1" },
1234 { "OUT1R", NULL, "CP1" },
1235 { "OUT2L", NULL, "CP1" },
1236 { "OUT2R", NULL, "CP1" },
1237 { "OUT3L", NULL, "CP1" },
1238 { "OUT3R", NULL, "CP1" },
1239
1240 { "Tone Generator 1", NULL, "TONE" },
1241 { "Tone Generator 2", NULL, "TONE" },
1242
1243 { "IN1L PGA", NULL, "IN1L" },
1244 { "IN1R PGA", NULL, "IN1R" },
1245 { "IN2L PGA", NULL, "IN2L" },
1246 { "IN2R PGA", NULL, "IN2R" },
1247 { "IN3L PGA", NULL, "IN3L" },
1248 { "IN3R PGA", NULL, "IN3R" },
1249 { "IN4L PGA", NULL, "IN4L" },
1250 { "IN4R PGA", NULL, "IN4R" },
1251
1252 WM5100_MIXER_ROUTES("OUT1L", "HPOUT1L"),
1253 WM5100_MIXER_ROUTES("OUT1R", "HPOUT1R"),
1254 WM5100_MIXER_ROUTES("OUT2L", "HPOUT2L"),
1255 WM5100_MIXER_ROUTES("OUT2R", "HPOUT2R"),
1256 WM5100_MIXER_ROUTES("OUT3L", "HPOUT3L"),
1257 WM5100_MIXER_ROUTES("OUT3R", "HPOUT3R"),
1258
1259 WM5100_MIXER_ROUTES("OUT4L", "SPKOUTL"),
1260 WM5100_MIXER_ROUTES("OUT4R", "SPKOUTR"),
1261 WM5100_MIXER_ROUTES("OUT5L", "SPKDAT1L"),
1262 WM5100_MIXER_ROUTES("OUT5R", "SPKDAT1R"),
1263 WM5100_MIXER_ROUTES("OUT6L", "SPKDAT2L"),
1264 WM5100_MIXER_ROUTES("OUT6R", "SPKDAT2R"),
1265
1266 WM5100_MIXER_ROUTES("PWM1 Driver", "PWM1"),
1267 WM5100_MIXER_ROUTES("PWM2 Driver", "PWM2"),
1268
1269 WM5100_MIXER_ROUTES("AIF1TX1", "AIF1TX1"),
1270 WM5100_MIXER_ROUTES("AIF1TX2", "AIF1TX2"),
1271 WM5100_MIXER_ROUTES("AIF1TX3", "AIF1TX3"),
1272 WM5100_MIXER_ROUTES("AIF1TX4", "AIF1TX4"),
1273 WM5100_MIXER_ROUTES("AIF1TX5", "AIF1TX5"),
1274 WM5100_MIXER_ROUTES("AIF1TX6", "AIF1TX6"),
1275 WM5100_MIXER_ROUTES("AIF1TX7", "AIF1TX7"),
1276 WM5100_MIXER_ROUTES("AIF1TX8", "AIF1TX8"),
1277
1278 WM5100_MIXER_ROUTES("AIF2TX1", "AIF2TX1"),
1279 WM5100_MIXER_ROUTES("AIF2TX2", "AIF2TX2"),
1280
1281 WM5100_MIXER_ROUTES("AIF3TX1", "AIF3TX1"),
1282 WM5100_MIXER_ROUTES("AIF3TX2", "AIF3TX2"),
1283
1284 WM5100_MIXER_ROUTES("EQ1", "EQ1"),
1285 WM5100_MIXER_ROUTES("EQ2", "EQ2"),
1286 WM5100_MIXER_ROUTES("EQ3", "EQ3"),
1287 WM5100_MIXER_ROUTES("EQ4", "EQ4"),
1288
1289 WM5100_MIXER_ROUTES("DRC1L", "DRC1L"),
1290 WM5100_MIXER_ROUTES("DRC1R", "DRC1R"),
1291
1292 WM5100_MIXER_ROUTES("LHPF1", "LHPF1"),
1293 WM5100_MIXER_ROUTES("LHPF2", "LHPF2"),
1294 WM5100_MIXER_ROUTES("LHPF3", "LHPF3"),
1295 WM5100_MIXER_ROUTES("LHPF4", "LHPF4"),
1296
1297 { "HPOUT1L", NULL, "OUT1L" },
1298 { "HPOUT1R", NULL, "OUT1R" },
1299 { "HPOUT2L", NULL, "OUT2L" },
1300 { "HPOUT2R", NULL, "OUT2R" },
1301 { "HPOUT3L", NULL, "OUT3L" },
1302 { "HPOUT3R", NULL, "OUT3R" },
1303 { "SPKOUTL", NULL, "OUT4L" },
1304 { "SPKOUTR", NULL, "OUT4R" },
1305 { "SPKDAT1", NULL, "OUT5L" },
1306 { "SPKDAT1", NULL, "OUT5R" },
1307 { "SPKDAT2", NULL, "OUT6L" },
1308 { "SPKDAT2", NULL, "OUT6R" },
1309 { "PWM1", NULL, "PWM1 Driver" },
1310 { "PWM2", NULL, "PWM2 Driver" },
1311};
1312
1313static struct {
1314 int reg;
1315 int val;
1316} wm5100_reva_patches[] = {
1317 { WM5100_AUDIO_IF_1_10, 0 },
1318 { WM5100_AUDIO_IF_1_11, 1 },
1319 { WM5100_AUDIO_IF_1_12, 2 },
1320 { WM5100_AUDIO_IF_1_13, 3 },
1321 { WM5100_AUDIO_IF_1_14, 4 },
1322 { WM5100_AUDIO_IF_1_15, 5 },
1323 { WM5100_AUDIO_IF_1_16, 6 },
1324 { WM5100_AUDIO_IF_1_17, 7 },
1325
1326 { WM5100_AUDIO_IF_1_18, 0 },
1327 { WM5100_AUDIO_IF_1_19, 1 },
1328 { WM5100_AUDIO_IF_1_20, 2 },
1329 { WM5100_AUDIO_IF_1_21, 3 },
1330 { WM5100_AUDIO_IF_1_22, 4 },
1331 { WM5100_AUDIO_IF_1_23, 5 },
1332 { WM5100_AUDIO_IF_1_24, 6 },
1333 { WM5100_AUDIO_IF_1_25, 7 },
1334
1335 { WM5100_AUDIO_IF_2_10, 0 },
1336 { WM5100_AUDIO_IF_2_11, 1 },
1337
1338 { WM5100_AUDIO_IF_2_18, 0 },
1339 { WM5100_AUDIO_IF_2_19, 1 },
1340
1341 { WM5100_AUDIO_IF_3_10, 0 },
1342 { WM5100_AUDIO_IF_3_11, 1 },
1343
1344 { WM5100_AUDIO_IF_3_18, 0 },
1345 { WM5100_AUDIO_IF_3_19, 1 },
1346};
1347
1348static int wm5100_set_bias_level(struct snd_soc_codec *codec,
1349 enum snd_soc_bias_level level)
1350{
1351 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
1352 int ret, i;
1353
1354 switch (level) {
1355 case SND_SOC_BIAS_ON:
1356 break;
1357
1358 case SND_SOC_BIAS_PREPARE:
1359 break;
1360
1361 case SND_SOC_BIAS_STANDBY:
1362 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1363 ret = regulator_bulk_enable(ARRAY_SIZE(wm5100->core_supplies),
1364 wm5100->core_supplies);
1365 if (ret != 0) {
1366 dev_err(codec->dev,
1367 "Failed to enable supplies: %d\n",
1368 ret);
1369 return ret;
1370 }
1371
1372 if (wm5100->pdata.ldo_ena) {
1373 gpio_set_value_cansleep(wm5100->pdata.ldo_ena,
1374 1);
1375 msleep(2);
1376 }
1377
1378 codec->cache_only = false;
1379
1380 switch (wm5100->rev) {
1381 case 0:
1382 snd_soc_write(codec, 0x11, 0x3);
1383 snd_soc_write(codec, 0x203, 0xc);
1384 snd_soc_write(codec, 0x206, 0);
1385 snd_soc_write(codec, 0x207, 0xf0);
1386 snd_soc_write(codec, 0x208, 0x3c);
1387 snd_soc_write(codec, 0x209, 0);
1388 snd_soc_write(codec, 0x211, 0x20d8);
1389 snd_soc_write(codec, 0x11, 0);
1390
1391 for (i = 0;
1392 i < ARRAY_SIZE(wm5100_reva_patches);
1393 i++)
1394 snd_soc_write(codec,
1395 wm5100_reva_patches[i].reg,
1396 wm5100_reva_patches[i].val);
1397 break;
1398 default:
1399 break;
1400 }
1401
1402 snd_soc_cache_sync(codec);
1403 }
1404 break;
1405
1406 case SND_SOC_BIAS_OFF:
1407 if (wm5100->pdata.ldo_ena)
1408 gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
1409 regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies),
1410 wm5100->core_supplies);
1411 break;
1412 }
1413 codec->dapm.bias_level = level;
1414
1415 return 0;
1416}
1417
1418static int wm5100_dai_to_base(struct snd_soc_dai *dai)
1419{
1420 switch (dai->id) {
1421 case 0:
1422 return WM5100_AUDIO_IF_1_1 - 1;
1423 case 1:
1424 return WM5100_AUDIO_IF_2_1 - 1;
1425 case 2:
1426 return WM5100_AUDIO_IF_3_1 - 1;
1427 default:
1428 BUG();
1429 return -EINVAL;
1430 }
1431}
1432
1433static int wm5100_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1434{
1435 struct snd_soc_codec *codec = dai->codec;
1436 int lrclk, bclk, mask, base;
1437
1438 base = wm5100_dai_to_base(dai);
1439 if (base < 0)
1440 return base;
1441
1442 lrclk = 0;
1443 bclk = 0;
1444
1445 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1446 case SND_SOC_DAIFMT_DSP_A:
1447 mask = 0;
1448 break;
1449 case SND_SOC_DAIFMT_DSP_B:
1450 mask = 1;
1451 break;
1452 case SND_SOC_DAIFMT_I2S:
1453 mask = 2;
1454 break;
1455 case SND_SOC_DAIFMT_LEFT_J:
1456 mask = 3;
1457 break;
1458 default:
1459 dev_err(codec->dev, "Unsupported DAI format %d\n",
1460 fmt & SND_SOC_DAIFMT_FORMAT_MASK);
1461 return -EINVAL;
1462 }
1463
1464 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1465 case SND_SOC_DAIFMT_CBS_CFS:
1466 break;
1467 case SND_SOC_DAIFMT_CBS_CFM:
1468 lrclk |= WM5100_AIF1TX_LRCLK_MSTR;
1469 break;
1470 case SND_SOC_DAIFMT_CBM_CFS:
1471 bclk |= WM5100_AIF1_BCLK_MSTR;
1472 break;
1473 case SND_SOC_DAIFMT_CBM_CFM:
1474 lrclk |= WM5100_AIF1TX_LRCLK_MSTR;
1475 bclk |= WM5100_AIF1_BCLK_MSTR;
1476 break;
1477 default:
1478 dev_err(codec->dev, "Unsupported master mode %d\n",
1479 fmt & SND_SOC_DAIFMT_MASTER_MASK);
1480 return -EINVAL;
1481 }
1482
1483 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1484 case SND_SOC_DAIFMT_NB_NF:
1485 break;
1486 case SND_SOC_DAIFMT_IB_IF:
1487 bclk |= WM5100_AIF1_BCLK_INV;
1488 lrclk |= WM5100_AIF1TX_LRCLK_INV;
1489 break;
1490 case SND_SOC_DAIFMT_IB_NF:
1491 bclk |= WM5100_AIF1_BCLK_INV;
1492 break;
1493 case SND_SOC_DAIFMT_NB_IF:
1494 lrclk |= WM5100_AIF1TX_LRCLK_INV;
1495 break;
1496 default:
1497 return -EINVAL;
1498 }
1499
1500 snd_soc_update_bits(codec, base + 1, WM5100_AIF1_BCLK_MSTR |
1501 WM5100_AIF1_BCLK_INV, bclk);
1502 snd_soc_update_bits(codec, base + 2, WM5100_AIF1TX_LRCLK_MSTR |
1503 WM5100_AIF1TX_LRCLK_INV, lrclk);
1504 snd_soc_update_bits(codec, base + 3, WM5100_AIF1TX_LRCLK_MSTR |
1505 WM5100_AIF1TX_LRCLK_INV, lrclk);
1506 snd_soc_update_bits(codec, base + 5, WM5100_AIF1_FMT_MASK, mask);
1507
1508 return 0;
1509}
1510
1511#define WM5100_NUM_BCLK_RATES 19
1512
1513static int wm5100_bclk_rates_dat[WM5100_NUM_BCLK_RATES] = {
1514 32000,
1515 48000,
1516 64000,
1517 96000,
1518 128000,
1519 192000,
1520 256000,
1521 384000,
1522 512000,
1523 768000,
1524 1024000,
1525 1536000,
1526 2048000,
1527 3072000,
1528 4096000,
1529 6144000,
1530 8192000,
1531 12288000,
1532 24576000,
1533};
1534
1535static int wm5100_bclk_rates_cd[WM5100_NUM_BCLK_RATES] = {
1536 29400,
1537 44100,
1538 58800,
1539 88200,
1540 117600,
1541 176400,
1542 235200,
1543 352800,
1544 470400,
1545 705600,
1546 940800,
1547 1411200,
1548 1881600,
1549 2882400,
1550 3763200,
1551 5644800,
1552 7526400,
1553 11289600,
1554 22579600,
1555};
1556
1557static int wm5100_hw_params(struct snd_pcm_substream *substream,
1558 struct snd_pcm_hw_params *params,
1559 struct snd_soc_dai *dai)
1560{
1561 struct snd_soc_codec *codec = dai->codec;
1562 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
1563 bool async = wm5100->aif_async[dai->id];
1564 int i, base, bclk, aif_rate, lrclk, wl, fl, sr;
1565 int *bclk_rates;
1566
1567 base = wm5100_dai_to_base(dai);
1568 if (base < 0)
1569 return base;
1570
1571 /* Data sizes if not using TDM */
1572 wl = snd_pcm_format_width(params_format(params));
1573 if (wl < 0)
1574 return wl;
1575 fl = snd_soc_params_to_frame_size(params);
1576 if (fl < 0)
1577 return fl;
1578
1579 dev_dbg(codec->dev, "Word length %d bits, frame length %d bits\n",
1580 wl, fl);
1581
1582 /* Target BCLK rate */
1583 bclk = snd_soc_params_to_bclk(params);
1584 if (bclk < 0)
1585 return bclk;
1586
1587 /* Root for BCLK depends on SYS/ASYNCCLK */
1588 if (!async) {
1589 aif_rate = wm5100->sysclk;
1590 sr = wm5100_alloc_sr(codec, params_rate(params));
1591 if (sr < 0)
1592 return sr;
1593 } else {
1594 /* If we're in ASYNCCLK set the ASYNC sample rate */
1595 aif_rate = wm5100->asyncclk;
1596 sr = 3;
1597
1598 for (i = 0; i < ARRAY_SIZE(wm5100_sr_code); i++)
1599 if (params_rate(params) == wm5100_sr_code[i])
1600 break;
1601 if (i == ARRAY_SIZE(wm5100_sr_code)) {
1602 dev_err(codec->dev, "Invalid rate %dHzn",
1603 params_rate(params));
1604 return -EINVAL;
1605 }
1606
1607 /* TODO: We should really check for symmetry */
1608 snd_soc_update_bits(codec, WM5100_CLOCKING_8,
1609 WM5100_ASYNC_SAMPLE_RATE_MASK, i);
1610 }
1611
1612 if (!aif_rate) {
1613 dev_err(codec->dev, "%s has no rate set\n",
1614 async ? "ASYNCCLK" : "SYSCLK");
1615 return -EINVAL;
1616 }
1617
1618 dev_dbg(codec->dev, "Target BCLK is %dHz, using %dHz %s\n",
1619 bclk, aif_rate, async ? "ASYNCCLK" : "SYSCLK");
1620
1621 if (aif_rate % 4000)
1622 bclk_rates = wm5100_bclk_rates_cd;
1623 else
1624 bclk_rates = wm5100_bclk_rates_dat;
1625
1626 for (i = 0; i < WM5100_NUM_BCLK_RATES; i++)
1627 if (bclk_rates[i] >= bclk && (bclk_rates[i] % bclk == 0))
1628 break;
1629 if (i == WM5100_NUM_BCLK_RATES) {
1630 dev_err(codec->dev,
1631 "No valid BCLK for %dHz found from %dHz %s\n",
1632 bclk, aif_rate, async ? "ASYNCCLK" : "SYSCLK");
1633 return -EINVAL;
1634 }
1635
1636 bclk = i;
1637 dev_dbg(codec->dev, "Setting %dHz BCLK\n", bclk_rates[bclk]);
1638 snd_soc_update_bits(codec, base + 1, WM5100_AIF1_BCLK_FREQ_MASK, bclk);
1639
1640 lrclk = bclk_rates[bclk] / params_rate(params);
1641 dev_dbg(codec->dev, "Setting %dHz LRCLK\n", bclk_rates[bclk] / lrclk);
1642 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
1643 wm5100->aif_symmetric[dai->id])
1644 snd_soc_update_bits(codec, base + 7,
1645 WM5100_AIF1RX_BCPF_MASK, lrclk);
1646 else
1647 snd_soc_update_bits(codec, base + 6,
1648 WM5100_AIF1TX_BCPF_MASK, lrclk);
1649
1650 i = (wl << WM5100_AIF1TX_WL_SHIFT) | fl;
1651 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1652 snd_soc_update_bits(codec, base + 9,
1653 WM5100_AIF1RX_WL_MASK |
1654 WM5100_AIF1RX_SLOT_LEN_MASK, i);
1655 else
1656 snd_soc_update_bits(codec, base + 8,
1657 WM5100_AIF1TX_WL_MASK |
1658 WM5100_AIF1TX_SLOT_LEN_MASK, i);
1659
1660 snd_soc_update_bits(codec, base + 4, WM5100_AIF1_RATE_MASK, sr);
1661
1662 return 0;
1663}
1664
1665static struct snd_soc_dai_ops wm5100_dai_ops = {
1666 .set_fmt = wm5100_set_fmt,
1667 .hw_params = wm5100_hw_params,
1668};
1669
1670static int wm5100_set_sysclk(struct snd_soc_codec *codec, int clk_id,
1671 int source, unsigned int freq, int dir)
1672{
1673 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
1674 int *rate_store;
1675 int fval, audio_rate, ret, reg;
1676
1677 switch (clk_id) {
1678 case WM5100_CLK_SYSCLK:
1679 reg = WM5100_CLOCKING_3;
1680 rate_store = &wm5100->sysclk;
1681 break;
1682 case WM5100_CLK_ASYNCCLK:
1683 reg = WM5100_CLOCKING_7;
1684 rate_store = &wm5100->asyncclk;
1685 break;
1686 case WM5100_CLK_32KHZ:
1687 /* The 32kHz clock is slightly different to the others */
1688 switch (source) {
1689 case WM5100_CLKSRC_MCLK1:
1690 case WM5100_CLKSRC_MCLK2:
1691 case WM5100_CLKSRC_SYSCLK:
1692 snd_soc_update_bits(codec, WM5100_CLOCKING_1,
1693 WM5100_CLK_32K_SRC_MASK,
1694 source);
1695 break;
1696 default:
1697 return -EINVAL;
1698 }
1699 return 0;
1700
1701 case WM5100_CLK_AIF1:
1702 case WM5100_CLK_AIF2:
1703 case WM5100_CLK_AIF3:
1704 /* Not real clocks, record which clock domain they're in */
1705 switch (source) {
1706 case WM5100_CLKSRC_SYSCLK:
1707 wm5100->aif_async[clk_id - 1] = false;
1708 break;
1709 case WM5100_CLKSRC_ASYNCCLK:
1710 wm5100->aif_async[clk_id - 1] = true;
1711 break;
1712 default:
1713 dev_err(codec->dev, "Invalid source %d\n", source);
1714 return -EINVAL;
1715 }
1716 return 0;
1717
1718 case WM5100_CLK_OPCLK:
1719 switch (freq) {
1720 case 5644800:
1721 case 6144000:
1722 snd_soc_update_bits(codec, WM5100_MISC_GPIO_1,
1723 WM5100_OPCLK_SEL_MASK, 0);
1724 break;
1725 case 11289600:
1726 case 12288000:
1727 snd_soc_update_bits(codec, WM5100_MISC_GPIO_1,
1728 WM5100_OPCLK_SEL_MASK, 0);
1729 break;
1730 case 22579200:
1731 case 24576000:
1732 snd_soc_update_bits(codec, WM5100_MISC_GPIO_1,
1733 WM5100_OPCLK_SEL_MASK, 0);
1734 break;
1735 default:
1736 dev_err(codec->dev, "Unsupported OPCLK %dHz\n",
1737 freq);
1738 return -EINVAL;
1739 }
1740 return 0;
1741
1742 default:
1743 dev_err(codec->dev, "Unknown clock %d\n", clk_id);
1744 return -EINVAL;
1745 }
1746
1747 switch (source) {
1748 case WM5100_CLKSRC_SYSCLK:
1749 case WM5100_CLKSRC_ASYNCCLK:
1750 dev_err(codec->dev, "Invalid source %d\n", source);
1751 return -EINVAL;
1752 }
1753
1754 switch (freq) {
1755 case 5644800:
1756 case 6144000:
1757 fval = 0;
1758 break;
1759 case 11289600:
1760 case 12288000:
1761 fval = 1;
1762 break;
1763 case 22579200:
1764 case 24576000:
1765 fval = 2;
1766 break;
1767 default:
1768 dev_err(codec->dev, "Invalid clock rate: %d\n", freq);
1769 return -EINVAL;
1770 }
1771
1772 switch (freq) {
1773 case 5644800:
1774 case 11289600:
1775 case 22579200:
1776 audio_rate = 44100;
1777 break;
1778
1779 case 6144000:
1780 case 12288000:
1781 case 24576000:
1782 audio_rate = 48000;
1783 break;
1784
1785 default:
1786 BUG();
1787 audio_rate = 0;
1788 break;
1789 }
1790
1791 /* TODO: Check if MCLKs are in use and enable/disable pulls to
1792 * match.
1793 */
1794
1795 snd_soc_update_bits(codec, reg, WM5100_SYSCLK_FREQ_MASK |
1796 WM5100_SYSCLK_SRC_MASK,
1797 fval << WM5100_SYSCLK_FREQ_SHIFT | source);
1798
1799 /* If this is SYSCLK then configure the clock rate for the
1800 * internal audio functions to the natural sample rate for
1801 * this clock rate.
1802 */
1803 if (clk_id == WM5100_CLK_SYSCLK) {
1804 dev_dbg(codec->dev, "Setting primary audio rate to %dHz",
1805 audio_rate);
1806 if (0 && *rate_store)
1807 wm5100_free_sr(codec, audio_rate);
1808 ret = wm5100_alloc_sr(codec, audio_rate);
1809 if (ret != 0)
1810 dev_warn(codec->dev, "Primary audio slot is %d\n",
1811 ret);
1812 }
1813
1814 *rate_store = freq;
1815
1816 return 0;
1817}
1818
1819struct _fll_div {
1820 u16 fll_fratio;
1821 u16 fll_outdiv;
1822 u16 fll_refclk_div;
1823 u16 n;
1824 u16 theta;
1825 u16 lambda;
1826};
1827
1828static struct {
1829 unsigned int min;
1830 unsigned int max;
1831 u16 fll_fratio;
1832 int ratio;
1833} fll_fratios[] = {
1834 { 0, 64000, 4, 16 },
1835 { 64000, 128000, 3, 8 },
1836 { 128000, 256000, 2, 4 },
1837 { 256000, 1000000, 1, 2 },
1838 { 1000000, 13500000, 0, 1 },
1839};
1840
1841static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
1842 unsigned int Fout)
1843{
1844 unsigned int target;
1845 unsigned int div;
1846 unsigned int fratio, gcd_fll;
1847 int i;
1848
1849 /* Fref must be <=13.5MHz */
1850 div = 1;
1851 fll_div->fll_refclk_div = 0;
1852 while ((Fref / div) > 13500000) {
1853 div *= 2;
1854 fll_div->fll_refclk_div++;
1855
1856 if (div > 8) {
1857 pr_err("Can't scale %dMHz input down to <=13.5MHz\n",
1858 Fref);
1859 return -EINVAL;
1860 }
1861 }
1862
1863 pr_debug("FLL Fref=%u Fout=%u\n", Fref, Fout);
1864
1865 /* Apply the division for our remaining calculations */
1866 Fref /= div;
1867
1868 /* Fvco should be 90-100MHz; don't check the upper bound */
1869 div = 2;
1870 while (Fout * div < 90000000) {
1871 div++;
1872 if (div > 64) {
1873 pr_err("Unable to find FLL_OUTDIV for Fout=%uHz\n",
1874 Fout);
1875 return -EINVAL;
1876 }
1877 }
1878 target = Fout * div;
1879 fll_div->fll_outdiv = div - 1;
1880
1881 pr_debug("FLL Fvco=%dHz\n", target);
1882
1883 /* Find an appropraite FLL_FRATIO and factor it out of the target */
1884 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
1885 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
1886 fll_div->fll_fratio = fll_fratios[i].fll_fratio;
1887 fratio = fll_fratios[i].ratio;
1888 break;
1889 }
1890 }
1891 if (i == ARRAY_SIZE(fll_fratios)) {
1892 pr_err("Unable to find FLL_FRATIO for Fref=%uHz\n", Fref);
1893 return -EINVAL;
1894 }
1895
1896 fll_div->n = target / (fratio * Fref);
1897
1898 if (target % Fref == 0) {
1899 fll_div->theta = 0;
1900 fll_div->lambda = 0;
1901 } else {
1902 gcd_fll = gcd(target, fratio * Fref);
1903
1904 fll_div->theta = (target - (fll_div->n * fratio * Fref))
1905 / gcd_fll;
1906 fll_div->lambda = (fratio * Fref) / gcd_fll;
1907 }
1908
1909 pr_debug("FLL N=%x THETA=%x LAMBDA=%x\n",
1910 fll_div->n, fll_div->theta, fll_div->lambda);
1911 pr_debug("FLL_FRATIO=%x(%d) FLL_OUTDIV=%x FLL_REFCLK_DIV=%x\n",
1912 fll_div->fll_fratio, fratio, fll_div->fll_outdiv,
1913 fll_div->fll_refclk_div);
1914
1915 return 0;
1916}
1917
1918static int wm5100_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
1919 unsigned int Fref, unsigned int Fout)
1920{
1921 struct i2c_client *i2c = to_i2c_client(codec->dev);
1922 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
1923 struct _fll_div factors;
1924 struct wm5100_fll *fll;
1925 int ret, base, lock, i, timeout;
1926
1927 switch (fll_id) {
1928 case WM5100_FLL1:
1929 fll = &wm5100->fll[0];
1930 base = WM5100_FLL1_CONTROL_1 - 1;
1931 lock = WM5100_FLL1_LOCK_STS;
1932 break;
1933 case WM5100_FLL2:
1934 fll = &wm5100->fll[1];
1935 base = WM5100_FLL2_CONTROL_2 - 1;
1936 lock = WM5100_FLL2_LOCK_STS;
1937 break;
1938 default:
1939 dev_err(codec->dev, "Unknown FLL %d\n",fll_id);
1940 return -EINVAL;
1941 }
1942
1943 if (!Fout) {
1944 dev_dbg(codec->dev, "FLL%d disabled", fll_id);
1945 fll->fout = 0;
1946 snd_soc_update_bits(codec, base + 1, WM5100_FLL1_ENA, 0);
1947 return 0;
1948 }
1949
1950 switch (source) {
1951 case WM5100_FLL_SRC_MCLK1:
1952 case WM5100_FLL_SRC_MCLK2:
1953 case WM5100_FLL_SRC_FLL1:
1954 case WM5100_FLL_SRC_FLL2:
1955 case WM5100_FLL_SRC_AIF1BCLK:
1956 case WM5100_FLL_SRC_AIF2BCLK:
1957 case WM5100_FLL_SRC_AIF3BCLK:
1958 break;
1959 default:
1960 dev_err(codec->dev, "Invalid FLL source %d\n", source);
1961 return -EINVAL;
1962 }
1963
1964 ret = fll_factors(&factors, Fref, Fout);
1965 if (ret < 0)
1966 return ret;
1967
1968 /* Disable the FLL while we reconfigure */
1969 snd_soc_update_bits(codec, base + 1, WM5100_FLL1_ENA, 0);
1970
1971 snd_soc_update_bits(codec, base + 2,
1972 WM5100_FLL1_OUTDIV_MASK | WM5100_FLL1_FRATIO_MASK,
1973 (factors.fll_outdiv << WM5100_FLL1_OUTDIV_SHIFT) |
1974 factors.fll_fratio);
1975 snd_soc_update_bits(codec, base + 3, WM5100_FLL1_THETA_MASK,
1976 factors.theta);
1977 snd_soc_update_bits(codec, base + 5, WM5100_FLL1_N_MASK, factors.n);
1978 snd_soc_update_bits(codec, base + 6,
1979 WM5100_FLL1_REFCLK_DIV_MASK |
1980 WM5100_FLL1_REFCLK_SRC_MASK,
1981 (factors.fll_refclk_div
1982 << WM5100_FLL1_REFCLK_DIV_SHIFT) | source);
1983 snd_soc_update_bits(codec, base + 7, WM5100_FLL1_LAMBDA_MASK,
1984 factors.lambda);
1985
1986 /* Clear any pending completions */
1987 try_wait_for_completion(&fll->lock);
1988
1989 snd_soc_update_bits(codec, base + 1, WM5100_FLL1_ENA, WM5100_FLL1_ENA);
1990
1991 if (i2c->irq)
1992 timeout = 2;
1993 else
1994 timeout = 50;
1995
1996 /* Poll for the lock; will use interrupt when we can test */
1997 for (i = 0; i < timeout; i++) {
1998 if (i2c->irq) {
1999 ret = wait_for_completion_timeout(&fll->lock,
2000 msecs_to_jiffies(25));
2001 if (ret > 0)
2002 break;
2003 } else {
2004 msleep(1);
2005 }
2006
2007 ret = snd_soc_read(codec,
2008 WM5100_INTERRUPT_RAW_STATUS_3);
2009 if (ret < 0) {
2010 dev_err(codec->dev,
2011 "Failed to read FLL status: %d\n",
2012 ret);
2013 continue;
2014 }
2015 if (ret & lock)
2016 break;
2017 }
2018 if (i == timeout) {
2019 dev_err(codec->dev, "FLL%d lock timed out\n", fll_id);
2020 return -ETIMEDOUT;
2021 }
2022
2023 fll->src = source;
2024 fll->fref = Fref;
2025 fll->fout = Fout;
2026
2027 dev_dbg(codec->dev, "FLL%d running %dHz->%dHz\n", fll_id,
2028 Fref, Fout);
2029
2030 return 0;
2031}
2032
2033/* Actually go much higher */
2034#define WM5100_RATES SNDRV_PCM_RATE_8000_192000
2035
2036#define WM5100_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
2037 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
2038
2039static struct snd_soc_dai_driver wm5100_dai[] = {
2040 {
2041 .name = "wm5100-aif1",
2042 .playback = {
2043 .stream_name = "AIF1 Playback",
2044 .channels_min = 2,
2045 .channels_max = 2,
2046 .rates = WM5100_RATES,
2047 .formats = WM5100_FORMATS,
2048 },
2049 .capture = {
2050 .stream_name = "AIF1 Capture",
2051 .channels_min = 2,
2052 .channels_max = 2,
2053 .rates = WM5100_RATES,
2054 .formats = WM5100_FORMATS,
2055 },
2056 .ops = &wm5100_dai_ops,
2057 },
2058 {
2059 .name = "wm5100-aif2",
2060 .id = 1,
2061 .playback = {
2062 .stream_name = "AIF2 Playback",
2063 .channels_min = 2,
2064 .channels_max = 2,
2065 .rates = WM5100_RATES,
2066 .formats = WM5100_FORMATS,
2067 },
2068 .capture = {
2069 .stream_name = "AIF2 Capture",
2070 .channels_min = 2,
2071 .channels_max = 2,
2072 .rates = WM5100_RATES,
2073 .formats = WM5100_FORMATS,
2074 },
2075 .ops = &wm5100_dai_ops,
2076 },
2077 {
2078 .name = "wm5100-aif3",
2079 .id = 2,
2080 .playback = {
2081 .stream_name = "AIF3 Playback",
2082 .channels_min = 2,
2083 .channels_max = 2,
2084 .rates = WM5100_RATES,
2085 .formats = WM5100_FORMATS,
2086 },
2087 .capture = {
2088 .stream_name = "AIF3 Capture",
2089 .channels_min = 2,
2090 .channels_max = 2,
2091 .rates = WM5100_RATES,
2092 .formats = WM5100_FORMATS,
2093 },
2094 .ops = &wm5100_dai_ops,
2095 },
2096};
2097
2098static int wm5100_dig_vu[] = {
2099 WM5100_ADC_DIGITAL_VOLUME_1L,
2100 WM5100_ADC_DIGITAL_VOLUME_1R,
2101 WM5100_ADC_DIGITAL_VOLUME_2L,
2102 WM5100_ADC_DIGITAL_VOLUME_2R,
2103 WM5100_ADC_DIGITAL_VOLUME_3L,
2104 WM5100_ADC_DIGITAL_VOLUME_3R,
2105 WM5100_ADC_DIGITAL_VOLUME_4L,
2106 WM5100_ADC_DIGITAL_VOLUME_4R,
2107
2108 WM5100_DAC_DIGITAL_VOLUME_1L,
2109 WM5100_DAC_DIGITAL_VOLUME_1R,
2110 WM5100_DAC_DIGITAL_VOLUME_2L,
2111 WM5100_DAC_DIGITAL_VOLUME_2R,
2112 WM5100_DAC_DIGITAL_VOLUME_3L,
2113 WM5100_DAC_DIGITAL_VOLUME_3R,
2114 WM5100_DAC_DIGITAL_VOLUME_4L,
2115 WM5100_DAC_DIGITAL_VOLUME_4R,
2116 WM5100_DAC_DIGITAL_VOLUME_5L,
2117 WM5100_DAC_DIGITAL_VOLUME_5R,
2118 WM5100_DAC_DIGITAL_VOLUME_6L,
2119 WM5100_DAC_DIGITAL_VOLUME_6R,
2120};
2121
2122static void wm5100_set_detect_mode(struct snd_soc_codec *codec, int the_mode)
2123{
2124 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
2125 struct wm5100_jack_mode *mode = &wm5100->pdata.jack_modes[the_mode];
2126
2127 BUG_ON(the_mode >= ARRAY_SIZE(wm5100->pdata.jack_modes));
2128
2129 gpio_set_value_cansleep(wm5100->pdata.hp_pol, mode->hp_pol);
2130 snd_soc_update_bits(codec, WM5100_ACCESSORY_DETECT_MODE_1,
2131 WM5100_ACCDET_BIAS_SRC_MASK |
2132 WM5100_ACCDET_SRC,
2133 (mode->bias << WM5100_ACCDET_BIAS_SRC_SHIFT) |
2134 mode->micd_src << WM5100_ACCDET_SRC_SHIFT);
2135 snd_soc_update_bits(codec, WM5100_MISC_CONTROL,
2136 WM5100_HPCOM_SRC,
2137 mode->micd_src << WM5100_HPCOM_SRC_SHIFT);
2138
2139 wm5100->jack_mode = the_mode;
2140
2141 dev_dbg(codec->dev, "Set microphone polarity to %d\n",
2142 wm5100->jack_mode);
2143}
2144
2145static void wm5100_micd_irq(struct snd_soc_codec *codec)
2146{
2147 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
2148 int val;
2149
2150 val = snd_soc_read(codec, WM5100_MIC_DETECT_3);
2151
2152 dev_dbg(codec->dev, "Microphone event: %x\n", val);
2153
2154 if (!(val & WM5100_ACCDET_VALID)) {
2155 dev_warn(codec->dev, "Microphone detection state invalid\n");
2156 return;
2157 }
2158
2159 /* No accessory, reset everything and report removal */
2160 if (!(val & WM5100_ACCDET_STS)) {
2161 dev_dbg(codec->dev, "Jack removal detected\n");
2162 wm5100->jack_mic = false;
2163 wm5100->jack_detecting = true;
2164 snd_soc_jack_report(wm5100->jack, 0,
2165 SND_JACK_LINEOUT | SND_JACK_HEADSET |
2166 SND_JACK_BTN_0);
2167
2168 snd_soc_update_bits(codec, WM5100_MIC_DETECT_1,
2169 WM5100_ACCDET_RATE_MASK,
2170 WM5100_ACCDET_RATE_MASK);
2171 return;
2172 }
2173
2174 /* If the measurement is very high we've got a microphone,
2175 * either we just detected one or if we already reported then
2176 * we've got a button release event.
2177 */
2178 if (val & 0x400) {
2179 if (wm5100->jack_detecting) {
2180 dev_dbg(codec->dev, "Microphone detected\n");
2181 wm5100->jack_mic = true;
2182 snd_soc_jack_report(wm5100->jack,
2183 SND_JACK_HEADSET,
2184 SND_JACK_HEADSET | SND_JACK_BTN_0);
2185
2186 /* Increase poll rate to give better responsiveness
2187 * for buttons */
2188 snd_soc_update_bits(codec, WM5100_MIC_DETECT_1,
2189 WM5100_ACCDET_RATE_MASK,
2190 5 << WM5100_ACCDET_RATE_SHIFT);
2191 } else {
2192 dev_dbg(codec->dev, "Mic button up\n");
2193 snd_soc_jack_report(wm5100->jack, 0, SND_JACK_BTN_0);
2194 }
2195
2196 return;
2197 }
2198
2199 /* If we detected a lower impedence during initial startup
2200 * then we probably have the wrong polarity, flip it. Don't
2201 * do this for the lowest impedences to speed up detection of
2202 * plain headphones.
2203 */
2204 if (wm5100->jack_detecting && (val & 0x3f8)) {
2205 wm5100_set_detect_mode(codec, !wm5100->jack_mode);
2206
2207 return;
2208 }
2209
2210 /* Don't distinguish between buttons, just report any low
2211 * impedence as BTN_0.
2212 */
2213 if (val & 0x3fc) {
2214 if (wm5100->jack_mic) {
2215 dev_dbg(codec->dev, "Mic button detected\n");
2216 snd_soc_jack_report(wm5100->jack, SND_JACK_BTN_0,
2217 SND_JACK_BTN_0);
2218 } else if (wm5100->jack_detecting) {
2219 dev_dbg(codec->dev, "Headphone detected\n");
2220 snd_soc_jack_report(wm5100->jack, SND_JACK_HEADPHONE,
2221 SND_JACK_HEADPHONE);
2222
2223 /* Increase the detection rate a bit for
2224 * responsiveness.
2225 */
2226 snd_soc_update_bits(codec, WM5100_MIC_DETECT_1,
2227 WM5100_ACCDET_RATE_MASK,
2228 7 << WM5100_ACCDET_RATE_SHIFT);
2229 }
2230 }
2231}
2232
2233int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
2234{
2235 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
2236
2237 if (jack) {
2238 wm5100->jack = jack;
2239 wm5100->jack_detecting = true;
2240
2241 wm5100_set_detect_mode(codec, 0);
2242
2243 /* Slowest detection rate, gives debounce for initial
2244 * detection */
2245 snd_soc_update_bits(codec, WM5100_MIC_DETECT_1,
2246 WM5100_ACCDET_BIAS_STARTTIME_MASK |
2247 WM5100_ACCDET_RATE_MASK,
2248 (7 << WM5100_ACCDET_BIAS_STARTTIME_SHIFT) |
2249 WM5100_ACCDET_RATE_MASK);
2250
2251 /* We need the charge pump to power MICBIAS */
2252 snd_soc_dapm_force_enable_pin(&codec->dapm, "CP2");
2253 snd_soc_dapm_force_enable_pin(&codec->dapm, "SYSCLK");
2254 snd_soc_dapm_sync(&codec->dapm);
2255
2256 /* We start off just enabling microphone detection - even a
2257 * plain headphone will trigger detection.
2258 */
2259 snd_soc_update_bits(codec, WM5100_MIC_DETECT_1,
2260 WM5100_ACCDET_ENA, WM5100_ACCDET_ENA);
2261
2262 snd_soc_update_bits(codec, WM5100_INTERRUPT_STATUS_3_MASK,
2263 WM5100_IM_ACCDET_EINT, 0);
2264 } else {
2265 snd_soc_update_bits(codec, WM5100_INTERRUPT_STATUS_3_MASK,
2266 WM5100_IM_HPDET_EINT |
2267 WM5100_IM_ACCDET_EINT,
2268 WM5100_IM_HPDET_EINT |
2269 WM5100_IM_ACCDET_EINT);
2270 snd_soc_update_bits(codec, WM5100_MIC_DETECT_1,
2271 WM5100_ACCDET_ENA, 0);
2272 wm5100->jack = NULL;
2273 }
2274
2275 return 0;
2276}
2277
2278static irqreturn_t wm5100_irq(int irq, void *data)
2279{
2280 struct snd_soc_codec *codec = data;
2281 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
2282 irqreturn_t status = IRQ_NONE;
2283 int irq_val;
2284
2285 irq_val = snd_soc_read(codec, WM5100_INTERRUPT_STATUS_3);
2286 if (irq_val < 0) {
2287 dev_err(codec->dev, "Failed to read IRQ status 3: %d\n",
2288 irq_val);
2289 irq_val = 0;
2290 }
2291 irq_val &= ~snd_soc_read(codec, WM5100_INTERRUPT_STATUS_3_MASK);
2292
2293 snd_soc_write(codec, WM5100_INTERRUPT_STATUS_3, irq_val);
2294
2295 if (irq_val)
2296 status = IRQ_HANDLED;
2297
2298 wm5100_log_status3(codec, irq_val);
2299
2300 if (irq_val & WM5100_FLL1_LOCK_EINT) {
2301 dev_dbg(codec->dev, "FLL1 locked\n");
2302 complete(&wm5100->fll[0].lock);
2303 }
2304 if (irq_val & WM5100_FLL2_LOCK_EINT) {
2305 dev_dbg(codec->dev, "FLL2 locked\n");
2306 complete(&wm5100->fll[1].lock);
2307 }
2308
2309 if (irq_val & WM5100_ACCDET_EINT)
2310 wm5100_micd_irq(codec);
2311
2312 irq_val = snd_soc_read(codec, WM5100_INTERRUPT_STATUS_4);
2313 if (irq_val < 0) {
2314 dev_err(codec->dev, "Failed to read IRQ status 4: %d\n",
2315 irq_val);
2316 irq_val = 0;
2317 }
2318 irq_val &= ~snd_soc_read(codec, WM5100_INTERRUPT_STATUS_4_MASK);
2319
2320 if (irq_val)
2321 status = IRQ_HANDLED;
2322
2323 snd_soc_write(codec, WM5100_INTERRUPT_STATUS_4, irq_val);
2324
2325 wm5100_log_status4(codec, irq_val);
2326
2327 return status;
2328}
2329
2330static irqreturn_t wm5100_edge_irq(int irq, void *data)
2331{
2332 irqreturn_t ret = IRQ_NONE;
2333 irqreturn_t val;
2334
2335 do {
2336 val = wm5100_irq(irq, data);
2337 if (val != IRQ_NONE)
2338 ret = val;
2339 } while (val != IRQ_NONE);
2340
2341 return ret;
2342}
2343
2344#ifdef CONFIG_GPIOLIB
2345static inline struct wm5100_priv *gpio_to_wm5100(struct gpio_chip *chip)
2346{
2347 return container_of(chip, struct wm5100_priv, gpio_chip);
2348}
2349
2350static void wm5100_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
2351{
2352 struct wm5100_priv *wm5100 = gpio_to_wm5100(chip);
2353 struct snd_soc_codec *codec = wm5100->codec;
2354
2355 snd_soc_update_bits(codec, WM5100_GPIO_CTRL_1 + offset,
2356 WM5100_GP1_LVL, !!value << WM5100_GP1_LVL_SHIFT);
2357}
2358
2359static int wm5100_gpio_direction_out(struct gpio_chip *chip,
2360 unsigned offset, int value)
2361{
2362 struct wm5100_priv *wm5100 = gpio_to_wm5100(chip);
2363 struct snd_soc_codec *codec = wm5100->codec;
2364 int val;
2365
2366 val = (1 << WM5100_GP1_FN_SHIFT) | (!!value << WM5100_GP1_LVL_SHIFT);
2367
2368 return snd_soc_update_bits(codec, WM5100_GPIO_CTRL_1 + offset,
2369 WM5100_GP1_FN_MASK | WM5100_GP1_DIR |
2370 WM5100_GP1_LVL, val);
2371}
2372
2373static int wm5100_gpio_get(struct gpio_chip *chip, unsigned offset)
2374{
2375 struct wm5100_priv *wm5100 = gpio_to_wm5100(chip);
2376 struct snd_soc_codec *codec = wm5100->codec;
2377 int ret;
2378
2379 ret = snd_soc_read(codec, WM5100_GPIO_CTRL_1 + offset);
2380 if (ret < 0)
2381 return ret;
2382
2383 return (ret & WM5100_GP1_LVL) != 0;
2384}
2385
2386static int wm5100_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
2387{
2388 struct wm5100_priv *wm5100 = gpio_to_wm5100(chip);
2389 struct snd_soc_codec *codec = wm5100->codec;
2390
2391 return snd_soc_update_bits(codec, WM5100_GPIO_CTRL_1 + offset,
2392 WM5100_GP1_FN_MASK | WM5100_GP1_DIR,
2393 (1 << WM5100_GP1_FN_SHIFT) |
2394 (1 << WM5100_GP1_DIR_SHIFT));
2395}
2396
2397static struct gpio_chip wm5100_template_chip = {
2398 .label = "wm5100",
2399 .owner = THIS_MODULE,
2400 .direction_output = wm5100_gpio_direction_out,
2401 .set = wm5100_gpio_set,
2402 .direction_input = wm5100_gpio_direction_in,
2403 .get = wm5100_gpio_get,
2404 .can_sleep = 1,
2405};
2406
2407static void wm5100_init_gpio(struct snd_soc_codec *codec)
2408{
2409 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
2410 int ret;
2411
2412 wm5100->gpio_chip = wm5100_template_chip;
2413 wm5100->gpio_chip.ngpio = 6;
2414 wm5100->gpio_chip.dev = codec->dev;
2415
2416 if (wm5100->pdata.gpio_base)
2417 wm5100->gpio_chip.base = wm5100->pdata.gpio_base;
2418 else
2419 wm5100->gpio_chip.base = -1;
2420
2421 ret = gpiochip_add(&wm5100->gpio_chip);
2422 if (ret != 0)
2423 dev_err(codec->dev, "Failed to add GPIOs: %d\n", ret);
2424}
2425
2426static void wm5100_free_gpio(struct snd_soc_codec *codec)
2427{
2428 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
2429 int ret;
2430
2431 ret = gpiochip_remove(&wm5100->gpio_chip);
2432 if (ret != 0)
2433 dev_err(codec->dev, "Failed to remove GPIOs: %d\n", ret);
2434}
2435#else
2436static void wm5100_init_gpio(struct snd_soc_codec *codec)
2437{
2438}
2439
2440static void wm5100_free_gpio(struct snd_soc_codec *codec)
2441{
2442}
2443#endif
2444
2445static int wm5100_probe(struct snd_soc_codec *codec)
2446{
2447 struct i2c_client *i2c = to_i2c_client(codec->dev);
2448 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
2449 int ret, i, irq_flags;
2450
2451 wm5100->codec = codec;
2452
2453 ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C);
2454 if (ret != 0) {
2455 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
2456 return ret;
2457 }
2458
2459 for (i = 0; i < ARRAY_SIZE(wm5100->core_supplies); i++)
2460 wm5100->core_supplies[i].supply = wm5100_core_supply_names[i];
2461
2462 ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm5100->core_supplies),
2463 wm5100->core_supplies);
2464 if (ret != 0) {
2465 dev_err(codec->dev, "Failed to request core supplies: %d\n",
2466 ret);
2467 return ret;
2468 }
2469
2470 wm5100->cpvdd = regulator_get(&i2c->dev, "CPVDD");
2471 if (IS_ERR(wm5100->cpvdd)) {
2472 ret = PTR_ERR(wm5100->cpvdd);
2473 dev_err(&i2c->dev, "Failed to get CPVDD: %d\n", ret);
2474 goto err_core;
2475 }
2476
2477 wm5100->dbvdd2 = regulator_get(&i2c->dev, "DBVDD2");
2478 if (IS_ERR(wm5100->dbvdd2)) {
2479 ret = PTR_ERR(wm5100->dbvdd2);
2480 dev_err(&i2c->dev, "Failed to get DBVDD2: %d\n", ret);
2481 goto err_cpvdd;
2482 }
2483
2484 wm5100->dbvdd3 = regulator_get(&i2c->dev, "DBVDD3");
2485 if (IS_ERR(wm5100->dbvdd3)) {
2486 ret = PTR_ERR(wm5100->dbvdd3);
2487 dev_err(&i2c->dev, "Failed to get DBVDD2: %d\n", ret);
2488 goto err_dbvdd2;
2489 }
2490
2491 ret = regulator_bulk_enable(ARRAY_SIZE(wm5100->core_supplies),
2492 wm5100->core_supplies);
2493 if (ret != 0) {
2494 dev_err(codec->dev, "Failed to enable core supplies: %d\n",
2495 ret);
2496 goto err_dbvdd3;
2497 }
2498
2499 if (wm5100->pdata.ldo_ena) {
2500 ret = gpio_request_one(wm5100->pdata.ldo_ena,
2501 GPIOF_OUT_INIT_HIGH, "WM5100 LDOENA");
2502 if (ret < 0) {
2503 dev_err(&i2c->dev, "Failed to request LDOENA %d: %d\n",
2504 wm5100->pdata.ldo_ena, ret);
2505 goto err_enable;
2506 }
2507 msleep(2);
2508 }
2509
2510 if (wm5100->pdata.reset) {
2511 ret = gpio_request_one(wm5100->pdata.reset,
2512 GPIOF_OUT_INIT_HIGH, "WM5100 /RESET");
2513 if (ret < 0) {
2514 dev_err(&i2c->dev, "Failed to request /RESET %d: %d\n",
2515 wm5100->pdata.reset, ret);
2516 goto err_ldo;
2517 }
2518 }
2519
2520 ret = snd_soc_read(codec, WM5100_SOFTWARE_RESET);
2521 if (ret < 0) {
2522 dev_err(codec->dev, "Failed to read ID register\n");
2523 goto err_reset;
2524 }
2525 switch (ret) {
2526 case 0x8997:
2527 case 0x5100:
2528 break;
2529
2530 default:
2531 dev_err(codec->dev, "Device is not a WM5100, ID is %x\n", ret);
2532 ret = -EINVAL;
2533 goto err_reset;
2534 }
2535
2536 ret = snd_soc_read(codec, WM5100_DEVICE_REVISION);
2537 if (ret < 0) {
2538 dev_err(codec->dev, "Failed to read revision register\n");
2539 goto err_reset;
2540 }
2541 wm5100->rev = ret & WM5100_DEVICE_REVISION_MASK;
2542
2543 dev_info(codec->dev, "revision %c\n", wm5100->rev + 'A');
2544
2545 ret = wm5100_reset(codec);
2546 if (ret < 0) {
2547 dev_err(codec->dev, "Failed to issue reset\n");
2548 goto err_reset;
2549 }
2550
2551 codec->cache_only = true;
2552
2553 wm5100_init_gpio(codec);
2554
2555 for (i = 0; i < ARRAY_SIZE(wm5100_dig_vu); i++)
2556 snd_soc_update_bits(codec, wm5100_dig_vu[i], WM5100_OUT_VU,
2557 WM5100_OUT_VU);
2558
2559 for (i = 0; i < ARRAY_SIZE(wm5100->pdata.in_mode); i++) {
2560 snd_soc_update_bits(codec, WM5100_IN1L_CONTROL,
2561 WM5100_IN1_MODE_MASK |
2562 WM5100_IN1_DMIC_SUP_MASK,
2563 (wm5100->pdata.in_mode[i] <<
2564 WM5100_IN1_MODE_SHIFT) |
2565 (wm5100->pdata.dmic_sup[i] <<
2566 WM5100_IN1_DMIC_SUP_SHIFT));
2567 }
2568
2569 for (i = 0; i < ARRAY_SIZE(wm5100->pdata.gpio_defaults); i++) {
2570 if (!wm5100->pdata.gpio_defaults[i])
2571 continue;
2572
2573 snd_soc_write(codec, WM5100_GPIO_CTRL_1 + i,
2574 wm5100->pdata.gpio_defaults[i]);
2575 }
2576
2577 /* Don't debounce interrupts to support use of SYSCLK only */
2578 snd_soc_write(codec, WM5100_IRQ_DEBOUNCE_1, 0);
2579 snd_soc_write(codec, WM5100_IRQ_DEBOUNCE_2, 0);
2580
2581 /* TODO: check if we're symmetric */
2582
2583 if (i2c->irq) {
2584 if (wm5100->pdata.irq_flags)
2585 irq_flags = wm5100->pdata.irq_flags;
2586 else
2587 irq_flags = IRQF_TRIGGER_LOW;
2588
2589 irq_flags |= IRQF_ONESHOT;
2590
2591 if (irq_flags & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING))
2592 ret = request_threaded_irq(i2c->irq, NULL,
2593 wm5100_edge_irq,
2594 irq_flags, "wm5100", codec);
2595 else
2596 ret = request_threaded_irq(i2c->irq, NULL, wm5100_irq,
2597 irq_flags, "wm5100", codec);
2598
2599 if (ret != 0) {
2600 dev_err(codec->dev, "Failed to request IRQ %d: %d\n",
2601 i2c->irq, ret);
2602 } else {
2603 /* Enable default interrupts */
2604 snd_soc_update_bits(codec,
2605 WM5100_INTERRUPT_STATUS_3_MASK,
2606 WM5100_IM_SPK_SHUTDOWN_WARN_EINT |
2607 WM5100_IM_SPK_SHUTDOWN_EINT |
2608 WM5100_IM_ASRC2_LOCK_EINT |
2609 WM5100_IM_ASRC1_LOCK_EINT |
2610 WM5100_IM_FLL2_LOCK_EINT |
2611 WM5100_IM_FLL1_LOCK_EINT |
2612 WM5100_CLKGEN_ERR_EINT |
2613 WM5100_CLKGEN_ERR_ASYNC_EINT, 0);
2614
2615 snd_soc_update_bits(codec,
2616 WM5100_INTERRUPT_STATUS_4_MASK,
2617 WM5100_AIF3_ERR_EINT |
2618 WM5100_AIF2_ERR_EINT |
2619 WM5100_AIF1_ERR_EINT |
2620 WM5100_CTRLIF_ERR_EINT |
2621 WM5100_ISRC2_UNDERCLOCKED_EINT |
2622 WM5100_ISRC1_UNDERCLOCKED_EINT |
2623 WM5100_FX_UNDERCLOCKED_EINT |
2624 WM5100_AIF3_UNDERCLOCKED_EINT |
2625 WM5100_AIF2_UNDERCLOCKED_EINT |
2626 WM5100_AIF1_UNDERCLOCKED_EINT |
2627 WM5100_ASRC_UNDERCLOCKED_EINT |
2628 WM5100_DAC_UNDERCLOCKED_EINT |
2629 WM5100_ADC_UNDERCLOCKED_EINT |
2630 WM5100_MIXER_UNDERCLOCKED_EINT, 0);
2631 }
2632 } else {
2633 snd_soc_dapm_new_controls(&codec->dapm,
2634 wm5100_dapm_widgets_noirq,
2635 ARRAY_SIZE(wm5100_dapm_widgets_noirq));
2636 }
2637
2638 if (wm5100->pdata.hp_pol) {
2639 ret = gpio_request_one(wm5100->pdata.hp_pol,
2640 GPIOF_OUT_INIT_HIGH, "WM5100 HP_POL");
2641 if (ret < 0) {
2642 dev_err(&i2c->dev, "Failed to request HP_POL %d: %d\n",
2643 wm5100->pdata.hp_pol, ret);
2644 goto err_gpio;
2645 }
2646 }
2647
2648 /* We'll get woken up again when the system has something useful
2649 * for us to do.
2650 */
2651 if (wm5100->pdata.ldo_ena)
2652 gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
2653 regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies),
2654 wm5100->core_supplies);
2655
2656 return 0;
2657
2658err_gpio:
2659 if (i2c->irq)
2660 free_irq(i2c->irq, codec);
2661 wm5100_free_gpio(codec);
2662err_reset:
2663 if (wm5100->pdata.reset) {
2664 gpio_set_value_cansleep(wm5100->pdata.reset, 1);
2665 gpio_free(wm5100->pdata.reset);
2666 }
2667err_ldo:
2668 if (wm5100->pdata.ldo_ena) {
2669 gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
2670 gpio_free(wm5100->pdata.ldo_ena);
2671 }
2672err_enable:
2673 regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies),
2674 wm5100->core_supplies);
2675err_dbvdd3:
2676 regulator_put(wm5100->dbvdd3);
2677err_dbvdd2:
2678 regulator_put(wm5100->dbvdd2);
2679err_cpvdd:
2680 regulator_put(wm5100->cpvdd);
2681err_core:
2682 regulator_bulk_free(ARRAY_SIZE(wm5100->core_supplies),
2683 wm5100->core_supplies);
2684
2685 return ret;
2686}
2687
2688static int wm5100_remove(struct snd_soc_codec *codec)
2689{
2690 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
2691 struct i2c_client *i2c = to_i2c_client(codec->dev);
2692
2693 wm5100_set_bias_level(codec, SND_SOC_BIAS_OFF);
2694 if (wm5100->pdata.hp_pol) {
2695 gpio_free(wm5100->pdata.hp_pol);
2696 }
2697 if (i2c->irq)
2698 free_irq(i2c->irq, codec);
2699 wm5100_free_gpio(codec);
2700 if (wm5100->pdata.reset) {
2701 gpio_set_value_cansleep(wm5100->pdata.reset, 1);
2702 gpio_free(wm5100->pdata.reset);
2703 }
2704 if (wm5100->pdata.ldo_ena) {
2705 gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
2706 gpio_free(wm5100->pdata.ldo_ena);
2707 }
2708 regulator_put(wm5100->dbvdd3);
2709 regulator_put(wm5100->dbvdd2);
2710 regulator_put(wm5100->cpvdd);
2711 regulator_bulk_free(ARRAY_SIZE(wm5100->core_supplies),
2712 wm5100->core_supplies);
2713 return 0;
2714}
2715
2716static struct snd_soc_codec_driver soc_codec_dev_wm5100 = {
2717 .probe = wm5100_probe,
2718 .remove = wm5100_remove,
2719
2720 .set_sysclk = wm5100_set_sysclk,
2721 .set_pll = wm5100_set_fll,
2722 .set_bias_level = wm5100_set_bias_level,
2723 .idle_bias_off = 1,
2724
2725 .seq_notifier = wm5100_seq_notifier,
2726 .controls = wm5100_snd_controls,
2727 .num_controls = ARRAY_SIZE(wm5100_snd_controls),
2728 .dapm_widgets = wm5100_dapm_widgets,
2729 .num_dapm_widgets = ARRAY_SIZE(wm5100_dapm_widgets),
2730 .dapm_routes = wm5100_dapm_routes,
2731 .num_dapm_routes = ARRAY_SIZE(wm5100_dapm_routes),
2732
2733 .reg_cache_size = ARRAY_SIZE(wm5100_reg_defaults),
2734 .reg_word_size = sizeof(u16),
2735 .compress_type = SND_SOC_RBTREE_COMPRESSION,
2736 .reg_cache_default = wm5100_reg_defaults,
2737
2738 .volatile_register = wm5100_volatile_register,
2739 .readable_register = wm5100_readable_register,
2740};
2741
2742static __devinit int wm5100_i2c_probe(struct i2c_client *i2c,
2743 const struct i2c_device_id *id)
2744{
2745 struct wm5100_pdata *pdata = dev_get_platdata(&i2c->dev);
2746 struct wm5100_priv *wm5100;
2747 int ret, i;
2748
2749 wm5100 = kzalloc(sizeof(struct wm5100_priv), GFP_KERNEL);
2750 if (wm5100 == NULL)
2751 return -ENOMEM;
2752
2753 for (i = 0; i < ARRAY_SIZE(wm5100->fll); i++)
2754 init_completion(&wm5100->fll[i].lock);
2755
2756 if (pdata)
2757 wm5100->pdata = *pdata;
2758
2759 i2c_set_clientdata(i2c, wm5100);
2760
2761 ret = snd_soc_register_codec(&i2c->dev,
2762 &soc_codec_dev_wm5100, wm5100_dai,
2763 ARRAY_SIZE(wm5100_dai));
2764 if (ret < 0) {
2765 dev_err(&i2c->dev, "Failed to register WM5100: %d\n", ret);
2766 kfree(wm5100);
2767 }
2768
2769 return ret;
2770}
2771
2772static __devexit int wm5100_i2c_remove(struct i2c_client *client)
2773{
2774 snd_soc_unregister_codec(&client->dev);
2775 kfree(i2c_get_clientdata(client));
2776 return 0;
2777}
2778
2779static const struct i2c_device_id wm5100_i2c_id[] = {
2780 { "wm5100", 0 },
2781 { }
2782};
2783MODULE_DEVICE_TABLE(i2c, wm5100_i2c_id);
2784
2785static struct i2c_driver wm5100_i2c_driver = {
2786 .driver = {
2787 .name = "wm5100",
2788 .owner = THIS_MODULE,
2789 },
2790 .probe = wm5100_i2c_probe,
2791 .remove = __devexit_p(wm5100_i2c_remove),
2792 .id_table = wm5100_i2c_id,
2793};
2794
2795static int __init wm5100_modinit(void)
2796{
2797 return i2c_add_driver(&wm5100_i2c_driver);
2798}
2799module_init(wm5100_modinit);
2800
2801static void __exit wm5100_exit(void)
2802{
2803 i2c_del_driver(&wm5100_i2c_driver);
2804}
2805module_exit(wm5100_exit);
2806
2807MODULE_DESCRIPTION("ASoC WM5100 driver");
2808MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
2809MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm5100.h b/sound/soc/codecs/wm5100.h
new file mode 100644
index 00000000000..970759636bd
--- /dev/null
+++ b/sound/soc/codecs/wm5100.h
@@ -0,0 +1,5155 @@
1/*
2 * wm5100.h -- WM5100 ALSA SoC Audio driver
3 *
4 * Copyright 2011 Wolfson Microelectronics plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
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 WM5100_ASOC_H
15#define WM5100_ASOC_H
16
17#include <sound/soc.h>
18
19int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack);
20
21#define WM5100_CLK_AIF1 1
22#define WM5100_CLK_AIF2 2
23#define WM5100_CLK_AIF3 3
24#define WM5100_CLK_SYSCLK 4
25#define WM5100_CLK_ASYNCCLK 5
26#define WM5100_CLK_32KHZ 6
27#define WM5100_CLK_OPCLK 7
28
29#define WM5100_CLKSRC_MCLK1 0
30#define WM5100_CLKSRC_MCLK2 1
31#define WM5100_CLKSRC_SYSCLK 2
32#define WM5100_CLKSRC_FLL1 4
33#define WM5100_CLKSRC_FLL2 5
34#define WM5100_CLKSRC_AIF1BCLK 8
35#define WM5100_CLKSRC_AIF2BCLK 9
36#define WM5100_CLKSRC_AIF3BCLK 10
37#define WM5100_CLKSRC_ASYNCCLK 0x100
38
39#define WM5100_FLL1 1
40#define WM5100_FLL2 2
41
42#define WM5100_FLL_SRC_MCLK1 0x0
43#define WM5100_FLL_SRC_MCLK2 0x1
44#define WM5100_FLL_SRC_FLL1 0x4
45#define WM5100_FLL_SRC_FLL2 0x5
46#define WM5100_FLL_SRC_AIF1BCLK 0x8
47#define WM5100_FLL_SRC_AIF2BCLK 0x9
48#define WM5100_FLL_SRC_AIF3BCLK 0xa
49
50/*
51 * Register values.
52 */
53#define WM5100_SOFTWARE_RESET 0x00
54#define WM5100_DEVICE_REVISION 0x01
55#define WM5100_CTRL_IF_1 0x10
56#define WM5100_TONE_GENERATOR_1 0x20
57#define WM5100_PWM_DRIVE_1 0x30
58#define WM5100_PWM_DRIVE_2 0x31
59#define WM5100_PWM_DRIVE_3 0x32
60#define WM5100_CLOCKING_1 0x100
61#define WM5100_CLOCKING_3 0x101
62#define WM5100_CLOCKING_4 0x102
63#define WM5100_CLOCKING_5 0x103
64#define WM5100_CLOCKING_6 0x104
65#define WM5100_CLOCKING_7 0x107
66#define WM5100_CLOCKING_8 0x108
67#define WM5100_ASRC_ENABLE 0x120
68#define WM5100_ASRC_STATUS 0x121
69#define WM5100_ASRC_RATE1 0x122
70#define WM5100_ISRC_1_CTRL_1 0x141
71#define WM5100_ISRC_1_CTRL_2 0x142
72#define WM5100_ISRC_2_CTRL1 0x143
73#define WM5100_ISRC_2_CTRL_2 0x144
74#define WM5100_FLL1_CONTROL_1 0x182
75#define WM5100_FLL1_CONTROL_2 0x183
76#define WM5100_FLL1_CONTROL_3 0x184
77#define WM5100_FLL1_CONTROL_5 0x186
78#define WM5100_FLL1_CONTROL_6 0x187
79#define WM5100_FLL1_EFS_1 0x188
80#define WM5100_FLL2_CONTROL_1 0x1A2
81#define WM5100_FLL2_CONTROL_2 0x1A3
82#define WM5100_FLL2_CONTROL_3 0x1A4
83#define WM5100_FLL2_CONTROL_5 0x1A6
84#define WM5100_FLL2_CONTROL_6 0x1A7
85#define WM5100_FLL2_EFS_1 0x1A8
86#define WM5100_MIC_CHARGE_PUMP_1 0x200
87#define WM5100_MIC_CHARGE_PUMP_2 0x201
88#define WM5100_HP_CHARGE_PUMP_1 0x202
89#define WM5100_LDO1_CONTROL 0x211
90#define WM5100_MIC_BIAS_CTRL_1 0x215
91#define WM5100_MIC_BIAS_CTRL_2 0x216
92#define WM5100_MIC_BIAS_CTRL_3 0x217
93#define WM5100_ACCESSORY_DETECT_MODE_1 0x280
94#define WM5100_HEADPHONE_DETECT_1 0x288
95#define WM5100_HEADPHONE_DETECT_2 0x289
96#define WM5100_MIC_DETECT_1 0x290
97#define WM5100_MIC_DETECT_2 0x291
98#define WM5100_MIC_DETECT_3 0x292
99#define WM5100_MISC_CONTROL 0x2BB
100#define WM5100_INPUT_ENABLES 0x301
101#define WM5100_INPUT_ENABLES_STATUS 0x302
102#define WM5100_IN1L_CONTROL 0x310
103#define WM5100_IN1R_CONTROL 0x311
104#define WM5100_IN2L_CONTROL 0x312
105#define WM5100_IN2R_CONTROL 0x313
106#define WM5100_IN3L_CONTROL 0x314
107#define WM5100_IN3R_CONTROL 0x315
108#define WM5100_IN4L_CONTROL 0x316
109#define WM5100_IN4R_CONTROL 0x317
110#define WM5100_RXANC_SRC 0x318
111#define WM5100_INPUT_VOLUME_RAMP 0x319
112#define WM5100_ADC_DIGITAL_VOLUME_1L 0x320
113#define WM5100_ADC_DIGITAL_VOLUME_1R 0x321
114#define WM5100_ADC_DIGITAL_VOLUME_2L 0x322
115#define WM5100_ADC_DIGITAL_VOLUME_2R 0x323
116#define WM5100_ADC_DIGITAL_VOLUME_3L 0x324
117#define WM5100_ADC_DIGITAL_VOLUME_3R 0x325
118#define WM5100_ADC_DIGITAL_VOLUME_4L 0x326
119#define WM5100_ADC_DIGITAL_VOLUME_4R 0x327
120#define WM5100_OUTPUT_ENABLES_2 0x401
121#define WM5100_OUTPUT_STATUS_1 0x402
122#define WM5100_OUTPUT_STATUS_2 0x403
123#define WM5100_CHANNEL_ENABLES_1 0x408
124#define WM5100_OUT_VOLUME_1L 0x410
125#define WM5100_OUT_VOLUME_1R 0x411
126#define WM5100_DAC_VOLUME_LIMIT_1L 0x412
127#define WM5100_DAC_VOLUME_LIMIT_1R 0x413
128#define WM5100_OUT_VOLUME_2L 0x414
129#define WM5100_OUT_VOLUME_2R 0x415
130#define WM5100_DAC_VOLUME_LIMIT_2L 0x416
131#define WM5100_DAC_VOLUME_LIMIT_2R 0x417
132#define WM5100_OUT_VOLUME_3L 0x418
133#define WM5100_OUT_VOLUME_3R 0x419
134#define WM5100_DAC_VOLUME_LIMIT_3L 0x41A
135#define WM5100_DAC_VOLUME_LIMIT_3R 0x41B
136#define WM5100_OUT_VOLUME_4L 0x41C
137#define WM5100_OUT_VOLUME_4R 0x41D
138#define WM5100_DAC_VOLUME_LIMIT_5L 0x41E
139#define WM5100_DAC_VOLUME_LIMIT_5R 0x41F
140#define WM5100_DAC_VOLUME_LIMIT_6L 0x420
141#define WM5100_DAC_VOLUME_LIMIT_6R 0x421
142#define WM5100_DAC_AEC_CONTROL_1 0x440
143#define WM5100_OUTPUT_VOLUME_RAMP 0x441
144#define WM5100_DAC_DIGITAL_VOLUME_1L 0x480
145#define WM5100_DAC_DIGITAL_VOLUME_1R 0x481
146#define WM5100_DAC_DIGITAL_VOLUME_2L 0x482
147#define WM5100_DAC_DIGITAL_VOLUME_2R 0x483
148#define WM5100_DAC_DIGITAL_VOLUME_3L 0x484
149#define WM5100_DAC_DIGITAL_VOLUME_3R 0x485
150#define WM5100_DAC_DIGITAL_VOLUME_4L 0x486
151#define WM5100_DAC_DIGITAL_VOLUME_4R 0x487
152#define WM5100_DAC_DIGITAL_VOLUME_5L 0x488
153#define WM5100_DAC_DIGITAL_VOLUME_5R 0x489
154#define WM5100_DAC_DIGITAL_VOLUME_6L 0x48A
155#define WM5100_DAC_DIGITAL_VOLUME_6R 0x48B
156#define WM5100_PDM_SPK1_CTRL_1 0x4C0
157#define WM5100_PDM_SPK1_CTRL_2 0x4C1
158#define WM5100_PDM_SPK2_CTRL_1 0x4C2
159#define WM5100_PDM_SPK2_CTRL_2 0x4C3
160#define WM5100_AUDIO_IF_1_1 0x500
161#define WM5100_AUDIO_IF_1_2 0x501
162#define WM5100_AUDIO_IF_1_3 0x502
163#define WM5100_AUDIO_IF_1_4 0x503
164#define WM5100_AUDIO_IF_1_5 0x504
165#define WM5100_AUDIO_IF_1_6 0x505
166#define WM5100_AUDIO_IF_1_7 0x506
167#define WM5100_AUDIO_IF_1_8 0x507
168#define WM5100_AUDIO_IF_1_9 0x508
169#define WM5100_AUDIO_IF_1_10 0x509
170#define WM5100_AUDIO_IF_1_11 0x50A
171#define WM5100_AUDIO_IF_1_12 0x50B
172#define WM5100_AUDIO_IF_1_13 0x50C
173#define WM5100_AUDIO_IF_1_14 0x50D
174#define WM5100_AUDIO_IF_1_15 0x50E
175#define WM5100_AUDIO_IF_1_16 0x50F
176#define WM5100_AUDIO_IF_1_17 0x510
177#define WM5100_AUDIO_IF_1_18 0x511
178#define WM5100_AUDIO_IF_1_19 0x512
179#define WM5100_AUDIO_IF_1_20 0x513
180#define WM5100_AUDIO_IF_1_21 0x514
181#define WM5100_AUDIO_IF_1_22 0x515
182#define WM5100_AUDIO_IF_1_23 0x516
183#define WM5100_AUDIO_IF_1_24 0x517
184#define WM5100_AUDIO_IF_1_25 0x518
185#define WM5100_AUDIO_IF_1_26 0x519
186#define WM5100_AUDIO_IF_1_27 0x51A
187#define WM5100_AUDIO_IF_2_1 0x540
188#define WM5100_AUDIO_IF_2_2 0x541
189#define WM5100_AUDIO_IF_2_3 0x542
190#define WM5100_AUDIO_IF_2_4 0x543
191#define WM5100_AUDIO_IF_2_5 0x544
192#define WM5100_AUDIO_IF_2_6 0x545
193#define WM5100_AUDIO_IF_2_7 0x546
194#define WM5100_AUDIO_IF_2_8 0x547
195#define WM5100_AUDIO_IF_2_9 0x548
196#define WM5100_AUDIO_IF_2_10 0x549
197#define WM5100_AUDIO_IF_2_11 0x54A
198#define WM5100_AUDIO_IF_2_18 0x551
199#define WM5100_AUDIO_IF_2_19 0x552
200#define WM5100_AUDIO_IF_2_26 0x559
201#define WM5100_AUDIO_IF_2_27 0x55A
202#define WM5100_AUDIO_IF_3_1 0x580
203#define WM5100_AUDIO_IF_3_2 0x581
204#define WM5100_AUDIO_IF_3_3 0x582
205#define WM5100_AUDIO_IF_3_4 0x583
206#define WM5100_AUDIO_IF_3_5 0x584
207#define WM5100_AUDIO_IF_3_6 0x585
208#define WM5100_AUDIO_IF_3_7 0x586
209#define WM5100_AUDIO_IF_3_8 0x587
210#define WM5100_AUDIO_IF_3_9 0x588
211#define WM5100_AUDIO_IF_3_10 0x589
212#define WM5100_AUDIO_IF_3_11 0x58A
213#define WM5100_AUDIO_IF_3_18 0x591
214#define WM5100_AUDIO_IF_3_19 0x592
215#define WM5100_AUDIO_IF_3_26 0x599
216#define WM5100_AUDIO_IF_3_27 0x59A
217#define WM5100_PWM1MIX_INPUT_1_SOURCE 0x640
218#define WM5100_PWM1MIX_INPUT_1_VOLUME 0x641
219#define WM5100_PWM1MIX_INPUT_2_SOURCE 0x642
220#define WM5100_PWM1MIX_INPUT_2_VOLUME 0x643
221#define WM5100_PWM1MIX_INPUT_3_SOURCE 0x644
222#define WM5100_PWM1MIX_INPUT_3_VOLUME 0x645
223#define WM5100_PWM1MIX_INPUT_4_SOURCE 0x646
224#define WM5100_PWM1MIX_INPUT_4_VOLUME 0x647
225#define WM5100_PWM2MIX_INPUT_1_SOURCE 0x648
226#define WM5100_PWM2MIX_INPUT_1_VOLUME 0x649
227#define WM5100_PWM2MIX_INPUT_2_SOURCE 0x64A
228#define WM5100_PWM2MIX_INPUT_2_VOLUME 0x64B
229#define WM5100_PWM2MIX_INPUT_3_SOURCE 0x64C
230#define WM5100_PWM2MIX_INPUT_3_VOLUME 0x64D
231#define WM5100_PWM2MIX_INPUT_4_SOURCE 0x64E
232#define WM5100_PWM2MIX_INPUT_4_VOLUME 0x64F
233#define WM5100_OUT1LMIX_INPUT_1_SOURCE 0x680
234#define WM5100_OUT1LMIX_INPUT_1_VOLUME 0x681
235#define WM5100_OUT1LMIX_INPUT_2_SOURCE 0x682
236#define WM5100_OUT1LMIX_INPUT_2_VOLUME 0x683
237#define WM5100_OUT1LMIX_INPUT_3_SOURCE 0x684
238#define WM5100_OUT1LMIX_INPUT_3_VOLUME 0x685
239#define WM5100_OUT1LMIX_INPUT_4_SOURCE 0x686
240#define WM5100_OUT1LMIX_INPUT_4_VOLUME 0x687
241#define WM5100_OUT1RMIX_INPUT_1_SOURCE 0x688
242#define WM5100_OUT1RMIX_INPUT_1_VOLUME 0x689
243#define WM5100_OUT1RMIX_INPUT_2_SOURCE 0x68A
244#define WM5100_OUT1RMIX_INPUT_2_VOLUME 0x68B
245#define WM5100_OUT1RMIX_INPUT_3_SOURCE 0x68C
246#define WM5100_OUT1RMIX_INPUT_3_VOLUME 0x68D
247#define WM5100_OUT1RMIX_INPUT_4_SOURCE 0x68E
248#define WM5100_OUT1RMIX_INPUT_4_VOLUME 0x68F
249#define WM5100_OUT2LMIX_INPUT_1_SOURCE 0x690
250#define WM5100_OUT2LMIX_INPUT_1_VOLUME 0x691
251#define WM5100_OUT2LMIX_INPUT_2_SOURCE 0x692
252#define WM5100_OUT2LMIX_INPUT_2_VOLUME 0x693
253#define WM5100_OUT2LMIX_INPUT_3_SOURCE 0x694
254#define WM5100_OUT2LMIX_INPUT_3_VOLUME 0x695
255#define WM5100_OUT2LMIX_INPUT_4_SOURCE 0x696
256#define WM5100_OUT2LMIX_INPUT_4_VOLUME 0x697
257#define WM5100_OUT2RMIX_INPUT_1_SOURCE 0x698
258#define WM5100_OUT2RMIX_INPUT_1_VOLUME 0x699
259#define WM5100_OUT2RMIX_INPUT_2_SOURCE 0x69A
260#define WM5100_OUT2RMIX_INPUT_2_VOLUME 0x69B
261#define WM5100_OUT2RMIX_INPUT_3_SOURCE 0x69C
262#define WM5100_OUT2RMIX_INPUT_3_VOLUME 0x69D
263#define WM5100_OUT2RMIX_INPUT_4_SOURCE 0x69E
264#define WM5100_OUT2RMIX_INPUT_4_VOLUME 0x69F
265#define WM5100_OUT3LMIX_INPUT_1_SOURCE 0x6A0
266#define WM5100_OUT3LMIX_INPUT_1_VOLUME 0x6A1
267#define WM5100_OUT3LMIX_INPUT_2_SOURCE 0x6A2
268#define WM5100_OUT3LMIX_INPUT_2_VOLUME 0x6A3
269#define WM5100_OUT3LMIX_INPUT_3_SOURCE 0x6A4
270#define WM5100_OUT3LMIX_INPUT_3_VOLUME 0x6A5
271#define WM5100_OUT3LMIX_INPUT_4_SOURCE 0x6A6
272#define WM5100_OUT3LMIX_INPUT_4_VOLUME 0x6A7
273#define WM5100_OUT3RMIX_INPUT_1_SOURCE 0x6A8
274#define WM5100_OUT3RMIX_INPUT_1_VOLUME 0x6A9
275#define WM5100_OUT3RMIX_INPUT_2_SOURCE 0x6AA
276#define WM5100_OUT3RMIX_INPUT_2_VOLUME 0x6AB
277#define WM5100_OUT3RMIX_INPUT_3_SOURCE 0x6AC
278#define WM5100_OUT3RMIX_INPUT_3_VOLUME 0x6AD
279#define WM5100_OUT3RMIX_INPUT_4_SOURCE 0x6AE
280#define WM5100_OUT3RMIX_INPUT_4_VOLUME 0x6AF
281#define WM5100_OUT4LMIX_INPUT_1_SOURCE 0x6B0
282#define WM5100_OUT4LMIX_INPUT_1_VOLUME 0x6B1
283#define WM5100_OUT4LMIX_INPUT_2_SOURCE 0x6B2
284#define WM5100_OUT4LMIX_INPUT_2_VOLUME 0x6B3
285#define WM5100_OUT4LMIX_INPUT_3_SOURCE 0x6B4
286#define WM5100_OUT4LMIX_INPUT_3_VOLUME 0x6B5
287#define WM5100_OUT4LMIX_INPUT_4_SOURCE 0x6B6
288#define WM5100_OUT4LMIX_INPUT_4_VOLUME 0x6B7
289#define WM5100_OUT4RMIX_INPUT_1_SOURCE 0x6B8
290#define WM5100_OUT4RMIX_INPUT_1_VOLUME 0x6B9
291#define WM5100_OUT4RMIX_INPUT_2_SOURCE 0x6BA
292#define WM5100_OUT4RMIX_INPUT_2_VOLUME 0x6BB
293#define WM5100_OUT4RMIX_INPUT_3_SOURCE 0x6BC
294#define WM5100_OUT4RMIX_INPUT_3_VOLUME 0x6BD
295#define WM5100_OUT4RMIX_INPUT_4_SOURCE 0x6BE
296#define WM5100_OUT4RMIX_INPUT_4_VOLUME 0x6BF
297#define WM5100_OUT5LMIX_INPUT_1_SOURCE 0x6C0
298#define WM5100_OUT5LMIX_INPUT_1_VOLUME 0x6C1
299#define WM5100_OUT5LMIX_INPUT_2_SOURCE 0x6C2
300#define WM5100_OUT5LMIX_INPUT_2_VOLUME 0x6C3
301#define WM5100_OUT5LMIX_INPUT_3_SOURCE 0x6C4
302#define WM5100_OUT5LMIX_INPUT_3_VOLUME 0x6C5
303#define WM5100_OUT5LMIX_INPUT_4_SOURCE 0x6C6
304#define WM5100_OUT5LMIX_INPUT_4_VOLUME 0x6C7
305#define WM5100_OUT5RMIX_INPUT_1_SOURCE 0x6C8
306#define WM5100_OUT5RMIX_INPUT_1_VOLUME 0x6C9
307#define WM5100_OUT5RMIX_INPUT_2_SOURCE 0x6CA
308#define WM5100_OUT5RMIX_INPUT_2_VOLUME 0x6CB
309#define WM5100_OUT5RMIX_INPUT_3_SOURCE 0x6CC
310#define WM5100_OUT5RMIX_INPUT_3_VOLUME 0x6CD
311#define WM5100_OUT5RMIX_INPUT_4_SOURCE 0x6CE
312#define WM5100_OUT5RMIX_INPUT_4_VOLUME 0x6CF
313#define WM5100_OUT6LMIX_INPUT_1_SOURCE 0x6D0
314#define WM5100_OUT6LMIX_INPUT_1_VOLUME 0x6D1
315#define WM5100_OUT6LMIX_INPUT_2_SOURCE 0x6D2
316#define WM5100_OUT6LMIX_INPUT_2_VOLUME 0x6D3
317#define WM5100_OUT6LMIX_INPUT_3_SOURCE 0x6D4
318#define WM5100_OUT6LMIX_INPUT_3_VOLUME 0x6D5
319#define WM5100_OUT6LMIX_INPUT_4_SOURCE 0x6D6
320#define WM5100_OUT6LMIX_INPUT_4_VOLUME 0x6D7
321#define WM5100_OUT6RMIX_INPUT_1_SOURCE 0x6D8
322#define WM5100_OUT6RMIX_INPUT_1_VOLUME 0x6D9
323#define WM5100_OUT6RMIX_INPUT_2_SOURCE 0x6DA
324#define WM5100_OUT6RMIX_INPUT_2_VOLUME 0x6DB
325#define WM5100_OUT6RMIX_INPUT_3_SOURCE 0x6DC
326#define WM5100_OUT6RMIX_INPUT_3_VOLUME 0x6DD
327#define WM5100_OUT6RMIX_INPUT_4_SOURCE 0x6DE
328#define WM5100_OUT6RMIX_INPUT_4_VOLUME 0x6DF
329#define WM5100_AIF1TX1MIX_INPUT_1_SOURCE 0x700
330#define WM5100_AIF1TX1MIX_INPUT_1_VOLUME 0x701
331#define WM5100_AIF1TX1MIX_INPUT_2_SOURCE 0x702
332#define WM5100_AIF1TX1MIX_INPUT_2_VOLUME 0x703
333#define WM5100_AIF1TX1MIX_INPUT_3_SOURCE 0x704
334#define WM5100_AIF1TX1MIX_INPUT_3_VOLUME 0x705
335#define WM5100_AIF1TX1MIX_INPUT_4_SOURCE 0x706
336#define WM5100_AIF1TX1MIX_INPUT_4_VOLUME 0x707
337#define WM5100_AIF1TX2MIX_INPUT_1_SOURCE 0x708
338#define WM5100_AIF1TX2MIX_INPUT_1_VOLUME 0x709
339#define WM5100_AIF1TX2MIX_INPUT_2_SOURCE 0x70A
340#define WM5100_AIF1TX2MIX_INPUT_2_VOLUME 0x70B
341#define WM5100_AIF1TX2MIX_INPUT_3_SOURCE 0x70C
342#define WM5100_AIF1TX2MIX_INPUT_3_VOLUME 0x70D
343#define WM5100_AIF1TX2MIX_INPUT_4_SOURCE 0x70E
344#define WM5100_AIF1TX2MIX_INPUT_4_VOLUME 0x70F
345#define WM5100_AIF1TX3MIX_INPUT_1_SOURCE 0x710
346#define WM5100_AIF1TX3MIX_INPUT_1_VOLUME 0x711
347#define WM5100_AIF1TX3MIX_INPUT_2_SOURCE 0x712
348#define WM5100_AIF1TX3MIX_INPUT_2_VOLUME 0x713
349#define WM5100_AIF1TX3MIX_INPUT_3_SOURCE 0x714
350#define WM5100_AIF1TX3MIX_INPUT_3_VOLUME 0x715
351#define WM5100_AIF1TX3MIX_INPUT_4_SOURCE 0x716
352#define WM5100_AIF1TX3MIX_INPUT_4_VOLUME 0x717
353#define WM5100_AIF1TX4MIX_INPUT_1_SOURCE 0x718
354#define WM5100_AIF1TX4MIX_INPUT_1_VOLUME 0x719
355#define WM5100_AIF1TX4MIX_INPUT_2_SOURCE 0x71A
356#define WM5100_AIF1TX4MIX_INPUT_2_VOLUME 0x71B
357#define WM5100_AIF1TX4MIX_INPUT_3_SOURCE 0x71C
358#define WM5100_AIF1TX4MIX_INPUT_3_VOLUME 0x71D
359#define WM5100_AIF1TX4MIX_INPUT_4_SOURCE 0x71E
360#define WM5100_AIF1TX4MIX_INPUT_4_VOLUME 0x71F
361#define WM5100_AIF1TX5MIX_INPUT_1_SOURCE 0x720
362#define WM5100_AIF1TX5MIX_INPUT_1_VOLUME 0x721
363#define WM5100_AIF1TX5MIX_INPUT_2_SOURCE 0x722
364#define WM5100_AIF1TX5MIX_INPUT_2_VOLUME 0x723
365#define WM5100_AIF1TX5MIX_INPUT_3_SOURCE 0x724
366#define WM5100_AIF1TX5MIX_INPUT_3_VOLUME 0x725
367#define WM5100_AIF1TX5MIX_INPUT_4_SOURCE 0x726
368#define WM5100_AIF1TX5MIX_INPUT_4_VOLUME 0x727
369#define WM5100_AIF1TX6MIX_INPUT_1_SOURCE 0x728
370#define WM5100_AIF1TX6MIX_INPUT_1_VOLUME 0x729
371#define WM5100_AIF1TX6MIX_INPUT_2_SOURCE 0x72A
372#define WM5100_AIF1TX6MIX_INPUT_2_VOLUME 0x72B
373#define WM5100_AIF1TX6MIX_INPUT_3_SOURCE 0x72C
374#define WM5100_AIF1TX6MIX_INPUT_3_VOLUME 0x72D
375#define WM5100_AIF1TX6MIX_INPUT_4_SOURCE 0x72E
376#define WM5100_AIF1TX6MIX_INPUT_4_VOLUME 0x72F
377#define WM5100_AIF1TX7MIX_INPUT_1_SOURCE 0x730
378#define WM5100_AIF1TX7MIX_INPUT_1_VOLUME 0x731
379#define WM5100_AIF1TX7MIX_INPUT_2_SOURCE 0x732
380#define WM5100_AIF1TX7MIX_INPUT_2_VOLUME 0x733
381#define WM5100_AIF1TX7MIX_INPUT_3_SOURCE 0x734
382#define WM5100_AIF1TX7MIX_INPUT_3_VOLUME 0x735
383#define WM5100_AIF1TX7MIX_INPUT_4_SOURCE 0x736
384#define WM5100_AIF1TX7MIX_INPUT_4_VOLUME 0x737
385#define WM5100_AIF1TX8MIX_INPUT_1_SOURCE 0x738
386#define WM5100_AIF1TX8MIX_INPUT_1_VOLUME 0x739
387#define WM5100_AIF1TX8MIX_INPUT_2_SOURCE 0x73A
388#define WM5100_AIF1TX8MIX_INPUT_2_VOLUME 0x73B
389#define WM5100_AIF1TX8MIX_INPUT_3_SOURCE 0x73C
390#define WM5100_AIF1TX8MIX_INPUT_3_VOLUME 0x73D
391#define WM5100_AIF1TX8MIX_INPUT_4_SOURCE 0x73E
392#define WM5100_AIF1TX8MIX_INPUT_4_VOLUME 0x73F
393#define WM5100_AIF2TX1MIX_INPUT_1_SOURCE 0x740
394#define WM5100_AIF2TX1MIX_INPUT_1_VOLUME 0x741
395#define WM5100_AIF2TX1MIX_INPUT_2_SOURCE 0x742
396#define WM5100_AIF2TX1MIX_INPUT_2_VOLUME 0x743
397#define WM5100_AIF2TX1MIX_INPUT_3_SOURCE 0x744
398#define WM5100_AIF2TX1MIX_INPUT_3_VOLUME 0x745
399#define WM5100_AIF2TX1MIX_INPUT_4_SOURCE 0x746
400#define WM5100_AIF2TX1MIX_INPUT_4_VOLUME 0x747
401#define WM5100_AIF2TX2MIX_INPUT_1_SOURCE 0x748
402#define WM5100_AIF2TX2MIX_INPUT_1_VOLUME 0x749
403#define WM5100_AIF2TX2MIX_INPUT_2_SOURCE 0x74A
404#define WM5100_AIF2TX2MIX_INPUT_2_VOLUME 0x74B
405#define WM5100_AIF2TX2MIX_INPUT_3_SOURCE 0x74C
406#define WM5100_AIF2TX2MIX_INPUT_3_VOLUME 0x74D
407#define WM5100_AIF2TX2MIX_INPUT_4_SOURCE 0x74E
408#define WM5100_AIF2TX2MIX_INPUT_4_VOLUME 0x74F
409#define WM5100_AIF3TX1MIX_INPUT_1_SOURCE 0x780
410#define WM5100_AIF3TX1MIX_INPUT_1_VOLUME 0x781
411#define WM5100_AIF3TX1MIX_INPUT_2_SOURCE 0x782
412#define WM5100_AIF3TX1MIX_INPUT_2_VOLUME 0x783
413#define WM5100_AIF3TX1MIX_INPUT_3_SOURCE 0x784
414#define WM5100_AIF3TX1MIX_INPUT_3_VOLUME 0x785
415#define WM5100_AIF3TX1MIX_INPUT_4_SOURCE 0x786
416#define WM5100_AIF3TX1MIX_INPUT_4_VOLUME 0x787
417#define WM5100_AIF3TX2MIX_INPUT_1_SOURCE 0x788
418#define WM5100_AIF3TX2MIX_INPUT_1_VOLUME 0x789
419#define WM5100_AIF3TX2MIX_INPUT_2_SOURCE 0x78A
420#define WM5100_AIF3TX2MIX_INPUT_2_VOLUME 0x78B
421#define WM5100_AIF3TX2MIX_INPUT_3_SOURCE 0x78C
422#define WM5100_AIF3TX2MIX_INPUT_3_VOLUME 0x78D
423#define WM5100_AIF3TX2MIX_INPUT_4_SOURCE 0x78E
424#define WM5100_AIF3TX2MIX_INPUT_4_VOLUME 0x78F
425#define WM5100_EQ1MIX_INPUT_1_SOURCE 0x880
426#define WM5100_EQ1MIX_INPUT_1_VOLUME 0x881
427#define WM5100_EQ1MIX_INPUT_2_SOURCE 0x882
428#define WM5100_EQ1MIX_INPUT_2_VOLUME 0x883
429#define WM5100_EQ1MIX_INPUT_3_SOURCE 0x884
430#define WM5100_EQ1MIX_INPUT_3_VOLUME 0x885
431#define WM5100_EQ1MIX_INPUT_4_SOURCE 0x886
432#define WM5100_EQ1MIX_INPUT_4_VOLUME 0x887
433#define WM5100_EQ2MIX_INPUT_1_SOURCE 0x888
434#define WM5100_EQ2MIX_INPUT_1_VOLUME 0x889
435#define WM5100_EQ2MIX_INPUT_2_SOURCE 0x88A
436#define WM5100_EQ2MIX_INPUT_2_VOLUME 0x88B
437#define WM5100_EQ2MIX_INPUT_3_SOURCE 0x88C
438#define WM5100_EQ2MIX_INPUT_3_VOLUME 0x88D
439#define WM5100_EQ2MIX_INPUT_4_SOURCE 0x88E
440#define WM5100_EQ2MIX_INPUT_4_VOLUME 0x88F
441#define WM5100_EQ3MIX_INPUT_1_SOURCE 0x890
442#define WM5100_EQ3MIX_INPUT_1_VOLUME 0x891
443#define WM5100_EQ3MIX_INPUT_2_SOURCE 0x892
444#define WM5100_EQ3MIX_INPUT_2_VOLUME 0x893
445#define WM5100_EQ3MIX_INPUT_3_SOURCE 0x894
446#define WM5100_EQ3MIX_INPUT_3_VOLUME 0x895
447#define WM5100_EQ3MIX_INPUT_4_SOURCE 0x896
448#define WM5100_EQ3MIX_INPUT_4_VOLUME 0x897
449#define WM5100_EQ4MIX_INPUT_1_SOURCE 0x898
450#define WM5100_EQ4MIX_INPUT_1_VOLUME 0x899
451#define WM5100_EQ4MIX_INPUT_2_SOURCE 0x89A
452#define WM5100_EQ4MIX_INPUT_2_VOLUME 0x89B
453#define WM5100_EQ4MIX_INPUT_3_SOURCE 0x89C
454#define WM5100_EQ4MIX_INPUT_3_VOLUME 0x89D
455#define WM5100_EQ4MIX_INPUT_4_SOURCE 0x89E
456#define WM5100_EQ4MIX_INPUT_4_VOLUME 0x89F
457#define WM5100_DRC1LMIX_INPUT_1_SOURCE 0x8C0
458#define WM5100_DRC1LMIX_INPUT_1_VOLUME 0x8C1
459#define WM5100_DRC1LMIX_INPUT_2_SOURCE 0x8C2
460#define WM5100_DRC1LMIX_INPUT_2_VOLUME 0x8C3
461#define WM5100_DRC1LMIX_INPUT_3_SOURCE 0x8C4
462#define WM5100_DRC1LMIX_INPUT_3_VOLUME 0x8C5
463#define WM5100_DRC1LMIX_INPUT_4_SOURCE 0x8C6
464#define WM5100_DRC1LMIX_INPUT_4_VOLUME 0x8C7
465#define WM5100_DRC1RMIX_INPUT_1_SOURCE 0x8C8
466#define WM5100_DRC1RMIX_INPUT_1_VOLUME 0x8C9
467#define WM5100_DRC1RMIX_INPUT_2_SOURCE 0x8CA
468#define WM5100_DRC1RMIX_INPUT_2_VOLUME 0x8CB
469#define WM5100_DRC1RMIX_INPUT_3_SOURCE 0x8CC
470#define WM5100_DRC1RMIX_INPUT_3_VOLUME 0x8CD
471#define WM5100_DRC1RMIX_INPUT_4_SOURCE 0x8CE
472#define WM5100_DRC1RMIX_INPUT_4_VOLUME 0x8CF
473#define WM5100_HPLP1MIX_INPUT_1_SOURCE 0x900
474#define WM5100_HPLP1MIX_INPUT_1_VOLUME 0x901
475#define WM5100_HPLP1MIX_INPUT_2_SOURCE 0x902
476#define WM5100_HPLP1MIX_INPUT_2_VOLUME 0x903
477#define WM5100_HPLP1MIX_INPUT_3_SOURCE 0x904
478#define WM5100_HPLP1MIX_INPUT_3_VOLUME 0x905
479#define WM5100_HPLP1MIX_INPUT_4_SOURCE 0x906
480#define WM5100_HPLP1MIX_INPUT_4_VOLUME 0x907
481#define WM5100_HPLP2MIX_INPUT_1_SOURCE 0x908
482#define WM5100_HPLP2MIX_INPUT_1_VOLUME 0x909
483#define WM5100_HPLP2MIX_INPUT_2_SOURCE 0x90A
484#define WM5100_HPLP2MIX_INPUT_2_VOLUME 0x90B
485#define WM5100_HPLP2MIX_INPUT_3_SOURCE 0x90C
486#define WM5100_HPLP2MIX_INPUT_3_VOLUME 0x90D
487#define WM5100_HPLP2MIX_INPUT_4_SOURCE 0x90E
488#define WM5100_HPLP2MIX_INPUT_4_VOLUME 0x90F
489#define WM5100_HPLP3MIX_INPUT_1_SOURCE 0x910
490#define WM5100_HPLP3MIX_INPUT_1_VOLUME 0x911
491#define WM5100_HPLP3MIX_INPUT_2_SOURCE 0x912
492#define WM5100_HPLP3MIX_INPUT_2_VOLUME 0x913
493#define WM5100_HPLP3MIX_INPUT_3_SOURCE 0x914
494#define WM5100_HPLP3MIX_INPUT_3_VOLUME 0x915
495#define WM5100_HPLP3MIX_INPUT_4_SOURCE 0x916
496#define WM5100_HPLP3MIX_INPUT_4_VOLUME 0x917
497#define WM5100_HPLP4MIX_INPUT_1_SOURCE 0x918
498#define WM5100_HPLP4MIX_INPUT_1_VOLUME 0x919
499#define WM5100_HPLP4MIX_INPUT_2_SOURCE 0x91A
500#define WM5100_HPLP4MIX_INPUT_2_VOLUME 0x91B
501#define WM5100_HPLP4MIX_INPUT_3_SOURCE 0x91C
502#define WM5100_HPLP4MIX_INPUT_3_VOLUME 0x91D
503#define WM5100_HPLP4MIX_INPUT_4_SOURCE 0x91E
504#define WM5100_HPLP4MIX_INPUT_4_VOLUME 0x91F
505#define WM5100_DSP1LMIX_INPUT_1_SOURCE 0x940
506#define WM5100_DSP1LMIX_INPUT_1_VOLUME 0x941
507#define WM5100_DSP1LMIX_INPUT_2_SOURCE 0x942
508#define WM5100_DSP1LMIX_INPUT_2_VOLUME 0x943
509#define WM5100_DSP1LMIX_INPUT_3_SOURCE 0x944
510#define WM5100_DSP1LMIX_INPUT_3_VOLUME 0x945
511#define WM5100_DSP1LMIX_INPUT_4_SOURCE 0x946
512#define WM5100_DSP1LMIX_INPUT_4_VOLUME 0x947
513#define WM5100_DSP1RMIX_INPUT_1_SOURCE 0x948
514#define WM5100_DSP1RMIX_INPUT_1_VOLUME 0x949
515#define WM5100_DSP1RMIX_INPUT_2_SOURCE 0x94A
516#define WM5100_DSP1RMIX_INPUT_2_VOLUME 0x94B
517#define WM5100_DSP1RMIX_INPUT_3_SOURCE 0x94C
518#define WM5100_DSP1RMIX_INPUT_3_VOLUME 0x94D
519#define WM5100_DSP1RMIX_INPUT_4_SOURCE 0x94E
520#define WM5100_DSP1RMIX_INPUT_4_VOLUME 0x94F
521#define WM5100_DSP1AUX1MIX_INPUT_1_SOURCE 0x950
522#define WM5100_DSP1AUX2MIX_INPUT_1_SOURCE 0x958
523#define WM5100_DSP1AUX3MIX_INPUT_1_SOURCE 0x960
524#define WM5100_DSP1AUX4MIX_INPUT_1_SOURCE 0x968
525#define WM5100_DSP1AUX5MIX_INPUT_1_SOURCE 0x970
526#define WM5100_DSP1AUX6MIX_INPUT_1_SOURCE 0x978
527#define WM5100_DSP2LMIX_INPUT_1_SOURCE 0x980
528#define WM5100_DSP2LMIX_INPUT_1_VOLUME 0x981
529#define WM5100_DSP2LMIX_INPUT_2_SOURCE 0x982
530#define WM5100_DSP2LMIX_INPUT_2_VOLUME 0x983
531#define WM5100_DSP2LMIX_INPUT_3_SOURCE 0x984
532#define WM5100_DSP2LMIX_INPUT_3_VOLUME 0x985
533#define WM5100_DSP2LMIX_INPUT_4_SOURCE 0x986
534#define WM5100_DSP2LMIX_INPUT_4_VOLUME 0x987
535#define WM5100_DSP2RMIX_INPUT_1_SOURCE 0x988
536#define WM5100_DSP2RMIX_INPUT_1_VOLUME 0x989
537#define WM5100_DSP2RMIX_INPUT_2_SOURCE 0x98A
538#define WM5100_DSP2RMIX_INPUT_2_VOLUME 0x98B
539#define WM5100_DSP2RMIX_INPUT_3_SOURCE 0x98C
540#define WM5100_DSP2RMIX_INPUT_3_VOLUME 0x98D
541#define WM5100_DSP2RMIX_INPUT_4_SOURCE 0x98E
542#define WM5100_DSP2RMIX_INPUT_4_VOLUME 0x98F
543#define WM5100_DSP2AUX1MIX_INPUT_1_SOURCE 0x990
544#define WM5100_DSP2AUX2MIX_INPUT_1_SOURCE 0x998
545#define WM5100_DSP2AUX3MIX_INPUT_1_SOURCE 0x9A0
546#define WM5100_DSP2AUX4MIX_INPUT_1_SOURCE 0x9A8
547#define WM5100_DSP2AUX5MIX_INPUT_1_SOURCE 0x9B0
548#define WM5100_DSP2AUX6MIX_INPUT_1_SOURCE 0x9B8
549#define WM5100_DSP3LMIX_INPUT_1_SOURCE 0x9C0
550#define WM5100_DSP3LMIX_INPUT_1_VOLUME 0x9C1
551#define WM5100_DSP3LMIX_INPUT_2_SOURCE 0x9C2
552#define WM5100_DSP3LMIX_INPUT_2_VOLUME 0x9C3
553#define WM5100_DSP3LMIX_INPUT_3_SOURCE 0x9C4
554#define WM5100_DSP3LMIX_INPUT_3_VOLUME 0x9C5
555#define WM5100_DSP3LMIX_INPUT_4_SOURCE 0x9C6
556#define WM5100_DSP3LMIX_INPUT_4_VOLUME 0x9C7
557#define WM5100_DSP3RMIX_INPUT_1_SOURCE 0x9C8
558#define WM5100_DSP3RMIX_INPUT_1_VOLUME 0x9C9
559#define WM5100_DSP3RMIX_INPUT_2_SOURCE 0x9CA
560#define WM5100_DSP3RMIX_INPUT_2_VOLUME 0x9CB
561#define WM5100_DSP3RMIX_INPUT_3_SOURCE 0x9CC
562#define WM5100_DSP3RMIX_INPUT_3_VOLUME 0x9CD
563#define WM5100_DSP3RMIX_INPUT_4_SOURCE 0x9CE
564#define WM5100_DSP3RMIX_INPUT_4_VOLUME 0x9CF
565#define WM5100_DSP3AUX1MIX_INPUT_1_SOURCE 0x9D0
566#define WM5100_DSP3AUX2MIX_INPUT_1_SOURCE 0x9D8
567#define WM5100_DSP3AUX3MIX_INPUT_1_SOURCE 0x9E0
568#define WM5100_DSP3AUX4MIX_INPUT_1_SOURCE 0x9E8
569#define WM5100_DSP3AUX5MIX_INPUT_1_SOURCE 0x9F0
570#define WM5100_DSP3AUX6MIX_INPUT_1_SOURCE 0x9F8
571#define WM5100_ASRC1LMIX_INPUT_1_SOURCE 0xA80
572#define WM5100_ASRC1RMIX_INPUT_1_SOURCE 0xA88
573#define WM5100_ASRC2LMIX_INPUT_1_SOURCE 0xA90
574#define WM5100_ASRC2RMIX_INPUT_1_SOURCE 0xA98
575#define WM5100_ISRC1DEC1MIX_INPUT_1_SOURCE 0xB00
576#define WM5100_ISRC1DEC2MIX_INPUT_1_SOURCE 0xB08
577#define WM5100_ISRC1DEC3MIX_INPUT_1_SOURCE 0xB10
578#define WM5100_ISRC1DEC4MIX_INPUT_1_SOURCE 0xB18
579#define WM5100_ISRC1INT1MIX_INPUT_1_SOURCE 0xB20
580#define WM5100_ISRC1INT2MIX_INPUT_1_SOURCE 0xB28
581#define WM5100_ISRC1INT3MIX_INPUT_1_SOURCE 0xB30
582#define WM5100_ISRC1INT4MIX_INPUT_1_SOURCE 0xB38
583#define WM5100_ISRC2DEC1MIX_INPUT_1_SOURCE 0xB40
584#define WM5100_ISRC2DEC2MIX_INPUT_1_SOURCE 0xB48
585#define WM5100_ISRC2DEC3MIX_INPUT_1_SOURCE 0xB50
586#define WM5100_ISRC2DEC4MIX_INPUT_1_SOURCE 0xB58
587#define WM5100_ISRC2INT1MIX_INPUT_1_SOURCE 0xB60
588#define WM5100_ISRC2INT2MIX_INPUT_1_SOURCE 0xB68
589#define WM5100_ISRC2INT3MIX_INPUT_1_SOURCE 0xB70
590#define WM5100_ISRC2INT4MIX_INPUT_1_SOURCE 0xB78
591#define WM5100_GPIO_CTRL_1 0xC00
592#define WM5100_GPIO_CTRL_2 0xC01
593#define WM5100_GPIO_CTRL_3 0xC02
594#define WM5100_GPIO_CTRL_4 0xC03
595#define WM5100_GPIO_CTRL_5 0xC04
596#define WM5100_GPIO_CTRL_6 0xC05
597#define WM5100_MISC_PAD_CTRL_1 0xC23
598#define WM5100_MISC_PAD_CTRL_2 0xC24
599#define WM5100_MISC_PAD_CTRL_3 0xC25
600#define WM5100_MISC_PAD_CTRL_4 0xC26
601#define WM5100_MISC_PAD_CTRL_5 0xC27
602#define WM5100_MISC_GPIO_1 0xC28
603#define WM5100_INTERRUPT_STATUS_1 0xD00
604#define WM5100_INTERRUPT_STATUS_2 0xD01
605#define WM5100_INTERRUPT_STATUS_3 0xD02
606#define WM5100_INTERRUPT_STATUS_4 0xD03
607#define WM5100_INTERRUPT_RAW_STATUS_2 0xD04
608#define WM5100_INTERRUPT_RAW_STATUS_3 0xD05
609#define WM5100_INTERRUPT_RAW_STATUS_4 0xD06
610#define WM5100_INTERRUPT_STATUS_1_MASK 0xD07
611#define WM5100_INTERRUPT_STATUS_2_MASK 0xD08
612#define WM5100_INTERRUPT_STATUS_3_MASK 0xD09
613#define WM5100_INTERRUPT_STATUS_4_MASK 0xD0A
614#define WM5100_INTERRUPT_CONTROL 0xD1F
615#define WM5100_IRQ_DEBOUNCE_1 0xD20
616#define WM5100_IRQ_DEBOUNCE_2 0xD21
617#define WM5100_FX_CTRL 0xE00
618#define WM5100_EQ1_1 0xE10
619#define WM5100_EQ1_2 0xE11
620#define WM5100_EQ1_3 0xE12
621#define WM5100_EQ1_4 0xE13
622#define WM5100_EQ1_5 0xE14
623#define WM5100_EQ1_6 0xE15
624#define WM5100_EQ1_7 0xE16
625#define WM5100_EQ1_8 0xE17
626#define WM5100_EQ1_9 0xE18
627#define WM5100_EQ1_10 0xE19
628#define WM5100_EQ1_11 0xE1A
629#define WM5100_EQ1_12 0xE1B
630#define WM5100_EQ1_13 0xE1C
631#define WM5100_EQ1_14 0xE1D
632#define WM5100_EQ1_15 0xE1E
633#define WM5100_EQ1_16 0xE1F
634#define WM5100_EQ1_17 0xE20
635#define WM5100_EQ1_18 0xE21
636#define WM5100_EQ1_19 0xE22
637#define WM5100_EQ1_20 0xE23
638#define WM5100_EQ2_1 0xE26
639#define WM5100_EQ2_2 0xE27
640#define WM5100_EQ2_3 0xE28
641#define WM5100_EQ2_4 0xE29
642#define WM5100_EQ2_5 0xE2A
643#define WM5100_EQ2_6 0xE2B
644#define WM5100_EQ2_7 0xE2C
645#define WM5100_EQ2_8 0xE2D
646#define WM5100_EQ2_9 0xE2E
647#define WM5100_EQ2_10 0xE2F
648#define WM5100_EQ2_11 0xE30
649#define WM5100_EQ2_12 0xE31
650#define WM5100_EQ2_13 0xE32
651#define WM5100_EQ2_14 0xE33
652#define WM5100_EQ2_15 0xE34
653#define WM5100_EQ2_16 0xE35
654#define WM5100_EQ2_17 0xE36
655#define WM5100_EQ2_18 0xE37
656#define WM5100_EQ2_19 0xE38
657#define WM5100_EQ2_20 0xE39
658#define WM5100_EQ3_1 0xE3C
659#define WM5100_EQ3_2 0xE3D
660#define WM5100_EQ3_3 0xE3E
661#define WM5100_EQ3_4 0xE3F
662#define WM5100_EQ3_5 0xE40
663#define WM5100_EQ3_6 0xE41
664#define WM5100_EQ3_7 0xE42
665#define WM5100_EQ3_8 0xE43
666#define WM5100_EQ3_9 0xE44
667#define WM5100_EQ3_10 0xE45
668#define WM5100_EQ3_11 0xE46
669#define WM5100_EQ3_12 0xE47
670#define WM5100_EQ3_13 0xE48
671#define WM5100_EQ3_14 0xE49
672#define WM5100_EQ3_15 0xE4A
673#define WM5100_EQ3_16 0xE4B
674#define WM5100_EQ3_17 0xE4C
675#define WM5100_EQ3_18 0xE4D
676#define WM5100_EQ3_19 0xE4E
677#define WM5100_EQ3_20 0xE4F
678#define WM5100_EQ4_1 0xE52
679#define WM5100_EQ4_2 0xE53
680#define WM5100_EQ4_3 0xE54
681#define WM5100_EQ4_4 0xE55
682#define WM5100_EQ4_5 0xE56
683#define WM5100_EQ4_6 0xE57
684#define WM5100_EQ4_7 0xE58
685#define WM5100_EQ4_8 0xE59
686#define WM5100_EQ4_9 0xE5A
687#define WM5100_EQ4_10 0xE5B
688#define WM5100_EQ4_11 0xE5C
689#define WM5100_EQ4_12 0xE5D
690#define WM5100_EQ4_13 0xE5E
691#define WM5100_EQ4_14 0xE5F
692#define WM5100_EQ4_15 0xE60
693#define WM5100_EQ4_16 0xE61
694#define WM5100_EQ4_17 0xE62
695#define WM5100_EQ4_18 0xE63
696#define WM5100_EQ4_19 0xE64
697#define WM5100_EQ4_20 0xE65
698#define WM5100_DRC1_CTRL1 0xE80
699#define WM5100_DRC1_CTRL2 0xE81
700#define WM5100_DRC1_CTRL3 0xE82
701#define WM5100_DRC1_CTRL4 0xE83
702#define WM5100_DRC1_CTRL5 0xE84
703#define WM5100_HPLPF1_1 0xEC0
704#define WM5100_HPLPF1_2 0xEC1
705#define WM5100_HPLPF2_1 0xEC4
706#define WM5100_HPLPF2_2 0xEC5
707#define WM5100_HPLPF3_1 0xEC8
708#define WM5100_HPLPF3_2 0xEC9
709#define WM5100_HPLPF4_1 0xECC
710#define WM5100_HPLPF4_2 0xECD
711#define WM5100_DSP1_DM_0 0x4000
712#define WM5100_DSP1_DM_1 0x4001
713#define WM5100_DSP1_DM_2 0x4002
714#define WM5100_DSP1_DM_3 0x4003
715#define WM5100_DSP1_DM_508 0x41FC
716#define WM5100_DSP1_DM_509 0x41FD
717#define WM5100_DSP1_DM_510 0x41FE
718#define WM5100_DSP1_DM_511 0x41FF
719#define WM5100_DSP1_PM_0 0x4800
720#define WM5100_DSP1_PM_1 0x4801
721#define WM5100_DSP1_PM_2 0x4802
722#define WM5100_DSP1_PM_3 0x4803
723#define WM5100_DSP1_PM_4 0x4804
724#define WM5100_DSP1_PM_5 0x4805
725#define WM5100_DSP1_PM_1530 0x4DFA
726#define WM5100_DSP1_PM_1531 0x4DFB
727#define WM5100_DSP1_PM_1532 0x4DFC
728#define WM5100_DSP1_PM_1533 0x4DFD
729#define WM5100_DSP1_PM_1534 0x4DFE
730#define WM5100_DSP1_PM_1535 0x4DFF
731#define WM5100_DSP1_ZM_0 0x5000
732#define WM5100_DSP1_ZM_1 0x5001
733#define WM5100_DSP1_ZM_2 0x5002
734#define WM5100_DSP1_ZM_3 0x5003
735#define WM5100_DSP1_ZM_2044 0x57FC
736#define WM5100_DSP1_ZM_2045 0x57FD
737#define WM5100_DSP1_ZM_2046 0x57FE
738#define WM5100_DSP1_ZM_2047 0x57FF
739#define WM5100_DSP2_DM_0 0x6000
740#define WM5100_DSP2_DM_1 0x6001
741#define WM5100_DSP2_DM_2 0x6002
742#define WM5100_DSP2_DM_3 0x6003
743#define WM5100_DSP2_DM_508 0x61FC
744#define WM5100_DSP2_DM_509 0x61FD
745#define WM5100_DSP2_DM_510 0x61FE
746#define WM5100_DSP2_DM_511 0x61FF
747#define WM5100_DSP2_PM_0 0x6800
748#define WM5100_DSP2_PM_1 0x6801
749#define WM5100_DSP2_PM_2 0x6802
750#define WM5100_DSP2_PM_3 0x6803
751#define WM5100_DSP2_PM_4 0x6804
752#define WM5100_DSP2_PM_5 0x6805
753#define WM5100_DSP2_PM_1530 0x6DFA
754#define WM5100_DSP2_PM_1531 0x6DFB
755#define WM5100_DSP2_PM_1532 0x6DFC
756#define WM5100_DSP2_PM_1533 0x6DFD
757#define WM5100_DSP2_PM_1534 0x6DFE
758#define WM5100_DSP2_PM_1535 0x6DFF
759#define WM5100_DSP2_ZM_0 0x7000
760#define WM5100_DSP2_ZM_1 0x7001
761#define WM5100_DSP2_ZM_2 0x7002
762#define WM5100_DSP2_ZM_3 0x7003
763#define WM5100_DSP2_ZM_2044 0x77FC
764#define WM5100_DSP2_ZM_2045 0x77FD
765#define WM5100_DSP2_ZM_2046 0x77FE
766#define WM5100_DSP2_ZM_2047 0x77FF
767#define WM5100_DSP3_DM_0 0x8000
768#define WM5100_DSP3_DM_1 0x8001
769#define WM5100_DSP3_DM_2 0x8002
770#define WM5100_DSP3_DM_3 0x8003
771#define WM5100_DSP3_DM_508 0x81FC
772#define WM5100_DSP3_DM_509 0x81FD
773#define WM5100_DSP3_DM_510 0x81FE
774#define WM5100_DSP3_DM_511 0x81FF
775#define WM5100_DSP3_PM_0 0x8800
776#define WM5100_DSP3_PM_1 0x8801
777#define WM5100_DSP3_PM_2 0x8802
778#define WM5100_DSP3_PM_3 0x8803
779#define WM5100_DSP3_PM_4 0x8804
780#define WM5100_DSP3_PM_5 0x8805
781#define WM5100_DSP3_PM_1530 0x8DFA
782#define WM5100_DSP3_PM_1531 0x8DFB
783#define WM5100_DSP3_PM_1532 0x8DFC
784#define WM5100_DSP3_PM_1533 0x8DFD
785#define WM5100_DSP3_PM_1534 0x8DFE
786#define WM5100_DSP3_PM_1535 0x8DFF
787#define WM5100_DSP3_ZM_0 0x9000
788#define WM5100_DSP3_ZM_1 0x9001
789#define WM5100_DSP3_ZM_2 0x9002
790#define WM5100_DSP3_ZM_3 0x9003
791#define WM5100_DSP3_ZM_2044 0x97FC
792#define WM5100_DSP3_ZM_2045 0x97FD
793#define WM5100_DSP3_ZM_2046 0x97FE
794#define WM5100_DSP3_ZM_2047 0x97FF
795
796#define WM5100_REGISTER_COUNT 1435
797#define WM5100_MAX_REGISTER 0x97FF
798
799/*
800 * Field Definitions.
801 */
802
803/*
804 * R0 (0x00) - software reset
805 */
806#define WM5100_SW_RST_DEV_ID1_MASK 0xFFFF /* SW_RST_DEV_ID1 - [15:0] */
807#define WM5100_SW_RST_DEV_ID1_SHIFT 0 /* SW_RST_DEV_ID1 - [15:0] */
808#define WM5100_SW_RST_DEV_ID1_WIDTH 16 /* SW_RST_DEV_ID1 - [15:0] */
809
810/*
811 * R1 (0x01) - Device Revision
812 */
813#define WM5100_DEVICE_REVISION_MASK 0x000F /* DEVICE_REVISION - [3:0] */
814#define WM5100_DEVICE_REVISION_SHIFT 0 /* DEVICE_REVISION - [3:0] */
815#define WM5100_DEVICE_REVISION_WIDTH 4 /* DEVICE_REVISION - [3:0] */
816
817/*
818 * R16 (0x10) - Ctrl IF 1
819 */
820#define WM5100_AUTO_INC 0x0001 /* AUTO_INC */
821#define WM5100_AUTO_INC_MASK 0x0001 /* AUTO_INC */
822#define WM5100_AUTO_INC_SHIFT 0 /* AUTO_INC */
823#define WM5100_AUTO_INC_WIDTH 1 /* AUTO_INC */
824
825/*
826 * R32 (0x20) - Tone Generator 1
827 */
828#define WM5100_TONE_RATE_MASK 0x3000 /* TONE_RATE - [13:12] */
829#define WM5100_TONE_RATE_SHIFT 12 /* TONE_RATE - [13:12] */
830#define WM5100_TONE_RATE_WIDTH 2 /* TONE_RATE - [13:12] */
831#define WM5100_TONE_OFFSET_MASK 0x0300 /* TONE_OFFSET - [9:8] */
832#define WM5100_TONE_OFFSET_SHIFT 8 /* TONE_OFFSET - [9:8] */
833#define WM5100_TONE_OFFSET_WIDTH 2 /* TONE_OFFSET - [9:8] */
834#define WM5100_TONE2_ENA 0x0002 /* TONE2_ENA */
835#define WM5100_TONE2_ENA_MASK 0x0002 /* TONE2_ENA */
836#define WM5100_TONE2_ENA_SHIFT 1 /* TONE2_ENA */
837#define WM5100_TONE2_ENA_WIDTH 1 /* TONE2_ENA */
838#define WM5100_TONE1_ENA 0x0001 /* TONE1_ENA */
839#define WM5100_TONE1_ENA_MASK 0x0001 /* TONE1_ENA */
840#define WM5100_TONE1_ENA_SHIFT 0 /* TONE1_ENA */
841#define WM5100_TONE1_ENA_WIDTH 1 /* TONE1_ENA */
842
843/*
844 * R48 (0x30) - PWM Drive 1
845 */
846#define WM5100_PWM_RATE_MASK 0x3000 /* PWM_RATE - [13:12] */
847#define WM5100_PWM_RATE_SHIFT 12 /* PWM_RATE - [13:12] */
848#define WM5100_PWM_RATE_WIDTH 2 /* PWM_RATE - [13:12] */
849#define WM5100_PWM_CLK_SEL_MASK 0x0300 /* PWM_CLK_SEL - [9:8] */
850#define WM5100_PWM_CLK_SEL_SHIFT 8 /* PWM_CLK_SEL - [9:8] */
851#define WM5100_PWM_CLK_SEL_WIDTH 2 /* PWM_CLK_SEL - [9:8] */
852#define WM5100_PWM2_OVD 0x0020 /* PWM2_OVD */
853#define WM5100_PWM2_OVD_MASK 0x0020 /* PWM2_OVD */
854#define WM5100_PWM2_OVD_SHIFT 5 /* PWM2_OVD */
855#define WM5100_PWM2_OVD_WIDTH 1 /* PWM2_OVD */
856#define WM5100_PWM1_OVD 0x0010 /* PWM1_OVD */
857#define WM5100_PWM1_OVD_MASK 0x0010 /* PWM1_OVD */
858#define WM5100_PWM1_OVD_SHIFT 4 /* PWM1_OVD */
859#define WM5100_PWM1_OVD_WIDTH 1 /* PWM1_OVD */
860#define WM5100_PWM2_ENA 0x0002 /* PWM2_ENA */
861#define WM5100_PWM2_ENA_MASK 0x0002 /* PWM2_ENA */
862#define WM5100_PWM2_ENA_SHIFT 1 /* PWM2_ENA */
863#define WM5100_PWM2_ENA_WIDTH 1 /* PWM2_ENA */
864#define WM5100_PWM1_ENA 0x0001 /* PWM1_ENA */
865#define WM5100_PWM1_ENA_MASK 0x0001 /* PWM1_ENA */
866#define WM5100_PWM1_ENA_SHIFT 0 /* PWM1_ENA */
867#define WM5100_PWM1_ENA_WIDTH 1 /* PWM1_ENA */
868
869/*
870 * R49 (0x31) - PWM Drive 2
871 */
872#define WM5100_PWM1_LVL_MASK 0x03FF /* PWM1_LVL - [9:0] */
873#define WM5100_PWM1_LVL_SHIFT 0 /* PWM1_LVL - [9:0] */
874#define WM5100_PWM1_LVL_WIDTH 10 /* PWM1_LVL - [9:0] */
875
876/*
877 * R50 (0x32) - PWM Drive 3
878 */
879#define WM5100_PWM2_LVL_MASK 0x03FF /* PWM2_LVL - [9:0] */
880#define WM5100_PWM2_LVL_SHIFT 0 /* PWM2_LVL - [9:0] */
881#define WM5100_PWM2_LVL_WIDTH 10 /* PWM2_LVL - [9:0] */
882
883/*
884 * R256 (0x100) - Clocking 1
885 */
886#define WM5100_CLK_32K_SRC_MASK 0x000F /* CLK_32K_SRC - [3:0] */
887#define WM5100_CLK_32K_SRC_SHIFT 0 /* CLK_32K_SRC - [3:0] */
888#define WM5100_CLK_32K_SRC_WIDTH 4 /* CLK_32K_SRC - [3:0] */
889
890/*
891 * R257 (0x101) - Clocking 3
892 */
893#define WM5100_SYSCLK_FREQ_MASK 0x0700 /* SYSCLK_FREQ - [10:8] */
894#define WM5100_SYSCLK_FREQ_SHIFT 8 /* SYSCLK_FREQ - [10:8] */
895#define WM5100_SYSCLK_FREQ_WIDTH 3 /* SYSCLK_FREQ - [10:8] */
896#define WM5100_SYSCLK_ENA 0x0040 /* SYSCLK_ENA */
897#define WM5100_SYSCLK_ENA_MASK 0x0040 /* SYSCLK_ENA */
898#define WM5100_SYSCLK_ENA_SHIFT 6 /* SYSCLK_ENA */
899#define WM5100_SYSCLK_ENA_WIDTH 1 /* SYSCLK_ENA */
900#define WM5100_SYSCLK_SRC_MASK 0x000F /* SYSCLK_SRC - [3:0] */
901#define WM5100_SYSCLK_SRC_SHIFT 0 /* SYSCLK_SRC - [3:0] */
902#define WM5100_SYSCLK_SRC_WIDTH 4 /* SYSCLK_SRC - [3:0] */
903
904/*
905 * R258 (0x102) - Clocking 4
906 */
907#define WM5100_SAMPLE_RATE_1_MASK 0x001F /* SAMPLE_RATE_1 - [4:0] */
908#define WM5100_SAMPLE_RATE_1_SHIFT 0 /* SAMPLE_RATE_1 - [4:0] */
909#define WM5100_SAMPLE_RATE_1_WIDTH 5 /* SAMPLE_RATE_1 - [4:0] */
910
911/*
912 * R259 (0x103) - Clocking 5
913 */
914#define WM5100_SAMPLE_RATE_2_MASK 0x001F /* SAMPLE_RATE_2 - [4:0] */
915#define WM5100_SAMPLE_RATE_2_SHIFT 0 /* SAMPLE_RATE_2 - [4:0] */
916#define WM5100_SAMPLE_RATE_2_WIDTH 5 /* SAMPLE_RATE_2 - [4:0] */
917
918/*
919 * R260 (0x104) - Clocking 6
920 */
921#define WM5100_SAMPLE_RATE_3_MASK 0x001F /* SAMPLE_RATE_3 - [4:0] */
922#define WM5100_SAMPLE_RATE_3_SHIFT 0 /* SAMPLE_RATE_3 - [4:0] */
923#define WM5100_SAMPLE_RATE_3_WIDTH 5 /* SAMPLE_RATE_3 - [4:0] */
924
925/*
926 * R263 (0x107) - Clocking 7
927 */
928#define WM5100_ASYNC_CLK_FREQ_MASK 0x0700 /* ASYNC_CLK_FREQ - [10:8] */
929#define WM5100_ASYNC_CLK_FREQ_SHIFT 8 /* ASYNC_CLK_FREQ - [10:8] */
930#define WM5100_ASYNC_CLK_FREQ_WIDTH 3 /* ASYNC_CLK_FREQ - [10:8] */
931#define WM5100_ASYNC_CLK_ENA 0x0040 /* ASYNC_CLK_ENA */
932#define WM5100_ASYNC_CLK_ENA_MASK 0x0040 /* ASYNC_CLK_ENA */
933#define WM5100_ASYNC_CLK_ENA_SHIFT 6 /* ASYNC_CLK_ENA */
934#define WM5100_ASYNC_CLK_ENA_WIDTH 1 /* ASYNC_CLK_ENA */
935#define WM5100_ASYNC_CLK_SRC_MASK 0x000F /* ASYNC_CLK_SRC - [3:0] */
936#define WM5100_ASYNC_CLK_SRC_SHIFT 0 /* ASYNC_CLK_SRC - [3:0] */
937#define WM5100_ASYNC_CLK_SRC_WIDTH 4 /* ASYNC_CLK_SRC - [3:0] */
938
939/*
940 * R264 (0x108) - Clocking 8
941 */
942#define WM5100_ASYNC_SAMPLE_RATE_MASK 0x001F /* ASYNC_SAMPLE_RATE - [4:0] */
943#define WM5100_ASYNC_SAMPLE_RATE_SHIFT 0 /* ASYNC_SAMPLE_RATE - [4:0] */
944#define WM5100_ASYNC_SAMPLE_RATE_WIDTH 5 /* ASYNC_SAMPLE_RATE - [4:0] */
945
946/*
947 * R288 (0x120) - ASRC_ENABLE
948 */
949#define WM5100_ASRC2L_ENA 0x0008 /* ASRC2L_ENA */
950#define WM5100_ASRC2L_ENA_MASK 0x0008 /* ASRC2L_ENA */
951#define WM5100_ASRC2L_ENA_SHIFT 3 /* ASRC2L_ENA */
952#define WM5100_ASRC2L_ENA_WIDTH 1 /* ASRC2L_ENA */
953#define WM5100_ASRC2R_ENA 0x0004 /* ASRC2R_ENA */
954#define WM5100_ASRC2R_ENA_MASK 0x0004 /* ASRC2R_ENA */
955#define WM5100_ASRC2R_ENA_SHIFT 2 /* ASRC2R_ENA */
956#define WM5100_ASRC2R_ENA_WIDTH 1 /* ASRC2R_ENA */
957#define WM5100_ASRC1L_ENA 0x0002 /* ASRC1L_ENA */
958#define WM5100_ASRC1L_ENA_MASK 0x0002 /* ASRC1L_ENA */
959#define WM5100_ASRC1L_ENA_SHIFT 1 /* ASRC1L_ENA */
960#define WM5100_ASRC1L_ENA_WIDTH 1 /* ASRC1L_ENA */
961#define WM5100_ASRC1R_ENA 0x0001 /* ASRC1R_ENA */
962#define WM5100_ASRC1R_ENA_MASK 0x0001 /* ASRC1R_ENA */
963#define WM5100_ASRC1R_ENA_SHIFT 0 /* ASRC1R_ENA */
964#define WM5100_ASRC1R_ENA_WIDTH 1 /* ASRC1R_ENA */
965
966/*
967 * R289 (0x121) - ASRC_STATUS
968 */
969#define WM5100_ASRC2L_ENA_STS 0x0008 /* ASRC2L_ENA_STS */
970#define WM5100_ASRC2L_ENA_STS_MASK 0x0008 /* ASRC2L_ENA_STS */
971#define WM5100_ASRC2L_ENA_STS_SHIFT 3 /* ASRC2L_ENA_STS */
972#define WM5100_ASRC2L_ENA_STS_WIDTH 1 /* ASRC2L_ENA_STS */
973#define WM5100_ASRC2R_ENA_STS 0x0004 /* ASRC2R_ENA_STS */
974#define WM5100_ASRC2R_ENA_STS_MASK 0x0004 /* ASRC2R_ENA_STS */
975#define WM5100_ASRC2R_ENA_STS_SHIFT 2 /* ASRC2R_ENA_STS */
976#define WM5100_ASRC2R_ENA_STS_WIDTH 1 /* ASRC2R_ENA_STS */
977#define WM5100_ASRC1L_ENA_STS 0x0002 /* ASRC1L_ENA_STS */
978#define WM5100_ASRC1L_ENA_STS_MASK 0x0002 /* ASRC1L_ENA_STS */
979#define WM5100_ASRC1L_ENA_STS_SHIFT 1 /* ASRC1L_ENA_STS */
980#define WM5100_ASRC1L_ENA_STS_WIDTH 1 /* ASRC1L_ENA_STS */
981#define WM5100_ASRC1R_ENA_STS 0x0001 /* ASRC1R_ENA_STS */
982#define WM5100_ASRC1R_ENA_STS_MASK 0x0001 /* ASRC1R_ENA_STS */
983#define WM5100_ASRC1R_ENA_STS_SHIFT 0 /* ASRC1R_ENA_STS */
984#define WM5100_ASRC1R_ENA_STS_WIDTH 1 /* ASRC1R_ENA_STS */
985
986/*
987 * R290 (0x122) - ASRC_RATE1
988 */
989#define WM5100_ASRC_RATE1_MASK 0x0006 /* ASRC_RATE1 - [2:1] */
990#define WM5100_ASRC_RATE1_SHIFT 1 /* ASRC_RATE1 - [2:1] */
991#define WM5100_ASRC_RATE1_WIDTH 2 /* ASRC_RATE1 - [2:1] */
992
993/*
994 * R321 (0x141) - ISRC 1 CTRL 1
995 */
996#define WM5100_ISRC1_DFS_ENA 0x2000 /* ISRC1_DFS_ENA */
997#define WM5100_ISRC1_DFS_ENA_MASK 0x2000 /* ISRC1_DFS_ENA */
998#define WM5100_ISRC1_DFS_ENA_SHIFT 13 /* ISRC1_DFS_ENA */
999#define WM5100_ISRC1_DFS_ENA_WIDTH 1 /* ISRC1_DFS_ENA */
1000#define WM5100_ISRC1_CLK_SEL_MASK 0x0300 /* ISRC1_CLK_SEL - [9:8] */
1001#define WM5100_ISRC1_CLK_SEL_SHIFT 8 /* ISRC1_CLK_SEL - [9:8] */
1002#define WM5100_ISRC1_CLK_SEL_WIDTH 2 /* ISRC1_CLK_SEL - [9:8] */
1003#define WM5100_ISRC1_FSH_MASK 0x000C /* ISRC1_FSH - [3:2] */
1004#define WM5100_ISRC1_FSH_SHIFT 2 /* ISRC1_FSH - [3:2] */
1005#define WM5100_ISRC1_FSH_WIDTH 2 /* ISRC1_FSH - [3:2] */
1006#define WM5100_ISRC1_FSL_MASK 0x0003 /* ISRC1_FSL - [1:0] */
1007#define WM5100_ISRC1_FSL_SHIFT 0 /* ISRC1_FSL - [1:0] */
1008#define WM5100_ISRC1_FSL_WIDTH 2 /* ISRC1_FSL - [1:0] */
1009
1010/*
1011 * R322 (0x142) - ISRC 1 CTRL 2
1012 */
1013#define WM5100_ISRC1_INT1_ENA 0x8000 /* ISRC1_INT1_ENA */
1014#define WM5100_ISRC1_INT1_ENA_MASK 0x8000 /* ISRC1_INT1_ENA */
1015#define WM5100_ISRC1_INT1_ENA_SHIFT 15 /* ISRC1_INT1_ENA */
1016#define WM5100_ISRC1_INT1_ENA_WIDTH 1 /* ISRC1_INT1_ENA */
1017#define WM5100_ISRC1_INT2_ENA 0x4000 /* ISRC1_INT2_ENA */
1018#define WM5100_ISRC1_INT2_ENA_MASK 0x4000 /* ISRC1_INT2_ENA */
1019#define WM5100_ISRC1_INT2_ENA_SHIFT 14 /* ISRC1_INT2_ENA */
1020#define WM5100_ISRC1_INT2_ENA_WIDTH 1 /* ISRC1_INT2_ENA */
1021#define WM5100_ISRC1_INT3_ENA 0x2000 /* ISRC1_INT3_ENA */
1022#define WM5100_ISRC1_INT3_ENA_MASK 0x2000 /* ISRC1_INT3_ENA */
1023#define WM5100_ISRC1_INT3_ENA_SHIFT 13 /* ISRC1_INT3_ENA */
1024#define WM5100_ISRC1_INT3_ENA_WIDTH 1 /* ISRC1_INT3_ENA */
1025#define WM5100_ISRC1_INT4_ENA 0x1000 /* ISRC1_INT4_ENA */
1026#define WM5100_ISRC1_INT4_ENA_MASK 0x1000 /* ISRC1_INT4_ENA */
1027#define WM5100_ISRC1_INT4_ENA_SHIFT 12 /* ISRC1_INT4_ENA */
1028#define WM5100_ISRC1_INT4_ENA_WIDTH 1 /* ISRC1_INT4_ENA */
1029#define WM5100_ISRC1_DEC1_ENA 0x0200 /* ISRC1_DEC1_ENA */
1030#define WM5100_ISRC1_DEC1_ENA_MASK 0x0200 /* ISRC1_DEC1_ENA */
1031#define WM5100_ISRC1_DEC1_ENA_SHIFT 9 /* ISRC1_DEC1_ENA */
1032#define WM5100_ISRC1_DEC1_ENA_WIDTH 1 /* ISRC1_DEC1_ENA */
1033#define WM5100_ISRC1_DEC2_ENA 0x0100 /* ISRC1_DEC2_ENA */
1034#define WM5100_ISRC1_DEC2_ENA_MASK 0x0100 /* ISRC1_DEC2_ENA */
1035#define WM5100_ISRC1_DEC2_ENA_SHIFT 8 /* ISRC1_DEC2_ENA */
1036#define WM5100_ISRC1_DEC2_ENA_WIDTH 1 /* ISRC1_DEC2_ENA */
1037#define WM5100_ISRC1_DEC3_ENA 0x0080 /* ISRC1_DEC3_ENA */
1038#define WM5100_ISRC1_DEC3_ENA_MASK 0x0080 /* ISRC1_DEC3_ENA */
1039#define WM5100_ISRC1_DEC3_ENA_SHIFT 7 /* ISRC1_DEC3_ENA */
1040#define WM5100_ISRC1_DEC3_ENA_WIDTH 1 /* ISRC1_DEC3_ENA */
1041#define WM5100_ISRC1_DEC4_ENA 0x0040 /* ISRC1_DEC4_ENA */
1042#define WM5100_ISRC1_DEC4_ENA_MASK 0x0040 /* ISRC1_DEC4_ENA */
1043#define WM5100_ISRC1_DEC4_ENA_SHIFT 6 /* ISRC1_DEC4_ENA */
1044#define WM5100_ISRC1_DEC4_ENA_WIDTH 1 /* ISRC1_DEC4_ENA */
1045#define WM5100_ISRC1_NOTCH_ENA 0x0001 /* ISRC1_NOTCH_ENA */
1046#define WM5100_ISRC1_NOTCH_ENA_MASK 0x0001 /* ISRC1_NOTCH_ENA */
1047#define WM5100_ISRC1_NOTCH_ENA_SHIFT 0 /* ISRC1_NOTCH_ENA */
1048#define WM5100_ISRC1_NOTCH_ENA_WIDTH 1 /* ISRC1_NOTCH_ENA */
1049
1050/*
1051 * R323 (0x143) - ISRC 2 CTRL1
1052 */
1053#define WM5100_ISRC2_DFS_ENA 0x2000 /* ISRC2_DFS_ENA */
1054#define WM5100_ISRC2_DFS_ENA_MASK 0x2000 /* ISRC2_DFS_ENA */
1055#define WM5100_ISRC2_DFS_ENA_SHIFT 13 /* ISRC2_DFS_ENA */
1056#define WM5100_ISRC2_DFS_ENA_WIDTH 1 /* ISRC2_DFS_ENA */
1057#define WM5100_ISRC2_CLK_SEL_MASK 0x0300 /* ISRC2_CLK_SEL - [9:8] */
1058#define WM5100_ISRC2_CLK_SEL_SHIFT 8 /* ISRC2_CLK_SEL - [9:8] */
1059#define WM5100_ISRC2_CLK_SEL_WIDTH 2 /* ISRC2_CLK_SEL - [9:8] */
1060#define WM5100_ISRC2_FSH_MASK 0x000C /* ISRC2_FSH - [3:2] */
1061#define WM5100_ISRC2_FSH_SHIFT 2 /* ISRC2_FSH - [3:2] */
1062#define WM5100_ISRC2_FSH_WIDTH 2 /* ISRC2_FSH - [3:2] */
1063#define WM5100_ISRC2_FSL_MASK 0x0003 /* ISRC2_FSL - [1:0] */
1064#define WM5100_ISRC2_FSL_SHIFT 0 /* ISRC2_FSL - [1:0] */
1065#define WM5100_ISRC2_FSL_WIDTH 2 /* ISRC2_FSL - [1:0] */
1066
1067/*
1068 * R324 (0x144) - ISRC 2 CTRL 2
1069 */
1070#define WM5100_ISRC2_INT1_ENA 0x8000 /* ISRC2_INT1_ENA */
1071#define WM5100_ISRC2_INT1_ENA_MASK 0x8000 /* ISRC2_INT1_ENA */
1072#define WM5100_ISRC2_INT1_ENA_SHIFT 15 /* ISRC2_INT1_ENA */
1073#define WM5100_ISRC2_INT1_ENA_WIDTH 1 /* ISRC2_INT1_ENA */
1074#define WM5100_ISRC2_INT2_ENA 0x4000 /* ISRC2_INT2_ENA */
1075#define WM5100_ISRC2_INT2_ENA_MASK 0x4000 /* ISRC2_INT2_ENA */
1076#define WM5100_ISRC2_INT2_ENA_SHIFT 14 /* ISRC2_INT2_ENA */
1077#define WM5100_ISRC2_INT2_ENA_WIDTH 1 /* ISRC2_INT2_ENA */
1078#define WM5100_ISRC2_INT3_ENA 0x2000 /* ISRC2_INT3_ENA */
1079#define WM5100_ISRC2_INT3_ENA_MASK 0x2000 /* ISRC2_INT3_ENA */
1080#define WM5100_ISRC2_INT3_ENA_SHIFT 13 /* ISRC2_INT3_ENA */
1081#define WM5100_ISRC2_INT3_ENA_WIDTH 1 /* ISRC2_INT3_ENA */
1082#define WM5100_ISRC2_INT4_ENA 0x1000 /* ISRC2_INT4_ENA */
1083#define WM5100_ISRC2_INT4_ENA_MASK 0x1000 /* ISRC2_INT4_ENA */
1084#define WM5100_ISRC2_INT4_ENA_SHIFT 12 /* ISRC2_INT4_ENA */
1085#define WM5100_ISRC2_INT4_ENA_WIDTH 1 /* ISRC2_INT4_ENA */
1086#define WM5100_ISRC2_DEC1_ENA 0x0200 /* ISRC2_DEC1_ENA */
1087#define WM5100_ISRC2_DEC1_ENA_MASK 0x0200 /* ISRC2_DEC1_ENA */
1088#define WM5100_ISRC2_DEC1_ENA_SHIFT 9 /* ISRC2_DEC1_ENA */
1089#define WM5100_ISRC2_DEC1_ENA_WIDTH 1 /* ISRC2_DEC1_ENA */
1090#define WM5100_ISRC2_DEC2_ENA 0x0100 /* ISRC2_DEC2_ENA */
1091#define WM5100_ISRC2_DEC2_ENA_MASK 0x0100 /* ISRC2_DEC2_ENA */
1092#define WM5100_ISRC2_DEC2_ENA_SHIFT 8 /* ISRC2_DEC2_ENA */
1093#define WM5100_ISRC2_DEC2_ENA_WIDTH 1 /* ISRC2_DEC2_ENA */
1094#define WM5100_ISRC2_DEC3_ENA 0x0080 /* ISRC2_DEC3_ENA */
1095#define WM5100_ISRC2_DEC3_ENA_MASK 0x0080 /* ISRC2_DEC3_ENA */
1096#define WM5100_ISRC2_DEC3_ENA_SHIFT 7 /* ISRC2_DEC3_ENA */
1097#define WM5100_ISRC2_DEC3_ENA_WIDTH 1 /* ISRC2_DEC3_ENA */
1098#define WM5100_ISRC2_DEC4_ENA 0x0040 /* ISRC2_DEC4_ENA */
1099#define WM5100_ISRC2_DEC4_ENA_MASK 0x0040 /* ISRC2_DEC4_ENA */
1100#define WM5100_ISRC2_DEC4_ENA_SHIFT 6 /* ISRC2_DEC4_ENA */
1101#define WM5100_ISRC2_DEC4_ENA_WIDTH 1 /* ISRC2_DEC4_ENA */
1102#define WM5100_ISRC2_NOTCH_ENA 0x0001 /* ISRC2_NOTCH_ENA */
1103#define WM5100_ISRC2_NOTCH_ENA_MASK 0x0001 /* ISRC2_NOTCH_ENA */
1104#define WM5100_ISRC2_NOTCH_ENA_SHIFT 0 /* ISRC2_NOTCH_ENA */
1105#define WM5100_ISRC2_NOTCH_ENA_WIDTH 1 /* ISRC2_NOTCH_ENA */
1106
1107/*
1108 * R386 (0x182) - FLL1 Control 1
1109 */
1110#define WM5100_FLL1_ENA 0x0001 /* FLL1_ENA */
1111#define WM5100_FLL1_ENA_MASK 0x0001 /* FLL1_ENA */
1112#define WM5100_FLL1_ENA_SHIFT 0 /* FLL1_ENA */
1113#define WM5100_FLL1_ENA_WIDTH 1 /* FLL1_ENA */
1114
1115/*
1116 * R387 (0x183) - FLL1 Control 2
1117 */
1118#define WM5100_FLL1_OUTDIV_MASK 0x3F00 /* FLL1_OUTDIV - [13:8] */
1119#define WM5100_FLL1_OUTDIV_SHIFT 8 /* FLL1_OUTDIV - [13:8] */
1120#define WM5100_FLL1_OUTDIV_WIDTH 6 /* FLL1_OUTDIV - [13:8] */
1121#define WM5100_FLL1_FRATIO_MASK 0x0007 /* FLL1_FRATIO - [2:0] */
1122#define WM5100_FLL1_FRATIO_SHIFT 0 /* FLL1_FRATIO - [2:0] */
1123#define WM5100_FLL1_FRATIO_WIDTH 3 /* FLL1_FRATIO - [2:0] */
1124
1125/*
1126 * R388 (0x184) - FLL1 Control 3
1127 */
1128#define WM5100_FLL1_THETA_MASK 0xFFFF /* FLL1_THETA - [15:0] */
1129#define WM5100_FLL1_THETA_SHIFT 0 /* FLL1_THETA - [15:0] */
1130#define WM5100_FLL1_THETA_WIDTH 16 /* FLL1_THETA - [15:0] */
1131
1132/*
1133 * R390 (0x186) - FLL1 Control 5
1134 */
1135#define WM5100_FLL1_N_MASK 0x03FF /* FLL1_N - [9:0] */
1136#define WM5100_FLL1_N_SHIFT 0 /* FLL1_N - [9:0] */
1137#define WM5100_FLL1_N_WIDTH 10 /* FLL1_N - [9:0] */
1138
1139/*
1140 * R391 (0x187) - FLL1 Control 6
1141 */
1142#define WM5100_FLL1_REFCLK_DIV_MASK 0x00C0 /* FLL1_REFCLK_DIV - [7:6] */
1143#define WM5100_FLL1_REFCLK_DIV_SHIFT 6 /* FLL1_REFCLK_DIV - [7:6] */
1144#define WM5100_FLL1_REFCLK_DIV_WIDTH 2 /* FLL1_REFCLK_DIV - [7:6] */
1145#define WM5100_FLL1_REFCLK_SRC_MASK 0x000F /* FLL1_REFCLK_SRC - [3:0] */
1146#define WM5100_FLL1_REFCLK_SRC_SHIFT 0 /* FLL1_REFCLK_SRC - [3:0] */
1147#define WM5100_FLL1_REFCLK_SRC_WIDTH 4 /* FLL1_REFCLK_SRC - [3:0] */
1148
1149/*
1150 * R392 (0x188) - FLL1 EFS 1
1151 */
1152#define WM5100_FLL1_LAMBDA_MASK 0xFFFF /* FLL1_LAMBDA - [15:0] */
1153#define WM5100_FLL1_LAMBDA_SHIFT 0 /* FLL1_LAMBDA - [15:0] */
1154#define WM5100_FLL1_LAMBDA_WIDTH 16 /* FLL1_LAMBDA - [15:0] */
1155
1156/*
1157 * R418 (0x1A2) - FLL2 Control 1
1158 */
1159#define WM5100_FLL2_ENA 0x0001 /* FLL2_ENA */
1160#define WM5100_FLL2_ENA_MASK 0x0001 /* FLL2_ENA */
1161#define WM5100_FLL2_ENA_SHIFT 0 /* FLL2_ENA */
1162#define WM5100_FLL2_ENA_WIDTH 1 /* FLL2_ENA */
1163
1164/*
1165 * R419 (0x1A3) - FLL2 Control 2
1166 */
1167#define WM5100_FLL2_OUTDIV_MASK 0x3F00 /* FLL2_OUTDIV - [13:8] */
1168#define WM5100_FLL2_OUTDIV_SHIFT 8 /* FLL2_OUTDIV - [13:8] */
1169#define WM5100_FLL2_OUTDIV_WIDTH 6 /* FLL2_OUTDIV - [13:8] */
1170#define WM5100_FLL2_FRATIO_MASK 0x0007 /* FLL2_FRATIO - [2:0] */
1171#define WM5100_FLL2_FRATIO_SHIFT 0 /* FLL2_FRATIO - [2:0] */
1172#define WM5100_FLL2_FRATIO_WIDTH 3 /* FLL2_FRATIO - [2:0] */
1173
1174/*
1175 * R420 (0x1A4) - FLL2 Control 3
1176 */
1177#define WM5100_FLL2_THETA_MASK 0xFFFF /* FLL2_THETA - [15:0] */
1178#define WM5100_FLL2_THETA_SHIFT 0 /* FLL2_THETA - [15:0] */
1179#define WM5100_FLL2_THETA_WIDTH 16 /* FLL2_THETA - [15:0] */
1180
1181/*
1182 * R422 (0x1A6) - FLL2 Control 5
1183 */
1184#define WM5100_FLL2_N_MASK 0x03FF /* FLL2_N - [9:0] */
1185#define WM5100_FLL2_N_SHIFT 0 /* FLL2_N - [9:0] */
1186#define WM5100_FLL2_N_WIDTH 10 /* FLL2_N - [9:0] */
1187
1188/*
1189 * R423 (0x1A7) - FLL2 Control 6
1190 */
1191#define WM5100_FLL2_REFCLK_DIV_MASK 0x00C0 /* FLL2_REFCLK_DIV - [7:6] */
1192#define WM5100_FLL2_REFCLK_DIV_SHIFT 6 /* FLL2_REFCLK_DIV - [7:6] */
1193#define WM5100_FLL2_REFCLK_DIV_WIDTH 2 /* FLL2_REFCLK_DIV - [7:6] */
1194#define WM5100_FLL2_REFCLK_SRC_MASK 0x000F /* FLL2_REFCLK_SRC - [3:0] */
1195#define WM5100_FLL2_REFCLK_SRC_SHIFT 0 /* FLL2_REFCLK_SRC - [3:0] */
1196#define WM5100_FLL2_REFCLK_SRC_WIDTH 4 /* FLL2_REFCLK_SRC - [3:0] */
1197
1198/*
1199 * R424 (0x1A8) - FLL2 EFS 1
1200 */
1201#define WM5100_FLL2_LAMBDA_MASK 0xFFFF /* FLL2_LAMBDA - [15:0] */
1202#define WM5100_FLL2_LAMBDA_SHIFT 0 /* FLL2_LAMBDA - [15:0] */
1203#define WM5100_FLL2_LAMBDA_WIDTH 16 /* FLL2_LAMBDA - [15:0] */
1204
1205/*
1206 * R512 (0x200) - Mic Charge Pump 1
1207 */
1208#define WM5100_CP2_BYPASS 0x0020 /* CP2_BYPASS */
1209#define WM5100_CP2_BYPASS_MASK 0x0020 /* CP2_BYPASS */
1210#define WM5100_CP2_BYPASS_SHIFT 5 /* CP2_BYPASS */
1211#define WM5100_CP2_BYPASS_WIDTH 1 /* CP2_BYPASS */
1212#define WM5100_CP2_ENA 0x0001 /* CP2_ENA */
1213#define WM5100_CP2_ENA_MASK 0x0001 /* CP2_ENA */
1214#define WM5100_CP2_ENA_SHIFT 0 /* CP2_ENA */
1215#define WM5100_CP2_ENA_WIDTH 1 /* CP2_ENA */
1216
1217/*
1218 * R513 (0x201) - Mic Charge Pump 2
1219 */
1220#define WM5100_LDO2_VSEL_MASK 0xF800 /* LDO2_VSEL - [15:11] */
1221#define WM5100_LDO2_VSEL_SHIFT 11 /* LDO2_VSEL - [15:11] */
1222#define WM5100_LDO2_VSEL_WIDTH 5 /* LDO2_VSEL - [15:11] */
1223
1224/*
1225 * R514 (0x202) - HP Charge Pump 1
1226 */
1227#define WM5100_CP1_ENA 0x0001 /* CP1_ENA */
1228#define WM5100_CP1_ENA_MASK 0x0001 /* CP1_ENA */
1229#define WM5100_CP1_ENA_SHIFT 0 /* CP1_ENA */
1230#define WM5100_CP1_ENA_WIDTH 1 /* CP1_ENA */
1231
1232/*
1233 * R529 (0x211) - LDO1 Control
1234 */
1235#define WM5100_LDO1_BYPASS 0x0002 /* LDO1_BYPASS */
1236#define WM5100_LDO1_BYPASS_MASK 0x0002 /* LDO1_BYPASS */
1237#define WM5100_LDO1_BYPASS_SHIFT 1 /* LDO1_BYPASS */
1238#define WM5100_LDO1_BYPASS_WIDTH 1 /* LDO1_BYPASS */
1239
1240/*
1241 * R533 (0x215) - Mic Bias Ctrl 1
1242 */
1243#define WM5100_MICB1_DISCH 0x0040 /* MICB1_DISCH */
1244#define WM5100_MICB1_DISCH_MASK 0x0040 /* MICB1_DISCH */
1245#define WM5100_MICB1_DISCH_SHIFT 6 /* MICB1_DISCH */
1246#define WM5100_MICB1_DISCH_WIDTH 1 /* MICB1_DISCH */
1247#define WM5100_MICB1_RATE 0x0020 /* MICB1_RATE */
1248#define WM5100_MICB1_RATE_MASK 0x0020 /* MICB1_RATE */
1249#define WM5100_MICB1_RATE_SHIFT 5 /* MICB1_RATE */
1250#define WM5100_MICB1_RATE_WIDTH 1 /* MICB1_RATE */
1251#define WM5100_MICB1_LVL_MASK 0x001C /* MICB1_LVL - [4:2] */
1252#define WM5100_MICB1_LVL_SHIFT 2 /* MICB1_LVL - [4:2] */
1253#define WM5100_MICB1_LVL_WIDTH 3 /* MICB1_LVL - [4:2] */
1254#define WM5100_MICB1_BYPASS 0x0002 /* MICB1_BYPASS */
1255#define WM5100_MICB1_BYPASS_MASK 0x0002 /* MICB1_BYPASS */
1256#define WM5100_MICB1_BYPASS_SHIFT 1 /* MICB1_BYPASS */
1257#define WM5100_MICB1_BYPASS_WIDTH 1 /* MICB1_BYPASS */
1258#define WM5100_MICB1_ENA 0x0001 /* MICB1_ENA */
1259#define WM5100_MICB1_ENA_MASK 0x0001 /* MICB1_ENA */
1260#define WM5100_MICB1_ENA_SHIFT 0 /* MICB1_ENA */
1261#define WM5100_MICB1_ENA_WIDTH 1 /* MICB1_ENA */
1262
1263/*
1264 * R534 (0x216) - Mic Bias Ctrl 2
1265 */
1266#define WM5100_MICB2_DISCH 0x0040 /* MICB2_DISCH */
1267#define WM5100_MICB2_DISCH_MASK 0x0040 /* MICB2_DISCH */
1268#define WM5100_MICB2_DISCH_SHIFT 6 /* MICB2_DISCH */
1269#define WM5100_MICB2_DISCH_WIDTH 1 /* MICB2_DISCH */
1270#define WM5100_MICB2_RATE 0x0020 /* MICB2_RATE */
1271#define WM5100_MICB2_RATE_MASK 0x0020 /* MICB2_RATE */
1272#define WM5100_MICB2_RATE_SHIFT 5 /* MICB2_RATE */
1273#define WM5100_MICB2_RATE_WIDTH 1 /* MICB2_RATE */
1274#define WM5100_MICB2_LVL_MASK 0x001C /* MICB2_LVL - [4:2] */
1275#define WM5100_MICB2_LVL_SHIFT 2 /* MICB2_LVL - [4:2] */
1276#define WM5100_MICB2_LVL_WIDTH 3 /* MICB2_LVL - [4:2] */
1277#define WM5100_MICB2_BYPASS 0x0002 /* MICB2_BYPASS */
1278#define WM5100_MICB2_BYPASS_MASK 0x0002 /* MICB2_BYPASS */
1279#define WM5100_MICB2_BYPASS_SHIFT 1 /* MICB2_BYPASS */
1280#define WM5100_MICB2_BYPASS_WIDTH 1 /* MICB2_BYPASS */
1281#define WM5100_MICB2_ENA 0x0001 /* MICB2_ENA */
1282#define WM5100_MICB2_ENA_MASK 0x0001 /* MICB2_ENA */
1283#define WM5100_MICB2_ENA_SHIFT 0 /* MICB2_ENA */
1284#define WM5100_MICB2_ENA_WIDTH 1 /* MICB2_ENA */
1285
1286/*
1287 * R535 (0x217) - Mic Bias Ctrl 3
1288 */
1289#define WM5100_MICB3_DISCH 0x0040 /* MICB3_DISCH */
1290#define WM5100_MICB3_DISCH_MASK 0x0040 /* MICB3_DISCH */
1291#define WM5100_MICB3_DISCH_SHIFT 6 /* MICB3_DISCH */
1292#define WM5100_MICB3_DISCH_WIDTH 1 /* MICB3_DISCH */
1293#define WM5100_MICB3_RATE 0x0020 /* MICB3_RATE */
1294#define WM5100_MICB3_RATE_MASK 0x0020 /* MICB3_RATE */
1295#define WM5100_MICB3_RATE_SHIFT 5 /* MICB3_RATE */
1296#define WM5100_MICB3_RATE_WIDTH 1 /* MICB3_RATE */
1297#define WM5100_MICB3_LVL_MASK 0x001C /* MICB3_LVL - [4:2] */
1298#define WM5100_MICB3_LVL_SHIFT 2 /* MICB3_LVL - [4:2] */
1299#define WM5100_MICB3_LVL_WIDTH 3 /* MICB3_LVL - [4:2] */
1300#define WM5100_MICB3_BYPASS 0x0002 /* MICB3_BYPASS */
1301#define WM5100_MICB3_BYPASS_MASK 0x0002 /* MICB3_BYPASS */
1302#define WM5100_MICB3_BYPASS_SHIFT 1 /* MICB3_BYPASS */
1303#define WM5100_MICB3_BYPASS_WIDTH 1 /* MICB3_BYPASS */
1304#define WM5100_MICB3_ENA 0x0001 /* MICB3_ENA */
1305#define WM5100_MICB3_ENA_MASK 0x0001 /* MICB3_ENA */
1306#define WM5100_MICB3_ENA_SHIFT 0 /* MICB3_ENA */
1307#define WM5100_MICB3_ENA_WIDTH 1 /* MICB3_ENA */
1308
1309/*
1310 * R640 (0x280) - Accessory Detect Mode 1
1311 */
1312#define WM5100_ACCDET_BIAS_SRC_MASK 0xC000 /* ACCDET_BIAS_SRC - [15:14] */
1313#define WM5100_ACCDET_BIAS_SRC_SHIFT 14 /* ACCDET_BIAS_SRC - [15:14] */
1314#define WM5100_ACCDET_BIAS_SRC_WIDTH 2 /* ACCDET_BIAS_SRC - [15:14] */
1315#define WM5100_ACCDET_SRC 0x2000 /* ACCDET_SRC */
1316#define WM5100_ACCDET_SRC_MASK 0x2000 /* ACCDET_SRC */
1317#define WM5100_ACCDET_SRC_SHIFT 13 /* ACCDET_SRC */
1318#define WM5100_ACCDET_SRC_WIDTH 1 /* ACCDET_SRC */
1319#define WM5100_ACCDET_MODE_MASK 0x0003 /* ACCDET_MODE - [1:0] */
1320#define WM5100_ACCDET_MODE_SHIFT 0 /* ACCDET_MODE - [1:0] */
1321#define WM5100_ACCDET_MODE_WIDTH 2 /* ACCDET_MODE - [1:0] */
1322
1323/*
1324 * R648 (0x288) - Headphone Detect 1
1325 */
1326#define WM5100_HP_HOLDTIME_MASK 0x00E0 /* HP_HOLDTIME - [7:5] */
1327#define WM5100_HP_HOLDTIME_SHIFT 5 /* HP_HOLDTIME - [7:5] */
1328#define WM5100_HP_HOLDTIME_WIDTH 3 /* HP_HOLDTIME - [7:5] */
1329#define WM5100_HP_CLK_DIV_MASK 0x0018 /* HP_CLK_DIV - [4:3] */
1330#define WM5100_HP_CLK_DIV_SHIFT 3 /* HP_CLK_DIV - [4:3] */
1331#define WM5100_HP_CLK_DIV_WIDTH 2 /* HP_CLK_DIV - [4:3] */
1332#define WM5100_HP_STEP_SIZE 0x0002 /* HP_STEP_SIZE */
1333#define WM5100_HP_STEP_SIZE_MASK 0x0002 /* HP_STEP_SIZE */
1334#define WM5100_HP_STEP_SIZE_SHIFT 1 /* HP_STEP_SIZE */
1335#define WM5100_HP_STEP_SIZE_WIDTH 1 /* HP_STEP_SIZE */
1336#define WM5100_HP_POLL 0x0001 /* HP_POLL */
1337#define WM5100_HP_POLL_MASK 0x0001 /* HP_POLL */
1338#define WM5100_HP_POLL_SHIFT 0 /* HP_POLL */
1339#define WM5100_HP_POLL_WIDTH 1 /* HP_POLL */
1340
1341/*
1342 * R649 (0x289) - Headphone Detect 2
1343 */
1344#define WM5100_HP_DONE 0x0080 /* HP_DONE */
1345#define WM5100_HP_DONE_MASK 0x0080 /* HP_DONE */
1346#define WM5100_HP_DONE_SHIFT 7 /* HP_DONE */
1347#define WM5100_HP_DONE_WIDTH 1 /* HP_DONE */
1348#define WM5100_HP_LVL_MASK 0x007F /* HP_LVL - [6:0] */
1349#define WM5100_HP_LVL_SHIFT 0 /* HP_LVL - [6:0] */
1350#define WM5100_HP_LVL_WIDTH 7 /* HP_LVL - [6:0] */
1351
1352/*
1353 * R656 (0x290) - Mic Detect 1
1354 */
1355#define WM5100_ACCDET_BIAS_STARTTIME_MASK 0xF000 /* ACCDET_BIAS_STARTTIME - [15:12] */
1356#define WM5100_ACCDET_BIAS_STARTTIME_SHIFT 12 /* ACCDET_BIAS_STARTTIME - [15:12] */
1357#define WM5100_ACCDET_BIAS_STARTTIME_WIDTH 4 /* ACCDET_BIAS_STARTTIME - [15:12] */
1358#define WM5100_ACCDET_RATE_MASK 0x0F00 /* ACCDET_RATE - [11:8] */
1359#define WM5100_ACCDET_RATE_SHIFT 8 /* ACCDET_RATE - [11:8] */
1360#define WM5100_ACCDET_RATE_WIDTH 4 /* ACCDET_RATE - [11:8] */
1361#define WM5100_ACCDET_DBTIME 0x0002 /* ACCDET_DBTIME */
1362#define WM5100_ACCDET_DBTIME_MASK 0x0002 /* ACCDET_DBTIME */
1363#define WM5100_ACCDET_DBTIME_SHIFT 1 /* ACCDET_DBTIME */
1364#define WM5100_ACCDET_DBTIME_WIDTH 1 /* ACCDET_DBTIME */
1365#define WM5100_ACCDET_ENA 0x0001 /* ACCDET_ENA */
1366#define WM5100_ACCDET_ENA_MASK 0x0001 /* ACCDET_ENA */
1367#define WM5100_ACCDET_ENA_SHIFT 0 /* ACCDET_ENA */
1368#define WM5100_ACCDET_ENA_WIDTH 1 /* ACCDET_ENA */
1369
1370/*
1371 * R657 (0x291) - Mic Detect 2
1372 */
1373#define WM5100_ACCDET_LVL_SEL_MASK 0x00FF /* ACCDET_LVL_SEL - [7:0] */
1374#define WM5100_ACCDET_LVL_SEL_SHIFT 0 /* ACCDET_LVL_SEL - [7:0] */
1375#define WM5100_ACCDET_LVL_SEL_WIDTH 8 /* ACCDET_LVL_SEL - [7:0] */
1376
1377/*
1378 * R658 (0x292) - Mic Detect 3
1379 */
1380#define WM5100_ACCDET_LVL_MASK 0x07FC /* ACCDET_LVL - [10:2] */
1381#define WM5100_ACCDET_LVL_SHIFT 2 /* ACCDET_LVL - [10:2] */
1382#define WM5100_ACCDET_LVL_WIDTH 9 /* ACCDET_LVL - [10:2] */
1383#define WM5100_ACCDET_VALID 0x0002 /* ACCDET_VALID */
1384#define WM5100_ACCDET_VALID_MASK 0x0002 /* ACCDET_VALID */
1385#define WM5100_ACCDET_VALID_SHIFT 1 /* ACCDET_VALID */
1386#define WM5100_ACCDET_VALID_WIDTH 1 /* ACCDET_VALID */
1387#define WM5100_ACCDET_STS 0x0001 /* ACCDET_STS */
1388#define WM5100_ACCDET_STS_MASK 0x0001 /* ACCDET_STS */
1389#define WM5100_ACCDET_STS_SHIFT 0 /* ACCDET_STS */
1390#define WM5100_ACCDET_STS_WIDTH 1 /* ACCDET_STS */
1391
1392/*
1393 * R699 (0x2BB) - Misc Control
1394 */
1395#define WM5100_HPCOM_SRC 0x200 /* HPCOM_SRC */
1396#define WM5100_HPCOM_SRC_SHIFT 9 /* HPCOM_SRC */
1397
1398/*
1399 * R769 (0x301) - Input Enables
1400 */
1401#define WM5100_IN4L_ENA 0x0080 /* IN4L_ENA */
1402#define WM5100_IN4L_ENA_MASK 0x0080 /* IN4L_ENA */
1403#define WM5100_IN4L_ENA_SHIFT 7 /* IN4L_ENA */
1404#define WM5100_IN4L_ENA_WIDTH 1 /* IN4L_ENA */
1405#define WM5100_IN4R_ENA 0x0040 /* IN4R_ENA */
1406#define WM5100_IN4R_ENA_MASK 0x0040 /* IN4R_ENA */
1407#define WM5100_IN4R_ENA_SHIFT 6 /* IN4R_ENA */
1408#define WM5100_IN4R_ENA_WIDTH 1 /* IN4R_ENA */
1409#define WM5100_IN3L_ENA 0x0020 /* IN3L_ENA */
1410#define WM5100_IN3L_ENA_MASK 0x0020 /* IN3L_ENA */
1411#define WM5100_IN3L_ENA_SHIFT 5 /* IN3L_ENA */
1412#define WM5100_IN3L_ENA_WIDTH 1 /* IN3L_ENA */
1413#define WM5100_IN3R_ENA 0x0010 /* IN3R_ENA */
1414#define WM5100_IN3R_ENA_MASK 0x0010 /* IN3R_ENA */
1415#define WM5100_IN3R_ENA_SHIFT 4 /* IN3R_ENA */
1416#define WM5100_IN3R_ENA_WIDTH 1 /* IN3R_ENA */
1417#define WM5100_IN2L_ENA 0x0008 /* IN2L_ENA */
1418#define WM5100_IN2L_ENA_MASK 0x0008 /* IN2L_ENA */
1419#define WM5100_IN2L_ENA_SHIFT 3 /* IN2L_ENA */
1420#define WM5100_IN2L_ENA_WIDTH 1 /* IN2L_ENA */
1421#define WM5100_IN2R_ENA 0x0004 /* IN2R_ENA */
1422#define WM5100_IN2R_ENA_MASK 0x0004 /* IN2R_ENA */
1423#define WM5100_IN2R_ENA_SHIFT 2 /* IN2R_ENA */
1424#define WM5100_IN2R_ENA_WIDTH 1 /* IN2R_ENA */
1425#define WM5100_IN1L_ENA 0x0002 /* IN1L_ENA */
1426#define WM5100_IN1L_ENA_MASK 0x0002 /* IN1L_ENA */
1427#define WM5100_IN1L_ENA_SHIFT 1 /* IN1L_ENA */
1428#define WM5100_IN1L_ENA_WIDTH 1 /* IN1L_ENA */
1429#define WM5100_IN1R_ENA 0x0001 /* IN1R_ENA */
1430#define WM5100_IN1R_ENA_MASK 0x0001 /* IN1R_ENA */
1431#define WM5100_IN1R_ENA_SHIFT 0 /* IN1R_ENA */
1432#define WM5100_IN1R_ENA_WIDTH 1 /* IN1R_ENA */
1433
1434/*
1435 * R770 (0x302) - Input Enables Status
1436 */
1437#define WM5100_IN4L_ENA_STS 0x0080 /* IN4L_ENA_STS */
1438#define WM5100_IN4L_ENA_STS_MASK 0x0080 /* IN4L_ENA_STS */
1439#define WM5100_IN4L_ENA_STS_SHIFT 7 /* IN4L_ENA_STS */
1440#define WM5100_IN4L_ENA_STS_WIDTH 1 /* IN4L_ENA_STS */
1441#define WM5100_IN4R_ENA_STS 0x0040 /* IN4R_ENA_STS */
1442#define WM5100_IN4R_ENA_STS_MASK 0x0040 /* IN4R_ENA_STS */
1443#define WM5100_IN4R_ENA_STS_SHIFT 6 /* IN4R_ENA_STS */
1444#define WM5100_IN4R_ENA_STS_WIDTH 1 /* IN4R_ENA_STS */
1445#define WM5100_IN3L_ENA_STS 0x0020 /* IN3L_ENA_STS */
1446#define WM5100_IN3L_ENA_STS_MASK 0x0020 /* IN3L_ENA_STS */
1447#define WM5100_IN3L_ENA_STS_SHIFT 5 /* IN3L_ENA_STS */
1448#define WM5100_IN3L_ENA_STS_WIDTH 1 /* IN3L_ENA_STS */
1449#define WM5100_IN3R_ENA_STS 0x0010 /* IN3R_ENA_STS */
1450#define WM5100_IN3R_ENA_STS_MASK 0x0010 /* IN3R_ENA_STS */
1451#define WM5100_IN3R_ENA_STS_SHIFT 4 /* IN3R_ENA_STS */
1452#define WM5100_IN3R_ENA_STS_WIDTH 1 /* IN3R_ENA_STS */
1453#define WM5100_IN2L_ENA_STS 0x0008 /* IN2L_ENA_STS */
1454#define WM5100_IN2L_ENA_STS_MASK 0x0008 /* IN2L_ENA_STS */
1455#define WM5100_IN2L_ENA_STS_SHIFT 3 /* IN2L_ENA_STS */
1456#define WM5100_IN2L_ENA_STS_WIDTH 1 /* IN2L_ENA_STS */
1457#define WM5100_IN2R_ENA_STS 0x0004 /* IN2R_ENA_STS */
1458#define WM5100_IN2R_ENA_STS_MASK 0x0004 /* IN2R_ENA_STS */
1459#define WM5100_IN2R_ENA_STS_SHIFT 2 /* IN2R_ENA_STS */
1460#define WM5100_IN2R_ENA_STS_WIDTH 1 /* IN2R_ENA_STS */
1461#define WM5100_IN1L_ENA_STS 0x0002 /* IN1L_ENA_STS */
1462#define WM5100_IN1L_ENA_STS_MASK 0x0002 /* IN1L_ENA_STS */
1463#define WM5100_IN1L_ENA_STS_SHIFT 1 /* IN1L_ENA_STS */
1464#define WM5100_IN1L_ENA_STS_WIDTH 1 /* IN1L_ENA_STS */
1465#define WM5100_IN1R_ENA_STS 0x0001 /* IN1R_ENA_STS */
1466#define WM5100_IN1R_ENA_STS_MASK 0x0001 /* IN1R_ENA_STS */
1467#define WM5100_IN1R_ENA_STS_SHIFT 0 /* IN1R_ENA_STS */
1468#define WM5100_IN1R_ENA_STS_WIDTH 1 /* IN1R_ENA_STS */
1469
1470/*
1471 * R784 (0x310) - IN1L Control
1472 */
1473#define WM5100_IN_RATE_MASK 0xC000 /* IN_RATE - [15:14] */
1474#define WM5100_IN_RATE_SHIFT 14 /* IN_RATE - [15:14] */
1475#define WM5100_IN_RATE_WIDTH 2 /* IN_RATE - [15:14] */
1476#define WM5100_IN1_OSR 0x2000 /* IN1_OSR */
1477#define WM5100_IN1_OSR_MASK 0x2000 /* IN1_OSR */
1478#define WM5100_IN1_OSR_SHIFT 13 /* IN1_OSR */
1479#define WM5100_IN1_OSR_WIDTH 1 /* IN1_OSR */
1480#define WM5100_IN1_DMIC_SUP_MASK 0x1800 /* IN1_DMIC_SUP - [12:11] */
1481#define WM5100_IN1_DMIC_SUP_SHIFT 11 /* IN1_DMIC_SUP - [12:11] */
1482#define WM5100_IN1_DMIC_SUP_WIDTH 2 /* IN1_DMIC_SUP - [12:11] */
1483#define WM5100_IN1_MODE_MASK 0x0600 /* IN1_MODE - [10:9] */
1484#define WM5100_IN1_MODE_SHIFT 9 /* IN1_MODE - [10:9] */
1485#define WM5100_IN1_MODE_WIDTH 2 /* IN1_MODE - [10:9] */
1486#define WM5100_IN1L_PGA_VOL_MASK 0x00FE /* IN1L_PGA_VOL - [7:1] */
1487#define WM5100_IN1L_PGA_VOL_SHIFT 1 /* IN1L_PGA_VOL - [7:1] */
1488#define WM5100_IN1L_PGA_VOL_WIDTH 7 /* IN1L_PGA_VOL - [7:1] */
1489
1490/*
1491 * R785 (0x311) - IN1R Control
1492 */
1493#define WM5100_IN1R_PGA_VOL_MASK 0x00FE /* IN1R_PGA_VOL - [7:1] */
1494#define WM5100_IN1R_PGA_VOL_SHIFT 1 /* IN1R_PGA_VOL - [7:1] */
1495#define WM5100_IN1R_PGA_VOL_WIDTH 7 /* IN1R_PGA_VOL - [7:1] */
1496
1497/*
1498 * R786 (0x312) - IN2L Control
1499 */
1500#define WM5100_IN2_OSR 0x2000 /* IN2_OSR */
1501#define WM5100_IN2_OSR_MASK 0x2000 /* IN2_OSR */
1502#define WM5100_IN2_OSR_SHIFT 13 /* IN2_OSR */
1503#define WM5100_IN2_OSR_WIDTH 1 /* IN2_OSR */
1504#define WM5100_IN2_DMIC_SUP_MASK 0x1800 /* IN2_DMIC_SUP - [12:11] */
1505#define WM5100_IN2_DMIC_SUP_SHIFT 11 /* IN2_DMIC_SUP - [12:11] */
1506#define WM5100_IN2_DMIC_SUP_WIDTH 2 /* IN2_DMIC_SUP - [12:11] */
1507#define WM5100_IN2_MODE_MASK 0x0600 /* IN2_MODE - [10:9] */
1508#define WM5100_IN2_MODE_SHIFT 9 /* IN2_MODE - [10:9] */
1509#define WM5100_IN2_MODE_WIDTH 2 /* IN2_MODE - [10:9] */
1510#define WM5100_IN2L_PGA_VOL_MASK 0x00FE /* IN2L_PGA_VOL - [7:1] */
1511#define WM5100_IN2L_PGA_VOL_SHIFT 1 /* IN2L_PGA_VOL - [7:1] */
1512#define WM5100_IN2L_PGA_VOL_WIDTH 7 /* IN2L_PGA_VOL - [7:1] */
1513
1514/*
1515 * R787 (0x313) - IN2R Control
1516 */
1517#define WM5100_IN2R_PGA_VOL_MASK 0x00FE /* IN2R_PGA_VOL - [7:1] */
1518#define WM5100_IN2R_PGA_VOL_SHIFT 1 /* IN2R_PGA_VOL - [7:1] */
1519#define WM5100_IN2R_PGA_VOL_WIDTH 7 /* IN2R_PGA_VOL - [7:1] */
1520
1521/*
1522 * R788 (0x314) - IN3L Control
1523 */
1524#define WM5100_IN3_OSR 0x2000 /* IN3_OSR */
1525#define WM5100_IN3_OSR_MASK 0x2000 /* IN3_OSR */
1526#define WM5100_IN3_OSR_SHIFT 13 /* IN3_OSR */
1527#define WM5100_IN3_OSR_WIDTH 1 /* IN3_OSR */
1528#define WM5100_IN3_DMIC_SUP_MASK 0x1800 /* IN3_DMIC_SUP - [12:11] */
1529#define WM5100_IN3_DMIC_SUP_SHIFT 11 /* IN3_DMIC_SUP - [12:11] */
1530#define WM5100_IN3_DMIC_SUP_WIDTH 2 /* IN3_DMIC_SUP - [12:11] */
1531#define WM5100_IN3_MODE_MASK 0x0600 /* IN3_MODE - [10:9] */
1532#define WM5100_IN3_MODE_SHIFT 9 /* IN3_MODE - [10:9] */
1533#define WM5100_IN3_MODE_WIDTH 2 /* IN3_MODE - [10:9] */
1534#define WM5100_IN3L_PGA_VOL_MASK 0x00FE /* IN3L_PGA_VOL - [7:1] */
1535#define WM5100_IN3L_PGA_VOL_SHIFT 1 /* IN3L_PGA_VOL - [7:1] */
1536#define WM5100_IN3L_PGA_VOL_WIDTH 7 /* IN3L_PGA_VOL - [7:1] */
1537
1538/*
1539 * R789 (0x315) - IN3R Control
1540 */
1541#define WM5100_IN3R_PGA_VOL_MASK 0x00FE /* IN3R_PGA_VOL - [7:1] */
1542#define WM5100_IN3R_PGA_VOL_SHIFT 1 /* IN3R_PGA_VOL - [7:1] */
1543#define WM5100_IN3R_PGA_VOL_WIDTH 7 /* IN3R_PGA_VOL - [7:1] */
1544
1545/*
1546 * R790 (0x316) - IN4L Control
1547 */
1548#define WM5100_IN4_OSR 0x2000 /* IN4_OSR */
1549#define WM5100_IN4_OSR_MASK 0x2000 /* IN4_OSR */
1550#define WM5100_IN4_OSR_SHIFT 13 /* IN4_OSR */
1551#define WM5100_IN4_OSR_WIDTH 1 /* IN4_OSR */
1552#define WM5100_IN4_DMIC_SUP_MASK 0x1800 /* IN4_DMIC_SUP - [12:11] */
1553#define WM5100_IN4_DMIC_SUP_SHIFT 11 /* IN4_DMIC_SUP - [12:11] */
1554#define WM5100_IN4_DMIC_SUP_WIDTH 2 /* IN4_DMIC_SUP - [12:11] */
1555#define WM5100_IN4_MODE_MASK 0x0600 /* IN4_MODE - [10:9] */
1556#define WM5100_IN4_MODE_SHIFT 9 /* IN4_MODE - [10:9] */
1557#define WM5100_IN4_MODE_WIDTH 2 /* IN4_MODE - [10:9] */
1558#define WM5100_IN4L_PGA_VOL_MASK 0x00FE /* IN4L_PGA_VOL - [7:1] */
1559#define WM5100_IN4L_PGA_VOL_SHIFT 1 /* IN4L_PGA_VOL - [7:1] */
1560#define WM5100_IN4L_PGA_VOL_WIDTH 7 /* IN4L_PGA_VOL - [7:1] */
1561
1562/*
1563 * R791 (0x317) - IN4R Control
1564 */
1565#define WM5100_IN4R_PGA_VOL_MASK 0x00FE /* IN4R_PGA_VOL - [7:1] */
1566#define WM5100_IN4R_PGA_VOL_SHIFT 1 /* IN4R_PGA_VOL - [7:1] */
1567#define WM5100_IN4R_PGA_VOL_WIDTH 7 /* IN4R_PGA_VOL - [7:1] */
1568
1569/*
1570 * R792 (0x318) - RXANC_SRC
1571 */
1572#define WM5100_IN_RXANC_SEL_MASK 0x0007 /* IN_RXANC_SEL - [2:0] */
1573#define WM5100_IN_RXANC_SEL_SHIFT 0 /* IN_RXANC_SEL - [2:0] */
1574#define WM5100_IN_RXANC_SEL_WIDTH 3 /* IN_RXANC_SEL - [2:0] */
1575
1576/*
1577 * R793 (0x319) - Input Volume Ramp
1578 */
1579#define WM5100_IN_VD_RAMP_MASK 0x0070 /* IN_VD_RAMP - [6:4] */
1580#define WM5100_IN_VD_RAMP_SHIFT 4 /* IN_VD_RAMP - [6:4] */
1581#define WM5100_IN_VD_RAMP_WIDTH 3 /* IN_VD_RAMP - [6:4] */
1582#define WM5100_IN_VI_RAMP_MASK 0x0007 /* IN_VI_RAMP - [2:0] */
1583#define WM5100_IN_VI_RAMP_SHIFT 0 /* IN_VI_RAMP - [2:0] */
1584#define WM5100_IN_VI_RAMP_WIDTH 3 /* IN_VI_RAMP - [2:0] */
1585
1586/*
1587 * R800 (0x320) - ADC Digital Volume 1L
1588 */
1589#define WM5100_IN_VU 0x0200 /* IN_VU */
1590#define WM5100_IN_VU_MASK 0x0200 /* IN_VU */
1591#define WM5100_IN_VU_SHIFT 9 /* IN_VU */
1592#define WM5100_IN_VU_WIDTH 1 /* IN_VU */
1593#define WM5100_IN1L_MUTE 0x0100 /* IN1L_MUTE */
1594#define WM5100_IN1L_MUTE_MASK 0x0100 /* IN1L_MUTE */
1595#define WM5100_IN1L_MUTE_SHIFT 8 /* IN1L_MUTE */
1596#define WM5100_IN1L_MUTE_WIDTH 1 /* IN1L_MUTE */
1597#define WM5100_IN1L_VOL_MASK 0x00FF /* IN1L_VOL - [7:0] */
1598#define WM5100_IN1L_VOL_SHIFT 0 /* IN1L_VOL - [7:0] */
1599#define WM5100_IN1L_VOL_WIDTH 8 /* IN1L_VOL - [7:0] */
1600
1601/*
1602 * R801 (0x321) - ADC Digital Volume 1R
1603 */
1604#define WM5100_IN_VU 0x0200 /* IN_VU */
1605#define WM5100_IN_VU_MASK 0x0200 /* IN_VU */
1606#define WM5100_IN_VU_SHIFT 9 /* IN_VU */
1607#define WM5100_IN_VU_WIDTH 1 /* IN_VU */
1608#define WM5100_IN1R_MUTE 0x0100 /* IN1R_MUTE */
1609#define WM5100_IN1R_MUTE_MASK 0x0100 /* IN1R_MUTE */
1610#define WM5100_IN1R_MUTE_SHIFT 8 /* IN1R_MUTE */
1611#define WM5100_IN1R_MUTE_WIDTH 1 /* IN1R_MUTE */
1612#define WM5100_IN1R_VOL_MASK 0x00FF /* IN1R_VOL - [7:0] */
1613#define WM5100_IN1R_VOL_SHIFT 0 /* IN1R_VOL - [7:0] */
1614#define WM5100_IN1R_VOL_WIDTH 8 /* IN1R_VOL - [7:0] */
1615
1616/*
1617 * R802 (0x322) - ADC Digital Volume 2L
1618 */
1619#define WM5100_IN_VU 0x0200 /* IN_VU */
1620#define WM5100_IN_VU_MASK 0x0200 /* IN_VU */
1621#define WM5100_IN_VU_SHIFT 9 /* IN_VU */
1622#define WM5100_IN_VU_WIDTH 1 /* IN_VU */
1623#define WM5100_IN2L_MUTE 0x0100 /* IN2L_MUTE */
1624#define WM5100_IN2L_MUTE_MASK 0x0100 /* IN2L_MUTE */
1625#define WM5100_IN2L_MUTE_SHIFT 8 /* IN2L_MUTE */
1626#define WM5100_IN2L_MUTE_WIDTH 1 /* IN2L_MUTE */
1627#define WM5100_IN2L_VOL_MASK 0x00FF /* IN2L_VOL - [7:0] */
1628#define WM5100_IN2L_VOL_SHIFT 0 /* IN2L_VOL - [7:0] */
1629#define WM5100_IN2L_VOL_WIDTH 8 /* IN2L_VOL - [7:0] */
1630
1631/*
1632 * R803 (0x323) - ADC Digital Volume 2R
1633 */
1634#define WM5100_IN_VU 0x0200 /* IN_VU */
1635#define WM5100_IN_VU_MASK 0x0200 /* IN_VU */
1636#define WM5100_IN_VU_SHIFT 9 /* IN_VU */
1637#define WM5100_IN_VU_WIDTH 1 /* IN_VU */
1638#define WM5100_IN2R_MUTE 0x0100 /* IN2R_MUTE */
1639#define WM5100_IN2R_MUTE_MASK 0x0100 /* IN2R_MUTE */
1640#define WM5100_IN2R_MUTE_SHIFT 8 /* IN2R_MUTE */
1641#define WM5100_IN2R_MUTE_WIDTH 1 /* IN2R_MUTE */
1642#define WM5100_IN2R_VOL_MASK 0x00FF /* IN2R_VOL - [7:0] */
1643#define WM5100_IN2R_VOL_SHIFT 0 /* IN2R_VOL - [7:0] */
1644#define WM5100_IN2R_VOL_WIDTH 8 /* IN2R_VOL - [7:0] */
1645
1646/*
1647 * R804 (0x324) - ADC Digital Volume 3L
1648 */
1649#define WM5100_IN_VU 0x0200 /* IN_VU */
1650#define WM5100_IN_VU_MASK 0x0200 /* IN_VU */
1651#define WM5100_IN_VU_SHIFT 9 /* IN_VU */
1652#define WM5100_IN_VU_WIDTH 1 /* IN_VU */
1653#define WM5100_IN3L_MUTE 0x0100 /* IN3L_MUTE */
1654#define WM5100_IN3L_MUTE_MASK 0x0100 /* IN3L_MUTE */
1655#define WM5100_IN3L_MUTE_SHIFT 8 /* IN3L_MUTE */
1656#define WM5100_IN3L_MUTE_WIDTH 1 /* IN3L_MUTE */
1657#define WM5100_IN3L_VOL_MASK 0x00FF /* IN3L_VOL - [7:0] */
1658#define WM5100_IN3L_VOL_SHIFT 0 /* IN3L_VOL - [7:0] */
1659#define WM5100_IN3L_VOL_WIDTH 8 /* IN3L_VOL - [7:0] */
1660
1661/*
1662 * R805 (0x325) - ADC Digital Volume 3R
1663 */
1664#define WM5100_IN_VU 0x0200 /* IN_VU */
1665#define WM5100_IN_VU_MASK 0x0200 /* IN_VU */
1666#define WM5100_IN_VU_SHIFT 9 /* IN_VU */
1667#define WM5100_IN_VU_WIDTH 1 /* IN_VU */
1668#define WM5100_IN3R_MUTE 0x0100 /* IN3R_MUTE */
1669#define WM5100_IN3R_MUTE_MASK 0x0100 /* IN3R_MUTE */
1670#define WM5100_IN3R_MUTE_SHIFT 8 /* IN3R_MUTE */
1671#define WM5100_IN3R_MUTE_WIDTH 1 /* IN3R_MUTE */
1672#define WM5100_IN3R_VOL_MASK 0x00FF /* IN3R_VOL - [7:0] */
1673#define WM5100_IN3R_VOL_SHIFT 0 /* IN3R_VOL - [7:0] */
1674#define WM5100_IN3R_VOL_WIDTH 8 /* IN3R_VOL - [7:0] */
1675
1676/*
1677 * R806 (0x326) - ADC Digital Volume 4L
1678 */
1679#define WM5100_IN_VU 0x0200 /* IN_VU */
1680#define WM5100_IN_VU_MASK 0x0200 /* IN_VU */
1681#define WM5100_IN_VU_SHIFT 9 /* IN_VU */
1682#define WM5100_IN_VU_WIDTH 1 /* IN_VU */
1683#define WM5100_IN4L_MUTE 0x0100 /* IN4L_MUTE */
1684#define WM5100_IN4L_MUTE_MASK 0x0100 /* IN4L_MUTE */
1685#define WM5100_IN4L_MUTE_SHIFT 8 /* IN4L_MUTE */
1686#define WM5100_IN4L_MUTE_WIDTH 1 /* IN4L_MUTE */
1687#define WM5100_IN4L_VOL_MASK 0x00FF /* IN4L_VOL - [7:0] */
1688#define WM5100_IN4L_VOL_SHIFT 0 /* IN4L_VOL - [7:0] */
1689#define WM5100_IN4L_VOL_WIDTH 8 /* IN4L_VOL - [7:0] */
1690
1691/*
1692 * R807 (0x327) - ADC Digital Volume 4R
1693 */
1694#define WM5100_IN_VU 0x0200 /* IN_VU */
1695#define WM5100_IN_VU_MASK 0x0200 /* IN_VU */
1696#define WM5100_IN_VU_SHIFT 9 /* IN_VU */
1697#define WM5100_IN_VU_WIDTH 1 /* IN_VU */
1698#define WM5100_IN4R_MUTE 0x0100 /* IN4R_MUTE */
1699#define WM5100_IN4R_MUTE_MASK 0x0100 /* IN4R_MUTE */
1700#define WM5100_IN4R_MUTE_SHIFT 8 /* IN4R_MUTE */
1701#define WM5100_IN4R_MUTE_WIDTH 1 /* IN4R_MUTE */
1702#define WM5100_IN4R_VOL_MASK 0x00FF /* IN4R_VOL - [7:0] */
1703#define WM5100_IN4R_VOL_SHIFT 0 /* IN4R_VOL - [7:0] */
1704#define WM5100_IN4R_VOL_WIDTH 8 /* IN4R_VOL - [7:0] */
1705
1706/*
1707 * R1025 (0x401) - Output Enables 2
1708 */
1709#define WM5100_OUT6L_ENA 0x0800 /* OUT6L_ENA */
1710#define WM5100_OUT6L_ENA_MASK 0x0800 /* OUT6L_ENA */
1711#define WM5100_OUT6L_ENA_SHIFT 11 /* OUT6L_ENA */
1712#define WM5100_OUT6L_ENA_WIDTH 1 /* OUT6L_ENA */
1713#define WM5100_OUT6R_ENA 0x0400 /* OUT6R_ENA */
1714#define WM5100_OUT6R_ENA_MASK 0x0400 /* OUT6R_ENA */
1715#define WM5100_OUT6R_ENA_SHIFT 10 /* OUT6R_ENA */
1716#define WM5100_OUT6R_ENA_WIDTH 1 /* OUT6R_ENA */
1717#define WM5100_OUT5L_ENA 0x0200 /* OUT5L_ENA */
1718#define WM5100_OUT5L_ENA_MASK 0x0200 /* OUT5L_ENA */
1719#define WM5100_OUT5L_ENA_SHIFT 9 /* OUT5L_ENA */
1720#define WM5100_OUT5L_ENA_WIDTH 1 /* OUT5L_ENA */
1721#define WM5100_OUT5R_ENA 0x0100 /* OUT5R_ENA */
1722#define WM5100_OUT5R_ENA_MASK 0x0100 /* OUT5R_ENA */
1723#define WM5100_OUT5R_ENA_SHIFT 8 /* OUT5R_ENA */
1724#define WM5100_OUT5R_ENA_WIDTH 1 /* OUT5R_ENA */
1725#define WM5100_OUT4L_ENA 0x0080 /* OUT4L_ENA */
1726#define WM5100_OUT4L_ENA_MASK 0x0080 /* OUT4L_ENA */
1727#define WM5100_OUT4L_ENA_SHIFT 7 /* OUT4L_ENA */
1728#define WM5100_OUT4L_ENA_WIDTH 1 /* OUT4L_ENA */
1729#define WM5100_OUT4R_ENA 0x0040 /* OUT4R_ENA */
1730#define WM5100_OUT4R_ENA_MASK 0x0040 /* OUT4R_ENA */
1731#define WM5100_OUT4R_ENA_SHIFT 6 /* OUT4R_ENA */
1732#define WM5100_OUT4R_ENA_WIDTH 1 /* OUT4R_ENA */
1733
1734/*
1735 * R1026 (0x402) - Output Status 1
1736 */
1737#define WM5100_OUT3L_ENA_STS 0x0020 /* OUT3L_ENA_STS */
1738#define WM5100_OUT3L_ENA_STS_MASK 0x0020 /* OUT3L_ENA_STS */
1739#define WM5100_OUT3L_ENA_STS_SHIFT 5 /* OUT3L_ENA_STS */
1740#define WM5100_OUT3L_ENA_STS_WIDTH 1 /* OUT3L_ENA_STS */
1741#define WM5100_OUT3R_ENA_STS 0x0010 /* OUT3R_ENA_STS */
1742#define WM5100_OUT3R_ENA_STS_MASK 0x0010 /* OUT3R_ENA_STS */
1743#define WM5100_OUT3R_ENA_STS_SHIFT 4 /* OUT3R_ENA_STS */
1744#define WM5100_OUT3R_ENA_STS_WIDTH 1 /* OUT3R_ENA_STS */
1745#define WM5100_OUT2L_ENA_STS 0x0008 /* OUT2L_ENA_STS */
1746#define WM5100_OUT2L_ENA_STS_MASK 0x0008 /* OUT2L_ENA_STS */
1747#define WM5100_OUT2L_ENA_STS_SHIFT 3 /* OUT2L_ENA_STS */
1748#define WM5100_OUT2L_ENA_STS_WIDTH 1 /* OUT2L_ENA_STS */
1749#define WM5100_OUT2R_ENA_STS 0x0004 /* OUT2R_ENA_STS */
1750#define WM5100_OUT2R_ENA_STS_MASK 0x0004 /* OUT2R_ENA_STS */
1751#define WM5100_OUT2R_ENA_STS_SHIFT 2 /* OUT2R_ENA_STS */
1752#define WM5100_OUT2R_ENA_STS_WIDTH 1 /* OUT2R_ENA_STS */
1753#define WM5100_OUT1L_ENA_STS 0x0002 /* OUT1L_ENA_STS */
1754#define WM5100_OUT1L_ENA_STS_MASK 0x0002 /* OUT1L_ENA_STS */
1755#define WM5100_OUT1L_ENA_STS_SHIFT 1 /* OUT1L_ENA_STS */
1756#define WM5100_OUT1L_ENA_STS_WIDTH 1 /* OUT1L_ENA_STS */
1757#define WM5100_OUT1R_ENA_STS 0x0001 /* OUT1R_ENA_STS */
1758#define WM5100_OUT1R_ENA_STS_MASK 0x0001 /* OUT1R_ENA_STS */
1759#define WM5100_OUT1R_ENA_STS_SHIFT 0 /* OUT1R_ENA_STS */
1760#define WM5100_OUT1R_ENA_STS_WIDTH 1 /* OUT1R_ENA_STS */
1761
1762/*
1763 * R1027 (0x403) - Output Status 2
1764 */
1765#define WM5100_OUT6L_ENA_STS 0x0800 /* OUT6L_ENA_STS */
1766#define WM5100_OUT6L_ENA_STS_MASK 0x0800 /* OUT6L_ENA_STS */
1767#define WM5100_OUT6L_ENA_STS_SHIFT 11 /* OUT6L_ENA_STS */
1768#define WM5100_OUT6L_ENA_STS_WIDTH 1 /* OUT6L_ENA_STS */
1769#define WM5100_OUT6R_ENA_STS 0x0400 /* OUT6R_ENA_STS */
1770#define WM5100_OUT6R_ENA_STS_MASK 0x0400 /* OUT6R_ENA_STS */
1771#define WM5100_OUT6R_ENA_STS_SHIFT 10 /* OUT6R_ENA_STS */
1772#define WM5100_OUT6R_ENA_STS_WIDTH 1 /* OUT6R_ENA_STS */
1773#define WM5100_OUT5L_ENA_STS 0x0200 /* OUT5L_ENA_STS */
1774#define WM5100_OUT5L_ENA_STS_MASK 0x0200 /* OUT5L_ENA_STS */
1775#define WM5100_OUT5L_ENA_STS_SHIFT 9 /* OUT5L_ENA_STS */
1776#define WM5100_OUT5L_ENA_STS_WIDTH 1 /* OUT5L_ENA_STS */
1777#define WM5100_OUT5R_ENA_STS 0x0100 /* OUT5R_ENA_STS */
1778#define WM5100_OUT5R_ENA_STS_MASK 0x0100 /* OUT5R_ENA_STS */
1779#define WM5100_OUT5R_ENA_STS_SHIFT 8 /* OUT5R_ENA_STS */
1780#define WM5100_OUT5R_ENA_STS_WIDTH 1 /* OUT5R_ENA_STS */
1781#define WM5100_OUT4L_ENA_STS 0x0080 /* OUT4L_ENA_STS */
1782#define WM5100_OUT4L_ENA_STS_MASK 0x0080 /* OUT4L_ENA_STS */
1783#define WM5100_OUT4L_ENA_STS_SHIFT 7 /* OUT4L_ENA_STS */
1784#define WM5100_OUT4L_ENA_STS_WIDTH 1 /* OUT4L_ENA_STS */
1785#define WM5100_OUT4R_ENA_STS 0x0040 /* OUT4R_ENA_STS */
1786#define WM5100_OUT4R_ENA_STS_MASK 0x0040 /* OUT4R_ENA_STS */
1787#define WM5100_OUT4R_ENA_STS_SHIFT 6 /* OUT4R_ENA_STS */
1788#define WM5100_OUT4R_ENA_STS_WIDTH 1 /* OUT4R_ENA_STS */
1789
1790/*
1791 * R1032 (0x408) - Channel Enables 1
1792 */
1793#define WM5100_HP3L_ENA 0x0020 /* HP3L_ENA */
1794#define WM5100_HP3L_ENA_MASK 0x0020 /* HP3L_ENA */
1795#define WM5100_HP3L_ENA_SHIFT 5 /* HP3L_ENA */
1796#define WM5100_HP3L_ENA_WIDTH 1 /* HP3L_ENA */
1797#define WM5100_HP3R_ENA 0x0010 /* HP3R_ENA */
1798#define WM5100_HP3R_ENA_MASK 0x0010 /* HP3R_ENA */
1799#define WM5100_HP3R_ENA_SHIFT 4 /* HP3R_ENA */
1800#define WM5100_HP3R_ENA_WIDTH 1 /* HP3R_ENA */
1801#define WM5100_HP2L_ENA 0x0008 /* HP2L_ENA */
1802#define WM5100_HP2L_ENA_MASK 0x0008 /* HP2L_ENA */
1803#define WM5100_HP2L_ENA_SHIFT 3 /* HP2L_ENA */
1804#define WM5100_HP2L_ENA_WIDTH 1 /* HP2L_ENA */
1805#define WM5100_HP2R_ENA 0x0004 /* HP2R_ENA */
1806#define WM5100_HP2R_ENA_MASK 0x0004 /* HP2R_ENA */
1807#define WM5100_HP2R_ENA_SHIFT 2 /* HP2R_ENA */
1808#define WM5100_HP2R_ENA_WIDTH 1 /* HP2R_ENA */
1809#define WM5100_HP1L_ENA 0x0002 /* HP1L_ENA */
1810#define WM5100_HP1L_ENA_MASK 0x0002 /* HP1L_ENA */
1811#define WM5100_HP1L_ENA_SHIFT 1 /* HP1L_ENA */
1812#define WM5100_HP1L_ENA_WIDTH 1 /* HP1L_ENA */
1813#define WM5100_HP1R_ENA 0x0001 /* HP1R_ENA */
1814#define WM5100_HP1R_ENA_MASK 0x0001 /* HP1R_ENA */
1815#define WM5100_HP1R_ENA_SHIFT 0 /* HP1R_ENA */
1816#define WM5100_HP1R_ENA_WIDTH 1 /* HP1R_ENA */
1817
1818/*
1819 * R1040 (0x410) - Out Volume 1L
1820 */
1821#define WM5100_OUT_RATE_MASK 0xC000 /* OUT_RATE - [15:14] */
1822#define WM5100_OUT_RATE_SHIFT 14 /* OUT_RATE - [15:14] */
1823#define WM5100_OUT_RATE_WIDTH 2 /* OUT_RATE - [15:14] */
1824#define WM5100_OUT1_OSR 0x2000 /* OUT1_OSR */
1825#define WM5100_OUT1_OSR_MASK 0x2000 /* OUT1_OSR */
1826#define WM5100_OUT1_OSR_SHIFT 13 /* OUT1_OSR */
1827#define WM5100_OUT1_OSR_WIDTH 1 /* OUT1_OSR */
1828#define WM5100_OUT1_MONO 0x1000 /* OUT1_MONO */
1829#define WM5100_OUT1_MONO_MASK 0x1000 /* OUT1_MONO */
1830#define WM5100_OUT1_MONO_SHIFT 12 /* OUT1_MONO */
1831#define WM5100_OUT1_MONO_WIDTH 1 /* OUT1_MONO */
1832#define WM5100_OUT1L_ANC_SRC 0x0800 /* OUT1L_ANC_SRC */
1833#define WM5100_OUT1L_ANC_SRC_MASK 0x0800 /* OUT1L_ANC_SRC */
1834#define WM5100_OUT1L_ANC_SRC_SHIFT 11 /* OUT1L_ANC_SRC */
1835#define WM5100_OUT1L_ANC_SRC_WIDTH 1 /* OUT1L_ANC_SRC */
1836#define WM5100_OUT1L_PGA_VOL_MASK 0x00FE /* OUT1L_PGA_VOL - [7:1] */
1837#define WM5100_OUT1L_PGA_VOL_SHIFT 1 /* OUT1L_PGA_VOL - [7:1] */
1838#define WM5100_OUT1L_PGA_VOL_WIDTH 7 /* OUT1L_PGA_VOL - [7:1] */
1839
1840/*
1841 * R1041 (0x411) - Out Volume 1R
1842 */
1843#define WM5100_OUT1R_ANC_SRC 0x0800 /* OUT1R_ANC_SRC */
1844#define WM5100_OUT1R_ANC_SRC_MASK 0x0800 /* OUT1R_ANC_SRC */
1845#define WM5100_OUT1R_ANC_SRC_SHIFT 11 /* OUT1R_ANC_SRC */
1846#define WM5100_OUT1R_ANC_SRC_WIDTH 1 /* OUT1R_ANC_SRC */
1847#define WM5100_OUT1R_PGA_VOL_MASK 0x00FE /* OUT1R_PGA_VOL - [7:1] */
1848#define WM5100_OUT1R_PGA_VOL_SHIFT 1 /* OUT1R_PGA_VOL - [7:1] */
1849#define WM5100_OUT1R_PGA_VOL_WIDTH 7 /* OUT1R_PGA_VOL - [7:1] */
1850
1851/*
1852 * R1042 (0x412) - DAC Volume Limit 1L
1853 */
1854#define WM5100_OUT1L_VOL_LIM_MASK 0x00FF /* OUT1L_VOL_LIM - [7:0] */
1855#define WM5100_OUT1L_VOL_LIM_SHIFT 0 /* OUT1L_VOL_LIM - [7:0] */
1856#define WM5100_OUT1L_VOL_LIM_WIDTH 8 /* OUT1L_VOL_LIM - [7:0] */
1857
1858/*
1859 * R1043 (0x413) - DAC Volume Limit 1R
1860 */
1861#define WM5100_OUT1R_VOL_LIM_MASK 0x00FF /* OUT1R_VOL_LIM - [7:0] */
1862#define WM5100_OUT1R_VOL_LIM_SHIFT 0 /* OUT1R_VOL_LIM - [7:0] */
1863#define WM5100_OUT1R_VOL_LIM_WIDTH 8 /* OUT1R_VOL_LIM - [7:0] */
1864
1865/*
1866 * R1044 (0x414) - Out Volume 2L
1867 */
1868#define WM5100_OUT2_OSR 0x2000 /* OUT2_OSR */
1869#define WM5100_OUT2_OSR_MASK 0x2000 /* OUT2_OSR */
1870#define WM5100_OUT2_OSR_SHIFT 13 /* OUT2_OSR */
1871#define WM5100_OUT2_OSR_WIDTH 1 /* OUT2_OSR */
1872#define WM5100_OUT2_MONO 0x1000 /* OUT2_MONO */
1873#define WM5100_OUT2_MONO_MASK 0x1000 /* OUT2_MONO */
1874#define WM5100_OUT2_MONO_SHIFT 12 /* OUT2_MONO */
1875#define WM5100_OUT2_MONO_WIDTH 1 /* OUT2_MONO */
1876#define WM5100_OUT2L_ANC_SRC 0x0800 /* OUT2L_ANC_SRC */
1877#define WM5100_OUT2L_ANC_SRC_MASK 0x0800 /* OUT2L_ANC_SRC */
1878#define WM5100_OUT2L_ANC_SRC_SHIFT 11 /* OUT2L_ANC_SRC */
1879#define WM5100_OUT2L_ANC_SRC_WIDTH 1 /* OUT2L_ANC_SRC */
1880#define WM5100_OUT2L_PGA_VOL_MASK 0x00FE /* OUT2L_PGA_VOL - [7:1] */
1881#define WM5100_OUT2L_PGA_VOL_SHIFT 1 /* OUT2L_PGA_VOL - [7:1] */
1882#define WM5100_OUT2L_PGA_VOL_WIDTH 7 /* OUT2L_PGA_VOL - [7:1] */
1883
1884/*
1885 * R1045 (0x415) - Out Volume 2R
1886 */
1887#define WM5100_OUT2R_ANC_SRC 0x0800 /* OUT2R_ANC_SRC */
1888#define WM5100_OUT2R_ANC_SRC_MASK 0x0800 /* OUT2R_ANC_SRC */
1889#define WM5100_OUT2R_ANC_SRC_SHIFT 11 /* OUT2R_ANC_SRC */
1890#define WM5100_OUT2R_ANC_SRC_WIDTH 1 /* OUT2R_ANC_SRC */
1891#define WM5100_OUT2R_PGA_VOL_MASK 0x00FE /* OUT2R_PGA_VOL - [7:1] */
1892#define WM5100_OUT2R_PGA_VOL_SHIFT 1 /* OUT2R_PGA_VOL - [7:1] */
1893#define WM5100_OUT2R_PGA_VOL_WIDTH 7 /* OUT2R_PGA_VOL - [7:1] */
1894
1895/*
1896 * R1046 (0x416) - DAC Volume Limit 2L
1897 */
1898#define WM5100_OUT2L_VOL_LIM_MASK 0x00FF /* OUT2L_VOL_LIM - [7:0] */
1899#define WM5100_OUT2L_VOL_LIM_SHIFT 0 /* OUT2L_VOL_LIM - [7:0] */
1900#define WM5100_OUT2L_VOL_LIM_WIDTH 8 /* OUT2L_VOL_LIM - [7:0] */
1901
1902/*
1903 * R1047 (0x417) - DAC Volume Limit 2R
1904 */
1905#define WM5100_OUT2R_VOL_LIM_MASK 0x00FF /* OUT2R_VOL_LIM - [7:0] */
1906#define WM5100_OUT2R_VOL_LIM_SHIFT 0 /* OUT2R_VOL_LIM - [7:0] */
1907#define WM5100_OUT2R_VOL_LIM_WIDTH 8 /* OUT2R_VOL_LIM - [7:0] */
1908
1909/*
1910 * R1048 (0x418) - Out Volume 3L
1911 */
1912#define WM5100_OUT3_OSR 0x2000 /* OUT3_OSR */
1913#define WM5100_OUT3_OSR_MASK 0x2000 /* OUT3_OSR */
1914#define WM5100_OUT3_OSR_SHIFT 13 /* OUT3_OSR */
1915#define WM5100_OUT3_OSR_WIDTH 1 /* OUT3_OSR */
1916#define WM5100_OUT3_MONO 0x1000 /* OUT3_MONO */
1917#define WM5100_OUT3_MONO_MASK 0x1000 /* OUT3_MONO */
1918#define WM5100_OUT3_MONO_SHIFT 12 /* OUT3_MONO */
1919#define WM5100_OUT3_MONO_WIDTH 1 /* OUT3_MONO */
1920#define WM5100_OUT3L_ANC_SRC 0x0800 /* OUT3L_ANC_SRC */
1921#define WM5100_OUT3L_ANC_SRC_MASK 0x0800 /* OUT3L_ANC_SRC */
1922#define WM5100_OUT3L_ANC_SRC_SHIFT 11 /* OUT3L_ANC_SRC */
1923#define WM5100_OUT3L_ANC_SRC_WIDTH 1 /* OUT3L_ANC_SRC */
1924#define WM5100_OUT3L_PGA_VOL_MASK 0x00FE /* OUT3L_PGA_VOL - [7:1] */
1925#define WM5100_OUT3L_PGA_VOL_SHIFT 1 /* OUT3L_PGA_VOL - [7:1] */
1926#define WM5100_OUT3L_PGA_VOL_WIDTH 7 /* OUT3L_PGA_VOL - [7:1] */
1927
1928/*
1929 * R1049 (0x419) - Out Volume 3R
1930 */
1931#define WM5100_OUT3R_ANC_SRC 0x0800 /* OUT3R_ANC_SRC */
1932#define WM5100_OUT3R_ANC_SRC_MASK 0x0800 /* OUT3R_ANC_SRC */
1933#define WM5100_OUT3R_ANC_SRC_SHIFT 11 /* OUT3R_ANC_SRC */
1934#define WM5100_OUT3R_ANC_SRC_WIDTH 1 /* OUT3R_ANC_SRC */
1935#define WM5100_OUT3R_PGA_VOL_MASK 0x00FE /* OUT3R_PGA_VOL - [7:1] */
1936#define WM5100_OUT3R_PGA_VOL_SHIFT 1 /* OUT3R_PGA_VOL - [7:1] */
1937#define WM5100_OUT3R_PGA_VOL_WIDTH 7 /* OUT3R_PGA_VOL - [7:1] */
1938
1939/*
1940 * R1050 (0x41A) - DAC Volume Limit 3L
1941 */
1942#define WM5100_OUT3L_VOL_LIM_MASK 0x00FF /* OUT3L_VOL_LIM - [7:0] */
1943#define WM5100_OUT3L_VOL_LIM_SHIFT 0 /* OUT3L_VOL_LIM - [7:0] */
1944#define WM5100_OUT3L_VOL_LIM_WIDTH 8 /* OUT3L_VOL_LIM - [7:0] */
1945
1946/*
1947 * R1051 (0x41B) - DAC Volume Limit 3R
1948 */
1949#define WM5100_OUT3R_VOL_LIM_MASK 0x00FF /* OUT3R_VOL_LIM - [7:0] */
1950#define WM5100_OUT3R_VOL_LIM_SHIFT 0 /* OUT3R_VOL_LIM - [7:0] */
1951#define WM5100_OUT3R_VOL_LIM_WIDTH 8 /* OUT3R_VOL_LIM - [7:0] */
1952
1953/*
1954 * R1052 (0x41C) - Out Volume 4L
1955 */
1956#define WM5100_OUT4_OSR 0x2000 /* OUT4_OSR */
1957#define WM5100_OUT4_OSR_MASK 0x2000 /* OUT4_OSR */
1958#define WM5100_OUT4_OSR_SHIFT 13 /* OUT4_OSR */
1959#define WM5100_OUT4_OSR_WIDTH 1 /* OUT4_OSR */
1960#define WM5100_OUT4L_ANC_SRC 0x0800 /* OUT4L_ANC_SRC */
1961#define WM5100_OUT4L_ANC_SRC_MASK 0x0800 /* OUT4L_ANC_SRC */
1962#define WM5100_OUT4L_ANC_SRC_SHIFT 11 /* OUT4L_ANC_SRC */
1963#define WM5100_OUT4L_ANC_SRC_WIDTH 1 /* OUT4L_ANC_SRC */
1964#define WM5100_OUT4L_VOL_LIM_MASK 0x00FF /* OUT4L_VOL_LIM - [7:0] */
1965#define WM5100_OUT4L_VOL_LIM_SHIFT 0 /* OUT4L_VOL_LIM - [7:0] */
1966#define WM5100_OUT4L_VOL_LIM_WIDTH 8 /* OUT4L_VOL_LIM - [7:0] */
1967
1968/*
1969 * R1053 (0x41D) - Out Volume 4R
1970 */
1971#define WM5100_OUT4R_ANC_SRC 0x0800 /* OUT4R_ANC_SRC */
1972#define WM5100_OUT4R_ANC_SRC_MASK 0x0800 /* OUT4R_ANC_SRC */
1973#define WM5100_OUT4R_ANC_SRC_SHIFT 11 /* OUT4R_ANC_SRC */
1974#define WM5100_OUT4R_ANC_SRC_WIDTH 1 /* OUT4R_ANC_SRC */
1975#define WM5100_OUT4R_VOL_LIM_MASK 0x00FF /* OUT4R_VOL_LIM - [7:0] */
1976#define WM5100_OUT4R_VOL_LIM_SHIFT 0 /* OUT4R_VOL_LIM - [7:0] */
1977#define WM5100_OUT4R_VOL_LIM_WIDTH 8 /* OUT4R_VOL_LIM - [7:0] */
1978
1979/*
1980 * R1054 (0x41E) - DAC Volume Limit 5L
1981 */
1982#define WM5100_OUT5_OSR 0x2000 /* OUT5_OSR */
1983#define WM5100_OUT5_OSR_MASK 0x2000 /* OUT5_OSR */
1984#define WM5100_OUT5_OSR_SHIFT 13 /* OUT5_OSR */
1985#define WM5100_OUT5_OSR_WIDTH 1 /* OUT5_OSR */
1986#define WM5100_OUT5L_ANC_SRC 0x0800 /* OUT5L_ANC_SRC */
1987#define WM5100_OUT5L_ANC_SRC_MASK 0x0800 /* OUT5L_ANC_SRC */
1988#define WM5100_OUT5L_ANC_SRC_SHIFT 11 /* OUT5L_ANC_SRC */
1989#define WM5100_OUT5L_ANC_SRC_WIDTH 1 /* OUT5L_ANC_SRC */
1990#define WM5100_OUT5L_VOL_LIM_MASK 0x00FF /* OUT5L_VOL_LIM - [7:0] */
1991#define WM5100_OUT5L_VOL_LIM_SHIFT 0 /* OUT5L_VOL_LIM - [7:0] */
1992#define WM5100_OUT5L_VOL_LIM_WIDTH 8 /* OUT5L_VOL_LIM - [7:0] */
1993
1994/*
1995 * R1055 (0x41F) - DAC Volume Limit 5R
1996 */
1997#define WM5100_OUT5R_ANC_SRC 0x0800 /* OUT5R_ANC_SRC */
1998#define WM5100_OUT5R_ANC_SRC_MASK 0x0800 /* OUT5R_ANC_SRC */
1999#define WM5100_OUT5R_ANC_SRC_SHIFT 11 /* OUT5R_ANC_SRC */
2000#define WM5100_OUT5R_ANC_SRC_WIDTH 1 /* OUT5R_ANC_SRC */
2001#define WM5100_OUT5R_VOL_LIM_MASK 0x00FF /* OUT5R_VOL_LIM - [7:0] */
2002#define WM5100_OUT5R_VOL_LIM_SHIFT 0 /* OUT5R_VOL_LIM - [7:0] */
2003#define WM5100_OUT5R_VOL_LIM_WIDTH 8 /* OUT5R_VOL_LIM - [7:0] */
2004
2005/*
2006 * R1056 (0x420) - DAC Volume Limit 6L
2007 */
2008#define WM5100_OUT6_OSR 0x2000 /* OUT6_OSR */
2009#define WM5100_OUT6_OSR_MASK 0x2000 /* OUT6_OSR */
2010#define WM5100_OUT6_OSR_SHIFT 13 /* OUT6_OSR */
2011#define WM5100_OUT6_OSR_WIDTH 1 /* OUT6_OSR */
2012#define WM5100_OUT6L_ANC_SRC 0x0800 /* OUT6L_ANC_SRC */
2013#define WM5100_OUT6L_ANC_SRC_MASK 0x0800 /* OUT6L_ANC_SRC */
2014#define WM5100_OUT6L_ANC_SRC_SHIFT 11 /* OUT6L_ANC_SRC */
2015#define WM5100_OUT6L_ANC_SRC_WIDTH 1 /* OUT6L_ANC_SRC */
2016#define WM5100_OUT6L_VOL_LIM_MASK 0x00FF /* OUT6L_VOL_LIM - [7:0] */
2017#define WM5100_OUT6L_VOL_LIM_SHIFT 0 /* OUT6L_VOL_LIM - [7:0] */
2018#define WM5100_OUT6L_VOL_LIM_WIDTH 8 /* OUT6L_VOL_LIM - [7:0] */
2019
2020/*
2021 * R1057 (0x421) - DAC Volume Limit 6R
2022 */
2023#define WM5100_OUT6R_ANC_SRC 0x0800 /* OUT6R_ANC_SRC */
2024#define WM5100_OUT6R_ANC_SRC_MASK 0x0800 /* OUT6R_ANC_SRC */
2025#define WM5100_OUT6R_ANC_SRC_SHIFT 11 /* OUT6R_ANC_SRC */
2026#define WM5100_OUT6R_ANC_SRC_WIDTH 1 /* OUT6R_ANC_SRC */
2027#define WM5100_OUT6R_VOL_LIM_MASK 0x00FF /* OUT6R_VOL_LIM - [7:0] */
2028#define WM5100_OUT6R_VOL_LIM_SHIFT 0 /* OUT6R_VOL_LIM - [7:0] */
2029#define WM5100_OUT6R_VOL_LIM_WIDTH 8 /* OUT6R_VOL_LIM - [7:0] */
2030
2031/*
2032 * R1088 (0x440) - DAC AEC Control 1
2033 */
2034#define WM5100_AEC_LOOPBACK_SRC_MASK 0x003C /* AEC_LOOPBACK_SRC - [5:2] */
2035#define WM5100_AEC_LOOPBACK_SRC_SHIFT 2 /* AEC_LOOPBACK_SRC - [5:2] */
2036#define WM5100_AEC_LOOPBACK_SRC_WIDTH 4 /* AEC_LOOPBACK_SRC - [5:2] */
2037#define WM5100_AEC_ENA_STS 0x0002 /* AEC_ENA_STS */
2038#define WM5100_AEC_ENA_STS_MASK 0x0002 /* AEC_ENA_STS */
2039#define WM5100_AEC_ENA_STS_SHIFT 1 /* AEC_ENA_STS */
2040#define WM5100_AEC_ENA_STS_WIDTH 1 /* AEC_ENA_STS */
2041#define WM5100_AEC_LOOPBACK_ENA 0x0001 /* AEC_LOOPBACK_ENA */
2042#define WM5100_AEC_LOOPBACK_ENA_MASK 0x0001 /* AEC_LOOPBACK_ENA */
2043#define WM5100_AEC_LOOPBACK_ENA_SHIFT 0 /* AEC_LOOPBACK_ENA */
2044#define WM5100_AEC_LOOPBACK_ENA_WIDTH 1 /* AEC_LOOPBACK_ENA */
2045
2046/*
2047 * R1089 (0x441) - Output Volume Ramp
2048 */
2049#define WM5100_OUT_VD_RAMP_MASK 0x0070 /* OUT_VD_RAMP - [6:4] */
2050#define WM5100_OUT_VD_RAMP_SHIFT 4 /* OUT_VD_RAMP - [6:4] */
2051#define WM5100_OUT_VD_RAMP_WIDTH 3 /* OUT_VD_RAMP - [6:4] */
2052#define WM5100_OUT_VI_RAMP_MASK 0x0007 /* OUT_VI_RAMP - [2:0] */
2053#define WM5100_OUT_VI_RAMP_SHIFT 0 /* OUT_VI_RAMP - [2:0] */
2054#define WM5100_OUT_VI_RAMP_WIDTH 3 /* OUT_VI_RAMP - [2:0] */
2055
2056/*
2057 * R1152 (0x480) - DAC Digital Volume 1L
2058 */
2059#define WM5100_OUT_VU 0x0200 /* OUT_VU */
2060#define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */
2061#define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */
2062#define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */
2063#define WM5100_OUT1L_MUTE 0x0100 /* OUT1L_MUTE */
2064#define WM5100_OUT1L_MUTE_MASK 0x0100 /* OUT1L_MUTE */
2065#define WM5100_OUT1L_MUTE_SHIFT 8 /* OUT1L_MUTE */
2066#define WM5100_OUT1L_MUTE_WIDTH 1 /* OUT1L_MUTE */
2067#define WM5100_OUT1L_VOL_MASK 0x00FF /* OUT1L_VOL - [7:0] */
2068#define WM5100_OUT1L_VOL_SHIFT 0 /* OUT1L_VOL - [7:0] */
2069#define WM5100_OUT1L_VOL_WIDTH 8 /* OUT1L_VOL - [7:0] */
2070
2071/*
2072 * R1153 (0x481) - DAC Digital Volume 1R
2073 */
2074#define WM5100_OUT_VU 0x0200 /* OUT_VU */
2075#define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */
2076#define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */
2077#define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */
2078#define WM5100_OUT1R_MUTE 0x0100 /* OUT1R_MUTE */
2079#define WM5100_OUT1R_MUTE_MASK 0x0100 /* OUT1R_MUTE */
2080#define WM5100_OUT1R_MUTE_SHIFT 8 /* OUT1R_MUTE */
2081#define WM5100_OUT1R_MUTE_WIDTH 1 /* OUT1R_MUTE */
2082#define WM5100_OUT1R_VOL_MASK 0x00FF /* OUT1R_VOL - [7:0] */
2083#define WM5100_OUT1R_VOL_SHIFT 0 /* OUT1R_VOL - [7:0] */
2084#define WM5100_OUT1R_VOL_WIDTH 8 /* OUT1R_VOL - [7:0] */
2085
2086/*
2087 * R1154 (0x482) - DAC Digital Volume 2L
2088 */
2089#define WM5100_OUT_VU 0x0200 /* OUT_VU */
2090#define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */
2091#define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */
2092#define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */
2093#define WM5100_OUT2L_MUTE 0x0100 /* OUT2L_MUTE */
2094#define WM5100_OUT2L_MUTE_MASK 0x0100 /* OUT2L_MUTE */
2095#define WM5100_OUT2L_MUTE_SHIFT 8 /* OUT2L_MUTE */
2096#define WM5100_OUT2L_MUTE_WIDTH 1 /* OUT2L_MUTE */
2097#define WM5100_OUT2L_VOL_MASK 0x00FF /* OUT2L_VOL - [7:0] */
2098#define WM5100_OUT2L_VOL_SHIFT 0 /* OUT2L_VOL - [7:0] */
2099#define WM5100_OUT2L_VOL_WIDTH 8 /* OUT2L_VOL - [7:0] */
2100
2101/*
2102 * R1155 (0x483) - DAC Digital Volume 2R
2103 */
2104#define WM5100_OUT_VU 0x0200 /* OUT_VU */
2105#define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */
2106#define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */
2107#define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */
2108#define WM5100_OUT2R_MUTE 0x0100 /* OUT2R_MUTE */
2109#define WM5100_OUT2R_MUTE_MASK 0x0100 /* OUT2R_MUTE */
2110#define WM5100_OUT2R_MUTE_SHIFT 8 /* OUT2R_MUTE */
2111#define WM5100_OUT2R_MUTE_WIDTH 1 /* OUT2R_MUTE */
2112#define WM5100_OUT2R_VOL_MASK 0x00FF /* OUT2R_VOL - [7:0] */
2113#define WM5100_OUT2R_VOL_SHIFT 0 /* OUT2R_VOL - [7:0] */
2114#define WM5100_OUT2R_VOL_WIDTH 8 /* OUT2R_VOL - [7:0] */
2115
2116/*
2117 * R1156 (0x484) - DAC Digital Volume 3L
2118 */
2119#define WM5100_OUT_VU 0x0200 /* OUT_VU */
2120#define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */
2121#define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */
2122#define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */
2123#define WM5100_OUT3L_MUTE 0x0100 /* OUT3L_MUTE */
2124#define WM5100_OUT3L_MUTE_MASK 0x0100 /* OUT3L_MUTE */
2125#define WM5100_OUT3L_MUTE_SHIFT 8 /* OUT3L_MUTE */
2126#define WM5100_OUT3L_MUTE_WIDTH 1 /* OUT3L_MUTE */
2127#define WM5100_OUT3L_VOL_MASK 0x00FF /* OUT3L_VOL - [7:0] */
2128#define WM5100_OUT3L_VOL_SHIFT 0 /* OUT3L_VOL - [7:0] */
2129#define WM5100_OUT3L_VOL_WIDTH 8 /* OUT3L_VOL - [7:0] */
2130
2131/*
2132 * R1157 (0x485) - DAC Digital Volume 3R
2133 */
2134#define WM5100_OUT_VU 0x0200 /* OUT_VU */
2135#define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */
2136#define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */
2137#define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */
2138#define WM5100_OUT3R_MUTE 0x0100 /* OUT3R_MUTE */
2139#define WM5100_OUT3R_MUTE_MASK 0x0100 /* OUT3R_MUTE */
2140#define WM5100_OUT3R_MUTE_SHIFT 8 /* OUT3R_MUTE */
2141#define WM5100_OUT3R_MUTE_WIDTH 1 /* OUT3R_MUTE */
2142#define WM5100_OUT3R_VOL_MASK 0x00FF /* OUT3R_VOL - [7:0] */
2143#define WM5100_OUT3R_VOL_SHIFT 0 /* OUT3R_VOL - [7:0] */
2144#define WM5100_OUT3R_VOL_WIDTH 8 /* OUT3R_VOL - [7:0] */
2145
2146/*
2147 * R1158 (0x486) - DAC Digital Volume 4L
2148 */
2149#define WM5100_OUT_VU 0x0200 /* OUT_VU */
2150#define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */
2151#define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */
2152#define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */
2153#define WM5100_OUT4L_MUTE 0x0100 /* OUT4L_MUTE */
2154#define WM5100_OUT4L_MUTE_MASK 0x0100 /* OUT4L_MUTE */
2155#define WM5100_OUT4L_MUTE_SHIFT 8 /* OUT4L_MUTE */
2156#define WM5100_OUT4L_MUTE_WIDTH 1 /* OUT4L_MUTE */
2157#define WM5100_OUT4L_VOL_MASK 0x00FF /* OUT4L_VOL - [7:0] */
2158#define WM5100_OUT4L_VOL_SHIFT 0 /* OUT4L_VOL - [7:0] */
2159#define WM5100_OUT4L_VOL_WIDTH 8 /* OUT4L_VOL - [7:0] */
2160
2161/*
2162 * R1159 (0x487) - DAC Digital Volume 4R
2163 */
2164#define WM5100_OUT_VU 0x0200 /* OUT_VU */
2165#define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */
2166#define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */
2167#define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */
2168#define WM5100_OUT4R_MUTE 0x0100 /* OUT4R_MUTE */
2169#define WM5100_OUT4R_MUTE_MASK 0x0100 /* OUT4R_MUTE */
2170#define WM5100_OUT4R_MUTE_SHIFT 8 /* OUT4R_MUTE */
2171#define WM5100_OUT4R_MUTE_WIDTH 1 /* OUT4R_MUTE */
2172#define WM5100_OUT4R_VOL_MASK 0x00FF /* OUT4R_VOL - [7:0] */
2173#define WM5100_OUT4R_VOL_SHIFT 0 /* OUT4R_VOL - [7:0] */
2174#define WM5100_OUT4R_VOL_WIDTH 8 /* OUT4R_VOL - [7:0] */
2175
2176/*
2177 * R1160 (0x488) - DAC Digital Volume 5L
2178 */
2179#define WM5100_OUT_VU 0x0200 /* OUT_VU */
2180#define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */
2181#define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */
2182#define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */
2183#define WM5100_OUT5L_MUTE 0x0100 /* OUT5L_MUTE */
2184#define WM5100_OUT5L_MUTE_MASK 0x0100 /* OUT5L_MUTE */
2185#define WM5100_OUT5L_MUTE_SHIFT 8 /* OUT5L_MUTE */
2186#define WM5100_OUT5L_MUTE_WIDTH 1 /* OUT5L_MUTE */
2187#define WM5100_OUT5L_VOL_MASK 0x00FF /* OUT5L_VOL - [7:0] */
2188#define WM5100_OUT5L_VOL_SHIFT 0 /* OUT5L_VOL - [7:0] */
2189#define WM5100_OUT5L_VOL_WIDTH 8 /* OUT5L_VOL - [7:0] */
2190
2191/*
2192 * R1161 (0x489) - DAC Digital Volume 5R
2193 */
2194#define WM5100_OUT_VU 0x0200 /* OUT_VU */
2195#define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */
2196#define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */
2197#define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */
2198#define WM5100_OUT5R_MUTE 0x0100 /* OUT5R_MUTE */
2199#define WM5100_OUT5R_MUTE_MASK 0x0100 /* OUT5R_MUTE */
2200#define WM5100_OUT5R_MUTE_SHIFT 8 /* OUT5R_MUTE */
2201#define WM5100_OUT5R_MUTE_WIDTH 1 /* OUT5R_MUTE */
2202#define WM5100_OUT5R_VOL_MASK 0x00FF /* OUT5R_VOL - [7:0] */
2203#define WM5100_OUT5R_VOL_SHIFT 0 /* OUT5R_VOL - [7:0] */
2204#define WM5100_OUT5R_VOL_WIDTH 8 /* OUT5R_VOL - [7:0] */
2205
2206/*
2207 * R1162 (0x48A) - DAC Digital Volume 6L
2208 */
2209#define WM5100_OUT_VU 0x0200 /* OUT_VU */
2210#define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */
2211#define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */
2212#define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */
2213#define WM5100_OUT6L_MUTE 0x0100 /* OUT6L_MUTE */
2214#define WM5100_OUT6L_MUTE_MASK 0x0100 /* OUT6L_MUTE */
2215#define WM5100_OUT6L_MUTE_SHIFT 8 /* OUT6L_MUTE */
2216#define WM5100_OUT6L_MUTE_WIDTH 1 /* OUT6L_MUTE */
2217#define WM5100_OUT6L_VOL_MASK 0x00FF /* OUT6L_VOL - [7:0] */
2218#define WM5100_OUT6L_VOL_SHIFT 0 /* OUT6L_VOL - [7:0] */
2219#define WM5100_OUT6L_VOL_WIDTH 8 /* OUT6L_VOL - [7:0] */
2220
2221/*
2222 * R1163 (0x48B) - DAC Digital Volume 6R
2223 */
2224#define WM5100_OUT_VU 0x0200 /* OUT_VU */
2225#define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */
2226#define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */
2227#define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */
2228#define WM5100_OUT6R_MUTE 0x0100 /* OUT6R_MUTE */
2229#define WM5100_OUT6R_MUTE_MASK 0x0100 /* OUT6R_MUTE */
2230#define WM5100_OUT6R_MUTE_SHIFT 8 /* OUT6R_MUTE */
2231#define WM5100_OUT6R_MUTE_WIDTH 1 /* OUT6R_MUTE */
2232#define WM5100_OUT6R_VOL_MASK 0x00FF /* OUT6R_VOL - [7:0] */
2233#define WM5100_OUT6R_VOL_SHIFT 0 /* OUT6R_VOL - [7:0] */
2234#define WM5100_OUT6R_VOL_WIDTH 8 /* OUT6R_VOL - [7:0] */
2235
2236/*
2237 * R1216 (0x4C0) - PDM SPK1 CTRL 1
2238 */
2239#define WM5100_SPK1R_MUTE 0x2000 /* SPK1R_MUTE */
2240#define WM5100_SPK1R_MUTE_MASK 0x2000 /* SPK1R_MUTE */
2241#define WM5100_SPK1R_MUTE_SHIFT 13 /* SPK1R_MUTE */
2242#define WM5100_SPK1R_MUTE_WIDTH 1 /* SPK1R_MUTE */
2243#define WM5100_SPK1L_MUTE 0x1000 /* SPK1L_MUTE */
2244#define WM5100_SPK1L_MUTE_MASK 0x1000 /* SPK1L_MUTE */
2245#define WM5100_SPK1L_MUTE_SHIFT 12 /* SPK1L_MUTE */
2246#define WM5100_SPK1L_MUTE_WIDTH 1 /* SPK1L_MUTE */
2247#define WM5100_SPK1_MUTE_ENDIAN 0x0100 /* SPK1_MUTE_ENDIAN */
2248#define WM5100_SPK1_MUTE_ENDIAN_MASK 0x0100 /* SPK1_MUTE_ENDIAN */
2249#define WM5100_SPK1_MUTE_ENDIAN_SHIFT 8 /* SPK1_MUTE_ENDIAN */
2250#define WM5100_SPK1_MUTE_ENDIAN_WIDTH 1 /* SPK1_MUTE_ENDIAN */
2251#define WM5100_SPK1_MUTE_SEQ1_MASK 0x00FF /* SPK1_MUTE_SEQ1 - [7:0] */
2252#define WM5100_SPK1_MUTE_SEQ1_SHIFT 0 /* SPK1_MUTE_SEQ1 - [7:0] */
2253#define WM5100_SPK1_MUTE_SEQ1_WIDTH 8 /* SPK1_MUTE_SEQ1 - [7:0] */
2254
2255/*
2256 * R1217 (0x4C1) - PDM SPK1 CTRL 2
2257 */
2258#define WM5100_SPK1_FMT 0x0001 /* SPK1_FMT */
2259#define WM5100_SPK1_FMT_MASK 0x0001 /* SPK1_FMT */
2260#define WM5100_SPK1_FMT_SHIFT 0 /* SPK1_FMT */
2261#define WM5100_SPK1_FMT_WIDTH 1 /* SPK1_FMT */
2262
2263/*
2264 * R1218 (0x4C2) - PDM SPK2 CTRL 1
2265 */
2266#define WM5100_SPK2R_MUTE 0x2000 /* SPK2R_MUTE */
2267#define WM5100_SPK2R_MUTE_MASK 0x2000 /* SPK2R_MUTE */
2268#define WM5100_SPK2R_MUTE_SHIFT 13 /* SPK2R_MUTE */
2269#define WM5100_SPK2R_MUTE_WIDTH 1 /* SPK2R_MUTE */
2270#define WM5100_SPK2L_MUTE 0x1000 /* SPK2L_MUTE */
2271#define WM5100_SPK2L_MUTE_MASK 0x1000 /* SPK2L_MUTE */
2272#define WM5100_SPK2L_MUTE_SHIFT 12 /* SPK2L_MUTE */
2273#define WM5100_SPK2L_MUTE_WIDTH 1 /* SPK2L_MUTE */
2274#define WM5100_SPK2_MUTE_ENDIAN 0x0100 /* SPK2_MUTE_ENDIAN */
2275#define WM5100_SPK2_MUTE_ENDIAN_MASK 0x0100 /* SPK2_MUTE_ENDIAN */
2276#define WM5100_SPK2_MUTE_ENDIAN_SHIFT 8 /* SPK2_MUTE_ENDIAN */
2277#define WM5100_SPK2_MUTE_ENDIAN_WIDTH 1 /* SPK2_MUTE_ENDIAN */
2278#define WM5100_SPK2_MUTE_SEQ1_MASK 0x00FF /* SPK2_MUTE_SEQ1 - [7:0] */
2279#define WM5100_SPK2_MUTE_SEQ1_SHIFT 0 /* SPK2_MUTE_SEQ1 - [7:0] */
2280#define WM5100_SPK2_MUTE_SEQ1_WIDTH 8 /* SPK2_MUTE_SEQ1 - [7:0] */
2281
2282/*
2283 * R1219 (0x4C3) - PDM SPK2 CTRL 2
2284 */
2285#define WM5100_SPK2_FMT 0x0001 /* SPK2_FMT */
2286#define WM5100_SPK2_FMT_MASK 0x0001 /* SPK2_FMT */
2287#define WM5100_SPK2_FMT_SHIFT 0 /* SPK2_FMT */
2288#define WM5100_SPK2_FMT_WIDTH 1 /* SPK2_FMT */
2289
2290/*
2291 * R1280 (0x500) - Audio IF 1_1
2292 */
2293#define WM5100_AIF1_BCLK_INV 0x0080 /* AIF1_BCLK_INV */
2294#define WM5100_AIF1_BCLK_INV_MASK 0x0080 /* AIF1_BCLK_INV */
2295#define WM5100_AIF1_BCLK_INV_SHIFT 7 /* AIF1_BCLK_INV */
2296#define WM5100_AIF1_BCLK_INV_WIDTH 1 /* AIF1_BCLK_INV */
2297#define WM5100_AIF1_BCLK_FRC 0x0040 /* AIF1_BCLK_FRC */
2298#define WM5100_AIF1_BCLK_FRC_MASK 0x0040 /* AIF1_BCLK_FRC */
2299#define WM5100_AIF1_BCLK_FRC_SHIFT 6 /* AIF1_BCLK_FRC */
2300#define WM5100_AIF1_BCLK_FRC_WIDTH 1 /* AIF1_BCLK_FRC */
2301#define WM5100_AIF1_BCLK_MSTR 0x0020 /* AIF1_BCLK_MSTR */
2302#define WM5100_AIF1_BCLK_MSTR_MASK 0x0020 /* AIF1_BCLK_MSTR */
2303#define WM5100_AIF1_BCLK_MSTR_SHIFT 5 /* AIF1_BCLK_MSTR */
2304#define WM5100_AIF1_BCLK_MSTR_WIDTH 1 /* AIF1_BCLK_MSTR */
2305#define WM5100_AIF1_BCLK_FREQ_MASK 0x001F /* AIF1_BCLK_FREQ - [4:0] */
2306#define WM5100_AIF1_BCLK_FREQ_SHIFT 0 /* AIF1_BCLK_FREQ - [4:0] */
2307#define WM5100_AIF1_BCLK_FREQ_WIDTH 5 /* AIF1_BCLK_FREQ - [4:0] */
2308
2309/*
2310 * R1281 (0x501) - Audio IF 1_2
2311 */
2312#define WM5100_AIF1TX_DAT_TRI 0x0020 /* AIF1TX_DAT_TRI */
2313#define WM5100_AIF1TX_DAT_TRI_MASK 0x0020 /* AIF1TX_DAT_TRI */
2314#define WM5100_AIF1TX_DAT_TRI_SHIFT 5 /* AIF1TX_DAT_TRI */
2315#define WM5100_AIF1TX_DAT_TRI_WIDTH 1 /* AIF1TX_DAT_TRI */
2316#define WM5100_AIF1TX_LRCLK_SRC 0x0008 /* AIF1TX_LRCLK_SRC */
2317#define WM5100_AIF1TX_LRCLK_SRC_MASK 0x0008 /* AIF1TX_LRCLK_SRC */
2318#define WM5100_AIF1TX_LRCLK_SRC_SHIFT 3 /* AIF1TX_LRCLK_SRC */
2319#define WM5100_AIF1TX_LRCLK_SRC_WIDTH 1 /* AIF1TX_LRCLK_SRC */
2320#define WM5100_AIF1TX_LRCLK_INV 0x0004 /* AIF1TX_LRCLK_INV */
2321#define WM5100_AIF1TX_LRCLK_INV_MASK 0x0004 /* AIF1TX_LRCLK_INV */
2322#define WM5100_AIF1TX_LRCLK_INV_SHIFT 2 /* AIF1TX_LRCLK_INV */
2323#define WM5100_AIF1TX_LRCLK_INV_WIDTH 1 /* AIF1TX_LRCLK_INV */
2324#define WM5100_AIF1TX_LRCLK_FRC 0x0002 /* AIF1TX_LRCLK_FRC */
2325#define WM5100_AIF1TX_LRCLK_FRC_MASK 0x0002 /* AIF1TX_LRCLK_FRC */
2326#define WM5100_AIF1TX_LRCLK_FRC_SHIFT 1 /* AIF1TX_LRCLK_FRC */
2327#define WM5100_AIF1TX_LRCLK_FRC_WIDTH 1 /* AIF1TX_LRCLK_FRC */
2328#define WM5100_AIF1TX_LRCLK_MSTR 0x0001 /* AIF1TX_LRCLK_MSTR */
2329#define WM5100_AIF1TX_LRCLK_MSTR_MASK 0x0001 /* AIF1TX_LRCLK_MSTR */
2330#define WM5100_AIF1TX_LRCLK_MSTR_SHIFT 0 /* AIF1TX_LRCLK_MSTR */
2331#define WM5100_AIF1TX_LRCLK_MSTR_WIDTH 1 /* AIF1TX_LRCLK_MSTR */
2332
2333/*
2334 * R1282 (0x502) - Audio IF 1_3
2335 */
2336#define WM5100_AIF1RX_LRCLK_INV 0x0004 /* AIF1RX_LRCLK_INV */
2337#define WM5100_AIF1RX_LRCLK_INV_MASK 0x0004 /* AIF1RX_LRCLK_INV */
2338#define WM5100_AIF1RX_LRCLK_INV_SHIFT 2 /* AIF1RX_LRCLK_INV */
2339#define WM5100_AIF1RX_LRCLK_INV_WIDTH 1 /* AIF1RX_LRCLK_INV */
2340#define WM5100_AIF1RX_LRCLK_FRC 0x0002 /* AIF1RX_LRCLK_FRC */
2341#define WM5100_AIF1RX_LRCLK_FRC_MASK 0x0002 /* AIF1RX_LRCLK_FRC */
2342#define WM5100_AIF1RX_LRCLK_FRC_SHIFT 1 /* AIF1RX_LRCLK_FRC */
2343#define WM5100_AIF1RX_LRCLK_FRC_WIDTH 1 /* AIF1RX_LRCLK_FRC */
2344#define WM5100_AIF1RX_LRCLK_MSTR 0x0001 /* AIF1RX_LRCLK_MSTR */
2345#define WM5100_AIF1RX_LRCLK_MSTR_MASK 0x0001 /* AIF1RX_LRCLK_MSTR */
2346#define WM5100_AIF1RX_LRCLK_MSTR_SHIFT 0 /* AIF1RX_LRCLK_MSTR */
2347#define WM5100_AIF1RX_LRCLK_MSTR_WIDTH 1 /* AIF1RX_LRCLK_MSTR */
2348
2349/*
2350 * R1283 (0x503) - Audio IF 1_4
2351 */
2352#define WM5100_AIF1_TRI 0x0040 /* AIF1_TRI */
2353#define WM5100_AIF1_TRI_MASK 0x0040 /* AIF1_TRI */
2354#define WM5100_AIF1_TRI_SHIFT 6 /* AIF1_TRI */
2355#define WM5100_AIF1_TRI_WIDTH 1 /* AIF1_TRI */
2356#define WM5100_AIF1_RATE_MASK 0x0003 /* AIF1_RATE - [1:0] */
2357#define WM5100_AIF1_RATE_SHIFT 0 /* AIF1_RATE - [1:0] */
2358#define WM5100_AIF1_RATE_WIDTH 2 /* AIF1_RATE - [1:0] */
2359
2360/*
2361 * R1284 (0x504) - Audio IF 1_5
2362 */
2363#define WM5100_AIF1_FMT_MASK 0x0007 /* AIF1_FMT - [2:0] */
2364#define WM5100_AIF1_FMT_SHIFT 0 /* AIF1_FMT - [2:0] */
2365#define WM5100_AIF1_FMT_WIDTH 3 /* AIF1_FMT - [2:0] */
2366
2367/*
2368 * R1285 (0x505) - Audio IF 1_6
2369 */
2370#define WM5100_AIF1TX_BCPF_MASK 0x1FFF /* AIF1TX_BCPF - [12:0] */
2371#define WM5100_AIF1TX_BCPF_SHIFT 0 /* AIF1TX_BCPF - [12:0] */
2372#define WM5100_AIF1TX_BCPF_WIDTH 13 /* AIF1TX_BCPF - [12:0] */
2373
2374/*
2375 * R1286 (0x506) - Audio IF 1_7
2376 */
2377#define WM5100_AIF1RX_BCPF_MASK 0x1FFF /* AIF1RX_BCPF - [12:0] */
2378#define WM5100_AIF1RX_BCPF_SHIFT 0 /* AIF1RX_BCPF - [12:0] */
2379#define WM5100_AIF1RX_BCPF_WIDTH 13 /* AIF1RX_BCPF - [12:0] */
2380
2381/*
2382 * R1287 (0x507) - Audio IF 1_8
2383 */
2384#define WM5100_AIF1TX_WL_MASK 0x3F00 /* AIF1TX_WL - [13:8] */
2385#define WM5100_AIF1TX_WL_SHIFT 8 /* AIF1TX_WL - [13:8] */
2386#define WM5100_AIF1TX_WL_WIDTH 6 /* AIF1TX_WL - [13:8] */
2387#define WM5100_AIF1TX_SLOT_LEN_MASK 0x00FF /* AIF1TX_SLOT_LEN - [7:0] */
2388#define WM5100_AIF1TX_SLOT_LEN_SHIFT 0 /* AIF1TX_SLOT_LEN - [7:0] */
2389#define WM5100_AIF1TX_SLOT_LEN_WIDTH 8 /* AIF1TX_SLOT_LEN - [7:0] */
2390
2391/*
2392 * R1288 (0x508) - Audio IF 1_9
2393 */
2394#define WM5100_AIF1RX_WL_MASK 0x3F00 /* AIF1RX_WL - [13:8] */
2395#define WM5100_AIF1RX_WL_SHIFT 8 /* AIF1RX_WL - [13:8] */
2396#define WM5100_AIF1RX_WL_WIDTH 6 /* AIF1RX_WL - [13:8] */
2397#define WM5100_AIF1RX_SLOT_LEN_MASK 0x00FF /* AIF1RX_SLOT_LEN - [7:0] */
2398#define WM5100_AIF1RX_SLOT_LEN_SHIFT 0 /* AIF1RX_SLOT_LEN - [7:0] */
2399#define WM5100_AIF1RX_SLOT_LEN_WIDTH 8 /* AIF1RX_SLOT_LEN - [7:0] */
2400
2401/*
2402 * R1289 (0x509) - Audio IF 1_10
2403 */
2404#define WM5100_AIF1TX1_SLOT_MASK 0x003F /* AIF1TX1_SLOT - [5:0] */
2405#define WM5100_AIF1TX1_SLOT_SHIFT 0 /* AIF1TX1_SLOT - [5:0] */
2406#define WM5100_AIF1TX1_SLOT_WIDTH 6 /* AIF1TX1_SLOT - [5:0] */
2407
2408/*
2409 * R1290 (0x50A) - Audio IF 1_11
2410 */
2411#define WM5100_AIF1TX2_SLOT_MASK 0x003F /* AIF1TX2_SLOT - [5:0] */
2412#define WM5100_AIF1TX2_SLOT_SHIFT 0 /* AIF1TX2_SLOT - [5:0] */
2413#define WM5100_AIF1TX2_SLOT_WIDTH 6 /* AIF1TX2_SLOT - [5:0] */
2414
2415/*
2416 * R1291 (0x50B) - Audio IF 1_12
2417 */
2418#define WM5100_AIF1TX3_SLOT_MASK 0x003F /* AIF1TX3_SLOT - [5:0] */
2419#define WM5100_AIF1TX3_SLOT_SHIFT 0 /* AIF1TX3_SLOT - [5:0] */
2420#define WM5100_AIF1TX3_SLOT_WIDTH 6 /* AIF1TX3_SLOT - [5:0] */
2421
2422/*
2423 * R1292 (0x50C) - Audio IF 1_13
2424 */
2425#define WM5100_AIF1TX4_SLOT_MASK 0x003F /* AIF1TX4_SLOT - [5:0] */
2426#define WM5100_AIF1TX4_SLOT_SHIFT 0 /* AIF1TX4_SLOT - [5:0] */
2427#define WM5100_AIF1TX4_SLOT_WIDTH 6 /* AIF1TX4_SLOT - [5:0] */
2428
2429/*
2430 * R1293 (0x50D) - Audio IF 1_14
2431 */
2432#define WM5100_AIF1TX5_SLOT_MASK 0x003F /* AIF1TX5_SLOT - [5:0] */
2433#define WM5100_AIF1TX5_SLOT_SHIFT 0 /* AIF1TX5_SLOT - [5:0] */
2434#define WM5100_AIF1TX5_SLOT_WIDTH 6 /* AIF1TX5_SLOT - [5:0] */
2435
2436/*
2437 * R1294 (0x50E) - Audio IF 1_15
2438 */
2439#define WM5100_AIF1TX6_SLOT_MASK 0x003F /* AIF1TX6_SLOT - [5:0] */
2440#define WM5100_AIF1TX6_SLOT_SHIFT 0 /* AIF1TX6_SLOT - [5:0] */
2441#define WM5100_AIF1TX6_SLOT_WIDTH 6 /* AIF1TX6_SLOT - [5:0] */
2442
2443/*
2444 * R1295 (0x50F) - Audio IF 1_16
2445 */
2446#define WM5100_AIF1TX7_SLOT_MASK 0x003F /* AIF1TX7_SLOT - [5:0] */
2447#define WM5100_AIF1TX7_SLOT_SHIFT 0 /* AIF1TX7_SLOT - [5:0] */
2448#define WM5100_AIF1TX7_SLOT_WIDTH 6 /* AIF1TX7_SLOT - [5:0] */
2449
2450/*
2451 * R1296 (0x510) - Audio IF 1_17
2452 */
2453#define WM5100_AIF1TX8_SLOT_MASK 0x003F /* AIF1TX8_SLOT - [5:0] */
2454#define WM5100_AIF1TX8_SLOT_SHIFT 0 /* AIF1TX8_SLOT - [5:0] */
2455#define WM5100_AIF1TX8_SLOT_WIDTH 6 /* AIF1TX8_SLOT - [5:0] */
2456
2457/*
2458 * R1297 (0x511) - Audio IF 1_18
2459 */
2460#define WM5100_AIF1RX1_SLOT_MASK 0x003F /* AIF1RX1_SLOT - [5:0] */
2461#define WM5100_AIF1RX1_SLOT_SHIFT 0 /* AIF1RX1_SLOT - [5:0] */
2462#define WM5100_AIF1RX1_SLOT_WIDTH 6 /* AIF1RX1_SLOT - [5:0] */
2463
2464/*
2465 * R1298 (0x512) - Audio IF 1_19
2466 */
2467#define WM5100_AIF1RX2_SLOT_MASK 0x003F /* AIF1RX2_SLOT - [5:0] */
2468#define WM5100_AIF1RX2_SLOT_SHIFT 0 /* AIF1RX2_SLOT - [5:0] */
2469#define WM5100_AIF1RX2_SLOT_WIDTH 6 /* AIF1RX2_SLOT - [5:0] */
2470
2471/*
2472 * R1299 (0x513) - Audio IF 1_20
2473 */
2474#define WM5100_AIF1RX3_SLOT_MASK 0x003F /* AIF1RX3_SLOT - [5:0] */
2475#define WM5100_AIF1RX3_SLOT_SHIFT 0 /* AIF1RX3_SLOT - [5:0] */
2476#define WM5100_AIF1RX3_SLOT_WIDTH 6 /* AIF1RX3_SLOT - [5:0] */
2477
2478/*
2479 * R1300 (0x514) - Audio IF 1_21
2480 */
2481#define WM5100_AIF1RX4_SLOT_MASK 0x003F /* AIF1RX4_SLOT - [5:0] */
2482#define WM5100_AIF1RX4_SLOT_SHIFT 0 /* AIF1RX4_SLOT - [5:0] */
2483#define WM5100_AIF1RX4_SLOT_WIDTH 6 /* AIF1RX4_SLOT - [5:0] */
2484
2485/*
2486 * R1301 (0x515) - Audio IF 1_22
2487 */
2488#define WM5100_AIF1RX5_SLOT_MASK 0x003F /* AIF1RX5_SLOT - [5:0] */
2489#define WM5100_AIF1RX5_SLOT_SHIFT 0 /* AIF1RX5_SLOT - [5:0] */
2490#define WM5100_AIF1RX5_SLOT_WIDTH 6 /* AIF1RX5_SLOT - [5:0] */
2491
2492/*
2493 * R1302 (0x516) - Audio IF 1_23
2494 */
2495#define WM5100_AIF1RX6_SLOT_MASK 0x003F /* AIF1RX6_SLOT - [5:0] */
2496#define WM5100_AIF1RX6_SLOT_SHIFT 0 /* AIF1RX6_SLOT - [5:0] */
2497#define WM5100_AIF1RX6_SLOT_WIDTH 6 /* AIF1RX6_SLOT - [5:0] */
2498
2499/*
2500 * R1303 (0x517) - Audio IF 1_24
2501 */
2502#define WM5100_AIF1RX7_SLOT_MASK 0x003F /* AIF1RX7_SLOT - [5:0] */
2503#define WM5100_AIF1RX7_SLOT_SHIFT 0 /* AIF1RX7_SLOT - [5:0] */
2504#define WM5100_AIF1RX7_SLOT_WIDTH 6 /* AIF1RX7_SLOT - [5:0] */
2505
2506/*
2507 * R1304 (0x518) - Audio IF 1_25
2508 */
2509#define WM5100_AIF1RX8_SLOT_MASK 0x003F /* AIF1RX8_SLOT - [5:0] */
2510#define WM5100_AIF1RX8_SLOT_SHIFT 0 /* AIF1RX8_SLOT - [5:0] */
2511#define WM5100_AIF1RX8_SLOT_WIDTH 6 /* AIF1RX8_SLOT - [5:0] */
2512
2513/*
2514 * R1305 (0x519) - Audio IF 1_26
2515 */
2516#define WM5100_AIF1TX8_ENA 0x0080 /* AIF1TX8_ENA */
2517#define WM5100_AIF1TX8_ENA_MASK 0x0080 /* AIF1TX8_ENA */
2518#define WM5100_AIF1TX8_ENA_SHIFT 7 /* AIF1TX8_ENA */
2519#define WM5100_AIF1TX8_ENA_WIDTH 1 /* AIF1TX8_ENA */
2520#define WM5100_AIF1TX7_ENA 0x0040 /* AIF1TX7_ENA */
2521#define WM5100_AIF1TX7_ENA_MASK 0x0040 /* AIF1TX7_ENA */
2522#define WM5100_AIF1TX7_ENA_SHIFT 6 /* AIF1TX7_ENA */
2523#define WM5100_AIF1TX7_ENA_WIDTH 1 /* AIF1TX7_ENA */
2524#define WM5100_AIF1TX6_ENA 0x0020 /* AIF1TX6_ENA */
2525#define WM5100_AIF1TX6_ENA_MASK 0x0020 /* AIF1TX6_ENA */
2526#define WM5100_AIF1TX6_ENA_SHIFT 5 /* AIF1TX6_ENA */
2527#define WM5100_AIF1TX6_ENA_WIDTH 1 /* AIF1TX6_ENA */
2528#define WM5100_AIF1TX5_ENA 0x0010 /* AIF1TX5_ENA */
2529#define WM5100_AIF1TX5_ENA_MASK 0x0010 /* AIF1TX5_ENA */
2530#define WM5100_AIF1TX5_ENA_SHIFT 4 /* AIF1TX5_ENA */
2531#define WM5100_AIF1TX5_ENA_WIDTH 1 /* AIF1TX5_ENA */
2532#define WM5100_AIF1TX4_ENA 0x0008 /* AIF1TX4_ENA */
2533#define WM5100_AIF1TX4_ENA_MASK 0x0008 /* AIF1TX4_ENA */
2534#define WM5100_AIF1TX4_ENA_SHIFT 3 /* AIF1TX4_ENA */
2535#define WM5100_AIF1TX4_ENA_WIDTH 1 /* AIF1TX4_ENA */
2536#define WM5100_AIF1TX3_ENA 0x0004 /* AIF1TX3_ENA */
2537#define WM5100_AIF1TX3_ENA_MASK 0x0004 /* AIF1TX3_ENA */
2538#define WM5100_AIF1TX3_ENA_SHIFT 2 /* AIF1TX3_ENA */
2539#define WM5100_AIF1TX3_ENA_WIDTH 1 /* AIF1TX3_ENA */
2540#define WM5100_AIF1TX2_ENA 0x0002 /* AIF1TX2_ENA */
2541#define WM5100_AIF1TX2_ENA_MASK 0x0002 /* AIF1TX2_ENA */
2542#define WM5100_AIF1TX2_ENA_SHIFT 1 /* AIF1TX2_ENA */
2543#define WM5100_AIF1TX2_ENA_WIDTH 1 /* AIF1TX2_ENA */
2544#define WM5100_AIF1TX1_ENA 0x0001 /* AIF1TX1_ENA */
2545#define WM5100_AIF1TX1_ENA_MASK 0x0001 /* AIF1TX1_ENA */
2546#define WM5100_AIF1TX1_ENA_SHIFT 0 /* AIF1TX1_ENA */
2547#define WM5100_AIF1TX1_ENA_WIDTH 1 /* AIF1TX1_ENA */
2548
2549/*
2550 * R1306 (0x51A) - Audio IF 1_27
2551 */
2552#define WM5100_AIF1RX8_ENA 0x0080 /* AIF1RX8_ENA */
2553#define WM5100_AIF1RX8_ENA_MASK 0x0080 /* AIF1RX8_ENA */
2554#define WM5100_AIF1RX8_ENA_SHIFT 7 /* AIF1RX8_ENA */
2555#define WM5100_AIF1RX8_ENA_WIDTH 1 /* AIF1RX8_ENA */
2556#define WM5100_AIF1RX7_ENA 0x0040 /* AIF1RX7_ENA */
2557#define WM5100_AIF1RX7_ENA_MASK 0x0040 /* AIF1RX7_ENA */
2558#define WM5100_AIF1RX7_ENA_SHIFT 6 /* AIF1RX7_ENA */
2559#define WM5100_AIF1RX7_ENA_WIDTH 1 /* AIF1RX7_ENA */
2560#define WM5100_AIF1RX6_ENA 0x0020 /* AIF1RX6_ENA */
2561#define WM5100_AIF1RX6_ENA_MASK 0x0020 /* AIF1RX6_ENA */
2562#define WM5100_AIF1RX6_ENA_SHIFT 5 /* AIF1RX6_ENA */
2563#define WM5100_AIF1RX6_ENA_WIDTH 1 /* AIF1RX6_ENA */
2564#define WM5100_AIF1RX5_ENA 0x0010 /* AIF1RX5_ENA */
2565#define WM5100_AIF1RX5_ENA_MASK 0x0010 /* AIF1RX5_ENA */
2566#define WM5100_AIF1RX5_ENA_SHIFT 4 /* AIF1RX5_ENA */
2567#define WM5100_AIF1RX5_ENA_WIDTH 1 /* AIF1RX5_ENA */
2568#define WM5100_AIF1RX4_ENA 0x0008 /* AIF1RX4_ENA */
2569#define WM5100_AIF1RX4_ENA_MASK 0x0008 /* AIF1RX4_ENA */
2570#define WM5100_AIF1RX4_ENA_SHIFT 3 /* AIF1RX4_ENA */
2571#define WM5100_AIF1RX4_ENA_WIDTH 1 /* AIF1RX4_ENA */
2572#define WM5100_AIF1RX3_ENA 0x0004 /* AIF1RX3_ENA */
2573#define WM5100_AIF1RX3_ENA_MASK 0x0004 /* AIF1RX3_ENA */
2574#define WM5100_AIF1RX3_ENA_SHIFT 2 /* AIF1RX3_ENA */
2575#define WM5100_AIF1RX3_ENA_WIDTH 1 /* AIF1RX3_ENA */
2576#define WM5100_AIF1RX2_ENA 0x0002 /* AIF1RX2_ENA */
2577#define WM5100_AIF1RX2_ENA_MASK 0x0002 /* AIF1RX2_ENA */
2578#define WM5100_AIF1RX2_ENA_SHIFT 1 /* AIF1RX2_ENA */
2579#define WM5100_AIF1RX2_ENA_WIDTH 1 /* AIF1RX2_ENA */
2580#define WM5100_AIF1RX1_ENA 0x0001 /* AIF1RX1_ENA */
2581#define WM5100_AIF1RX1_ENA_MASK 0x0001 /* AIF1RX1_ENA */
2582#define WM5100_AIF1RX1_ENA_SHIFT 0 /* AIF1RX1_ENA */
2583#define WM5100_AIF1RX1_ENA_WIDTH 1 /* AIF1RX1_ENA */
2584
2585/*
2586 * R1344 (0x540) - Audio IF 2_1
2587 */
2588#define WM5100_AIF2_BCLK_INV 0x0080 /* AIF2_BCLK_INV */
2589#define WM5100_AIF2_BCLK_INV_MASK 0x0080 /* AIF2_BCLK_INV */
2590#define WM5100_AIF2_BCLK_INV_SHIFT 7 /* AIF2_BCLK_INV */
2591#define WM5100_AIF2_BCLK_INV_WIDTH 1 /* AIF2_BCLK_INV */
2592#define WM5100_AIF2_BCLK_FRC 0x0040 /* AIF2_BCLK_FRC */
2593#define WM5100_AIF2_BCLK_FRC_MASK 0x0040 /* AIF2_BCLK_FRC */
2594#define WM5100_AIF2_BCLK_FRC_SHIFT 6 /* AIF2_BCLK_FRC */
2595#define WM5100_AIF2_BCLK_FRC_WIDTH 1 /* AIF2_BCLK_FRC */
2596#define WM5100_AIF2_BCLK_MSTR 0x0020 /* AIF2_BCLK_MSTR */
2597#define WM5100_AIF2_BCLK_MSTR_MASK 0x0020 /* AIF2_BCLK_MSTR */
2598#define WM5100_AIF2_BCLK_MSTR_SHIFT 5 /* AIF2_BCLK_MSTR */
2599#define WM5100_AIF2_BCLK_MSTR_WIDTH 1 /* AIF2_BCLK_MSTR */
2600#define WM5100_AIF2_BCLK_FREQ_MASK 0x001F /* AIF2_BCLK_FREQ - [4:0] */
2601#define WM5100_AIF2_BCLK_FREQ_SHIFT 0 /* AIF2_BCLK_FREQ - [4:0] */
2602#define WM5100_AIF2_BCLK_FREQ_WIDTH 5 /* AIF2_BCLK_FREQ - [4:0] */
2603
2604/*
2605 * R1345 (0x541) - Audio IF 2_2
2606 */
2607#define WM5100_AIF2TX_DAT_TRI 0x0020 /* AIF2TX_DAT_TRI */
2608#define WM5100_AIF2TX_DAT_TRI_MASK 0x0020 /* AIF2TX_DAT_TRI */
2609#define WM5100_AIF2TX_DAT_TRI_SHIFT 5 /* AIF2TX_DAT_TRI */
2610#define WM5100_AIF2TX_DAT_TRI_WIDTH 1 /* AIF2TX_DAT_TRI */
2611#define WM5100_AIF2TX_LRCLK_SRC 0x0008 /* AIF2TX_LRCLK_SRC */
2612#define WM5100_AIF2TX_LRCLK_SRC_MASK 0x0008 /* AIF2TX_LRCLK_SRC */
2613#define WM5100_AIF2TX_LRCLK_SRC_SHIFT 3 /* AIF2TX_LRCLK_SRC */
2614#define WM5100_AIF2TX_LRCLK_SRC_WIDTH 1 /* AIF2TX_LRCLK_SRC */
2615#define WM5100_AIF2TX_LRCLK_INV 0x0004 /* AIF2TX_LRCLK_INV */
2616#define WM5100_AIF2TX_LRCLK_INV_MASK 0x0004 /* AIF2TX_LRCLK_INV */
2617#define WM5100_AIF2TX_LRCLK_INV_SHIFT 2 /* AIF2TX_LRCLK_INV */
2618#define WM5100_AIF2TX_LRCLK_INV_WIDTH 1 /* AIF2TX_LRCLK_INV */
2619#define WM5100_AIF2TX_LRCLK_FRC 0x0002 /* AIF2TX_LRCLK_FRC */
2620#define WM5100_AIF2TX_LRCLK_FRC_MASK 0x0002 /* AIF2TX_LRCLK_FRC */
2621#define WM5100_AIF2TX_LRCLK_FRC_SHIFT 1 /* AIF2TX_LRCLK_FRC */
2622#define WM5100_AIF2TX_LRCLK_FRC_WIDTH 1 /* AIF2TX_LRCLK_FRC */
2623#define WM5100_AIF2TX_LRCLK_MSTR 0x0001 /* AIF2TX_LRCLK_MSTR */
2624#define WM5100_AIF2TX_LRCLK_MSTR_MASK 0x0001 /* AIF2TX_LRCLK_MSTR */
2625#define WM5100_AIF2TX_LRCLK_MSTR_SHIFT 0 /* AIF2TX_LRCLK_MSTR */
2626#define WM5100_AIF2TX_LRCLK_MSTR_WIDTH 1 /* AIF2TX_LRCLK_MSTR */
2627
2628/*
2629 * R1346 (0x542) - Audio IF 2_3
2630 */
2631#define WM5100_AIF2RX_LRCLK_INV 0x0004 /* AIF2RX_LRCLK_INV */
2632#define WM5100_AIF2RX_LRCLK_INV_MASK 0x0004 /* AIF2RX_LRCLK_INV */
2633#define WM5100_AIF2RX_LRCLK_INV_SHIFT 2 /* AIF2RX_LRCLK_INV */
2634#define WM5100_AIF2RX_LRCLK_INV_WIDTH 1 /* AIF2RX_LRCLK_INV */
2635#define WM5100_AIF2RX_LRCLK_FRC 0x0002 /* AIF2RX_LRCLK_FRC */
2636#define WM5100_AIF2RX_LRCLK_FRC_MASK 0x0002 /* AIF2RX_LRCLK_FRC */
2637#define WM5100_AIF2RX_LRCLK_FRC_SHIFT 1 /* AIF2RX_LRCLK_FRC */
2638#define WM5100_AIF2RX_LRCLK_FRC_WIDTH 1 /* AIF2RX_LRCLK_FRC */
2639#define WM5100_AIF2RX_LRCLK_MSTR 0x0001 /* AIF2RX_LRCLK_MSTR */
2640#define WM5100_AIF2RX_LRCLK_MSTR_MASK 0x0001 /* AIF2RX_LRCLK_MSTR */
2641#define WM5100_AIF2RX_LRCLK_MSTR_SHIFT 0 /* AIF2RX_LRCLK_MSTR */
2642#define WM5100_AIF2RX_LRCLK_MSTR_WIDTH 1 /* AIF2RX_LRCLK_MSTR */
2643
2644/*
2645 * R1347 (0x543) - Audio IF 2_4
2646 */
2647#define WM5100_AIF2_TRI 0x0040 /* AIF2_TRI */
2648#define WM5100_AIF2_TRI_MASK 0x0040 /* AIF2_TRI */
2649#define WM5100_AIF2_TRI_SHIFT 6 /* AIF2_TRI */
2650#define WM5100_AIF2_TRI_WIDTH 1 /* AIF2_TRI */
2651#define WM5100_AIF2_RATE_MASK 0x0003 /* AIF2_RATE - [1:0] */
2652#define WM5100_AIF2_RATE_SHIFT 0 /* AIF2_RATE - [1:0] */
2653#define WM5100_AIF2_RATE_WIDTH 2 /* AIF2_RATE - [1:0] */
2654
2655/*
2656 * R1348 (0x544) - Audio IF 2_5
2657 */
2658#define WM5100_AIF2_FMT_MASK 0x0007 /* AIF2_FMT - [2:0] */
2659#define WM5100_AIF2_FMT_SHIFT 0 /* AIF2_FMT - [2:0] */
2660#define WM5100_AIF2_FMT_WIDTH 3 /* AIF2_FMT - [2:0] */
2661
2662/*
2663 * R1349 (0x545) - Audio IF 2_6
2664 */
2665#define WM5100_AIF2TX_BCPF_MASK 0x1FFF /* AIF2TX_BCPF - [12:0] */
2666#define WM5100_AIF2TX_BCPF_SHIFT 0 /* AIF2TX_BCPF - [12:0] */
2667#define WM5100_AIF2TX_BCPF_WIDTH 13 /* AIF2TX_BCPF - [12:0] */
2668
2669/*
2670 * R1350 (0x546) - Audio IF 2_7
2671 */
2672#define WM5100_AIF2RX_BCPF_MASK 0x1FFF /* AIF2RX_BCPF - [12:0] */
2673#define WM5100_AIF2RX_BCPF_SHIFT 0 /* AIF2RX_BCPF - [12:0] */
2674#define WM5100_AIF2RX_BCPF_WIDTH 13 /* AIF2RX_BCPF - [12:0] */
2675
2676/*
2677 * R1351 (0x547) - Audio IF 2_8
2678 */
2679#define WM5100_AIF2TX_WL_MASK 0x3F00 /* AIF2TX_WL - [13:8] */
2680#define WM5100_AIF2TX_WL_SHIFT 8 /* AIF2TX_WL - [13:8] */
2681#define WM5100_AIF2TX_WL_WIDTH 6 /* AIF2TX_WL - [13:8] */
2682#define WM5100_AIF2TX_SLOT_LEN_MASK 0x00FF /* AIF2TX_SLOT_LEN - [7:0] */
2683#define WM5100_AIF2TX_SLOT_LEN_SHIFT 0 /* AIF2TX_SLOT_LEN - [7:0] */
2684#define WM5100_AIF2TX_SLOT_LEN_WIDTH 8 /* AIF2TX_SLOT_LEN - [7:0] */
2685
2686/*
2687 * R1352 (0x548) - Audio IF 2_9
2688 */
2689#define WM5100_AIF2RX_WL_MASK 0x3F00 /* AIF2RX_WL - [13:8] */
2690#define WM5100_AIF2RX_WL_SHIFT 8 /* AIF2RX_WL - [13:8] */
2691#define WM5100_AIF2RX_WL_WIDTH 6 /* AIF2RX_WL - [13:8] */
2692#define WM5100_AIF2RX_SLOT_LEN_MASK 0x00FF /* AIF2RX_SLOT_LEN - [7:0] */
2693#define WM5100_AIF2RX_SLOT_LEN_SHIFT 0 /* AIF2RX_SLOT_LEN - [7:0] */
2694#define WM5100_AIF2RX_SLOT_LEN_WIDTH 8 /* AIF2RX_SLOT_LEN - [7:0] */
2695
2696/*
2697 * R1353 (0x549) - Audio IF 2_10
2698 */
2699#define WM5100_AIF2TX1_SLOT_MASK 0x003F /* AIF2TX1_SLOT - [5:0] */
2700#define WM5100_AIF2TX1_SLOT_SHIFT 0 /* AIF2TX1_SLOT - [5:0] */
2701#define WM5100_AIF2TX1_SLOT_WIDTH 6 /* AIF2TX1_SLOT - [5:0] */
2702
2703/*
2704 * R1354 (0x54A) - Audio IF 2_11
2705 */
2706#define WM5100_AIF2TX2_SLOT_MASK 0x003F /* AIF2TX2_SLOT - [5:0] */
2707#define WM5100_AIF2TX2_SLOT_SHIFT 0 /* AIF2TX2_SLOT - [5:0] */
2708#define WM5100_AIF2TX2_SLOT_WIDTH 6 /* AIF2TX2_SLOT - [5:0] */
2709
2710/*
2711 * R1361 (0x551) - Audio IF 2_18
2712 */
2713#define WM5100_AIF2RX1_SLOT_MASK 0x003F /* AIF2RX1_SLOT - [5:0] */
2714#define WM5100_AIF2RX1_SLOT_SHIFT 0 /* AIF2RX1_SLOT - [5:0] */
2715#define WM5100_AIF2RX1_SLOT_WIDTH 6 /* AIF2RX1_SLOT - [5:0] */
2716
2717/*
2718 * R1362 (0x552) - Audio IF 2_19
2719 */
2720#define WM5100_AIF2RX2_SLOT_MASK 0x003F /* AIF2RX2_SLOT - [5:0] */
2721#define WM5100_AIF2RX2_SLOT_SHIFT 0 /* AIF2RX2_SLOT - [5:0] */
2722#define WM5100_AIF2RX2_SLOT_WIDTH 6 /* AIF2RX2_SLOT - [5:0] */
2723
2724/*
2725 * R1369 (0x559) - Audio IF 2_26
2726 */
2727#define WM5100_AIF2TX2_ENA 0x0002 /* AIF2TX2_ENA */
2728#define WM5100_AIF2TX2_ENA_MASK 0x0002 /* AIF2TX2_ENA */
2729#define WM5100_AIF2TX2_ENA_SHIFT 1 /* AIF2TX2_ENA */
2730#define WM5100_AIF2TX2_ENA_WIDTH 1 /* AIF2TX2_ENA */
2731#define WM5100_AIF2TX1_ENA 0x0001 /* AIF2TX1_ENA */
2732#define WM5100_AIF2TX1_ENA_MASK 0x0001 /* AIF2TX1_ENA */
2733#define WM5100_AIF2TX1_ENA_SHIFT 0 /* AIF2TX1_ENA */
2734#define WM5100_AIF2TX1_ENA_WIDTH 1 /* AIF2TX1_ENA */
2735
2736/*
2737 * R1370 (0x55A) - Audio IF 2_27
2738 */
2739#define WM5100_AIF2RX2_ENA 0x0002 /* AIF2RX2_ENA */
2740#define WM5100_AIF2RX2_ENA_MASK 0x0002 /* AIF2RX2_ENA */
2741#define WM5100_AIF2RX2_ENA_SHIFT 1 /* AIF2RX2_ENA */
2742#define WM5100_AIF2RX2_ENA_WIDTH 1 /* AIF2RX2_ENA */
2743#define WM5100_AIF2RX1_ENA 0x0001 /* AIF2RX1_ENA */
2744#define WM5100_AIF2RX1_ENA_MASK 0x0001 /* AIF2RX1_ENA */
2745#define WM5100_AIF2RX1_ENA_SHIFT 0 /* AIF2RX1_ENA */
2746#define WM5100_AIF2RX1_ENA_WIDTH 1 /* AIF2RX1_ENA */
2747
2748/*
2749 * R1408 (0x580) - Audio IF 3_1
2750 */
2751#define WM5100_AIF3_BCLK_INV 0x0080 /* AIF3_BCLK_INV */
2752#define WM5100_AIF3_BCLK_INV_MASK 0x0080 /* AIF3_BCLK_INV */
2753#define WM5100_AIF3_BCLK_INV_SHIFT 7 /* AIF3_BCLK_INV */
2754#define WM5100_AIF3_BCLK_INV_WIDTH 1 /* AIF3_BCLK_INV */
2755#define WM5100_AIF3_BCLK_FRC 0x0040 /* AIF3_BCLK_FRC */
2756#define WM5100_AIF3_BCLK_FRC_MASK 0x0040 /* AIF3_BCLK_FRC */
2757#define WM5100_AIF3_BCLK_FRC_SHIFT 6 /* AIF3_BCLK_FRC */
2758#define WM5100_AIF3_BCLK_FRC_WIDTH 1 /* AIF3_BCLK_FRC */
2759#define WM5100_AIF3_BCLK_MSTR 0x0020 /* AIF3_BCLK_MSTR */
2760#define WM5100_AIF3_BCLK_MSTR_MASK 0x0020 /* AIF3_BCLK_MSTR */
2761#define WM5100_AIF3_BCLK_MSTR_SHIFT 5 /* AIF3_BCLK_MSTR */
2762#define WM5100_AIF3_BCLK_MSTR_WIDTH 1 /* AIF3_BCLK_MSTR */
2763#define WM5100_AIF3_BCLK_FREQ_MASK 0x001F /* AIF3_BCLK_FREQ - [4:0] */
2764#define WM5100_AIF3_BCLK_FREQ_SHIFT 0 /* AIF3_BCLK_FREQ - [4:0] */
2765#define WM5100_AIF3_BCLK_FREQ_WIDTH 5 /* AIF3_BCLK_FREQ - [4:0] */
2766
2767/*
2768 * R1409 (0x581) - Audio IF 3_2
2769 */
2770#define WM5100_AIF3TX_DAT_TRI 0x0020 /* AIF3TX_DAT_TRI */
2771#define WM5100_AIF3TX_DAT_TRI_MASK 0x0020 /* AIF3TX_DAT_TRI */
2772#define WM5100_AIF3TX_DAT_TRI_SHIFT 5 /* AIF3TX_DAT_TRI */
2773#define WM5100_AIF3TX_DAT_TRI_WIDTH 1 /* AIF3TX_DAT_TRI */
2774#define WM5100_AIF3TX_LRCLK_SRC 0x0008 /* AIF3TX_LRCLK_SRC */
2775#define WM5100_AIF3TX_LRCLK_SRC_MASK 0x0008 /* AIF3TX_LRCLK_SRC */
2776#define WM5100_AIF3TX_LRCLK_SRC_SHIFT 3 /* AIF3TX_LRCLK_SRC */
2777#define WM5100_AIF3TX_LRCLK_SRC_WIDTH 1 /* AIF3TX_LRCLK_SRC */
2778#define WM5100_AIF3TX_LRCLK_INV 0x0004 /* AIF3TX_LRCLK_INV */
2779#define WM5100_AIF3TX_LRCLK_INV_MASK 0x0004 /* AIF3TX_LRCLK_INV */
2780#define WM5100_AIF3TX_LRCLK_INV_SHIFT 2 /* AIF3TX_LRCLK_INV */
2781#define WM5100_AIF3TX_LRCLK_INV_WIDTH 1 /* AIF3TX_LRCLK_INV */
2782#define WM5100_AIF3TX_LRCLK_FRC 0x0002 /* AIF3TX_LRCLK_FRC */
2783#define WM5100_AIF3TX_LRCLK_FRC_MASK 0x0002 /* AIF3TX_LRCLK_FRC */
2784#define WM5100_AIF3TX_LRCLK_FRC_SHIFT 1 /* AIF3TX_LRCLK_FRC */
2785#define WM5100_AIF3TX_LRCLK_FRC_WIDTH 1 /* AIF3TX_LRCLK_FRC */
2786#define WM5100_AIF3TX_LRCLK_MSTR 0x0001 /* AIF3TX_LRCLK_MSTR */
2787#define WM5100_AIF3TX_LRCLK_MSTR_MASK 0x0001 /* AIF3TX_LRCLK_MSTR */
2788#define WM5100_AIF3TX_LRCLK_MSTR_SHIFT 0 /* AIF3TX_LRCLK_MSTR */
2789#define WM5100_AIF3TX_LRCLK_MSTR_WIDTH 1 /* AIF3TX_LRCLK_MSTR */
2790
2791/*
2792 * R1410 (0x582) - Audio IF 3_3
2793 */
2794#define WM5100_AIF3RX_LRCLK_INV 0x0004 /* AIF3RX_LRCLK_INV */
2795#define WM5100_AIF3RX_LRCLK_INV_MASK 0x0004 /* AIF3RX_LRCLK_INV */
2796#define WM5100_AIF3RX_LRCLK_INV_SHIFT 2 /* AIF3RX_LRCLK_INV */
2797#define WM5100_AIF3RX_LRCLK_INV_WIDTH 1 /* AIF3RX_LRCLK_INV */
2798#define WM5100_AIF3RX_LRCLK_FRC 0x0002 /* AIF3RX_LRCLK_FRC */
2799#define WM5100_AIF3RX_LRCLK_FRC_MASK 0x0002 /* AIF3RX_LRCLK_FRC */
2800#define WM5100_AIF3RX_LRCLK_FRC_SHIFT 1 /* AIF3RX_LRCLK_FRC */
2801#define WM5100_AIF3RX_LRCLK_FRC_WIDTH 1 /* AIF3RX_LRCLK_FRC */
2802#define WM5100_AIF3RX_LRCLK_MSTR 0x0001 /* AIF3RX_LRCLK_MSTR */
2803#define WM5100_AIF3RX_LRCLK_MSTR_MASK 0x0001 /* AIF3RX_LRCLK_MSTR */
2804#define WM5100_AIF3RX_LRCLK_MSTR_SHIFT 0 /* AIF3RX_LRCLK_MSTR */
2805#define WM5100_AIF3RX_LRCLK_MSTR_WIDTH 1 /* AIF3RX_LRCLK_MSTR */
2806
2807/*
2808 * R1411 (0x583) - Audio IF 3_4
2809 */
2810#define WM5100_AIF3_TRI 0x0040 /* AIF3_TRI */
2811#define WM5100_AIF3_TRI_MASK 0x0040 /* AIF3_TRI */
2812#define WM5100_AIF3_TRI_SHIFT 6 /* AIF3_TRI */
2813#define WM5100_AIF3_TRI_WIDTH 1 /* AIF3_TRI */
2814#define WM5100_AIF3_RATE_MASK 0x0003 /* AIF3_RATE - [1:0] */
2815#define WM5100_AIF3_RATE_SHIFT 0 /* AIF3_RATE - [1:0] */
2816#define WM5100_AIF3_RATE_WIDTH 2 /* AIF3_RATE - [1:0] */
2817
2818/*
2819 * R1412 (0x584) - Audio IF 3_5
2820 */
2821#define WM5100_AIF3_FMT_MASK 0x0007 /* AIF3_FMT - [2:0] */
2822#define WM5100_AIF3_FMT_SHIFT 0 /* AIF3_FMT - [2:0] */
2823#define WM5100_AIF3_FMT_WIDTH 3 /* AIF3_FMT - [2:0] */
2824
2825/*
2826 * R1413 (0x585) - Audio IF 3_6
2827 */
2828#define WM5100_AIF3TX_BCPF_MASK 0x1FFF /* AIF3TX_BCPF - [12:0] */
2829#define WM5100_AIF3TX_BCPF_SHIFT 0 /* AIF3TX_BCPF - [12:0] */
2830#define WM5100_AIF3TX_BCPF_WIDTH 13 /* AIF3TX_BCPF - [12:0] */
2831
2832/*
2833 * R1414 (0x586) - Audio IF 3_7
2834 */
2835#define WM5100_AIF3RX_BCPF_MASK 0x1FFF /* AIF3RX_BCPF - [12:0] */
2836#define WM5100_AIF3RX_BCPF_SHIFT 0 /* AIF3RX_BCPF - [12:0] */
2837#define WM5100_AIF3RX_BCPF_WIDTH 13 /* AIF3RX_BCPF - [12:0] */
2838
2839/*
2840 * R1415 (0x587) - Audio IF 3_8
2841 */
2842#define WM5100_AIF3TX_WL_MASK 0x3F00 /* AIF3TX_WL - [13:8] */
2843#define WM5100_AIF3TX_WL_SHIFT 8 /* AIF3TX_WL - [13:8] */
2844#define WM5100_AIF3TX_WL_WIDTH 6 /* AIF3TX_WL - [13:8] */
2845#define WM5100_AIF3TX_SLOT_LEN_MASK 0x00FF /* AIF3TX_SLOT_LEN - [7:0] */
2846#define WM5100_AIF3TX_SLOT_LEN_SHIFT 0 /* AIF3TX_SLOT_LEN - [7:0] */
2847#define WM5100_AIF3TX_SLOT_LEN_WIDTH 8 /* AIF3TX_SLOT_LEN - [7:0] */
2848
2849/*
2850 * R1416 (0x588) - Audio IF 3_9
2851 */
2852#define WM5100_AIF3RX_WL_MASK 0x3F00 /* AIF3RX_WL - [13:8] */
2853#define WM5100_AIF3RX_WL_SHIFT 8 /* AIF3RX_WL - [13:8] */
2854#define WM5100_AIF3RX_WL_WIDTH 6 /* AIF3RX_WL - [13:8] */
2855#define WM5100_AIF3RX_SLOT_LEN_MASK 0x00FF /* AIF3RX_SLOT_LEN - [7:0] */
2856#define WM5100_AIF3RX_SLOT_LEN_SHIFT 0 /* AIF3RX_SLOT_LEN - [7:0] */
2857#define WM5100_AIF3RX_SLOT_LEN_WIDTH 8 /* AIF3RX_SLOT_LEN - [7:0] */
2858
2859/*
2860 * R1417 (0x589) - Audio IF 3_10
2861 */
2862#define WM5100_AIF3TX1_SLOT_MASK 0x003F /* AIF3TX1_SLOT - [5:0] */
2863#define WM5100_AIF3TX1_SLOT_SHIFT 0 /* AIF3TX1_SLOT - [5:0] */
2864#define WM5100_AIF3TX1_SLOT_WIDTH 6 /* AIF3TX1_SLOT - [5:0] */
2865
2866/*
2867 * R1418 (0x58A) - Audio IF 3_11
2868 */
2869#define WM5100_AIF3TX2_SLOT_MASK 0x003F /* AIF3TX2_SLOT - [5:0] */
2870#define WM5100_AIF3TX2_SLOT_SHIFT 0 /* AIF3TX2_SLOT - [5:0] */
2871#define WM5100_AIF3TX2_SLOT_WIDTH 6 /* AIF3TX2_SLOT - [5:0] */
2872
2873/*
2874 * R1425 (0x591) - Audio IF 3_18
2875 */
2876#define WM5100_AIF3RX1_SLOT_MASK 0x003F /* AIF3RX1_SLOT - [5:0] */
2877#define WM5100_AIF3RX1_SLOT_SHIFT 0 /* AIF3RX1_SLOT - [5:0] */
2878#define WM5100_AIF3RX1_SLOT_WIDTH 6 /* AIF3RX1_SLOT - [5:0] */
2879
2880/*
2881 * R1426 (0x592) - Audio IF 3_19
2882 */
2883#define WM5100_AIF3RX2_SLOT_MASK 0x003F /* AIF3RX2_SLOT - [5:0] */
2884#define WM5100_AIF3RX2_SLOT_SHIFT 0 /* AIF3RX2_SLOT - [5:0] */
2885#define WM5100_AIF3RX2_SLOT_WIDTH 6 /* AIF3RX2_SLOT - [5:0] */
2886
2887/*
2888 * R1433 (0x599) - Audio IF 3_26
2889 */
2890#define WM5100_AIF3TX2_ENA 0x0002 /* AIF3TX2_ENA */
2891#define WM5100_AIF3TX2_ENA_MASK 0x0002 /* AIF3TX2_ENA */
2892#define WM5100_AIF3TX2_ENA_SHIFT 1 /* AIF3TX2_ENA */
2893#define WM5100_AIF3TX2_ENA_WIDTH 1 /* AIF3TX2_ENA */
2894#define WM5100_AIF3TX1_ENA 0x0001 /* AIF3TX1_ENA */
2895#define WM5100_AIF3TX1_ENA_MASK 0x0001 /* AIF3TX1_ENA */
2896#define WM5100_AIF3TX1_ENA_SHIFT 0 /* AIF3TX1_ENA */
2897#define WM5100_AIF3TX1_ENA_WIDTH 1 /* AIF3TX1_ENA */
2898
2899/*
2900 * R1434 (0x59A) - Audio IF 3_27
2901 */
2902#define WM5100_AIF3RX2_ENA 0x0002 /* AIF3RX2_ENA */
2903#define WM5100_AIF3RX2_ENA_MASK 0x0002 /* AIF3RX2_ENA */
2904#define WM5100_AIF3RX2_ENA_SHIFT 1 /* AIF3RX2_ENA */
2905#define WM5100_AIF3RX2_ENA_WIDTH 1 /* AIF3RX2_ENA */
2906#define WM5100_AIF3RX1_ENA 0x0001 /* AIF3RX1_ENA */
2907#define WM5100_AIF3RX1_ENA_MASK 0x0001 /* AIF3RX1_ENA */
2908#define WM5100_AIF3RX1_ENA_SHIFT 0 /* AIF3RX1_ENA */
2909#define WM5100_AIF3RX1_ENA_WIDTH 1 /* AIF3RX1_ENA */
2910
2911#define WM5100_MIXER_VOL_MASK 0x00FE /* MIXER_VOL - [7:1] */
2912#define WM5100_MIXER_VOL_SHIFT 1 /* MIXER_VOL - [7:1] */
2913#define WM5100_MIXER_VOL_WIDTH 7 /* MIXER_VOL - [7:1] */
2914
2915/*
2916 * R3072 (0xC00) - GPIO CTRL 1
2917 */
2918#define WM5100_GP1_DIR 0x8000 /* GP1_DIR */
2919#define WM5100_GP1_DIR_MASK 0x8000 /* GP1_DIR */
2920#define WM5100_GP1_DIR_SHIFT 15 /* GP1_DIR */
2921#define WM5100_GP1_DIR_WIDTH 1 /* GP1_DIR */
2922#define WM5100_GP1_PU 0x4000 /* GP1_PU */
2923#define WM5100_GP1_PU_MASK 0x4000 /* GP1_PU */
2924#define WM5100_GP1_PU_SHIFT 14 /* GP1_PU */
2925#define WM5100_GP1_PU_WIDTH 1 /* GP1_PU */
2926#define WM5100_GP1_PD 0x2000 /* GP1_PD */
2927#define WM5100_GP1_PD_MASK 0x2000 /* GP1_PD */
2928#define WM5100_GP1_PD_SHIFT 13 /* GP1_PD */
2929#define WM5100_GP1_PD_WIDTH 1 /* GP1_PD */
2930#define WM5100_GP1_POL 0x0400 /* GP1_POL */
2931#define WM5100_GP1_POL_MASK 0x0400 /* GP1_POL */
2932#define WM5100_GP1_POL_SHIFT 10 /* GP1_POL */
2933#define WM5100_GP1_POL_WIDTH 1 /* GP1_POL */
2934#define WM5100_GP1_OP_CFG 0x0200 /* GP1_OP_CFG */
2935#define WM5100_GP1_OP_CFG_MASK 0x0200 /* GP1_OP_CFG */
2936#define WM5100_GP1_OP_CFG_SHIFT 9 /* GP1_OP_CFG */
2937#define WM5100_GP1_OP_CFG_WIDTH 1 /* GP1_OP_CFG */
2938#define WM5100_GP1_DB 0x0100 /* GP1_DB */
2939#define WM5100_GP1_DB_MASK 0x0100 /* GP1_DB */
2940#define WM5100_GP1_DB_SHIFT 8 /* GP1_DB */
2941#define WM5100_GP1_DB_WIDTH 1 /* GP1_DB */
2942#define WM5100_GP1_LVL 0x0040 /* GP1_LVL */
2943#define WM5100_GP1_LVL_MASK 0x0040 /* GP1_LVL */
2944#define WM5100_GP1_LVL_SHIFT 6 /* GP1_LVL */
2945#define WM5100_GP1_LVL_WIDTH 1 /* GP1_LVL */
2946#define WM5100_GP1_FN_MASK 0x003F /* GP1_FN - [5:0] */
2947#define WM5100_GP1_FN_SHIFT 0 /* GP1_FN - [5:0] */
2948#define WM5100_GP1_FN_WIDTH 6 /* GP1_FN - [5:0] */
2949
2950/*
2951 * R3073 (0xC01) - GPIO CTRL 2
2952 */
2953#define WM5100_GP2_DIR 0x8000 /* GP2_DIR */
2954#define WM5100_GP2_DIR_MASK 0x8000 /* GP2_DIR */
2955#define WM5100_GP2_DIR_SHIFT 15 /* GP2_DIR */
2956#define WM5100_GP2_DIR_WIDTH 1 /* GP2_DIR */
2957#define WM5100_GP2_PU 0x4000 /* GP2_PU */
2958#define WM5100_GP2_PU_MASK 0x4000 /* GP2_PU */
2959#define WM5100_GP2_PU_SHIFT 14 /* GP2_PU */
2960#define WM5100_GP2_PU_WIDTH 1 /* GP2_PU */
2961#define WM5100_GP2_PD 0x2000 /* GP2_PD */
2962#define WM5100_GP2_PD_MASK 0x2000 /* GP2_PD */
2963#define WM5100_GP2_PD_SHIFT 13 /* GP2_PD */
2964#define WM5100_GP2_PD_WIDTH 1 /* GP2_PD */
2965#define WM5100_GP2_POL 0x0400 /* GP2_POL */
2966#define WM5100_GP2_POL_MASK 0x0400 /* GP2_POL */
2967#define WM5100_GP2_POL_SHIFT 10 /* GP2_POL */
2968#define WM5100_GP2_POL_WIDTH 1 /* GP2_POL */
2969#define WM5100_GP2_OP_CFG 0x0200 /* GP2_OP_CFG */
2970#define WM5100_GP2_OP_CFG_MASK 0x0200 /* GP2_OP_CFG */
2971#define WM5100_GP2_OP_CFG_SHIFT 9 /* GP2_OP_CFG */
2972#define WM5100_GP2_OP_CFG_WIDTH 1 /* GP2_OP_CFG */
2973#define WM5100_GP2_DB 0x0100 /* GP2_DB */
2974#define WM5100_GP2_DB_MASK 0x0100 /* GP2_DB */
2975#define WM5100_GP2_DB_SHIFT 8 /* GP2_DB */
2976#define WM5100_GP2_DB_WIDTH 1 /* GP2_DB */
2977#define WM5100_GP2_LVL 0x0040 /* GP2_LVL */
2978#define WM5100_GP2_LVL_MASK 0x0040 /* GP2_LVL */
2979#define WM5100_GP2_LVL_SHIFT 6 /* GP2_LVL */
2980#define WM5100_GP2_LVL_WIDTH 1 /* GP2_LVL */
2981#define WM5100_GP2_FN_MASK 0x003F /* GP2_FN - [5:0] */
2982#define WM5100_GP2_FN_SHIFT 0 /* GP2_FN - [5:0] */
2983#define WM5100_GP2_FN_WIDTH 6 /* GP2_FN - [5:0] */
2984
2985/*
2986 * R3074 (0xC02) - GPIO CTRL 3
2987 */
2988#define WM5100_GP3_DIR 0x8000 /* GP3_DIR */
2989#define WM5100_GP3_DIR_MASK 0x8000 /* GP3_DIR */
2990#define WM5100_GP3_DIR_SHIFT 15 /* GP3_DIR */
2991#define WM5100_GP3_DIR_WIDTH 1 /* GP3_DIR */
2992#define WM5100_GP3_PU 0x4000 /* GP3_PU */
2993#define WM5100_GP3_PU_MASK 0x4000 /* GP3_PU */
2994#define WM5100_GP3_PU_SHIFT 14 /* GP3_PU */
2995#define WM5100_GP3_PU_WIDTH 1 /* GP3_PU */
2996#define WM5100_GP3_PD 0x2000 /* GP3_PD */
2997#define WM5100_GP3_PD_MASK 0x2000 /* GP3_PD */
2998#define WM5100_GP3_PD_SHIFT 13 /* GP3_PD */
2999#define WM5100_GP3_PD_WIDTH 1 /* GP3_PD */
3000#define WM5100_GP3_POL 0x0400 /* GP3_POL */
3001#define WM5100_GP3_POL_MASK 0x0400 /* GP3_POL */
3002#define WM5100_GP3_POL_SHIFT 10 /* GP3_POL */
3003#define WM5100_GP3_POL_WIDTH 1 /* GP3_POL */
3004#define WM5100_GP3_OP_CFG 0x0200 /* GP3_OP_CFG */
3005#define WM5100_GP3_OP_CFG_MASK 0x0200 /* GP3_OP_CFG */
3006#define WM5100_GP3_OP_CFG_SHIFT 9 /* GP3_OP_CFG */
3007#define WM5100_GP3_OP_CFG_WIDTH 1 /* GP3_OP_CFG */
3008#define WM5100_GP3_DB 0x0100 /* GP3_DB */
3009#define WM5100_GP3_DB_MASK 0x0100 /* GP3_DB */
3010#define WM5100_GP3_DB_SHIFT 8 /* GP3_DB */
3011#define WM5100_GP3_DB_WIDTH 1 /* GP3_DB */
3012#define WM5100_GP3_LVL 0x0040 /* GP3_LVL */
3013#define WM5100_GP3_LVL_MASK 0x0040 /* GP3_LVL */
3014#define WM5100_GP3_LVL_SHIFT 6 /* GP3_LVL */
3015#define WM5100_GP3_LVL_WIDTH 1 /* GP3_LVL */
3016#define WM5100_GP3_FN_MASK 0x003F /* GP3_FN - [5:0] */
3017#define WM5100_GP3_FN_SHIFT 0 /* GP3_FN - [5:0] */
3018#define WM5100_GP3_FN_WIDTH 6 /* GP3_FN - [5:0] */
3019
3020/*
3021 * R3075 (0xC03) - GPIO CTRL 4
3022 */
3023#define WM5100_GP4_DIR 0x8000 /* GP4_DIR */
3024#define WM5100_GP4_DIR_MASK 0x8000 /* GP4_DIR */
3025#define WM5100_GP4_DIR_SHIFT 15 /* GP4_DIR */
3026#define WM5100_GP4_DIR_WIDTH 1 /* GP4_DIR */
3027#define WM5100_GP4_PU 0x4000 /* GP4_PU */
3028#define WM5100_GP4_PU_MASK 0x4000 /* GP4_PU */
3029#define WM5100_GP4_PU_SHIFT 14 /* GP4_PU */
3030#define WM5100_GP4_PU_WIDTH 1 /* GP4_PU */
3031#define WM5100_GP4_PD 0x2000 /* GP4_PD */
3032#define WM5100_GP4_PD_MASK 0x2000 /* GP4_PD */
3033#define WM5100_GP4_PD_SHIFT 13 /* GP4_PD */
3034#define WM5100_GP4_PD_WIDTH 1 /* GP4_PD */
3035#define WM5100_GP4_POL 0x0400 /* GP4_POL */
3036#define WM5100_GP4_POL_MASK 0x0400 /* GP4_POL */
3037#define WM5100_GP4_POL_SHIFT 10 /* GP4_POL */
3038#define WM5100_GP4_POL_WIDTH 1 /* GP4_POL */
3039#define WM5100_GP4_OP_CFG 0x0200 /* GP4_OP_CFG */
3040#define WM5100_GP4_OP_CFG_MASK 0x0200 /* GP4_OP_CFG */
3041#define WM5100_GP4_OP_CFG_SHIFT 9 /* GP4_OP_CFG */
3042#define WM5100_GP4_OP_CFG_WIDTH 1 /* GP4_OP_CFG */
3043#define WM5100_GP4_DB 0x0100 /* GP4_DB */
3044#define WM5100_GP4_DB_MASK 0x0100 /* GP4_DB */
3045#define WM5100_GP4_DB_SHIFT 8 /* GP4_DB */
3046#define WM5100_GP4_DB_WIDTH 1 /* GP4_DB */
3047#define WM5100_GP4_LVL 0x0040 /* GP4_LVL */
3048#define WM5100_GP4_LVL_MASK 0x0040 /* GP4_LVL */
3049#define WM5100_GP4_LVL_SHIFT 6 /* GP4_LVL */
3050#define WM5100_GP4_LVL_WIDTH 1 /* GP4_LVL */
3051#define WM5100_GP4_FN_MASK 0x003F /* GP4_FN - [5:0] */
3052#define WM5100_GP4_FN_SHIFT 0 /* GP4_FN - [5:0] */
3053#define WM5100_GP4_FN_WIDTH 6 /* GP4_FN - [5:0] */
3054
3055/*
3056 * R3076 (0xC04) - GPIO CTRL 5
3057 */
3058#define WM5100_GP5_DIR 0x8000 /* GP5_DIR */
3059#define WM5100_GP5_DIR_MASK 0x8000 /* GP5_DIR */
3060#define WM5100_GP5_DIR_SHIFT 15 /* GP5_DIR */
3061#define WM5100_GP5_DIR_WIDTH 1 /* GP5_DIR */
3062#define WM5100_GP5_PU 0x4000 /* GP5_PU */
3063#define WM5100_GP5_PU_MASK 0x4000 /* GP5_PU */
3064#define WM5100_GP5_PU_SHIFT 14 /* GP5_PU */
3065#define WM5100_GP5_PU_WIDTH 1 /* GP5_PU */
3066#define WM5100_GP5_PD 0x2000 /* GP5_PD */
3067#define WM5100_GP5_PD_MASK 0x2000 /* GP5_PD */
3068#define WM5100_GP5_PD_SHIFT 13 /* GP5_PD */
3069#define WM5100_GP5_PD_WIDTH 1 /* GP5_PD */
3070#define WM5100_GP5_POL 0x0400 /* GP5_POL */
3071#define WM5100_GP5_POL_MASK 0x0400 /* GP5_POL */
3072#define WM5100_GP5_POL_SHIFT 10 /* GP5_POL */
3073#define WM5100_GP5_POL_WIDTH 1 /* GP5_POL */
3074#define WM5100_GP5_OP_CFG 0x0200 /* GP5_OP_CFG */
3075#define WM5100_GP5_OP_CFG_MASK 0x0200 /* GP5_OP_CFG */
3076#define WM5100_GP5_OP_CFG_SHIFT 9 /* GP5_OP_CFG */
3077#define WM5100_GP5_OP_CFG_WIDTH 1 /* GP5_OP_CFG */
3078#define WM5100_GP5_DB 0x0100 /* GP5_DB */
3079#define WM5100_GP5_DB_MASK 0x0100 /* GP5_DB */
3080#define WM5100_GP5_DB_SHIFT 8 /* GP5_DB */
3081#define WM5100_GP5_DB_WIDTH 1 /* GP5_DB */
3082#define WM5100_GP5_LVL 0x0040 /* GP5_LVL */
3083#define WM5100_GP5_LVL_MASK 0x0040 /* GP5_LVL */
3084#define WM5100_GP5_LVL_SHIFT 6 /* GP5_LVL */
3085#define WM5100_GP5_LVL_WIDTH 1 /* GP5_LVL */
3086#define WM5100_GP5_FN_MASK 0x003F /* GP5_FN - [5:0] */
3087#define WM5100_GP5_FN_SHIFT 0 /* GP5_FN - [5:0] */
3088#define WM5100_GP5_FN_WIDTH 6 /* GP5_FN - [5:0] */
3089
3090/*
3091 * R3077 (0xC05) - GPIO CTRL 6
3092 */
3093#define WM5100_GP6_DIR 0x8000 /* GP6_DIR */
3094#define WM5100_GP6_DIR_MASK 0x8000 /* GP6_DIR */
3095#define WM5100_GP6_DIR_SHIFT 15 /* GP6_DIR */
3096#define WM5100_GP6_DIR_WIDTH 1 /* GP6_DIR */
3097#define WM5100_GP6_PU 0x4000 /* GP6_PU */
3098#define WM5100_GP6_PU_MASK 0x4000 /* GP6_PU */
3099#define WM5100_GP6_PU_SHIFT 14 /* GP6_PU */
3100#define WM5100_GP6_PU_WIDTH 1 /* GP6_PU */
3101#define WM5100_GP6_PD 0x2000 /* GP6_PD */
3102#define WM5100_GP6_PD_MASK 0x2000 /* GP6_PD */
3103#define WM5100_GP6_PD_SHIFT 13 /* GP6_PD */
3104#define WM5100_GP6_PD_WIDTH 1 /* GP6_PD */
3105#define WM5100_GP6_POL 0x0400 /* GP6_POL */
3106#define WM5100_GP6_POL_MASK 0x0400 /* GP6_POL */
3107#define WM5100_GP6_POL_SHIFT 10 /* GP6_POL */
3108#define WM5100_GP6_POL_WIDTH 1 /* GP6_POL */
3109#define WM5100_GP6_OP_CFG 0x0200 /* GP6_OP_CFG */
3110#define WM5100_GP6_OP_CFG_MASK 0x0200 /* GP6_OP_CFG */
3111#define WM5100_GP6_OP_CFG_SHIFT 9 /* GP6_OP_CFG */
3112#define WM5100_GP6_OP_CFG_WIDTH 1 /* GP6_OP_CFG */
3113#define WM5100_GP6_DB 0x0100 /* GP6_DB */
3114#define WM5100_GP6_DB_MASK 0x0100 /* GP6_DB */
3115#define WM5100_GP6_DB_SHIFT 8 /* GP6_DB */
3116#define WM5100_GP6_DB_WIDTH 1 /* GP6_DB */
3117#define WM5100_GP6_LVL 0x0040 /* GP6_LVL */
3118#define WM5100_GP6_LVL_MASK 0x0040 /* GP6_LVL */
3119#define WM5100_GP6_LVL_SHIFT 6 /* GP6_LVL */
3120#define WM5100_GP6_LVL_WIDTH 1 /* GP6_LVL */
3121#define WM5100_GP6_FN_MASK 0x003F /* GP6_FN - [5:0] */
3122#define WM5100_GP6_FN_SHIFT 0 /* GP6_FN - [5:0] */
3123#define WM5100_GP6_FN_WIDTH 6 /* GP6_FN - [5:0] */
3124
3125/*
3126 * R3107 (0xC23) - Misc Pad Ctrl 1
3127 */
3128#define WM5100_LDO1ENA_PD 0x8000 /* LDO1ENA_PD */
3129#define WM5100_LDO1ENA_PD_MASK 0x8000 /* LDO1ENA_PD */
3130#define WM5100_LDO1ENA_PD_SHIFT 15 /* LDO1ENA_PD */
3131#define WM5100_LDO1ENA_PD_WIDTH 1 /* LDO1ENA_PD */
3132#define WM5100_MCLK2_PD 0x2000 /* MCLK2_PD */
3133#define WM5100_MCLK2_PD_MASK 0x2000 /* MCLK2_PD */
3134#define WM5100_MCLK2_PD_SHIFT 13 /* MCLK2_PD */
3135#define WM5100_MCLK2_PD_WIDTH 1 /* MCLK2_PD */
3136#define WM5100_MCLK1_PD 0x1000 /* MCLK1_PD */
3137#define WM5100_MCLK1_PD_MASK 0x1000 /* MCLK1_PD */
3138#define WM5100_MCLK1_PD_SHIFT 12 /* MCLK1_PD */
3139#define WM5100_MCLK1_PD_WIDTH 1 /* MCLK1_PD */
3140#define WM5100_RESET_PU 0x0002 /* RESET_PU */
3141#define WM5100_RESET_PU_MASK 0x0002 /* RESET_PU */
3142#define WM5100_RESET_PU_SHIFT 1 /* RESET_PU */
3143#define WM5100_RESET_PU_WIDTH 1 /* RESET_PU */
3144#define WM5100_ADDR_PD 0x0001 /* ADDR_PD */
3145#define WM5100_ADDR_PD_MASK 0x0001 /* ADDR_PD */
3146#define WM5100_ADDR_PD_SHIFT 0 /* ADDR_PD */
3147#define WM5100_ADDR_PD_WIDTH 1 /* ADDR_PD */
3148
3149/*
3150 * R3108 (0xC24) - Misc Pad Ctrl 2
3151 */
3152#define WM5100_DMICDAT4_PD 0x0008 /* DMICDAT4_PD */
3153#define WM5100_DMICDAT4_PD_MASK 0x0008 /* DMICDAT4_PD */
3154#define WM5100_DMICDAT4_PD_SHIFT 3 /* DMICDAT4_PD */
3155#define WM5100_DMICDAT4_PD_WIDTH 1 /* DMICDAT4_PD */
3156#define WM5100_DMICDAT3_PD 0x0004 /* DMICDAT3_PD */
3157#define WM5100_DMICDAT3_PD_MASK 0x0004 /* DMICDAT3_PD */
3158#define WM5100_DMICDAT3_PD_SHIFT 2 /* DMICDAT3_PD */
3159#define WM5100_DMICDAT3_PD_WIDTH 1 /* DMICDAT3_PD */
3160#define WM5100_DMICDAT2_PD 0x0002 /* DMICDAT2_PD */
3161#define WM5100_DMICDAT2_PD_MASK 0x0002 /* DMICDAT2_PD */
3162#define WM5100_DMICDAT2_PD_SHIFT 1 /* DMICDAT2_PD */
3163#define WM5100_DMICDAT2_PD_WIDTH 1 /* DMICDAT2_PD */
3164#define WM5100_DMICDAT1_PD 0x0001 /* DMICDAT1_PD */
3165#define WM5100_DMICDAT1_PD_MASK 0x0001 /* DMICDAT1_PD */
3166#define WM5100_DMICDAT1_PD_SHIFT 0 /* DMICDAT1_PD */
3167#define WM5100_DMICDAT1_PD_WIDTH 1 /* DMICDAT1_PD */
3168
3169/*
3170 * R3109 (0xC25) - Misc Pad Ctrl 3
3171 */
3172#define WM5100_AIF1RXLRCLK_PU 0x0020 /* AIF1RXLRCLK_PU */
3173#define WM5100_AIF1RXLRCLK_PU_MASK 0x0020 /* AIF1RXLRCLK_PU */
3174#define WM5100_AIF1RXLRCLK_PU_SHIFT 5 /* AIF1RXLRCLK_PU */
3175#define WM5100_AIF1RXLRCLK_PU_WIDTH 1 /* AIF1RXLRCLK_PU */
3176#define WM5100_AIF1RXLRCLK_PD 0x0010 /* AIF1RXLRCLK_PD */
3177#define WM5100_AIF1RXLRCLK_PD_MASK 0x0010 /* AIF1RXLRCLK_PD */
3178#define WM5100_AIF1RXLRCLK_PD_SHIFT 4 /* AIF1RXLRCLK_PD */
3179#define WM5100_AIF1RXLRCLK_PD_WIDTH 1 /* AIF1RXLRCLK_PD */
3180#define WM5100_AIF1BCLK_PU 0x0008 /* AIF1BCLK_PU */
3181#define WM5100_AIF1BCLK_PU_MASK 0x0008 /* AIF1BCLK_PU */
3182#define WM5100_AIF1BCLK_PU_SHIFT 3 /* AIF1BCLK_PU */
3183#define WM5100_AIF1BCLK_PU_WIDTH 1 /* AIF1BCLK_PU */
3184#define WM5100_AIF1BCLK_PD 0x0004 /* AIF1BCLK_PD */
3185#define WM5100_AIF1BCLK_PD_MASK 0x0004 /* AIF1BCLK_PD */
3186#define WM5100_AIF1BCLK_PD_SHIFT 2 /* AIF1BCLK_PD */
3187#define WM5100_AIF1BCLK_PD_WIDTH 1 /* AIF1BCLK_PD */
3188#define WM5100_AIF1RXDAT_PU 0x0002 /* AIF1RXDAT_PU */
3189#define WM5100_AIF1RXDAT_PU_MASK 0x0002 /* AIF1RXDAT_PU */
3190#define WM5100_AIF1RXDAT_PU_SHIFT 1 /* AIF1RXDAT_PU */
3191#define WM5100_AIF1RXDAT_PU_WIDTH 1 /* AIF1RXDAT_PU */
3192#define WM5100_AIF1RXDAT_PD 0x0001 /* AIF1RXDAT_PD */
3193#define WM5100_AIF1RXDAT_PD_MASK 0x0001 /* AIF1RXDAT_PD */
3194#define WM5100_AIF1RXDAT_PD_SHIFT 0 /* AIF1RXDAT_PD */
3195#define WM5100_AIF1RXDAT_PD_WIDTH 1 /* AIF1RXDAT_PD */
3196
3197/*
3198 * R3110 (0xC26) - Misc Pad Ctrl 4
3199 */
3200#define WM5100_AIF2RXLRCLK_PU 0x0020 /* AIF2RXLRCLK_PU */
3201#define WM5100_AIF2RXLRCLK_PU_MASK 0x0020 /* AIF2RXLRCLK_PU */
3202#define WM5100_AIF2RXLRCLK_PU_SHIFT 5 /* AIF2RXLRCLK_PU */
3203#define WM5100_AIF2RXLRCLK_PU_WIDTH 1 /* AIF2RXLRCLK_PU */
3204#define WM5100_AIF2RXLRCLK_PD 0x0010 /* AIF2RXLRCLK_PD */
3205#define WM5100_AIF2RXLRCLK_PD_MASK 0x0010 /* AIF2RXLRCLK_PD */
3206#define WM5100_AIF2RXLRCLK_PD_SHIFT 4 /* AIF2RXLRCLK_PD */
3207#define WM5100_AIF2RXLRCLK_PD_WIDTH 1 /* AIF2RXLRCLK_PD */
3208#define WM5100_AIF2BCLK_PU 0x0008 /* AIF2BCLK_PU */
3209#define WM5100_AIF2BCLK_PU_MASK 0x0008 /* AIF2BCLK_PU */
3210#define WM5100_AIF2BCLK_PU_SHIFT 3 /* AIF2BCLK_PU */
3211#define WM5100_AIF2BCLK_PU_WIDTH 1 /* AIF2BCLK_PU */
3212#define WM5100_AIF2BCLK_PD 0x0004 /* AIF2BCLK_PD */
3213#define WM5100_AIF2BCLK_PD_MASK 0x0004 /* AIF2BCLK_PD */
3214#define WM5100_AIF2BCLK_PD_SHIFT 2 /* AIF2BCLK_PD */
3215#define WM5100_AIF2BCLK_PD_WIDTH 1 /* AIF2BCLK_PD */
3216#define WM5100_AIF2RXDAT_PU 0x0002 /* AIF2RXDAT_PU */
3217#define WM5100_AIF2RXDAT_PU_MASK 0x0002 /* AIF2RXDAT_PU */
3218#define WM5100_AIF2RXDAT_PU_SHIFT 1 /* AIF2RXDAT_PU */
3219#define WM5100_AIF2RXDAT_PU_WIDTH 1 /* AIF2RXDAT_PU */
3220#define WM5100_AIF2RXDAT_PD 0x0001 /* AIF2RXDAT_PD */
3221#define WM5100_AIF2RXDAT_PD_MASK 0x0001 /* AIF2RXDAT_PD */
3222#define WM5100_AIF2RXDAT_PD_SHIFT 0 /* AIF2RXDAT_PD */
3223#define WM5100_AIF2RXDAT_PD_WIDTH 1 /* AIF2RXDAT_PD */
3224
3225/*
3226 * R3111 (0xC27) - Misc Pad Ctrl 5
3227 */
3228#define WM5100_AIF3RXLRCLK_PU 0x0020 /* AIF3RXLRCLK_PU */
3229#define WM5100_AIF3RXLRCLK_PU_MASK 0x0020 /* AIF3RXLRCLK_PU */
3230#define WM5100_AIF3RXLRCLK_PU_SHIFT 5 /* AIF3RXLRCLK_PU */
3231#define WM5100_AIF3RXLRCLK_PU_WIDTH 1 /* AIF3RXLRCLK_PU */
3232#define WM5100_AIF3RXLRCLK_PD 0x0010 /* AIF3RXLRCLK_PD */
3233#define WM5100_AIF3RXLRCLK_PD_MASK 0x0010 /* AIF3RXLRCLK_PD */
3234#define WM5100_AIF3RXLRCLK_PD_SHIFT 4 /* AIF3RXLRCLK_PD */
3235#define WM5100_AIF3RXLRCLK_PD_WIDTH 1 /* AIF3RXLRCLK_PD */
3236#define WM5100_AIF3BCLK_PU 0x0008 /* AIF3BCLK_PU */
3237#define WM5100_AIF3BCLK_PU_MASK 0x0008 /* AIF3BCLK_PU */
3238#define WM5100_AIF3BCLK_PU_SHIFT 3 /* AIF3BCLK_PU */
3239#define WM5100_AIF3BCLK_PU_WIDTH 1 /* AIF3BCLK_PU */
3240#define WM5100_AIF3BCLK_PD 0x0004 /* AIF3BCLK_PD */
3241#define WM5100_AIF3BCLK_PD_MASK 0x0004 /* AIF3BCLK_PD */
3242#define WM5100_AIF3BCLK_PD_SHIFT 2 /* AIF3BCLK_PD */
3243#define WM5100_AIF3BCLK_PD_WIDTH 1 /* AIF3BCLK_PD */
3244#define WM5100_AIF3RXDAT_PU 0x0002 /* AIF3RXDAT_PU */
3245#define WM5100_AIF3RXDAT_PU_MASK 0x0002 /* AIF3RXDAT_PU */
3246#define WM5100_AIF3RXDAT_PU_SHIFT 1 /* AIF3RXDAT_PU */
3247#define WM5100_AIF3RXDAT_PU_WIDTH 1 /* AIF3RXDAT_PU */
3248#define WM5100_AIF3RXDAT_PD 0x0001 /* AIF3RXDAT_PD */
3249#define WM5100_AIF3RXDAT_PD_MASK 0x0001 /* AIF3RXDAT_PD */
3250#define WM5100_AIF3RXDAT_PD_SHIFT 0 /* AIF3RXDAT_PD */
3251#define WM5100_AIF3RXDAT_PD_WIDTH 1 /* AIF3RXDAT_PD */
3252
3253/*
3254 * R3112 (0xC28) - Misc GPIO 1
3255 */
3256#define WM5100_OPCLK_SEL_MASK 0x0003 /* OPCLK_SEL - [1:0] */
3257#define WM5100_OPCLK_SEL_SHIFT 0 /* OPCLK_SEL - [1:0] */
3258#define WM5100_OPCLK_SEL_WIDTH 2 /* OPCLK_SEL - [1:0] */
3259
3260/*
3261 * R3328 (0xD00) - Interrupt Status 1
3262 */
3263#define WM5100_GP6_EINT 0x0020 /* GP6_EINT */
3264#define WM5100_GP6_EINT_MASK 0x0020 /* GP6_EINT */
3265#define WM5100_GP6_EINT_SHIFT 5 /* GP6_EINT */
3266#define WM5100_GP6_EINT_WIDTH 1 /* GP6_EINT */
3267#define WM5100_GP5_EINT 0x0010 /* GP5_EINT */
3268#define WM5100_GP5_EINT_MASK 0x0010 /* GP5_EINT */
3269#define WM5100_GP5_EINT_SHIFT 4 /* GP5_EINT */
3270#define WM5100_GP5_EINT_WIDTH 1 /* GP5_EINT */
3271#define WM5100_GP4_EINT 0x0008 /* GP4_EINT */
3272#define WM5100_GP4_EINT_MASK 0x0008 /* GP4_EINT */
3273#define WM5100_GP4_EINT_SHIFT 3 /* GP4_EINT */
3274#define WM5100_GP4_EINT_WIDTH 1 /* GP4_EINT */
3275#define WM5100_GP3_EINT 0x0004 /* GP3_EINT */
3276#define WM5100_GP3_EINT_MASK 0x0004 /* GP3_EINT */
3277#define WM5100_GP3_EINT_SHIFT 2 /* GP3_EINT */
3278#define WM5100_GP3_EINT_WIDTH 1 /* GP3_EINT */
3279#define WM5100_GP2_EINT 0x0002 /* GP2_EINT */
3280#define WM5100_GP2_EINT_MASK 0x0002 /* GP2_EINT */
3281#define WM5100_GP2_EINT_SHIFT 1 /* GP2_EINT */
3282#define WM5100_GP2_EINT_WIDTH 1 /* GP2_EINT */
3283#define WM5100_GP1_EINT 0x0001 /* GP1_EINT */
3284#define WM5100_GP1_EINT_MASK 0x0001 /* GP1_EINT */
3285#define WM5100_GP1_EINT_SHIFT 0 /* GP1_EINT */
3286#define WM5100_GP1_EINT_WIDTH 1 /* GP1_EINT */
3287
3288/*
3289 * R3329 (0xD01) - Interrupt Status 2
3290 */
3291#define WM5100_DSP_IRQ6_EINT 0x0020 /* DSP_IRQ6_EINT */
3292#define WM5100_DSP_IRQ6_EINT_MASK 0x0020 /* DSP_IRQ6_EINT */
3293#define WM5100_DSP_IRQ6_EINT_SHIFT 5 /* DSP_IRQ6_EINT */
3294#define WM5100_DSP_IRQ6_EINT_WIDTH 1 /* DSP_IRQ6_EINT */
3295#define WM5100_DSP_IRQ5_EINT 0x0010 /* DSP_IRQ5_EINT */
3296#define WM5100_DSP_IRQ5_EINT_MASK 0x0010 /* DSP_IRQ5_EINT */
3297#define WM5100_DSP_IRQ5_EINT_SHIFT 4 /* DSP_IRQ5_EINT */
3298#define WM5100_DSP_IRQ5_EINT_WIDTH 1 /* DSP_IRQ5_EINT */
3299#define WM5100_DSP_IRQ4_EINT 0x0008 /* DSP_IRQ4_EINT */
3300#define WM5100_DSP_IRQ4_EINT_MASK 0x0008 /* DSP_IRQ4_EINT */
3301#define WM5100_DSP_IRQ4_EINT_SHIFT 3 /* DSP_IRQ4_EINT */
3302#define WM5100_DSP_IRQ4_EINT_WIDTH 1 /* DSP_IRQ4_EINT */
3303#define WM5100_DSP_IRQ3_EINT 0x0004 /* DSP_IRQ3_EINT */
3304#define WM5100_DSP_IRQ3_EINT_MASK 0x0004 /* DSP_IRQ3_EINT */
3305#define WM5100_DSP_IRQ3_EINT_SHIFT 2 /* DSP_IRQ3_EINT */
3306#define WM5100_DSP_IRQ3_EINT_WIDTH 1 /* DSP_IRQ3_EINT */
3307#define WM5100_DSP_IRQ2_EINT 0x0002 /* DSP_IRQ2_EINT */
3308#define WM5100_DSP_IRQ2_EINT_MASK 0x0002 /* DSP_IRQ2_EINT */
3309#define WM5100_DSP_IRQ2_EINT_SHIFT 1 /* DSP_IRQ2_EINT */
3310#define WM5100_DSP_IRQ2_EINT_WIDTH 1 /* DSP_IRQ2_EINT */
3311#define WM5100_DSP_IRQ1_EINT 0x0001 /* DSP_IRQ1_EINT */
3312#define WM5100_DSP_IRQ1_EINT_MASK 0x0001 /* DSP_IRQ1_EINT */
3313#define WM5100_DSP_IRQ1_EINT_SHIFT 0 /* DSP_IRQ1_EINT */
3314#define WM5100_DSP_IRQ1_EINT_WIDTH 1 /* DSP_IRQ1_EINT */
3315
3316/*
3317 * R3330 (0xD02) - Interrupt Status 3
3318 */
3319#define WM5100_SPK_SHUTDOWN_WARN_EINT 0x8000 /* SPK_SHUTDOWN_WARN_EINT */
3320#define WM5100_SPK_SHUTDOWN_WARN_EINT_MASK 0x8000 /* SPK_SHUTDOWN_WARN_EINT */
3321#define WM5100_SPK_SHUTDOWN_WARN_EINT_SHIFT 15 /* SPK_SHUTDOWN_WARN_EINT */
3322#define WM5100_SPK_SHUTDOWN_WARN_EINT_WIDTH 1 /* SPK_SHUTDOWN_WARN_EINT */
3323#define WM5100_SPK_SHUTDOWN_EINT 0x4000 /* SPK_SHUTDOWN_EINT */
3324#define WM5100_SPK_SHUTDOWN_EINT_MASK 0x4000 /* SPK_SHUTDOWN_EINT */
3325#define WM5100_SPK_SHUTDOWN_EINT_SHIFT 14 /* SPK_SHUTDOWN_EINT */
3326#define WM5100_SPK_SHUTDOWN_EINT_WIDTH 1 /* SPK_SHUTDOWN_EINT */
3327#define WM5100_HPDET_EINT 0x2000 /* HPDET_EINT */
3328#define WM5100_HPDET_EINT_MASK 0x2000 /* HPDET_EINT */
3329#define WM5100_HPDET_EINT_SHIFT 13 /* HPDET_EINT */
3330#define WM5100_HPDET_EINT_WIDTH 1 /* HPDET_EINT */
3331#define WM5100_ACCDET_EINT 0x1000 /* ACCDET_EINT */
3332#define WM5100_ACCDET_EINT_MASK 0x1000 /* ACCDET_EINT */
3333#define WM5100_ACCDET_EINT_SHIFT 12 /* ACCDET_EINT */
3334#define WM5100_ACCDET_EINT_WIDTH 1 /* ACCDET_EINT */
3335#define WM5100_DRC_SIG_DET_EINT 0x0200 /* DRC_SIG_DET_EINT */
3336#define WM5100_DRC_SIG_DET_EINT_MASK 0x0200 /* DRC_SIG_DET_EINT */
3337#define WM5100_DRC_SIG_DET_EINT_SHIFT 9 /* DRC_SIG_DET_EINT */
3338#define WM5100_DRC_SIG_DET_EINT_WIDTH 1 /* DRC_SIG_DET_EINT */
3339#define WM5100_ASRC2_LOCK_EINT 0x0100 /* ASRC2_LOCK_EINT */
3340#define WM5100_ASRC2_LOCK_EINT_MASK 0x0100 /* ASRC2_LOCK_EINT */
3341#define WM5100_ASRC2_LOCK_EINT_SHIFT 8 /* ASRC2_LOCK_EINT */
3342#define WM5100_ASRC2_LOCK_EINT_WIDTH 1 /* ASRC2_LOCK_EINT */
3343#define WM5100_ASRC1_LOCK_EINT 0x0080 /* ASRC1_LOCK_EINT */
3344#define WM5100_ASRC1_LOCK_EINT_MASK 0x0080 /* ASRC1_LOCK_EINT */
3345#define WM5100_ASRC1_LOCK_EINT_SHIFT 7 /* ASRC1_LOCK_EINT */
3346#define WM5100_ASRC1_LOCK_EINT_WIDTH 1 /* ASRC1_LOCK_EINT */
3347#define WM5100_FLL2_LOCK_EINT 0x0008 /* FLL2_LOCK_EINT */
3348#define WM5100_FLL2_LOCK_EINT_MASK 0x0008 /* FLL2_LOCK_EINT */
3349#define WM5100_FLL2_LOCK_EINT_SHIFT 3 /* FLL2_LOCK_EINT */
3350#define WM5100_FLL2_LOCK_EINT_WIDTH 1 /* FLL2_LOCK_EINT */
3351#define WM5100_FLL1_LOCK_EINT 0x0004 /* FLL1_LOCK_EINT */
3352#define WM5100_FLL1_LOCK_EINT_MASK 0x0004 /* FLL1_LOCK_EINT */
3353#define WM5100_FLL1_LOCK_EINT_SHIFT 2 /* FLL1_LOCK_EINT */
3354#define WM5100_FLL1_LOCK_EINT_WIDTH 1 /* FLL1_LOCK_EINT */
3355#define WM5100_CLKGEN_ERR_EINT 0x0002 /* CLKGEN_ERR_EINT */
3356#define WM5100_CLKGEN_ERR_EINT_MASK 0x0002 /* CLKGEN_ERR_EINT */
3357#define WM5100_CLKGEN_ERR_EINT_SHIFT 1 /* CLKGEN_ERR_EINT */
3358#define WM5100_CLKGEN_ERR_EINT_WIDTH 1 /* CLKGEN_ERR_EINT */
3359#define WM5100_CLKGEN_ERR_ASYNC_EINT 0x0001 /* CLKGEN_ERR_ASYNC_EINT */
3360#define WM5100_CLKGEN_ERR_ASYNC_EINT_MASK 0x0001 /* CLKGEN_ERR_ASYNC_EINT */
3361#define WM5100_CLKGEN_ERR_ASYNC_EINT_SHIFT 0 /* CLKGEN_ERR_ASYNC_EINT */
3362#define WM5100_CLKGEN_ERR_ASYNC_EINT_WIDTH 1 /* CLKGEN_ERR_ASYNC_EINT */
3363
3364/*
3365 * R3331 (0xD03) - Interrupt Status 4
3366 */
3367#define WM5100_AIF3_ERR_EINT 0x2000 /* AIF3_ERR_EINT */
3368#define WM5100_AIF3_ERR_EINT_MASK 0x2000 /* AIF3_ERR_EINT */
3369#define WM5100_AIF3_ERR_EINT_SHIFT 13 /* AIF3_ERR_EINT */
3370#define WM5100_AIF3_ERR_EINT_WIDTH 1 /* AIF3_ERR_EINT */
3371#define WM5100_AIF2_ERR_EINT 0x1000 /* AIF2_ERR_EINT */
3372#define WM5100_AIF2_ERR_EINT_MASK 0x1000 /* AIF2_ERR_EINT */
3373#define WM5100_AIF2_ERR_EINT_SHIFT 12 /* AIF2_ERR_EINT */
3374#define WM5100_AIF2_ERR_EINT_WIDTH 1 /* AIF2_ERR_EINT */
3375#define WM5100_AIF1_ERR_EINT 0x0800 /* AIF1_ERR_EINT */
3376#define WM5100_AIF1_ERR_EINT_MASK 0x0800 /* AIF1_ERR_EINT */
3377#define WM5100_AIF1_ERR_EINT_SHIFT 11 /* AIF1_ERR_EINT */
3378#define WM5100_AIF1_ERR_EINT_WIDTH 1 /* AIF1_ERR_EINT */
3379#define WM5100_CTRLIF_ERR_EINT 0x0400 /* CTRLIF_ERR_EINT */
3380#define WM5100_CTRLIF_ERR_EINT_MASK 0x0400 /* CTRLIF_ERR_EINT */
3381#define WM5100_CTRLIF_ERR_EINT_SHIFT 10 /* CTRLIF_ERR_EINT */
3382#define WM5100_CTRLIF_ERR_EINT_WIDTH 1 /* CTRLIF_ERR_EINT */
3383#define WM5100_ISRC2_UNDERCLOCKED_EINT 0x0200 /* ISRC2_UNDERCLOCKED_EINT */
3384#define WM5100_ISRC2_UNDERCLOCKED_EINT_MASK 0x0200 /* ISRC2_UNDERCLOCKED_EINT */
3385#define WM5100_ISRC2_UNDERCLOCKED_EINT_SHIFT 9 /* ISRC2_UNDERCLOCKED_EINT */
3386#define WM5100_ISRC2_UNDERCLOCKED_EINT_WIDTH 1 /* ISRC2_UNDERCLOCKED_EINT */
3387#define WM5100_ISRC1_UNDERCLOCKED_EINT 0x0100 /* ISRC1_UNDERCLOCKED_EINT */
3388#define WM5100_ISRC1_UNDERCLOCKED_EINT_MASK 0x0100 /* ISRC1_UNDERCLOCKED_EINT */
3389#define WM5100_ISRC1_UNDERCLOCKED_EINT_SHIFT 8 /* ISRC1_UNDERCLOCKED_EINT */
3390#define WM5100_ISRC1_UNDERCLOCKED_EINT_WIDTH 1 /* ISRC1_UNDERCLOCKED_EINT */
3391#define WM5100_FX_UNDERCLOCKED_EINT 0x0080 /* FX_UNDERCLOCKED_EINT */
3392#define WM5100_FX_UNDERCLOCKED_EINT_MASK 0x0080 /* FX_UNDERCLOCKED_EINT */
3393#define WM5100_FX_UNDERCLOCKED_EINT_SHIFT 7 /* FX_UNDERCLOCKED_EINT */
3394#define WM5100_FX_UNDERCLOCKED_EINT_WIDTH 1 /* FX_UNDERCLOCKED_EINT */
3395#define WM5100_AIF3_UNDERCLOCKED_EINT 0x0040 /* AIF3_UNDERCLOCKED_EINT */
3396#define WM5100_AIF3_UNDERCLOCKED_EINT_MASK 0x0040 /* AIF3_UNDERCLOCKED_EINT */
3397#define WM5100_AIF3_UNDERCLOCKED_EINT_SHIFT 6 /* AIF3_UNDERCLOCKED_EINT */
3398#define WM5100_AIF3_UNDERCLOCKED_EINT_WIDTH 1 /* AIF3_UNDERCLOCKED_EINT */
3399#define WM5100_AIF2_UNDERCLOCKED_EINT 0x0020 /* AIF2_UNDERCLOCKED_EINT */
3400#define WM5100_AIF2_UNDERCLOCKED_EINT_MASK 0x0020 /* AIF2_UNDERCLOCKED_EINT */
3401#define WM5100_AIF2_UNDERCLOCKED_EINT_SHIFT 5 /* AIF2_UNDERCLOCKED_EINT */
3402#define WM5100_AIF2_UNDERCLOCKED_EINT_WIDTH 1 /* AIF2_UNDERCLOCKED_EINT */
3403#define WM5100_AIF1_UNDERCLOCKED_EINT 0x0010 /* AIF1_UNDERCLOCKED_EINT */
3404#define WM5100_AIF1_UNDERCLOCKED_EINT_MASK 0x0010 /* AIF1_UNDERCLOCKED_EINT */
3405#define WM5100_AIF1_UNDERCLOCKED_EINT_SHIFT 4 /* AIF1_UNDERCLOCKED_EINT */
3406#define WM5100_AIF1_UNDERCLOCKED_EINT_WIDTH 1 /* AIF1_UNDERCLOCKED_EINT */
3407#define WM5100_ASRC_UNDERCLOCKED_EINT 0x0008 /* ASRC_UNDERCLOCKED_EINT */
3408#define WM5100_ASRC_UNDERCLOCKED_EINT_MASK 0x0008 /* ASRC_UNDERCLOCKED_EINT */
3409#define WM5100_ASRC_UNDERCLOCKED_EINT_SHIFT 3 /* ASRC_UNDERCLOCKED_EINT */
3410#define WM5100_ASRC_UNDERCLOCKED_EINT_WIDTH 1 /* ASRC_UNDERCLOCKED_EINT */
3411#define WM5100_DAC_UNDERCLOCKED_EINT 0x0004 /* DAC_UNDERCLOCKED_EINT */
3412#define WM5100_DAC_UNDERCLOCKED_EINT_MASK 0x0004 /* DAC_UNDERCLOCKED_EINT */
3413#define WM5100_DAC_UNDERCLOCKED_EINT_SHIFT 2 /* DAC_UNDERCLOCKED_EINT */
3414#define WM5100_DAC_UNDERCLOCKED_EINT_WIDTH 1 /* DAC_UNDERCLOCKED_EINT */
3415#define WM5100_ADC_UNDERCLOCKED_EINT 0x0002 /* ADC_UNDERCLOCKED_EINT */
3416#define WM5100_ADC_UNDERCLOCKED_EINT_MASK 0x0002 /* ADC_UNDERCLOCKED_EINT */
3417#define WM5100_ADC_UNDERCLOCKED_EINT_SHIFT 1 /* ADC_UNDERCLOCKED_EINT */
3418#define WM5100_ADC_UNDERCLOCKED_EINT_WIDTH 1 /* ADC_UNDERCLOCKED_EINT */
3419#define WM5100_MIXER_UNDERCLOCKED_EINT 0x0001 /* MIXER_UNDERCLOCKED_EINT */
3420#define WM5100_MIXER_UNDERCLOCKED_EINT_MASK 0x0001 /* MIXER_UNDERCLOCKED_EINT */
3421#define WM5100_MIXER_UNDERCLOCKED_EINT_SHIFT 0 /* MIXER_UNDERCLOCKED_EINT */
3422#define WM5100_MIXER_UNDERCLOCKED_EINT_WIDTH 1 /* MIXER_UNDERCLOCKED_EINT */
3423
3424/*
3425 * R3332 (0xD04) - Interrupt Raw Status 2
3426 */
3427#define WM5100_DSP_IRQ6_STS 0x0020 /* DSP_IRQ6_STS */
3428#define WM5100_DSP_IRQ6_STS_MASK 0x0020 /* DSP_IRQ6_STS */
3429#define WM5100_DSP_IRQ6_STS_SHIFT 5 /* DSP_IRQ6_STS */
3430#define WM5100_DSP_IRQ6_STS_WIDTH 1 /* DSP_IRQ6_STS */
3431#define WM5100_DSP_IRQ5_STS 0x0010 /* DSP_IRQ5_STS */
3432#define WM5100_DSP_IRQ5_STS_MASK 0x0010 /* DSP_IRQ5_STS */
3433#define WM5100_DSP_IRQ5_STS_SHIFT 4 /* DSP_IRQ5_STS */
3434#define WM5100_DSP_IRQ5_STS_WIDTH 1 /* DSP_IRQ5_STS */
3435#define WM5100_DSP_IRQ4_STS 0x0008 /* DSP_IRQ4_STS */
3436#define WM5100_DSP_IRQ4_STS_MASK 0x0008 /* DSP_IRQ4_STS */
3437#define WM5100_DSP_IRQ4_STS_SHIFT 3 /* DSP_IRQ4_STS */
3438#define WM5100_DSP_IRQ4_STS_WIDTH 1 /* DSP_IRQ4_STS */
3439#define WM5100_DSP_IRQ3_STS 0x0004 /* DSP_IRQ3_STS */
3440#define WM5100_DSP_IRQ3_STS_MASK 0x0004 /* DSP_IRQ3_STS */
3441#define WM5100_DSP_IRQ3_STS_SHIFT 2 /* DSP_IRQ3_STS */
3442#define WM5100_DSP_IRQ3_STS_WIDTH 1 /* DSP_IRQ3_STS */
3443#define WM5100_DSP_IRQ2_STS 0x0002 /* DSP_IRQ2_STS */
3444#define WM5100_DSP_IRQ2_STS_MASK 0x0002 /* DSP_IRQ2_STS */
3445#define WM5100_DSP_IRQ2_STS_SHIFT 1 /* DSP_IRQ2_STS */
3446#define WM5100_DSP_IRQ2_STS_WIDTH 1 /* DSP_IRQ2_STS */
3447#define WM5100_DSP_IRQ1_STS 0x0001 /* DSP_IRQ1_STS */
3448#define WM5100_DSP_IRQ1_STS_MASK 0x0001 /* DSP_IRQ1_STS */
3449#define WM5100_DSP_IRQ1_STS_SHIFT 0 /* DSP_IRQ1_STS */
3450#define WM5100_DSP_IRQ1_STS_WIDTH 1 /* DSP_IRQ1_STS */
3451
3452/*
3453 * R3333 (0xD05) - Interrupt Raw Status 3
3454 */
3455#define WM5100_SPK_SHUTDOWN_WARN_STS 0x8000 /* SPK_SHUTDOWN_WARN_STS */
3456#define WM5100_SPK_SHUTDOWN_WARN_STS_MASK 0x8000 /* SPK_SHUTDOWN_WARN_STS */
3457#define WM5100_SPK_SHUTDOWN_WARN_STS_SHIFT 15 /* SPK_SHUTDOWN_WARN_STS */
3458#define WM5100_SPK_SHUTDOWN_WARN_STS_WIDTH 1 /* SPK_SHUTDOWN_WARN_STS */
3459#define WM5100_SPK_SHUTDOWN_STS 0x4000 /* SPK_SHUTDOWN_STS */
3460#define WM5100_SPK_SHUTDOWN_STS_MASK 0x4000 /* SPK_SHUTDOWN_STS */
3461#define WM5100_SPK_SHUTDOWN_STS_SHIFT 14 /* SPK_SHUTDOWN_STS */
3462#define WM5100_SPK_SHUTDOWN_STS_WIDTH 1 /* SPK_SHUTDOWN_STS */
3463#define WM5100_HPDET_STS 0x2000 /* HPDET_STS */
3464#define WM5100_HPDET_STS_MASK 0x2000 /* HPDET_STS */
3465#define WM5100_HPDET_STS_SHIFT 13 /* HPDET_STS */
3466#define WM5100_HPDET_STS_WIDTH 1 /* HPDET_STS */
3467#define WM5100_DRC_SID_DET_STS 0x0200 /* DRC_SID_DET_STS */
3468#define WM5100_DRC_SID_DET_STS_MASK 0x0200 /* DRC_SID_DET_STS */
3469#define WM5100_DRC_SID_DET_STS_SHIFT 9 /* DRC_SID_DET_STS */
3470#define WM5100_DRC_SID_DET_STS_WIDTH 1 /* DRC_SID_DET_STS */
3471#define WM5100_ASRC2_LOCK_STS 0x0100 /* ASRC2_LOCK_STS */
3472#define WM5100_ASRC2_LOCK_STS_MASK 0x0100 /* ASRC2_LOCK_STS */
3473#define WM5100_ASRC2_LOCK_STS_SHIFT 8 /* ASRC2_LOCK_STS */
3474#define WM5100_ASRC2_LOCK_STS_WIDTH 1 /* ASRC2_LOCK_STS */
3475#define WM5100_ASRC1_LOCK_STS 0x0080 /* ASRC1_LOCK_STS */
3476#define WM5100_ASRC1_LOCK_STS_MASK 0x0080 /* ASRC1_LOCK_STS */
3477#define WM5100_ASRC1_LOCK_STS_SHIFT 7 /* ASRC1_LOCK_STS */
3478#define WM5100_ASRC1_LOCK_STS_WIDTH 1 /* ASRC1_LOCK_STS */
3479#define WM5100_FLL2_LOCK_STS 0x0008 /* FLL2_LOCK_STS */
3480#define WM5100_FLL2_LOCK_STS_MASK 0x0008 /* FLL2_LOCK_STS */
3481#define WM5100_FLL2_LOCK_STS_SHIFT 3 /* FLL2_LOCK_STS */
3482#define WM5100_FLL2_LOCK_STS_WIDTH 1 /* FLL2_LOCK_STS */
3483#define WM5100_FLL1_LOCK_STS 0x0004 /* FLL1_LOCK_STS */
3484#define WM5100_FLL1_LOCK_STS_MASK 0x0004 /* FLL1_LOCK_STS */
3485#define WM5100_FLL1_LOCK_STS_SHIFT 2 /* FLL1_LOCK_STS */
3486#define WM5100_FLL1_LOCK_STS_WIDTH 1 /* FLL1_LOCK_STS */
3487#define WM5100_CLKGEN_ERR_STS 0x0002 /* CLKGEN_ERR_STS */
3488#define WM5100_CLKGEN_ERR_STS_MASK 0x0002 /* CLKGEN_ERR_STS */
3489#define WM5100_CLKGEN_ERR_STS_SHIFT 1 /* CLKGEN_ERR_STS */
3490#define WM5100_CLKGEN_ERR_STS_WIDTH 1 /* CLKGEN_ERR_STS */
3491#define WM5100_CLKGEN_ERR_ASYNC_STS 0x0001 /* CLKGEN_ERR_ASYNC_STS */
3492#define WM5100_CLKGEN_ERR_ASYNC_STS_MASK 0x0001 /* CLKGEN_ERR_ASYNC_STS */
3493#define WM5100_CLKGEN_ERR_ASYNC_STS_SHIFT 0 /* CLKGEN_ERR_ASYNC_STS */
3494#define WM5100_CLKGEN_ERR_ASYNC_STS_WIDTH 1 /* CLKGEN_ERR_ASYNC_STS */
3495
3496/*
3497 * R3334 (0xD06) - Interrupt Raw Status 4
3498 */
3499#define WM5100_AIF3_ERR_STS 0x2000 /* AIF3_ERR_STS */
3500#define WM5100_AIF3_ERR_STS_MASK 0x2000 /* AIF3_ERR_STS */
3501#define WM5100_AIF3_ERR_STS_SHIFT 13 /* AIF3_ERR_STS */
3502#define WM5100_AIF3_ERR_STS_WIDTH 1 /* AIF3_ERR_STS */
3503#define WM5100_AIF2_ERR_STS 0x1000 /* AIF2_ERR_STS */
3504#define WM5100_AIF2_ERR_STS_MASK 0x1000 /* AIF2_ERR_STS */
3505#define WM5100_AIF2_ERR_STS_SHIFT 12 /* AIF2_ERR_STS */
3506#define WM5100_AIF2_ERR_STS_WIDTH 1 /* AIF2_ERR_STS */
3507#define WM5100_AIF1_ERR_STS 0x0800 /* AIF1_ERR_STS */
3508#define WM5100_AIF1_ERR_STS_MASK 0x0800 /* AIF1_ERR_STS */
3509#define WM5100_AIF1_ERR_STS_SHIFT 11 /* AIF1_ERR_STS */
3510#define WM5100_AIF1_ERR_STS_WIDTH 1 /* AIF1_ERR_STS */
3511#define WM5100_CTRLIF_ERR_STS 0x0400 /* CTRLIF_ERR_STS */
3512#define WM5100_CTRLIF_ERR_STS_MASK 0x0400 /* CTRLIF_ERR_STS */
3513#define WM5100_CTRLIF_ERR_STS_SHIFT 10 /* CTRLIF_ERR_STS */
3514#define WM5100_CTRLIF_ERR_STS_WIDTH 1 /* CTRLIF_ERR_STS */
3515#define WM5100_ISRC2_UNDERCLOCKED_STS 0x0200 /* ISRC2_UNDERCLOCKED_STS */
3516#define WM5100_ISRC2_UNDERCLOCKED_STS_MASK 0x0200 /* ISRC2_UNDERCLOCKED_STS */
3517#define WM5100_ISRC2_UNDERCLOCKED_STS_SHIFT 9 /* ISRC2_UNDERCLOCKED_STS */
3518#define WM5100_ISRC2_UNDERCLOCKED_STS_WIDTH 1 /* ISRC2_UNDERCLOCKED_STS */
3519#define WM5100_ISRC1_UNDERCLOCKED_STS 0x0100 /* ISRC1_UNDERCLOCKED_STS */
3520#define WM5100_ISRC1_UNDERCLOCKED_STS_MASK 0x0100 /* ISRC1_UNDERCLOCKED_STS */
3521#define WM5100_ISRC1_UNDERCLOCKED_STS_SHIFT 8 /* ISRC1_UNDERCLOCKED_STS */
3522#define WM5100_ISRC1_UNDERCLOCKED_STS_WIDTH 1 /* ISRC1_UNDERCLOCKED_STS */
3523#define WM5100_FX_UNDERCLOCKED_STS 0x0080 /* FX_UNDERCLOCKED_STS */
3524#define WM5100_FX_UNDERCLOCKED_STS_MASK 0x0080 /* FX_UNDERCLOCKED_STS */
3525#define WM5100_FX_UNDERCLOCKED_STS_SHIFT 7 /* FX_UNDERCLOCKED_STS */
3526#define WM5100_FX_UNDERCLOCKED_STS_WIDTH 1 /* FX_UNDERCLOCKED_STS */
3527#define WM5100_AIF3_UNDERCLOCKED_STS 0x0040 /* AIF3_UNDERCLOCKED_STS */
3528#define WM5100_AIF3_UNDERCLOCKED_STS_MASK 0x0040 /* AIF3_UNDERCLOCKED_STS */
3529#define WM5100_AIF3_UNDERCLOCKED_STS_SHIFT 6 /* AIF3_UNDERCLOCKED_STS */
3530#define WM5100_AIF3_UNDERCLOCKED_STS_WIDTH 1 /* AIF3_UNDERCLOCKED_STS */
3531#define WM5100_AIF2_UNDERCLOCKED_STS 0x0020 /* AIF2_UNDERCLOCKED_STS */
3532#define WM5100_AIF2_UNDERCLOCKED_STS_MASK 0x0020 /* AIF2_UNDERCLOCKED_STS */
3533#define WM5100_AIF2_UNDERCLOCKED_STS_SHIFT 5 /* AIF2_UNDERCLOCKED_STS */
3534#define WM5100_AIF2_UNDERCLOCKED_STS_WIDTH 1 /* AIF2_UNDERCLOCKED_STS */
3535#define WM5100_AIF1_UNDERCLOCKED_STS 0x0010 /* AIF1_UNDERCLOCKED_STS */
3536#define WM5100_AIF1_UNDERCLOCKED_STS_MASK 0x0010 /* AIF1_UNDERCLOCKED_STS */
3537#define WM5100_AIF1_UNDERCLOCKED_STS_SHIFT 4 /* AIF1_UNDERCLOCKED_STS */
3538#define WM5100_AIF1_UNDERCLOCKED_STS_WIDTH 1 /* AIF1_UNDERCLOCKED_STS */
3539#define WM5100_ASRC_UNDERCLOCKED_STS 0x0008 /* ASRC_UNDERCLOCKED_STS */
3540#define WM5100_ASRC_UNDERCLOCKED_STS_MASK 0x0008 /* ASRC_UNDERCLOCKED_STS */
3541#define WM5100_ASRC_UNDERCLOCKED_STS_SHIFT 3 /* ASRC_UNDERCLOCKED_STS */
3542#define WM5100_ASRC_UNDERCLOCKED_STS_WIDTH 1 /* ASRC_UNDERCLOCKED_STS */
3543#define WM5100_DAC_UNDERCLOCKED_STS 0x0004 /* DAC_UNDERCLOCKED_STS */
3544#define WM5100_DAC_UNDERCLOCKED_STS_MASK 0x0004 /* DAC_UNDERCLOCKED_STS */
3545#define WM5100_DAC_UNDERCLOCKED_STS_SHIFT 2 /* DAC_UNDERCLOCKED_STS */
3546#define WM5100_DAC_UNDERCLOCKED_STS_WIDTH 1 /* DAC_UNDERCLOCKED_STS */
3547#define WM5100_ADC_UNDERCLOCKED_STS 0x0002 /* ADC_UNDERCLOCKED_STS */
3548#define WM5100_ADC_UNDERCLOCKED_STS_MASK 0x0002 /* ADC_UNDERCLOCKED_STS */
3549#define WM5100_ADC_UNDERCLOCKED_STS_SHIFT 1 /* ADC_UNDERCLOCKED_STS */
3550#define WM5100_ADC_UNDERCLOCKED_STS_WIDTH 1 /* ADC_UNDERCLOCKED_STS */
3551#define WM5100_MIXER_UNDERCLOCKED_STS 0x0001 /* MIXER_UNDERCLOCKED_STS */
3552#define WM5100_MIXER_UNDERCLOCKED_STS_MASK 0x0001 /* MIXER_UNDERCLOCKED_STS */
3553#define WM5100_MIXER_UNDERCLOCKED_STS_SHIFT 0 /* MIXER_UNDERCLOCKED_STS */
3554#define WM5100_MIXER_UNDERCLOCKED_STS_WIDTH 1 /* MIXER_UNDERCLOCKED_STS */
3555
3556/*
3557 * R3335 (0xD07) - Interrupt Status 1 Mask
3558 */
3559#define WM5100_IM_GP6_EINT 0x0020 /* IM_GP6_EINT */
3560#define WM5100_IM_GP6_EINT_MASK 0x0020 /* IM_GP6_EINT */
3561#define WM5100_IM_GP6_EINT_SHIFT 5 /* IM_GP6_EINT */
3562#define WM5100_IM_GP6_EINT_WIDTH 1 /* IM_GP6_EINT */
3563#define WM5100_IM_GP5_EINT 0x0010 /* IM_GP5_EINT */
3564#define WM5100_IM_GP5_EINT_MASK 0x0010 /* IM_GP5_EINT */
3565#define WM5100_IM_GP5_EINT_SHIFT 4 /* IM_GP5_EINT */
3566#define WM5100_IM_GP5_EINT_WIDTH 1 /* IM_GP5_EINT */
3567#define WM5100_IM_GP4_EINT 0x0008 /* IM_GP4_EINT */
3568#define WM5100_IM_GP4_EINT_MASK 0x0008 /* IM_GP4_EINT */
3569#define WM5100_IM_GP4_EINT_SHIFT 3 /* IM_GP4_EINT */
3570#define WM5100_IM_GP4_EINT_WIDTH 1 /* IM_GP4_EINT */
3571#define WM5100_IM_GP3_EINT 0x0004 /* IM_GP3_EINT */
3572#define WM5100_IM_GP3_EINT_MASK 0x0004 /* IM_GP3_EINT */
3573#define WM5100_IM_GP3_EINT_SHIFT 2 /* IM_GP3_EINT */
3574#define WM5100_IM_GP3_EINT_WIDTH 1 /* IM_GP3_EINT */
3575#define WM5100_IM_GP2_EINT 0x0002 /* IM_GP2_EINT */
3576#define WM5100_IM_GP2_EINT_MASK 0x0002 /* IM_GP2_EINT */
3577#define WM5100_IM_GP2_EINT_SHIFT 1 /* IM_GP2_EINT */
3578#define WM5100_IM_GP2_EINT_WIDTH 1 /* IM_GP2_EINT */
3579#define WM5100_IM_GP1_EINT 0x0001 /* IM_GP1_EINT */
3580#define WM5100_IM_GP1_EINT_MASK 0x0001 /* IM_GP1_EINT */
3581#define WM5100_IM_GP1_EINT_SHIFT 0 /* IM_GP1_EINT */
3582#define WM5100_IM_GP1_EINT_WIDTH 1 /* IM_GP1_EINT */
3583
3584/*
3585 * R3336 (0xD08) - Interrupt Status 2 Mask
3586 */
3587#define WM5100_IM_DSP_IRQ6_EINT 0x0020 /* IM_DSP_IRQ6_EINT */
3588#define WM5100_IM_DSP_IRQ6_EINT_MASK 0x0020 /* IM_DSP_IRQ6_EINT */
3589#define WM5100_IM_DSP_IRQ6_EINT_SHIFT 5 /* IM_DSP_IRQ6_EINT */
3590#define WM5100_IM_DSP_IRQ6_EINT_WIDTH 1 /* IM_DSP_IRQ6_EINT */
3591#define WM5100_IM_DSP_IRQ5_EINT 0x0010 /* IM_DSP_IRQ5_EINT */
3592#define WM5100_IM_DSP_IRQ5_EINT_MASK 0x0010 /* IM_DSP_IRQ5_EINT */
3593#define WM5100_IM_DSP_IRQ5_EINT_SHIFT 4 /* IM_DSP_IRQ5_EINT */
3594#define WM5100_IM_DSP_IRQ5_EINT_WIDTH 1 /* IM_DSP_IRQ5_EINT */
3595#define WM5100_IM_DSP_IRQ4_EINT 0x0008 /* IM_DSP_IRQ4_EINT */
3596#define WM5100_IM_DSP_IRQ4_EINT_MASK 0x0008 /* IM_DSP_IRQ4_EINT */
3597#define WM5100_IM_DSP_IRQ4_EINT_SHIFT 3 /* IM_DSP_IRQ4_EINT */
3598#define WM5100_IM_DSP_IRQ4_EINT_WIDTH 1 /* IM_DSP_IRQ4_EINT */
3599#define WM5100_IM_DSP_IRQ3_EINT 0x0004 /* IM_DSP_IRQ3_EINT */
3600#define WM5100_IM_DSP_IRQ3_EINT_MASK 0x0004 /* IM_DSP_IRQ3_EINT */
3601#define WM5100_IM_DSP_IRQ3_EINT_SHIFT 2 /* IM_DSP_IRQ3_EINT */
3602#define WM5100_IM_DSP_IRQ3_EINT_WIDTH 1 /* IM_DSP_IRQ3_EINT */
3603#define WM5100_IM_DSP_IRQ2_EINT 0x0002 /* IM_DSP_IRQ2_EINT */
3604#define WM5100_IM_DSP_IRQ2_EINT_MASK 0x0002 /* IM_DSP_IRQ2_EINT */
3605#define WM5100_IM_DSP_IRQ2_EINT_SHIFT 1 /* IM_DSP_IRQ2_EINT */
3606#define WM5100_IM_DSP_IRQ2_EINT_WIDTH 1 /* IM_DSP_IRQ2_EINT */
3607#define WM5100_IM_DSP_IRQ1_EINT 0x0001 /* IM_DSP_IRQ1_EINT */
3608#define WM5100_IM_DSP_IRQ1_EINT_MASK 0x0001 /* IM_DSP_IRQ1_EINT */
3609#define WM5100_IM_DSP_IRQ1_EINT_SHIFT 0 /* IM_DSP_IRQ1_EINT */
3610#define WM5100_IM_DSP_IRQ1_EINT_WIDTH 1 /* IM_DSP_IRQ1_EINT */
3611
3612/*
3613 * R3337 (0xD09) - Interrupt Status 3 Mask
3614 */
3615#define WM5100_IM_SPK_SHUTDOWN_WARN_EINT 0x8000 /* IM_SPK_SHUTDOWN_WARN_EINT */
3616#define WM5100_IM_SPK_SHUTDOWN_WARN_EINT_MASK 0x8000 /* IM_SPK_SHUTDOWN_WARN_EINT */
3617#define WM5100_IM_SPK_SHUTDOWN_WARN_EINT_SHIFT 15 /* IM_SPK_SHUTDOWN_WARN_EINT */
3618#define WM5100_IM_SPK_SHUTDOWN_WARN_EINT_WIDTH 1 /* IM_SPK_SHUTDOWN_WARN_EINT */
3619#define WM5100_IM_SPK_SHUTDOWN_EINT 0x4000 /* IM_SPK_SHUTDOWN_EINT */
3620#define WM5100_IM_SPK_SHUTDOWN_EINT_MASK 0x4000 /* IM_SPK_SHUTDOWN_EINT */
3621#define WM5100_IM_SPK_SHUTDOWN_EINT_SHIFT 14 /* IM_SPK_SHUTDOWN_EINT */
3622#define WM5100_IM_SPK_SHUTDOWN_EINT_WIDTH 1 /* IM_SPK_SHUTDOWN_EINT */
3623#define WM5100_IM_HPDET_EINT 0x2000 /* IM_HPDET_EINT */
3624#define WM5100_IM_HPDET_EINT_MASK 0x2000 /* IM_HPDET_EINT */
3625#define WM5100_IM_HPDET_EINT_SHIFT 13 /* IM_HPDET_EINT */
3626#define WM5100_IM_HPDET_EINT_WIDTH 1 /* IM_HPDET_EINT */
3627#define WM5100_IM_ACCDET_EINT 0x1000 /* IM_ACCDET_EINT */
3628#define WM5100_IM_ACCDET_EINT_MASK 0x1000 /* IM_ACCDET_EINT */
3629#define WM5100_IM_ACCDET_EINT_SHIFT 12 /* IM_ACCDET_EINT */
3630#define WM5100_IM_ACCDET_EINT_WIDTH 1 /* IM_ACCDET_EINT */
3631#define WM5100_IM_DRC_SIG_DET_EINT 0x0200 /* IM_DRC_SIG_DET_EINT */
3632#define WM5100_IM_DRC_SIG_DET_EINT_MASK 0x0200 /* IM_DRC_SIG_DET_EINT */
3633#define WM5100_IM_DRC_SIG_DET_EINT_SHIFT 9 /* IM_DRC_SIG_DET_EINT */
3634#define WM5100_IM_DRC_SIG_DET_EINT_WIDTH 1 /* IM_DRC_SIG_DET_EINT */
3635#define WM5100_IM_ASRC2_LOCK_EINT 0x0100 /* IM_ASRC2_LOCK_EINT */
3636#define WM5100_IM_ASRC2_LOCK_EINT_MASK 0x0100 /* IM_ASRC2_LOCK_EINT */
3637#define WM5100_IM_ASRC2_LOCK_EINT_SHIFT 8 /* IM_ASRC2_LOCK_EINT */
3638#define WM5100_IM_ASRC2_LOCK_EINT_WIDTH 1 /* IM_ASRC2_LOCK_EINT */
3639#define WM5100_IM_ASRC1_LOCK_EINT 0x0080 /* IM_ASRC1_LOCK_EINT */
3640#define WM5100_IM_ASRC1_LOCK_EINT_MASK 0x0080 /* IM_ASRC1_LOCK_EINT */
3641#define WM5100_IM_ASRC1_LOCK_EINT_SHIFT 7 /* IM_ASRC1_LOCK_EINT */
3642#define WM5100_IM_ASRC1_LOCK_EINT_WIDTH 1 /* IM_ASRC1_LOCK_EINT */
3643#define WM5100_IM_FLL2_LOCK_EINT 0x0008 /* IM_FLL2_LOCK_EINT */
3644#define WM5100_IM_FLL2_LOCK_EINT_MASK 0x0008 /* IM_FLL2_LOCK_EINT */
3645#define WM5100_IM_FLL2_LOCK_EINT_SHIFT 3 /* IM_FLL2_LOCK_EINT */
3646#define WM5100_IM_FLL2_LOCK_EINT_WIDTH 1 /* IM_FLL2_LOCK_EINT */
3647#define WM5100_IM_FLL1_LOCK_EINT 0x0004 /* IM_FLL1_LOCK_EINT */
3648#define WM5100_IM_FLL1_LOCK_EINT_MASK 0x0004 /* IM_FLL1_LOCK_EINT */
3649#define WM5100_IM_FLL1_LOCK_EINT_SHIFT 2 /* IM_FLL1_LOCK_EINT */
3650#define WM5100_IM_FLL1_LOCK_EINT_WIDTH 1 /* IM_FLL1_LOCK_EINT */
3651#define WM5100_IM_CLKGEN_ERR_EINT 0x0002 /* IM_CLKGEN_ERR_EINT */
3652#define WM5100_IM_CLKGEN_ERR_EINT_MASK 0x0002 /* IM_CLKGEN_ERR_EINT */
3653#define WM5100_IM_CLKGEN_ERR_EINT_SHIFT 1 /* IM_CLKGEN_ERR_EINT */
3654#define WM5100_IM_CLKGEN_ERR_EINT_WIDTH 1 /* IM_CLKGEN_ERR_EINT */
3655#define WM5100_IM_CLKGEN_ERR_ASYNC_EINT 0x0001 /* IM_CLKGEN_ERR_ASYNC_EINT */
3656#define WM5100_IM_CLKGEN_ERR_ASYNC_EINT_MASK 0x0001 /* IM_CLKGEN_ERR_ASYNC_EINT */
3657#define WM5100_IM_CLKGEN_ERR_ASYNC_EINT_SHIFT 0 /* IM_CLKGEN_ERR_ASYNC_EINT */
3658#define WM5100_IM_CLKGEN_ERR_ASYNC_EINT_WIDTH 1 /* IM_CLKGEN_ERR_ASYNC_EINT */
3659
3660/*
3661 * R3338 (0xD0A) - Interrupt Status 4 Mask
3662 */
3663#define WM5100_IM_AIF3_ERR_EINT 0x2000 /* IM_AIF3_ERR_EINT */
3664#define WM5100_IM_AIF3_ERR_EINT_MASK 0x2000 /* IM_AIF3_ERR_EINT */
3665#define WM5100_IM_AIF3_ERR_EINT_SHIFT 13 /* IM_AIF3_ERR_EINT */
3666#define WM5100_IM_AIF3_ERR_EINT_WIDTH 1 /* IM_AIF3_ERR_EINT */
3667#define WM5100_IM_AIF2_ERR_EINT 0x1000 /* IM_AIF2_ERR_EINT */
3668#define WM5100_IM_AIF2_ERR_EINT_MASK 0x1000 /* IM_AIF2_ERR_EINT */
3669#define WM5100_IM_AIF2_ERR_EINT_SHIFT 12 /* IM_AIF2_ERR_EINT */
3670#define WM5100_IM_AIF2_ERR_EINT_WIDTH 1 /* IM_AIF2_ERR_EINT */
3671#define WM5100_IM_AIF1_ERR_EINT 0x0800 /* IM_AIF1_ERR_EINT */
3672#define WM5100_IM_AIF1_ERR_EINT_MASK 0x0800 /* IM_AIF1_ERR_EINT */
3673#define WM5100_IM_AIF1_ERR_EINT_SHIFT 11 /* IM_AIF1_ERR_EINT */
3674#define WM5100_IM_AIF1_ERR_EINT_WIDTH 1 /* IM_AIF1_ERR_EINT */
3675#define WM5100_IM_CTRLIF_ERR_EINT 0x0400 /* IM_CTRLIF_ERR_EINT */
3676#define WM5100_IM_CTRLIF_ERR_EINT_MASK 0x0400 /* IM_CTRLIF_ERR_EINT */
3677#define WM5100_IM_CTRLIF_ERR_EINT_SHIFT 10 /* IM_CTRLIF_ERR_EINT */
3678#define WM5100_IM_CTRLIF_ERR_EINT_WIDTH 1 /* IM_CTRLIF_ERR_EINT */
3679#define WM5100_IM_ISRC2_UNDERCLOCKED_EINT 0x0200 /* IM_ISRC2_UNDERCLOCKED_EINT */
3680#define WM5100_IM_ISRC2_UNDERCLOCKED_EINT_MASK 0x0200 /* IM_ISRC2_UNDERCLOCKED_EINT */
3681#define WM5100_IM_ISRC2_UNDERCLOCKED_EINT_SHIFT 9 /* IM_ISRC2_UNDERCLOCKED_EINT */
3682#define WM5100_IM_ISRC2_UNDERCLOCKED_EINT_WIDTH 1 /* IM_ISRC2_UNDERCLOCKED_EINT */
3683#define WM5100_IM_ISRC1_UNDERCLOCKED_EINT 0x0100 /* IM_ISRC1_UNDERCLOCKED_EINT */
3684#define WM5100_IM_ISRC1_UNDERCLOCKED_EINT_MASK 0x0100 /* IM_ISRC1_UNDERCLOCKED_EINT */
3685#define WM5100_IM_ISRC1_UNDERCLOCKED_EINT_SHIFT 8 /* IM_ISRC1_UNDERCLOCKED_EINT */
3686#define WM5100_IM_ISRC1_UNDERCLOCKED_EINT_WIDTH 1 /* IM_ISRC1_UNDERCLOCKED_EINT */
3687#define WM5100_IM_FX_UNDERCLOCKED_EINT 0x0080 /* IM_FX_UNDERCLOCKED_EINT */
3688#define WM5100_IM_FX_UNDERCLOCKED_EINT_MASK 0x0080 /* IM_FX_UNDERCLOCKED_EINT */
3689#define WM5100_IM_FX_UNDERCLOCKED_EINT_SHIFT 7 /* IM_FX_UNDERCLOCKED_EINT */
3690#define WM5100_IM_FX_UNDERCLOCKED_EINT_WIDTH 1 /* IM_FX_UNDERCLOCKED_EINT */
3691#define WM5100_IM_AIF3_UNDERCLOCKED_EINT 0x0040 /* IM_AIF3_UNDERCLOCKED_EINT */
3692#define WM5100_IM_AIF3_UNDERCLOCKED_EINT_MASK 0x0040 /* IM_AIF3_UNDERCLOCKED_EINT */
3693#define WM5100_IM_AIF3_UNDERCLOCKED_EINT_SHIFT 6 /* IM_AIF3_UNDERCLOCKED_EINT */
3694#define WM5100_IM_AIF3_UNDERCLOCKED_EINT_WIDTH 1 /* IM_AIF3_UNDERCLOCKED_EINT */
3695#define WM5100_IM_AIF2_UNDERCLOCKED_EINT 0x0020 /* IM_AIF2_UNDERCLOCKED_EINT */
3696#define WM5100_IM_AIF2_UNDERCLOCKED_EINT_MASK 0x0020 /* IM_AIF2_UNDERCLOCKED_EINT */
3697#define WM5100_IM_AIF2_UNDERCLOCKED_EINT_SHIFT 5 /* IM_AIF2_UNDERCLOCKED_EINT */
3698#define WM5100_IM_AIF2_UNDERCLOCKED_EINT_WIDTH 1 /* IM_AIF2_UNDERCLOCKED_EINT */
3699#define WM5100_IM_AIF1_UNDERCLOCKED_EINT 0x0010 /* IM_AIF1_UNDERCLOCKED_EINT */
3700#define WM5100_IM_AIF1_UNDERCLOCKED_EINT_MASK 0x0010 /* IM_AIF1_UNDERCLOCKED_EINT */
3701#define WM5100_IM_AIF1_UNDERCLOCKED_EINT_SHIFT 4 /* IM_AIF1_UNDERCLOCKED_EINT */
3702#define WM5100_IM_AIF1_UNDERCLOCKED_EINT_WIDTH 1 /* IM_AIF1_UNDERCLOCKED_EINT */
3703#define WM5100_IM_ASRC_UNDERCLOCKED_EINT 0x0008 /* IM_ASRC_UNDERCLOCKED_EINT */
3704#define WM5100_IM_ASRC_UNDERCLOCKED_EINT_MASK 0x0008 /* IM_ASRC_UNDERCLOCKED_EINT */
3705#define WM5100_IM_ASRC_UNDERCLOCKED_EINT_SHIFT 3 /* IM_ASRC_UNDERCLOCKED_EINT */
3706#define WM5100_IM_ASRC_UNDERCLOCKED_EINT_WIDTH 1 /* IM_ASRC_UNDERCLOCKED_EINT */
3707#define WM5100_IM_DAC_UNDERCLOCKED_EINT 0x0004 /* IM_DAC_UNDERCLOCKED_EINT */
3708#define WM5100_IM_DAC_UNDERCLOCKED_EINT_MASK 0x0004 /* IM_DAC_UNDERCLOCKED_EINT */
3709#define WM5100_IM_DAC_UNDERCLOCKED_EINT_SHIFT 2 /* IM_DAC_UNDERCLOCKED_EINT */
3710#define WM5100_IM_DAC_UNDERCLOCKED_EINT_WIDTH 1 /* IM_DAC_UNDERCLOCKED_EINT */
3711#define WM5100_IM_ADC_UNDERCLOCKED_EINT 0x0002 /* IM_ADC_UNDERCLOCKED_EINT */
3712#define WM5100_IM_ADC_UNDERCLOCKED_EINT_MASK 0x0002 /* IM_ADC_UNDERCLOCKED_EINT */
3713#define WM5100_IM_ADC_UNDERCLOCKED_EINT_SHIFT 1 /* IM_ADC_UNDERCLOCKED_EINT */
3714#define WM5100_IM_ADC_UNDERCLOCKED_EINT_WIDTH 1 /* IM_ADC_UNDERCLOCKED_EINT */
3715#define WM5100_IM_MIXER_UNDERCLOCKED_EINT 0x0001 /* IM_MIXER_UNDERCLOCKED_EINT */
3716#define WM5100_IM_MIXER_UNDERCLOCKED_EINT_MASK 0x0001 /* IM_MIXER_UNDERCLOCKED_EINT */
3717#define WM5100_IM_MIXER_UNDERCLOCKED_EINT_SHIFT 0 /* IM_MIXER_UNDERCLOCKED_EINT */
3718#define WM5100_IM_MIXER_UNDERCLOCKED_EINT_WIDTH 1 /* IM_MIXER_UNDERCLOCKED_EINT */
3719
3720/*
3721 * R3359 (0xD1F) - Interrupt Control
3722 */
3723#define WM5100_IM_IRQ 0x0001 /* IM_IRQ */
3724#define WM5100_IM_IRQ_MASK 0x0001 /* IM_IRQ */
3725#define WM5100_IM_IRQ_SHIFT 0 /* IM_IRQ */
3726#define WM5100_IM_IRQ_WIDTH 1 /* IM_IRQ */
3727
3728/*
3729 * R3360 (0xD20) - IRQ Debounce 1
3730 */
3731#define WM5100_SPK_SHUTDOWN_WARN_DB 0x0200 /* SPK_SHUTDOWN_WARN_DB */
3732#define WM5100_SPK_SHUTDOWN_WARN_DB_MASK 0x0200 /* SPK_SHUTDOWN_WARN_DB */
3733#define WM5100_SPK_SHUTDOWN_WARN_DB_SHIFT 9 /* SPK_SHUTDOWN_WARN_DB */
3734#define WM5100_SPK_SHUTDOWN_WARN_DB_WIDTH 1 /* SPK_SHUTDOWN_WARN_DB */
3735#define WM5100_SPK_SHUTDOWN_DB 0x0100 /* SPK_SHUTDOWN_DB */
3736#define WM5100_SPK_SHUTDOWN_DB_MASK 0x0100 /* SPK_SHUTDOWN_DB */
3737#define WM5100_SPK_SHUTDOWN_DB_SHIFT 8 /* SPK_SHUTDOWN_DB */
3738#define WM5100_SPK_SHUTDOWN_DB_WIDTH 1 /* SPK_SHUTDOWN_DB */
3739#define WM5100_FLL1_LOCK_IRQ_DB 0x0008 /* FLL1_LOCK_IRQ_DB */
3740#define WM5100_FLL1_LOCK_IRQ_DB_MASK 0x0008 /* FLL1_LOCK_IRQ_DB */
3741#define WM5100_FLL1_LOCK_IRQ_DB_SHIFT 3 /* FLL1_LOCK_IRQ_DB */
3742#define WM5100_FLL1_LOCK_IRQ_DB_WIDTH 1 /* FLL1_LOCK_IRQ_DB */
3743#define WM5100_FLL2_LOCK_IRQ_DB 0x0004 /* FLL2_LOCK_IRQ_DB */
3744#define WM5100_FLL2_LOCK_IRQ_DB_MASK 0x0004 /* FLL2_LOCK_IRQ_DB */
3745#define WM5100_FLL2_LOCK_IRQ_DB_SHIFT 2 /* FLL2_LOCK_IRQ_DB */
3746#define WM5100_FLL2_LOCK_IRQ_DB_WIDTH 1 /* FLL2_LOCK_IRQ_DB */
3747#define WM5100_CLKGEN_ERR_IRQ_DB 0x0002 /* CLKGEN_ERR_IRQ_DB */
3748#define WM5100_CLKGEN_ERR_IRQ_DB_MASK 0x0002 /* CLKGEN_ERR_IRQ_DB */
3749#define WM5100_CLKGEN_ERR_IRQ_DB_SHIFT 1 /* CLKGEN_ERR_IRQ_DB */
3750#define WM5100_CLKGEN_ERR_IRQ_DB_WIDTH 1 /* CLKGEN_ERR_IRQ_DB */
3751#define WM5100_CLKGEN_ERR_ASYNC_IRQ_DB 0x0001 /* CLKGEN_ERR_ASYNC_IRQ_DB */
3752#define WM5100_CLKGEN_ERR_ASYNC_IRQ_DB_MASK 0x0001 /* CLKGEN_ERR_ASYNC_IRQ_DB */
3753#define WM5100_CLKGEN_ERR_ASYNC_IRQ_DB_SHIFT 0 /* CLKGEN_ERR_ASYNC_IRQ_DB */
3754#define WM5100_CLKGEN_ERR_ASYNC_IRQ_DB_WIDTH 1 /* CLKGEN_ERR_ASYNC_IRQ_DB */
3755
3756/*
3757 * R3361 (0xD21) - IRQ Debounce 2
3758 */
3759#define WM5100_AIF_ERR_DB 0x0001 /* AIF_ERR_DB */
3760#define WM5100_AIF_ERR_DB_MASK 0x0001 /* AIF_ERR_DB */
3761#define WM5100_AIF_ERR_DB_SHIFT 0 /* AIF_ERR_DB */
3762#define WM5100_AIF_ERR_DB_WIDTH 1 /* AIF_ERR_DB */
3763
3764/*
3765 * R3584 (0xE00) - FX_Ctrl
3766 */
3767#define WM5100_FX_STS_MASK 0xFFC0 /* FX_STS - [15:6] */
3768#define WM5100_FX_STS_SHIFT 6 /* FX_STS - [15:6] */
3769#define WM5100_FX_STS_WIDTH 10 /* FX_STS - [15:6] */
3770#define WM5100_FX_RATE_MASK 0x0003 /* FX_RATE - [1:0] */
3771#define WM5100_FX_RATE_SHIFT 0 /* FX_RATE - [1:0] */
3772#define WM5100_FX_RATE_WIDTH 2 /* FX_RATE - [1:0] */
3773
3774/*
3775 * R3600 (0xE10) - EQ1_1
3776 */
3777#define WM5100_EQ1_B1_GAIN_MASK 0xF800 /* EQ1_B1_GAIN - [15:11] */
3778#define WM5100_EQ1_B1_GAIN_SHIFT 11 /* EQ1_B1_GAIN - [15:11] */
3779#define WM5100_EQ1_B1_GAIN_WIDTH 5 /* EQ1_B1_GAIN - [15:11] */
3780#define WM5100_EQ1_B2_GAIN_MASK 0x07C0 /* EQ1_B2_GAIN - [10:6] */
3781#define WM5100_EQ1_B2_GAIN_SHIFT 6 /* EQ1_B2_GAIN - [10:6] */
3782#define WM5100_EQ1_B2_GAIN_WIDTH 5 /* EQ1_B2_GAIN - [10:6] */
3783#define WM5100_EQ1_B3_GAIN_MASK 0x003E /* EQ1_B3_GAIN - [5:1] */
3784#define WM5100_EQ1_B3_GAIN_SHIFT 1 /* EQ1_B3_GAIN - [5:1] */
3785#define WM5100_EQ1_B3_GAIN_WIDTH 5 /* EQ1_B3_GAIN - [5:1] */
3786#define WM5100_EQ1_ENA 0x0001 /* EQ1_ENA */
3787#define WM5100_EQ1_ENA_MASK 0x0001 /* EQ1_ENA */
3788#define WM5100_EQ1_ENA_SHIFT 0 /* EQ1_ENA */
3789#define WM5100_EQ1_ENA_WIDTH 1 /* EQ1_ENA */
3790
3791/*
3792 * R3601 (0xE11) - EQ1_2
3793 */
3794#define WM5100_EQ1_B4_GAIN_MASK 0xF800 /* EQ1_B4_GAIN - [15:11] */
3795#define WM5100_EQ1_B4_GAIN_SHIFT 11 /* EQ1_B4_GAIN - [15:11] */
3796#define WM5100_EQ1_B4_GAIN_WIDTH 5 /* EQ1_B4_GAIN - [15:11] */
3797#define WM5100_EQ1_B5_GAIN_MASK 0x07C0 /* EQ1_B5_GAIN - [10:6] */
3798#define WM5100_EQ1_B5_GAIN_SHIFT 6 /* EQ1_B5_GAIN - [10:6] */
3799#define WM5100_EQ1_B5_GAIN_WIDTH 5 /* EQ1_B5_GAIN - [10:6] */
3800
3801/*
3802 * R3602 (0xE12) - EQ1_3
3803 */
3804#define WM5100_EQ1_B1_A_MASK 0xFFFF /* EQ1_B1_A - [15:0] */
3805#define WM5100_EQ1_B1_A_SHIFT 0 /* EQ1_B1_A - [15:0] */
3806#define WM5100_EQ1_B1_A_WIDTH 16 /* EQ1_B1_A - [15:0] */
3807
3808/*
3809 * R3603 (0xE13) - EQ1_4
3810 */
3811#define WM5100_EQ1_B1_B_MASK 0xFFFF /* EQ1_B1_B - [15:0] */
3812#define WM5100_EQ1_B1_B_SHIFT 0 /* EQ1_B1_B - [15:0] */
3813#define WM5100_EQ1_B1_B_WIDTH 16 /* EQ1_B1_B - [15:0] */
3814
3815/*
3816 * R3604 (0xE14) - EQ1_5
3817 */
3818#define WM5100_EQ1_B1_PG_MASK 0xFFFF /* EQ1_B1_PG - [15:0] */
3819#define WM5100_EQ1_B1_PG_SHIFT 0 /* EQ1_B1_PG - [15:0] */
3820#define WM5100_EQ1_B1_PG_WIDTH 16 /* EQ1_B1_PG - [15:0] */
3821
3822/*
3823 * R3605 (0xE15) - EQ1_6
3824 */
3825#define WM5100_EQ1_B2_A_MASK 0xFFFF /* EQ1_B2_A - [15:0] */
3826#define WM5100_EQ1_B2_A_SHIFT 0 /* EQ1_B2_A - [15:0] */
3827#define WM5100_EQ1_B2_A_WIDTH 16 /* EQ1_B2_A - [15:0] */
3828
3829/*
3830 * R3606 (0xE16) - EQ1_7
3831 */
3832#define WM5100_EQ1_B2_B_MASK 0xFFFF /* EQ1_B2_B - [15:0] */
3833#define WM5100_EQ1_B2_B_SHIFT 0 /* EQ1_B2_B - [15:0] */
3834#define WM5100_EQ1_B2_B_WIDTH 16 /* EQ1_B2_B - [15:0] */
3835
3836/*
3837 * R3607 (0xE17) - EQ1_8
3838 */
3839#define WM5100_EQ1_B2_C_MASK 0xFFFF /* EQ1_B2_C - [15:0] */
3840#define WM5100_EQ1_B2_C_SHIFT 0 /* EQ1_B2_C - [15:0] */
3841#define WM5100_EQ1_B2_C_WIDTH 16 /* EQ1_B2_C - [15:0] */
3842
3843/*
3844 * R3608 (0xE18) - EQ1_9
3845 */
3846#define WM5100_EQ1_B2_PG_MASK 0xFFFF /* EQ1_B2_PG - [15:0] */
3847#define WM5100_EQ1_B2_PG_SHIFT 0 /* EQ1_B2_PG - [15:0] */
3848#define WM5100_EQ1_B2_PG_WIDTH 16 /* EQ1_B2_PG - [15:0] */
3849
3850/*
3851 * R3609 (0xE19) - EQ1_10
3852 */
3853#define WM5100_EQ1_B3_A_MASK 0xFFFF /* EQ1_B3_A - [15:0] */
3854#define WM5100_EQ1_B3_A_SHIFT 0 /* EQ1_B3_A - [15:0] */
3855#define WM5100_EQ1_B3_A_WIDTH 16 /* EQ1_B3_A - [15:0] */
3856
3857/*
3858 * R3610 (0xE1A) - EQ1_11
3859 */
3860#define WM5100_EQ1_B3_B_MASK 0xFFFF /* EQ1_B3_B - [15:0] */
3861#define WM5100_EQ1_B3_B_SHIFT 0 /* EQ1_B3_B - [15:0] */
3862#define WM5100_EQ1_B3_B_WIDTH 16 /* EQ1_B3_B - [15:0] */
3863
3864/*
3865 * R3611 (0xE1B) - EQ1_12
3866 */
3867#define WM5100_EQ1_B3_C_MASK 0xFFFF /* EQ1_B3_C - [15:0] */
3868#define WM5100_EQ1_B3_C_SHIFT 0 /* EQ1_B3_C - [15:0] */
3869#define WM5100_EQ1_B3_C_WIDTH 16 /* EQ1_B3_C - [15:0] */
3870
3871/*
3872 * R3612 (0xE1C) - EQ1_13
3873 */
3874#define WM5100_EQ1_B3_PG_MASK 0xFFFF /* EQ1_B3_PG - [15:0] */
3875#define WM5100_EQ1_B3_PG_SHIFT 0 /* EQ1_B3_PG - [15:0] */
3876#define WM5100_EQ1_B3_PG_WIDTH 16 /* EQ1_B3_PG - [15:0] */
3877
3878/*
3879 * R3613 (0xE1D) - EQ1_14
3880 */
3881#define WM5100_EQ1_B4_A_MASK 0xFFFF /* EQ1_B4_A - [15:0] */
3882#define WM5100_EQ1_B4_A_SHIFT 0 /* EQ1_B4_A - [15:0] */
3883#define WM5100_EQ1_B4_A_WIDTH 16 /* EQ1_B4_A - [15:0] */
3884
3885/*
3886 * R3614 (0xE1E) - EQ1_15
3887 */
3888#define WM5100_EQ1_B4_B_MASK 0xFFFF /* EQ1_B4_B - [15:0] */
3889#define WM5100_EQ1_B4_B_SHIFT 0 /* EQ1_B4_B - [15:0] */
3890#define WM5100_EQ1_B4_B_WIDTH 16 /* EQ1_B4_B - [15:0] */
3891
3892/*
3893 * R3615 (0xE1F) - EQ1_16
3894 */
3895#define WM5100_EQ1_B4_C_MASK 0xFFFF /* EQ1_B4_C - [15:0] */
3896#define WM5100_EQ1_B4_C_SHIFT 0 /* EQ1_B4_C - [15:0] */
3897#define WM5100_EQ1_B4_C_WIDTH 16 /* EQ1_B4_C - [15:0] */
3898
3899/*
3900 * R3616 (0xE20) - EQ1_17
3901 */
3902#define WM5100_EQ1_B4_PG_MASK 0xFFFF /* EQ1_B4_PG - [15:0] */
3903#define WM5100_EQ1_B4_PG_SHIFT 0 /* EQ1_B4_PG - [15:0] */
3904#define WM5100_EQ1_B4_PG_WIDTH 16 /* EQ1_B4_PG - [15:0] */
3905
3906/*
3907 * R3617 (0xE21) - EQ1_18
3908 */
3909#define WM5100_EQ1_B5_A_MASK 0xFFFF /* EQ1_B5_A - [15:0] */
3910#define WM5100_EQ1_B5_A_SHIFT 0 /* EQ1_B5_A - [15:0] */
3911#define WM5100_EQ1_B5_A_WIDTH 16 /* EQ1_B5_A - [15:0] */
3912
3913/*
3914 * R3618 (0xE22) - EQ1_19
3915 */
3916#define WM5100_EQ1_B5_B_MASK 0xFFFF /* EQ1_B5_B - [15:0] */
3917#define WM5100_EQ1_B5_B_SHIFT 0 /* EQ1_B5_B - [15:0] */
3918#define WM5100_EQ1_B5_B_WIDTH 16 /* EQ1_B5_B - [15:0] */
3919
3920/*
3921 * R3619 (0xE23) - EQ1_20
3922 */
3923#define WM5100_EQ1_B5_PG_MASK 0xFFFF /* EQ1_B5_PG - [15:0] */
3924#define WM5100_EQ1_B5_PG_SHIFT 0 /* EQ1_B5_PG - [15:0] */
3925#define WM5100_EQ1_B5_PG_WIDTH 16 /* EQ1_B5_PG - [15:0] */
3926
3927/*
3928 * R3622 (0xE26) - EQ2_1
3929 */
3930#define WM5100_EQ2_B1_GAIN_MASK 0xF800 /* EQ2_B1_GAIN - [15:11] */
3931#define WM5100_EQ2_B1_GAIN_SHIFT 11 /* EQ2_B1_GAIN - [15:11] */
3932#define WM5100_EQ2_B1_GAIN_WIDTH 5 /* EQ2_B1_GAIN - [15:11] */
3933#define WM5100_EQ2_B2_GAIN_MASK 0x07C0 /* EQ2_B2_GAIN - [10:6] */
3934#define WM5100_EQ2_B2_GAIN_SHIFT 6 /* EQ2_B2_GAIN - [10:6] */
3935#define WM5100_EQ2_B2_GAIN_WIDTH 5 /* EQ2_B2_GAIN - [10:6] */
3936#define WM5100_EQ2_B3_GAIN_MASK 0x003E /* EQ2_B3_GAIN - [5:1] */
3937#define WM5100_EQ2_B3_GAIN_SHIFT 1 /* EQ2_B3_GAIN - [5:1] */
3938#define WM5100_EQ2_B3_GAIN_WIDTH 5 /* EQ2_B3_GAIN - [5:1] */
3939#define WM5100_EQ2_ENA 0x0001 /* EQ2_ENA */
3940#define WM5100_EQ2_ENA_MASK 0x0001 /* EQ2_ENA */
3941#define WM5100_EQ2_ENA_SHIFT 0 /* EQ2_ENA */
3942#define WM5100_EQ2_ENA_WIDTH 1 /* EQ2_ENA */
3943
3944/*
3945 * R3623 (0xE27) - EQ2_2
3946 */
3947#define WM5100_EQ2_B4_GAIN_MASK 0xF800 /* EQ2_B4_GAIN - [15:11] */
3948#define WM5100_EQ2_B4_GAIN_SHIFT 11 /* EQ2_B4_GAIN - [15:11] */
3949#define WM5100_EQ2_B4_GAIN_WIDTH 5 /* EQ2_B4_GAIN - [15:11] */
3950#define WM5100_EQ2_B5_GAIN_MASK 0x07C0 /* EQ2_B5_GAIN - [10:6] */
3951#define WM5100_EQ2_B5_GAIN_SHIFT 6 /* EQ2_B5_GAIN - [10:6] */
3952#define WM5100_EQ2_B5_GAIN_WIDTH 5 /* EQ2_B5_GAIN - [10:6] */
3953
3954/*
3955 * R3624 (0xE28) - EQ2_3
3956 */
3957#define WM5100_EQ2_B1_A_MASK 0xFFFF /* EQ2_B1_A - [15:0] */
3958#define WM5100_EQ2_B1_A_SHIFT 0 /* EQ2_B1_A - [15:0] */
3959#define WM5100_EQ2_B1_A_WIDTH 16 /* EQ2_B1_A - [15:0] */
3960
3961/*
3962 * R3625 (0xE29) - EQ2_4
3963 */
3964#define WM5100_EQ2_B1_B_MASK 0xFFFF /* EQ2_B1_B - [15:0] */
3965#define WM5100_EQ2_B1_B_SHIFT 0 /* EQ2_B1_B - [15:0] */
3966#define WM5100_EQ2_B1_B_WIDTH 16 /* EQ2_B1_B - [15:0] */
3967
3968/*
3969 * R3626 (0xE2A) - EQ2_5
3970 */
3971#define WM5100_EQ2_B1_PG_MASK 0xFFFF /* EQ2_B1_PG - [15:0] */
3972#define WM5100_EQ2_B1_PG_SHIFT 0 /* EQ2_B1_PG - [15:0] */
3973#define WM5100_EQ2_B1_PG_WIDTH 16 /* EQ2_B1_PG - [15:0] */
3974
3975/*
3976 * R3627 (0xE2B) - EQ2_6
3977 */
3978#define WM5100_EQ2_B2_A_MASK 0xFFFF /* EQ2_B2_A - [15:0] */
3979#define WM5100_EQ2_B2_A_SHIFT 0 /* EQ2_B2_A - [15:0] */
3980#define WM5100_EQ2_B2_A_WIDTH 16 /* EQ2_B2_A - [15:0] */
3981
3982/*
3983 * R3628 (0xE2C) - EQ2_7
3984 */
3985#define WM5100_EQ2_B2_B_MASK 0xFFFF /* EQ2_B2_B - [15:0] */
3986#define WM5100_EQ2_B2_B_SHIFT 0 /* EQ2_B2_B - [15:0] */
3987#define WM5100_EQ2_B2_B_WIDTH 16 /* EQ2_B2_B - [15:0] */
3988
3989/*
3990 * R3629 (0xE2D) - EQ2_8
3991 */
3992#define WM5100_EQ2_B2_C_MASK 0xFFFF /* EQ2_B2_C - [15:0] */
3993#define WM5100_EQ2_B2_C_SHIFT 0 /* EQ2_B2_C - [15:0] */
3994#define WM5100_EQ2_B2_C_WIDTH 16 /* EQ2_B2_C - [15:0] */
3995
3996/*
3997 * R3630 (0xE2E) - EQ2_9
3998 */
3999#define WM5100_EQ2_B2_PG_MASK 0xFFFF /* EQ2_B2_PG - [15:0] */
4000#define WM5100_EQ2_B2_PG_SHIFT 0 /* EQ2_B2_PG - [15:0] */
4001#define WM5100_EQ2_B2_PG_WIDTH 16 /* EQ2_B2_PG - [15:0] */
4002
4003/*
4004 * R3631 (0xE2F) - EQ2_10
4005 */
4006#define WM5100_EQ2_B3_A_MASK 0xFFFF /* EQ2_B3_A - [15:0] */
4007#define WM5100_EQ2_B3_A_SHIFT 0 /* EQ2_B3_A - [15:0] */
4008#define WM5100_EQ2_B3_A_WIDTH 16 /* EQ2_B3_A - [15:0] */
4009
4010/*
4011 * R3632 (0xE30) - EQ2_11
4012 */
4013#define WM5100_EQ2_B3_B_MASK 0xFFFF /* EQ2_B3_B - [15:0] */
4014#define WM5100_EQ2_B3_B_SHIFT 0 /* EQ2_B3_B - [15:0] */
4015#define WM5100_EQ2_B3_B_WIDTH 16 /* EQ2_B3_B - [15:0] */
4016
4017/*
4018 * R3633 (0xE31) - EQ2_12
4019 */
4020#define WM5100_EQ2_B3_C_MASK 0xFFFF /* EQ2_B3_C - [15:0] */
4021#define WM5100_EQ2_B3_C_SHIFT 0 /* EQ2_B3_C - [15:0] */
4022#define WM5100_EQ2_B3_C_WIDTH 16 /* EQ2_B3_C - [15:0] */
4023
4024/*
4025 * R3634 (0xE32) - EQ2_13
4026 */
4027#define WM5100_EQ2_B3_PG_MASK 0xFFFF /* EQ2_B3_PG - [15:0] */
4028#define WM5100_EQ2_B3_PG_SHIFT 0 /* EQ2_B3_PG - [15:0] */
4029#define WM5100_EQ2_B3_PG_WIDTH 16 /* EQ2_B3_PG - [15:0] */
4030
4031/*
4032 * R3635 (0xE33) - EQ2_14
4033 */
4034#define WM5100_EQ2_B4_A_MASK 0xFFFF /* EQ2_B4_A - [15:0] */
4035#define WM5100_EQ2_B4_A_SHIFT 0 /* EQ2_B4_A - [15:0] */
4036#define WM5100_EQ2_B4_A_WIDTH 16 /* EQ2_B4_A - [15:0] */
4037
4038/*
4039 * R3636 (0xE34) - EQ2_15
4040 */
4041#define WM5100_EQ2_B4_B_MASK 0xFFFF /* EQ2_B4_B - [15:0] */
4042#define WM5100_EQ2_B4_B_SHIFT 0 /* EQ2_B4_B - [15:0] */
4043#define WM5100_EQ2_B4_B_WIDTH 16 /* EQ2_B4_B - [15:0] */
4044
4045/*
4046 * R3637 (0xE35) - EQ2_16
4047 */
4048#define WM5100_EQ2_B4_C_MASK 0xFFFF /* EQ2_B4_C - [15:0] */
4049#define WM5100_EQ2_B4_C_SHIFT 0 /* EQ2_B4_C - [15:0] */
4050#define WM5100_EQ2_B4_C_WIDTH 16 /* EQ2_B4_C - [15:0] */
4051
4052/*
4053 * R3638 (0xE36) - EQ2_17
4054 */
4055#define WM5100_EQ2_B4_PG_MASK 0xFFFF /* EQ2_B4_PG - [15:0] */
4056#define WM5100_EQ2_B4_PG_SHIFT 0 /* EQ2_B4_PG - [15:0] */
4057#define WM5100_EQ2_B4_PG_WIDTH 16 /* EQ2_B4_PG - [15:0] */
4058
4059/*
4060 * R3639 (0xE37) - EQ2_18
4061 */
4062#define WM5100_EQ2_B5_A_MASK 0xFFFF /* EQ2_B5_A - [15:0] */
4063#define WM5100_EQ2_B5_A_SHIFT 0 /* EQ2_B5_A - [15:0] */
4064#define WM5100_EQ2_B5_A_WIDTH 16 /* EQ2_B5_A - [15:0] */
4065
4066/*
4067 * R3640 (0xE38) - EQ2_19
4068 */
4069#define WM5100_EQ2_B5_B_MASK 0xFFFF /* EQ2_B5_B - [15:0] */
4070#define WM5100_EQ2_B5_B_SHIFT 0 /* EQ2_B5_B - [15:0] */
4071#define WM5100_EQ2_B5_B_WIDTH 16 /* EQ2_B5_B - [15:0] */
4072
4073/*
4074 * R3641 (0xE39) - EQ2_20
4075 */
4076#define WM5100_EQ2_B5_PG_MASK 0xFFFF /* EQ2_B5_PG - [15:0] */
4077#define WM5100_EQ2_B5_PG_SHIFT 0 /* EQ2_B5_PG - [15:0] */
4078#define WM5100_EQ2_B5_PG_WIDTH 16 /* EQ2_B5_PG - [15:0] */
4079
4080/*
4081 * R3644 (0xE3C) - EQ3_1
4082 */
4083#define WM5100_EQ3_B1_GAIN_MASK 0xF800 /* EQ3_B1_GAIN - [15:11] */
4084#define WM5100_EQ3_B1_GAIN_SHIFT 11 /* EQ3_B1_GAIN - [15:11] */
4085#define WM5100_EQ3_B1_GAIN_WIDTH 5 /* EQ3_B1_GAIN - [15:11] */
4086#define WM5100_EQ3_B2_GAIN_MASK 0x07C0 /* EQ3_B2_GAIN - [10:6] */
4087#define WM5100_EQ3_B2_GAIN_SHIFT 6 /* EQ3_B2_GAIN - [10:6] */
4088#define WM5100_EQ3_B2_GAIN_WIDTH 5 /* EQ3_B2_GAIN - [10:6] */
4089#define WM5100_EQ3_B3_GAIN_MASK 0x003E /* EQ3_B3_GAIN - [5:1] */
4090#define WM5100_EQ3_B3_GAIN_SHIFT 1 /* EQ3_B3_GAIN - [5:1] */
4091#define WM5100_EQ3_B3_GAIN_WIDTH 5 /* EQ3_B3_GAIN - [5:1] */
4092#define WM5100_EQ3_ENA 0x0001 /* EQ3_ENA */
4093#define WM5100_EQ3_ENA_MASK 0x0001 /* EQ3_ENA */
4094#define WM5100_EQ3_ENA_SHIFT 0 /* EQ3_ENA */
4095#define WM5100_EQ3_ENA_WIDTH 1 /* EQ3_ENA */
4096
4097/*
4098 * R3645 (0xE3D) - EQ3_2
4099 */
4100#define WM5100_EQ3_B4_GAIN_MASK 0xF800 /* EQ3_B4_GAIN - [15:11] */
4101#define WM5100_EQ3_B4_GAIN_SHIFT 11 /* EQ3_B4_GAIN - [15:11] */
4102#define WM5100_EQ3_B4_GAIN_WIDTH 5 /* EQ3_B4_GAIN - [15:11] */
4103#define WM5100_EQ3_B5_GAIN_MASK 0x07C0 /* EQ3_B5_GAIN - [10:6] */
4104#define WM5100_EQ3_B5_GAIN_SHIFT 6 /* EQ3_B5_GAIN - [10:6] */
4105#define WM5100_EQ3_B5_GAIN_WIDTH 5 /* EQ3_B5_GAIN - [10:6] */
4106
4107/*
4108 * R3646 (0xE3E) - EQ3_3
4109 */
4110#define WM5100_EQ3_B1_A_MASK 0xFFFF /* EQ3_B1_A - [15:0] */
4111#define WM5100_EQ3_B1_A_SHIFT 0 /* EQ3_B1_A - [15:0] */
4112#define WM5100_EQ3_B1_A_WIDTH 16 /* EQ3_B1_A - [15:0] */
4113
4114/*
4115 * R3647 (0xE3F) - EQ3_4
4116 */
4117#define WM5100_EQ3_B1_B_MASK 0xFFFF /* EQ3_B1_B - [15:0] */
4118#define WM5100_EQ3_B1_B_SHIFT 0 /* EQ3_B1_B - [15:0] */
4119#define WM5100_EQ3_B1_B_WIDTH 16 /* EQ3_B1_B - [15:0] */
4120
4121/*
4122 * R3648 (0xE40) - EQ3_5
4123 */
4124#define WM5100_EQ3_B1_PG_MASK 0xFFFF /* EQ3_B1_PG - [15:0] */
4125#define WM5100_EQ3_B1_PG_SHIFT 0 /* EQ3_B1_PG - [15:0] */
4126#define WM5100_EQ3_B1_PG_WIDTH 16 /* EQ3_B1_PG - [15:0] */
4127
4128/*
4129 * R3649 (0xE41) - EQ3_6
4130 */
4131#define WM5100_EQ3_B2_A_MASK 0xFFFF /* EQ3_B2_A - [15:0] */
4132#define WM5100_EQ3_B2_A_SHIFT 0 /* EQ3_B2_A - [15:0] */
4133#define WM5100_EQ3_B2_A_WIDTH 16 /* EQ3_B2_A - [15:0] */
4134
4135/*
4136 * R3650 (0xE42) - EQ3_7
4137 */
4138#define WM5100_EQ3_B2_B_MASK 0xFFFF /* EQ3_B2_B - [15:0] */
4139#define WM5100_EQ3_B2_B_SHIFT 0 /* EQ3_B2_B - [15:0] */
4140#define WM5100_EQ3_B2_B_WIDTH 16 /* EQ3_B2_B - [15:0] */
4141
4142/*
4143 * R3651 (0xE43) - EQ3_8
4144 */
4145#define WM5100_EQ3_B2_C_MASK 0xFFFF /* EQ3_B2_C - [15:0] */
4146#define WM5100_EQ3_B2_C_SHIFT 0 /* EQ3_B2_C - [15:0] */
4147#define WM5100_EQ3_B2_C_WIDTH 16 /* EQ3_B2_C - [15:0] */
4148
4149/*
4150 * R3652 (0xE44) - EQ3_9
4151 */
4152#define WM5100_EQ3_B2_PG_MASK 0xFFFF /* EQ3_B2_PG - [15:0] */
4153#define WM5100_EQ3_B2_PG_SHIFT 0 /* EQ3_B2_PG - [15:0] */
4154#define WM5100_EQ3_B2_PG_WIDTH 16 /* EQ3_B2_PG - [15:0] */
4155
4156/*
4157 * R3653 (0xE45) - EQ3_10
4158 */
4159#define WM5100_EQ3_B3_A_MASK 0xFFFF /* EQ3_B3_A - [15:0] */
4160#define WM5100_EQ3_B3_A_SHIFT 0 /* EQ3_B3_A - [15:0] */
4161#define WM5100_EQ3_B3_A_WIDTH 16 /* EQ3_B3_A - [15:0] */
4162
4163/*
4164 * R3654 (0xE46) - EQ3_11
4165 */
4166#define WM5100_EQ3_B3_B_MASK 0xFFFF /* EQ3_B3_B - [15:0] */
4167#define WM5100_EQ3_B3_B_SHIFT 0 /* EQ3_B3_B - [15:0] */
4168#define WM5100_EQ3_B3_B_WIDTH 16 /* EQ3_B3_B - [15:0] */
4169
4170/*
4171 * R3655 (0xE47) - EQ3_12
4172 */
4173#define WM5100_EQ3_B3_C_MASK 0xFFFF /* EQ3_B3_C - [15:0] */
4174#define WM5100_EQ3_B3_C_SHIFT 0 /* EQ3_B3_C - [15:0] */
4175#define WM5100_EQ3_B3_C_WIDTH 16 /* EQ3_B3_C - [15:0] */
4176
4177/*
4178 * R3656 (0xE48) - EQ3_13
4179 */
4180#define WM5100_EQ3_B3_PG_MASK 0xFFFF /* EQ3_B3_PG - [15:0] */
4181#define WM5100_EQ3_B3_PG_SHIFT 0 /* EQ3_B3_PG - [15:0] */
4182#define WM5100_EQ3_B3_PG_WIDTH 16 /* EQ3_B3_PG - [15:0] */
4183
4184/*
4185 * R3657 (0xE49) - EQ3_14
4186 */
4187#define WM5100_EQ3_B4_A_MASK 0xFFFF /* EQ3_B4_A - [15:0] */
4188#define WM5100_EQ3_B4_A_SHIFT 0 /* EQ3_B4_A - [15:0] */
4189#define WM5100_EQ3_B4_A_WIDTH 16 /* EQ3_B4_A - [15:0] */
4190
4191/*
4192 * R3658 (0xE4A) - EQ3_15
4193 */
4194#define WM5100_EQ3_B4_B_MASK 0xFFFF /* EQ3_B4_B - [15:0] */
4195#define WM5100_EQ3_B4_B_SHIFT 0 /* EQ3_B4_B - [15:0] */
4196#define WM5100_EQ3_B4_B_WIDTH 16 /* EQ3_B4_B - [15:0] */
4197
4198/*
4199 * R3659 (0xE4B) - EQ3_16
4200 */
4201#define WM5100_EQ3_B4_C_MASK 0xFFFF /* EQ3_B4_C - [15:0] */
4202#define WM5100_EQ3_B4_C_SHIFT 0 /* EQ3_B4_C - [15:0] */
4203#define WM5100_EQ3_B4_C_WIDTH 16 /* EQ3_B4_C - [15:0] */
4204
4205/*
4206 * R3660 (0xE4C) - EQ3_17
4207 */
4208#define WM5100_EQ3_B4_PG_MASK 0xFFFF /* EQ3_B4_PG - [15:0] */
4209#define WM5100_EQ3_B4_PG_SHIFT 0 /* EQ3_B4_PG - [15:0] */
4210#define WM5100_EQ3_B4_PG_WIDTH 16 /* EQ3_B4_PG - [15:0] */
4211
4212/*
4213 * R3661 (0xE4D) - EQ3_18
4214 */
4215#define WM5100_EQ3_B5_A_MASK 0xFFFF /* EQ3_B5_A - [15:0] */
4216#define WM5100_EQ3_B5_A_SHIFT 0 /* EQ3_B5_A - [15:0] */
4217#define WM5100_EQ3_B5_A_WIDTH 16 /* EQ3_B5_A - [15:0] */
4218
4219/*
4220 * R3662 (0xE4E) - EQ3_19
4221 */
4222#define WM5100_EQ3_B5_B_MASK 0xFFFF /* EQ3_B5_B - [15:0] */
4223#define WM5100_EQ3_B5_B_SHIFT 0 /* EQ3_B5_B - [15:0] */
4224#define WM5100_EQ3_B5_B_WIDTH 16 /* EQ3_B5_B - [15:0] */
4225
4226/*
4227 * R3663 (0xE4F) - EQ3_20
4228 */
4229#define WM5100_EQ3_B5_PG_MASK 0xFFFF /* EQ3_B5_PG - [15:0] */
4230#define WM5100_EQ3_B5_PG_SHIFT 0 /* EQ3_B5_PG - [15:0] */
4231#define WM5100_EQ3_B5_PG_WIDTH 16 /* EQ3_B5_PG - [15:0] */
4232
4233/*
4234 * R3666 (0xE52) - EQ4_1
4235 */
4236#define WM5100_EQ4_B1_GAIN_MASK 0xF800 /* EQ4_B1_GAIN - [15:11] */
4237#define WM5100_EQ4_B1_GAIN_SHIFT 11 /* EQ4_B1_GAIN - [15:11] */
4238#define WM5100_EQ4_B1_GAIN_WIDTH 5 /* EQ4_B1_GAIN - [15:11] */
4239#define WM5100_EQ4_B2_GAIN_MASK 0x07C0 /* EQ4_B2_GAIN - [10:6] */
4240#define WM5100_EQ4_B2_GAIN_SHIFT 6 /* EQ4_B2_GAIN - [10:6] */
4241#define WM5100_EQ4_B2_GAIN_WIDTH 5 /* EQ4_B2_GAIN - [10:6] */
4242#define WM5100_EQ4_B3_GAIN_MASK 0x003E /* EQ4_B3_GAIN - [5:1] */
4243#define WM5100_EQ4_B3_GAIN_SHIFT 1 /* EQ4_B3_GAIN - [5:1] */
4244#define WM5100_EQ4_B3_GAIN_WIDTH 5 /* EQ4_B3_GAIN - [5:1] */
4245#define WM5100_EQ4_ENA 0x0001 /* EQ4_ENA */
4246#define WM5100_EQ4_ENA_MASK 0x0001 /* EQ4_ENA */
4247#define WM5100_EQ4_ENA_SHIFT 0 /* EQ4_ENA */
4248#define WM5100_EQ4_ENA_WIDTH 1 /* EQ4_ENA */
4249
4250/*
4251 * R3667 (0xE53) - EQ4_2
4252 */
4253#define WM5100_EQ4_B4_GAIN_MASK 0xF800 /* EQ4_B4_GAIN - [15:11] */
4254#define WM5100_EQ4_B4_GAIN_SHIFT 11 /* EQ4_B4_GAIN - [15:11] */
4255#define WM5100_EQ4_B4_GAIN_WIDTH 5 /* EQ4_B4_GAIN - [15:11] */
4256#define WM5100_EQ4_B5_GAIN_MASK 0x07C0 /* EQ4_B5_GAIN - [10:6] */
4257#define WM5100_EQ4_B5_GAIN_SHIFT 6 /* EQ4_B5_GAIN - [10:6] */
4258#define WM5100_EQ4_B5_GAIN_WIDTH 5 /* EQ4_B5_GAIN - [10:6] */
4259
4260/*
4261 * R3668 (0xE54) - EQ4_3
4262 */
4263#define WM5100_EQ4_B1_A_MASK 0xFFFF /* EQ4_B1_A - [15:0] */
4264#define WM5100_EQ4_B1_A_SHIFT 0 /* EQ4_B1_A - [15:0] */
4265#define WM5100_EQ4_B1_A_WIDTH 16 /* EQ4_B1_A - [15:0] */
4266
4267/*
4268 * R3669 (0xE55) - EQ4_4
4269 */
4270#define WM5100_EQ4_B1_B_MASK 0xFFFF /* EQ4_B1_B - [15:0] */
4271#define WM5100_EQ4_B1_B_SHIFT 0 /* EQ4_B1_B - [15:0] */
4272#define WM5100_EQ4_B1_B_WIDTH 16 /* EQ4_B1_B - [15:0] */
4273
4274/*
4275 * R3670 (0xE56) - EQ4_5
4276 */
4277#define WM5100_EQ4_B1_PG_MASK 0xFFFF /* EQ4_B1_PG - [15:0] */
4278#define WM5100_EQ4_B1_PG_SHIFT 0 /* EQ4_B1_PG - [15:0] */
4279#define WM5100_EQ4_B1_PG_WIDTH 16 /* EQ4_B1_PG - [15:0] */
4280
4281/*
4282 * R3671 (0xE57) - EQ4_6
4283 */
4284#define WM5100_EQ4_B2_A_MASK 0xFFFF /* EQ4_B2_A - [15:0] */
4285#define WM5100_EQ4_B2_A_SHIFT 0 /* EQ4_B2_A - [15:0] */
4286#define WM5100_EQ4_B2_A_WIDTH 16 /* EQ4_B2_A - [15:0] */
4287
4288/*
4289 * R3672 (0xE58) - EQ4_7
4290 */
4291#define WM5100_EQ4_B2_B_MASK 0xFFFF /* EQ4_B2_B - [15:0] */
4292#define WM5100_EQ4_B2_B_SHIFT 0 /* EQ4_B2_B - [15:0] */
4293#define WM5100_EQ4_B2_B_WIDTH 16 /* EQ4_B2_B - [15:0] */
4294
4295/*
4296 * R3673 (0xE59) - EQ4_8
4297 */
4298#define WM5100_EQ4_B2_C_MASK 0xFFFF /* EQ4_B2_C - [15:0] */
4299#define WM5100_EQ4_B2_C_SHIFT 0 /* EQ4_B2_C - [15:0] */
4300#define WM5100_EQ4_B2_C_WIDTH 16 /* EQ4_B2_C - [15:0] */
4301
4302/*
4303 * R3674 (0xE5A) - EQ4_9
4304 */
4305#define WM5100_EQ4_B2_PG_MASK 0xFFFF /* EQ4_B2_PG - [15:0] */
4306#define WM5100_EQ4_B2_PG_SHIFT 0 /* EQ4_B2_PG - [15:0] */
4307#define WM5100_EQ4_B2_PG_WIDTH 16 /* EQ4_B2_PG - [15:0] */
4308
4309/*
4310 * R3675 (0xE5B) - EQ4_10
4311 */
4312#define WM5100_EQ4_B3_A_MASK 0xFFFF /* EQ4_B3_A - [15:0] */
4313#define WM5100_EQ4_B3_A_SHIFT 0 /* EQ4_B3_A - [15:0] */
4314#define WM5100_EQ4_B3_A_WIDTH 16 /* EQ4_B3_A - [15:0] */
4315
4316/*
4317 * R3676 (0xE5C) - EQ4_11
4318 */
4319#define WM5100_EQ4_B3_B_MASK 0xFFFF /* EQ4_B3_B - [15:0] */
4320#define WM5100_EQ4_B3_B_SHIFT 0 /* EQ4_B3_B - [15:0] */
4321#define WM5100_EQ4_B3_B_WIDTH 16 /* EQ4_B3_B - [15:0] */
4322
4323/*
4324 * R3677 (0xE5D) - EQ4_12
4325 */
4326#define WM5100_EQ4_B3_C_MASK 0xFFFF /* EQ4_B3_C - [15:0] */
4327#define WM5100_EQ4_B3_C_SHIFT 0 /* EQ4_B3_C - [15:0] */
4328#define WM5100_EQ4_B3_C_WIDTH 16 /* EQ4_B3_C - [15:0] */
4329
4330/*
4331 * R3678 (0xE5E) - EQ4_13
4332 */
4333#define WM5100_EQ4_B3_PG_MASK 0xFFFF /* EQ4_B3_PG - [15:0] */
4334#define WM5100_EQ4_B3_PG_SHIFT 0 /* EQ4_B3_PG - [15:0] */
4335#define WM5100_EQ4_B3_PG_WIDTH 16 /* EQ4_B3_PG - [15:0] */
4336
4337/*
4338 * R3679 (0xE5F) - EQ4_14
4339 */
4340#define WM5100_EQ4_B4_A_MASK 0xFFFF /* EQ4_B4_A - [15:0] */
4341#define WM5100_EQ4_B4_A_SHIFT 0 /* EQ4_B4_A - [15:0] */
4342#define WM5100_EQ4_B4_A_WIDTH 16 /* EQ4_B4_A - [15:0] */
4343
4344/*
4345 * R3680 (0xE60) - EQ4_15
4346 */
4347#define WM5100_EQ4_B4_B_MASK 0xFFFF /* EQ4_B4_B - [15:0] */
4348#define WM5100_EQ4_B4_B_SHIFT 0 /* EQ4_B4_B - [15:0] */
4349#define WM5100_EQ4_B4_B_WIDTH 16 /* EQ4_B4_B - [15:0] */
4350
4351/*
4352 * R3681 (0xE61) - EQ4_16
4353 */
4354#define WM5100_EQ4_B4_C_MASK 0xFFFF /* EQ4_B4_C - [15:0] */
4355#define WM5100_EQ4_B4_C_SHIFT 0 /* EQ4_B4_C - [15:0] */
4356#define WM5100_EQ4_B4_C_WIDTH 16 /* EQ4_B4_C - [15:0] */
4357
4358/*
4359 * R3682 (0xE62) - EQ4_17
4360 */
4361#define WM5100_EQ4_B4_PG_MASK 0xFFFF /* EQ4_B4_PG - [15:0] */
4362#define WM5100_EQ4_B4_PG_SHIFT 0 /* EQ4_B4_PG - [15:0] */
4363#define WM5100_EQ4_B4_PG_WIDTH 16 /* EQ4_B4_PG - [15:0] */
4364
4365/*
4366 * R3683 (0xE63) - EQ4_18
4367 */
4368#define WM5100_EQ4_B5_A_MASK 0xFFFF /* EQ4_B5_A - [15:0] */
4369#define WM5100_EQ4_B5_A_SHIFT 0 /* EQ4_B5_A - [15:0] */
4370#define WM5100_EQ4_B5_A_WIDTH 16 /* EQ4_B5_A - [15:0] */
4371
4372/*
4373 * R3684 (0xE64) - EQ4_19
4374 */
4375#define WM5100_EQ4_B5_B_MASK 0xFFFF /* EQ4_B5_B - [15:0] */
4376#define WM5100_EQ4_B5_B_SHIFT 0 /* EQ4_B5_B - [15:0] */
4377#define WM5100_EQ4_B5_B_WIDTH 16 /* EQ4_B5_B - [15:0] */
4378
4379/*
4380 * R3685 (0xE65) - EQ4_20
4381 */
4382#define WM5100_EQ4_B5_PG_MASK 0xFFFF /* EQ4_B5_PG - [15:0] */
4383#define WM5100_EQ4_B5_PG_SHIFT 0 /* EQ4_B5_PG - [15:0] */
4384#define WM5100_EQ4_B5_PG_WIDTH 16 /* EQ4_B5_PG - [15:0] */
4385
4386/*
4387 * R3712 (0xE80) - DRC1 ctrl1
4388 */
4389#define WM5100_DRC_SIG_DET_RMS_MASK 0xF800 /* DRC_SIG_DET_RMS - [15:11] */
4390#define WM5100_DRC_SIG_DET_RMS_SHIFT 11 /* DRC_SIG_DET_RMS - [15:11] */
4391#define WM5100_DRC_SIG_DET_RMS_WIDTH 5 /* DRC_SIG_DET_RMS - [15:11] */
4392#define WM5100_DRC_SIG_DET_PK_MASK 0x0600 /* DRC_SIG_DET_PK - [10:9] */
4393#define WM5100_DRC_SIG_DET_PK_SHIFT 9 /* DRC_SIG_DET_PK - [10:9] */
4394#define WM5100_DRC_SIG_DET_PK_WIDTH 2 /* DRC_SIG_DET_PK - [10:9] */
4395#define WM5100_DRC_NG_ENA 0x0100 /* DRC_NG_ENA */
4396#define WM5100_DRC_NG_ENA_MASK 0x0100 /* DRC_NG_ENA */
4397#define WM5100_DRC_NG_ENA_SHIFT 8 /* DRC_NG_ENA */
4398#define WM5100_DRC_NG_ENA_WIDTH 1 /* DRC_NG_ENA */
4399#define WM5100_DRC_SIG_DET_MODE 0x0080 /* DRC_SIG_DET_MODE */
4400#define WM5100_DRC_SIG_DET_MODE_MASK 0x0080 /* DRC_SIG_DET_MODE */
4401#define WM5100_DRC_SIG_DET_MODE_SHIFT 7 /* DRC_SIG_DET_MODE */
4402#define WM5100_DRC_SIG_DET_MODE_WIDTH 1 /* DRC_SIG_DET_MODE */
4403#define WM5100_DRC_SIG_DET 0x0040 /* DRC_SIG_DET */
4404#define WM5100_DRC_SIG_DET_MASK 0x0040 /* DRC_SIG_DET */
4405#define WM5100_DRC_SIG_DET_SHIFT 6 /* DRC_SIG_DET */
4406#define WM5100_DRC_SIG_DET_WIDTH 1 /* DRC_SIG_DET */
4407#define WM5100_DRC_KNEE2_OP_ENA 0x0020 /* DRC_KNEE2_OP_ENA */
4408#define WM5100_DRC_KNEE2_OP_ENA_MASK 0x0020 /* DRC_KNEE2_OP_ENA */
4409#define WM5100_DRC_KNEE2_OP_ENA_SHIFT 5 /* DRC_KNEE2_OP_ENA */
4410#define WM5100_DRC_KNEE2_OP_ENA_WIDTH 1 /* DRC_KNEE2_OP_ENA */
4411#define WM5100_DRC_QR 0x0010 /* DRC_QR */
4412#define WM5100_DRC_QR_MASK 0x0010 /* DRC_QR */
4413#define WM5100_DRC_QR_SHIFT 4 /* DRC_QR */
4414#define WM5100_DRC_QR_WIDTH 1 /* DRC_QR */
4415#define WM5100_DRC_ANTICLIP 0x0008 /* DRC_ANTICLIP */
4416#define WM5100_DRC_ANTICLIP_MASK 0x0008 /* DRC_ANTICLIP */
4417#define WM5100_DRC_ANTICLIP_SHIFT 3 /* DRC_ANTICLIP */
4418#define WM5100_DRC_ANTICLIP_WIDTH 1 /* DRC_ANTICLIP */
4419#define WM5100_DRCL_ENA 0x0002 /* DRCL_ENA */
4420#define WM5100_DRCL_ENA_MASK 0x0002 /* DRCL_ENA */
4421#define WM5100_DRCL_ENA_SHIFT 1 /* DRCL_ENA */
4422#define WM5100_DRCL_ENA_WIDTH 1 /* DRCL_ENA */
4423#define WM5100_DRCR_ENA 0x0001 /* DRCR_ENA */
4424#define WM5100_DRCR_ENA_MASK 0x0001 /* DRCR_ENA */
4425#define WM5100_DRCR_ENA_SHIFT 0 /* DRCR_ENA */
4426#define WM5100_DRCR_ENA_WIDTH 1 /* DRCR_ENA */
4427
4428/*
4429 * R3713 (0xE81) - DRC1 ctrl2
4430 */
4431#define WM5100_DRC_ATK_MASK 0x1E00 /* DRC_ATK - [12:9] */
4432#define WM5100_DRC_ATK_SHIFT 9 /* DRC_ATK - [12:9] */
4433#define WM5100_DRC_ATK_WIDTH 4 /* DRC_ATK - [12:9] */
4434#define WM5100_DRC_DCY_MASK 0x01E0 /* DRC_DCY - [8:5] */
4435#define WM5100_DRC_DCY_SHIFT 5 /* DRC_DCY - [8:5] */
4436#define WM5100_DRC_DCY_WIDTH 4 /* DRC_DCY - [8:5] */
4437#define WM5100_DRC_MINGAIN_MASK 0x001C /* DRC_MINGAIN - [4:2] */
4438#define WM5100_DRC_MINGAIN_SHIFT 2 /* DRC_MINGAIN - [4:2] */
4439#define WM5100_DRC_MINGAIN_WIDTH 3 /* DRC_MINGAIN - [4:2] */
4440#define WM5100_DRC_MAXGAIN_MASK 0x0003 /* DRC_MAXGAIN - [1:0] */
4441#define WM5100_DRC_MAXGAIN_SHIFT 0 /* DRC_MAXGAIN - [1:0] */
4442#define WM5100_DRC_MAXGAIN_WIDTH 2 /* DRC_MAXGAIN - [1:0] */
4443
4444/*
4445 * R3714 (0xE82) - DRC1 ctrl3
4446 */
4447#define WM5100_DRC_NG_MINGAIN_MASK 0xF000 /* DRC_NG_MINGAIN - [15:12] */
4448#define WM5100_DRC_NG_MINGAIN_SHIFT 12 /* DRC_NG_MINGAIN - [15:12] */
4449#define WM5100_DRC_NG_MINGAIN_WIDTH 4 /* DRC_NG_MINGAIN - [15:12] */
4450#define WM5100_DRC_NG_EXP_MASK 0x0C00 /* DRC_NG_EXP - [11:10] */
4451#define WM5100_DRC_NG_EXP_SHIFT 10 /* DRC_NG_EXP - [11:10] */
4452#define WM5100_DRC_NG_EXP_WIDTH 2 /* DRC_NG_EXP - [11:10] */
4453#define WM5100_DRC_QR_THR_MASK 0x0300 /* DRC_QR_THR - [9:8] */
4454#define WM5100_DRC_QR_THR_SHIFT 8 /* DRC_QR_THR - [9:8] */
4455#define WM5100_DRC_QR_THR_WIDTH 2 /* DRC_QR_THR - [9:8] */
4456#define WM5100_DRC_QR_DCY_MASK 0x00C0 /* DRC_QR_DCY - [7:6] */
4457#define WM5100_DRC_QR_DCY_SHIFT 6 /* DRC_QR_DCY - [7:6] */
4458#define WM5100_DRC_QR_DCY_WIDTH 2 /* DRC_QR_DCY - [7:6] */
4459#define WM5100_DRC_HI_COMP_MASK 0x0038 /* DRC_HI_COMP - [5:3] */
4460#define WM5100_DRC_HI_COMP_SHIFT 3 /* DRC_HI_COMP - [5:3] */
4461#define WM5100_DRC_HI_COMP_WIDTH 3 /* DRC_HI_COMP - [5:3] */
4462#define WM5100_DRC_LO_COMP_MASK 0x0007 /* DRC_LO_COMP - [2:0] */
4463#define WM5100_DRC_LO_COMP_SHIFT 0 /* DRC_LO_COMP - [2:0] */
4464#define WM5100_DRC_LO_COMP_WIDTH 3 /* DRC_LO_COMP - [2:0] */
4465
4466/*
4467 * R3715 (0xE83) - DRC1 ctrl4
4468 */
4469#define WM5100_DRC_KNEE_IP_MASK 0x07E0 /* DRC_KNEE_IP - [10:5] */
4470#define WM5100_DRC_KNEE_IP_SHIFT 5 /* DRC_KNEE_IP - [10:5] */
4471#define WM5100_DRC_KNEE_IP_WIDTH 6 /* DRC_KNEE_IP - [10:5] */
4472#define WM5100_DRC_KNEE_OP_MASK 0x001F /* DRC_KNEE_OP - [4:0] */
4473#define WM5100_DRC_KNEE_OP_SHIFT 0 /* DRC_KNEE_OP - [4:0] */
4474#define WM5100_DRC_KNEE_OP_WIDTH 5 /* DRC_KNEE_OP - [4:0] */
4475
4476/*
4477 * R3716 (0xE84) - DRC1 ctrl5
4478 */
4479#define WM5100_DRC_KNEE2_IP_MASK 0x03E0 /* DRC_KNEE2_IP - [9:5] */
4480#define WM5100_DRC_KNEE2_IP_SHIFT 5 /* DRC_KNEE2_IP - [9:5] */
4481#define WM5100_DRC_KNEE2_IP_WIDTH 5 /* DRC_KNEE2_IP - [9:5] */
4482#define WM5100_DRC_KNEE2_OP_MASK 0x001F /* DRC_KNEE2_OP - [4:0] */
4483#define WM5100_DRC_KNEE2_OP_SHIFT 0 /* DRC_KNEE2_OP - [4:0] */
4484#define WM5100_DRC_KNEE2_OP_WIDTH 5 /* DRC_KNEE2_OP - [4:0] */
4485
4486/*
4487 * R3776 (0xEC0) - HPLPF1_1
4488 */
4489#define WM5100_LHPF1_MODE 0x0002 /* LHPF1_MODE */
4490#define WM5100_LHPF1_MODE_MASK 0x0002 /* LHPF1_MODE */
4491#define WM5100_LHPF1_MODE_SHIFT 1 /* LHPF1_MODE */
4492#define WM5100_LHPF1_MODE_WIDTH 1 /* LHPF1_MODE */
4493#define WM5100_LHPF1_ENA 0x0001 /* LHPF1_ENA */
4494#define WM5100_LHPF1_ENA_MASK 0x0001 /* LHPF1_ENA */
4495#define WM5100_LHPF1_ENA_SHIFT 0 /* LHPF1_ENA */
4496#define WM5100_LHPF1_ENA_WIDTH 1 /* LHPF1_ENA */
4497
4498/*
4499 * R3777 (0xEC1) - HPLPF1_2
4500 */
4501#define WM5100_LHPF1_COEFF_MASK 0xFFFF /* LHPF1_COEFF - [15:0] */
4502#define WM5100_LHPF1_COEFF_SHIFT 0 /* LHPF1_COEFF - [15:0] */
4503#define WM5100_LHPF1_COEFF_WIDTH 16 /* LHPF1_COEFF - [15:0] */
4504
4505/*
4506 * R3780 (0xEC4) - HPLPF2_1
4507 */
4508#define WM5100_LHPF2_MODE 0x0002 /* LHPF2_MODE */
4509#define WM5100_LHPF2_MODE_MASK 0x0002 /* LHPF2_MODE */
4510#define WM5100_LHPF2_MODE_SHIFT 1 /* LHPF2_MODE */
4511#define WM5100_LHPF2_MODE_WIDTH 1 /* LHPF2_MODE */
4512#define WM5100_LHPF2_ENA 0x0001 /* LHPF2_ENA */
4513#define WM5100_LHPF2_ENA_MASK 0x0001 /* LHPF2_ENA */
4514#define WM5100_LHPF2_ENA_SHIFT 0 /* LHPF2_ENA */
4515#define WM5100_LHPF2_ENA_WIDTH 1 /* LHPF2_ENA */
4516
4517/*
4518 * R3781 (0xEC5) - HPLPF2_2
4519 */
4520#define WM5100_LHPF2_COEFF_MASK 0xFFFF /* LHPF2_COEFF - [15:0] */
4521#define WM5100_LHPF2_COEFF_SHIFT 0 /* LHPF2_COEFF - [15:0] */
4522#define WM5100_LHPF2_COEFF_WIDTH 16 /* LHPF2_COEFF - [15:0] */
4523
4524/*
4525 * R3784 (0xEC8) - HPLPF3_1
4526 */
4527#define WM5100_LHPF3_MODE 0x0002 /* LHPF3_MODE */
4528#define WM5100_LHPF3_MODE_MASK 0x0002 /* LHPF3_MODE */
4529#define WM5100_LHPF3_MODE_SHIFT 1 /* LHPF3_MODE */
4530#define WM5100_LHPF3_MODE_WIDTH 1 /* LHPF3_MODE */
4531#define WM5100_LHPF3_ENA 0x0001 /* LHPF3_ENA */
4532#define WM5100_LHPF3_ENA_MASK 0x0001 /* LHPF3_ENA */
4533#define WM5100_LHPF3_ENA_SHIFT 0 /* LHPF3_ENA */
4534#define WM5100_LHPF3_ENA_WIDTH 1 /* LHPF3_ENA */
4535
4536/*
4537 * R3785 (0xEC9) - HPLPF3_2
4538 */
4539#define WM5100_LHPF3_COEFF_MASK 0xFFFF /* LHPF3_COEFF - [15:0] */
4540#define WM5100_LHPF3_COEFF_SHIFT 0 /* LHPF3_COEFF - [15:0] */
4541#define WM5100_LHPF3_COEFF_WIDTH 16 /* LHPF3_COEFF - [15:0] */
4542
4543/*
4544 * R3788 (0xECC) - HPLPF4_1
4545 */
4546#define WM5100_LHPF4_MODE 0x0002 /* LHPF4_MODE */
4547#define WM5100_LHPF4_MODE_MASK 0x0002 /* LHPF4_MODE */
4548#define WM5100_LHPF4_MODE_SHIFT 1 /* LHPF4_MODE */
4549#define WM5100_LHPF4_MODE_WIDTH 1 /* LHPF4_MODE */
4550#define WM5100_LHPF4_ENA 0x0001 /* LHPF4_ENA */
4551#define WM5100_LHPF4_ENA_MASK 0x0001 /* LHPF4_ENA */
4552#define WM5100_LHPF4_ENA_SHIFT 0 /* LHPF4_ENA */
4553#define WM5100_LHPF4_ENA_WIDTH 1 /* LHPF4_ENA */
4554
4555/*
4556 * R3789 (0xECD) - HPLPF4_2
4557 */
4558#define WM5100_LHPF4_COEFF_MASK 0xFFFF /* LHPF4_COEFF - [15:0] */
4559#define WM5100_LHPF4_COEFF_SHIFT 0 /* LHPF4_COEFF - [15:0] */
4560#define WM5100_LHPF4_COEFF_WIDTH 16 /* LHPF4_COEFF - [15:0] */
4561
4562/*
4563 * R16384 (0x4000) - DSP1 DM 0
4564 */
4565#define WM5100_DSP1_DM_START_1_MASK 0x00FF /* DSP1_DM_START - [7:0] */
4566#define WM5100_DSP1_DM_START_1_SHIFT 0 /* DSP1_DM_START - [7:0] */
4567#define WM5100_DSP1_DM_START_1_WIDTH 8 /* DSP1_DM_START - [7:0] */
4568
4569/*
4570 * R16385 (0x4001) - DSP1 DM 1
4571 */
4572#define WM5100_DSP1_DM_START_MASK 0xFFFF /* DSP1_DM_START - [15:0] */
4573#define WM5100_DSP1_DM_START_SHIFT 0 /* DSP1_DM_START - [15:0] */
4574#define WM5100_DSP1_DM_START_WIDTH 16 /* DSP1_DM_START - [15:0] */
4575
4576/*
4577 * R16386 (0x4002) - DSP1 DM 2
4578 */
4579#define WM5100_DSP1_DM_1_1_MASK 0x00FF /* DSP1_DM_1 - [7:0] */
4580#define WM5100_DSP1_DM_1_1_SHIFT 0 /* DSP1_DM_1 - [7:0] */
4581#define WM5100_DSP1_DM_1_1_WIDTH 8 /* DSP1_DM_1 - [7:0] */
4582
4583/*
4584 * R16387 (0x4003) - DSP1 DM 3
4585 */
4586#define WM5100_DSP1_DM_1_MASK 0xFFFF /* DSP1_DM_1 - [15:0] */
4587#define WM5100_DSP1_DM_1_SHIFT 0 /* DSP1_DM_1 - [15:0] */
4588#define WM5100_DSP1_DM_1_WIDTH 16 /* DSP1_DM_1 - [15:0] */
4589
4590/*
4591 * R16892 (0x41FC) - DSP1 DM 508
4592 */
4593#define WM5100_DSP1_DM_254_1_MASK 0x00FF /* DSP1_DM_254 - [7:0] */
4594#define WM5100_DSP1_DM_254_1_SHIFT 0 /* DSP1_DM_254 - [7:0] */
4595#define WM5100_DSP1_DM_254_1_WIDTH 8 /* DSP1_DM_254 - [7:0] */
4596
4597/*
4598 * R16893 (0x41FD) - DSP1 DM 509
4599 */
4600#define WM5100_DSP1_DM_254_MASK 0xFFFF /* DSP1_DM_254 - [15:0] */
4601#define WM5100_DSP1_DM_254_SHIFT 0 /* DSP1_DM_254 - [15:0] */
4602#define WM5100_DSP1_DM_254_WIDTH 16 /* DSP1_DM_254 - [15:0] */
4603
4604/*
4605 * R16894 (0x41FE) - DSP1 DM 510
4606 */
4607#define WM5100_DSP1_DM_END_1_MASK 0x00FF /* DSP1_DM_END - [7:0] */
4608#define WM5100_DSP1_DM_END_1_SHIFT 0 /* DSP1_DM_END - [7:0] */
4609#define WM5100_DSP1_DM_END_1_WIDTH 8 /* DSP1_DM_END - [7:0] */
4610
4611/*
4612 * R16895 (0x41FF) - DSP1 DM 511
4613 */
4614#define WM5100_DSP1_DM_END_MASK 0xFFFF /* DSP1_DM_END - [15:0] */
4615#define WM5100_DSP1_DM_END_SHIFT 0 /* DSP1_DM_END - [15:0] */
4616#define WM5100_DSP1_DM_END_WIDTH 16 /* DSP1_DM_END - [15:0] */
4617
4618/*
4619 * R18432 (0x4800) - DSP1 PM 0
4620 */
4621#define WM5100_DSP1_PM_START_2_MASK 0x00FF /* DSP1_PM_START - [7:0] */
4622#define WM5100_DSP1_PM_START_2_SHIFT 0 /* DSP1_PM_START - [7:0] */
4623#define WM5100_DSP1_PM_START_2_WIDTH 8 /* DSP1_PM_START - [7:0] */
4624
4625/*
4626 * R18433 (0x4801) - DSP1 PM 1
4627 */
4628#define WM5100_DSP1_PM_START_1_MASK 0xFFFF /* DSP1_PM_START - [15:0] */
4629#define WM5100_DSP1_PM_START_1_SHIFT 0 /* DSP1_PM_START - [15:0] */
4630#define WM5100_DSP1_PM_START_1_WIDTH 16 /* DSP1_PM_START - [15:0] */
4631
4632/*
4633 * R18434 (0x4802) - DSP1 PM 2
4634 */
4635#define WM5100_DSP1_PM_START_MASK 0xFFFF /* DSP1_PM_START - [15:0] */
4636#define WM5100_DSP1_PM_START_SHIFT 0 /* DSP1_PM_START - [15:0] */
4637#define WM5100_DSP1_PM_START_WIDTH 16 /* DSP1_PM_START - [15:0] */
4638
4639/*
4640 * R18435 (0x4803) - DSP1 PM 3
4641 */
4642#define WM5100_DSP1_PM_1_2_MASK 0x00FF /* DSP1_PM_1 - [7:0] */
4643#define WM5100_DSP1_PM_1_2_SHIFT 0 /* DSP1_PM_1 - [7:0] */
4644#define WM5100_DSP1_PM_1_2_WIDTH 8 /* DSP1_PM_1 - [7:0] */
4645
4646/*
4647 * R18436 (0x4804) - DSP1 PM 4
4648 */
4649#define WM5100_DSP1_PM_1_1_MASK 0xFFFF /* DSP1_PM_1 - [15:0] */
4650#define WM5100_DSP1_PM_1_1_SHIFT 0 /* DSP1_PM_1 - [15:0] */
4651#define WM5100_DSP1_PM_1_1_WIDTH 16 /* DSP1_PM_1 - [15:0] */
4652
4653/*
4654 * R18437 (0x4805) - DSP1 PM 5
4655 */
4656#define WM5100_DSP1_PM_1_MASK 0xFFFF /* DSP1_PM_1 - [15:0] */
4657#define WM5100_DSP1_PM_1_SHIFT 0 /* DSP1_PM_1 - [15:0] */
4658#define WM5100_DSP1_PM_1_WIDTH 16 /* DSP1_PM_1 - [15:0] */
4659
4660/*
4661 * R19962 (0x4DFA) - DSP1 PM 1530
4662 */
4663#define WM5100_DSP1_PM_510_2_MASK 0x00FF /* DSP1_PM_510 - [7:0] */
4664#define WM5100_DSP1_PM_510_2_SHIFT 0 /* DSP1_PM_510 - [7:0] */
4665#define WM5100_DSP1_PM_510_2_WIDTH 8 /* DSP1_PM_510 - [7:0] */
4666
4667/*
4668 * R19963 (0x4DFB) - DSP1 PM 1531
4669 */
4670#define WM5100_DSP1_PM_510_1_MASK 0xFFFF /* DSP1_PM_510 - [15:0] */
4671#define WM5100_DSP1_PM_510_1_SHIFT 0 /* DSP1_PM_510 - [15:0] */
4672#define WM5100_DSP1_PM_510_1_WIDTH 16 /* DSP1_PM_510 - [15:0] */
4673
4674/*
4675 * R19964 (0x4DFC) - DSP1 PM 1532
4676 */
4677#define WM5100_DSP1_PM_510_MASK 0xFFFF /* DSP1_PM_510 - [15:0] */
4678#define WM5100_DSP1_PM_510_SHIFT 0 /* DSP1_PM_510 - [15:0] */
4679#define WM5100_DSP1_PM_510_WIDTH 16 /* DSP1_PM_510 - [15:0] */
4680
4681/*
4682 * R19965 (0x4DFD) - DSP1 PM 1533
4683 */
4684#define WM5100_DSP1_PM_END_2_MASK 0x00FF /* DSP1_PM_END - [7:0] */
4685#define WM5100_DSP1_PM_END_2_SHIFT 0 /* DSP1_PM_END - [7:0] */
4686#define WM5100_DSP1_PM_END_2_WIDTH 8 /* DSP1_PM_END - [7:0] */
4687
4688/*
4689 * R19966 (0x4DFE) - DSP1 PM 1534
4690 */
4691#define WM5100_DSP1_PM_END_1_MASK 0xFFFF /* DSP1_PM_END - [15:0] */
4692#define WM5100_DSP1_PM_END_1_SHIFT 0 /* DSP1_PM_END - [15:0] */
4693#define WM5100_DSP1_PM_END_1_WIDTH 16 /* DSP1_PM_END - [15:0] */
4694
4695/*
4696 * R19967 (0x4DFF) - DSP1 PM 1535
4697 */
4698#define WM5100_DSP1_PM_END_MASK 0xFFFF /* DSP1_PM_END - [15:0] */
4699#define WM5100_DSP1_PM_END_SHIFT 0 /* DSP1_PM_END - [15:0] */
4700#define WM5100_DSP1_PM_END_WIDTH 16 /* DSP1_PM_END - [15:0] */
4701
4702/*
4703 * R20480 (0x5000) - DSP1 ZM 0
4704 */
4705#define WM5100_DSP1_ZM_START_1_MASK 0x00FF /* DSP1_ZM_START - [7:0] */
4706#define WM5100_DSP1_ZM_START_1_SHIFT 0 /* DSP1_ZM_START - [7:0] */
4707#define WM5100_DSP1_ZM_START_1_WIDTH 8 /* DSP1_ZM_START - [7:0] */
4708
4709/*
4710 * R20481 (0x5001) - DSP1 ZM 1
4711 */
4712#define WM5100_DSP1_ZM_START_MASK 0xFFFF /* DSP1_ZM_START - [15:0] */
4713#define WM5100_DSP1_ZM_START_SHIFT 0 /* DSP1_ZM_START - [15:0] */
4714#define WM5100_DSP1_ZM_START_WIDTH 16 /* DSP1_ZM_START - [15:0] */
4715
4716/*
4717 * R20482 (0x5002) - DSP1 ZM 2
4718 */
4719#define WM5100_DSP1_ZM_1_1_MASK 0x00FF /* DSP1_ZM_1 - [7:0] */
4720#define WM5100_DSP1_ZM_1_1_SHIFT 0 /* DSP1_ZM_1 - [7:0] */
4721#define WM5100_DSP1_ZM_1_1_WIDTH 8 /* DSP1_ZM_1 - [7:0] */
4722
4723/*
4724 * R20483 (0x5003) - DSP1 ZM 3
4725 */
4726#define WM5100_DSP1_ZM_1_MASK 0xFFFF /* DSP1_ZM_1 - [15:0] */
4727#define WM5100_DSP1_ZM_1_SHIFT 0 /* DSP1_ZM_1 - [15:0] */
4728#define WM5100_DSP1_ZM_1_WIDTH 16 /* DSP1_ZM_1 - [15:0] */
4729
4730/*
4731 * R22524 (0x57FC) - DSP1 ZM 2044
4732 */
4733#define WM5100_DSP1_ZM_1022_1_MASK 0x00FF /* DSP1_ZM_1022 - [7:0] */
4734#define WM5100_DSP1_ZM_1022_1_SHIFT 0 /* DSP1_ZM_1022 - [7:0] */
4735#define WM5100_DSP1_ZM_1022_1_WIDTH 8 /* DSP1_ZM_1022 - [7:0] */
4736
4737/*
4738 * R22525 (0x57FD) - DSP1 ZM 2045
4739 */
4740#define WM5100_DSP1_ZM_1022_MASK 0xFFFF /* DSP1_ZM_1022 - [15:0] */
4741#define WM5100_DSP1_ZM_1022_SHIFT 0 /* DSP1_ZM_1022 - [15:0] */
4742#define WM5100_DSP1_ZM_1022_WIDTH 16 /* DSP1_ZM_1022 - [15:0] */
4743
4744/*
4745 * R22526 (0x57FE) - DSP1 ZM 2046
4746 */
4747#define WM5100_DSP1_ZM_END_1_MASK 0x00FF /* DSP1_ZM_END - [7:0] */
4748#define WM5100_DSP1_ZM_END_1_SHIFT 0 /* DSP1_ZM_END - [7:0] */
4749#define WM5100_DSP1_ZM_END_1_WIDTH 8 /* DSP1_ZM_END - [7:0] */
4750
4751/*
4752 * R22527 (0x57FF) - DSP1 ZM 2047
4753 */
4754#define WM5100_DSP1_ZM_END_MASK 0xFFFF /* DSP1_ZM_END - [15:0] */
4755#define WM5100_DSP1_ZM_END_SHIFT 0 /* DSP1_ZM_END - [15:0] */
4756#define WM5100_DSP1_ZM_END_WIDTH 16 /* DSP1_ZM_END - [15:0] */
4757
4758/*
4759 * R24576 (0x6000) - DSP2 DM 0
4760 */
4761#define WM5100_DSP2_DM_START_1_MASK 0x00FF /* DSP2_DM_START - [7:0] */
4762#define WM5100_DSP2_DM_START_1_SHIFT 0 /* DSP2_DM_START - [7:0] */
4763#define WM5100_DSP2_DM_START_1_WIDTH 8 /* DSP2_DM_START - [7:0] */
4764
4765/*
4766 * R24577 (0x6001) - DSP2 DM 1
4767 */
4768#define WM5100_DSP2_DM_START_MASK 0xFFFF /* DSP2_DM_START - [15:0] */
4769#define WM5100_DSP2_DM_START_SHIFT 0 /* DSP2_DM_START - [15:0] */
4770#define WM5100_DSP2_DM_START_WIDTH 16 /* DSP2_DM_START - [15:0] */
4771
4772/*
4773 * R24578 (0x6002) - DSP2 DM 2
4774 */
4775#define WM5100_DSP2_DM_1_1_MASK 0x00FF /* DSP2_DM_1 - [7:0] */
4776#define WM5100_DSP2_DM_1_1_SHIFT 0 /* DSP2_DM_1 - [7:0] */
4777#define WM5100_DSP2_DM_1_1_WIDTH 8 /* DSP2_DM_1 - [7:0] */
4778
4779/*
4780 * R24579 (0x6003) - DSP2 DM 3
4781 */
4782#define WM5100_DSP2_DM_1_MASK 0xFFFF /* DSP2_DM_1 - [15:0] */
4783#define WM5100_DSP2_DM_1_SHIFT 0 /* DSP2_DM_1 - [15:0] */
4784#define WM5100_DSP2_DM_1_WIDTH 16 /* DSP2_DM_1 - [15:0] */
4785
4786/*
4787 * R25084 (0x61FC) - DSP2 DM 508
4788 */
4789#define WM5100_DSP2_DM_254_1_MASK 0x00FF /* DSP2_DM_254 - [7:0] */
4790#define WM5100_DSP2_DM_254_1_SHIFT 0 /* DSP2_DM_254 - [7:0] */
4791#define WM5100_DSP2_DM_254_1_WIDTH 8 /* DSP2_DM_254 - [7:0] */
4792
4793/*
4794 * R25085 (0x61FD) - DSP2 DM 509
4795 */
4796#define WM5100_DSP2_DM_254_MASK 0xFFFF /* DSP2_DM_254 - [15:0] */
4797#define WM5100_DSP2_DM_254_SHIFT 0 /* DSP2_DM_254 - [15:0] */
4798#define WM5100_DSP2_DM_254_WIDTH 16 /* DSP2_DM_254 - [15:0] */
4799
4800/*
4801 * R25086 (0x61FE) - DSP2 DM 510
4802 */
4803#define WM5100_DSP2_DM_END_1_MASK 0x00FF /* DSP2_DM_END - [7:0] */
4804#define WM5100_DSP2_DM_END_1_SHIFT 0 /* DSP2_DM_END - [7:0] */
4805#define WM5100_DSP2_DM_END_1_WIDTH 8 /* DSP2_DM_END - [7:0] */
4806
4807/*
4808 * R25087 (0x61FF) - DSP2 DM 511
4809 */
4810#define WM5100_DSP2_DM_END_MASK 0xFFFF /* DSP2_DM_END - [15:0] */
4811#define WM5100_DSP2_DM_END_SHIFT 0 /* DSP2_DM_END - [15:0] */
4812#define WM5100_DSP2_DM_END_WIDTH 16 /* DSP2_DM_END - [15:0] */
4813
4814/*
4815 * R26624 (0x6800) - DSP2 PM 0
4816 */
4817#define WM5100_DSP2_PM_START_2_MASK 0x00FF /* DSP2_PM_START - [7:0] */
4818#define WM5100_DSP2_PM_START_2_SHIFT 0 /* DSP2_PM_START - [7:0] */
4819#define WM5100_DSP2_PM_START_2_WIDTH 8 /* DSP2_PM_START - [7:0] */
4820
4821/*
4822 * R26625 (0x6801) - DSP2 PM 1
4823 */
4824#define WM5100_DSP2_PM_START_1_MASK 0xFFFF /* DSP2_PM_START - [15:0] */
4825#define WM5100_DSP2_PM_START_1_SHIFT 0 /* DSP2_PM_START - [15:0] */
4826#define WM5100_DSP2_PM_START_1_WIDTH 16 /* DSP2_PM_START - [15:0] */
4827
4828/*
4829 * R26626 (0x6802) - DSP2 PM 2
4830 */
4831#define WM5100_DSP2_PM_START_MASK 0xFFFF /* DSP2_PM_START - [15:0] */
4832#define WM5100_DSP2_PM_START_SHIFT 0 /* DSP2_PM_START - [15:0] */
4833#define WM5100_DSP2_PM_START_WIDTH 16 /* DSP2_PM_START - [15:0] */
4834
4835/*
4836 * R26627 (0x6803) - DSP2 PM 3
4837 */
4838#define WM5100_DSP2_PM_1_2_MASK 0x00FF /* DSP2_PM_1 - [7:0] */
4839#define WM5100_DSP2_PM_1_2_SHIFT 0 /* DSP2_PM_1 - [7:0] */
4840#define WM5100_DSP2_PM_1_2_WIDTH 8 /* DSP2_PM_1 - [7:0] */
4841
4842/*
4843 * R26628 (0x6804) - DSP2 PM 4
4844 */
4845#define WM5100_DSP2_PM_1_1_MASK 0xFFFF /* DSP2_PM_1 - [15:0] */
4846#define WM5100_DSP2_PM_1_1_SHIFT 0 /* DSP2_PM_1 - [15:0] */
4847#define WM5100_DSP2_PM_1_1_WIDTH 16 /* DSP2_PM_1 - [15:0] */
4848
4849/*
4850 * R26629 (0x6805) - DSP2 PM 5
4851 */
4852#define WM5100_DSP2_PM_1_MASK 0xFFFF /* DSP2_PM_1 - [15:0] */
4853#define WM5100_DSP2_PM_1_SHIFT 0 /* DSP2_PM_1 - [15:0] */
4854#define WM5100_DSP2_PM_1_WIDTH 16 /* DSP2_PM_1 - [15:0] */
4855
4856/*
4857 * R28154 (0x6DFA) - DSP2 PM 1530
4858 */
4859#define WM5100_DSP2_PM_510_2_MASK 0x00FF /* DSP2_PM_510 - [7:0] */
4860#define WM5100_DSP2_PM_510_2_SHIFT 0 /* DSP2_PM_510 - [7:0] */
4861#define WM5100_DSP2_PM_510_2_WIDTH 8 /* DSP2_PM_510 - [7:0] */
4862
4863/*
4864 * R28155 (0x6DFB) - DSP2 PM 1531
4865 */
4866#define WM5100_DSP2_PM_510_1_MASK 0xFFFF /* DSP2_PM_510 - [15:0] */
4867#define WM5100_DSP2_PM_510_1_SHIFT 0 /* DSP2_PM_510 - [15:0] */
4868#define WM5100_DSP2_PM_510_1_WIDTH 16 /* DSP2_PM_510 - [15:0] */
4869
4870/*
4871 * R28156 (0x6DFC) - DSP2 PM 1532
4872 */
4873#define WM5100_DSP2_PM_510_MASK 0xFFFF /* DSP2_PM_510 - [15:0] */
4874#define WM5100_DSP2_PM_510_SHIFT 0 /* DSP2_PM_510 - [15:0] */
4875#define WM5100_DSP2_PM_510_WIDTH 16 /* DSP2_PM_510 - [15:0] */
4876
4877/*
4878 * R28157 (0x6DFD) - DSP2 PM 1533
4879 */
4880#define WM5100_DSP2_PM_END_2_MASK 0x00FF /* DSP2_PM_END - [7:0] */
4881#define WM5100_DSP2_PM_END_2_SHIFT 0 /* DSP2_PM_END - [7:0] */
4882#define WM5100_DSP2_PM_END_2_WIDTH 8 /* DSP2_PM_END - [7:0] */
4883
4884/*
4885 * R28158 (0x6DFE) - DSP2 PM 1534
4886 */
4887#define WM5100_DSP2_PM_END_1_MASK 0xFFFF /* DSP2_PM_END - [15:0] */
4888#define WM5100_DSP2_PM_END_1_SHIFT 0 /* DSP2_PM_END - [15:0] */
4889#define WM5100_DSP2_PM_END_1_WIDTH 16 /* DSP2_PM_END - [15:0] */
4890
4891/*
4892 * R28159 (0x6DFF) - DSP2 PM 1535
4893 */
4894#define WM5100_DSP2_PM_END_MASK 0xFFFF /* DSP2_PM_END - [15:0] */
4895#define WM5100_DSP2_PM_END_SHIFT 0 /* DSP2_PM_END - [15:0] */
4896#define WM5100_DSP2_PM_END_WIDTH 16 /* DSP2_PM_END - [15:0] */
4897
4898/*
4899 * R28672 (0x7000) - DSP2 ZM 0
4900 */
4901#define WM5100_DSP2_ZM_START_1_MASK 0x00FF /* DSP2_ZM_START - [7:0] */
4902#define WM5100_DSP2_ZM_START_1_SHIFT 0 /* DSP2_ZM_START - [7:0] */
4903#define WM5100_DSP2_ZM_START_1_WIDTH 8 /* DSP2_ZM_START - [7:0] */
4904
4905/*
4906 * R28673 (0x7001) - DSP2 ZM 1
4907 */
4908#define WM5100_DSP2_ZM_START_MASK 0xFFFF /* DSP2_ZM_START - [15:0] */
4909#define WM5100_DSP2_ZM_START_SHIFT 0 /* DSP2_ZM_START - [15:0] */
4910#define WM5100_DSP2_ZM_START_WIDTH 16 /* DSP2_ZM_START - [15:0] */
4911
4912/*
4913 * R28674 (0x7002) - DSP2 ZM 2
4914 */
4915#define WM5100_DSP2_ZM_1_1_MASK 0x00FF /* DSP2_ZM_1 - [7:0] */
4916#define WM5100_DSP2_ZM_1_1_SHIFT 0 /* DSP2_ZM_1 - [7:0] */
4917#define WM5100_DSP2_ZM_1_1_WIDTH 8 /* DSP2_ZM_1 - [7:0] */
4918
4919/*
4920 * R28675 (0x7003) - DSP2 ZM 3
4921 */
4922#define WM5100_DSP2_ZM_1_MASK 0xFFFF /* DSP2_ZM_1 - [15:0] */
4923#define WM5100_DSP2_ZM_1_SHIFT 0 /* DSP2_ZM_1 - [15:0] */
4924#define WM5100_DSP2_ZM_1_WIDTH 16 /* DSP2_ZM_1 - [15:0] */
4925
4926/*
4927 * R30716 (0x77FC) - DSP2 ZM 2044
4928 */
4929#define WM5100_DSP2_ZM_1022_1_MASK 0x00FF /* DSP2_ZM_1022 - [7:0] */
4930#define WM5100_DSP2_ZM_1022_1_SHIFT 0 /* DSP2_ZM_1022 - [7:0] */
4931#define WM5100_DSP2_ZM_1022_1_WIDTH 8 /* DSP2_ZM_1022 - [7:0] */
4932
4933/*
4934 * R30717 (0x77FD) - DSP2 ZM 2045
4935 */
4936#define WM5100_DSP2_ZM_1022_MASK 0xFFFF /* DSP2_ZM_1022 - [15:0] */
4937#define WM5100_DSP2_ZM_1022_SHIFT 0 /* DSP2_ZM_1022 - [15:0] */
4938#define WM5100_DSP2_ZM_1022_WIDTH 16 /* DSP2_ZM_1022 - [15:0] */
4939
4940/*
4941 * R30718 (0x77FE) - DSP2 ZM 2046
4942 */
4943#define WM5100_DSP2_ZM_END_1_MASK 0x00FF /* DSP2_ZM_END - [7:0] */
4944#define WM5100_DSP2_ZM_END_1_SHIFT 0 /* DSP2_ZM_END - [7:0] */
4945#define WM5100_DSP2_ZM_END_1_WIDTH 8 /* DSP2_ZM_END - [7:0] */
4946
4947/*
4948 * R30719 (0x77FF) - DSP2 ZM 2047
4949 */
4950#define WM5100_DSP2_ZM_END_MASK 0xFFFF /* DSP2_ZM_END - [15:0] */
4951#define WM5100_DSP2_ZM_END_SHIFT 0 /* DSP2_ZM_END - [15:0] */
4952#define WM5100_DSP2_ZM_END_WIDTH 16 /* DSP2_ZM_END - [15:0] */
4953
4954/*
4955 * R32768 (0x8000) - DSP3 DM 0
4956 */
4957#define WM5100_DSP3_DM_START_1_MASK 0x00FF /* DSP3_DM_START - [7:0] */
4958#define WM5100_DSP3_DM_START_1_SHIFT 0 /* DSP3_DM_START - [7:0] */
4959#define WM5100_DSP3_DM_START_1_WIDTH 8 /* DSP3_DM_START - [7:0] */
4960
4961/*
4962 * R32769 (0x8001) - DSP3 DM 1
4963 */
4964#define WM5100_DSP3_DM_START_MASK 0xFFFF /* DSP3_DM_START - [15:0] */
4965#define WM5100_DSP3_DM_START_SHIFT 0 /* DSP3_DM_START - [15:0] */
4966#define WM5100_DSP3_DM_START_WIDTH 16 /* DSP3_DM_START - [15:0] */
4967
4968/*
4969 * R32770 (0x8002) - DSP3 DM 2
4970 */
4971#define WM5100_DSP3_DM_1_1_MASK 0x00FF /* DSP3_DM_1 - [7:0] */
4972#define WM5100_DSP3_DM_1_1_SHIFT 0 /* DSP3_DM_1 - [7:0] */
4973#define WM5100_DSP3_DM_1_1_WIDTH 8 /* DSP3_DM_1 - [7:0] */
4974
4975/*
4976 * R32771 (0x8003) - DSP3 DM 3
4977 */
4978#define WM5100_DSP3_DM_1_MASK 0xFFFF /* DSP3_DM_1 - [15:0] */
4979#define WM5100_DSP3_DM_1_SHIFT 0 /* DSP3_DM_1 - [15:0] */
4980#define WM5100_DSP3_DM_1_WIDTH 16 /* DSP3_DM_1 - [15:0] */
4981
4982/*
4983 * R33276 (0x81FC) - DSP3 DM 508
4984 */
4985#define WM5100_DSP3_DM_254_1_MASK 0x00FF /* DSP3_DM_254 - [7:0] */
4986#define WM5100_DSP3_DM_254_1_SHIFT 0 /* DSP3_DM_254 - [7:0] */
4987#define WM5100_DSP3_DM_254_1_WIDTH 8 /* DSP3_DM_254 - [7:0] */
4988
4989/*
4990 * R33277 (0x81FD) - DSP3 DM 509
4991 */
4992#define WM5100_DSP3_DM_254_MASK 0xFFFF /* DSP3_DM_254 - [15:0] */
4993#define WM5100_DSP3_DM_254_SHIFT 0 /* DSP3_DM_254 - [15:0] */
4994#define WM5100_DSP3_DM_254_WIDTH 16 /* DSP3_DM_254 - [15:0] */
4995
4996/*
4997 * R33278 (0x81FE) - DSP3 DM 510
4998 */
4999#define WM5100_DSP3_DM_END_1_MASK 0x00FF /* DSP3_DM_END - [7:0] */
5000#define WM5100_DSP3_DM_END_1_SHIFT 0 /* DSP3_DM_END - [7:0] */
5001#define WM5100_DSP3_DM_END_1_WIDTH 8 /* DSP3_DM_END - [7:0] */
5002
5003/*
5004 * R33279 (0x81FF) - DSP3 DM 511
5005 */
5006#define WM5100_DSP3_DM_END_MASK 0xFFFF /* DSP3_DM_END - [15:0] */
5007#define WM5100_DSP3_DM_END_SHIFT 0 /* DSP3_DM_END - [15:0] */
5008#define WM5100_DSP3_DM_END_WIDTH 16 /* DSP3_DM_END - [15:0] */
5009
5010/*
5011 * R34816 (0x8800) - DSP3 PM 0
5012 */
5013#define WM5100_DSP3_PM_START_2_MASK 0x00FF /* DSP3_PM_START - [7:0] */
5014#define WM5100_DSP3_PM_START_2_SHIFT 0 /* DSP3_PM_START - [7:0] */
5015#define WM5100_DSP3_PM_START_2_WIDTH 8 /* DSP3_PM_START - [7:0] */
5016
5017/*
5018 * R34817 (0x8801) - DSP3 PM 1
5019 */
5020#define WM5100_DSP3_PM_START_1_MASK 0xFFFF /* DSP3_PM_START - [15:0] */
5021#define WM5100_DSP3_PM_START_1_SHIFT 0 /* DSP3_PM_START - [15:0] */
5022#define WM5100_DSP3_PM_START_1_WIDTH 16 /* DSP3_PM_START - [15:0] */
5023
5024/*
5025 * R34818 (0x8802) - DSP3 PM 2
5026 */
5027#define WM5100_DSP3_PM_START_MASK 0xFFFF /* DSP3_PM_START - [15:0] */
5028#define WM5100_DSP3_PM_START_SHIFT 0 /* DSP3_PM_START - [15:0] */
5029#define WM5100_DSP3_PM_START_WIDTH 16 /* DSP3_PM_START - [15:0] */
5030
5031/*
5032 * R34819 (0x8803) - DSP3 PM 3
5033 */
5034#define WM5100_DSP3_PM_1_2_MASK 0x00FF /* DSP3_PM_1 - [7:0] */
5035#define WM5100_DSP3_PM_1_2_SHIFT 0 /* DSP3_PM_1 - [7:0] */
5036#define WM5100_DSP3_PM_1_2_WIDTH 8 /* DSP3_PM_1 - [7:0] */
5037
5038/*
5039 * R34820 (0x8804) - DSP3 PM 4
5040 */
5041#define WM5100_DSP3_PM_1_1_MASK 0xFFFF /* DSP3_PM_1 - [15:0] */
5042#define WM5100_DSP3_PM_1_1_SHIFT 0 /* DSP3_PM_1 - [15:0] */
5043#define WM5100_DSP3_PM_1_1_WIDTH 16 /* DSP3_PM_1 - [15:0] */
5044
5045/*
5046 * R34821 (0x8805) - DSP3 PM 5
5047 */
5048#define WM5100_DSP3_PM_1_MASK 0xFFFF /* DSP3_PM_1 - [15:0] */
5049#define WM5100_DSP3_PM_1_SHIFT 0 /* DSP3_PM_1 - [15:0] */
5050#define WM5100_DSP3_PM_1_WIDTH 16 /* DSP3_PM_1 - [15:0] */
5051
5052/*
5053 * R36346 (0x8DFA) - DSP3 PM 1530
5054 */
5055#define WM5100_DSP3_PM_510_2_MASK 0x00FF /* DSP3_PM_510 - [7:0] */
5056#define WM5100_DSP3_PM_510_2_SHIFT 0 /* DSP3_PM_510 - [7:0] */
5057#define WM5100_DSP3_PM_510_2_WIDTH 8 /* DSP3_PM_510 - [7:0] */
5058
5059/*
5060 * R36347 (0x8DFB) - DSP3 PM 1531
5061 */
5062#define WM5100_DSP3_PM_510_1_MASK 0xFFFF /* DSP3_PM_510 - [15:0] */
5063#define WM5100_DSP3_PM_510_1_SHIFT 0 /* DSP3_PM_510 - [15:0] */
5064#define WM5100_DSP3_PM_510_1_WIDTH 16 /* DSP3_PM_510 - [15:0] */
5065
5066/*
5067 * R36348 (0x8DFC) - DSP3 PM 1532
5068 */
5069#define WM5100_DSP3_PM_510_MASK 0xFFFF /* DSP3_PM_510 - [15:0] */
5070#define WM5100_DSP3_PM_510_SHIFT 0 /* DSP3_PM_510 - [15:0] */
5071#define WM5100_DSP3_PM_510_WIDTH 16 /* DSP3_PM_510 - [15:0] */
5072
5073/*
5074 * R36349 (0x8DFD) - DSP3 PM 1533
5075 */
5076#define WM5100_DSP3_PM_END_2_MASK 0x00FF /* DSP3_PM_END - [7:0] */
5077#define WM5100_DSP3_PM_END_2_SHIFT 0 /* DSP3_PM_END - [7:0] */
5078#define WM5100_DSP3_PM_END_2_WIDTH 8 /* DSP3_PM_END - [7:0] */
5079
5080/*
5081 * R36350 (0x8DFE) - DSP3 PM 1534
5082 */
5083#define WM5100_DSP3_PM_END_1_MASK 0xFFFF /* DSP3_PM_END - [15:0] */
5084#define WM5100_DSP3_PM_END_1_SHIFT 0 /* DSP3_PM_END - [15:0] */
5085#define WM5100_DSP3_PM_END_1_WIDTH 16 /* DSP3_PM_END - [15:0] */
5086
5087/*
5088 * R36351 (0x8DFF) - DSP3 PM 1535
5089 */
5090#define WM5100_DSP3_PM_END_MASK 0xFFFF /* DSP3_PM_END - [15:0] */
5091#define WM5100_DSP3_PM_END_SHIFT 0 /* DSP3_PM_END - [15:0] */
5092#define WM5100_DSP3_PM_END_WIDTH 16 /* DSP3_PM_END - [15:0] */
5093
5094/*
5095 * R36864 (0x9000) - DSP3 ZM 0
5096 */
5097#define WM5100_DSP3_ZM_START_1_MASK 0x00FF /* DSP3_ZM_START - [7:0] */
5098#define WM5100_DSP3_ZM_START_1_SHIFT 0 /* DSP3_ZM_START - [7:0] */
5099#define WM5100_DSP3_ZM_START_1_WIDTH 8 /* DSP3_ZM_START - [7:0] */
5100
5101/*
5102 * R36865 (0x9001) - DSP3 ZM 1
5103 */
5104#define WM5100_DSP3_ZM_START_MASK 0xFFFF /* DSP3_ZM_START - [15:0] */
5105#define WM5100_DSP3_ZM_START_SHIFT 0 /* DSP3_ZM_START - [15:0] */
5106#define WM5100_DSP3_ZM_START_WIDTH 16 /* DSP3_ZM_START - [15:0] */
5107
5108/*
5109 * R36866 (0x9002) - DSP3 ZM 2
5110 */
5111#define WM5100_DSP3_ZM_1_1_MASK 0x00FF /* DSP3_ZM_1 - [7:0] */
5112#define WM5100_DSP3_ZM_1_1_SHIFT 0 /* DSP3_ZM_1 - [7:0] */
5113#define WM5100_DSP3_ZM_1_1_WIDTH 8 /* DSP3_ZM_1 - [7:0] */
5114
5115/*
5116 * R36867 (0x9003) - DSP3 ZM 3
5117 */
5118#define WM5100_DSP3_ZM_1_MASK 0xFFFF /* DSP3_ZM_1 - [15:0] */
5119#define WM5100_DSP3_ZM_1_SHIFT 0 /* DSP3_ZM_1 - [15:0] */
5120#define WM5100_DSP3_ZM_1_WIDTH 16 /* DSP3_ZM_1 - [15:0] */
5121
5122/*
5123 * R38908 (0x97FC) - DSP3 ZM 2044
5124 */
5125#define WM5100_DSP3_ZM_1022_1_MASK 0x00FF /* DSP3_ZM_1022 - [7:0] */
5126#define WM5100_DSP3_ZM_1022_1_SHIFT 0 /* DSP3_ZM_1022 - [7:0] */
5127#define WM5100_DSP3_ZM_1022_1_WIDTH 8 /* DSP3_ZM_1022 - [7:0] */
5128
5129/*
5130 * R38909 (0x97FD) - DSP3 ZM 2045
5131 */
5132#define WM5100_DSP3_ZM_1022_MASK 0xFFFF /* DSP3_ZM_1022 - [15:0] */
5133#define WM5100_DSP3_ZM_1022_SHIFT 0 /* DSP3_ZM_1022 - [15:0] */
5134#define WM5100_DSP3_ZM_1022_WIDTH 16 /* DSP3_ZM_1022 - [15:0] */
5135
5136/*
5137 * R38910 (0x97FE) - DSP3 ZM 2046
5138 */
5139#define WM5100_DSP3_ZM_END_1_MASK 0x00FF /* DSP3_ZM_END - [7:0] */
5140#define WM5100_DSP3_ZM_END_1_SHIFT 0 /* DSP3_ZM_END - [7:0] */
5141#define WM5100_DSP3_ZM_END_1_WIDTH 8 /* DSP3_ZM_END - [7:0] */
5142
5143/*
5144 * R38911 (0x97FF) - DSP3 ZM 2047
5145 */
5146#define WM5100_DSP3_ZM_END_MASK 0xFFFF /* DSP3_ZM_END - [15:0] */
5147#define WM5100_DSP3_ZM_END_SHIFT 0 /* DSP3_ZM_END - [15:0] */
5148#define WM5100_DSP3_ZM_END_WIDTH 16 /* DSP3_ZM_END - [15:0] */
5149
5150int wm5100_readable_register(struct snd_soc_codec *codec, unsigned int reg);
5151int wm5100_volatile_register(struct snd_soc_codec *codec, unsigned int reg);
5152
5153extern u16 wm5100_reg_defaults[WM5100_MAX_REGISTER + 1];
5154
5155#endif
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
index 6d6dc9efe91..35f3ad83dfb 100644
--- a/sound/soc/codecs/wm8350.c
+++ b/sound/soc/codecs/wm8350.c
@@ -355,7 +355,7 @@ static int wm8350_put_volsw_2r_vu(struct snd_kcontrol *kcontrol,
355 return 1; 355 return 1;
356 } 356 }
357 357
358 ret = snd_soc_put_volsw_2r(kcontrol, ucontrol); 358 ret = snd_soc_put_volsw(kcontrol, ucontrol);
359 if (ret < 0) 359 if (ret < 0)
360 return ret; 360 return ret;
361 361
@@ -392,23 +392,9 @@ static int wm8350_get_volsw_2r(struct snd_kcontrol *kcontrol,
392 break; 392 break;
393 } 393 }
394 394
395 return snd_soc_get_volsw_2r(kcontrol, ucontrol); 395 return snd_soc_get_volsw(kcontrol, ucontrol);
396} 396}
397 397
398/* double control with volume update */
399#define SOC_WM8350_DOUBLE_R_TLV(xname, reg_left, reg_right, xshift, xmax, \
400 xinvert, tlv_array) \
401{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
402 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
403 SNDRV_CTL_ELEM_ACCESS_READWRITE | \
404 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
405 .tlv.p = (tlv_array), \
406 .info = snd_soc_info_volsw_2r, \
407 .get = wm8350_get_volsw_2r, .put = wm8350_put_volsw_2r_vu, \
408 .private_value = (unsigned long)&(struct soc_mixer_control) \
409 {.reg = reg_left, .rreg = reg_right, .shift = xshift, \
410 .rshift = xshift, .max = xmax, .invert = xinvert}, }
411
412static const char *wm8350_deemp[] = { "None", "32kHz", "44.1kHz", "48kHz" }; 398static const char *wm8350_deemp[] = { "None", "32kHz", "44.1kHz", "48kHz" };
413static const char *wm8350_pol[] = { "Normal", "Inv R", "Inv L", "Inv L & R" }; 399static const char *wm8350_pol[] = { "Normal", "Inv R", "Inv L", "Inv L & R" };
414static const char *wm8350_dacmutem[] = { "Normal", "Soft" }; 400static const char *wm8350_dacmutem[] = { "Normal", "Soft" };
@@ -443,26 +429,29 @@ static const unsigned int capture_sd_tlv[] = {
443static const struct snd_kcontrol_new wm8350_snd_controls[] = { 429static const struct snd_kcontrol_new wm8350_snd_controls[] = {
444 SOC_ENUM("Playback Deemphasis", wm8350_enum[0]), 430 SOC_ENUM("Playback Deemphasis", wm8350_enum[0]),
445 SOC_ENUM("Playback DAC Inversion", wm8350_enum[1]), 431 SOC_ENUM("Playback DAC Inversion", wm8350_enum[1]),
446 SOC_WM8350_DOUBLE_R_TLV("Playback PCM Volume", 432 SOC_DOUBLE_R_EXT_TLV("Playback PCM Volume",
447 WM8350_DAC_DIGITAL_VOLUME_L, 433 WM8350_DAC_DIGITAL_VOLUME_L,
448 WM8350_DAC_DIGITAL_VOLUME_R, 434 WM8350_DAC_DIGITAL_VOLUME_R,
449 0, 255, 0, dac_pcm_tlv), 435 0, 255, 0, wm8350_get_volsw_2r,
436 wm8350_put_volsw_2r_vu, dac_pcm_tlv),
450 SOC_ENUM("Playback PCM Mute Function", wm8350_enum[2]), 437 SOC_ENUM("Playback PCM Mute Function", wm8350_enum[2]),
451 SOC_ENUM("Playback PCM Mute Speed", wm8350_enum[3]), 438 SOC_ENUM("Playback PCM Mute Speed", wm8350_enum[3]),
452 SOC_ENUM("Capture PCM Filter", wm8350_enum[4]), 439 SOC_ENUM("Capture PCM Filter", wm8350_enum[4]),
453 SOC_ENUM("Capture PCM HP Filter", wm8350_enum[5]), 440 SOC_ENUM("Capture PCM HP Filter", wm8350_enum[5]),
454 SOC_ENUM("Capture ADC Inversion", wm8350_enum[6]), 441 SOC_ENUM("Capture ADC Inversion", wm8350_enum[6]),
455 SOC_WM8350_DOUBLE_R_TLV("Capture PCM Volume", 442 SOC_DOUBLE_R_EXT_TLV("Capture PCM Volume",
456 WM8350_ADC_DIGITAL_VOLUME_L, 443 WM8350_ADC_DIGITAL_VOLUME_L,
457 WM8350_ADC_DIGITAL_VOLUME_R, 444 WM8350_ADC_DIGITAL_VOLUME_R,
458 0, 255, 0, adc_pcm_tlv), 445 0, 255, 0, wm8350_get_volsw_2r,
446 wm8350_put_volsw_2r_vu, adc_pcm_tlv),
459 SOC_DOUBLE_TLV("Capture Sidetone Volume", 447 SOC_DOUBLE_TLV("Capture Sidetone Volume",
460 WM8350_ADC_DIVIDER, 448 WM8350_ADC_DIVIDER,
461 8, 4, 15, 1, capture_sd_tlv), 449 8, 4, 15, 1, capture_sd_tlv),
462 SOC_WM8350_DOUBLE_R_TLV("Capture Volume", 450 SOC_DOUBLE_R_EXT_TLV("Capture Volume",
463 WM8350_LEFT_INPUT_VOLUME, 451 WM8350_LEFT_INPUT_VOLUME,
464 WM8350_RIGHT_INPUT_VOLUME, 452 WM8350_RIGHT_INPUT_VOLUME,
465 2, 63, 0, pre_amp_tlv), 453 2, 63, 0, wm8350_get_volsw_2r,
454 wm8350_put_volsw_2r_vu, pre_amp_tlv),
466 SOC_DOUBLE_R("Capture ZC Switch", 455 SOC_DOUBLE_R("Capture ZC Switch",
467 WM8350_LEFT_INPUT_VOLUME, 456 WM8350_LEFT_INPUT_VOLUME,
468 WM8350_RIGHT_INPUT_VOLUME, 13, 1, 0), 457 WM8350_RIGHT_INPUT_VOLUME, 13, 1, 0),
@@ -490,17 +479,19 @@ static const struct snd_kcontrol_new wm8350_snd_controls[] = {
490 SOC_SINGLE_TLV("Out4 Capture Volume", 479 SOC_SINGLE_TLV("Out4 Capture Volume",
491 WM8350_INPUT_MIXER_VOLUME, 480 WM8350_INPUT_MIXER_VOLUME,
492 1, 7, 0, out_mix_tlv), 481 1, 7, 0, out_mix_tlv),
493 SOC_WM8350_DOUBLE_R_TLV("Out1 Playback Volume", 482 SOC_DOUBLE_R_EXT_TLV("Out1 Playback Volume",
494 WM8350_LOUT1_VOLUME, 483 WM8350_LOUT1_VOLUME,
495 WM8350_ROUT1_VOLUME, 484 WM8350_ROUT1_VOLUME,
496 2, 63, 0, out_pga_tlv), 485 2, 63, 0, wm8350_get_volsw_2r,
486 wm8350_put_volsw_2r_vu, out_pga_tlv),
497 SOC_DOUBLE_R("Out1 Playback ZC Switch", 487 SOC_DOUBLE_R("Out1 Playback ZC Switch",
498 WM8350_LOUT1_VOLUME, 488 WM8350_LOUT1_VOLUME,
499 WM8350_ROUT1_VOLUME, 13, 1, 0), 489 WM8350_ROUT1_VOLUME, 13, 1, 0),
500 SOC_WM8350_DOUBLE_R_TLV("Out2 Playback Volume", 490 SOC_DOUBLE_R_EXT_TLV("Out2 Playback Volume",
501 WM8350_LOUT2_VOLUME, 491 WM8350_LOUT2_VOLUME,
502 WM8350_ROUT2_VOLUME, 492 WM8350_ROUT2_VOLUME,
503 2, 63, 0, out_pga_tlv), 493 2, 63, 0, wm8350_get_volsw_2r,
494 wm8350_put_volsw_2r_vu, out_pga_tlv),
504 SOC_DOUBLE_R("Out2 Playback ZC Switch", WM8350_LOUT2_VOLUME, 495 SOC_DOUBLE_R("Out2 Playback ZC Switch", WM8350_LOUT2_VOLUME,
505 WM8350_ROUT2_VOLUME, 13, 1, 0), 496 WM8350_ROUT2_VOLUME, 13, 1, 0),
506 SOC_SINGLE("Out2 Right Invert Switch", WM8350_ROUT2_VOLUME, 10, 1, 0), 497 SOC_SINGLE("Out2 Right Invert Switch", WM8350_ROUT2_VOLUME, 10, 1, 0),
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c
index fbee556cbf3..dc13be2a09c 100644
--- a/sound/soc/codecs/wm8400.c
+++ b/sound/soc/codecs/wm8400.c
@@ -383,7 +383,7 @@ static int inmixer_event (struct snd_soc_dapm_widget *w,
383 (1 << WM8400_AINRMUX_PWR))) { 383 (1 << WM8400_AINRMUX_PWR))) {
384 reg |= WM8400_AINR_ENA; 384 reg |= WM8400_AINR_ENA;
385 } else { 385 } else {
386 reg &= ~WM8400_AINL_ENA; 386 reg &= ~WM8400_AINR_ENA;
387 } 387 }
388 wm8400_write(w->codec, WM8400_POWER_MANAGEMENT_2, reg); 388 wm8400_write(w->codec, WM8400_POWER_MANAGEMENT_2, reg);
389 389
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c
index db0dced7484..07c9cc759e9 100644
--- a/sound/soc/codecs/wm8510.c
+++ b/sound/soc/codecs/wm8510.c
@@ -20,6 +20,7 @@
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/spi/spi.h> 21#include <linux/spi/spi.h>
22#include <linux/slab.h> 22#include <linux/slab.h>
23#include <linux/of_device.h>
23#include <sound/core.h> 24#include <sound/core.h>
24#include <sound/pcm.h> 25#include <sound/pcm.h>
25#include <sound/pcm_params.h> 26#include <sound/pcm_params.h>
@@ -479,6 +480,8 @@ static int wm8510_set_bias_level(struct snd_soc_codec *codec,
479 power1 |= WM8510_POWER1_BIASEN | WM8510_POWER1_BUFIOEN; 480 power1 |= WM8510_POWER1_BIASEN | WM8510_POWER1_BUFIOEN;
480 481
481 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { 482 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
483 snd_soc_cache_sync(codec);
484
482 /* Initial cap charge at VMID 5k */ 485 /* Initial cap charge at VMID 5k */
483 snd_soc_write(codec, WM8510_POWER1, power1 | 0x3); 486 snd_soc_write(codec, WM8510_POWER1, power1 | 0x3);
484 mdelay(100); 487 mdelay(100);
@@ -540,18 +543,7 @@ static int wm8510_suspend(struct snd_soc_codec *codec, pm_message_t state)
540 543
541static int wm8510_resume(struct snd_soc_codec *codec) 544static int wm8510_resume(struct snd_soc_codec *codec)
542{ 545{
543 int i;
544 u8 data[2];
545 u16 *cache = codec->reg_cache;
546
547 /* Sync reg_cache with the hardware */
548 for (i = 0; i < ARRAY_SIZE(wm8510_reg); i++) {
549 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
550 data[1] = cache[i] & 0x00ff;
551 codec->hw_write(codec->control_data, data, 2);
552 }
553 wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 546 wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
554
555 return 0; 547 return 0;
556} 548}
557 549
@@ -598,6 +590,11 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8510 = {
598 .reg_cache_default =wm8510_reg, 590 .reg_cache_default =wm8510_reg,
599}; 591};
600 592
593static const struct of_device_id wm8510_of_match[] = {
594 { .compatible = "wlf,wm8510" },
595 { },
596};
597
601#if defined(CONFIG_SPI_MASTER) 598#if defined(CONFIG_SPI_MASTER)
602static int __devinit wm8510_spi_probe(struct spi_device *spi) 599static int __devinit wm8510_spi_probe(struct spi_device *spi)
603{ 600{
@@ -628,6 +625,7 @@ static struct spi_driver wm8510_spi_driver = {
628 .driver = { 625 .driver = {
629 .name = "wm8510", 626 .name = "wm8510",
630 .owner = THIS_MODULE, 627 .owner = THIS_MODULE,
628 .of_match_table = wm8510_of_match,
631 }, 629 },
632 .probe = wm8510_spi_probe, 630 .probe = wm8510_spi_probe,
633 .remove = __devexit_p(wm8510_spi_remove), 631 .remove = __devexit_p(wm8510_spi_remove),
@@ -671,6 +669,7 @@ static struct i2c_driver wm8510_i2c_driver = {
671 .driver = { 669 .driver = {
672 .name = "wm8510-codec", 670 .name = "wm8510-codec",
673 .owner = THIS_MODULE, 671 .owner = THIS_MODULE,
672 .of_match_table = wm8510_of_match,
674 }, 673 },
675 .probe = wm8510_i2c_probe, 674 .probe = wm8510_i2c_probe,
676 .remove = __devexit_p(wm8510_i2c_remove), 675 .remove = __devexit_p(wm8510_i2c_remove),
diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c
index 4fd4d8dca0f..db7a6819499 100644
--- a/sound/soc/codecs/wm8523.c
+++ b/sound/soc/codecs/wm8523.c
@@ -20,6 +20,7 @@
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/regulator/consumer.h> 21#include <linux/regulator/consumer.h>
22#include <linux/slab.h> 22#include <linux/slab.h>
23#include <linux/of_device.h>
23#include <sound/core.h> 24#include <sound/core.h>
24#include <sound/pcm.h> 25#include <sound/pcm.h>
25#include <sound/pcm_params.h> 26#include <sound/pcm_params.h>
@@ -84,7 +85,7 @@ static const char *wm8523_zd_count_text[] = {
84static const struct soc_enum wm8523_zc_count = 85static const struct soc_enum wm8523_zc_count =
85 SOC_ENUM_SINGLE(WM8523_ZERO_DETECT, 0, 2, wm8523_zd_count_text); 86 SOC_ENUM_SINGLE(WM8523_ZERO_DETECT, 0, 2, wm8523_zd_count_text);
86 87
87static const struct snd_kcontrol_new wm8523_snd_controls[] = { 88static const struct snd_kcontrol_new wm8523_controls[] = {
88SOC_DOUBLE_R_TLV("Playback Volume", WM8523_DAC_GAINL, WM8523_DAC_GAINR, 89SOC_DOUBLE_R_TLV("Playback Volume", WM8523_DAC_GAINL, WM8523_DAC_GAINR,
89 0, 448, 0, dac_tlv), 90 0, 448, 0, dac_tlv),
90SOC_SINGLE("ZC Switch", WM8523_DAC_CTRL3, 4, 1, 0), 91SOC_SINGLE("ZC Switch", WM8523_DAC_CTRL3, 4, 1, 0),
@@ -101,22 +102,11 @@ SND_SOC_DAPM_OUTPUT("LINEVOUTL"),
101SND_SOC_DAPM_OUTPUT("LINEVOUTR"), 102SND_SOC_DAPM_OUTPUT("LINEVOUTR"),
102}; 103};
103 104
104static const struct snd_soc_dapm_route intercon[] = { 105static const struct snd_soc_dapm_route wm8523_dapm_routes[] = {
105 { "LINEVOUTL", NULL, "DAC" }, 106 { "LINEVOUTL", NULL, "DAC" },
106 { "LINEVOUTR", NULL, "DAC" }, 107 { "LINEVOUTR", NULL, "DAC" },
107}; 108};
108 109
109static int wm8523_add_widgets(struct snd_soc_codec *codec)
110{
111 struct snd_soc_dapm_context *dapm = &codec->dapm;
112
113 snd_soc_dapm_new_controls(dapm, wm8523_dapm_widgets,
114 ARRAY_SIZE(wm8523_dapm_widgets));
115 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
116
117 return 0;
118}
119
120static struct { 110static struct {
121 int value; 111 int value;
122 int ratio; 112 int ratio;
@@ -416,7 +406,6 @@ static int wm8523_probe(struct snd_soc_codec *codec)
416 struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec); 406 struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
417 int ret, i; 407 int ret, i;
418 408
419 codec->hw_write = (hw_write_t)i2c_master_send;
420 wm8523->rate_constraint.list = &wm8523->rate_constraint_list[0]; 409 wm8523->rate_constraint.list = &wm8523->rate_constraint_list[0];
421 wm8523->rate_constraint.count = 410 wm8523->rate_constraint.count =
422 ARRAY_SIZE(wm8523->rate_constraint_list); 411 ARRAY_SIZE(wm8523->rate_constraint_list);
@@ -479,10 +468,6 @@ static int wm8523_probe(struct snd_soc_codec *codec)
479 /* Bias level configuration will have done an extra enable */ 468 /* Bias level configuration will have done an extra enable */
480 regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies); 469 regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
481 470
482 snd_soc_add_controls(codec, wm8523_snd_controls,
483 ARRAY_SIZE(wm8523_snd_controls));
484 wm8523_add_widgets(codec);
485
486 return 0; 471 return 0;
487 472
488err_enable: 473err_enable:
@@ -512,6 +497,18 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8523 = {
512 .reg_word_size = sizeof(u16), 497 .reg_word_size = sizeof(u16),
513 .reg_cache_default = wm8523_reg, 498 .reg_cache_default = wm8523_reg,
514 .volatile_register = wm8523_volatile_register, 499 .volatile_register = wm8523_volatile_register,
500
501 .controls = wm8523_controls,
502 .num_controls = ARRAY_SIZE(wm8523_controls),
503 .dapm_widgets = wm8523_dapm_widgets,
504 .num_dapm_widgets = ARRAY_SIZE(wm8523_dapm_widgets),
505 .dapm_routes = wm8523_dapm_routes,
506 .num_dapm_routes = ARRAY_SIZE(wm8523_dapm_routes),
507};
508
509static const struct of_device_id wm8523_of_match[] = {
510 { .compatible = "wlf,wm8523" },
511 { },
515}; 512};
516 513
517#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 514#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
@@ -551,8 +548,9 @@ MODULE_DEVICE_TABLE(i2c, wm8523_i2c_id);
551 548
552static struct i2c_driver wm8523_i2c_driver = { 549static struct i2c_driver wm8523_i2c_driver = {
553 .driver = { 550 .driver = {
554 .name = "wm8523-codec", 551 .name = "wm8523",
555 .owner = THIS_MODULE, 552 .owner = THIS_MODULE,
553 .of_match_table = wm8523_of_match,
556 }, 554 },
557 .probe = wm8523_i2c_probe, 555 .probe = wm8523_i2c_probe,
558 .remove = __devexit_p(wm8523_i2c_remove), 556 .remove = __devexit_p(wm8523_i2c_remove),
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
index 4bbc0a79f01..8212b3c8bfd 100644
--- a/sound/soc/codecs/wm8580.c
+++ b/sound/soc/codecs/wm8580.c
@@ -26,6 +26,7 @@
26#include <linux/platform_device.h> 26#include <linux/platform_device.h>
27#include <linux/regulator/consumer.h> 27#include <linux/regulator/consumer.h>
28#include <linux/slab.h> 28#include <linux/slab.h>
29#include <linux/of_device.h>
29 30
30#include <sound/core.h> 31#include <sound/core.h>
31#include <sound/pcm.h> 32#include <sound/pcm.h>
@@ -212,7 +213,7 @@ static int wm8580_out_vu(struct snd_kcontrol *kcontrol,
212 reg_cache[reg] = 0; 213 reg_cache[reg] = 0;
213 reg_cache[reg2] = 0; 214 reg_cache[reg2] = 0;
214 215
215 ret = snd_soc_put_volsw_2r(kcontrol, ucontrol); 216 ret = snd_soc_put_volsw(kcontrol, ucontrol);
216 if (ret < 0) 217 if (ret < 0)
217 return ret; 218 return ret;
218 219
@@ -223,31 +224,19 @@ static int wm8580_out_vu(struct snd_kcontrol *kcontrol,
223 return 0; 224 return 0;
224} 225}
225 226
226#define SOC_WM8580_OUT_DOUBLE_R_TLV(xname, reg_left, reg_right, xshift, xmax, \
227 xinvert, tlv_array) \
228{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
229 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
230 SNDRV_CTL_ELEM_ACCESS_READWRITE, \
231 .tlv.p = (tlv_array), \
232 .info = snd_soc_info_volsw_2r, \
233 .get = snd_soc_get_volsw_2r, .put = wm8580_out_vu, \
234 .private_value = (unsigned long)&(struct soc_mixer_control) \
235 {.reg = reg_left, .rreg = reg_right, .shift = xshift, \
236 .max = xmax, .invert = xinvert} }
237
238static const struct snd_kcontrol_new wm8580_snd_controls[] = { 227static const struct snd_kcontrol_new wm8580_snd_controls[] = {
239SOC_WM8580_OUT_DOUBLE_R_TLV("DAC1 Playback Volume", 228SOC_DOUBLE_R_EXT_TLV("DAC1 Playback Volume",
240 WM8580_DIGITAL_ATTENUATION_DACL1, 229 WM8580_DIGITAL_ATTENUATION_DACL1,
241 WM8580_DIGITAL_ATTENUATION_DACR1, 230 WM8580_DIGITAL_ATTENUATION_DACR1,
242 0, 0xff, 0, dac_tlv), 231 0, 0xff, 0, snd_soc_get_volsw, wm8580_out_vu, dac_tlv),
243SOC_WM8580_OUT_DOUBLE_R_TLV("DAC2 Playback Volume", 232SOC_DOUBLE_R_EXT_TLV("DAC2 Playback Volume",
244 WM8580_DIGITAL_ATTENUATION_DACL2, 233 WM8580_DIGITAL_ATTENUATION_DACL2,
245 WM8580_DIGITAL_ATTENUATION_DACR2, 234 WM8580_DIGITAL_ATTENUATION_DACR2,
246 0, 0xff, 0, dac_tlv), 235 0, 0xff, 0, snd_soc_get_volsw, wm8580_out_vu, dac_tlv),
247SOC_WM8580_OUT_DOUBLE_R_TLV("DAC3 Playback Volume", 236SOC_DOUBLE_R_EXT_TLV("DAC3 Playback Volume",
248 WM8580_DIGITAL_ATTENUATION_DACL3, 237 WM8580_DIGITAL_ATTENUATION_DACL3,
249 WM8580_DIGITAL_ATTENUATION_DACR3, 238 WM8580_DIGITAL_ATTENUATION_DACR3,
250 0, 0xff, 0, dac_tlv), 239 0, 0xff, 0, snd_soc_get_volsw, wm8580_out_vu, dac_tlv),
251 240
252SOC_SINGLE("DAC1 Deemphasis Switch", WM8580_DAC_CONTROL3, 0, 1, 0), 241SOC_SINGLE("DAC1 Deemphasis Switch", WM8580_DAC_CONTROL3, 0, 1, 0),
253SOC_SINGLE("DAC2 Deemphasis Switch", WM8580_DAC_CONTROL3, 1, 1, 0), 242SOC_SINGLE("DAC2 Deemphasis Switch", WM8580_DAC_CONTROL3, 1, 1, 0),
@@ -441,8 +430,7 @@ static int wm8580_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
441 /* Always disable the PLL - it is not safe to leave it running 430 /* Always disable the PLL - it is not safe to leave it running
442 * while reprogramming it. 431 * while reprogramming it.
443 */ 432 */
444 reg = snd_soc_read(codec, WM8580_PWRDN2); 433 snd_soc_update_bits(codec, WM8580_PWRDN2, pwr_mask, pwr_mask);
445 snd_soc_write(codec, WM8580_PWRDN2, reg | pwr_mask);
446 434
447 if (!freq_in || !freq_out) 435 if (!freq_in || !freq_out)
448 return 0; 436 return 0;
@@ -460,8 +448,7 @@ static int wm8580_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
460 snd_soc_write(codec, WM8580_PLLA4 + offset, reg); 448 snd_soc_write(codec, WM8580_PLLA4 + offset, reg);
461 449
462 /* All done, turn it on */ 450 /* All done, turn it on */
463 reg = snd_soc_read(codec, WM8580_PWRDN2); 451 snd_soc_update_bits(codec, WM8580_PWRDN2, pwr_mask, 0);
464 snd_soc_write(codec, WM8580_PWRDN2, reg & ~pwr_mask);
465 452
466 return 0; 453 return 0;
467} 454}
@@ -759,7 +746,6 @@ static int wm8580_digital_mute(struct snd_soc_dai *codec_dai, int mute)
759static int wm8580_set_bias_level(struct snd_soc_codec *codec, 746static int wm8580_set_bias_level(struct snd_soc_codec *codec,
760 enum snd_soc_bias_level level) 747 enum snd_soc_bias_level level)
761{ 748{
762 u16 reg;
763 switch (level) { 749 switch (level) {
764 case SND_SOC_BIAS_ON: 750 case SND_SOC_BIAS_ON:
765 case SND_SOC_BIAS_PREPARE: 751 case SND_SOC_BIAS_PREPARE:
@@ -768,20 +754,19 @@ static int wm8580_set_bias_level(struct snd_soc_codec *codec,
768 case SND_SOC_BIAS_STANDBY: 754 case SND_SOC_BIAS_STANDBY:
769 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { 755 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
770 /* Power up and get individual control of the DACs */ 756 /* Power up and get individual control of the DACs */
771 reg = snd_soc_read(codec, WM8580_PWRDN1); 757 snd_soc_update_bits(codec, WM8580_PWRDN1,
772 reg &= ~(WM8580_PWRDN1_PWDN | WM8580_PWRDN1_ALLDACPD); 758 WM8580_PWRDN1_PWDN |
773 snd_soc_write(codec, WM8580_PWRDN1, reg); 759 WM8580_PWRDN1_ALLDACPD, 0);
774 760
775 /* Make VMID high impedance */ 761 /* Make VMID high impedance */
776 reg = snd_soc_read(codec, WM8580_ADC_CONTROL1); 762 snd_soc_update_bits(codec, WM8580_ADC_CONTROL1,
777 reg &= ~0x100; 763 0x100, 0);
778 snd_soc_write(codec, WM8580_ADC_CONTROL1, reg);
779 } 764 }
780 break; 765 break;
781 766
782 case SND_SOC_BIAS_OFF: 767 case SND_SOC_BIAS_OFF:
783 reg = snd_soc_read(codec, WM8580_PWRDN1); 768 snd_soc_update_bits(codec, WM8580_PWRDN1,
784 snd_soc_write(codec, WM8580_PWRDN1, reg | WM8580_PWRDN1_PWDN); 769 WM8580_PWRDN1_PWDN, WM8580_PWRDN1_PWDN);
785 break; 770 break;
786 } 771 }
787 codec->dapm.bias_level = level; 772 codec->dapm.bias_level = level;
@@ -907,6 +892,11 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8580 = {
907 .reg_cache_default = wm8580_reg, 892 .reg_cache_default = wm8580_reg,
908}; 893};
909 894
895static const struct of_device_id wm8580_of_match[] = {
896 { .compatible = "wlf,wm8580" },
897 { },
898};
899
910#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 900#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
911static int wm8580_i2c_probe(struct i2c_client *i2c, 901static int wm8580_i2c_probe(struct i2c_client *i2c,
912 const struct i2c_device_id *id) 902 const struct i2c_device_id *id)
@@ -943,8 +933,9 @@ MODULE_DEVICE_TABLE(i2c, wm8580_i2c_id);
943 933
944static struct i2c_driver wm8580_i2c_driver = { 934static struct i2c_driver wm8580_i2c_driver = {
945 .driver = { 935 .driver = {
946 .name = "wm8580-codec", 936 .name = "wm8580",
947 .owner = THIS_MODULE, 937 .owner = THIS_MODULE,
938 .of_match_table = wm8580_of_match,
948 }, 939 },
949 .probe = wm8580_i2c_probe, 940 .probe = wm8580_i2c_probe,
950 .remove = wm8580_i2c_remove, 941 .remove = wm8580_i2c_remove,
diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c
index a537e4af6ae..8d0347cf0e9 100644
--- a/sound/soc/codecs/wm8711.c
+++ b/sound/soc/codecs/wm8711.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright 2006 Wolfson Microelectronics 4 * Copyright 2006 Wolfson Microelectronics
5 * 5 *
6 * Author: Mike Arthur <linux@wolfsonmicro.com> 6 * Author: Mike Arthur <Mike.Arthur@wolfsonmicro.com>
7 * 7 *
8 * Based on wm8731.c by Richard Purdie 8 * Based on wm8731.c by Richard Purdie
9 * 9 *
@@ -21,6 +21,7 @@
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/spi/spi.h> 22#include <linux/spi/spi.h>
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/of_device.h>
24#include <sound/core.h> 25#include <sound/core.h>
25#include <sound/pcm.h> 26#include <sound/pcm.h>
26#include <sound/pcm_params.h> 27#include <sound/pcm_params.h>
@@ -286,7 +287,6 @@ static int wm8711_set_dai_fmt(struct snd_soc_dai *codec_dai,
286 return 0; 287 return 0;
287} 288}
288 289
289
290static int wm8711_set_bias_level(struct snd_soc_codec *codec, 290static int wm8711_set_bias_level(struct snd_soc_codec *codec,
291 enum snd_soc_bias_level level) 291 enum snd_soc_bias_level level)
292{ 292{
@@ -299,6 +299,9 @@ static int wm8711_set_bias_level(struct snd_soc_codec *codec,
299 case SND_SOC_BIAS_PREPARE: 299 case SND_SOC_BIAS_PREPARE:
300 break; 300 break;
301 case SND_SOC_BIAS_STANDBY: 301 case SND_SOC_BIAS_STANDBY:
302 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
303 snd_soc_cache_sync(codec);
304
302 snd_soc_write(codec, WM8711_PWR, reg | 0x0040); 305 snd_soc_write(codec, WM8711_PWR, reg | 0x0040);
303 break; 306 break;
304 case SND_SOC_BIAS_OFF: 307 case SND_SOC_BIAS_OFF:
@@ -345,25 +348,14 @@ static int wm8711_suspend(struct snd_soc_codec *codec, pm_message_t state)
345 348
346static int wm8711_resume(struct snd_soc_codec *codec) 349static int wm8711_resume(struct snd_soc_codec *codec)
347{ 350{
348 int i;
349 u8 data[2];
350 u16 *cache = codec->reg_cache;
351
352 /* Sync reg_cache with the hardware */
353 for (i = 0; i < ARRAY_SIZE(wm8711_reg); i++) {
354 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
355 data[1] = cache[i] & 0x00ff;
356 codec->hw_write(codec->control_data, data, 2);
357 }
358 wm8711_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 351 wm8711_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
359
360 return 0; 352 return 0;
361} 353}
362 354
363static int wm8711_probe(struct snd_soc_codec *codec) 355static int wm8711_probe(struct snd_soc_codec *codec)
364{ 356{
365 struct wm8711_priv *wm8711 = snd_soc_codec_get_drvdata(codec); 357 struct wm8711_priv *wm8711 = snd_soc_codec_get_drvdata(codec);
366 int ret, reg; 358 int ret;
367 359
368 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8711->bus_type); 360 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8711->bus_type);
369 if (ret < 0) { 361 if (ret < 0) {
@@ -380,10 +372,8 @@ static int wm8711_probe(struct snd_soc_codec *codec)
380 wm8711_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 372 wm8711_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
381 373
382 /* Latch the update bits */ 374 /* Latch the update bits */
383 reg = snd_soc_read(codec, WM8711_LOUT1V); 375 snd_soc_update_bits(codec, WM8711_LOUT1V, 0x0100, 0x0100);
384 snd_soc_write(codec, WM8711_LOUT1V, reg | 0x0100); 376 snd_soc_update_bits(codec, WM8711_ROUT1V, 0x0100, 0x0100);
385 reg = snd_soc_read(codec, WM8711_ROUT1V);
386 snd_soc_write(codec, WM8711_ROUT1V, reg | 0x0100);
387 377
388 snd_soc_add_controls(codec, wm8711_snd_controls, 378 snd_soc_add_controls(codec, wm8711_snd_controls,
389 ARRAY_SIZE(wm8711_snd_controls)); 379 ARRAY_SIZE(wm8711_snd_controls));
@@ -414,6 +404,12 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8711 = {
414 .num_dapm_routes = ARRAY_SIZE(wm8711_intercon), 404 .num_dapm_routes = ARRAY_SIZE(wm8711_intercon),
415}; 405};
416 406
407static const struct of_device_id wm8711_of_match[] = {
408 { .compatible = "wlf,wm8711", },
409 { }
410};
411MODULE_DEVICE_TABLE(of, wm8711_of_match);
412
417#if defined(CONFIG_SPI_MASTER) 413#if defined(CONFIG_SPI_MASTER)
418static int __devinit wm8711_spi_probe(struct spi_device *spi) 414static int __devinit wm8711_spi_probe(struct spi_device *spi)
419{ 415{
@@ -443,8 +439,9 @@ static int __devexit wm8711_spi_remove(struct spi_device *spi)
443 439
444static struct spi_driver wm8711_spi_driver = { 440static struct spi_driver wm8711_spi_driver = {
445 .driver = { 441 .driver = {
446 .name = "wm8711-codec", 442 .name = "wm8711",
447 .owner = THIS_MODULE, 443 .owner = THIS_MODULE,
444 .of_match_table = wm8711_of_match,
448 }, 445 },
449 .probe = wm8711_spi_probe, 446 .probe = wm8711_spi_probe,
450 .remove = __devexit_p(wm8711_spi_remove), 447 .remove = __devexit_p(wm8711_spi_remove),
@@ -487,8 +484,9 @@ MODULE_DEVICE_TABLE(i2c, wm8711_i2c_id);
487 484
488static struct i2c_driver wm8711_i2c_driver = { 485static struct i2c_driver wm8711_i2c_driver = {
489 .driver = { 486 .driver = {
490 .name = "wm8711-codec", 487 .name = "wm8711",
491 .owner = THIS_MODULE, 488 .owner = THIS_MODULE,
489 .of_match_table = wm8711_of_match,
492 }, 490 },
493 .probe = wm8711_i2c_probe, 491 .probe = wm8711_i2c_probe,
494 .remove = __devexit_p(wm8711_i2c_remove), 492 .remove = __devexit_p(wm8711_i2c_remove),
diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c
index 86d4718d3a7..04b027efd5c 100644
--- a/sound/soc/codecs/wm8728.c
+++ b/sound/soc/codecs/wm8728.c
@@ -19,6 +19,7 @@
19#include <linux/platform_device.h> 19#include <linux/platform_device.h>
20#include <linux/spi/spi.h> 20#include <linux/spi/spi.h>
21#include <linux/slab.h> 21#include <linux/slab.h>
22#include <linux/of_device.h>
22#include <sound/core.h> 23#include <sound/core.h>
23#include <sound/pcm.h> 24#include <sound/pcm.h>
24#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
@@ -269,6 +270,12 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8728 = {
269 .num_dapm_routes = ARRAY_SIZE(wm8728_intercon), 270 .num_dapm_routes = ARRAY_SIZE(wm8728_intercon),
270}; 271};
271 272
273static const struct of_device_id wm8728_of_match[] = {
274 { .compatible = "wlf,wm8728", },
275 { }
276};
277MODULE_DEVICE_TABLE(of, wm8728_of_match);
278
272#if defined(CONFIG_SPI_MASTER) 279#if defined(CONFIG_SPI_MASTER)
273static int __devinit wm8728_spi_probe(struct spi_device *spi) 280static int __devinit wm8728_spi_probe(struct spi_device *spi)
274{ 281{
@@ -298,8 +305,9 @@ static int __devexit wm8728_spi_remove(struct spi_device *spi)
298 305
299static struct spi_driver wm8728_spi_driver = { 306static struct spi_driver wm8728_spi_driver = {
300 .driver = { 307 .driver = {
301 .name = "wm8728-codec", 308 .name = "wm8728",
302 .owner = THIS_MODULE, 309 .owner = THIS_MODULE,
310 .of_match_table = wm8728_of_match,
303 }, 311 },
304 .probe = wm8728_spi_probe, 312 .probe = wm8728_spi_probe,
305 .remove = __devexit_p(wm8728_spi_remove), 313 .remove = __devexit_p(wm8728_spi_remove),
@@ -342,8 +350,9 @@ MODULE_DEVICE_TABLE(i2c, wm8728_i2c_id);
342 350
343static struct i2c_driver wm8728_i2c_driver = { 351static struct i2c_driver wm8728_i2c_driver = {
344 .driver = { 352 .driver = {
345 .name = "wm8728-codec", 353 .name = "wm8728",
346 .owner = THIS_MODULE, 354 .owner = THIS_MODULE,
355 .of_match_table = wm8728_of_match,
347 }, 356 },
348 .probe = wm8728_i2c_probe, 357 .probe = wm8728_i2c_probe,
349 .remove = __devexit_p(wm8728_i2c_remove), 358 .remove = __devexit_p(wm8728_i2c_remove),
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index 76b4361e9b8..7e5ec03f6f8 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -22,6 +22,7 @@
22#include <linux/platform_device.h> 22#include <linux/platform_device.h>
23#include <linux/regulator/consumer.h> 23#include <linux/regulator/consumer.h>
24#include <linux/spi/spi.h> 24#include <linux/spi/spi.h>
25#include <linux/of_device.h>
25#include <sound/core.h> 26#include <sound/core.h>
26#include <sound/pcm.h> 27#include <sound/pcm.h>
27#include <sound/pcm_params.h> 28#include <sound/pcm_params.h>
@@ -426,9 +427,7 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec,
426 enum snd_soc_bias_level level) 427 enum snd_soc_bias_level level)
427{ 428{
428 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); 429 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
429 int i, ret; 430 int ret;
430 u8 data[2];
431 u16 *cache = codec->reg_cache;
432 u16 reg; 431 u16 reg;
433 432
434 switch (level) { 433 switch (level) {
@@ -443,16 +442,7 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec,
443 if (ret != 0) 442 if (ret != 0)
444 return ret; 443 return ret;
445 444
446 /* Sync reg_cache with the hardware */ 445 snd_soc_cache_sync(codec);
447 for (i = 0; i < ARRAY_SIZE(wm8731_reg); i++) {
448 if (cache[i] == wm8731_reg[i])
449 continue;
450
451 data[0] = (i << 1) | ((cache[i] >> 8)
452 & 0x0001);
453 data[1] = cache[i] & 0x00ff;
454 codec->hw_write(codec->control_data, data, 2);
455 }
456 } 446 }
457 447
458 /* Clear PWROFF, gate CLKOUT, everything else as-is */ 448 /* Clear PWROFF, gate CLKOUT, everything else as-is */
@@ -607,6 +597,13 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8731 = {
607 .num_dapm_routes = ARRAY_SIZE(wm8731_intercon), 597 .num_dapm_routes = ARRAY_SIZE(wm8731_intercon),
608}; 598};
609 599
600static const struct of_device_id wm8731_of_match[] = {
601 { .compatible = "wlf,wm8731", },
602 { }
603};
604
605MODULE_DEVICE_TABLE(of, wm8731_of_match);
606
610#if defined(CONFIG_SPI_MASTER) 607#if defined(CONFIG_SPI_MASTER)
611static int __devinit wm8731_spi_probe(struct spi_device *spi) 608static int __devinit wm8731_spi_probe(struct spi_device *spi)
612{ 609{
@@ -638,6 +635,7 @@ static struct spi_driver wm8731_spi_driver = {
638 .driver = { 635 .driver = {
639 .name = "wm8731", 636 .name = "wm8731",
640 .owner = THIS_MODULE, 637 .owner = THIS_MODULE,
638 .of_match_table = wm8731_of_match,
641 }, 639 },
642 .probe = wm8731_spi_probe, 640 .probe = wm8731_spi_probe,
643 .remove = __devexit_p(wm8731_spi_remove), 641 .remove = __devexit_p(wm8731_spi_remove),
@@ -682,6 +680,7 @@ static struct i2c_driver wm8731_i2c_driver = {
682 .driver = { 680 .driver = {
683 .name = "wm8731", 681 .name = "wm8731",
684 .owner = THIS_MODULE, 682 .owner = THIS_MODULE,
683 .of_match_table = wm8731_of_match,
685 }, 684 },
686 .probe = wm8731_i2c_probe, 685 .probe = wm8731_i2c_probe,
687 .remove = __devexit_p(wm8731_i2c_remove), 686 .remove = __devexit_p(wm8731_i2c_remove),
diff --git a/sound/soc/codecs/wm8737.c b/sound/soc/codecs/wm8737.c
index 30c67d06a90..f6aef58845c 100644
--- a/sound/soc/codecs/wm8737.c
+++ b/sound/soc/codecs/wm8737.c
@@ -20,6 +20,7 @@
20#include <linux/regulator/consumer.h> 20#include <linux/regulator/consumer.h>
21#include <linux/spi/spi.h> 21#include <linux/spi/spi.h>
22#include <linux/slab.h> 22#include <linux/slab.h>
23#include <linux/of_device.h>
23#include <sound/core.h> 24#include <sound/core.h>
24#include <sound/pcm.h> 25#include <sound/pcm.h>
25#include <sound/pcm_params.h> 26#include <sound/pcm_params.h>
@@ -634,6 +635,13 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8737 = {
634 .reg_cache_default = wm8737_reg, 635 .reg_cache_default = wm8737_reg,
635}; 636};
636 637
638static const struct of_device_id wm8737_of_match[] = {
639 { .compatible = "wlf,wm8737", },
640 { }
641};
642
643MODULE_DEVICE_TABLE(of, wm8737_of_match);
644
637#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 645#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
638static __devinit int wm8737_i2c_probe(struct i2c_client *i2c, 646static __devinit int wm8737_i2c_probe(struct i2c_client *i2c,
639 const struct i2c_device_id *id) 647 const struct i2c_device_id *id)
@@ -673,6 +681,7 @@ static struct i2c_driver wm8737_i2c_driver = {
673 .driver = { 681 .driver = {
674 .name = "wm8737", 682 .name = "wm8737",
675 .owner = THIS_MODULE, 683 .owner = THIS_MODULE,
684 .of_match_table = wm8737_of_match,
676 }, 685 },
677 .probe = wm8737_i2c_probe, 686 .probe = wm8737_i2c_probe,
678 .remove = __devexit_p(wm8737_i2c_remove), 687 .remove = __devexit_p(wm8737_i2c_remove),
@@ -711,6 +720,7 @@ static struct spi_driver wm8737_spi_driver = {
711 .driver = { 720 .driver = {
712 .name = "wm8737", 721 .name = "wm8737",
713 .owner = THIS_MODULE, 722 .owner = THIS_MODULE,
723 .of_match_table = wm8737_of_match,
714 }, 724 },
715 .probe = wm8737_spi_probe, 725 .probe = wm8737_spi_probe,
716 .remove = __devexit_p(wm8737_spi_remove), 726 .remove = __devexit_p(wm8737_spi_remove),
diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c
index 25af901fe81..57ad22aacc5 100644
--- a/sound/soc/codecs/wm8741.c
+++ b/sound/soc/codecs/wm8741.c
@@ -17,9 +17,11 @@
17#include <linux/delay.h> 17#include <linux/delay.h>
18#include <linux/pm.h> 18#include <linux/pm.h>
19#include <linux/i2c.h> 19#include <linux/i2c.h>
20#include <linux/spi/spi.h>
20#include <linux/platform_device.h> 21#include <linux/platform_device.h>
21#include <linux/regulator/consumer.h> 22#include <linux/regulator/consumer.h>
22#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/of_device.h>
23#include <sound/core.h> 25#include <sound/core.h>
24#include <sound/pcm.h> 26#include <sound/pcm.h>
25#include <sound/pcm_params.h> 27#include <sound/pcm_params.h>
@@ -337,10 +339,10 @@ static int wm8741_set_dai_fmt(struct snd_soc_dai *codec_dai,
337 iface |= 0x0004; 339 iface |= 0x0004;
338 break; 340 break;
339 case SND_SOC_DAIFMT_DSP_A: 341 case SND_SOC_DAIFMT_DSP_A:
340 iface |= 0x0003; 342 iface |= 0x000C;
341 break; 343 break;
342 case SND_SOC_DAIFMT_DSP_B: 344 case SND_SOC_DAIFMT_DSP_B:
343 iface |= 0x0013; 345 iface |= 0x001C;
344 break; 346 break;
345 default: 347 default:
346 return -EINVAL; 348 return -EINVAL;
@@ -402,15 +404,7 @@ static struct snd_soc_dai_driver wm8741_dai = {
402#ifdef CONFIG_PM 404#ifdef CONFIG_PM
403static int wm8741_resume(struct snd_soc_codec *codec) 405static int wm8741_resume(struct snd_soc_codec *codec)
404{ 406{
405 u16 *cache = codec->reg_cache; 407 snd_soc_cache_sync(codec);
406 int i;
407
408 /* RESTORE REG Cache */
409 for (i = 0; i < WM8741_REGISTER_COUNT; i++) {
410 if (cache[i] == wm8741_reg_defaults[i] || WM8741_RESET == i)
411 continue;
412 snd_soc_write(codec, i, cache[i]);
413 }
414 return 0; 408 return 0;
415} 409}
416#else 410#else
@@ -422,17 +416,35 @@ static int wm8741_probe(struct snd_soc_codec *codec)
422{ 416{
423 struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec); 417 struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
424 int ret = 0; 418 int ret = 0;
419 int i;
420
421 for (i = 0; i < ARRAY_SIZE(wm8741->supplies); i++)
422 wm8741->supplies[i].supply = wm8741_supply_names[i];
423
424 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8741->supplies),
425 wm8741->supplies);
426 if (ret != 0) {
427 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
428 goto err;
429 }
430
431 ret = regulator_bulk_enable(ARRAY_SIZE(wm8741->supplies),
432 wm8741->supplies);
433 if (ret != 0) {
434 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
435 goto err_get;
436 }
425 437
426 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8741->control_type); 438 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8741->control_type);
427 if (ret != 0) { 439 if (ret != 0) {
428 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 440 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
429 return ret; 441 goto err_enable;
430 } 442 }
431 443
432 ret = wm8741_reset(codec); 444 ret = wm8741_reset(codec);
433 if (ret < 0) { 445 if (ret < 0) {
434 dev_err(codec->dev, "Failed to issue reset\n"); 446 dev_err(codec->dev, "Failed to issue reset\n");
435 return ret; 447 goto err_enable;
436 } 448 }
437 449
438 /* Change some default settings - latch VU */ 450 /* Change some default settings - latch VU */
@@ -442,7 +454,7 @@ static int wm8741_probe(struct snd_soc_codec *codec)
442 WM8741_UPDATELM, WM8741_UPDATELM); 454 WM8741_UPDATELM, WM8741_UPDATELM);
443 snd_soc_update_bits(codec, WM8741_DACRLSB_ATTENUATION, 455 snd_soc_update_bits(codec, WM8741_DACRLSB_ATTENUATION,
444 WM8741_UPDATERL, WM8741_UPDATERL); 456 WM8741_UPDATERL, WM8741_UPDATERL);
445 snd_soc_update_bits(codec, WM8741_DACRLSB_ATTENUATION, 457 snd_soc_update_bits(codec, WM8741_DACRMSB_ATTENUATION,
446 WM8741_UPDATERM, WM8741_UPDATERM); 458 WM8741_UPDATERM, WM8741_UPDATERM);
447 459
448 snd_soc_add_controls(codec, wm8741_snd_controls, 460 snd_soc_add_controls(codec, wm8741_snd_controls,
@@ -451,58 +463,61 @@ static int wm8741_probe(struct snd_soc_codec *codec)
451 463
452 dev_dbg(codec->dev, "Successful registration\n"); 464 dev_dbg(codec->dev, "Successful registration\n");
453 return ret; 465 return ret;
466
467err_enable:
468 regulator_bulk_disable(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
469err_get:
470 regulator_bulk_free(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
471err:
472 return ret;
473}
474
475static int wm8741_remove(struct snd_soc_codec *codec)
476{
477 struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
478
479 regulator_bulk_disable(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
480 regulator_bulk_free(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
481
482 return 0;
454} 483}
455 484
456static struct snd_soc_codec_driver soc_codec_dev_wm8741 = { 485static struct snd_soc_codec_driver soc_codec_dev_wm8741 = {
457 .probe = wm8741_probe, 486 .probe = wm8741_probe,
487 .remove = wm8741_remove,
458 .resume = wm8741_resume, 488 .resume = wm8741_resume,
459 .reg_cache_size = ARRAY_SIZE(wm8741_reg_defaults), 489 .reg_cache_size = ARRAY_SIZE(wm8741_reg_defaults),
460 .reg_word_size = sizeof(u16), 490 .reg_word_size = sizeof(u16),
461 .reg_cache_default = wm8741_reg_defaults, 491 .reg_cache_default = wm8741_reg_defaults,
462}; 492};
463 493
494static const struct of_device_id wm8741_of_match[] = {
495 { .compatible = "wlf,wm8741", },
496 { }
497};
498MODULE_DEVICE_TABLE(of, wm8741_of_match);
499
464#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 500#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
465static int wm8741_i2c_probe(struct i2c_client *i2c, 501static int wm8741_i2c_probe(struct i2c_client *i2c,
466 const struct i2c_device_id *id) 502 const struct i2c_device_id *id)
467{ 503{
468 struct wm8741_priv *wm8741; 504 struct wm8741_priv *wm8741;
469 int ret, i; 505 int ret;
470 506
471 wm8741 = kzalloc(sizeof(struct wm8741_priv), GFP_KERNEL); 507 wm8741 = kzalloc(sizeof(struct wm8741_priv), GFP_KERNEL);
472 if (wm8741 == NULL) 508 if (wm8741 == NULL)
473 return -ENOMEM; 509 return -ENOMEM;
474 510
475 for (i = 0; i < ARRAY_SIZE(wm8741->supplies); i++)
476 wm8741->supplies[i].supply = wm8741_supply_names[i];
477
478 ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8741->supplies),
479 wm8741->supplies);
480 if (ret != 0) {
481 dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
482 goto err;
483 }
484
485 ret = regulator_bulk_enable(ARRAY_SIZE(wm8741->supplies),
486 wm8741->supplies);
487 if (ret != 0) {
488 dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
489 goto err_get;
490 }
491
492 i2c_set_clientdata(i2c, wm8741); 511 i2c_set_clientdata(i2c, wm8741);
493 wm8741->control_type = SND_SOC_I2C; 512 wm8741->control_type = SND_SOC_I2C;
494 513
495 ret = snd_soc_register_codec(&i2c->dev, 514 ret = snd_soc_register_codec(&i2c->dev,
496 &soc_codec_dev_wm8741, &wm8741_dai, 1); 515 &soc_codec_dev_wm8741, &wm8741_dai, 1);
497 if (ret < 0) 516 if (ret != 0)
498 goto err_enable; 517 goto err;
499 return ret;
500 518
501err_enable: 519 return ret;
502 regulator_bulk_disable(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
503 520
504err_get:
505 regulator_bulk_free(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
506err: 521err:
507 kfree(wm8741); 522 kfree(wm8741);
508 return ret; 523 return ret;
@@ -510,10 +525,7 @@ err:
510 525
511static int wm8741_i2c_remove(struct i2c_client *client) 526static int wm8741_i2c_remove(struct i2c_client *client)
512{ 527{
513 struct wm8741_priv *wm8741 = i2c_get_clientdata(client);
514
515 snd_soc_unregister_codec(&client->dev); 528 snd_soc_unregister_codec(&client->dev);
516 regulator_bulk_free(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
517 kfree(i2c_get_clientdata(client)); 529 kfree(i2c_get_clientdata(client));
518 return 0; 530 return 0;
519} 531}
@@ -526,8 +538,9 @@ MODULE_DEVICE_TABLE(i2c, wm8741_i2c_id);
526 538
527static struct i2c_driver wm8741_i2c_driver = { 539static struct i2c_driver wm8741_i2c_driver = {
528 .driver = { 540 .driver = {
529 .name = "wm8741-codec", 541 .name = "wm8741",
530 .owner = THIS_MODULE, 542 .owner = THIS_MODULE,
543 .of_match_table = wm8741_of_match,
531 }, 544 },
532 .probe = wm8741_i2c_probe, 545 .probe = wm8741_i2c_probe,
533 .remove = wm8741_i2c_remove, 546 .remove = wm8741_i2c_remove,
@@ -535,6 +548,44 @@ static struct i2c_driver wm8741_i2c_driver = {
535}; 548};
536#endif 549#endif
537 550
551#if defined(CONFIG_SPI_MASTER)
552static int __devinit wm8741_spi_probe(struct spi_device *spi)
553{
554 struct wm8741_priv *wm8741;
555 int ret;
556
557 wm8741 = kzalloc(sizeof(struct wm8741_priv), GFP_KERNEL);
558 if (wm8741 == NULL)
559 return -ENOMEM;
560
561 wm8741->control_type = SND_SOC_SPI;
562 spi_set_drvdata(spi, wm8741);
563
564 ret = snd_soc_register_codec(&spi->dev,
565 &soc_codec_dev_wm8741, &wm8741_dai, 1);
566 if (ret < 0)
567 kfree(wm8741);
568 return ret;
569}
570
571static int __devexit wm8741_spi_remove(struct spi_device *spi)
572{
573 snd_soc_unregister_codec(&spi->dev);
574 kfree(spi_get_drvdata(spi));
575 return 0;
576}
577
578static struct spi_driver wm8741_spi_driver = {
579 .driver = {
580 .name = "wm8741",
581 .owner = THIS_MODULE,
582 .of_match_table = wm8741_of_match,
583 },
584 .probe = wm8741_spi_probe,
585 .remove = __devexit_p(wm8741_spi_remove),
586};
587#endif /* CONFIG_SPI_MASTER */
588
538static int __init wm8741_modinit(void) 589static int __init wm8741_modinit(void)
539{ 590{
540 int ret = 0; 591 int ret = 0;
@@ -544,6 +595,13 @@ static int __init wm8741_modinit(void)
544 if (ret != 0) 595 if (ret != 0)
545 pr_err("Failed to register WM8741 I2C driver: %d\n", ret); 596 pr_err("Failed to register WM8741 I2C driver: %d\n", ret);
546#endif 597#endif
598#if defined(CONFIG_SPI_MASTER)
599 ret = spi_register_driver(&wm8741_spi_driver);
600 if (ret != 0) {
601 printk(KERN_ERR "Failed to register wm8741 SPI driver: %d\n",
602 ret);
603 }
604#endif
547 605
548 return ret; 606 return ret;
549} 607}
@@ -551,6 +609,9 @@ module_init(wm8741_modinit);
551 609
552static void __exit wm8741_exit(void) 610static void __exit wm8741_exit(void)
553{ 611{
612#if defined(CONFIG_SPI_MASTER)
613 spi_unregister_driver(&wm8741_spi_driver);
614#endif
554#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 615#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
555 i2c_del_driver(&wm8741_i2c_driver); 616 i2c_del_driver(&wm8741_i2c_driver);
556#endif 617#endif
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index d0003cc3bcd..ca75a818070 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.c
@@ -21,6 +21,7 @@
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/spi/spi.h> 22#include <linux/spi/spi.h>
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/of_device.h>
24#include <sound/core.h> 25#include <sound/core.h>
25#include <sound/pcm.h> 26#include <sound/pcm.h>
26#include <sound/pcm_params.h> 27#include <sound/pcm_params.h>
@@ -615,6 +616,8 @@ static int wm8750_set_bias_level(struct snd_soc_codec *codec,
615 break; 616 break;
616 case SND_SOC_BIAS_STANDBY: 617 case SND_SOC_BIAS_STANDBY:
617 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { 618 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
619 snd_soc_cache_sync(codec);
620
618 /* Set VMID to 5k */ 621 /* Set VMID to 5k */
619 snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x01c1); 622 snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x01c1);
620 623
@@ -672,28 +675,14 @@ static int wm8750_suspend(struct snd_soc_codec *codec, pm_message_t state)
672 675
673static int wm8750_resume(struct snd_soc_codec *codec) 676static int wm8750_resume(struct snd_soc_codec *codec)
674{ 677{
675 int i;
676 u8 data[2];
677 u16 *cache = codec->reg_cache;
678
679 /* Sync reg_cache with the hardware */
680 for (i = 0; i < ARRAY_SIZE(wm8750_reg); i++) {
681 if (i == WM8750_RESET)
682 continue;
683 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
684 data[1] = cache[i] & 0x00ff;
685 codec->hw_write(codec->control_data, data, 2);
686 }
687
688 wm8750_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 678 wm8750_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
689
690 return 0; 679 return 0;
691} 680}
692 681
693static int wm8750_probe(struct snd_soc_codec *codec) 682static int wm8750_probe(struct snd_soc_codec *codec)
694{ 683{
695 struct wm8750_priv *wm8750 = snd_soc_codec_get_drvdata(codec); 684 struct wm8750_priv *wm8750 = snd_soc_codec_get_drvdata(codec);
696 int reg, ret; 685 int ret;
697 686
698 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8750->control_type); 687 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8750->control_type);
699 if (ret < 0) { 688 if (ret < 0) {
@@ -711,22 +700,14 @@ static int wm8750_probe(struct snd_soc_codec *codec)
711 wm8750_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 700 wm8750_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
712 701
713 /* set the update bits */ 702 /* set the update bits */
714 reg = snd_soc_read(codec, WM8750_LDAC); 703 snd_soc_update_bits(codec, WM8750_LDAC, 0x0100, 0x0100);
715 snd_soc_write(codec, WM8750_LDAC, reg | 0x0100); 704 snd_soc_update_bits(codec, WM8750_RDAC, 0x0100, 0x0100);
716 reg = snd_soc_read(codec, WM8750_RDAC); 705 snd_soc_update_bits(codec, WM8750_LOUT1V, 0x0100, 0x0100);
717 snd_soc_write(codec, WM8750_RDAC, reg | 0x0100); 706 snd_soc_update_bits(codec, WM8750_ROUT1V, 0x0100, 0x0100);
718 reg = snd_soc_read(codec, WM8750_LOUT1V); 707 snd_soc_update_bits(codec, WM8750_LOUT2V, 0x0100, 0x0100);
719 snd_soc_write(codec, WM8750_LOUT1V, reg | 0x0100); 708 snd_soc_update_bits(codec, WM8750_ROUT2V, 0x0100, 0x0100);
720 reg = snd_soc_read(codec, WM8750_ROUT1V); 709 snd_soc_update_bits(codec, WM8750_LINVOL, 0x0100, 0x0100);
721 snd_soc_write(codec, WM8750_ROUT1V, reg | 0x0100); 710 snd_soc_update_bits(codec, WM8750_RINVOL, 0x0100, 0x0100);
722 reg = snd_soc_read(codec, WM8750_LOUT2V);
723 snd_soc_write(codec, WM8750_LOUT2V, reg | 0x0100);
724 reg = snd_soc_read(codec, WM8750_ROUT2V);
725 snd_soc_write(codec, WM8750_ROUT2V, reg | 0x0100);
726 reg = snd_soc_read(codec, WM8750_LINVOL);
727 snd_soc_write(codec, WM8750_LINVOL, reg | 0x0100);
728 reg = snd_soc_read(codec, WM8750_RINVOL);
729 snd_soc_write(codec, WM8750_RINVOL, reg | 0x0100);
730 711
731 snd_soc_add_controls(codec, wm8750_snd_controls, 712 snd_soc_add_controls(codec, wm8750_snd_controls,
732 ARRAY_SIZE(wm8750_snd_controls)); 713 ARRAY_SIZE(wm8750_snd_controls));
@@ -751,6 +732,13 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8750 = {
751 .reg_cache_default = wm8750_reg, 732 .reg_cache_default = wm8750_reg,
752}; 733};
753 734
735static const struct of_device_id wm8750_of_match[] = {
736 { .compatible = "wlf,wm8750", },
737 { .compatible = "wlf,wm8987", },
738 { }
739};
740MODULE_DEVICE_TABLE(of, wm8750_of_match);
741
754#if defined(CONFIG_SPI_MASTER) 742#if defined(CONFIG_SPI_MASTER)
755static int __devinit wm8750_spi_probe(struct spi_device *spi) 743static int __devinit wm8750_spi_probe(struct spi_device *spi)
756{ 744{
@@ -787,8 +775,9 @@ MODULE_DEVICE_TABLE(spi, wm8750_spi_ids);
787 775
788static struct spi_driver wm8750_spi_driver = { 776static struct spi_driver wm8750_spi_driver = {
789 .driver = { 777 .driver = {
790 .name = "wm8750-codec", 778 .name = "wm8750",
791 .owner = THIS_MODULE, 779 .owner = THIS_MODULE,
780 .of_match_table = wm8750_of_match,
792 }, 781 },
793 .id_table = wm8750_spi_ids, 782 .id_table = wm8750_spi_ids,
794 .probe = wm8750_spi_probe, 783 .probe = wm8750_spi_probe,
@@ -833,8 +822,9 @@ MODULE_DEVICE_TABLE(i2c, wm8750_i2c_id);
833 822
834static struct i2c_driver wm8750_i2c_driver = { 823static struct i2c_driver wm8750_i2c_driver = {
835 .driver = { 824 .driver = {
836 .name = "wm8750-codec", 825 .name = "wm8750",
837 .owner = THIS_MODULE, 826 .owner = THIS_MODULE,
827 .of_match_table = wm8750_of_match,
838 }, 828 },
839 .probe = wm8750_i2c_probe, 829 .probe = wm8750_i2c_probe,
840 .remove = __devexit_p(wm8750_i2c_remove), 830 .remove = __devexit_p(wm8750_i2c_remove),
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index aa091a0d818..a9504710bb6 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -38,6 +38,7 @@
38#include <linux/delay.h> 38#include <linux/delay.h>
39#include <linux/pm.h> 39#include <linux/pm.h>
40#include <linux/i2c.h> 40#include <linux/i2c.h>
41#include <linux/of_device.h>
41#include <linux/platform_device.h> 42#include <linux/platform_device.h>
42#include <linux/spi/spi.h> 43#include <linux/spi/spi.h>
43#include <linux/slab.h> 44#include <linux/slab.h>
@@ -1490,6 +1491,12 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8753 = {
1490 .reg_cache_default = wm8753_reg, 1491 .reg_cache_default = wm8753_reg,
1491}; 1492};
1492 1493
1494static const struct of_device_id wm8753_of_match[] = {
1495 { .compatible = "wlf,wm8753", },
1496 { }
1497};
1498MODULE_DEVICE_TABLE(of, wm8753_of_match);
1499
1493#if defined(CONFIG_SPI_MASTER) 1500#if defined(CONFIG_SPI_MASTER)
1494static int __devinit wm8753_spi_probe(struct spi_device *spi) 1501static int __devinit wm8753_spi_probe(struct spi_device *spi)
1495{ 1502{
@@ -1519,8 +1526,9 @@ static int __devexit wm8753_spi_remove(struct spi_device *spi)
1519 1526
1520static struct spi_driver wm8753_spi_driver = { 1527static struct spi_driver wm8753_spi_driver = {
1521 .driver = { 1528 .driver = {
1522 .name = "wm8753-codec", 1529 .name = "wm8753",
1523 .owner = THIS_MODULE, 1530 .owner = THIS_MODULE,
1531 .of_match_table = wm8753_of_match,
1524 }, 1532 },
1525 .probe = wm8753_spi_probe, 1533 .probe = wm8753_spi_probe,
1526 .remove = __devexit_p(wm8753_spi_remove), 1534 .remove = __devexit_p(wm8753_spi_remove),
@@ -1563,8 +1571,9 @@ MODULE_DEVICE_TABLE(i2c, wm8753_i2c_id);
1563 1571
1564static struct i2c_driver wm8753_i2c_driver = { 1572static struct i2c_driver wm8753_i2c_driver = {
1565 .driver = { 1573 .driver = {
1566 .name = "wm8753-codec", 1574 .name = "wm8753",
1567 .owner = THIS_MODULE, 1575 .owner = THIS_MODULE,
1576 .of_match_table = wm8753_of_match,
1568 }, 1577 },
1569 .probe = wm8753_i2c_probe, 1578 .probe = wm8753_i2c_probe,
1570 .remove = __devexit_p(wm8753_i2c_remove), 1579 .remove = __devexit_p(wm8753_i2c_remove),
diff --git a/sound/soc/codecs/wm8770.c b/sound/soc/codecs/wm8770.c
index 19b92baa9e8..aa05e6507f8 100644
--- a/sound/soc/codecs/wm8770.c
+++ b/sound/soc/codecs/wm8770.c
@@ -14,6 +14,7 @@
14#include <linux/moduleparam.h> 14#include <linux/moduleparam.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/delay.h> 16#include <linux/delay.h>
17#include <linux/of_device.h>
17#include <linux/pm.h> 18#include <linux/pm.h>
18#include <linux/platform_device.h> 19#include <linux/platform_device.h>
19#include <linux/spi/spi.h> 20#include <linux/spi/spi.h>
@@ -684,6 +685,12 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8770 = {
684 .reg_cache_default = wm8770_reg_defs 685 .reg_cache_default = wm8770_reg_defs
685}; 686};
686 687
688static const struct of_device_id wm8770_of_match[] = {
689 { .compatible = "wlf,wm8770", },
690 { }
691};
692MODULE_DEVICE_TABLE(of, wm8770_of_match);
693
687#if defined(CONFIG_SPI_MASTER) 694#if defined(CONFIG_SPI_MASTER)
688static int __devinit wm8770_spi_probe(struct spi_device *spi) 695static int __devinit wm8770_spi_probe(struct spi_device *spi)
689{ 696{
@@ -715,6 +722,7 @@ static struct spi_driver wm8770_spi_driver = {
715 .driver = { 722 .driver = {
716 .name = "wm8770", 723 .name = "wm8770",
717 .owner = THIS_MODULE, 724 .owner = THIS_MODULE,
725 .of_match_table = wm8770_of_match,
718 }, 726 },
719 .probe = wm8770_spi_probe, 727 .probe = wm8770_spi_probe,
720 .remove = __devexit_p(wm8770_spi_remove) 728 .remove = __devexit_p(wm8770_spi_remove)
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c
index 8e7953b1b79..bfdc52370ad 100644
--- a/sound/soc/codecs/wm8776.c
+++ b/sound/soc/codecs/wm8776.c
@@ -18,6 +18,7 @@
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/pm.h> 19#include <linux/pm.h>
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include <linux/of_device.h>
21#include <linux/platform_device.h> 22#include <linux/platform_device.h>
22#include <linux/spi/spi.h> 23#include <linux/spi/spi.h>
23#include <linux/slab.h> 24#include <linux/slab.h>
@@ -215,8 +216,6 @@ static int wm8776_hw_params(struct snd_pcm_substream *substream,
215 int ratio_shift, master; 216 int ratio_shift, master;
216 int i; 217 int i;
217 218
218 iface = 0;
219
220 switch (dai->driver->id) { 219 switch (dai->driver->id) {
221 case WM8776_DAI_DAC: 220 case WM8776_DAI_DAC:
222 iface_reg = WM8776_DACIFCTRL; 221 iface_reg = WM8776_DACIFCTRL;
@@ -232,20 +231,23 @@ static int wm8776_hw_params(struct snd_pcm_substream *substream,
232 return -EINVAL; 231 return -EINVAL;
233 } 232 }
234 233
235
236 /* Set word length */ 234 /* Set word length */
237 switch (params_format(params)) { 235 switch (snd_pcm_format_width(params_format(params))) {
238 case SNDRV_PCM_FORMAT_S16_LE: 236 case 16:
239 break; 237 iface = 0;
240 case SNDRV_PCM_FORMAT_S20_3LE: 238 case 20:
241 iface |= 0x10; 239 iface = 0x10;
242 break; 240 break;
243 case SNDRV_PCM_FORMAT_S24_LE: 241 case 24:
244 iface |= 0x20; 242 iface = 0x20;
245 break; 243 break;
246 case SNDRV_PCM_FORMAT_S32_LE: 244 case 32:
247 iface |= 0x30; 245 iface = 0x30;
248 break; 246 break;
247 default:
248 dev_err(codec->dev, "Unsupported sample size: %i\n",
249 snd_pcm_format_width(params_format(params)));
250 return -EINVAL;
249 } 251 }
250 252
251 /* Only need to set MCLK/LRCLK ratio if we're master */ 253 /* Only need to set MCLK/LRCLK ratio if we're master */
@@ -306,6 +308,8 @@ static int wm8776_set_bias_level(struct snd_soc_codec *codec,
306 break; 308 break;
307 case SND_SOC_BIAS_STANDBY: 309 case SND_SOC_BIAS_STANDBY:
308 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { 310 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
311 snd_soc_cache_sync(codec);
312
309 /* Disable the global powerdown; DAPM does the rest */ 313 /* Disable the global powerdown; DAPM does the rest */
310 snd_soc_update_bits(codec, WM8776_PWRDOWN, 1, 0); 314 snd_soc_update_bits(codec, WM8776_PWRDOWN, 1, 0);
311 } 315 }
@@ -320,11 +324,6 @@ static int wm8776_set_bias_level(struct snd_soc_codec *codec,
320 return 0; 324 return 0;
321} 325}
322 326
323#define WM8776_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
324 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
325 SNDRV_PCM_RATE_96000)
326
327
328#define WM8776_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 327#define WM8776_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
329 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) 328 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
330 329
@@ -349,7 +348,9 @@ static struct snd_soc_dai_driver wm8776_dai[] = {
349 .stream_name = "Playback", 348 .stream_name = "Playback",
350 .channels_min = 2, 349 .channels_min = 2,
351 .channels_max = 2, 350 .channels_max = 2,
352 .rates = WM8776_RATES, 351 .rates = SNDRV_PCM_RATE_CONTINUOUS,
352 .rate_min = 32000,
353 .rate_max = 192000,
353 .formats = WM8776_FORMATS, 354 .formats = WM8776_FORMATS,
354 }, 355 },
355 .ops = &wm8776_dac_ops, 356 .ops = &wm8776_dac_ops,
@@ -361,7 +362,9 @@ static struct snd_soc_dai_driver wm8776_dai[] = {
361 .stream_name = "Capture", 362 .stream_name = "Capture",
362 .channels_min = 2, 363 .channels_min = 2,
363 .channels_max = 2, 364 .channels_max = 2,
364 .rates = WM8776_RATES, 365 .rates = SNDRV_PCM_RATE_CONTINUOUS,
366 .rate_min = 32000,
367 .rate_max = 96000,
365 .formats = WM8776_FORMATS, 368 .formats = WM8776_FORMATS,
366 }, 369 },
367 .ops = &wm8776_adc_ops, 370 .ops = &wm8776_adc_ops,
@@ -378,21 +381,7 @@ static int wm8776_suspend(struct snd_soc_codec *codec, pm_message_t state)
378 381
379static int wm8776_resume(struct snd_soc_codec *codec) 382static int wm8776_resume(struct snd_soc_codec *codec)
380{ 383{
381 int i;
382 u8 data[2];
383 u16 *cache = codec->reg_cache;
384
385 /* Sync reg_cache with the hardware */
386 for (i = 0; i < ARRAY_SIZE(wm8776_reg); i++) {
387 if (cache[i] == wm8776_reg[i])
388 continue;
389 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
390 data[1] = cache[i] & 0x00ff;
391 codec->hw_write(codec->control_data, data, 2);
392 }
393
394 wm8776_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 384 wm8776_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
395
396 return 0; 385 return 0;
397} 386}
398#else 387#else
@@ -452,6 +441,12 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8776 = {
452 .reg_cache_default = wm8776_reg, 441 .reg_cache_default = wm8776_reg,
453}; 442};
454 443
444static const struct of_device_id wm8776_of_match[] = {
445 { .compatible = "wlf,wm8776", },
446 { }
447};
448MODULE_DEVICE_TABLE(of, wm8776_of_match);
449
455#if defined(CONFIG_SPI_MASTER) 450#if defined(CONFIG_SPI_MASTER)
456static int __devinit wm8776_spi_probe(struct spi_device *spi) 451static int __devinit wm8776_spi_probe(struct spi_device *spi)
457{ 452{
@@ -481,8 +476,9 @@ static int __devexit wm8776_spi_remove(struct spi_device *spi)
481 476
482static struct spi_driver wm8776_spi_driver = { 477static struct spi_driver wm8776_spi_driver = {
483 .driver = { 478 .driver = {
484 .name = "wm8776-codec", 479 .name = "wm8776",
485 .owner = THIS_MODULE, 480 .owner = THIS_MODULE,
481 .of_match_table = wm8776_of_match,
486 }, 482 },
487 .probe = wm8776_spi_probe, 483 .probe = wm8776_spi_probe,
488 .remove = __devexit_p(wm8776_spi_remove), 484 .remove = __devexit_p(wm8776_spi_remove),
@@ -525,8 +521,9 @@ MODULE_DEVICE_TABLE(i2c, wm8776_i2c_id);
525 521
526static struct i2c_driver wm8776_i2c_driver = { 522static struct i2c_driver wm8776_i2c_driver = {
527 .driver = { 523 .driver = {
528 .name = "wm8776-codec", 524 .name = "wm8776",
529 .owner = THIS_MODULE, 525 .owner = THIS_MODULE,
526 .of_match_table = wm8776_of_match,
530 }, 527 },
531 .probe = wm8776_i2c_probe, 528 .probe = wm8776_i2c_probe,
532 .remove = __devexit_p(wm8776_i2c_remove), 529 .remove = __devexit_p(wm8776_i2c_remove),
diff --git a/sound/soc/codecs/wm8782.c b/sound/soc/codecs/wm8782.c
index a2a09f85ea9..f2ced71328b 100644
--- a/sound/soc/codecs/wm8782.c
+++ b/sound/soc/codecs/wm8782.c
@@ -60,7 +60,7 @@ static struct platform_driver wm8782_codec_driver = {
60 .owner = THIS_MODULE, 60 .owner = THIS_MODULE,
61 }, 61 },
62 .probe = wm8782_probe, 62 .probe = wm8782_probe,
63 .remove = wm8782_remove, 63 .remove = __devexit_p(wm8782_remove),
64}; 64};
65 65
66static int __init wm8782_init(void) 66static int __init wm8782_init(void)
diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c
index 9a5e67c5a6b..9ee072b8597 100644
--- a/sound/soc/codecs/wm8804.c
+++ b/sound/soc/codecs/wm8804.c
@@ -16,6 +16,7 @@
16#include <linux/delay.h> 16#include <linux/delay.h>
17#include <linux/pm.h> 17#include <linux/pm.h>
18#include <linux/i2c.h> 18#include <linux/i2c.h>
19#include <linux/of_device.h>
19#include <linux/spi/spi.h> 20#include <linux/spi/spi.h>
20#include <linux/regulator/consumer.h> 21#include <linux/regulator/consumer.h>
21#include <linux/slab.h> 22#include <linux/slab.h>
@@ -717,6 +718,12 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8804 = {
717 .volatile_register = wm8804_volatile 718 .volatile_register = wm8804_volatile
718}; 719};
719 720
721static const struct of_device_id wm8804_of_match[] = {
722 { .compatible = "wlf,wm8804", },
723 { }
724};
725MODULE_DEVICE_TABLE(of, wm8804_of_match);
726
720#if defined(CONFIG_SPI_MASTER) 727#if defined(CONFIG_SPI_MASTER)
721static int __devinit wm8804_spi_probe(struct spi_device *spi) 728static int __devinit wm8804_spi_probe(struct spi_device *spi)
722{ 729{
@@ -748,6 +755,7 @@ static struct spi_driver wm8804_spi_driver = {
748 .driver = { 755 .driver = {
749 .name = "wm8804", 756 .name = "wm8804",
750 .owner = THIS_MODULE, 757 .owner = THIS_MODULE,
758 .of_match_table = wm8804_of_match,
751 }, 759 },
752 .probe = wm8804_spi_probe, 760 .probe = wm8804_spi_probe,
753 .remove = __devexit_p(wm8804_spi_remove) 761 .remove = __devexit_p(wm8804_spi_remove)
@@ -792,6 +800,7 @@ static struct i2c_driver wm8804_i2c_driver = {
792 .driver = { 800 .driver = {
793 .name = "wm8804", 801 .name = "wm8804",
794 .owner = THIS_MODULE, 802 .owner = THIS_MODULE,
803 .of_match_table = wm8804_of_match,
795 }, 804 },
796 .probe = wm8804_i2c_probe, 805 .probe = wm8804_i2c_probe,
797 .remove = __devexit_p(wm8804_i2c_remove), 806 .remove = __devexit_p(wm8804_i2c_remove),
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c
index 082040eda8a..3d0dc1591ec 100644
--- a/sound/soc/codecs/wm8900.c
+++ b/sound/soc/codecs/wm8900.c
@@ -110,8 +110,8 @@
110 110
111#define WM8900_REG_CLOCKING1_BCLK_DIR 0x1 111#define WM8900_REG_CLOCKING1_BCLK_DIR 0x1
112#define WM8900_REG_CLOCKING1_MCLK_SRC 0x100 112#define WM8900_REG_CLOCKING1_MCLK_SRC 0x100
113#define WM8900_REG_CLOCKING1_BCLK_MASK (~0x01e) 113#define WM8900_REG_CLOCKING1_BCLK_MASK 0x01e
114#define WM8900_REG_CLOCKING1_OPCLK_MASK (~0x7000) 114#define WM8900_REG_CLOCKING1_OPCLK_MASK 0x7000
115 115
116#define WM8900_REG_CLOCKING2_ADC_CLKDIV 0xe0 116#define WM8900_REG_CLOCKING2_ADC_CLKDIV 0xe0
117#define WM8900_REG_CLOCKING2_DAC_CLKDIV 0x1c 117#define WM8900_REG_CLOCKING2_DAC_CLKDIV 0x1c
@@ -135,7 +135,7 @@
135#define WM8900_REG_HPCTL1_HP_SHORT 0x08 135#define WM8900_REG_HPCTL1_HP_SHORT 0x08
136#define WM8900_REG_HPCTL1_HP_SHORT2 0x04 136#define WM8900_REG_HPCTL1_HP_SHORT2 0x04
137 137
138#define WM8900_LRC_MASK 0xfc00 138#define WM8900_LRC_MASK 0x03ff
139 139
140struct wm8900_priv { 140struct wm8900_priv {
141 enum snd_soc_control_type control_type; 141 enum snd_soc_control_type control_type;
@@ -742,26 +742,20 @@ static int wm8900_set_fll(struct snd_soc_codec *codec,
742{ 742{
743 struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec); 743 struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec);
744 struct _fll_div fll_div; 744 struct _fll_div fll_div;
745 unsigned int reg;
746 745
747 if (wm8900->fll_in == freq_in && wm8900->fll_out == freq_out) 746 if (wm8900->fll_in == freq_in && wm8900->fll_out == freq_out)
748 return 0; 747 return 0;
749 748
750 /* The digital side should be disabled during any change. */ 749 /* The digital side should be disabled during any change. */
751 reg = snd_soc_read(codec, WM8900_REG_POWER1); 750 snd_soc_update_bits(codec, WM8900_REG_POWER1,
752 snd_soc_write(codec, WM8900_REG_POWER1, 751 WM8900_REG_POWER1_FLL_ENA, 0);
753 reg & (~WM8900_REG_POWER1_FLL_ENA));
754 752
755 /* Disable the FLL? */ 753 /* Disable the FLL? */
756 if (!freq_in || !freq_out) { 754 if (!freq_in || !freq_out) {
757 reg = snd_soc_read(codec, WM8900_REG_CLOCKING1); 755 snd_soc_update_bits(codec, WM8900_REG_CLOCKING1,
758 snd_soc_write(codec, WM8900_REG_CLOCKING1, 756 WM8900_REG_CLOCKING1_MCLK_SRC, 0);
759 reg & (~WM8900_REG_CLOCKING1_MCLK_SRC)); 757 snd_soc_update_bits(codec, WM8900_REG_FLLCTL1,
760 758 WM8900_REG_FLLCTL1_OSC_ENA, 0);
761 reg = snd_soc_read(codec, WM8900_REG_FLLCTL1);
762 snd_soc_write(codec, WM8900_REG_FLLCTL1,
763 reg & (~WM8900_REG_FLLCTL1_OSC_ENA));
764
765 wm8900->fll_in = freq_in; 759 wm8900->fll_in = freq_in;
766 wm8900->fll_out = freq_out; 760 wm8900->fll_out = freq_out;
767 761
@@ -796,15 +790,14 @@ static int wm8900_set_fll(struct snd_soc_codec *codec,
796 else 790 else
797 snd_soc_write(codec, WM8900_REG_FLLCTL6, 0); 791 snd_soc_write(codec, WM8900_REG_FLLCTL6, 0);
798 792
799 reg = snd_soc_read(codec, WM8900_REG_POWER1); 793 snd_soc_update_bits(codec, WM8900_REG_POWER1,
800 snd_soc_write(codec, WM8900_REG_POWER1, 794 WM8900_REG_POWER1_FLL_ENA,
801 reg | WM8900_REG_POWER1_FLL_ENA); 795 WM8900_REG_POWER1_FLL_ENA);
802 796
803reenable: 797reenable:
804 reg = snd_soc_read(codec, WM8900_REG_CLOCKING1); 798 snd_soc_update_bits(codec, WM8900_REG_CLOCKING1,
805 snd_soc_write(codec, WM8900_REG_CLOCKING1, 799 WM8900_REG_CLOCKING1_MCLK_SRC,
806 reg | WM8900_REG_CLOCKING1_MCLK_SRC); 800 WM8900_REG_CLOCKING1_MCLK_SRC);
807
808 return 0; 801 return 0;
809} 802}
810 803
@@ -818,43 +811,35 @@ static int wm8900_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
818 int div_id, int div) 811 int div_id, int div)
819{ 812{
820 struct snd_soc_codec *codec = codec_dai->codec; 813 struct snd_soc_codec *codec = codec_dai->codec;
821 unsigned int reg;
822 814
823 switch (div_id) { 815 switch (div_id) {
824 case WM8900_BCLK_DIV: 816 case WM8900_BCLK_DIV:
825 reg = snd_soc_read(codec, WM8900_REG_CLOCKING1); 817 snd_soc_update_bits(codec, WM8900_REG_CLOCKING1,
826 snd_soc_write(codec, WM8900_REG_CLOCKING1, 818 WM8900_REG_CLOCKING1_BCLK_MASK, div);
827 div | (reg & WM8900_REG_CLOCKING1_BCLK_MASK));
828 break; 819 break;
829 case WM8900_OPCLK_DIV: 820 case WM8900_OPCLK_DIV:
830 reg = snd_soc_read(codec, WM8900_REG_CLOCKING1); 821 snd_soc_update_bits(codec, WM8900_REG_CLOCKING1,
831 snd_soc_write(codec, WM8900_REG_CLOCKING1, 822 WM8900_REG_CLOCKING1_OPCLK_MASK, div);
832 div | (reg & WM8900_REG_CLOCKING1_OPCLK_MASK));
833 break; 823 break;
834 case WM8900_DAC_LRCLK: 824 case WM8900_DAC_LRCLK:
835 reg = snd_soc_read(codec, WM8900_REG_AUDIO4); 825 snd_soc_update_bits(codec, WM8900_REG_AUDIO4,
836 snd_soc_write(codec, WM8900_REG_AUDIO4, 826 WM8900_LRC_MASK, div);
837 div | (reg & WM8900_LRC_MASK));
838 break; 827 break;
839 case WM8900_ADC_LRCLK: 828 case WM8900_ADC_LRCLK:
840 reg = snd_soc_read(codec, WM8900_REG_AUDIO3); 829 snd_soc_update_bits(codec, WM8900_REG_AUDIO3,
841 snd_soc_write(codec, WM8900_REG_AUDIO3, 830 WM8900_LRC_MASK, div);
842 div | (reg & WM8900_LRC_MASK));
843 break; 831 break;
844 case WM8900_DAC_CLKDIV: 832 case WM8900_DAC_CLKDIV:
845 reg = snd_soc_read(codec, WM8900_REG_CLOCKING2); 833 snd_soc_update_bits(codec, WM8900_REG_CLOCKING2,
846 snd_soc_write(codec, WM8900_REG_CLOCKING2, 834 WM8900_REG_CLOCKING2_DAC_CLKDIV, div);
847 div | (reg & WM8900_REG_CLOCKING2_DAC_CLKDIV));
848 break; 835 break;
849 case WM8900_ADC_CLKDIV: 836 case WM8900_ADC_CLKDIV:
850 reg = snd_soc_read(codec, WM8900_REG_CLOCKING2); 837 snd_soc_update_bits(codec, WM8900_REG_CLOCKING2,
851 snd_soc_write(codec, WM8900_REG_CLOCKING2, 838 WM8900_REG_CLOCKING2_ADC_CLKDIV, div);
852 div | (reg & WM8900_REG_CLOCKING2_ADC_CLKDIV));
853 break; 839 break;
854 case WM8900_LRCLK_MODE: 840 case WM8900_LRCLK_MODE:
855 reg = snd_soc_read(codec, WM8900_REG_DACCTRL); 841 snd_soc_update_bits(codec, WM8900_REG_DACCTRL,
856 snd_soc_write(codec, WM8900_REG_DACCTRL, 842 WM8900_REG_DACCTRL_AIF_LRCLKRATE, div);
857 div | (reg & WM8900_REG_DACCTRL_AIF_LRCLKRATE));
858 break; 843 break;
859 default: 844 default:
860 return -EINVAL; 845 return -EINVAL;
@@ -1037,12 +1022,12 @@ static int wm8900_set_bias_level(struct snd_soc_codec *codec,
1037 switch (level) { 1022 switch (level) {
1038 case SND_SOC_BIAS_ON: 1023 case SND_SOC_BIAS_ON:
1039 /* Enable thermal shutdown */ 1024 /* Enable thermal shutdown */
1040 reg = snd_soc_read(codec, WM8900_REG_GPIO); 1025 snd_soc_update_bits(codec, WM8900_REG_GPIO,
1041 snd_soc_write(codec, WM8900_REG_GPIO, 1026 WM8900_REG_GPIO_TEMP_ENA,
1042 reg | WM8900_REG_GPIO_TEMP_ENA); 1027 WM8900_REG_GPIO_TEMP_ENA);
1043 reg = snd_soc_read(codec, WM8900_REG_ADDCTL); 1028 snd_soc_update_bits(codec, WM8900_REG_ADDCTL,
1044 snd_soc_write(codec, WM8900_REG_ADDCTL, 1029 WM8900_REG_ADDCTL_TEMP_SD,
1045 reg | WM8900_REG_ADDCTL_TEMP_SD); 1030 WM8900_REG_ADDCTL_TEMP_SD);
1046 break; 1031 break;
1047 1032
1048 case SND_SOC_BIAS_PREPARE: 1033 case SND_SOC_BIAS_PREPARE:
@@ -1205,26 +1190,16 @@ static int wm8900_probe(struct snd_soc_codec *codec)
1205 wm8900_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1190 wm8900_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1206 1191
1207 /* Latch the volume update bits */ 1192 /* Latch the volume update bits */
1208 snd_soc_write(codec, WM8900_REG_LINVOL, 1193 snd_soc_update_bits(codec, WM8900_REG_LINVOL, 0x100, 0x100);
1209 snd_soc_read(codec, WM8900_REG_LINVOL) | 0x100); 1194 snd_soc_update_bits(codec, WM8900_REG_RINVOL, 0x100, 0x100);
1210 snd_soc_write(codec, WM8900_REG_RINVOL, 1195 snd_soc_update_bits(codec, WM8900_REG_LOUT1CTL, 0x100, 0x100);
1211 snd_soc_read(codec, WM8900_REG_RINVOL) | 0x100); 1196 snd_soc_update_bits(codec, WM8900_REG_ROUT1CTL, 0x100, 0x100);
1212 snd_soc_write(codec, WM8900_REG_LOUT1CTL, 1197 snd_soc_update_bits(codec, WM8900_REG_LOUT2CTL, 0x100, 0x100);
1213 snd_soc_read(codec, WM8900_REG_LOUT1CTL) | 0x100); 1198 snd_soc_update_bits(codec, WM8900_REG_ROUT2CTL, 0x100, 0x100);
1214 snd_soc_write(codec, WM8900_REG_ROUT1CTL, 1199 snd_soc_update_bits(codec, WM8900_REG_LDAC_DV, 0x100, 0x100);
1215 snd_soc_read(codec, WM8900_REG_ROUT1CTL) | 0x100); 1200 snd_soc_update_bits(codec, WM8900_REG_RDAC_DV, 0x100, 0x100);
1216 snd_soc_write(codec, WM8900_REG_LOUT2CTL, 1201 snd_soc_update_bits(codec, WM8900_REG_LADC_DV, 0x100, 0x100);
1217 snd_soc_read(codec, WM8900_REG_LOUT2CTL) | 0x100); 1202 snd_soc_update_bits(codec, WM8900_REG_RADC_DV, 0x100, 0x100);
1218 snd_soc_write(codec, WM8900_REG_ROUT2CTL,
1219 snd_soc_read(codec, WM8900_REG_ROUT2CTL) | 0x100);
1220 snd_soc_write(codec, WM8900_REG_LDAC_DV,
1221 snd_soc_read(codec, WM8900_REG_LDAC_DV) | 0x100);
1222 snd_soc_write(codec, WM8900_REG_RDAC_DV,
1223 snd_soc_read(codec, WM8900_REG_RDAC_DV) | 0x100);
1224 snd_soc_write(codec, WM8900_REG_LADC_DV,
1225 snd_soc_read(codec, WM8900_REG_LADC_DV) | 0x100);
1226 snd_soc_write(codec, WM8900_REG_RADC_DV,
1227 snd_soc_read(codec, WM8900_REG_RADC_DV) | 0x100);
1228 1203
1229 /* Set the DAC and mixer output bias */ 1204 /* Set the DAC and mixer output bias */
1230 snd_soc_write(codec, WM8900_REG_OUTBIASCTL, 0x81); 1205 snd_soc_write(codec, WM8900_REG_OUTBIASCTL, 0x81);
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index b085575d4aa..9fc8f4c0a9a 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -50,7 +50,6 @@ static const char *wm8904_supply_names[WM8904_NUM_SUPPLIES] = {
50struct wm8904_priv { 50struct wm8904_priv {
51 51
52 enum wm8904_type devtype; 52 enum wm8904_type devtype;
53 void *control_data;
54 53
55 struct regulator_bulk_data supplies[WM8904_NUM_SUPPLIES]; 54 struct regulator_bulk_data supplies[WM8904_NUM_SUPPLIES];
56 55
@@ -2540,7 +2539,6 @@ static __devinit int wm8904_i2c_probe(struct i2c_client *i2c,
2540 2539
2541 wm8904->devtype = id->driver_data; 2540 wm8904->devtype = id->driver_data;
2542 i2c_set_clientdata(i2c, wm8904); 2541 i2c_set_clientdata(i2c, wm8904);
2543 wm8904->control_data = i2c;
2544 wm8904->pdata = i2c->dev.platform_data; 2542 wm8904->pdata = i2c->dev.platform_data;
2545 2543
2546 ret = snd_soc_register_codec(&i2c->dev, 2544 ret = snd_soc_register_codec(&i2c->dev,
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
index 056daa0010f..dc5cb315085 100644
--- a/sound/soc/codecs/wm8940.c
+++ b/sound/soc/codecs/wm8940.c
@@ -43,9 +43,19 @@
43struct wm8940_priv { 43struct wm8940_priv {
44 unsigned int sysclk; 44 unsigned int sysclk;
45 enum snd_soc_control_type control_type; 45 enum snd_soc_control_type control_type;
46 void *control_data;
47}; 46};
48 47
48static int wm8940_volatile_register(struct snd_soc_codec *codec,
49 unsigned int reg)
50{
51 switch (reg) {
52 case WM8940_SOFTRESET:
53 return 1;
54 default:
55 return 0;
56 }
57}
58
49static u16 wm8940_reg_defaults[] = { 59static u16 wm8940_reg_defaults[] = {
50 0x8940, /* Soft Reset */ 60 0x8940, /* Soft Reset */
51 0x0000, /* Power 1 */ 61 0x0000, /* Power 1 */
@@ -460,6 +470,14 @@ static int wm8940_set_bias_level(struct snd_soc_codec *codec,
460 ret = snd_soc_write(codec, WM8940_POWER1, pwr_reg | 0x1); 470 ret = snd_soc_write(codec, WM8940_POWER1, pwr_reg | 0x1);
461 break; 471 break;
462 case SND_SOC_BIAS_STANDBY: 472 case SND_SOC_BIAS_STANDBY:
473 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
474 ret = snd_soc_cache_sync(codec);
475 if (ret < 0) {
476 dev_err(codec->dev, "Failed to sync cache: %d\n", ret);
477 return ret;
478 }
479 }
480
463 /* ensure bufioen and biasen */ 481 /* ensure bufioen and biasen */
464 pwr_reg |= (1 << 2) | (1 << 3); 482 pwr_reg |= (1 << 2) | (1 << 3);
465 /* set vmid to 300k for standby */ 483 /* set vmid to 300k for standby */
@@ -470,6 +488,8 @@ static int wm8940_set_bias_level(struct snd_soc_codec *codec,
470 break; 488 break;
471 } 489 }
472 490
491 codec->dapm.bias_level = level;
492
473 return ret; 493 return ret;
474} 494}
475 495
@@ -660,30 +680,8 @@ static int wm8940_suspend(struct snd_soc_codec *codec, pm_message_t state)
660 680
661static int wm8940_resume(struct snd_soc_codec *codec) 681static int wm8940_resume(struct snd_soc_codec *codec)
662{ 682{
663 int i; 683 wm8940_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
664 int ret; 684 return 0;
665 u8 data[3];
666 u16 *cache = codec->reg_cache;
667
668 /* Sync reg_cache with the hardware
669 * Could use auto incremented writes to speed this up
670 */
671 for (i = 0; i < ARRAY_SIZE(wm8940_reg_defaults); i++) {
672 data[0] = i;
673 data[1] = (cache[i] & 0xFF00) >> 8;
674 data[2] = cache[i] & 0x00FF;
675 ret = codec->hw_write(codec->control_data, data, 3);
676 if (ret < 0)
677 goto error_ret;
678 else if (ret != 3) {
679 ret = -EIO;
680 goto error_ret;
681 }
682 }
683 ret = wm8940_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
684
685error_ret:
686 return ret;
687} 685}
688 686
689static int wm8940_probe(struct snd_soc_codec *codec) 687static int wm8940_probe(struct snd_soc_codec *codec)
@@ -693,7 +691,6 @@ static int wm8940_probe(struct snd_soc_codec *codec)
693 int ret; 691 int ret;
694 u16 reg; 692 u16 reg;
695 693
696 codec->control_data = wm8940->control_data;
697 ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm8940->control_type); 694 ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm8940->control_type);
698 if (ret < 0) { 695 if (ret < 0) {
699 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 696 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
@@ -744,6 +741,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8940 = {
744 .reg_cache_size = ARRAY_SIZE(wm8940_reg_defaults), 741 .reg_cache_size = ARRAY_SIZE(wm8940_reg_defaults),
745 .reg_word_size = sizeof(u16), 742 .reg_word_size = sizeof(u16),
746 .reg_cache_default = wm8940_reg_defaults, 743 .reg_cache_default = wm8940_reg_defaults,
744 .volatile_register = wm8940_volatile_register,
747}; 745};
748 746
749#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 747#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
@@ -758,7 +756,6 @@ static __devinit int wm8940_i2c_probe(struct i2c_client *i2c,
758 return -ENOMEM; 756 return -ENOMEM;
759 757
760 i2c_set_clientdata(i2c, wm8940); 758 i2c_set_clientdata(i2c, wm8940);
761 wm8940->control_data = i2c;
762 wm8940->control_type = SND_SOC_I2C; 759 wm8940->control_type = SND_SOC_I2C;
763 760
764 ret = snd_soc_register_codec(&i2c->dev, 761 ret = snd_soc_register_codec(&i2c->dev,
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index 4393394b7bc..2df253c1856 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -72,7 +72,6 @@ static const u16 wm8960_reg[WM8960_CACHEREGNUM] = {
72 72
73struct wm8960_priv { 73struct wm8960_priv {
74 enum snd_soc_control_type control_type; 74 enum snd_soc_control_type control_type;
75 void *control_data;
76 int (*set_bias_level)(struct snd_soc_codec *, 75 int (*set_bias_level)(struct snd_soc_codec *,
77 enum snd_soc_bias_level level); 76 enum snd_soc_bias_level level);
78 struct snd_soc_dapm_widget *lout1; 77 struct snd_soc_dapm_widget *lout1;
@@ -575,6 +574,8 @@ static int wm8960_set_bias_level_out3(struct snd_soc_codec *codec,
575 574
576 case SND_SOC_BIAS_STANDBY: 575 case SND_SOC_BIAS_STANDBY:
577 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { 576 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
577 snd_soc_cache_sync(codec);
578
578 /* Enable anti-pop features */ 579 /* Enable anti-pop features */
579 snd_soc_write(codec, WM8960_APOP1, 580 snd_soc_write(codec, WM8960_APOP1,
580 WM8960_POBCTRL | WM8960_SOFT_ST | 581 WM8960_POBCTRL | WM8960_SOFT_ST |
@@ -677,6 +678,9 @@ static int wm8960_set_bias_level_capless(struct snd_soc_codec *codec,
677 WM8960_VREF | WM8960_VMID_MASK, 0); 678 WM8960_VREF | WM8960_VMID_MASK, 0);
678 break; 679 break;
679 680
681 case SND_SOC_BIAS_OFF:
682 snd_soc_cache_sync(codec);
683 break;
680 default: 684 default:
681 break; 685 break;
682 } 686 }
@@ -902,16 +906,6 @@ static int wm8960_suspend(struct snd_soc_codec *codec, pm_message_t state)
902static int wm8960_resume(struct snd_soc_codec *codec) 906static int wm8960_resume(struct snd_soc_codec *codec)
903{ 907{
904 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); 908 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
905 int i;
906 u8 data[2];
907 u16 *cache = codec->reg_cache;
908
909 /* Sync reg_cache with the hardware */
910 for (i = 0; i < ARRAY_SIZE(wm8960_reg); i++) {
911 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
912 data[1] = cache[i] & 0x00ff;
913 codec->hw_write(codec->control_data, data, 2);
914 }
915 909
916 wm8960->set_bias_level(codec, SND_SOC_BIAS_STANDBY); 910 wm8960->set_bias_level(codec, SND_SOC_BIAS_STANDBY);
917 return 0; 911 return 0;
@@ -925,7 +919,6 @@ static int wm8960_probe(struct snd_soc_codec *codec)
925 u16 reg; 919 u16 reg;
926 920
927 wm8960->set_bias_level = wm8960_set_bias_level_out3; 921 wm8960->set_bias_level = wm8960_set_bias_level_out3;
928 codec->control_data = wm8960->control_data;
929 922
930 if (!pdata) { 923 if (!pdata) {
931 dev_warn(codec->dev, "No platform data supplied\n"); 924 dev_warn(codec->dev, "No platform data supplied\n");
@@ -1015,7 +1008,6 @@ static __devinit int wm8960_i2c_probe(struct i2c_client *i2c,
1015 1008
1016 i2c_set_clientdata(i2c, wm8960); 1009 i2c_set_clientdata(i2c, wm8960);
1017 wm8960->control_type = SND_SOC_I2C; 1010 wm8960->control_type = SND_SOC_I2C;
1018 wm8960->control_data = i2c;
1019 1011
1020 ret = snd_soc_register_codec(&i2c->dev, 1012 ret = snd_soc_register_codec(&i2c->dev,
1021 &soc_codec_dev_wm8960, &wm8960_dai, 1); 1013 &soc_codec_dev_wm8960, &wm8960_dai, 1);
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c
index cdee8103d09..9568c8a49f9 100644
--- a/sound/soc/codecs/wm8961.c
+++ b/sound/soc/codecs/wm8961.c
@@ -974,7 +974,9 @@ static int wm8961_probe(struct snd_soc_codec *codec)
974 } 974 }
975 975
976 /* This isn't volatile - readback doesn't correspond to write */ 976 /* This isn't volatile - readback doesn't correspond to write */
977 reg = codec->hw_read(codec, WM8961_RIGHT_INPUT_VOLUME); 977 codec->cache_bypass = 1;
978 reg = snd_soc_read(codec, WM8961_RIGHT_INPUT_VOLUME);
979 codec->cache_bypass = 0;
978 dev_info(codec->dev, "WM8961 family %d revision %c\n", 980 dev_info(codec->dev, "WM8961 family %d revision %c\n",
979 (reg & WM8961_DEVICE_ID_MASK) >> WM8961_DEVICE_ID_SHIFT, 981 (reg & WM8961_DEVICE_ID_MASK) >> WM8961_DEVICE_ID_SHIFT,
980 ((reg & WM8961_CHIP_REV_MASK) >> WM8961_CHIP_REV_SHIFT) 982 ((reg & WM8961_CHIP_REV_MASK) >> WM8961_CHIP_REV_SHIFT)
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index d2c315fa1b9..f60dfa16545 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -63,6 +63,8 @@ struct wm8962_priv {
63 int fll_fref; 63 int fll_fref;
64 int fll_fout; 64 int fll_fout;
65 65
66 u16 dsp2_ena;
67
66 struct delayed_work mic_work; 68 struct delayed_work mic_work;
67 struct snd_soc_jack *jack; 69 struct snd_soc_jack *jack;
68 70
@@ -837,7 +839,7 @@ static const struct wm8962_reg_access {
837 [40] = { 0x00FF, 0x01FF, 0x0000 }, /* R40 - SPKOUTL volume */ 839 [40] = { 0x00FF, 0x01FF, 0x0000 }, /* R40 - SPKOUTL volume */
838 [41] = { 0x00FF, 0x01FF, 0x0000 }, /* R41 - SPKOUTR volume */ 840 [41] = { 0x00FF, 0x01FF, 0x0000 }, /* R41 - SPKOUTR volume */
839 841
840 [47] = { 0x000F, 0x0000, 0x0000 }, /* R47 - Thermal Shutdown Status */ 842 [47] = { 0x000F, 0x0000, 0xFFFF }, /* R47 - Thermal Shutdown Status */
841 [48] = { 0x7EC7, 0x7E07, 0xFFFF }, /* R48 - Additional Control (4) */ 843 [48] = { 0x7EC7, 0x7E07, 0xFFFF }, /* R48 - Additional Control (4) */
842 [49] = { 0x00D3, 0x00D7, 0xFFFF }, /* R49 - Class D Control 1 */ 844 [49] = { 0x00D3, 0x00D7, 0xFFFF }, /* R49 - Class D Control 1 */
843 [51] = { 0x0047, 0x0047, 0x0000 }, /* R51 - Class D Control 2 */ 845 [51] = { 0x0047, 0x0047, 0x0000 }, /* R51 - Class D Control 2 */
@@ -965,7 +967,7 @@ static const struct wm8962_reg_access {
965 [584] = { 0x002D, 0x002D, 0x0000 }, /* R584 - IRQ Debounce */ 967 [584] = { 0x002D, 0x002D, 0x0000 }, /* R584 - IRQ Debounce */
966 [586] = { 0xC000, 0xC000, 0x0000 }, /* R586 - MICINT Source Pol */ 968 [586] = { 0xC000, 0xC000, 0x0000 }, /* R586 - MICINT Source Pol */
967 [768] = { 0x0001, 0x0001, 0x0000 }, /* R768 - DSP2 Power Management */ 969 [768] = { 0x0001, 0x0001, 0x0000 }, /* R768 - DSP2 Power Management */
968 [1037] = { 0x0000, 0x003F, 0x0000 }, /* R1037 - DSP2_ExecControl */ 970 [1037] = { 0x0000, 0x003F, 0xFFFF }, /* R1037 - DSP2_ExecControl */
969 [4096] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4096 - Write Sequencer 0 */ 971 [4096] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4096 - Write Sequencer 0 */
970 [4097] = { 0x00FF, 0x00FF, 0x0000 }, /* R4097 - Write Sequencer 1 */ 972 [4097] = { 0x00FF, 0x00FF, 0x0000 }, /* R4097 - Write Sequencer 1 */
971 [4098] = { 0x070F, 0x070F, 0x0000 }, /* R4098 - Write Sequencer 2 */ 973 [4098] = { 0x070F, 0x070F, 0x0000 }, /* R4098 - Write Sequencer 2 */
@@ -1986,6 +1988,122 @@ static const unsigned int classd_tlv[] = {
1986}; 1988};
1987static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); 1989static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
1988 1990
1991static int wm8962_dsp2_write_config(struct snd_soc_codec *codec)
1992{
1993 return 0;
1994}
1995
1996static int wm8962_dsp2_set_enable(struct snd_soc_codec *codec, u16 val)
1997{
1998 u16 adcl = snd_soc_read(codec, WM8962_LEFT_ADC_VOLUME);
1999 u16 adcr = snd_soc_read(codec, WM8962_RIGHT_ADC_VOLUME);
2000 u16 dac = snd_soc_read(codec, WM8962_ADC_DAC_CONTROL_1);
2001
2002 /* Mute the ADCs and DACs */
2003 snd_soc_write(codec, WM8962_LEFT_ADC_VOLUME, 0);
2004 snd_soc_write(codec, WM8962_RIGHT_ADC_VOLUME, WM8962_ADC_VU);
2005 snd_soc_update_bits(codec, WM8962_ADC_DAC_CONTROL_1,
2006 WM8962_DAC_MUTE, WM8962_DAC_MUTE);
2007
2008 snd_soc_write(codec, WM8962_SOUNDSTAGE_ENABLES_0, val);
2009
2010 /* Restore the ADCs and DACs */
2011 snd_soc_write(codec, WM8962_LEFT_ADC_VOLUME, adcl);
2012 snd_soc_write(codec, WM8962_RIGHT_ADC_VOLUME, adcr);
2013 snd_soc_update_bits(codec, WM8962_ADC_DAC_CONTROL_1,
2014 WM8962_DAC_MUTE, dac);
2015
2016 return 0;
2017}
2018
2019static int wm8962_dsp2_start(struct snd_soc_codec *codec)
2020{
2021 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
2022
2023 wm8962_dsp2_write_config(codec);
2024
2025 snd_soc_write(codec, WM8962_DSP2_EXECCONTROL, WM8962_DSP2_RUNR);
2026
2027 wm8962_dsp2_set_enable(codec, wm8962->dsp2_ena);
2028
2029 return 0;
2030}
2031
2032static int wm8962_dsp2_stop(struct snd_soc_codec *codec)
2033{
2034 wm8962_dsp2_set_enable(codec, 0);
2035
2036 snd_soc_write(codec, WM8962_DSP2_EXECCONTROL, WM8962_DSP2_STOP);
2037
2038 return 0;
2039}
2040
2041#define WM8962_DSP2_ENABLE(xname, xshift) \
2042{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
2043 .info = wm8962_dsp2_ena_info, \
2044 .get = wm8962_dsp2_ena_get, .put = wm8962_dsp2_ena_put, \
2045 .private_value = xshift }
2046
2047static int wm8962_dsp2_ena_info(struct snd_kcontrol *kcontrol,
2048 struct snd_ctl_elem_info *uinfo)
2049{
2050 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
2051
2052 uinfo->count = 1;
2053 uinfo->value.integer.min = 0;
2054 uinfo->value.integer.max = 1;
2055
2056 return 0;
2057}
2058
2059static int wm8962_dsp2_ena_get(struct snd_kcontrol *kcontrol,
2060 struct snd_ctl_elem_value *ucontrol)
2061{
2062 int shift = kcontrol->private_value;
2063 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2064 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
2065
2066 ucontrol->value.integer.value[0] = !!(wm8962->dsp2_ena & 1 << shift);
2067
2068 return 0;
2069}
2070
2071static int wm8962_dsp2_ena_put(struct snd_kcontrol *kcontrol,
2072 struct snd_ctl_elem_value *ucontrol)
2073{
2074 int shift = kcontrol->private_value;
2075 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2076 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
2077 int old = wm8962->dsp2_ena;
2078 int ret = 0;
2079 int dsp2_running = snd_soc_read(codec, WM8962_DSP2_POWER_MANAGEMENT) &
2080 WM8962_DSP2_ENA;
2081
2082 mutex_lock(&codec->mutex);
2083
2084 if (ucontrol->value.integer.value[0])
2085 wm8962->dsp2_ena |= 1 << shift;
2086 else
2087 wm8962->dsp2_ena &= ~(1 << shift);
2088
2089 if (wm8962->dsp2_ena == old)
2090 goto out;
2091
2092 ret = 1;
2093
2094 if (dsp2_running) {
2095 if (wm8962->dsp2_ena)
2096 wm8962_dsp2_set_enable(codec, wm8962->dsp2_ena);
2097 else
2098 wm8962_dsp2_stop(codec);
2099 }
2100
2101out:
2102 mutex_unlock(&codec->mutex);
2103
2104 return ret;
2105}
2106
1989/* The VU bits for the headphones are in a different register to the mute 2107/* The VU bits for the headphones are in a different register to the mute
1990 * bits and only take effect on the PGA if it is actually powered. 2108 * bits and only take effect on the PGA if it is actually powered.
1991 */ 2109 */
@@ -2021,7 +2139,6 @@ static int wm8962_put_spk_sw(struct snd_kcontrol *kcontrol,
2021 struct snd_ctl_elem_value *ucontrol) 2139 struct snd_ctl_elem_value *ucontrol)
2022{ 2140{
2023 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 2141 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2024 u16 *reg_cache = codec->reg_cache;
2025 int ret; 2142 int ret;
2026 2143
2027 /* Apply the update (if any) */ 2144 /* Apply the update (if any) */
@@ -2030,16 +2147,19 @@ static int wm8962_put_spk_sw(struct snd_kcontrol *kcontrol,
2030 return 0; 2147 return 0;
2031 2148
2032 /* If the left PGA is enabled hit that VU bit... */ 2149 /* If the left PGA is enabled hit that VU bit... */
2033 if (reg_cache[WM8962_PWR_MGMT_2] & WM8962_SPKOUTL_PGA_ENA) 2150 ret = snd_soc_read(codec, WM8962_PWR_MGMT_2);
2034 return snd_soc_write(codec, WM8962_SPKOUTL_VOLUME, 2151 if (ret & WM8962_SPKOUTL_PGA_ENA) {
2035 reg_cache[WM8962_SPKOUTL_VOLUME]); 2152 snd_soc_write(codec, WM8962_SPKOUTL_VOLUME,
2153 snd_soc_read(codec, WM8962_SPKOUTL_VOLUME));
2154 return 1;
2155 }
2036 2156
2037 /* ...otherwise the right. The VU is stereo. */ 2157 /* ...otherwise the right. The VU is stereo. */
2038 if (reg_cache[WM8962_PWR_MGMT_2] & WM8962_SPKOUTR_PGA_ENA) 2158 if (ret & WM8962_SPKOUTR_PGA_ENA)
2039 return snd_soc_write(codec, WM8962_SPKOUTR_VOLUME, 2159 snd_soc_write(codec, WM8962_SPKOUTR_VOLUME,
2040 reg_cache[WM8962_SPKOUTR_VOLUME]); 2160 snd_soc_read(codec, WM8962_SPKOUTR_VOLUME));
2041 2161
2042 return 0; 2162 return 1;
2043} 2163}
2044 2164
2045static const char *cap_hpf_mode_text[] = { 2165static const char *cap_hpf_mode_text[] = {
@@ -2049,6 +2169,14 @@ static const char *cap_hpf_mode_text[] = {
2049static const struct soc_enum cap_hpf_mode = 2169static const struct soc_enum cap_hpf_mode =
2050 SOC_ENUM_SINGLE(WM8962_ADC_DAC_CONTROL_2, 10, 2, cap_hpf_mode_text); 2170 SOC_ENUM_SINGLE(WM8962_ADC_DAC_CONTROL_2, 10, 2, cap_hpf_mode_text);
2051 2171
2172
2173static const char *cap_lhpf_mode_text[] = {
2174 "LPF", "HPF"
2175};
2176
2177static const struct soc_enum cap_lhpf_mode =
2178 SOC_ENUM_SINGLE(WM8962_LHPF1, 1, 2, cap_lhpf_mode_text);
2179
2052static const struct snd_kcontrol_new wm8962_snd_controls[] = { 2180static const struct snd_kcontrol_new wm8962_snd_controls[] = {
2053SOC_DOUBLE("Input Mixer Switch", WM8962_INPUT_MIXER_CONTROL_1, 3, 2, 1, 1), 2181SOC_DOUBLE("Input Mixer Switch", WM8962_INPUT_MIXER_CONTROL_1, 3, 2, 1, 1),
2054 2182
@@ -2077,6 +2205,8 @@ SOC_DOUBLE_R("Capture ZC Switch", WM8962_LEFT_INPUT_VOLUME,
2077SOC_SINGLE("Capture HPF Switch", WM8962_ADC_DAC_CONTROL_1, 0, 1, 1), 2205SOC_SINGLE("Capture HPF Switch", WM8962_ADC_DAC_CONTROL_1, 0, 1, 1),
2078SOC_ENUM("Capture HPF Mode", cap_hpf_mode), 2206SOC_ENUM("Capture HPF Mode", cap_hpf_mode),
2079SOC_SINGLE("Capture HPF Cutoff", WM8962_ADC_DAC_CONTROL_2, 7, 7, 0), 2207SOC_SINGLE("Capture HPF Cutoff", WM8962_ADC_DAC_CONTROL_2, 7, 7, 0),
2208SOC_SINGLE("Capture LHPF Switch", WM8962_LHPF1, 0, 1, 0),
2209SOC_ENUM("Capture LHPF Mode", cap_lhpf_mode),
2080 2210
2081SOC_DOUBLE_R_TLV("Sidetone Volume", WM8962_DAC_DSP_MIXING_1, 2211SOC_DOUBLE_R_TLV("Sidetone Volume", WM8962_DAC_DSP_MIXING_1,
2082 WM8962_DAC_DSP_MIXING_2, 4, 12, 0, st_tlv), 2212 WM8962_DAC_DSP_MIXING_2, 4, 12, 0, st_tlv),
@@ -2134,6 +2264,11 @@ SOC_DOUBLE_R_TLV("EQ4 Volume", WM8962_EQ3, WM8962_EQ23,
2134 WM8962_EQL_B4_GAIN_SHIFT, 31, 0, eq_tlv), 2264 WM8962_EQL_B4_GAIN_SHIFT, 31, 0, eq_tlv),
2135SOC_DOUBLE_R_TLV("EQ5 Volume", WM8962_EQ3, WM8962_EQ23, 2265SOC_DOUBLE_R_TLV("EQ5 Volume", WM8962_EQ3, WM8962_EQ23,
2136 WM8962_EQL_B5_GAIN_SHIFT, 31, 0, eq_tlv), 2266 WM8962_EQL_B5_GAIN_SHIFT, 31, 0, eq_tlv),
2267
2268WM8962_DSP2_ENABLE("VSS Switch", WM8962_VSS_ENA_SHIFT),
2269WM8962_DSP2_ENABLE("HPF1 Switch", WM8962_HPF1_ENA_SHIFT),
2270WM8962_DSP2_ENABLE("HPF2 Switch", WM8962_HPF2_ENA_SHIFT),
2271WM8962_DSP2_ENABLE("HD Bass Switch", WM8962_HDBASS_ENA_SHIFT),
2137}; 2272};
2138 2273
2139static const struct snd_kcontrol_new wm8962_spk_mono_controls[] = { 2274static const struct snd_kcontrol_new wm8962_spk_mono_controls[] = {
@@ -2365,7 +2500,6 @@ static int out_pga_event(struct snd_soc_dapm_widget *w,
2365 struct snd_kcontrol *kcontrol, int event) 2500 struct snd_kcontrol *kcontrol, int event)
2366{ 2501{
2367 struct snd_soc_codec *codec = w->codec; 2502 struct snd_soc_codec *codec = w->codec;
2368 u16 *reg_cache = codec->reg_cache;
2369 int reg; 2503 int reg;
2370 2504
2371 switch (w->shift) { 2505 switch (w->shift) {
@@ -2388,11 +2522,36 @@ static int out_pga_event(struct snd_soc_dapm_widget *w,
2388 2522
2389 switch (event) { 2523 switch (event) {
2390 case SND_SOC_DAPM_POST_PMU: 2524 case SND_SOC_DAPM_POST_PMU:
2391 return snd_soc_write(codec, reg, reg_cache[reg]); 2525 return snd_soc_write(codec, reg, snd_soc_read(codec, reg));
2526 default:
2527 BUG();
2528 return -EINVAL;
2529 }
2530}
2531
2532static int dsp2_event(struct snd_soc_dapm_widget *w,
2533 struct snd_kcontrol *kcontrol, int event)
2534{
2535 struct snd_soc_codec *codec = w->codec;
2536 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
2537
2538 switch (event) {
2539 case SND_SOC_DAPM_POST_PMU:
2540 if (wm8962->dsp2_ena)
2541 wm8962_dsp2_start(codec);
2542 break;
2543
2544 case SND_SOC_DAPM_PRE_PMD:
2545 if (wm8962->dsp2_ena)
2546 wm8962_dsp2_stop(codec);
2547 break;
2548
2392 default: 2549 default:
2393 BUG(); 2550 BUG();
2394 return -EINVAL; 2551 return -EINVAL;
2395 } 2552 }
2553
2554 return 0;
2396} 2555}
2397 2556
2398static const char *st_text[] = { "None", "Right", "Left" }; 2557static const char *st_text[] = { "None", "Right", "Left" };
@@ -2509,7 +2668,7 @@ SND_SOC_DAPM_INPUT("IN4R"),
2509SND_SOC_DAPM_INPUT("Beep"), 2668SND_SOC_DAPM_INPUT("Beep"),
2510SND_SOC_DAPM_INPUT("DMICDAT"), 2669SND_SOC_DAPM_INPUT("DMICDAT"),
2511 2670
2512SND_SOC_DAPM_MICBIAS("MICBIAS", WM8962_PWR_MGMT_1, 1, 0), 2671SND_SOC_DAPM_SUPPLY("MICBIAS", WM8962_PWR_MGMT_1, 1, 0, NULL, 0),
2513 2672
2514SND_SOC_DAPM_SUPPLY("Class G", WM8962_CHARGE_PUMP_B, 0, 1, NULL, 0), 2673SND_SOC_DAPM_SUPPLY("Class G", WM8962_CHARGE_PUMP_B, 0, 1, NULL, 0),
2515SND_SOC_DAPM_SUPPLY("SYSCLK", WM8962_CLOCKING2, 5, 0, sysclk_event, 2674SND_SOC_DAPM_SUPPLY("SYSCLK", WM8962_CLOCKING2, 5, 0, sysclk_event,
@@ -2517,6 +2676,9 @@ SND_SOC_DAPM_SUPPLY("SYSCLK", WM8962_CLOCKING2, 5, 0, sysclk_event,
2517SND_SOC_DAPM_SUPPLY("Charge Pump", WM8962_CHARGE_PUMP_1, 0, 0, cp_event, 2676SND_SOC_DAPM_SUPPLY("Charge Pump", WM8962_CHARGE_PUMP_1, 0, 0, cp_event,
2518 SND_SOC_DAPM_POST_PMU), 2677 SND_SOC_DAPM_POST_PMU),
2519SND_SOC_DAPM_SUPPLY("TOCLK", WM8962_ADDITIONAL_CONTROL_1, 0, 0, NULL, 0), 2678SND_SOC_DAPM_SUPPLY("TOCLK", WM8962_ADDITIONAL_CONTROL_1, 0, 0, NULL, 0),
2679SND_SOC_DAPM_SUPPLY_S("DSP2", 1, WM8962_DSP2_POWER_MANAGEMENT,
2680 WM8962_DSP2_ENA_SHIFT, 0, dsp2_event,
2681 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
2520 2682
2521SND_SOC_DAPM_MIXER("INPGAL", WM8962_LEFT_INPUT_PGA_CONTROL, 4, 0, 2683SND_SOC_DAPM_MIXER("INPGAL", WM8962_LEFT_INPUT_PGA_CONTROL, 4, 0,
2522 inpgal, ARRAY_SIZE(inpgal)), 2684 inpgal, ARRAY_SIZE(inpgal)),
@@ -2527,7 +2689,7 @@ SND_SOC_DAPM_MIXER("MIXINL", WM8962_PWR_MGMT_1, 5, 0,
2527SND_SOC_DAPM_MIXER("MIXINR", WM8962_PWR_MGMT_1, 4, 0, 2689SND_SOC_DAPM_MIXER("MIXINR", WM8962_PWR_MGMT_1, 4, 0,
2528 mixinr, ARRAY_SIZE(mixinr)), 2690 mixinr, ARRAY_SIZE(mixinr)),
2529 2691
2530SND_SOC_DAPM_AIF_IN("DMIC", NULL, 0, WM8962_PWR_MGMT_1, 10, 0), 2692SND_SOC_DAPM_AIF_IN("DMIC_ENA", NULL, 0, WM8962_PWR_MGMT_1, 10, 0),
2531 2693
2532SND_SOC_DAPM_ADC("ADCL", "Capture", WM8962_PWR_MGMT_1, 3, 0), 2694SND_SOC_DAPM_ADC("ADCL", "Capture", WM8962_PWR_MGMT_1, 3, 0),
2533SND_SOC_DAPM_ADC("ADCR", "Capture", WM8962_PWR_MGMT_1, 2, 0), 2695SND_SOC_DAPM_ADC("ADCR", "Capture", WM8962_PWR_MGMT_1, 2, 0),
@@ -2606,17 +2768,19 @@ static const struct snd_soc_dapm_route wm8962_intercon[] = {
2606 2768
2607 { "MICBIAS", NULL, "SYSCLK" }, 2769 { "MICBIAS", NULL, "SYSCLK" },
2608 2770
2609 { "DMIC", NULL, "DMICDAT" }, 2771 { "DMIC_ENA", NULL, "DMICDAT" },
2610 2772
2611 { "ADCL", NULL, "SYSCLK" }, 2773 { "ADCL", NULL, "SYSCLK" },
2612 { "ADCL", NULL, "TOCLK" }, 2774 { "ADCL", NULL, "TOCLK" },
2613 { "ADCL", NULL, "MIXINL" }, 2775 { "ADCL", NULL, "MIXINL" },
2614 { "ADCL", NULL, "DMIC" }, 2776 { "ADCL", NULL, "DMIC_ENA" },
2777 { "ADCL", NULL, "DSP2" },
2615 2778
2616 { "ADCR", NULL, "SYSCLK" }, 2779 { "ADCR", NULL, "SYSCLK" },
2617 { "ADCR", NULL, "TOCLK" }, 2780 { "ADCR", NULL, "TOCLK" },
2618 { "ADCR", NULL, "MIXINR" }, 2781 { "ADCR", NULL, "MIXINR" },
2619 { "ADCR", NULL, "DMIC" }, 2782 { "ADCR", NULL, "DMIC_ENA" },
2783 { "ADCR", NULL, "DSP2" },
2620 2784
2621 { "STL", "Left", "ADCL" }, 2785 { "STL", "Left", "ADCL" },
2622 { "STL", "Right", "ADCR" }, 2786 { "STL", "Right", "ADCR" },
@@ -2628,11 +2792,13 @@ static const struct snd_soc_dapm_route wm8962_intercon[] = {
2628 { "DACL", NULL, "TOCLK" }, 2792 { "DACL", NULL, "TOCLK" },
2629 { "DACL", NULL, "Beep" }, 2793 { "DACL", NULL, "Beep" },
2630 { "DACL", NULL, "STL" }, 2794 { "DACL", NULL, "STL" },
2795 { "DACL", NULL, "DSP2" },
2631 2796
2632 { "DACR", NULL, "SYSCLK" }, 2797 { "DACR", NULL, "SYSCLK" },
2633 { "DACR", NULL, "TOCLK" }, 2798 { "DACR", NULL, "TOCLK" },
2634 { "DACR", NULL, "Beep" }, 2799 { "DACR", NULL, "Beep" },
2635 { "DACR", NULL, "STR" }, 2800 { "DACR", NULL, "STR" },
2801 { "DACR", NULL, "DSP2" },
2636 2802
2637 { "HPMIXL", "IN4L Switch", "IN4L" }, 2803 { "HPMIXL", "IN4L Switch", "IN4L" },
2638 { "HPMIXL", "IN4R Switch", "IN4R" }, 2804 { "HPMIXL", "IN4R Switch", "IN4R" },
@@ -3058,9 +3224,9 @@ static int wm8962_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
3058 int aif0 = 0; 3224 int aif0 = 0;
3059 3225
3060 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 3226 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
3061 case SND_SOC_DAIFMT_DSP_A:
3062 aif0 |= WM8962_LRCLK_INV;
3063 case SND_SOC_DAIFMT_DSP_B: 3227 case SND_SOC_DAIFMT_DSP_B:
3228 aif0 |= WM8962_LRCLK_INV | 3;
3229 case SND_SOC_DAIFMT_DSP_A:
3064 aif0 |= 3; 3230 aif0 |= 3;
3065 3231
3066 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 3232 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
@@ -3403,12 +3569,16 @@ static irqreturn_t wm8962_irq(int irq, void *data)
3403 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); 3569 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
3404 int mask; 3570 int mask;
3405 int active; 3571 int active;
3572 int reg;
3406 3573
3407 mask = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2_MASK); 3574 mask = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2_MASK);
3408 3575
3409 active = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2); 3576 active = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2);
3410 active &= ~mask; 3577 active &= ~mask;
3411 3578
3579 if (!active)
3580 return IRQ_NONE;
3581
3412 /* Acknowledge the interrupts */ 3582 /* Acknowledge the interrupts */
3413 snd_soc_write(codec, WM8962_INTERRUPT_STATUS_2, active); 3583 snd_soc_write(codec, WM8962_INTERRUPT_STATUS_2, active);
3414 3584
@@ -3420,9 +3590,21 @@ static irqreturn_t wm8962_irq(int irq, void *data)
3420 if (active & WM8962_FIFOS_ERR_EINT) 3590 if (active & WM8962_FIFOS_ERR_EINT)
3421 dev_err(codec->dev, "FIFO error\n"); 3591 dev_err(codec->dev, "FIFO error\n");
3422 3592
3423 if (active & WM8962_TEMP_SHUT_EINT) 3593 if (active & WM8962_TEMP_SHUT_EINT) {
3424 dev_crit(codec->dev, "Thermal shutdown\n"); 3594 dev_crit(codec->dev, "Thermal shutdown\n");
3425 3595
3596 reg = snd_soc_read(codec, WM8962_THERMAL_SHUTDOWN_STATUS);
3597
3598 if (reg & WM8962_TEMP_ERR_HP)
3599 dev_crit(codec->dev, "Headphone thermal error\n");
3600 if (reg & WM8962_TEMP_WARN_HP)
3601 dev_crit(codec->dev, "Headphone thermal warning\n");
3602 if (reg & WM8962_TEMP_ERR_SPK)
3603 dev_crit(codec->dev, "Speaker thermal error\n");
3604 if (reg & WM8962_TEMP_WARN_SPK)
3605 dev_crit(codec->dev, "Speaker thermal warning\n");
3606 }
3607
3426 if (active & (WM8962_MICSCD_EINT | WM8962_MICD_EINT)) { 3608 if (active & (WM8962_MICSCD_EINT | WM8962_MICD_EINT)) {
3427 dev_dbg(codec->dev, "Microphone event detected\n"); 3609 dev_dbg(codec->dev, "Microphone event detected\n");
3428 3610
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
index 572bb80627a..b444b297d0b 100644
--- a/sound/soc/codecs/wm8971.c
+++ b/sound/soc/codecs/wm8971.c
@@ -546,6 +546,9 @@ static int wm8971_set_bias_level(struct snd_soc_codec *codec,
546 case SND_SOC_BIAS_PREPARE: 546 case SND_SOC_BIAS_PREPARE:
547 break; 547 break;
548 case SND_SOC_BIAS_STANDBY: 548 case SND_SOC_BIAS_STANDBY:
549 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
550 snd_soc_cache_sync(codec);
551
549 /* mute dac and set vmid to 500k, enable VREF */ 552 /* mute dac and set vmid to 500k, enable VREF */
550 snd_soc_write(codec, WM8971_PWR1, pwr_reg | 0x0140); 553 snd_soc_write(codec, WM8971_PWR1, pwr_reg | 0x0140);
551 break; 554 break;
@@ -605,20 +608,8 @@ static int wm8971_suspend(struct snd_soc_codec *codec, pm_message_t state)
605 608
606static int wm8971_resume(struct snd_soc_codec *codec) 609static int wm8971_resume(struct snd_soc_codec *codec)
607{ 610{
608 int i;
609 u8 data[2];
610 u16 *cache = codec->reg_cache;
611 u16 reg; 611 u16 reg;
612 612
613 /* Sync reg_cache with the hardware */
614 for (i = 0; i < ARRAY_SIZE(wm8971_reg); i++) {
615 if (i + 1 == WM8971_RESET)
616 continue;
617 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
618 data[1] = cache[i] & 0x00ff;
619 codec->hw_write(codec->control_data, data, 2);
620 }
621
622 wm8971_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 613 wm8971_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
623 614
624 /* charge wm8971 caps */ 615 /* charge wm8971 caps */
@@ -660,25 +651,14 @@ static int wm8971_probe(struct snd_soc_codec *codec)
660 msecs_to_jiffies(1000)); 651 msecs_to_jiffies(1000));
661 652
662 /* set the update bits */ 653 /* set the update bits */
663 reg = snd_soc_read(codec, WM8971_LDAC); 654 snd_soc_update_bits(codec, WM8971_LDAC, 0x0100, 0x0100);
664 snd_soc_write(codec, WM8971_LDAC, reg | 0x0100); 655 snd_soc_update_bits(codec, WM8971_RDAC, 0x0100, 0x0100);
665 reg = snd_soc_read(codec, WM8971_RDAC); 656 snd_soc_update_bits(codec, WM8971_LOUT1V, 0x0100, 0x0100);
666 snd_soc_write(codec, WM8971_RDAC, reg | 0x0100); 657 snd_soc_update_bits(codec, WM8971_ROUT1V, 0x0100, 0x0100);
667 658 snd_soc_update_bits(codec, WM8971_LOUT2V, 0x0100, 0x0100);
668 reg = snd_soc_read(codec, WM8971_LOUT1V); 659 snd_soc_update_bits(codec, WM8971_ROUT2V, 0x0100, 0x0100);
669 snd_soc_write(codec, WM8971_LOUT1V, reg | 0x0100); 660 snd_soc_update_bits(codec, WM8971_LINVOL, 0x0100, 0x0100);
670 reg = snd_soc_read(codec, WM8971_ROUT1V); 661 snd_soc_update_bits(codec, WM8971_RINVOL, 0x0100, 0x0100);
671 snd_soc_write(codec, WM8971_ROUT1V, reg | 0x0100);
672
673 reg = snd_soc_read(codec, WM8971_LOUT2V);
674 snd_soc_write(codec, WM8971_LOUT2V, reg | 0x0100);
675 reg = snd_soc_read(codec, WM8971_ROUT2V);
676 snd_soc_write(codec, WM8971_ROUT2V, reg | 0x0100);
677
678 reg = snd_soc_read(codec, WM8971_LINVOL);
679 snd_soc_write(codec, WM8971_LINVOL, reg | 0x0100);
680 reg = snd_soc_read(codec, WM8971_RINVOL);
681 snd_soc_write(codec, WM8971_RINVOL, reg | 0x0100);
682 662
683 snd_soc_add_controls(codec, wm8971_snd_controls, 663 snd_soc_add_controls(codec, wm8971_snd_controls,
684 ARRAY_SIZE(wm8971_snd_controls)); 664 ARRAY_SIZE(wm8971_snd_controls));
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c
index ca646a82244..9352f1e088d 100644
--- a/sound/soc/codecs/wm8974.c
+++ b/sound/soc/codecs/wm8974.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright 2006-2009 Wolfson Microelectronics PLC. 4 * Copyright 2006-2009 Wolfson Microelectronics PLC.
5 * 5 *
6 * Author: Liam Girdwood <linux@wolfsonmicro.com> 6 * Author: Liam Girdwood <Liam.Girdwood@wolfsonmicro.com>
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 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 9 * it under the terms of the GNU General Public License version 2 as
@@ -530,6 +530,8 @@ static int wm8974_set_bias_level(struct snd_soc_codec *codec,
530 power1 |= WM8974_POWER1_BIASEN | WM8974_POWER1_BUFIOEN; 530 power1 |= WM8974_POWER1_BIASEN | WM8974_POWER1_BUFIOEN;
531 531
532 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { 532 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
533 snd_soc_cache_sync(codec);
534
533 /* Initial cap charge at VMID 5k */ 535 /* Initial cap charge at VMID 5k */
534 snd_soc_write(codec, WM8974_POWER1, power1 | 0x3); 536 snd_soc_write(codec, WM8974_POWER1, power1 | 0x3);
535 mdelay(100); 537 mdelay(100);
@@ -589,18 +591,7 @@ static int wm8974_suspend(struct snd_soc_codec *codec, pm_message_t state)
589 591
590static int wm8974_resume(struct snd_soc_codec *codec) 592static int wm8974_resume(struct snd_soc_codec *codec)
591{ 593{
592 int i;
593 u8 data[2];
594 u16 *cache = codec->reg_cache;
595
596 /* Sync reg_cache with the hardware */
597 for (i = 0; i < ARRAY_SIZE(wm8974_reg); i++) {
598 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
599 data[1] = cache[i] & 0x00ff;
600 codec->hw_write(codec->control_data, data, 2);
601 }
602 wm8974_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 594 wm8974_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
603
604 return 0; 595 return 0;
605} 596}
606 597
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c
index 85e3e630e76..41ca4d9ac20 100644
--- a/sound/soc/codecs/wm8978.c
+++ b/sound/soc/codecs/wm8978.c
@@ -52,7 +52,6 @@ static const u16 wm8978_reg[WM8978_CACHEREGNUM] = {
52/* codec private data */ 52/* codec private data */
53struct wm8978_priv { 53struct wm8978_priv {
54 enum snd_soc_control_type control_type; 54 enum snd_soc_control_type control_type;
55 void *control_data;
56 unsigned int f_pllout; 55 unsigned int f_pllout;
57 unsigned int f_mclk; 56 unsigned int f_mclk;
58 unsigned int f_256fs; 57 unsigned int f_256fs;
@@ -955,7 +954,6 @@ static int wm8978_probe(struct snd_soc_codec *codec)
955 * default hardware setting 954 * default hardware setting
956 */ 955 */
957 wm8978->sysclk = WM8978_PLL; 956 wm8978->sysclk = WM8978_PLL;
958 codec->control_data = wm8978->control_data;
959 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);
960 if (ret < 0) { 958 if (ret < 0) {
961 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);
@@ -1016,7 +1014,6 @@ static __devinit int wm8978_i2c_probe(struct i2c_client *i2c,
1016 return -ENOMEM; 1014 return -ENOMEM;
1017 1015
1018 i2c_set_clientdata(i2c, wm8978); 1016 i2c_set_clientdata(i2c, wm8978);
1019 wm8978->control_data = i2c;
1020 1017
1021 ret = snd_soc_register_codec(&i2c->dev, 1018 ret = snd_soc_register_codec(&i2c->dev,
1022 &soc_codec_dev_wm8978, &wm8978_dai, 1); 1019 &soc_codec_dev_wm8978, &wm8978_dai, 1);
diff --git a/sound/soc/codecs/wm8983.c b/sound/soc/codecs/wm8983.c
index 17f04ec2b94..93ee28439be 100644
--- a/sound/soc/codecs/wm8983.c
+++ b/sound/soc/codecs/wm8983.c
@@ -1007,7 +1007,7 @@ static int wm8983_probe(struct snd_soc_codec *codec)
1007 return ret; 1007 return ret;
1008 } 1008 }
1009 1009
1010 ret = snd_soc_write(codec, WM8983_SOFTWARE_RESET, 0x8983); 1010 ret = snd_soc_write(codec, WM8983_SOFTWARE_RESET, 0);
1011 if (ret < 0) { 1011 if (ret < 0) {
1012 dev_err(codec->dev, "Failed to issue reset: %d\n", ret); 1012 dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
1013 return ret; 1013 return ret;
diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c
index d7170f1381a..2e9eba717d1 100644
--- a/sound/soc/codecs/wm8988.c
+++ b/sound/soc/codecs/wm8988.c
@@ -55,7 +55,6 @@ struct wm8988_priv {
55 struct snd_pcm_hw_constraint_list *sysclk_constraints; 55 struct snd_pcm_hw_constraint_list *sysclk_constraints;
56}; 56};
57 57
58
59#define wm8988_reset(c) snd_soc_write(c, WM8988_RESET, 0) 58#define wm8988_reset(c) snd_soc_write(c, WM8988_RESET, 0)
60 59
61/* 60/*
@@ -676,6 +675,8 @@ static int wm8988_set_bias_level(struct snd_soc_codec *codec,
676 675
677 case SND_SOC_BIAS_STANDBY: 676 case SND_SOC_BIAS_STANDBY:
678 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { 677 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
678 snd_soc_cache_sync(codec);
679
679 /* VREF, VMID=2x5k */ 680 /* VREF, VMID=2x5k */
680 snd_soc_write(codec, WM8988_PWR1, pwr_reg | 0x1c1); 681 snd_soc_write(codec, WM8988_PWR1, pwr_reg | 0x1c1);
681 682
@@ -736,21 +737,7 @@ static int wm8988_suspend(struct snd_soc_codec *codec, pm_message_t state)
736 737
737static int wm8988_resume(struct snd_soc_codec *codec) 738static int wm8988_resume(struct snd_soc_codec *codec)
738{ 739{
739 int i;
740 u8 data[2];
741 u16 *cache = codec->reg_cache;
742
743 /* Sync reg_cache with the hardware */
744 for (i = 0; i < WM8988_NUM_REG; i++) {
745 if (i == WM8988_RESET)
746 continue;
747 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
748 data[1] = cache[i] & 0x00ff;
749 codec->hw_write(codec->control_data, data, 2);
750 }
751
752 wm8988_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 740 wm8988_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
753
754 return 0; 741 return 0;
755} 742}
756 743
@@ -759,7 +746,6 @@ static int wm8988_probe(struct snd_soc_codec *codec)
759 struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec); 746 struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
760 struct snd_soc_dapm_context *dapm = &codec->dapm; 747 struct snd_soc_dapm_context *dapm = &codec->dapm;
761 int ret = 0; 748 int ret = 0;
762 u16 reg;
763 749
764 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8988->control_type); 750 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8988->control_type);
765 if (ret < 0) { 751 if (ret < 0) {
@@ -774,16 +760,11 @@ static int wm8988_probe(struct snd_soc_codec *codec)
774 } 760 }
775 761
776 /* set the update bits (we always update left then right) */ 762 /* set the update bits (we always update left then right) */
777 reg = snd_soc_read(codec, WM8988_RADC); 763 snd_soc_update_bits(codec, WM8988_RADC, 0x0100, 0x0100);
778 snd_soc_write(codec, WM8988_RADC, reg | 0x100); 764 snd_soc_update_bits(codec, WM8988_RDAC, 0x0100, 0x0100);
779 reg = snd_soc_read(codec, WM8988_RDAC); 765 snd_soc_update_bits(codec, WM8988_ROUT1V, 0x0100, 0x0100);
780 snd_soc_write(codec, WM8988_RDAC, reg | 0x0100); 766 snd_soc_update_bits(codec, WM8988_ROUT2V, 0x0100, 0x0100);
781 reg = snd_soc_read(codec, WM8988_ROUT1V); 767 snd_soc_update_bits(codec, WM8988_RINVOL, 0x0100, 0x0100);
782 snd_soc_write(codec, WM8988_ROUT1V, reg | 0x0100);
783 reg = snd_soc_read(codec, WM8988_ROUT2V);
784 snd_soc_write(codec, WM8988_ROUT2V, reg | 0x0100);
785 reg = snd_soc_read(codec, WM8988_RINVOL);
786 snd_soc_write(codec, WM8988_RINVOL, reg | 0x0100);
787 768
788 wm8988_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 769 wm8988_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
789 770
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index 100aeee5ba9..d29a9622964 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -36,10 +36,17 @@ struct wm8990_priv {
36 unsigned int pcmclk; 36 unsigned int pcmclk;
37}; 37};
38 38
39/* 39static int wm8990_volatile_register(struct snd_soc_codec *codec,
40 * wm8990 register cache. Note that register 0 is not included in the 40 unsigned int reg)
41 * cache. 41{
42 */ 42 switch (reg) {
43 case WM8990_RESET:
44 return 1;
45 default:
46 return 0;
47 }
48}
49
43static const u16 wm8990_reg[] = { 50static const u16 wm8990_reg[] = {
44 0x8990, /* R0 - Reset */ 51 0x8990, /* R0 - Reset */
45 0x0000, /* R1 - Power Management (1) */ 52 0x0000, /* R1 - Power Management (1) */
@@ -394,7 +401,7 @@ static int inmixer_event(struct snd_soc_dapm_widget *w,
394 (1 << WM8990_AINRMUX_PWR_BIT))) { 401 (1 << WM8990_AINRMUX_PWR_BIT))) {
395 reg |= WM8990_AINR_ENA; 402 reg |= WM8990_AINR_ENA;
396 } else { 403 } else {
397 reg &= ~WM8990_AINL_ENA; 404 reg &= ~WM8990_AINR_ENA;
398 } 405 }
399 snd_soc_write(w->codec, WM8990_POWER_MANAGEMENT_2, reg); 406 snd_soc_write(w->codec, WM8990_POWER_MANAGEMENT_2, reg);
400 407
@@ -974,7 +981,6 @@ static void pll_factors(struct _pll_div *pll_div, unsigned int target,
974static int wm8990_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, 981static int wm8990_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
975 int source, unsigned int freq_in, unsigned int freq_out) 982 int source, unsigned int freq_in, unsigned int freq_out)
976{ 983{
977 u16 reg;
978 struct snd_soc_codec *codec = codec_dai->codec; 984 struct snd_soc_codec *codec = codec_dai->codec;
979 struct _pll_div pll_div; 985 struct _pll_div pll_div;
980 986
@@ -982,13 +988,12 @@ static int wm8990_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
982 pll_factors(&pll_div, freq_out * 4, freq_in); 988 pll_factors(&pll_div, freq_out * 4, freq_in);
983 989
984 /* Turn on PLL */ 990 /* Turn on PLL */
985 reg = snd_soc_read(codec, WM8990_POWER_MANAGEMENT_2); 991 snd_soc_update_bits(codec, WM8990_POWER_MANAGEMENT_2,
986 reg |= WM8990_PLL_ENA; 992 WM8990_PLL_ENA, WM8990_PLL_ENA);
987 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_2, reg);
988 993
989 /* sysclk comes from PLL */ 994 /* sysclk comes from PLL */
990 reg = snd_soc_read(codec, WM8990_CLOCKING_2); 995 snd_soc_update_bits(codec, WM8990_CLOCKING_2,
991 snd_soc_write(codec, WM8990_CLOCKING_2, reg | WM8990_SYSCLK_SRC); 996 WM8990_SYSCLK_SRC, WM8990_SYSCLK_SRC);
992 997
993 /* set up N , fractional mode and pre-divisor if necessary */ 998 /* set up N , fractional mode and pre-divisor if necessary */
994 snd_soc_write(codec, WM8990_PLL1, pll_div.n | WM8990_SDM | 999 snd_soc_write(codec, WM8990_PLL1, pll_div.n | WM8990_SDM |
@@ -996,10 +1001,9 @@ static int wm8990_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
996 snd_soc_write(codec, WM8990_PLL2, (u8)(pll_div.k>>8)); 1001 snd_soc_write(codec, WM8990_PLL2, (u8)(pll_div.k>>8));
997 snd_soc_write(codec, WM8990_PLL3, (u8)(pll_div.k & 0xFF)); 1002 snd_soc_write(codec, WM8990_PLL3, (u8)(pll_div.k & 0xFF));
998 } else { 1003 } else {
999 /* Turn on PLL */ 1004 /* Turn off PLL */
1000 reg = snd_soc_read(codec, WM8990_POWER_MANAGEMENT_2); 1005 snd_soc_update_bits(codec, WM8990_POWER_MANAGEMENT_2,
1001 reg &= ~WM8990_PLL_ENA; 1006 WM8990_PLL_ENA, 0);
1002 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_2, reg);
1003 } 1007 }
1004 return 0; 1008 return 0;
1005} 1009}
@@ -1077,28 +1081,23 @@ static int wm8990_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
1077 int div_id, int div) 1081 int div_id, int div)
1078{ 1082{
1079 struct snd_soc_codec *codec = codec_dai->codec; 1083 struct snd_soc_codec *codec = codec_dai->codec;
1080 u16 reg;
1081 1084
1082 switch (div_id) { 1085 switch (div_id) {
1083 case WM8990_MCLK_DIV: 1086 case WM8990_MCLK_DIV:
1084 reg = snd_soc_read(codec, WM8990_CLOCKING_2) & 1087 snd_soc_update_bits(codec, WM8990_CLOCKING_2,
1085 ~WM8990_MCLK_DIV_MASK; 1088 WM8990_MCLK_DIV_MASK, div);
1086 snd_soc_write(codec, WM8990_CLOCKING_2, reg | div);
1087 break; 1089 break;
1088 case WM8990_DACCLK_DIV: 1090 case WM8990_DACCLK_DIV:
1089 reg = snd_soc_read(codec, WM8990_CLOCKING_2) & 1091 snd_soc_update_bits(codec, WM8990_CLOCKING_2,
1090 ~WM8990_DAC_CLKDIV_MASK; 1092 WM8990_DAC_CLKDIV_MASK, div);
1091 snd_soc_write(codec, WM8990_CLOCKING_2, reg | div);
1092 break; 1093 break;
1093 case WM8990_ADCCLK_DIV: 1094 case WM8990_ADCCLK_DIV:
1094 reg = snd_soc_read(codec, WM8990_CLOCKING_2) & 1095 snd_soc_update_bits(codec, WM8990_CLOCKING_2,
1095 ~WM8990_ADC_CLKDIV_MASK; 1096 WM8990_ADC_CLKDIV_MASK, div);
1096 snd_soc_write(codec, WM8990_CLOCKING_2, reg | div);
1097 break; 1097 break;
1098 case WM8990_BCLK_DIV: 1098 case WM8990_BCLK_DIV:
1099 reg = snd_soc_read(codec, WM8990_CLOCKING_1) & 1099 snd_soc_update_bits(codec, WM8990_CLOCKING_1,
1100 ~WM8990_BCLK_DIV_MASK; 1100 WM8990_BCLK_DIV_MASK, div);
1101 snd_soc_write(codec, WM8990_CLOCKING_1, reg | div);
1102 break; 1101 break;
1103 default: 1102 default:
1104 return -EINVAL; 1103 return -EINVAL;
@@ -1156,7 +1155,7 @@ static int wm8990_mute(struct snd_soc_dai *dai, int mute)
1156static int wm8990_set_bias_level(struct snd_soc_codec *codec, 1155static int wm8990_set_bias_level(struct snd_soc_codec *codec,
1157 enum snd_soc_bias_level level) 1156 enum snd_soc_bias_level level)
1158{ 1157{
1159 u16 val; 1158 int ret;
1160 1159
1161 switch (level) { 1160 switch (level) {
1162 case SND_SOC_BIAS_ON: 1161 case SND_SOC_BIAS_ON:
@@ -1164,13 +1163,18 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec,
1164 1163
1165 case SND_SOC_BIAS_PREPARE: 1164 case SND_SOC_BIAS_PREPARE:
1166 /* VMID=2*50k */ 1165 /* VMID=2*50k */
1167 val = snd_soc_read(codec, WM8990_POWER_MANAGEMENT_1) & 1166 snd_soc_update_bits(codec, WM8990_POWER_MANAGEMENT_1,
1168 ~WM8990_VMID_MODE_MASK; 1167 WM8990_VMID_MODE_MASK, 0x2);
1169 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, val | 0x2);
1170 break; 1168 break;
1171 1169
1172 case SND_SOC_BIAS_STANDBY: 1170 case SND_SOC_BIAS_STANDBY:
1173 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { 1171 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1172 ret = snd_soc_cache_sync(codec);
1173 if (ret < 0) {
1174 dev_err(codec->dev, "Failed to sync cache: %d\n", ret);
1175 return ret;
1176 }
1177
1174 /* Enable all output discharge bits */ 1178 /* Enable all output discharge bits */
1175 snd_soc_write(codec, WM8990_ANTIPOP1, WM8990_DIS_LLINE | 1179 snd_soc_write(codec, WM8990_ANTIPOP1, WM8990_DIS_LLINE |
1176 WM8990_DIS_RLINE | WM8990_DIS_OUT3 | 1180 WM8990_DIS_RLINE | WM8990_DIS_OUT3 |
@@ -1225,9 +1229,8 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec,
1225 } 1229 }
1226 1230
1227 /* VMID=2*250k */ 1231 /* VMID=2*250k */
1228 val = snd_soc_read(codec, WM8990_POWER_MANAGEMENT_1) & 1232 snd_soc_update_bits(codec, WM8990_POWER_MANAGEMENT_1,
1229 ~WM8990_VMID_MODE_MASK; 1233 WM8990_VMID_MODE_MASK, 0x4);
1230 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, val | 0x4);
1231 break; 1234 break;
1232 1235
1233 case SND_SOC_BIAS_OFF: 1236 case SND_SOC_BIAS_OFF:
@@ -1241,8 +1244,8 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec,
1241 WM8990_BUFIOEN); 1244 WM8990_BUFIOEN);
1242 1245
1243 /* mute DAC */ 1246 /* mute DAC */
1244 val = snd_soc_read(codec, WM8990_DAC_CTRL); 1247 snd_soc_update_bits(codec, WM8990_DAC_CTRL,
1245 snd_soc_write(codec, WM8990_DAC_CTRL, val | WM8990_DAC_MUTE); 1248 WM8990_DAC_MUTE, WM8990_DAC_MUTE);
1246 1249
1247 /* Enable any disabled outputs */ 1250 /* Enable any disabled outputs */
1248 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f03); 1251 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f03);
@@ -1319,19 +1322,6 @@ static int wm8990_suspend(struct snd_soc_codec *codec, pm_message_t state)
1319 1322
1320static int wm8990_resume(struct snd_soc_codec *codec) 1323static int wm8990_resume(struct snd_soc_codec *codec)
1321{ 1324{
1322 int i;
1323 u8 data[2];
1324 u16 *cache = codec->reg_cache;
1325
1326 /* Sync reg_cache with the hardware */
1327 for (i = 0; i < ARRAY_SIZE(wm8990_reg); i++) {
1328 if (i + 1 == WM8990_RESET)
1329 continue;
1330 data[0] = ((i + 1) << 1) | ((cache[i] >> 8) & 0x0001);
1331 data[1] = cache[i] & 0x00ff;
1332 codec->hw_write(codec->control_data, data, 2);
1333 }
1334
1335 wm8990_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1325 wm8990_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1336 return 0; 1326 return 0;
1337} 1327}
@@ -1343,7 +1333,6 @@ static int wm8990_resume(struct snd_soc_codec *codec)
1343static int wm8990_probe(struct snd_soc_codec *codec) 1333static int wm8990_probe(struct snd_soc_codec *codec)
1344{ 1334{
1345 int ret; 1335 int ret;
1346 u16 reg;
1347 1336
1348 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); 1337 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
1349 if (ret < 0) { 1338 if (ret < 0) {
@@ -1356,15 +1345,14 @@ static int wm8990_probe(struct snd_soc_codec *codec)
1356 /* charge output caps */ 1345 /* charge output caps */
1357 wm8990_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1346 wm8990_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1358 1347
1359 reg = snd_soc_read(codec, WM8990_AUDIO_INTERFACE_4); 1348 snd_soc_update_bits(codec, WM8990_AUDIO_INTERFACE_4,
1360 snd_soc_write(codec, WM8990_AUDIO_INTERFACE_4, reg | WM8990_ALRCGPIO1); 1349 WM8990_ALRCGPIO1, WM8990_ALRCGPIO1);
1361 1350
1362 reg = snd_soc_read(codec, WM8990_GPIO1_GPIO2) & 1351 snd_soc_update_bits(codec, WM8990_GPIO1_GPIO2,
1363 ~WM8990_GPIO1_SEL_MASK; 1352 WM8990_GPIO1_SEL_MASK, 1);
1364 snd_soc_write(codec, WM8990_GPIO1_GPIO2, reg | 1);
1365 1353
1366 reg = snd_soc_read(codec, WM8990_POWER_MANAGEMENT_2); 1354 snd_soc_update_bits(codec, WM8990_POWER_MANAGEMENT_2,
1367 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_2, reg | WM8990_OPCLK_ENA); 1355 WM8990_OPCLK_ENA, WM8990_OPCLK_ENA);
1368 1356
1369 snd_soc_write(codec, WM8990_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8)); 1357 snd_soc_write(codec, WM8990_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8));
1370 snd_soc_write(codec, WM8990_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8)); 1358 snd_soc_write(codec, WM8990_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8));
@@ -1392,6 +1380,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8990 = {
1392 .reg_cache_size = ARRAY_SIZE(wm8990_reg), 1380 .reg_cache_size = ARRAY_SIZE(wm8990_reg),
1393 .reg_word_size = sizeof(u16), 1381 .reg_word_size = sizeof(u16),
1394 .reg_cache_default = wm8990_reg, 1382 .reg_cache_default = wm8990_reg,
1383 .volatile_register = wm8990_volatile_register,
1395}; 1384};
1396 1385
1397#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1386#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
diff --git a/sound/soc/codecs/wm8991.c b/sound/soc/codecs/wm8991.c
index 6af23d06870..c9ab3ba9bce 100644
--- a/sound/soc/codecs/wm8991.c
+++ b/sound/soc/codecs/wm8991.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright 2007-2010 Wolfson Microelectronics PLC. 4 * Copyright 2007-2010 Wolfson Microelectronics PLC.
5 * Author: Graeme Gregory 5 * Author: Graeme Gregory
6 * linux@wolfsonmicro.com 6 * Graeme.Gregory@wolfsonmicro.com
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify it 8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the 9 * under the terms of the GNU General Public License as published by the
@@ -393,7 +393,7 @@ static int inmixer_event(struct snd_soc_dapm_widget *w,
393 (1 << WM8991_AINRMUX_PWR_BIT))) 393 (1 << WM8991_AINRMUX_PWR_BIT)))
394 reg |= WM8991_AINR_ENA; 394 reg |= WM8991_AINR_ENA;
395 else 395 else
396 reg &= ~WM8991_AINL_ENA; 396 reg &= ~WM8991_AINR_ENA;
397 397
398 snd_soc_write(w->codec, WM8991_POWER_MANAGEMENT_2, reg); 398 snd_soc_write(w->codec, WM8991_POWER_MANAGEMENT_2, reg);
399 return 0; 399 return 0;
@@ -1264,7 +1264,6 @@ static int wm8991_probe(struct snd_soc_codec *codec)
1264{ 1264{
1265 struct wm8991_priv *wm8991; 1265 struct wm8991_priv *wm8991;
1266 int ret; 1266 int ret;
1267 unsigned int reg;
1268 1267
1269 wm8991 = snd_soc_codec_get_drvdata(codec); 1268 wm8991 = snd_soc_codec_get_drvdata(codec);
1270 1269
@@ -1282,19 +1281,18 @@ static int wm8991_probe(struct snd_soc_codec *codec)
1282 1281
1283 wm8991_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1282 wm8991_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1284 1283
1285 reg = snd_soc_read(codec, WM8991_AUDIO_INTERFACE_4); 1284 snd_soc_update_bits(codec, WM8991_AUDIO_INTERFACE_4,
1286 snd_soc_write(codec, WM8991_AUDIO_INTERFACE_4, reg | WM8991_ALRCGPIO1); 1285 WM8991_ALRCGPIO1, WM8991_ALRCGPIO1);
1287 1286
1288 reg = snd_soc_read(codec, WM8991_GPIO1_GPIO2) & 1287 snd_soc_update_bits(codec, WM8991_GPIO1_GPIO2,
1289 ~WM8991_GPIO1_SEL_MASK; 1288 WM8991_GPIO1_SEL_MASK, 1);
1290 snd_soc_write(codec, WM8991_GPIO1_GPIO2, reg | 1);
1291 1289
1292 reg = snd_soc_read(codec, WM8991_POWER_MANAGEMENT_1); 1290 snd_soc_update_bits(codec, WM8991_POWER_MANAGEMENT_1,
1293 snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, reg | WM8991_VREF_ENA| 1291 WM8991_VREF_ENA | WM8991_VMID_MODE_MASK,
1294 WM8991_VMID_MODE_MASK); 1292 WM8991_VREF_ENA | WM8991_VMID_MODE_MASK);
1295 1293
1296 reg = snd_soc_read(codec, WM8991_POWER_MANAGEMENT_2); 1294 snd_soc_update_bits(codec, WM8991_POWER_MANAGEMENT_2,
1297 snd_soc_write(codec, WM8991_POWER_MANAGEMENT_2, reg | WM8991_OPCLK_ENA); 1295 WM8991_OPCLK_ENA, WM8991_OPCLK_ENA);
1298 1296
1299 snd_soc_write(codec, WM8991_DAC_CTRL, 0); 1297 snd_soc_write(codec, WM8991_DAC_CTRL, 0);
1300 snd_soc_write(codec, WM8991_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8)); 1298 snd_soc_write(codec, WM8991_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8));
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c
index 6e85b8869af..eec8e143511 100644
--- a/sound/soc/codecs/wm8993.c
+++ b/sound/soc/codecs/wm8993.c
@@ -847,6 +847,7 @@ SND_SOC_DAPM_SUPPLY("CLK_SYS", WM8993_BUS_CONTROL_1, 1, 0, clk_sys_event,
847 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 847 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
848SND_SOC_DAPM_SUPPLY("TOCLK", WM8993_CLOCKING_1, 14, 0, NULL, 0), 848SND_SOC_DAPM_SUPPLY("TOCLK", WM8993_CLOCKING_1, 14, 0, NULL, 0),
849SND_SOC_DAPM_SUPPLY("CLK_DSP", WM8993_CLOCKING_3, 0, 0, NULL, 0), 849SND_SOC_DAPM_SUPPLY("CLK_DSP", WM8993_CLOCKING_3, 0, 0, NULL, 0),
850SND_SOC_DAPM_SUPPLY("VMID", SND_SOC_NOPM, 0, 0, NULL, 0),
850 851
851SND_SOC_DAPM_ADC("ADCL", NULL, WM8993_POWER_MANAGEMENT_2, 1, 0), 852SND_SOC_DAPM_ADC("ADCL", NULL, WM8993_POWER_MANAGEMENT_2, 1, 0),
852SND_SOC_DAPM_ADC("ADCR", NULL, WM8993_POWER_MANAGEMENT_2, 0, 0), 853SND_SOC_DAPM_ADC("ADCR", NULL, WM8993_POWER_MANAGEMENT_2, 0, 0),
@@ -880,6 +881,9 @@ SND_SOC_DAPM_PGA("Direct Voice", SND_SOC_NOPM, 0, 0, NULL, 0),
880}; 881};
881 882
882static const struct snd_soc_dapm_route routes[] = { 883static const struct snd_soc_dapm_route routes[] = {
884 { "MICBIAS1", NULL, "VMID" },
885 { "MICBIAS2", NULL, "VMID" },
886
883 { "ADCL", NULL, "CLK_SYS" }, 887 { "ADCL", NULL, "CLK_SYS" },
884 { "ADCL", NULL, "CLK_DSP" }, 888 { "ADCL", NULL, "CLK_DSP" },
885 { "ADCR", NULL, "CLK_SYS" }, 889 { "ADCR", NULL, "CLK_SYS" },
@@ -1433,7 +1437,8 @@ static int wm8993_probe(struct snd_soc_codec *codec)
1433 int ret, i, val; 1437 int ret, i, val;
1434 1438
1435 wm8993->hubs_data.hp_startup_mode = 1; 1439 wm8993->hubs_data.hp_startup_mode = 1;
1436 wm8993->hubs_data.dcs_codes = -2; 1440 wm8993->hubs_data.dcs_codes_l = -2;
1441 wm8993->hubs_data.dcs_codes_r = -2;
1437 wm8993->hubs_data.series_startup = 1; 1442 wm8993->hubs_data.series_startup = 1;
1438 1443
1439 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); 1444 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
diff --git a/sound/soc/codecs/wm8994-tables.c b/sound/soc/codecs/wm8994-tables.c
index a87adbd05ee..df5a8b9a250 100644
--- a/sound/soc/codecs/wm8994-tables.c
+++ b/sound/soc/codecs/wm8994-tables.c
@@ -1073,8 +1073,8 @@ const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE] = {
1073 { 0x0000, 0x0000 }, /* R1069 */ 1073 { 0x0000, 0x0000 }, /* R1069 */
1074 { 0x0000, 0x0000 }, /* R1070 */ 1074 { 0x0000, 0x0000 }, /* R1070 */
1075 { 0x0000, 0x0000 }, /* R1071 */ 1075 { 0x0000, 0x0000 }, /* R1071 */
1076 { 0x0000, 0x0000 }, /* R1072 */ 1076 { 0x006F, 0x006F }, /* R1072 - AIF1 DAC1 Noise Gate */
1077 { 0x0000, 0x0000 }, /* R1073 */ 1077 { 0x006F, 0x006F }, /* R1073 - AIF1 DAC2 Noise Gate */
1078 { 0x0000, 0x0000 }, /* R1074 */ 1078 { 0x0000, 0x0000 }, /* R1074 */
1079 { 0x0000, 0x0000 }, /* R1075 */ 1079 { 0x0000, 0x0000 }, /* R1075 */
1080 { 0x0000, 0x0000 }, /* R1076 */ 1080 { 0x0000, 0x0000 }, /* R1076 */
@@ -1329,7 +1329,7 @@ const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE] = {
1329 { 0x0000, 0x0000 }, /* R1325 */ 1329 { 0x0000, 0x0000 }, /* R1325 */
1330 { 0x0000, 0x0000 }, /* R1326 */ 1330 { 0x0000, 0x0000 }, /* R1326 */
1331 { 0x0000, 0x0000 }, /* R1327 */ 1331 { 0x0000, 0x0000 }, /* R1327 */
1332 { 0x0000, 0x0000 }, /* R1328 */ 1332 { 0x006F, 0x006F }, /* R1328 - AIF2 DAC Noise Gate */
1333 { 0x0000, 0x0000 }, /* R1329 */ 1333 { 0x0000, 0x0000 }, /* R1329 */
1334 { 0x0000, 0x0000 }, /* R1330 */ 1334 { 0x0000, 0x0000 }, /* R1330 */
1335 { 0x0000, 0x0000 }, /* R1331 */ 1335 { 0x0000, 0x0000 }, /* R1331 */
@@ -1635,8 +1635,8 @@ const u16 wm8994_reg_defaults[WM8994_CACHE_SIZE] = {
1635 0x0000, /* R58 - MICBIAS */ 1635 0x0000, /* R58 - MICBIAS */
1636 0x000D, /* R59 - LDO 1 */ 1636 0x000D, /* R59 - LDO 1 */
1637 0x0003, /* R60 - LDO 2 */ 1637 0x0003, /* R60 - LDO 2 */
1638 0x0000, /* R61 */ 1638 0x0039, /* R61 - MICBIAS1 */
1639 0x0000, /* R62 */ 1639 0x0039, /* R62 - MICBIAS2 */
1640 0x0000, /* R63 */ 1640 0x0000, /* R63 */
1641 0x0000, /* R64 */ 1641 0x0000, /* R64 */
1642 0x0000, /* R65 */ 1642 0x0000, /* R65 */
@@ -2646,8 +2646,8 @@ const u16 wm8994_reg_defaults[WM8994_CACHE_SIZE] = {
2646 0x0000, /* R1069 */ 2646 0x0000, /* R1069 */
2647 0x0000, /* R1070 */ 2647 0x0000, /* R1070 */
2648 0x0000, /* R1071 */ 2648 0x0000, /* R1071 */
2649 0x0000, /* R1072 */ 2649 0x0068, /* R1072 - AIF1 DAC1 Noise Gate */
2650 0x0000, /* R1073 */ 2650 0x0068, /* R1073 - AIF1 DAC2 Noise Gate */
2651 0x0000, /* R1074 */ 2651 0x0000, /* R1074 */
2652 0x0000, /* R1075 */ 2652 0x0000, /* R1075 */
2653 0x0000, /* R1076 */ 2653 0x0000, /* R1076 */
@@ -2902,7 +2902,7 @@ const u16 wm8994_reg_defaults[WM8994_CACHE_SIZE] = {
2902 0x0000, /* R1325 */ 2902 0x0000, /* R1325 */
2903 0x0000, /* R1326 */ 2903 0x0000, /* R1326 */
2904 0x0000, /* R1327 */ 2904 0x0000, /* R1327 */
2905 0x0000, /* R1328 */ 2905 0x0068, /* R1328 - AIF2 DAC Noise Gate */
2906 0x0000, /* R1329 */ 2906 0x0000, /* R1329 */
2907 0x0000, /* R1330 */ 2907 0x0000, /* R1330 */
2908 0x0000, /* R1331 */ 2908 0x0000, /* R1331 */
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index b393f9fac97..6b73efd2699 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -107,6 +107,7 @@ static int wm8994_volatile(struct snd_soc_codec *codec, unsigned int reg)
107 case WM8994_LDO_2: 107 case WM8994_LDO_2:
108 case WM8958_DSP2_EXECCONTROL: 108 case WM8958_DSP2_EXECCONTROL:
109 case WM8958_MIC_DETECT_3: 109 case WM8958_MIC_DETECT_3:
110 case WM8994_DC_SERVO_4E:
110 return 1; 111 return 1;
111 default: 112 default:
112 return 0; 113 return 0;
@@ -207,7 +208,7 @@ static int configure_aif_clock(struct snd_soc_codec *codec, int aif)
207static int configure_clock(struct snd_soc_codec *codec) 208static int configure_clock(struct snd_soc_codec *codec)
208{ 209{
209 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 210 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
210 int old, new; 211 int change, new;
211 212
212 /* Bring up the AIF clocks first */ 213 /* Bring up the AIF clocks first */
213 configure_aif_clock(codec, 0); 214 configure_aif_clock(codec, 0);
@@ -228,14 +229,11 @@ static int configure_clock(struct snd_soc_codec *codec)
228 else 229 else
229 new = 0; 230 new = 0;
230 231
231 old = snd_soc_read(codec, WM8994_CLOCKING_1) & WM8994_SYSCLK_SRC; 232 change = snd_soc_update_bits(codec, WM8994_CLOCKING_1,
232 233 WM8994_SYSCLK_SRC, new);
233 /* If there's no change then we're done. */ 234 if (!change)
234 if (old == new)
235 return 0; 235 return 0;
236 236
237 snd_soc_update_bits(codec, WM8994_CLOCKING_1, WM8994_SYSCLK_SRC, new);
238
239 snd_soc_dapm_sync(&codec->dapm); 237 snd_soc_dapm_sync(&codec->dapm);
240 238
241 return 0; 239 return 0;
@@ -281,6 +279,8 @@ static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
281static const DECLARE_TLV_DB_SCALE(st_tlv, -3600, 300, 0); 279static const DECLARE_TLV_DB_SCALE(st_tlv, -3600, 300, 0);
282static const DECLARE_TLV_DB_SCALE(wm8994_3d_tlv, -1600, 183, 0); 280static const DECLARE_TLV_DB_SCALE(wm8994_3d_tlv, -1600, 183, 0);
283static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); 281static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
282static const DECLARE_TLV_DB_SCALE(ng_tlv, -10200, 600, 0);
283static const DECLARE_TLV_DB_SCALE(mixin_boost_tlv, 0, 900, 0);
284 284
285#define WM8994_DRC_SWITCH(xname, reg, shift) \ 285#define WM8994_DRC_SWITCH(xname, reg, shift) \
286{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 286{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
@@ -660,8 +660,52 @@ SOC_SINGLE_TLV("AIF2 EQ5 Volume", WM8994_AIF2_EQ_GAINS_2, 6, 31, 0,
660 eq_tlv), 660 eq_tlv),
661}; 661};
662 662
663static const char *wm8958_ng_text[] = {
664 "30ms", "125ms", "250ms", "500ms",
665};
666
667static const struct soc_enum wm8958_aif1dac1_ng_hold =
668 SOC_ENUM_SINGLE(WM8958_AIF1_DAC1_NOISE_GATE,
669 WM8958_AIF1DAC1_NG_THR_SHIFT, 4, wm8958_ng_text);
670
671static const struct soc_enum wm8958_aif1dac2_ng_hold =
672 SOC_ENUM_SINGLE(WM8958_AIF1_DAC2_NOISE_GATE,
673 WM8958_AIF1DAC2_NG_THR_SHIFT, 4, wm8958_ng_text);
674
675static const struct soc_enum wm8958_aif2dac_ng_hold =
676 SOC_ENUM_SINGLE(WM8958_AIF2_DAC_NOISE_GATE,
677 WM8958_AIF2DAC_NG_THR_SHIFT, 4, wm8958_ng_text);
678
663static const struct snd_kcontrol_new wm8958_snd_controls[] = { 679static const struct snd_kcontrol_new wm8958_snd_controls[] = {
664SOC_SINGLE_TLV("AIF3 Boost Volume", WM8958_AIF3_CONTROL_2, 10, 3, 0, aif_tlv), 680SOC_SINGLE_TLV("AIF3 Boost Volume", WM8958_AIF3_CONTROL_2, 10, 3, 0, aif_tlv),
681
682SOC_SINGLE("AIF1DAC1 Noise Gate Switch", WM8958_AIF1_DAC1_NOISE_GATE,
683 WM8958_AIF1DAC1_NG_ENA_SHIFT, 1, 0),
684SOC_ENUM("AIF1DAC1 Noise Gate Hold Time", wm8958_aif1dac1_ng_hold),
685SOC_SINGLE_TLV("AIF1DAC1 Noise Gate Threshold Volume",
686 WM8958_AIF1_DAC1_NOISE_GATE, WM8958_AIF1DAC1_NG_THR_SHIFT,
687 7, 1, ng_tlv),
688
689SOC_SINGLE("AIF1DAC2 Noise Gate Switch", WM8958_AIF1_DAC2_NOISE_GATE,
690 WM8958_AIF1DAC2_NG_ENA_SHIFT, 1, 0),
691SOC_ENUM("AIF1DAC2 Noise Gate Hold Time", wm8958_aif1dac2_ng_hold),
692SOC_SINGLE_TLV("AIF1DAC2 Noise Gate Threshold Volume",
693 WM8958_AIF1_DAC2_NOISE_GATE, WM8958_AIF1DAC2_NG_THR_SHIFT,
694 7, 1, ng_tlv),
695
696SOC_SINGLE("AIF2DAC Noise Gate Switch", WM8958_AIF2_DAC_NOISE_GATE,
697 WM8958_AIF2DAC_NG_ENA_SHIFT, 1, 0),
698SOC_ENUM("AIF2DAC Noise Gate Hold Time", wm8958_aif2dac_ng_hold),
699SOC_SINGLE_TLV("AIF2DAC Noise Gate Threshold Volume",
700 WM8958_AIF2_DAC_NOISE_GATE, WM8958_AIF2DAC_NG_THR_SHIFT,
701 7, 1, ng_tlv),
702};
703
704static const struct snd_kcontrol_new wm1811_snd_controls[] = {
705SOC_SINGLE_TLV("MIXINL IN1LP Boost Volume", WM8994_INPUT_MIXER_1, 7, 1, 0,
706 mixin_boost_tlv),
707SOC_SINGLE_TLV("MIXINL IN1RP Boost Volume", WM8994_INPUT_MIXER_1, 8, 1, 0,
708 mixin_boost_tlv),
665}; 709};
666 710
667static int clk_sys_event(struct snd_soc_dapm_widget *w, 711static int clk_sys_event(struct snd_soc_dapm_widget *w,
@@ -681,6 +725,97 @@ static int clk_sys_event(struct snd_soc_dapm_widget *w,
681 return 0; 725 return 0;
682} 726}
683 727
728static void vmid_reference(struct snd_soc_codec *codec)
729{
730 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
731
732 wm8994->vmid_refcount++;
733
734 dev_dbg(codec->dev, "Referencing VMID, refcount is now %d\n",
735 wm8994->vmid_refcount);
736
737 if (wm8994->vmid_refcount == 1) {
738 /* Startup bias, VMID ramp & buffer */
739 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
740 WM8994_STARTUP_BIAS_ENA |
741 WM8994_VMID_BUF_ENA |
742 WM8994_VMID_RAMP_MASK,
743 WM8994_STARTUP_BIAS_ENA |
744 WM8994_VMID_BUF_ENA |
745 (0x11 << WM8994_VMID_RAMP_SHIFT));
746
747 /* Main bias enable, VMID=2x40k */
748 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
749 WM8994_BIAS_ENA |
750 WM8994_VMID_SEL_MASK,
751 WM8994_BIAS_ENA | 0x2);
752
753 msleep(20);
754 }
755}
756
757static void vmid_dereference(struct snd_soc_codec *codec)
758{
759 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
760
761 wm8994->vmid_refcount--;
762
763 dev_dbg(codec->dev, "Dereferencing VMID, refcount is now %d\n",
764 wm8994->vmid_refcount);
765
766 if (wm8994->vmid_refcount == 0) {
767 /* Switch over to startup biases */
768 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
769 WM8994_BIAS_SRC |
770 WM8994_STARTUP_BIAS_ENA |
771 WM8994_VMID_BUF_ENA |
772 WM8994_VMID_RAMP_MASK,
773 WM8994_BIAS_SRC |
774 WM8994_STARTUP_BIAS_ENA |
775 WM8994_VMID_BUF_ENA |
776 (1 << WM8994_VMID_RAMP_SHIFT));
777
778 /* Disable main biases */
779 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
780 WM8994_BIAS_ENA |
781 WM8994_VMID_SEL_MASK, 0);
782
783 /* Discharge line */
784 snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
785 WM8994_LINEOUT1_DISCH |
786 WM8994_LINEOUT2_DISCH,
787 WM8994_LINEOUT1_DISCH |
788 WM8994_LINEOUT2_DISCH);
789
790 msleep(5);
791
792 /* Switch off startup biases */
793 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
794 WM8994_BIAS_SRC |
795 WM8994_STARTUP_BIAS_ENA |
796 WM8994_VMID_BUF_ENA |
797 WM8994_VMID_RAMP_MASK, 0);
798 }
799}
800
801static int vmid_event(struct snd_soc_dapm_widget *w,
802 struct snd_kcontrol *kcontrol, int event)
803{
804 struct snd_soc_codec *codec = w->codec;
805
806 switch (event) {
807 case SND_SOC_DAPM_PRE_PMU:
808 vmid_reference(codec);
809 break;
810
811 case SND_SOC_DAPM_POST_PMD:
812 vmid_dereference(codec);
813 break;
814 }
815
816 return 0;
817}
818
684static void wm8994_update_class_w(struct snd_soc_codec *codec) 819static void wm8994_update_class_w(struct snd_soc_codec *codec)
685{ 820{
686 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 821 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
@@ -1208,6 +1343,8 @@ SND_SOC_DAPM_INPUT("Clock"),
1208 1343
1209SND_SOC_DAPM_SUPPLY_S("MICBIAS Supply", 1, SND_SOC_NOPM, 0, 0, micbias_ev, 1344SND_SOC_DAPM_SUPPLY_S("MICBIAS Supply", 1, SND_SOC_NOPM, 0, 0, micbias_ev,
1210 SND_SOC_DAPM_PRE_PMU), 1345 SND_SOC_DAPM_PRE_PMU),
1346SND_SOC_DAPM_SUPPLY("VMID", SND_SOC_NOPM, 0, 0, vmid_event,
1347 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1211 1348
1212SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event, 1349SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event,
1213 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 1350 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
@@ -1282,7 +1419,7 @@ SND_SOC_DAPM_MUX("AIF2DAC Mux", SND_SOC_NOPM, 0, 0, &aif2dac_mux),
1282SND_SOC_DAPM_MUX("AIF2ADC Mux", SND_SOC_NOPM, 0, 0, &aif2adc_mux), 1419SND_SOC_DAPM_MUX("AIF2ADC Mux", SND_SOC_NOPM, 0, 0, &aif2adc_mux),
1283 1420
1284SND_SOC_DAPM_AIF_IN("AIF3DACDAT", "AIF3 Playback", 0, SND_SOC_NOPM, 0, 0), 1421SND_SOC_DAPM_AIF_IN("AIF3DACDAT", "AIF3 Playback", 0, SND_SOC_NOPM, 0, 0),
1285SND_SOC_DAPM_AIF_IN("AIF3ADCDAT", "AIF3 Capture", 0, SND_SOC_NOPM, 0, 0), 1422SND_SOC_DAPM_AIF_OUT("AIF3ADCDAT", "AIF3 Capture", 0, SND_SOC_NOPM, 0, 0),
1286 1423
1287SND_SOC_DAPM_SUPPLY("TOCLK", WM8994_CLOCKING_1, 4, 0, NULL, 0), 1424SND_SOC_DAPM_SUPPLY("TOCLK", WM8994_CLOCKING_1, 4, 0, NULL, 0),
1288 1425
@@ -1525,6 +1662,8 @@ static const struct snd_soc_dapm_route wm8994_revd_intercon[] = {
1525static const struct snd_soc_dapm_route wm8994_intercon[] = { 1662static const struct snd_soc_dapm_route wm8994_intercon[] = {
1526 { "AIF2DACL", NULL, "AIF2DAC Mux" }, 1663 { "AIF2DACL", NULL, "AIF2DAC Mux" },
1527 { "AIF2DACR", NULL, "AIF2DAC Mux" }, 1664 { "AIF2DACR", NULL, "AIF2DAC Mux" },
1665 { "MICBIAS1", NULL, "VMID" },
1666 { "MICBIAS2", NULL, "VMID" },
1528}; 1667};
1529 1668
1530static const struct snd_soc_dapm_route wm8958_intercon[] = { 1669static const struct snd_soc_dapm_route wm8958_intercon[] = {
@@ -1629,10 +1768,12 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
1629 unsigned int freq_in, unsigned int freq_out) 1768 unsigned int freq_in, unsigned int freq_out)
1630{ 1769{
1631 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 1770 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
1771 struct wm8994 *control = codec->control_data;
1632 int reg_offset, ret; 1772 int reg_offset, ret;
1633 struct fll_div fll; 1773 struct fll_div fll;
1634 u16 reg, aif1, aif2; 1774 u16 reg, aif1, aif2;
1635 unsigned long timeout; 1775 unsigned long timeout;
1776 bool was_enabled;
1636 1777
1637 aif1 = snd_soc_read(codec, WM8994_AIF1_CLOCKING_1) 1778 aif1 = snd_soc_read(codec, WM8994_AIF1_CLOCKING_1)
1638 & WM8994_AIF1CLK_ENA; 1779 & WM8994_AIF1CLK_ENA;
@@ -1653,6 +1794,9 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
1653 return -EINVAL; 1794 return -EINVAL;
1654 } 1795 }
1655 1796
1797 reg = snd_soc_read(codec, WM8994_FLL1_CONTROL_1 + reg_offset);
1798 was_enabled = reg & WM8994_FLL1_ENA;
1799
1656 switch (src) { 1800 switch (src) {
1657 case 0: 1801 case 0:
1658 /* Allow no source specification when stopping */ 1802 /* Allow no source specification when stopping */
@@ -1719,6 +1863,21 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
1719 1863
1720 /* Enable (with fractional mode if required) */ 1864 /* Enable (with fractional mode if required) */
1721 if (freq_out) { 1865 if (freq_out) {
1866 /* Enable VMID if we need it */
1867 if (!was_enabled) {
1868 switch (control->type) {
1869 case WM8994:
1870 vmid_reference(codec);
1871 break;
1872 case WM8958:
1873 if (wm8994->revision < 1)
1874 vmid_reference(codec);
1875 break;
1876 default:
1877 break;
1878 }
1879 }
1880
1722 if (fll.k) 1881 if (fll.k)
1723 reg = WM8994_FLL1_ENA | WM8994_FLL1_FRAC; 1882 reg = WM8994_FLL1_ENA | WM8994_FLL1_FRAC;
1724 else 1883 else
@@ -1736,6 +1895,20 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
1736 } else { 1895 } else {
1737 msleep(5); 1896 msleep(5);
1738 } 1897 }
1898 } else {
1899 if (was_enabled) {
1900 switch (control->type) {
1901 case WM8994:
1902 vmid_dereference(codec);
1903 break;
1904 case WM8958:
1905 if (wm8994->revision < 1)
1906 vmid_dereference(codec);
1907 break;
1908 default:
1909 break;
1910 }
1911 }
1739 } 1912 }
1740 1913
1741 wm8994->fll[id].in = freq_in; 1914 wm8994->fll[id].in = freq_in;
@@ -1852,9 +2025,6 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
1852 break; 2025 break;
1853 2026
1854 case SND_SOC_BIAS_PREPARE: 2027 case SND_SOC_BIAS_PREPARE:
1855 /* VMID=2x40k */
1856 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
1857 WM8994_VMID_SEL_MASK, 0x2);
1858 break; 2028 break;
1859 2029
1860 case SND_SOC_BIAS_STANDBY: 2030 case SND_SOC_BIAS_STANDBY:
@@ -1888,6 +2058,15 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
1888 WM8958_CP_DISCH); 2058 WM8958_CP_DISCH);
1889 } 2059 }
1890 break; 2060 break;
2061
2062 case WM1811:
2063 if (wm8994->revision < 2) {
2064 snd_soc_write(codec, 0x102, 0x3);
2065 snd_soc_write(codec, 0x5d, 0x7e);
2066 snd_soc_write(codec, 0x5e, 0x0);
2067 snd_soc_write(codec, 0x102, 0x0);
2068 }
2069 break;
1891 } 2070 }
1892 2071
1893 /* Discharge LINEOUT1 & 2 */ 2072 /* Discharge LINEOUT1 & 2 */
@@ -1896,65 +2075,13 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
1896 WM8994_LINEOUT2_DISCH, 2075 WM8994_LINEOUT2_DISCH,
1897 WM8994_LINEOUT1_DISCH | 2076 WM8994_LINEOUT1_DISCH |
1898 WM8994_LINEOUT2_DISCH); 2077 WM8994_LINEOUT2_DISCH);
1899
1900 /* Startup bias, VMID ramp & buffer */
1901 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
1902 WM8994_STARTUP_BIAS_ENA |
1903 WM8994_VMID_BUF_ENA |
1904 WM8994_VMID_RAMP_MASK,
1905 WM8994_STARTUP_BIAS_ENA |
1906 WM8994_VMID_BUF_ENA |
1907 (0x11 << WM8994_VMID_RAMP_SHIFT));
1908
1909 /* Main bias enable, VMID=2x40k */
1910 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
1911 WM8994_BIAS_ENA |
1912 WM8994_VMID_SEL_MASK,
1913 WM8994_BIAS_ENA | 0x2);
1914
1915 msleep(20);
1916 } 2078 }
1917 2079
1918 /* VMID=2x500k */
1919 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
1920 WM8994_VMID_SEL_MASK, 0x4);
1921 2080
1922 break; 2081 break;
1923 2082
1924 case SND_SOC_BIAS_OFF: 2083 case SND_SOC_BIAS_OFF:
1925 if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) { 2084 if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) {
1926 /* Switch over to startup biases */
1927 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
1928 WM8994_BIAS_SRC |
1929 WM8994_STARTUP_BIAS_ENA |
1930 WM8994_VMID_BUF_ENA |
1931 WM8994_VMID_RAMP_MASK,
1932 WM8994_BIAS_SRC |
1933 WM8994_STARTUP_BIAS_ENA |
1934 WM8994_VMID_BUF_ENA |
1935 (1 << WM8994_VMID_RAMP_SHIFT));
1936
1937 /* Disable main biases */
1938 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
1939 WM8994_BIAS_ENA |
1940 WM8994_VMID_SEL_MASK, 0);
1941
1942 /* Discharge line */
1943 snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
1944 WM8994_LINEOUT1_DISCH |
1945 WM8994_LINEOUT2_DISCH,
1946 WM8994_LINEOUT1_DISCH |
1947 WM8994_LINEOUT2_DISCH);
1948
1949 msleep(5);
1950
1951 /* Switch off startup biases */
1952 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
1953 WM8994_BIAS_SRC |
1954 WM8994_STARTUP_BIAS_ENA |
1955 WM8994_VMID_BUF_ENA |
1956 WM8994_VMID_RAMP_MASK, 0);
1957
1958 wm8994->cur_fw = NULL; 2085 wm8994->cur_fw = NULL;
1959 2086
1960 pm_runtime_put(codec->dev); 2087 pm_runtime_put(codec->dev);
@@ -2055,10 +2182,18 @@ static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
2055 2182
2056 /* The AIF2 format configuration needs to be mirrored to AIF3 2183 /* The AIF2 format configuration needs to be mirrored to AIF3
2057 * on WM8958 if it's in use so just do it all the time. */ 2184 * on WM8958 if it's in use so just do it all the time. */
2058 if (control->type == WM8958 && dai->id == 2) 2185 switch (control->type) {
2059 snd_soc_update_bits(codec, WM8958_AIF3_CONTROL_1, 2186 case WM1811:
2060 WM8994_AIF1_LRCLK_INV | 2187 case WM8958:
2061 WM8958_AIF3_FMT_MASK, aif1); 2188 if (dai->id == 2)
2189 snd_soc_update_bits(codec, WM8958_AIF3_CONTROL_1,
2190 WM8994_AIF1_LRCLK_INV |
2191 WM8958_AIF3_FMT_MASK, aif1);
2192 break;
2193
2194 default:
2195 break;
2196 }
2062 2197
2063 snd_soc_update_bits(codec, aif1_reg, 2198 snd_soc_update_bits(codec, aif1_reg,
2064 WM8994_AIF1_BCLK_INV | WM8994_AIF1_LRCLK_INV | 2199 WM8994_AIF1_BCLK_INV | WM8994_AIF1_LRCLK_INV |
@@ -2100,7 +2235,6 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
2100 struct snd_soc_dai *dai) 2235 struct snd_soc_dai *dai)
2101{ 2236{
2102 struct snd_soc_codec *codec = dai->codec; 2237 struct snd_soc_codec *codec = dai->codec;
2103 struct wm8994 *control = codec->control_data;
2104 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 2238 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
2105 int aif1_reg; 2239 int aif1_reg;
2106 int aif2_reg; 2240 int aif2_reg;
@@ -2143,14 +2277,6 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
2143 dev_dbg(codec->dev, "AIF2 using split LRCLK\n"); 2277 dev_dbg(codec->dev, "AIF2 using split LRCLK\n");
2144 } 2278 }
2145 break; 2279 break;
2146 case 3:
2147 switch (control->type) {
2148 case WM8958:
2149 aif1_reg = WM8958_AIF3_CONTROL_1;
2150 break;
2151 default:
2152 return 0;
2153 }
2154 default: 2280 default:
2155 return -EINVAL; 2281 return -EINVAL;
2156 } 2282 }
@@ -2271,6 +2397,7 @@ static int wm8994_aif3_hw_params(struct snd_pcm_substream *substream,
2271 switch (dai->id) { 2397 switch (dai->id) {
2272 case 3: 2398 case 3:
2273 switch (control->type) { 2399 switch (control->type) {
2400 case WM1811:
2274 case WM8958: 2401 case WM8958:
2275 aif1_reg = WM8958_AIF3_CONTROL_1; 2402 aif1_reg = WM8958_AIF3_CONTROL_1;
2276 break; 2403 break;
@@ -2311,7 +2438,7 @@ static void wm8994_aif_shutdown(struct snd_pcm_substream *substream,
2311 rate_reg = WM8994_AIF1_RATE; 2438 rate_reg = WM8994_AIF1_RATE;
2312 break; 2439 break;
2313 case 2: 2440 case 2:
2314 rate_reg = WM8994_AIF1_RATE; 2441 rate_reg = WM8994_AIF2_RATE;
2315 break; 2442 break;
2316 default: 2443 default:
2317 break; 2444 break;
@@ -2384,6 +2511,21 @@ static int wm8994_set_tristate(struct snd_soc_dai *codec_dai, int tristate)
2384 return snd_soc_update_bits(codec, reg, mask, val); 2511 return snd_soc_update_bits(codec, reg, mask, val);
2385} 2512}
2386 2513
2514static int wm8994_aif2_probe(struct snd_soc_dai *dai)
2515{
2516 struct snd_soc_codec *codec = dai->codec;
2517
2518 /* Disable the pulls on the AIF if we're using it to save power. */
2519 snd_soc_update_bits(codec, WM8994_GPIO_3,
2520 WM8994_GPN_PU | WM8994_GPN_PD, 0);
2521 snd_soc_update_bits(codec, WM8994_GPIO_4,
2522 WM8994_GPN_PU | WM8994_GPN_PD, 0);
2523 snd_soc_update_bits(codec, WM8994_GPIO_5,
2524 WM8994_GPN_PU | WM8994_GPN_PD, 0);
2525
2526 return 0;
2527}
2528
2387#define WM8994_RATES SNDRV_PCM_RATE_8000_96000 2529#define WM8994_RATES SNDRV_PCM_RATE_8000_96000
2388 2530
2389#define WM8994_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 2531#define WM8994_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
@@ -2451,6 +2593,7 @@ static struct snd_soc_dai_driver wm8994_dai[] = {
2451 .rates = WM8994_RATES, 2593 .rates = WM8994_RATES,
2452 .formats = WM8994_FORMATS, 2594 .formats = WM8994_FORMATS,
2453 }, 2595 },
2596 .probe = wm8994_aif2_probe,
2454 .ops = &wm8994_aif2_dai_ops, 2597 .ops = &wm8994_aif2_dai_ops,
2455 }, 2598 },
2456 { 2599 {
@@ -2485,6 +2628,7 @@ static int wm8994_suspend(struct snd_soc_codec *codec, pm_message_t state)
2485 case WM8994: 2628 case WM8994:
2486 snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, 0); 2629 snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, 0);
2487 break; 2630 break;
2631 case WM1811:
2488 case WM8958: 2632 case WM8958:
2489 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, 2633 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
2490 WM8958_MICD_ENA, 0); 2634 WM8958_MICD_ENA, 0);
@@ -2553,6 +2697,7 @@ static int wm8994_resume(struct snd_soc_codec *codec)
2553 snd_soc_update_bits(codec, WM8994_MICBIAS, 2697 snd_soc_update_bits(codec, WM8994_MICBIAS,
2554 WM8994_MICD_ENA, WM8994_MICD_ENA); 2698 WM8994_MICD_ENA, WM8994_MICD_ENA);
2555 break; 2699 break;
2700 case WM1811:
2556 case WM8958: 2701 case WM8958:
2557 if (wm8994->jack_cb) 2702 if (wm8994->jack_cb)
2558 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, 2703 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
@@ -2851,8 +2996,13 @@ int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
2851 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 2996 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
2852 struct wm8994 *control = codec->control_data; 2997 struct wm8994 *control = codec->control_data;
2853 2998
2854 if (control->type != WM8958) 2999 switch (control->type) {
3000 case WM1811:
3001 case WM8958:
3002 break;
3003 default:
2855 return -EINVAL; 3004 return -EINVAL;
3005 }
2856 3006
2857 if (jack) { 3007 if (jack) {
2858 if (!cb) { 3008 if (!cb) {
@@ -2916,6 +3066,24 @@ static irqreturn_t wm8994_fifo_error(int irq, void *data)
2916 return IRQ_HANDLED; 3066 return IRQ_HANDLED;
2917} 3067}
2918 3068
3069static irqreturn_t wm8994_temp_warn(int irq, void *data)
3070{
3071 struct snd_soc_codec *codec = data;
3072
3073 dev_err(codec->dev, "Thermal warning\n");
3074
3075 return IRQ_HANDLED;
3076}
3077
3078static irqreturn_t wm8994_temp_shut(int irq, void *data)
3079{
3080 struct snd_soc_codec *codec = data;
3081
3082 dev_crit(codec->dev, "Thermal shutdown\n");
3083
3084 return IRQ_HANDLED;
3085}
3086
2919static int wm8994_codec_probe(struct snd_soc_codec *codec) 3087static int wm8994_codec_probe(struct snd_soc_codec *codec)
2920{ 3088{
2921 struct wm8994 *control; 3089 struct wm8994 *control;
@@ -2972,13 +3140,14 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
2972 switch (wm8994->revision) { 3140 switch (wm8994->revision) {
2973 case 2: 3141 case 2:
2974 case 3: 3142 case 3:
2975 wm8994->hubs.dcs_codes = -5; 3143 wm8994->hubs.dcs_codes_l = -5;
3144 wm8994->hubs.dcs_codes_r = -5;
2976 wm8994->hubs.hp_startup_mode = 1; 3145 wm8994->hubs.hp_startup_mode = 1;
2977 wm8994->hubs.dcs_readback_mode = 1; 3146 wm8994->hubs.dcs_readback_mode = 1;
2978 wm8994->hubs.series_startup = 1; 3147 wm8994->hubs.series_startup = 1;
2979 break; 3148 break;
2980 default: 3149 default:
2981 wm8994->hubs.dcs_readback_mode = 1; 3150 wm8994->hubs.dcs_readback_mode = 2;
2982 break; 3151 break;
2983 } 3152 }
2984 break; 3153 break;
@@ -2987,12 +3156,34 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
2987 wm8994->hubs.dcs_readback_mode = 1; 3156 wm8994->hubs.dcs_readback_mode = 1;
2988 break; 3157 break;
2989 3158
3159 case WM1811:
3160 wm8994->hubs.dcs_readback_mode = 2;
3161 wm8994->hubs.no_series_update = 1;
3162
3163 switch (wm8994->revision) {
3164 case 0:
3165 case 1:
3166 wm8994->hubs.dcs_codes_l = -9;
3167 wm8994->hubs.dcs_codes_r = -5;
3168 break;
3169 default:
3170 break;
3171 }
3172
3173 snd_soc_update_bits(codec, WM8994_ANALOGUE_HP_1,
3174 WM1811_HPOUT1_ATTN, WM1811_HPOUT1_ATTN);
3175 break;
3176
2990 default: 3177 default:
2991 break; 3178 break;
2992 } 3179 }
2993 3180
2994 wm8994_request_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR, 3181 wm8994_request_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR,
2995 wm8994_fifo_error, "FIFO error", codec); 3182 wm8994_fifo_error, "FIFO error", codec);
3183 wm8994_request_irq(wm8994->control_data, WM8994_IRQ_TEMP_WARN,
3184 wm8994_temp_warn, "Thermal warning", codec);
3185 wm8994_request_irq(wm8994->control_data, WM8994_IRQ_TEMP_SHUT,
3186 wm8994_temp_shut, "Thermal shutdown", codec);
2996 3187
2997 ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_DCS_DONE, 3188 ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_DCS_DONE,
2998 wm_hubs_dcs_done, "DC servo done", 3189 wm_hubs_dcs_done, "DC servo done",
@@ -3043,6 +3234,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3043 break; 3234 break;
3044 3235
3045 case WM8958: 3236 case WM8958:
3237 case WM1811:
3046 if (wm8994->micdet_irq) { 3238 if (wm8994->micdet_irq) {
3047 ret = request_threaded_irq(wm8994->micdet_irq, NULL, 3239 ret = request_threaded_irq(wm8994->micdet_irq, NULL,
3048 wm8958_mic_irq, 3240 wm8958_mic_irq,
@@ -3205,6 +3397,19 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3205 ARRAY_SIZE(wm8994_dac_widgets)); 3397 ARRAY_SIZE(wm8994_dac_widgets));
3206 } 3398 }
3207 break; 3399 break;
3400
3401 case WM1811:
3402 snd_soc_add_controls(codec, wm8958_snd_controls,
3403 ARRAY_SIZE(wm8958_snd_controls));
3404 snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets,
3405 ARRAY_SIZE(wm8958_dapm_widgets));
3406 snd_soc_dapm_new_controls(dapm, wm8994_lateclk_widgets,
3407 ARRAY_SIZE(wm8994_lateclk_widgets));
3408 snd_soc_dapm_new_controls(dapm, wm8994_adc_widgets,
3409 ARRAY_SIZE(wm8994_adc_widgets));
3410 snd_soc_dapm_new_controls(dapm, wm8994_dac_widgets,
3411 ARRAY_SIZE(wm8994_dac_widgets));
3412 break;
3208 } 3413 }
3209 3414
3210 3415
@@ -3241,6 +3446,12 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3241 3446
3242 wm8958_dsp2_init(codec); 3447 wm8958_dsp2_init(codec);
3243 break; 3448 break;
3449 case WM1811:
3450 snd_soc_dapm_add_routes(dapm, wm8994_lateclk_intercon,
3451 ARRAY_SIZE(wm8994_lateclk_intercon));
3452 snd_soc_dapm_add_routes(dapm, wm8958_intercon,
3453 ARRAY_SIZE(wm8958_intercon));
3454 break;
3244 } 3455 }
3245 3456
3246 return 0; 3457 return 0;
@@ -3257,6 +3468,8 @@ err_irq:
3257 wm8994_free_irq(codec->control_data, WM8994_IRQ_DCS_DONE, 3468 wm8994_free_irq(codec->control_data, WM8994_IRQ_DCS_DONE,
3258 &wm8994->hubs); 3469 &wm8994->hubs);
3259 wm8994_free_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR, codec); 3470 wm8994_free_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR, codec);
3471 wm8994_free_irq(codec->control_data, WM8994_IRQ_TEMP_SHUT, codec);
3472 wm8994_free_irq(codec->control_data, WM8994_IRQ_TEMP_WARN, codec);
3260err: 3473err:
3261 kfree(wm8994); 3474 kfree(wm8994);
3262 return ret; 3475 return ret;
@@ -3279,6 +3492,8 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec)
3279 wm8994_free_irq(codec->control_data, WM8994_IRQ_DCS_DONE, 3492 wm8994_free_irq(codec->control_data, WM8994_IRQ_DCS_DONE,
3280 &wm8994->hubs); 3493 &wm8994->hubs);
3281 wm8994_free_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR, codec); 3494 wm8994_free_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR, codec);
3495 wm8994_free_irq(codec->control_data, WM8994_IRQ_TEMP_SHUT, codec);
3496 wm8994_free_irq(codec->control_data, WM8994_IRQ_TEMP_WARN, codec);
3282 3497
3283 switch (control->type) { 3498 switch (control->type) {
3284 case WM8994: 3499 case WM8994:
@@ -3292,6 +3507,7 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec)
3292 wm8994); 3507 wm8994);
3293 break; 3508 break;
3294 3509
3510 case WM1811:
3295 case WM8958: 3511 case WM8958:
3296 if (wm8994->micdet_irq) 3512 if (wm8994->micdet_irq)
3297 free_irq(wm8994->micdet_irq, wm8994); 3513 free_irq(wm8994->micdet_irq, wm8994);
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h
index 1ab2266039f..f4f1355efc8 100644
--- a/sound/soc/codecs/wm8994.h
+++ b/sound/soc/codecs/wm8994.h
@@ -83,6 +83,8 @@ struct wm8994_priv {
83 struct completion fll_locked[2]; 83 struct completion fll_locked[2];
84 bool fll_locked_irq; 84 bool fll_locked_irq;
85 85
86 int vmid_refcount;
87
86 int dac_rates[2]; 88 int dac_rates[2];
87 int lrclk_shared[2]; 89 int lrclk_shared[2];
88 90
diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c
index 5ad873fda81..78eeb21e669 100644
--- a/sound/soc/codecs/wm8995.c
+++ b/sound/soc/codecs/wm8995.c
@@ -485,7 +485,7 @@ static int configure_aif_clock(struct snd_soc_codec *codec, int aif)
485static int configure_clock(struct snd_soc_codec *codec) 485static int configure_clock(struct snd_soc_codec *codec)
486{ 486{
487 struct wm8995_priv *wm8995; 487 struct wm8995_priv *wm8995;
488 int old, new; 488 int change, new;
489 489
490 wm8995 = snd_soc_codec_get_drvdata(codec); 490 wm8995 = snd_soc_codec_get_drvdata(codec);
491 491
@@ -509,15 +509,11 @@ static int configure_clock(struct snd_soc_codec *codec)
509 else 509 else
510 new = 0; 510 new = 0;
511 511
512 old = snd_soc_read(codec, WM8995_CLOCKING_1) & WM8995_SYSCLK_SRC; 512 change = snd_soc_update_bits(codec, WM8995_CLOCKING_1,
513 513 WM8995_SYSCLK_SRC_MASK, new);
514 /* If there's no change then we're done. */ 514 if (!change)
515 if (old == new)
516 return 0; 515 return 0;
517 516
518 snd_soc_update_bits(codec, WM8995_CLOCKING_1,
519 WM8995_SYSCLK_SRC_MASK, new);
520
521 snd_soc_dapm_sync(&codec->dapm); 517 snd_soc_dapm_sync(&codec->dapm);
522 518
523 return 0; 519 return 0;
@@ -1573,11 +1569,16 @@ static int wm8995_resume(struct snd_soc_codec *codec)
1573static int wm8995_remove(struct snd_soc_codec *codec) 1569static int wm8995_remove(struct snd_soc_codec *codec)
1574{ 1570{
1575 struct wm8995_priv *wm8995; 1571 struct wm8995_priv *wm8995;
1576 struct i2c_client *i2c; 1572 int i;
1577 1573
1578 i2c = container_of(codec->dev, struct i2c_client, dev);
1579 wm8995 = snd_soc_codec_get_drvdata(codec); 1574 wm8995 = snd_soc_codec_get_drvdata(codec);
1580 wm8995_set_bias_level(codec, SND_SOC_BIAS_OFF); 1575 wm8995_set_bias_level(codec, SND_SOC_BIAS_OFF);
1576
1577 for (i = 0; i < ARRAY_SIZE(wm8995->supplies); ++i)
1578 regulator_unregister_notifier(wm8995->supplies[i].consumer,
1579 &wm8995->disable_nb[i]);
1580
1581 regulator_bulk_free(ARRAY_SIZE(wm8995->supplies), wm8995->supplies);
1581 return 0; 1582 return 0;
1582} 1583}
1583 1584
@@ -1642,6 +1643,7 @@ static int wm8995_probe(struct snd_soc_codec *codec)
1642 1643
1643 if (ret != 0x8995) { 1644 if (ret != 0x8995) {
1644 dev_err(codec->dev, "Invalid device ID: %#x\n", ret); 1645 dev_err(codec->dev, "Invalid device ID: %#x\n", ret);
1646 ret = -EINVAL;
1645 goto err_reg_enable; 1647 goto err_reg_enable;
1646 } 1648 }
1647 1649
diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c
index 0cdb9d10567..645c980d6b8 100644
--- a/sound/soc/codecs/wm8996.c
+++ b/sound/soc/codecs/wm8996.c
@@ -41,12 +41,11 @@
41#define HPOUT2L 4 41#define HPOUT2L 4
42#define HPOUT2R 8 42#define HPOUT2R 8
43 43
44#define WM8996_NUM_SUPPLIES 4 44#define WM8996_NUM_SUPPLIES 3
45static const char *wm8996_supply_names[WM8996_NUM_SUPPLIES] = { 45static const char *wm8996_supply_names[WM8996_NUM_SUPPLIES] = {
46 "DBVDD", 46 "DBVDD",
47 "AVDD1", 47 "AVDD1",
48 "AVDD2", 48 "AVDD2",
49 "CPVDD",
50}; 49};
51 50
52struct wm8996_priv { 51struct wm8996_priv {
@@ -71,6 +70,8 @@ struct wm8996_priv {
71 70
72 struct regulator_bulk_data supplies[WM8996_NUM_SUPPLIES]; 71 struct regulator_bulk_data supplies[WM8996_NUM_SUPPLIES];
73 struct notifier_block disable_nb[WM8996_NUM_SUPPLIES]; 72 struct notifier_block disable_nb[WM8996_NUM_SUPPLIES];
73 struct regulator *cpvdd;
74 int bg_ena;
74 75
75 struct wm8996_pdata pdata; 76 struct wm8996_pdata pdata;
76 77
@@ -112,7 +113,6 @@ static int wm8996_regulator_event_##n(struct notifier_block *nb, \
112WM8996_REGULATOR_EVENT(0) 113WM8996_REGULATOR_EVENT(0)
113WM8996_REGULATOR_EVENT(1) 114WM8996_REGULATOR_EVENT(1)
114WM8996_REGULATOR_EVENT(2) 115WM8996_REGULATOR_EVENT(2)
115WM8996_REGULATOR_EVENT(3)
116 116
117static const u16 wm8996_reg[WM8996_MAX_REGISTER] = { 117static const u16 wm8996_reg[WM8996_MAX_REGISTER] = {
118 [WM8996_SOFTWARE_RESET] = 0x8996, 118 [WM8996_SOFTWARE_RESET] = 0x8996,
@@ -414,6 +414,7 @@ static const DECLARE_TLV_DB_SCALE(out_digital_tlv, -1200, 150, 0);
414static const DECLARE_TLV_DB_SCALE(out_tlv, -900, 75, 0); 414static const DECLARE_TLV_DB_SCALE(out_tlv, -900, 75, 0);
415static const DECLARE_TLV_DB_SCALE(spk_tlv, -900, 150, 0); 415static const DECLARE_TLV_DB_SCALE(spk_tlv, -900, 150, 0);
416static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); 416static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
417static const DECLARE_TLV_DB_SCALE(threedstereo_tlv, -1600, 183, 1);
417 418
418static const char *sidetone_hpf_text[] = { 419static const char *sidetone_hpf_text[] = {
419 "2.9kHz", "1.5kHz", "735Hz", "403Hz", "196Hz", "98Hz", "49Hz" 420 "2.9kHz", "1.5kHz", "735Hz", "403Hz", "196Hz", "98Hz", "49Hz"
@@ -608,6 +609,14 @@ SOC_SINGLE("DAC High Performance Switch", WM8996_OVERSAMPLING, 0, 1, 0),
608SOC_SINGLE("DAC Soft Mute Switch", WM8996_DAC_SOFTMUTE, 1, 1, 0), 609SOC_SINGLE("DAC Soft Mute Switch", WM8996_DAC_SOFTMUTE, 1, 1, 0),
609SOC_SINGLE("DAC Slow Soft Mute Switch", WM8996_DAC_SOFTMUTE, 0, 1, 0), 610SOC_SINGLE("DAC Slow Soft Mute Switch", WM8996_DAC_SOFTMUTE, 0, 1, 0),
610 611
612SOC_SINGLE("DSP1 3D Stereo Switch", WM8996_DSP1_RX_FILTERS_2, 8, 1, 0),
613SOC_SINGLE("DSP2 3D Stereo Switch", WM8996_DSP2_RX_FILTERS_2, 8, 1, 0),
614
615SOC_SINGLE_TLV("DSP1 3D Stereo Volume", WM8996_DSP1_RX_FILTERS_2, 10, 15,
616 0, threedstereo_tlv),
617SOC_SINGLE_TLV("DSP2 3D Stereo Volume", WM8996_DSP2_RX_FILTERS_2, 10, 15,
618 0, threedstereo_tlv),
619
611SOC_DOUBLE_TLV("Digital Output 1 Volume", WM8996_DAC1_HPOUT1_VOLUME, 0, 4, 620SOC_DOUBLE_TLV("Digital Output 1 Volume", WM8996_DAC1_HPOUT1_VOLUME, 0, 4,
612 8, 0, out_digital_tlv), 621 8, 0, out_digital_tlv),
613SOC_DOUBLE_TLV("Digital Output 2 Volume", WM8996_DAC2_HPOUT2_VOLUME, 0, 4, 622SOC_DOUBLE_TLV("Digital Output 2 Volume", WM8996_DAC2_HPOUT2_VOLUME, 0, 4,
@@ -632,6 +641,14 @@ SOC_DOUBLE_R("Speaker ZC Switch", WM8996_LEFT_PDM_SPEAKER,
632 641
633SOC_SINGLE("DSP1 EQ Switch", WM8996_DSP1_RX_EQ_GAINS_1, 0, 1, 0), 642SOC_SINGLE("DSP1 EQ Switch", WM8996_DSP1_RX_EQ_GAINS_1, 0, 1, 0),
634SOC_SINGLE("DSP2 EQ Switch", WM8996_DSP2_RX_EQ_GAINS_1, 0, 1, 0), 643SOC_SINGLE("DSP2 EQ Switch", WM8996_DSP2_RX_EQ_GAINS_1, 0, 1, 0),
644
645SOC_SINGLE("DSP1 DRC TXL Switch", WM8996_DSP1_DRC_1, 0, 1, 0),
646SOC_SINGLE("DSP1 DRC TXR Switch", WM8996_DSP1_DRC_1, 1, 1, 0),
647SOC_SINGLE("DSP1 DRC RX Switch", WM8996_DSP1_DRC_1, 2, 1, 0),
648
649SOC_SINGLE("DSP2 DRC TXL Switch", WM8996_DSP2_DRC_1, 0, 1, 0),
650SOC_SINGLE("DSP2 DRC TXR Switch", WM8996_DSP2_DRC_1, 1, 1, 0),
651SOC_SINGLE("DSP2 DRC RX Switch", WM8996_DSP2_DRC_1, 2, 1, 0),
635}; 652};
636 653
637static const struct snd_kcontrol_new wm8996_eq_controls[] = { 654static const struct snd_kcontrol_new wm8996_eq_controls[] = {
@@ -658,19 +675,75 @@ SOC_SINGLE_TLV("DSP2 EQ B5 Volume", WM8996_DSP2_RX_EQ_GAINS_2, 6, 31, 0,
658 eq_tlv), 675 eq_tlv),
659}; 676};
660 677
678static void wm8996_bg_enable(struct snd_soc_codec *codec)
679{
680 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
681
682 wm8996->bg_ena++;
683 if (wm8996->bg_ena == 1) {
684 snd_soc_update_bits(codec, WM8996_POWER_MANAGEMENT_1,
685 WM8996_BG_ENA, WM8996_BG_ENA);
686 msleep(2);
687 }
688}
689
690static void wm8996_bg_disable(struct snd_soc_codec *codec)
691{
692 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
693
694 wm8996->bg_ena--;
695 if (!wm8996->bg_ena)
696 snd_soc_update_bits(codec, WM8996_POWER_MANAGEMENT_1,
697 WM8996_BG_ENA, 0);
698}
699
700static int bg_event(struct snd_soc_dapm_widget *w,
701 struct snd_kcontrol *kcontrol, int event)
702{
703 struct snd_soc_codec *codec = w->codec;
704 int ret = 0;
705
706 switch (event) {
707 case SND_SOC_DAPM_PRE_PMU:
708 wm8996_bg_enable(codec);
709 break;
710 case SND_SOC_DAPM_POST_PMD:
711 wm8996_bg_disable(codec);
712 break;
713 default:
714 BUG();
715 ret = -EINVAL;
716 }
717
718 return ret;
719}
720
661static int cp_event(struct snd_soc_dapm_widget *w, 721static int cp_event(struct snd_soc_dapm_widget *w,
662 struct snd_kcontrol *kcontrol, int event) 722 struct snd_kcontrol *kcontrol, int event)
663{ 723{
724 struct snd_soc_codec *codec = w->codec;
725 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
726 int ret = 0;
727
664 switch (event) { 728 switch (event) {
729 case SND_SOC_DAPM_PRE_PMU:
730 ret = regulator_enable(wm8996->cpvdd);
731 if (ret != 0)
732 dev_err(codec->dev, "Failed to enable CPVDD: %d\n",
733 ret);
734 break;
665 case SND_SOC_DAPM_POST_PMU: 735 case SND_SOC_DAPM_POST_PMU:
666 msleep(5); 736 msleep(5);
667 break; 737 break;
738 case SND_SOC_DAPM_POST_PMD:
739 regulator_disable_deferred(wm8996->cpvdd, 20);
740 break;
668 default: 741 default:
669 BUG(); 742 BUG();
670 return -EINVAL; 743 ret = -EINVAL;
671 } 744 }
672 745
673 return 0; 746 return ret;
674} 747}
675 748
676static int rmv_short_event(struct snd_soc_dapm_widget *w, 749static int rmv_short_event(struct snd_soc_dapm_widget *w,
@@ -698,7 +771,7 @@ static void wait_for_dc_servo(struct snd_soc_codec *codec, u16 mask)
698{ 771{
699 struct i2c_client *i2c = to_i2c_client(codec->dev); 772 struct i2c_client *i2c = to_i2c_client(codec->dev);
700 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); 773 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
701 int i, ret; 774 int ret;
702 unsigned long timeout = 200; 775 unsigned long timeout = 200;
703 776
704 snd_soc_write(codec, WM8996_DC_SERVO_2, mask); 777 snd_soc_write(codec, WM8996_DC_SERVO_2, mask);
@@ -713,15 +786,12 @@ static void wait_for_dc_servo(struct snd_soc_codec *codec, u16 mask)
713 786
714 } else { 787 } else {
715 msleep(1); 788 msleep(1);
716 if (--i) { 789 timeout--;
717 timeout = 0;
718 break;
719 }
720 } 790 }
721 791
722 ret = snd_soc_read(codec, WM8996_DC_SERVO_2); 792 ret = snd_soc_read(codec, WM8996_DC_SERVO_2);
723 dev_dbg(codec->dev, "DC servo state: %x\n", ret); 793 dev_dbg(codec->dev, "DC servo state: %x\n", ret);
724 } while (ret & mask); 794 } while (timeout && ret & mask);
725 795
726 if (timeout == 0) 796 if (timeout == 0)
727 dev_err(codec->dev, "DC servo timed out for %x\n", mask); 797 dev_err(codec->dev, "DC servo timed out for %x\n", mask);
@@ -979,9 +1049,12 @@ SND_SOC_DAPM_SUPPLY_S("SYSCLK", 1, WM8996_AIF_CLOCKING_1, 0, 0, NULL, 0),
979SND_SOC_DAPM_SUPPLY_S("SYSDSPCLK", 2, WM8996_CLOCKING_1, 1, 0, NULL, 0), 1049SND_SOC_DAPM_SUPPLY_S("SYSDSPCLK", 2, WM8996_CLOCKING_1, 1, 0, NULL, 0),
980SND_SOC_DAPM_SUPPLY_S("AIFCLK", 2, WM8996_CLOCKING_1, 2, 0, NULL, 0), 1050SND_SOC_DAPM_SUPPLY_S("AIFCLK", 2, WM8996_CLOCKING_1, 2, 0, NULL, 0),
981SND_SOC_DAPM_SUPPLY_S("Charge Pump", 2, WM8996_CHARGE_PUMP_1, 15, 0, cp_event, 1051SND_SOC_DAPM_SUPPLY_S("Charge Pump", 2, WM8996_CHARGE_PUMP_1, 15, 0, cp_event,
982 SND_SOC_DAPM_POST_PMU), 1052 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
983 1053SND_SOC_DAPM_SUPPLY("Bandgap", SND_SOC_NOPM, 0, 0, bg_event,
1054 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
984SND_SOC_DAPM_SUPPLY("LDO2", WM8996_POWER_MANAGEMENT_2, 1, 0, NULL, 0), 1055SND_SOC_DAPM_SUPPLY("LDO2", WM8996_POWER_MANAGEMENT_2, 1, 0, NULL, 0),
1056SND_SOC_DAPM_SUPPLY("MICB1 Audio", WM8996_MICBIAS_1, 4, 1, NULL, 0),
1057SND_SOC_DAPM_SUPPLY("MICB2 Audio", WM8996_MICBIAS_2, 4, 1, NULL, 0),
985SND_SOC_DAPM_MICBIAS("MICB2", WM8996_POWER_MANAGEMENT_1, 9, 0), 1058SND_SOC_DAPM_MICBIAS("MICB2", WM8996_POWER_MANAGEMENT_1, 9, 0),
986SND_SOC_DAPM_MICBIAS("MICB1", WM8996_POWER_MANAGEMENT_1, 8, 0), 1059SND_SOC_DAPM_MICBIAS("MICB1", WM8996_POWER_MANAGEMENT_1, 8, 0),
987 1060
@@ -1035,14 +1108,14 @@ SND_SOC_DAPM_DAC("DAC2R", NULL, WM8996_POWER_MANAGEMENT_5, 2, 0),
1035SND_SOC_DAPM_DAC("DAC1L", NULL, WM8996_POWER_MANAGEMENT_5, 1, 0), 1108SND_SOC_DAPM_DAC("DAC1L", NULL, WM8996_POWER_MANAGEMENT_5, 1, 0),
1036SND_SOC_DAPM_DAC("DAC1R", NULL, WM8996_POWER_MANAGEMENT_5, 0, 0), 1109SND_SOC_DAPM_DAC("DAC1R", NULL, WM8996_POWER_MANAGEMENT_5, 0, 0),
1037 1110
1038SND_SOC_DAPM_AIF_IN("AIF2RX1", "AIF2 Playback", 1, 1111SND_SOC_DAPM_AIF_IN("AIF2RX1", "AIF2 Playback", 0,
1039 WM8996_POWER_MANAGEMENT_4, 9, 0), 1112 WM8996_POWER_MANAGEMENT_4, 9, 0),
1040SND_SOC_DAPM_AIF_IN("AIF2RX0", "AIF2 Playback", 2, 1113SND_SOC_DAPM_AIF_IN("AIF2RX0", "AIF2 Playback", 1,
1041 WM8996_POWER_MANAGEMENT_4, 8, 0), 1114 WM8996_POWER_MANAGEMENT_4, 8, 0),
1042 1115
1043SND_SOC_DAPM_AIF_IN("AIF2TX1", "AIF2 Capture", 1, 1116SND_SOC_DAPM_AIF_OUT("AIF2TX1", "AIF2 Capture", 0,
1044 WM8996_POWER_MANAGEMENT_6, 9, 0), 1117 WM8996_POWER_MANAGEMENT_6, 9, 0),
1045SND_SOC_DAPM_AIF_IN("AIF2TX0", "AIF2 Capture", 2, 1118SND_SOC_DAPM_AIF_OUT("AIF2TX0", "AIF2 Capture", 1,
1046 WM8996_POWER_MANAGEMENT_6, 8, 0), 1119 WM8996_POWER_MANAGEMENT_6, 8, 0),
1047 1120
1048SND_SOC_DAPM_AIF_IN("AIF1RX5", "AIF1 Playback", 5, 1121SND_SOC_DAPM_AIF_IN("AIF1RX5", "AIF1 Playback", 5,
@@ -1137,17 +1210,23 @@ static const struct snd_soc_dapm_route wm8996_dapm_routes[] = {
1137 { "Charge Pump", NULL, "SYSCLK" }, 1210 { "Charge Pump", NULL, "SYSCLK" },
1138 1211
1139 { "MICB1", NULL, "LDO2" }, 1212 { "MICB1", NULL, "LDO2" },
1213 { "MICB1", NULL, "MICB1 Audio" },
1214 { "MICB1", NULL, "Bandgap" },
1140 { "MICB2", NULL, "LDO2" }, 1215 { "MICB2", NULL, "LDO2" },
1216 { "MICB2", NULL, "MICB2 Audio" },
1217 { "MICB2", NULL, "Bandgap" },
1141 1218
1142 { "IN1L PGA", NULL, "IN2LN" }, 1219 { "IN1L PGA", NULL, "IN2LN" },
1143 { "IN1L PGA", NULL, "IN2LP" }, 1220 { "IN1L PGA", NULL, "IN2LP" },
1144 { "IN1L PGA", NULL, "IN1LN" }, 1221 { "IN1L PGA", NULL, "IN1LN" },
1145 { "IN1L PGA", NULL, "IN1LP" }, 1222 { "IN1L PGA", NULL, "IN1LP" },
1223 { "IN1L PGA", NULL, "Bandgap" },
1146 1224
1147 { "IN1R PGA", NULL, "IN2RN" }, 1225 { "IN1R PGA", NULL, "IN2RN" },
1148 { "IN1R PGA", NULL, "IN2RP" }, 1226 { "IN1R PGA", NULL, "IN2RP" },
1149 { "IN1R PGA", NULL, "IN1RN" }, 1227 { "IN1R PGA", NULL, "IN1RN" },
1150 { "IN1R PGA", NULL, "IN1RP" }, 1228 { "IN1R PGA", NULL, "IN1RP" },
1229 { "IN1R PGA", NULL, "Bandgap" },
1151 1230
1152 { "ADCL", NULL, "IN1L PGA" }, 1231 { "ADCL", NULL, "IN1L PGA" },
1153 1232
@@ -1281,6 +1360,7 @@ static const struct snd_soc_dapm_route wm8996_dapm_routes[] = {
1281 { "DAC2R", NULL, "DAC2R Mixer" }, 1360 { "DAC2R", NULL, "DAC2R Mixer" },
1282 1361
1283 { "HPOUT2L PGA", NULL, "Charge Pump" }, 1362 { "HPOUT2L PGA", NULL, "Charge Pump" },
1363 { "HPOUT2L PGA", NULL, "Bandgap" },
1284 { "HPOUT2L PGA", NULL, "DAC2L" }, 1364 { "HPOUT2L PGA", NULL, "DAC2L" },
1285 { "HPOUT2L_DLY", NULL, "HPOUT2L PGA" }, 1365 { "HPOUT2L_DLY", NULL, "HPOUT2L PGA" },
1286 { "HPOUT2L_DCS", NULL, "HPOUT2L_DLY" }, 1366 { "HPOUT2L_DCS", NULL, "HPOUT2L_DLY" },
@@ -1288,6 +1368,7 @@ static const struct snd_soc_dapm_route wm8996_dapm_routes[] = {
1288 { "HPOUT2L_RMV_SHORT", NULL, "HPOUT2L_OUTP" }, 1368 { "HPOUT2L_RMV_SHORT", NULL, "HPOUT2L_OUTP" },
1289 1369
1290 { "HPOUT2R PGA", NULL, "Charge Pump" }, 1370 { "HPOUT2R PGA", NULL, "Charge Pump" },
1371 { "HPOUT2R PGA", NULL, "Bandgap" },
1291 { "HPOUT2R PGA", NULL, "DAC2R" }, 1372 { "HPOUT2R PGA", NULL, "DAC2R" },
1292 { "HPOUT2R_DLY", NULL, "HPOUT2R PGA" }, 1373 { "HPOUT2R_DLY", NULL, "HPOUT2R PGA" },
1293 { "HPOUT2R_DCS", NULL, "HPOUT2R_DLY" }, 1374 { "HPOUT2R_DCS", NULL, "HPOUT2R_DLY" },
@@ -1295,6 +1376,7 @@ static const struct snd_soc_dapm_route wm8996_dapm_routes[] = {
1295 { "HPOUT2R_RMV_SHORT", NULL, "HPOUT2R_OUTP" }, 1376 { "HPOUT2R_RMV_SHORT", NULL, "HPOUT2R_OUTP" },
1296 1377
1297 { "HPOUT1L PGA", NULL, "Charge Pump" }, 1378 { "HPOUT1L PGA", NULL, "Charge Pump" },
1379 { "HPOUT1L PGA", NULL, "Bandgap" },
1298 { "HPOUT1L PGA", NULL, "DAC1L" }, 1380 { "HPOUT1L PGA", NULL, "DAC1L" },
1299 { "HPOUT1L_DLY", NULL, "HPOUT1L PGA" }, 1381 { "HPOUT1L_DLY", NULL, "HPOUT1L PGA" },
1300 { "HPOUT1L_DCS", NULL, "HPOUT1L_DLY" }, 1382 { "HPOUT1L_DCS", NULL, "HPOUT1L_DLY" },
@@ -1302,6 +1384,7 @@ static const struct snd_soc_dapm_route wm8996_dapm_routes[] = {
1302 { "HPOUT1L_RMV_SHORT", NULL, "HPOUT1L_OUTP" }, 1384 { "HPOUT1L_RMV_SHORT", NULL, "HPOUT1L_OUTP" },
1303 1385
1304 { "HPOUT1R PGA", NULL, "Charge Pump" }, 1386 { "HPOUT1R PGA", NULL, "Charge Pump" },
1387 { "HPOUT1R PGA", NULL, "Bandgap" },
1305 { "HPOUT1R PGA", NULL, "DAC1R" }, 1388 { "HPOUT1R PGA", NULL, "DAC1R" },
1306 { "HPOUT1R_DLY", NULL, "HPOUT1R PGA" }, 1389 { "HPOUT1R_DLY", NULL, "HPOUT1R PGA" },
1307 { "HPOUT1R_DCS", NULL, "HPOUT1R_DLY" }, 1390 { "HPOUT1R_DCS", NULL, "HPOUT1R_DLY" },
@@ -1620,14 +1703,7 @@ static int wm8996_set_bias_level(struct snd_soc_codec *codec,
1620 1703
1621 switch (level) { 1704 switch (level) {
1622 case SND_SOC_BIAS_ON: 1705 case SND_SOC_BIAS_ON:
1623 break;
1624
1625 case SND_SOC_BIAS_PREPARE: 1706 case SND_SOC_BIAS_PREPARE:
1626 if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) {
1627 snd_soc_update_bits(codec, WM8996_POWER_MANAGEMENT_1,
1628 WM8996_BG_ENA, WM8996_BG_ENA);
1629 msleep(2);
1630 }
1631 break; 1707 break;
1632 1708
1633 case SND_SOC_BIAS_STANDBY: 1709 case SND_SOC_BIAS_STANDBY:
@@ -1650,9 +1726,6 @@ static int wm8996_set_bias_level(struct snd_soc_codec *codec,
1650 codec->cache_only = false; 1726 codec->cache_only = false;
1651 snd_soc_cache_sync(codec); 1727 snd_soc_cache_sync(codec);
1652 } 1728 }
1653
1654 snd_soc_update_bits(codec, WM8996_POWER_MANAGEMENT_1,
1655 WM8996_BG_ENA, 0);
1656 break; 1729 break;
1657 1730
1658 case SND_SOC_BIAS_OFF: 1731 case SND_SOC_BIAS_OFF:
@@ -1847,7 +1920,7 @@ static int wm8996_hw_params(struct snd_pcm_substream *substream,
1847 snd_soc_update_bits(codec, lrclk_reg, WM8996_AIF1RX_RATE_MASK, 1920 snd_soc_update_bits(codec, lrclk_reg, WM8996_AIF1RX_RATE_MASK,
1848 lrclk); 1921 lrclk);
1849 snd_soc_update_bits(codec, WM8996_AIF_CLOCKING_2, 1922 snd_soc_update_bits(codec, WM8996_AIF_CLOCKING_2,
1850 WM8996_DSP1_DIV_SHIFT << dsp_shift, dsp); 1923 WM8996_DSP1_DIV_MASK << dsp_shift, dsp);
1851 1924
1852 return 0; 1925 return 0;
1853} 1926}
@@ -2041,7 +2114,7 @@ static int wm8996_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
2041 struct i2c_client *i2c = to_i2c_client(codec->dev); 2114 struct i2c_client *i2c = to_i2c_client(codec->dev);
2042 struct _fll_div fll_div; 2115 struct _fll_div fll_div;
2043 unsigned long timeout; 2116 unsigned long timeout;
2044 int ret, reg; 2117 int ret, reg, retry;
2045 2118
2046 /* Any change? */ 2119 /* Any change? */
2047 if (source == wm8996->fll_src && Fref == wm8996->fll_fref && 2120 if (source == wm8996->fll_src && Fref == wm8996->fll_fref &&
@@ -2057,6 +2130,8 @@ static int wm8996_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
2057 snd_soc_update_bits(codec, WM8996_FLL_CONTROL_1, 2130 snd_soc_update_bits(codec, WM8996_FLL_CONTROL_1,
2058 WM8996_FLL_ENA, 0); 2131 WM8996_FLL_ENA, 0);
2059 2132
2133 wm8996_bg_disable(codec);
2134
2060 return 0; 2135 return 0;
2061 } 2136 }
2062 2137
@@ -2111,6 +2186,11 @@ static int wm8996_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
2111 2186
2112 snd_soc_write(codec, WM8996_FLL_EFS_1, fll_div.lambda); 2187 snd_soc_write(codec, WM8996_FLL_EFS_1, fll_div.lambda);
2113 2188
2189 /* Enable the bandgap if it's not already enabled */
2190 ret = snd_soc_read(codec, WM8996_FLL_CONTROL_1);
2191 if (!(ret & WM8996_FLL_ENA))
2192 wm8996_bg_enable(codec);
2193
2114 /* Clear any pending completions (eg, from failed startups) */ 2194 /* Clear any pending completions (eg, from failed startups) */
2115 try_wait_for_completion(&wm8996->fll_lock); 2195 try_wait_for_completion(&wm8996->fll_lock);
2116 2196
@@ -2128,17 +2208,29 @@ static int wm8996_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
2128 else 2208 else
2129 timeout = msecs_to_jiffies(2); 2209 timeout = msecs_to_jiffies(2);
2130 2210
2131 /* Allow substantially longer if we've actually got the IRQ */ 2211 /* Allow substantially longer if we've actually got the IRQ, poll
2212 * at a slightly higher rate if we don't.
2213 */
2132 if (i2c->irq) 2214 if (i2c->irq)
2133 timeout *= 1000; 2215 timeout *= 10;
2216 else
2217 timeout /= 2;
2134 2218
2135 ret = wait_for_completion_timeout(&wm8996->fll_lock, timeout); 2219 for (retry = 0; retry < 10; retry++) {
2220 ret = wait_for_completion_timeout(&wm8996->fll_lock,
2221 timeout);
2222 if (ret != 0) {
2223 WARN_ON(!i2c->irq);
2224 break;
2225 }
2136 2226
2137 if (ret == 0 && i2c->irq) { 2227 ret = snd_soc_read(codec, WM8996_INTERRUPT_RAW_STATUS_2);
2228 if (ret & WM8996_FLL_LOCK_STS)
2229 break;
2230 }
2231 if (retry == 10) {
2138 dev_err(codec->dev, "Timed out waiting for FLL\n"); 2232 dev_err(codec->dev, "Timed out waiting for FLL\n");
2139 ret = -ETIMEDOUT; 2233 ret = -ETIMEDOUT;
2140 } else {
2141 ret = 0;
2142 } 2234 }
2143 2235
2144 dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout); 2236 dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout);
@@ -2297,12 +2389,94 @@ int wm8996_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
2297 2389
2298 /* Enable interrupts and we're off */ 2390 /* Enable interrupts and we're off */
2299 snd_soc_update_bits(codec, WM8996_INTERRUPT_STATUS_2_MASK, 2391 snd_soc_update_bits(codec, WM8996_INTERRUPT_STATUS_2_MASK,
2300 WM8996_IM_MICD_EINT, 0); 2392 WM8996_IM_MICD_EINT | WM8996_HP_DONE_EINT, 0);
2301 2393
2302 return 0; 2394 return 0;
2303} 2395}
2304EXPORT_SYMBOL_GPL(wm8996_detect); 2396EXPORT_SYMBOL_GPL(wm8996_detect);
2305 2397
2398static void wm8996_hpdet_irq(struct snd_soc_codec *codec)
2399{
2400 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
2401 int val, reg, report;
2402
2403 /* Assume headphone in error conditions; we need to report
2404 * something or we stall our state machine.
2405 */
2406 report = SND_JACK_HEADPHONE;
2407
2408 reg = snd_soc_read(codec, WM8996_HEADPHONE_DETECT_2);
2409 if (reg < 0) {
2410 dev_err(codec->dev, "Failed to read HPDET status\n");
2411 goto out;
2412 }
2413
2414 if (!(reg & WM8996_HP_DONE)) {
2415 dev_err(codec->dev, "Got HPDET IRQ but HPDET is busy\n");
2416 goto out;
2417 }
2418
2419 val = reg & WM8996_HP_LVL_MASK;
2420
2421 dev_dbg(codec->dev, "HPDET measured %d ohms\n", val);
2422
2423 /* If we've got high enough impedence then report as line,
2424 * otherwise assume headphone.
2425 */
2426 if (val >= 126)
2427 report = SND_JACK_LINEOUT;
2428 else
2429 report = SND_JACK_HEADPHONE;
2430
2431out:
2432 if (wm8996->jack_mic)
2433 report |= SND_JACK_MICROPHONE;
2434
2435 snd_soc_jack_report(wm8996->jack, report,
2436 SND_JACK_LINEOUT | SND_JACK_HEADSET);
2437
2438 wm8996->detecting = false;
2439
2440 /* If the output isn't running re-clamp it */
2441 if (!(snd_soc_read(codec, WM8996_POWER_MANAGEMENT_1) &
2442 (WM8996_HPOUT1L_ENA | WM8996_HPOUT1R_RMV_SHORT)))
2443 snd_soc_update_bits(codec, WM8996_ANALOGUE_HP_1,
2444 WM8996_HPOUT1L_RMV_SHORT |
2445 WM8996_HPOUT1R_RMV_SHORT, 0);
2446
2447 /* Go back to looking at the microphone */
2448 snd_soc_update_bits(codec, WM8996_ACCESSORY_DETECT_MODE_1,
2449 WM8996_JD_MODE_MASK, 0);
2450 snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, WM8996_MICD_ENA,
2451 WM8996_MICD_ENA);
2452
2453 snd_soc_dapm_disable_pin(&codec->dapm, "Bandgap");
2454 snd_soc_dapm_sync(&codec->dapm);
2455}
2456
2457static void wm8996_hpdet_start(struct snd_soc_codec *codec)
2458{
2459 /* Unclamp the output, we can't measure while we're shorting it */
2460 snd_soc_update_bits(codec, WM8996_ANALOGUE_HP_1,
2461 WM8996_HPOUT1L_RMV_SHORT |
2462 WM8996_HPOUT1R_RMV_SHORT,
2463 WM8996_HPOUT1L_RMV_SHORT |
2464 WM8996_HPOUT1R_RMV_SHORT);
2465
2466 /* We need bandgap for HPDET */
2467 snd_soc_dapm_force_enable_pin(&codec->dapm, "Bandgap");
2468 snd_soc_dapm_sync(&codec->dapm);
2469
2470 /* Go into headphone detect left mode */
2471 snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, WM8996_MICD_ENA, 0);
2472 snd_soc_update_bits(codec, WM8996_ACCESSORY_DETECT_MODE_1,
2473 WM8996_JD_MODE_MASK, 1);
2474
2475 /* Trigger a measurement */
2476 snd_soc_update_bits(codec, WM8996_HEADPHONE_DETECT_1,
2477 WM8996_HP_POLL, WM8996_HP_POLL);
2478}
2479
2306static void wm8996_micd(struct snd_soc_codec *codec) 2480static void wm8996_micd(struct snd_soc_codec *codec)
2307{ 2481{
2308 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); 2482 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
@@ -2323,28 +2497,36 @@ static void wm8996_micd(struct snd_soc_codec *codec)
2323 wm8996->jack_mic = false; 2497 wm8996->jack_mic = false;
2324 wm8996->detecting = true; 2498 wm8996->detecting = true;
2325 snd_soc_jack_report(wm8996->jack, 0, 2499 snd_soc_jack_report(wm8996->jack, 0,
2326 SND_JACK_HEADSET | SND_JACK_BTN_0); 2500 SND_JACK_LINEOUT | SND_JACK_HEADSET |
2501 SND_JACK_BTN_0);
2502
2327 snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, 2503 snd_soc_update_bits(codec, WM8996_MIC_DETECT_1,
2328 WM8996_MICD_RATE_MASK, 2504 WM8996_MICD_RATE_MASK,
2329 WM8996_MICD_RATE_MASK); 2505 WM8996_MICD_RATE_MASK);
2330 return; 2506 return;
2331 } 2507 }
2332 2508
2333 /* If the measurement is very high we've got a microphone but 2509 /* If the measurement is very high we've got a microphone,
2334 * do a little debounce to account for mechanical issues. 2510 * either we just detected one or if we already reported then
2511 * we've got a button release event.
2335 */ 2512 */
2336 if (val & 0x400) { 2513 if (val & 0x400) {
2337 dev_dbg(codec->dev, "Microphone detected\n"); 2514 if (wm8996->detecting) {
2338 snd_soc_jack_report(wm8996->jack, SND_JACK_HEADSET, 2515 dev_dbg(codec->dev, "Microphone detected\n");
2339 SND_JACK_HEADSET | SND_JACK_BTN_0); 2516 wm8996->jack_mic = true;
2340 wm8996->jack_mic = true; 2517 wm8996_hpdet_start(codec);
2341 wm8996->detecting = false; 2518
2342 2519 /* Increase poll rate to give better responsiveness
2343 /* Increase poll rate to give better responsiveness 2520 * for buttons */
2344 * for buttons */ 2521 snd_soc_update_bits(codec, WM8996_MIC_DETECT_1,
2345 snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, 2522 WM8996_MICD_RATE_MASK,
2346 WM8996_MICD_RATE_MASK, 2523 5 << WM8996_MICD_RATE_SHIFT);
2347 5 << WM8996_MICD_RATE_SHIFT); 2524 } else {
2525 dev_dbg(codec->dev, "Mic button up\n");
2526 snd_soc_jack_report(wm8996->jack, 0, SND_JACK_BTN_0);
2527 }
2528
2529 return;
2348 } 2530 }
2349 2531
2350 /* If we detected a lower impedence during initial startup 2532 /* If we detected a lower impedence during initial startup
@@ -2376,15 +2558,11 @@ static void wm8996_micd(struct snd_soc_codec *codec)
2376 if (val & 0x3fc) { 2558 if (val & 0x3fc) {
2377 if (wm8996->jack_mic) { 2559 if (wm8996->jack_mic) {
2378 dev_dbg(codec->dev, "Mic button detected\n"); 2560 dev_dbg(codec->dev, "Mic button detected\n");
2379 snd_soc_jack_report(wm8996->jack, 2561 snd_soc_jack_report(wm8996->jack, SND_JACK_BTN_0,
2380 SND_JACK_HEADSET | SND_JACK_BTN_0,
2381 SND_JACK_HEADSET | SND_JACK_BTN_0);
2382 } else {
2383 dev_dbg(codec->dev, "Headphone detected\n");
2384 snd_soc_jack_report(wm8996->jack,
2385 SND_JACK_HEADPHONE,
2386 SND_JACK_HEADSET |
2387 SND_JACK_BTN_0); 2562 SND_JACK_BTN_0);
2563 } else if (wm8996->detecting) {
2564 dev_dbg(codec->dev, "Headphone detected\n");
2565 wm8996_hpdet_start(codec);
2388 2566
2389 /* Increase the detection rate a bit for 2567 /* Increase the detection rate a bit for
2390 * responsiveness. 2568 * responsiveness.
@@ -2392,8 +2570,6 @@ static void wm8996_micd(struct snd_soc_codec *codec)
2392 snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, 2570 snd_soc_update_bits(codec, WM8996_MIC_DETECT_1,
2393 WM8996_MICD_RATE_MASK, 2571 WM8996_MICD_RATE_MASK,
2394 7 << WM8996_MICD_RATE_SHIFT); 2572 7 << WM8996_MICD_RATE_SHIFT);
2395
2396 wm8996->detecting = false;
2397 } 2573 }
2398 } 2574 }
2399} 2575}
@@ -2412,6 +2588,9 @@ static irqreturn_t wm8996_irq(int irq, void *data)
2412 } 2588 }
2413 irq_val &= ~snd_soc_read(codec, WM8996_INTERRUPT_STATUS_2_MASK); 2589 irq_val &= ~snd_soc_read(codec, WM8996_INTERRUPT_STATUS_2_MASK);
2414 2590
2591 if (!irq_val)
2592 return IRQ_NONE;
2593
2415 snd_soc_write(codec, WM8996_INTERRUPT_STATUS_2, irq_val); 2594 snd_soc_write(codec, WM8996_INTERRUPT_STATUS_2, irq_val);
2416 2595
2417 if (irq_val & (WM8996_DCS_DONE_01_EINT | WM8996_DCS_DONE_23_EINT)) { 2596 if (irq_val & (WM8996_DCS_DONE_01_EINT | WM8996_DCS_DONE_23_EINT)) {
@@ -2430,10 +2609,10 @@ static irqreturn_t wm8996_irq(int irq, void *data)
2430 if (irq_val & WM8996_MICD_EINT) 2609 if (irq_val & WM8996_MICD_EINT)
2431 wm8996_micd(codec); 2610 wm8996_micd(codec);
2432 2611
2433 if (irq_val) 2612 if (irq_val & WM8996_HP_DONE_EINT)
2434 return IRQ_HANDLED; 2613 wm8996_hpdet_irq(codec);
2435 else 2614
2436 return IRQ_NONE; 2615 return IRQ_HANDLED;
2437} 2616}
2438 2617
2439static irqreturn_t wm8996_edge_irq(int irq, void *data) 2618static irqreturn_t wm8996_edge_irq(int irq, void *data)
@@ -2527,7 +2706,6 @@ static int wm8996_probe(struct snd_soc_codec *codec)
2527 init_completion(&wm8996->fll_lock); 2706 init_completion(&wm8996->fll_lock);
2528 2707
2529 dapm->idle_bias_off = true; 2708 dapm->idle_bias_off = true;
2530 dapm->bias_level = SND_SOC_BIAS_OFF;
2531 2709
2532 ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C); 2710 ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C);
2533 if (ret != 0) { 2711 if (ret != 0) {
@@ -2548,7 +2726,13 @@ static int wm8996_probe(struct snd_soc_codec *codec)
2548 wm8996->disable_nb[0].notifier_call = wm8996_regulator_event_0; 2726 wm8996->disable_nb[0].notifier_call = wm8996_regulator_event_0;
2549 wm8996->disable_nb[1].notifier_call = wm8996_regulator_event_1; 2727 wm8996->disable_nb[1].notifier_call = wm8996_regulator_event_1;
2550 wm8996->disable_nb[2].notifier_call = wm8996_regulator_event_2; 2728 wm8996->disable_nb[2].notifier_call = wm8996_regulator_event_2;
2551 wm8996->disable_nb[3].notifier_call = wm8996_regulator_event_3; 2729
2730 wm8996->cpvdd = regulator_get(&i2c->dev, "CPVDD");
2731 if (IS_ERR(wm8996->cpvdd)) {
2732 ret = PTR_ERR(wm8996->cpvdd);
2733 dev_err(&i2c->dev, "Failed to get CPVDD: %d\n", ret);
2734 goto err_get;
2735 }
2552 2736
2553 /* This should really be moved into the regulator core */ 2737 /* This should really be moved into the regulator core */
2554 for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) { 2738 for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) {
@@ -2565,7 +2749,7 @@ static int wm8996_probe(struct snd_soc_codec *codec)
2565 wm8996->supplies); 2749 wm8996->supplies);
2566 if (ret != 0) { 2750 if (ret != 0) {
2567 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); 2751 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
2568 goto err_get; 2752 goto err_cpvdd;
2569 } 2753 }
2570 2754
2571 if (wm8996->pdata.ldo_ena >= 0) { 2755 if (wm8996->pdata.ldo_ena >= 0) {
@@ -2808,6 +2992,8 @@ err_enable:
2808 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); 2992 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
2809 2993
2810 regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); 2994 regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
2995err_cpvdd:
2996 regulator_put(wm8996->cpvdd);
2811err_get: 2997err_get:
2812 regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); 2998 regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
2813err: 2999err:
@@ -2831,6 +3017,7 @@ static int wm8996_remove(struct snd_soc_codec *codec)
2831 for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) 3017 for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++)
2832 regulator_unregister_notifier(wm8996->supplies[i].consumer, 3018 regulator_unregister_notifier(wm8996->supplies[i].consumer,
2833 &wm8996->disable_nb[i]); 3019 &wm8996->disable_nb[i]);
3020 regulator_put(wm8996->cpvdd);
2834 regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); 3021 regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
2835 3022
2836 return 0; 3023 return 0;
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c
index a4691321f9b..3cd35a02c28 100644
--- a/sound/soc/codecs/wm9081.c
+++ b/sound/soc/codecs/wm9081.c
@@ -157,7 +157,6 @@ static struct {
157 157
158struct wm9081_priv { 158struct wm9081_priv {
159 enum snd_soc_control_type control_type; 159 enum snd_soc_control_type control_type;
160 void *control_data;
161 int sysclk_source; 160 int sysclk_source;
162 int mclk_rate; 161 int mclk_rate;
163 int sysclk_rate; 162 int sysclk_rate;
@@ -174,6 +173,7 @@ static int wm9081_volatile_register(struct snd_soc_codec *codec, unsigned int re
174{ 173{
175 switch (reg) { 174 switch (reg) {
176 case WM9081_SOFTWARE_RESET: 175 case WM9081_SOFTWARE_RESET:
176 case WM9081_INTERRUPT_STATUS:
177 return 1; 177 return 1;
178 default: 178 default:
179 return 0; 179 return 0;
@@ -820,7 +820,7 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec,
820 /* VMID 2*240k */ 820 /* VMID 2*240k */
821 reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1); 821 reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1);
822 reg &= ~WM9081_VMID_SEL_MASK; 822 reg &= ~WM9081_VMID_SEL_MASK;
823 reg |= 0x40; 823 reg |= 0x04;
824 snd_soc_write(codec, WM9081_VMID_CONTROL, reg); 824 snd_soc_write(codec, WM9081_VMID_CONTROL, reg);
825 825
826 /* Standby bias current on */ 826 /* Standby bias current on */
@@ -1120,8 +1120,8 @@ static int wm9081_digital_mute(struct snd_soc_dai *codec_dai, int mute)
1120 return 0; 1120 return 0;
1121} 1121}
1122 1122
1123static int wm9081_set_sysclk(struct snd_soc_codec *codec, 1123static int wm9081_set_sysclk(struct snd_soc_codec *codec, int clk_id,
1124 int clk_id, unsigned int freq, int dir) 1124 int source, unsigned int freq, int dir)
1125{ 1125{
1126 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec); 1126 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
1127 1127
@@ -1213,7 +1213,6 @@ static int wm9081_probe(struct snd_soc_codec *codec)
1213 int ret; 1213 int ret;
1214 u16 reg; 1214 u16 reg;
1215 1215
1216 codec->control_data = wm9081->control_data;
1217 ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm9081->control_type); 1216 ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm9081->control_type);
1218 if (ret != 0) { 1217 if (ret != 0) {
1219 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 1218 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
@@ -1250,8 +1249,6 @@ static int wm9081_probe(struct snd_soc_codec *codec)
1250 snd_soc_write(codec, WM9081_ANALOGUE_SPEAKER_PGA, 1249 snd_soc_write(codec, WM9081_ANALOGUE_SPEAKER_PGA,
1251 reg | WM9081_SPKPGAZC); 1250 reg | WM9081_SPKPGAZC);
1252 1251
1253 snd_soc_add_controls(codec, wm9081_snd_controls,
1254 ARRAY_SIZE(wm9081_snd_controls));
1255 if (!wm9081->pdata.num_retune_configs) { 1252 if (!wm9081->pdata.num_retune_configs) {
1256 dev_dbg(codec->dev, 1253 dev_dbg(codec->dev,
1257 "No ReTune Mobile data, using normal EQ\n"); 1254 "No ReTune Mobile data, using normal EQ\n");
@@ -1311,6 +1308,8 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9081 = {
1311 .reg_cache_default = wm9081_reg_defaults, 1308 .reg_cache_default = wm9081_reg_defaults,
1312 .volatile_register = wm9081_volatile_register, 1309 .volatile_register = wm9081_volatile_register,
1313 1310
1311 .controls = wm9081_snd_controls,
1312 .num_controls = ARRAY_SIZE(wm9081_snd_controls),
1314 .dapm_widgets = wm9081_dapm_widgets, 1313 .dapm_widgets = wm9081_dapm_widgets,
1315 .num_dapm_widgets = ARRAY_SIZE(wm9081_dapm_widgets), 1314 .num_dapm_widgets = ARRAY_SIZE(wm9081_dapm_widgets),
1316 .dapm_routes = wm9081_audio_paths, 1315 .dapm_routes = wm9081_audio_paths,
@@ -1330,7 +1329,6 @@ static __devinit int wm9081_i2c_probe(struct i2c_client *i2c,
1330 1329
1331 i2c_set_clientdata(i2c, wm9081); 1330 i2c_set_clientdata(i2c, wm9081);
1332 wm9081->control_type = SND_SOC_I2C; 1331 wm9081->control_type = SND_SOC_I2C;
1333 wm9081->control_data = i2c;
1334 1332
1335 if (dev_get_platdata(&i2c->dev)) 1333 if (dev_get_platdata(&i2c->dev))
1336 memcpy(&wm9081->pdata, dev_get_platdata(&i2c->dev), 1334 memcpy(&wm9081->pdata, dev_get_platdata(&i2c->dev),
diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c
index 4de12203e61..2b5252c9e37 100644
--- a/sound/soc/codecs/wm9090.c
+++ b/sound/soc/codecs/wm9090.c
@@ -139,9 +139,7 @@ static const u16 wm9090_reg_defaults[] = {
139 139
140/* This struct is used to save the context */ 140/* This struct is used to save the context */
141struct wm9090_priv { 141struct wm9090_priv {
142 struct mutex mutex;
143 struct wm9090_platform_data pdata; 142 struct wm9090_platform_data pdata;
144 void *control_data;
145}; 143};
146 144
147static int wm9090_volatile(struct snd_soc_codec *codec, unsigned int reg) 145static int wm9090_volatile(struct snd_soc_codec *codec, unsigned int reg)
@@ -550,10 +548,8 @@ static int wm9090_set_bias_level(struct snd_soc_codec *codec,
550 548
551static int wm9090_probe(struct snd_soc_codec *codec) 549static int wm9090_probe(struct snd_soc_codec *codec)
552{ 550{
553 struct wm9090_priv *wm9090 = snd_soc_codec_get_drvdata(codec);
554 int ret; 551 int ret;
555 552
556 codec->control_data = wm9090->control_data;
557 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); 553 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
558 if (ret != 0) { 554 if (ret != 0) {
559 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 555 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
@@ -662,8 +658,6 @@ static int wm9090_i2c_probe(struct i2c_client *i2c,
662 sizeof(wm9090->pdata)); 658 sizeof(wm9090->pdata));
663 659
664 i2c_set_clientdata(i2c, wm9090); 660 i2c_set_clientdata(i2c, wm9090);
665 wm9090->control_data = i2c;
666 mutex_init(&wm9090->mutex);
667 661
668 ret = snd_soc_register_codec(&i2c->dev, 662 ret = snd_soc_register_codec(&i2c->dev,
669 &soc_codec_dev_wm9090, NULL, 0); 663 &soc_codec_dev_wm9090, NULL, 0);
@@ -684,6 +678,7 @@ static int __devexit wm9090_i2c_remove(struct i2c_client *i2c)
684 678
685static const struct i2c_device_id wm9090_id[] = { 679static const struct i2c_device_id wm9090_id[] = {
686 { "wm9090", 0 }, 680 { "wm9090", 0 },
681 { "wm9093", 0 },
687 { } 682 { }
688}; 683};
689MODULE_DEVICE_TABLE(i2c, wm9090_id); 684MODULE_DEVICE_TABLE(i2c, wm9090_id);
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index e763c54c55d..84f33d4ea2c 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -18,6 +18,7 @@
18#include <linux/pm.h> 18#include <linux/pm.h>
19#include <linux/i2c.h> 19#include <linux/i2c.h>
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/mfd/wm8994/registers.h>
21#include <sound/core.h> 22#include <sound/core.h>
22#include <sound/pcm.h> 23#include <sound/pcm.h>
23#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
@@ -116,14 +117,23 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
116{ 117{
117 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); 118 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
118 s8 offset; 119 s8 offset;
119 u16 reg, reg_l, reg_r, dcs_cfg; 120 u16 reg, reg_l, reg_r, dcs_cfg, dcs_reg;
121
122 switch (hubs->dcs_readback_mode) {
123 case 2:
124 dcs_reg = WM8994_DC_SERVO_4E;
125 break;
126 default:
127 dcs_reg = WM8993_DC_SERVO_3;
128 break;
129 }
120 130
121 /* If we're using a digital only path and have a previously 131 /* If we're using a digital only path and have a previously
122 * callibrated DC servo offset stored then use that. */ 132 * callibrated DC servo offset stored then use that. */
123 if (hubs->class_w && hubs->class_w_dcs) { 133 if (hubs->class_w && hubs->class_w_dcs) {
124 dev_dbg(codec->dev, "Using cached DC servo offset %x\n", 134 dev_dbg(codec->dev, "Using cached DC servo offset %x\n",
125 hubs->class_w_dcs); 135 hubs->class_w_dcs);
126 snd_soc_write(codec, WM8993_DC_SERVO_3, hubs->class_w_dcs); 136 snd_soc_write(codec, dcs_reg, hubs->class_w_dcs);
127 wait_for_dc_servo(codec, 137 wait_for_dc_servo(codec,
128 WM8993_DCS_TRIG_DAC_WR_0 | 138 WM8993_DCS_TRIG_DAC_WR_0 |
129 WM8993_DCS_TRIG_DAC_WR_1); 139 WM8993_DCS_TRIG_DAC_WR_1);
@@ -154,8 +164,9 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
154 reg_r = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2) 164 reg_r = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2)
155 & WM8993_DCS_INTEG_CHAN_1_MASK; 165 & WM8993_DCS_INTEG_CHAN_1_MASK;
156 break; 166 break;
167 case 2:
157 case 1: 168 case 1:
158 reg = snd_soc_read(codec, WM8993_DC_SERVO_3); 169 reg = snd_soc_read(codec, dcs_reg);
159 reg_r = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK) 170 reg_r = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK)
160 >> WM8993_DCS_DAC_WR_VAL_1_SHIFT; 171 >> WM8993_DCS_DAC_WR_VAL_1_SHIFT;
161 reg_l = reg & WM8993_DCS_DAC_WR_VAL_0_MASK; 172 reg_l = reg & WM8993_DCS_DAC_WR_VAL_0_MASK;
@@ -168,24 +179,25 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
168 dev_dbg(codec->dev, "DCS input: %x %x\n", reg_l, reg_r); 179 dev_dbg(codec->dev, "DCS input: %x %x\n", reg_l, reg_r);
169 180
170 /* Apply correction to DC servo result */ 181 /* Apply correction to DC servo result */
171 if (hubs->dcs_codes) { 182 if (hubs->dcs_codes_l || hubs->dcs_codes_r) {
172 dev_dbg(codec->dev, "Applying %d code DC servo correction\n", 183 dev_dbg(codec->dev,
173 hubs->dcs_codes); 184 "Applying %d/%d code DC servo correction\n",
185 hubs->dcs_codes_l, hubs->dcs_codes_r);
174 186
175 /* HPOUT1R */ 187 /* HPOUT1R */
176 offset = reg_r; 188 offset = reg_r;
177 offset += hubs->dcs_codes; 189 offset += hubs->dcs_codes_r;
178 dcs_cfg = (u8)offset << WM8993_DCS_DAC_WR_VAL_1_SHIFT; 190 dcs_cfg = (u8)offset << WM8993_DCS_DAC_WR_VAL_1_SHIFT;
179 191
180 /* HPOUT1L */ 192 /* HPOUT1L */
181 offset = reg_l; 193 offset = reg_l;
182 offset += hubs->dcs_codes; 194 offset += hubs->dcs_codes_l;
183 dcs_cfg |= (u8)offset; 195 dcs_cfg |= (u8)offset;
184 196
185 dev_dbg(codec->dev, "DCS result: %x\n", dcs_cfg); 197 dev_dbg(codec->dev, "DCS result: %x\n", dcs_cfg);
186 198
187 /* Do it */ 199 /* Do it */
188 snd_soc_write(codec, WM8993_DC_SERVO_3, dcs_cfg); 200 snd_soc_write(codec, dcs_reg, dcs_cfg);
189 wait_for_dc_servo(codec, 201 wait_for_dc_servo(codec,
190 WM8993_DCS_TRIG_DAC_WR_0 | 202 WM8993_DCS_TRIG_DAC_WR_0 |
191 WM8993_DCS_TRIG_DAC_WR_1); 203 WM8993_DCS_TRIG_DAC_WR_1);
@@ -210,14 +222,14 @@ static int wm8993_put_dc_servo(struct snd_kcontrol *kcontrol,
210 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); 222 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
211 int ret; 223 int ret;
212 224
213 ret = snd_soc_put_volsw_2r(kcontrol, ucontrol); 225 ret = snd_soc_put_volsw(kcontrol, ucontrol);
214 226
215 /* Updating the analogue gains invalidates the DC servo cache */ 227 /* Updating the analogue gains invalidates the DC servo cache */
216 hubs->class_w_dcs = 0; 228 hubs->class_w_dcs = 0;
217 229
218 /* If we're applying an offset correction then updating the 230 /* If we're applying an offset correction then updating the
219 * callibration would be likely to introduce further offsets. */ 231 * callibration would be likely to introduce further offsets. */
220 if (hubs->dcs_codes || hubs->no_series_update) 232 if (hubs->dcs_codes_l || hubs->dcs_codes_r || hubs->no_series_update)
221 return ret; 233 return ret;
222 234
223 /* Only need to do this if the outputs are active */ 235 /* Only need to do this if the outputs are active */
@@ -350,19 +362,11 @@ SOC_DOUBLE_TLV("Speaker Boost Volume", WM8993_SPKOUT_BOOST, 3, 0, 7, 0,
350SOC_ENUM("Speaker Reference", speaker_ref), 362SOC_ENUM("Speaker Reference", speaker_ref),
351SOC_ENUM("Speaker Mode", speaker_mode), 363SOC_ENUM("Speaker Mode", speaker_mode),
352 364
353{ 365SOC_DOUBLE_R_EXT_TLV("Headphone Volume",
354 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Headphone Volume", 366 WM8993_LEFT_OUTPUT_VOLUME, WM8993_RIGHT_OUTPUT_VOLUME,
355 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | 367 0, 63, 0, snd_soc_get_volsw, wm8993_put_dc_servo,
356 SNDRV_CTL_ELEM_ACCESS_READWRITE, 368 outpga_tlv),
357 .tlv.p = outpga_tlv, 369
358 .info = snd_soc_info_volsw_2r,
359 .get = snd_soc_get_volsw_2r, .put = wm8993_put_dc_servo,
360 .private_value = (unsigned long)&(struct soc_mixer_control) {
361 .reg = WM8993_LEFT_OUTPUT_VOLUME,
362 .rreg = WM8993_RIGHT_OUTPUT_VOLUME,
363 .shift = 0, .max = 63
364 },
365},
366SOC_DOUBLE_R("Headphone Switch", WM8993_LEFT_OUTPUT_VOLUME, 370SOC_DOUBLE_R("Headphone Switch", WM8993_LEFT_OUTPUT_VOLUME,
367 WM8993_RIGHT_OUTPUT_VOLUME, 6, 1, 0), 371 WM8993_RIGHT_OUTPUT_VOLUME, 6, 1, 0),
368SOC_DOUBLE_R("Headphone ZC Switch", WM8993_LEFT_OUTPUT_VOLUME, 372SOC_DOUBLE_R("Headphone ZC Switch", WM8993_LEFT_OUTPUT_VOLUME,
@@ -699,6 +703,11 @@ static const struct snd_soc_dapm_route analogue_routes[] = {
699 { "IN1L PGA", "IN1LP Switch", "IN1LP" }, 703 { "IN1L PGA", "IN1LP Switch", "IN1LP" },
700 { "IN1L PGA", "IN1LN Switch", "IN1LN" }, 704 { "IN1L PGA", "IN1LN Switch", "IN1LN" },
701 705
706 { "IN1L PGA", NULL, "VMID" },
707 { "IN1R PGA", NULL, "VMID" },
708 { "IN2L PGA", NULL, "VMID" },
709 { "IN2R PGA", NULL, "VMID" },
710
702 { "IN1R PGA", "IN1RP Switch", "IN1RP" }, 711 { "IN1R PGA", "IN1RP Switch", "IN1RP" },
703 { "IN1R PGA", "IN1RN Switch", "IN1RN" }, 712 { "IN1R PGA", "IN1RN Switch", "IN1RN" },
704 713
@@ -716,12 +725,14 @@ static const struct snd_soc_dapm_route analogue_routes[] = {
716 { "MIXINL", NULL, "Direct Voice" }, 725 { "MIXINL", NULL, "Direct Voice" },
717 { "MIXINL", NULL, "IN1LP" }, 726 { "MIXINL", NULL, "IN1LP" },
718 { "MIXINL", NULL, "Left Output Mixer" }, 727 { "MIXINL", NULL, "Left Output Mixer" },
728 { "MIXINL", NULL, "VMID" },
719 729
720 { "MIXINR", "IN1R Switch", "IN1R PGA" }, 730 { "MIXINR", "IN1R Switch", "IN1R PGA" },
721 { "MIXINR", "IN2R Switch", "IN2R PGA" }, 731 { "MIXINR", "IN2R Switch", "IN2R PGA" },
722 { "MIXINR", NULL, "Direct Voice" }, 732 { "MIXINR", NULL, "Direct Voice" },
723 { "MIXINR", NULL, "IN1RP" }, 733 { "MIXINR", NULL, "IN1RP" },
724 { "MIXINR", NULL, "Right Output Mixer" }, 734 { "MIXINR", NULL, "Right Output Mixer" },
735 { "MIXINR", NULL, "VMID" },
725 736
726 { "ADCL", NULL, "MIXINL" }, 737 { "ADCL", NULL, "MIXINL" },
727 { "ADCR", NULL, "MIXINR" }, 738 { "ADCR", NULL, "MIXINR" },
@@ -752,6 +763,7 @@ static const struct snd_soc_dapm_route analogue_routes[] = {
752 { "Earpiece Mixer", "Left Output Switch", "Left Output PGA" }, 763 { "Earpiece Mixer", "Left Output Switch", "Left Output PGA" },
753 { "Earpiece Mixer", "Right Output Switch", "Right Output PGA" }, 764 { "Earpiece Mixer", "Right Output Switch", "Right Output PGA" },
754 765
766 { "Earpiece Driver", NULL, "VMID" },
755 { "Earpiece Driver", NULL, "Earpiece Mixer" }, 767 { "Earpiece Driver", NULL, "Earpiece Mixer" },
756 { "HPOUT2N", NULL, "Earpiece Driver" }, 768 { "HPOUT2N", NULL, "Earpiece Driver" },
757 { "HPOUT2P", NULL, "Earpiece Driver" }, 769 { "HPOUT2P", NULL, "Earpiece Driver" },
@@ -774,9 +786,11 @@ static const struct snd_soc_dapm_route analogue_routes[] = {
774 { "SPKR Boost", "SPKR Switch", "SPKR" }, 786 { "SPKR Boost", "SPKR Switch", "SPKR" },
775 { "SPKR Boost", "SPKL Switch", "SPKL" }, 787 { "SPKR Boost", "SPKL Switch", "SPKL" },
776 788
789 { "SPKL Driver", NULL, "VMID" },
777 { "SPKL Driver", NULL, "SPKL Boost" }, 790 { "SPKL Driver", NULL, "SPKL Boost" },
778 { "SPKL Driver", NULL, "CLK_SYS" }, 791 { "SPKL Driver", NULL, "CLK_SYS" },
779 792
793 { "SPKR Driver", NULL, "VMID" },
780 { "SPKR Driver", NULL, "SPKR Boost" }, 794 { "SPKR Driver", NULL, "SPKR Boost" },
781 { "SPKR Driver", NULL, "CLK_SYS" }, 795 { "SPKR Driver", NULL, "CLK_SYS" },
782 796
@@ -790,12 +804,18 @@ static const struct snd_soc_dapm_route analogue_routes[] = {
790 804
791 { "Headphone PGA", NULL, "Left Headphone Mux" }, 805 { "Headphone PGA", NULL, "Left Headphone Mux" },
792 { "Headphone PGA", NULL, "Right Headphone Mux" }, 806 { "Headphone PGA", NULL, "Right Headphone Mux" },
807 { "Headphone PGA", NULL, "VMID" },
793 { "Headphone PGA", NULL, "CLK_SYS" }, 808 { "Headphone PGA", NULL, "CLK_SYS" },
794 { "Headphone PGA", NULL, "Headphone Supply" }, 809 { "Headphone PGA", NULL, "Headphone Supply" },
795 810
796 { "HPOUT1L", NULL, "Headphone PGA" }, 811 { "HPOUT1L", NULL, "Headphone PGA" },
797 { "HPOUT1R", NULL, "Headphone PGA" }, 812 { "HPOUT1R", NULL, "Headphone PGA" },
798 813
814 { "LINEOUT1N Driver", NULL, "VMID" },
815 { "LINEOUT1P Driver", NULL, "VMID" },
816 { "LINEOUT2N Driver", NULL, "VMID" },
817 { "LINEOUT2P Driver", NULL, "VMID" },
818
799 { "LINEOUT1N", NULL, "LINEOUT1N Driver" }, 819 { "LINEOUT1N", NULL, "LINEOUT1N Driver" },
800 { "LINEOUT1P", NULL, "LINEOUT1P Driver" }, 820 { "LINEOUT1P", NULL, "LINEOUT1P Driver" },
801 { "LINEOUT2N", NULL, "LINEOUT2N Driver" }, 821 { "LINEOUT2N", NULL, "LINEOUT2N Driver" },
diff --git a/sound/soc/codecs/wm_hubs.h b/sound/soc/codecs/wm_hubs.h
index 676b1252ab9..c674c7a502a 100644
--- a/sound/soc/codecs/wm_hubs.h
+++ b/sound/soc/codecs/wm_hubs.h
@@ -23,7 +23,8 @@ extern const unsigned int wm_hubs_spkmix_tlv[];
23 23
24/* This *must* be the first element of the codec->private_data struct */ 24/* This *must* be the first element of the codec->private_data struct */
25struct wm_hubs_data { 25struct wm_hubs_data {
26 int dcs_codes; 26 int dcs_codes_l;
27 int dcs_codes_r;
27 int dcs_readback_mode; 28 int dcs_readback_mode;
28 int hp_startup_mode; 29 int hp_startup_mode;
29 int series_startup; 30 int series_startup;
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c
index fe7984221eb..f78c3f0f280 100644
--- a/sound/soc/davinci/davinci-evm.c
+++ b/sound/soc/davinci/davinci-evm.c
@@ -150,8 +150,6 @@ static int evm_aic3x_init(struct snd_soc_pcm_runtime *rtd)
150 snd_soc_dapm_enable_pin(dapm, "Mic Jack"); 150 snd_soc_dapm_enable_pin(dapm, "Mic Jack");
151 snd_soc_dapm_enable_pin(dapm, "Line In"); 151 snd_soc_dapm_enable_pin(dapm, "Line In");
152 152
153 snd_soc_dapm_sync(dapm);
154
155 return 0; 153 return 0;
156} 154}
157 155
diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c
index d0d60b8a54d..300e12118c0 100644
--- a/sound/soc/davinci/davinci-i2s.c
+++ b/sound/soc/davinci/davinci-i2s.c
@@ -265,6 +265,7 @@ static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
265 struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(cpu_dai); 265 struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(cpu_dai);
266 unsigned int pcr; 266 unsigned int pcr;
267 unsigned int srgr; 267 unsigned int srgr;
268 bool inv_fs = false;
268 /* Attention srgr is updated by hw_params! */ 269 /* Attention srgr is updated by hw_params! */
269 srgr = DAVINCI_MCBSP_SRGR_FSGM | 270 srgr = DAVINCI_MCBSP_SRGR_FSGM |
270 DAVINCI_MCBSP_SRGR_FPER(DEFAULT_BITPERSAMPLE * 2 - 1) | 271 DAVINCI_MCBSP_SRGR_FPER(DEFAULT_BITPERSAMPLE * 2 - 1) |
@@ -330,7 +331,7 @@ static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
330 * more empty bit clock slots between channels as the sample 331 * more empty bit clock slots between channels as the sample
331 * rate is lowered. 332 * rate is lowered.
332 */ 333 */
333 fmt ^= SND_SOC_DAIFMT_NB_IF; 334 inv_fs = true;
334 case SND_SOC_DAIFMT_DSP_A: 335 case SND_SOC_DAIFMT_DSP_A:
335 dev->mode = MOD_DSP_A; 336 dev->mode = MOD_DSP_A;
336 break; 337 break;
@@ -394,6 +395,8 @@ static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
394 default: 395 default:
395 return -EINVAL; 396 return -EINVAL;
396 } 397 }
398 if (inv_fs == true)
399 pcr ^= (DAVINCI_MCBSP_PCR_FSXP | DAVINCI_MCBSP_PCR_FSRP);
397 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG, srgr); 400 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG, srgr);
398 dev->pcr = pcr; 401 dev->pcr = pcr;
399 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, pcr); 402 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, pcr);
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index 8566238db2a..7173df254a9 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -732,16 +732,19 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
732 davinci_hw_param(dev, substream->stream); 732 davinci_hw_param(dev, substream->stream);
733 733
734 switch (params_format(params)) { 734 switch (params_format(params)) {
735 case SNDRV_PCM_FORMAT_U8:
735 case SNDRV_PCM_FORMAT_S8: 736 case SNDRV_PCM_FORMAT_S8:
736 dma_params->data_type = 1; 737 dma_params->data_type = 1;
737 word_length = DAVINCI_AUDIO_WORD_8; 738 word_length = DAVINCI_AUDIO_WORD_8;
738 break; 739 break;
739 740
741 case SNDRV_PCM_FORMAT_U16_LE:
740 case SNDRV_PCM_FORMAT_S16_LE: 742 case SNDRV_PCM_FORMAT_S16_LE:
741 dma_params->data_type = 2; 743 dma_params->data_type = 2;
742 word_length = DAVINCI_AUDIO_WORD_16; 744 word_length = DAVINCI_AUDIO_WORD_16;
743 break; 745 break;
744 746
747 case SNDRV_PCM_FORMAT_U32_LE:
745 case SNDRV_PCM_FORMAT_S32_LE: 748 case SNDRV_PCM_FORMAT_S32_LE:
746 dma_params->data_type = 4; 749 dma_params->data_type = 4;
747 word_length = DAVINCI_AUDIO_WORD_32; 750 word_length = DAVINCI_AUDIO_WORD_32;
@@ -818,6 +821,13 @@ static struct snd_soc_dai_ops davinci_mcasp_dai_ops = {
818 821
819}; 822};
820 823
824#define DAVINCI_MCASP_PCM_FMTS (SNDRV_PCM_FMTBIT_S8 | \
825 SNDRV_PCM_FMTBIT_U8 | \
826 SNDRV_PCM_FMTBIT_S16_LE | \
827 SNDRV_PCM_FMTBIT_U16_LE | \
828 SNDRV_PCM_FMTBIT_S32_LE | \
829 SNDRV_PCM_FMTBIT_U32_LE)
830
821static struct snd_soc_dai_driver davinci_mcasp_dai[] = { 831static struct snd_soc_dai_driver davinci_mcasp_dai[] = {
822 { 832 {
823 .name = "davinci-mcasp.0", 833 .name = "davinci-mcasp.0",
@@ -825,17 +835,13 @@ static struct snd_soc_dai_driver davinci_mcasp_dai[] = {
825 .channels_min = 2, 835 .channels_min = 2,
826 .channels_max = 2, 836 .channels_max = 2,
827 .rates = DAVINCI_MCASP_RATES, 837 .rates = DAVINCI_MCASP_RATES,
828 .formats = SNDRV_PCM_FMTBIT_S8 | 838 .formats = DAVINCI_MCASP_PCM_FMTS,
829 SNDRV_PCM_FMTBIT_S16_LE |
830 SNDRV_PCM_FMTBIT_S32_LE,
831 }, 839 },
832 .capture = { 840 .capture = {
833 .channels_min = 2, 841 .channels_min = 2,
834 .channels_max = 2, 842 .channels_max = 2,
835 .rates = DAVINCI_MCASP_RATES, 843 .rates = DAVINCI_MCASP_RATES,
836 .formats = SNDRV_PCM_FMTBIT_S8 | 844 .formats = DAVINCI_MCASP_PCM_FMTS,
837 SNDRV_PCM_FMTBIT_S16_LE |
838 SNDRV_PCM_FMTBIT_S32_LE,
839 }, 845 },
840 .ops = &davinci_mcasp_dai_ops, 846 .ops = &davinci_mcasp_dai_ops,
841 847
@@ -846,7 +852,7 @@ static struct snd_soc_dai_driver davinci_mcasp_dai[] = {
846 .channels_min = 1, 852 .channels_min = 1,
847 .channels_max = 384, 853 .channels_max = 384,
848 .rates = DAVINCI_MCASP_RATES, 854 .rates = DAVINCI_MCASP_RATES,
849 .formats = SNDRV_PCM_FMTBIT_S16_LE, 855 .formats = DAVINCI_MCASP_PCM_FMTS,
850 }, 856 },
851 .ops = &davinci_mcasp_dai_ops, 857 .ops = &davinci_mcasp_dai_ops,
852 }, 858 },
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c
index a49e667373b..d5fe08cc5db 100644
--- a/sound/soc/davinci/davinci-pcm.c
+++ b/sound/soc/davinci/davinci-pcm.c
@@ -180,7 +180,6 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream)
180{ 180{
181 struct davinci_runtime_data *prtd = substream->runtime->private_data; 181 struct davinci_runtime_data *prtd = substream->runtime->private_data;
182 struct snd_pcm_runtime *runtime = substream->runtime; 182 struct snd_pcm_runtime *runtime = substream->runtime;
183 int link = prtd->asp_link[0];
184 unsigned int period_size; 183 unsigned int period_size;
185 unsigned int dma_offset; 184 unsigned int dma_offset;
186 dma_addr_t dma_pos; 185 dma_addr_t dma_pos;
@@ -198,7 +197,8 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream)
198 fifo_level = prtd->params->fifo_level; 197 fifo_level = prtd->params->fifo_level;
199 198
200 pr_debug("davinci_pcm: audio_set_dma_params_play channel = %d " 199 pr_debug("davinci_pcm: audio_set_dma_params_play channel = %d "
201 "dma_ptr = %x period_size=%x\n", link, dma_pos, period_size); 200 "dma_ptr = %x period_size=%x\n", prtd->asp_link[0], dma_pos,
201 period_size);
202 202
203 data_type = prtd->params->data_type; 203 data_type = prtd->params->data_type;
204 count = period_size / data_type; 204 count = period_size / data_type;
@@ -222,17 +222,19 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream)
222 } 222 }
223 223
224 acnt = prtd->params->acnt; 224 acnt = prtd->params->acnt;
225 edma_set_src(link, src, INCR, W8BIT); 225 edma_set_src(prtd->asp_link[0], src, INCR, W8BIT);
226 edma_set_dest(link, dst, INCR, W8BIT); 226 edma_set_dest(prtd->asp_link[0], dst, INCR, W8BIT);
227 227
228 edma_set_src_index(link, src_bidx, src_cidx); 228 edma_set_src_index(prtd->asp_link[0], src_bidx, src_cidx);
229 edma_set_dest_index(link, dst_bidx, dst_cidx); 229 edma_set_dest_index(prtd->asp_link[0], dst_bidx, dst_cidx);
230 230
231 if (!fifo_level) 231 if (!fifo_level)
232 edma_set_transfer_params(link, acnt, count, 1, 0, ASYNC); 232 edma_set_transfer_params(prtd->asp_link[0], acnt, count, 1, 0,
233 ASYNC);
233 else 234 else
234 edma_set_transfer_params(link, acnt, fifo_level, count, 235 edma_set_transfer_params(prtd->asp_link[0], acnt, fifo_level,
235 fifo_level, ABSYNC); 236 count, fifo_level,
237 ABSYNC);
236} 238}
237 239
238static void davinci_pcm_dma_irq(unsigned link, u16 ch_status, void *data) 240static void davinci_pcm_dma_irq(unsigned link, u16 ch_status, void *data)
@@ -305,7 +307,6 @@ static int ping_pong_dma_setup(struct snd_pcm_substream *substream)
305 unsigned int acnt = params->acnt; 307 unsigned int acnt = params->acnt;
306 /* divide by 2 for ping/pong */ 308 /* divide by 2 for ping/pong */
307 unsigned int ping_size = snd_pcm_lib_period_bytes(substream) >> 1; 309 unsigned int ping_size = snd_pcm_lib_period_bytes(substream) >> 1;
308 int link = prtd->asp_link[1];
309 unsigned int fifo_level = prtd->params->fifo_level; 310 unsigned int fifo_level = prtd->params->fifo_level;
310 unsigned int count; 311 unsigned int count;
311 if ((data_type == 0) || (data_type > 4)) { 312 if ((data_type == 0) || (data_type > 4)) {
@@ -316,28 +317,26 @@ static int ping_pong_dma_setup(struct snd_pcm_substream *substream)
316 dma_addr_t asp_src_pong = iram_dma->addr + ping_size; 317 dma_addr_t asp_src_pong = iram_dma->addr + ping_size;
317 ram_src_cidx = ping_size; 318 ram_src_cidx = ping_size;
318 ram_dst_cidx = -ping_size; 319 ram_dst_cidx = -ping_size;
319 edma_set_src(link, asp_src_pong, INCR, W8BIT); 320 edma_set_src(prtd->asp_link[1], asp_src_pong, INCR, W8BIT);
320 321
321 link = prtd->asp_link[0]; 322 edma_set_src_index(prtd->asp_link[0], data_type,
322 edma_set_src_index(link, data_type, data_type * fifo_level); 323 data_type * fifo_level);
323 link = prtd->asp_link[1]; 324 edma_set_src_index(prtd->asp_link[1], data_type,
324 edma_set_src_index(link, data_type, data_type * fifo_level); 325 data_type * fifo_level);
325 326
326 link = prtd->ram_link; 327 edma_set_src(prtd->ram_link, runtime->dma_addr, INCR, W32BIT);
327 edma_set_src(link, runtime->dma_addr, INCR, W32BIT);
328 } else { 328 } else {
329 dma_addr_t asp_dst_pong = iram_dma->addr + ping_size; 329 dma_addr_t asp_dst_pong = iram_dma->addr + ping_size;
330 ram_src_cidx = -ping_size; 330 ram_src_cidx = -ping_size;
331 ram_dst_cidx = ping_size; 331 ram_dst_cidx = ping_size;
332 edma_set_dest(link, asp_dst_pong, INCR, W8BIT); 332 edma_set_dest(prtd->asp_link[1], asp_dst_pong, INCR, W8BIT);
333 333
334 link = prtd->asp_link[0]; 334 edma_set_dest_index(prtd->asp_link[0], data_type,
335 edma_set_dest_index(link, data_type, data_type * fifo_level); 335 data_type * fifo_level);
336 link = prtd->asp_link[1]; 336 edma_set_dest_index(prtd->asp_link[1], data_type,
337 edma_set_dest_index(link, data_type, data_type * fifo_level); 337 data_type * fifo_level);
338 338
339 link = prtd->ram_link; 339 edma_set_dest(prtd->ram_link, runtime->dma_addr, INCR, W32BIT);
340 edma_set_dest(link, runtime->dma_addr, INCR, W32BIT);
341 } 340 }
342 341
343 if (!fifo_level) { 342 if (!fifo_level) {
@@ -354,10 +353,9 @@ static int ping_pong_dma_setup(struct snd_pcm_substream *substream)
354 count, fifo_level, ABSYNC); 353 count, fifo_level, ABSYNC);
355 } 354 }
356 355
357 link = prtd->ram_link; 356 edma_set_src_index(prtd->ram_link, ping_size, ram_src_cidx);
358 edma_set_src_index(link, ping_size, ram_src_cidx); 357 edma_set_dest_index(prtd->ram_link, ping_size, ram_dst_cidx);
359 edma_set_dest_index(link, ping_size, ram_dst_cidx); 358 edma_set_transfer_params(prtd->ram_link, ping_size, 2,
360 edma_set_transfer_params(link, ping_size, 2,
361 runtime->periods, 2, ASYNC); 359 runtime->periods, 2, ASYNC);
362 360
363 /* init master params */ 361 /* init master params */
@@ -406,32 +404,32 @@ static int request_ping_pong(struct snd_pcm_substream *substream,
406{ 404{
407 dma_addr_t asp_src_ping; 405 dma_addr_t asp_src_ping;
408 dma_addr_t asp_dst_ping; 406 dma_addr_t asp_dst_ping;
409 int link; 407 int ret;
410 struct davinci_pcm_dma_params *params = prtd->params; 408 struct davinci_pcm_dma_params *params = prtd->params;
411 409
412 /* Request ram master channel */ 410 /* Request ram master channel */
413 link = prtd->ram_channel = edma_alloc_channel(EDMA_CHANNEL_ANY, 411 ret = prtd->ram_channel = edma_alloc_channel(EDMA_CHANNEL_ANY,
414 davinci_pcm_dma_irq, substream, 412 davinci_pcm_dma_irq, substream,
415 prtd->params->ram_chan_q); 413 prtd->params->ram_chan_q);
416 if (link < 0) 414 if (ret < 0)
417 goto exit1; 415 goto exit1;
418 416
419 /* Request ram link channel */ 417 /* Request ram link channel */
420 link = prtd->ram_link = edma_alloc_slot( 418 ret = prtd->ram_link = edma_alloc_slot(
421 EDMA_CTLR(prtd->ram_channel), EDMA_SLOT_ANY); 419 EDMA_CTLR(prtd->ram_channel), EDMA_SLOT_ANY);
422 if (link < 0) 420 if (ret < 0)
423 goto exit2; 421 goto exit2;
424 422
425 link = prtd->asp_link[1] = edma_alloc_slot( 423 ret = prtd->asp_link[1] = edma_alloc_slot(
426 EDMA_CTLR(prtd->asp_channel), EDMA_SLOT_ANY); 424 EDMA_CTLR(prtd->asp_channel), EDMA_SLOT_ANY);
427 if (link < 0) 425 if (ret < 0)
428 goto exit3; 426 goto exit3;
429 427
430 prtd->ram_link2 = -1; 428 prtd->ram_link2 = -1;
431 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 429 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
432 link = prtd->ram_link2 = edma_alloc_slot( 430 ret = prtd->ram_link2 = edma_alloc_slot(
433 EDMA_CTLR(prtd->ram_channel), EDMA_SLOT_ANY); 431 EDMA_CTLR(prtd->ram_channel), EDMA_SLOT_ANY);
434 if (link < 0) 432 if (ret < 0)
435 goto exit4; 433 goto exit4;
436 } 434 }
437 /* circle ping-pong buffers */ 435 /* circle ping-pong buffers */
@@ -448,36 +446,33 @@ static int request_ping_pong(struct snd_pcm_substream *substream,
448 asp_dst_ping = iram_dma->addr; 446 asp_dst_ping = iram_dma->addr;
449 } 447 }
450 /* ping */ 448 /* ping */
451 link = prtd->asp_link[0]; 449 edma_set_src(prtd->asp_link[0], asp_src_ping, INCR, W16BIT);
452 edma_set_src(link, asp_src_ping, INCR, W16BIT); 450 edma_set_dest(prtd->asp_link[0], asp_dst_ping, INCR, W16BIT);
453 edma_set_dest(link, asp_dst_ping, INCR, W16BIT); 451 edma_set_src_index(prtd->asp_link[0], 0, 0);
454 edma_set_src_index(link, 0, 0); 452 edma_set_dest_index(prtd->asp_link[0], 0, 0);
455 edma_set_dest_index(link, 0, 0);
456 453
457 edma_read_slot(link, &prtd->asp_params); 454 edma_read_slot(prtd->asp_link[0], &prtd->asp_params);
458 prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f) | TCINTEN); 455 prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f) | TCINTEN);
459 prtd->asp_params.opt |= TCCHEN | 456 prtd->asp_params.opt |= TCCHEN |
460 EDMA_TCC(prtd->ram_channel & 0x3f); 457 EDMA_TCC(prtd->ram_channel & 0x3f);
461 edma_write_slot(link, &prtd->asp_params); 458 edma_write_slot(prtd->asp_link[0], &prtd->asp_params);
462 459
463 /* pong */ 460 /* pong */
464 link = prtd->asp_link[1]; 461 edma_set_src(prtd->asp_link[1], asp_src_ping, INCR, W16BIT);
465 edma_set_src(link, asp_src_ping, INCR, W16BIT); 462 edma_set_dest(prtd->asp_link[1], asp_dst_ping, INCR, W16BIT);
466 edma_set_dest(link, asp_dst_ping, INCR, W16BIT); 463 edma_set_src_index(prtd->asp_link[1], 0, 0);
467 edma_set_src_index(link, 0, 0); 464 edma_set_dest_index(prtd->asp_link[1], 0, 0);
468 edma_set_dest_index(link, 0, 0);
469 465
470 edma_read_slot(link, &prtd->asp_params); 466 edma_read_slot(prtd->asp_link[1], &prtd->asp_params);
471 prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f)); 467 prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f));
472 /* interrupt after every pong completion */ 468 /* interrupt after every pong completion */
473 prtd->asp_params.opt |= TCINTEN | TCCHEN | 469 prtd->asp_params.opt |= TCINTEN | TCCHEN |
474 EDMA_TCC(prtd->ram_channel & 0x3f); 470 EDMA_TCC(prtd->ram_channel & 0x3f);
475 edma_write_slot(link, &prtd->asp_params); 471 edma_write_slot(prtd->asp_link[1], &prtd->asp_params);
476 472
477 /* ram */ 473 /* ram */
478 link = prtd->ram_link; 474 edma_set_src(prtd->ram_link, iram_dma->addr, INCR, W32BIT);
479 edma_set_src(link, iram_dma->addr, INCR, W32BIT); 475 edma_set_dest(prtd->ram_link, iram_dma->addr, INCR, W32BIT);
480 edma_set_dest(link, iram_dma->addr, INCR, W32BIT);
481 pr_debug("%s: audio dma channels/slots in use for ram:%u %u %u," 476 pr_debug("%s: audio dma channels/slots in use for ram:%u %u %u,"
482 "for asp:%u %u %u\n", __func__, 477 "for asp:%u %u %u\n", __func__,
483 prtd->ram_channel, prtd->ram_link, prtd->ram_link2, 478 prtd->ram_channel, prtd->ram_link, prtd->ram_link2,
@@ -494,7 +489,7 @@ exit2:
494 edma_free_channel(prtd->ram_channel); 489 edma_free_channel(prtd->ram_channel);
495 prtd->ram_channel = -1; 490 prtd->ram_channel = -1;
496exit1: 491exit1:
497 return link; 492 return ret;
498} 493}
499 494
500static int davinci_pcm_dma_request(struct snd_pcm_substream *substream) 495static int davinci_pcm_dma_request(struct snd_pcm_substream *substream)
@@ -502,22 +497,22 @@ static int davinci_pcm_dma_request(struct snd_pcm_substream *substream)
502 struct snd_dma_buffer *iram_dma; 497 struct snd_dma_buffer *iram_dma;
503 struct davinci_runtime_data *prtd = substream->runtime->private_data; 498 struct davinci_runtime_data *prtd = substream->runtime->private_data;
504 struct davinci_pcm_dma_params *params = prtd->params; 499 struct davinci_pcm_dma_params *params = prtd->params;
505 int link; 500 int ret;
506 501
507 if (!params) 502 if (!params)
508 return -ENODEV; 503 return -ENODEV;
509 504
510 /* Request asp master DMA channel */ 505 /* Request asp master DMA channel */
511 link = prtd->asp_channel = edma_alloc_channel(params->channel, 506 ret = prtd->asp_channel = edma_alloc_channel(params->channel,
512 davinci_pcm_dma_irq, substream, 507 davinci_pcm_dma_irq, substream,
513 prtd->params->asp_chan_q); 508 prtd->params->asp_chan_q);
514 if (link < 0) 509 if (ret < 0)
515 goto exit1; 510 goto exit1;
516 511
517 /* Request asp link channels */ 512 /* Request asp link channels */
518 link = prtd->asp_link[0] = edma_alloc_slot( 513 ret = prtd->asp_link[0] = edma_alloc_slot(
519 EDMA_CTLR(prtd->asp_channel), EDMA_SLOT_ANY); 514 EDMA_CTLR(prtd->asp_channel), EDMA_SLOT_ANY);
520 if (link < 0) 515 if (ret < 0)
521 goto exit2; 516 goto exit2;
522 517
523 iram_dma = (struct snd_dma_buffer *)substream->dma_buffer.private_data; 518 iram_dma = (struct snd_dma_buffer *)substream->dma_buffer.private_data;
@@ -537,17 +532,17 @@ static int davinci_pcm_dma_request(struct snd_pcm_substream *substream)
537 * the buffer and its length (ccnt) ... use it as a template 532 * the buffer and its length (ccnt) ... use it as a template
538 * so davinci_pcm_enqueue_dma() takes less time in IRQ. 533 * so davinci_pcm_enqueue_dma() takes less time in IRQ.
539 */ 534 */
540 edma_read_slot(link, &prtd->asp_params); 535 edma_read_slot(prtd->asp_link[0], &prtd->asp_params);
541 prtd->asp_params.opt |= TCINTEN | 536 prtd->asp_params.opt |= TCINTEN |
542 EDMA_TCC(EDMA_CHAN_SLOT(prtd->asp_channel)); 537 EDMA_TCC(EDMA_CHAN_SLOT(prtd->asp_channel));
543 prtd->asp_params.link_bcntrld = EDMA_CHAN_SLOT(link) << 5; 538 prtd->asp_params.link_bcntrld = EDMA_CHAN_SLOT(prtd->asp_link[0]) << 5;
544 edma_write_slot(link, &prtd->asp_params); 539 edma_write_slot(prtd->asp_link[0], &prtd->asp_params);
545 return 0; 540 return 0;
546exit2: 541exit2:
547 edma_free_channel(prtd->asp_channel); 542 edma_free_channel(prtd->asp_channel);
548 prtd->asp_channel = -1; 543 prtd->asp_channel = -1;
549exit1: 544exit1:
550 return link; 545 return ret;
551} 546}
552 547
553static int davinci_pcm_trigger(struct snd_pcm_substream *substream, int cmd) 548static int davinci_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
diff --git a/sound/soc/ep93xx/edb93xx.c b/sound/soc/ep93xx/edb93xx.c
index d3aa15119d2..0134d4e9131 100644
--- a/sound/soc/ep93xx/edb93xx.c
+++ b/sound/soc/ep93xx/edb93xx.c
@@ -28,12 +28,6 @@
28#include <mach/hardware.h> 28#include <mach/hardware.h>
29#include "ep93xx-pcm.h" 29#include "ep93xx-pcm.h"
30 30
31#define edb93xx_has_audio() (machine_is_edb9301() || \
32 machine_is_edb9302() || \
33 machine_is_edb9302a() || \
34 machine_is_edb9307a() || \
35 machine_is_edb9315a())
36
37static int edb93xx_hw_params(struct snd_pcm_substream *substream, 31static int edb93xx_hw_params(struct snd_pcm_substream *substream,
38 struct snd_pcm_hw_params *params) 32 struct snd_pcm_hw_params *params)
39{ 33{
@@ -94,49 +88,61 @@ static struct snd_soc_card snd_soc_edb93xx = {
94 .num_links = 1, 88 .num_links = 1,
95}; 89};
96 90
97static struct platform_device *edb93xx_snd_device; 91static int __devinit edb93xx_probe(struct platform_device *pdev)
98
99static int __init edb93xx_init(void)
100{ 92{
93 struct snd_soc_card *card = &snd_soc_edb93xx;
101 int ret; 94 int ret;
102 95
103 if (!edb93xx_has_audio())
104 return -ENODEV;
105
106 ret = ep93xx_i2s_acquire(EP93XX_SYSCON_DEVCFG_I2SONAC97, 96 ret = ep93xx_i2s_acquire(EP93XX_SYSCON_DEVCFG_I2SONAC97,
107 EP93XX_SYSCON_I2SCLKDIV_ORIDE | 97 EP93XX_SYSCON_I2SCLKDIV_ORIDE |
108 EP93XX_SYSCON_I2SCLKDIV_SPOL); 98 EP93XX_SYSCON_I2SCLKDIV_SPOL);
109 if (ret) 99 if (ret)
110 return ret; 100 return ret;
111 101
112 edb93xx_snd_device = platform_device_alloc("soc-audio", -1); 102 card->dev = &pdev->dev;
113 if (!edb93xx_snd_device) { 103
114 ret = -ENOMEM; 104 ret = snd_soc_register_card(card);
115 goto free_i2s; 105 if (ret) {
106 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
107 ret);
108 ep93xx_i2s_release();
116 } 109 }
117 110
118 platform_set_drvdata(edb93xx_snd_device, &snd_soc_edb93xx); 111 return ret;
119 ret = platform_device_add(edb93xx_snd_device); 112}
120 if (ret)
121 goto device_put;
122 113
123 return 0; 114static int __devexit edb93xx_remove(struct platform_device *pdev)
115{
116 struct snd_soc_card *card = platform_get_drvdata(pdev);
124 117
125device_put: 118 snd_soc_unregister_card(card);
126 platform_device_put(edb93xx_snd_device);
127free_i2s:
128 ep93xx_i2s_release(); 119 ep93xx_i2s_release();
129 return ret; 120
121 return 0;
122}
123
124static struct platform_driver edb93xx_driver = {
125 .driver = {
126 .name = "edb93xx-audio",
127 .owner = THIS_MODULE,
128 },
129 .probe = edb93xx_probe,
130 .remove = __devexit_p(edb93xx_remove),
131};
132
133static int __init edb93xx_init(void)
134{
135 return platform_driver_register(&edb93xx_driver);
130} 136}
131module_init(edb93xx_init); 137module_init(edb93xx_init);
132 138
133static void __exit edb93xx_exit(void) 139static void __exit edb93xx_exit(void)
134{ 140{
135 platform_device_unregister(edb93xx_snd_device); 141 platform_driver_unregister(&edb93xx_driver);
136 ep93xx_i2s_release();
137} 142}
138module_exit(edb93xx_exit); 143module_exit(edb93xx_exit);
139 144
140MODULE_AUTHOR("Alexander Sverdlin <subaparts@yandex.ru>"); 145MODULE_AUTHOR("Alexander Sverdlin <subaparts@yandex.ru>");
141MODULE_DESCRIPTION("ALSA SoC EDB93xx"); 146MODULE_DESCRIPTION("ALSA SoC EDB93xx");
142MODULE_LICENSE("GPL"); 147MODULE_LICENSE("GPL");
148MODULE_ALIAS("platform:edb93xx-audio");
diff --git a/sound/soc/ep93xx/ep93xx-ac97.c b/sound/soc/ep93xx/ep93xx-ac97.c
index c7417c76552..3cd6158d83e 100644
--- a/sound/soc/ep93xx/ep93xx-ac97.c
+++ b/sound/soc/ep93xx/ep93xx-ac97.c
@@ -335,7 +335,7 @@ static struct snd_soc_dai_ops ep93xx_ac97_dai_ops = {
335 .trigger = ep93xx_ac97_trigger, 335 .trigger = ep93xx_ac97_trigger,
336}; 336};
337 337
338struct snd_soc_dai_driver ep93xx_ac97_dai = { 338static struct snd_soc_dai_driver ep93xx_ac97_dai = {
339 .name = "ep93xx-ac97", 339 .name = "ep93xx-ac97",
340 .id = 0, 340 .id = 0,
341 .ac97_control = 1, 341 .ac97_control = 1,
diff --git a/sound/soc/ep93xx/ep93xx-pcm.c b/sound/soc/ep93xx/ep93xx-pcm.c
index 8dfd3ad84b1..d00230a591b 100644
--- a/sound/soc/ep93xx/ep93xx-pcm.c
+++ b/sound/soc/ep93xx/ep93xx-pcm.c
@@ -355,3 +355,4 @@ module_exit(ep93xx_soc_platform_exit);
355MODULE_AUTHOR("Ryan Mallon"); 355MODULE_AUTHOR("Ryan Mallon");
356MODULE_DESCRIPTION("EP93xx ALSA PCM interface"); 356MODULE_DESCRIPTION("EP93xx ALSA PCM interface");
357MODULE_LICENSE("GPL"); 357MODULE_LICENSE("GPL");
358MODULE_ALIAS("platform:ep93xx-pcm-audio");
diff --git a/sound/soc/ep93xx/simone.c b/sound/soc/ep93xx/simone.c
index 286817946c5..968cb316d51 100644
--- a/sound/soc/ep93xx/simone.c
+++ b/sound/soc/ep93xx/simone.c
@@ -39,53 +39,61 @@ static struct snd_soc_card snd_soc_simone = {
39}; 39};
40 40
41static struct platform_device *simone_snd_ac97_device; 41static struct platform_device *simone_snd_ac97_device;
42static struct platform_device *simone_snd_device;
43 42
44static int __init simone_init(void) 43static int __devinit simone_probe(struct platform_device *pdev)
45{ 44{
45 struct snd_soc_card *card = &snd_soc_simone;
46 int ret; 46 int ret;
47 47
48 if (!machine_is_sim_one()) 48 simone_snd_ac97_device = platform_device_register_simple("ac97-codec",
49 return -ENODEV; 49 -1, NULL, 0);
50 50 if (IS_ERR(simone_snd_ac97_device))
51 simone_snd_ac97_device = platform_device_alloc("ac97-codec", -1); 51 return PTR_ERR(simone_snd_ac97_device);
52 if (!simone_snd_ac97_device)
53 return -ENOMEM;
54 52
55 ret = platform_device_add(simone_snd_ac97_device); 53 card->dev = &pdev->dev;
56 if (ret)
57 goto fail1;
58 54
59 simone_snd_device = platform_device_alloc("soc-audio", -1); 55 ret = snd_soc_register_card(card);
60 if (!simone_snd_device) { 56 if (ret) {
61 ret = -ENOMEM; 57 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
62 goto fail2; 58 ret);
59 platform_device_unregister(simone_snd_ac97_device);
63 } 60 }
64 61
65 platform_set_drvdata(simone_snd_device, &snd_soc_simone); 62 return ret;
66 ret = platform_device_add(simone_snd_device); 63}
67 if (ret) 64
68 goto fail3; 65static int __devexit simone_remove(struct platform_device *pdev)
66{
67 struct snd_soc_card *card = platform_get_drvdata(pdev);
68
69 snd_soc_unregister_card(card);
70 platform_device_unregister(simone_snd_ac97_device);
69 71
70 return 0; 72 return 0;
73}
71 74
72fail3: 75static struct platform_driver simone_driver = {
73 platform_device_put(simone_snd_device); 76 .driver = {
74fail2: 77 .name = "simone-audio",
75 platform_device_del(simone_snd_ac97_device); 78 .owner = THIS_MODULE,
76fail1: 79 },
77 platform_device_put(simone_snd_ac97_device); 80 .probe = simone_probe,
78 return ret; 81 .remove = __devexit_p(simone_remove),
82};
83
84static int __init simone_init(void)
85{
86 return platform_driver_register(&simone_driver);
79} 87}
80module_init(simone_init); 88module_init(simone_init);
81 89
82static void __exit simone_exit(void) 90static void __exit simone_exit(void)
83{ 91{
84 platform_device_unregister(simone_snd_device); 92 platform_driver_unregister(&simone_driver);
85 platform_device_unregister(simone_snd_ac97_device);
86} 93}
87module_exit(simone_exit); 94module_exit(simone_exit);
88 95
89MODULE_DESCRIPTION("ALSA SoC Simplemachines Sim.One"); 96MODULE_DESCRIPTION("ALSA SoC Simplemachines Sim.One");
90MODULE_AUTHOR("Mika Westerberg <mika.westerberg@iki.fi>"); 97MODULE_AUTHOR("Mika Westerberg <mika.westerberg@iki.fi>");
91MODULE_LICENSE("GPL"); 98MODULE_LICENSE("GPL");
99MODULE_ALIAS("platform:simone-audio");
diff --git a/sound/soc/ep93xx/snappercl15.c b/sound/soc/ep93xx/snappercl15.c
index c8aa8a5003c..f74ac54c285 100644
--- a/sound/soc/ep93xx/snappercl15.c
+++ b/sound/soc/ep93xx/snappercl15.c
@@ -104,37 +104,56 @@ static struct snd_soc_card snd_soc_snappercl15 = {
104 .num_links = 1, 104 .num_links = 1,
105}; 105};
106 106
107static struct platform_device *snappercl15_snd_device; 107static int __devinit snappercl15_probe(struct platform_device *pdev)
108
109static int __init snappercl15_init(void)
110{ 108{
109 struct snd_soc_card *card = &snd_soc_snappercl15;
111 int ret; 110 int ret;
112 111
113 if (!machine_is_snapper_cl15())
114 return -ENODEV;
115
116 ret = ep93xx_i2s_acquire(EP93XX_SYSCON_DEVCFG_I2SONAC97, 112 ret = ep93xx_i2s_acquire(EP93XX_SYSCON_DEVCFG_I2SONAC97,
117 EP93XX_SYSCON_I2SCLKDIV_ORIDE | 113 EP93XX_SYSCON_I2SCLKDIV_ORIDE |
118 EP93XX_SYSCON_I2SCLKDIV_SPOL); 114 EP93XX_SYSCON_I2SCLKDIV_SPOL);
119 if (ret) 115 if (ret)
120 return ret; 116 return ret;
121 117
122 snappercl15_snd_device = platform_device_alloc("soc-audio", -1); 118 card->dev = &pdev->dev;
123 if (!snappercl15_snd_device) 119
124 return -ENOMEM; 120 ret = snd_soc_register_card(card);
125 121 if (ret) {
126 platform_set_drvdata(snappercl15_snd_device, &snd_soc_snappercl15); 122 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
127 ret = platform_device_add(snappercl15_snd_device); 123 ret);
128 if (ret) 124 ep93xx_i2s_release();
129 platform_device_put(snappercl15_snd_device); 125 }
130 126
131 return ret; 127 return ret;
132} 128}
133 129
134static void __exit snappercl15_exit(void) 130static int __devexit snappercl15_remove(struct platform_device *pdev)
135{ 131{
136 platform_device_unregister(snappercl15_snd_device); 132 struct snd_soc_card *card = platform_get_drvdata(pdev);
133
134 snd_soc_unregister_card(card);
137 ep93xx_i2s_release(); 135 ep93xx_i2s_release();
136
137 return 0;
138}
139
140static struct platform_driver snappercl15_driver = {
141 .driver = {
142 .name = "snappercl15-audio",
143 .owner = THIS_MODULE,
144 },
145 .probe = snappercl15_probe,
146 .remove = __devexit_p(snappercl15_remove),
147};
148
149static int __init snappercl15_init(void)
150{
151 return platform_driver_register(&snappercl15_driver);
152}
153
154static void __exit snappercl15_exit(void)
155{
156 platform_driver_unregister(&snappercl15_driver);
138} 157}
139 158
140module_init(snappercl15_init); 159module_init(snappercl15_init);
@@ -143,4 +162,4 @@ module_exit(snappercl15_exit);
143MODULE_AUTHOR("Ryan Mallon"); 162MODULE_AUTHOR("Ryan Mallon");
144MODULE_DESCRIPTION("ALSA SoC Snapper CL15"); 163MODULE_DESCRIPTION("ALSA SoC Snapper CL15");
145MODULE_LICENSE("GPL"); 164MODULE_LICENSE("GPL");
146 165MODULE_ALIAS("platform:snappercl15-audio");
diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c
index cb50598338e..ef15402a3bc 100644
--- a/sound/soc/fsl/fsl_dma.c
+++ b/sound/soc/fsl/fsl_dma.c
@@ -297,7 +297,6 @@ static irqreturn_t fsl_dma_isr(int irq, void *dev_id)
297static int fsl_dma_new(struct snd_soc_pcm_runtime *rtd) 297static int fsl_dma_new(struct snd_soc_pcm_runtime *rtd)
298{ 298{
299 struct snd_card *card = rtd->card->snd_card; 299 struct snd_card *card = rtd->card->snd_card;
300 struct snd_soc_dai *dai = rtd->cpu_dai;
301 struct snd_pcm *pcm = rtd->pcm; 300 struct snd_pcm *pcm = rtd->pcm;
302 static u64 fsl_dma_dmamask = DMA_BIT_MASK(36); 301 static u64 fsl_dma_dmamask = DMA_BIT_MASK(36);
303 int ret; 302 int ret;
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index d48afea5d93..0268cf98973 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -78,7 +78,6 @@
78 * @second_stream: pointer to second stream 78 * @second_stream: pointer to second stream
79 * @playback: the number of playback streams opened 79 * @playback: the number of playback streams opened
80 * @capture: the number of capture streams opened 80 * @capture: the number of capture streams opened
81 * @asynchronous: 0=synchronous mode, 1=asynchronous mode
82 * @cpu_dai: the CPU DAI for this device 81 * @cpu_dai: the CPU DAI for this device
83 * @dev_attr: the sysfs device attribute structure 82 * @dev_attr: the sysfs device attribute structure
84 * @stats: SSI statistics 83 * @stats: SSI statistics
@@ -90,9 +89,6 @@ struct fsl_ssi_private {
90 unsigned int irq; 89 unsigned int irq;
91 struct snd_pcm_substream *first_stream; 90 struct snd_pcm_substream *first_stream;
92 struct snd_pcm_substream *second_stream; 91 struct snd_pcm_substream *second_stream;
93 unsigned int playback;
94 unsigned int capture;
95 int asynchronous;
96 unsigned int fifo_depth; 92 unsigned int fifo_depth;
97 struct snd_soc_dai_driver cpu_dai_drv; 93 struct snd_soc_dai_driver cpu_dai_drv;
98 struct device_attribute dev_attr; 94 struct device_attribute dev_attr;
@@ -281,24 +277,18 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
281 struct snd_soc_dai *dai) 277 struct snd_soc_dai *dai)
282{ 278{
283 struct snd_soc_pcm_runtime *rtd = substream->private_data; 279 struct snd_soc_pcm_runtime *rtd = substream->private_data;
284 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(rtd->cpu_dai); 280 struct fsl_ssi_private *ssi_private =
281 snd_soc_dai_get_drvdata(rtd->cpu_dai);
282 int synchronous = ssi_private->cpu_dai_drv.symmetric_rates;
285 283
286 /* 284 /*
287 * If this is the first stream opened, then request the IRQ 285 * If this is the first stream opened, then request the IRQ
288 * and initialize the SSI registers. 286 * and initialize the SSI registers.
289 */ 287 */
290 if (!ssi_private->playback && !ssi_private->capture) { 288 if (!ssi_private->first_stream) {
291 struct ccsr_ssi __iomem *ssi = ssi_private->ssi; 289 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
292 int ret; 290
293 291 ssi_private->first_stream = substream;
294 /* The 'name' should not have any slashes in it. */
295 ret = request_irq(ssi_private->irq, fsl_ssi_isr, 0,
296 ssi_private->name, ssi_private);
297 if (ret < 0) {
298 dev_err(substream->pcm->card->dev,
299 "could not claim irq %u\n", ssi_private->irq);
300 return ret;
301 }
302 292
303 /* 293 /*
304 * Section 16.5 of the MPC8610 reference manual says that the 294 * Section 16.5 of the MPC8610 reference manual says that the
@@ -316,7 +306,7 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
316 clrsetbits_be32(&ssi->scr, 306 clrsetbits_be32(&ssi->scr,
317 CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_SYN, 307 CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_SYN,
318 CCSR_SSI_SCR_TFR_CLK_DIS | CCSR_SSI_SCR_I2S_MODE_SLAVE 308 CCSR_SSI_SCR_TFR_CLK_DIS | CCSR_SSI_SCR_I2S_MODE_SLAVE
319 | (ssi_private->asynchronous ? 0 : CCSR_SSI_SCR_SYN)); 309 | (synchronous ? CCSR_SSI_SCR_SYN : 0));
320 310
321 out_be32(&ssi->stcr, 311 out_be32(&ssi->stcr,
322 CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFEN0 | 312 CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFEN0 |
@@ -333,7 +323,7 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
333 * master. 323 * master.
334 */ 324 */
335 325
336 /* 4. Enable the interrupts and DMA requests */ 326 /* Enable the interrupts and DMA requests */
337 out_be32(&ssi->sier, SIER_FLAGS); 327 out_be32(&ssi->sier, SIER_FLAGS);
338 328
339 /* 329 /*
@@ -362,58 +352,47 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
362 * this is bad is because at this point, the PCM driver has not 352 * this is bad is because at this point, the PCM driver has not
363 * finished initializing the DMA controller. 353 * finished initializing the DMA controller.
364 */ 354 */
365 } 355 } else {
356 if (synchronous) {
357 struct snd_pcm_runtime *first_runtime =
358 ssi_private->first_stream->runtime;
359 /*
360 * This is the second stream open, and we're in
361 * synchronous mode, so we need to impose sample
362 * sample size constraints. This is because STCCR is
363 * used for playback and capture in synchronous mode,
364 * so there's no way to specify different word
365 * lengths.
366 *
367 * Note that this can cause a race condition if the
368 * second stream is opened before the first stream is
369 * fully initialized. We provide some protection by
370 * checking to make sure the first stream is
371 * initialized, but it's not perfect. ALSA sometimes
372 * re-initializes the driver with a different sample
373 * rate or size. If the second stream is opened
374 * before the first stream has received its final
375 * parameters, then the second stream may be
376 * constrained to the wrong sample rate or size.
377 */
378 if (!first_runtime->sample_bits) {
379 dev_err(substream->pcm->card->dev,
380 "set sample size in %s stream first\n",
381 substream->stream ==
382 SNDRV_PCM_STREAM_PLAYBACK
383 ? "capture" : "playback");
384 return -EAGAIN;
385 }
366 386
367 if (!ssi_private->first_stream)
368 ssi_private->first_stream = substream;
369 else {
370 /* This is the second stream open, so we need to impose sample
371 * rate and maybe sample size constraints. Note that this can
372 * cause a race condition if the second stream is opened before
373 * the first stream is fully initialized.
374 *
375 * We provide some protection by checking to make sure the first
376 * stream is initialized, but it's not perfect. ALSA sometimes
377 * re-initializes the driver with a different sample rate or
378 * size. If the second stream is opened before the first stream
379 * has received its final parameters, then the second stream may
380 * be constrained to the wrong sample rate or size.
381 *
382 * FIXME: This code does not handle opening and closing streams
383 * repeatedly. If you open two streams and then close the first
384 * one, you may not be able to open another stream until you
385 * close the second one as well.
386 */
387 struct snd_pcm_runtime *first_runtime =
388 ssi_private->first_stream->runtime;
389
390 if (!first_runtime->sample_bits) {
391 dev_err(substream->pcm->card->dev,
392 "set sample size in %s stream first\n",
393 substream->stream == SNDRV_PCM_STREAM_PLAYBACK
394 ? "capture" : "playback");
395 return -EAGAIN;
396 }
397
398 /* If we're in synchronous mode, then we need to constrain
399 * the sample size as well. We don't support independent sample
400 * rates in asynchronous mode.
401 */
402 if (!ssi_private->asynchronous)
403 snd_pcm_hw_constraint_minmax(substream->runtime, 387 snd_pcm_hw_constraint_minmax(substream->runtime,
404 SNDRV_PCM_HW_PARAM_SAMPLE_BITS, 388 SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
405 first_runtime->sample_bits, 389 first_runtime->sample_bits,
406 first_runtime->sample_bits); 390 first_runtime->sample_bits);
391 }
407 392
408 ssi_private->second_stream = substream; 393 ssi_private->second_stream = substream;
409 } 394 }
410 395
411 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
412 ssi_private->playback++;
413
414 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
415 ssi_private->capture++;
416
417 return 0; 396 return 0;
418} 397}
419 398
@@ -434,24 +413,35 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
434 struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *cpu_dai) 413 struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *cpu_dai)
435{ 414{
436 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai); 415 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai);
416 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
417 unsigned int sample_size =
418 snd_pcm_format_width(params_format(hw_params));
419 u32 wl = CCSR_SSI_SxCCR_WL(sample_size);
420 int enabled = in_be32(&ssi->scr) & CCSR_SSI_SCR_SSIEN;
437 421
438 if (substream == ssi_private->first_stream) { 422 /*
439 struct ccsr_ssi __iomem *ssi = ssi_private->ssi; 423 * If we're in synchronous mode, and the SSI is already enabled,
440 unsigned int sample_size = 424 * then STCCR is already set properly.
441 snd_pcm_format_width(params_format(hw_params)); 425 */
442 u32 wl = CCSR_SSI_SxCCR_WL(sample_size); 426 if (enabled && ssi_private->cpu_dai_drv.symmetric_rates)
427 return 0;
443 428
444 /* The SSI should always be disabled at this points (SSIEN=0) */ 429 /*
430 * FIXME: The documentation says that SxCCR[WL] should not be
431 * modified while the SSI is enabled. The only time this can
432 * happen is if we're trying to do simultaneous playback and
433 * capture in asynchronous mode. Unfortunately, I have been enable
434 * to get that to work at all on the P1022DS. Therefore, we don't
435 * bother to disable/enable the SSI when setting SxCCR[WL], because
436 * the SSI will stop anyway. Maybe one day, this will get fixed.
437 */
445 438
446 /* In synchronous mode, the SSI uses STCCR for capture */ 439 /* In synchronous mode, the SSI uses STCCR for capture */
447 if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) || 440 if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ||
448 !ssi_private->asynchronous) 441 ssi_private->cpu_dai_drv.symmetric_rates)
449 clrsetbits_be32(&ssi->stccr, 442 clrsetbits_be32(&ssi->stccr, CCSR_SSI_SxCCR_WL_MASK, wl);
450 CCSR_SSI_SxCCR_WL_MASK, wl); 443 else
451 else 444 clrsetbits_be32(&ssi->srccr, CCSR_SSI_SxCCR_WL_MASK, wl);
452 clrsetbits_be32(&ssi->srccr,
453 CCSR_SSI_SxCCR_WL_MASK, wl);
454 }
455 445
456 return 0; 446 return 0;
457} 447}
@@ -474,7 +464,6 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
474 464
475 switch (cmd) { 465 switch (cmd) {
476 case SNDRV_PCM_TRIGGER_START: 466 case SNDRV_PCM_TRIGGER_START:
477 clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN);
478 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 467 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
479 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 468 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
480 setbits32(&ssi->scr, 469 setbits32(&ssi->scr,
@@ -510,27 +499,18 @@ static void fsl_ssi_shutdown(struct snd_pcm_substream *substream,
510 struct snd_soc_pcm_runtime *rtd = substream->private_data; 499 struct snd_soc_pcm_runtime *rtd = substream->private_data;
511 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(rtd->cpu_dai); 500 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(rtd->cpu_dai);
512 501
513 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
514 ssi_private->playback--;
515
516 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
517 ssi_private->capture--;
518
519 if (ssi_private->first_stream == substream) 502 if (ssi_private->first_stream == substream)
520 ssi_private->first_stream = ssi_private->second_stream; 503 ssi_private->first_stream = ssi_private->second_stream;
521 504
522 ssi_private->second_stream = NULL; 505 ssi_private->second_stream = NULL;
523 506
524 /* 507 /*
525 * If this is the last active substream, disable the SSI and release 508 * If this is the last active substream, disable the SSI.
526 * the IRQ.
527 */ 509 */
528 if (!ssi_private->playback && !ssi_private->capture) { 510 if (!ssi_private->first_stream) {
529 struct ccsr_ssi __iomem *ssi = ssi_private->ssi; 511 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
530 512
531 clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN); 513 clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN);
532
533 free_irq(ssi_private->irq, ssi_private);
534 } 514 }
535} 515}
536 516
@@ -675,22 +655,33 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev)
675 ret = of_address_to_resource(np, 0, &res); 655 ret = of_address_to_resource(np, 0, &res);
676 if (ret) { 656 if (ret) {
677 dev_err(&pdev->dev, "could not determine device resources\n"); 657 dev_err(&pdev->dev, "could not determine device resources\n");
678 kfree(ssi_private); 658 goto error_kmalloc;
679 return ret;
680 } 659 }
681 ssi_private->ssi = of_iomap(np, 0); 660 ssi_private->ssi = of_iomap(np, 0);
682 if (!ssi_private->ssi) { 661 if (!ssi_private->ssi) {
683 dev_err(&pdev->dev, "could not map device resources\n"); 662 dev_err(&pdev->dev, "could not map device resources\n");
684 kfree(ssi_private); 663 ret = -ENOMEM;
685 return -ENOMEM; 664 goto error_kmalloc;
686 } 665 }
687 ssi_private->ssi_phys = res.start; 666 ssi_private->ssi_phys = res.start;
667
688 ssi_private->irq = irq_of_parse_and_map(np, 0); 668 ssi_private->irq = irq_of_parse_and_map(np, 0);
669 if (ssi_private->irq == NO_IRQ) {
670 dev_err(&pdev->dev, "no irq for node %s\n", np->full_name);
671 ret = -ENXIO;
672 goto error_iomap;
673 }
674
675 /* The 'name' should not have any slashes in it. */
676 ret = request_irq(ssi_private->irq, fsl_ssi_isr, 0, ssi_private->name,
677 ssi_private);
678 if (ret < 0) {
679 dev_err(&pdev->dev, "could not claim irq %u\n", ssi_private->irq);
680 goto error_irqmap;
681 }
689 682
690 /* Are the RX and the TX clocks locked? */ 683 /* Are the RX and the TX clocks locked? */
691 if (of_find_property(np, "fsl,ssi-asynchronous", NULL)) 684 if (!of_find_property(np, "fsl,ssi-asynchronous", NULL))
692 ssi_private->asynchronous = 1;
693 else
694 ssi_private->cpu_dai_drv.symmetric_rates = 1; 685 ssi_private->cpu_dai_drv.symmetric_rates = 1;
695 686
696 /* Determine the FIFO depth. */ 687 /* Determine the FIFO depth. */
@@ -711,7 +702,7 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev)
711 if (ret) { 702 if (ret) {
712 dev_err(&pdev->dev, "could not create sysfs %s file\n", 703 dev_err(&pdev->dev, "could not create sysfs %s file\n",
713 ssi_private->dev_attr.attr.name); 704 ssi_private->dev_attr.attr.name);
714 goto error; 705 goto error_irq;
715 } 706 }
716 707
717 /* Register with ASoC */ 708 /* Register with ASoC */
@@ -720,7 +711,7 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev)
720 ret = snd_soc_register_dai(&pdev->dev, &ssi_private->cpu_dai_drv); 711 ret = snd_soc_register_dai(&pdev->dev, &ssi_private->cpu_dai_drv);
721 if (ret) { 712 if (ret) {
722 dev_err(&pdev->dev, "failed to register DAI: %d\n", ret); 713 dev_err(&pdev->dev, "failed to register DAI: %d\n", ret);
723 goto error; 714 goto error_dev;
724 } 715 }
725 716
726 /* Trigger the machine driver's probe function. The platform driver 717 /* Trigger the machine driver's probe function. The platform driver
@@ -741,18 +732,28 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev)
741 if (IS_ERR(ssi_private->pdev)) { 732 if (IS_ERR(ssi_private->pdev)) {
742 ret = PTR_ERR(ssi_private->pdev); 733 ret = PTR_ERR(ssi_private->pdev);
743 dev_err(&pdev->dev, "failed to register platform: %d\n", ret); 734 dev_err(&pdev->dev, "failed to register platform: %d\n", ret);
744 goto error; 735 goto error_dai;
745 } 736 }
746 737
747 return 0; 738 return 0;
748 739
749error: 740error_dai:
750 snd_soc_unregister_dai(&pdev->dev); 741 snd_soc_unregister_dai(&pdev->dev);
742
743error_dev:
751 dev_set_drvdata(&pdev->dev, NULL); 744 dev_set_drvdata(&pdev->dev, NULL);
752 if (dev_attr) 745 device_remove_file(&pdev->dev, dev_attr);
753 device_remove_file(&pdev->dev, dev_attr); 746
747error_irq:
748 free_irq(ssi_private->irq, ssi_private);
749
750error_irqmap:
754 irq_dispose_mapping(ssi_private->irq); 751 irq_dispose_mapping(ssi_private->irq);
752
753error_iomap:
755 iounmap(ssi_private->ssi); 754 iounmap(ssi_private->ssi);
755
756error_kmalloc:
756 kfree(ssi_private); 757 kfree(ssi_private);
757 758
758 return ret; 759 return ret;
@@ -766,6 +767,9 @@ static int fsl_ssi_remove(struct platform_device *pdev)
766 snd_soc_unregister_dai(&pdev->dev); 767 snd_soc_unregister_dai(&pdev->dev);
767 device_remove_file(&pdev->dev, &ssi_private->dev_attr); 768 device_remove_file(&pdev->dev, &ssi_private->dev_attr);
768 769
770 free_irq(ssi_private->irq, ssi_private);
771 irq_dispose_mapping(ssi_private->irq);
772
769 kfree(ssi_private); 773 kfree(ssi_private);
770 dev_set_drvdata(&pdev->dev, NULL); 774 dev_set_drvdata(&pdev->dev, NULL);
771 775
diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c
index 358f0baaf71..31af405bda8 100644
--- a/sound/soc/fsl/mpc8610_hpcd.c
+++ b/sound/soc/fsl/mpc8610_hpcd.c
@@ -505,7 +505,7 @@ static int mpc8610_hpcd_probe(struct platform_device *pdev)
505 return 0; 505 return 0;
506 506
507error_sound: 507error_sound:
508 platform_device_unregister(sound_device); 508 platform_device_put(sound_device);
509error: 509error:
510 kfree(machine_data); 510 kfree(machine_data);
511error_alloc: 511error_alloc:
diff --git a/sound/soc/fsl/p1022_ds.c b/sound/soc/fsl/p1022_ds.c
index fcb862eb0c7..2c064a9824a 100644
--- a/sound/soc/fsl/p1022_ds.c
+++ b/sound/soc/fsl/p1022_ds.c
@@ -267,7 +267,7 @@ static int codec_node_dev_name(struct device_node *np, char *buf, size_t len)
267 if (bus < 0) 267 if (bus < 0)
268 return bus; 268 return bus;
269 269
270 snprintf(buf, len, "%s-codec.%u-%04x", temp, bus, addr); 270 snprintf(buf, len, "%s.%u-%04x", temp, bus, addr);
271 271
272 return 0; 272 return 0;
273} 273}
@@ -506,7 +506,7 @@ static int p1022_ds_probe(struct platform_device *pdev)
506 506
507error: 507error:
508 if (sound_device) 508 if (sound_device)
509 platform_device_unregister(sound_device); 509 platform_device_put(sound_device);
510 510
511 kfree(mdata); 511 kfree(mdata);
512error_put: 512error_put:
diff --git a/sound/soc/imx/Kconfig b/sound/soc/imx/Kconfig
index bb699bb55a5..b133bfcc584 100644
--- a/sound/soc/imx/Kconfig
+++ b/sound/soc/imx/Kconfig
@@ -29,7 +29,7 @@ config SND_MXC_SOC_WM1133_EV1
29config SND_SOC_MX27VIS_AIC32X4 29config SND_SOC_MX27VIS_AIC32X4
30 tristate "SoC audio support for Visstrim M10 boards" 30 tristate "SoC audio support for Visstrim M10 boards"
31 depends on MACH_IMX27_VISSTRIM_M10 31 depends on MACH_IMX27_VISSTRIM_M10
32 select SND_SOC_TVL320AIC32X4 32 select SND_SOC_TLV320AIC32X4
33 select SND_MXC_SOC_MX2 33 select SND_MXC_SOC_MX2
34 help 34 help
35 Say Y if you want to add support for SoC audio on Visstrim SM10 35 Say Y if you want to add support for SoC audio on Visstrim SM10
@@ -50,6 +50,7 @@ config SND_SOC_EUKREA_TLV320
50 || MACH_EUKREA_MBIMXSD25_BASEBOARD \ 50 || MACH_EUKREA_MBIMXSD25_BASEBOARD \
51 || MACH_EUKREA_MBIMXSD35_BASEBOARD \ 51 || MACH_EUKREA_MBIMXSD35_BASEBOARD \
52 || MACH_EUKREA_MBIMXSD51_BASEBOARD 52 || MACH_EUKREA_MBIMXSD51_BASEBOARD
53 depends on I2C
53 select SND_SOC_TLV320AIC23 54 select SND_SOC_TLV320AIC23
54 select SND_MXC_SOC_FIQ 55 select SND_MXC_SOC_FIQ
55 help 56 help
diff --git a/sound/soc/imx/imx-pcm-fiq.c b/sound/soc/imx/imx-pcm-fiq.c
index 7945625e0e0..8df0fae2194 100644
--- a/sound/soc/imx/imx-pcm-fiq.c
+++ b/sound/soc/imx/imx-pcm-fiq.c
@@ -240,25 +240,23 @@ static int ssi_irq = 0;
240 240
241static int imx_pcm_fiq_new(struct snd_soc_pcm_runtime *rtd) 241static int imx_pcm_fiq_new(struct snd_soc_pcm_runtime *rtd)
242{ 242{
243 struct snd_soc_dai *dai = rtd->cpu_dai;
244 struct snd_pcm *pcm = rtd->pcm; 243 struct snd_pcm *pcm = rtd->pcm;
244 struct snd_pcm_substream *substream;
245 int ret; 245 int ret;
246 246
247 ret = imx_pcm_new(rtd); 247 ret = imx_pcm_new(rtd);
248 if (ret) 248 if (ret)
249 return ret; 249 return ret;
250 250
251 if (dai->driver->playback.channels_min) { 251 substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
252 struct snd_pcm_substream *substream = 252 if (substream) {
253 pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
254 struct snd_dma_buffer *buf = &substream->dma_buffer; 253 struct snd_dma_buffer *buf = &substream->dma_buffer;
255 254
256 imx_ssi_fiq_tx_buffer = (unsigned long)buf->area; 255 imx_ssi_fiq_tx_buffer = (unsigned long)buf->area;
257 } 256 }
258 257
259 if (dai->driver->capture.channels_min) { 258 substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
260 struct snd_pcm_substream *substream = 259 if (substream) {
261 pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
262 struct snd_dma_buffer *buf = &substream->dma_buffer; 260 struct snd_dma_buffer *buf = &substream->dma_buffer;
263 261
264 imx_ssi_fiq_rx_buffer = (unsigned long)buf->area; 262 imx_ssi_fiq_rx_buffer = (unsigned long)buf->area;
diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c
index 10a8e278375..4c05e2b8f4d 100644
--- a/sound/soc/imx/imx-ssi.c
+++ b/sound/soc/imx/imx-ssi.c
@@ -357,8 +357,8 @@ int snd_imx_pcm_mmap(struct snd_pcm_substream *substream,
357 struct snd_pcm_runtime *runtime = substream->runtime; 357 struct snd_pcm_runtime *runtime = substream->runtime;
358 int ret; 358 int ret;
359 359
360 ret = dma_mmap_coherent(NULL, vma, runtime->dma_area, 360 ret = dma_mmap_writecombine(substream->pcm->card->dev, vma,
361 runtime->dma_addr, runtime->dma_bytes); 361 runtime->dma_area, runtime->dma_addr, runtime->dma_bytes);
362 362
363 pr_debug("%s: ret: %d %p 0x%08x 0x%08x\n", __func__, ret, 363 pr_debug("%s: ret: %d %p 0x%08x 0x%08x\n", __func__, ret,
364 runtime->dma_area, 364 runtime->dma_area,
@@ -391,7 +391,6 @@ static u64 imx_pcm_dmamask = DMA_BIT_MASK(32);
391int imx_pcm_new(struct snd_soc_pcm_runtime *rtd) 391int imx_pcm_new(struct snd_soc_pcm_runtime *rtd)
392{ 392{
393 struct snd_card *card = rtd->card->snd_card; 393 struct snd_card *card = rtd->card->snd_card;
394 struct snd_soc_dai *dai = rtd->cpu_dai;
395 struct snd_pcm *pcm = rtd->pcm; 394 struct snd_pcm *pcm = rtd->pcm;
396 int ret = 0; 395 int ret = 0;
397 396
@@ -399,14 +398,14 @@ int imx_pcm_new(struct snd_soc_pcm_runtime *rtd)
399 card->dev->dma_mask = &imx_pcm_dmamask; 398 card->dev->dma_mask = &imx_pcm_dmamask;
400 if (!card->dev->coherent_dma_mask) 399 if (!card->dev->coherent_dma_mask)
401 card->dev->coherent_dma_mask = DMA_BIT_MASK(32); 400 card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
402 if (dai->driver->playback.channels_min) { 401 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
403 ret = imx_pcm_preallocate_dma_buffer(pcm, 402 ret = imx_pcm_preallocate_dma_buffer(pcm,
404 SNDRV_PCM_STREAM_PLAYBACK); 403 SNDRV_PCM_STREAM_PLAYBACK);
405 if (ret) 404 if (ret)
406 goto out; 405 goto out;
407 } 406 }
408 407
409 if (dai->driver->capture.channels_min) { 408 if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
410 ret = imx_pcm_preallocate_dma_buffer(pcm, 409 ret = imx_pcm_preallocate_dma_buffer(pcm,
411 SNDRV_PCM_STREAM_CAPTURE); 410 SNDRV_PCM_STREAM_CAPTURE);
412 if (ret) 411 if (ret)
diff --git a/sound/soc/imx/imx-ssi.h b/sound/soc/imx/imx-ssi.h
index 0a84cec3599..1072dfb53e4 100644
--- a/sound/soc/imx/imx-ssi.h
+++ b/sound/soc/imx/imx-ssi.h
@@ -218,12 +218,6 @@ struct imx_ssi {
218 struct platform_device *soc_platform_pdev_fiq; 218 struct platform_device *soc_platform_pdev_fiq;
219}; 219};
220 220
221struct snd_soc_platform *imx_ssi_fiq_init(struct platform_device *pdev,
222 struct imx_ssi *ssi);
223void imx_ssi_fiq_exit(struct platform_device *pdev, struct imx_ssi *ssi);
224struct snd_soc_platform *imx_ssi_dma_mx2_init(struct platform_device *pdev,
225 struct imx_ssi *ssi);
226
227int snd_imx_pcm_mmap(struct snd_pcm_substream *substream, struct vm_area_struct *vma); 221int snd_imx_pcm_mmap(struct snd_pcm_substream *substream, struct vm_area_struct *vma);
228int imx_pcm_new(struct snd_soc_pcm_runtime *rtd); 222int imx_pcm_new(struct snd_soc_pcm_runtime *rtd);
229void imx_pcm_free(struct snd_pcm *pcm); 223void imx_pcm_free(struct snd_pcm *pcm);
diff --git a/sound/soc/jz4740/jz4740-pcm.c b/sound/soc/jz4740/jz4740-pcm.c
index a7c9578be98..d1989cde9f1 100644
--- a/sound/soc/jz4740/jz4740-pcm.c
+++ b/sound/soc/jz4740/jz4740-pcm.c
@@ -299,7 +299,7 @@ static void jz4740_pcm_free(struct snd_pcm *pcm)
299 299
300static u64 jz4740_pcm_dmamask = DMA_BIT_MASK(32); 300static u64 jz4740_pcm_dmamask = DMA_BIT_MASK(32);
301 301
302int jz4740_pcm_new(struct snd_soc_pcm_runtime *rtd) 302static int jz4740_pcm_new(struct snd_soc_pcm_runtime *rtd)
303{ 303{
304 struct snd_card *card = rtd->card->snd_card; 304 struct snd_card *card = rtd->card->snd_card;
305 struct snd_soc_dai *dai = rtd->cpu_dai; 305 struct snd_soc_dai *dai = rtd->cpu_dai;
diff --git a/sound/soc/kirkwood/kirkwood-i2s.c b/sound/soc/kirkwood/kirkwood-i2s.c
index d0bcf3fcea0..715e841c050 100644
--- a/sound/soc/kirkwood/kirkwood-i2s.c
+++ b/sound/soc/kirkwood/kirkwood-i2s.c
@@ -476,7 +476,7 @@ static __devexit int kirkwood_i2s_dev_remove(struct platform_device *pdev)
476 476
477static struct platform_driver kirkwood_i2s_driver = { 477static struct platform_driver kirkwood_i2s_driver = {
478 .probe = kirkwood_i2s_dev_probe, 478 .probe = kirkwood_i2s_dev_probe,
479 .remove = kirkwood_i2s_dev_remove, 479 .remove = __devexit_p(kirkwood_i2s_dev_remove),
480 .driver = { 480 .driver = {
481 .name = DRV_NAME, 481 .name = DRV_NAME,
482 .owner = THIS_MODULE, 482 .owner = THIS_MODULE,
diff --git a/sound/soc/kirkwood/kirkwood-t5325.c b/sound/soc/kirkwood/kirkwood-t5325.c
index c8d21956ab5..c772b3cf403 100644
--- a/sound/soc/kirkwood/kirkwood-t5325.c
+++ b/sound/soc/kirkwood/kirkwood-t5325.c
@@ -79,8 +79,6 @@ static int t5325_dai_init(struct snd_soc_pcm_runtime *rtd)
79 snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); 79 snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
80 snd_soc_dapm_enable_pin(dapm, "Speaker"); 80 snd_soc_dapm_enable_pin(dapm, "Speaker");
81 81
82 snd_soc_dapm_sync(dapm);
83
84 return 0; 82 return 0;
85} 83}
86 84
diff --git a/sound/soc/mid-x86/mfld_machine.c b/sound/soc/mid-x86/mfld_machine.c
index 429aa1be2cf..598f48c0d8f 100644
--- a/sound/soc/mid-x86/mfld_machine.c
+++ b/sound/soc/mid-x86/mfld_machine.c
@@ -54,9 +54,7 @@ static unsigned int hs_switch;
54static unsigned int lo_dac; 54static unsigned int lo_dac;
55 55
56struct mfld_mc_private { 56struct mfld_mc_private {
57 struct platform_device *socdev;
58 void __iomem *int_base; 57 void __iomem *int_base;
59 struct snd_soc_codec *codec;
60 u8 interrupt_status; 58 u8 interrupt_status;
61}; 59};
62 60
@@ -235,7 +233,6 @@ static int mfld_init(struct snd_soc_pcm_runtime *runtime)
235 /* always connected */ 233 /* always connected */
236 snd_soc_dapm_enable_pin(dapm, "Headphones"); 234 snd_soc_dapm_enable_pin(dapm, "Headphones");
237 snd_soc_dapm_enable_pin(dapm, "Mic"); 235 snd_soc_dapm_enable_pin(dapm, "Mic");
238 snd_soc_dapm_sync(dapm);
239 236
240 ret_val = snd_soc_add_controls(codec, mfld_snd_controls, 237 ret_val = snd_soc_add_controls(codec, mfld_snd_controls,
241 ARRAY_SIZE(mfld_snd_controls)); 238 ARRAY_SIZE(mfld_snd_controls));
@@ -253,7 +250,6 @@ static int mfld_init(struct snd_soc_pcm_runtime *runtime)
253 /* we dont use linein in this so set to NC */ 250 /* we dont use linein in this so set to NC */
254 snd_soc_dapm_disable_pin(dapm, "LINEINL"); 251 snd_soc_dapm_disable_pin(dapm, "LINEINL");
255 snd_soc_dapm_disable_pin(dapm, "LINEINR"); 252 snd_soc_dapm_disable_pin(dapm, "LINEINR");
256 snd_soc_dapm_sync(dapm);
257 253
258 /* Headset and button jack detection */ 254 /* Headset and button jack detection */
259 ret_val = snd_soc_jack_new(codec, "Intel(R) MID Audio Jack", 255 ret_val = snd_soc_jack_new(codec, "Intel(R) MID Audio Jack",
diff --git a/sound/soc/mid-x86/sst_platform.c b/sound/soc/mid-x86/sst_platform.c
index 3e7826058ef..7df8c58ba50 100644
--- a/sound/soc/mid-x86/sst_platform.c
+++ b/sound/soc/mid-x86/sst_platform.c
@@ -63,7 +63,7 @@ static struct snd_pcm_hardware sst_platform_pcm_hw = {
63}; 63};
64 64
65/* MFLD - MSIC */ 65/* MFLD - MSIC */
66struct snd_soc_dai_driver sst_platform_dai[] = { 66static struct snd_soc_dai_driver sst_platform_dai[] = {
67{ 67{
68 .name = "Headset-cpu-dai", 68 .name = "Headset-cpu-dai",
69 .id = 0, 69 .id = 0,
@@ -226,13 +226,18 @@ static int sst_platform_init_stream(struct snd_pcm_substream *substream)
226 226
227static int sst_platform_open(struct snd_pcm_substream *substream) 227static int sst_platform_open(struct snd_pcm_substream *substream)
228{ 228{
229 struct snd_pcm_runtime *runtime; 229 struct snd_pcm_runtime *runtime = substream->runtime;
230 struct sst_runtime_stream *stream; 230 struct sst_runtime_stream *stream;
231 int ret_val = 0; 231 int ret_val = 0;
232 232
233 pr_debug("sst_platform_open called\n"); 233 pr_debug("sst_platform_open called\n");
234 runtime = substream->runtime; 234
235 runtime->hw = sst_platform_pcm_hw; 235 snd_soc_set_runtime_hwparams(substream, &sst_platform_pcm_hw);
236 ret_val = snd_pcm_hw_constraint_integer(runtime,
237 SNDRV_PCM_HW_PARAM_PERIODS);
238 if (ret_val < 0)
239 return ret_val;
240
236 stream = kzalloc(sizeof(*stream), GFP_KERNEL); 241 stream = kzalloc(sizeof(*stream), GFP_KERNEL);
237 if (!stream) 242 if (!stream)
238 return -ENOMEM; 243 return -ENOMEM;
@@ -259,8 +264,8 @@ static int sst_platform_open(struct snd_pcm_substream *substream)
259 return ret_val; 264 return ret_val;
260 } 265 }
261 runtime->private_data = stream; 266 runtime->private_data = stream;
262 return snd_pcm_hw_constraint_integer(runtime, 267
263 SNDRV_PCM_HW_PARAM_PERIODS); 268 return 0;
264} 269}
265 270
266static int sst_platform_close(struct snd_pcm_substream *substream) 271static int sst_platform_close(struct snd_pcm_substream *substream)
@@ -469,7 +474,7 @@ static struct platform_driver sst_platform_driver = {
469static int __init sst_soc_platform_init(void) 474static int __init sst_soc_platform_init(void)
470{ 475{
471 pr_debug("sst_soc_platform_init called\n"); 476 pr_debug("sst_soc_platform_init called\n");
472 return platform_driver_register(&sst_platform_driver); 477 return platform_driver_register(&sst_platform_driver);
473} 478}
474module_init(sst_soc_platform_init); 479module_init(sst_soc_platform_init);
475 480
diff --git a/sound/soc/mxs/Kconfig b/sound/soc/mxs/Kconfig
new file mode 100644
index 00000000000..e4ba8d5f25f
--- /dev/null
+++ b/sound/soc/mxs/Kconfig
@@ -0,0 +1,20 @@
1menuconfig SND_MXS_SOC
2 tristate "SoC Audio for Freescale MXS CPUs"
3 depends on ARCH_MXS
4 select SND_PCM
5 help
6 Say Y or M if you want to add support for codecs attached to
7 the MXS SAIF interface.
8
9
10if SND_MXS_SOC
11
12config SND_SOC_MXS_SGTL5000
13 tristate "SoC Audio support for i.MX boards with sgtl5000"
14 depends on I2C
15 select SND_SOC_SGTL5000
16 help
17 Say Y if you want to add support for SoC audio on an MXS board with
18 a sgtl5000 codec.
19
20endif # SND_MXS_SOC
diff --git a/sound/soc/mxs/Makefile b/sound/soc/mxs/Makefile
new file mode 100644
index 00000000000..565b5b51e8b
--- /dev/null
+++ b/sound/soc/mxs/Makefile
@@ -0,0 +1,10 @@
1# MXS Platform Support
2snd-soc-mxs-objs := mxs-saif.o
3snd-soc-mxs-pcm-objs := mxs-pcm.o
4
5obj-$(CONFIG_SND_MXS_SOC) += snd-soc-mxs.o snd-soc-mxs-pcm.o
6
7# i.MX Machine Support
8snd-soc-mxs-sgtl5000-objs := mxs-sgtl5000.o
9
10obj-$(CONFIG_SND_SOC_MXS_SGTL5000) += snd-soc-mxs-sgtl5000.o
diff --git a/sound/soc/mxs/mxs-pcm.c b/sound/soc/mxs/mxs-pcm.c
new file mode 100644
index 00000000000..dea5aa4aa64
--- /dev/null
+++ b/sound/soc/mxs/mxs-pcm.c
@@ -0,0 +1,359 @@
1/*
2 * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
3 *
4 * Based on sound/soc/imx/imx-pcm-dma-mx2.c
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21#include <linux/clk.h>
22#include <linux/delay.h>
23#include <linux/device.h>
24#include <linux/dma-mapping.h>
25#include <linux/init.h>
26#include <linux/interrupt.h>
27#include <linux/module.h>
28#include <linux/platform_device.h>
29#include <linux/slab.h>
30#include <linux/dmaengine.h>
31
32#include <sound/core.h>
33#include <sound/initval.h>
34#include <sound/pcm.h>
35#include <sound/pcm_params.h>
36#include <sound/soc.h>
37
38#include <mach/dma.h>
39#include "mxs-pcm.h"
40
41static struct snd_pcm_hardware snd_mxs_hardware = {
42 .info = SNDRV_PCM_INFO_MMAP |
43 SNDRV_PCM_INFO_MMAP_VALID |
44 SNDRV_PCM_INFO_PAUSE |
45 SNDRV_PCM_INFO_RESUME |
46 SNDRV_PCM_INFO_INTERLEAVED,
47 .formats = SNDRV_PCM_FMTBIT_S16_LE |
48 SNDRV_PCM_FMTBIT_S20_3LE |
49 SNDRV_PCM_FMTBIT_S24_LE,
50 .channels_min = 2,
51 .channels_max = 2,
52 .period_bytes_min = 32,
53 .period_bytes_max = 8192,
54 .periods_min = 1,
55 .periods_max = 52,
56 .buffer_bytes_max = 64 * 1024,
57 .fifo_size = 32,
58
59};
60
61static void audio_dma_irq(void *data)
62{
63 struct snd_pcm_substream *substream = (struct snd_pcm_substream *)data;
64 struct snd_pcm_runtime *runtime = substream->runtime;
65 struct mxs_pcm_runtime_data *iprtd = runtime->private_data;
66
67 iprtd->offset += iprtd->period_bytes;
68 iprtd->offset %= iprtd->period_bytes * iprtd->periods;
69 snd_pcm_period_elapsed(substream);
70}
71
72static bool filter(struct dma_chan *chan, void *param)
73{
74 struct mxs_pcm_runtime_data *iprtd = param;
75 struct mxs_pcm_dma_params *dma_params = iprtd->dma_params;
76
77 if (!mxs_dma_is_apbx(chan))
78 return false;
79
80 if (chan->chan_id != dma_params->chan_num)
81 return false;
82
83 chan->private = &iprtd->dma_data;
84
85 return true;
86}
87
88static int mxs_dma_alloc(struct snd_pcm_substream *substream,
89 struct snd_pcm_hw_params *params)
90{
91 struct snd_soc_pcm_runtime *rtd = substream->private_data;
92 struct snd_pcm_runtime *runtime = substream->runtime;
93 struct mxs_pcm_runtime_data *iprtd = runtime->private_data;
94 dma_cap_mask_t mask;
95
96 iprtd->dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
97
98 dma_cap_zero(mask);
99 dma_cap_set(DMA_SLAVE, mask);
100 iprtd->dma_data.chan_irq = iprtd->dma_params->chan_irq;
101 iprtd->dma_chan = dma_request_channel(mask, filter, iprtd);
102 if (!iprtd->dma_chan)
103 return -EINVAL;
104
105 return 0;
106}
107
108static int snd_mxs_pcm_hw_params(struct snd_pcm_substream *substream,
109 struct snd_pcm_hw_params *params)
110{
111 struct snd_pcm_runtime *runtime = substream->runtime;
112 struct mxs_pcm_runtime_data *iprtd = runtime->private_data;
113 unsigned long dma_addr;
114 struct dma_chan *chan;
115 int ret;
116
117 ret = mxs_dma_alloc(substream, params);
118 if (ret)
119 return ret;
120 chan = iprtd->dma_chan;
121
122 iprtd->size = params_buffer_bytes(params);
123 iprtd->periods = params_periods(params);
124 iprtd->period_bytes = params_period_bytes(params);
125 iprtd->offset = 0;
126 iprtd->period_time = HZ / (params_rate(params) /
127 params_period_size(params));
128
129 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
130
131 dma_addr = runtime->dma_addr;
132
133 iprtd->buf = substream->dma_buffer.area;
134
135 iprtd->desc = chan->device->device_prep_dma_cyclic(chan, dma_addr,
136 iprtd->period_bytes * iprtd->periods,
137 iprtd->period_bytes,
138 substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
139 DMA_TO_DEVICE : DMA_FROM_DEVICE);
140 if (!iprtd->desc) {
141 dev_err(&chan->dev->device, "cannot prepare slave dma\n");
142 return -EINVAL;
143 }
144
145 iprtd->desc->callback = audio_dma_irq;
146 iprtd->desc->callback_param = substream;
147
148 return 0;
149}
150
151static int snd_mxs_pcm_hw_free(struct snd_pcm_substream *substream)
152{
153 struct snd_pcm_runtime *runtime = substream->runtime;
154 struct mxs_pcm_runtime_data *iprtd = runtime->private_data;
155
156 if (iprtd->dma_chan) {
157 dma_release_channel(iprtd->dma_chan);
158 iprtd->dma_chan = NULL;
159 }
160
161 return 0;
162}
163
164static int snd_mxs_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
165{
166 struct snd_pcm_runtime *runtime = substream->runtime;
167 struct mxs_pcm_runtime_data *iprtd = runtime->private_data;
168
169 switch (cmd) {
170 case SNDRV_PCM_TRIGGER_START:
171 case SNDRV_PCM_TRIGGER_RESUME:
172 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
173 dmaengine_submit(iprtd->desc);
174
175 break;
176 case SNDRV_PCM_TRIGGER_STOP:
177 case SNDRV_PCM_TRIGGER_SUSPEND:
178 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
179 dmaengine_terminate_all(iprtd->dma_chan);
180
181 break;
182 default:
183 return -EINVAL;
184 }
185
186 return 0;
187}
188
189static snd_pcm_uframes_t snd_mxs_pcm_pointer(
190 struct snd_pcm_substream *substream)
191{
192 struct snd_pcm_runtime *runtime = substream->runtime;
193 struct mxs_pcm_runtime_data *iprtd = runtime->private_data;
194
195 return bytes_to_frames(substream->runtime, iprtd->offset);
196}
197
198static int snd_mxs_open(struct snd_pcm_substream *substream)
199{
200 struct snd_pcm_runtime *runtime = substream->runtime;
201 struct mxs_pcm_runtime_data *iprtd;
202 int ret;
203
204 iprtd = kzalloc(sizeof(*iprtd), GFP_KERNEL);
205 if (iprtd == NULL)
206 return -ENOMEM;
207 runtime->private_data = iprtd;
208
209 ret = snd_pcm_hw_constraint_integer(substream->runtime,
210 SNDRV_PCM_HW_PARAM_PERIODS);
211 if (ret < 0) {
212 kfree(iprtd);
213 return ret;
214 }
215
216 snd_soc_set_runtime_hwparams(substream, &snd_mxs_hardware);
217
218 return 0;
219}
220
221static int snd_mxs_close(struct snd_pcm_substream *substream)
222{
223 struct snd_pcm_runtime *runtime = substream->runtime;
224 struct mxs_pcm_runtime_data *iprtd = runtime->private_data;
225
226 kfree(iprtd);
227
228 return 0;
229}
230
231static int snd_mxs_pcm_mmap(struct snd_pcm_substream *substream,
232 struct vm_area_struct *vma)
233{
234 struct snd_pcm_runtime *runtime = substream->runtime;
235
236 return dma_mmap_writecombine(substream->pcm->card->dev, vma,
237 runtime->dma_area,
238 runtime->dma_addr,
239 runtime->dma_bytes);
240}
241
242static struct snd_pcm_ops mxs_pcm_ops = {
243 .open = snd_mxs_open,
244 .close = snd_mxs_close,
245 .ioctl = snd_pcm_lib_ioctl,
246 .hw_params = snd_mxs_pcm_hw_params,
247 .hw_free = snd_mxs_pcm_hw_free,
248 .trigger = snd_mxs_pcm_trigger,
249 .pointer = snd_mxs_pcm_pointer,
250 .mmap = snd_mxs_pcm_mmap,
251};
252
253static int mxs_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
254{
255 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
256 struct snd_dma_buffer *buf = &substream->dma_buffer;
257 size_t size = snd_mxs_hardware.buffer_bytes_max;
258
259 buf->dev.type = SNDRV_DMA_TYPE_DEV;
260 buf->dev.dev = pcm->card->dev;
261 buf->private_data = NULL;
262 buf->area = dma_alloc_writecombine(pcm->card->dev, size,
263 &buf->addr, GFP_KERNEL);
264 if (!buf->area)
265 return -ENOMEM;
266 buf->bytes = size;
267
268 return 0;
269}
270
271static u64 mxs_pcm_dmamask = DMA_BIT_MASK(32);
272static int mxs_pcm_new(struct snd_soc_pcm_runtime *rtd)
273{
274 struct snd_card *card = rtd->card->snd_card;
275 struct snd_pcm *pcm = rtd->pcm;
276 int ret = 0;
277
278 if (!card->dev->dma_mask)
279 card->dev->dma_mask = &mxs_pcm_dmamask;
280 if (!card->dev->coherent_dma_mask)
281 card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
282
283 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
284 ret = mxs_pcm_preallocate_dma_buffer(pcm,
285 SNDRV_PCM_STREAM_PLAYBACK);
286 if (ret)
287 goto out;
288 }
289
290 if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
291 ret = mxs_pcm_preallocate_dma_buffer(pcm,
292 SNDRV_PCM_STREAM_CAPTURE);
293 if (ret)
294 goto out;
295 }
296
297out:
298 return ret;
299}
300
301static void mxs_pcm_free(struct snd_pcm *pcm)
302{
303 struct snd_pcm_substream *substream;
304 struct snd_dma_buffer *buf;
305 int stream;
306
307 for (stream = 0; stream < 2; stream++) {
308 substream = pcm->streams[stream].substream;
309 if (!substream)
310 continue;
311
312 buf = &substream->dma_buffer;
313 if (!buf->area)
314 continue;
315
316 dma_free_writecombine(pcm->card->dev, buf->bytes,
317 buf->area, buf->addr);
318 buf->area = NULL;
319 }
320}
321
322static struct snd_soc_platform_driver mxs_soc_platform = {
323 .ops = &mxs_pcm_ops,
324 .pcm_new = mxs_pcm_new,
325 .pcm_free = mxs_pcm_free,
326};
327
328static int __devinit mxs_soc_platform_probe(struct platform_device *pdev)
329{
330 return snd_soc_register_platform(&pdev->dev, &mxs_soc_platform);
331}
332
333static int __devexit mxs_soc_platform_remove(struct platform_device *pdev)
334{
335 snd_soc_unregister_platform(&pdev->dev);
336
337 return 0;
338}
339
340static struct platform_driver mxs_pcm_driver = {
341 .driver = {
342 .name = "mxs-pcm-audio",
343 .owner = THIS_MODULE,
344 },
345 .probe = mxs_soc_platform_probe,
346 .remove = __devexit_p(mxs_soc_platform_remove),
347};
348
349static int __init snd_mxs_pcm_init(void)
350{
351 return platform_driver_register(&mxs_pcm_driver);
352}
353module_init(snd_mxs_pcm_init);
354
355static void __exit snd_mxs_pcm_exit(void)
356{
357 platform_driver_unregister(&mxs_pcm_driver);
358}
359module_exit(snd_mxs_pcm_exit);
diff --git a/sound/soc/mxs/mxs-pcm.h b/sound/soc/mxs/mxs-pcm.h
new file mode 100644
index 00000000000..f55ac4f7a76
--- /dev/null
+++ b/sound/soc/mxs/mxs-pcm.h
@@ -0,0 +1,43 @@
1/*
2 * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
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 as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19#ifndef _MXS_PCM_H
20#define _MXS_PCM_H
21
22#include <mach/dma.h>
23
24struct mxs_pcm_dma_params {
25 int chan_irq;
26 int chan_num;
27};
28
29struct mxs_pcm_runtime_data {
30 int period_bytes;
31 int periods;
32 int dma;
33 unsigned long offset;
34 unsigned long size;
35 void *buf;
36 int period_time;
37 struct dma_async_tx_descriptor *desc;
38 struct dma_chan *dma_chan;
39 struct mxs_dma_data dma_data;
40 struct mxs_pcm_dma_params *dma_params;
41};
42
43#endif
diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c
new file mode 100644
index 00000000000..76dc74d24fc
--- /dev/null
+++ b/sound/soc/mxs/mxs-saif.c
@@ -0,0 +1,798 @@
1/*
2 * Copyright 2011 Freescale Semiconductor, Inc.
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 as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19#include <linux/module.h>
20#include <linux/init.h>
21#include <linux/platform_device.h>
22#include <linux/slab.h>
23#include <linux/dma-mapping.h>
24#include <linux/clk.h>
25#include <linux/delay.h>
26#include <linux/time.h>
27#include <sound/core.h>
28#include <sound/pcm.h>
29#include <sound/pcm_params.h>
30#include <sound/soc.h>
31#include <sound/saif.h>
32#include <mach/dma.h>
33#include <asm/mach-types.h>
34#include <mach/hardware.h>
35#include <mach/mxs.h>
36
37#include "mxs-saif.h"
38
39static struct mxs_saif *mxs_saif[2];
40
41/*
42 * SAIF is a little different with other normal SOC DAIs on clock using.
43 *
44 * For MXS, two SAIF modules are instantiated on-chip.
45 * Each SAIF has a set of clock pins and can be operating in master
46 * mode simultaneously if they are connected to different off-chip codecs.
47 * Also, one of the two SAIFs can master or drive the clock pins while the
48 * other SAIF, in slave mode, receives clocking from the master SAIF.
49 * This also means that both SAIFs must operate at the same sample rate.
50 *
51 * We abstract this as each saif has a master, the master could be
52 * himself or other saifs. In the generic saif driver, saif does not need
53 * to know the different clkmux. Saif only needs to know who is his master
54 * and operating his master to generate the proper clock rate for him.
55 * The master id is provided in mach-specific layer according to different
56 * clkmux setting.
57 */
58
59static int mxs_saif_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
60 int clk_id, unsigned int freq, int dir)
61{
62 struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai);
63
64 switch (clk_id) {
65 case MXS_SAIF_MCLK:
66 saif->mclk = freq;
67 break;
68 default:
69 return -EINVAL;
70 }
71 return 0;
72}
73
74/*
75 * Since SAIF may work on EXTMASTER mode, IOW, it's working BITCLK&LRCLK
76 * is provided by other SAIF, we provide a interface here to get its master
77 * from its master_id.
78 * Note that the master could be himself.
79 */
80static inline struct mxs_saif *mxs_saif_get_master(struct mxs_saif * saif)
81{
82 return mxs_saif[saif->master_id];
83}
84
85/*
86 * Set SAIF clock and MCLK
87 */
88static int mxs_saif_set_clk(struct mxs_saif *saif,
89 unsigned int mclk,
90 unsigned int rate)
91{
92 u32 scr;
93 int ret;
94 struct mxs_saif *master_saif;
95
96 dev_dbg(saif->dev, "mclk %d rate %d\n", mclk, rate);
97
98 /* Set master saif to generate proper clock */
99 master_saif = mxs_saif_get_master(saif);
100 if (!master_saif)
101 return -EINVAL;
102
103 dev_dbg(saif->dev, "master saif%d\n", master_saif->id);
104
105 /* Checking if can playback and capture simutaneously */
106 if (master_saif->ongoing && rate != master_saif->cur_rate) {
107 dev_err(saif->dev,
108 "can not change clock, master saif%d(rate %d) is ongoing\n",
109 master_saif->id, master_saif->cur_rate);
110 return -EINVAL;
111 }
112
113 scr = __raw_readl(master_saif->base + SAIF_CTRL);
114 scr &= ~BM_SAIF_CTRL_BITCLK_MULT_RATE;
115 scr &= ~BM_SAIF_CTRL_BITCLK_BASE_RATE;
116
117 /*
118 * Set SAIF clock
119 *
120 * The SAIF clock should be either 384*fs or 512*fs.
121 * If MCLK is used, the SAIF clk ratio need to match mclk ratio.
122 * For 32x mclk, set saif clk as 512*fs.
123 * For 48x mclk, set saif clk as 384*fs.
124 *
125 * If MCLK is not used, we just set saif clk to 512*fs.
126 */
127 if (master_saif->mclk_in_use) {
128 if (mclk % 32 == 0) {
129 scr &= ~BM_SAIF_CTRL_BITCLK_BASE_RATE;
130 ret = clk_set_rate(master_saif->clk, 512 * rate);
131 } else if (mclk % 48 == 0) {
132 scr |= BM_SAIF_CTRL_BITCLK_BASE_RATE;
133 ret = clk_set_rate(master_saif->clk, 384 * rate);
134 } else {
135 /* SAIF MCLK should be either 32x or 48x */
136 return -EINVAL;
137 }
138 } else {
139 ret = clk_set_rate(master_saif->clk, 512 * rate);
140 scr &= ~BM_SAIF_CTRL_BITCLK_BASE_RATE;
141 }
142
143 if (ret)
144 return ret;
145
146 master_saif->cur_rate = rate;
147
148 if (!master_saif->mclk_in_use) {
149 __raw_writel(scr, master_saif->base + SAIF_CTRL);
150 return 0;
151 }
152
153 /*
154 * Program the over-sample rate for MCLK output
155 *
156 * The available MCLK range is 32x, 48x... 512x. The rate
157 * could be from 8kHz to 192kH.
158 */
159 switch (mclk / rate) {
160 case 32:
161 scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(4);
162 break;
163 case 64:
164 scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(3);
165 break;
166 case 128:
167 scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(2);
168 break;
169 case 256:
170 scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(1);
171 break;
172 case 512:
173 scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(0);
174 break;
175 case 48:
176 scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(3);
177 break;
178 case 96:
179 scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(2);
180 break;
181 case 192:
182 scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(1);
183 break;
184 case 384:
185 scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(0);
186 break;
187 default:
188 return -EINVAL;
189 }
190
191 __raw_writel(scr, master_saif->base + SAIF_CTRL);
192
193 return 0;
194}
195
196/*
197 * Put and disable MCLK.
198 */
199int mxs_saif_put_mclk(unsigned int saif_id)
200{
201 struct mxs_saif *saif = mxs_saif[saif_id];
202 u32 stat;
203
204 if (!saif)
205 return -EINVAL;
206
207 stat = __raw_readl(saif->base + SAIF_STAT);
208 if (stat & BM_SAIF_STAT_BUSY) {
209 dev_err(saif->dev, "error: busy\n");
210 return -EBUSY;
211 }
212
213 clk_disable(saif->clk);
214
215 /* disable MCLK output */
216 __raw_writel(BM_SAIF_CTRL_CLKGATE,
217 saif->base + SAIF_CTRL + MXS_SET_ADDR);
218 __raw_writel(BM_SAIF_CTRL_RUN,
219 saif->base + SAIF_CTRL + MXS_CLR_ADDR);
220
221 saif->mclk_in_use = 0;
222 return 0;
223}
224
225/*
226 * Get MCLK and set clock rate, then enable it
227 *
228 * This interface is used for codecs who are using MCLK provided
229 * by saif.
230 */
231int mxs_saif_get_mclk(unsigned int saif_id, unsigned int mclk,
232 unsigned int rate)
233{
234 struct mxs_saif *saif = mxs_saif[saif_id];
235 u32 stat;
236 int ret;
237 struct mxs_saif *master_saif;
238
239 if (!saif)
240 return -EINVAL;
241
242 /* Clear Reset */
243 __raw_writel(BM_SAIF_CTRL_SFTRST,
244 saif->base + SAIF_CTRL + MXS_CLR_ADDR);
245
246 /* FIXME: need clear clk gate for register r/w */
247 __raw_writel(BM_SAIF_CTRL_CLKGATE,
248 saif->base + SAIF_CTRL + MXS_CLR_ADDR);
249
250 master_saif = mxs_saif_get_master(saif);
251 if (saif != master_saif) {
252 dev_err(saif->dev, "can not get mclk from a non-master saif\n");
253 return -EINVAL;
254 }
255
256 stat = __raw_readl(saif->base + SAIF_STAT);
257 if (stat & BM_SAIF_STAT_BUSY) {
258 dev_err(saif->dev, "error: busy\n");
259 return -EBUSY;
260 }
261
262 saif->mclk_in_use = 1;
263 ret = mxs_saif_set_clk(saif, mclk, rate);
264 if (ret)
265 return ret;
266
267 ret = clk_enable(saif->clk);
268 if (ret)
269 return ret;
270
271 /* enable MCLK output */
272 __raw_writel(BM_SAIF_CTRL_RUN,
273 saif->base + SAIF_CTRL + MXS_SET_ADDR);
274
275 return 0;
276}
277
278/*
279 * SAIF DAI format configuration.
280 * Should only be called when port is inactive.
281 */
282static int mxs_saif_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
283{
284 u32 scr, stat;
285 u32 scr0;
286 struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai);
287
288 stat = __raw_readl(saif->base + SAIF_STAT);
289 if (stat & BM_SAIF_STAT_BUSY) {
290 dev_err(cpu_dai->dev, "error: busy\n");
291 return -EBUSY;
292 }
293
294 scr0 = __raw_readl(saif->base + SAIF_CTRL);
295 scr0 = scr0 & ~BM_SAIF_CTRL_BITCLK_EDGE & ~BM_SAIF_CTRL_LRCLK_POLARITY \
296 & ~BM_SAIF_CTRL_JUSTIFY & ~BM_SAIF_CTRL_DELAY;
297 scr = 0;
298
299 /* DAI mode */
300 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
301 case SND_SOC_DAIFMT_I2S:
302 /* data frame low 1clk before data */
303 scr |= BM_SAIF_CTRL_DELAY;
304 scr &= ~BM_SAIF_CTRL_LRCLK_POLARITY;
305 break;
306 case SND_SOC_DAIFMT_LEFT_J:
307 /* data frame high with data */
308 scr &= ~BM_SAIF_CTRL_DELAY;
309 scr &= ~BM_SAIF_CTRL_LRCLK_POLARITY;
310 scr &= ~BM_SAIF_CTRL_JUSTIFY;
311 break;
312 default:
313 return -EINVAL;
314 }
315
316 /* DAI clock inversion */
317 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
318 case SND_SOC_DAIFMT_IB_IF:
319 scr |= BM_SAIF_CTRL_BITCLK_EDGE;
320 scr |= BM_SAIF_CTRL_LRCLK_POLARITY;
321 break;
322 case SND_SOC_DAIFMT_IB_NF:
323 scr |= BM_SAIF_CTRL_BITCLK_EDGE;
324 scr &= ~BM_SAIF_CTRL_LRCLK_POLARITY;
325 break;
326 case SND_SOC_DAIFMT_NB_IF:
327 scr &= ~BM_SAIF_CTRL_BITCLK_EDGE;
328 scr |= BM_SAIF_CTRL_LRCLK_POLARITY;
329 break;
330 case SND_SOC_DAIFMT_NB_NF:
331 scr &= ~BM_SAIF_CTRL_BITCLK_EDGE;
332 scr &= ~BM_SAIF_CTRL_LRCLK_POLARITY;
333 break;
334 }
335
336 /*
337 * Note: We simply just support master mode since SAIF TX can only
338 * work as master.
339 * Here the master is relative to codec side.
340 * Saif internally could be slave when working on EXTMASTER mode.
341 * We just hide this to machine driver.
342 */
343 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
344 case SND_SOC_DAIFMT_CBS_CFS:
345 if (saif->id == saif->master_id)
346 scr &= ~BM_SAIF_CTRL_SLAVE_MODE;
347 else
348 scr |= BM_SAIF_CTRL_SLAVE_MODE;
349
350 __raw_writel(scr | scr0, saif->base + SAIF_CTRL);
351 break;
352 default:
353 return -EINVAL;
354 }
355
356 return 0;
357}
358
359static int mxs_saif_startup(struct snd_pcm_substream *substream,
360 struct snd_soc_dai *cpu_dai)
361{
362 struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai);
363 snd_soc_dai_set_dma_data(cpu_dai, substream, &saif->dma_param);
364
365 /* clear error status to 0 for each re-open */
366 saif->fifo_underrun = 0;
367 saif->fifo_overrun = 0;
368
369 /* Clear Reset for normal operations */
370 __raw_writel(BM_SAIF_CTRL_SFTRST,
371 saif->base + SAIF_CTRL + MXS_CLR_ADDR);
372
373 /* clear clock gate */
374 __raw_writel(BM_SAIF_CTRL_CLKGATE,
375 saif->base + SAIF_CTRL + MXS_CLR_ADDR);
376
377 return 0;
378}
379
380/*
381 * Should only be called when port is inactive.
382 * although can be called multiple times by upper layers.
383 */
384static int mxs_saif_hw_params(struct snd_pcm_substream *substream,
385 struct snd_pcm_hw_params *params,
386 struct snd_soc_dai *cpu_dai)
387{
388 struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai);
389 u32 scr, stat;
390 int ret;
391
392 /* mclk should already be set */
393 if (!saif->mclk && saif->mclk_in_use) {
394 dev_err(cpu_dai->dev, "set mclk first\n");
395 return -EINVAL;
396 }
397
398 stat = __raw_readl(saif->base + SAIF_STAT);
399 if (stat & BM_SAIF_STAT_BUSY) {
400 dev_err(cpu_dai->dev, "error: busy\n");
401 return -EBUSY;
402 }
403
404 /*
405 * Set saif clk based on sample rate.
406 * If mclk is used, we also set mclk, if not, saif->mclk is
407 * default 0, means not used.
408 */
409 ret = mxs_saif_set_clk(saif, saif->mclk, params_rate(params));
410 if (ret) {
411 dev_err(cpu_dai->dev, "unable to get proper clk\n");
412 return ret;
413 }
414
415 scr = __raw_readl(saif->base + SAIF_CTRL);
416
417 scr &= ~BM_SAIF_CTRL_WORD_LENGTH;
418 scr &= ~BM_SAIF_CTRL_BITCLK_48XFS_ENABLE;
419 switch (params_format(params)) {
420 case SNDRV_PCM_FORMAT_S16_LE:
421 scr |= BF_SAIF_CTRL_WORD_LENGTH(0);
422 break;
423 case SNDRV_PCM_FORMAT_S20_3LE:
424 scr |= BF_SAIF_CTRL_WORD_LENGTH(4);
425 scr |= BM_SAIF_CTRL_BITCLK_48XFS_ENABLE;
426 break;
427 case SNDRV_PCM_FORMAT_S24_LE:
428 scr |= BF_SAIF_CTRL_WORD_LENGTH(8);
429 scr |= BM_SAIF_CTRL_BITCLK_48XFS_ENABLE;
430 break;
431 default:
432 return -EINVAL;
433 }
434
435 /* Tx/Rx config */
436 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
437 /* enable TX mode */
438 scr &= ~BM_SAIF_CTRL_READ_MODE;
439 } else {
440 /* enable RX mode */
441 scr |= BM_SAIF_CTRL_READ_MODE;
442 }
443
444 __raw_writel(scr, saif->base + SAIF_CTRL);
445 return 0;
446}
447
448static int mxs_saif_prepare(struct snd_pcm_substream *substream,
449 struct snd_soc_dai *cpu_dai)
450{
451 struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai);
452
453 /* enable FIFO error irqs */
454 __raw_writel(BM_SAIF_CTRL_FIFO_ERROR_IRQ_EN,
455 saif->base + SAIF_CTRL + MXS_SET_ADDR);
456
457 return 0;
458}
459
460static int mxs_saif_trigger(struct snd_pcm_substream *substream, int cmd,
461 struct snd_soc_dai *cpu_dai)
462{
463 struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai);
464 struct mxs_saif *master_saif;
465 u32 delay;
466
467 master_saif = mxs_saif_get_master(saif);
468 if (!master_saif)
469 return -EINVAL;
470
471 switch (cmd) {
472 case SNDRV_PCM_TRIGGER_START:
473 case SNDRV_PCM_TRIGGER_RESUME:
474 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
475 dev_dbg(cpu_dai->dev, "start\n");
476
477 clk_enable(master_saif->clk);
478 if (!master_saif->mclk_in_use)
479 __raw_writel(BM_SAIF_CTRL_RUN,
480 master_saif->base + SAIF_CTRL + MXS_SET_ADDR);
481
482 /*
483 * If the saif's master is not himself, we also need to enable
484 * itself clk for its internal basic logic to work.
485 */
486 if (saif != master_saif) {
487 clk_enable(saif->clk);
488 __raw_writel(BM_SAIF_CTRL_RUN,
489 saif->base + SAIF_CTRL + MXS_SET_ADDR);
490 }
491
492 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
493 /*
494 * write a data to saif data register to trigger
495 * the transfer
496 */
497 __raw_writel(0, saif->base + SAIF_DATA);
498 } else {
499 /*
500 * read a data from saif data register to trigger
501 * the receive
502 */
503 __raw_readl(saif->base + SAIF_DATA);
504 }
505
506 master_saif->ongoing = 1;
507
508 dev_dbg(saif->dev, "CTRL 0x%x STAT 0x%x\n",
509 __raw_readl(saif->base + SAIF_CTRL),
510 __raw_readl(saif->base + SAIF_STAT));
511
512 dev_dbg(master_saif->dev, "CTRL 0x%x STAT 0x%x\n",
513 __raw_readl(master_saif->base + SAIF_CTRL),
514 __raw_readl(master_saif->base + SAIF_STAT));
515 break;
516 case SNDRV_PCM_TRIGGER_SUSPEND:
517 case SNDRV_PCM_TRIGGER_STOP:
518 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
519 dev_dbg(cpu_dai->dev, "stop\n");
520
521 /* wait a while for the current sample to complete */
522 delay = USEC_PER_SEC / master_saif->cur_rate;
523
524 if (!master_saif->mclk_in_use) {
525 __raw_writel(BM_SAIF_CTRL_RUN,
526 master_saif->base + SAIF_CTRL + MXS_CLR_ADDR);
527 udelay(delay);
528 }
529 clk_disable(master_saif->clk);
530
531 if (saif != master_saif) {
532 __raw_writel(BM_SAIF_CTRL_RUN,
533 saif->base + SAIF_CTRL + MXS_CLR_ADDR);
534 udelay(delay);
535 clk_disable(saif->clk);
536 }
537
538 master_saif->ongoing = 0;
539
540 break;
541 default:
542 return -EINVAL;
543 }
544
545 return 0;
546}
547
548#define MXS_SAIF_RATES SNDRV_PCM_RATE_8000_192000
549#define MXS_SAIF_FORMATS \
550 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
551 SNDRV_PCM_FMTBIT_S24_LE)
552
553static struct snd_soc_dai_ops mxs_saif_dai_ops = {
554 .startup = mxs_saif_startup,
555 .trigger = mxs_saif_trigger,
556 .prepare = mxs_saif_prepare,
557 .hw_params = mxs_saif_hw_params,
558 .set_sysclk = mxs_saif_set_dai_sysclk,
559 .set_fmt = mxs_saif_set_dai_fmt,
560};
561
562static int mxs_saif_dai_probe(struct snd_soc_dai *dai)
563{
564 struct mxs_saif *saif = dev_get_drvdata(dai->dev);
565
566 snd_soc_dai_set_drvdata(dai, saif);
567
568 return 0;
569}
570
571static struct snd_soc_dai_driver mxs_saif_dai = {
572 .name = "mxs-saif",
573 .probe = mxs_saif_dai_probe,
574 .playback = {
575 .channels_min = 2,
576 .channels_max = 2,
577 .rates = MXS_SAIF_RATES,
578 .formats = MXS_SAIF_FORMATS,
579 },
580 .capture = {
581 .channels_min = 2,
582 .channels_max = 2,
583 .rates = MXS_SAIF_RATES,
584 .formats = MXS_SAIF_FORMATS,
585 },
586 .ops = &mxs_saif_dai_ops,
587};
588
589static irqreturn_t mxs_saif_irq(int irq, void *dev_id)
590{
591 struct mxs_saif *saif = dev_id;
592 unsigned int stat;
593
594 stat = __raw_readl(saif->base + SAIF_STAT);
595 if (!(stat & (BM_SAIF_STAT_FIFO_UNDERFLOW_IRQ |
596 BM_SAIF_STAT_FIFO_OVERFLOW_IRQ)))
597 return IRQ_NONE;
598
599 if (stat & BM_SAIF_STAT_FIFO_UNDERFLOW_IRQ) {
600 dev_dbg(saif->dev, "underrun!!! %d\n", ++saif->fifo_underrun);
601 __raw_writel(BM_SAIF_STAT_FIFO_UNDERFLOW_IRQ,
602 saif->base + SAIF_STAT + MXS_CLR_ADDR);
603 }
604
605 if (stat & BM_SAIF_STAT_FIFO_OVERFLOW_IRQ) {
606 dev_dbg(saif->dev, "overrun!!! %d\n", ++saif->fifo_overrun);
607 __raw_writel(BM_SAIF_STAT_FIFO_OVERFLOW_IRQ,
608 saif->base + SAIF_STAT + MXS_CLR_ADDR);
609 }
610
611 dev_dbg(saif->dev, "SAIF_CTRL %x SAIF_STAT %x\n",
612 __raw_readl(saif->base + SAIF_CTRL),
613 __raw_readl(saif->base + SAIF_STAT));
614
615 return IRQ_HANDLED;
616}
617
618static int mxs_saif_probe(struct platform_device *pdev)
619{
620 struct resource *iores, *dmares;
621 struct mxs_saif *saif;
622 struct mxs_saif_platform_data *pdata;
623 int ret = 0;
624
625 if (pdev->id >= ARRAY_SIZE(mxs_saif))
626 return -EINVAL;
627
628 pdata = pdev->dev.platform_data;
629 if (pdata && pdata->init) {
630 ret = pdata->init();
631 if (ret)
632 return ret;
633 }
634
635 saif = kzalloc(sizeof(*saif), GFP_KERNEL);
636 if (!saif)
637 return -ENOMEM;
638
639 mxs_saif[pdev->id] = saif;
640 saif->id = pdev->id;
641
642 saif->master_id = saif->id;
643 if (pdata && pdata->get_master_id) {
644 saif->master_id = pdata->get_master_id(saif->id);
645 if (saif->master_id < 0 ||
646 saif->master_id >= ARRAY_SIZE(mxs_saif))
647 return -EINVAL;
648 }
649
650 saif->clk = clk_get(&pdev->dev, NULL);
651 if (IS_ERR(saif->clk)) {
652 ret = PTR_ERR(saif->clk);
653 dev_err(&pdev->dev, "Cannot get the clock: %d\n",
654 ret);
655 goto failed_clk;
656 }
657
658 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
659 if (!iores) {
660 ret = -ENODEV;
661 dev_err(&pdev->dev, "failed to get io resource: %d\n",
662 ret);
663 goto failed_get_resource;
664 }
665
666 if (!request_mem_region(iores->start, resource_size(iores),
667 "mxs-saif")) {
668 dev_err(&pdev->dev, "request_mem_region failed\n");
669 ret = -EBUSY;
670 goto failed_get_resource;
671 }
672
673 saif->base = ioremap(iores->start, resource_size(iores));
674 if (!saif->base) {
675 dev_err(&pdev->dev, "ioremap failed\n");
676 ret = -ENODEV;
677 goto failed_ioremap;
678 }
679
680 dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
681 if (!dmares) {
682 ret = -ENODEV;
683 dev_err(&pdev->dev, "failed to get dma resource: %d\n",
684 ret);
685 goto failed_ioremap;
686 }
687 saif->dma_param.chan_num = dmares->start;
688
689 saif->irq = platform_get_irq(pdev, 0);
690 if (saif->irq < 0) {
691 ret = saif->irq;
692 dev_err(&pdev->dev, "failed to get irq resource: %d\n",
693 ret);
694 goto failed_get_irq1;
695 }
696
697 saif->dev = &pdev->dev;
698 ret = request_irq(saif->irq, mxs_saif_irq, 0, "mxs-saif", saif);
699 if (ret) {
700 dev_err(&pdev->dev, "failed to request irq\n");
701 goto failed_get_irq1;
702 }
703
704 saif->dma_param.chan_irq = platform_get_irq(pdev, 1);
705 if (saif->dma_param.chan_irq < 0) {
706 ret = saif->dma_param.chan_irq;
707 dev_err(&pdev->dev, "failed to get dma irq resource: %d\n",
708 ret);
709 goto failed_get_irq2;
710 }
711
712 platform_set_drvdata(pdev, saif);
713
714 ret = snd_soc_register_dai(&pdev->dev, &mxs_saif_dai);
715 if (ret) {
716 dev_err(&pdev->dev, "register DAI failed\n");
717 goto failed_register;
718 }
719
720 saif->soc_platform_pdev = platform_device_alloc(
721 "mxs-pcm-audio", pdev->id);
722 if (!saif->soc_platform_pdev) {
723 ret = -ENOMEM;
724 goto failed_pdev_alloc;
725 }
726
727 platform_set_drvdata(saif->soc_platform_pdev, saif);
728 ret = platform_device_add(saif->soc_platform_pdev);
729 if (ret) {
730 dev_err(&pdev->dev, "failed to add soc platform device\n");
731 goto failed_pdev_add;
732 }
733
734 return 0;
735
736failed_pdev_add:
737 platform_device_put(saif->soc_platform_pdev);
738failed_pdev_alloc:
739 snd_soc_unregister_dai(&pdev->dev);
740failed_register:
741failed_get_irq2:
742 free_irq(saif->irq, saif);
743failed_get_irq1:
744 iounmap(saif->base);
745failed_ioremap:
746 release_mem_region(iores->start, resource_size(iores));
747failed_get_resource:
748 clk_put(saif->clk);
749failed_clk:
750 kfree(saif);
751
752 return ret;
753}
754
755static int __devexit mxs_saif_remove(struct platform_device *pdev)
756{
757 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
758 struct mxs_saif *saif = platform_get_drvdata(pdev);
759
760 platform_device_unregister(saif->soc_platform_pdev);
761
762 snd_soc_unregister_dai(&pdev->dev);
763
764 iounmap(saif->base);
765 release_mem_region(res->start, resource_size(res));
766 free_irq(saif->irq, saif);
767
768 clk_put(saif->clk);
769 kfree(saif);
770
771 return 0;
772}
773
774static struct platform_driver mxs_saif_driver = {
775 .probe = mxs_saif_probe,
776 .remove = __devexit_p(mxs_saif_remove),
777
778 .driver = {
779 .name = "mxs-saif",
780 .owner = THIS_MODULE,
781 },
782};
783
784static int __init mxs_saif_init(void)
785{
786 return platform_driver_register(&mxs_saif_driver);
787}
788
789static void __exit mxs_saif_exit(void)
790{
791 platform_driver_unregister(&mxs_saif_driver);
792}
793
794module_init(mxs_saif_init);
795module_exit(mxs_saif_exit);
796MODULE_AUTHOR("Freescale Semiconductor, Inc.");
797MODULE_DESCRIPTION("MXS ASoC SAIF driver");
798MODULE_LICENSE("GPL");
diff --git a/sound/soc/mxs/mxs-saif.h b/sound/soc/mxs/mxs-saif.h
new file mode 100644
index 00000000000..12c91e4eb94
--- /dev/null
+++ b/sound/soc/mxs/mxs-saif.h
@@ -0,0 +1,134 @@
1/*
2 * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
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 as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19
20#ifndef _MXS_SAIF_H
21#define _MXS_SAIF_H
22
23#define SAIF_CTRL 0x0
24#define SAIF_STAT 0x10
25#define SAIF_DATA 0x20
26#define SAIF_VERSION 0X30
27
28/* SAIF_CTRL */
29#define BM_SAIF_CTRL_SFTRST 0x80000000
30#define BM_SAIF_CTRL_CLKGATE 0x40000000
31#define BP_SAIF_CTRL_BITCLK_MULT_RATE 27
32#define BM_SAIF_CTRL_BITCLK_MULT_RATE 0x38000000
33#define BF_SAIF_CTRL_BITCLK_MULT_RATE(v) \
34 (((v) << 27) & BM_SAIF_CTRL_BITCLK_MULT_RATE)
35#define BM_SAIF_CTRL_BITCLK_BASE_RATE 0x04000000
36#define BM_SAIF_CTRL_FIFO_ERROR_IRQ_EN 0x02000000
37#define BM_SAIF_CTRL_FIFO_SERVICE_IRQ_EN 0x01000000
38#define BP_SAIF_CTRL_RSRVD2 21
39#define BM_SAIF_CTRL_RSRVD2 0x00E00000
40
41#define BP_SAIF_CTRL_DMAWAIT_COUNT 16
42#define BM_SAIF_CTRL_DMAWAIT_COUNT 0x001F0000
43#define BF_SAIF_CTRL_DMAWAIT_COUNT(v) \
44 (((v) << 16) & BM_SAIF_CTRL_DMAWAIT_COUNT)
45#define BP_SAIF_CTRL_CHANNEL_NUM_SELECT 14
46#define BM_SAIF_CTRL_CHANNEL_NUM_SELECT 0x0000C000
47#define BF_SAIF_CTRL_CHANNEL_NUM_SELECT(v) \
48 (((v) << 14) & BM_SAIF_CTRL_CHANNEL_NUM_SELECT)
49#define BM_SAIF_CTRL_LRCLK_PULSE 0x00002000
50#define BM_SAIF_CTRL_BIT_ORDER 0x00001000
51#define BM_SAIF_CTRL_DELAY 0x00000800
52#define BM_SAIF_CTRL_JUSTIFY 0x00000400
53#define BM_SAIF_CTRL_LRCLK_POLARITY 0x00000200
54#define BM_SAIF_CTRL_BITCLK_EDGE 0x00000100
55#define BP_SAIF_CTRL_WORD_LENGTH 4
56#define BM_SAIF_CTRL_WORD_LENGTH 0x000000F0
57#define BF_SAIF_CTRL_WORD_LENGTH(v) \
58 (((v) << 4) & BM_SAIF_CTRL_WORD_LENGTH)
59#define BM_SAIF_CTRL_BITCLK_48XFS_ENABLE 0x00000008
60#define BM_SAIF_CTRL_SLAVE_MODE 0x00000004
61#define BM_SAIF_CTRL_READ_MODE 0x00000002
62#define BM_SAIF_CTRL_RUN 0x00000001
63
64/* SAIF_STAT */
65#define BM_SAIF_STAT_PRESENT 0x80000000
66#define BP_SAIF_STAT_RSRVD2 17
67#define BM_SAIF_STAT_RSRVD2 0x7FFE0000
68#define BF_SAIF_STAT_RSRVD2(v) \
69 (((v) << 17) & BM_SAIF_STAT_RSRVD2)
70#define BM_SAIF_STAT_DMA_PREQ 0x00010000
71#define BP_SAIF_STAT_RSRVD1 7
72#define BM_SAIF_STAT_RSRVD1 0x0000FF80
73#define BF_SAIF_STAT_RSRVD1(v) \
74 (((v) << 7) & BM_SAIF_STAT_RSRVD1)
75
76#define BM_SAIF_STAT_FIFO_UNDERFLOW_IRQ 0x00000040
77#define BM_SAIF_STAT_FIFO_OVERFLOW_IRQ 0x00000020
78#define BM_SAIF_STAT_FIFO_SERVICE_IRQ 0x00000010
79#define BP_SAIF_STAT_RSRVD0 1
80#define BM_SAIF_STAT_RSRVD0 0x0000000E
81#define BF_SAIF_STAT_RSRVD0(v) \
82 (((v) << 1) & BM_SAIF_STAT_RSRVD0)
83#define BM_SAIF_STAT_BUSY 0x00000001
84
85/* SAFI_DATA */
86#define BP_SAIF_DATA_PCM_RIGHT 16
87#define BM_SAIF_DATA_PCM_RIGHT 0xFFFF0000
88#define BF_SAIF_DATA_PCM_RIGHT(v) \
89 (((v) << 16) & BM_SAIF_DATA_PCM_RIGHT)
90#define BP_SAIF_DATA_PCM_LEFT 0
91#define BM_SAIF_DATA_PCM_LEFT 0x0000FFFF
92#define BF_SAIF_DATA_PCM_LEFT(v) \
93 (((v) << 0) & BM_SAIF_DATA_PCM_LEFT)
94
95/* SAIF_VERSION */
96#define BP_SAIF_VERSION_MAJOR 24
97#define BM_SAIF_VERSION_MAJOR 0xFF000000
98#define BF_SAIF_VERSION_MAJOR(v) \
99 (((v) << 24) & BM_SAIF_VERSION_MAJOR)
100#define BP_SAIF_VERSION_MINOR 16
101#define BM_SAIF_VERSION_MINOR 0x00FF0000
102#define BF_SAIF_VERSION_MINOR(v) \
103 (((v) << 16) & BM_SAIF_VERSION_MINOR)
104#define BP_SAIF_VERSION_STEP 0
105#define BM_SAIF_VERSION_STEP 0x0000FFFF
106#define BF_SAIF_VERSION_STEP(v) \
107 (((v) << 0) & BM_SAIF_VERSION_STEP)
108
109#define MXS_SAIF_MCLK 0
110
111#include "mxs-pcm.h"
112
113struct mxs_saif {
114 struct device *dev;
115 struct clk *clk;
116 unsigned int mclk;
117 unsigned int mclk_in_use;
118 void __iomem *base;
119 int irq;
120 struct mxs_pcm_dma_params dma_param;
121 unsigned int id;
122 unsigned int master_id;
123 unsigned int cur_rate;
124 unsigned int ongoing;
125
126 struct platform_device *soc_platform_pdev;
127 u32 fifo_underrun;
128 u32 fifo_overrun;
129};
130
131extern int mxs_saif_put_mclk(unsigned int saif_id);
132extern int mxs_saif_get_mclk(unsigned int saif_id, unsigned int mclk,
133 unsigned int rate);
134#endif
diff --git a/sound/soc/mxs/mxs-sgtl5000.c b/sound/soc/mxs/mxs-sgtl5000.c
new file mode 100644
index 00000000000..7fbeaec06eb
--- /dev/null
+++ b/sound/soc/mxs/mxs-sgtl5000.c
@@ -0,0 +1,173 @@
1/*
2 * Copyright 2011 Freescale Semiconductor, Inc.
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 as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19#include <linux/module.h>
20#include <linux/device.h>
21#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/soc.h>
24#include <sound/jack.h>
25#include <sound/soc-dapm.h>
26#include <asm/mach-types.h>
27
28#include "../codecs/sgtl5000.h"
29#include "mxs-saif.h"
30
31static int mxs_sgtl5000_hw_params(struct snd_pcm_substream *substream,
32 struct snd_pcm_hw_params *params)
33{
34 struct snd_soc_pcm_runtime *rtd = substream->private_data;
35 struct snd_soc_dai *codec_dai = rtd->codec_dai;
36 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
37 unsigned int rate = params_rate(params);
38 u32 dai_format, mclk;
39 int ret;
40
41 /* sgtl5000 does not support 512*rate when in 96000 fs */
42 switch (rate) {
43 case 96000:
44 mclk = 256 * rate;
45 break;
46 default:
47 mclk = 512 * rate;
48 break;
49 }
50
51 /* Sgtl5000 sysclk should be >= 8MHz and <= 27M */
52 if (mclk < 8000000 || mclk > 27000000)
53 return -EINVAL;
54
55 /* Set SGTL5000's SYSCLK (provided by SAIF MCLK) */
56 ret = snd_soc_dai_set_sysclk(codec_dai, SGTL5000_SYSCLK, mclk, 0);
57 if (ret)
58 return ret;
59
60 /* The SAIF MCLK should be the same as SGTL5000_SYSCLK */
61 ret = snd_soc_dai_set_sysclk(cpu_dai, MXS_SAIF_MCLK, mclk, 0);
62 if (ret)
63 return ret;
64
65 /* set codec to slave mode */
66 dai_format = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
67 SND_SOC_DAIFMT_CBS_CFS;
68
69 /* set codec DAI configuration */
70 ret = snd_soc_dai_set_fmt(codec_dai, dai_format);
71 if (ret)
72 return ret;
73
74 /* set cpu DAI configuration */
75 ret = snd_soc_dai_set_fmt(cpu_dai, dai_format);
76 if (ret)
77 return ret;
78
79 return 0;
80}
81
82static struct snd_soc_ops mxs_sgtl5000_hifi_ops = {
83 .hw_params = mxs_sgtl5000_hw_params,
84};
85
86static struct snd_soc_dai_link mxs_sgtl5000_dai[] = {
87 {
88 .name = "HiFi Tx",
89 .stream_name = "HiFi Playback",
90 .codec_dai_name = "sgtl5000",
91 .codec_name = "sgtl5000.0-000a",
92 .cpu_dai_name = "mxs-saif.0",
93 .platform_name = "mxs-pcm-audio.0",
94 .ops = &mxs_sgtl5000_hifi_ops,
95 }, {
96 .name = "HiFi Rx",
97 .stream_name = "HiFi Capture",
98 .codec_dai_name = "sgtl5000",
99 .codec_name = "sgtl5000.0-000a",
100 .cpu_dai_name = "mxs-saif.1",
101 .platform_name = "mxs-pcm-audio.1",
102 .ops = &mxs_sgtl5000_hifi_ops,
103 },
104};
105
106static struct snd_soc_card mxs_sgtl5000 = {
107 .name = "mxs_sgtl5000",
108 .dai_link = mxs_sgtl5000_dai,
109 .num_links = ARRAY_SIZE(mxs_sgtl5000_dai),
110};
111
112static int __devinit mxs_sgtl5000_probe(struct platform_device *pdev)
113{
114 struct snd_soc_card *card = &mxs_sgtl5000;
115 int ret;
116
117 /*
118 * Set an init clock(11.28Mhz) for sgtl5000 initialization(i2c r/w).
119 * The Sgtl5000 sysclk is derived from saif0 mclk and it's range
120 * should be >= 8MHz and <= 27M.
121 */
122 ret = mxs_saif_get_mclk(0, 44100 * 256, 44100);
123 if (ret)
124 return ret;
125
126 card->dev = &pdev->dev;
127 platform_set_drvdata(pdev, card);
128
129 ret = snd_soc_register_card(card);
130 if (ret) {
131 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
132 ret);
133 return ret;
134 }
135
136 return 0;
137}
138
139static int __devexit mxs_sgtl5000_remove(struct platform_device *pdev)
140{
141 struct snd_soc_card *card = platform_get_drvdata(pdev);
142
143 mxs_saif_put_mclk(0);
144
145 snd_soc_unregister_card(card);
146
147 return 0;
148}
149
150static struct platform_driver mxs_sgtl5000_audio_driver = {
151 .driver = {
152 .name = "mxs-sgtl5000",
153 .owner = THIS_MODULE,
154 },
155 .probe = mxs_sgtl5000_probe,
156 .remove = __devexit_p(mxs_sgtl5000_remove),
157};
158
159static int __init mxs_sgtl5000_init(void)
160{
161 return platform_driver_register(&mxs_sgtl5000_audio_driver);
162}
163module_init(mxs_sgtl5000_init);
164
165static void __exit mxs_sgtl5000_exit(void)
166{
167 platform_driver_unregister(&mxs_sgtl5000_audio_driver);
168}
169module_exit(mxs_sgtl5000_exit);
170
171MODULE_AUTHOR("Freescale Semiconductor, Inc.");
172MODULE_DESCRIPTION("MXS ALSA SoC Machine driver");
173MODULE_LICENSE("GPL");
diff --git a/sound/soc/nuc900/nuc900-pcm.c b/sound/soc/nuc900/nuc900-pcm.c
index d589ef14e91..ae8d6806966 100644
--- a/sound/soc/nuc900/nuc900-pcm.c
+++ b/sound/soc/nuc900/nuc900-pcm.c
@@ -227,7 +227,7 @@ static int nuc900_dma_trigger(struct snd_pcm_substream *substream, int cmd)
227 return ret; 227 return ret;
228} 228}
229 229
230int nuc900_dma_getposition(struct snd_pcm_substream *substream, 230static int nuc900_dma_getposition(struct snd_pcm_substream *substream,
231 dma_addr_t *src, dma_addr_t *dst) 231 dma_addr_t *src, dma_addr_t *dst)
232{ 232{
233 struct snd_pcm_runtime *runtime = substream->runtime; 233 struct snd_pcm_runtime *runtime = substream->runtime;
@@ -268,7 +268,7 @@ static int nuc900_dma_open(struct snd_pcm_substream *substream)
268 nuc900_audio = nuc900_ac97_data; 268 nuc900_audio = nuc900_ac97_data;
269 269
270 if (request_irq(nuc900_audio->irq_num, nuc900_dma_interrupt, 270 if (request_irq(nuc900_audio->irq_num, nuc900_dma_interrupt,
271 IRQF_DISABLED, "nuc900-dma", substream)) 271 0, "nuc900-dma", substream))
272 return -EBUSY; 272 return -EBUSY;
273 273
274 runtime->private_data = nuc900_audio; 274 runtime->private_data = nuc900_audio;
@@ -318,7 +318,6 @@ static u64 nuc900_pcm_dmamask = DMA_BIT_MASK(32);
318static int nuc900_dma_new(struct snd_soc_pcm_runtime *rtd) 318static int nuc900_dma_new(struct snd_soc_pcm_runtime *rtd)
319{ 319{
320 struct snd_card *card = rtd->card->snd_card; 320 struct snd_card *card = rtd->card->snd_card;
321 struct snd_soc_dai *dai = rtd->cpu_dai;
322 struct snd_pcm *pcm = rtd->pcm; 321 struct snd_pcm *pcm = rtd->pcm;
323 322
324 if (!card->dev->dma_mask) 323 if (!card->dev->dma_mask)
diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile
index 59e2c8d1e38..052fd758722 100644
--- a/sound/soc/omap/Makefile
+++ b/sound/soc/omap/Makefile
@@ -1,7 +1,7 @@
1# OMAP Platform Support 1# OMAP Platform Support
2snd-soc-omap-objs := omap-pcm.o 2snd-soc-omap-objs := omap-pcm.o
3snd-soc-omap-mcbsp-objs := omap-mcbsp.o 3snd-soc-omap-mcbsp-objs := omap-mcbsp.o
4snd-soc-omap-mcpdm-objs := omap-mcpdm.o mcpdm.o 4snd-soc-omap-mcpdm-objs := omap-mcpdm.o
5snd-soc-omap-hdmi-objs := omap-hdmi.o 5snd-soc-omap-hdmi-objs := omap-hdmi.o
6 6
7obj-$(CONFIG_SND_OMAP_SOC) += snd-soc-omap.o 7obj-$(CONFIG_SND_OMAP_SOC) += snd-soc-omap.o
diff --git a/sound/soc/omap/am3517evm.c b/sound/soc/omap/am3517evm.c
index 73dde4a1adc..8da55e91645 100644
--- a/sound/soc/omap/am3517evm.c
+++ b/sound/soc/omap/am3517evm.c
@@ -43,26 +43,6 @@ static int am3517evm_hw_params(struct snd_pcm_substream *substream,
43 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 43 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
44 int ret; 44 int ret;
45 45
46 /* Set codec DAI configuration */
47 ret = snd_soc_dai_set_fmt(codec_dai,
48 SND_SOC_DAIFMT_DSP_B |
49 SND_SOC_DAIFMT_NB_NF |
50 SND_SOC_DAIFMT_CBM_CFM);
51 if (ret < 0) {
52 printk(KERN_ERR "can't set codec DAI configuration\n");
53 return ret;
54 }
55
56 /* Set cpu DAI configuration */
57 ret = snd_soc_dai_set_fmt(cpu_dai,
58 SND_SOC_DAIFMT_DSP_B |
59 SND_SOC_DAIFMT_NB_NF |
60 SND_SOC_DAIFMT_CBM_CFM);
61 if (ret < 0) {
62 printk(KERN_ERR "can't set cpu DAI configuration\n");
63 return ret;
64 }
65
66 /* Set the codec system clock for DAC and ADC */ 46 /* Set the codec system clock for DAC and ADC */
67 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 47 ret = snd_soc_dai_set_sysclk(codec_dai, 0,
68 CODEC_CLOCK, SND_SOC_CLOCK_IN); 48 CODEC_CLOCK, SND_SOC_CLOCK_IN);
@@ -110,28 +90,6 @@ static const struct snd_soc_dapm_route audio_map[] = {
110 {"MICIN", NULL, "Mic In"}, 90 {"MICIN", NULL, "Mic In"},
111}; 91};
112 92
113static int am3517evm_aic23_init(struct snd_soc_pcm_runtime *rtd)
114{
115 struct snd_soc_codec *codec = rtd->codec;
116 struct snd_soc_dapm_context *dapm = &codec->dapm;
117
118 /* Add am3517-evm specific widgets */
119 snd_soc_dapm_new_controls(dapm, tlv320aic23_dapm_widgets,
120 ARRAY_SIZE(tlv320aic23_dapm_widgets));
121
122 /* Set up davinci-evm specific audio path audio_map */
123 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
124
125 /* always connected */
126 snd_soc_dapm_enable_pin(dapm, "Line Out");
127 snd_soc_dapm_enable_pin(dapm, "Line In");
128 snd_soc_dapm_enable_pin(dapm, "Mic In");
129
130 snd_soc_dapm_sync(dapm);
131
132 return 0;
133}
134
135/* Digital audio interface glue - connects codec <--> CPU */ 93/* Digital audio interface glue - connects codec <--> CPU */
136static struct snd_soc_dai_link am3517evm_dai = { 94static struct snd_soc_dai_link am3517evm_dai = {
137 .name = "TLV320AIC23", 95 .name = "TLV320AIC23",
@@ -140,7 +98,8 @@ static struct snd_soc_dai_link am3517evm_dai = {
140 .codec_dai_name = "tlv320aic23-hifi", 98 .codec_dai_name = "tlv320aic23-hifi",
141 .platform_name = "omap-pcm-audio", 99 .platform_name = "omap-pcm-audio",
142 .codec_name = "tlv320aic23-codec.2-001a", 100 .codec_name = "tlv320aic23-codec.2-001a",
143 .init = am3517evm_aic23_init, 101 .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF |
102 SND_SOC_DAIFMT_CBM_CFM,
144 .ops = &am3517evm_ops, 103 .ops = &am3517evm_ops,
145}; 104};
146 105
@@ -149,6 +108,11 @@ static struct snd_soc_card snd_soc_am3517evm = {
149 .name = "am3517evm", 108 .name = "am3517evm",
150 .dai_link = &am3517evm_dai, 109 .dai_link = &am3517evm_dai,
151 .num_links = 1, 110 .num_links = 1,
111
112 .dapm_widgets = tlv320aic23_dapm_widgets,
113 .num_dapm_widgets = ARRAY_SIZE(tlv320aic23_dapm_widgets),
114 .dapm_routes = audio_map,
115 .num_dapm_routes = ARRAY_SIZE(audio_map),
152}; 116};
153 117
154static struct platform_device *am3517evm_snd_device; 118static struct platform_device *am3517evm_snd_device;
diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c
index 0aa475f92ef..dcb7b689a4e 100644
--- a/sound/soc/omap/ams-delta.c
+++ b/sound/soc/omap/ams-delta.c
@@ -569,7 +569,6 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd)
569 snd_soc_dapm_disable_pin(dapm, "Speaker"); 569 snd_soc_dapm_disable_pin(dapm, "Speaker");
570 snd_soc_dapm_disable_pin(dapm, "AGCIN"); 570 snd_soc_dapm_disable_pin(dapm, "AGCIN");
571 snd_soc_dapm_disable_pin(dapm, "AGCOUT"); 571 snd_soc_dapm_disable_pin(dapm, "AGCOUT");
572 snd_soc_dapm_sync(dapm);
573 572
574 /* Add virtual switch */ 573 /* Add virtual switch */
575 ret = snd_soc_add_controls(codec, ams_delta_audio_controls, 574 ret = snd_soc_add_controls(codec, ams_delta_audio_controls,
diff --git a/sound/soc/omap/igep0020.c b/sound/soc/omap/igep0020.c
index 0ae34702995..84615a7de6a 100644
--- a/sound/soc/omap/igep0020.c
+++ b/sound/soc/omap/igep0020.c
@@ -38,29 +38,8 @@ static int igep2_hw_params(struct snd_pcm_substream *substream,
38{ 38{
39 struct snd_soc_pcm_runtime *rtd = substream->private_data; 39 struct snd_soc_pcm_runtime *rtd = substream->private_data;
40 struct snd_soc_dai *codec_dai = rtd->codec_dai; 40 struct snd_soc_dai *codec_dai = rtd->codec_dai;
41 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
42 int ret; 41 int ret;
43 42
44 /* Set codec DAI configuration */
45 ret = snd_soc_dai_set_fmt(codec_dai,
46 SND_SOC_DAIFMT_I2S |
47 SND_SOC_DAIFMT_NB_NF |
48 SND_SOC_DAIFMT_CBM_CFM);
49 if (ret < 0) {
50 printk(KERN_ERR "can't set codec DAI configuration\n");
51 return ret;
52 }
53
54 /* Set cpu DAI configuration */
55 ret = snd_soc_dai_set_fmt(cpu_dai,
56 SND_SOC_DAIFMT_I2S |
57 SND_SOC_DAIFMT_NB_NF |
58 SND_SOC_DAIFMT_CBM_CFM);
59 if (ret < 0) {
60 printk(KERN_ERR "can't set cpu DAI configuration\n");
61 return ret;
62 }
63
64 /* Set the codec system clock for DAC and ADC */ 43 /* Set the codec system clock for DAC and ADC */
65 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000, 44 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
66 SND_SOC_CLOCK_IN); 45 SND_SOC_CLOCK_IN);
@@ -84,6 +63,8 @@ static struct snd_soc_dai_link igep2_dai = {
84 .codec_dai_name = "twl4030-hifi", 63 .codec_dai_name = "twl4030-hifi",
85 .platform_name = "omap-pcm-audio", 64 .platform_name = "omap-pcm-audio",
86 .codec_name = "twl4030-codec", 65 .codec_name = "twl4030-codec",
66 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
67 SND_SOC_DAIFMT_CBM_CFM,
87 .ops = &igep2_ops, 68 .ops = &igep2_ops,
88}; 69};
89 70
diff --git a/sound/soc/omap/mcpdm.c b/sound/soc/omap/mcpdm.c
deleted file mode 100644
index 50e59194ad8..00000000000
--- a/sound/soc/omap/mcpdm.c
+++ /dev/null
@@ -1,470 +0,0 @@
1/*
2 * mcpdm.c -- McPDM interface driver
3 *
4 * Author: Jorge Eduardo Candelaria <x0107209@ti.com>
5 * Copyright (C) 2009 - Texas Instruments, Inc.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19 * 02110-1301 USA
20 *
21 */
22
23#include <linux/module.h>
24#include <linux/init.h>
25#include <linux/device.h>
26#include <linux/platform_device.h>
27#include <linux/wait.h>
28#include <linux/slab.h>
29#include <linux/interrupt.h>
30#include <linux/err.h>
31#include <linux/clk.h>
32#include <linux/delay.h>
33#include <linux/io.h>
34#include <linux/irq.h>
35
36#include "mcpdm.h"
37
38static struct omap_mcpdm *mcpdm;
39
40static inline void omap_mcpdm_write(u16 reg, u32 val)
41{
42 __raw_writel(val, mcpdm->io_base + reg);
43}
44
45static inline int omap_mcpdm_read(u16 reg)
46{
47 return __raw_readl(mcpdm->io_base + reg);
48}
49
50static void omap_mcpdm_reg_dump(void)
51{
52 dev_dbg(mcpdm->dev, "***********************\n");
53 dev_dbg(mcpdm->dev, "IRQSTATUS_RAW: 0x%04x\n",
54 omap_mcpdm_read(MCPDM_IRQSTATUS_RAW));
55 dev_dbg(mcpdm->dev, "IRQSTATUS: 0x%04x\n",
56 omap_mcpdm_read(MCPDM_IRQSTATUS));
57 dev_dbg(mcpdm->dev, "IRQENABLE_SET: 0x%04x\n",
58 omap_mcpdm_read(MCPDM_IRQENABLE_SET));
59 dev_dbg(mcpdm->dev, "IRQENABLE_CLR: 0x%04x\n",
60 omap_mcpdm_read(MCPDM_IRQENABLE_CLR));
61 dev_dbg(mcpdm->dev, "IRQWAKE_EN: 0x%04x\n",
62 omap_mcpdm_read(MCPDM_IRQWAKE_EN));
63 dev_dbg(mcpdm->dev, "DMAENABLE_SET: 0x%04x\n",
64 omap_mcpdm_read(MCPDM_DMAENABLE_SET));
65 dev_dbg(mcpdm->dev, "DMAENABLE_CLR: 0x%04x\n",
66 omap_mcpdm_read(MCPDM_DMAENABLE_CLR));
67 dev_dbg(mcpdm->dev, "DMAWAKEEN: 0x%04x\n",
68 omap_mcpdm_read(MCPDM_DMAWAKEEN));
69 dev_dbg(mcpdm->dev, "CTRL: 0x%04x\n",
70 omap_mcpdm_read(MCPDM_CTRL));
71 dev_dbg(mcpdm->dev, "DN_DATA: 0x%04x\n",
72 omap_mcpdm_read(MCPDM_DN_DATA));
73 dev_dbg(mcpdm->dev, "UP_DATA: 0x%04x\n",
74 omap_mcpdm_read(MCPDM_UP_DATA));
75 dev_dbg(mcpdm->dev, "FIFO_CTRL_DN: 0x%04x\n",
76 omap_mcpdm_read(MCPDM_FIFO_CTRL_DN));
77 dev_dbg(mcpdm->dev, "FIFO_CTRL_UP: 0x%04x\n",
78 omap_mcpdm_read(MCPDM_FIFO_CTRL_UP));
79 dev_dbg(mcpdm->dev, "DN_OFFSET: 0x%04x\n",
80 omap_mcpdm_read(MCPDM_DN_OFFSET));
81 dev_dbg(mcpdm->dev, "***********************\n");
82}
83
84/*
85 * Takes the McPDM module in and out of reset state.
86 * Uplink and downlink can be reset individually.
87 */
88static void omap_mcpdm_reset_capture(int reset)
89{
90 int ctrl = omap_mcpdm_read(MCPDM_CTRL);
91
92 if (reset)
93 ctrl |= SW_UP_RST;
94 else
95 ctrl &= ~SW_UP_RST;
96
97 omap_mcpdm_write(MCPDM_CTRL, ctrl);
98}
99
100static void omap_mcpdm_reset_playback(int reset)
101{
102 int ctrl = omap_mcpdm_read(MCPDM_CTRL);
103
104 if (reset)
105 ctrl |= SW_DN_RST;
106 else
107 ctrl &= ~SW_DN_RST;
108
109 omap_mcpdm_write(MCPDM_CTRL, ctrl);
110}
111
112/*
113 * Enables the transfer through the PDM interface to/from the Phoenix
114 * codec by enabling the corresponding UP or DN channels.
115 */
116void omap_mcpdm_start(int stream)
117{
118 int ctrl = omap_mcpdm_read(MCPDM_CTRL);
119
120 if (stream)
121 ctrl |= mcpdm->up_channels;
122 else
123 ctrl |= mcpdm->dn_channels;
124
125 omap_mcpdm_write(MCPDM_CTRL, ctrl);
126}
127
128/*
129 * Disables the transfer through the PDM interface to/from the Phoenix
130 * codec by disabling the corresponding UP or DN channels.
131 */
132void omap_mcpdm_stop(int stream)
133{
134 int ctrl = omap_mcpdm_read(MCPDM_CTRL);
135
136 if (stream)
137 ctrl &= ~mcpdm->up_channels;
138 else
139 ctrl &= ~mcpdm->dn_channels;
140
141 omap_mcpdm_write(MCPDM_CTRL, ctrl);
142}
143
144/*
145 * Configures McPDM uplink for audio recording.
146 * This function should be called before omap_mcpdm_start.
147 */
148int omap_mcpdm_capture_open(struct omap_mcpdm_link *uplink)
149{
150 int irq_mask = 0;
151 int ctrl;
152
153 if (!uplink)
154 return -EINVAL;
155
156 mcpdm->uplink = uplink;
157
158 /* Enable irq request generation */
159 irq_mask |= uplink->irq_mask & MCPDM_UPLINK_IRQ_MASK;
160 omap_mcpdm_write(MCPDM_IRQENABLE_SET, irq_mask);
161
162 /* Configure uplink threshold */
163 if (uplink->threshold > UP_THRES_MAX)
164 uplink->threshold = UP_THRES_MAX;
165
166 omap_mcpdm_write(MCPDM_FIFO_CTRL_UP, uplink->threshold);
167
168 /* Configure DMA controller */
169 omap_mcpdm_write(MCPDM_DMAENABLE_SET, DMA_UP_ENABLE);
170
171 /* Set pdm out format */
172 ctrl = omap_mcpdm_read(MCPDM_CTRL);
173 ctrl &= ~PDMOUTFORMAT;
174 ctrl |= uplink->format & PDMOUTFORMAT;
175
176 /* Uplink channels */
177 mcpdm->up_channels = uplink->channels & (PDM_UP_MASK | PDM_STATUS_MASK);
178
179 omap_mcpdm_write(MCPDM_CTRL, ctrl);
180
181 return 0;
182}
183
184/*
185 * Configures McPDM downlink for audio playback.
186 * This function should be called before omap_mcpdm_start.
187 */
188int omap_mcpdm_playback_open(struct omap_mcpdm_link *downlink)
189{
190 int irq_mask = 0;
191 int ctrl;
192
193 if (!downlink)
194 return -EINVAL;
195
196 mcpdm->downlink = downlink;
197
198 /* Enable irq request generation */
199 irq_mask |= downlink->irq_mask & MCPDM_DOWNLINK_IRQ_MASK;
200 omap_mcpdm_write(MCPDM_IRQENABLE_SET, irq_mask);
201
202 /* Configure uplink threshold */
203 if (downlink->threshold > DN_THRES_MAX)
204 downlink->threshold = DN_THRES_MAX;
205
206 omap_mcpdm_write(MCPDM_FIFO_CTRL_DN, downlink->threshold);
207
208 /* Enable DMA request generation */
209 omap_mcpdm_write(MCPDM_DMAENABLE_SET, DMA_DN_ENABLE);
210
211 /* Set pdm out format */
212 ctrl = omap_mcpdm_read(MCPDM_CTRL);
213 ctrl &= ~PDMOUTFORMAT;
214 ctrl |= downlink->format & PDMOUTFORMAT;
215
216 /* Downlink channels */
217 mcpdm->dn_channels = downlink->channels & (PDM_DN_MASK | PDM_CMD_MASK);
218
219 omap_mcpdm_write(MCPDM_CTRL, ctrl);
220
221 return 0;
222}
223
224/*
225 * Cleans McPDM uplink configuration.
226 * This function should be called when the stream is closed.
227 */
228int omap_mcpdm_capture_close(struct omap_mcpdm_link *uplink)
229{
230 int irq_mask = 0;
231
232 if (!uplink)
233 return -EINVAL;
234
235 /* Disable irq request generation */
236 irq_mask |= uplink->irq_mask & MCPDM_UPLINK_IRQ_MASK;
237 omap_mcpdm_write(MCPDM_IRQENABLE_CLR, irq_mask);
238
239 /* Disable DMA request generation */
240 omap_mcpdm_write(MCPDM_DMAENABLE_CLR, DMA_UP_ENABLE);
241
242 /* Clear Downlink channels */
243 mcpdm->up_channels = 0;
244
245 mcpdm->uplink = NULL;
246
247 return 0;
248}
249
250/*
251 * Cleans McPDM downlink configuration.
252 * This function should be called when the stream is closed.
253 */
254int omap_mcpdm_playback_close(struct omap_mcpdm_link *downlink)
255{
256 int irq_mask = 0;
257
258 if (!downlink)
259 return -EINVAL;
260
261 /* Disable irq request generation */
262 irq_mask |= downlink->irq_mask & MCPDM_DOWNLINK_IRQ_MASK;
263 omap_mcpdm_write(MCPDM_IRQENABLE_CLR, irq_mask);
264
265 /* Disable DMA request generation */
266 omap_mcpdm_write(MCPDM_DMAENABLE_CLR, DMA_DN_ENABLE);
267
268 /* clear Downlink channels */
269 mcpdm->dn_channels = 0;
270
271 mcpdm->downlink = NULL;
272
273 return 0;
274}
275
276static irqreturn_t omap_mcpdm_irq_handler(int irq, void *dev_id)
277{
278 struct omap_mcpdm *mcpdm_irq = dev_id;
279 int irq_status;
280
281 irq_status = omap_mcpdm_read(MCPDM_IRQSTATUS);
282
283 /* Acknowledge irq event */
284 omap_mcpdm_write(MCPDM_IRQSTATUS, irq_status);
285
286 if (irq & MCPDM_DN_IRQ_FULL) {
287 dev_err(mcpdm_irq->dev, "DN FIFO error %x\n", irq_status);
288 omap_mcpdm_reset_playback(1);
289 omap_mcpdm_playback_open(mcpdm_irq->downlink);
290 omap_mcpdm_reset_playback(0);
291 }
292
293 if (irq & MCPDM_DN_IRQ_EMPTY) {
294 dev_err(mcpdm_irq->dev, "DN FIFO error %x\n", irq_status);
295 omap_mcpdm_reset_playback(1);
296 omap_mcpdm_playback_open(mcpdm_irq->downlink);
297 omap_mcpdm_reset_playback(0);
298 }
299
300 if (irq & MCPDM_DN_IRQ) {
301 dev_dbg(mcpdm_irq->dev, "DN write request\n");
302 }
303
304 if (irq & MCPDM_UP_IRQ_FULL) {
305 dev_err(mcpdm_irq->dev, "UP FIFO error %x\n", irq_status);
306 omap_mcpdm_reset_capture(1);
307 omap_mcpdm_capture_open(mcpdm_irq->uplink);
308 omap_mcpdm_reset_capture(0);
309 }
310
311 if (irq & MCPDM_UP_IRQ_EMPTY) {
312 dev_err(mcpdm_irq->dev, "UP FIFO error %x\n", irq_status);
313 omap_mcpdm_reset_capture(1);
314 omap_mcpdm_capture_open(mcpdm_irq->uplink);
315 omap_mcpdm_reset_capture(0);
316 }
317
318 if (irq & MCPDM_UP_IRQ) {
319 dev_dbg(mcpdm_irq->dev, "UP write request\n");
320 }
321
322 return IRQ_HANDLED;
323}
324
325int omap_mcpdm_request(void)
326{
327 int ret;
328
329 clk_enable(mcpdm->clk);
330
331 spin_lock(&mcpdm->lock);
332
333 if (!mcpdm->free) {
334 dev_err(mcpdm->dev, "McPDM interface is in use\n");
335 spin_unlock(&mcpdm->lock);
336 ret = -EBUSY;
337 goto err;
338 }
339 mcpdm->free = 0;
340
341 spin_unlock(&mcpdm->lock);
342
343 /* Disable lines while request is ongoing */
344 omap_mcpdm_write(MCPDM_CTRL, 0x00);
345
346 ret = request_irq(mcpdm->irq, omap_mcpdm_irq_handler,
347 0, "McPDM", (void *)mcpdm);
348 if (ret) {
349 dev_err(mcpdm->dev, "Request for McPDM IRQ failed\n");
350 goto err;
351 }
352
353 return 0;
354
355err:
356 clk_disable(mcpdm->clk);
357 return ret;
358}
359
360void omap_mcpdm_free(void)
361{
362 spin_lock(&mcpdm->lock);
363 if (mcpdm->free) {
364 dev_err(mcpdm->dev, "McPDM interface is already free\n");
365 spin_unlock(&mcpdm->lock);
366 return;
367 }
368 mcpdm->free = 1;
369 spin_unlock(&mcpdm->lock);
370
371 clk_disable(mcpdm->clk);
372
373 free_irq(mcpdm->irq, (void *)mcpdm);
374}
375
376/* Enable/disable DC offset cancelation for the analog
377 * headset path (PDM channels 1 and 2).
378 */
379int omap_mcpdm_set_offset(int offset1, int offset2)
380{
381 int offset;
382
383 if ((offset1 > DN_OFST_MAX) || (offset2 > DN_OFST_MAX))
384 return -EINVAL;
385
386 offset = (offset1 << DN_OFST_RX1) | (offset2 << DN_OFST_RX2);
387
388 /* offset cancellation for channel 1 */
389 if (offset1)
390 offset |= DN_OFST_RX1_EN;
391 else
392 offset &= ~DN_OFST_RX1_EN;
393
394 /* offset cancellation for channel 2 */
395 if (offset2)
396 offset |= DN_OFST_RX2_EN;
397 else
398 offset &= ~DN_OFST_RX2_EN;
399
400 omap_mcpdm_write(MCPDM_DN_OFFSET, offset);
401
402 return 0;
403}
404
405int __devinit omap_mcpdm_probe(struct platform_device *pdev)
406{
407 struct resource *res;
408 int ret = 0;
409
410 mcpdm = kzalloc(sizeof(struct omap_mcpdm), GFP_KERNEL);
411 if (!mcpdm) {
412 ret = -ENOMEM;
413 goto exit;
414 }
415
416 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
417 if (res == NULL) {
418 dev_err(&pdev->dev, "no resource\n");
419 goto err_resource;
420 }
421
422 spin_lock_init(&mcpdm->lock);
423 mcpdm->free = 1;
424 mcpdm->io_base = ioremap(res->start, resource_size(res));
425 if (!mcpdm->io_base) {
426 ret = -ENOMEM;
427 goto err_resource;
428 }
429
430 mcpdm->irq = platform_get_irq(pdev, 0);
431
432 mcpdm->clk = clk_get(&pdev->dev, "pdm_ck");
433 if (IS_ERR(mcpdm->clk)) {
434 ret = PTR_ERR(mcpdm->clk);
435 dev_err(&pdev->dev, "unable to get pdm_ck: %d\n", ret);
436 goto err_clk;
437 }
438
439 mcpdm->dev = &pdev->dev;
440 platform_set_drvdata(pdev, mcpdm);
441
442 return 0;
443
444err_clk:
445 iounmap(mcpdm->io_base);
446err_resource:
447 kfree(mcpdm);
448exit:
449 return ret;
450}
451
452int omap_mcpdm_remove(struct platform_device *pdev)
453{
454 struct omap_mcpdm *mcpdm_ptr = platform_get_drvdata(pdev);
455
456 platform_set_drvdata(pdev, NULL);
457
458 clk_put(mcpdm_ptr->clk);
459
460 iounmap(mcpdm_ptr->io_base);
461
462 mcpdm_ptr->clk = NULL;
463 mcpdm_ptr->free = 0;
464 mcpdm_ptr->dev = NULL;
465
466 kfree(mcpdm_ptr);
467
468 return 0;
469}
470
diff --git a/sound/soc/omap/mcpdm.h b/sound/soc/omap/mcpdm.h
deleted file mode 100644
index 20c20a8649f..00000000000
--- a/sound/soc/omap/mcpdm.h
+++ /dev/null
@@ -1,153 +0,0 @@
1/*
2 * mcpdm.h -- Defines for McPDM driver
3 *
4 * Author: Jorge Eduardo Candelaria <x0107209@ti.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21
22/* McPDM registers */
23
24#define MCPDM_REVISION 0x00
25#define MCPDM_SYSCONFIG 0x10
26#define MCPDM_IRQSTATUS_RAW 0x24
27#define MCPDM_IRQSTATUS 0x28
28#define MCPDM_IRQENABLE_SET 0x2C
29#define MCPDM_IRQENABLE_CLR 0x30
30#define MCPDM_IRQWAKE_EN 0x34
31#define MCPDM_DMAENABLE_SET 0x38
32#define MCPDM_DMAENABLE_CLR 0x3C
33#define MCPDM_DMAWAKEEN 0x40
34#define MCPDM_CTRL 0x44
35#define MCPDM_DN_DATA 0x48
36#define MCPDM_UP_DATA 0x4C
37#define MCPDM_FIFO_CTRL_DN 0x50
38#define MCPDM_FIFO_CTRL_UP 0x54
39#define MCPDM_DN_OFFSET 0x58
40
41/*
42 * MCPDM_IRQ bit fields
43 * IRQSTATUS_RAW, IRQSTATUS, IRQENABLE_SET, IRQENABLE_CLR
44 */
45
46#define MCPDM_DN_IRQ (1 << 0)
47#define MCPDM_DN_IRQ_EMPTY (1 << 1)
48#define MCPDM_DN_IRQ_ALMST_EMPTY (1 << 2)
49#define MCPDM_DN_IRQ_FULL (1 << 3)
50
51#define MCPDM_UP_IRQ (1 << 8)
52#define MCPDM_UP_IRQ_EMPTY (1 << 9)
53#define MCPDM_UP_IRQ_ALMST_FULL (1 << 10)
54#define MCPDM_UP_IRQ_FULL (1 << 11)
55
56#define MCPDM_DOWNLINK_IRQ_MASK 0x00F
57#define MCPDM_UPLINK_IRQ_MASK 0xF00
58
59/*
60 * MCPDM_DMAENABLE bit fields
61 */
62
63#define DMA_DN_ENABLE 0x1
64#define DMA_UP_ENABLE 0x2
65
66/*
67 * MCPDM_CTRL bit fields
68 */
69
70#define PDM_UP1_EN 0x0001
71#define PDM_UP2_EN 0x0002
72#define PDM_UP3_EN 0x0004
73#define PDM_DN1_EN 0x0008
74#define PDM_DN2_EN 0x0010
75#define PDM_DN3_EN 0x0020
76#define PDM_DN4_EN 0x0040
77#define PDM_DN5_EN 0x0080
78#define PDMOUTFORMAT 0x0100
79#define CMD_INT 0x0200
80#define STATUS_INT 0x0400
81#define SW_UP_RST 0x0800
82#define SW_DN_RST 0x1000
83#define PDM_UP_MASK 0x007
84#define PDM_DN_MASK 0x0F8
85#define PDM_CMD_MASK 0x200
86#define PDM_STATUS_MASK 0x400
87
88
89#define PDMOUTFORMAT_LJUST (0 << 8)
90#define PDMOUTFORMAT_RJUST (1 << 8)
91
92/*
93 * MCPDM_FIFO_CTRL bit fields
94 */
95
96#define UP_THRES_MAX 0xF
97#define DN_THRES_MAX 0xF
98
99/*
100 * MCPDM_DN_OFFSET bit fields
101 */
102
103#define DN_OFST_RX1_EN 0x0001
104#define DN_OFST_RX2_EN 0x0100
105
106#define DN_OFST_RX1 1
107#define DN_OFST_RX2 9
108#define DN_OFST_MAX 0x1F
109
110#define MCPDM_UPLINK 1
111#define MCPDM_DOWNLINK 2
112
113struct omap_mcpdm_link {
114 int irq_mask;
115 int threshold;
116 int format;
117 int channels;
118};
119
120struct omap_mcpdm_platform_data {
121 unsigned long phys_base;
122 u16 irq;
123};
124
125struct omap_mcpdm {
126 struct device *dev;
127 unsigned long phys_base;
128 void __iomem *io_base;
129 u8 free;
130 int irq;
131
132 spinlock_t lock;
133 struct omap_mcpdm_platform_data *pdata;
134 struct clk *clk;
135 struct omap_mcpdm_link *downlink;
136 struct omap_mcpdm_link *uplink;
137 struct completion irq_completion;
138
139 int dn_channels;
140 int up_channels;
141};
142
143extern void omap_mcpdm_start(int stream);
144extern void omap_mcpdm_stop(int stream);
145extern int omap_mcpdm_capture_open(struct omap_mcpdm_link *uplink);
146extern int omap_mcpdm_playback_open(struct omap_mcpdm_link *downlink);
147extern int omap_mcpdm_capture_close(struct omap_mcpdm_link *uplink);
148extern int omap_mcpdm_playback_close(struct omap_mcpdm_link *downlink);
149extern int omap_mcpdm_request(void);
150extern void omap_mcpdm_free(void);
151extern int omap_mcpdm_set_offset(int offset1, int offset2);
152int __devinit omap_mcpdm_probe(struct platform_device *pdev);
153int omap_mcpdm_remove(struct platform_device *pdev);
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c
index 62e292f4931..7e3c20c965c 100644
--- a/sound/soc/omap/n810.c
+++ b/sound/soc/omap/n810.c
@@ -115,25 +115,8 @@ static int n810_hw_params(struct snd_pcm_substream *substream,
115{ 115{
116 struct snd_soc_pcm_runtime *rtd = substream->private_data; 116 struct snd_soc_pcm_runtime *rtd = substream->private_data;
117 struct snd_soc_dai *codec_dai = rtd->codec_dai; 117 struct snd_soc_dai *codec_dai = rtd->codec_dai;
118 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
119 int err; 118 int err;
120 119
121 /* Set codec DAI configuration */
122 err = snd_soc_dai_set_fmt(codec_dai,
123 SND_SOC_DAIFMT_I2S |
124 SND_SOC_DAIFMT_NB_NF |
125 SND_SOC_DAIFMT_CBM_CFM);
126 if (err < 0)
127 return err;
128
129 /* Set cpu DAI configuration */
130 err = snd_soc_dai_set_fmt(cpu_dai,
131 SND_SOC_DAIFMT_I2S |
132 SND_SOC_DAIFMT_NB_NF |
133 SND_SOC_DAIFMT_CBM_CFM);
134 if (err < 0)
135 return err;
136
137 /* Set the codec system clock for DAC and ADC */ 120 /* Set the codec system clock for DAC and ADC */
138 err = snd_soc_dai_set_sysclk(codec_dai, 0, 12000000, 121 err = snd_soc_dai_set_sysclk(codec_dai, 0, 12000000,
139 SND_SOC_CLOCK_IN); 122 SND_SOC_CLOCK_IN);
@@ -274,7 +257,6 @@ static int n810_aic33_init(struct snd_soc_pcm_runtime *rtd)
274{ 257{
275 struct snd_soc_codec *codec = rtd->codec; 258 struct snd_soc_codec *codec = rtd->codec;
276 struct snd_soc_dapm_context *dapm = &codec->dapm; 259 struct snd_soc_dapm_context *dapm = &codec->dapm;
277 int err;
278 260
279 /* Not connected */ 261 /* Not connected */
280 snd_soc_dapm_nc_pin(dapm, "MONO_LOUT"); 262 snd_soc_dapm_nc_pin(dapm, "MONO_LOUT");
@@ -286,21 +268,6 @@ static int n810_aic33_init(struct snd_soc_pcm_runtime *rtd)
286 snd_soc_dapm_nc_pin(dapm, "LINE2L"); 268 snd_soc_dapm_nc_pin(dapm, "LINE2L");
287 snd_soc_dapm_nc_pin(dapm, "LINE2R"); 269 snd_soc_dapm_nc_pin(dapm, "LINE2R");
288 270
289 /* Add N810 specific controls */
290 err = snd_soc_add_controls(codec, aic33_n810_controls,
291 ARRAY_SIZE(aic33_n810_controls));
292 if (err < 0)
293 return err;
294
295 /* Add N810 specific widgets */
296 snd_soc_dapm_new_controls(dapm, aic33_dapm_widgets,
297 ARRAY_SIZE(aic33_dapm_widgets));
298
299 /* Set up N810 specific audio path audio_map */
300 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
301
302 snd_soc_dapm_sync(dapm);
303
304 return 0; 271 return 0;
305} 272}
306 273
@@ -312,6 +279,8 @@ static struct snd_soc_dai_link n810_dai = {
312 .platform_name = "omap-pcm-audio", 279 .platform_name = "omap-pcm-audio",
313 .codec_name = "tlv320aic3x-codec.2-0018", 280 .codec_name = "tlv320aic3x-codec.2-0018",
314 .codec_dai_name = "tlv320aic3x-hifi", 281 .codec_dai_name = "tlv320aic3x-hifi",
282 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
283 SND_SOC_DAIFMT_CBM_CFM,
315 .init = n810_aic33_init, 284 .init = n810_aic33_init,
316 .ops = &n810_ops, 285 .ops = &n810_ops,
317}; 286};
@@ -321,6 +290,13 @@ static struct snd_soc_card snd_soc_n810 = {
321 .name = "N810", 290 .name = "N810",
322 .dai_link = &n810_dai, 291 .dai_link = &n810_dai,
323 .num_links = 1, 292 .num_links = 1,
293
294 .controls = aic33_n810_controls,
295 .num_controls = ARRAY_SIZE(aic33_n810_controls),
296 .dapm_widgets = aic33_dapm_widgets,
297 .num_dapm_widgets = ARRAY_SIZE(aic33_dapm_widgets),
298 .dapm_routes = audio_map,
299 .num_dapm_routes = ARRAY_SIZE(audio_map),
324}; 300};
325 301
326static struct platform_device *n810_snd_device; 302static struct platform_device *n810_snd_device;
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index 478d6077845..4314647e735 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -317,6 +317,10 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
317 return 0; 317 return 0;
318 } 318 }
319 319
320 regs->rcr2 &= ~(RPHASE | RFRLEN2(0x7f) | RWDLEN2(7));
321 regs->xcr2 &= ~(RPHASE | XFRLEN2(0x7f) | XWDLEN2(7));
322 regs->rcr1 &= ~(RFRLEN1(0x7f) | RWDLEN1(7));
323 regs->xcr1 &= ~(XFRLEN1(0x7f) | XWDLEN1(7));
320 format = mcbsp_data->fmt & SND_SOC_DAIFMT_FORMAT_MASK; 324 format = mcbsp_data->fmt & SND_SOC_DAIFMT_FORMAT_MASK;
321 wpf = channels = params_channels(params); 325 wpf = channels = params_channels(params);
322 if (channels == 2 && (format == SND_SOC_DAIFMT_I2S || 326 if (channels == 2 && (format == SND_SOC_DAIFMT_I2S ||
@@ -369,6 +373,8 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
369 framesize = wlen * channels; 373 framesize = wlen * channels;
370 374
371 /* Set FS period and length in terms of bit clock periods */ 375 /* Set FS period and length in terms of bit clock periods */
376 regs->srgr2 &= ~FPER(0xfff);
377 regs->srgr1 &= ~FWID(0xff);
372 switch (format) { 378 switch (format) {
373 case SND_SOC_DAIFMT_I2S: 379 case SND_SOC_DAIFMT_I2S:
374 case SND_SOC_DAIFMT_LEFT_J: 380 case SND_SOC_DAIFMT_LEFT_J:
@@ -398,7 +404,7 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
398{ 404{
399 struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai); 405 struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai);
400 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs; 406 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs;
401 unsigned int temp_fmt = fmt; 407 bool inv_fs = false;
402 408
403 if (mcbsp_data->configured) 409 if (mcbsp_data->configured)
404 return 0; 410 return 0;
@@ -430,21 +436,21 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
430 regs->xcr2 |= XDATDLY(0); 436 regs->xcr2 |= XDATDLY(0);
431 regs->spcr1 |= RJUST(2); 437 regs->spcr1 |= RJUST(2);
432 /* Invert FS polarity configuration */ 438 /* Invert FS polarity configuration */
433 temp_fmt ^= SND_SOC_DAIFMT_NB_IF; 439 inv_fs = true;
434 break; 440 break;
435 case SND_SOC_DAIFMT_DSP_A: 441 case SND_SOC_DAIFMT_DSP_A:
436 /* 1-bit data delay */ 442 /* 1-bit data delay */
437 regs->rcr2 |= RDATDLY(1); 443 regs->rcr2 |= RDATDLY(1);
438 regs->xcr2 |= XDATDLY(1); 444 regs->xcr2 |= XDATDLY(1);
439 /* Invert FS polarity configuration */ 445 /* Invert FS polarity configuration */
440 temp_fmt ^= SND_SOC_DAIFMT_NB_IF; 446 inv_fs = true;
441 break; 447 break;
442 case SND_SOC_DAIFMT_DSP_B: 448 case SND_SOC_DAIFMT_DSP_B:
443 /* 0-bit data delay */ 449 /* 0-bit data delay */
444 regs->rcr2 |= RDATDLY(0); 450 regs->rcr2 |= RDATDLY(0);
445 regs->xcr2 |= XDATDLY(0); 451 regs->xcr2 |= XDATDLY(0);
446 /* Invert FS polarity configuration */ 452 /* Invert FS polarity configuration */
447 temp_fmt ^= SND_SOC_DAIFMT_NB_IF; 453 inv_fs = true;
448 break; 454 break;
449 default: 455 default:
450 /* Unsupported data format */ 456 /* Unsupported data format */
@@ -468,7 +474,7 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
468 } 474 }
469 475
470 /* Set bit clock (CLKX/CLKR) and FS polarities */ 476 /* Set bit clock (CLKX/CLKR) and FS polarities */
471 switch (temp_fmt & SND_SOC_DAIFMT_INV_MASK) { 477 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
472 case SND_SOC_DAIFMT_NB_NF: 478 case SND_SOC_DAIFMT_NB_NF:
473 /* 479 /*
474 * Normal BCLK + FS. 480 * Normal BCLK + FS.
@@ -489,6 +495,8 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
489 default: 495 default:
490 return -EINVAL; 496 return -EINVAL;
491 } 497 }
498 if (inv_fs == true)
499 regs->pcr0 ^= FSXP | FSRP;
492 500
493 return 0; 501 return 0;
494} 502}
@@ -503,6 +511,7 @@ static int omap_mcbsp_dai_set_clkdiv(struct snd_soc_dai *cpu_dai,
503 return -ENODEV; 511 return -ENODEV;
504 512
505 mcbsp_data->clk_div = div; 513 mcbsp_data->clk_div = div;
514 regs->srgr1 &= ~CLKGDV(0xff);
506 regs->srgr1 |= CLKGDV(div - 1); 515 regs->srgr1 |= CLKGDV(div - 1);
507 516
508 return 0; 517 return 0;
@@ -516,11 +525,12 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
516 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs; 525 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs;
517 int err = 0; 526 int err = 0;
518 527
519 if (mcbsp_data->active) 528 if (mcbsp_data->active) {
520 if (freq == mcbsp_data->in_freq) 529 if (freq == mcbsp_data->in_freq)
521 return 0; 530 return 0;
522 else 531 else
523 return -EBUSY; 532 return -EBUSY;
533 }
524 534
525 /* The McBSP signal muxing functions are only available on McBSP1 */ 535 /* The McBSP signal muxing functions are only available on McBSP1 */
526 if (clk_id == OMAP_MCBSP_CLKR_SRC_CLKR || 536 if (clk_id == OMAP_MCBSP_CLKR_SRC_CLKR ||
@@ -531,6 +541,8 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
531 return -EINVAL; 541 return -EINVAL;
532 542
533 mcbsp_data->in_freq = freq; 543 mcbsp_data->in_freq = freq;
544 regs->srgr2 &= ~CLKSM;
545 regs->pcr0 &= ~SCLKME;
534 546
535 switch (clk_id) { 547 switch (clk_id) {
536 case OMAP_MCBSP_SYSCLK_CLK: 548 case OMAP_MCBSP_SYSCLK_CLK:
@@ -605,8 +617,7 @@ static int mcbsp_dai_probe(struct snd_soc_dai *dai)
605 return 0; 617 return 0;
606} 618}
607 619
608static struct snd_soc_dai_driver omap_mcbsp_dai = 620static struct snd_soc_dai_driver omap_mcbsp_dai = {
609{
610 .probe = mcbsp_dai_probe, 621 .probe = mcbsp_dai_probe,
611 .playback = { 622 .playback = {
612 .channels_min = 1, 623 .channels_min = 1,
diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c
index bed09c27e44..41d17067cc7 100644
--- a/sound/soc/omap/omap-mcpdm.c
+++ b/sound/soc/omap/omap-mcpdm.c
@@ -1,11 +1,12 @@
1/* 1/*
2 * omap-mcpdm.c -- OMAP ALSA SoC DAI driver using McPDM port 2 * omap-mcpdm.c -- OMAP ALSA SoC DAI driver using McPDM port
3 * 3 *
4 * Copyright (C) 2009 Texas Instruments 4 * Copyright (C) 2009 - 2011 Texas Instruments
5 * 5 *
6 * Author: Misael Lopez Cruz <x0052729@ti.com> 6 * Author: Misael Lopez Cruz <misael.lopez@ti.com>
7 * Contact: Jorge Eduardo Candelaria <x0107209@ti.com> 7 * Contact: Jorge Eduardo Candelaria <x0107209@ti.com>
8 * Margarita Olaya <magi.olaya@ti.com> 8 * Margarita Olaya <magi.olaya@ti.com>
9 * Peter Ujfalusi <peter.ujfalusi@ti.com>
9 * 10 *
10 * This program is free software; you can redistribute it and/or 11 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License 12 * modify it under the terms of the GNU General Public License
@@ -25,41 +26,42 @@
25 26
26#include <linux/init.h> 27#include <linux/init.h>
27#include <linux/module.h> 28#include <linux/module.h>
28#include <linux/device.h> 29#include <linux/platform_device.h>
30#include <linux/interrupt.h>
31#include <linux/err.h>
32#include <linux/io.h>
33#include <linux/irq.h>
34#include <linux/slab.h>
35#include <linux/pm_runtime.h>
36
29#include <sound/core.h> 37#include <sound/core.h>
30#include <sound/pcm.h> 38#include <sound/pcm.h>
31#include <sound/pcm_params.h> 39#include <sound/pcm_params.h>
32#include <sound/initval.h>
33#include <sound/soc.h> 40#include <sound/soc.h>
34 41
35#include <plat/dma.h> 42#include <plat/dma.h>
36#include <plat/mcbsp.h> 43#include <plat/omap_hwmod.h>
37#include "mcpdm.h" 44#include "omap-mcpdm.h"
38#include "omap-pcm.h" 45#include "omap-pcm.h"
39 46
40struct omap_mcpdm_data { 47struct omap_mcpdm {
41 struct omap_mcpdm_link *links; 48 struct device *dev;
42 int active; 49 unsigned long phys_base;
43}; 50 void __iomem *io_base;
51 int irq;
44 52
45static struct omap_mcpdm_link omap_mcpdm_links[] = { 53 struct mutex mutex;
46 /* downlink */ 54
47 { 55 /* channel data */
48 .irq_mask = MCPDM_DN_IRQ_EMPTY | MCPDM_DN_IRQ_FULL, 56 u32 dn_channels;
49 .threshold = 1, 57 u32 up_channels;
50 .format = PDMOUTFORMAT_LJUST, 58
51 }, 59 /* McPDM FIFO thresholds */
52 /* uplink */ 60 u32 dn_threshold;
53 { 61 u32 up_threshold;
54 .irq_mask = MCPDM_UP_IRQ_EMPTY | MCPDM_UP_IRQ_FULL,
55 .threshold = 1,
56 .format = PDMOUTFORMAT_LJUST,
57 },
58};
59 62
60static struct omap_mcpdm_data mcpdm_data = { 63 /* McPDM dn offsets for rx1, and 2 channels */
61 .links = omap_mcpdm_links, 64 u32 dn_rx_offset;
62 .active = 0,
63}; 65};
64 66
65/* 67/*
@@ -71,88 +73,259 @@ static struct omap_pcm_dma_data omap_mcpdm_dai_dma_params[] = {
71 .dma_req = OMAP44XX_DMA_MCPDM_DL, 73 .dma_req = OMAP44XX_DMA_MCPDM_DL,
72 .data_type = OMAP_DMA_DATA_TYPE_S32, 74 .data_type = OMAP_DMA_DATA_TYPE_S32,
73 .sync_mode = OMAP_DMA_SYNC_PACKET, 75 .sync_mode = OMAP_DMA_SYNC_PACKET,
74 .packet_size = 16, 76 .port_addr = OMAP44XX_MCPDM_L3_BASE + MCPDM_REG_DN_DATA,
75 .port_addr = OMAP44XX_MCPDM_L3_BASE + MCPDM_DN_DATA,
76 }, 77 },
77 { 78 {
78 .name = "Audio capture", 79 .name = "Audio capture",
79 .dma_req = OMAP44XX_DMA_MCPDM_UP, 80 .dma_req = OMAP44XX_DMA_MCPDM_UP,
80 .data_type = OMAP_DMA_DATA_TYPE_S32, 81 .data_type = OMAP_DMA_DATA_TYPE_S32,
81 .sync_mode = OMAP_DMA_SYNC_PACKET, 82 .sync_mode = OMAP_DMA_SYNC_PACKET,
82 .packet_size = 16, 83 .port_addr = OMAP44XX_MCPDM_L3_BASE + MCPDM_REG_UP_DATA,
83 .port_addr = OMAP44XX_MCPDM_L3_BASE + MCPDM_UP_DATA,
84 }, 84 },
85}; 85};
86 86
87static int omap_mcpdm_dai_startup(struct snd_pcm_substream *substream, 87static inline void omap_mcpdm_write(struct omap_mcpdm *mcpdm, u16 reg, u32 val)
88 struct snd_soc_dai *dai)
89{ 88{
90 int err = 0; 89 __raw_writel(val, mcpdm->io_base + reg);
90}
91 91
92 if (!dai->active) 92static inline int omap_mcpdm_read(struct omap_mcpdm *mcpdm, u16 reg)
93 err = omap_mcpdm_request(); 93{
94 return __raw_readl(mcpdm->io_base + reg);
95}
94 96
95 return err; 97#ifdef DEBUG
98static void omap_mcpdm_reg_dump(struct omap_mcpdm *mcpdm)
99{
100 dev_dbg(mcpdm->dev, "***********************\n");
101 dev_dbg(mcpdm->dev, "IRQSTATUS_RAW: 0x%04x\n",
102 omap_mcpdm_read(mcpdm, MCPDM_REG_IRQSTATUS_RAW));
103 dev_dbg(mcpdm->dev, "IRQSTATUS: 0x%04x\n",
104 omap_mcpdm_read(mcpdm, MCPDM_REG_IRQSTATUS));
105 dev_dbg(mcpdm->dev, "IRQENABLE_SET: 0x%04x\n",
106 omap_mcpdm_read(mcpdm, MCPDM_REG_IRQENABLE_SET));
107 dev_dbg(mcpdm->dev, "IRQENABLE_CLR: 0x%04x\n",
108 omap_mcpdm_read(mcpdm, MCPDM_REG_IRQENABLE_CLR));
109 dev_dbg(mcpdm->dev, "IRQWAKE_EN: 0x%04x\n",
110 omap_mcpdm_read(mcpdm, MCPDM_REG_IRQWAKE_EN));
111 dev_dbg(mcpdm->dev, "DMAENABLE_SET: 0x%04x\n",
112 omap_mcpdm_read(mcpdm, MCPDM_REG_DMAENABLE_SET));
113 dev_dbg(mcpdm->dev, "DMAENABLE_CLR: 0x%04x\n",
114 omap_mcpdm_read(mcpdm, MCPDM_REG_DMAENABLE_CLR));
115 dev_dbg(mcpdm->dev, "DMAWAKEEN: 0x%04x\n",
116 omap_mcpdm_read(mcpdm, MCPDM_REG_DMAWAKEEN));
117 dev_dbg(mcpdm->dev, "CTRL: 0x%04x\n",
118 omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL));
119 dev_dbg(mcpdm->dev, "DN_DATA: 0x%04x\n",
120 omap_mcpdm_read(mcpdm, MCPDM_REG_DN_DATA));
121 dev_dbg(mcpdm->dev, "UP_DATA: 0x%04x\n",
122 omap_mcpdm_read(mcpdm, MCPDM_REG_UP_DATA));
123 dev_dbg(mcpdm->dev, "FIFO_CTRL_DN: 0x%04x\n",
124 omap_mcpdm_read(mcpdm, MCPDM_REG_FIFO_CTRL_DN));
125 dev_dbg(mcpdm->dev, "FIFO_CTRL_UP: 0x%04x\n",
126 omap_mcpdm_read(mcpdm, MCPDM_REG_FIFO_CTRL_UP));
127 dev_dbg(mcpdm->dev, "***********************\n");
96} 128}
129#else
130static void omap_mcpdm_reg_dump(struct omap_mcpdm *mcpdm) {}
131#endif
97 132
98static void omap_mcpdm_dai_shutdown(struct snd_pcm_substream *substream, 133/*
99 struct snd_soc_dai *dai) 134 * Enables the transfer through the PDM interface to/from the Phoenix
135 * codec by enabling the corresponding UP or DN channels.
136 */
137static void omap_mcpdm_start(struct omap_mcpdm *mcpdm)
138{
139 u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL);
140
141 ctrl |= (MCPDM_SW_DN_RST | MCPDM_SW_UP_RST);
142 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl);
143
144 ctrl |= mcpdm->dn_channels | mcpdm->up_channels;
145 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl);
146
147 ctrl &= ~(MCPDM_SW_DN_RST | MCPDM_SW_UP_RST);
148 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl);
149}
150
151/*
152 * Disables the transfer through the PDM interface to/from the Phoenix
153 * codec by disabling the corresponding UP or DN channels.
154 */
155static void omap_mcpdm_stop(struct omap_mcpdm *mcpdm)
156{
157 u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL);
158
159 ctrl |= (MCPDM_SW_DN_RST | MCPDM_SW_UP_RST);
160 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl);
161
162 ctrl &= ~(mcpdm->dn_channels | mcpdm->up_channels);
163 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl);
164
165 ctrl &= ~(MCPDM_SW_DN_RST | MCPDM_SW_UP_RST);
166 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl);
167
168}
169
170/*
171 * Is the physical McPDM interface active.
172 */
173static inline int omap_mcpdm_active(struct omap_mcpdm *mcpdm)
174{
175 return omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL) &
176 (MCPDM_PDM_DN_MASK | MCPDM_PDM_UP_MASK);
177}
178
179/*
180 * Configures McPDM uplink, and downlink for audio.
181 * This function should be called before omap_mcpdm_start.
182 */
183static void omap_mcpdm_open_streams(struct omap_mcpdm *mcpdm)
184{
185 omap_mcpdm_write(mcpdm, MCPDM_REG_IRQENABLE_SET,
186 MCPDM_DN_IRQ_EMPTY | MCPDM_DN_IRQ_FULL |
187 MCPDM_UP_IRQ_EMPTY | MCPDM_UP_IRQ_FULL);
188
189 /* Enable DN RX1/2 offset cancellation feature, if configured */
190 if (mcpdm->dn_rx_offset) {
191 u32 dn_offset = mcpdm->dn_rx_offset;
192
193 omap_mcpdm_write(mcpdm, MCPDM_REG_DN_OFFSET, dn_offset);
194 dn_offset |= (MCPDM_DN_OFST_RX1_EN | MCPDM_DN_OFST_RX2_EN);
195 omap_mcpdm_write(mcpdm, MCPDM_REG_DN_OFFSET, dn_offset);
196 }
197
198 omap_mcpdm_write(mcpdm, MCPDM_REG_FIFO_CTRL_DN, mcpdm->dn_threshold);
199 omap_mcpdm_write(mcpdm, MCPDM_REG_FIFO_CTRL_UP, mcpdm->up_threshold);
200
201 omap_mcpdm_write(mcpdm, MCPDM_REG_DMAENABLE_SET,
202 MCPDM_DMA_DN_ENABLE | MCPDM_DMA_UP_ENABLE);
203}
204
205/*
206 * Cleans McPDM uplink, and downlink configuration.
207 * This function should be called when the stream is closed.
208 */
209static void omap_mcpdm_close_streams(struct omap_mcpdm *mcpdm)
210{
211 /* Disable irq request generation for downlink */
212 omap_mcpdm_write(mcpdm, MCPDM_REG_IRQENABLE_CLR,
213 MCPDM_DN_IRQ_EMPTY | MCPDM_DN_IRQ_FULL);
214
215 /* Disable DMA request generation for downlink */
216 omap_mcpdm_write(mcpdm, MCPDM_REG_DMAENABLE_CLR, MCPDM_DMA_DN_ENABLE);
217
218 /* Disable irq request generation for uplink */
219 omap_mcpdm_write(mcpdm, MCPDM_REG_IRQENABLE_CLR,
220 MCPDM_UP_IRQ_EMPTY | MCPDM_UP_IRQ_FULL);
221
222 /* Disable DMA request generation for uplink */
223 omap_mcpdm_write(mcpdm, MCPDM_REG_DMAENABLE_CLR, MCPDM_DMA_UP_ENABLE);
224
225 /* Disable RX1/2 offset cancellation */
226 if (mcpdm->dn_rx_offset)
227 omap_mcpdm_write(mcpdm, MCPDM_REG_DN_OFFSET, 0);
228}
229
230static irqreturn_t omap_mcpdm_irq_handler(int irq, void *dev_id)
231{
232 struct omap_mcpdm *mcpdm = dev_id;
233 int irq_status;
234
235 irq_status = omap_mcpdm_read(mcpdm, MCPDM_REG_IRQSTATUS);
236
237 /* Acknowledge irq event */
238 omap_mcpdm_write(mcpdm, MCPDM_REG_IRQSTATUS, irq_status);
239
240 if (irq_status & MCPDM_DN_IRQ_FULL)
241 dev_dbg(mcpdm->dev, "DN (playback) FIFO Full\n");
242
243 if (irq_status & MCPDM_DN_IRQ_EMPTY)
244 dev_dbg(mcpdm->dev, "DN (playback) FIFO Empty\n");
245
246 if (irq_status & MCPDM_DN_IRQ)
247 dev_dbg(mcpdm->dev, "DN (playback) write request\n");
248
249 if (irq_status & MCPDM_UP_IRQ_FULL)
250 dev_dbg(mcpdm->dev, "UP (capture) FIFO Full\n");
251
252 if (irq_status & MCPDM_UP_IRQ_EMPTY)
253 dev_dbg(mcpdm->dev, "UP (capture) FIFO Empty\n");
254
255 if (irq_status & MCPDM_UP_IRQ)
256 dev_dbg(mcpdm->dev, "UP (capture) write request\n");
257
258 return IRQ_HANDLED;
259}
260
261static int omap_mcpdm_dai_startup(struct snd_pcm_substream *substream,
262 struct snd_soc_dai *dai)
100{ 263{
101 if (!dai->active) 264 struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
102 omap_mcpdm_free(); 265
266 mutex_lock(&mcpdm->mutex);
267
268 if (!dai->active) {
269 pm_runtime_get_sync(mcpdm->dev);
270
271 /* Enable watch dog for ES above ES 1.0 to avoid saturation */
272 if (omap_rev() != OMAP4430_REV_ES1_0) {
273 u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL);
274
275 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL,
276 ctrl | MCPDM_WD_EN);
277 }
278 omap_mcpdm_open_streams(mcpdm);
279 }
280
281 mutex_unlock(&mcpdm->mutex);
282
283 return 0;
103} 284}
104 285
105static int omap_mcpdm_dai_trigger(struct snd_pcm_substream *substream, int cmd, 286static void omap_mcpdm_dai_shutdown(struct snd_pcm_substream *substream,
106 struct snd_soc_dai *dai) 287 struct snd_soc_dai *dai)
107{ 288{
108 struct omap_mcpdm_data *mcpdm_priv = snd_soc_dai_get_drvdata(dai); 289 struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
109 int stream = substream->stream;
110 int err = 0;
111
112 switch (cmd) {
113 case SNDRV_PCM_TRIGGER_START:
114 case SNDRV_PCM_TRIGGER_RESUME:
115 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
116 if (!mcpdm_priv->active++)
117 omap_mcpdm_start(stream);
118 break;
119 290
120 case SNDRV_PCM_TRIGGER_STOP: 291 mutex_lock(&mcpdm->mutex);
121 case SNDRV_PCM_TRIGGER_SUSPEND: 292
122 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 293 if (!dai->active) {
123 if (!--mcpdm_priv->active) 294 if (omap_mcpdm_active(mcpdm)) {
124 omap_mcpdm_stop(stream); 295 omap_mcpdm_stop(mcpdm);
125 break; 296 omap_mcpdm_close_streams(mcpdm);
126 default: 297 }
127 err = -EINVAL; 298
299 if (!omap_mcpdm_active(mcpdm))
300 pm_runtime_put_sync(mcpdm->dev);
128 } 301 }
129 302
130 return err; 303 mutex_unlock(&mcpdm->mutex);
131} 304}
132 305
133static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream, 306static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream,
134 struct snd_pcm_hw_params *params, 307 struct snd_pcm_hw_params *params,
135 struct snd_soc_dai *dai) 308 struct snd_soc_dai *dai)
136{ 309{
137 struct omap_mcpdm_data *mcpdm_priv = snd_soc_dai_get_drvdata(dai); 310 struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
138 struct omap_mcpdm_link *mcpdm_links = mcpdm_priv->links;
139 int stream = substream->stream; 311 int stream = substream->stream;
140 int channels, err, link_mask = 0; 312 struct omap_pcm_dma_data *dma_data;
141 313 int channels;
142 snd_soc_dai_set_dma_data(dai, substream, 314 int link_mask = 0;
143 &omap_mcpdm_dai_dma_params[stream]);
144 315
145 channels = params_channels(params); 316 channels = params_channels(params);
146 switch (channels) { 317 switch (channels) {
318 case 5:
319 if (stream == SNDRV_PCM_STREAM_CAPTURE)
320 /* up to 3 channels for capture */
321 return -EINVAL;
322 link_mask |= 1 << 4;
147 case 4: 323 case 4:
148 if (stream == SNDRV_PCM_STREAM_CAPTURE) 324 if (stream == SNDRV_PCM_STREAM_CAPTURE)
149 /* up to 2 channels for capture */ 325 /* up to 3 channels for capture */
150 return -EINVAL; 326 return -EINVAL;
151 link_mask |= 1 << 3; 327 link_mask |= 1 << 3;
152 case 3: 328 case 3:
153 if (stream == SNDRV_PCM_STREAM_CAPTURE)
154 /* up to 2 channels for capture */
155 return -EINVAL;
156 link_mask |= 1 << 2; 329 link_mask |= 1 << 2;
157 case 2: 330 case 2:
158 link_mask |= 1 << 1; 331 link_mask |= 1 << 1;
@@ -164,95 +337,187 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream,
164 return -EINVAL; 337 return -EINVAL;
165 } 338 }
166 339
340 dma_data = &omap_mcpdm_dai_dma_params[stream];
341
342 /* Configure McPDM channels, and DMA packet size */
167 if (stream == SNDRV_PCM_STREAM_PLAYBACK) { 343 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
168 mcpdm_links[stream].channels = link_mask << 3; 344 mcpdm->dn_channels = link_mask << 3;
169 err = omap_mcpdm_playback_open(&mcpdm_links[stream]); 345 dma_data->packet_size =
346 (MCPDM_DN_THRES_MAX - mcpdm->dn_threshold) * channels;
170 } else { 347 } else {
171 mcpdm_links[stream].channels = link_mask << 0; 348 mcpdm->up_channels = link_mask << 0;
172 err = omap_mcpdm_capture_open(&mcpdm_links[stream]); 349 dma_data->packet_size = mcpdm->up_threshold * channels;
173 } 350 }
174 351
175 return err; 352 snd_soc_dai_set_dma_data(dai, substream, dma_data);
353
354 return 0;
176} 355}
177 356
178static int omap_mcpdm_dai_hw_free(struct snd_pcm_substream *substream, 357static int omap_mcpdm_prepare(struct snd_pcm_substream *substream,
179 struct snd_soc_dai *dai) 358 struct snd_soc_dai *dai)
180{ 359{
181 struct omap_mcpdm_data *mcpdm_priv = snd_soc_dai_get_drvdata(dai); 360 struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
182 struct omap_mcpdm_link *mcpdm_links = mcpdm_priv->links;
183 int stream = substream->stream;
184 int err;
185 361
186 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 362 if (!omap_mcpdm_active(mcpdm)) {
187 err = omap_mcpdm_playback_close(&mcpdm_links[stream]); 363 omap_mcpdm_start(mcpdm);
188 else 364 omap_mcpdm_reg_dump(mcpdm);
189 err = omap_mcpdm_capture_close(&mcpdm_links[stream]); 365 }
190 366
191 return err; 367 return 0;
192} 368}
193 369
194static struct snd_soc_dai_ops omap_mcpdm_dai_ops = { 370static struct snd_soc_dai_ops omap_mcpdm_dai_ops = {
195 .startup = omap_mcpdm_dai_startup, 371 .startup = omap_mcpdm_dai_startup,
196 .shutdown = omap_mcpdm_dai_shutdown, 372 .shutdown = omap_mcpdm_dai_shutdown,
197 .trigger = omap_mcpdm_dai_trigger,
198 .hw_params = omap_mcpdm_dai_hw_params, 373 .hw_params = omap_mcpdm_dai_hw_params,
199 .hw_free = omap_mcpdm_dai_hw_free, 374 .prepare = omap_mcpdm_prepare,
200}; 375};
201 376
202#define OMAP_MCPDM_RATES (SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) 377static int omap_mcpdm_probe(struct snd_soc_dai *dai)
203#define OMAP_MCPDM_FORMATS (SNDRV_PCM_FMTBIT_S32_LE) 378{
379 struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
380 int ret;
204 381
205static int omap_mcpdm_dai_probe(struct snd_soc_dai *dai) 382 pm_runtime_enable(mcpdm->dev);
383
384 /* Disable lines while request is ongoing */
385 pm_runtime_get_sync(mcpdm->dev);
386 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, 0x00);
387
388 ret = request_irq(mcpdm->irq, omap_mcpdm_irq_handler,
389 0, "McPDM", (void *)mcpdm);
390
391 pm_runtime_put_sync(mcpdm->dev);
392
393 if (ret) {
394 dev_err(mcpdm->dev, "Request for IRQ failed\n");
395 pm_runtime_disable(mcpdm->dev);
396 }
397
398 /* Configure McPDM threshold values */
399 mcpdm->dn_threshold = 2;
400 mcpdm->up_threshold = MCPDM_UP_THRES_MAX - 3;
401 return ret;
402}
403
404static int omap_mcpdm_remove(struct snd_soc_dai *dai)
206{ 405{
207 snd_soc_dai_set_drvdata(dai, &mcpdm_data); 406 struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
407
408 free_irq(mcpdm->irq, (void *)mcpdm);
409 pm_runtime_disable(mcpdm->dev);
410
208 return 0; 411 return 0;
209} 412}
210 413
414#define OMAP_MCPDM_RATES (SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
415#define OMAP_MCPDM_FORMATS SNDRV_PCM_FMTBIT_S32_LE
416
211static struct snd_soc_dai_driver omap_mcpdm_dai = { 417static struct snd_soc_dai_driver omap_mcpdm_dai = {
212 .probe = omap_mcpdm_dai_probe, 418 .probe = omap_mcpdm_probe,
419 .remove = omap_mcpdm_remove,
420 .probe_order = SND_SOC_COMP_ORDER_LATE,
421 .remove_order = SND_SOC_COMP_ORDER_EARLY,
213 .playback = { 422 .playback = {
214 .channels_min = 1, 423 .channels_min = 1,
215 .channels_max = 4, 424 .channels_max = 5,
216 .rates = OMAP_MCPDM_RATES, 425 .rates = OMAP_MCPDM_RATES,
217 .formats = OMAP_MCPDM_FORMATS, 426 .formats = OMAP_MCPDM_FORMATS,
218 }, 427 },
219 .capture = { 428 .capture = {
220 .channels_min = 1, 429 .channels_min = 1,
221 .channels_max = 2, 430 .channels_max = 3,
222 .rates = OMAP_MCPDM_RATES, 431 .rates = OMAP_MCPDM_RATES,
223 .formats = OMAP_MCPDM_FORMATS, 432 .formats = OMAP_MCPDM_FORMATS,
224 }, 433 },
225 .ops = &omap_mcpdm_dai_ops, 434 .ops = &omap_mcpdm_dai_ops,
226}; 435};
227 436
437void omap_mcpdm_configure_dn_offsets(struct snd_soc_pcm_runtime *rtd,
438 u8 rx1, u8 rx2)
439{
440 struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(rtd->cpu_dai);
441
442 mcpdm->dn_rx_offset = MCPDM_DNOFST_RX1(rx1) | MCPDM_DNOFST_RX2(rx2);
443}
444EXPORT_SYMBOL_GPL(omap_mcpdm_configure_dn_offsets);
445
228static __devinit int asoc_mcpdm_probe(struct platform_device *pdev) 446static __devinit int asoc_mcpdm_probe(struct platform_device *pdev)
229{ 447{
230 int ret; 448 struct omap_mcpdm *mcpdm;
449 struct resource *res;
450 int ret = 0;
451
452 mcpdm = kzalloc(sizeof(struct omap_mcpdm), GFP_KERNEL);
453 if (!mcpdm)
454 return -ENOMEM;
455
456 platform_set_drvdata(pdev, mcpdm);
457
458 mutex_init(&mcpdm->mutex);
459
460 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
461 if (res == NULL) {
462 dev_err(&pdev->dev, "no resource\n");
463 goto err_res;
464 }
465
466 if (!request_mem_region(res->start, resource_size(res), "McPDM")) {
467 ret = -EBUSY;
468 goto err_res;
469 }
470
471 mcpdm->io_base = ioremap(res->start, resource_size(res));
472 if (!mcpdm->io_base) {
473 ret = -ENOMEM;
474 goto err_iomap;
475 }
476
477 mcpdm->irq = platform_get_irq(pdev, 0);
478 if (mcpdm->irq < 0) {
479 ret = mcpdm->irq;
480 goto err_irq;
481 }
482
483 mcpdm->dev = &pdev->dev;
231 484
232 ret = omap_mcpdm_probe(pdev);
233 if (ret < 0)
234 return ret;
235 ret = snd_soc_register_dai(&pdev->dev, &omap_mcpdm_dai); 485 ret = snd_soc_register_dai(&pdev->dev, &omap_mcpdm_dai);
236 if (ret < 0) 486 if (!ret)
237 omap_mcpdm_remove(pdev); 487 return 0;
488
489err_irq:
490 iounmap(mcpdm->io_base);
491err_iomap:
492 release_mem_region(res->start, resource_size(res));
493err_res:
494 kfree(mcpdm);
238 return ret; 495 return ret;
239} 496}
240 497
241static int __devexit asoc_mcpdm_remove(struct platform_device *pdev) 498static int __devexit asoc_mcpdm_remove(struct platform_device *pdev)
242{ 499{
500 struct omap_mcpdm *mcpdm = platform_get_drvdata(pdev);
501 struct resource *res;
502
243 snd_soc_unregister_dai(&pdev->dev); 503 snd_soc_unregister_dai(&pdev->dev);
244 omap_mcpdm_remove(pdev); 504
505 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
506 iounmap(mcpdm->io_base);
507 release_mem_region(res->start, resource_size(res));
508
509 kfree(mcpdm);
245 return 0; 510 return 0;
246} 511}
247 512
248static struct platform_driver asoc_mcpdm_driver = { 513static struct platform_driver asoc_mcpdm_driver = {
249 .driver = { 514 .driver = {
250 .name = "omap-mcpdm-dai", 515 .name = "omap-mcpdm",
251 .owner = THIS_MODULE, 516 .owner = THIS_MODULE,
252 }, 517 },
253 518
254 .probe = asoc_mcpdm_probe, 519 .probe = asoc_mcpdm_probe,
255 .remove = __devexit_p(asoc_mcpdm_remove), 520 .remove = __devexit_p(asoc_mcpdm_remove),
256}; 521};
257 522
258static int __init snd_omap_mcpdm_init(void) 523static int __init snd_omap_mcpdm_init(void)
@@ -267,6 +532,6 @@ static void __exit snd_omap_mcpdm_exit(void)
267} 532}
268module_exit(snd_omap_mcpdm_exit); 533module_exit(snd_omap_mcpdm_exit);
269 534
270MODULE_AUTHOR("Misael Lopez Cruz <x0052729@ti.com>"); 535MODULE_AUTHOR("Misael Lopez Cruz <misael.lopez@ti.com>");
271MODULE_DESCRIPTION("OMAP PDM SoC Interface"); 536MODULE_DESCRIPTION("OMAP PDM SoC Interface");
272MODULE_LICENSE("GPL"); 537MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/omap-mcpdm.h b/sound/soc/omap/omap-mcpdm.h
new file mode 100644
index 00000000000..de8cf26595b
--- /dev/null
+++ b/sound/soc/omap/omap-mcpdm.h
@@ -0,0 +1,107 @@
1/*
2 * omap-mcpdm.h
3 *
4 * Copyright (C) 2009 - 2011 Texas Instruments
5 *
6 * Contact: Misael Lopez Cruz <misael.lopez@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
27#define MCPDM_REG_REVISION 0x00
28#define MCPDM_REG_SYSCONFIG 0x10
29#define MCPDM_REG_IRQSTATUS_RAW 0x24
30#define MCPDM_REG_IRQSTATUS 0x28
31#define MCPDM_REG_IRQENABLE_SET 0x2C
32#define MCPDM_REG_IRQENABLE_CLR 0x30
33#define MCPDM_REG_IRQWAKE_EN 0x34
34#define MCPDM_REG_DMAENABLE_SET 0x38
35#define MCPDM_REG_DMAENABLE_CLR 0x3C
36#define MCPDM_REG_DMAWAKEEN 0x40
37#define MCPDM_REG_CTRL 0x44
38#define MCPDM_REG_DN_DATA 0x48
39#define MCPDM_REG_UP_DATA 0x4C
40#define MCPDM_REG_FIFO_CTRL_DN 0x50
41#define MCPDM_REG_FIFO_CTRL_UP 0x54
42#define MCPDM_REG_DN_OFFSET 0x58
43
44/*
45 * MCPDM_IRQ bit fields
46 * IRQSTATUS_RAW, IRQSTATUS, IRQENABLE_SET, IRQENABLE_CLR
47 */
48
49#define MCPDM_DN_IRQ (1 << 0)
50#define MCPDM_DN_IRQ_EMPTY (1 << 1)
51#define MCPDM_DN_IRQ_ALMST_EMPTY (1 << 2)
52#define MCPDM_DN_IRQ_FULL (1 << 3)
53
54#define MCPDM_UP_IRQ (1 << 8)
55#define MCPDM_UP_IRQ_EMPTY (1 << 9)
56#define MCPDM_UP_IRQ_ALMST_FULL (1 << 10)
57#define MCPDM_UP_IRQ_FULL (1 << 11)
58
59#define MCPDM_DOWNLINK_IRQ_MASK 0x00F
60#define MCPDM_UPLINK_IRQ_MASK 0xF00
61
62/*
63 * MCPDM_DMAENABLE bit fields
64 */
65
66#define MCPDM_DMA_DN_ENABLE (1 << 0)
67#define MCPDM_DMA_UP_ENABLE (1 << 1)
68
69/*
70 * MCPDM_CTRL bit fields
71 */
72
73#define MCPDM_PDM_UPLINK_EN(x) (1 << (x - 1)) /* ch1 is at bit 0 */
74#define MCPDM_PDM_DOWNLINK_EN(x) (1 << (x + 2)) /* ch1 is at bit 3 */
75#define MCPDM_PDMOUTFORMAT (1 << 8)
76#define MCPDM_CMD_INT (1 << 9)
77#define MCPDM_STATUS_INT (1 << 10)
78#define MCPDM_SW_UP_RST (1 << 11)
79#define MCPDM_SW_DN_RST (1 << 12)
80#define MCPDM_WD_EN (1 << 14)
81#define MCPDM_PDM_UP_MASK 0x7
82#define MCPDM_PDM_DN_MASK (0x1f << 3)
83
84
85#define MCPDM_PDMOUTFORMAT_LJUST (0 << 8)
86#define MCPDM_PDMOUTFORMAT_RJUST (1 << 8)
87
88/*
89 * MCPDM_FIFO_CTRL bit fields
90 */
91
92#define MCPDM_UP_THRES_MAX 0xF
93#define MCPDM_DN_THRES_MAX 0xF
94
95/*
96 * MCPDM_DN_OFFSET bit fields
97 */
98
99#define MCPDM_DN_OFST_RX1_EN (1 << 0)
100#define MCPDM_DNOFST_RX1(x) ((x & 0x1f) << 1)
101#define MCPDM_DN_OFST_RX2_EN (1 << 8)
102#define MCPDM_DNOFST_RX2(x) ((x & 0x1f) << 9)
103
104void omap_mcpdm_configure_dn_offsets(struct snd_soc_pcm_runtime *rtd,
105 u8 rx1, u8 rx2);
106
107#endif /* End of __OMAP_MCPDM_H__ */
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c
index 9b5c88ac35b..5e37ec915de 100644
--- a/sound/soc/omap/omap-pcm.c
+++ b/sound/soc/omap/omap-pcm.c
@@ -198,6 +198,14 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream)
198 OMAP_DMA_LAST_IRQ | OMAP_DMA_BLOCK_IRQ); 198 OMAP_DMA_LAST_IRQ | OMAP_DMA_BLOCK_IRQ);
199 else if (!substream->runtime->no_period_wakeup) 199 else if (!substream->runtime->no_period_wakeup)
200 omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ); 200 omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ);
201 else {
202 /*
203 * No period wakeup:
204 * we need to disable BLOCK_IRQ, which is enabled by the omap
205 * dma core at request dma time.
206 */
207 omap_disable_dma_irq(prtd->dma_ch, OMAP_DMA_BLOCK_IRQ);
208 }
201 209
202 if (!(cpu_class_is_omap1())) { 210 if (!(cpu_class_is_omap1())) {
203 omap_set_dma_src_burst_mode(prtd->dma_ch, 211 omap_set_dma_src_burst_mode(prtd->dma_ch,
diff --git a/sound/soc/omap/omap3evm.c b/sound/soc/omap/omap3evm.c
index 0daa0446983..bf9ae2a6f90 100644
--- a/sound/soc/omap/omap3evm.c
+++ b/sound/soc/omap/omap3evm.c
@@ -36,29 +36,8 @@ static int omap3evm_hw_params(struct snd_pcm_substream *substream,
36{ 36{
37 struct snd_soc_pcm_runtime *rtd = substream->private_data; 37 struct snd_soc_pcm_runtime *rtd = substream->private_data;
38 struct snd_soc_dai *codec_dai = rtd->codec_dai; 38 struct snd_soc_dai *codec_dai = rtd->codec_dai;
39 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
40 int ret; 39 int ret;
41 40
42 /* Set codec DAI configuration */
43 ret = snd_soc_dai_set_fmt(codec_dai,
44 SND_SOC_DAIFMT_I2S |
45 SND_SOC_DAIFMT_NB_NF |
46 SND_SOC_DAIFMT_CBM_CFM);
47 if (ret < 0) {
48 printk(KERN_ERR "Can't set codec DAI configuration\n");
49 return ret;
50 }
51
52 /* Set cpu DAI configuration */
53 ret = snd_soc_dai_set_fmt(cpu_dai,
54 SND_SOC_DAIFMT_I2S |
55 SND_SOC_DAIFMT_NB_NF |
56 SND_SOC_DAIFMT_CBM_CFM);
57 if (ret < 0) {
58 printk(KERN_ERR "Can't set cpu DAI configuration\n");
59 return ret;
60 }
61
62 /* Set the codec system clock for DAC and ADC */ 41 /* Set the codec system clock for DAC and ADC */
63 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000, 42 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
64 SND_SOC_CLOCK_IN); 43 SND_SOC_CLOCK_IN);
@@ -82,6 +61,8 @@ static struct snd_soc_dai_link omap3evm_dai = {
82 .codec_dai_name = "twl4030-hifi", 61 .codec_dai_name = "twl4030-hifi",
83 .platform_name = "omap-pcm-audio", 62 .platform_name = "omap-pcm-audio",
84 .codec_name = "twl4030-codec", 63 .codec_name = "twl4030-codec",
64 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
65 SND_SOC_DAIFMT_CBM_CFM,
85 .ops = &omap3evm_ops, 66 .ops = &omap3evm_ops,
86}; 67};
87 68
diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c
index 8047c521e31..30a75b406ae 100644
--- a/sound/soc/omap/omap3pandora.c
+++ b/sound/soc/omap/omap3pandora.c
@@ -48,24 +48,8 @@ static int omap3pandora_hw_params(struct snd_pcm_substream *substream,
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->codec_dai; 49 struct snd_soc_dai *codec_dai = rtd->codec_dai;
50 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 50 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
51 int fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
52 SND_SOC_DAIFMT_CBS_CFS;
53 int ret; 51 int ret;
54 52
55 /* Set codec DAI configuration */
56 ret = snd_soc_dai_set_fmt(codec_dai, fmt);
57 if (ret < 0) {
58 pr_err(PREFIX "can't set codec DAI configuration\n");
59 return ret;
60 }
61
62 /* Set cpu DAI configuration */
63 ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
64 if (ret < 0) {
65 pr_err(PREFIX "can't set cpu DAI configuration\n");
66 return ret;
67 }
68
69 /* Set the codec system clock for DAC and ADC */ 53 /* Set the codec system clock for DAC and ADC */
70 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000, 54 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
71 SND_SOC_CLOCK_IN); 55 SND_SOC_CLOCK_IN);
@@ -189,10 +173,8 @@ static int omap3pandora_out_init(struct snd_soc_pcm_runtime *rtd)
189 if (ret < 0) 173 if (ret < 0)
190 return ret; 174 return ret;
191 175
192 snd_soc_dapm_add_routes(dapm, omap3pandora_out_map, 176 return snd_soc_dapm_add_routes(dapm, omap3pandora_out_map,
193 ARRAY_SIZE(omap3pandora_out_map)); 177 ARRAY_SIZE(omap3pandora_out_map));
194
195 return snd_soc_dapm_sync(dapm);
196} 178}
197 179
198static int omap3pandora_in_init(struct snd_soc_pcm_runtime *rtd) 180static int omap3pandora_in_init(struct snd_soc_pcm_runtime *rtd)
@@ -212,10 +194,8 @@ static int omap3pandora_in_init(struct snd_soc_pcm_runtime *rtd)
212 if (ret < 0) 194 if (ret < 0)
213 return ret; 195 return ret;
214 196
215 snd_soc_dapm_add_routes(dapm, omap3pandora_in_map, 197 return snd_soc_dapm_add_routes(dapm, omap3pandora_in_map,
216 ARRAY_SIZE(omap3pandora_in_map)); 198 ARRAY_SIZE(omap3pandora_in_map));
217
218 return snd_soc_dapm_sync(dapm);
219} 199}
220 200
221static struct snd_soc_ops omap3pandora_ops = { 201static struct snd_soc_ops omap3pandora_ops = {
@@ -231,6 +211,8 @@ static struct snd_soc_dai_link omap3pandora_dai[] = {
231 .codec_dai_name = "twl4030-hifi", 211 .codec_dai_name = "twl4030-hifi",
232 .platform_name = "omap-pcm-audio", 212 .platform_name = "omap-pcm-audio",
233 .codec_name = "twl4030-codec", 213 .codec_name = "twl4030-codec",
214 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
215 SND_SOC_DAIFMT_CBS_CFS,
234 .ops = &omap3pandora_ops, 216 .ops = &omap3pandora_ops,
235 .init = omap3pandora_out_init, 217 .init = omap3pandora_out_init,
236 }, { 218 }, {
@@ -240,6 +222,8 @@ static struct snd_soc_dai_link omap3pandora_dai[] = {
240 .codec_dai_name = "twl4030-hifi", 222 .codec_dai_name = "twl4030-hifi",
241 .platform_name = "omap-pcm-audio", 223 .platform_name = "omap-pcm-audio",
242 .codec_name = "twl4030-codec", 224 .codec_name = "twl4030-codec",
225 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
226 SND_SOC_DAIFMT_CBS_CFS,
243 .ops = &omap3pandora_ops, 227 .ops = &omap3pandora_ops,
244 .init = omap3pandora_in_init, 228 .init = omap3pandora_in_init,
245 } 229 }
diff --git a/sound/soc/omap/osk5912.c b/sound/soc/omap/osk5912.c
index 7e75e775fb4..db91ccaf6c9 100644
--- a/sound/soc/omap/osk5912.c
+++ b/sound/soc/omap/osk5912.c
@@ -55,29 +55,8 @@ static int osk_hw_params(struct snd_pcm_substream *substream,
55{ 55{
56 struct snd_soc_pcm_runtime *rtd = substream->private_data; 56 struct snd_soc_pcm_runtime *rtd = substream->private_data;
57 struct snd_soc_dai *codec_dai = rtd->codec_dai; 57 struct snd_soc_dai *codec_dai = rtd->codec_dai;
58 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
59 int err; 58 int err;
60 59
61 /* Set codec DAI configuration */
62 err = snd_soc_dai_set_fmt(codec_dai,
63 SND_SOC_DAIFMT_DSP_B |
64 SND_SOC_DAIFMT_NB_NF |
65 SND_SOC_DAIFMT_CBM_CFM);
66 if (err < 0) {
67 printk(KERN_ERR "can't set codec DAI configuration\n");
68 return err;
69 }
70
71 /* Set cpu DAI configuration */
72 err = snd_soc_dai_set_fmt(cpu_dai,
73 SND_SOC_DAIFMT_DSP_B |
74 SND_SOC_DAIFMT_NB_NF |
75 SND_SOC_DAIFMT_CBM_CFM);
76 if (err < 0) {
77 printk(KERN_ERR "can't set cpu DAI configuration\n");
78 return err;
79 }
80
81 /* Set the codec system clock for DAC and ADC */ 60 /* Set the codec system clock for DAC and ADC */
82 err = 61 err =
83 snd_soc_dai_set_sysclk(codec_dai, 0, CODEC_CLOCK, SND_SOC_CLOCK_IN); 62 snd_soc_dai_set_sysclk(codec_dai, 0, CODEC_CLOCK, SND_SOC_CLOCK_IN);
@@ -112,27 +91,6 @@ static const struct snd_soc_dapm_route audio_map[] = {
112 {"MICIN", NULL, "Mic Jack"}, 91 {"MICIN", NULL, "Mic Jack"},
113}; 92};
114 93
115static int osk_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd)
116{
117 struct snd_soc_codec *codec = rtd->codec;
118 struct snd_soc_dapm_context *dapm = &codec->dapm;
119
120 /* Add osk5912 specific widgets */
121 snd_soc_dapm_new_controls(dapm, tlv320aic23_dapm_widgets,
122 ARRAY_SIZE(tlv320aic23_dapm_widgets));
123
124 /* Set up osk5912 specific audio path audio_map */
125 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
126
127 snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
128 snd_soc_dapm_enable_pin(dapm, "Line In");
129 snd_soc_dapm_enable_pin(dapm, "Mic Jack");
130
131 snd_soc_dapm_sync(dapm);
132
133 return 0;
134}
135
136/* Digital audio interface glue - connects codec <--> CPU */ 94/* Digital audio interface glue - connects codec <--> CPU */
137static struct snd_soc_dai_link osk_dai = { 95static struct snd_soc_dai_link osk_dai = {
138 .name = "TLV320AIC23", 96 .name = "TLV320AIC23",
@@ -141,7 +99,8 @@ static struct snd_soc_dai_link osk_dai = {
141 .codec_dai_name = "tlv320aic23-hifi", 99 .codec_dai_name = "tlv320aic23-hifi",
142 .platform_name = "omap-pcm-audio", 100 .platform_name = "omap-pcm-audio",
143 .codec_name = "tlv320aic23-codec", 101 .codec_name = "tlv320aic23-codec",
144 .init = osk_tlv320aic23_init, 102 .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF |
103 SND_SOC_DAIFMT_CBM_CFM,
145 .ops = &osk_ops, 104 .ops = &osk_ops,
146}; 105};
147 106
@@ -150,6 +109,11 @@ static struct snd_soc_card snd_soc_card_osk = {
150 .name = "OSK5912", 109 .name = "OSK5912",
151 .dai_link = &osk_dai, 110 .dai_link = &osk_dai,
152 .num_links = 1, 111 .num_links = 1,
112
113 .dapm_widgets = tlv320aic23_dapm_widgets,
114 .num_dapm_widgets = ARRAY_SIZE(tlv320aic23_dapm_widgets),
115 .dapm_routes = audio_map,
116 .num_dapm_routes = ARRAY_SIZE(audio_map),
153}; 117};
154 118
155static struct platform_device *osk_snd_device; 119static struct platform_device *osk_snd_device;
diff --git a/sound/soc/omap/overo.c b/sound/soc/omap/overo.c
index bbcf380bfb5..739efe9e327 100644
--- a/sound/soc/omap/overo.c
+++ b/sound/soc/omap/overo.c
@@ -38,29 +38,8 @@ static int overo_hw_params(struct snd_pcm_substream *substream,
38{ 38{
39 struct snd_soc_pcm_runtime *rtd = substream->private_data; 39 struct snd_soc_pcm_runtime *rtd = substream->private_data;
40 struct snd_soc_dai *codec_dai = rtd->codec_dai; 40 struct snd_soc_dai *codec_dai = rtd->codec_dai;
41 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
42 int ret; 41 int ret;
43 42
44 /* Set codec DAI configuration */
45 ret = snd_soc_dai_set_fmt(codec_dai,
46 SND_SOC_DAIFMT_I2S |
47 SND_SOC_DAIFMT_NB_NF |
48 SND_SOC_DAIFMT_CBM_CFM);
49 if (ret < 0) {
50 printk(KERN_ERR "can't set codec DAI configuration\n");
51 return ret;
52 }
53
54 /* Set cpu DAI configuration */
55 ret = snd_soc_dai_set_fmt(cpu_dai,
56 SND_SOC_DAIFMT_I2S |
57 SND_SOC_DAIFMT_NB_NF |
58 SND_SOC_DAIFMT_CBM_CFM);
59 if (ret < 0) {
60 printk(KERN_ERR "can't set cpu DAI configuration\n");
61 return ret;
62 }
63
64 /* Set the codec system clock for DAC and ADC */ 43 /* Set the codec system clock for DAC and ADC */
65 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000, 44 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
66 SND_SOC_CLOCK_IN); 45 SND_SOC_CLOCK_IN);
@@ -84,6 +63,8 @@ static struct snd_soc_dai_link overo_dai = {
84 .codec_dai_name = "twl4030-hifi", 63 .codec_dai_name = "twl4030-hifi",
85 .platform_name = "omap-pcm-audio", 64 .platform_name = "omap-pcm-audio",
86 .codec_name = "twl4030-codec", 65 .codec_name = "twl4030-codec",
66 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
67 SND_SOC_DAIFMT_CBM_CFM,
87 .ops = &overo_ops, 68 .ops = &overo_ops,
88}; 69};
89 70
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c
index 893300a53ba..a56842380c7 100644
--- a/sound/soc/omap/rx51.c
+++ b/sound/soc/omap/rx51.c
@@ -115,24 +115,6 @@ static int rx51_hw_params(struct snd_pcm_substream *substream,
115{ 115{
116 struct snd_soc_pcm_runtime *rtd = substream->private_data; 116 struct snd_soc_pcm_runtime *rtd = substream->private_data;
117 struct snd_soc_dai *codec_dai = rtd->codec_dai; 117 struct snd_soc_dai *codec_dai = rtd->codec_dai;
118 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
119 int err;
120
121 /* Set codec DAI configuration */
122 err = snd_soc_dai_set_fmt(codec_dai,
123 SND_SOC_DAIFMT_DSP_A |
124 SND_SOC_DAIFMT_IB_NF |
125 SND_SOC_DAIFMT_CBM_CFM);
126 if (err < 0)
127 return err;
128
129 /* Set cpu DAI configuration */
130 err = snd_soc_dai_set_fmt(cpu_dai,
131 SND_SOC_DAIFMT_DSP_A |
132 SND_SOC_DAIFMT_IB_NF |
133 SND_SOC_DAIFMT_CBM_CFM);
134 if (err < 0)
135 return err;
136 118
137 /* Set the codec system clock for DAC and ADC */ 119 /* Set the codec system clock for DAC and ADC */
138 return snd_soc_dai_set_sysclk(codec_dai, 0, 19200000, 120 return snd_soc_dai_set_sysclk(codec_dai, 0, 19200000,
@@ -335,8 +317,6 @@ static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd)
335 if (err < 0) 317 if (err < 0)
336 return err; 318 return err;
337 319
338 snd_soc_dapm_sync(dapm);
339
340 /* AV jack detection */ 320 /* AV jack detection */
341 err = snd_soc_jack_new(codec, "AV Jack", 321 err = snd_soc_jack_new(codec, "AV Jack",
342 SND_JACK_HEADSET | SND_JACK_VIDEOOUT, 322 SND_JACK_HEADSET | SND_JACK_VIDEOOUT,
@@ -377,6 +357,8 @@ static struct snd_soc_dai_link rx51_dai[] = {
377 .codec_dai_name = "tlv320aic3x-hifi", 357 .codec_dai_name = "tlv320aic3x-hifi",
378 .platform_name = "omap-pcm-audio", 358 .platform_name = "omap-pcm-audio",
379 .codec_name = "tlv320aic3x-codec.2-0018", 359 .codec_name = "tlv320aic3x-codec.2-0018",
360 .dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF |
361 SND_SOC_DAIFMT_CBM_CFM,
380 .init = rx51_aic34_init, 362 .init = rx51_aic34_init,
381 .ops = &rx51_ops, 363 .ops = &rx51_ops,
382 }, 364 },
diff --git a/sound/soc/omap/sdp3430.c b/sound/soc/omap/sdp3430.c
index 9f6a758029d..4f1969de91a 100644
--- a/sound/soc/omap/sdp3430.c
+++ b/sound/soc/omap/sdp3430.c
@@ -53,29 +53,8 @@ static int sdp3430_hw_params(struct snd_pcm_substream *substream,
53{ 53{
54 struct snd_soc_pcm_runtime *rtd = substream->private_data; 54 struct snd_soc_pcm_runtime *rtd = substream->private_data;
55 struct snd_soc_dai *codec_dai = rtd->codec_dai; 55 struct snd_soc_dai *codec_dai = rtd->codec_dai;
56 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
57 int ret; 56 int ret;
58 57
59 /* Set codec DAI configuration */
60 ret = snd_soc_dai_set_fmt(codec_dai,
61 SND_SOC_DAIFMT_I2S |
62 SND_SOC_DAIFMT_NB_NF |
63 SND_SOC_DAIFMT_CBM_CFM);
64 if (ret < 0) {
65 printk(KERN_ERR "can't set codec DAI configuration\n");
66 return ret;
67 }
68
69 /* Set cpu DAI configuration */
70 ret = snd_soc_dai_set_fmt(cpu_dai,
71 SND_SOC_DAIFMT_I2S |
72 SND_SOC_DAIFMT_NB_NF |
73 SND_SOC_DAIFMT_CBM_CFM);
74 if (ret < 0) {
75 printk(KERN_ERR "can't set cpu DAI configuration\n");
76 return ret;
77 }
78
79 /* Set the codec system clock for DAC and ADC */ 58 /* Set the codec system clock for DAC and ADC */
80 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000, 59 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
81 SND_SOC_CLOCK_IN); 60 SND_SOC_CLOCK_IN);
@@ -91,49 +70,6 @@ static struct snd_soc_ops sdp3430_ops = {
91 .hw_params = sdp3430_hw_params, 70 .hw_params = sdp3430_hw_params,
92}; 71};
93 72
94static int sdp3430_hw_voice_params(struct snd_pcm_substream *substream,
95 struct snd_pcm_hw_params *params)
96{
97 struct snd_soc_pcm_runtime *rtd = substream->private_data;
98 struct snd_soc_dai *codec_dai = rtd->codec_dai;
99 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
100 int ret;
101
102 /* Set codec DAI configuration */
103 ret = snd_soc_dai_set_fmt(codec_dai,
104 SND_SOC_DAIFMT_DSP_A |
105 SND_SOC_DAIFMT_IB_NF |
106 SND_SOC_DAIFMT_CBM_CFM);
107 if (ret) {
108 printk(KERN_ERR "can't set codec DAI configuration\n");
109 return ret;
110 }
111
112 /* Set cpu DAI configuration */
113 ret = snd_soc_dai_set_fmt(cpu_dai,
114 SND_SOC_DAIFMT_DSP_A |
115 SND_SOC_DAIFMT_IB_NF |
116 SND_SOC_DAIFMT_CBM_CFM);
117 if (ret < 0) {
118 printk(KERN_ERR "can't set cpu DAI configuration\n");
119 return ret;
120 }
121
122 /* Set the codec system clock for DAC and ADC */
123 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
124 SND_SOC_CLOCK_IN);
125 if (ret < 0) {
126 printk(KERN_ERR "can't set codec system clock\n");
127 return ret;
128 }
129
130 return 0;
131}
132
133static struct snd_soc_ops sdp3430_voice_ops = {
134 .hw_params = sdp3430_hw_voice_params,
135};
136
137/* Headset jack */ 73/* Headset jack */
138static struct snd_soc_jack hs_jack; 74static struct snd_soc_jack hs_jack;
139 75
@@ -193,15 +129,6 @@ static int sdp3430_twl4030_init(struct snd_soc_pcm_runtime *rtd)
193 struct snd_soc_dapm_context *dapm = &codec->dapm; 129 struct snd_soc_dapm_context *dapm = &codec->dapm;
194 int ret; 130 int ret;
195 131
196 /* Add SDP3430 specific widgets */
197 ret = snd_soc_dapm_new_controls(dapm, sdp3430_twl4030_dapm_widgets,
198 ARRAY_SIZE(sdp3430_twl4030_dapm_widgets));
199 if (ret)
200 return ret;
201
202 /* Set up SDP3430 specific audio path audio_map */
203 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
204
205 /* SDP3430 connected pins */ 132 /* SDP3430 connected pins */
206 snd_soc_dapm_enable_pin(dapm, "Ext Mic"); 133 snd_soc_dapm_enable_pin(dapm, "Ext Mic");
207 snd_soc_dapm_enable_pin(dapm, "Ext Spk"); 134 snd_soc_dapm_enable_pin(dapm, "Ext Spk");
@@ -223,10 +150,6 @@ static int sdp3430_twl4030_init(struct snd_soc_pcm_runtime *rtd)
223 snd_soc_dapm_nc_pin(dapm, "CARKITL"); 150 snd_soc_dapm_nc_pin(dapm, "CARKITL");
224 snd_soc_dapm_nc_pin(dapm, "CARKITR"); 151 snd_soc_dapm_nc_pin(dapm, "CARKITR");
225 152
226 ret = snd_soc_dapm_sync(dapm);
227 if (ret)
228 return ret;
229
230 /* Headset jack detection */ 153 /* Headset jack detection */
231 ret = snd_soc_jack_new(codec, "Headset Jack", 154 ret = snd_soc_jack_new(codec, "Headset Jack",
232 SND_JACK_HEADSET, &hs_jack); 155 SND_JACK_HEADSET, &hs_jack);
@@ -267,6 +190,8 @@ static struct snd_soc_dai_link sdp3430_dai[] = {
267 .codec_dai_name = "twl4030-hifi", 190 .codec_dai_name = "twl4030-hifi",
268 .platform_name = "omap-pcm-audio", 191 .platform_name = "omap-pcm-audio",
269 .codec_name = "twl4030-codec", 192 .codec_name = "twl4030-codec",
193 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
194 SND_SOC_DAIFMT_CBM_CFM,
270 .init = sdp3430_twl4030_init, 195 .init = sdp3430_twl4030_init,
271 .ops = &sdp3430_ops, 196 .ops = &sdp3430_ops,
272 }, 197 },
@@ -277,8 +202,10 @@ static struct snd_soc_dai_link sdp3430_dai[] = {
277 .codec_dai_name = "twl4030-voice", 202 .codec_dai_name = "twl4030-voice",
278 .platform_name = "omap-pcm-audio", 203 .platform_name = "omap-pcm-audio",
279 .codec_name = "twl4030-codec", 204 .codec_name = "twl4030-codec",
205 .dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF |
206 SND_SOC_DAIFMT_CBM_CFM,
280 .init = sdp3430_twl4030_voice_init, 207 .init = sdp3430_twl4030_voice_init,
281 .ops = &sdp3430_voice_ops, 208 .ops = &sdp3430_ops,
282 }, 209 },
283}; 210};
284 211
@@ -287,6 +214,11 @@ static struct snd_soc_card snd_soc_sdp3430 = {
287 .name = "SDP3430", 214 .name = "SDP3430",
288 .dai_link = sdp3430_dai, 215 .dai_link = sdp3430_dai,
289 .num_links = ARRAY_SIZE(sdp3430_dai), 216 .num_links = ARRAY_SIZE(sdp3430_dai),
217
218 .dapm_widgets = sdp3430_twl4030_dapm_widgets,
219 .num_dapm_widgets = ARRAY_SIZE(sdp3430_twl4030_dapm_widgets),
220 .dapm_routes = audio_map,
221 .num_dapm_routes = ARRAY_SIZE(audio_map),
290}; 222};
291 223
292static struct platform_device *sdp3430_snd_device; 224static struct platform_device *sdp3430_snd_device;
diff --git a/sound/soc/omap/sdp4430.c b/sound/soc/omap/sdp4430.c
index b80efb02bfc..cc3d792af5e 100644
--- a/sound/soc/omap/sdp4430.c
+++ b/sound/soc/omap/sdp4430.c
@@ -32,7 +32,7 @@
32#include <plat/hardware.h> 32#include <plat/hardware.h>
33#include <plat/mux.h> 33#include <plat/mux.h>
34 34
35#include "mcpdm.h" 35#include "omap-mcpdm.h"
36#include "omap-pcm.h" 36#include "omap-pcm.h"
37#include "../codecs/twl6040.h" 37#include "../codecs/twl6040.h"
38 38
@@ -88,7 +88,7 @@ static const struct snd_soc_dapm_widget sdp4430_twl6040_dapm_widgets[] = {
88 SND_SOC_DAPM_MIC("Headset Mic", NULL), 88 SND_SOC_DAPM_MIC("Headset Mic", NULL),
89 SND_SOC_DAPM_HP("Headset Stereophone", NULL), 89 SND_SOC_DAPM_HP("Headset Stereophone", NULL),
90 SND_SOC_DAPM_SPK("Earphone Spk", NULL), 90 SND_SOC_DAPM_SPK("Earphone Spk", NULL),
91 SND_SOC_DAPM_INPUT("Aux/FM Stereo In"), 91 SND_SOC_DAPM_INPUT("FM Stereo In"),
92}; 92};
93 93
94static const struct snd_soc_dapm_route audio_map[] = { 94static const struct snd_soc_dapm_route audio_map[] = {
@@ -113,36 +113,22 @@ static const struct snd_soc_dapm_route audio_map[] = {
113 {"Earphone Spk", NULL, "EP"}, 113 {"Earphone Spk", NULL, "EP"},
114 114
115 /* Aux/FM Stereo In: AFML, AFMR */ 115 /* Aux/FM Stereo In: AFML, AFMR */
116 {"AFML", NULL, "Aux/FM Stereo In"}, 116 {"AFML", NULL, "FM Stereo In"},
117 {"AFMR", NULL, "Aux/FM Stereo In"}, 117 {"AFMR", NULL, "FM Stereo In"},
118}; 118};
119 119
120static int sdp4430_twl6040_init(struct snd_soc_pcm_runtime *rtd) 120static int sdp4430_twl6040_init(struct snd_soc_pcm_runtime *rtd)
121{ 121{
122 struct snd_soc_codec *codec = rtd->codec; 122 struct snd_soc_codec *codec = rtd->codec;
123 struct snd_soc_dapm_context *dapm = &codec->dapm; 123 int ret, hs_trim;
124 int ret;
125
126 /* Add SDP4430 specific widgets */
127 ret = snd_soc_dapm_new_controls(dapm, sdp4430_twl6040_dapm_widgets,
128 ARRAY_SIZE(sdp4430_twl6040_dapm_widgets));
129 if (ret)
130 return ret;
131
132 /* Set up SDP4430 specific audio path audio_map */
133 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
134 124
135 /* SDP4430 connected pins */ 125 /*
136 snd_soc_dapm_enable_pin(dapm, "Ext Mic"); 126 * Configure McPDM offset cancellation based on the HSOTRIM value from
137 snd_soc_dapm_enable_pin(dapm, "Ext Spk"); 127 * twl6040.
138 snd_soc_dapm_enable_pin(dapm, "AFML"); 128 */
139 snd_soc_dapm_enable_pin(dapm, "AFMR"); 129 hs_trim = twl6040_get_trim_value(codec, TWL6040_TRIM_HSOTRIM);
140 snd_soc_dapm_enable_pin(dapm, "Headset Mic"); 130 omap_mcpdm_configure_dn_offsets(rtd, TWL6040_HSF_TRIM_LEFT(hs_trim),
141 snd_soc_dapm_enable_pin(dapm, "Headset Stereophone"); 131 TWL6040_HSF_TRIM_RIGHT(hs_trim));
142
143 ret = snd_soc_dapm_sync(dapm);
144 if (ret)
145 return ret;
146 132
147 /* Headset jack detection */ 133 /* Headset jack detection */
148 ret = snd_soc_jack_new(codec, "Headset Jack", 134 ret = snd_soc_jack_new(codec, "Headset Jack",
@@ -165,8 +151,8 @@ static int sdp4430_twl6040_init(struct snd_soc_pcm_runtime *rtd)
165static struct snd_soc_dai_link sdp4430_dai = { 151static struct snd_soc_dai_link sdp4430_dai = {
166 .name = "TWL6040", 152 .name = "TWL6040",
167 .stream_name = "TWL6040", 153 .stream_name = "TWL6040",
168 .cpu_dai_name ="omap-mcpdm-dai", 154 .cpu_dai_name = "omap-mcpdm",
169 .codec_dai_name = "twl6040-hifi", 155 .codec_dai_name = "twl6040-legacy",
170 .platform_name = "omap-pcm-audio", 156 .platform_name = "omap-pcm-audio",
171 .codec_name = "twl6040-codec", 157 .codec_name = "twl6040-codec",
172 .init = sdp4430_twl6040_init, 158 .init = sdp4430_twl6040_init,
@@ -178,6 +164,11 @@ static struct snd_soc_card snd_soc_sdp4430 = {
178 .name = "SDP4430", 164 .name = "SDP4430",
179 .dai_link = &sdp4430_dai, 165 .dai_link = &sdp4430_dai,
180 .num_links = 1, 166 .num_links = 1,
167
168 .dapm_widgets = sdp4430_twl6040_dapm_widgets,
169 .num_dapm_widgets = ARRAY_SIZE(sdp4430_twl6040_dapm_widgets),
170 .dapm_routes = audio_map,
171 .num_dapm_routes = ARRAY_SIZE(audio_map),
181}; 172};
182 173
183static struct platform_device *sdp4430_snd_device; 174static struct platform_device *sdp4430_snd_device;
diff --git a/sound/soc/omap/zoom2.c b/sound/soc/omap/zoom2.c
index 9a2666ffc16..7cf35c82368 100644
--- a/sound/soc/omap/zoom2.c
+++ b/sound/soc/omap/zoom2.c
@@ -44,29 +44,8 @@ static int zoom2_hw_params(struct snd_pcm_substream *substream,
44{ 44{
45 struct snd_soc_pcm_runtime *rtd = substream->private_data; 45 struct snd_soc_pcm_runtime *rtd = substream->private_data;
46 struct snd_soc_dai *codec_dai = rtd->codec_dai; 46 struct snd_soc_dai *codec_dai = rtd->codec_dai;
47 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
48 int ret; 47 int ret;
49 48
50 /* Set codec DAI configuration */
51 ret = snd_soc_dai_set_fmt(codec_dai,
52 SND_SOC_DAIFMT_I2S |
53 SND_SOC_DAIFMT_NB_NF |
54 SND_SOC_DAIFMT_CBM_CFM);
55 if (ret < 0) {
56 printk(KERN_ERR "can't set codec DAI configuration\n");
57 return ret;
58 }
59
60 /* Set cpu DAI configuration */
61 ret = snd_soc_dai_set_fmt(cpu_dai,
62 SND_SOC_DAIFMT_I2S |
63 SND_SOC_DAIFMT_NB_NF |
64 SND_SOC_DAIFMT_CBM_CFM);
65 if (ret < 0) {
66 printk(KERN_ERR "can't set cpu DAI configuration\n");
67 return ret;
68 }
69
70 /* Set the codec system clock for DAC and ADC */ 49 /* Set the codec system clock for DAC and ADC */
71 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000, 50 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
72 SND_SOC_CLOCK_IN); 51 SND_SOC_CLOCK_IN);
@@ -82,49 +61,6 @@ static struct snd_soc_ops zoom2_ops = {
82 .hw_params = zoom2_hw_params, 61 .hw_params = zoom2_hw_params,
83}; 62};
84 63
85static int zoom2_hw_voice_params(struct snd_pcm_substream *substream,
86 struct snd_pcm_hw_params *params)
87{
88 struct snd_soc_pcm_runtime *rtd = substream->private_data;
89 struct snd_soc_dai *codec_dai = rtd->codec_dai;
90 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
91 int ret;
92
93 /* Set codec DAI configuration */
94 ret = snd_soc_dai_set_fmt(codec_dai,
95 SND_SOC_DAIFMT_DSP_A |
96 SND_SOC_DAIFMT_IB_NF |
97 SND_SOC_DAIFMT_CBM_CFM);
98 if (ret) {
99 printk(KERN_ERR "can't set codec DAI configuration\n");
100 return ret;
101 }
102
103 /* Set cpu DAI configuration */
104 ret = snd_soc_dai_set_fmt(cpu_dai,
105 SND_SOC_DAIFMT_DSP_A |
106 SND_SOC_DAIFMT_IB_NF |
107 SND_SOC_DAIFMT_CBM_CFM);
108 if (ret < 0) {
109 printk(KERN_ERR "can't set cpu DAI configuration\n");
110 return ret;
111 }
112
113 /* Set the codec system clock for DAC and ADC */
114 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
115 SND_SOC_CLOCK_IN);
116 if (ret < 0) {
117 printk(KERN_ERR "can't set codec system clock\n");
118 return ret;
119 }
120
121 return 0;
122}
123
124static struct snd_soc_ops zoom2_voice_ops = {
125 .hw_params = zoom2_hw_voice_params,
126};
127
128/* Zoom2 machine DAPM */ 64/* Zoom2 machine DAPM */
129static const struct snd_soc_dapm_widget zoom2_twl4030_dapm_widgets[] = { 65static const struct snd_soc_dapm_widget zoom2_twl4030_dapm_widgets[] = {
130 SND_SOC_DAPM_MIC("Ext Mic", NULL), 66 SND_SOC_DAPM_MIC("Ext Mic", NULL),
@@ -162,23 +98,6 @@ static int zoom2_twl4030_init(struct snd_soc_pcm_runtime *rtd)
162{ 98{
163 struct snd_soc_codec *codec = rtd->codec; 99 struct snd_soc_codec *codec = rtd->codec;
164 struct snd_soc_dapm_context *dapm = &codec->dapm; 100 struct snd_soc_dapm_context *dapm = &codec->dapm;
165 int ret;
166
167 /* Add Zoom2 specific widgets */
168 ret = snd_soc_dapm_new_controls(dapm, zoom2_twl4030_dapm_widgets,
169 ARRAY_SIZE(zoom2_twl4030_dapm_widgets));
170 if (ret)
171 return ret;
172
173 /* Set up Zoom2 specific audio path audio_map */
174 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
175
176 /* Zoom2 connected pins */
177 snd_soc_dapm_enable_pin(dapm, "Ext Mic");
178 snd_soc_dapm_enable_pin(dapm, "Ext Spk");
179 snd_soc_dapm_enable_pin(dapm, "Headset Mic");
180 snd_soc_dapm_enable_pin(dapm, "Headset Stereophone");
181 snd_soc_dapm_enable_pin(dapm, "Aux In");
182 101
183 /* TWL4030 not connected pins */ 102 /* TWL4030 not connected pins */
184 snd_soc_dapm_nc_pin(dapm, "CARKITMIC"); 103 snd_soc_dapm_nc_pin(dapm, "CARKITMIC");
@@ -190,9 +109,7 @@ static int zoom2_twl4030_init(struct snd_soc_pcm_runtime *rtd)
190 snd_soc_dapm_nc_pin(dapm, "CARKITL"); 109 snd_soc_dapm_nc_pin(dapm, "CARKITL");
191 snd_soc_dapm_nc_pin(dapm, "CARKITR"); 110 snd_soc_dapm_nc_pin(dapm, "CARKITR");
192 111
193 ret = snd_soc_dapm_sync(dapm); 112 return 0;
194
195 return ret;
196} 113}
197 114
198static int zoom2_twl4030_voice_init(struct snd_soc_pcm_runtime *rtd) 115static int zoom2_twl4030_voice_init(struct snd_soc_pcm_runtime *rtd)
@@ -217,6 +134,8 @@ static struct snd_soc_dai_link zoom2_dai[] = {
217 .codec_dai_name = "twl4030-hifi", 134 .codec_dai_name = "twl4030-hifi",
218 .platform_name = "omap-pcm-audio", 135 .platform_name = "omap-pcm-audio",
219 .codec_name = "twl4030-codec", 136 .codec_name = "twl4030-codec",
137 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
138 SND_SOC_DAIFMT_CBM_CFM,
220 .init = zoom2_twl4030_init, 139 .init = zoom2_twl4030_init,
221 .ops = &zoom2_ops, 140 .ops = &zoom2_ops,
222 }, 141 },
@@ -227,8 +146,10 @@ static struct snd_soc_dai_link zoom2_dai[] = {
227 .codec_dai_name = "twl4030-voice", 146 .codec_dai_name = "twl4030-voice",
228 .platform_name = "omap-pcm-audio", 147 .platform_name = "omap-pcm-audio",
229 .codec_name = "twl4030-codec", 148 .codec_name = "twl4030-codec",
149 .dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF |
150 SND_SOC_DAIFMT_CBM_CFM,
230 .init = zoom2_twl4030_voice_init, 151 .init = zoom2_twl4030_voice_init,
231 .ops = &zoom2_voice_ops, 152 .ops = &zoom2_ops,
232 }, 153 },
233}; 154};
234 155
@@ -237,6 +158,11 @@ static struct snd_soc_card snd_soc_zoom2 = {
237 .name = "Zoom2", 158 .name = "Zoom2",
238 .dai_link = zoom2_dai, 159 .dai_link = zoom2_dai,
239 .num_links = ARRAY_SIZE(zoom2_dai), 160 .num_links = ARRAY_SIZE(zoom2_dai),
161
162 .dapm_widgets = zoom2_twl4030_dapm_widgets,
163 .num_dapm_widgets = ARRAY_SIZE(zoom2_twl4030_dapm_widgets),
164 .dapm_routes = audio_map,
165 .num_dapm_routes = ARRAY_SIZE(audio_map),
240}; 166};
241 167
242static struct platform_device *zoom2_snd_device; 168static struct platform_device *zoom2_snd_device;
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index 33ebc46b45b..ffd2242e305 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -121,6 +121,7 @@ config SND_PXA2XX_SOC_PALM27X
121config SND_SOC_SAARB 121config SND_SOC_SAARB
122 tristate "SoC Audio support for Marvell Saarb" 122 tristate "SoC Audio support for Marvell Saarb"
123 depends on SND_PXA2XX_SOC && MACH_SAARB 123 depends on SND_PXA2XX_SOC && MACH_SAARB
124 select MFD_88PM860X
124 select SND_PXA_SOC_SSP 125 select SND_PXA_SOC_SSP
125 select SND_SOC_88PM860X 126 select SND_SOC_88PM860X
126 help 127 help
@@ -130,6 +131,7 @@ config SND_SOC_SAARB
130config SND_SOC_TAVOREVB3 131config SND_SOC_TAVOREVB3
131 tristate "SoC Audio support for Marvell Tavor EVB3" 132 tristate "SoC Audio support for Marvell Tavor EVB3"
132 depends on SND_PXA2XX_SOC && MACH_TAVOREVB3 133 depends on SND_PXA2XX_SOC && MACH_TAVOREVB3
134 select MFD_88PM860X
133 select SND_PXA_SOC_SSP 135 select SND_PXA_SOC_SSP
134 select SND_SOC_88PM860X 136 select SND_SOC_88PM860X
135 help 137 help
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c
index 28757fb9df3..b0e2fb72091 100644
--- a/sound/soc/pxa/corgi.c
+++ b/sound/soc/pxa/corgi.c
@@ -299,7 +299,6 @@ static int corgi_wm8731_init(struct snd_soc_pcm_runtime *rtd)
299 /* Set up corgi specific audio path audio_map */ 299 /* Set up corgi specific audio path audio_map */
300 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); 300 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
301 301
302 snd_soc_dapm_sync(dapm);
303 return 0; 302 return 0;
304} 303}
305 304
diff --git a/sound/soc/pxa/e740_wm9705.c b/sound/soc/pxa/e740_wm9705.c
index dc65650a6fa..35ed7eb8cff 100644
--- a/sound/soc/pxa/e740_wm9705.c
+++ b/sound/soc/pxa/e740_wm9705.c
@@ -108,8 +108,6 @@ static int e740_ac97_init(struct snd_soc_pcm_runtime *rtd)
108 108
109 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); 109 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
110 110
111 snd_soc_dapm_sync(dapm);
112
113 return 0; 111 return 0;
114} 112}
115 113
diff --git a/sound/soc/pxa/e750_wm9705.c b/sound/soc/pxa/e750_wm9705.c
index 51897fcd911..ce5f056009a 100644
--- a/sound/soc/pxa/e750_wm9705.c
+++ b/sound/soc/pxa/e750_wm9705.c
@@ -90,8 +90,6 @@ static int e750_ac97_init(struct snd_soc_pcm_runtime *rtd)
90 90
91 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); 91 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
92 92
93 snd_soc_dapm_sync(dapm);
94
95 return 0; 93 return 0;
96} 94}
97 95
diff --git a/sound/soc/pxa/e800_wm9712.c b/sound/soc/pxa/e800_wm9712.c
index 053ed208e59..6a8f38b6c37 100644
--- a/sound/soc/pxa/e800_wm9712.c
+++ b/sound/soc/pxa/e800_wm9712.c
@@ -80,7 +80,6 @@ static int e800_ac97_init(struct snd_soc_pcm_runtime *rtd)
80 ARRAY_SIZE(e800_dapm_widgets)); 80 ARRAY_SIZE(e800_dapm_widgets));
81 81
82 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); 82 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
83 snd_soc_dapm_sync(dapm);
84 83
85 return 0; 84 return 0;
86} 85}
diff --git a/sound/soc/pxa/magician.c b/sound/soc/pxa/magician.c
index 67dcc36cd62..e79f516c400 100644
--- a/sound/soc/pxa/magician.c
+++ b/sound/soc/pxa/magician.c
@@ -92,11 +92,10 @@ static int magician_playback_hw_params(struct snd_pcm_substream *substream,
92 struct snd_soc_pcm_runtime *rtd = substream->private_data; 92 struct snd_soc_pcm_runtime *rtd = substream->private_data;
93 struct snd_soc_dai *codec_dai = rtd->codec_dai; 93 struct snd_soc_dai *codec_dai = rtd->codec_dai;
94 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 94 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
95 unsigned int acps, acds, width, rate; 95 unsigned int acps, acds, width;
96 unsigned int div4 = PXA_SSP_CLK_SCDB_4; 96 unsigned int div4 = PXA_SSP_CLK_SCDB_4;
97 int ret = 0; 97 int ret = 0;
98 98
99 rate = params_rate(params);
100 width = snd_pcm_format_physical_width(params_format(params)); 99 width = snd_pcm_format_physical_width(params_format(params));
101 100
102 /* 101 /*
@@ -424,7 +423,6 @@ static int magician_uda1380_init(struct snd_soc_pcm_runtime *rtd)
424 /* Set up magician specific audio path interconnects */ 423 /* Set up magician specific audio path interconnects */
425 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); 424 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
426 425
427 snd_soc_dapm_sync(dapm);
428 return 0; 426 return 0;
429} 427}
430 428
diff --git a/sound/soc/pxa/mioa701_wm9713.c b/sound/soc/pxa/mioa701_wm9713.c
index 38ca6759907..0b8d1ee738a 100644
--- a/sound/soc/pxa/mioa701_wm9713.c
+++ b/sound/soc/pxa/mioa701_wm9713.c
@@ -151,7 +151,6 @@ static int mioa701_wm9713_init(struct snd_soc_pcm_runtime *rtd)
151 snd_soc_dapm_enable_pin(dapm, "Front Mic"); 151 snd_soc_dapm_enable_pin(dapm, "Front Mic");
152 snd_soc_dapm_enable_pin(dapm, "GSM Line In"); 152 snd_soc_dapm_enable_pin(dapm, "GSM Line In");
153 snd_soc_dapm_enable_pin(dapm, "GSM Line Out"); 153 snd_soc_dapm_enable_pin(dapm, "GSM Line Out");
154 snd_soc_dapm_sync(dapm);
155 154
156 return 0; 155 return 0;
157} 156}
diff --git a/sound/soc/pxa/palm27x.c b/sound/soc/pxa/palm27x.c
index 504e4004f00..7edc1fb71fa 100644
--- a/sound/soc/pxa/palm27x.c
+++ b/sound/soc/pxa/palm27x.c
@@ -107,10 +107,6 @@ static int palm27x_ac97_init(struct snd_soc_pcm_runtime *rtd)
107 snd_soc_dapm_nc_pin(dapm, "PHONE"); 107 snd_soc_dapm_nc_pin(dapm, "PHONE");
108 snd_soc_dapm_nc_pin(dapm, "MIC2"); 108 snd_soc_dapm_nc_pin(dapm, "MIC2");
109 109
110 err = snd_soc_dapm_sync(dapm);
111 if (err)
112 return err;
113
114 /* Jack detection API stuff */ 110 /* Jack detection API stuff */
115 err = snd_soc_jack_new(codec, "Headphone Jack", 111 err = snd_soc_jack_new(codec, "Headphone Jack",
116 SND_JACK_HEADPHONE, &hs_jack); 112 SND_JACK_HEADPHONE, &hs_jack);
diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c
index da3ae4316cf..4c29bc1f9cf 100644
--- a/sound/soc/pxa/poodle.c
+++ b/sound/soc/pxa/poodle.c
@@ -265,7 +265,6 @@ static int poodle_wm8731_init(struct snd_soc_pcm_runtime *rtd)
265 /* Set up poodle specific audio path audio_map */ 265 /* Set up poodle specific audio path audio_map */
266 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); 266 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
267 267
268 snd_soc_dapm_sync(dapm);
269 return 0; 268 return 0;
270} 269}
271 270
diff --git a/sound/soc/pxa/raumfeld.c b/sound/soc/pxa/raumfeld.c
index 1a591f1ebfb..b899a3bc8f4 100644
--- a/sound/soc/pxa/raumfeld.c
+++ b/sound/soc/pxa/raumfeld.c
@@ -306,8 +306,10 @@ static int __init raumfeld_audio_init(void)
306 &snd_soc_raumfeld_connector); 306 &snd_soc_raumfeld_connector);
307 307
308 ret = platform_device_add(raumfeld_audio_device); 308 ret = platform_device_add(raumfeld_audio_device);
309 if (ret < 0) 309 if (ret < 0) {
310 platform_device_put(raumfeld_audio_device);
310 return ret; 311 return ret;
312 }
311 313
312 raumfeld_enable_audio(true); 314 raumfeld_enable_audio(true);
313 return 0; 315 return 0;
diff --git a/sound/soc/pxa/saarb.c b/sound/soc/pxa/saarb.c
index 9595189fc68..d9467a2c6de 100644
--- a/sound/soc/pxa/saarb.c
+++ b/sound/soc/pxa/saarb.c
@@ -146,10 +146,6 @@ static int saarb_pm860x_init(struct snd_soc_pcm_runtime *rtd)
146 snd_soc_dapm_disable_pin(dapm, "Headset Mic 2"); 146 snd_soc_dapm_disable_pin(dapm, "Headset Mic 2");
147 snd_soc_dapm_disable_pin(dapm, "Headset Stereophone"); 147 snd_soc_dapm_disable_pin(dapm, "Headset Stereophone");
148 148
149 ret = snd_soc_dapm_sync(dapm);
150 if (ret)
151 return ret;
152
153 /* Headset jack detection */ 149 /* Headset jack detection */
154 snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE 150 snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE
155 | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2, 151 | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2,
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c
index b253d864868..c2d6ff9b158 100644
--- a/sound/soc/pxa/spitz.c
+++ b/sound/soc/pxa/spitz.c
@@ -301,7 +301,6 @@ static int spitz_wm8750_init(struct snd_soc_pcm_runtime *rtd)
301 /* Set up spitz specific audio paths */ 301 /* Set up spitz specific audio paths */
302 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); 302 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
303 303
304 snd_soc_dapm_sync(dapm);
305 return 0; 304 return 0;
306} 305}
307 306
@@ -312,7 +311,7 @@ static struct snd_soc_dai_link spitz_dai = {
312 .cpu_dai_name = "pxa2xx-i2s", 311 .cpu_dai_name = "pxa2xx-i2s",
313 .codec_dai_name = "wm8750-hifi", 312 .codec_dai_name = "wm8750-hifi",
314 .platform_name = "pxa-pcm-audio", 313 .platform_name = "pxa-pcm-audio",
315 .codec_name = "wm8750-codec.0-001b", 314 .codec_name = "wm8750.0-001b",
316 .init = spitz_wm8750_init, 315 .init = spitz_wm8750_init,
317 .ops = &spitz_ops, 316 .ops = &spitz_ops,
318}; 317};
diff --git a/sound/soc/pxa/tavorevb3.c b/sound/soc/pxa/tavorevb3.c
index f881f65ec17..eeec892e0e0 100644
--- a/sound/soc/pxa/tavorevb3.c
+++ b/sound/soc/pxa/tavorevb3.c
@@ -146,10 +146,6 @@ static int evb3_pm860x_init(struct snd_soc_pcm_runtime *rtd)
146 snd_soc_dapm_disable_pin(dapm, "Headset Mic 2"); 146 snd_soc_dapm_disable_pin(dapm, "Headset Mic 2");
147 snd_soc_dapm_disable_pin(dapm, "Headset Stereophone"); 147 snd_soc_dapm_disable_pin(dapm, "Headset Stereophone");
148 148
149 ret = snd_soc_dapm_sync(dapm);
150 if (ret)
151 return ret;
152
153 /* Headset jack detection */ 149 /* Headset jack detection */
154 snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE 150 snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE
155 | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2, 151 | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2,
diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c
index 9a235136695..620fc69ae63 100644
--- a/sound/soc/pxa/tosa.c
+++ b/sound/soc/pxa/tosa.c
@@ -211,7 +211,6 @@ static int tosa_ac97_init(struct snd_soc_pcm_runtime *rtd)
211 /* set up tosa specific audio path audio_map */ 211 /* set up tosa specific audio path audio_map */
212 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); 212 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
213 213
214 snd_soc_dapm_sync(dapm);
215 return 0; 214 return 0;
216} 215}
217 216
diff --git a/sound/soc/pxa/z2.c b/sound/soc/pxa/z2.c
index d69d9fc3223..b311ffe04b7 100644
--- a/sound/soc/pxa/z2.c
+++ b/sound/soc/pxa/z2.c
@@ -161,10 +161,6 @@ static int z2_wm8750_init(struct snd_soc_pcm_runtime *rtd)
161 /* Set up z2 specific audio paths */ 161 /* Set up z2 specific audio paths */
162 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); 162 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
163 163
164 ret = snd_soc_dapm_sync(dapm);
165 if (ret)
166 goto err;
167
168 /* Jack detection API stuff */ 164 /* Jack detection API stuff */
169 ret = snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET, 165 ret = snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET,
170 &hs_jack); 166 &hs_jack);
@@ -198,7 +194,7 @@ static struct snd_soc_dai_link z2_dai = {
198 .cpu_dai_name = "pxa2xx-i2s", 194 .cpu_dai_name = "pxa2xx-i2s",
199 .codec_dai_name = "wm8750-hifi", 195 .codec_dai_name = "wm8750-hifi",
200 .platform_name = "pxa-pcm-audio", 196 .platform_name = "pxa-pcm-audio",
201 .codec_name = "wm8750-codec.0-001b", 197 .codec_name = "wm8750.0-001b",
202 .init = z2_wm8750_init, 198 .init = z2_wm8750_init,
203 .ops = &z2_ops, 199 .ops = &z2_ops,
204}; 200};
diff --git a/sound/soc/pxa/zylonite.c b/sound/soc/pxa/zylonite.c
index 2b8350b5223..580aae38e50 100644
--- a/sound/soc/pxa/zylonite.c
+++ b/sound/soc/pxa/zylonite.c
@@ -87,7 +87,6 @@ static int zylonite_wm9713_init(struct snd_soc_pcm_runtime *rtd)
87 snd_soc_dapm_enable_pin(dapm, "Headphone"); 87 snd_soc_dapm_enable_pin(dapm, "Headphone");
88 snd_soc_dapm_enable_pin(dapm, "Headset Earpiece"); 88 snd_soc_dapm_enable_pin(dapm, "Headset Earpiece");
89 89
90 snd_soc_dapm_sync(dapm);
91 return 0; 90 return 0;
92} 91}
93 92
diff --git a/sound/soc/s6000/s6000-pcm.c b/sound/soc/s6000/s6000-pcm.c
index 80c85fd64e1..55efc2bdf0b 100644
--- a/sound/soc/s6000/s6000-pcm.c
+++ b/sound/soc/s6000/s6000-pcm.c
@@ -446,7 +446,6 @@ static u64 s6000_pcm_dmamask = DMA_BIT_MASK(32);
446static int s6000_pcm_new(struct snd_soc_pcm_runtime *runtime) 446static int s6000_pcm_new(struct snd_soc_pcm_runtime *runtime)
447{ 447{
448 struct snd_card *card = runtime->card->snd_card; 448 struct snd_card *card = runtime->card->snd_card;
449 struct snd_soc_dai *dai = runtime->cpu_dai;
450 struct snd_pcm *pcm = runtime->pcm; 449 struct snd_pcm *pcm = runtime->pcm;
451 struct s6000_pcm_dma_params *params; 450 struct s6000_pcm_dma_params *params;
452 int res; 451 int res;
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig
index 65f980ef287..53aaa69eda0 100644
--- a/sound/soc/samsung/Kconfig
+++ b/sound/soc/samsung/Kconfig
@@ -63,7 +63,9 @@ config SND_SOC_SAMSUNG_SMDK_WM8580
63 63
64config SND_SOC_SAMSUNG_SMDK_WM8994 64config SND_SOC_SAMSUNG_SMDK_WM8994
65 tristate "SoC I2S Audio support for WM8994 on SMDK" 65 tristate "SoC I2S Audio support for WM8994 on SMDK"
66 depends on SND_SOC_SAMSUNG && (MACH_SMDKV310 || MACH_SMDKC210) 66 depends on SND_SOC_SAMSUNG && (MACH_SMDKV310 || MACH_SMDKC210 || MACH_SMDK4212)
67 depends on I2C=y && GENERIC_HARDIRQS
68 select MFD_WM8994
67 select SND_SOC_WM8994 69 select SND_SOC_WM8994
68 select SND_SAMSUNG_I2S 70 select SND_SAMSUNG_I2S
69 help 71 help
@@ -150,7 +152,9 @@ config SND_SOC_SMARTQ
150config SND_SOC_GONI_AQUILA_WM8994 152config SND_SOC_GONI_AQUILA_WM8994
151 tristate "SoC I2S Audio support for AQUILA/GONI - WM8994" 153 tristate "SoC I2S Audio support for AQUILA/GONI - WM8994"
152 depends on SND_SOC_SAMSUNG && (MACH_GONI || MACH_AQUILA) 154 depends on SND_SOC_SAMSUNG && (MACH_GONI || MACH_AQUILA)
155 depends on I2C=y && GENERIC_HARDIRQS
153 select SND_SAMSUNG_I2S 156 select SND_SAMSUNG_I2S
157 select MFD_WM8994
154 select SND_SOC_WM8994 158 select SND_SOC_WM8994
155 help 159 help
156 Say Y if you want to add support for SoC audio on goni or aquila 160 Say Y if you want to add support for SoC audio on goni or aquila
@@ -158,7 +162,7 @@ config SND_SOC_GONI_AQUILA_WM8994
158 162
159config SND_SOC_SAMSUNG_SMDK_SPDIF 163config SND_SOC_SAMSUNG_SMDK_SPDIF
160 tristate "SoC S/PDIF Audio support for SMDK" 164 tristate "SoC S/PDIF Audio support for SMDK"
161 depends on SND_SOC_SAMSUNG && (MACH_SMDKC100 || MACH_SMDKC110 || MACH_SMDKV210 || MACH_SMDKV310) 165 depends on SND_SOC_SAMSUNG && (MACH_SMDKC100 || MACH_SMDKC110 || MACH_SMDKV210 || MACH_SMDKV310 || MACH_SMDK4212)
162 select SND_SAMSUNG_SPDIF 166 select SND_SAMSUNG_SPDIF
163 help 167 help
164 Say Y if you want to add support for SoC S/PDIF audio on the SMDK. 168 Say Y if you want to add support for SoC S/PDIF audio on the SMDK.
@@ -173,7 +177,9 @@ config SND_SOC_SMDK_WM8580_PCM
173 177
174config SND_SOC_SMDK_WM8994_PCM 178config SND_SOC_SMDK_WM8994_PCM
175 tristate "SoC PCM Audio support for WM8994 on SMDK" 179 tristate "SoC PCM Audio support for WM8994 on SMDK"
176 depends on SND_SOC_SAMSUNG && (MACH_SMDKC210 || MACH_SMDKV310) 180 depends on SND_SOC_SAMSUNG && (MACH_SMDKC210 || MACH_SMDKV310 || MACH_SMDK4212)
181 depends on I2C=y && GENERIC_HARDIRQS
182 select MFD_WM8994
177 select SND_SOC_WM8994 183 select SND_SOC_WM8994
178 select SND_SAMSUNG_PCM 184 select SND_SAMSUNG_PCM
179 help 185 help
diff --git a/sound/soc/samsung/ac97.c b/sound/soc/samsung/ac97.c
index f97110e72e8..b5e922f469d 100644
--- a/sound/soc/samsung/ac97.c
+++ b/sound/soc/samsung/ac97.c
@@ -444,7 +444,7 @@ static __devinit int s3c_ac97_probe(struct platform_device *pdev)
444 } 444 }
445 445
446 ret = request_irq(irq_res->start, s3c_ac97_irq, 446 ret = request_irq(irq_res->start, s3c_ac97_irq,
447 IRQF_DISABLED, "AC97", NULL); 447 0, "AC97", NULL);
448 if (ret < 0) { 448 if (ret < 0) {
449 dev_err(&pdev->dev, "ac97: interrupt request failed.\n"); 449 dev_err(&pdev->dev, "ac97: interrupt request failed.\n");
450 goto err4; 450 goto err4;
@@ -495,7 +495,7 @@ static __devexit int s3c_ac97_remove(struct platform_device *pdev)
495 495
496static struct platform_driver s3c_ac97_driver = { 496static struct platform_driver s3c_ac97_driver = {
497 .probe = s3c_ac97_probe, 497 .probe = s3c_ac97_probe,
498 .remove = s3c_ac97_remove, 498 .remove = __devexit_p(s3c_ac97_remove),
499 .driver = { 499 .driver = {
500 .name = "samsung-ac97", 500 .name = "samsung-ac97",
501 .owner = THIS_MODULE, 501 .owner = THIS_MODULE,
diff --git a/sound/soc/samsung/goni_wm8994.c b/sound/soc/samsung/goni_wm8994.c
index eb6d72ed55a..4a34f608e13 100644
--- a/sound/soc/samsung/goni_wm8994.c
+++ b/sound/soc/samsung/goni_wm8994.c
@@ -99,14 +99,6 @@ static int goni_wm8994_init(struct snd_soc_pcm_runtime *rtd)
99 struct snd_soc_dapm_context *dapm = &codec->dapm; 99 struct snd_soc_dapm_context *dapm = &codec->dapm;
100 int ret; 100 int ret;
101 101
102 /* add goni specific widgets */
103 snd_soc_dapm_new_controls(dapm, goni_dapm_widgets,
104 ARRAY_SIZE(goni_dapm_widgets));
105
106 /* set up goni specific audio routes */
107 snd_soc_dapm_add_routes(dapm, goni_dapm_routes,
108 ARRAY_SIZE(goni_dapm_routes));
109
110 /* set endpoints to not connected */ 102 /* set endpoints to not connected */
111 snd_soc_dapm_nc_pin(dapm, "IN2LP:VXRN"); 103 snd_soc_dapm_nc_pin(dapm, "IN2LP:VXRN");
112 snd_soc_dapm_nc_pin(dapm, "IN2RP:VXRP"); 104 snd_soc_dapm_nc_pin(dapm, "IN2RP:VXRP");
@@ -120,8 +112,6 @@ static int goni_wm8994_init(struct snd_soc_pcm_runtime *rtd)
120 snd_soc_dapm_nc_pin(dapm, "SPKOUTRP"); 112 snd_soc_dapm_nc_pin(dapm, "SPKOUTRP");
121 } 113 }
122 114
123 snd_soc_dapm_sync(dapm);
124
125 /* Headset jack detection */ 115 /* Headset jack detection */
126 ret = snd_soc_jack_new(codec, "Headset Jack", 116 ret = snd_soc_jack_new(codec, "Headset Jack",
127 SND_JACK_HEADSET | SND_JACK_MECHANICAL | SND_JACK_AVOUT, 117 SND_JACK_HEADSET | SND_JACK_MECHANICAL | SND_JACK_AVOUT,
@@ -255,6 +245,11 @@ static struct snd_soc_card goni = {
255 .name = "goni", 245 .name = "goni",
256 .dai_link = goni_dai, 246 .dai_link = goni_dai,
257 .num_links = ARRAY_SIZE(goni_dai), 247 .num_links = ARRAY_SIZE(goni_dai),
248
249 .dapm_widgets = goni_dapm_widgets,
250 .num_dapm_widgets = ARRAY_SIZE(goni_dapm_widgets),
251 .dapm_routes = goni_dapm_routes,
252 .num_dapm_routes = ARRAY_SIZE(goni_dapm_routes),
258}; 253};
259 254
260static int __init goni_init(void) 255static int __init goni_init(void)
diff --git a/sound/soc/samsung/h1940_uda1380.c b/sound/soc/samsung/h1940_uda1380.c
index c6c65892294..f75a4b60cf3 100644
--- a/sound/soc/samsung/h1940_uda1380.c
+++ b/sound/soc/samsung/h1940_uda1380.c
@@ -182,24 +182,10 @@ static int h1940_uda1380_init(struct snd_soc_pcm_runtime *rtd)
182 struct snd_soc_dapm_context *dapm = &codec->dapm; 182 struct snd_soc_dapm_context *dapm = &codec->dapm;
183 int err; 183 int err;
184 184
185 /* Add h1940 specific widgets */
186 err = snd_soc_dapm_new_controls(dapm, uda1380_dapm_widgets,
187 ARRAY_SIZE(uda1380_dapm_widgets));
188 if (err)
189 return err;
190
191 /* Set up h1940 specific audio path audio_mapnects */
192 err = snd_soc_dapm_add_routes(dapm, audio_map,
193 ARRAY_SIZE(audio_map));
194 if (err)
195 return err;
196
197 snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); 185 snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
198 snd_soc_dapm_enable_pin(dapm, "Speaker"); 186 snd_soc_dapm_enable_pin(dapm, "Speaker");
199 snd_soc_dapm_enable_pin(dapm, "Mic Jack"); 187 snd_soc_dapm_enable_pin(dapm, "Mic Jack");
200 188
201 snd_soc_dapm_sync(dapm);
202
203 snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE, 189 snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE,
204 &hp_jack); 190 &hp_jack);
205 191
@@ -230,6 +216,11 @@ static struct snd_soc_card h1940_asoc = {
230 .name = "h1940", 216 .name = "h1940",
231 .dai_link = h1940_uda1380_dai, 217 .dai_link = h1940_uda1380_dai,
232 .num_links = ARRAY_SIZE(h1940_uda1380_dai), 218 .num_links = ARRAY_SIZE(h1940_uda1380_dai),
219
220 .dapm_widgets = uda1380_dapm_widgets,
221 .num_dapm_widgets = ARRAY_SIZE(uda1380_dapm_widgets),
222 .dapm_routes = audio_map,
223 .num_dapm_routes = ARRAY_SIZE(audio_map),
233}; 224};
234 225
235static int __init h1940_init(void) 226static int __init h1940_init(void)
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index c086b78539e..0c9ac20d222 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -1136,7 +1136,7 @@ static __devexit int samsung_i2s_remove(struct platform_device *pdev)
1136 1136
1137static struct platform_driver samsung_i2s_driver = { 1137static struct platform_driver samsung_i2s_driver = {
1138 .probe = samsung_i2s_probe, 1138 .probe = samsung_i2s_probe,
1139 .remove = samsung_i2s_remove, 1139 .remove = __devexit_p(samsung_i2s_remove),
1140 .driver = { 1140 .driver = {
1141 .name = "samsung-i2s", 1141 .name = "samsung-i2s",
1142 .owner = THIS_MODULE, 1142 .owner = THIS_MODULE,
diff --git a/sound/soc/samsung/jive_wm8750.c b/sound/soc/samsung/jive_wm8750.c
index 14eb6ea69e7..f5f7c6f822d 100644
--- a/sound/soc/samsung/jive_wm8750.c
+++ b/sound/soc/samsung/jive_wm8750.c
@@ -110,18 +110,6 @@ static int jive_wm8750_init(struct snd_soc_pcm_runtime *rtd)
110 snd_soc_dapm_nc_pin(dapm, "OUT3"); 110 snd_soc_dapm_nc_pin(dapm, "OUT3");
111 snd_soc_dapm_nc_pin(dapm, "MONO"); 111 snd_soc_dapm_nc_pin(dapm, "MONO");
112 112
113 /* Add jive specific widgets */
114 err = snd_soc_dapm_new_controls(dapm, wm8750_dapm_widgets,
115 ARRAY_SIZE(wm8750_dapm_widgets));
116 if (err) {
117 printk(KERN_ERR "%s: failed to add widgets (%d)\n",
118 __func__, err);
119 return err;
120 }
121
122 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
123 snd_soc_dapm_sync(dapm);
124
125 return 0; 113 return 0;
126} 114}
127 115
@@ -131,7 +119,7 @@ static struct snd_soc_dai_link jive_dai = {
131 .cpu_dai_name = "s3c2412-i2s", 119 .cpu_dai_name = "s3c2412-i2s",
132 .codec_dai_name = "wm8750-hifi", 120 .codec_dai_name = "wm8750-hifi",
133 .platform_name = "samsung-audio", 121 .platform_name = "samsung-audio",
134 .codec_name = "wm8750-codec.0-001a", 122 .codec_name = "wm8750.0-001a",
135 .init = jive_wm8750_init, 123 .init = jive_wm8750_init,
136 .ops = &jive_ops, 124 .ops = &jive_ops,
137}; 125};
@@ -141,6 +129,11 @@ static struct snd_soc_card snd_soc_machine_jive = {
141 .name = "Jive", 129 .name = "Jive",
142 .dai_link = &jive_dai, 130 .dai_link = &jive_dai,
143 .num_links = 1, 131 .num_links = 1,
132
133 .dapm_widgtets = wm8750_dapm_widgets,
134 .num_dapm_widgets = ARRAY_SIZE(wm8750_dapm_widgets),
135 .dapm_routes = audio_map,
136 .num_dapm_routes = ARRAY_SIZE(audio_map),
144}; 137};
145 138
146static struct platform_device *jive_snd_device; 139static struct platform_device *jive_snd_device;
diff --git a/sound/soc/samsung/neo1973_wm8753.c b/sound/soc/samsung/neo1973_wm8753.c
index 16152ed0864..7207189cd21 100644
--- a/sound/soc/samsung/neo1973_wm8753.c
+++ b/sound/soc/samsung/neo1973_wm8753.c
@@ -367,8 +367,6 @@ static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd)
367 return ret; 367 return ret;
368 } 368 }
369 369
370 snd_soc_dapm_sync(dapm);
371
372 return 0; 370 return 0;
373} 371}
374 372
@@ -409,8 +407,6 @@ static int neo1973_lm4857_init(struct snd_soc_dapm_context *dapm)
409 snd_soc_dapm_ignore_suspend(dapm, "Handset Spk"); 407 snd_soc_dapm_ignore_suspend(dapm, "Handset Spk");
410 snd_soc_dapm_ignore_suspend(dapm, "Headphone"); 408 snd_soc_dapm_ignore_suspend(dapm, "Headphone");
411 409
412 snd_soc_dapm_sync(dapm);
413
414 return 0; 410 return 0;
415} 411}
416 412
diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c
index 9c7e8b48aed..e55d7a5c4bd 100644
--- a/sound/soc/samsung/pcm.c
+++ b/sound/soc/samsung/pcm.c
@@ -624,7 +624,7 @@ static __devexit int s3c_pcm_dev_remove(struct platform_device *pdev)
624 624
625static struct platform_driver s3c_pcm_driver = { 625static struct platform_driver s3c_pcm_driver = {
626 .probe = s3c_pcm_dev_probe, 626 .probe = s3c_pcm_dev_probe,
627 .remove = s3c_pcm_dev_remove, 627 .remove = __devexit_p(s3c_pcm_dev_remove),
628 .driver = { 628 .driver = {
629 .name = "samsung-pcm", 629 .name = "samsung-pcm",
630 .owner = THIS_MODULE, 630 .owner = THIS_MODULE,
diff --git a/sound/soc/samsung/rx1950_uda1380.c b/sound/soc/samsung/rx1950_uda1380.c
index bc8c1676459..aea7f1b24e6 100644
--- a/sound/soc/samsung/rx1950_uda1380.c
+++ b/sound/soc/samsung/rx1950_uda1380.c
@@ -90,12 +90,6 @@ static struct snd_soc_dai_link rx1950_uda1380_dai[] = {
90 }, 90 },
91}; 91};
92 92
93static struct snd_soc_card rx1950_asoc = {
94 .name = "rx1950",
95 .dai_link = rx1950_uda1380_dai,
96 .num_links = ARRAY_SIZE(rx1950_uda1380_dai),
97};
98
99/* rx1950 machine dapm widgets */ 93/* rx1950 machine dapm widgets */
100static const struct snd_soc_dapm_widget uda1380_dapm_widgets[] = { 94static const struct snd_soc_dapm_widget uda1380_dapm_widgets[] = {
101 SND_SOC_DAPM_HP("Headphone Jack", NULL), 95 SND_SOC_DAPM_HP("Headphone Jack", NULL),
@@ -117,6 +111,17 @@ static const struct snd_soc_dapm_route audio_map[] = {
117 {"VINM", NULL, "Mic Jack"}, 111 {"VINM", NULL, "Mic Jack"},
118}; 112};
119 113
114static struct snd_soc_card rx1950_asoc = {
115 .name = "rx1950",
116 .dai_link = rx1950_uda1380_dai,
117 .num_links = ARRAY_SIZE(rx1950_uda1380_dai),
118
119 .dapm_widgets = uda1380_dapm_widgets,
120 .num_dapm_widgets = ARRAY_SIZE(uda1380_dapm_widgets),
121 .dapm_routes = audio_map,
122 .num_dapm_routes = ARRAY_SIZE(audio_map),
123};
124
120static struct platform_device *s3c24xx_snd_device; 125static struct platform_device *s3c24xx_snd_device;
121 126
122static int rx1950_startup(struct snd_pcm_substream *substream) 127static int rx1950_startup(struct snd_pcm_substream *substream)
@@ -220,26 +225,10 @@ static int rx1950_uda1380_init(struct snd_soc_pcm_runtime *rtd)
220 struct snd_soc_dapm_context *dapm = &codec->dapm; 225 struct snd_soc_dapm_context *dapm = &codec->dapm;
221 int err; 226 int err;
222 227
223 /* Add rx1950 specific widgets */
224 err = snd_soc_dapm_new_controls(dapm, uda1380_dapm_widgets,
225 ARRAY_SIZE(uda1380_dapm_widgets));
226
227 if (err)
228 return err;
229
230 /* Set up rx1950 specific audio path audio_mapnects */
231 err = snd_soc_dapm_add_routes(dapm, audio_map,
232 ARRAY_SIZE(audio_map));
233
234 if (err)
235 return err;
236
237 snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); 228 snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
238 snd_soc_dapm_enable_pin(dapm, "Speaker"); 229 snd_soc_dapm_enable_pin(dapm, "Speaker");
239 snd_soc_dapm_enable_pin(dapm, "Mic Jack"); 230 snd_soc_dapm_enable_pin(dapm, "Mic Jack");
240 231
241 snd_soc_dapm_sync(dapm);
242
243 snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE, 232 snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE,
244 &hp_jack); 233 &hp_jack);
245 234
diff --git a/sound/soc/samsung/s3c-i2s-v2.c b/sound/soc/samsung/s3c-i2s-v2.c
index 52074a2b069..7a73380b356 100644
--- a/sound/soc/samsung/s3c-i2s-v2.c
+++ b/sound/soc/samsung/s3c-i2s-v2.c
@@ -16,6 +16,7 @@
16 * option) any later version. 16 * option) any later version.
17 */ 17 */
18 18
19#include <linux/module.h>
19#include <linux/delay.h> 20#include <linux/delay.h>
20#include <linux/clk.h> 21#include <linux/clk.h>
21#include <linux/io.h> 22#include <linux/io.h>
diff --git a/sound/soc/samsung/s3c2412-i2s.c b/sound/soc/samsung/s3c2412-i2s.c
index 841ab14c110..f26a8bfb235 100644
--- a/sound/soc/samsung/s3c2412-i2s.c
+++ b/sound/soc/samsung/s3c2412-i2s.c
@@ -69,10 +69,10 @@ static int s3c2412_i2s_probe(struct snd_soc_dai *dai)
69 s3c2412_i2s.dma_playback = &s3c2412_i2s_pcm_stereo_out; 69 s3c2412_i2s.dma_playback = &s3c2412_i2s_pcm_stereo_out;
70 70
71 s3c2412_i2s.iis_cclk = clk_get(dai->dev, "i2sclk"); 71 s3c2412_i2s.iis_cclk = clk_get(dai->dev, "i2sclk");
72 if (s3c2412_i2s.iis_cclk == NULL) { 72 if (IS_ERR(s3c2412_i2s.iis_cclk)) {
73 pr_err("failed to get i2sclk clock\n"); 73 pr_err("failed to get i2sclk clock\n");
74 iounmap(s3c2412_i2s.regs); 74 iounmap(s3c2412_i2s.regs);
75 return -ENODEV; 75 return PTR_ERR(s3c2412_i2s.iis_cclk);
76 } 76 }
77 77
78 /* Set MPLL as the source for IIS CLK */ 78 /* Set MPLL as the source for IIS CLK */
@@ -176,7 +176,7 @@ static __devexit int s3c2412_iis_dev_remove(struct platform_device *pdev)
176 176
177static struct platform_driver s3c2412_iis_driver = { 177static struct platform_driver s3c2412_iis_driver = {
178 .probe = s3c2412_iis_dev_probe, 178 .probe = s3c2412_iis_dev_probe,
179 .remove = s3c2412_iis_dev_remove, 179 .remove = __devexit_p(s3c2412_iis_dev_remove),
180 .driver = { 180 .driver = {
181 .name = "s3c2412-iis", 181 .name = "s3c2412-iis",
182 .owner = THIS_MODULE, 182 .owner = THIS_MODULE,
diff --git a/sound/soc/samsung/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c
index 63d8849d80b..c08117e658d 100644
--- a/sound/soc/samsung/s3c24xx-i2s.c
+++ b/sound/soc/samsung/s3c24xx-i2s.c
@@ -383,10 +383,10 @@ static int s3c24xx_i2s_probe(struct snd_soc_dai *dai)
383 return -ENXIO; 383 return -ENXIO;
384 384
385 s3c24xx_i2s.iis_clk = clk_get(dai->dev, "iis"); 385 s3c24xx_i2s.iis_clk = clk_get(dai->dev, "iis");
386 if (s3c24xx_i2s.iis_clk == NULL) { 386 if (IS_ERR(s3c24xx_i2s.iis_clk)) {
387 pr_err("failed to get iis_clock\n"); 387 pr_err("failed to get iis_clock\n");
388 iounmap(s3c24xx_i2s.regs); 388 iounmap(s3c24xx_i2s.regs);
389 return -ENODEV; 389 return PTR_ERR(s3c24xx_i2s.iis_clk);
390 } 390 }
391 clk_enable(s3c24xx_i2s.iis_clk); 391 clk_enable(s3c24xx_i2s.iis_clk);
392 392
@@ -481,7 +481,7 @@ static __devexit int s3c24xx_iis_dev_remove(struct platform_device *pdev)
481 481
482static struct platform_driver s3c24xx_iis_driver = { 482static struct platform_driver s3c24xx_iis_driver = {
483 .probe = s3c24xx_iis_dev_probe, 483 .probe = s3c24xx_iis_dev_probe,
484 .remove = s3c24xx_iis_dev_remove, 484 .remove = __devexit_p(s3c24xx_iis_dev_remove),
485 .driver = { 485 .driver = {
486 .name = "s3c24xx-iis", 486 .name = "s3c24xx-iis",
487 .owner = THIS_MODULE, 487 .owner = THIS_MODULE,
diff --git a/sound/soc/samsung/s3c24xx_simtec.c b/sound/soc/samsung/s3c24xx_simtec.c
index 349566f0686..c8d525bf612 100644
--- a/sound/soc/samsung/s3c24xx_simtec.c
+++ b/sound/soc/samsung/s3c24xx_simtec.c
@@ -300,7 +300,7 @@ static void detach_gpio_amp(struct s3c24xx_audio_simtec_pdata *pd)
300} 300}
301 301
302#ifdef CONFIG_PM 302#ifdef CONFIG_PM
303int simtec_audio_resume(struct device *dev) 303static int simtec_audio_resume(struct device *dev)
304{ 304{
305 simtec_call_startup(pdata); 305 simtec_call_startup(pdata);
306 return 0; 306 return 0;
diff --git a/sound/soc/samsung/s3c24xx_simtec_hermes.c b/sound/soc/samsung/s3c24xx_simtec_hermes.c
index ce6aef60417..6bc5a36af1d 100644
--- a/sound/soc/samsung/s3c24xx_simtec_hermes.c
+++ b/sound/soc/samsung/s3c24xx_simtec_hermes.c
@@ -65,18 +65,12 @@ static int simtec_hermes_init(struct snd_soc_pcm_runtime *rtd)
65 struct snd_soc_codec *codec = rtd->codec; 65 struct snd_soc_codec *codec = rtd->codec;
66 struct snd_soc_dapm_context *dapm = &codec->dapm; 66 struct snd_soc_dapm_context *dapm = &codec->dapm;
67 67
68 snd_soc_dapm_new_controls(dapm, dapm_widgets,
69 ARRAY_SIZE(dapm_widgets));
70
71 snd_soc_dapm_add_routes(dapm, base_map, ARRAY_SIZE(base_map));
72
73 snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); 68 snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
74 snd_soc_dapm_enable_pin(dapm, "Line In"); 69 snd_soc_dapm_enable_pin(dapm, "Line In");
75 snd_soc_dapm_enable_pin(dapm, "Line Out"); 70 snd_soc_dapm_enable_pin(dapm, "Line Out");
76 snd_soc_dapm_enable_pin(dapm, "Mic Jack"); 71 snd_soc_dapm_enable_pin(dapm, "Mic Jack");
77 72
78 simtec_audio_init(rtd); 73 simtec_audio_init(rtd);
79 snd_soc_dapm_sync(dapm);
80 74
81 return 0; 75 return 0;
82} 76}
@@ -96,6 +90,11 @@ static struct snd_soc_card snd_soc_machine_simtec_aic33 = {
96 .name = "Simtec-Hermes", 90 .name = "Simtec-Hermes",
97 .dai_link = &simtec_dai_aic33, 91 .dai_link = &simtec_dai_aic33,
98 .num_links = 1, 92 .num_links = 1,
93
94 .dapm_widgets = dapm_widgets,
95 .num_dapm_widgets = ARRAY_SIZE(dapm_widgets),
96 .dapm_routes = base_map,
97 .num_dapm_routes = ARRAY_SIZE(base_map),
99}; 98};
100 99
101static int __devinit simtec_audio_hermes_probe(struct platform_device *pd) 100static int __devinit simtec_audio_hermes_probe(struct platform_device *pd)
diff --git a/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c b/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c
index a7ef7db5468..7bdda767400 100644
--- a/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c
+++ b/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c
@@ -54,18 +54,12 @@ static int simtec_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd)
54 struct snd_soc_codec *codec = rtd->codec; 54 struct snd_soc_codec *codec = rtd->codec;
55 struct snd_soc_dapm_context *dapm = &codec->dapm; 55 struct snd_soc_dapm_context *dapm = &codec->dapm;
56 56
57 snd_soc_dapm_new_controls(dapm, dapm_widgets,
58 ARRAY_SIZE(dapm_widgets));
59
60 snd_soc_dapm_add_routes(dapm, base_map, ARRAY_SIZE(base_map));
61
62 snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); 57 snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
63 snd_soc_dapm_enable_pin(dapm, "Line In"); 58 snd_soc_dapm_enable_pin(dapm, "Line In");
64 snd_soc_dapm_enable_pin(dapm, "Line Out"); 59 snd_soc_dapm_enable_pin(dapm, "Line Out");
65 snd_soc_dapm_enable_pin(dapm, "Mic Jack"); 60 snd_soc_dapm_enable_pin(dapm, "Mic Jack");
66 61
67 simtec_audio_init(rtd); 62 simtec_audio_init(rtd);
68 snd_soc_dapm_sync(dapm);
69 63
70 return 0; 64 return 0;
71} 65}
@@ -85,6 +79,11 @@ static struct snd_soc_card snd_soc_machine_simtec_aic23 = {
85 .name = "Simtec", 79 .name = "Simtec",
86 .dai_link = &simtec_dai_aic23, 80 .dai_link = &simtec_dai_aic23,
87 .num_links = 1, 81 .num_links = 1,
82
83 .dapm_widgets = dapm_widgets,
84 .num_dapm_widgets = ARRAY_SIZE(dapm_widgets),
85 .dapm_routes = base_map,
86 .num_dapm_routes = ARRAY_SIZE(base_map),
88}; 87};
89 88
90static int __devinit simtec_audio_tlv320aic23_probe(struct platform_device *pd) 89static int __devinit simtec_audio_tlv320aic23_probe(struct platform_device *pd)
diff --git a/sound/soc/samsung/s3c24xx_uda134x.c b/sound/soc/samsung/s3c24xx_uda134x.c
index dc9d551f678..65c1cfd47d8 100644
--- a/sound/soc/samsung/s3c24xx_uda134x.c
+++ b/sound/soc/samsung/s3c24xx_uda134x.c
@@ -66,17 +66,17 @@ static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream)
66 pr_debug("%s %d\n", __func__, clk_users); 66 pr_debug("%s %d\n", __func__, clk_users);
67 if (clk_users == 0) { 67 if (clk_users == 0) {
68 xtal = clk_get(&s3c24xx_uda134x_snd_device->dev, "xtal"); 68 xtal = clk_get(&s3c24xx_uda134x_snd_device->dev, "xtal");
69 if (!xtal) { 69 if (IS_ERR(xtal)) {
70 printk(KERN_ERR "%s cannot get xtal\n", __func__); 70 printk(KERN_ERR "%s cannot get xtal\n", __func__);
71 ret = -EBUSY; 71 ret = PTR_ERR(xtal);
72 } else { 72 } else {
73 pclk = clk_get(&s3c24xx_uda134x_snd_device->dev, 73 pclk = clk_get(&s3c24xx_uda134x_snd_device->dev,
74 "pclk"); 74 "pclk");
75 if (!pclk) { 75 if (IS_ERR(pclk)) {
76 printk(KERN_ERR "%s cannot get pclk\n", 76 printk(KERN_ERR "%s cannot get pclk\n",
77 __func__); 77 __func__);
78 clk_put(xtal); 78 clk_put(xtal);
79 ret = -EBUSY; 79 ret = PTR_ERR(pclk);
80 } 80 }
81 } 81 }
82 if (!ret) { 82 if (!ret) {
diff --git a/sound/soc/samsung/smartq_wm8987.c b/sound/soc/samsung/smartq_wm8987.c
index 0a2c4f22303..6ac6bc2bcc4 100644
--- a/sound/soc/samsung/smartq_wm8987.c
+++ b/sound/soc/samsung/smartq_wm8987.c
@@ -153,20 +153,6 @@ static int smartq_wm8987_init(struct snd_soc_pcm_runtime *rtd)
153 struct snd_soc_dapm_context *dapm = &codec->dapm; 153 struct snd_soc_dapm_context *dapm = &codec->dapm;
154 int err = 0; 154 int err = 0;
155 155
156 /* Add SmartQ specific widgets */
157 snd_soc_dapm_new_controls(dapm, wm8987_dapm_widgets,
158 ARRAY_SIZE(wm8987_dapm_widgets));
159
160 /* add SmartQ specific controls */
161 err = snd_soc_add_controls(codec, wm8987_smartq_controls,
162 ARRAY_SIZE(wm8987_smartq_controls));
163
164 if (err < 0)
165 return err;
166
167 /* setup SmartQ specific audio path */
168 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
169
170 /* set endpoints to not connected */ 156 /* set endpoints to not connected */
171 snd_soc_dapm_nc_pin(dapm, "LINPUT1"); 157 snd_soc_dapm_nc_pin(dapm, "LINPUT1");
172 snd_soc_dapm_nc_pin(dapm, "RINPUT1"); 158 snd_soc_dapm_nc_pin(dapm, "RINPUT1");
@@ -178,10 +164,6 @@ static int smartq_wm8987_init(struct snd_soc_pcm_runtime *rtd)
178 snd_soc_dapm_enable_pin(dapm, "Internal Mic"); 164 snd_soc_dapm_enable_pin(dapm, "Internal Mic");
179 snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); 165 snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
180 166
181 err = snd_soc_dapm_sync(dapm);
182 if (err)
183 return err;
184
185 /* Headphone jack detection */ 167 /* Headphone jack detection */
186 err = snd_soc_jack_new(codec, "Headphone Jack", 168 err = snd_soc_jack_new(codec, "Headphone Jack",
187 SND_JACK_HEADPHONE, &smartq_jack); 169 SND_JACK_HEADPHONE, &smartq_jack);
@@ -207,7 +189,7 @@ static struct snd_soc_dai_link smartq_dai[] = {
207 .cpu_dai_name = "samsung-i2s.0", 189 .cpu_dai_name = "samsung-i2s.0",
208 .codec_dai_name = "wm8750-hifi", 190 .codec_dai_name = "wm8750-hifi",
209 .platform_name = "samsung-audio", 191 .platform_name = "samsung-audio",
210 .codec_name = "wm8750-codec.0-0x1a", 192 .codec_name = "wm8750.0-0x1a",
211 .init = smartq_wm8987_init, 193 .init = smartq_wm8987_init,
212 .ops = &smartq_hifi_ops, 194 .ops = &smartq_hifi_ops,
213 }, 195 },
@@ -217,6 +199,13 @@ static struct snd_soc_card snd_soc_smartq = {
217 .name = "SmartQ", 199 .name = "SmartQ",
218 .dai_link = smartq_dai, 200 .dai_link = smartq_dai,
219 .num_links = ARRAY_SIZE(smartq_dai), 201 .num_links = ARRAY_SIZE(smartq_dai),
202
203 .dapm_widgets = wm8987_dapm_widgets,
204 .num_dapm_widgets = ARRAY_SIZE(wm8987_dapm_widgets),
205 .dapm_routes = audio_map,
206 .num_dapm_routes = ARRAY_SIZE(audio_map),
207 .controls = wm8987_smartq_controls,
208 .num_controls = ARRAY_SIZE(wm8987_smartq_controls),
220}; 209};
221 210
222static struct platform_device *smartq_snd_device; 211static struct platform_device *smartq_snd_device;
diff --git a/sound/soc/samsung/smdk_wm8580.c b/sound/soc/samsung/smdk_wm8580.c
index 3d26f6607aa..8f92ffceb5c 100644
--- a/sound/soc/samsung/smdk_wm8580.c
+++ b/sound/soc/samsung/smdk_wm8580.c
@@ -119,30 +119,24 @@ static struct snd_soc_ops smdk_ops = {
119}; 119};
120 120
121/* SMDK Playback widgets */ 121/* SMDK Playback widgets */
122static const struct snd_soc_dapm_widget wm8580_dapm_widgets_pbk[] = { 122static const struct snd_soc_dapm_widget smdk_wm8580_dapm_widgets[] = {
123 SND_SOC_DAPM_HP("Front", NULL), 123 SND_SOC_DAPM_HP("Front", NULL),
124 SND_SOC_DAPM_HP("Center+Sub", NULL), 124 SND_SOC_DAPM_HP("Center+Sub", NULL),
125 SND_SOC_DAPM_HP("Rear", NULL), 125 SND_SOC_DAPM_HP("Rear", NULL),
126};
127 126
128/* SMDK Capture widgets */
129static const struct snd_soc_dapm_widget wm8580_dapm_widgets_cpt[] = {
130 SND_SOC_DAPM_MIC("MicIn", NULL), 127 SND_SOC_DAPM_MIC("MicIn", NULL),
131 SND_SOC_DAPM_LINE("LineIn", NULL), 128 SND_SOC_DAPM_LINE("LineIn", NULL),
132}; 129};
133 130
134/* SMDK-PAIFTX connections */ 131/* SMDK-PAIFTX connections */
135static const struct snd_soc_dapm_route audio_map_tx[] = { 132static const struct snd_soc_dapm_route smdk_wm8580_audio_map[] = {
136 /* MicIn feeds AINL */ 133 /* MicIn feeds AINL */
137 {"AINL", NULL, "MicIn"}, 134 {"AINL", NULL, "MicIn"},
138 135
139 /* LineIn feeds AINL/R */ 136 /* LineIn feeds AINL/R */
140 {"AINL", NULL, "LineIn"}, 137 {"AINL", NULL, "LineIn"},
141 {"AINR", NULL, "LineIn"}, 138 {"AINR", NULL, "LineIn"},
142};
143 139
144/* SMDK-PAIFRX connections */
145static const struct snd_soc_dapm_route audio_map_rx[] = {
146 /* Front Left/Right are fed VOUT1L/R */ 140 /* Front Left/Right are fed VOUT1L/R */
147 {"Front", NULL, "VOUT1L"}, 141 {"Front", NULL, "VOUT1L"},
148 {"Front", NULL, "VOUT1R"}, 142 {"Front", NULL, "VOUT1R"},
@@ -161,39 +155,11 @@ static int smdk_wm8580_init_paiftx(struct snd_soc_pcm_runtime *rtd)
161 struct snd_soc_codec *codec = rtd->codec; 155 struct snd_soc_codec *codec = rtd->codec;
162 struct snd_soc_dapm_context *dapm = &codec->dapm; 156 struct snd_soc_dapm_context *dapm = &codec->dapm;
163 157
164 /* Add smdk specific Capture widgets */
165 snd_soc_dapm_new_controls(dapm, wm8580_dapm_widgets_cpt,
166 ARRAY_SIZE(wm8580_dapm_widgets_cpt));
167
168 /* Set up PAIFTX audio path */
169 snd_soc_dapm_add_routes(dapm, audio_map_tx, ARRAY_SIZE(audio_map_tx));
170
171 /* Enabling the microphone requires the fitting of a 0R 158 /* Enabling the microphone requires the fitting of a 0R
172 * resistor to connect the line from the microphone jack. 159 * resistor to connect the line from the microphone jack.
173 */ 160 */
174 snd_soc_dapm_disable_pin(dapm, "MicIn"); 161 snd_soc_dapm_disable_pin(dapm, "MicIn");
175 162
176 /* signal a DAPM event */
177 snd_soc_dapm_sync(dapm);
178
179 return 0;
180}
181
182static int smdk_wm8580_init_paifrx(struct snd_soc_pcm_runtime *rtd)
183{
184 struct snd_soc_codec *codec = rtd->codec;
185 struct snd_soc_dapm_context *dapm = &codec->dapm;
186
187 /* Add smdk specific Playback widgets */
188 snd_soc_dapm_new_controls(dapm, wm8580_dapm_widgets_pbk,
189 ARRAY_SIZE(wm8580_dapm_widgets_pbk));
190
191 /* Set up PAIFRX audio path */
192 snd_soc_dapm_add_routes(dapm, audio_map_rx, ARRAY_SIZE(audio_map_rx));
193
194 /* signal a DAPM event */
195 snd_soc_dapm_sync(dapm);
196
197 return 0; 163 return 0;
198} 164}
199 165
@@ -210,8 +176,7 @@ static struct snd_soc_dai_link smdk_dai[] = {
210 .cpu_dai_name = "samsung-i2s.0", 176 .cpu_dai_name = "samsung-i2s.0",
211 .codec_dai_name = "wm8580-hifi-playback", 177 .codec_dai_name = "wm8580-hifi-playback",
212 .platform_name = "samsung-audio", 178 .platform_name = "samsung-audio",
213 .codec_name = "wm8580-codec.0-001b", 179 .codec_name = "wm8580.0-001b",
214 .init = smdk_wm8580_init_paifrx,
215 .ops = &smdk_ops, 180 .ops = &smdk_ops,
216 }, 181 },
217 [PRI_CAPTURE] = { /* Primary Capture i/f */ 182 [PRI_CAPTURE] = { /* Primary Capture i/f */
@@ -220,7 +185,7 @@ static struct snd_soc_dai_link smdk_dai[] = {
220 .cpu_dai_name = "samsung-i2s.0", 185 .cpu_dai_name = "samsung-i2s.0",
221 .codec_dai_name = "wm8580-hifi-capture", 186 .codec_dai_name = "wm8580-hifi-capture",
222 .platform_name = "samsung-audio", 187 .platform_name = "samsung-audio",
223 .codec_name = "wm8580-codec.0-001b", 188 .codec_name = "wm8580.0-001b",
224 .init = smdk_wm8580_init_paiftx, 189 .init = smdk_wm8580_init_paiftx,
225 .ops = &smdk_ops, 190 .ops = &smdk_ops,
226 }, 191 },
@@ -230,8 +195,7 @@ static struct snd_soc_dai_link smdk_dai[] = {
230 .cpu_dai_name = "samsung-i2s.x", 195 .cpu_dai_name = "samsung-i2s.x",
231 .codec_dai_name = "wm8580-hifi-playback", 196 .codec_dai_name = "wm8580-hifi-playback",
232 .platform_name = "samsung-audio", 197 .platform_name = "samsung-audio",
233 .codec_name = "wm8580-codec.0-001b", 198 .codec_name = "wm8580.0-001b",
234 .init = smdk_wm8580_init_paifrx,
235 .ops = &smdk_ops, 199 .ops = &smdk_ops,
236 }, 200 },
237}; 201};
@@ -240,6 +204,11 @@ static struct snd_soc_card smdk = {
240 .name = "SMDK-I2S", 204 .name = "SMDK-I2S",
241 .dai_link = smdk_dai, 205 .dai_link = smdk_dai,
242 .num_links = 2, 206 .num_links = 2,
207
208 .dapm_widgets = smdk_wm8580_dapm_widgets,
209 .num_dapm_widgets = ARRAY_SIZE(smdk_wm8580_dapm_widgets),
210 .dapm_routes = smdk_wm8580_audio_map,
211 .num_dapm_routes = ARRAY_SIZE(smdk_wm8580_audio_map),
243}; 212};
244 213
245static struct platform_device *smdk_snd_device; 214static struct platform_device *smdk_snd_device;
diff --git a/sound/soc/samsung/smdk_wm8580pcm.c b/sound/soc/samsung/smdk_wm8580pcm.c
index 0d12092df16..4b9c73477ce 100644
--- a/sound/soc/samsung/smdk_wm8580pcm.c
+++ b/sound/soc/samsung/smdk_wm8580pcm.c
@@ -127,7 +127,7 @@ static struct snd_soc_dai_link smdk_dai[] = {
127 .cpu_dai_name = "samsung-pcm.0", 127 .cpu_dai_name = "samsung-pcm.0",
128 .codec_dai_name = "wm8580-hifi-playback", 128 .codec_dai_name = "wm8580-hifi-playback",
129 .platform_name = "samsung-audio", 129 .platform_name = "samsung-audio",
130 .codec_name = "wm8580-codec.0-001b", 130 .codec_name = "wm8580.0-001b",
131 .ops = &smdk_wm8580_pcm_ops, 131 .ops = &smdk_wm8580_pcm_ops,
132 }, { 132 }, {
133 .name = "WM8580 PAIF PCM TX", 133 .name = "WM8580 PAIF PCM TX",
@@ -135,7 +135,7 @@ static struct snd_soc_dai_link smdk_dai[] = {
135 .cpu_dai_name = "samsung-pcm.0", 135 .cpu_dai_name = "samsung-pcm.0",
136 .codec_dai_name = "wm8580-hifi-capture", 136 .codec_dai_name = "wm8580-hifi-capture",
137 .platform_name = "samsung-audio", 137 .platform_name = "samsung-audio",
138 .codec_name = "wm8580-codec.0-001b", 138 .codec_name = "wm8580.0-001b",
139 .ops = &smdk_wm8580_pcm_ops, 139 .ops = &smdk_wm8580_pcm_ops,
140 }, 140 },
141}; 141};
diff --git a/sound/soc/samsung/smdk_wm8994.c b/sound/soc/samsung/smdk_wm8994.c
index 45fbe2b3727..f75e43997d5 100644
--- a/sound/soc/samsung/smdk_wm8994.c
+++ b/sound/soc/samsung/smdk_wm8994.c
@@ -117,8 +117,6 @@ static int smdk_wm8994_init_paiftx(struct snd_soc_pcm_runtime *rtd)
117 snd_soc_dapm_nc_pin(dapm, "IN1RP"); 117 snd_soc_dapm_nc_pin(dapm, "IN1RP");
118 snd_soc_dapm_nc_pin(dapm, "IN2RP:VXRP"); 118 snd_soc_dapm_nc_pin(dapm, "IN2RP:VXRP");
119 119
120 snd_soc_dapm_sync(dapm);
121
122 return 0; 120 return 0;
123} 121}
124 122
diff --git a/sound/soc/samsung/spdif.c b/sound/soc/samsung/spdif.c
index 28c491dacf7..3122f3154bf 100644
--- a/sound/soc/samsung/spdif.c
+++ b/sound/soc/samsung/spdif.c
@@ -340,7 +340,7 @@ static struct snd_soc_dai_ops spdif_dai_ops = {
340 .shutdown = spdif_shutdown, 340 .shutdown = spdif_shutdown,
341}; 341};
342 342
343struct snd_soc_dai_driver samsung_spdif_dai = { 343static struct snd_soc_dai_driver samsung_spdif_dai = {
344 .name = "samsung-spdif", 344 .name = "samsung-spdif",
345 .playback = { 345 .playback = {
346 .stream_name = "S/PDIF Playback", 346 .stream_name = "S/PDIF Playback",
@@ -475,7 +475,7 @@ static __devexit int spdif_remove(struct platform_device *pdev)
475 475
476static struct platform_driver samsung_spdif_driver = { 476static struct platform_driver samsung_spdif_driver = {
477 .probe = spdif_probe, 477 .probe = spdif_probe,
478 .remove = spdif_remove, 478 .remove = __devexit_p(spdif_remove),
479 .driver = { 479 .driver = {
480 .name = "samsung-spdif", 480 .name = "samsung-spdif",
481 .owner = THIS_MODULE, 481 .owner = THIS_MODULE,
diff --git a/sound/soc/samsung/speyside.c b/sound/soc/samsung/speyside.c
index 590e9274b06..b9e213f6cc0 100644
--- a/sound/soc/samsung/speyside.c
+++ b/sound/soc/samsung/speyside.c
@@ -125,10 +125,6 @@ static struct snd_soc_jack_pin speyside_headset_pins[] = {
125 .pin = "Headset Mic", 125 .pin = "Headset Mic",
126 .mask = SND_JACK_MICROPHONE, 126 .mask = SND_JACK_MICROPHONE,
127 }, 127 },
128 {
129 .pin = "Headphone",
130 .mask = SND_JACK_HEADPHONE,
131 },
132}; 128};
133 129
134/* Default the headphone selection to active high */ 130/* Default the headphone selection to active high */
@@ -171,7 +167,8 @@ static int speyside_wm8996_init(struct snd_soc_pcm_runtime *rtd)
171 gpio_direction_output(WM8996_HPSEL_GPIO, speyside_jack_polarity); 167 gpio_direction_output(WM8996_HPSEL_GPIO, speyside_jack_polarity);
172 168
173 ret = snd_soc_jack_new(codec, "Headset", 169 ret = snd_soc_jack_new(codec, "Headset",
174 SND_JACK_HEADSET | SND_JACK_BTN_0, 170 SND_JACK_LINEOUT | SND_JACK_HEADSET |
171 SND_JACK_BTN_0,
175 &speyside_headset); 172 &speyside_headset);
176 if (ret) 173 if (ret)
177 return ret; 174 return ret;
@@ -227,7 +224,7 @@ static int speyside_wm9081_init(struct snd_soc_dapm_context *dapm)
227 snd_soc_dapm_nc_pin(dapm, "LINEOUT"); 224 snd_soc_dapm_nc_pin(dapm, "LINEOUT");
228 225
229 /* At any time the WM9081 is active it will have this clock */ 226 /* At any time the WM9081 is active it will have this clock */
230 return snd_soc_codec_set_sysclk(dapm->codec, WM9081_SYSCLK_MCLK, 227 return snd_soc_codec_set_sysclk(dapm->codec, WM9081_SYSCLK_MCLK, 0,
231 48000 * 256, 0); 228 48000 * 256, 0);
232} 229}
233 230
@@ -252,6 +249,7 @@ static const struct snd_kcontrol_new controls[] = {
252 SOC_DAPM_PIN_SWITCH("Main AMIC"), 249 SOC_DAPM_PIN_SWITCH("Main AMIC"),
253 SOC_DAPM_PIN_SWITCH("WM1250 Input"), 250 SOC_DAPM_PIN_SWITCH("WM1250 Input"),
254 SOC_DAPM_PIN_SWITCH("WM1250 Output"), 251 SOC_DAPM_PIN_SWITCH("WM1250 Output"),
252 SOC_DAPM_PIN_SWITCH("Headphone"),
255}; 253};
256 254
257static struct snd_soc_dapm_widget widgets[] = { 255static struct snd_soc_dapm_widget widgets[] = {
diff --git a/sound/soc/samsung/speyside_wm8962.c b/sound/soc/samsung/speyside_wm8962.c
index 72535f2daaf..8a082044436 100644
--- a/sound/soc/samsung/speyside_wm8962.c
+++ b/sound/soc/samsung/speyside_wm8962.c
@@ -16,6 +16,8 @@
16 16
17#include "../codecs/wm8962.h" 17#include "../codecs/wm8962.h"
18 18
19static int sample_rate = 44100;
20
19static int speyside_wm8962_set_bias_level(struct snd_soc_card *card, 21static int speyside_wm8962_set_bias_level(struct snd_soc_card *card,
20 struct snd_soc_dapm_context *dapm, 22 struct snd_soc_dapm_context *dapm,
21 enum snd_soc_bias_level level) 23 enum snd_soc_bias_level level)
@@ -31,13 +33,13 @@ static int speyside_wm8962_set_bias_level(struct snd_soc_card *card,
31 if (dapm->bias_level == SND_SOC_BIAS_STANDBY) { 33 if (dapm->bias_level == SND_SOC_BIAS_STANDBY) {
32 ret = snd_soc_dai_set_pll(codec_dai, WM8962_FLL, 34 ret = snd_soc_dai_set_pll(codec_dai, WM8962_FLL,
33 WM8962_FLL_MCLK, 32768, 35 WM8962_FLL_MCLK, 32768,
34 44100 * 256); 36 sample_rate * 512);
35 if (ret < 0) 37 if (ret < 0)
36 pr_err("Failed to start FLL: %d\n", ret); 38 pr_err("Failed to start FLL: %d\n", ret);
37 39
38 ret = snd_soc_dai_set_sysclk(codec_dai, 40 ret = snd_soc_dai_set_sysclk(codec_dai,
39 WM8962_SYSCLK_FLL, 41 WM8962_SYSCLK_FLL,
40 44100 * 256, 42 sample_rate * 512,
41 SND_SOC_CLOCK_IN); 43 SND_SOC_CLOCK_IN);
42 if (ret < 0) { 44 if (ret < 0) {
43 pr_err("Failed to set SYSCLK: %d\n", ret); 45 pr_err("Failed to set SYSCLK: %d\n", ret);
@@ -92,22 +94,7 @@ static int speyside_wm8962_set_bias_level_post(struct snd_soc_card *card,
92static int speyside_wm8962_hw_params(struct snd_pcm_substream *substream, 94static int speyside_wm8962_hw_params(struct snd_pcm_substream *substream,
93 struct snd_pcm_hw_params *params) 95 struct snd_pcm_hw_params *params)
94{ 96{
95 struct snd_soc_pcm_runtime *rtd = substream->private_data; 97 sample_rate = params_rate(params);
96 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
97 struct snd_soc_dai *codec_dai = rtd->codec_dai;
98 int ret;
99
100 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S
101 | SND_SOC_DAIFMT_NB_NF
102 | SND_SOC_DAIFMT_CBM_CFM);
103 if (ret < 0)
104 return ret;
105
106 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S
107 | SND_SOC_DAIFMT_NB_NF
108 | SND_SOC_DAIFMT_CBM_CFM);
109 if (ret < 0)
110 return ret;
111 98
112 return 0; 99 return 0;
113} 100}
@@ -124,12 +111,15 @@ static struct snd_soc_dai_link speyside_wm8962_dai[] = {
124 .codec_dai_name = "wm8962", 111 .codec_dai_name = "wm8962",
125 .platform_name = "samsung-audio", 112 .platform_name = "samsung-audio",
126 .codec_name = "wm8962.1-001a", 113 .codec_name = "wm8962.1-001a",
114 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
115 | SND_SOC_DAIFMT_CBM_CFM,
127 .ops = &speyside_wm8962_ops, 116 .ops = &speyside_wm8962_ops,
128 }, 117 },
129}; 118};
130 119
131static const struct snd_kcontrol_new controls[] = { 120static const struct snd_kcontrol_new controls[] = {
132 SOC_DAPM_PIN_SWITCH("Main Speaker"), 121 SOC_DAPM_PIN_SWITCH("Main Speaker"),
122 SOC_DAPM_PIN_SWITCH("DMIC"),
133}; 123};
134 124
135static struct snd_soc_dapm_widget widgets[] = { 125static struct snd_soc_dapm_widget widgets[] = {
@@ -137,6 +127,7 @@ static struct snd_soc_dapm_widget widgets[] = {
137 SND_SOC_DAPM_MIC("Headset Mic", NULL), 127 SND_SOC_DAPM_MIC("Headset Mic", NULL),
138 128
139 SND_SOC_DAPM_MIC("DMIC", NULL), 129 SND_SOC_DAPM_MIC("DMIC", NULL),
130 SND_SOC_DAPM_MIC("AMIC", NULL),
140 131
141 SND_SOC_DAPM_SPK("Main Speaker", NULL), 132 SND_SOC_DAPM_SPK("Main Speaker", NULL),
142}; 133};
@@ -148,12 +139,16 @@ static struct snd_soc_dapm_route audio_paths[] = {
148 { "Main Speaker", NULL, "SPKOUTL" }, 139 { "Main Speaker", NULL, "SPKOUTL" },
149 { "Main Speaker", NULL, "SPKOUTR" }, 140 { "Main Speaker", NULL, "SPKOUTR" },
150 141
151 { "MICBIAS", NULL, "Headset Mic" }, 142 { "Headset Mic", NULL, "MICBIAS" },
152 { "IN4L", NULL, "MICBIAS" }, 143 { "IN4L", NULL, "Headset Mic" },
153 { "IN4R", NULL, "MICBIAS" }, 144 { "IN4R", NULL, "Headset Mic" },
145
146 { "AMIC", NULL, "MICBIAS" },
147 { "IN1L", NULL, "AMIC" },
148 { "IN1R", NULL, "AMIC" },
154 149
155 { "MICBIAS", NULL, "DMIC" }, 150 { "DMIC", NULL, "MICBIAS" },
156 { "DMICDAT", NULL, "MICBIAS" }, 151 { "DMICDAT", NULL, "DMIC" },
157}; 152};
158 153
159static struct snd_soc_jack speyside_wm8962_headset; 154static struct snd_soc_jack speyside_wm8962_headset;
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 8e112ccffb1..a32fd16ad66 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -210,7 +210,7 @@ struct fsi_master {
210 * basic read write function 210 * basic read write function
211 */ 211 */
212 212
213static void __fsi_reg_write(u32 reg, u32 data) 213static void __fsi_reg_write(u32 __iomem *reg, u32 data)
214{ 214{
215 /* valid data area is 24bit */ 215 /* valid data area is 24bit */
216 data &= 0x00ffffff; 216 data &= 0x00ffffff;
@@ -218,12 +218,12 @@ static void __fsi_reg_write(u32 reg, u32 data)
218 __raw_writel(data, reg); 218 __raw_writel(data, reg);
219} 219}
220 220
221static u32 __fsi_reg_read(u32 reg) 221static u32 __fsi_reg_read(u32 __iomem *reg)
222{ 222{
223 return __raw_readl(reg); 223 return __raw_readl(reg);
224} 224}
225 225
226static void __fsi_reg_mask_set(u32 reg, u32 mask, u32 data) 226static void __fsi_reg_mask_set(u32 __iomem *reg, u32 mask, u32 data)
227{ 227{
228 u32 val = __fsi_reg_read(reg); 228 u32 val = __fsi_reg_read(reg);
229 229
@@ -250,7 +250,7 @@ static u32 _fsi_master_read(struct fsi_master *master, u32 reg)
250 unsigned long flags; 250 unsigned long flags;
251 251
252 spin_lock_irqsave(&master->lock, flags); 252 spin_lock_irqsave(&master->lock, flags);
253 ret = __fsi_reg_read((u32)(master->base + reg)); 253 ret = __fsi_reg_read(master->base + reg);
254 spin_unlock_irqrestore(&master->lock, flags); 254 spin_unlock_irqrestore(&master->lock, flags);
255 255
256 return ret; 256 return ret;
@@ -264,7 +264,7 @@ static void _fsi_master_mask_set(struct fsi_master *master,
264 unsigned long flags; 264 unsigned long flags;
265 265
266 spin_lock_irqsave(&master->lock, flags); 266 spin_lock_irqsave(&master->lock, flags);
267 __fsi_reg_mask_set((u32)(master->base + reg), mask, data); 267 __fsi_reg_mask_set(master->base + reg, mask, data);
268 spin_unlock_irqrestore(&master->lock, flags); 268 spin_unlock_irqrestore(&master->lock, flags);
269} 269}
270 270
@@ -1285,7 +1285,7 @@ static int fsi_probe(struct platform_device *pdev)
1285 pm_runtime_enable(&pdev->dev); 1285 pm_runtime_enable(&pdev->dev);
1286 dev_set_drvdata(&pdev->dev, master); 1286 dev_set_drvdata(&pdev->dev, master);
1287 1287
1288 ret = request_irq(irq, &fsi_interrupt, IRQF_DISABLED, 1288 ret = request_irq(irq, &fsi_interrupt, 0,
1289 id_entry->name, master); 1289 id_entry->name, master);
1290 if (ret) { 1290 if (ret) {
1291 dev_err(&pdev->dev, "irq request err\n"); 1291 dev_err(&pdev->dev, "irq request err\n");
diff --git a/sound/soc/sh/sh7760-ac97.c b/sound/soc/sh/sh7760-ac97.c
index 917d3ceadc9..c62ae689c4a 100644
--- a/sound/soc/sh/sh7760-ac97.c
+++ b/sound/soc/sh/sh7760-ac97.c
@@ -20,12 +20,6 @@
20extern struct snd_soc_dai_driver sh4_hac_dai[2]; 20extern struct snd_soc_dai_driver sh4_hac_dai[2];
21extern struct snd_soc_platform_driver sh7760_soc_platform; 21extern struct snd_soc_platform_driver sh7760_soc_platform;
22 22
23static int machine_init(struct snd_soc_pcm_runtime *rtd)
24{
25 snd_soc_dapm_sync(&rtd->codec->dapm);
26 return 0;
27}
28
29static struct snd_soc_dai_link sh7760_ac97_dai = { 23static struct snd_soc_dai_link sh7760_ac97_dai = {
30 .name = "AC97", 24 .name = "AC97",
31 .stream_name = "AC97 HiFi", 25 .stream_name = "AC97 HiFi",
@@ -33,7 +27,6 @@ static struct snd_soc_dai_link sh7760_ac97_dai = {
33 .codec_dai_name = "ac97-hifi", 27 .codec_dai_name = "ac97-hifi",
34 .platform_name = "sh7760-pcm-audio", 28 .platform_name = "sh7760-pcm-audio",
35 .codec_name = "ac97-codec", 29 .codec_name = "ac97-codec",
36 .init = machine_init,
37 .ops = NULL, 30 .ops = NULL,
38}; 31};
39 32
diff --git a/sound/soc/sh/ssi.c b/sound/soc/sh/ssi.c
index 05192d97b37..e0c621c0553 100644
--- a/sound/soc/sh/ssi.c
+++ b/sound/soc/sh/ssi.c
@@ -342,7 +342,7 @@ static struct snd_soc_dai_ops ssi_dai_ops = {
342 .set_fmt = ssi_set_fmt, 342 .set_fmt = ssi_set_fmt,
343}; 343};
344 344
345struct snd_soc_dai_driver sh4_ssi_dai[] = { 345static struct snd_soc_dai_driver sh4_ssi_dai[] = {
346{ 346{
347 .name = "ssi-dai.0", 347 .name = "ssi-dai.0",
348 .playback = { 348 .playback = {
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c
index 20b7f3b003a..143c705ac27 100644
--- a/sound/soc/soc-cache.c
+++ b/sound/soc/soc-cache.c
@@ -548,9 +548,6 @@ static inline int snd_soc_lzo_get_blkpos(struct snd_soc_codec *codec,
548 548
549static inline int snd_soc_lzo_get_blksize(struct snd_soc_codec *codec) 549static inline int snd_soc_lzo_get_blksize(struct snd_soc_codec *codec)
550{ 550{
551 const struct snd_soc_codec_driver *codec_drv;
552
553 codec_drv = codec->driver;
554 return DIV_ROUND_UP(codec->reg_size, snd_soc_lzo_block_count()); 551 return DIV_ROUND_UP(codec->reg_size, snd_soc_lzo_block_count());
555} 552}
556 553
@@ -868,10 +865,6 @@ static int snd_soc_flat_cache_exit(struct snd_soc_codec *codec)
868 865
869static int snd_soc_flat_cache_init(struct snd_soc_codec *codec) 866static int snd_soc_flat_cache_init(struct snd_soc_codec *codec)
870{ 867{
871 const struct snd_soc_codec_driver *codec_drv;
872
873 codec_drv = codec->driver;
874
875 if (codec->reg_def_copy) 868 if (codec->reg_def_copy)
876 codec->reg_cache = kmemdup(codec->reg_def_copy, 869 codec->reg_cache = kmemdup(codec->reg_def_copy,
877 codec->reg_size, GFP_KERNEL); 870 codec->reg_size, GFP_KERNEL);
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index ef69f5a0270..a5d3685a5d3 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -106,7 +106,7 @@ static int format_register_str(struct snd_soc_codec *codec,
106 if (wordsize + regsize + 2 + 1 != len) 106 if (wordsize + regsize + 2 + 1 != len)
107 return -EINVAL; 107 return -EINVAL;
108 108
109 ret = snd_soc_read(codec , reg); 109 ret = snd_soc_read(codec, reg);
110 if (ret < 0) { 110 if (ret < 0) {
111 memset(regbuf, 'X', regsize); 111 memset(regbuf, 'X', regsize);
112 regbuf[regsize] = '\0'; 112 regbuf[regsize] = '\0';
@@ -144,7 +144,7 @@ static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf,
144 step = codec->driver->reg_cache_step; 144 step = codec->driver->reg_cache_step;
145 145
146 for (i = 0; i < codec->driver->reg_cache_size; i += step) { 146 for (i = 0; i < codec->driver->reg_cache_size; i += step) {
147 if (codec->readable_register && !codec->readable_register(codec, i)) 147 if (!snd_soc_codec_readable_register(codec, i))
148 continue; 148 continue;
149 if (codec->driver->display_register) { 149 if (codec->driver->display_register) {
150 count += codec->driver->display_register(codec, buf + count, 150 count += codec->driver->display_register(codec, buf + count,
@@ -245,7 +245,6 @@ static ssize_t codec_reg_write_file(struct file *file,
245 size_t buf_size; 245 size_t buf_size;
246 char *start = buf; 246 char *start = buf;
247 unsigned long reg, value; 247 unsigned long reg, value;
248 int step = 1;
249 struct snd_soc_codec *codec = file->private_data; 248 struct snd_soc_codec *codec = file->private_data;
250 249
251 buf_size = min(count, (sizeof(buf)-1)); 250 buf_size = min(count, (sizeof(buf)-1));
@@ -253,9 +252,6 @@ static ssize_t codec_reg_write_file(struct file *file,
253 return -EFAULT; 252 return -EFAULT;
254 buf[buf_size] = 0; 253 buf[buf_size] = 0;
255 254
256 if (codec->driver->reg_cache_step)
257 step = codec->driver->reg_cache_step;
258
259 while (*start == ' ') 255 while (*start == ' ')
260 start++; 256 start++;
261 reg = simple_strtoul(start, &start, 16); 257 reg = simple_strtoul(start, &start, 16);
@@ -957,6 +953,8 @@ static int soc_probe_codec(struct snd_soc_card *card,
957 snd_soc_dapm_new_controls(&codec->dapm, driver->dapm_widgets, 953 snd_soc_dapm_new_controls(&codec->dapm, driver->dapm_widgets,
958 driver->num_dapm_widgets); 954 driver->num_dapm_widgets);
959 955
956 codec->dapm.idle_bias_off = driver->idle_bias_off;
957
960 if (driver->probe) { 958 if (driver->probe) {
961 ret = driver->probe(codec); 959 ret = driver->probe(codec);
962 if (ret < 0) { 960 if (ret < 0) {
@@ -1057,6 +1055,9 @@ static int soc_post_component_init(struct snd_soc_card *card,
1057 } 1055 }
1058 rtd->card = card; 1056 rtd->card = card;
1059 1057
1058 /* Make sure all DAPM widgets are instantiated */
1059 snd_soc_dapm_new_widgets(&codec->dapm);
1060
1060 /* machine controls, routes and widgets are not prefixed */ 1061 /* machine controls, routes and widgets are not prefixed */
1061 temp = codec->name_prefix; 1062 temp = codec->name_prefix;
1062 codec->name_prefix = NULL; 1063 codec->name_prefix = NULL;
@@ -1072,9 +1073,6 @@ static int soc_post_component_init(struct snd_soc_card *card,
1072 } 1073 }
1073 codec->name_prefix = temp; 1074 codec->name_prefix = temp;
1074 1075
1075 /* Make sure all DAPM widgets are instantiated */
1076 snd_soc_dapm_new_widgets(&codec->dapm);
1077
1078 /* register the rtd device */ 1076 /* register the rtd device */
1079 rtd->codec = codec; 1077 rtd->codec = codec;
1080 rtd->dev.parent = card->dev; 1078 rtd->dev.parent = card->dev;
@@ -1319,6 +1317,7 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1319 struct snd_soc_codec *codec; 1317 struct snd_soc_codec *codec;
1320 struct snd_soc_codec_conf *codec_conf; 1318 struct snd_soc_codec_conf *codec_conf;
1321 enum snd_soc_compress_type compress_type; 1319 enum snd_soc_compress_type compress_type;
1320 struct snd_soc_dai_link *dai_link;
1322 int ret, i, order; 1321 int ret, i, order;
1323 1322
1324 mutex_lock(&card->mutex); 1323 mutex_lock(&card->mutex);
@@ -1431,6 +1430,28 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1431 snd_soc_dapm_add_routes(&card->dapm, card->dapm_routes, 1430 snd_soc_dapm_add_routes(&card->dapm, card->dapm_routes,
1432 card->num_dapm_routes); 1431 card->num_dapm_routes);
1433 1432
1433 snd_soc_dapm_new_widgets(&card->dapm);
1434
1435 for (i = 0; i < card->num_links; i++) {
1436 dai_link = &card->dai_link[i];
1437
1438 if (dai_link->dai_fmt) {
1439 ret = snd_soc_dai_set_fmt(card->rtd[i].codec_dai,
1440 dai_link->dai_fmt);
1441 if (ret != 0)
1442 dev_warn(card->rtd[i].codec_dai->dev,
1443 "Failed to set DAI format: %d\n",
1444 ret);
1445
1446 ret = snd_soc_dai_set_fmt(card->rtd[i].cpu_dai,
1447 dai_link->dai_fmt);
1448 if (ret != 0)
1449 dev_warn(card->rtd[i].cpu_dai->dev,
1450 "Failed to set DAI format: %d\n",
1451 ret);
1452 }
1453 }
1454
1434 snprintf(card->snd_card->shortname, sizeof(card->snd_card->shortname), 1455 snprintf(card->snd_card->shortname, sizeof(card->snd_card->shortname),
1435 "%s", card->name); 1456 "%s", card->name);
1436 snprintf(card->snd_card->longname, sizeof(card->snd_card->longname), 1457 snprintf(card->snd_card->longname, sizeof(card->snd_card->longname),
@@ -1459,6 +1480,8 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1459 } 1480 }
1460 } 1481 }
1461 1482
1483 snd_soc_dapm_new_widgets(&card->dapm);
1484
1462 ret = snd_card_register(card->snd_card); 1485 ret = snd_card_register(card->snd_card);
1463 if (ret < 0) { 1486 if (ret < 0) {
1464 printk(KERN_ERR "asoc: failed to register soundcard for %s\n", card->name); 1487 printk(KERN_ERR "asoc: failed to register soundcard for %s\n", card->name);
@@ -1479,6 +1502,7 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1479#endif 1502#endif
1480 1503
1481 card->instantiated = 1; 1504 card->instantiated = 1;
1505 snd_soc_dapm_sync(&card->dapm);
1482 mutex_unlock(&card->mutex); 1506 mutex_unlock(&card->mutex);
1483 return; 1507 return;
1484 1508
@@ -2229,7 +2253,8 @@ EXPORT_SYMBOL_GPL(snd_soc_info_volsw_ext);
2229 * @kcontrol: mixer control 2253 * @kcontrol: mixer control
2230 * @uinfo: control element information 2254 * @uinfo: control element information
2231 * 2255 *
2232 * Callback to provide information about a single mixer control. 2256 * Callback to provide information about a single mixer control, or a double
2257 * mixer control that spans 2 registers.
2233 * 2258 *
2234 * Returns 0 for success. 2259 * Returns 0 for success.
2235 */ 2260 */
@@ -2239,8 +2264,6 @@ int snd_soc_info_volsw(struct snd_kcontrol *kcontrol,
2239 struct soc_mixer_control *mc = 2264 struct soc_mixer_control *mc =
2240 (struct soc_mixer_control *)kcontrol->private_value; 2265 (struct soc_mixer_control *)kcontrol->private_value;
2241 int platform_max; 2266 int platform_max;
2242 unsigned int shift = mc->shift;
2243 unsigned int rshift = mc->rshift;
2244 2267
2245 if (!mc->platform_max) 2268 if (!mc->platform_max)
2246 mc->platform_max = mc->max; 2269 mc->platform_max = mc->max;
@@ -2251,7 +2274,7 @@ int snd_soc_info_volsw(struct snd_kcontrol *kcontrol,
2251 else 2274 else
2252 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 2275 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2253 2276
2254 uinfo->count = shift == rshift ? 1 : 2; 2277 uinfo->count = snd_soc_volsw_is_stereo(mc) ? 2 : 1;
2255 uinfo->value.integer.min = 0; 2278 uinfo->value.integer.min = 0;
2256 uinfo->value.integer.max = platform_max; 2279 uinfo->value.integer.max = platform_max;
2257 return 0; 2280 return 0;
@@ -2263,7 +2286,8 @@ EXPORT_SYMBOL_GPL(snd_soc_info_volsw);
2263 * @kcontrol: mixer control 2286 * @kcontrol: mixer control
2264 * @ucontrol: control element information 2287 * @ucontrol: control element information
2265 * 2288 *
2266 * Callback to get the value of a single mixer control. 2289 * Callback to get the value of a single mixer control, or a double mixer
2290 * control that spans 2 registers.
2267 * 2291 *
2268 * Returns 0 for success. 2292 * Returns 0 for success.
2269 */ 2293 */
@@ -2274,6 +2298,7 @@ int snd_soc_get_volsw(struct snd_kcontrol *kcontrol,
2274 (struct soc_mixer_control *)kcontrol->private_value; 2298 (struct soc_mixer_control *)kcontrol->private_value;
2275 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 2299 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2276 unsigned int reg = mc->reg; 2300 unsigned int reg = mc->reg;
2301 unsigned int reg2 = mc->rreg;
2277 unsigned int shift = mc->shift; 2302 unsigned int shift = mc->shift;
2278 unsigned int rshift = mc->rshift; 2303 unsigned int rshift = mc->rshift;
2279 int max = mc->max; 2304 int max = mc->max;
@@ -2282,13 +2307,18 @@ int snd_soc_get_volsw(struct snd_kcontrol *kcontrol,
2282 2307
2283 ucontrol->value.integer.value[0] = 2308 ucontrol->value.integer.value[0] =
2284 (snd_soc_read(codec, reg) >> shift) & mask; 2309 (snd_soc_read(codec, reg) >> shift) & mask;
2285 if (shift != rshift) 2310 if (invert)
2286 ucontrol->value.integer.value[1] =
2287 (snd_soc_read(codec, reg) >> rshift) & mask;
2288 if (invert) {
2289 ucontrol->value.integer.value[0] = 2311 ucontrol->value.integer.value[0] =
2290 max - ucontrol->value.integer.value[0]; 2312 max - ucontrol->value.integer.value[0];
2291 if (shift != rshift) 2313
2314 if (snd_soc_volsw_is_stereo(mc)) {
2315 if (reg == reg2)
2316 ucontrol->value.integer.value[1] =
2317 (snd_soc_read(codec, reg) >> rshift) & mask;
2318 else
2319 ucontrol->value.integer.value[1] =
2320 (snd_soc_read(codec, reg2) >> shift) & mask;
2321 if (invert)
2292 ucontrol->value.integer.value[1] = 2322 ucontrol->value.integer.value[1] =
2293 max - ucontrol->value.integer.value[1]; 2323 max - ucontrol->value.integer.value[1];
2294 } 2324 }
@@ -2302,7 +2332,8 @@ EXPORT_SYMBOL_GPL(snd_soc_get_volsw);
2302 * @kcontrol: mixer control 2332 * @kcontrol: mixer control
2303 * @ucontrol: control element information 2333 * @ucontrol: control element information
2304 * 2334 *
2305 * Callback to set the value of a single mixer control. 2335 * Callback to set the value of a single mixer control, or a double mixer
2336 * control that spans 2 registers.
2306 * 2337 *
2307 * Returns 0 for success. 2338 * Returns 0 for success.
2308 */ 2339 */
@@ -2313,143 +2344,44 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
2313 (struct soc_mixer_control *)kcontrol->private_value; 2344 (struct soc_mixer_control *)kcontrol->private_value;
2314 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 2345 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2315 unsigned int reg = mc->reg; 2346 unsigned int reg = mc->reg;
2347 unsigned int reg2 = mc->rreg;
2316 unsigned int shift = mc->shift; 2348 unsigned int shift = mc->shift;
2317 unsigned int rshift = mc->rshift; 2349 unsigned int rshift = mc->rshift;
2318 int max = mc->max; 2350 int max = mc->max;
2319 unsigned int mask = (1 << fls(max)) - 1; 2351 unsigned int mask = (1 << fls(max)) - 1;
2320 unsigned int invert = mc->invert; 2352 unsigned int invert = mc->invert;
2321 unsigned int val, val2, val_mask; 2353 int err;
2354 bool type_2r = 0;
2355 unsigned int val2 = 0;
2356 unsigned int val, val_mask;
2322 2357
2323 val = (ucontrol->value.integer.value[0] & mask); 2358 val = (ucontrol->value.integer.value[0] & mask);
2324 if (invert) 2359 if (invert)
2325 val = max - val; 2360 val = max - val;
2326 val_mask = mask << shift; 2361 val_mask = mask << shift;
2327 val = val << shift; 2362 val = val << shift;
2328 if (shift != rshift) { 2363 if (snd_soc_volsw_is_stereo(mc)) {
2329 val2 = (ucontrol->value.integer.value[1] & mask); 2364 val2 = (ucontrol->value.integer.value[1] & mask);
2330 if (invert) 2365 if (invert)
2331 val2 = max - val2; 2366 val2 = max - val2;
2332 val_mask |= mask << rshift; 2367 if (reg == reg2) {
2333 val |= val2 << rshift; 2368 val_mask |= mask << rshift;
2334 } 2369 val |= val2 << rshift;
2335 return snd_soc_update_bits_locked(codec, reg, val_mask, val); 2370 } else {
2336} 2371 val2 = val2 << shift;
2337EXPORT_SYMBOL_GPL(snd_soc_put_volsw); 2372 type_2r = 1;
2338 2373 }
2339/**
2340 * snd_soc_info_volsw_2r - double mixer info callback
2341 * @kcontrol: mixer control
2342 * @uinfo: control element information
2343 *
2344 * Callback to provide information about a double mixer control that
2345 * spans 2 codec registers.
2346 *
2347 * Returns 0 for success.
2348 */
2349int snd_soc_info_volsw_2r(struct snd_kcontrol *kcontrol,
2350 struct snd_ctl_elem_info *uinfo)
2351{
2352 struct soc_mixer_control *mc =
2353 (struct soc_mixer_control *)kcontrol->private_value;
2354 int platform_max;
2355
2356 if (!mc->platform_max)
2357 mc->platform_max = mc->max;
2358 platform_max = mc->platform_max;
2359
2360 if (platform_max == 1 && !strstr(kcontrol->id.name, " Volume"))
2361 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
2362 else
2363 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2364
2365 uinfo->count = 2;
2366 uinfo->value.integer.min = 0;
2367 uinfo->value.integer.max = platform_max;
2368 return 0;
2369}
2370EXPORT_SYMBOL_GPL(snd_soc_info_volsw_2r);
2371
2372/**
2373 * snd_soc_get_volsw_2r - double mixer get callback
2374 * @kcontrol: mixer control
2375 * @ucontrol: control element information
2376 *
2377 * Callback to get the value of a double mixer control that spans 2 registers.
2378 *
2379 * Returns 0 for success.
2380 */
2381int snd_soc_get_volsw_2r(struct snd_kcontrol *kcontrol,
2382 struct snd_ctl_elem_value *ucontrol)
2383{
2384 struct soc_mixer_control *mc =
2385 (struct soc_mixer_control *)kcontrol->private_value;
2386 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2387 unsigned int reg = mc->reg;
2388 unsigned int reg2 = mc->rreg;
2389 unsigned int shift = mc->shift;
2390 int max = mc->max;
2391 unsigned int mask = (1 << fls(max)) - 1;
2392 unsigned int invert = mc->invert;
2393
2394 ucontrol->value.integer.value[0] =
2395 (snd_soc_read(codec, reg) >> shift) & mask;
2396 ucontrol->value.integer.value[1] =
2397 (snd_soc_read(codec, reg2) >> shift) & mask;
2398 if (invert) {
2399 ucontrol->value.integer.value[0] =
2400 max - ucontrol->value.integer.value[0];
2401 ucontrol->value.integer.value[1] =
2402 max - ucontrol->value.integer.value[1];
2403 }
2404
2405 return 0;
2406}
2407EXPORT_SYMBOL_GPL(snd_soc_get_volsw_2r);
2408
2409/**
2410 * snd_soc_put_volsw_2r - double mixer set callback
2411 * @kcontrol: mixer control
2412 * @ucontrol: control element information
2413 *
2414 * Callback to set the value of a double mixer control that spans 2 registers.
2415 *
2416 * Returns 0 for success.
2417 */
2418int snd_soc_put_volsw_2r(struct snd_kcontrol *kcontrol,
2419 struct snd_ctl_elem_value *ucontrol)
2420{
2421 struct soc_mixer_control *mc =
2422 (struct soc_mixer_control *)kcontrol->private_value;
2423 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2424 unsigned int reg = mc->reg;
2425 unsigned int reg2 = mc->rreg;
2426 unsigned int shift = mc->shift;
2427 int max = mc->max;
2428 unsigned int mask = (1 << fls(max)) - 1;
2429 unsigned int invert = mc->invert;
2430 int err;
2431 unsigned int val, val2, val_mask;
2432
2433 val_mask = mask << shift;
2434 val = (ucontrol->value.integer.value[0] & mask);
2435 val2 = (ucontrol->value.integer.value[1] & mask);
2436
2437 if (invert) {
2438 val = max - val;
2439 val2 = max - val2;
2440 } 2374 }
2441
2442 val = val << shift;
2443 val2 = val2 << shift;
2444
2445 err = snd_soc_update_bits_locked(codec, reg, val_mask, val); 2375 err = snd_soc_update_bits_locked(codec, reg, val_mask, val);
2446 if (err < 0) 2376 if (err < 0)
2447 return err; 2377 return err;
2448 2378
2449 err = snd_soc_update_bits_locked(codec, reg2, val_mask, val2); 2379 if (type_2r)
2380 err = snd_soc_update_bits_locked(codec, reg2, val_mask, val2);
2381
2450 return err; 2382 return err;
2451} 2383}
2452EXPORT_SYMBOL_GPL(snd_soc_put_volsw_2r); 2384EXPORT_SYMBOL_GPL(snd_soc_put_volsw);
2453 2385
2454/** 2386/**
2455 * snd_soc_info_volsw_s8 - signed mixer info callback 2387 * snd_soc_info_volsw_s8 - signed mixer info callback
@@ -2680,7 +2612,7 @@ int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
2680 if (dai->driver && dai->driver->ops->set_sysclk) 2612 if (dai->driver && dai->driver->ops->set_sysclk)
2681 return dai->driver->ops->set_sysclk(dai, clk_id, freq, dir); 2613 return dai->driver->ops->set_sysclk(dai, clk_id, freq, dir);
2682 else if (dai->codec && dai->codec->driver->set_sysclk) 2614 else if (dai->codec && dai->codec->driver->set_sysclk)
2683 return dai->codec->driver->set_sysclk(dai->codec, clk_id, 2615 return dai->codec->driver->set_sysclk(dai->codec, clk_id, 0,
2684 freq, dir); 2616 freq, dir);
2685 else 2617 else
2686 return -EINVAL; 2618 return -EINVAL;
@@ -2691,16 +2623,18 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_sysclk);
2691 * snd_soc_codec_set_sysclk - configure CODEC system or master clock. 2623 * snd_soc_codec_set_sysclk - configure CODEC system or master clock.
2692 * @codec: CODEC 2624 * @codec: CODEC
2693 * @clk_id: DAI specific clock ID 2625 * @clk_id: DAI specific clock ID
2626 * @source: Source for the clock
2694 * @freq: new clock frequency in Hz 2627 * @freq: new clock frequency in Hz
2695 * @dir: new clock direction - input/output. 2628 * @dir: new clock direction - input/output.
2696 * 2629 *
2697 * Configures the CODEC master (MCLK) or system (SYSCLK) clocking. 2630 * Configures the CODEC master (MCLK) or system (SYSCLK) clocking.
2698 */ 2631 */
2699int snd_soc_codec_set_sysclk(struct snd_soc_codec *codec, int clk_id, 2632int snd_soc_codec_set_sysclk(struct snd_soc_codec *codec, int clk_id,
2700 unsigned int freq, int dir) 2633 int source, unsigned int freq, int dir)
2701{ 2634{
2702 if (codec->driver->set_sysclk) 2635 if (codec->driver->set_sysclk)
2703 return codec->driver->set_sysclk(codec, clk_id, freq, dir); 2636 return codec->driver->set_sysclk(codec, clk_id, source,
2637 freq, dir);
2704 else 2638 else
2705 return -EINVAL; 2639 return -EINVAL;
2706} 2640}
@@ -2895,6 +2829,7 @@ int snd_soc_register_card(struct snd_soc_card *card)
2895 card->rtd[i].dai_link = &card->dai_link[i]; 2829 card->rtd[i].dai_link = &card->dai_link[i];
2896 2830
2897 INIT_LIST_HEAD(&card->list); 2831 INIT_LIST_HEAD(&card->list);
2832 INIT_LIST_HEAD(&card->dapm_dirty);
2898 card->instantiated = 0; 2833 card->instantiated = 0;
2899 mutex_init(&card->mutex); 2834 mutex_init(&card->mutex);
2900 2835
@@ -3153,6 +3088,7 @@ int snd_soc_register_platform(struct device *dev,
3153 platform->driver = platform_drv; 3088 platform->driver = platform_drv;
3154 platform->dapm.dev = dev; 3089 platform->dapm.dev = dev;
3155 platform->dapm.platform = platform; 3090 platform->dapm.platform = platform;
3091 platform->dapm.stream_event = platform_drv->stream_event;
3156 3092
3157 mutex_lock(&client_mutex); 3093 mutex_lock(&client_mutex);
3158 list_add(&platform->list, &platform_list); 3094 list_add(&platform->list, &platform_list);
@@ -3265,6 +3201,7 @@ int snd_soc_register_codec(struct device *dev,
3265 codec->dapm.dev = dev; 3201 codec->dapm.dev = dev;
3266 codec->dapm.codec = codec; 3202 codec->dapm.codec = codec;
3267 codec->dapm.seq_notifier = codec_drv->seq_notifier; 3203 codec->dapm.seq_notifier = codec_drv->seq_notifier;
3204 codec->dapm.stream_event = codec_drv->stream_event;
3268 codec->dev = dev; 3205 codec->dev = dev;
3269 codec->driver = codec_drv; 3206 codec->driver = codec_drv;
3270 codec->num_dai = num_dai; 3207 codec->num_dai = num_dai;
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index d67c637557a..f42e8b9fb17 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -48,6 +48,8 @@
48 48
49#include <trace/events/asoc.h> 49#include <trace/events/asoc.h>
50 50
51#define DAPM_UPDATE_STAT(widget, val) widget->dapm->card->dapm_stats.val++;
52
51/* dapm power sequences - make this per codec in the future */ 53/* dapm power sequences - make this per codec in the future */
52static int dapm_up_seq[] = { 54static int dapm_up_seq[] = {
53 [snd_soc_dapm_pre] = 0, 55 [snd_soc_dapm_pre] = 0,
@@ -117,6 +119,21 @@ static void pop_dbg(struct device *dev, u32 pop_time, const char *fmt, ...)
117 kfree(buf); 119 kfree(buf);
118} 120}
119 121
122static bool dapm_dirty_widget(struct snd_soc_dapm_widget *w)
123{
124 return !list_empty(&w->dirty);
125}
126
127void dapm_mark_dirty(struct snd_soc_dapm_widget *w, const char *reason)
128{
129 if (!dapm_dirty_widget(w)) {
130 dev_vdbg(w->dapm->dev, "Marking %s dirty due to %s\n",
131 w->name, reason);
132 list_add_tail(&w->dirty, &w->dapm->card->dapm_dirty);
133 }
134}
135EXPORT_SYMBOL_GPL(dapm_mark_dirty);
136
120/* create a new dapm widget */ 137/* create a new dapm widget */
121static inline struct snd_soc_dapm_widget *dapm_cnew_widget( 138static inline struct snd_soc_dapm_widget *dapm_cnew_widget(
122 const struct snd_soc_dapm_widget *_widget) 139 const struct snd_soc_dapm_widget *_widget)
@@ -316,7 +333,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
316 } 333 }
317 } 334 }
318 break; 335 break;
319 /* does not effect routing - always connected */ 336 /* does not affect routing - always connected */
320 case snd_soc_dapm_pga: 337 case snd_soc_dapm_pga:
321 case snd_soc_dapm_out_drv: 338 case snd_soc_dapm_out_drv:
322 case snd_soc_dapm_output: 339 case snd_soc_dapm_output:
@@ -328,13 +345,13 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
328 case snd_soc_dapm_supply: 345 case snd_soc_dapm_supply:
329 case snd_soc_dapm_aif_in: 346 case snd_soc_dapm_aif_in:
330 case snd_soc_dapm_aif_out: 347 case snd_soc_dapm_aif_out:
331 p->connect = 1;
332 break;
333 /* does effect routing - dynamically connected */
334 case snd_soc_dapm_hp: 348 case snd_soc_dapm_hp:
335 case snd_soc_dapm_mic: 349 case snd_soc_dapm_mic:
336 case snd_soc_dapm_spk: 350 case snd_soc_dapm_spk:
337 case snd_soc_dapm_line: 351 case snd_soc_dapm_line:
352 p->connect = 1;
353 break;
354 /* does affect routing - dynamically connected */
338 case snd_soc_dapm_pre: 355 case snd_soc_dapm_pre:
339 case snd_soc_dapm_post: 356 case snd_soc_dapm_post:
340 p->connect = 0; 357 p->connect = 0;
@@ -443,6 +460,11 @@ static int dapm_new_mixer(struct snd_soc_dapm_widget *w)
443 if (path->name != (char *)w->kcontrol_news[i].name) 460 if (path->name != (char *)w->kcontrol_news[i].name)
444 continue; 461 continue;
445 462
463 if (w->kcontrols[i]) {
464 path->kcontrol = w->kcontrols[i];
465 continue;
466 }
467
446 wlistsize = sizeof(struct snd_soc_dapm_widget_list) + 468 wlistsize = sizeof(struct snd_soc_dapm_widget_list) +
447 sizeof(struct snd_soc_dapm_widget *), 469 sizeof(struct snd_soc_dapm_widget *),
448 wlist = kzalloc(wlistsize, GFP_KERNEL); 470 wlist = kzalloc(wlistsize, GFP_KERNEL);
@@ -579,8 +601,8 @@ static int dapm_new_mux(struct snd_soc_dapm_widget *w)
579 name + prefix_len, prefix); 601 name + prefix_len, prefix);
580 ret = snd_ctl_add(card, kcontrol); 602 ret = snd_ctl_add(card, kcontrol);
581 if (ret < 0) { 603 if (ret < 0) {
582 dev_err(dapm->dev, 604 dev_err(dapm->dev, "failed to add kcontrol %s: %d\n",
583 "asoc: failed to add kcontrol %s\n", w->name); 605 w->name, ret);
584 kfree(wlist); 606 kfree(wlist);
585 return ret; 607 return ret;
586 } 608 }
@@ -644,30 +666,45 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget)
644 struct snd_soc_dapm_path *path; 666 struct snd_soc_dapm_path *path;
645 int con = 0; 667 int con = 0;
646 668
669 if (widget->outputs >= 0)
670 return widget->outputs;
671
672 DAPM_UPDATE_STAT(widget, path_checks);
673
647 if (widget->id == snd_soc_dapm_supply) 674 if (widget->id == snd_soc_dapm_supply)
648 return 0; 675 return 0;
649 676
650 switch (widget->id) { 677 switch (widget->id) {
651 case snd_soc_dapm_adc: 678 case snd_soc_dapm_adc:
652 case snd_soc_dapm_aif_out: 679 case snd_soc_dapm_aif_out:
653 if (widget->active) 680 if (widget->active) {
654 return snd_soc_dapm_suspend_check(widget); 681 widget->outputs = snd_soc_dapm_suspend_check(widget);
682 return widget->outputs;
683 }
655 default: 684 default:
656 break; 685 break;
657 } 686 }
658 687
659 if (widget->connected) { 688 if (widget->connected) {
660 /* connected pin ? */ 689 /* connected pin ? */
661 if (widget->id == snd_soc_dapm_output && !widget->ext) 690 if (widget->id == snd_soc_dapm_output && !widget->ext) {
662 return snd_soc_dapm_suspend_check(widget); 691 widget->outputs = snd_soc_dapm_suspend_check(widget);
692 return widget->outputs;
693 }
663 694
664 /* connected jack or spk ? */ 695 /* connected jack or spk ? */
665 if (widget->id == snd_soc_dapm_hp || widget->id == snd_soc_dapm_spk || 696 if (widget->id == snd_soc_dapm_hp ||
666 (widget->id == snd_soc_dapm_line && !list_empty(&widget->sources))) 697 widget->id == snd_soc_dapm_spk ||
667 return snd_soc_dapm_suspend_check(widget); 698 (widget->id == snd_soc_dapm_line &&
699 !list_empty(&widget->sources))) {
700 widget->outputs = snd_soc_dapm_suspend_check(widget);
701 return widget->outputs;
702 }
668 } 703 }
669 704
670 list_for_each_entry(path, &widget->sinks, list_source) { 705 list_for_each_entry(path, &widget->sinks, list_source) {
706 DAPM_UPDATE_STAT(widget, neighbour_checks);
707
671 if (path->weak) 708 if (path->weak)
672 continue; 709 continue;
673 710
@@ -680,6 +717,8 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget)
680 } 717 }
681 } 718 }
682 719
720 widget->outputs = con;
721
683 return con; 722 return con;
684} 723}
685 724
@@ -692,6 +731,11 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget)
692 struct snd_soc_dapm_path *path; 731 struct snd_soc_dapm_path *path;
693 int con = 0; 732 int con = 0;
694 733
734 if (widget->inputs >= 0)
735 return widget->inputs;
736
737 DAPM_UPDATE_STAT(widget, path_checks);
738
695 if (widget->id == snd_soc_dapm_supply) 739 if (widget->id == snd_soc_dapm_supply)
696 return 0; 740 return 0;
697 741
@@ -699,28 +743,40 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget)
699 switch (widget->id) { 743 switch (widget->id) {
700 case snd_soc_dapm_dac: 744 case snd_soc_dapm_dac:
701 case snd_soc_dapm_aif_in: 745 case snd_soc_dapm_aif_in:
702 if (widget->active) 746 if (widget->active) {
703 return snd_soc_dapm_suspend_check(widget); 747 widget->inputs = snd_soc_dapm_suspend_check(widget);
748 return widget->inputs;
749 }
704 default: 750 default:
705 break; 751 break;
706 } 752 }
707 753
708 if (widget->connected) { 754 if (widget->connected) {
709 /* connected pin ? */ 755 /* connected pin ? */
710 if (widget->id == snd_soc_dapm_input && !widget->ext) 756 if (widget->id == snd_soc_dapm_input && !widget->ext) {
711 return snd_soc_dapm_suspend_check(widget); 757 widget->inputs = snd_soc_dapm_suspend_check(widget);
758 return widget->inputs;
759 }
712 760
713 /* connected VMID/Bias for lower pops */ 761 /* connected VMID/Bias for lower pops */
714 if (widget->id == snd_soc_dapm_vmid) 762 if (widget->id == snd_soc_dapm_vmid) {
715 return snd_soc_dapm_suspend_check(widget); 763 widget->inputs = snd_soc_dapm_suspend_check(widget);
764 return widget->inputs;
765 }
716 766
717 /* connected jack ? */ 767 /* connected jack ? */
718 if (widget->id == snd_soc_dapm_mic || 768 if (widget->id == snd_soc_dapm_mic ||
719 (widget->id == snd_soc_dapm_line && !list_empty(&widget->sinks))) 769 (widget->id == snd_soc_dapm_line &&
720 return snd_soc_dapm_suspend_check(widget); 770 !list_empty(&widget->sinks))) {
771 widget->inputs = snd_soc_dapm_suspend_check(widget);
772 return widget->inputs;
773 }
774
721 } 775 }
722 776
723 list_for_each_entry(path, &widget->sources, list_sink) { 777 list_for_each_entry(path, &widget->sources, list_sink) {
778 DAPM_UPDATE_STAT(widget, neighbour_checks);
779
724 if (path->weak) 780 if (path->weak)
725 continue; 781 continue;
726 782
@@ -733,6 +789,8 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget)
733 } 789 }
734 } 790 }
735 791
792 widget->inputs = con;
793
736 return con; 794 return con;
737} 795}
738 796
@@ -756,12 +814,29 @@ int dapm_reg_event(struct snd_soc_dapm_widget *w,
756} 814}
757EXPORT_SYMBOL_GPL(dapm_reg_event); 815EXPORT_SYMBOL_GPL(dapm_reg_event);
758 816
817static int dapm_widget_power_check(struct snd_soc_dapm_widget *w)
818{
819 if (w->power_checked)
820 return w->new_power;
821
822 if (w->force)
823 w->new_power = 1;
824 else
825 w->new_power = w->power_check(w);
826
827 w->power_checked = true;
828
829 return w->new_power;
830}
831
759/* Generic check to see if a widget should be powered. 832/* Generic check to see if a widget should be powered.
760 */ 833 */
761static int dapm_generic_check_power(struct snd_soc_dapm_widget *w) 834static int dapm_generic_check_power(struct snd_soc_dapm_widget *w)
762{ 835{
763 int in, out; 836 int in, out;
764 837
838 DAPM_UPDATE_STAT(w, power_checks);
839
765 in = is_connected_input_ep(w); 840 in = is_connected_input_ep(w);
766 dapm_clear_walk(w->dapm); 841 dapm_clear_walk(w->dapm);
767 out = is_connected_output_ep(w); 842 out = is_connected_output_ep(w);
@@ -774,6 +849,8 @@ static int dapm_adc_check_power(struct snd_soc_dapm_widget *w)
774{ 849{
775 int in; 850 int in;
776 851
852 DAPM_UPDATE_STAT(w, power_checks);
853
777 if (w->active) { 854 if (w->active) {
778 in = is_connected_input_ep(w); 855 in = is_connected_input_ep(w);
779 dapm_clear_walk(w->dapm); 856 dapm_clear_walk(w->dapm);
@@ -788,6 +865,8 @@ static int dapm_dac_check_power(struct snd_soc_dapm_widget *w)
788{ 865{
789 int out; 866 int out;
790 867
868 DAPM_UPDATE_STAT(w, power_checks);
869
791 if (w->active) { 870 if (w->active) {
792 out = is_connected_output_ep(w); 871 out = is_connected_output_ep(w);
793 dapm_clear_walk(w->dapm); 872 dapm_clear_walk(w->dapm);
@@ -801,10 +880,13 @@ static int dapm_dac_check_power(struct snd_soc_dapm_widget *w)
801static int dapm_supply_check_power(struct snd_soc_dapm_widget *w) 880static int dapm_supply_check_power(struct snd_soc_dapm_widget *w)
802{ 881{
803 struct snd_soc_dapm_path *path; 882 struct snd_soc_dapm_path *path;
804 int power = 0; 883
884 DAPM_UPDATE_STAT(w, power_checks);
805 885
806 /* Check if one of our outputs is connected */ 886 /* Check if one of our outputs is connected */
807 list_for_each_entry(path, &w->sinks, list_source) { 887 list_for_each_entry(path, &w->sinks, list_source) {
888 DAPM_UPDATE_STAT(w, neighbour_checks);
889
808 if (path->weak) 890 if (path->weak)
809 continue; 891 continue;
810 892
@@ -815,21 +897,18 @@ static int dapm_supply_check_power(struct snd_soc_dapm_widget *w)
815 if (!path->sink) 897 if (!path->sink)
816 continue; 898 continue;
817 899
818 if (path->sink->force) { 900 if (dapm_widget_power_check(path->sink))
819 power = 1; 901 return 1;
820 break;
821 }
822
823 if (path->sink->power_check &&
824 path->sink->power_check(path->sink)) {
825 power = 1;
826 break;
827 }
828 } 902 }
829 903
830 dapm_clear_walk(w->dapm); 904 dapm_clear_walk(w->dapm);
831 905
832 return power; 906 return 0;
907}
908
909static int dapm_always_on_check_power(struct snd_soc_dapm_widget *w)
910{
911 return 1;
833} 912}
834 913
835static int dapm_seq_compare(struct snd_soc_dapm_widget *a, 914static int dapm_seq_compare(struct snd_soc_dapm_widget *a,
@@ -1172,6 +1251,85 @@ static void dapm_post_sequence_async(void *data, async_cookie_t cookie)
1172 } 1251 }
1173} 1252}
1174 1253
1254static void dapm_widget_set_peer_power(struct snd_soc_dapm_widget *peer,
1255 bool power, bool connect)
1256{
1257 /* If a connection is being made or broken then that update
1258 * will have marked the peer dirty, otherwise the widgets are
1259 * not connected and this update has no impact. */
1260 if (!connect)
1261 return;
1262
1263 /* If the peer is already in the state we're moving to then we
1264 * won't have an impact on it. */
1265 if (power != peer->power)
1266 dapm_mark_dirty(peer, "peer state change");
1267}
1268
1269static void dapm_widget_set_power(struct snd_soc_dapm_widget *w, bool power,
1270 struct list_head *up_list,
1271 struct list_head *down_list)
1272{
1273 struct snd_soc_dapm_path *path;
1274
1275 if (w->power == power)
1276 return;
1277
1278 trace_snd_soc_dapm_widget_power(w, power);
1279
1280 /* If we changed our power state perhaps our neigbours changed
1281 * also.
1282 */
1283 list_for_each_entry(path, &w->sources, list_sink) {
1284 if (path->source) {
1285 dapm_widget_set_peer_power(path->source, power,
1286 path->connect);
1287 }
1288 }
1289 switch (w->id) {
1290 case snd_soc_dapm_supply:
1291 /* Supplies can't affect their outputs, only their inputs */
1292 break;
1293 default:
1294 list_for_each_entry(path, &w->sinks, list_source) {
1295 if (path->sink) {
1296 dapm_widget_set_peer_power(path->sink, power,
1297 path->connect);
1298 }
1299 }
1300 break;
1301 }
1302
1303 if (power)
1304 dapm_seq_insert(w, up_list, true);
1305 else
1306 dapm_seq_insert(w, down_list, false);
1307
1308 w->power = power;
1309}
1310
1311static void dapm_power_one_widget(struct snd_soc_dapm_widget *w,
1312 struct list_head *up_list,
1313 struct list_head *down_list)
1314{
1315 int power;
1316
1317 switch (w->id) {
1318 case snd_soc_dapm_pre:
1319 dapm_seq_insert(w, down_list, false);
1320 break;
1321 case snd_soc_dapm_post:
1322 dapm_seq_insert(w, up_list, true);
1323 break;
1324
1325 default:
1326 power = dapm_widget_power_check(w);
1327
1328 dapm_widget_set_power(w, power, up_list, down_list);
1329 break;
1330 }
1331}
1332
1175/* 1333/*
1176 * Scan each dapm widget for complete audio path. 1334 * Scan each dapm widget for complete audio path.
1177 * A complete path is a route that has valid endpoints i.e.:- 1335 * A complete path is a route that has valid endpoints i.e.:-
@@ -1190,7 +1348,6 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1190 LIST_HEAD(down_list); 1348 LIST_HEAD(down_list);
1191 LIST_HEAD(async_domain); 1349 LIST_HEAD(async_domain);
1192 enum snd_soc_bias_level bias; 1350 enum snd_soc_bias_level bias;
1193 int power;
1194 1351
1195 trace_snd_soc_dapm_start(card); 1352 trace_snd_soc_dapm_start(card);
1196 1353
@@ -1203,61 +1360,47 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1203 } 1360 }
1204 } 1361 }
1205 1362
1206 /* Check which widgets we need to power and store them in 1363 memset(&card->dapm_stats, 0, sizeof(card->dapm_stats));
1207 * lists indicating if they should be powered up or down. 1364
1208 */
1209 list_for_each_entry(w, &card->widgets, list) { 1365 list_for_each_entry(w, &card->widgets, list) {
1210 switch (w->id) { 1366 w->power_checked = false;
1211 case snd_soc_dapm_pre: 1367 w->inputs = -1;
1212 dapm_seq_insert(w, &down_list, false); 1368 w->outputs = -1;
1213 break; 1369 }
1214 case snd_soc_dapm_post:
1215 dapm_seq_insert(w, &up_list, true);
1216 break;
1217 1370
1218 default: 1371 /* Check which widgets we need to power and store them in
1219 if (!w->power_check) 1372 * lists indicating if they should be powered up or down. We
1220 continue; 1373 * only check widgets that have been flagged as dirty but note
1374 * that new widgets may be added to the dirty list while we
1375 * iterate.
1376 */
1377 list_for_each_entry(w, &card->dapm_dirty, dirty) {
1378 dapm_power_one_widget(w, &up_list, &down_list);
1379 }
1221 1380
1222 if (!w->force) 1381 list_for_each_entry(w, &card->widgets, list) {
1223 power = w->power_check(w); 1382 list_del_init(&w->dirty);
1224 else
1225 power = 1;
1226 1383
1227 if (power) { 1384 if (w->power) {
1228 d = w->dapm; 1385 d = w->dapm;
1229 1386
1230 /* Supplies and micbiases only bring 1387 /* Supplies and micbiases only bring the
1231 * the context up to STANDBY as unless 1388 * context up to STANDBY as unless something
1232 * something else is active and 1389 * else is active and passing audio they
1233 * passing audio they generally don't 1390 * generally don't require full power.
1234 * require full power. 1391 */
1235 */ 1392 switch (w->id) {
1236 switch (w->id) { 1393 case snd_soc_dapm_supply:
1237 case snd_soc_dapm_supply: 1394 case snd_soc_dapm_micbias:
1238 case snd_soc_dapm_micbias: 1395 if (d->target_bias_level < SND_SOC_BIAS_STANDBY)
1239 if (d->target_bias_level < SND_SOC_BIAS_STANDBY) 1396 d->target_bias_level = SND_SOC_BIAS_STANDBY;
1240 d->target_bias_level = SND_SOC_BIAS_STANDBY; 1397 break;
1241 break; 1398 default:
1242 default: 1399 d->target_bias_level = SND_SOC_BIAS_ON;
1243 d->target_bias_level = SND_SOC_BIAS_ON; 1400 break;
1244 break;
1245 }
1246 } 1401 }
1247
1248 if (w->power == power)
1249 continue;
1250
1251 trace_snd_soc_dapm_widget_power(w, power);
1252
1253 if (power)
1254 dapm_seq_insert(w, &up_list, true);
1255 else
1256 dapm_seq_insert(w, &down_list, false);
1257
1258 w->power = power;
1259 break;
1260 } 1402 }
1403
1261 } 1404 }
1262 1405
1263 /* If there are no DAPM widgets then try to figure out power from the 1406 /* If there are no DAPM widgets then try to figure out power from the
@@ -1286,14 +1429,18 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1286 } 1429 }
1287 } 1430 }
1288 1431
1289 /* Force all contexts in the card to the same bias state */ 1432 /* Force all contexts in the card to the same bias state if
1433 * they're not ground referenced.
1434 */
1290 bias = SND_SOC_BIAS_OFF; 1435 bias = SND_SOC_BIAS_OFF;
1291 list_for_each_entry(d, &card->dapm_list, list) 1436 list_for_each_entry(d, &card->dapm_list, list)
1292 if (d->target_bias_level > bias) 1437 if (d->target_bias_level > bias)
1293 bias = d->target_bias_level; 1438 bias = d->target_bias_level;
1294 list_for_each_entry(d, &card->dapm_list, list) 1439 list_for_each_entry(d, &card->dapm_list, list)
1295 d->target_bias_level = bias; 1440 if (!d->idle_bias_off)
1441 d->target_bias_level = bias;
1296 1442
1443 trace_snd_soc_dapm_walk_done(card);
1297 1444
1298 /* Run all the bias changes in parallel */ 1445 /* Run all the bias changes in parallel */
1299 list_for_each_entry(d, &dapm->card->dapm_list, list) 1446 list_for_each_entry(d, &dapm->card->dapm_list, list)
@@ -1524,14 +1671,21 @@ static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
1524 1671
1525 found = 1; 1672 found = 1;
1526 /* we now need to match the string in the enum to the path */ 1673 /* we now need to match the string in the enum to the path */
1527 if (!(strcmp(path->name, e->texts[mux]))) 1674 if (!(strcmp(path->name, e->texts[mux]))) {
1528 path->connect = 1; /* new connection */ 1675 path->connect = 1; /* new connection */
1529 else 1676 dapm_mark_dirty(path->source, "mux connection");
1677 } else {
1678 if (path->connect)
1679 dapm_mark_dirty(path->source,
1680 "mux disconnection");
1530 path->connect = 0; /* old connection must be powered down */ 1681 path->connect = 0; /* old connection must be powered down */
1682 }
1531 } 1683 }
1532 1684
1533 if (found) 1685 if (found) {
1686 dapm_mark_dirty(widget, "mux change");
1534 dapm_power_widgets(widget->dapm, SND_SOC_DAPM_STREAM_NOP); 1687 dapm_power_widgets(widget->dapm, SND_SOC_DAPM_STREAM_NOP);
1688 }
1535 1689
1536 return 0; 1690 return 0;
1537} 1691}
@@ -1556,11 +1710,13 @@ static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
1556 /* found, now check type */ 1710 /* found, now check type */
1557 found = 1; 1711 found = 1;
1558 path->connect = connect; 1712 path->connect = connect;
1559 break; 1713 dapm_mark_dirty(path->source, "mixer connection");
1560 } 1714 }
1561 1715
1562 if (found) 1716 if (found) {
1717 dapm_mark_dirty(widget, "mixer update");
1563 dapm_power_widgets(widget->dapm, SND_SOC_DAPM_STREAM_NOP); 1718 dapm_power_widgets(widget->dapm, SND_SOC_DAPM_STREAM_NOP);
1719 }
1564 1720
1565 return 0; 1721 return 0;
1566} 1722}
@@ -1704,6 +1860,7 @@ static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm,
1704 w->connected = status; 1860 w->connected = status;
1705 if (status == 0) 1861 if (status == 0)
1706 w->force = 0; 1862 w->force = 0;
1863 dapm_mark_dirty(w, "pin configuration");
1707 1864
1708 return 0; 1865 return 0;
1709} 1866}
@@ -1719,6 +1876,13 @@ static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm,
1719 */ 1876 */
1720int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm) 1877int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm)
1721{ 1878{
1879 /*
1880 * Suppress early reports (eg, jacks syncing their state) to avoid
1881 * silly DAPM runs during card startup.
1882 */
1883 if (!dapm->card || !dapm->card->instantiated)
1884 return 0;
1885
1722 return dapm_power_widgets(dapm, SND_SOC_DAPM_STREAM_NOP); 1886 return dapm_power_widgets(dapm, SND_SOC_DAPM_STREAM_NOP);
1723} 1887}
1724EXPORT_SYMBOL_GPL(snd_soc_dapm_sync); 1888EXPORT_SYMBOL_GPL(snd_soc_dapm_sync);
@@ -2004,42 +2168,18 @@ int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm)
2004 case snd_soc_dapm_switch: 2168 case snd_soc_dapm_switch:
2005 case snd_soc_dapm_mixer: 2169 case snd_soc_dapm_mixer:
2006 case snd_soc_dapm_mixer_named_ctl: 2170 case snd_soc_dapm_mixer_named_ctl:
2007 w->power_check = dapm_generic_check_power;
2008 dapm_new_mixer(w); 2171 dapm_new_mixer(w);
2009 break; 2172 break;
2010 case snd_soc_dapm_mux: 2173 case snd_soc_dapm_mux:
2011 case snd_soc_dapm_virt_mux: 2174 case snd_soc_dapm_virt_mux:
2012 case snd_soc_dapm_value_mux: 2175 case snd_soc_dapm_value_mux:
2013 w->power_check = dapm_generic_check_power;
2014 dapm_new_mux(w); 2176 dapm_new_mux(w);
2015 break; 2177 break;
2016 case snd_soc_dapm_adc:
2017 case snd_soc_dapm_aif_out:
2018 w->power_check = dapm_adc_check_power;
2019 break;
2020 case snd_soc_dapm_dac:
2021 case snd_soc_dapm_aif_in:
2022 w->power_check = dapm_dac_check_power;
2023 break;
2024 case snd_soc_dapm_pga: 2178 case snd_soc_dapm_pga:
2025 case snd_soc_dapm_out_drv: 2179 case snd_soc_dapm_out_drv:
2026 w->power_check = dapm_generic_check_power;
2027 dapm_new_pga(w); 2180 dapm_new_pga(w);
2028 break; 2181 break;
2029 case snd_soc_dapm_input: 2182 default:
2030 case snd_soc_dapm_output:
2031 case snd_soc_dapm_micbias:
2032 case snd_soc_dapm_spk:
2033 case snd_soc_dapm_hp:
2034 case snd_soc_dapm_mic:
2035 case snd_soc_dapm_line:
2036 w->power_check = dapm_generic_check_power;
2037 break;
2038 case snd_soc_dapm_supply:
2039 w->power_check = dapm_supply_check_power;
2040 case snd_soc_dapm_vmid:
2041 case snd_soc_dapm_pre:
2042 case snd_soc_dapm_post:
2043 break; 2183 break;
2044 } 2184 }
2045 2185
@@ -2056,6 +2196,7 @@ int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm)
2056 2196
2057 w->new = 1; 2197 w->new = 1;
2058 2198
2199 dapm_mark_dirty(w, "new widget");
2059 dapm_debugfs_add_widget(w); 2200 dapm_debugfs_add_widget(w);
2060 } 2201 }
2061 2202
@@ -2530,6 +2671,44 @@ int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
2530 else 2671 else
2531 snprintf(w->name, name_len, "%s", widget->name); 2672 snprintf(w->name, name_len, "%s", widget->name);
2532 2673
2674 switch (w->id) {
2675 case snd_soc_dapm_switch:
2676 case snd_soc_dapm_mixer:
2677 case snd_soc_dapm_mixer_named_ctl:
2678 w->power_check = dapm_generic_check_power;
2679 break;
2680 case snd_soc_dapm_mux:
2681 case snd_soc_dapm_virt_mux:
2682 case snd_soc_dapm_value_mux:
2683 w->power_check = dapm_generic_check_power;
2684 break;
2685 case snd_soc_dapm_adc:
2686 case snd_soc_dapm_aif_out:
2687 w->power_check = dapm_adc_check_power;
2688 break;
2689 case snd_soc_dapm_dac:
2690 case snd_soc_dapm_aif_in:
2691 w->power_check = dapm_dac_check_power;
2692 break;
2693 case snd_soc_dapm_pga:
2694 case snd_soc_dapm_out_drv:
2695 case snd_soc_dapm_input:
2696 case snd_soc_dapm_output:
2697 case snd_soc_dapm_micbias:
2698 case snd_soc_dapm_spk:
2699 case snd_soc_dapm_hp:
2700 case snd_soc_dapm_mic:
2701 case snd_soc_dapm_line:
2702 w->power_check = dapm_generic_check_power;
2703 break;
2704 case snd_soc_dapm_supply:
2705 w->power_check = dapm_supply_check_power;
2706 break;
2707 default:
2708 w->power_check = dapm_always_on_check_power;
2709 break;
2710 }
2711
2533 dapm->n_widgets++; 2712 dapm->n_widgets++;
2534 w->dapm = dapm; 2713 w->dapm = dapm;
2535 w->codec = dapm->codec; 2714 w->codec = dapm->codec;
@@ -2537,6 +2716,7 @@ int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
2537 INIT_LIST_HEAD(&w->sources); 2716 INIT_LIST_HEAD(&w->sources);
2538 INIT_LIST_HEAD(&w->sinks); 2717 INIT_LIST_HEAD(&w->sinks);
2539 INIT_LIST_HEAD(&w->list); 2718 INIT_LIST_HEAD(&w->list);
2719 INIT_LIST_HEAD(&w->dirty);
2540 list_add(&w->list, &dapm->card->widgets); 2720 list_add(&w->list, &dapm->card->widgets);
2541 2721
2542 /* machine layer set ups unconnected pins and insertions */ 2722 /* machine layer set ups unconnected pins and insertions */
@@ -2584,9 +2764,10 @@ static void soc_dapm_stream_event(struct snd_soc_dapm_context *dapm,
2584 { 2764 {
2585 if (!w->sname || w->dapm != dapm) 2765 if (!w->sname || w->dapm != dapm)
2586 continue; 2766 continue;
2587 dev_dbg(w->dapm->dev, "widget %s\n %s stream %s event %d\n", 2767 dev_vdbg(w->dapm->dev, "widget %s\n %s stream %s event %d\n",
2588 w->name, w->sname, stream, event); 2768 w->name, w->sname, stream, event);
2589 if (strstr(w->sname, stream)) { 2769 if (strstr(w->sname, stream)) {
2770 dapm_mark_dirty(w, "stream event");
2590 switch(event) { 2771 switch(event) {
2591 case SND_SOC_DAPM_STREAM_START: 2772 case SND_SOC_DAPM_STREAM_START:
2592 w->active = 1; 2773 w->active = 1;
@@ -2604,6 +2785,10 @@ static void soc_dapm_stream_event(struct snd_soc_dapm_context *dapm,
2604 } 2785 }
2605 2786
2606 dapm_power_widgets(dapm, event); 2787 dapm_power_widgets(dapm, event);
2788
2789 /* do we need to notify any clients that DAPM stream is complete */
2790 if (dapm->stream_event)
2791 dapm->stream_event(dapm, event);
2607} 2792}
2608 2793
2609/** 2794/**
@@ -2672,6 +2857,7 @@ int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm,
2672 dev_dbg(w->dapm->dev, "dapm: force enable pin %s\n", pin); 2857 dev_dbg(w->dapm->dev, "dapm: force enable pin %s\n", pin);
2673 w->connected = 1; 2858 w->connected = 1;
2674 w->force = 1; 2859 w->force = 1;
2860 dapm_mark_dirty(w, "force enable");
2675 2861
2676 return 0; 2862 return 0;
2677} 2863}
diff --git a/sound/soc/soc-io.c b/sound/soc/soc-io.c
index a62f7dd4ba9..dd89933e2c7 100644
--- a/sound/soc/soc-io.c
+++ b/sound/soc/soc-io.c
@@ -13,26 +13,14 @@
13 13
14#include <linux/i2c.h> 14#include <linux/i2c.h>
15#include <linux/spi/spi.h> 15#include <linux/spi/spi.h>
16#include <linux/regmap.h>
16#include <sound/soc.h> 17#include <sound/soc.h>
17 18
18#include <trace/events/asoc.h> 19#include <trace/events/asoc.h>
19 20
20#ifdef CONFIG_SPI_MASTER 21#ifdef CONFIG_REGMAP
21static int do_spi_write(void *control, const char *data, int len) 22static int hw_write(struct snd_soc_codec *codec, unsigned int reg,
22{ 23 unsigned int value)
23 struct spi_device *spi = control;
24 int ret;
25
26 ret = spi_write(spi, data, len);
27 if (ret < 0)
28 return ret;
29
30 return len;
31}
32#endif
33
34static int do_hw_write(struct snd_soc_codec *codec, unsigned int reg,
35 unsigned int value, const void *data, int len)
36{ 24{
37 int ret; 25 int ret;
38 26
@@ -49,13 +37,7 @@ static int do_hw_write(struct snd_soc_codec *codec, unsigned int reg,
49 return 0; 37 return 0;
50 } 38 }
51 39
52 ret = codec->hw_write(codec->control_data, data, len); 40 return regmap_write(codec->control_data, reg, value);
53 if (ret == len)
54 return 0;
55 if (ret < 0)
56 return ret;
57 else
58 return -EIO;
59} 41}
60 42
61static unsigned int hw_read(struct snd_soc_codec *codec, unsigned int reg) 43static unsigned int hw_read(struct snd_soc_codec *codec, unsigned int reg)
@@ -69,8 +51,11 @@ static unsigned int hw_read(struct snd_soc_codec *codec, unsigned int reg)
69 if (codec->cache_only) 51 if (codec->cache_only)
70 return -1; 52 return -1;
71 53
72 BUG_ON(!codec->hw_read); 54 ret = regmap_read(codec->control_data, reg, &val);
73 return codec->hw_read(codec, reg); 55 if (ret == 0)
56 return val;
57 else
58 return -1;
74 } 59 }
75 60
76 ret = snd_soc_cache_read(codec, reg, &val); 61 ret = snd_soc_cache_read(codec, reg, &val);
@@ -79,202 +64,18 @@ static unsigned int hw_read(struct snd_soc_codec *codec, unsigned int reg)
79 return val; 64 return val;
80} 65}
81 66
82static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg,
83 unsigned int value)
84{
85 u16 data;
86
87 data = cpu_to_be16((reg << 12) | (value & 0xffffff));
88
89 return do_hw_write(codec, reg, value, &data, 2);
90}
91
92static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg,
93 unsigned int value)
94{
95 u16 data;
96
97 data = cpu_to_be16((reg << 9) | (value & 0x1ff));
98
99 return do_hw_write(codec, reg, value, &data, 2);
100}
101
102static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg,
103 unsigned int value)
104{
105 u8 data[2];
106
107 reg &= 0xff;
108 data[0] = reg;
109 data[1] = value & 0xff;
110
111 return do_hw_write(codec, reg, value, data, 2);
112}
113
114static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg,
115 unsigned int value)
116{
117 u8 data[3];
118 u16 val = cpu_to_be16(value);
119
120 data[0] = reg;
121 memcpy(&data[1], &val, sizeof(val));
122
123 return do_hw_write(codec, reg, value, data, 3);
124}
125
126#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
127static unsigned int do_i2c_read(struct snd_soc_codec *codec,
128 void *reg, int reglen,
129 void *data, int datalen)
130{
131 struct i2c_msg xfer[2];
132 int ret;
133 struct i2c_client *client = codec->control_data;
134
135 /* Write register */
136 xfer[0].addr = client->addr;
137 xfer[0].flags = 0;
138 xfer[0].len = reglen;
139 xfer[0].buf = reg;
140
141 /* Read data */
142 xfer[1].addr = client->addr;
143 xfer[1].flags = I2C_M_RD;
144 xfer[1].len = datalen;
145 xfer[1].buf = data;
146
147 ret = i2c_transfer(client->adapter, xfer, 2);
148 if (ret == 2)
149 return 0;
150 else if (ret < 0)
151 return ret;
152 else
153 return -EIO;
154}
155#endif
156
157#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
158static unsigned int snd_soc_8_8_read_i2c(struct snd_soc_codec *codec,
159 unsigned int r)
160{
161 u8 reg = r;
162 u8 data;
163 int ret;
164
165 ret = do_i2c_read(codec, &reg, 1, &data, 1);
166 if (ret < 0)
167 return 0;
168 return data;
169}
170#else
171#define snd_soc_8_8_read_i2c NULL
172#endif
173
174#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
175static unsigned int snd_soc_8_16_read_i2c(struct snd_soc_codec *codec,
176 unsigned int r)
177{
178 u8 reg = r;
179 u16 data;
180 int ret;
181
182 ret = do_i2c_read(codec, &reg, 1, &data, 2);
183 if (ret < 0)
184 return 0;
185 return (data >> 8) | ((data & 0xff) << 8);
186}
187#else
188#define snd_soc_8_16_read_i2c NULL
189#endif
190
191#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
192static unsigned int snd_soc_16_8_read_i2c(struct snd_soc_codec *codec,
193 unsigned int r)
194{
195 u16 reg = r;
196 u8 data;
197 int ret;
198
199 ret = do_i2c_read(codec, &reg, 2, &data, 1);
200 if (ret < 0)
201 return 0;
202 return data;
203}
204#else
205#define snd_soc_16_8_read_i2c NULL
206#endif
207
208#if defined(CONFIG_SPI_MASTER)
209static unsigned int snd_soc_16_8_read_spi(struct snd_soc_codec *codec,
210 unsigned int r)
211{
212 struct spi_device *spi = codec->control_data;
213
214 const u16 reg = cpu_to_be16(r | 0x100);
215 u8 data;
216 int ret;
217
218 ret = spi_write_then_read(spi, &reg, 2, &data, 1);
219 if (ret < 0)
220 return 0;
221 return data;
222}
223#else
224#define snd_soc_16_8_read_spi NULL
225#endif
226
227static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg,
228 unsigned int value)
229{
230 u8 data[3];
231 u16 rval = cpu_to_be16(reg);
232
233 memcpy(data, &rval, sizeof(rval));
234 data[2] = value;
235
236 return do_hw_write(codec, reg, value, data, 3);
237}
238
239#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
240static unsigned int snd_soc_16_16_read_i2c(struct snd_soc_codec *codec,
241 unsigned int r)
242{
243 u16 reg = cpu_to_be16(r);
244 u16 data;
245 int ret;
246
247 ret = do_i2c_read(codec, &reg, 2, &data, 2);
248 if (ret < 0)
249 return 0;
250 return be16_to_cpu(data);
251}
252#else
253#define snd_soc_16_16_read_i2c NULL
254#endif
255
256static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg,
257 unsigned int value)
258{
259 u16 data[2];
260
261 data[0] = cpu_to_be16(reg);
262 data[1] = cpu_to_be16(value);
263
264 return do_hw_write(codec, reg, value, data, sizeof(data));
265}
266
267/* Primitive bulk write support for soc-cache. The data pointed to by 67/* Primitive bulk write support for soc-cache. The data pointed to by
268 * `data' needs to already be in the form the hardware expects 68 * `data' needs to already be in the form the hardware expects. Any
269 * including any leading register specific data. Any data written 69 * data written through this function will not go through the cache as
270 * through this function will not go through the cache as it only 70 * it only handles writing to volatile or out of bounds registers.
271 * handles writing to volatile or out of bounds registers. 71 *
72 * This is currently only supported for devices using the regmap API
73 * wrappers.
272 */ 74 */
273static int snd_soc_hw_bulk_write_raw(struct snd_soc_codec *codec, unsigned int reg, 75static int snd_soc_hw_bulk_write_raw(struct snd_soc_codec *codec,
76 unsigned int reg,
274 const void *data, size_t len) 77 const void *data, size_t len)
275{ 78{
276 int ret;
277
278 /* To ensure that we don't get out of sync with the cache, check 79 /* To ensure that we don't get out of sync with the cache, check
279 * whether the base register is volatile or if we've directly asked 80 * whether the base register is volatile or if we've directly asked
280 * to bypass the cache. Out of bounds registers are considered 81 * to bypass the cache. Out of bounds registers are considered
@@ -285,68 +86,9 @@ static int snd_soc_hw_bulk_write_raw(struct snd_soc_codec *codec, unsigned int r
285 && reg < codec->driver->reg_cache_size) 86 && reg < codec->driver->reg_cache_size)
286 return -EINVAL; 87 return -EINVAL;
287 88
288 switch (codec->control_type) { 89 return regmap_raw_write(codec->control_data, reg, data, len);
289#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
290 case SND_SOC_I2C:
291 ret = i2c_master_send(to_i2c_client(codec->dev), data, len);
292 break;
293#endif
294#if defined(CONFIG_SPI_MASTER)
295 case SND_SOC_SPI:
296 ret = spi_write(to_spi_device(codec->dev), data, len);
297 break;
298#endif
299 default:
300 BUG();
301 }
302
303 if (ret == len)
304 return 0;
305 if (ret < 0)
306 return ret;
307 else
308 return -EIO;
309} 90}
310 91
311static struct {
312 int addr_bits;
313 int data_bits;
314 int (*write)(struct snd_soc_codec *codec, unsigned int, unsigned int);
315 unsigned int (*read)(struct snd_soc_codec *, unsigned int);
316 unsigned int (*i2c_read)(struct snd_soc_codec *, unsigned int);
317 unsigned int (*spi_read)(struct snd_soc_codec *, unsigned int);
318} io_types[] = {
319 {
320 .addr_bits = 4, .data_bits = 12,
321 .write = snd_soc_4_12_write,
322 },
323 {
324 .addr_bits = 7, .data_bits = 9,
325 .write = snd_soc_7_9_write,
326 },
327 {
328 .addr_bits = 8, .data_bits = 8,
329 .write = snd_soc_8_8_write,
330 .i2c_read = snd_soc_8_8_read_i2c,
331 },
332 {
333 .addr_bits = 8, .data_bits = 16,
334 .write = snd_soc_8_16_write,
335 .i2c_read = snd_soc_8_16_read_i2c,
336 },
337 {
338 .addr_bits = 16, .data_bits = 8,
339 .write = snd_soc_16_8_write,
340 .i2c_read = snd_soc_16_8_read_i2c,
341 .spi_read = snd_soc_16_8_read_spi,
342 },
343 {
344 .addr_bits = 16, .data_bits = 16,
345 .write = snd_soc_16_16_write,
346 .i2c_read = snd_soc_16_16_read_i2c,
347 },
348};
349
350/** 92/**
351 * snd_soc_codec_set_cache_io: Set up standard I/O functions. 93 * snd_soc_codec_set_cache_io: Set up standard I/O functions.
352 * 94 *
@@ -370,50 +112,51 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
370 int addr_bits, int data_bits, 112 int addr_bits, int data_bits,
371 enum snd_soc_control_type control) 113 enum snd_soc_control_type control)
372{ 114{
373 int i; 115 struct regmap_config config;
374
375 for (i = 0; i < ARRAY_SIZE(io_types); i++)
376 if (io_types[i].addr_bits == addr_bits &&
377 io_types[i].data_bits == data_bits)
378 break;
379 if (i == ARRAY_SIZE(io_types)) {
380 printk(KERN_ERR
381 "No I/O functions for %d bit address %d bit data\n",
382 addr_bits, data_bits);
383 return -EINVAL;
384 }
385 116
386 codec->write = io_types[i].write; 117 memset(&config, 0, sizeof(config));
118 codec->write = hw_write;
387 codec->read = hw_read; 119 codec->read = hw_read;
388 codec->bulk_write_raw = snd_soc_hw_bulk_write_raw; 120 codec->bulk_write_raw = snd_soc_hw_bulk_write_raw;
389 121
122 config.reg_bits = addr_bits;
123 config.val_bits = data_bits;
124
390 switch (control) { 125 switch (control) {
126#if defined(CONFIG_REGMAP_I2C) || defined(CONFIG_REGMAP_I2C_MODULE)
391 case SND_SOC_I2C: 127 case SND_SOC_I2C:
392#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) 128 codec->control_data = regmap_init_i2c(to_i2c_client(codec->dev),
393 codec->hw_write = (hw_write_t)i2c_master_send; 129 &config);
394#endif
395 if (io_types[i].i2c_read)
396 codec->hw_read = io_types[i].i2c_read;
397
398 codec->control_data = container_of(codec->dev,
399 struct i2c_client,
400 dev);
401 break; 130 break;
131#endif
402 132
133#if defined(CONFIG_REGMAP_SPI) || defined(CONFIG_REGMAP_SPI_MODULE)
403 case SND_SOC_SPI: 134 case SND_SOC_SPI:
404#ifdef CONFIG_SPI_MASTER 135 codec->control_data = regmap_init_spi(to_spi_device(codec->dev),
405 codec->hw_write = do_spi_write; 136 &config);
137 break;
406#endif 138#endif
407 if (io_types[i].spi_read)
408 codec->hw_read = io_types[i].spi_read;
409 139
410 codec->control_data = container_of(codec->dev, 140 case SND_SOC_REGMAP:
411 struct spi_device, 141 /* Device has made its own regmap arrangements */
412 dev);
413 break; 142 break;
143
144 default:
145 return -EINVAL;
414 } 146 }
415 147
148 if (IS_ERR(codec->control_data))
149 return PTR_ERR(codec->control_data);
150
416 return 0; 151 return 0;
417} 152}
418EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io); 153EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io);
419 154#else
155int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
156 int addr_bits, int data_bits,
157 enum snd_soc_control_type control)
158{
159 return -ENOTSUPP;
160}
161EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io);
162#endif
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c
index fa31d9c2abd..52db9663629 100644
--- a/sound/soc/soc-jack.c
+++ b/sound/soc/soc-jack.c
@@ -188,6 +188,8 @@ int snd_soc_jack_add_pins(struct snd_soc_jack *jack, int count,
188 list_add(&(pins[i].list), &jack->pins); 188 list_add(&(pins[i].list), &jack->pins);
189 } 189 }
190 190
191 snd_soc_dapm_new_widgets(&jack->codec->card->dapm);
192
191 /* Update to reflect the last reported status; canned jack 193 /* Update to reflect the last reported status; canned jack
192 * implementations are likely to set their state before the 194 * implementations are likely to set their state before the
193 * card has an opportunity to associate pins. 195 * card has an opportunity to associate pins.
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 2879c883eeb..ee15337353f 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -27,17 +27,13 @@
27#include <sound/soc.h> 27#include <sound/soc.h>
28#include <sound/initval.h> 28#include <sound/initval.h>
29 29
30static DEFINE_MUTEX(pcm_mutex); 30static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream,
31 31 struct snd_soc_dai *soc_dai)
32static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream)
33{ 32{
34 struct snd_soc_pcm_runtime *rtd = substream->private_data; 33 struct snd_soc_pcm_runtime *rtd = substream->private_data;
35 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
36 struct snd_soc_dai *codec_dai = rtd->codec_dai;
37 int ret; 34 int ret;
38 35
39 if (!codec_dai->driver->symmetric_rates && 36 if (!soc_dai->driver->symmetric_rates &&
40 !cpu_dai->driver->symmetric_rates &&
41 !rtd->dai_link->symmetric_rates) 37 !rtd->dai_link->symmetric_rates)
42 return 0; 38 return 0;
43 39
@@ -45,19 +41,19 @@ static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream)
45 * the second can need to get its constraints before the first has 41 * the second can need to get its constraints before the first has
46 * picked a rate. Complain and allow the application to carry on. 42 * picked a rate. Complain and allow the application to carry on.
47 */ 43 */
48 if (!rtd->rate) { 44 if (!soc_dai->rate) {
49 dev_warn(&rtd->dev, 45 dev_warn(soc_dai->dev,
50 "Not enforcing symmetric_rates due to race\n"); 46 "Not enforcing symmetric_rates due to race\n");
51 return 0; 47 return 0;
52 } 48 }
53 49
54 dev_dbg(&rtd->dev, "Symmetry forces %dHz rate\n", rtd->rate); 50 dev_dbg(soc_dai->dev, "Symmetry forces %dHz rate\n", soc_dai->rate);
55 51
56 ret = snd_pcm_hw_constraint_minmax(substream->runtime, 52 ret = snd_pcm_hw_constraint_minmax(substream->runtime,
57 SNDRV_PCM_HW_PARAM_RATE, 53 SNDRV_PCM_HW_PARAM_RATE,
58 rtd->rate, rtd->rate); 54 soc_dai->rate, soc_dai->rate);
59 if (ret < 0) { 55 if (ret < 0) {
60 dev_err(&rtd->dev, 56 dev_err(soc_dai->dev,
61 "Unable to apply rate symmetry constraint: %d\n", ret); 57 "Unable to apply rate symmetry constraint: %d\n", ret);
62 return ret; 58 return ret;
63 } 59 }
@@ -187,8 +183,14 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
187 } 183 }
188 184
189 /* Symmetry only applies if we've already got an active stream. */ 185 /* Symmetry only applies if we've already got an active stream. */
190 if (cpu_dai->active || codec_dai->active) { 186 if (cpu_dai->active) {
191 ret = soc_pcm_apply_symmetry(substream); 187 ret = soc_pcm_apply_symmetry(substream, cpu_dai);
188 if (ret != 0)
189 goto config_err;
190 }
191
192 if (codec_dai->active) {
193 ret = soc_pcm_apply_symmetry(substream, codec_dai);
192 if (ret != 0) 194 if (ret != 0)
193 goto config_err; 195 goto config_err;
194 } 196 }
@@ -290,8 +292,12 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
290 codec_dai->active--; 292 codec_dai->active--;
291 codec->active--; 293 codec->active--;
292 294
293 if (!cpu_dai->active && !codec_dai->active) 295 /* clear the corresponding DAIs rate when inactive */
294 rtd->rate = 0; 296 if (!cpu_dai->active)
297 cpu_dai->rate = 0;
298
299 if (!codec_dai->active)
300 codec_dai->rate = 0;
295 301
296 /* Muting the DAC suppresses artifacts caused during digital 302 /* Muting the DAC suppresses artifacts caused during digital
297 * shutdown, for example from stopping clocks. 303 * shutdown, for example from stopping clocks.
@@ -313,10 +319,17 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
313 cpu_dai->runtime = NULL; 319 cpu_dai->runtime = NULL;
314 320
315 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 321 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
316 /* start delayed pop wq here for playback streams */ 322 if (unlikely(codec->ignore_pmdown_time)) {
317 codec_dai->pop_wait = 1; 323 /* powered down playback stream now */
318 schedule_delayed_work(&rtd->delayed_work, 324 snd_soc_dapm_stream_event(rtd,
319 msecs_to_jiffies(rtd->pmdown_time)); 325 codec_dai->driver->playback.stream_name,
326 SND_SOC_DAPM_STREAM_STOP);
327 } else {
328 /* start delayed pop wq here for playback streams */
329 codec_dai->pop_wait = 1;
330 schedule_delayed_work(&rtd->delayed_work,
331 msecs_to_jiffies(rtd->pmdown_time));
332 }
320 } else { 333 } else {
321 /* capture streams can be powered down now */ 334 /* capture streams can be powered down now */
322 snd_soc_dapm_stream_event(rtd, 335 snd_soc_dapm_stream_event(rtd,
@@ -449,7 +462,9 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
449 } 462 }
450 } 463 }
451 464
452 rtd->rate = params_rate(params); 465 /* store the rate for each DAIs */
466 cpu_dai->rate = params_rate(params);
467 codec_dai->rate = params_rate(params);
453 468
454out: 469out:
455 mutex_unlock(&rtd->pcm_mutex); 470 mutex_unlock(&rtd->pcm_mutex);
diff --git a/sound/soc/tegra/tegra_das.c b/sound/soc/tegra/tegra_das.c
index 9f24ef73f2c..3b55a44146a 100644
--- a/sound/soc/tegra/tegra_das.c
+++ b/sound/soc/tegra/tegra_das.c
@@ -212,7 +212,7 @@ err_release:
212 release_mem_region(res->start, resource_size(res)); 212 release_mem_region(res->start, resource_size(res));
213err_free: 213err_free:
214 kfree(das); 214 kfree(das);
215 das = 0; 215 das = NULL;
216exit: 216exit:
217 return ret; 217 return ret;
218} 218}
@@ -234,7 +234,7 @@ static int __devexit tegra_das_remove(struct platform_device *pdev)
234 release_mem_region(res->start, resource_size(res)); 234 release_mem_region(res->start, resource_size(res));
235 235
236 kfree(das); 236 kfree(das);
237 das = 0; 237 das = NULL;
238 238
239 return 0; 239 return 0;
240} 240}
diff --git a/sound/soc/tegra/tegra_i2s.c b/sound/soc/tegra/tegra_i2s.c
index f36b9969cfe..6728fab8c41 100644
--- a/sound/soc/tegra/tegra_i2s.c
+++ b/sound/soc/tegra/tegra_i2s.c
@@ -312,7 +312,7 @@ static struct snd_soc_dai_ops tegra_i2s_dai_ops = {
312 .trigger = tegra_i2s_trigger, 312 .trigger = tegra_i2s_trigger,
313}; 313};
314 314
315struct snd_soc_dai_driver tegra_i2s_dai[] = { 315static struct snd_soc_dai_driver tegra_i2s_dai[] = {
316 { 316 {
317 .name = DRV_NAME ".0", 317 .name = DRV_NAME ".0",
318 .probe = tegra_i2s_probe, 318 .probe = tegra_i2s_probe,
diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c
index c7cfd96e991..436def1dfa3 100644
--- a/sound/soc/tegra/tegra_pcm.c
+++ b/sound/soc/tegra/tegra_pcm.c
@@ -367,7 +367,7 @@ static void tegra_pcm_free(struct snd_pcm *pcm)
367 tegra_pcm_deallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_PLAYBACK); 367 tegra_pcm_deallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_PLAYBACK);
368} 368}
369 369
370struct snd_soc_platform_driver tegra_pcm_platform = { 370static struct snd_soc_platform_driver tegra_pcm_platform = {
371 .ops = &tegra_pcm_ops, 371 .ops = &tegra_pcm_ops,
372 .pcm_new = tegra_pcm_new, 372 .pcm_new = tegra_pcm_new,
373 .pcm_free = tegra_pcm_free, 373 .pcm_free = tegra_pcm_free,
diff --git a/sound/soc/tegra/tegra_spdif.c b/sound/soc/tegra/tegra_spdif.c
index abe606b0a29..dd11d0c6347 100644
--- a/sound/soc/tegra/tegra_spdif.c
+++ b/sound/soc/tegra/tegra_spdif.c
@@ -127,7 +127,7 @@ static int tegra_spdif_hw_params(struct snd_pcm_substream *substream,
127{ 127{
128 struct device *dev = substream->pcm->card->dev; 128 struct device *dev = substream->pcm->card->dev;
129 struct tegra_spdif *spdif = snd_soc_dai_get_drvdata(dai); 129 struct tegra_spdif *spdif = snd_soc_dai_get_drvdata(dai);
130 int ret, srate, spdifclock; 130 int ret, spdifclock;
131 131
132 spdif->reg_ctrl &= ~TEGRA_SPDIF_CTRL_PACK; 132 spdif->reg_ctrl &= ~TEGRA_SPDIF_CTRL_PACK;
133 spdif->reg_ctrl &= ~TEGRA_SPDIF_CTRL_BIT_MODE_MASK; 133 spdif->reg_ctrl &= ~TEGRA_SPDIF_CTRL_BIT_MODE_MASK;
@@ -140,7 +140,6 @@ static int tegra_spdif_hw_params(struct snd_pcm_substream *substream,
140 return -EINVAL; 140 return -EINVAL;
141 } 141 }
142 142
143 srate = params_rate(params);
144 switch (params_rate(params)) { 143 switch (params_rate(params)) {
145 case 32000: 144 case 32000:
146 spdifclock = 4096000; 145 spdifclock = 4096000;
@@ -232,7 +231,7 @@ static struct snd_soc_dai_ops tegra_spdif_dai_ops = {
232 .trigger = tegra_spdif_trigger, 231 .trigger = tegra_spdif_trigger,
233}; 232};
234 233
235struct snd_soc_dai_driver tegra_spdif_dai = { 234static struct snd_soc_dai_driver tegra_spdif_dai = {
236 .name = DRV_NAME, 235 .name = DRV_NAME,
237 .probe = tegra_spdif_probe, 236 .probe = tegra_spdif_probe,
238 .playback = { 237 .playback = {
diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c
index be27f1d229a..a81cf39257b 100644
--- a/sound/soc/tegra/tegra_wm8903.c
+++ b/sound/soc/tegra/tegra_wm8903.c
@@ -339,8 +339,6 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd)
339 snd_soc_dapm_nc_pin(dapm, "LINEOUTL"); 339 snd_soc_dapm_nc_pin(dapm, "LINEOUTL");
340 } 340 }
341 341
342 snd_soc_dapm_sync(dapm);
343
344 return 0; 342 return 0;
345} 343}
346 344
diff --git a/sound/soc/tegra/trimslice.c b/sound/soc/tegra/trimslice.c
index 8fc07e9adf2..b3a7efa6d96 100644
--- a/sound/soc/tegra/trimslice.c
+++ b/sound/soc/tegra/trimslice.c
@@ -124,8 +124,6 @@ static int trimslice_asoc_init(struct snd_soc_pcm_runtime *rtd)
124 snd_soc_dapm_nc_pin(dapm, "RHPOUT"); 124 snd_soc_dapm_nc_pin(dapm, "RHPOUT");
125 snd_soc_dapm_nc_pin(dapm, "MICIN"); 125 snd_soc_dapm_nc_pin(dapm, "MICIN");
126 126
127 snd_soc_dapm_sync(dapm);
128
129 return 0; 127 return 0;
130} 128}
131 129
diff --git a/sound/soc/txx9/txx9aclc-ac97.c b/sound/soc/txx9/txx9aclc-ac97.c
index 743d07b82c0..a4e3f550184 100644
--- a/sound/soc/txx9/txx9aclc-ac97.c
+++ b/sound/soc/txx9/txx9aclc-ac97.c
@@ -201,7 +201,7 @@ static int __devinit txx9aclc_ac97_dev_probe(struct platform_device *pdev)
201 if (!drvdata->base) 201 if (!drvdata->base)
202 return -EBUSY; 202 return -EBUSY;
203 err = devm_request_irq(&pdev->dev, irq, txx9aclc_ac97_irq, 203 err = devm_request_irq(&pdev->dev, irq, txx9aclc_ac97_irq,
204 IRQF_DISABLED, dev_name(&pdev->dev), drvdata); 204 0, dev_name(&pdev->dev), drvdata);
205 if (err < 0) 205 if (err < 0)
206 return err; 206 return err;
207 207
diff --git a/sound/soc/txx9/txx9aclc-generic.c b/sound/soc/txx9/txx9aclc-generic.c
index 6770e7166be..9b5e283af51 100644
--- a/sound/soc/txx9/txx9aclc-generic.c
+++ b/sound/soc/txx9/txx9aclc-generic.c
@@ -62,7 +62,7 @@ static int __exit txx9aclc_generic_remove(struct platform_device *pdev)
62} 62}
63 63
64static struct platform_driver txx9aclc_generic_driver = { 64static struct platform_driver txx9aclc_generic_driver = {
65 .remove = txx9aclc_generic_remove, 65 .remove = __exit_p(txx9aclc_generic_remove),
66 .driver = { 66 .driver = {
67 .name = "txx9aclc-generic", 67 .name = "txx9aclc-generic",
68 .owner = THIS_MODULE, 68 .owner = THIS_MODULE,
diff --git a/sound/sparc/amd7930.c b/sound/sparc/amd7930.c
index ad7d4d7d923..f036776380b 100644
--- a/sound/sparc/amd7930.c
+++ b/sound/sparc/amd7930.c
@@ -962,7 +962,7 @@ static int __devinit snd_amd7930_create(struct snd_card *card,
962 amd7930_idle(amd); 962 amd7930_idle(amd);
963 963
964 if (request_irq(irq, snd_amd7930_interrupt, 964 if (request_irq(irq, snd_amd7930_interrupt,
965 IRQF_DISABLED | IRQF_SHARED, "amd7930", amd)) { 965 IRQF_SHARED, "amd7930", amd)) {
966 snd_printk(KERN_ERR "amd7930-%d: Unable to grab IRQ %d\n", 966 snd_printk(KERN_ERR "amd7930-%d: Unable to grab IRQ %d\n",
967 dev, irq); 967 dev, irq);
968 snd_amd7930_free(amd); 968 snd_amd7930_free(amd);
diff --git a/sound/usb/6fire/firmware.c b/sound/usb/6fire/firmware.c
index 1e3ae3327dd..07bcfe4d18a 100644
--- a/sound/usb/6fire/firmware.c
+++ b/sound/usb/6fire/firmware.c
@@ -16,6 +16,7 @@
16 16
17#include <linux/firmware.h> 17#include <linux/firmware.h>
18#include <linux/bitrev.h> 18#include <linux/bitrev.h>
19#include <linux/kernel.h>
19 20
20#include "firmware.h" 21#include "firmware.h"
21#include "chip.h" 22#include "chip.h"
@@ -59,21 +60,19 @@ struct ihex_record {
59 unsigned int txt_offset; /* current position in txt_data */ 60 unsigned int txt_offset; /* current position in txt_data */
60}; 61};
61 62
62static u8 usb6fire_fw_ihex_nibble(const u8 n)
63{
64 if (n >= '0' && n <= '9')
65 return n - '0';
66 else if (n >= 'A' && n <= 'F')
67 return n - ('A' - 10);
68 else if (n >= 'a' && n <= 'f')
69 return n - ('a' - 10);
70 return 0;
71}
72
73static u8 usb6fire_fw_ihex_hex(const u8 *data, u8 *crc) 63static u8 usb6fire_fw_ihex_hex(const u8 *data, u8 *crc)
74{ 64{
75 u8 val = (usb6fire_fw_ihex_nibble(data[0]) << 4) | 65 u8 val = 0;
76 usb6fire_fw_ihex_nibble(data[1]); 66 int hval;
67
68 hval = hex_to_bin(data[0]);
69 if (hval >= 0)
70 val |= (hval << 4);
71
72 hval = hex_to_bin(data[1]);
73 if (hval >= 0)
74 val |= hval;
75
77 *crc += val; 76 *crc += val;
78 return val; 77 return val;
79} 78}
diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig
index 8beb77563da..3efc21c3d67 100644
--- a/sound/usb/Kconfig
+++ b/sound/usb/Kconfig
@@ -67,6 +67,7 @@ config SND_USB_CAIAQ
67 * Native Instruments Guitar Rig mobile 67 * Native Instruments Guitar Rig mobile
68 * Native Instruments Traktor Kontrol X1 68 * Native Instruments Traktor Kontrol X1
69 * Native Instruments Traktor Kontrol S4 69 * Native Instruments Traktor Kontrol S4
70 * Native Instruments Maschine Controller
70 71
71 To compile this driver as a module, choose M here: the module 72 To compile this driver as a module, choose M here: the module
72 will be called snd-usb-caiaq. 73 will be called snd-usb-caiaq.
@@ -85,6 +86,7 @@ config SND_USB_CAIAQ_INPUT
85 * Native Instruments Kore Controller 2 86 * Native Instruments Kore Controller 2
86 * Native Instruments Audio Kontrol 1 87 * Native Instruments Audio Kontrol 1
87 * Native Instruments Traktor Kontrol S4 88 * Native Instruments Traktor Kontrol S4
89 * Native Instruments Maschine Controller
88 90
89config SND_USB_US122L 91config SND_USB_US122L
90 tristate "Tascam US-122L USB driver" 92 tristate "Tascam US-122L USB driver"
diff --git a/sound/usb/Makefile b/sound/usb/Makefile
index cf9ed66445f..ac256dc4c6b 100644
--- a/sound/usb/Makefile
+++ b/sound/usb/Makefile
@@ -3,16 +3,16 @@
3# 3#
4 4
5snd-usb-audio-objs := card.o \ 5snd-usb-audio-objs := card.o \
6 clock.o \
7 endpoint.o \
8 format.o \
9 helper.o \
6 mixer.o \ 10 mixer.o \
7 mixer_quirks.o \ 11 mixer_quirks.o \
12 pcm.o \
8 proc.o \ 13 proc.o \
9 quirks.o \ 14 quirks.o \
10 format.o \ 15 stream.o
11 endpoint.o \
12 urb.o \
13 pcm.o \
14 helper.o \
15 clock.o
16 16
17snd-usbmidi-lib-objs := midi.o 17snd-usbmidi-lib-objs := midi.o
18 18
diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
index 45bc4a2dc6f..3eb605bd950 100644
--- a/sound/usb/caiaq/device.c
+++ b/sound/usb/caiaq/device.c
@@ -50,7 +50,8 @@ MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2},"
50 "{Native Instruments, Session I/O}," 50 "{Native Instruments, Session I/O},"
51 "{Native Instruments, GuitarRig mobile}" 51 "{Native Instruments, GuitarRig mobile}"
52 "{Native Instruments, Traktor Kontrol X1}" 52 "{Native Instruments, Traktor Kontrol X1}"
53 "{Native Instruments, Traktor Kontrol S4}"); 53 "{Native Instruments, Traktor Kontrol S4}"
54 "{Native Instruments, Maschine Controller}");
54 55
55static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ 56static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */
56static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */ 57static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */
@@ -146,6 +147,11 @@ static struct usb_device_id snd_usb_id_table[] = {
146 .idVendor = USB_VID_NATIVEINSTRUMENTS, 147 .idVendor = USB_VID_NATIVEINSTRUMENTS,
147 .idProduct = USB_PID_TRAKTORAUDIO2 148 .idProduct = USB_PID_TRAKTORAUDIO2
148 }, 149 },
150 {
151 .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
152 .idVendor = USB_VID_NATIVEINSTRUMENTS,
153 .idProduct = USB_PID_MASCHINECONTROLLER
154 },
149 { /* terminator */ } 155 { /* terminator */ }
150}; 156};
151 157
diff --git a/sound/usb/caiaq/device.h b/sound/usb/caiaq/device.h
index 3f9c6339ae9..562b0bff9c4 100644
--- a/sound/usb/caiaq/device.h
+++ b/sound/usb/caiaq/device.h
@@ -18,6 +18,7 @@
18#define USB_PID_TRAKTORKONTROLX1 0x2305 18#define USB_PID_TRAKTORKONTROLX1 0x2305
19#define USB_PID_TRAKTORKONTROLS4 0xbaff 19#define USB_PID_TRAKTORKONTROLS4 0xbaff
20#define USB_PID_TRAKTORAUDIO2 0x041d 20#define USB_PID_TRAKTORAUDIO2 0x041d
21#define USB_PID_MASCHINECONTROLLER 0x0808
21 22
22#define EP1_BUFSIZE 64 23#define EP1_BUFSIZE 64
23#define EP4_BUFSIZE 512 24#define EP4_BUFSIZE 512
diff --git a/sound/usb/caiaq/input.c b/sound/usb/caiaq/input.c
index a213813487b..26a121b42c3 100644
--- a/sound/usb/caiaq/input.c
+++ b/sound/usb/caiaq/input.c
@@ -67,6 +67,61 @@ static unsigned short keycode_kore[] = {
67 KEY_BRL_DOT5 67 KEY_BRL_DOT5
68}; 68};
69 69
70#define MASCHINE_BUTTONS (42)
71#define MASCHINE_BUTTON(X) ((X) + BTN_MISC)
72#define MASCHINE_PADS (16)
73#define MASCHINE_PAD(X) ((X) + ABS_PRESSURE)
74
75static unsigned short keycode_maschine[] = {
76 MASCHINE_BUTTON(40), /* mute */
77 MASCHINE_BUTTON(39), /* solo */
78 MASCHINE_BUTTON(38), /* select */
79 MASCHINE_BUTTON(37), /* duplicate */
80 MASCHINE_BUTTON(36), /* navigate */
81 MASCHINE_BUTTON(35), /* pad mode */
82 MASCHINE_BUTTON(34), /* pattern */
83 MASCHINE_BUTTON(33), /* scene */
84 KEY_RESERVED, /* spacer */
85
86 MASCHINE_BUTTON(30), /* rec */
87 MASCHINE_BUTTON(31), /* erase */
88 MASCHINE_BUTTON(32), /* shift */
89 MASCHINE_BUTTON(28), /* grid */
90 MASCHINE_BUTTON(27), /* > */
91 MASCHINE_BUTTON(26), /* < */
92 MASCHINE_BUTTON(25), /* restart */
93
94 MASCHINE_BUTTON(21), /* E */
95 MASCHINE_BUTTON(22), /* F */
96 MASCHINE_BUTTON(23), /* G */
97 MASCHINE_BUTTON(24), /* H */
98 MASCHINE_BUTTON(20), /* D */
99 MASCHINE_BUTTON(19), /* C */
100 MASCHINE_BUTTON(18), /* B */
101 MASCHINE_BUTTON(17), /* A */
102
103 MASCHINE_BUTTON(0), /* control */
104 MASCHINE_BUTTON(2), /* browse */
105 MASCHINE_BUTTON(4), /* < */
106 MASCHINE_BUTTON(6), /* snap */
107 MASCHINE_BUTTON(7), /* autowrite */
108 MASCHINE_BUTTON(5), /* > */
109 MASCHINE_BUTTON(3), /* sampling */
110 MASCHINE_BUTTON(1), /* step */
111
112 MASCHINE_BUTTON(15), /* 8 softkeys */
113 MASCHINE_BUTTON(14),
114 MASCHINE_BUTTON(13),
115 MASCHINE_BUTTON(12),
116 MASCHINE_BUTTON(11),
117 MASCHINE_BUTTON(10),
118 MASCHINE_BUTTON(9),
119 MASCHINE_BUTTON(8),
120
121 MASCHINE_BUTTON(16), /* note repeat */
122 MASCHINE_BUTTON(29) /* play */
123};
124
70#define KONTROLX1_INPUTS (40) 125#define KONTROLX1_INPUTS (40)
71#define KONTROLS4_BUTTONS (12 * 8) 126#define KONTROLS4_BUTTONS (12 * 8)
72#define KONTROLS4_AXIS (46) 127#define KONTROLS4_AXIS (46)
@@ -218,6 +273,29 @@ static void snd_caiaq_input_read_erp(struct snd_usb_caiaqdev *dev,
218 input_report_abs(input_dev, ABS_HAT3Y, i); 273 input_report_abs(input_dev, ABS_HAT3Y, i);
219 input_sync(input_dev); 274 input_sync(input_dev);
220 break; 275 break;
276
277 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER):
278 /* 4 under the left screen */
279 input_report_abs(input_dev, ABS_HAT0X, decode_erp(buf[21], buf[20]));
280 input_report_abs(input_dev, ABS_HAT0Y, decode_erp(buf[15], buf[14]));
281 input_report_abs(input_dev, ABS_HAT1X, decode_erp(buf[9], buf[8]));
282 input_report_abs(input_dev, ABS_HAT1Y, decode_erp(buf[3], buf[2]));
283
284 /* 4 under the right screen */
285 input_report_abs(input_dev, ABS_HAT2X, decode_erp(buf[19], buf[18]));
286 input_report_abs(input_dev, ABS_HAT2Y, decode_erp(buf[13], buf[12]));
287 input_report_abs(input_dev, ABS_HAT3X, decode_erp(buf[7], buf[6]));
288 input_report_abs(input_dev, ABS_HAT3Y, decode_erp(buf[1], buf[0]));
289
290 /* volume */
291 input_report_abs(input_dev, ABS_RX, decode_erp(buf[17], buf[16]));
292 /* tempo */
293 input_report_abs(input_dev, ABS_RY, decode_erp(buf[11], buf[10]));
294 /* swing */
295 input_report_abs(input_dev, ABS_RZ, decode_erp(buf[5], buf[4]));
296
297 input_sync(input_dev);
298 break;
221 } 299 }
222} 300}
223 301
@@ -400,6 +478,25 @@ static void snd_usb_caiaq_tks4_dispatch(struct snd_usb_caiaqdev *dev,
400 input_sync(dev->input_dev); 478 input_sync(dev->input_dev);
401} 479}
402 480
481#define MASCHINE_MSGBLOCK_SIZE 2
482
483static void snd_usb_caiaq_maschine_dispatch(struct snd_usb_caiaqdev *dev,
484 const unsigned char *buf,
485 unsigned int len)
486{
487 unsigned int i, pad_id;
488 uint16_t pressure;
489
490 for (i = 0; i < MASCHINE_PADS; i++) {
491 pressure = be16_to_cpu(buf[i * 2] << 8 | buf[(i * 2) + 1]);
492 pad_id = pressure >> 12;
493
494 input_report_abs(dev->input_dev, MASCHINE_PAD(pad_id), pressure & 0xfff);
495 }
496
497 input_sync(dev->input_dev);
498}
499
403static void snd_usb_caiaq_ep4_reply_dispatch(struct urb *urb) 500static void snd_usb_caiaq_ep4_reply_dispatch(struct urb *urb)
404{ 501{
405 struct snd_usb_caiaqdev *dev = urb->context; 502 struct snd_usb_caiaqdev *dev = urb->context;
@@ -425,6 +522,13 @@ static void snd_usb_caiaq_ep4_reply_dispatch(struct urb *urb)
425 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4): 522 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4):
426 snd_usb_caiaq_tks4_dispatch(dev, buf, urb->actual_length); 523 snd_usb_caiaq_tks4_dispatch(dev, buf, urb->actual_length);
427 break; 524 break;
525
526 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER):
527 if (urb->actual_length < (MASCHINE_PADS * MASCHINE_MSGBLOCK_SIZE))
528 goto requeue;
529
530 snd_usb_caiaq_maschine_dispatch(dev, buf, urb->actual_length);
531 break;
428 } 532 }
429 533
430requeue: 534requeue:
@@ -444,6 +548,7 @@ static int snd_usb_caiaq_input_open(struct input_dev *idev)
444 switch (dev->chip.usb_id) { 548 switch (dev->chip.usb_id) {
445 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): 549 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
446 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4): 550 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4):
551 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER):
447 if (usb_submit_urb(dev->ep4_in_urb, GFP_KERNEL) != 0) 552 if (usb_submit_urb(dev->ep4_in_urb, GFP_KERNEL) != 0)
448 return -EIO; 553 return -EIO;
449 break; 554 break;
@@ -462,6 +567,7 @@ static void snd_usb_caiaq_input_close(struct input_dev *idev)
462 switch (dev->chip.usb_id) { 567 switch (dev->chip.usb_id) {
463 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): 568 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
464 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4): 569 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4):
570 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER):
465 usb_kill_urb(dev->ep4_in_urb); 571 usb_kill_urb(dev->ep4_in_urb);
466 break; 572 break;
467 } 573 }
@@ -652,6 +758,50 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev)
652 758
653 break; 759 break;
654 760
761 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER):
762 input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
763 input->absbit[0] = BIT_MASK(ABS_HAT0X) | BIT_MASK(ABS_HAT0Y) |
764 BIT_MASK(ABS_HAT1X) | BIT_MASK(ABS_HAT1Y) |
765 BIT_MASK(ABS_HAT2X) | BIT_MASK(ABS_HAT2Y) |
766 BIT_MASK(ABS_HAT3X) | BIT_MASK(ABS_HAT3Y) |
767 BIT_MASK(ABS_RX) | BIT_MASK(ABS_RY) |
768 BIT_MASK(ABS_RZ);
769
770 BUILD_BUG_ON(sizeof(dev->keycode) < sizeof(keycode_maschine));
771 memcpy(dev->keycode, keycode_maschine, sizeof(keycode_maschine));
772 input->keycodemax = ARRAY_SIZE(keycode_maschine);
773
774 for (i = 0; i < MASCHINE_PADS; i++) {
775 input->absbit[0] |= MASCHINE_PAD(i);
776 input_set_abs_params(input, MASCHINE_PAD(i), 0, 0xfff, 5, 10);
777 }
778
779 input_set_abs_params(input, ABS_HAT0X, 0, 999, 0, 10);
780 input_set_abs_params(input, ABS_HAT0Y, 0, 999, 0, 10);
781 input_set_abs_params(input, ABS_HAT1X, 0, 999, 0, 10);
782 input_set_abs_params(input, ABS_HAT1Y, 0, 999, 0, 10);
783 input_set_abs_params(input, ABS_HAT2X, 0, 999, 0, 10);
784 input_set_abs_params(input, ABS_HAT2Y, 0, 999, 0, 10);
785 input_set_abs_params(input, ABS_HAT3X, 0, 999, 0, 10);
786 input_set_abs_params(input, ABS_HAT3Y, 0, 999, 0, 10);
787 input_set_abs_params(input, ABS_RX, 0, 999, 0, 10);
788 input_set_abs_params(input, ABS_RY, 0, 999, 0, 10);
789 input_set_abs_params(input, ABS_RZ, 0, 999, 0, 10);
790
791 dev->ep4_in_urb = usb_alloc_urb(0, GFP_KERNEL);
792 if (!dev->ep4_in_urb) {
793 ret = -ENOMEM;
794 goto exit_free_idev;
795 }
796
797 usb_fill_bulk_urb(dev->ep4_in_urb, usb_dev,
798 usb_rcvbulkpipe(usb_dev, 0x4),
799 dev->ep4_in_buf, EP4_BUFSIZE,
800 snd_usb_caiaq_ep4_reply_dispatch, dev);
801
802 snd_usb_caiaq_set_auto_msg(dev, 1, 10, 5);
803 break;
804
655 default: 805 default:
656 /* no input methods supported on this device */ 806 /* no input methods supported on this device */
657 goto exit_free_idev; 807 goto exit_free_idev;
@@ -664,15 +814,17 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev)
664 for (i = 0; i < input->keycodemax; i++) 814 for (i = 0; i < input->keycodemax; i++)
665 __set_bit(dev->keycode[i], input->keybit); 815 __set_bit(dev->keycode[i], input->keybit);
666 816
817 dev->input_dev = input;
818
667 ret = input_register_device(input); 819 ret = input_register_device(input);
668 if (ret < 0) 820 if (ret < 0)
669 goto exit_free_idev; 821 goto exit_free_idev;
670 822
671 dev->input_dev = input;
672 return 0; 823 return 0;
673 824
674exit_free_idev: 825exit_free_idev:
675 input_free_device(input); 826 input_free_device(input);
827 dev->input_dev = NULL;
676 return ret; 828 return ret;
677} 829}
678 830
@@ -688,4 +840,3 @@ void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *dev)
688 input_unregister_device(dev->input_dev); 840 input_unregister_device(dev->input_dev);
689 dev->input_dev = NULL; 841 dev->input_dev = NULL;
690} 842}
691
diff --git a/sound/usb/card.c b/sound/usb/card.c
index 3068f043099..05c1aae0b01 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -65,9 +65,9 @@
65#include "helper.h" 65#include "helper.h"
66#include "debug.h" 66#include "debug.h"
67#include "pcm.h" 67#include "pcm.h"
68#include "urb.h"
69#include "format.h" 68#include "format.h"
70#include "power.h" 69#include "power.h"
70#include "stream.h"
71 71
72MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>"); 72MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
73MODULE_DESCRIPTION("USB Audio"); 73MODULE_DESCRIPTION("USB Audio");
@@ -185,7 +185,7 @@ static int snd_usb_create_stream(struct snd_usb_audio *chip, int ctrlif, int int
185 return -EINVAL; 185 return -EINVAL;
186 } 186 }
187 187
188 if (! snd_usb_parse_audio_endpoints(chip, interface)) { 188 if (! snd_usb_parse_audio_interface(chip, interface)) {
189 usb_set_interface(dev, interface, 0); /* reset the current interface */ 189 usb_set_interface(dev, interface, 0); /* reset the current interface */
190 usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L); 190 usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L);
191 return -EINVAL; 191 return -EINVAL;
diff --git a/sound/usb/card.h b/sound/usb/card.h
index ae4251d5abf..a39edcc32a9 100644
--- a/sound/usb/card.h
+++ b/sound/usb/card.h
@@ -94,6 +94,8 @@ struct snd_usb_substream {
94 spinlock_t lock; 94 spinlock_t lock;
95 95
96 struct snd_urb_ops ops; /* callbacks (must be filled at init) */ 96 struct snd_urb_ops ops; /* callbacks (must be filled at init) */
97 int last_frame_number; /* stored frame number */
98 int last_delay; /* stored delay */
97}; 99};
98 100
99struct snd_usb_stream { 101struct snd_usb_stream {
diff --git a/sound/usb/clock.c b/sound/usb/clock.c
index 075195e8661..379baad3d5a 100644
--- a/sound/usb/clock.c
+++ b/sound/usb/clock.c
@@ -91,7 +91,7 @@ static int uac_clock_selector_get_val(struct snd_usb_audio *chip, int selector_i
91 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, 91 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
92 UAC2_CX_CLOCK_SELECTOR << 8, 92 UAC2_CX_CLOCK_SELECTOR << 8,
93 snd_usb_ctrl_intf(chip) | (selector_id << 8), 93 snd_usb_ctrl_intf(chip) | (selector_id << 8),
94 &buf, sizeof(buf), 1000); 94 &buf, sizeof(buf));
95 95
96 if (ret < 0) 96 if (ret < 0)
97 return ret; 97 return ret;
@@ -118,7 +118,7 @@ static bool uac_clock_source_is_valid(struct snd_usb_audio *chip, int source_id)
118 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, 118 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
119 UAC2_CS_CONTROL_CLOCK_VALID << 8, 119 UAC2_CS_CONTROL_CLOCK_VALID << 8,
120 snd_usb_ctrl_intf(chip) | (source_id << 8), 120 snd_usb_ctrl_intf(chip) | (source_id << 8),
121 &data, sizeof(data), 1000); 121 &data, sizeof(data));
122 122
123 if (err < 0) { 123 if (err < 0) {
124 snd_printk(KERN_WARNING "%s(): cannot get clock validity for id %d\n", 124 snd_printk(KERN_WARNING "%s(): cannot get clock validity for id %d\n",
@@ -222,7 +222,7 @@ static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface,
222 if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR, 222 if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR,
223 USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_OUT, 223 USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_OUT,
224 UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep, 224 UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep,
225 data, sizeof(data), 1000)) < 0) { 225 data, sizeof(data))) < 0) {
226 snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d to ep %#x\n", 226 snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d to ep %#x\n",
227 dev->devnum, iface, fmt->altsetting, rate, ep); 227 dev->devnum, iface, fmt->altsetting, rate, ep);
228 return err; 228 return err;
@@ -231,7 +231,7 @@ static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface,
231 if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC_GET_CUR, 231 if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC_GET_CUR,
232 USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_IN, 232 USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_IN,
233 UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep, 233 UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep,
234 data, sizeof(data), 1000)) < 0) { 234 data, sizeof(data))) < 0) {
235 snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq at ep %#x\n", 235 snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq at ep %#x\n",
236 dev->devnum, iface, fmt->altsetting, ep); 236 dev->devnum, iface, fmt->altsetting, ep);
237 return 0; /* some devices don't support reading */ 237 return 0; /* some devices don't support reading */
@@ -273,7 +273,7 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface,
273 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, 273 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
274 UAC2_CS_CONTROL_SAM_FREQ << 8, 274 UAC2_CS_CONTROL_SAM_FREQ << 8,
275 snd_usb_ctrl_intf(chip) | (clock << 8), 275 snd_usb_ctrl_intf(chip) | (clock << 8),
276 data, sizeof(data), 1000)) < 0) { 276 data, sizeof(data))) < 0) {
277 snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d (v2)\n", 277 snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d (v2)\n",
278 dev->devnum, iface, fmt->altsetting, rate); 278 dev->devnum, iface, fmt->altsetting, rate);
279 return err; 279 return err;
@@ -283,7 +283,7 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface,
283 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, 283 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
284 UAC2_CS_CONTROL_SAM_FREQ << 8, 284 UAC2_CS_CONTROL_SAM_FREQ << 8,
285 snd_usb_ctrl_intf(chip) | (clock << 8), 285 snd_usb_ctrl_intf(chip) | (clock << 8),
286 data, sizeof(data), 1000)) < 0) { 286 data, sizeof(data))) < 0) {
287 snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq (v2)\n", 287 snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq (v2)\n",
288 dev->devnum, iface, fmt->altsetting); 288 dev->devnum, iface, fmt->altsetting);
289 return err; 289 return err;
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
index 7d46e482375..81c6edecd86 100644
--- a/sound/usb/endpoint.c
+++ b/sound/usb/endpoint.c
@@ -15,436 +15,951 @@
15 * 15 *
16 */ 16 */
17 17
18#include <linux/gfp.h>
18#include <linux/init.h> 19#include <linux/init.h>
19#include <linux/slab.h>
20#include <linux/usb.h> 20#include <linux/usb.h>
21#include <linux/usb/audio.h> 21#include <linux/usb/audio.h>
22#include <linux/usb/audio-v2.h>
23 22
24#include <sound/core.h> 23#include <sound/core.h>
25#include <sound/pcm.h> 24#include <sound/pcm.h>
26 25
27#include "usbaudio.h" 26#include "usbaudio.h"
27#include "helper.h"
28#include "card.h" 28#include "card.h"
29#include "proc.h"
30#include "quirks.h"
31#include "endpoint.h" 29#include "endpoint.h"
32#include "urb.h"
33#include "pcm.h" 30#include "pcm.h"
34#include "helper.h"
35#include "format.h"
36#include "clock.h"
37 31
38/* 32/*
39 * free a substream 33 * convert a sampling rate into our full speed format (fs/1000 in Q16.16)
34 * this will overflow at approx 524 kHz
40 */ 35 */
41static void free_substream(struct snd_usb_substream *subs) 36static inline unsigned get_usb_full_speed_rate(unsigned int rate)
42{ 37{
43 struct list_head *p, *n; 38 return ((rate << 13) + 62) / 125;
44
45 if (!subs->num_formats)
46 return; /* not initialized */
47 list_for_each_safe(p, n, &subs->fmt_list) {
48 struct audioformat *fp = list_entry(p, struct audioformat, list);
49 kfree(fp->rate_table);
50 kfree(fp);
51 }
52 kfree(subs->rate_list.list);
53} 39}
54 40
41/*
42 * convert a sampling rate into USB high speed format (fs/8000 in Q16.16)
43 * this will overflow at approx 4 MHz
44 */
45static inline unsigned get_usb_high_speed_rate(unsigned int rate)
46{
47 return ((rate << 10) + 62) / 125;
48}
55 49
56/* 50/*
57 * free a usb stream instance 51 * unlink active urbs.
58 */ 52 */
59static void snd_usb_audio_stream_free(struct snd_usb_stream *stream) 53static int deactivate_urbs(struct snd_usb_substream *subs, int force, int can_sleep)
60{ 54{
61 free_substream(&stream->substream[0]); 55 struct snd_usb_audio *chip = subs->stream->chip;
62 free_substream(&stream->substream[1]); 56 unsigned int i;
63 list_del(&stream->list); 57 int async;
64 kfree(stream); 58
59 subs->running = 0;
60
61 if (!force && subs->stream->chip->shutdown) /* to be sure... */
62 return -EBADFD;
63
64 async = !can_sleep && chip->async_unlink;
65
66 if (!async && in_interrupt())
67 return 0;
68
69 for (i = 0; i < subs->nurbs; i++) {
70 if (test_bit(i, &subs->active_mask)) {
71 if (!test_and_set_bit(i, &subs->unlink_mask)) {
72 struct urb *u = subs->dataurb[i].urb;
73 if (async)
74 usb_unlink_urb(u);
75 else
76 usb_kill_urb(u);
77 }
78 }
79 }
80 if (subs->syncpipe) {
81 for (i = 0; i < SYNC_URBS; i++) {
82 if (test_bit(i+16, &subs->active_mask)) {
83 if (!test_and_set_bit(i+16, &subs->unlink_mask)) {
84 struct urb *u = subs->syncurb[i].urb;
85 if (async)
86 usb_unlink_urb(u);
87 else
88 usb_kill_urb(u);
89 }
90 }
91 }
92 }
93 return 0;
65} 94}
66 95
67static void snd_usb_audio_pcm_free(struct snd_pcm *pcm) 96
97/*
98 * release a urb data
99 */
100static void release_urb_ctx(struct snd_urb_ctx *u)
68{ 101{
69 struct snd_usb_stream *stream = pcm->private_data; 102 if (u->urb) {
70 if (stream) { 103 if (u->buffer_size)
71 stream->pcm = NULL; 104 usb_free_coherent(u->subs->dev, u->buffer_size,
72 snd_usb_audio_stream_free(stream); 105 u->urb->transfer_buffer,
106 u->urb->transfer_dma);
107 usb_free_urb(u->urb);
108 u->urb = NULL;
73 } 109 }
74} 110}
75 111
112/*
113 * wait until all urbs are processed.
114 */
115static int wait_clear_urbs(struct snd_usb_substream *subs)
116{
117 unsigned long end_time = jiffies + msecs_to_jiffies(1000);
118 unsigned int i;
119 int alive;
120
121 do {
122 alive = 0;
123 for (i = 0; i < subs->nurbs; i++) {
124 if (test_bit(i, &subs->active_mask))
125 alive++;
126 }
127 if (subs->syncpipe) {
128 for (i = 0; i < SYNC_URBS; i++) {
129 if (test_bit(i + 16, &subs->active_mask))
130 alive++;
131 }
132 }
133 if (! alive)
134 break;
135 schedule_timeout_uninterruptible(1);
136 } while (time_before(jiffies, end_time));
137 if (alive)
138 snd_printk(KERN_ERR "timeout: still %d active urbs..\n", alive);
139 return 0;
140}
76 141
77/* 142/*
78 * add this endpoint to the chip instance. 143 * release a substream
79 * if a stream with the same endpoint already exists, append to it.
80 * if not, create a new pcm stream.
81 */ 144 */
82int snd_usb_add_audio_endpoint(struct snd_usb_audio *chip, int stream, struct audioformat *fp) 145void snd_usb_release_substream_urbs(struct snd_usb_substream *subs, int force)
83{ 146{
84 struct list_head *p; 147 int i;
85 struct snd_usb_stream *as; 148
86 struct snd_usb_substream *subs; 149 /* stop urbs (to be sure) */
87 struct snd_pcm *pcm; 150 deactivate_urbs(subs, force, 1);
88 int err; 151 wait_clear_urbs(subs);
152
153 for (i = 0; i < MAX_URBS; i++)
154 release_urb_ctx(&subs->dataurb[i]);
155 for (i = 0; i < SYNC_URBS; i++)
156 release_urb_ctx(&subs->syncurb[i]);
157 usb_free_coherent(subs->dev, SYNC_URBS * 4,
158 subs->syncbuf, subs->sync_dma);
159 subs->syncbuf = NULL;
160 subs->nurbs = 0;
161}
89 162
90 list_for_each(p, &chip->pcm_list) { 163/*
91 as = list_entry(p, struct snd_usb_stream, list); 164 * complete callback from data urb
92 if (as->fmt_type != fp->fmt_type) 165 */
93 continue; 166static void snd_complete_urb(struct urb *urb)
94 subs = &as->substream[stream]; 167{
95 if (!subs->endpoint) 168 struct snd_urb_ctx *ctx = urb->context;
96 continue; 169 struct snd_usb_substream *subs = ctx->subs;
97 if (subs->endpoint == fp->endpoint) { 170 struct snd_pcm_substream *substream = ctx->subs->pcm_substream;
98 list_add_tail(&fp->list, &subs->fmt_list); 171 int err = 0;
99 subs->num_formats++; 172
100 subs->formats |= fp->formats; 173 if ((subs->running && subs->ops.retire(subs, substream->runtime, urb)) ||
101 return 0; 174 !subs->running || /* can be stopped during retire callback */
175 (err = subs->ops.prepare(subs, substream->runtime, urb)) < 0 ||
176 (err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
177 clear_bit(ctx->index, &subs->active_mask);
178 if (err < 0) {
179 snd_printd(KERN_ERR "cannot submit urb (err = %d)\n", err);
180 snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
102 } 181 }
103 } 182 }
104 /* look for an empty stream */ 183}
105 list_for_each(p, &chip->pcm_list) { 184
106 as = list_entry(p, struct snd_usb_stream, list); 185
107 if (as->fmt_type != fp->fmt_type) 186/*
108 continue; 187 * complete callback from sync urb
109 subs = &as->substream[stream]; 188 */
110 if (subs->endpoint) 189static void snd_complete_sync_urb(struct urb *urb)
111 continue; 190{
112 err = snd_pcm_new_stream(as->pcm, stream, 1); 191 struct snd_urb_ctx *ctx = urb->context;
113 if (err < 0) 192 struct snd_usb_substream *subs = ctx->subs;
114 return err; 193 struct snd_pcm_substream *substream = ctx->subs->pcm_substream;
115 snd_usb_init_substream(as, stream, fp); 194 int err = 0;
116 return 0; 195
196 if ((subs->running && subs->ops.retire_sync(subs, substream->runtime, urb)) ||
197 !subs->running || /* can be stopped during retire callback */
198 (err = subs->ops.prepare_sync(subs, substream->runtime, urb)) < 0 ||
199 (err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
200 clear_bit(ctx->index + 16, &subs->active_mask);
201 if (err < 0) {
202 snd_printd(KERN_ERR "cannot submit sync urb (err = %d)\n", err);
203 snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
204 }
117 } 205 }
206}
207
118 208
119 /* create a new pcm */ 209/*
120 as = kzalloc(sizeof(*as), GFP_KERNEL); 210 * initialize a substream for plaback/capture
121 if (!as) 211 */
122 return -ENOMEM; 212int snd_usb_init_substream_urbs(struct snd_usb_substream *subs,
123 as->pcm_index = chip->pcm_devs; 213 unsigned int period_bytes,
124 as->chip = chip; 214 unsigned int rate,
125 as->fmt_type = fp->fmt_type; 215 unsigned int frame_bits)
126 err = snd_pcm_new(chip->card, "USB Audio", chip->pcm_devs, 216{
127 stream == SNDRV_PCM_STREAM_PLAYBACK ? 1 : 0, 217 unsigned int maxsize, i;
128 stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1, 218 int is_playback = subs->direction == SNDRV_PCM_STREAM_PLAYBACK;
129 &pcm); 219 unsigned int urb_packs, total_packs, packs_per_ms;
130 if (err < 0) { 220 struct snd_usb_audio *chip = subs->stream->chip;
131 kfree(as); 221
132 return err; 222 /* calculate the frequency in 16.16 format */
223 if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL)
224 subs->freqn = get_usb_full_speed_rate(rate);
225 else
226 subs->freqn = get_usb_high_speed_rate(rate);
227 subs->freqm = subs->freqn;
228 subs->freqshift = INT_MIN;
229 /* calculate max. frequency */
230 if (subs->maxpacksize) {
231 /* whatever fits into a max. size packet */
232 maxsize = subs->maxpacksize;
233 subs->freqmax = (maxsize / (frame_bits >> 3))
234 << (16 - subs->datainterval);
235 } else {
236 /* no max. packet size: just take 25% higher than nominal */
237 subs->freqmax = subs->freqn + (subs->freqn >> 2);
238 maxsize = ((subs->freqmax + 0xffff) * (frame_bits >> 3))
239 >> (16 - subs->datainterval);
133 } 240 }
134 as->pcm = pcm; 241 subs->phase = 0;
135 pcm->private_data = as; 242
136 pcm->private_free = snd_usb_audio_pcm_free; 243 if (subs->fill_max)
137 pcm->info_flags = 0; 244 subs->curpacksize = subs->maxpacksize;
138 if (chip->pcm_devs > 0)
139 sprintf(pcm->name, "USB Audio #%d", chip->pcm_devs);
140 else 245 else
141 strcpy(pcm->name, "USB Audio"); 246 subs->curpacksize = maxsize;
142 247
143 snd_usb_init_substream(as, stream, fp); 248 if (snd_usb_get_speed(subs->dev) != USB_SPEED_FULL)
249 packs_per_ms = 8 >> subs->datainterval;
250 else
251 packs_per_ms = 1;
252
253 if (is_playback) {
254 urb_packs = max(chip->nrpacks, 1);
255 urb_packs = min(urb_packs, (unsigned int)MAX_PACKS);
256 } else
257 urb_packs = 1;
258 urb_packs *= packs_per_ms;
259 if (subs->syncpipe)
260 urb_packs = min(urb_packs, 1U << subs->syncinterval);
261
262 /* decide how many packets to be used */
263 if (is_playback) {
264 unsigned int minsize, maxpacks;
265 /* determine how small a packet can be */
266 minsize = (subs->freqn >> (16 - subs->datainterval))
267 * (frame_bits >> 3);
268 /* with sync from device, assume it can be 12% lower */
269 if (subs->syncpipe)
270 minsize -= minsize >> 3;
271 minsize = max(minsize, 1u);
272 total_packs = (period_bytes + minsize - 1) / minsize;
273 /* we need at least two URBs for queueing */
274 if (total_packs < 2) {
275 total_packs = 2;
276 } else {
277 /* and we don't want too long a queue either */
278 maxpacks = max(MAX_QUEUE * packs_per_ms, urb_packs * 2);
279 total_packs = min(total_packs, maxpacks);
280 }
281 } else {
282 while (urb_packs > 1 && urb_packs * maxsize >= period_bytes)
283 urb_packs >>= 1;
284 total_packs = MAX_URBS * urb_packs;
285 }
286 subs->nurbs = (total_packs + urb_packs - 1) / urb_packs;
287 if (subs->nurbs > MAX_URBS) {
288 /* too much... */
289 subs->nurbs = MAX_URBS;
290 total_packs = MAX_URBS * urb_packs;
291 } else if (subs->nurbs < 2) {
292 /* too little - we need at least two packets
293 * to ensure contiguous playback/capture
294 */
295 subs->nurbs = 2;
296 }
144 297
145 list_add(&as->list, &chip->pcm_list); 298 /* allocate and initialize data urbs */
146 chip->pcm_devs++; 299 for (i = 0; i < subs->nurbs; i++) {
300 struct snd_urb_ctx *u = &subs->dataurb[i];
301 u->index = i;
302 u->subs = subs;
303 u->packets = (i + 1) * total_packs / subs->nurbs
304 - i * total_packs / subs->nurbs;
305 u->buffer_size = maxsize * u->packets;
306 if (subs->fmt_type == UAC_FORMAT_TYPE_II)
307 u->packets++; /* for transfer delimiter */
308 u->urb = usb_alloc_urb(u->packets, GFP_KERNEL);
309 if (!u->urb)
310 goto out_of_memory;
311 u->urb->transfer_buffer =
312 usb_alloc_coherent(subs->dev, u->buffer_size,
313 GFP_KERNEL, &u->urb->transfer_dma);
314 if (!u->urb->transfer_buffer)
315 goto out_of_memory;
316 u->urb->pipe = subs->datapipe;
317 u->urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
318 u->urb->interval = 1 << subs->datainterval;
319 u->urb->context = u;
320 u->urb->complete = snd_complete_urb;
321 }
322
323 if (subs->syncpipe) {
324 /* allocate and initialize sync urbs */
325 subs->syncbuf = usb_alloc_coherent(subs->dev, SYNC_URBS * 4,
326 GFP_KERNEL, &subs->sync_dma);
327 if (!subs->syncbuf)
328 goto out_of_memory;
329 for (i = 0; i < SYNC_URBS; i++) {
330 struct snd_urb_ctx *u = &subs->syncurb[i];
331 u->index = i;
332 u->subs = subs;
333 u->packets = 1;
334 u->urb = usb_alloc_urb(1, GFP_KERNEL);
335 if (!u->urb)
336 goto out_of_memory;
337 u->urb->transfer_buffer = subs->syncbuf + i * 4;
338 u->urb->transfer_dma = subs->sync_dma + i * 4;
339 u->urb->transfer_buffer_length = 4;
340 u->urb->pipe = subs->syncpipe;
341 u->urb->transfer_flags = URB_ISO_ASAP |
342 URB_NO_TRANSFER_DMA_MAP;
343 u->urb->number_of_packets = 1;
344 u->urb->interval = 1 << subs->syncinterval;
345 u->urb->context = u;
346 u->urb->complete = snd_complete_sync_urb;
347 }
348 }
349 return 0;
147 350
148 snd_usb_proc_pcm_format_add(as); 351out_of_memory:
352 snd_usb_release_substream_urbs(subs, 0);
353 return -ENOMEM;
354}
149 355
356/*
357 * prepare urb for full speed capture sync pipe
358 *
359 * fill the length and offset of each urb descriptor.
360 * the fixed 10.14 frequency is passed through the pipe.
361 */
362static int prepare_capture_sync_urb(struct snd_usb_substream *subs,
363 struct snd_pcm_runtime *runtime,
364 struct urb *urb)
365{
366 unsigned char *cp = urb->transfer_buffer;
367 struct snd_urb_ctx *ctx = urb->context;
368
369 urb->dev = ctx->subs->dev; /* we need to set this at each time */
370 urb->iso_frame_desc[0].length = 3;
371 urb->iso_frame_desc[0].offset = 0;
372 cp[0] = subs->freqn >> 2;
373 cp[1] = subs->freqn >> 10;
374 cp[2] = subs->freqn >> 18;
150 return 0; 375 return 0;
151} 376}
152 377
153static int parse_uac_endpoint_attributes(struct snd_usb_audio *chip, 378/*
154 struct usb_host_interface *alts, 379 * prepare urb for high speed capture sync pipe
155 int protocol, int iface_no) 380 *
381 * fill the length and offset of each urb descriptor.
382 * the fixed 12.13 frequency is passed as 16.16 through the pipe.
383 */
384static int prepare_capture_sync_urb_hs(struct snd_usb_substream *subs,
385 struct snd_pcm_runtime *runtime,
386 struct urb *urb)
156{ 387{
157 /* parsed with a v1 header here. that's ok as we only look at the 388 unsigned char *cp = urb->transfer_buffer;
158 * header first which is the same for both versions */ 389 struct snd_urb_ctx *ctx = urb->context;
159 struct uac_iso_endpoint_descriptor *csep; 390
160 struct usb_interface_descriptor *altsd = get_iface_desc(alts); 391 urb->dev = ctx->subs->dev; /* we need to set this at each time */
161 int attributes = 0; 392 urb->iso_frame_desc[0].length = 4;
162 393 urb->iso_frame_desc[0].offset = 0;
163 csep = snd_usb_find_desc(alts->endpoint[0].extra, alts->endpoint[0].extralen, NULL, USB_DT_CS_ENDPOINT); 394 cp[0] = subs->freqn;
164 395 cp[1] = subs->freqn >> 8;
165 /* Creamware Noah has this descriptor after the 2nd endpoint */ 396 cp[2] = subs->freqn >> 16;
166 if (!csep && altsd->bNumEndpoints >= 2) 397 cp[3] = subs->freqn >> 24;
167 csep = snd_usb_find_desc(alts->endpoint[1].extra, alts->endpoint[1].extralen, NULL, USB_DT_CS_ENDPOINT); 398 return 0;
168 399}
169 if (!csep || csep->bLength < 7 ||
170 csep->bDescriptorSubtype != UAC_EP_GENERAL) {
171 snd_printk(KERN_WARNING "%d:%u:%d : no or invalid"
172 " class specific endpoint descriptor\n",
173 chip->dev->devnum, iface_no,
174 altsd->bAlternateSetting);
175 return 0;
176 }
177 400
178 if (protocol == UAC_VERSION_1) { 401/*
179 attributes = csep->bmAttributes; 402 * process after capture sync complete
180 } else { 403 * - nothing to do
181 struct uac2_iso_endpoint_descriptor *csep2 = 404 */
182 (struct uac2_iso_endpoint_descriptor *) csep; 405static int retire_capture_sync_urb(struct snd_usb_substream *subs,
406 struct snd_pcm_runtime *runtime,
407 struct urb *urb)
408{
409 return 0;
410}
183 411
184 attributes = csep->bmAttributes & UAC_EP_CS_ATTR_FILL_MAX; 412/*
413 * prepare urb for capture data pipe
414 *
415 * fill the offset and length of each descriptor.
416 *
417 * we use a temporary buffer to write the captured data.
418 * since the length of written data is determined by host, we cannot
419 * write onto the pcm buffer directly... the data is thus copied
420 * later at complete callback to the global buffer.
421 */
422static int prepare_capture_urb(struct snd_usb_substream *subs,
423 struct snd_pcm_runtime *runtime,
424 struct urb *urb)
425{
426 int i, offs;
427 struct snd_urb_ctx *ctx = urb->context;
428
429 offs = 0;
430 urb->dev = ctx->subs->dev; /* we need to set this at each time */
431 for (i = 0; i < ctx->packets; i++) {
432 urb->iso_frame_desc[i].offset = offs;
433 urb->iso_frame_desc[i].length = subs->curpacksize;
434 offs += subs->curpacksize;
435 }
436 urb->transfer_buffer_length = offs;
437 urb->number_of_packets = ctx->packets;
438 return 0;
439}
185 440
186 /* emulate the endpoint attributes of a v1 device */ 441/*
187 if (csep2->bmControls & UAC2_CONTROL_PITCH) 442 * process after capture complete
188 attributes |= UAC_EP_CS_ATTR_PITCH_CONTROL; 443 *
444 * copy the data from each desctiptor to the pcm buffer, and
445 * update the current position.
446 */
447static int retire_capture_urb(struct snd_usb_substream *subs,
448 struct snd_pcm_runtime *runtime,
449 struct urb *urb)
450{
451 unsigned long flags;
452 unsigned char *cp;
453 int i;
454 unsigned int stride, frames, bytes, oldptr;
455 int period_elapsed = 0;
456
457 stride = runtime->frame_bits >> 3;
458
459 for (i = 0; i < urb->number_of_packets; i++) {
460 cp = (unsigned char *)urb->transfer_buffer + urb->iso_frame_desc[i].offset;
461 if (urb->iso_frame_desc[i].status) {
462 snd_printd(KERN_ERR "frame %d active: %d\n", i, urb->iso_frame_desc[i].status);
463 // continue;
464 }
465 bytes = urb->iso_frame_desc[i].actual_length;
466 frames = bytes / stride;
467 if (!subs->txfr_quirk)
468 bytes = frames * stride;
469 if (bytes % (runtime->sample_bits >> 3) != 0) {
470#ifdef CONFIG_SND_DEBUG_VERBOSE
471 int oldbytes = bytes;
472#endif
473 bytes = frames * stride;
474 snd_printdd(KERN_ERR "Corrected urb data len. %d->%d\n",
475 oldbytes, bytes);
476 }
477 /* update the current pointer */
478 spin_lock_irqsave(&subs->lock, flags);
479 oldptr = subs->hwptr_done;
480 subs->hwptr_done += bytes;
481 if (subs->hwptr_done >= runtime->buffer_size * stride)
482 subs->hwptr_done -= runtime->buffer_size * stride;
483 frames = (bytes + (oldptr % stride)) / stride;
484 subs->transfer_done += frames;
485 if (subs->transfer_done >= runtime->period_size) {
486 subs->transfer_done -= runtime->period_size;
487 period_elapsed = 1;
488 }
489 spin_unlock_irqrestore(&subs->lock, flags);
490 /* copy a data chunk */
491 if (oldptr + bytes > runtime->buffer_size * stride) {
492 unsigned int bytes1 =
493 runtime->buffer_size * stride - oldptr;
494 memcpy(runtime->dma_area + oldptr, cp, bytes1);
495 memcpy(runtime->dma_area, cp + bytes1, bytes - bytes1);
496 } else {
497 memcpy(runtime->dma_area + oldptr, cp, bytes);
498 }
189 } 499 }
500 if (period_elapsed)
501 snd_pcm_period_elapsed(subs->pcm_substream);
502 return 0;
503}
190 504
191 return attributes; 505/*
506 * Process after capture complete when paused. Nothing to do.
507 */
508static int retire_paused_capture_urb(struct snd_usb_substream *subs,
509 struct snd_pcm_runtime *runtime,
510 struct urb *urb)
511{
512 return 0;
192} 513}
193 514
194static struct uac2_input_terminal_descriptor * 515
195 snd_usb_find_input_terminal_descriptor(struct usb_host_interface *ctrl_iface, 516/*
196 int terminal_id) 517 * prepare urb for playback sync pipe
518 *
519 * set up the offset and length to receive the current frequency.
520 */
521static int prepare_playback_sync_urb(struct snd_usb_substream *subs,
522 struct snd_pcm_runtime *runtime,
523 struct urb *urb)
197{ 524{
198 struct uac2_input_terminal_descriptor *term = NULL; 525 struct snd_urb_ctx *ctx = urb->context;
526
527 urb->dev = ctx->subs->dev; /* we need to set this at each time */
528 urb->iso_frame_desc[0].length = min(4u, ctx->subs->syncmaxsize);
529 urb->iso_frame_desc[0].offset = 0;
530 return 0;
531}
199 532
200 while ((term = snd_usb_find_csint_desc(ctrl_iface->extra, 533/*
201 ctrl_iface->extralen, 534 * process after playback sync complete
202 term, UAC_INPUT_TERMINAL))) { 535 *
203 if (term->bTerminalID == terminal_id) 536 * Full speed devices report feedback values in 10.14 format as samples per
204 return term; 537 * frame, high speed devices in 16.16 format as samples per microframe.
538 * Because the Audio Class 1 spec was written before USB 2.0, many high speed
539 * devices use a wrong interpretation, some others use an entirely different
540 * format. Therefore, we cannot predict what format any particular device uses
541 * and must detect it automatically.
542 */
543static int retire_playback_sync_urb(struct snd_usb_substream *subs,
544 struct snd_pcm_runtime *runtime,
545 struct urb *urb)
546{
547 unsigned int f;
548 int shift;
549 unsigned long flags;
550
551 if (urb->iso_frame_desc[0].status != 0 ||
552 urb->iso_frame_desc[0].actual_length < 3)
553 return 0;
554
555 f = le32_to_cpup(urb->transfer_buffer);
556 if (urb->iso_frame_desc[0].actual_length == 3)
557 f &= 0x00ffffff;
558 else
559 f &= 0x0fffffff;
560 if (f == 0)
561 return 0;
562
563 if (unlikely(subs->freqshift == INT_MIN)) {
564 /*
565 * The first time we see a feedback value, determine its format
566 * by shifting it left or right until it matches the nominal
567 * frequency value. This assumes that the feedback does not
568 * differ from the nominal value more than +50% or -25%.
569 */
570 shift = 0;
571 while (f < subs->freqn - subs->freqn / 4) {
572 f <<= 1;
573 shift++;
574 }
575 while (f > subs->freqn + subs->freqn / 2) {
576 f >>= 1;
577 shift--;
578 }
579 subs->freqshift = shift;
580 }
581 else if (subs->freqshift >= 0)
582 f <<= subs->freqshift;
583 else
584 f >>= -subs->freqshift;
585
586 if (likely(f >= subs->freqn - subs->freqn / 8 && f <= subs->freqmax)) {
587 /*
588 * If the frequency looks valid, set it.
589 * This value is referred to in prepare_playback_urb().
590 */
591 spin_lock_irqsave(&subs->lock, flags);
592 subs->freqm = f;
593 spin_unlock_irqrestore(&subs->lock, flags);
594 } else {
595 /*
596 * Out of range; maybe the shift value is wrong.
597 * Reset it so that we autodetect again the next time.
598 */
599 subs->freqshift = INT_MIN;
205 } 600 }
206 601
207 return NULL; 602 return 0;
208} 603}
209 604
210static struct uac2_output_terminal_descriptor * 605/* determine the number of frames in the next packet */
211 snd_usb_find_output_terminal_descriptor(struct usb_host_interface *ctrl_iface, 606static int snd_usb_audio_next_packet_size(struct snd_usb_substream *subs)
212 int terminal_id)
213{ 607{
214 struct uac2_output_terminal_descriptor *term = NULL; 608 if (subs->fill_max)
215 609 return subs->maxframesize;
216 while ((term = snd_usb_find_csint_desc(ctrl_iface->extra, 610 else {
217 ctrl_iface->extralen, 611 subs->phase = (subs->phase & 0xffff)
218 term, UAC_OUTPUT_TERMINAL))) { 612 + (subs->freqm << subs->datainterval);
219 if (term->bTerminalID == terminal_id) 613 return min(subs->phase >> 16, subs->maxframesize);
220 return term;
221 } 614 }
615}
222 616
223 return NULL; 617/*
618 * Prepare urb for streaming before playback starts or when paused.
619 *
620 * We don't have any data, so we send silence.
621 */
622static int prepare_nodata_playback_urb(struct snd_usb_substream *subs,
623 struct snd_pcm_runtime *runtime,
624 struct urb *urb)
625{
626 unsigned int i, offs, counts;
627 struct snd_urb_ctx *ctx = urb->context;
628 int stride = runtime->frame_bits >> 3;
629
630 offs = 0;
631 urb->dev = ctx->subs->dev;
632 for (i = 0; i < ctx->packets; ++i) {
633 counts = snd_usb_audio_next_packet_size(subs);
634 urb->iso_frame_desc[i].offset = offs * stride;
635 urb->iso_frame_desc[i].length = counts * stride;
636 offs += counts;
637 }
638 urb->number_of_packets = ctx->packets;
639 urb->transfer_buffer_length = offs * stride;
640 memset(urb->transfer_buffer,
641 runtime->format == SNDRV_PCM_FORMAT_U8 ? 0x80 : 0,
642 offs * stride);
643 return 0;
224} 644}
225 645
226int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) 646/*
647 * prepare urb for playback data pipe
648 *
649 * Since a URB can handle only a single linear buffer, we must use double
650 * buffering when the data to be transferred overflows the buffer boundary.
651 * To avoid inconsistencies when updating hwptr_done, we use double buffering
652 * for all URBs.
653 */
654static int prepare_playback_urb(struct snd_usb_substream *subs,
655 struct snd_pcm_runtime *runtime,
656 struct urb *urb)
227{ 657{
228 struct usb_device *dev; 658 int i, stride;
229 struct usb_interface *iface; 659 unsigned int counts, frames, bytes;
230 struct usb_host_interface *alts; 660 unsigned long flags;
231 struct usb_interface_descriptor *altsd; 661 int period_elapsed = 0;
232 int i, altno, err, stream; 662 struct snd_urb_ctx *ctx = urb->context;
233 int format = 0, num_channels = 0; 663
234 struct audioformat *fp = NULL; 664 stride = runtime->frame_bits >> 3;
235 int num, protocol, clock = 0; 665
236 struct uac_format_type_i_continuous_descriptor *fmt; 666 frames = 0;
667 urb->dev = ctx->subs->dev; /* we need to set this at each time */
668 urb->number_of_packets = 0;
669 spin_lock_irqsave(&subs->lock, flags);
670 for (i = 0; i < ctx->packets; i++) {
671 counts = snd_usb_audio_next_packet_size(subs);
672 /* set up descriptor */
673 urb->iso_frame_desc[i].offset = frames * stride;
674 urb->iso_frame_desc[i].length = counts * stride;
675 frames += counts;
676 urb->number_of_packets++;
677 subs->transfer_done += counts;
678 if (subs->transfer_done >= runtime->period_size) {
679 subs->transfer_done -= runtime->period_size;
680 period_elapsed = 1;
681 if (subs->fmt_type == UAC_FORMAT_TYPE_II) {
682 if (subs->transfer_done > 0) {
683 /* FIXME: fill-max mode is not
684 * supported yet */
685 frames -= subs->transfer_done;
686 counts -= subs->transfer_done;
687 urb->iso_frame_desc[i].length =
688 counts * stride;
689 subs->transfer_done = 0;
690 }
691 i++;
692 if (i < ctx->packets) {
693 /* add a transfer delimiter */
694 urb->iso_frame_desc[i].offset =
695 frames * stride;
696 urb->iso_frame_desc[i].length = 0;
697 urb->number_of_packets++;
698 }
699 break;
700 }
701 }
702 if (period_elapsed) /* finish at the period boundary */
703 break;
704 }
705 bytes = frames * stride;
706 if (subs->hwptr_done + bytes > runtime->buffer_size * stride) {
707 /* err, the transferred area goes over buffer boundary. */
708 unsigned int bytes1 =
709 runtime->buffer_size * stride - subs->hwptr_done;
710 memcpy(urb->transfer_buffer,
711 runtime->dma_area + subs->hwptr_done, bytes1);
712 memcpy(urb->transfer_buffer + bytes1,
713 runtime->dma_area, bytes - bytes1);
714 } else {
715 memcpy(urb->transfer_buffer,
716 runtime->dma_area + subs->hwptr_done, bytes);
717 }
718 subs->hwptr_done += bytes;
719 if (subs->hwptr_done >= runtime->buffer_size * stride)
720 subs->hwptr_done -= runtime->buffer_size * stride;
721
722 /* update delay with exact number of samples queued */
723 runtime->delay = subs->last_delay;
724 runtime->delay += frames;
725 subs->last_delay = runtime->delay;
726
727 /* realign last_frame_number */
728 subs->last_frame_number = usb_get_current_frame_number(subs->dev);
729 subs->last_frame_number &= 0xFF; /* keep 8 LSBs */
730
731 spin_unlock_irqrestore(&subs->lock, flags);
732 urb->transfer_buffer_length = bytes;
733 if (period_elapsed)
734 snd_pcm_period_elapsed(subs->pcm_substream);
735 return 0;
736}
237 737
238 dev = chip->dev; 738/*
739 * process after playback data complete
740 * - decrease the delay count again
741 */
742static int retire_playback_urb(struct snd_usb_substream *subs,
743 struct snd_pcm_runtime *runtime,
744 struct urb *urb)
745{
746 unsigned long flags;
747 int stride = runtime->frame_bits >> 3;
748 int processed = urb->transfer_buffer_length / stride;
749 int est_delay;
239 750
240 /* parse the interface's altsettings */ 751 spin_lock_irqsave(&subs->lock, flags);
241 iface = usb_ifnum_to_if(dev, iface_no);
242 752
243 num = iface->num_altsetting; 753 est_delay = snd_usb_pcm_delay(subs, runtime->rate);
754 /* update delay with exact number of samples played */
755 if (processed > subs->last_delay)
756 subs->last_delay = 0;
757 else
758 subs->last_delay -= processed;
759 runtime->delay = subs->last_delay;
244 760
245 /* 761 /*
246 * Dallas DS4201 workaround: It presents 5 altsettings, but the last 762 * Report when delay estimate is off by more than 2ms.
247 * one misses syncpipe, and does not produce any sound. 763 * The error should be lower than 2ms since the estimate relies
764 * on two reads of a counter updated every ms.
248 */ 765 */
249 if (chip->usb_id == USB_ID(0x04fa, 0x4201)) 766 if (abs(est_delay - subs->last_delay) * 1000 > runtime->rate * 2)
250 num = 4; 767 snd_printk(KERN_DEBUG "delay: estimated %d, actual %d\n",
251 768 est_delay, subs->last_delay);
252 for (i = 0; i < num; i++) {
253 alts = &iface->altsetting[i];
254 altsd = get_iface_desc(alts);
255 protocol = altsd->bInterfaceProtocol;
256 /* skip invalid one */
257 if ((altsd->bInterfaceClass != USB_CLASS_AUDIO &&
258 altsd->bInterfaceClass != USB_CLASS_VENDOR_SPEC) ||
259 (altsd->bInterfaceSubClass != USB_SUBCLASS_AUDIOSTREAMING &&
260 altsd->bInterfaceSubClass != USB_SUBCLASS_VENDOR_SPEC) ||
261 altsd->bNumEndpoints < 1 ||
262 le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) == 0)
263 continue;
264 /* must be isochronous */
265 if ((get_endpoint(alts, 0)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) !=
266 USB_ENDPOINT_XFER_ISOC)
267 continue;
268 /* check direction */
269 stream = (get_endpoint(alts, 0)->bEndpointAddress & USB_DIR_IN) ?
270 SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
271 altno = altsd->bAlternateSetting;
272
273 if (snd_usb_apply_interface_quirk(chip, iface_no, altno))
274 continue;
275
276 /* get audio formats */
277 switch (protocol) {
278 default:
279 snd_printdd(KERN_WARNING "%d:%u:%d: unknown interface protocol %#02x, assuming v1\n",
280 dev->devnum, iface_no, altno, protocol);
281 protocol = UAC_VERSION_1;
282 /* fall through */
283
284 case UAC_VERSION_1: {
285 struct uac1_as_header_descriptor *as =
286 snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL);
287
288 if (!as) {
289 snd_printk(KERN_ERR "%d:%u:%d : UAC_AS_GENERAL descriptor not found\n",
290 dev->devnum, iface_no, altno);
291 continue;
292 }
293 769
294 if (as->bLength < sizeof(*as)) { 770 spin_unlock_irqrestore(&subs->lock, flags);
295 snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_AS_GENERAL desc\n", 771 return 0;
296 dev->devnum, iface_no, altno); 772}
297 continue;
298 }
299 773
300 format = le16_to_cpu(as->wFormatTag); /* remember the format value */ 774static const char *usb_error_string(int err)
301 break; 775{
302 } 776 switch (err) {
777 case -ENODEV:
778 return "no device";
779 case -ENOENT:
780 return "endpoint not enabled";
781 case -EPIPE:
782 return "endpoint stalled";
783 case -ENOSPC:
784 return "not enough bandwidth";
785 case -ESHUTDOWN:
786 return "device disabled";
787 case -EHOSTUNREACH:
788 return "device suspended";
789 case -EINVAL:
790 case -EAGAIN:
791 case -EFBIG:
792 case -EMSGSIZE:
793 return "internal error";
794 default:
795 return "unknown error";
796 }
797}
303 798
304 case UAC_VERSION_2: { 799/*
305 struct uac2_input_terminal_descriptor *input_term; 800 * set up and start data/sync urbs
306 struct uac2_output_terminal_descriptor *output_term; 801 */
307 struct uac2_as_header_descriptor *as = 802static int start_urbs(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime)
308 snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL); 803{
804 unsigned int i;
805 int err;
309 806
310 if (!as) { 807 if (subs->stream->chip->shutdown)
311 snd_printk(KERN_ERR "%d:%u:%d : UAC_AS_GENERAL descriptor not found\n", 808 return -EBADFD;
312 dev->devnum, iface_no, altno); 809
313 continue; 810 for (i = 0; i < subs->nurbs; i++) {
811 if (snd_BUG_ON(!subs->dataurb[i].urb))
812 return -EINVAL;
813 if (subs->ops.prepare(subs, runtime, subs->dataurb[i].urb) < 0) {
814 snd_printk(KERN_ERR "cannot prepare datapipe for urb %d\n", i);
815 goto __error;
816 }
817 }
818 if (subs->syncpipe) {
819 for (i = 0; i < SYNC_URBS; i++) {
820 if (snd_BUG_ON(!subs->syncurb[i].urb))
821 return -EINVAL;
822 if (subs->ops.prepare_sync(subs, runtime, subs->syncurb[i].urb) < 0) {
823 snd_printk(KERN_ERR "cannot prepare syncpipe for urb %d\n", i);
824 goto __error;
314 } 825 }
826 }
827 }
315 828
316 if (as->bLength < sizeof(*as)) { 829 subs->active_mask = 0;
317 snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_AS_GENERAL desc\n", 830 subs->unlink_mask = 0;
318 dev->devnum, iface_no, altno); 831 subs->running = 1;
319 continue; 832 for (i = 0; i < subs->nurbs; i++) {
833 err = usb_submit_urb(subs->dataurb[i].urb, GFP_ATOMIC);
834 if (err < 0) {
835 snd_printk(KERN_ERR "cannot submit datapipe "
836 "for urb %d, error %d: %s\n",
837 i, err, usb_error_string(err));
838 goto __error;
839 }
840 set_bit(i, &subs->active_mask);
841 }
842 if (subs->syncpipe) {
843 for (i = 0; i < SYNC_URBS; i++) {
844 err = usb_submit_urb(subs->syncurb[i].urb, GFP_ATOMIC);
845 if (err < 0) {
846 snd_printk(KERN_ERR "cannot submit syncpipe "
847 "for urb %d, error %d: %s\n",
848 i, err, usb_error_string(err));
849 goto __error;
320 } 850 }
851 set_bit(i + 16, &subs->active_mask);
852 }
853 }
854 return 0;
321 855
322 num_channels = as->bNrChannels; 856 __error:
323 format = le32_to_cpu(as->bmFormats); 857 // snd_pcm_stop(subs->pcm_substream, SNDRV_PCM_STATE_XRUN);
858 deactivate_urbs(subs, 0, 0);
859 return -EPIPE;
860}
324 861
325 /* lookup the terminal associated to this interface
326 * to extract the clock */
327 input_term = snd_usb_find_input_terminal_descriptor(chip->ctrl_intf,
328 as->bTerminalLink);
329 if (input_term) {
330 clock = input_term->bCSourceID;
331 break;
332 }
333 862
334 output_term = snd_usb_find_output_terminal_descriptor(chip->ctrl_intf, 863/*
335 as->bTerminalLink); 864 */
336 if (output_term) { 865static struct snd_urb_ops audio_urb_ops[2] = {
337 clock = output_term->bCSourceID; 866 {
338 break; 867 .prepare = prepare_nodata_playback_urb,
339 } 868 .retire = retire_playback_urb,
869 .prepare_sync = prepare_playback_sync_urb,
870 .retire_sync = retire_playback_sync_urb,
871 },
872 {
873 .prepare = prepare_capture_urb,
874 .retire = retire_capture_urb,
875 .prepare_sync = prepare_capture_sync_urb,
876 .retire_sync = retire_capture_sync_urb,
877 },
878};
340 879
341 snd_printk(KERN_ERR "%d:%u:%d : bogus bTerminalLink %d\n", 880/*
342 dev->devnum, iface_no, altno, as->bTerminalLink); 881 * initialize the substream instance.
343 continue; 882 */
344 }
345 }
346 883
347 /* get format type */ 884void snd_usb_init_substream(struct snd_usb_stream *as,
348 fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_FORMAT_TYPE); 885 int stream, struct audioformat *fp)
349 if (!fmt) { 886{
350 snd_printk(KERN_ERR "%d:%u:%d : no UAC_FORMAT_TYPE desc\n", 887 struct snd_usb_substream *subs = &as->substream[stream];
351 dev->devnum, iface_no, altno); 888
352 continue; 889 INIT_LIST_HEAD(&subs->fmt_list);
353 } 890 spin_lock_init(&subs->lock);
354 if (((protocol == UAC_VERSION_1) && (fmt->bLength < 8)) || 891
355 ((protocol == UAC_VERSION_2) && (fmt->bLength < 6))) { 892 subs->stream = as;
356 snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n", 893 subs->direction = stream;
357 dev->devnum, iface_no, altno); 894 subs->dev = as->chip->dev;
358 continue; 895 subs->txfr_quirk = as->chip->txfr_quirk;
359 } 896 subs->ops = audio_urb_ops[stream];
897 if (snd_usb_get_speed(subs->dev) >= USB_SPEED_HIGH)
898 subs->ops.prepare_sync = prepare_capture_sync_urb_hs;
899
900 snd_usb_set_pcm_ops(as->pcm, stream);
901
902 list_add_tail(&fp->list, &subs->fmt_list);
903 subs->formats |= fp->formats;
904 subs->endpoint = fp->endpoint;
905 subs->num_formats++;
906 subs->fmt_type = fp->fmt_type;
907}
360 908
361 /* 909int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substream, int cmd)
362 * Blue Microphones workaround: The last altsetting is identical 910{
363 * with the previous one, except for a larger packet size, but 911 struct snd_usb_substream *subs = substream->runtime->private_data;
364 * is actually a mislabeled two-channel setting; ignore it.
365 */
366 if (fmt->bNrChannels == 1 &&
367 fmt->bSubframeSize == 2 &&
368 altno == 2 && num == 3 &&
369 fp && fp->altsetting == 1 && fp->channels == 1 &&
370 fp->formats == SNDRV_PCM_FMTBIT_S16_LE &&
371 protocol == UAC_VERSION_1 &&
372 le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) ==
373 fp->maxpacksize * 2)
374 continue;
375
376 fp = kzalloc(sizeof(*fp), GFP_KERNEL);
377 if (! fp) {
378 snd_printk(KERN_ERR "cannot malloc\n");
379 return -ENOMEM;
380 }
381 912
382 fp->iface = iface_no; 913 switch (cmd) {
383 fp->altsetting = altno; 914 case SNDRV_PCM_TRIGGER_START:
384 fp->altset_idx = i; 915 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
385 fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress; 916 subs->ops.prepare = prepare_playback_urb;
386 fp->ep_attr = get_endpoint(alts, 0)->bmAttributes; 917 return 0;
387 fp->datainterval = snd_usb_parse_datainterval(chip, alts); 918 case SNDRV_PCM_TRIGGER_STOP:
388 fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize); 919 return deactivate_urbs(subs, 0, 0);
389 /* num_channels is only set for v2 interfaces */ 920 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
390 fp->channels = num_channels; 921 subs->ops.prepare = prepare_nodata_playback_urb;
391 if (snd_usb_get_speed(dev) == USB_SPEED_HIGH) 922 return 0;
392 fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1) 923 }
393 * (fp->maxpacksize & 0x7ff);
394 fp->attributes = parse_uac_endpoint_attributes(chip, alts, protocol, iface_no);
395 fp->clock = clock;
396
397 /* some quirks for attributes here */
398
399 switch (chip->usb_id) {
400 case USB_ID(0x0a92, 0x0053): /* AudioTrak Optoplay */
401 /* Optoplay sets the sample rate attribute although
402 * it seems not supporting it in fact.
403 */
404 fp->attributes &= ~UAC_EP_CS_ATTR_SAMPLE_RATE;
405 break;
406 case USB_ID(0x041e, 0x3020): /* Creative SB Audigy 2 NX */
407 case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
408 /* doesn't set the sample rate attribute, but supports it */
409 fp->attributes |= UAC_EP_CS_ATTR_SAMPLE_RATE;
410 break;
411 case USB_ID(0x0763, 0x2001): /* M-Audio Quattro USB */
412 case USB_ID(0x0763, 0x2012): /* M-Audio Fast Track Pro USB */
413 case USB_ID(0x047f, 0x0ca1): /* plantronics headset */
414 case USB_ID(0x077d, 0x07af): /* Griffin iMic (note that there is
415 an older model 77d:223) */
416 /*
417 * plantronics headset and Griffin iMic have set adaptive-in
418 * although it's really not...
419 */
420 fp->ep_attr &= ~USB_ENDPOINT_SYNCTYPE;
421 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
422 fp->ep_attr |= USB_ENDPOINT_SYNC_ADAPTIVE;
423 else
424 fp->ep_attr |= USB_ENDPOINT_SYNC_SYNC;
425 break;
426 }
427 924
428 /* ok, let's parse further... */ 925 return -EINVAL;
429 if (snd_usb_parse_audio_format(chip, fp, format, fmt, stream, alts) < 0) { 926}
430 kfree(fp->rate_table);
431 kfree(fp);
432 fp = NULL;
433 continue;
434 }
435 927
436 snd_printdd(KERN_INFO "%d:%u:%d: add audio endpoint %#x\n", dev->devnum, iface_no, altno, fp->endpoint); 928int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream, int cmd)
437 err = snd_usb_add_audio_endpoint(chip, stream, fp); 929{
438 if (err < 0) { 930 struct snd_usb_substream *subs = substream->runtime->private_data;
439 kfree(fp->rate_table); 931
440 kfree(fp); 932 switch (cmd) {
441 return err; 933 case SNDRV_PCM_TRIGGER_START:
442 } 934 subs->ops.retire = retire_capture_urb;
443 /* try to set the interface... */ 935 return start_urbs(subs, substream->runtime);
444 usb_set_interface(chip->dev, iface_no, altno); 936 case SNDRV_PCM_TRIGGER_STOP:
445 snd_usb_init_pitch(chip, iface_no, alts, fp); 937 return deactivate_urbs(subs, 0, 0);
446 snd_usb_init_sample_rate(chip, iface_no, alts, fp, fp->rate_max); 938 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
939 subs->ops.retire = retire_paused_capture_urb;
940 return 0;
941 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
942 subs->ops.retire = retire_capture_urb;
943 return 0;
447 } 944 }
945
946 return -EINVAL;
947}
948
949int snd_usb_substream_prepare(struct snd_usb_substream *subs,
950 struct snd_pcm_runtime *runtime)
951{
952 /* clear urbs (to be sure) */
953 deactivate_urbs(subs, 0, 1);
954 wait_clear_urbs(subs);
955
956 /* for playback, submit the URBs now; otherwise, the first hwptr_done
957 * updates for all URBs would happen at the same time when starting */
958 if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) {
959 subs->ops.prepare = prepare_nodata_playback_urb;
960 return start_urbs(subs, runtime);
961 }
962
448 return 0; 963 return 0;
449} 964}
450 965
diff --git a/sound/usb/endpoint.h b/sound/usb/endpoint.h
index 64dd0db023b..88eb63a636e 100644
--- a/sound/usb/endpoint.h
+++ b/sound/usb/endpoint.h
@@ -1,11 +1,21 @@
1#ifndef __USBAUDIO_ENDPOINT_H 1#ifndef __USBAUDIO_ENDPOINT_H
2#define __USBAUDIO_ENDPOINT_H 2#define __USBAUDIO_ENDPOINT_H
3 3
4int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, 4void snd_usb_init_substream(struct snd_usb_stream *as,
5 int iface_no); 5 int stream,
6 struct audioformat *fp);
6 7
7int snd_usb_add_audio_endpoint(struct snd_usb_audio *chip, 8int snd_usb_init_substream_urbs(struct snd_usb_substream *subs,
8 int stream, 9 unsigned int period_bytes,
9 struct audioformat *fp); 10 unsigned int rate,
11 unsigned int frame_bits);
12
13void snd_usb_release_substream_urbs(struct snd_usb_substream *subs, int force);
14
15int snd_usb_substream_prepare(struct snd_usb_substream *subs,
16 struct snd_pcm_runtime *runtime);
17
18int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substream, int cmd);
19int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream, int cmd);
10 20
11#endif /* __USBAUDIO_ENDPOINT_H */ 21#endif /* __USBAUDIO_ENDPOINT_H */
diff --git a/sound/usb/format.c b/sound/usb/format.c
index 8d042dce0d1..89421d17657 100644
--- a/sound/usb/format.c
+++ b/sound/usb/format.c
@@ -286,7 +286,7 @@ static int parse_audio_format_rates_v2(struct snd_usb_audio *chip,
286 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, 286 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
287 UAC2_CS_CONTROL_SAM_FREQ << 8, 287 UAC2_CS_CONTROL_SAM_FREQ << 8,
288 snd_usb_ctrl_intf(chip) | (clock << 8), 288 snd_usb_ctrl_intf(chip) | (clock << 8),
289 tmp, sizeof(tmp), 1000); 289 tmp, sizeof(tmp));
290 290
291 if (ret < 0) { 291 if (ret < 0) {
292 snd_printk(KERN_ERR "%s(): unable to retrieve number of sample rates (clock %d)\n", 292 snd_printk(KERN_ERR "%s(): unable to retrieve number of sample rates (clock %d)\n",
@@ -307,7 +307,7 @@ static int parse_audio_format_rates_v2(struct snd_usb_audio *chip,
307 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, 307 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
308 UAC2_CS_CONTROL_SAM_FREQ << 8, 308 UAC2_CS_CONTROL_SAM_FREQ << 8,
309 snd_usb_ctrl_intf(chip) | (clock << 8), 309 snd_usb_ctrl_intf(chip) | (clock << 8),
310 data, data_size, 1000); 310 data, data_size);
311 311
312 if (ret < 0) { 312 if (ret < 0) {
313 snd_printk(KERN_ERR "%s(): unable to retrieve sample rate range (clock %d)\n", 313 snd_printk(KERN_ERR "%s(): unable to retrieve sample rate range (clock %d)\n",
diff --git a/sound/usb/helper.c b/sound/usb/helper.c
index f280c1903c2..9eed8f40b17 100644
--- a/sound/usb/helper.c
+++ b/sound/usb/helper.c
@@ -81,7 +81,7 @@ void *snd_usb_find_csint_desc(void *buffer, int buflen, void *after, u8 dsubtype
81 */ 81 */
82int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe, __u8 request, 82int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe, __u8 request,
83 __u8 requesttype, __u16 value, __u16 index, void *data, 83 __u8 requesttype, __u16 value, __u16 index, void *data,
84 __u16 size, int timeout) 84 __u16 size)
85{ 85{
86 int err; 86 int err;
87 void *buf = NULL; 87 void *buf = NULL;
@@ -92,7 +92,7 @@ int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe, __u8 request,
92 return -ENOMEM; 92 return -ENOMEM;
93 } 93 }
94 err = usb_control_msg(dev, pipe, request, requesttype, 94 err = usb_control_msg(dev, pipe, request, requesttype,
95 value, index, buf, size, timeout); 95 value, index, buf, size, 1000);
96 if (size > 0) { 96 if (size > 0) {
97 memcpy(data, buf, size); 97 memcpy(data, buf, size);
98 kfree(buf); 98 kfree(buf);
diff --git a/sound/usb/helper.h b/sound/usb/helper.h
index 09bd943c43b..805c300dd00 100644
--- a/sound/usb/helper.h
+++ b/sound/usb/helper.h
@@ -8,7 +8,7 @@ void *snd_usb_find_csint_desc(void *descstart, int desclen, void *after, u8 dsub
8 8
9int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe, 9int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe,
10 __u8 request, __u8 requesttype, __u16 value, __u16 index, 10 __u8 request, __u8 requesttype, __u16 value, __u16 index,
11 void *data, __u16 size, int timeout); 11 void *data, __u16 size);
12 12
13unsigned char snd_usb_parse_datainterval(struct snd_usb_audio *chip, 13unsigned char snd_usb_parse_datainterval(struct snd_usb_audio *chip,
14 struct usb_host_interface *alts); 14 struct usb_host_interface *alts);
diff --git a/sound/usb/midi.c b/sound/usb/midi.c
index f9289102886..e21f026d957 100644
--- a/sound/usb/midi.c
+++ b/sound/usb/midi.c
@@ -816,6 +816,22 @@ static struct usb_protocol_ops snd_usbmidi_raw_ops = {
816 .output = snd_usbmidi_raw_output, 816 .output = snd_usbmidi_raw_output,
817}; 817};
818 818
819/*
820 * FTDI protocol: raw MIDI bytes, but input packets have two modem status bytes.
821 */
822
823static void snd_usbmidi_ftdi_input(struct snd_usb_midi_in_endpoint* ep,
824 uint8_t* buffer, int buffer_length)
825{
826 if (buffer_length > 2)
827 snd_usbmidi_input_data(ep, 0, buffer + 2, buffer_length - 2);
828}
829
830static struct usb_protocol_ops snd_usbmidi_ftdi_ops = {
831 .input = snd_usbmidi_ftdi_input,
832 .output = snd_usbmidi_raw_output,
833};
834
819static void snd_usbmidi_us122l_input(struct snd_usb_midi_in_endpoint *ep, 835static void snd_usbmidi_us122l_input(struct snd_usb_midi_in_endpoint *ep,
820 uint8_t *buffer, int buffer_length) 836 uint8_t *buffer, int buffer_length)
821{ 837{
@@ -2163,6 +2179,17 @@ int snd_usbmidi_create(struct snd_card *card,
2163 /* endpoint 1 is input-only */ 2179 /* endpoint 1 is input-only */
2164 endpoints[1].out_cables = 0; 2180 endpoints[1].out_cables = 0;
2165 break; 2181 break;
2182 case QUIRK_MIDI_FTDI:
2183 umidi->usb_protocol_ops = &snd_usbmidi_ftdi_ops;
2184
2185 /* set baud rate to 31250 (48 MHz / 16 / 96) */
2186 err = usb_control_msg(umidi->dev, usb_sndctrlpipe(umidi->dev, 0),
2187 3, 0x40, 0x60, 0, NULL, 0, 1000);
2188 if (err < 0)
2189 break;
2190
2191 err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
2192 break;
2166 default: 2193 default:
2167 snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type); 2194 snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type);
2168 err = -ENXIO; 2195 err = -ENXIO;
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index cdd19d7fe50..60f65ace747 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -296,7 +296,7 @@ static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, int v
296 if (snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), request, 296 if (snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), request,
297 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, 297 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
298 validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), 298 validx, snd_usb_ctrl_intf(chip) | (cval->id << 8),
299 buf, val_len, 100) >= val_len) { 299 buf, val_len) >= val_len) {
300 *value_ret = convert_signed_value(cval, snd_usb_combine_bytes(buf, val_len)); 300 *value_ret = convert_signed_value(cval, snd_usb_combine_bytes(buf, val_len));
301 snd_usb_autosuspend(cval->mixer->chip); 301 snd_usb_autosuspend(cval->mixer->chip);
302 return 0; 302 return 0;
@@ -333,7 +333,7 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int v
333 ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest, 333 ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest,
334 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, 334 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
335 validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), 335 validx, snd_usb_ctrl_intf(chip) | (cval->id << 8),
336 buf, size, 1000); 336 buf, size);
337 snd_usb_autosuspend(chip); 337 snd_usb_autosuspend(chip);
338 338
339 if (ret < 0) { 339 if (ret < 0) {
@@ -445,7 +445,7 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
445 usb_sndctrlpipe(chip->dev, 0), request, 445 usb_sndctrlpipe(chip->dev, 0), request,
446 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, 446 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
447 validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), 447 validx, snd_usb_ctrl_intf(chip) | (cval->id << 8),
448 buf, val_len, 100) >= 0) { 448 buf, val_len) >= 0) {
449 snd_usb_autosuspend(chip); 449 snd_usb_autosuspend(chip);
450 return 0; 450 return 0;
451 } 451 }
@@ -881,8 +881,17 @@ static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, struct snd_ctl_
881 uinfo->value.integer.min = 0; 881 uinfo->value.integer.min = 0;
882 uinfo->value.integer.max = 1; 882 uinfo->value.integer.max = 1;
883 } else { 883 } else {
884 if (! cval->initialized) 884 if (!cval->initialized) {
885 get_min_max(cval, 0); 885 get_min_max(cval, 0);
886 if (cval->initialized && cval->dBmin >= cval->dBmax) {
887 kcontrol->vd[0].access &=
888 ~(SNDRV_CTL_ELEM_ACCESS_TLV_READ |
889 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK);
890 snd_ctl_notify(cval->mixer->chip->card,
891 SNDRV_CTL_EVENT_MASK_INFO,
892 &kcontrol->id);
893 }
894 }
886 uinfo->value.integer.min = 0; 895 uinfo->value.integer.min = 0;
887 uinfo->value.integer.max = 896 uinfo->value.integer.max =
888 (cval->max - cval->min + cval->res - 1) / cval->res; 897 (cval->max - cval->min + cval->res - 1) / cval->res;
@@ -1250,7 +1259,7 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void
1250 build_feature_ctl(state, _ftr, 0, i, &iterm, unitid, 0); 1259 build_feature_ctl(state, _ftr, 0, i, &iterm, unitid, 0);
1251 } 1260 }
1252 } else { /* UAC_VERSION_2 */ 1261 } else { /* UAC_VERSION_2 */
1253 for (i = 0; i < 30/2; i++) { 1262 for (i = 0; i < ARRAY_SIZE(audio_feature_info); i++) {
1254 unsigned int ch_bits = 0; 1263 unsigned int ch_bits = 0;
1255 unsigned int ch_read_only = 0; 1264 unsigned int ch_read_only = 0;
1256 1265
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
index 3d0f4873112..ab125ee0b0f 100644
--- a/sound/usb/mixer_quirks.c
+++ b/sound/usb/mixer_quirks.c
@@ -190,18 +190,18 @@ static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
190 err = snd_usb_ctl_msg(mixer->chip->dev, 190 err = snd_usb_ctl_msg(mixer->chip->dev,
191 usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, 191 usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
192 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, 192 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
193 !value, 0, NULL, 0, 100); 193 !value, 0, NULL, 0);
194 /* USB X-Fi S51 Pro */ 194 /* USB X-Fi S51 Pro */
195 if (mixer->chip->usb_id == USB_ID(0x041e, 0x30df)) 195 if (mixer->chip->usb_id == USB_ID(0x041e, 0x30df))
196 err = snd_usb_ctl_msg(mixer->chip->dev, 196 err = snd_usb_ctl_msg(mixer->chip->dev,
197 usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, 197 usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
198 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, 198 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
199 !value, 0, NULL, 0, 100); 199 !value, 0, NULL, 0);
200 else 200 else
201 err = snd_usb_ctl_msg(mixer->chip->dev, 201 err = snd_usb_ctl_msg(mixer->chip->dev,
202 usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, 202 usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
203 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, 203 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
204 value, index + 2, NULL, 0, 100); 204 value, index + 2, NULL, 0);
205 if (err < 0) 205 if (err < 0)
206 return err; 206 return err;
207 mixer->audigy2nx_leds[index] = value; 207 mixer->audigy2nx_leds[index] = value;
@@ -299,7 +299,7 @@ static void snd_audigy2nx_proc_read(struct snd_info_entry *entry,
299 usb_rcvctrlpipe(mixer->chip->dev, 0), 299 usb_rcvctrlpipe(mixer->chip->dev, 0),
300 UAC_GET_MEM, USB_DIR_IN | USB_TYPE_CLASS | 300 UAC_GET_MEM, USB_DIR_IN | USB_TYPE_CLASS |
301 USB_RECIP_INTERFACE, 0, 301 USB_RECIP_INTERFACE, 0,
302 jacks[i].unitid << 8, buf, 3, 100); 302 jacks[i].unitid << 8, buf, 3);
303 if (err == 3 && (buf[0] == 3 || buf[0] == 6)) 303 if (err == 3 && (buf[0] == 3 || buf[0] == 6))
304 snd_iprintf(buffer, "%02x %02x\n", buf[1], buf[2]); 304 snd_iprintf(buffer, "%02x %02x\n", buf[1], buf[2]);
305 else 305 else
@@ -332,7 +332,7 @@ static int snd_xonar_u1_switch_put(struct snd_kcontrol *kcontrol,
332 err = snd_usb_ctl_msg(mixer->chip->dev, 332 err = snd_usb_ctl_msg(mixer->chip->dev,
333 usb_sndctrlpipe(mixer->chip->dev, 0), 0x08, 333 usb_sndctrlpipe(mixer->chip->dev, 0), 0x08,
334 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, 334 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
335 50, 0, &new_status, 1, 100); 335 50, 0, &new_status, 1);
336 if (err < 0) 336 if (err < 0)
337 return err; 337 return err;
338 mixer->xonar_u1_status = new_status; 338 mixer->xonar_u1_status = new_status;
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index b8dcbf407bb..0220b0f335b 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -28,12 +28,36 @@
28#include "card.h" 28#include "card.h"
29#include "quirks.h" 29#include "quirks.h"
30#include "debug.h" 30#include "debug.h"
31#include "urb.h" 31#include "endpoint.h"
32#include "helper.h" 32#include "helper.h"
33#include "pcm.h" 33#include "pcm.h"
34#include "clock.h" 34#include "clock.h"
35#include "power.h" 35#include "power.h"
36 36
37/* return the estimated delay based on USB frame counters */
38snd_pcm_uframes_t snd_usb_pcm_delay(struct snd_usb_substream *subs,
39 unsigned int rate)
40{
41 int current_frame_number;
42 int frame_diff;
43 int est_delay;
44
45 current_frame_number = usb_get_current_frame_number(subs->dev);
46 /*
47 * HCD implementations use different widths, use lower 8 bits.
48 * The delay will be managed up to 256ms, which is more than
49 * enough
50 */
51 frame_diff = (current_frame_number - subs->last_frame_number) & 0xff;
52
53 /* Approximation based on number of samples per USB frame (ms),
54 some truncation for 44.1 but the estimate is good enough */
55 est_delay = subs->last_delay - (frame_diff * rate / 1000);
56 if (est_delay < 0)
57 est_delay = 0;
58 return est_delay;
59}
60
37/* 61/*
38 * return the current pcm pointer. just based on the hwptr_done value. 62 * return the current pcm pointer. just based on the hwptr_done value.
39 */ 63 */
@@ -45,6 +69,8 @@ static snd_pcm_uframes_t snd_usb_pcm_pointer(struct snd_pcm_substream *substream
45 subs = (struct snd_usb_substream *)substream->runtime->private_data; 69 subs = (struct snd_usb_substream *)substream->runtime->private_data;
46 spin_lock(&subs->lock); 70 spin_lock(&subs->lock);
47 hwptr_done = subs->hwptr_done; 71 hwptr_done = subs->hwptr_done;
72 substream->runtime->delay = snd_usb_pcm_delay(subs,
73 substream->runtime->rate);
48 spin_unlock(&subs->lock); 74 spin_unlock(&subs->lock);
49 return hwptr_done / (substream->runtime->frame_bits >> 3); 75 return hwptr_done / (substream->runtime->frame_bits >> 3);
50} 76}
@@ -126,7 +152,7 @@ static int init_pitch_v1(struct snd_usb_audio *chip, int iface,
126 if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR, 152 if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR,
127 USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, 153 USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT,
128 UAC_EP_CS_ATTR_PITCH_CONTROL << 8, ep, 154 UAC_EP_CS_ATTR_PITCH_CONTROL << 8, ep,
129 data, sizeof(data), 1000)) < 0) { 155 data, sizeof(data))) < 0) {
130 snd_printk(KERN_ERR "%d:%d:%d: cannot set enable PITCH\n", 156 snd_printk(KERN_ERR "%d:%d:%d: cannot set enable PITCH\n",
131 dev->devnum, iface, ep); 157 dev->devnum, iface, ep);
132 return err; 158 return err;
@@ -150,7 +176,7 @@ static int init_pitch_v2(struct snd_usb_audio *chip, int iface,
150 if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR, 176 if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR,
151 USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_OUT, 177 USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_OUT,
152 UAC2_EP_CS_PITCH << 8, 0, 178 UAC2_EP_CS_PITCH << 8, 0,
153 data, sizeof(data), 1000)) < 0) { 179 data, sizeof(data))) < 0) {
154 snd_printk(KERN_ERR "%d:%d:%d: cannot set enable PITCH (v2)\n", 180 snd_printk(KERN_ERR "%d:%d:%d: cannot set enable PITCH (v2)\n",
155 dev->devnum, iface, fmt->altsetting); 181 dev->devnum, iface, fmt->altsetting);
156 return err; 182 return err;
@@ -417,6 +443,8 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
417 subs->hwptr_done = 0; 443 subs->hwptr_done = 0;
418 subs->transfer_done = 0; 444 subs->transfer_done = 0;
419 subs->phase = 0; 445 subs->phase = 0;
446 subs->last_delay = 0;
447 subs->last_frame_number = 0;
420 runtime->delay = 0; 448 runtime->delay = 0;
421 449
422 return snd_usb_substream_prepare(subs, runtime); 450 return snd_usb_substream_prepare(subs, runtime);
diff --git a/sound/usb/pcm.h b/sound/usb/pcm.h
index ed3e283f618..df7a003682a 100644
--- a/sound/usb/pcm.h
+++ b/sound/usb/pcm.h
@@ -1,6 +1,9 @@
1#ifndef __USBAUDIO_PCM_H 1#ifndef __USBAUDIO_PCM_H
2#define __USBAUDIO_PCM_H 2#define __USBAUDIO_PCM_H
3 3
4snd_pcm_uframes_t snd_usb_pcm_delay(struct snd_usb_substream *subs,
5 unsigned int rate);
6
4void snd_usb_set_pcm_ops(struct snd_pcm *pcm, int stream); 7void snd_usb_set_pcm_ops(struct snd_pcm *pcm, int stream);
5 8
6int snd_usb_init_pitch(struct snd_usb_audio *chip, int iface, 9int snd_usb_init_pitch(struct snd_usb_audio *chip, int iface,
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
index a42e3ef3832..b61945f3af9 100644
--- a/sound/usb/quirks-table.h
+++ b/sound/usb/quirks-table.h
@@ -39,6 +39,17 @@
39 .idProduct = prod, \ 39 .idProduct = prod, \
40 .bInterfaceClass = USB_CLASS_VENDOR_SPEC 40 .bInterfaceClass = USB_CLASS_VENDOR_SPEC
41 41
42/* FTDI devices */
43{
44 USB_DEVICE(0x0403, 0xb8d8),
45 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
46 /* .vendor_name = "STARR LABS", */
47 /* .product_name = "Starr Labs MIDI USB device", */
48 .ifnum = 0,
49 .type = QUIRK_MIDI_FTDI
50 }
51},
52
42/* Creative/Toshiba Multimedia Center SB-0500 */ 53/* Creative/Toshiba Multimedia Center SB-0500 */
43{ 54{
44 USB_DEVICE(0x041e, 0x3048), 55 USB_DEVICE(0x041e, 0x3048),
@@ -1678,6 +1689,20 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1678 } 1689 }
1679}, 1690},
1680{ 1691{
1692 /* Added support for Roland UM-ONE which differs from UM-1 */
1693 USB_DEVICE(0x0582, 0x012a),
1694 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1695 /* .vendor_name = "ROLAND", */
1696 /* .product_name = "UM-ONE", */
1697 .ifnum = 0,
1698 .type = QUIRK_MIDI_FIXED_ENDPOINT,
1699 .data = & (const struct snd_usb_midi_endpoint_info) {
1700 .out_cables = 0x0001,
1701 .in_cables = 0x0003
1702 }
1703 }
1704},
1705{
1681 USB_DEVICE(0x0582, 0x011e), 1706 USB_DEVICE(0x0582, 0x011e),
1682 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { 1707 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1683 /* .vendor_name = "BOSS", */ 1708 /* .vendor_name = "BOSS", */
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index 81e07d84258..2e5bc734402 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -34,6 +34,7 @@
34#include "endpoint.h" 34#include "endpoint.h"
35#include "pcm.h" 35#include "pcm.h"
36#include "clock.h" 36#include "clock.h"
37#include "stream.h"
37 38
38/* 39/*
39 * handle the quirks for the contained interfaces 40 * handle the quirks for the contained interfaces
@@ -106,7 +107,7 @@ static int create_standard_audio_quirk(struct snd_usb_audio *chip,
106 107
107 alts = &iface->altsetting[0]; 108 alts = &iface->altsetting[0];
108 altsd = get_iface_desc(alts); 109 altsd = get_iface_desc(alts);
109 err = snd_usb_parse_audio_endpoints(chip, altsd->bInterfaceNumber); 110 err = snd_usb_parse_audio_interface(chip, altsd->bInterfaceNumber);
110 if (err < 0) { 111 if (err < 0) {
111 snd_printk(KERN_ERR "cannot setup if %d: error %d\n", 112 snd_printk(KERN_ERR "cannot setup if %d: error %d\n",
112 altsd->bInterfaceNumber, err); 113 altsd->bInterfaceNumber, err);
@@ -147,7 +148,7 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip,
147 148
148 stream = (fp->endpoint & USB_DIR_IN) 149 stream = (fp->endpoint & USB_DIR_IN)
149 ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK; 150 ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
150 err = snd_usb_add_audio_endpoint(chip, stream, fp); 151 err = snd_usb_add_audio_stream(chip, stream, fp);
151 if (err < 0) { 152 if (err < 0) {
152 kfree(fp); 153 kfree(fp);
153 kfree(rate_table); 154 kfree(rate_table);
@@ -254,7 +255,7 @@ static int create_uaxx_quirk(struct snd_usb_audio *chip,
254 255
255 stream = (fp->endpoint & USB_DIR_IN) 256 stream = (fp->endpoint & USB_DIR_IN)
256 ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK; 257 ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
257 err = snd_usb_add_audio_endpoint(chip, stream, fp); 258 err = snd_usb_add_audio_stream(chip, stream, fp);
258 if (err < 0) { 259 if (err < 0) {
259 kfree(fp); 260 kfree(fp);
260 return err; 261 return err;
@@ -306,6 +307,7 @@ int snd_usb_create_quirk(struct snd_usb_audio *chip,
306 [QUIRK_MIDI_EMAGIC] = create_any_midi_quirk, 307 [QUIRK_MIDI_EMAGIC] = create_any_midi_quirk,
307 [QUIRK_MIDI_CME] = create_any_midi_quirk, 308 [QUIRK_MIDI_CME] = create_any_midi_quirk,
308 [QUIRK_MIDI_AKAI] = create_any_midi_quirk, 309 [QUIRK_MIDI_AKAI] = create_any_midi_quirk,
310 [QUIRK_MIDI_FTDI] = create_any_midi_quirk,
309 [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk, 311 [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk,
310 [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk, 312 [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk,
311 [QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk, 313 [QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk,
@@ -338,7 +340,7 @@ static int snd_usb_extigy_boot_quirk(struct usb_device *dev, struct usb_interfac
338 snd_printdd("sending Extigy boot sequence...\n"); 340 snd_printdd("sending Extigy boot sequence...\n");
339 /* Send message to force it to reconnect with full interface. */ 341 /* Send message to force it to reconnect with full interface. */
340 err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev,0), 342 err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev,0),
341 0x10, 0x43, 0x0001, 0x000a, NULL, 0, 1000); 343 0x10, 0x43, 0x0001, 0x000a, NULL, 0);
342 if (err < 0) snd_printdd("error sending boot message: %d\n", err); 344 if (err < 0) snd_printdd("error sending boot message: %d\n", err);
343 err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, 345 err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
344 &dev->descriptor, sizeof(dev->descriptor)); 346 &dev->descriptor, sizeof(dev->descriptor));
@@ -359,11 +361,11 @@ static int snd_usb_audigy2nx_boot_quirk(struct usb_device *dev)
359 361
360 snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), 0x2a, 362 snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), 0x2a,
361 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_OTHER, 363 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_OTHER,
362 0, 0, &buf, 1, 1000); 364 0, 0, &buf, 1);
363 if (buf == 0) { 365 if (buf == 0) {
364 snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 0x29, 366 snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 0x29,
365 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, 367 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
366 1, 2000, NULL, 0, 1000); 368 1, 2000, NULL, 0);
367 return -ENODEV; 369 return -ENODEV;
368 } 370 }
369 return 0; 371 return 0;
@@ -406,7 +408,7 @@ static int snd_usb_cm106_write_int_reg(struct usb_device *dev, int reg, u16 valu
406 buf[3] = reg; 408 buf[3] = reg;
407 return snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), USB_REQ_SET_CONFIGURATION, 409 return snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), USB_REQ_SET_CONFIGURATION,
408 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT, 410 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT,
409 0, 0, &buf, 4, 1000); 411 0, 0, &buf, 4);
410} 412}
411 413
412static int snd_usb_cm106_boot_quirk(struct usb_device *dev) 414static int snd_usb_cm106_boot_quirk(struct usb_device *dev)
diff --git a/sound/usb/stream.c b/sound/usb/stream.c
new file mode 100644
index 00000000000..5ff8010b2d6
--- /dev/null
+++ b/sound/usb/stream.c
@@ -0,0 +1,452 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15 */
16
17
18#include <linux/init.h>
19#include <linux/slab.h>
20#include <linux/usb.h>
21#include <linux/usb/audio.h>
22#include <linux/usb/audio-v2.h>
23
24#include <sound/core.h>
25#include <sound/pcm.h>
26
27#include "usbaudio.h"
28#include "card.h"
29#include "proc.h"
30#include "quirks.h"
31#include "endpoint.h"
32#include "pcm.h"
33#include "helper.h"
34#include "format.h"
35#include "clock.h"
36#include "stream.h"
37
38/*
39 * free a substream
40 */
41static void free_substream(struct snd_usb_substream *subs)
42{
43 struct list_head *p, *n;
44
45 if (!subs->num_formats)
46 return; /* not initialized */
47 list_for_each_safe(p, n, &subs->fmt_list) {
48 struct audioformat *fp = list_entry(p, struct audioformat, list);
49 kfree(fp->rate_table);
50 kfree(fp);
51 }
52 kfree(subs->rate_list.list);
53}
54
55
56/*
57 * free a usb stream instance
58 */
59static void snd_usb_audio_stream_free(struct snd_usb_stream *stream)
60{
61 free_substream(&stream->substream[0]);
62 free_substream(&stream->substream[1]);
63 list_del(&stream->list);
64 kfree(stream);
65}
66
67static void snd_usb_audio_pcm_free(struct snd_pcm *pcm)
68{
69 struct snd_usb_stream *stream = pcm->private_data;
70 if (stream) {
71 stream->pcm = NULL;
72 snd_usb_audio_stream_free(stream);
73 }
74}
75
76
77/*
78 * add this endpoint to the chip instance.
79 * if a stream with the same endpoint already exists, append to it.
80 * if not, create a new pcm stream.
81 */
82int snd_usb_add_audio_stream(struct snd_usb_audio *chip,
83 int stream,
84 struct audioformat *fp)
85{
86 struct list_head *p;
87 struct snd_usb_stream *as;
88 struct snd_usb_substream *subs;
89 struct snd_pcm *pcm;
90 int err;
91
92 list_for_each(p, &chip->pcm_list) {
93 as = list_entry(p, struct snd_usb_stream, list);
94 if (as->fmt_type != fp->fmt_type)
95 continue;
96 subs = &as->substream[stream];
97 if (!subs->endpoint)
98 continue;
99 if (subs->endpoint == fp->endpoint) {
100 list_add_tail(&fp->list, &subs->fmt_list);
101 subs->num_formats++;
102 subs->formats |= fp->formats;
103 return 0;
104 }
105 }
106 /* look for an empty stream */
107 list_for_each(p, &chip->pcm_list) {
108 as = list_entry(p, struct snd_usb_stream, list);
109 if (as->fmt_type != fp->fmt_type)
110 continue;
111 subs = &as->substream[stream];
112 if (subs->endpoint)
113 continue;
114 err = snd_pcm_new_stream(as->pcm, stream, 1);
115 if (err < 0)
116 return err;
117 snd_usb_init_substream(as, stream, fp);
118 return 0;
119 }
120
121 /* create a new pcm */
122 as = kzalloc(sizeof(*as), GFP_KERNEL);
123 if (!as)
124 return -ENOMEM;
125 as->pcm_index = chip->pcm_devs;
126 as->chip = chip;
127 as->fmt_type = fp->fmt_type;
128 err = snd_pcm_new(chip->card, "USB Audio", chip->pcm_devs,
129 stream == SNDRV_PCM_STREAM_PLAYBACK ? 1 : 0,
130 stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1,
131 &pcm);
132 if (err < 0) {
133 kfree(as);
134 return err;
135 }
136 as->pcm = pcm;
137 pcm->private_data = as;
138 pcm->private_free = snd_usb_audio_pcm_free;
139 pcm->info_flags = 0;
140 if (chip->pcm_devs > 0)
141 sprintf(pcm->name, "USB Audio #%d", chip->pcm_devs);
142 else
143 strcpy(pcm->name, "USB Audio");
144
145 snd_usb_init_substream(as, stream, fp);
146
147 list_add(&as->list, &chip->pcm_list);
148 chip->pcm_devs++;
149
150 snd_usb_proc_pcm_format_add(as);
151
152 return 0;
153}
154
155static int parse_uac_endpoint_attributes(struct snd_usb_audio *chip,
156 struct usb_host_interface *alts,
157 int protocol, int iface_no)
158{
159 /* parsed with a v1 header here. that's ok as we only look at the
160 * header first which is the same for both versions */
161 struct uac_iso_endpoint_descriptor *csep;
162 struct usb_interface_descriptor *altsd = get_iface_desc(alts);
163 int attributes = 0;
164
165 csep = snd_usb_find_desc(alts->endpoint[0].extra, alts->endpoint[0].extralen, NULL, USB_DT_CS_ENDPOINT);
166
167 /* Creamware Noah has this descriptor after the 2nd endpoint */
168 if (!csep && altsd->bNumEndpoints >= 2)
169 csep = snd_usb_find_desc(alts->endpoint[1].extra, alts->endpoint[1].extralen, NULL, USB_DT_CS_ENDPOINT);
170
171 if (!csep || csep->bLength < 7 ||
172 csep->bDescriptorSubtype != UAC_EP_GENERAL) {
173 snd_printk(KERN_WARNING "%d:%u:%d : no or invalid"
174 " class specific endpoint descriptor\n",
175 chip->dev->devnum, iface_no,
176 altsd->bAlternateSetting);
177 return 0;
178 }
179
180 if (protocol == UAC_VERSION_1) {
181 attributes = csep->bmAttributes;
182 } else {
183 struct uac2_iso_endpoint_descriptor *csep2 =
184 (struct uac2_iso_endpoint_descriptor *) csep;
185
186 attributes = csep->bmAttributes & UAC_EP_CS_ATTR_FILL_MAX;
187
188 /* emulate the endpoint attributes of a v1 device */
189 if (csep2->bmControls & UAC2_CONTROL_PITCH)
190 attributes |= UAC_EP_CS_ATTR_PITCH_CONTROL;
191 }
192
193 return attributes;
194}
195
196static struct uac2_input_terminal_descriptor *
197 snd_usb_find_input_terminal_descriptor(struct usb_host_interface *ctrl_iface,
198 int terminal_id)
199{
200 struct uac2_input_terminal_descriptor *term = NULL;
201
202 while ((term = snd_usb_find_csint_desc(ctrl_iface->extra,
203 ctrl_iface->extralen,
204 term, UAC_INPUT_TERMINAL))) {
205 if (term->bTerminalID == terminal_id)
206 return term;
207 }
208
209 return NULL;
210}
211
212static struct uac2_output_terminal_descriptor *
213 snd_usb_find_output_terminal_descriptor(struct usb_host_interface *ctrl_iface,
214 int terminal_id)
215{
216 struct uac2_output_terminal_descriptor *term = NULL;
217
218 while ((term = snd_usb_find_csint_desc(ctrl_iface->extra,
219 ctrl_iface->extralen,
220 term, UAC_OUTPUT_TERMINAL))) {
221 if (term->bTerminalID == terminal_id)
222 return term;
223 }
224
225 return NULL;
226}
227
228int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)
229{
230 struct usb_device *dev;
231 struct usb_interface *iface;
232 struct usb_host_interface *alts;
233 struct usb_interface_descriptor *altsd;
234 int i, altno, err, stream;
235 int format = 0, num_channels = 0;
236 struct audioformat *fp = NULL;
237 int num, protocol, clock = 0;
238 struct uac_format_type_i_continuous_descriptor *fmt;
239
240 dev = chip->dev;
241
242 /* parse the interface's altsettings */
243 iface = usb_ifnum_to_if(dev, iface_no);
244
245 num = iface->num_altsetting;
246
247 /*
248 * Dallas DS4201 workaround: It presents 5 altsettings, but the last
249 * one misses syncpipe, and does not produce any sound.
250 */
251 if (chip->usb_id == USB_ID(0x04fa, 0x4201))
252 num = 4;
253
254 for (i = 0; i < num; i++) {
255 alts = &iface->altsetting[i];
256 altsd = get_iface_desc(alts);
257 protocol = altsd->bInterfaceProtocol;
258 /* skip invalid one */
259 if ((altsd->bInterfaceClass != USB_CLASS_AUDIO &&
260 altsd->bInterfaceClass != USB_CLASS_VENDOR_SPEC) ||
261 (altsd->bInterfaceSubClass != USB_SUBCLASS_AUDIOSTREAMING &&
262 altsd->bInterfaceSubClass != USB_SUBCLASS_VENDOR_SPEC) ||
263 altsd->bNumEndpoints < 1 ||
264 le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) == 0)
265 continue;
266 /* must be isochronous */
267 if ((get_endpoint(alts, 0)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) !=
268 USB_ENDPOINT_XFER_ISOC)
269 continue;
270 /* check direction */
271 stream = (get_endpoint(alts, 0)->bEndpointAddress & USB_DIR_IN) ?
272 SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
273 altno = altsd->bAlternateSetting;
274
275 if (snd_usb_apply_interface_quirk(chip, iface_no, altno))
276 continue;
277
278 /* get audio formats */
279 switch (protocol) {
280 default:
281 snd_printdd(KERN_WARNING "%d:%u:%d: unknown interface protocol %#02x, assuming v1\n",
282 dev->devnum, iface_no, altno, protocol);
283 protocol = UAC_VERSION_1;
284 /* fall through */
285
286 case UAC_VERSION_1: {
287 struct uac1_as_header_descriptor *as =
288 snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL);
289
290 if (!as) {
291 snd_printk(KERN_ERR "%d:%u:%d : UAC_AS_GENERAL descriptor not found\n",
292 dev->devnum, iface_no, altno);
293 continue;
294 }
295
296 if (as->bLength < sizeof(*as)) {
297 snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_AS_GENERAL desc\n",
298 dev->devnum, iface_no, altno);
299 continue;
300 }
301
302 format = le16_to_cpu(as->wFormatTag); /* remember the format value */
303 break;
304 }
305
306 case UAC_VERSION_2: {
307 struct uac2_input_terminal_descriptor *input_term;
308 struct uac2_output_terminal_descriptor *output_term;
309 struct uac2_as_header_descriptor *as =
310 snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL);
311
312 if (!as) {
313 snd_printk(KERN_ERR "%d:%u:%d : UAC_AS_GENERAL descriptor not found\n",
314 dev->devnum, iface_no, altno);
315 continue;
316 }
317
318 if (as->bLength < sizeof(*as)) {
319 snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_AS_GENERAL desc\n",
320 dev->devnum, iface_no, altno);
321 continue;
322 }
323
324 num_channels = as->bNrChannels;
325 format = le32_to_cpu(as->bmFormats);
326
327 /* lookup the terminal associated to this interface
328 * to extract the clock */
329 input_term = snd_usb_find_input_terminal_descriptor(chip->ctrl_intf,
330 as->bTerminalLink);
331 if (input_term) {
332 clock = input_term->bCSourceID;
333 break;
334 }
335
336 output_term = snd_usb_find_output_terminal_descriptor(chip->ctrl_intf,
337 as->bTerminalLink);
338 if (output_term) {
339 clock = output_term->bCSourceID;
340 break;
341 }
342
343 snd_printk(KERN_ERR "%d:%u:%d : bogus bTerminalLink %d\n",
344 dev->devnum, iface_no, altno, as->bTerminalLink);
345 continue;
346 }
347 }
348
349 /* get format type */
350 fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_FORMAT_TYPE);
351 if (!fmt) {
352 snd_printk(KERN_ERR "%d:%u:%d : no UAC_FORMAT_TYPE desc\n",
353 dev->devnum, iface_no, altno);
354 continue;
355 }
356 if (((protocol == UAC_VERSION_1) && (fmt->bLength < 8)) ||
357 ((protocol == UAC_VERSION_2) && (fmt->bLength < 6))) {
358 snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n",
359 dev->devnum, iface_no, altno);
360 continue;
361 }
362
363 /*
364 * Blue Microphones workaround: The last altsetting is identical
365 * with the previous one, except for a larger packet size, but
366 * is actually a mislabeled two-channel setting; ignore it.
367 */
368 if (fmt->bNrChannels == 1 &&
369 fmt->bSubframeSize == 2 &&
370 altno == 2 && num == 3 &&
371 fp && fp->altsetting == 1 && fp->channels == 1 &&
372 fp->formats == SNDRV_PCM_FMTBIT_S16_LE &&
373 protocol == UAC_VERSION_1 &&
374 le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) ==
375 fp->maxpacksize * 2)
376 continue;
377
378 fp = kzalloc(sizeof(*fp), GFP_KERNEL);
379 if (! fp) {
380 snd_printk(KERN_ERR "cannot malloc\n");
381 return -ENOMEM;
382 }
383
384 fp->iface = iface_no;
385 fp->altsetting = altno;
386 fp->altset_idx = i;
387 fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;
388 fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
389 fp->datainterval = snd_usb_parse_datainterval(chip, alts);
390 fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
391 /* num_channels is only set for v2 interfaces */
392 fp->channels = num_channels;
393 if (snd_usb_get_speed(dev) == USB_SPEED_HIGH)
394 fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1)
395 * (fp->maxpacksize & 0x7ff);
396 fp->attributes = parse_uac_endpoint_attributes(chip, alts, protocol, iface_no);
397 fp->clock = clock;
398
399 /* some quirks for attributes here */
400
401 switch (chip->usb_id) {
402 case USB_ID(0x0a92, 0x0053): /* AudioTrak Optoplay */
403 /* Optoplay sets the sample rate attribute although
404 * it seems not supporting it in fact.
405 */
406 fp->attributes &= ~UAC_EP_CS_ATTR_SAMPLE_RATE;
407 break;
408 case USB_ID(0x041e, 0x3020): /* Creative SB Audigy 2 NX */
409 case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
410 /* doesn't set the sample rate attribute, but supports it */
411 fp->attributes |= UAC_EP_CS_ATTR_SAMPLE_RATE;
412 break;
413 case USB_ID(0x0763, 0x2001): /* M-Audio Quattro USB */
414 case USB_ID(0x0763, 0x2012): /* M-Audio Fast Track Pro USB */
415 case USB_ID(0x047f, 0x0ca1): /* plantronics headset */
416 case USB_ID(0x077d, 0x07af): /* Griffin iMic (note that there is
417 an older model 77d:223) */
418 /*
419 * plantronics headset and Griffin iMic have set adaptive-in
420 * although it's really not...
421 */
422 fp->ep_attr &= ~USB_ENDPOINT_SYNCTYPE;
423 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
424 fp->ep_attr |= USB_ENDPOINT_SYNC_ADAPTIVE;
425 else
426 fp->ep_attr |= USB_ENDPOINT_SYNC_SYNC;
427 break;
428 }
429
430 /* ok, let's parse further... */
431 if (snd_usb_parse_audio_format(chip, fp, format, fmt, stream, alts) < 0) {
432 kfree(fp->rate_table);
433 kfree(fp);
434 fp = NULL;
435 continue;
436 }
437
438 snd_printdd(KERN_INFO "%d:%u:%d: add audio endpoint %#x\n", dev->devnum, iface_no, altno, fp->endpoint);
439 err = snd_usb_add_audio_stream(chip, stream, fp);
440 if (err < 0) {
441 kfree(fp->rate_table);
442 kfree(fp);
443 return err;
444 }
445 /* try to set the interface... */
446 usb_set_interface(chip->dev, iface_no, altno);
447 snd_usb_init_pitch(chip, iface_no, alts, fp);
448 snd_usb_init_sample_rate(chip, iface_no, alts, fp, fp->rate_max);
449 }
450 return 0;
451}
452
diff --git a/sound/usb/stream.h b/sound/usb/stream.h
new file mode 100644
index 00000000000..c97f679fc84
--- /dev/null
+++ b/sound/usb/stream.h
@@ -0,0 +1,12 @@
1#ifndef __USBAUDIO_STREAM_H
2#define __USBAUDIO_STREAM_H
3
4int snd_usb_parse_audio_interface(struct snd_usb_audio *chip,
5 int iface_no);
6
7int snd_usb_add_audio_stream(struct snd_usb_audio *chip,
8 int stream,
9 struct audioformat *fp);
10
11#endif /* __USBAUDIO_STREAM_H */
12
diff --git a/sound/usb/urb.c b/sound/usb/urb.c
deleted file mode 100644
index e184349aee8..00000000000
--- a/sound/usb/urb.c
+++ /dev/null
@@ -1,941 +0,0 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15 *
16 */
17
18#include <linux/gfp.h>
19#include <linux/init.h>
20#include <linux/usb.h>
21#include <linux/usb/audio.h>
22
23#include <sound/core.h>
24#include <sound/pcm.h>
25
26#include "usbaudio.h"
27#include "helper.h"
28#include "card.h"
29#include "urb.h"
30#include "pcm.h"
31
32/*
33 * convert a sampling rate into our full speed format (fs/1000 in Q16.16)
34 * this will overflow at approx 524 kHz
35 */
36static inline unsigned get_usb_full_speed_rate(unsigned int rate)
37{
38 return ((rate << 13) + 62) / 125;
39}
40
41/*
42 * convert a sampling rate into USB high speed format (fs/8000 in Q16.16)
43 * this will overflow at approx 4 MHz
44 */
45static inline unsigned get_usb_high_speed_rate(unsigned int rate)
46{
47 return ((rate << 10) + 62) / 125;
48}
49
50/*
51 * unlink active urbs.
52 */
53static int deactivate_urbs(struct snd_usb_substream *subs, int force, int can_sleep)
54{
55 struct snd_usb_audio *chip = subs->stream->chip;
56 unsigned int i;
57 int async;
58
59 subs->running = 0;
60
61 if (!force && subs->stream->chip->shutdown) /* to be sure... */
62 return -EBADFD;
63
64 async = !can_sleep && chip->async_unlink;
65
66 if (!async && in_interrupt())
67 return 0;
68
69 for (i = 0; i < subs->nurbs; i++) {
70 if (test_bit(i, &subs->active_mask)) {
71 if (!test_and_set_bit(i, &subs->unlink_mask)) {
72 struct urb *u = subs->dataurb[i].urb;
73 if (async)
74 usb_unlink_urb(u);
75 else
76 usb_kill_urb(u);
77 }
78 }
79 }
80 if (subs->syncpipe) {
81 for (i = 0; i < SYNC_URBS; i++) {
82 if (test_bit(i+16, &subs->active_mask)) {
83 if (!test_and_set_bit(i+16, &subs->unlink_mask)) {
84 struct urb *u = subs->syncurb[i].urb;
85 if (async)
86 usb_unlink_urb(u);
87 else
88 usb_kill_urb(u);
89 }
90 }
91 }
92 }
93 return 0;
94}
95
96
97/*
98 * release a urb data
99 */
100static void release_urb_ctx(struct snd_urb_ctx *u)
101{
102 if (u->urb) {
103 if (u->buffer_size)
104 usb_free_coherent(u->subs->dev, u->buffer_size,
105 u->urb->transfer_buffer,
106 u->urb->transfer_dma);
107 usb_free_urb(u->urb);
108 u->urb = NULL;
109 }
110}
111
112/*
113 * wait until all urbs are processed.
114 */
115static int wait_clear_urbs(struct snd_usb_substream *subs)
116{
117 unsigned long end_time = jiffies + msecs_to_jiffies(1000);
118 unsigned int i;
119 int alive;
120
121 do {
122 alive = 0;
123 for (i = 0; i < subs->nurbs; i++) {
124 if (test_bit(i, &subs->active_mask))
125 alive++;
126 }
127 if (subs->syncpipe) {
128 for (i = 0; i < SYNC_URBS; i++) {
129 if (test_bit(i + 16, &subs->active_mask))
130 alive++;
131 }
132 }
133 if (! alive)
134 break;
135 schedule_timeout_uninterruptible(1);
136 } while (time_before(jiffies, end_time));
137 if (alive)
138 snd_printk(KERN_ERR "timeout: still %d active urbs..\n", alive);
139 return 0;
140}
141
142/*
143 * release a substream
144 */
145void snd_usb_release_substream_urbs(struct snd_usb_substream *subs, int force)
146{
147 int i;
148
149 /* stop urbs (to be sure) */
150 deactivate_urbs(subs, force, 1);
151 wait_clear_urbs(subs);
152
153 for (i = 0; i < MAX_URBS; i++)
154 release_urb_ctx(&subs->dataurb[i]);
155 for (i = 0; i < SYNC_URBS; i++)
156 release_urb_ctx(&subs->syncurb[i]);
157 usb_free_coherent(subs->dev, SYNC_URBS * 4,
158 subs->syncbuf, subs->sync_dma);
159 subs->syncbuf = NULL;
160 subs->nurbs = 0;
161}
162
163/*
164 * complete callback from data urb
165 */
166static void snd_complete_urb(struct urb *urb)
167{
168 struct snd_urb_ctx *ctx = urb->context;
169 struct snd_usb_substream *subs = ctx->subs;
170 struct snd_pcm_substream *substream = ctx->subs->pcm_substream;
171 int err = 0;
172
173 if ((subs->running && subs->ops.retire(subs, substream->runtime, urb)) ||
174 !subs->running || /* can be stopped during retire callback */
175 (err = subs->ops.prepare(subs, substream->runtime, urb)) < 0 ||
176 (err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
177 clear_bit(ctx->index, &subs->active_mask);
178 if (err < 0) {
179 snd_printd(KERN_ERR "cannot submit urb (err = %d)\n", err);
180 snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
181 }
182 }
183}
184
185
186/*
187 * complete callback from sync urb
188 */
189static void snd_complete_sync_urb(struct urb *urb)
190{
191 struct snd_urb_ctx *ctx = urb->context;
192 struct snd_usb_substream *subs = ctx->subs;
193 struct snd_pcm_substream *substream = ctx->subs->pcm_substream;
194 int err = 0;
195
196 if ((subs->running && subs->ops.retire_sync(subs, substream->runtime, urb)) ||
197 !subs->running || /* can be stopped during retire callback */
198 (err = subs->ops.prepare_sync(subs, substream->runtime, urb)) < 0 ||
199 (err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
200 clear_bit(ctx->index + 16, &subs->active_mask);
201 if (err < 0) {
202 snd_printd(KERN_ERR "cannot submit sync urb (err = %d)\n", err);
203 snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
204 }
205 }
206}
207
208
209/*
210 * initialize a substream for plaback/capture
211 */
212int snd_usb_init_substream_urbs(struct snd_usb_substream *subs,
213 unsigned int period_bytes,
214 unsigned int rate,
215 unsigned int frame_bits)
216{
217 unsigned int maxsize, i;
218 int is_playback = subs->direction == SNDRV_PCM_STREAM_PLAYBACK;
219 unsigned int urb_packs, total_packs, packs_per_ms;
220 struct snd_usb_audio *chip = subs->stream->chip;
221
222 /* calculate the frequency in 16.16 format */
223 if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL)
224 subs->freqn = get_usb_full_speed_rate(rate);
225 else
226 subs->freqn = get_usb_high_speed_rate(rate);
227 subs->freqm = subs->freqn;
228 subs->freqshift = INT_MIN;
229 /* calculate max. frequency */
230 if (subs->maxpacksize) {
231 /* whatever fits into a max. size packet */
232 maxsize = subs->maxpacksize;
233 subs->freqmax = (maxsize / (frame_bits >> 3))
234 << (16 - subs->datainterval);
235 } else {
236 /* no max. packet size: just take 25% higher than nominal */
237 subs->freqmax = subs->freqn + (subs->freqn >> 2);
238 maxsize = ((subs->freqmax + 0xffff) * (frame_bits >> 3))
239 >> (16 - subs->datainterval);
240 }
241 subs->phase = 0;
242
243 if (subs->fill_max)
244 subs->curpacksize = subs->maxpacksize;
245 else
246 subs->curpacksize = maxsize;
247
248 if (snd_usb_get_speed(subs->dev) != USB_SPEED_FULL)
249 packs_per_ms = 8 >> subs->datainterval;
250 else
251 packs_per_ms = 1;
252
253 if (is_playback) {
254 urb_packs = max(chip->nrpacks, 1);
255 urb_packs = min(urb_packs, (unsigned int)MAX_PACKS);
256 } else
257 urb_packs = 1;
258 urb_packs *= packs_per_ms;
259 if (subs->syncpipe)
260 urb_packs = min(urb_packs, 1U << subs->syncinterval);
261
262 /* decide how many packets to be used */
263 if (is_playback) {
264 unsigned int minsize, maxpacks;
265 /* determine how small a packet can be */
266 minsize = (subs->freqn >> (16 - subs->datainterval))
267 * (frame_bits >> 3);
268 /* with sync from device, assume it can be 12% lower */
269 if (subs->syncpipe)
270 minsize -= minsize >> 3;
271 minsize = max(minsize, 1u);
272 total_packs = (period_bytes + minsize - 1) / minsize;
273 /* we need at least two URBs for queueing */
274 if (total_packs < 2) {
275 total_packs = 2;
276 } else {
277 /* and we don't want too long a queue either */
278 maxpacks = max(MAX_QUEUE * packs_per_ms, urb_packs * 2);
279 total_packs = min(total_packs, maxpacks);
280 }
281 } else {
282 while (urb_packs > 1 && urb_packs * maxsize >= period_bytes)
283 urb_packs >>= 1;
284 total_packs = MAX_URBS * urb_packs;
285 }
286 subs->nurbs = (total_packs + urb_packs - 1) / urb_packs;
287 if (subs->nurbs > MAX_URBS) {
288 /* too much... */
289 subs->nurbs = MAX_URBS;
290 total_packs = MAX_URBS * urb_packs;
291 } else if (subs->nurbs < 2) {
292 /* too little - we need at least two packets
293 * to ensure contiguous playback/capture
294 */
295 subs->nurbs = 2;
296 }
297
298 /* allocate and initialize data urbs */
299 for (i = 0; i < subs->nurbs; i++) {
300 struct snd_urb_ctx *u = &subs->dataurb[i];
301 u->index = i;
302 u->subs = subs;
303 u->packets = (i + 1) * total_packs / subs->nurbs
304 - i * total_packs / subs->nurbs;
305 u->buffer_size = maxsize * u->packets;
306 if (subs->fmt_type == UAC_FORMAT_TYPE_II)
307 u->packets++; /* for transfer delimiter */
308 u->urb = usb_alloc_urb(u->packets, GFP_KERNEL);
309 if (!u->urb)
310 goto out_of_memory;
311 u->urb->transfer_buffer =
312 usb_alloc_coherent(subs->dev, u->buffer_size,
313 GFP_KERNEL, &u->urb->transfer_dma);
314 if (!u->urb->transfer_buffer)
315 goto out_of_memory;
316 u->urb->pipe = subs->datapipe;
317 u->urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
318 u->urb->interval = 1 << subs->datainterval;
319 u->urb->context = u;
320 u->urb->complete = snd_complete_urb;
321 }
322
323 if (subs->syncpipe) {
324 /* allocate and initialize sync urbs */
325 subs->syncbuf = usb_alloc_coherent(subs->dev, SYNC_URBS * 4,
326 GFP_KERNEL, &subs->sync_dma);
327 if (!subs->syncbuf)
328 goto out_of_memory;
329 for (i = 0; i < SYNC_URBS; i++) {
330 struct snd_urb_ctx *u = &subs->syncurb[i];
331 u->index = i;
332 u->subs = subs;
333 u->packets = 1;
334 u->urb = usb_alloc_urb(1, GFP_KERNEL);
335 if (!u->urb)
336 goto out_of_memory;
337 u->urb->transfer_buffer = subs->syncbuf + i * 4;
338 u->urb->transfer_dma = subs->sync_dma + i * 4;
339 u->urb->transfer_buffer_length = 4;
340 u->urb->pipe = subs->syncpipe;
341 u->urb->transfer_flags = URB_ISO_ASAP |
342 URB_NO_TRANSFER_DMA_MAP;
343 u->urb->number_of_packets = 1;
344 u->urb->interval = 1 << subs->syncinterval;
345 u->urb->context = u;
346 u->urb->complete = snd_complete_sync_urb;
347 }
348 }
349 return 0;
350
351out_of_memory:
352 snd_usb_release_substream_urbs(subs, 0);
353 return -ENOMEM;
354}
355
356/*
357 * prepare urb for full speed capture sync pipe
358 *
359 * fill the length and offset of each urb descriptor.
360 * the fixed 10.14 frequency is passed through the pipe.
361 */
362static int prepare_capture_sync_urb(struct snd_usb_substream *subs,
363 struct snd_pcm_runtime *runtime,
364 struct urb *urb)
365{
366 unsigned char *cp = urb->transfer_buffer;
367 struct snd_urb_ctx *ctx = urb->context;
368
369 urb->dev = ctx->subs->dev; /* we need to set this at each time */
370 urb->iso_frame_desc[0].length = 3;
371 urb->iso_frame_desc[0].offset = 0;
372 cp[0] = subs->freqn >> 2;
373 cp[1] = subs->freqn >> 10;
374 cp[2] = subs->freqn >> 18;
375 return 0;
376}
377
378/*
379 * prepare urb for high speed capture sync pipe
380 *
381 * fill the length and offset of each urb descriptor.
382 * the fixed 12.13 frequency is passed as 16.16 through the pipe.
383 */
384static int prepare_capture_sync_urb_hs(struct snd_usb_substream *subs,
385 struct snd_pcm_runtime *runtime,
386 struct urb *urb)
387{
388 unsigned char *cp = urb->transfer_buffer;
389 struct snd_urb_ctx *ctx = urb->context;
390
391 urb->dev = ctx->subs->dev; /* we need to set this at each time */
392 urb->iso_frame_desc[0].length = 4;
393 urb->iso_frame_desc[0].offset = 0;
394 cp[0] = subs->freqn;
395 cp[1] = subs->freqn >> 8;
396 cp[2] = subs->freqn >> 16;
397 cp[3] = subs->freqn >> 24;
398 return 0;
399}
400
401/*
402 * process after capture sync complete
403 * - nothing to do
404 */
405static int retire_capture_sync_urb(struct snd_usb_substream *subs,
406 struct snd_pcm_runtime *runtime,
407 struct urb *urb)
408{
409 return 0;
410}
411
412/*
413 * prepare urb for capture data pipe
414 *
415 * fill the offset and length of each descriptor.
416 *
417 * we use a temporary buffer to write the captured data.
418 * since the length of written data is determined by host, we cannot
419 * write onto the pcm buffer directly... the data is thus copied
420 * later at complete callback to the global buffer.
421 */
422static int prepare_capture_urb(struct snd_usb_substream *subs,
423 struct snd_pcm_runtime *runtime,
424 struct urb *urb)
425{
426 int i, offs;
427 struct snd_urb_ctx *ctx = urb->context;
428
429 offs = 0;
430 urb->dev = ctx->subs->dev; /* we need to set this at each time */
431 for (i = 0; i < ctx->packets; i++) {
432 urb->iso_frame_desc[i].offset = offs;
433 urb->iso_frame_desc[i].length = subs->curpacksize;
434 offs += subs->curpacksize;
435 }
436 urb->transfer_buffer_length = offs;
437 urb->number_of_packets = ctx->packets;
438 return 0;
439}
440
441/*
442 * process after capture complete
443 *
444 * copy the data from each desctiptor to the pcm buffer, and
445 * update the current position.
446 */
447static int retire_capture_urb(struct snd_usb_substream *subs,
448 struct snd_pcm_runtime *runtime,
449 struct urb *urb)
450{
451 unsigned long flags;
452 unsigned char *cp;
453 int i;
454 unsigned int stride, frames, bytes, oldptr;
455 int period_elapsed = 0;
456
457 stride = runtime->frame_bits >> 3;
458
459 for (i = 0; i < urb->number_of_packets; i++) {
460 cp = (unsigned char *)urb->transfer_buffer + urb->iso_frame_desc[i].offset;
461 if (urb->iso_frame_desc[i].status) {
462 snd_printd(KERN_ERR "frame %d active: %d\n", i, urb->iso_frame_desc[i].status);
463 // continue;
464 }
465 bytes = urb->iso_frame_desc[i].actual_length;
466 frames = bytes / stride;
467 if (!subs->txfr_quirk)
468 bytes = frames * stride;
469 if (bytes % (runtime->sample_bits >> 3) != 0) {
470#ifdef CONFIG_SND_DEBUG_VERBOSE
471 int oldbytes = bytes;
472#endif
473 bytes = frames * stride;
474 snd_printdd(KERN_ERR "Corrected urb data len. %d->%d\n",
475 oldbytes, bytes);
476 }
477 /* update the current pointer */
478 spin_lock_irqsave(&subs->lock, flags);
479 oldptr = subs->hwptr_done;
480 subs->hwptr_done += bytes;
481 if (subs->hwptr_done >= runtime->buffer_size * stride)
482 subs->hwptr_done -= runtime->buffer_size * stride;
483 frames = (bytes + (oldptr % stride)) / stride;
484 subs->transfer_done += frames;
485 if (subs->transfer_done >= runtime->period_size) {
486 subs->transfer_done -= runtime->period_size;
487 period_elapsed = 1;
488 }
489 spin_unlock_irqrestore(&subs->lock, flags);
490 /* copy a data chunk */
491 if (oldptr + bytes > runtime->buffer_size * stride) {
492 unsigned int bytes1 =
493 runtime->buffer_size * stride - oldptr;
494 memcpy(runtime->dma_area + oldptr, cp, bytes1);
495 memcpy(runtime->dma_area, cp + bytes1, bytes - bytes1);
496 } else {
497 memcpy(runtime->dma_area + oldptr, cp, bytes);
498 }
499 }
500 if (period_elapsed)
501 snd_pcm_period_elapsed(subs->pcm_substream);
502 return 0;
503}
504
505/*
506 * Process after capture complete when paused. Nothing to do.
507 */
508static int retire_paused_capture_urb(struct snd_usb_substream *subs,
509 struct snd_pcm_runtime *runtime,
510 struct urb *urb)
511{
512 return 0;
513}
514
515
516/*
517 * prepare urb for playback sync pipe
518 *
519 * set up the offset and length to receive the current frequency.
520 */
521static int prepare_playback_sync_urb(struct snd_usb_substream *subs,
522 struct snd_pcm_runtime *runtime,
523 struct urb *urb)
524{
525 struct snd_urb_ctx *ctx = urb->context;
526
527 urb->dev = ctx->subs->dev; /* we need to set this at each time */
528 urb->iso_frame_desc[0].length = min(4u, ctx->subs->syncmaxsize);
529 urb->iso_frame_desc[0].offset = 0;
530 return 0;
531}
532
533/*
534 * process after playback sync complete
535 *
536 * Full speed devices report feedback values in 10.14 format as samples per
537 * frame, high speed devices in 16.16 format as samples per microframe.
538 * Because the Audio Class 1 spec was written before USB 2.0, many high speed
539 * devices use a wrong interpretation, some others use an entirely different
540 * format. Therefore, we cannot predict what format any particular device uses
541 * and must detect it automatically.
542 */
543static int retire_playback_sync_urb(struct snd_usb_substream *subs,
544 struct snd_pcm_runtime *runtime,
545 struct urb *urb)
546{
547 unsigned int f;
548 int shift;
549 unsigned long flags;
550
551 if (urb->iso_frame_desc[0].status != 0 ||
552 urb->iso_frame_desc[0].actual_length < 3)
553 return 0;
554
555 f = le32_to_cpup(urb->transfer_buffer);
556 if (urb->iso_frame_desc[0].actual_length == 3)
557 f &= 0x00ffffff;
558 else
559 f &= 0x0fffffff;
560 if (f == 0)
561 return 0;
562
563 if (unlikely(subs->freqshift == INT_MIN)) {
564 /*
565 * The first time we see a feedback value, determine its format
566 * by shifting it left or right until it matches the nominal
567 * frequency value. This assumes that the feedback does not
568 * differ from the nominal value more than +50% or -25%.
569 */
570 shift = 0;
571 while (f < subs->freqn - subs->freqn / 4) {
572 f <<= 1;
573 shift++;
574 }
575 while (f > subs->freqn + subs->freqn / 2) {
576 f >>= 1;
577 shift--;
578 }
579 subs->freqshift = shift;
580 }
581 else if (subs->freqshift >= 0)
582 f <<= subs->freqshift;
583 else
584 f >>= -subs->freqshift;
585
586 if (likely(f >= subs->freqn - subs->freqn / 8 && f <= subs->freqmax)) {
587 /*
588 * If the frequency looks valid, set it.
589 * This value is referred to in prepare_playback_urb().
590 */
591 spin_lock_irqsave(&subs->lock, flags);
592 subs->freqm = f;
593 spin_unlock_irqrestore(&subs->lock, flags);
594 } else {
595 /*
596 * Out of range; maybe the shift value is wrong.
597 * Reset it so that we autodetect again the next time.
598 */
599 subs->freqshift = INT_MIN;
600 }
601
602 return 0;
603}
604
605/* determine the number of frames in the next packet */
606static int snd_usb_audio_next_packet_size(struct snd_usb_substream *subs)
607{
608 if (subs->fill_max)
609 return subs->maxframesize;
610 else {
611 subs->phase = (subs->phase & 0xffff)
612 + (subs->freqm << subs->datainterval);
613 return min(subs->phase >> 16, subs->maxframesize);
614 }
615}
616
617/*
618 * Prepare urb for streaming before playback starts or when paused.
619 *
620 * We don't have any data, so we send silence.
621 */
622static int prepare_nodata_playback_urb(struct snd_usb_substream *subs,
623 struct snd_pcm_runtime *runtime,
624 struct urb *urb)
625{
626 unsigned int i, offs, counts;
627 struct snd_urb_ctx *ctx = urb->context;
628 int stride = runtime->frame_bits >> 3;
629
630 offs = 0;
631 urb->dev = ctx->subs->dev;
632 for (i = 0; i < ctx->packets; ++i) {
633 counts = snd_usb_audio_next_packet_size(subs);
634 urb->iso_frame_desc[i].offset = offs * stride;
635 urb->iso_frame_desc[i].length = counts * stride;
636 offs += counts;
637 }
638 urb->number_of_packets = ctx->packets;
639 urb->transfer_buffer_length = offs * stride;
640 memset(urb->transfer_buffer,
641 runtime->format == SNDRV_PCM_FORMAT_U8 ? 0x80 : 0,
642 offs * stride);
643 return 0;
644}
645
646/*
647 * prepare urb for playback data pipe
648 *
649 * Since a URB can handle only a single linear buffer, we must use double
650 * buffering when the data to be transferred overflows the buffer boundary.
651 * To avoid inconsistencies when updating hwptr_done, we use double buffering
652 * for all URBs.
653 */
654static int prepare_playback_urb(struct snd_usb_substream *subs,
655 struct snd_pcm_runtime *runtime,
656 struct urb *urb)
657{
658 int i, stride;
659 unsigned int counts, frames, bytes;
660 unsigned long flags;
661 int period_elapsed = 0;
662 struct snd_urb_ctx *ctx = urb->context;
663
664 stride = runtime->frame_bits >> 3;
665
666 frames = 0;
667 urb->dev = ctx->subs->dev; /* we need to set this at each time */
668 urb->number_of_packets = 0;
669 spin_lock_irqsave(&subs->lock, flags);
670 for (i = 0; i < ctx->packets; i++) {
671 counts = snd_usb_audio_next_packet_size(subs);
672 /* set up descriptor */
673 urb->iso_frame_desc[i].offset = frames * stride;
674 urb->iso_frame_desc[i].length = counts * stride;
675 frames += counts;
676 urb->number_of_packets++;
677 subs->transfer_done += counts;
678 if (subs->transfer_done >= runtime->period_size) {
679 subs->transfer_done -= runtime->period_size;
680 period_elapsed = 1;
681 if (subs->fmt_type == UAC_FORMAT_TYPE_II) {
682 if (subs->transfer_done > 0) {
683 /* FIXME: fill-max mode is not
684 * supported yet */
685 frames -= subs->transfer_done;
686 counts -= subs->transfer_done;
687 urb->iso_frame_desc[i].length =
688 counts * stride;
689 subs->transfer_done = 0;
690 }
691 i++;
692 if (i < ctx->packets) {
693 /* add a transfer delimiter */
694 urb->iso_frame_desc[i].offset =
695 frames * stride;
696 urb->iso_frame_desc[i].length = 0;
697 urb->number_of_packets++;
698 }
699 break;
700 }
701 }
702 if (period_elapsed) /* finish at the period boundary */
703 break;
704 }
705 bytes = frames * stride;
706 if (subs->hwptr_done + bytes > runtime->buffer_size * stride) {
707 /* err, the transferred area goes over buffer boundary. */
708 unsigned int bytes1 =
709 runtime->buffer_size * stride - subs->hwptr_done;
710 memcpy(urb->transfer_buffer,
711 runtime->dma_area + subs->hwptr_done, bytes1);
712 memcpy(urb->transfer_buffer + bytes1,
713 runtime->dma_area, bytes - bytes1);
714 } else {
715 memcpy(urb->transfer_buffer,
716 runtime->dma_area + subs->hwptr_done, bytes);
717 }
718 subs->hwptr_done += bytes;
719 if (subs->hwptr_done >= runtime->buffer_size * stride)
720 subs->hwptr_done -= runtime->buffer_size * stride;
721 runtime->delay += frames;
722 spin_unlock_irqrestore(&subs->lock, flags);
723 urb->transfer_buffer_length = bytes;
724 if (period_elapsed)
725 snd_pcm_period_elapsed(subs->pcm_substream);
726 return 0;
727}
728
729/*
730 * process after playback data complete
731 * - decrease the delay count again
732 */
733static int retire_playback_urb(struct snd_usb_substream *subs,
734 struct snd_pcm_runtime *runtime,
735 struct urb *urb)
736{
737 unsigned long flags;
738 int stride = runtime->frame_bits >> 3;
739 int processed = urb->transfer_buffer_length / stride;
740
741 spin_lock_irqsave(&subs->lock, flags);
742 if (processed > runtime->delay)
743 runtime->delay = 0;
744 else
745 runtime->delay -= processed;
746 spin_unlock_irqrestore(&subs->lock, flags);
747 return 0;
748}
749
750static const char *usb_error_string(int err)
751{
752 switch (err) {
753 case -ENODEV:
754 return "no device";
755 case -ENOENT:
756 return "endpoint not enabled";
757 case -EPIPE:
758 return "endpoint stalled";
759 case -ENOSPC:
760 return "not enough bandwidth";
761 case -ESHUTDOWN:
762 return "device disabled";
763 case -EHOSTUNREACH:
764 return "device suspended";
765 case -EINVAL:
766 case -EAGAIN:
767 case -EFBIG:
768 case -EMSGSIZE:
769 return "internal error";
770 default:
771 return "unknown error";
772 }
773}
774
775/*
776 * set up and start data/sync urbs
777 */
778static int start_urbs(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime)
779{
780 unsigned int i;
781 int err;
782
783 if (subs->stream->chip->shutdown)
784 return -EBADFD;
785
786 for (i = 0; i < subs->nurbs; i++) {
787 if (snd_BUG_ON(!subs->dataurb[i].urb))
788 return -EINVAL;
789 if (subs->ops.prepare(subs, runtime, subs->dataurb[i].urb) < 0) {
790 snd_printk(KERN_ERR "cannot prepare datapipe for urb %d\n", i);
791 goto __error;
792 }
793 }
794 if (subs->syncpipe) {
795 for (i = 0; i < SYNC_URBS; i++) {
796 if (snd_BUG_ON(!subs->syncurb[i].urb))
797 return -EINVAL;
798 if (subs->ops.prepare_sync(subs, runtime, subs->syncurb[i].urb) < 0) {
799 snd_printk(KERN_ERR "cannot prepare syncpipe for urb %d\n", i);
800 goto __error;
801 }
802 }
803 }
804
805 subs->active_mask = 0;
806 subs->unlink_mask = 0;
807 subs->running = 1;
808 for (i = 0; i < subs->nurbs; i++) {
809 err = usb_submit_urb(subs->dataurb[i].urb, GFP_ATOMIC);
810 if (err < 0) {
811 snd_printk(KERN_ERR "cannot submit datapipe "
812 "for urb %d, error %d: %s\n",
813 i, err, usb_error_string(err));
814 goto __error;
815 }
816 set_bit(i, &subs->active_mask);
817 }
818 if (subs->syncpipe) {
819 for (i = 0; i < SYNC_URBS; i++) {
820 err = usb_submit_urb(subs->syncurb[i].urb, GFP_ATOMIC);
821 if (err < 0) {
822 snd_printk(KERN_ERR "cannot submit syncpipe "
823 "for urb %d, error %d: %s\n",
824 i, err, usb_error_string(err));
825 goto __error;
826 }
827 set_bit(i + 16, &subs->active_mask);
828 }
829 }
830 return 0;
831
832 __error:
833 // snd_pcm_stop(subs->pcm_substream, SNDRV_PCM_STATE_XRUN);
834 deactivate_urbs(subs, 0, 0);
835 return -EPIPE;
836}
837
838
839/*
840 */
841static struct snd_urb_ops audio_urb_ops[2] = {
842 {
843 .prepare = prepare_nodata_playback_urb,
844 .retire = retire_playback_urb,
845 .prepare_sync = prepare_playback_sync_urb,
846 .retire_sync = retire_playback_sync_urb,
847 },
848 {
849 .prepare = prepare_capture_urb,
850 .retire = retire_capture_urb,
851 .prepare_sync = prepare_capture_sync_urb,
852 .retire_sync = retire_capture_sync_urb,
853 },
854};
855
856/*
857 * initialize the substream instance.
858 */
859
860void snd_usb_init_substream(struct snd_usb_stream *as,
861 int stream, struct audioformat *fp)
862{
863 struct snd_usb_substream *subs = &as->substream[stream];
864
865 INIT_LIST_HEAD(&subs->fmt_list);
866 spin_lock_init(&subs->lock);
867
868 subs->stream = as;
869 subs->direction = stream;
870 subs->dev = as->chip->dev;
871 subs->txfr_quirk = as->chip->txfr_quirk;
872 subs->ops = audio_urb_ops[stream];
873 if (snd_usb_get_speed(subs->dev) >= USB_SPEED_HIGH)
874 subs->ops.prepare_sync = prepare_capture_sync_urb_hs;
875
876 snd_usb_set_pcm_ops(as->pcm, stream);
877
878 list_add_tail(&fp->list, &subs->fmt_list);
879 subs->formats |= fp->formats;
880 subs->endpoint = fp->endpoint;
881 subs->num_formats++;
882 subs->fmt_type = fp->fmt_type;
883}
884
885int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substream, int cmd)
886{
887 struct snd_usb_substream *subs = substream->runtime->private_data;
888
889 switch (cmd) {
890 case SNDRV_PCM_TRIGGER_START:
891 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
892 subs->ops.prepare = prepare_playback_urb;
893 return 0;
894 case SNDRV_PCM_TRIGGER_STOP:
895 return deactivate_urbs(subs, 0, 0);
896 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
897 subs->ops.prepare = prepare_nodata_playback_urb;
898 return 0;
899 }
900
901 return -EINVAL;
902}
903
904int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream, int cmd)
905{
906 struct snd_usb_substream *subs = substream->runtime->private_data;
907
908 switch (cmd) {
909 case SNDRV_PCM_TRIGGER_START:
910 subs->ops.retire = retire_capture_urb;
911 return start_urbs(subs, substream->runtime);
912 case SNDRV_PCM_TRIGGER_STOP:
913 return deactivate_urbs(subs, 0, 0);
914 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
915 subs->ops.retire = retire_paused_capture_urb;
916 return 0;
917 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
918 subs->ops.retire = retire_capture_urb;
919 return 0;
920 }
921
922 return -EINVAL;
923}
924
925int snd_usb_substream_prepare(struct snd_usb_substream *subs,
926 struct snd_pcm_runtime *runtime)
927{
928 /* clear urbs (to be sure) */
929 deactivate_urbs(subs, 0, 1);
930 wait_clear_urbs(subs);
931
932 /* for playback, submit the URBs now; otherwise, the first hwptr_done
933 * updates for all URBs would happen at the same time when starting */
934 if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) {
935 subs->ops.prepare = prepare_nodata_playback_urb;
936 return start_urbs(subs, runtime);
937 }
938
939 return 0;
940}
941
diff --git a/sound/usb/urb.h b/sound/usb/urb.h
deleted file mode 100644
index 888da38079c..00000000000
--- a/sound/usb/urb.h
+++ /dev/null
@@ -1,21 +0,0 @@
1#ifndef __USBAUDIO_URB_H
2#define __USBAUDIO_URB_H
3
4void snd_usb_init_substream(struct snd_usb_stream *as,
5 int stream,
6 struct audioformat *fp);
7
8int snd_usb_init_substream_urbs(struct snd_usb_substream *subs,
9 unsigned int period_bytes,
10 unsigned int rate,
11 unsigned int frame_bits);
12
13void snd_usb_release_substream_urbs(struct snd_usb_substream *subs, int force);
14
15int snd_usb_substream_prepare(struct snd_usb_substream *subs,
16 struct snd_pcm_runtime *runtime);
17
18int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substream, int cmd);
19int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream, int cmd);
20
21#endif /* __USBAUDIO_URB_H */
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
index 1e79986b577..3e2b0357793 100644
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -80,6 +80,7 @@ enum quirk_type {
80 QUIRK_MIDI_CME, 80 QUIRK_MIDI_CME,
81 QUIRK_MIDI_AKAI, 81 QUIRK_MIDI_AKAI,
82 QUIRK_MIDI_US122L, 82 QUIRK_MIDI_US122L,
83 QUIRK_MIDI_FTDI,
83 QUIRK_AUDIO_STANDARD_INTERFACE, 84 QUIRK_AUDIO_STANDARD_INTERFACE,
84 QUIRK_AUDIO_FIXED_ENDPOINT, 85 QUIRK_AUDIO_FIXED_ENDPOINT,
85 QUIRK_AUDIO_EDIROL_UAXX, 86 QUIRK_AUDIO_EDIROL_UAXX,