aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2008-10-14 20:31:54 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2008-10-14 20:31:54 -0400
commit6dc6472581f693b5fc95aebedf67b4960fb85cf0 (patch)
tree06a5a9a08519950575505273eabced331ed51405 /sound
parentee673eaa72d8d185012b1027a05e25aba18c267f (diff)
parent8acd3a60bcca17c6d89c73cee3ad6057eb83ba1e (diff)
Merge commit 'origin'
Manual fixup of conflicts on: arch/powerpc/include/asm/dcr-regs.h drivers/net/ibm_newemac/core.h
Diffstat (limited to 'sound')
-rw-r--r--sound/Kconfig5
-rw-r--r--sound/aoa/codecs/snd-aoa-codec-tas.c6
-rw-r--r--sound/arm/Kconfig9
-rw-r--r--sound/arm/Makefile4
-rw-r--r--sound/arm/aaci.c6
-rw-r--r--sound/arm/pxa2xx-ac97-lib.c384
-rw-r--r--sound/arm/pxa2xx-ac97.c251
-rw-r--r--sound/arm/pxa2xx-pcm-lib.c278
-rw-r--r--sound/arm/pxa2xx-pcm.c252
-rw-r--r--sound/arm/pxa2xx-pcm.h13
-rw-r--r--sound/arm/sa11xx-uda1341.c7
-rw-r--r--sound/core/Kconfig10
-rw-r--r--sound/core/Makefile1
-rw-r--r--sound/core/control.c54
-rw-r--r--sound/core/control_compat.c3
-rw-r--r--sound/core/device.c26
-rw-r--r--sound/core/hwdep.c16
-rw-r--r--sound/core/info.c23
-rw-r--r--sound/core/info_oss.c6
-rw-r--r--sound/core/init.c3
-rw-r--r--sound/core/jack.c163
-rw-r--r--sound/core/memalloc.c100
-rw-r--r--sound/core/oss/copy.c30
-rw-r--r--sound/core/oss/io.c24
-rw-r--r--sound/core/oss/linear.c29
-rw-r--r--sound/core/oss/mixer_oss.c18
-rw-r--r--sound/core/oss/mulaw.c27
-rw-r--r--sound/core/oss/pcm_oss.c52
-rw-r--r--sound/core/oss/pcm_plugin.c38
-rw-r--r--sound/core/oss/rate.c42
-rw-r--r--sound/core/oss/route.c12
-rw-r--r--sound/core/pcm.c88
-rw-r--r--sound/core/pcm_compat.c3
-rw-r--r--sound/core/pcm_lib.c102
-rw-r--r--sound/core/pcm_memory.c40
-rw-r--r--sound/core/pcm_native.c153
-rw-r--r--sound/core/pcm_timer.c6
-rw-r--r--sound/core/rawmidi.c29
-rw-r--r--sound/core/rtctimer.c6
-rw-r--r--sound/core/seq/oss/seq_oss.c12
-rw-r--r--sound/core/seq/oss/seq_oss_synth.c6
-rw-r--r--sound/core/seq/seq_clientmgr.c30
-rw-r--r--sound/core/seq/seq_compat.c3
-rw-r--r--sound/core/seq/seq_device.c6
-rw-r--r--sound/core/seq/seq_fifo.c15
-rw-r--r--sound/core/seq/seq_memory.c12
-rw-r--r--sound/core/seq/seq_midi.c15
-rw-r--r--sound/core/seq/seq_ports.c13
-rw-r--r--sound/core/seq/seq_prioq.c4
-rw-r--r--sound/core/seq/seq_queue.c6
-rw-r--r--sound/core/seq/seq_timer.c24
-rw-r--r--sound/core/sgbuf.c62
-rw-r--r--sound/core/sound.c14
-rw-r--r--sound/core/sound_oss.c12
-rw-r--r--sound/core/timer.c33
-rw-r--r--sound/core/timer_compat.c9
-rw-r--r--sound/drivers/dummy.c41
-rw-r--r--sound/drivers/mtpav.c8
-rw-r--r--sound/drivers/opl3/opl3_lib.c6
-rw-r--r--sound/drivers/opl3/opl3_midi.c6
-rw-r--r--sound/drivers/opl3/opl3_oss.c15
-rw-r--r--sound/drivers/opl3/opl3_synth.c3
-rw-r--r--sound/drivers/opl4/opl4_synth.c2
-rw-r--r--sound/drivers/vx/vx_cmd.c3
-rw-r--r--sound/drivers/vx/vx_core.c21
-rw-r--r--sound/drivers/vx/vx_hwdep.c6
-rw-r--r--sound/drivers/vx/vx_mixer.c3
-rw-r--r--sound/drivers/vx/vx_pcm.c9
-rw-r--r--sound/drivers/vx/vx_uer.c6
-rw-r--r--sound/i2c/cs8427.c15
-rw-r--r--sound/i2c/i2c.c6
-rw-r--r--sound/i2c/l3/uda1341.c3
-rw-r--r--sound/i2c/other/ak4114.c3
-rw-r--r--sound/i2c/other/ak4117.c3
-rw-r--r--sound/i2c/other/ak4xxx-adda.c4
-rw-r--r--sound/i2c/other/tea575x-tuner.c23
-rw-r--r--sound/isa/Kconfig44
-rw-r--r--sound/isa/Makefile2
-rw-r--r--sound/isa/ad1816a/ad1816a.c4
-rw-r--r--sound/isa/ad1816a/ad1816a_lib.c6
-rw-r--r--sound/isa/ad1848/Makefile2
-rw-r--r--sound/isa/ad1848/ad1848.c17
-rw-r--r--sound/isa/ad1848/ad1848_lib.c1267
-rw-r--r--sound/isa/azt2320.c29
-rw-r--r--sound/isa/cmi8330.c106
-rw-r--r--sound/isa/cs423x/Makefile2
-rw-r--r--sound/isa/cs423x/cs4231.c18
-rw-r--r--sound/isa/cs423x/cs4231_lib.c1945
-rw-r--r--sound/isa/cs423x/cs4236.c51
-rw-r--r--sound/isa/cs423x/cs4236_lib.c349
-rw-r--r--sound/isa/es1688/es1688_lib.c3
-rw-r--r--sound/isa/gus/gus_main.c6
-rw-r--r--sound/isa/gus/gus_mixer.c6
-rw-r--r--sound/isa/gus/gus_pcm.c12
-rw-r--r--sound/isa/gus/gusmax.c50
-rw-r--r--sound/isa/gus/interwave.c67
-rw-r--r--sound/isa/opl3sa2.c99
-rw-r--r--sound/isa/opti9xx/miro.c28
-rw-r--r--sound/isa/opti9xx/opti92x-ad1848.c70
-rw-r--r--sound/isa/sb/emu8000.c3
-rw-r--r--sound/isa/sb/emu8000_patch.c3
-rw-r--r--sound/isa/sb/sb16_csp.c9
-rw-r--r--sound/isa/sb/sb16_main.c3
-rw-r--r--sound/isa/sb/sb8_main.c8
-rw-r--r--sound/isa/sb/sb_common.c3
-rw-r--r--sound/isa/sb/sb_mixer.c9
-rw-r--r--sound/isa/sc6000.c18
-rw-r--r--sound/isa/sgalaxy.c43
-rw-r--r--sound/isa/sscape.c63
-rw-r--r--sound/isa/wavefront/wavefront.c62
-rw-r--r--sound/isa/wavefront/wavefront_fx.c8
-rw-r--r--sound/isa/wavefront/wavefront_midi.c24
-rw-r--r--sound/isa/wavefront/wavefront_synth.c7
-rw-r--r--sound/isa/wss/Makefile10
-rw-r--r--sound/isa/wss/wss_lib.c2322
-rw-r--r--sound/mips/au1x00.c6
-rw-r--r--sound/oss/Kconfig35
-rw-r--r--sound/oss/Makefile1
-rw-r--r--sound/oss/ac97_codec.c2
-rw-r--r--sound/oss/aedsp16.c8
-rw-r--r--sound/oss/dmasound/Kconfig1
-rw-r--r--sound/oss/hal2.c1558
-rw-r--r--sound/oss/hal2.h248
-rw-r--r--sound/oss/mpu401.c2
-rw-r--r--sound/parisc/harmony.c3
-rw-r--r--sound/pci/Kconfig33
-rw-r--r--sound/pci/ac97/ac97_codec.c41
-rw-r--r--sound/pci/ac97/ac97_patch.c210
-rw-r--r--sound/pci/ad1889.c6
-rw-r--r--sound/pci/ak4531_codec.c10
-rw-r--r--sound/pci/als4000.c391
-rw-r--r--sound/pci/atiixp.c13
-rw-r--r--sound/pci/atiixp_modem.c10
-rw-r--r--sound/pci/au88x0/au88x0.h7
-rw-r--r--sound/pci/au88x0/au88x0_core.c40
-rw-r--r--sound/pci/au88x0/au88x0_pcm.c14
-rw-r--r--sound/pci/azt3328.c6
-rw-r--r--sound/pci/bt87x.c5
-rw-r--r--sound/pci/ca0106/ca0106_main.c2
-rw-r--r--sound/pci/ca0106/ca_midi.c20
-rw-r--r--sound/pci/cmipci.c9
-rw-r--r--sound/pci/cs4281.c13
-rw-r--r--sound/pci/cs46xx/cs46xx_lib.c91
-rw-r--r--sound/pci/cs46xx/dsp_spos.c51
-rw-r--r--sound/pci/cs46xx/dsp_spos_scb_lib.c115
-rw-r--r--sound/pci/echoaudio/darla20_dsp.c3
-rw-r--r--sound/pci/echoaudio/darla24_dsp.c8
-rw-r--r--sound/pci/echoaudio/echo3g_dsp.c9
-rw-r--r--sound/pci/echoaudio/echoaudio.c22
-rw-r--r--sound/pci/echoaudio/echoaudio_3g.c11
-rw-r--r--sound/pci/echoaudio/echoaudio_dsp.c21
-rw-r--r--sound/pci/echoaudio/echoaudio_gml.c6
-rw-r--r--sound/pci/echoaudio/gina20_dsp.c6
-rw-r--r--sound/pci/echoaudio/gina24_dsp.c11
-rw-r--r--sound/pci/echoaudio/indigo_dsp.c8
-rw-r--r--sound/pci/echoaudio/indigodj_dsp.c8
-rw-r--r--sound/pci/echoaudio/indigoio_dsp.c8
-rw-r--r--sound/pci/echoaudio/layla20_dsp.c9
-rw-r--r--sound/pci/echoaudio/layla24_dsp.c11
-rw-r--r--sound/pci/echoaudio/mia_dsp.c13
-rw-r--r--sound/pci/echoaudio/midi.c6
-rw-r--r--sound/pci/echoaudio/mona_dsp.c6
-rw-r--r--sound/pci/emu10k1/emu10k1_callback.c6
-rw-r--r--sound/pci/emu10k1/emu10k1_patch.c23
-rw-r--r--sound/pci/emu10k1/emu10k1x.c18
-rw-r--r--sound/pci/emu10k1/emufx.c6
-rw-r--r--sound/pci/emu10k1/emumpu401.c18
-rw-r--r--sound/pci/emu10k1/memory.c31
-rw-r--r--sound/pci/emu10k1/voice.c9
-rw-r--r--sound/pci/es1938.c3
-rw-r--r--sound/pci/es1968.c6
-rw-r--r--sound/pci/hda/Makefile2
-rw-r--r--sound/pci/hda/hda_beep.c134
-rw-r--r--sound/pci/hda/hda_beep.h44
-rw-r--r--sound/pci/hda/hda_codec.c113
-rw-r--r--sound/pci/hda/hda_codec.h93
-rw-r--r--sound/pci/hda/hda_generic.c3
-rw-r--r--sound/pci/hda/hda_intel.c146
-rw-r--r--sound/pci/hda/hda_local.h24
-rw-r--r--sound/pci/hda/hda_patch.h2
-rw-r--r--sound/pci/hda/hda_proc.c25
-rw-r--r--sound/pci/hda/patch_analog.c96
-rw-r--r--sound/pci/hda/patch_atihdmi.c45
-rw-r--r--sound/pci/hda/patch_nvhdmi.c164
-rw-r--r--sound/pci/hda/patch_realtek.c1816
-rw-r--r--sound/pci/hda/patch_sigmatel.c1008
-rw-r--r--sound/pci/hda/patch_via.c1407
-rw-r--r--sound/pci/ice1712/ak4xxx.c3
-rw-r--r--sound/pci/ice1712/aureon.c699
-rw-r--r--sound/pci/ice1712/delta.c2
-rw-r--r--sound/pci/ice1712/delta.h1
-rw-r--r--sound/pci/ice1712/ews.c9
-rw-r--r--sound/pci/ice1712/ice1712.c240
-rw-r--r--sound/pci/ice1712/ice1712.h52
-rw-r--r--sound/pci/ice1712/ice1724.c188
-rw-r--r--sound/pci/ice1712/juli.c47
-rw-r--r--sound/pci/ice1712/phase.c277
-rw-r--r--sound/pci/ice1712/phase.h8
-rw-r--r--sound/pci/ice1712/pontis.c5
-rw-r--r--sound/pci/ice1712/revo.c25
-rw-r--r--sound/pci/ice1712/wtm.c104
-rw-r--r--sound/pci/ice1712/wtm.h4
-rw-r--r--sound/pci/intel8x0.c50
-rw-r--r--sound/pci/intel8x0m.c3
-rw-r--r--sound/pci/korg1212/korg1212.c9
-rw-r--r--sound/pci/maestro3.c10
-rw-r--r--sound/pci/mixart/mixart.c4
-rw-r--r--sound/pci/mixart/mixart_core.c18
-rw-r--r--sound/pci/mixart/mixart_hwdep.c19
-rw-r--r--sound/pci/mixart/mixart_mixer.c8
-rw-r--r--sound/pci/nm256/nm256.c15
-rw-r--r--sound/pci/oxygen/hifier.c15
-rw-r--r--sound/pci/oxygen/oxygen.c92
-rw-r--r--sound/pci/oxygen/oxygen.h103
-rw-r--r--sound/pci/oxygen/oxygen_io.c22
-rw-r--r--sound/pci/oxygen/oxygen_lib.c101
-rw-r--r--sound/pci/oxygen/oxygen_mixer.c48
-rw-r--r--sound/pci/oxygen/oxygen_pcm.c47
-rw-r--r--sound/pci/oxygen/virtuoso.c594
-rw-r--r--sound/pci/pcxhr/pcxhr.c6
-rw-r--r--sound/pci/pcxhr/pcxhr_core.c27
-rw-r--r--sound/pci/pcxhr/pcxhr_hwdep.c15
-rw-r--r--sound/pci/riptide/riptide.c31
-rw-r--r--sound/pci/rme9652/hdsp.c25
-rw-r--r--sound/pci/rme9652/hdspm.c52
-rw-r--r--sound/pci/rme9652/rme9652.c23
-rw-r--r--sound/pci/sonicvibes.c10
-rw-r--r--sound/pci/trident/trident_main.c22
-rw-r--r--sound/pci/trident/trident_memory.c37
-rw-r--r--sound/pci/via82xx.c60
-rw-r--r--sound/pci/via82xx_modem.c8
-rw-r--r--sound/pci/vx222/vx222_ops.c12
-rw-r--r--sound/pci/ymfpci/ymfpci_main.c21
-rw-r--r--sound/pcmcia/vx/vxp_ops.c3
-rw-r--r--sound/ppc/awacs.c73
-rw-r--r--sound/ppc/beep.c6
-rw-r--r--sound/ppc/tumbler.c17
-rw-r--r--sound/sh/aica.c9
-rw-r--r--sound/soc/Kconfig2
-rw-r--r--sound/soc/Makefile2
-rw-r--r--sound/soc/at32/at32-pcm.c5
-rw-r--r--sound/soc/at32/playpaq_wm8510.c7
-rw-r--r--sound/soc/at91/Kconfig17
-rw-r--r--sound/soc/at91/Makefile5
-rw-r--r--sound/soc/at91/at91-ssc.c4
-rw-r--r--sound/soc/at91/eti_b1_wm8731.c348
-rw-r--r--sound/soc/blackfin/Kconfig101
-rw-r--r--sound/soc/blackfin/Makefile21
-rw-r--r--sound/soc/blackfin/bf5xx-ac97-pcm.c457
-rw-r--r--sound/soc/blackfin/bf5xx-ac97-pcm.h29
-rw-r--r--sound/soc/blackfin/bf5xx-ac97.c406
-rw-r--r--sound/soc/blackfin/bf5xx-ac97.h36
-rw-r--r--sound/soc/blackfin/bf5xx-ad1980.c113
-rw-r--r--sound/soc/blackfin/bf5xx-ad73311.c240
-rw-r--r--sound/soc/blackfin/bf5xx-i2s-pcm.c288
-rw-r--r--sound/soc/blackfin/bf5xx-i2s-pcm.h29
-rw-r--r--sound/soc/blackfin/bf5xx-i2s.c311
-rw-r--r--sound/soc/blackfin/bf5xx-i2s.h14
-rw-r--r--sound/soc/blackfin/bf5xx-sport.c1032
-rw-r--r--sound/soc/blackfin/bf5xx-sport.h194
-rw-r--r--sound/soc/blackfin/bf5xx-ssm2602.c186
-rw-r--r--sound/soc/codecs/Kconfig100
-rw-r--r--sound/soc/codecs/Makefile26
-rw-r--r--sound/soc/codecs/ac97.c3
-rw-r--r--sound/soc/codecs/ad1980.c308
-rw-r--r--sound/soc/codecs/ad1980.h23
-rw-r--r--sound/soc/codecs/ad73311.c107
-rw-r--r--sound/soc/codecs/ad73311.h90
-rw-r--r--sound/soc/codecs/ak4535.c117
-rw-r--r--sound/soc/codecs/ak4535.h1
-rw-r--r--sound/soc/codecs/cs4270.c103
-rw-r--r--sound/soc/codecs/ssm2602.c775
-rw-r--r--sound/soc/codecs/ssm2602.h130
-rw-r--r--sound/soc/codecs/tlv320aic23.c714
-rw-r--r--sound/soc/codecs/tlv320aic23.h122
-rw-r--r--sound/soc/codecs/tlv320aic26.c520
-rw-r--r--sound/soc/codecs/tlv320aic26.h96
-rw-r--r--sound/soc/codecs/tlv320aic3x.c113
-rw-r--r--sound/soc/codecs/tlv320aic3x.h3
-rw-r--r--sound/soc/codecs/uda1380.c116
-rw-r--r--sound/soc/codecs/uda1380.h1
-rw-r--r--sound/soc/codecs/wm8510.c221
-rw-r--r--sound/soc/codecs/wm8510.h2
-rw-r--r--sound/soc/codecs/wm8580.c1053
-rw-r--r--sound/soc/codecs/wm8580.h42
-rw-r--r--sound/soc/codecs/wm8731.c179
-rw-r--r--sound/soc/codecs/wm8731.h2
-rw-r--r--sound/soc/codecs/wm8750.c178
-rw-r--r--sound/soc/codecs/wm8750.h2
-rw-r--r--sound/soc/codecs/wm8753.c181
-rw-r--r--sound/soc/codecs/wm8753.h5
-rw-r--r--sound/soc/codecs/wm8900.c1541
-rw-r--r--sound/soc/codecs/wm8900.h64
-rw-r--r--sound/soc/codecs/wm8903.c1813
-rw-r--r--sound/soc/codecs/wm8903.h1463
-rw-r--r--sound/soc/codecs/wm8971.c941
-rw-r--r--sound/soc/codecs/wm8971.h64
-rw-r--r--sound/soc/codecs/wm8990.c110
-rw-r--r--sound/soc/codecs/wm8990.h1
-rw-r--r--sound/soc/codecs/wm9712.c3
-rw-r--r--sound/soc/codecs/wm9713.c37
-rw-r--r--sound/soc/davinci/davinci-evm.c3
-rw-r--r--sound/soc/davinci/davinci-i2s.c4
-rw-r--r--sound/soc/davinci/davinci-i2s.h2
-rw-r--r--sound/soc/davinci/davinci-pcm.c2
-rw-r--r--sound/soc/davinci/davinci-pcm.h2
-rw-r--r--sound/soc/fsl/Kconfig10
-rw-r--r--sound/soc/fsl/Makefile5
-rw-r--r--sound/soc/fsl/mpc5200_psc_i2s.c884
-rw-r--r--sound/soc/fsl/mpc8610_hpcd.c26
-rw-r--r--sound/soc/fsl/soc-of-simple.c171
-rw-r--r--sound/soc/omap/Kconfig8
-rw-r--r--sound/soc/omap/Makefile2
-rw-r--r--sound/soc/omap/n810.c7
-rw-r--r--sound/soc/omap/omap-mcbsp.c181
-rw-r--r--sound/soc/omap/omap-mcbsp.h16
-rw-r--r--sound/soc/omap/omap-pcm.c4
-rw-r--r--sound/soc/omap/osk5912.c232
-rw-r--r--sound/soc/pxa/Kconfig3
-rw-r--r--sound/soc/pxa/corgi.c41
-rw-r--r--sound/soc/pxa/em-x270.c2
-rw-r--r--sound/soc/pxa/poodle.c7
-rw-r--r--sound/soc/pxa/pxa2xx-ac97.c282
-rw-r--r--sound/soc/pxa/pxa2xx-i2s.c67
-rw-r--r--sound/soc/pxa/pxa2xx-pcm.c265
-rw-r--r--sound/soc/pxa/pxa2xx-pcm.h15
-rw-r--r--sound/soc/pxa/spitz.c63
-rw-r--r--sound/soc/pxa/tosa.c6
-rw-r--r--sound/soc/s3c24xx/neo1973_wm8753.c96
-rw-r--r--sound/soc/soc-core.c143
-rw-r--r--sound/soc/soc-dapm.c152
-rw-r--r--sound/sound_core.c79
-rw-r--r--sound/sparc/amd7930.c104
-rw-r--r--sound/sparc/cs4231.c202
-rw-r--r--sound/sparc/dbri.c106
-rw-r--r--sound/synth/emux/emux.c8
-rw-r--r--sound/synth/emux/emux_nrpn.c8
-rw-r--r--sound/synth/emux/emux_oss.c42
-rw-r--r--sound/synth/emux/emux_seq.c15
-rw-r--r--sound/synth/emux/emux_synth.c47
-rw-r--r--sound/synth/util_mem.c10
-rw-r--r--sound/usb/Kconfig12
-rw-r--r--sound/usb/Makefile1
-rw-r--r--sound/usb/usbaudio.c46
-rw-r--r--sound/usb/usbaudio.h6
-rw-r--r--sound/usb/usbmidi.c48
-rw-r--r--sound/usb/usbmixer.c19
-rw-r--r--sound/usb/usbquirks.h80
-rw-r--r--sound/usb/usx2y/Makefile2
-rw-r--r--sound/usb/usx2y/us122l.c692
-rw-r--r--sound/usb/usx2y/us122l.h27
-rw-r--r--sound/usb/usx2y/usb_stream.c761
-rw-r--r--sound/usb/usx2y/usb_stream.h112
353 files changed, 30477 insertions, 11065 deletions
diff --git a/sound/Kconfig b/sound/Kconfig
index 8ebf512ced6c..200aca1faa71 100644
--- a/sound/Kconfig
+++ b/sound/Kconfig
@@ -28,6 +28,10 @@ menuconfig SOUND
28 28
29if SOUND 29if SOUND
30 30
31config SOUND_OSS_CORE
32 bool
33 default n
34
31source "sound/oss/dmasound/Kconfig" 35source "sound/oss/dmasound/Kconfig"
32 36
33if !M68K 37if !M68K
@@ -80,6 +84,7 @@ endif # SND
80 84
81menuconfig SOUND_PRIME 85menuconfig SOUND_PRIME
82 tristate "Open Sound System (DEPRECATED)" 86 tristate "Open Sound System (DEPRECATED)"
87 select SOUND_OSS_CORE
83 help 88 help
84 Say 'Y' or 'M' to enable Open Sound System drivers. 89 Say 'Y' or 'M' to enable Open Sound System drivers.
85 90
diff --git a/sound/aoa/codecs/snd-aoa-codec-tas.c b/sound/aoa/codecs/snd-aoa-codec-tas.c
index 7a16a3331f7e..6c515b2b8bbd 100644
--- a/sound/aoa/codecs/snd-aoa-codec-tas.c
+++ b/sound/aoa/codecs/snd-aoa-codec-tas.c
@@ -654,15 +654,13 @@ static struct snd_kcontrol_new bass_control = {
654static struct transfer_info tas_transfers[] = { 654static struct transfer_info tas_transfers[] = {
655 { 655 {
656 /* input */ 656 /* input */
657 .formats = SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_S16_BE | 657 .formats = SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_S24_BE,
658 SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S24_BE,
659 .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000, 658 .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
660 .transfer_in = 1, 659 .transfer_in = 1,
661 }, 660 },
662 { 661 {
663 /* output */ 662 /* output */
664 .formats = SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_S16_BE | 663 .formats = SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_S24_BE,
665 SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S24_BE,
666 .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000, 664 .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
667 .transfer_in = 0, 665 .transfer_in = 0,
668 }, 666 },
diff --git a/sound/arm/Kconfig b/sound/arm/Kconfig
index 351e19ea3785..f8e6de48d816 100644
--- a/sound/arm/Kconfig
+++ b/sound/arm/Kconfig
@@ -32,11 +32,20 @@ config SND_PXA2XX_PCM
32 tristate 32 tristate
33 select SND_PCM 33 select SND_PCM
34 34
35config SND_PXA2XX_LIB
36 tristate
37 select SND_AC97_CODEC if SND_PXA2XX_LIB_AC97
38
39config SND_PXA2XX_LIB_AC97
40 bool
41
35config SND_PXA2XX_AC97 42config SND_PXA2XX_AC97
36 tristate "AC97 driver for the Intel PXA2xx chip" 43 tristate "AC97 driver for the Intel PXA2xx chip"
37 depends on ARCH_PXA 44 depends on ARCH_PXA
38 select SND_PXA2XX_PCM 45 select SND_PXA2XX_PCM
39 select SND_AC97_CODEC 46 select SND_AC97_CODEC
47 select SND_PXA2XX_LIB
48 select SND_PXA2XX_LIB_AC97
40 help 49 help
41 Say Y or M if you want to support any AC97 codec attached to 50 Say Y or M if you want to support any AC97 codec attached to
42 the PXA2xx AC97 interface. 51 the PXA2xx AC97 interface.
diff --git a/sound/arm/Makefile b/sound/arm/Makefile
index 4ef6dd00c6ee..2054de11de8a 100644
--- a/sound/arm/Makefile
+++ b/sound/arm/Makefile
@@ -11,5 +11,9 @@ snd-aaci-objs := aaci.o devdma.o
11obj-$(CONFIG_SND_PXA2XX_PCM) += snd-pxa2xx-pcm.o 11obj-$(CONFIG_SND_PXA2XX_PCM) += snd-pxa2xx-pcm.o
12snd-pxa2xx-pcm-objs := pxa2xx-pcm.o 12snd-pxa2xx-pcm-objs := pxa2xx-pcm.o
13 13
14obj-$(CONFIG_SND_PXA2XX_LIB) += snd-pxa2xx-lib.o
15snd-pxa2xx-lib-y := pxa2xx-pcm-lib.o
16snd-pxa2xx-lib-$(CONFIG_SND_PXA2XX_LIB_AC97) += pxa2xx-ac97-lib.o
17
14obj-$(CONFIG_SND_PXA2XX_AC97) += snd-pxa2xx-ac97.o 18obj-$(CONFIG_SND_PXA2XX_AC97) += snd-pxa2xx-ac97.o
15snd-pxa2xx-ac97-objs := pxa2xx-ac97.o 19snd-pxa2xx-ac97-objs := pxa2xx-ac97.o
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c
index b0a474494966..89096e811a4b 100644
--- a/sound/arm/aaci.c
+++ b/sound/arm/aaci.c
@@ -999,7 +999,7 @@ static struct aaci * __devinit aaci_init_card(struct amba_device *dev)
999 card = snd_card_new(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, 999 card = snd_card_new(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
1000 THIS_MODULE, sizeof(struct aaci)); 1000 THIS_MODULE, sizeof(struct aaci));
1001 if (card == NULL) 1001 if (card == NULL)
1002 return ERR_PTR(-ENOMEM); 1002 return NULL;
1003 1003
1004 card->private_free = aaci_free_card; 1004 card->private_free = aaci_free_card;
1005 1005
@@ -1083,8 +1083,8 @@ static int __devinit aaci_probe(struct amba_device *dev, void *id)
1083 return ret; 1083 return ret;
1084 1084
1085 aaci = aaci_init_card(dev); 1085 aaci = aaci_init_card(dev);
1086 if (IS_ERR(aaci)) { 1086 if (!aaci) {
1087 ret = PTR_ERR(aaci); 1087 ret = -ENOMEM;
1088 goto out; 1088 goto out;
1089 } 1089 }
1090 1090
diff --git a/sound/arm/pxa2xx-ac97-lib.c b/sound/arm/pxa2xx-ac97-lib.c
new file mode 100644
index 000000000000..99026dfb81ea
--- /dev/null
+++ b/sound/arm/pxa2xx-ac97-lib.c
@@ -0,0 +1,384 @@
1/*
2 * Based on sound/arm/pxa2xx-ac97.c and sound/soc/pxa/pxa2xx-ac97.c
3 * which contain:
4 *
5 * Author: Nicolas Pitre
6 * Created: Dec 02, 2004
7 * Copyright: MontaVista Software Inc.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/kernel.h>
15#include <linux/platform_device.h>
16#include <linux/interrupt.h>
17#include <linux/clk.h>
18#include <linux/delay.h>
19
20#include <sound/ac97_codec.h>
21#include <sound/pxa2xx-lib.h>
22
23#include <asm/irq.h>
24#include <mach/hardware.h>
25#include <mach/pxa-regs.h>
26#include <mach/pxa2xx-gpio.h>
27#include <mach/audio.h>
28
29static DEFINE_MUTEX(car_mutex);
30static DECLARE_WAIT_QUEUE_HEAD(gsr_wq);
31static volatile long gsr_bits;
32static struct clk *ac97_clk;
33static struct clk *ac97conf_clk;
34
35/*
36 * Beware PXA27x bugs:
37 *
38 * o Slot 12 read from modem space will hang controller.
39 * o CDONE, SDONE interrupt fails after any slot 12 IO.
40 *
41 * We therefore have an hybrid approach for waiting on SDONE (interrupt or
42 * 1 jiffy timeout if interrupt never comes).
43 */
44
45unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
46{
47 unsigned short val = -1;
48 volatile u32 *reg_addr;
49
50 mutex_lock(&car_mutex);
51
52 /* set up primary or secondary codec space */
53 if ((cpu_is_pxa21x() || cpu_is_pxa25x()) && reg == AC97_GPIO_STATUS)
54 reg_addr = ac97->num ? &SMC_REG_BASE : &PMC_REG_BASE;
55 else
56 reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE;
57 reg_addr += (reg >> 1);
58
59 /* start read access across the ac97 link */
60 GSR = GSR_CDONE | GSR_SDONE;
61 gsr_bits = 0;
62 val = *reg_addr;
63 if (reg == AC97_GPIO_STATUS)
64 goto out;
65 if (wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1) <= 0 &&
66 !((GSR | gsr_bits) & GSR_SDONE)) {
67 printk(KERN_ERR "%s: read error (ac97_reg=%d GSR=%#lx)\n",
68 __func__, reg, GSR | gsr_bits);
69 val = -1;
70 goto out;
71 }
72
73 /* valid data now */
74 GSR = GSR_CDONE | GSR_SDONE;
75 gsr_bits = 0;
76 val = *reg_addr;
77 /* but we've just started another cycle... */
78 wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1);
79
80out: mutex_unlock(&car_mutex);
81 return val;
82}
83EXPORT_SYMBOL_GPL(pxa2xx_ac97_read);
84
85void pxa2xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
86 unsigned short val)
87{
88 volatile u32 *reg_addr;
89
90 mutex_lock(&car_mutex);
91
92 /* set up primary or secondary codec space */
93 if ((cpu_is_pxa21x() || cpu_is_pxa25x()) && reg == AC97_GPIO_STATUS)
94 reg_addr = ac97->num ? &SMC_REG_BASE : &PMC_REG_BASE;
95 else
96 reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE;
97 reg_addr += (reg >> 1);
98
99 GSR = GSR_CDONE | GSR_SDONE;
100 gsr_bits = 0;
101 *reg_addr = val;
102 if (wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_CDONE, 1) <= 0 &&
103 !((GSR | gsr_bits) & GSR_CDONE))
104 printk(KERN_ERR "%s: write error (ac97_reg=%d GSR=%#lx)\n",
105 __func__, reg, GSR | gsr_bits);
106
107 mutex_unlock(&car_mutex);
108}
109EXPORT_SYMBOL_GPL(pxa2xx_ac97_write);
110
111#ifdef CONFIG_PXA25x
112static inline void pxa_ac97_warm_pxa25x(void)
113{
114 gsr_bits = 0;
115
116 GCR |= GCR_WARM_RST | GCR_PRIRDY_IEN | GCR_SECRDY_IEN;
117 wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1);
118}
119
120static inline void pxa_ac97_cold_pxa25x(void)
121{
122 GCR &= GCR_COLD_RST; /* clear everything but nCRST */
123 GCR &= ~GCR_COLD_RST; /* then assert nCRST */
124
125 gsr_bits = 0;
126
127 GCR = GCR_COLD_RST;
128 GCR |= GCR_CDONE_IE|GCR_SDONE_IE;
129 wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1);
130}
131#endif
132
133#ifdef CONFIG_PXA27x
134static inline void pxa_ac97_warm_pxa27x(void)
135{
136 gsr_bits = 0;
137
138 /* warm reset broken on Bulverde,
139 so manually keep AC97 reset high */
140 pxa_gpio_mode(113 | GPIO_OUT | GPIO_DFLT_HIGH);
141 udelay(10);
142 GCR |= GCR_WARM_RST;
143 pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT);
144 udelay(500);
145}
146
147static inline void pxa_ac97_cold_pxa27x(void)
148{
149 GCR &= GCR_COLD_RST; /* clear everything but nCRST */
150 GCR &= ~GCR_COLD_RST; /* then assert nCRST */
151
152 gsr_bits = 0;
153
154 /* PXA27x Developers Manual section 13.5.2.2.1 */
155 clk_enable(ac97conf_clk);
156 udelay(5);
157 clk_disable(ac97conf_clk);
158 GCR = GCR_COLD_RST;
159 udelay(50);
160}
161#endif
162
163#ifdef CONFIG_PXA3xx
164static inline void pxa_ac97_warm_pxa3xx(void)
165{
166 int timeout = 100;
167
168 gsr_bits = 0;
169
170 /* Can't use interrupts */
171 GCR |= GCR_WARM_RST;
172 while (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR)) && timeout--)
173 mdelay(1);
174}
175
176static inline void pxa_ac97_cold_pxa3xx(void)
177{
178 int timeout = 1000;
179
180 /* Hold CLKBPB for 100us */
181 GCR = 0;
182 GCR = GCR_CLKBPB;
183 udelay(100);
184 GCR = 0;
185
186 GCR &= GCR_COLD_RST; /* clear everything but nCRST */
187 GCR &= ~GCR_COLD_RST; /* then assert nCRST */
188
189 gsr_bits = 0;
190
191 /* Can't use interrupts on PXA3xx */
192 GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN);
193
194 GCR = GCR_WARM_RST | GCR_COLD_RST;
195 while (!(GSR & (GSR_PCR | GSR_SCR)) && timeout--)
196 mdelay(10);
197}
198#endif
199
200bool pxa2xx_ac97_try_warm_reset(struct snd_ac97 *ac97)
201{
202#ifdef CONFIG_PXA25x
203 if (cpu_is_pxa21x() || cpu_is_pxa25x())
204 pxa_ac97_warm_pxa25x();
205 else
206#endif
207#ifdef CONFIG_PXA27x
208 if (cpu_is_pxa27x())
209 pxa_ac97_warm_pxa27x();
210 else
211#endif
212#ifdef CONFIG_PXA3xx
213 if (cpu_is_pxa3xx())
214 pxa_ac97_warm_pxa3xx();
215 else
216#endif
217 BUG();
218
219 if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR))) {
220 printk(KERN_INFO "%s: warm reset timeout (GSR=%#lx)\n",
221 __func__, gsr_bits);
222
223 return false;
224 }
225
226 return true;
227}
228EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_warm_reset);
229
230bool pxa2xx_ac97_try_cold_reset(struct snd_ac97 *ac97)
231{
232#ifdef CONFIG_PXA25x
233 if (cpu_is_pxa21x() || cpu_is_pxa25x())
234 pxa_ac97_cold_pxa25x();
235 else
236#endif
237#ifdef CONFIG_PXA27x
238 if (cpu_is_pxa27x())
239 pxa_ac97_cold_pxa27x();
240 else
241#endif
242#ifdef CONFIG_PXA3xx
243 if (cpu_is_pxa3xx())
244 pxa_ac97_cold_pxa3xx();
245 else
246#endif
247 BUG();
248
249 if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR))) {
250 printk(KERN_INFO "%s: cold reset timeout (GSR=%#lx)\n",
251 __func__, gsr_bits);
252
253 return false;
254 }
255
256 return true;
257}
258EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_cold_reset);
259
260
261void pxa2xx_ac97_finish_reset(struct snd_ac97 *ac97)
262{
263 GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN);
264 GCR |= GCR_SDONE_IE|GCR_CDONE_IE;
265}
266EXPORT_SYMBOL_GPL(pxa2xx_ac97_finish_reset);
267
268static irqreturn_t pxa2xx_ac97_irq(int irq, void *dev_id)
269{
270 long status;
271
272 status = GSR;
273 if (status) {
274 GSR = status;
275 gsr_bits |= status;
276 wake_up(&gsr_wq);
277
278 /* Although we don't use those we still need to clear them
279 since they tend to spuriously trigger when MMC is used
280 (hardware bug? go figure)... */
281 if (cpu_is_pxa27x()) {
282 MISR = MISR_EOC;
283 PISR = PISR_EOC;
284 MCSR = MCSR_EOC;
285 }
286
287 return IRQ_HANDLED;
288 }
289
290 return IRQ_NONE;
291}
292
293#ifdef CONFIG_PM
294int pxa2xx_ac97_hw_suspend(void)
295{
296 GCR |= GCR_ACLINK_OFF;
297 clk_disable(ac97_clk);
298 return 0;
299}
300EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_suspend);
301
302int pxa2xx_ac97_hw_resume(void)
303{
304 if (cpu_is_pxa21x() || cpu_is_pxa25x() || cpu_is_pxa27x()) {
305 pxa_gpio_mode(GPIO31_SYNC_AC97_MD);
306 pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD);
307 pxa_gpio_mode(GPIO28_BITCLK_AC97_MD);
308 pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD);
309 }
310 if (cpu_is_pxa27x()) {
311 /* Use GPIO 113 as AC97 Reset on Bulverde */
312 pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT);
313 }
314 clk_enable(ac97_clk);
315 return 0;
316}
317EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_resume);
318#endif
319
320int __devinit pxa2xx_ac97_hw_probe(struct platform_device *dev)
321{
322 int ret;
323
324 ret = request_irq(IRQ_AC97, pxa2xx_ac97_irq, 0, "AC97", NULL);
325 if (ret < 0)
326 goto err;
327
328 if (cpu_is_pxa21x() || cpu_is_pxa25x() || cpu_is_pxa27x()) {
329 pxa_gpio_mode(GPIO31_SYNC_AC97_MD);
330 pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD);
331 pxa_gpio_mode(GPIO28_BITCLK_AC97_MD);
332 pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD);
333 }
334
335 if (cpu_is_pxa27x()) {
336 /* Use GPIO 113 as AC97 Reset on Bulverde */
337 pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT);
338 ac97conf_clk = clk_get(&dev->dev, "AC97CONFCLK");
339 if (IS_ERR(ac97conf_clk)) {
340 ret = PTR_ERR(ac97conf_clk);
341 ac97conf_clk = NULL;
342 goto err_irq;
343 }
344 }
345
346 ac97_clk = clk_get(&dev->dev, "AC97CLK");
347 if (IS_ERR(ac97_clk)) {
348 ret = PTR_ERR(ac97_clk);
349 ac97_clk = NULL;
350 goto err_irq;
351 }
352
353 return clk_enable(ac97_clk);
354
355err_irq:
356 GCR |= GCR_ACLINK_OFF;
357 if (ac97conf_clk) {
358 clk_put(ac97conf_clk);
359 ac97conf_clk = NULL;
360 }
361 free_irq(IRQ_AC97, NULL);
362err:
363 return ret;
364}
365EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_probe);
366
367void pxa2xx_ac97_hw_remove(struct platform_device *dev)
368{
369 GCR |= GCR_ACLINK_OFF;
370 free_irq(IRQ_AC97, NULL);
371 if (ac97conf_clk) {
372 clk_put(ac97conf_clk);
373 ac97conf_clk = NULL;
374 }
375 clk_disable(ac97_clk);
376 clk_put(ac97_clk);
377 ac97_clk = NULL;
378}
379EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_remove);
380
381MODULE_AUTHOR("Nicolas Pitre");
382MODULE_DESCRIPTION("Intel/Marvell PXA sound library");
383MODULE_LICENSE("GPL");
384
diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c
index 199cca3366df..c2635beb4c88 100644
--- a/sound/arm/pxa2xx-ac97.c
+++ b/sound/arm/pxa2xx-ac97.c
@@ -12,198 +12,27 @@
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/kernel.h>
16#include <linux/platform_device.h> 15#include <linux/platform_device.h>
17#include <linux/interrupt.h>
18#include <linux/wait.h>
19#include <linux/clk.h>
20#include <linux/delay.h>
21 16
22#include <sound/core.h> 17#include <sound/core.h>
23#include <sound/pcm.h> 18#include <sound/pcm.h>
24#include <sound/ac97_codec.h> 19#include <sound/ac97_codec.h>
25#include <sound/initval.h> 20#include <sound/initval.h>
21#include <sound/pxa2xx-lib.h>
26 22
27#include <asm/irq.h>
28#include <linux/mutex.h>
29#include <mach/hardware.h> 23#include <mach/hardware.h>
30#include <mach/pxa-regs.h> 24#include <mach/pxa-regs.h>
31#include <mach/pxa2xx-gpio.h>
32#include <mach/audio.h> 25#include <mach/audio.h>
33 26
34#include "pxa2xx-pcm.h" 27#include "pxa2xx-pcm.h"
35 28
36
37static DEFINE_MUTEX(car_mutex);
38static DECLARE_WAIT_QUEUE_HEAD(gsr_wq);
39static volatile long gsr_bits;
40static struct clk *ac97_clk;
41#ifdef CONFIG_PXA27x
42static struct clk *ac97conf_clk;
43#endif
44
45/*
46 * Beware PXA27x bugs:
47 *
48 * o Slot 12 read from modem space will hang controller.
49 * o CDONE, SDONE interrupt fails after any slot 12 IO.
50 *
51 * We therefore have an hybrid approach for waiting on SDONE (interrupt or
52 * 1 jiffy timeout if interrupt never comes).
53 */
54
55static unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
56{
57 unsigned short val = -1;
58 volatile u32 *reg_addr;
59
60 mutex_lock(&car_mutex);
61
62 /* set up primary or secondary codec space */
63 reg_addr = (ac97->num & 1) ? &SAC_REG_BASE : &PAC_REG_BASE;
64 reg_addr += (reg >> 1);
65
66 /* start read access across the ac97 link */
67 GSR = GSR_CDONE | GSR_SDONE;
68 gsr_bits = 0;
69 val = *reg_addr;
70 if (reg == AC97_GPIO_STATUS)
71 goto out;
72 if (wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1) <= 0 &&
73 !((GSR | gsr_bits) & GSR_SDONE)) {
74 printk(KERN_ERR "%s: read error (ac97_reg=%d GSR=%#lx)\n",
75 __func__, reg, GSR | gsr_bits);
76 val = -1;
77 goto out;
78 }
79
80 /* valid data now */
81 GSR = GSR_CDONE | GSR_SDONE;
82 gsr_bits = 0;
83 val = *reg_addr;
84 /* but we've just started another cycle... */
85 wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1);
86
87out: mutex_unlock(&car_mutex);
88 return val;
89}
90
91static void pxa2xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val)
92{
93 volatile u32 *reg_addr;
94
95 mutex_lock(&car_mutex);
96
97 /* set up primary or secondary codec space */
98 reg_addr = (ac97->num & 1) ? &SAC_REG_BASE : &PAC_REG_BASE;
99 reg_addr += (reg >> 1);
100
101 GSR = GSR_CDONE | GSR_SDONE;
102 gsr_bits = 0;
103 *reg_addr = val;
104 if (wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_CDONE, 1) <= 0 &&
105 !((GSR | gsr_bits) & GSR_CDONE))
106 printk(KERN_ERR "%s: write error (ac97_reg=%d GSR=%#lx)\n",
107 __func__, reg, GSR | gsr_bits);
108
109 mutex_unlock(&car_mutex);
110}
111
112static void pxa2xx_ac97_reset(struct snd_ac97 *ac97) 29static void pxa2xx_ac97_reset(struct snd_ac97 *ac97)
113{ 30{
114 /* First, try cold reset */ 31 if (!pxa2xx_ac97_try_cold_reset(ac97)) {
115#ifdef CONFIG_PXA3xx 32 pxa2xx_ac97_try_warm_reset(ac97);
116 int timeout;
117
118 /* Hold CLKBPB for 100us */
119 GCR = 0;
120 GCR = GCR_CLKBPB;
121 udelay(100);
122 GCR = 0;
123#endif
124
125 GCR &= GCR_COLD_RST; /* clear everything but nCRST */
126 GCR &= ~GCR_COLD_RST; /* then assert nCRST */
127
128 gsr_bits = 0;
129#ifdef CONFIG_PXA27x
130 /* PXA27x Developers Manual section 13.5.2.2.1 */
131 clk_enable(ac97conf_clk);
132 udelay(5);
133 clk_disable(ac97conf_clk);
134 GCR = GCR_COLD_RST;
135 udelay(50);
136#elif defined(CONFIG_PXA3xx)
137 timeout = 1000;
138 /* Can't use interrupts on PXA3xx */
139 GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN);
140
141 GCR = GCR_WARM_RST | GCR_COLD_RST;
142 while (!(GSR & (GSR_PCR | GSR_SCR)) && timeout--)
143 mdelay(10);
144#else
145 GCR = GCR_COLD_RST;
146 GCR |= GCR_CDONE_IE|GCR_SDONE_IE;
147 wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1);
148#endif
149
150 if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR))) {
151 printk(KERN_INFO "%s: cold reset timeout (GSR=%#lx)\n",
152 __func__, gsr_bits);
153
154 /* let's try warm reset */
155 gsr_bits = 0;
156#ifdef CONFIG_PXA27x
157 /* warm reset broken on Bulverde,
158 so manually keep AC97 reset high */
159 pxa_gpio_mode(113 | GPIO_OUT | GPIO_DFLT_HIGH);
160 udelay(10);
161 GCR |= GCR_WARM_RST;
162 pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT);
163 udelay(500);
164#elif defined(CONFIG_PXA3xx)
165 timeout = 100;
166 /* Can't use interrupts */
167 GCR |= GCR_WARM_RST;
168 while (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR)) && timeout--)
169 mdelay(1);
170#else
171 GCR |= GCR_WARM_RST|GCR_PRIRDY_IEN|GCR_SECRDY_IEN;
172 wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1);
173#endif
174
175 if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR)))
176 printk(KERN_INFO "%s: warm reset timeout (GSR=%#lx)\n",
177 __func__, gsr_bits);
178 }
179
180 GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN);
181 GCR |= GCR_SDONE_IE|GCR_CDONE_IE;
182}
183
184static irqreturn_t pxa2xx_ac97_irq(int irq, void *dev_id)
185{
186 long status;
187
188 status = GSR;
189 if (status) {
190 GSR = status;
191 gsr_bits |= status;
192 wake_up(&gsr_wq);
193
194#ifdef CONFIG_PXA27x
195 /* Although we don't use those we still need to clear them
196 since they tend to spuriously trigger when MMC is used
197 (hardware bug? go figure)... */
198 MISR = MISR_EOC;
199 PISR = PISR_EOC;
200 MCSR = MCSR_EOC;
201#endif
202
203 return IRQ_HANDLED;
204 } 33 }
205 34
206 return IRQ_NONE; 35 pxa2xx_ac97_finish_reset(ac97);
207} 36}
208 37
209static struct snd_ac97_bus_ops pxa2xx_ac97_ops = { 38static struct snd_ac97_bus_ops pxa2xx_ac97_ops = {
@@ -215,7 +44,7 @@ static struct snd_ac97_bus_ops pxa2xx_ac97_ops = {
215static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_out = { 44static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_out = {
216 .name = "AC97 PCM out", 45 .name = "AC97 PCM out",
217 .dev_addr = __PREG(PCDR), 46 .dev_addr = __PREG(PCDR),
218 .drcmr = &DRCMRTXPCDR, 47 .drcmr = &DRCMR(12),
219 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG | 48 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
220 DCMD_BURST32 | DCMD_WIDTH4, 49 DCMD_BURST32 | DCMD_WIDTH4,
221}; 50};
@@ -223,7 +52,7 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_out = {
223static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_in = { 52static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_in = {
224 .name = "AC97 PCM in", 53 .name = "AC97 PCM in",
225 .dev_addr = __PREG(PCDR), 54 .dev_addr = __PREG(PCDR),
226 .drcmr = &DRCMRRXPCDR, 55 .drcmr = &DRCMR(11),
227 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | 56 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
228 DCMD_BURST32 | DCMD_WIDTH4, 57 DCMD_BURST32 | DCMD_WIDTH4,
229}; 58};
@@ -288,17 +117,19 @@ static int pxa2xx_ac97_do_suspend(struct snd_card *card, pm_message_t state)
288 snd_ac97_suspend(pxa2xx_ac97_ac97); 117 snd_ac97_suspend(pxa2xx_ac97_ac97);
289 if (platform_ops && platform_ops->suspend) 118 if (platform_ops && platform_ops->suspend)
290 platform_ops->suspend(platform_ops->priv); 119 platform_ops->suspend(platform_ops->priv);
291 GCR |= GCR_ACLINK_OFF;
292 clk_disable(ac97_clk);
293 120
294 return 0; 121 return pxa2xx_ac97_hw_suspend();
295} 122}
296 123
297static int pxa2xx_ac97_do_resume(struct snd_card *card) 124static int pxa2xx_ac97_do_resume(struct snd_card *card)
298{ 125{
299 pxa2xx_audio_ops_t *platform_ops = card->dev->platform_data; 126 pxa2xx_audio_ops_t *platform_ops = card->dev->platform_data;
127 int rc;
128
129 rc = pxa2xx_ac97_hw_resume();
130 if (rc)
131 return rc;
300 132
301 clk_enable(ac97_clk);
302 if (platform_ops && platform_ops->resume) 133 if (platform_ops && platform_ops->resume)
303 platform_ops->resume(platform_ops->priv); 134 platform_ops->resume(platform_ops->priv);
304 snd_ac97_resume(pxa2xx_ac97_ac97); 135 snd_ac97_resume(pxa2xx_ac97_ac97);
@@ -354,40 +185,17 @@ static int __devinit pxa2xx_ac97_probe(struct platform_device *dev)
354 if (ret) 185 if (ret)
355 goto err; 186 goto err;
356 187
357 ret = request_irq(IRQ_AC97, pxa2xx_ac97_irq, 0, "AC97", NULL); 188 ret = pxa2xx_ac97_hw_probe(dev);
358 if (ret < 0) 189 if (ret)
359 goto err;
360
361 pxa_gpio_mode(GPIO31_SYNC_AC97_MD);
362 pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD);
363 pxa_gpio_mode(GPIO28_BITCLK_AC97_MD);
364 pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD);
365#ifdef CONFIG_PXA27x
366 /* Use GPIO 113 as AC97 Reset on Bulverde */
367 pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT);
368 ac97conf_clk = clk_get(&dev->dev, "AC97CONFCLK");
369 if (IS_ERR(ac97conf_clk)) {
370 ret = PTR_ERR(ac97conf_clk);
371 ac97conf_clk = NULL;
372 goto err;
373 }
374#endif
375
376 ac97_clk = clk_get(&dev->dev, "AC97CLK");
377 if (IS_ERR(ac97_clk)) {
378 ret = PTR_ERR(ac97_clk);
379 ac97_clk = NULL;
380 goto err; 190 goto err;
381 }
382 clk_enable(ac97_clk);
383 191
384 ret = snd_ac97_bus(card, 0, &pxa2xx_ac97_ops, NULL, &ac97_bus); 192 ret = snd_ac97_bus(card, 0, &pxa2xx_ac97_ops, NULL, &ac97_bus);
385 if (ret) 193 if (ret)
386 goto err; 194 goto err_remove;
387 memset(&ac97_template, 0, sizeof(ac97_template)); 195 memset(&ac97_template, 0, sizeof(ac97_template));
388 ret = snd_ac97_mixer(ac97_bus, &ac97_template, &pxa2xx_ac97_ac97); 196 ret = snd_ac97_mixer(ac97_bus, &ac97_template, &pxa2xx_ac97_ac97);
389 if (ret) 197 if (ret)
390 goto err; 198 goto err_remove;
391 199
392 snprintf(card->shortname, sizeof(card->shortname), 200 snprintf(card->shortname, sizeof(card->shortname),
393 "%s", snd_ac97_get_short_name(pxa2xx_ac97_ac97)); 201 "%s", snd_ac97_get_short_name(pxa2xx_ac97_ac97));
@@ -401,22 +209,11 @@ static int __devinit pxa2xx_ac97_probe(struct platform_device *dev)
401 return 0; 209 return 0;
402 } 210 }
403 211
404 err: 212err_remove:
213 pxa2xx_ac97_hw_remove(dev);
214err:
405 if (card) 215 if (card)
406 snd_card_free(card); 216 snd_card_free(card);
407 if (ac97_clk) {
408 GCR |= GCR_ACLINK_OFF;
409 free_irq(IRQ_AC97, NULL);
410 clk_disable(ac97_clk);
411 clk_put(ac97_clk);
412 ac97_clk = NULL;
413 }
414#ifdef CONFIG_PXA27x
415 if (ac97conf_clk) {
416 clk_put(ac97conf_clk);
417 ac97conf_clk = NULL;
418 }
419#endif
420 return ret; 217 return ret;
421} 218}
422 219
@@ -427,15 +224,7 @@ static int __devexit pxa2xx_ac97_remove(struct platform_device *dev)
427 if (card) { 224 if (card) {
428 snd_card_free(card); 225 snd_card_free(card);
429 platform_set_drvdata(dev, NULL); 226 platform_set_drvdata(dev, NULL);
430 GCR |= GCR_ACLINK_OFF; 227 pxa2xx_ac97_hw_remove(dev);
431 free_irq(IRQ_AC97, NULL);
432 clk_disable(ac97_clk);
433 clk_put(ac97_clk);
434 ac97_clk = NULL;
435#ifdef CONFIG_PXA27x
436 clk_put(ac97conf_clk);
437 ac97conf_clk = NULL;
438#endif
439 } 228 }
440 229
441 return 0; 230 return 0;
diff --git a/sound/arm/pxa2xx-pcm-lib.c b/sound/arm/pxa2xx-pcm-lib.c
new file mode 100644
index 000000000000..1c93eb77cb99
--- /dev/null
+++ b/sound/arm/pxa2xx-pcm-lib.c
@@ -0,0 +1,278 @@
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 version 2 as
4 * published by the Free Software Foundation.
5 */
6
7#include <linux/module.h>
8#include <linux/dma-mapping.h>
9
10#include <sound/core.h>
11#include <sound/pcm.h>
12#include <sound/pcm_params.h>
13#include <sound/pxa2xx-lib.h>
14
15#include <asm/dma.h>
16#include <mach/pxa-regs.h>
17
18#include "pxa2xx-pcm.h"
19
20static const struct snd_pcm_hardware pxa2xx_pcm_hardware = {
21 .info = SNDRV_PCM_INFO_MMAP |
22 SNDRV_PCM_INFO_MMAP_VALID |
23 SNDRV_PCM_INFO_INTERLEAVED |
24 SNDRV_PCM_INFO_PAUSE |
25 SNDRV_PCM_INFO_RESUME,
26 .formats = SNDRV_PCM_FMTBIT_S16_LE |
27 SNDRV_PCM_FMTBIT_S24_LE |
28 SNDRV_PCM_FMTBIT_S32_LE,
29 .period_bytes_min = 32,
30 .period_bytes_max = 8192 - 32,
31 .periods_min = 1,
32 .periods_max = PAGE_SIZE/sizeof(pxa_dma_desc),
33 .buffer_bytes_max = 128 * 1024,
34 .fifo_size = 32,
35};
36
37int __pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
38 struct snd_pcm_hw_params *params)
39{
40 struct snd_pcm_runtime *runtime = substream->runtime;
41 struct pxa2xx_runtime_data *rtd = runtime->private_data;
42 size_t totsize = params_buffer_bytes(params);
43 size_t period = params_period_bytes(params);
44 pxa_dma_desc *dma_desc;
45 dma_addr_t dma_buff_phys, next_desc_phys;
46
47 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
48 runtime->dma_bytes = totsize;
49
50 dma_desc = rtd->dma_desc_array;
51 next_desc_phys = rtd->dma_desc_array_phys;
52 dma_buff_phys = runtime->dma_addr;
53 do {
54 next_desc_phys += sizeof(pxa_dma_desc);
55 dma_desc->ddadr = next_desc_phys;
56 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
57 dma_desc->dsadr = dma_buff_phys;
58 dma_desc->dtadr = rtd->params->dev_addr;
59 } else {
60 dma_desc->dsadr = rtd->params->dev_addr;
61 dma_desc->dtadr = dma_buff_phys;
62 }
63 if (period > totsize)
64 period = totsize;
65 dma_desc->dcmd = rtd->params->dcmd | period | DCMD_ENDIRQEN;
66 dma_desc++;
67 dma_buff_phys += period;
68 } while (totsize -= period);
69 dma_desc[-1].ddadr = rtd->dma_desc_array_phys;
70
71 return 0;
72}
73EXPORT_SYMBOL(__pxa2xx_pcm_hw_params);
74
75int __pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream)
76{
77 struct pxa2xx_runtime_data *rtd = substream->runtime->private_data;
78
79 if (rtd && rtd->params)
80 *rtd->params->drcmr = 0;
81
82 snd_pcm_set_runtime_buffer(substream, NULL);
83 return 0;
84}
85EXPORT_SYMBOL(__pxa2xx_pcm_hw_free);
86
87int pxa2xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
88{
89 struct pxa2xx_runtime_data *prtd = substream->runtime->private_data;
90 int ret = 0;
91
92 switch (cmd) {
93 case SNDRV_PCM_TRIGGER_START:
94 DDADR(prtd->dma_ch) = prtd->dma_desc_array_phys;
95 DCSR(prtd->dma_ch) = DCSR_RUN;
96 break;
97
98 case SNDRV_PCM_TRIGGER_STOP:
99 case SNDRV_PCM_TRIGGER_SUSPEND:
100 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
101 DCSR(prtd->dma_ch) &= ~DCSR_RUN;
102 break;
103
104 case SNDRV_PCM_TRIGGER_RESUME:
105 DCSR(prtd->dma_ch) |= DCSR_RUN;
106 break;
107 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
108 DDADR(prtd->dma_ch) = prtd->dma_desc_array_phys;
109 DCSR(prtd->dma_ch) |= DCSR_RUN;
110 break;
111
112 default:
113 ret = -EINVAL;
114 }
115
116 return ret;
117}
118EXPORT_SYMBOL(pxa2xx_pcm_trigger);
119
120snd_pcm_uframes_t
121pxa2xx_pcm_pointer(struct snd_pcm_substream *substream)
122{
123 struct snd_pcm_runtime *runtime = substream->runtime;
124 struct pxa2xx_runtime_data *prtd = runtime->private_data;
125
126 dma_addr_t ptr = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
127 DSADR(prtd->dma_ch) : DTADR(prtd->dma_ch);
128 snd_pcm_uframes_t x = bytes_to_frames(runtime, ptr - runtime->dma_addr);
129
130 if (x == runtime->buffer_size)
131 x = 0;
132 return x;
133}
134EXPORT_SYMBOL(pxa2xx_pcm_pointer);
135
136int __pxa2xx_pcm_prepare(struct snd_pcm_substream *substream)
137{
138 struct pxa2xx_runtime_data *prtd = substream->runtime->private_data;
139
140 DCSR(prtd->dma_ch) &= ~DCSR_RUN;
141 DCSR(prtd->dma_ch) = 0;
142 DCMD(prtd->dma_ch) = 0;
143 *prtd->params->drcmr = prtd->dma_ch | DRCMR_MAPVLD;
144
145 return 0;
146}
147EXPORT_SYMBOL(__pxa2xx_pcm_prepare);
148
149void pxa2xx_pcm_dma_irq(int dma_ch, void *dev_id)
150{
151 struct snd_pcm_substream *substream = dev_id;
152 struct pxa2xx_runtime_data *rtd = substream->runtime->private_data;
153 int dcsr;
154
155 dcsr = DCSR(dma_ch);
156 DCSR(dma_ch) = dcsr & ~DCSR_STOPIRQEN;
157
158 if (dcsr & DCSR_ENDINTR) {
159 snd_pcm_period_elapsed(substream);
160 } else {
161 printk(KERN_ERR "%s: DMA error on channel %d (DCSR=%#x)\n",
162 rtd->params->name, dma_ch, dcsr);
163 snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
164 }
165}
166EXPORT_SYMBOL(pxa2xx_pcm_dma_irq);
167
168int __pxa2xx_pcm_open(struct snd_pcm_substream *substream)
169{
170 struct snd_pcm_runtime *runtime = substream->runtime;
171 struct pxa2xx_runtime_data *rtd;
172 int ret;
173
174 runtime->hw = pxa2xx_pcm_hardware;
175
176 /*
177 * For mysterious reasons (and despite what the manual says)
178 * playback samples are lost if the DMA count is not a multiple
179 * of the DMA burst size. Let's add a rule to enforce that.
180 */
181 ret = snd_pcm_hw_constraint_step(runtime, 0,
182 SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32);
183 if (ret)
184 goto out;
185
186 ret = snd_pcm_hw_constraint_step(runtime, 0,
187 SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 32);
188 if (ret)
189 goto out;
190
191 ret = snd_pcm_hw_constraint_integer(runtime,
192 SNDRV_PCM_HW_PARAM_PERIODS);
193 if (ret < 0)
194 goto out;
195
196 ret = -ENOMEM;
197 rtd = kmalloc(sizeof(*rtd), GFP_KERNEL);
198 if (!rtd)
199 goto out;
200 rtd->dma_desc_array =
201 dma_alloc_writecombine(substream->pcm->card->dev, PAGE_SIZE,
202 &rtd->dma_desc_array_phys, GFP_KERNEL);
203 if (!rtd->dma_desc_array)
204 goto err1;
205
206 runtime->private_data = rtd;
207 return 0;
208
209 err1:
210 kfree(rtd);
211 out:
212 return ret;
213}
214EXPORT_SYMBOL(__pxa2xx_pcm_open);
215
216int __pxa2xx_pcm_close(struct snd_pcm_substream *substream)
217{
218 struct snd_pcm_runtime *runtime = substream->runtime;
219 struct pxa2xx_runtime_data *rtd = runtime->private_data;
220
221 dma_free_writecombine(substream->pcm->card->dev, PAGE_SIZE,
222 rtd->dma_desc_array, rtd->dma_desc_array_phys);
223 kfree(rtd);
224 return 0;
225}
226EXPORT_SYMBOL(__pxa2xx_pcm_close);
227
228int pxa2xx_pcm_mmap(struct snd_pcm_substream *substream,
229 struct vm_area_struct *vma)
230{
231 struct snd_pcm_runtime *runtime = substream->runtime;
232 return dma_mmap_writecombine(substream->pcm->card->dev, vma,
233 runtime->dma_area,
234 runtime->dma_addr,
235 runtime->dma_bytes);
236}
237EXPORT_SYMBOL(pxa2xx_pcm_mmap);
238
239int pxa2xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
240{
241 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
242 struct snd_dma_buffer *buf = &substream->dma_buffer;
243 size_t size = pxa2xx_pcm_hardware.buffer_bytes_max;
244 buf->dev.type = SNDRV_DMA_TYPE_DEV;
245 buf->dev.dev = pcm->card->dev;
246 buf->private_data = NULL;
247 buf->area = dma_alloc_writecombine(pcm->card->dev, size,
248 &buf->addr, GFP_KERNEL);
249 if (!buf->area)
250 return -ENOMEM;
251 buf->bytes = size;
252 return 0;
253}
254EXPORT_SYMBOL(pxa2xx_pcm_preallocate_dma_buffer);
255
256void pxa2xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
257{
258 struct snd_pcm_substream *substream;
259 struct snd_dma_buffer *buf;
260 int stream;
261
262 for (stream = 0; stream < 2; stream++) {
263 substream = pcm->streams[stream].substream;
264 if (!substream)
265 continue;
266 buf = &substream->dma_buffer;
267 if (!buf->area)
268 continue;
269 dma_free_writecombine(pcm->card->dev, buf->bytes,
270 buf->area, buf->addr);
271 buf->area = NULL;
272 }
273}
274EXPORT_SYMBOL(pxa2xx_pcm_free_dma_buffers);
275
276MODULE_AUTHOR("Nicolas Pitre");
277MODULE_DESCRIPTION("Intel PXA2xx sound library");
278MODULE_LICENSE("GPL");
diff --git a/sound/arm/pxa2xx-pcm.c b/sound/arm/pxa2xx-pcm.c
index 381094aab235..535704f77496 100644
--- a/sound/arm/pxa2xx-pcm.c
+++ b/sound/arm/pxa2xx-pcm.c
@@ -10,183 +10,20 @@
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11 */ 11 */
12 12
13#include <linux/module.h>
14#include <linux/init.h>
15#include <linux/device.h>
16#include <linux/slab.h>
17#include <linux/dma-mapping.h>
18
19#include <sound/core.h> 13#include <sound/core.h>
20#include <sound/pcm.h> 14#include <sound/pxa2xx-lib.h>
21#include <sound/pcm_params.h>
22
23#include <asm/dma.h>
24#include <mach/hardware.h>
25#include <mach/pxa-regs.h>
26 15
27#include "pxa2xx-pcm.h" 16#include "pxa2xx-pcm.h"
28 17
29
30static const struct snd_pcm_hardware pxa2xx_pcm_hardware = {
31 .info = SNDRV_PCM_INFO_MMAP |
32 SNDRV_PCM_INFO_MMAP_VALID |
33 SNDRV_PCM_INFO_INTERLEAVED |
34 SNDRV_PCM_INFO_PAUSE,
35 .formats = SNDRV_PCM_FMTBIT_S16_LE,
36 .period_bytes_min = 32,
37 .period_bytes_max = 8192 - 32,
38 .periods_min = 1,
39 .periods_max = PAGE_SIZE/sizeof(pxa_dma_desc),
40 .buffer_bytes_max = 128 * 1024,
41 .fifo_size = 32,
42};
43
44struct pxa2xx_runtime_data {
45 int dma_ch;
46 struct pxa2xx_pcm_dma_params *params;
47 pxa_dma_desc *dma_desc_array;
48 dma_addr_t dma_desc_array_phys;
49};
50
51static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
52 struct snd_pcm_hw_params *params)
53{
54 struct snd_pcm_runtime *runtime = substream->runtime;
55 struct pxa2xx_runtime_data *rtd = runtime->private_data;
56 size_t totsize = params_buffer_bytes(params);
57 size_t period = params_period_bytes(params);
58 pxa_dma_desc *dma_desc;
59 dma_addr_t dma_buff_phys, next_desc_phys;
60
61 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
62 runtime->dma_bytes = totsize;
63
64 dma_desc = rtd->dma_desc_array;
65 next_desc_phys = rtd->dma_desc_array_phys;
66 dma_buff_phys = runtime->dma_addr;
67 do {
68 next_desc_phys += sizeof(pxa_dma_desc);
69 dma_desc->ddadr = next_desc_phys;
70 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
71 dma_desc->dsadr = dma_buff_phys;
72 dma_desc->dtadr = rtd->params->dev_addr;
73 } else {
74 dma_desc->dsadr = rtd->params->dev_addr;
75 dma_desc->dtadr = dma_buff_phys;
76 }
77 if (period > totsize)
78 period = totsize;
79 dma_desc->dcmd = rtd->params->dcmd | period | DCMD_ENDIRQEN;
80 dma_desc++;
81 dma_buff_phys += period;
82 } while (totsize -= period);
83 dma_desc[-1].ddadr = rtd->dma_desc_array_phys;
84
85 return 0;
86}
87
88static int pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream)
89{
90 struct pxa2xx_runtime_data *rtd = substream->runtime->private_data;
91
92 *rtd->params->drcmr = 0;
93 snd_pcm_set_runtime_buffer(substream, NULL);
94 return 0;
95}
96
97static int pxa2xx_pcm_prepare(struct snd_pcm_substream *substream) 18static int pxa2xx_pcm_prepare(struct snd_pcm_substream *substream)
98{ 19{
99 struct pxa2xx_pcm_client *client = substream->private_data; 20 struct pxa2xx_pcm_client *client = substream->private_data;
100 struct snd_pcm_runtime *runtime = substream->runtime;
101 struct pxa2xx_runtime_data *rtd = runtime->private_data;
102 21
103 DCSR(rtd->dma_ch) &= ~DCSR_RUN; 22 __pxa2xx_pcm_prepare(substream);
104 DCSR(rtd->dma_ch) = 0;
105 DCMD(rtd->dma_ch) = 0;
106 *rtd->params->drcmr = rtd->dma_ch | DRCMR_MAPVLD;
107 23
108 return client->prepare(substream); 24 return client->prepare(substream);
109} 25}
110 26
111static int pxa2xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
112{
113 struct pxa2xx_runtime_data *rtd = substream->runtime->private_data;
114 int ret = 0;
115
116 switch (cmd) {
117 case SNDRV_PCM_TRIGGER_START:
118 DDADR(rtd->dma_ch) = rtd->dma_desc_array_phys;
119 DCSR(rtd->dma_ch) = DCSR_RUN;
120 break;
121
122 case SNDRV_PCM_TRIGGER_STOP:
123 case SNDRV_PCM_TRIGGER_SUSPEND:
124 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
125 DCSR(rtd->dma_ch) &= ~DCSR_RUN;
126 break;
127
128 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
129 DCSR(rtd->dma_ch) |= DCSR_RUN;
130 break;
131
132 default:
133 ret = -EINVAL;
134 }
135
136 return ret;
137}
138
139static void pxa2xx_pcm_dma_irq(int dma_ch, void *dev_id)
140{
141 struct snd_pcm_substream *substream = dev_id;
142 struct pxa2xx_runtime_data *rtd = substream->runtime->private_data;
143 int dcsr;
144
145 dcsr = DCSR(dma_ch);
146 DCSR(dma_ch) = dcsr & ~DCSR_STOPIRQEN;
147
148 if (dcsr & DCSR_ENDINTR) {
149 snd_pcm_period_elapsed(substream);
150 } else {
151 printk( KERN_ERR "%s: DMA error on channel %d (DCSR=%#x)\n",
152 rtd->params->name, dma_ch, dcsr );
153 snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
154 }
155}
156
157static snd_pcm_uframes_t pxa2xx_pcm_pointer(struct snd_pcm_substream *substream)
158{
159 struct snd_pcm_runtime *runtime = substream->runtime;
160 struct pxa2xx_runtime_data *rtd = runtime->private_data;
161 dma_addr_t ptr = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
162 DSADR(rtd->dma_ch) : DTADR(rtd->dma_ch);
163 snd_pcm_uframes_t x = bytes_to_frames(runtime, ptr - runtime->dma_addr);
164 if (x == runtime->buffer_size)
165 x = 0;
166 return x;
167}
168
169static int
170pxa2xx_pcm_hw_rule_mult32(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule)
171{
172 struct snd_interval *i = hw_param_interval(params, rule->var);
173 int changed = 0;
174
175 if (i->min & 31) {
176 i->min = (i->min & ~31) + 32;
177 i->openmin = 0;
178 changed = 1;
179 }
180
181 if (i->max & 31) {
182 i->max &= ~31;
183 i->openmax = 0;
184 changed = 1;
185 }
186
187 return changed;
188}
189
190static int pxa2xx_pcm_open(struct snd_pcm_substream *substream) 27static int pxa2xx_pcm_open(struct snd_pcm_substream *substream)
191{ 28{
192 struct pxa2xx_pcm_client *client = substream->private_data; 29 struct pxa2xx_pcm_client *client = substream->private_data;
@@ -194,33 +31,11 @@ static int pxa2xx_pcm_open(struct snd_pcm_substream *substream)
194 struct pxa2xx_runtime_data *rtd; 31 struct pxa2xx_runtime_data *rtd;
195 int ret; 32 int ret;
196 33
197 runtime->hw = pxa2xx_pcm_hardware; 34 ret = __pxa2xx_pcm_open(substream);
198
199 /*
200 * For mysterious reasons (and despite what the manual says)
201 * playback samples are lost if the DMA count is not a multiple
202 * of the DMA burst size. Let's add a rule to enforce that.
203 */
204 ret = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
205 pxa2xx_pcm_hw_rule_mult32, NULL,
206 SNDRV_PCM_HW_PARAM_PERIOD_BYTES, -1);
207 if (ret)
208 goto out;
209 ret = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
210 pxa2xx_pcm_hw_rule_mult32, NULL,
211 SNDRV_PCM_HW_PARAM_BUFFER_BYTES, -1);
212 if (ret) 35 if (ret)
213 goto out; 36 goto out;
214 37
215 ret = -ENOMEM; 38 rtd = runtime->private_data;
216 rtd = kmalloc(sizeof(*rtd), GFP_KERNEL);
217 if (!rtd)
218 goto out;
219 rtd->dma_desc_array =
220 dma_alloc_writecombine(substream->pcm->card->dev, PAGE_SIZE,
221 &rtd->dma_desc_array_phys, GFP_KERNEL);
222 if (!rtd->dma_desc_array)
223 goto err1;
224 39
225 rtd->params = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? 40 rtd->params = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
226 client->playback_params : client->capture_params; 41 client->playback_params : client->capture_params;
@@ -230,17 +45,13 @@ static int pxa2xx_pcm_open(struct snd_pcm_substream *substream)
230 goto err2; 45 goto err2;
231 rtd->dma_ch = ret; 46 rtd->dma_ch = ret;
232 47
233 runtime->private_data = rtd;
234 ret = client->startup(substream); 48 ret = client->startup(substream);
235 if (!ret) 49 if (!ret)
236 goto out; 50 goto out;
237 51
238 pxa_free_dma(rtd->dma_ch); 52 pxa_free_dma(rtd->dma_ch);
239 err2: 53 err2:
240 dma_free_writecombine(substream->pcm->card->dev, PAGE_SIZE, 54 __pxa2xx_pcm_close(substream);
241 rtd->dma_desc_array, rtd->dma_desc_array_phys);
242 err1:
243 kfree(rtd);
244 out: 55 out:
245 return ret; 56 return ret;
246} 57}
@@ -252,69 +63,22 @@ static int pxa2xx_pcm_close(struct snd_pcm_substream *substream)
252 63
253 pxa_free_dma(rtd->dma_ch); 64 pxa_free_dma(rtd->dma_ch);
254 client->shutdown(substream); 65 client->shutdown(substream);
255 dma_free_writecombine(substream->pcm->card->dev, PAGE_SIZE,
256 rtd->dma_desc_array, rtd->dma_desc_array_phys);
257 kfree(rtd);
258 return 0;
259}
260 66
261static int 67 return __pxa2xx_pcm_close(substream);
262pxa2xx_pcm_mmap(struct snd_pcm_substream *substream, struct vm_area_struct *vma)
263{
264 struct snd_pcm_runtime *runtime = substream->runtime;
265 return dma_mmap_writecombine(substream->pcm->card->dev, vma,
266 runtime->dma_area,
267 runtime->dma_addr,
268 runtime->dma_bytes);
269} 68}
270 69
271static struct snd_pcm_ops pxa2xx_pcm_ops = { 70static struct snd_pcm_ops pxa2xx_pcm_ops = {
272 .open = pxa2xx_pcm_open, 71 .open = pxa2xx_pcm_open,
273 .close = pxa2xx_pcm_close, 72 .close = pxa2xx_pcm_close,
274 .ioctl = snd_pcm_lib_ioctl, 73 .ioctl = snd_pcm_lib_ioctl,
275 .hw_params = pxa2xx_pcm_hw_params, 74 .hw_params = __pxa2xx_pcm_hw_params,
276 .hw_free = pxa2xx_pcm_hw_free, 75 .hw_free = __pxa2xx_pcm_hw_free,
277 .prepare = pxa2xx_pcm_prepare, 76 .prepare = pxa2xx_pcm_prepare,
278 .trigger = pxa2xx_pcm_trigger, 77 .trigger = pxa2xx_pcm_trigger,
279 .pointer = pxa2xx_pcm_pointer, 78 .pointer = pxa2xx_pcm_pointer,
280 .mmap = pxa2xx_pcm_mmap, 79 .mmap = pxa2xx_pcm_mmap,
281}; 80};
282 81
283static int pxa2xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
284{
285 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
286 struct snd_dma_buffer *buf = &substream->dma_buffer;
287 size_t size = pxa2xx_pcm_hardware.buffer_bytes_max;
288 buf->dev.type = SNDRV_DMA_TYPE_DEV;
289 buf->dev.dev = pcm->card->dev;
290 buf->private_data = NULL;
291 buf->area = dma_alloc_writecombine(pcm->card->dev, size,
292 &buf->addr, GFP_KERNEL);
293 if (!buf->area)
294 return -ENOMEM;
295 buf->bytes = size;
296 return 0;
297}
298
299static void pxa2xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
300{
301 struct snd_pcm_substream *substream;
302 struct snd_dma_buffer *buf;
303 int stream;
304
305 for (stream = 0; stream < 2; stream++) {
306 substream = pcm->streams[stream].substream;
307 if (!substream)
308 continue;
309 buf = &substream->dma_buffer;
310 if (!buf->area)
311 continue;
312 dma_free_writecombine(pcm->card->dev, buf->bytes,
313 buf->area, buf->addr);
314 buf->area = NULL;
315 }
316}
317
318static u64 pxa2xx_pcm_dmamask = 0xffffffff; 82static u64 pxa2xx_pcm_dmamask = 0xffffffff;
319 83
320int pxa2xx_pcm_new(struct snd_card *card, struct pxa2xx_pcm_client *client, 84int pxa2xx_pcm_new(struct snd_card *card, struct pxa2xx_pcm_client *client,
diff --git a/sound/arm/pxa2xx-pcm.h b/sound/arm/pxa2xx-pcm.h
index b79f1e803780..5c4a4d38a083 100644
--- a/sound/arm/pxa2xx-pcm.h
+++ b/sound/arm/pxa2xx-pcm.h
@@ -9,14 +9,15 @@
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
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11 */ 11 */
12#include <asm/dma.h>
12 13
13struct pxa2xx_pcm_dma_params { 14struct pxa2xx_runtime_data {
14 char *name; /* stream identifier */ 15 int dma_ch;
15 u32 dcmd; /* DMA descriptor dcmd field */ 16 struct pxa2xx_pcm_dma_params *params;
16 volatile u32 *drcmr; /* the DMA request channel to use */ 17 pxa_dma_desc *dma_desc_array;
17 u32 dev_addr; /* device physical address for DMA */ 18 dma_addr_t dma_desc_array_phys;
18}; 19};
19 20
20struct pxa2xx_pcm_client { 21struct pxa2xx_pcm_client {
21 struct pxa2xx_pcm_dma_params *playback_params; 22 struct pxa2xx_pcm_dma_params *playback_params;
22 struct pxa2xx_pcm_dma_params *capture_params; 23 struct pxa2xx_pcm_dma_params *capture_params;
diff --git a/sound/arm/sa11xx-uda1341.c b/sound/arm/sa11xx-uda1341.c
index b9c51bf8cd71..1dcd51d81d10 100644
--- a/sound/arm/sa11xx-uda1341.c
+++ b/sound/arm/sa11xx-uda1341.c
@@ -442,7 +442,8 @@ static void audio_process_dma(struct audio_stream *s)
442 442
443 /* we are requested to process synchronization DMA transfer */ 443 /* we are requested to process synchronization DMA transfer */
444 if (s->tx_spin) { 444 if (s->tx_spin) {
445 snd_assert(s->stream_id == SNDRV_PCM_STREAM_PLAYBACK, return); 445 if (snd_BUG_ON(s->stream_id != SNDRV_PCM_STREAM_PLAYBACK))
446 return;
446 /* fill the xmit dma buffers and return */ 447 /* fill the xmit dma buffers and return */
447#ifdef HH_VERSION 448#ifdef HH_VERSION
448 sa1100_dma_set_spin(s->dmach, FORCE_CLOCK_ADDR, FORCE_CLOCK_SIZE); 449 sa1100_dma_set_spin(s->dmach, FORCE_CLOCK_ADDR, FORCE_CLOCK_SIZE);
@@ -472,7 +473,7 @@ static void audio_process_dma(struct audio_stream *s)
472 continue; /* special case */ 473 continue; /* special case */
473 } else { 474 } else {
474 offset = dma_size * s->period; 475 offset = dma_size * s->period;
475 snd_assert(dma_size <= DMA_BUF_SIZE, ); 476 snd_BUG_ON(dma_size > DMA_BUF_SIZE);
476 } 477 }
477#ifdef HH_VERSION 478#ifdef HH_VERSION
478 ret = sa1100_dma_queue_buffer(s->dmach, s, runtime->dma_addr + offset, dma_size); 479 ret = sa1100_dma_queue_buffer(s->dmach, s, runtime->dma_addr + offset, dma_size);
@@ -879,7 +880,7 @@ void snd_sa11xx_uda1341_free(struct snd_card *card)
879 audio_dma_free(&chip->s[SNDRV_PCM_STREAM_CAPTURE]); 880 audio_dma_free(&chip->s[SNDRV_PCM_STREAM_CAPTURE]);
880} 881}
881 882
882static int __init sa11xx_uda1341_probe(struct platform_device *devptr) 883static int __devinit sa11xx_uda1341_probe(struct platform_device *devptr)
883{ 884{
884 int err; 885 int err;
885 struct snd_card *card; 886 struct snd_card *card;
diff --git a/sound/core/Kconfig b/sound/core/Kconfig
index 335d45ecde6a..66348c92f88d 100644
--- a/sound/core/Kconfig
+++ b/sound/core/Kconfig
@@ -12,6 +12,12 @@ config SND_HWDEP
12config SND_RAWMIDI 12config SND_RAWMIDI
13 tristate 13 tristate
14 14
15# To be effective this also requires INPUT - users should say:
16# select SND_JACK if INPUT=y || INPUT=SND
17# to avoid having to force INPUT on.
18config SND_JACK
19 bool
20
15config SND_SEQUENCER 21config SND_SEQUENCER
16 tristate "Sequencer support" 22 tristate "Sequencer support"
17 select SND_TIMER 23 select SND_TIMER
@@ -38,6 +44,7 @@ config SND_SEQ_DUMMY
38 will be called snd-seq-dummy. 44 will be called snd-seq-dummy.
39 45
40config SND_OSSEMUL 46config SND_OSSEMUL
47 select SOUND_OSS_CORE
41 bool 48 bool
42 49
43config SND_MIXER_OSS 50config SND_MIXER_OSS
@@ -101,6 +108,9 @@ config SND_RTCTIMER
101 To compile this driver as a module, choose M here: the module 108 To compile this driver as a module, choose M here: the module
102 will be called snd-rtctimer. 109 will be called snd-rtctimer.
103 110
111 Note that this option is exclusive with the new RTC drivers
112 (CONFIG_RTC_CLASS) since this requires the old API.
113
104config SND_SEQ_RTCTIMER_DEFAULT 114config SND_SEQ_RTCTIMER_DEFAULT
105 bool "Use RTC as default sequencer timer" 115 bool "Use RTC as default sequencer timer"
106 depends on SND_RTCTIMER && SND_SEQUENCER 116 depends on SND_RTCTIMER && SND_SEQUENCER
diff --git a/sound/core/Makefile b/sound/core/Makefile
index da8e685eef9c..d57125a5687d 100644
--- a/sound/core/Makefile
+++ b/sound/core/Makefile
@@ -7,6 +7,7 @@ snd-y := sound.o init.o memory.o info.o control.o misc.o device.o
7snd-$(CONFIG_ISA_DMA_API) += isadma.o 7snd-$(CONFIG_ISA_DMA_API) += isadma.o
8snd-$(CONFIG_SND_OSSEMUL) += sound_oss.o info_oss.o 8snd-$(CONFIG_SND_OSSEMUL) += sound_oss.o info_oss.o
9snd-$(CONFIG_SND_VMASTER) += vmaster.o 9snd-$(CONFIG_SND_VMASTER) += vmaster.o
10snd-$(CONFIG_SND_JACK) += jack.o
10 11
11snd-pcm-objs := pcm.o pcm_native.o pcm_lib.o pcm_timer.o pcm_misc.o \ 12snd-pcm-objs := pcm.o pcm_native.o pcm_lib.o pcm_timer.o pcm_misc.o \
12 pcm_memory.o 13 pcm_memory.o
diff --git a/sound/core/control.c b/sound/core/control.c
index 281b2e2ef0ea..6d71f9a7ccbb 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -139,7 +139,8 @@ void snd_ctl_notify(struct snd_card *card, unsigned int mask,
139 struct snd_ctl_file *ctl; 139 struct snd_ctl_file *ctl;
140 struct snd_kctl_event *ev; 140 struct snd_kctl_event *ev;
141 141
142 snd_assert(card != NULL && id != NULL, return); 142 if (snd_BUG_ON(!card || !id))
143 return;
143 read_lock(&card->ctl_files_rwlock); 144 read_lock(&card->ctl_files_rwlock);
144#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE) 145#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
145 card->mixer_oss_change_count++; 146 card->mixer_oss_change_count++;
@@ -188,8 +189,8 @@ static struct snd_kcontrol *snd_ctl_new(struct snd_kcontrol *control,
188 struct snd_kcontrol *kctl; 189 struct snd_kcontrol *kctl;
189 unsigned int idx; 190 unsigned int idx;
190 191
191 snd_assert(control != NULL, return NULL); 192 if (snd_BUG_ON(!control || !control->count))
192 snd_assert(control->count > 0, return NULL); 193 return NULL;
193 kctl = kzalloc(sizeof(*kctl) + sizeof(struct snd_kcontrol_volatile) * control->count, GFP_KERNEL); 194 kctl = kzalloc(sizeof(*kctl) + sizeof(struct snd_kcontrol_volatile) * control->count, GFP_KERNEL);
194 if (kctl == NULL) { 195 if (kctl == NULL) {
195 snd_printk(KERN_ERR "Cannot allocate control instance\n"); 196 snd_printk(KERN_ERR "Cannot allocate control instance\n");
@@ -218,8 +219,8 @@ struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new *ncontrol,
218 struct snd_kcontrol kctl; 219 struct snd_kcontrol kctl;
219 unsigned int access; 220 unsigned int access;
220 221
221 snd_assert(ncontrol != NULL, return NULL); 222 if (snd_BUG_ON(!ncontrol || !ncontrol->info))
222 snd_assert(ncontrol->info != NULL, return NULL); 223 return NULL;
223 memset(&kctl, 0, sizeof(kctl)); 224 memset(&kctl, 0, sizeof(kctl));
224 kctl.id.iface = ncontrol->iface; 225 kctl.id.iface = ncontrol->iface;
225 kctl.id.device = ncontrol->device; 226 kctl.id.device = ncontrol->device;
@@ -315,8 +316,8 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol)
315 316
316 if (! kcontrol) 317 if (! kcontrol)
317 return err; 318 return err;
318 snd_assert(card != NULL, goto error); 319 if (snd_BUG_ON(!card || !kcontrol->info))
319 snd_assert(kcontrol->info != NULL, goto error); 320 goto error;
320 id = kcontrol->id; 321 id = kcontrol->id;
321 down_write(&card->controls_rwsem); 322 down_write(&card->controls_rwsem);
322 if (snd_ctl_find_id(card, &id)) { 323 if (snd_ctl_find_id(card, &id)) {
@@ -367,7 +368,8 @@ int snd_ctl_remove(struct snd_card *card, struct snd_kcontrol *kcontrol)
367 struct snd_ctl_elem_id id; 368 struct snd_ctl_elem_id id;
368 unsigned int idx; 369 unsigned int idx;
369 370
370 snd_assert(card != NULL && kcontrol != NULL, return -EINVAL); 371 if (snd_BUG_ON(!card || !kcontrol))
372 return -EINVAL;
371 list_del(&kcontrol->list); 373 list_del(&kcontrol->list);
372 card->controls_count -= kcontrol->count; 374 card->controls_count -= kcontrol->count;
373 id = kcontrol->id; 375 id = kcontrol->id;
@@ -487,7 +489,8 @@ struct snd_kcontrol *snd_ctl_find_numid(struct snd_card *card, unsigned int numi
487{ 489{
488 struct snd_kcontrol *kctl; 490 struct snd_kcontrol *kctl;
489 491
490 snd_assert(card != NULL && numid != 0, return NULL); 492 if (snd_BUG_ON(!card || !numid))
493 return NULL;
491 list_for_each_entry(kctl, &card->controls, list) { 494 list_for_each_entry(kctl, &card->controls, list) {
492 if (kctl->id.numid <= numid && kctl->id.numid + kctl->count > numid) 495 if (kctl->id.numid <= numid && kctl->id.numid + kctl->count > numid)
493 return kctl; 496 return kctl;
@@ -514,7 +517,8 @@ struct snd_kcontrol *snd_ctl_find_id(struct snd_card *card,
514{ 517{
515 struct snd_kcontrol *kctl; 518 struct snd_kcontrol *kctl;
516 519
517 snd_assert(card != NULL && id != NULL, return NULL); 520 if (snd_BUG_ON(!card || !id))
521 return NULL;
518 if (id->numid != 0) 522 if (id->numid != 0)
519 return snd_ctl_find_numid(card, id->numid); 523 return snd_ctl_find_numid(card, id->numid);
520 list_for_each_entry(kctl, &card->controls, list) { 524 list_for_each_entry(kctl, &card->controls, list) {
@@ -647,7 +651,7 @@ static int snd_ctl_elem_info(struct snd_ctl_file *ctl,
647#endif 651#endif
648 result = kctl->info(kctl, info); 652 result = kctl->info(kctl, info);
649 if (result >= 0) { 653 if (result >= 0) {
650 snd_assert(info->access == 0, ); 654 snd_BUG_ON(info->access);
651 index_offset = snd_ctl_get_ioff(kctl, &info->id); 655 index_offset = snd_ctl_get_ioff(kctl, &info->id);
652 vd = &kctl->vd[index_offset]; 656 vd = &kctl->vd[index_offset];
653 snd_ctl_build_ioff(&info->id, kctl, index_offset); 657 snd_ctl_build_ioff(&info->id, kctl, index_offset);
@@ -1160,7 +1164,8 @@ static long snd_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg
1160 1164
1161 ctl = file->private_data; 1165 ctl = file->private_data;
1162 card = ctl->card; 1166 card = ctl->card;
1163 snd_assert(card != NULL, return -ENXIO); 1167 if (snd_BUG_ON(!card))
1168 return -ENXIO;
1164 switch (cmd) { 1169 switch (cmd) {
1165 case SNDRV_CTL_IOCTL_PVERSION: 1170 case SNDRV_CTL_IOCTL_PVERSION:
1166 return put_user(SNDRV_CTL_VERSION, ip) ? -EFAULT : 0; 1171 return put_user(SNDRV_CTL_VERSION, ip) ? -EFAULT : 0;
@@ -1222,7 +1227,8 @@ static ssize_t snd_ctl_read(struct file *file, char __user *buffer,
1222 ssize_t result = 0; 1227 ssize_t result = 0;
1223 1228
1224 ctl = file->private_data; 1229 ctl = file->private_data;
1225 snd_assert(ctl != NULL && ctl->card != NULL, return -ENXIO); 1230 if (snd_BUG_ON(!ctl || !ctl->card))
1231 return -ENXIO;
1226 if (!ctl->subscribed) 1232 if (!ctl->subscribed)
1227 return -EBADFD; 1233 return -EBADFD;
1228 if (count < sizeof(struct snd_ctl_event)) 1234 if (count < sizeof(struct snd_ctl_event))
@@ -1328,7 +1334,8 @@ static int _snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn,
1328{ 1334{
1329 struct snd_kctl_ioctl *p; 1335 struct snd_kctl_ioctl *p;
1330 1336
1331 snd_assert(fcn != NULL, return -EINVAL); 1337 if (snd_BUG_ON(!fcn))
1338 return -EINVAL;
1332 down_write(&snd_ioctl_rwsem); 1339 down_write(&snd_ioctl_rwsem);
1333 list_for_each_entry(p, lists, list) { 1340 list_for_each_entry(p, lists, list) {
1334 if (p->fioctl == fcn) { 1341 if (p->fioctl == fcn) {
@@ -1404,9 +1411,11 @@ static int snd_ctl_dev_register(struct snd_device *device)
1404 int err, cardnum; 1411 int err, cardnum;
1405 char name[16]; 1412 char name[16];
1406 1413
1407 snd_assert(card != NULL, return -ENXIO); 1414 if (snd_BUG_ON(!card))
1415 return -ENXIO;
1408 cardnum = card->number; 1416 cardnum = card->number;
1409 snd_assert(cardnum >= 0 && cardnum < SNDRV_CARDS, return -ENXIO); 1417 if (snd_BUG_ON(cardnum < 0 || cardnum >= SNDRV_CARDS))
1418 return -ENXIO;
1410 sprintf(name, "controlC%i", cardnum); 1419 sprintf(name, "controlC%i", cardnum);
1411 if ((err = snd_register_device(SNDRV_DEVICE_TYPE_CONTROL, card, -1, 1420 if ((err = snd_register_device(SNDRV_DEVICE_TYPE_CONTROL, card, -1,
1412 &snd_ctl_f_ops, card, name)) < 0) 1421 &snd_ctl_f_ops, card, name)) < 0)
@@ -1423,16 +1432,18 @@ static int snd_ctl_dev_disconnect(struct snd_device *device)
1423 struct snd_ctl_file *ctl; 1432 struct snd_ctl_file *ctl;
1424 int err, cardnum; 1433 int err, cardnum;
1425 1434
1426 snd_assert(card != NULL, return -ENXIO); 1435 if (snd_BUG_ON(!card))
1436 return -ENXIO;
1427 cardnum = card->number; 1437 cardnum = card->number;
1428 snd_assert(cardnum >= 0 && cardnum < SNDRV_CARDS, return -ENXIO); 1438 if (snd_BUG_ON(cardnum < 0 || cardnum >= SNDRV_CARDS))
1439 return -ENXIO;
1429 1440
1430 down_read(&card->controls_rwsem); 1441 read_lock(&card->ctl_files_rwlock);
1431 list_for_each_entry(ctl, &card->ctl_files, list) { 1442 list_for_each_entry(ctl, &card->ctl_files, list) {
1432 wake_up(&ctl->change_sleep); 1443 wake_up(&ctl->change_sleep);
1433 kill_fasync(&ctl->fasync, SIGIO, POLL_ERR); 1444 kill_fasync(&ctl->fasync, SIGIO, POLL_ERR);
1434 } 1445 }
1435 up_read(&card->controls_rwsem); 1446 read_unlock(&card->ctl_files_rwlock);
1436 1447
1437 if ((err = snd_unregister_device(SNDRV_DEVICE_TYPE_CONTROL, 1448 if ((err = snd_unregister_device(SNDRV_DEVICE_TYPE_CONTROL,
1438 card, -1)) < 0) 1449 card, -1)) < 0)
@@ -1469,7 +1480,8 @@ int snd_ctl_create(struct snd_card *card)
1469 .dev_disconnect = snd_ctl_dev_disconnect, 1480 .dev_disconnect = snd_ctl_dev_disconnect,
1470 }; 1481 };
1471 1482
1472 snd_assert(card != NULL, return -ENXIO); 1483 if (snd_BUG_ON(!card))
1484 return -ENXIO;
1473 return snd_device_new(card, SNDRV_DEV_CONTROL, card, &ops); 1485 return snd_device_new(card, SNDRV_DEV_CONTROL, card, &ops);
1474} 1486}
1475 1487
diff --git a/sound/core/control_compat.c b/sound/core/control_compat.c
index 6101259ad860..368dc9c4aef8 100644
--- a/sound/core/control_compat.c
+++ b/sound/core/control_compat.c
@@ -398,7 +398,8 @@ static inline long snd_ctl_ioctl_compat(struct file *file, unsigned int cmd, uns
398 int err; 398 int err;
399 399
400 ctl = file->private_data; 400 ctl = file->private_data;
401 snd_assert(ctl && ctl->card, return -ENXIO); 401 if (snd_BUG_ON(!ctl || !ctl->card))
402 return -ENXIO;
402 403
403 switch (cmd) { 404 switch (cmd) {
404 case SNDRV_CTL_IOCTL_PVERSION: 405 case SNDRV_CTL_IOCTL_PVERSION:
diff --git a/sound/core/device.c b/sound/core/device.c
index 202dac0e4d89..c58d8227254c 100644
--- a/sound/core/device.c
+++ b/sound/core/device.c
@@ -45,9 +45,8 @@ int snd_device_new(struct snd_card *card, snd_device_type_t type,
45{ 45{
46 struct snd_device *dev; 46 struct snd_device *dev;
47 47
48 snd_assert(card != NULL, return -ENXIO); 48 if (snd_BUG_ON(!card || !device_data || !ops))
49 snd_assert(device_data != NULL, return -ENXIO); 49 return -ENXIO;
50 snd_assert(ops != NULL, return -ENXIO);
51 dev = kzalloc(sizeof(*dev), GFP_KERNEL); 50 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
52 if (dev == NULL) { 51 if (dev == NULL) {
53 snd_printk(KERN_ERR "Cannot allocate device\n"); 52 snd_printk(KERN_ERR "Cannot allocate device\n");
@@ -80,8 +79,8 @@ int snd_device_free(struct snd_card *card, void *device_data)
80{ 79{
81 struct snd_device *dev; 80 struct snd_device *dev;
82 81
83 snd_assert(card != NULL, return -ENXIO); 82 if (snd_BUG_ON(!card || !device_data))
84 snd_assert(device_data != NULL, return -ENXIO); 83 return -ENXIO;
85 list_for_each_entry(dev, &card->devices, list) { 84 list_for_each_entry(dev, &card->devices, list) {
86 if (dev->device_data != device_data) 85 if (dev->device_data != device_data)
87 continue; 86 continue;
@@ -123,8 +122,8 @@ int snd_device_disconnect(struct snd_card *card, void *device_data)
123{ 122{
124 struct snd_device *dev; 123 struct snd_device *dev;
125 124
126 snd_assert(card != NULL, return -ENXIO); 125 if (snd_BUG_ON(!card || !device_data))
127 snd_assert(device_data != NULL, return -ENXIO); 126 return -ENXIO;
128 list_for_each_entry(dev, &card->devices, list) { 127 list_for_each_entry(dev, &card->devices, list) {
129 if (dev->device_data != device_data) 128 if (dev->device_data != device_data)
130 continue; 129 continue;
@@ -159,8 +158,8 @@ int snd_device_register(struct snd_card *card, void *device_data)
159 struct snd_device *dev; 158 struct snd_device *dev;
160 int err; 159 int err;
161 160
162 snd_assert(card != NULL, return -ENXIO); 161 if (snd_BUG_ON(!card || !device_data))
163 snd_assert(device_data != NULL, return -ENXIO); 162 return -ENXIO;
164 list_for_each_entry(dev, &card->devices, list) { 163 list_for_each_entry(dev, &card->devices, list) {
165 if (dev->device_data != device_data) 164 if (dev->device_data != device_data)
166 continue; 165 continue;
@@ -188,7 +187,8 @@ int snd_device_register_all(struct snd_card *card)
188 struct snd_device *dev; 187 struct snd_device *dev;
189 int err; 188 int err;
190 189
191 snd_assert(card != NULL, return -ENXIO); 190 if (snd_BUG_ON(!card))
191 return -ENXIO;
192 list_for_each_entry(dev, &card->devices, list) { 192 list_for_each_entry(dev, &card->devices, list) {
193 if (dev->state == SNDRV_DEV_BUILD && dev->ops->dev_register) { 193 if (dev->state == SNDRV_DEV_BUILD && dev->ops->dev_register) {
194 if ((err = dev->ops->dev_register(dev)) < 0) 194 if ((err = dev->ops->dev_register(dev)) < 0)
@@ -208,7 +208,8 @@ int snd_device_disconnect_all(struct snd_card *card)
208 struct snd_device *dev; 208 struct snd_device *dev;
209 int err = 0; 209 int err = 0;
210 210
211 snd_assert(card != NULL, return -ENXIO); 211 if (snd_BUG_ON(!card))
212 return -ENXIO;
212 list_for_each_entry(dev, &card->devices, list) { 213 list_for_each_entry(dev, &card->devices, list) {
213 if (snd_device_disconnect(card, dev->device_data) < 0) 214 if (snd_device_disconnect(card, dev->device_data) < 0)
214 err = -ENXIO; 215 err = -ENXIO;
@@ -226,7 +227,8 @@ int snd_device_free_all(struct snd_card *card, snd_device_cmd_t cmd)
226 int err; 227 int err;
227 unsigned int range_low, range_high; 228 unsigned int range_low, range_high;
228 229
229 snd_assert(card != NULL, return -ENXIO); 230 if (snd_BUG_ON(!card))
231 return -ENXIO;
230 range_low = cmd * SNDRV_DEV_TYPE_RANGE_SIZE; 232 range_low = cmd * SNDRV_DEV_TYPE_RANGE_SIZE;
231 range_high = range_low + SNDRV_DEV_TYPE_RANGE_SIZE - 1; 233 range_high = range_low + SNDRV_DEV_TYPE_RANGE_SIZE - 1;
232 __again: 234 __again:
diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c
index 6d6589f93899..195cafc5a553 100644
--- a/sound/core/hwdep.c
+++ b/sound/core/hwdep.c
@@ -353,9 +353,10 @@ int snd_hwdep_new(struct snd_card *card, char *id, int device,
353 .dev_disconnect = snd_hwdep_dev_disconnect, 353 .dev_disconnect = snd_hwdep_dev_disconnect,
354 }; 354 };
355 355
356 snd_assert(rhwdep != NULL, return -EINVAL); 356 if (snd_BUG_ON(!card))
357 *rhwdep = NULL; 357 return -ENXIO;
358 snd_assert(card != NULL, return -ENXIO); 358 if (rhwdep)
359 *rhwdep = NULL;
359 hwdep = kzalloc(sizeof(*hwdep), GFP_KERNEL); 360 hwdep = kzalloc(sizeof(*hwdep), GFP_KERNEL);
360 if (hwdep == NULL) { 361 if (hwdep == NULL) {
361 snd_printk(KERN_ERR "hwdep: cannot allocate\n"); 362 snd_printk(KERN_ERR "hwdep: cannot allocate\n");
@@ -374,13 +375,15 @@ int snd_hwdep_new(struct snd_card *card, char *id, int device,
374 } 375 }
375 init_waitqueue_head(&hwdep->open_wait); 376 init_waitqueue_head(&hwdep->open_wait);
376 mutex_init(&hwdep->open_mutex); 377 mutex_init(&hwdep->open_mutex);
377 *rhwdep = hwdep; 378 if (rhwdep)
379 *rhwdep = hwdep;
378 return 0; 380 return 0;
379} 381}
380 382
381static int snd_hwdep_free(struct snd_hwdep *hwdep) 383static int snd_hwdep_free(struct snd_hwdep *hwdep)
382{ 384{
383 snd_assert(hwdep != NULL, return -ENXIO); 385 if (!hwdep)
386 return 0;
384 if (hwdep->private_free) 387 if (hwdep->private_free)
385 hwdep->private_free(hwdep); 388 hwdep->private_free(hwdep);
386 kfree(hwdep); 389 kfree(hwdep);
@@ -440,7 +443,8 @@ static int snd_hwdep_dev_disconnect(struct snd_device *device)
440{ 443{
441 struct snd_hwdep *hwdep = device->device_data; 444 struct snd_hwdep *hwdep = device->device_data;
442 445
443 snd_assert(hwdep != NULL, return -ENXIO); 446 if (snd_BUG_ON(!hwdep))
447 return -ENXIO;
444 mutex_lock(&register_mutex); 448 mutex_lock(&register_mutex);
445 if (snd_hwdep_search(hwdep->card, hwdep->device) != hwdep) { 449 if (snd_hwdep_search(hwdep->card, hwdep->device) != hwdep) {
446 mutex_unlock(&register_mutex); 450 mutex_unlock(&register_mutex);
diff --git a/sound/core/info.c b/sound/core/info.c
index c67773ad9298..527b207462b0 100644
--- a/sound/core/info.c
+++ b/sound/core/info.c
@@ -217,7 +217,8 @@ static ssize_t snd_info_entry_read(struct file *file, char __user *buffer,
217 loff_t pos; 217 loff_t pos;
218 218
219 data = file->private_data; 219 data = file->private_data;
220 snd_assert(data != NULL, return -ENXIO); 220 if (snd_BUG_ON(!data))
221 return -ENXIO;
221 pos = *offset; 222 pos = *offset;
222 if (pos < 0 || (long) pos != pos || (ssize_t) count < 0) 223 if (pos < 0 || (long) pos != pos || (ssize_t) count < 0)
223 return -EIO; 224 return -EIO;
@@ -258,7 +259,8 @@ static ssize_t snd_info_entry_write(struct file *file, const char __user *buffer
258 loff_t pos; 259 loff_t pos;
259 260
260 data = file->private_data; 261 data = file->private_data;
261 snd_assert(data != NULL, return -ENXIO); 262 if (snd_BUG_ON(!data))
263 return -ENXIO;
262 entry = data->entry; 264 entry = data->entry;
263 pos = *offset; 265 pos = *offset;
264 if (pos < 0 || (long) pos != pos || (ssize_t) count < 0) 266 if (pos < 0 || (long) pos != pos || (ssize_t) count < 0)
@@ -614,7 +616,8 @@ int snd_info_card_create(struct snd_card *card)
614 char str[8]; 616 char str[8];
615 struct snd_info_entry *entry; 617 struct snd_info_entry *entry;
616 618
617 snd_assert(card != NULL, return -ENXIO); 619 if (snd_BUG_ON(!card))
620 return -ENXIO;
618 621
619 sprintf(str, "card%i", card->number); 622 sprintf(str, "card%i", card->number);
620 if ((entry = snd_info_create_module_entry(card->module, str, NULL)) == NULL) 623 if ((entry = snd_info_create_module_entry(card->module, str, NULL)) == NULL)
@@ -636,7 +639,8 @@ int snd_info_card_register(struct snd_card *card)
636{ 639{
637 struct proc_dir_entry *p; 640 struct proc_dir_entry *p;
638 641
639 snd_assert(card != NULL, return -ENXIO); 642 if (snd_BUG_ON(!card))
643 return -ENXIO;
640 644
641 if (!strcmp(card->id, card->proc_root->name)) 645 if (!strcmp(card->id, card->proc_root->name))
642 return 0; 646 return 0;
@@ -654,7 +658,8 @@ int snd_info_card_register(struct snd_card *card)
654 */ 658 */
655void snd_info_card_disconnect(struct snd_card *card) 659void snd_info_card_disconnect(struct snd_card *card)
656{ 660{
657 snd_assert(card != NULL, return); 661 if (!card)
662 return;
658 mutex_lock(&info_mutex); 663 mutex_lock(&info_mutex);
659 if (card->proc_root_link) { 664 if (card->proc_root_link) {
660 snd_remove_proc_entry(snd_proc_root, card->proc_root_link); 665 snd_remove_proc_entry(snd_proc_root, card->proc_root_link);
@@ -671,7 +676,8 @@ void snd_info_card_disconnect(struct snd_card *card)
671 */ 676 */
672int snd_info_card_free(struct snd_card *card) 677int snd_info_card_free(struct snd_card *card)
673{ 678{
674 snd_assert(card != NULL, return -ENXIO); 679 if (!card)
680 return 0;
675 snd_info_free_entry(card->proc_root); 681 snd_info_free_entry(card->proc_root);
676 card->proc_root = NULL; 682 card->proc_root = NULL;
677 return 0; 683 return 0;
@@ -849,7 +855,7 @@ static void snd_info_disconnect(struct snd_info_entry *entry)
849 return; 855 return;
850 list_del_init(&entry->list); 856 list_del_init(&entry->list);
851 root = entry->parent == NULL ? snd_proc_root : entry->parent->p; 857 root = entry->parent == NULL ? snd_proc_root : entry->parent->p;
852 snd_assert(root, return); 858 snd_BUG_ON(!root);
853 snd_remove_proc_entry(root, entry->p); 859 snd_remove_proc_entry(root, entry->p);
854 entry->p = NULL; 860 entry->p = NULL;
855} 861}
@@ -947,7 +953,8 @@ int snd_info_register(struct snd_info_entry * entry)
947{ 953{
948 struct proc_dir_entry *root, *p = NULL; 954 struct proc_dir_entry *root, *p = NULL;
949 955
950 snd_assert(entry != NULL, return -ENXIO); 956 if (snd_BUG_ON(!entry))
957 return -ENXIO;
951 root = entry->parent == NULL ? snd_proc_root : entry->parent->p; 958 root = entry->parent == NULL ? snd_proc_root : entry->parent->p;
952 mutex_lock(&info_mutex); 959 mutex_lock(&info_mutex);
953 p = snd_create_proc_entry(entry->name, entry->mode, root); 960 p = snd_create_proc_entry(entry->name, entry->mode, root);
diff --git a/sound/core/info_oss.c b/sound/core/info_oss.c
index e35789a92752..e4af138d651a 100644
--- a/sound/core/info_oss.c
+++ b/sound/core/info_oss.c
@@ -43,8 +43,10 @@ int snd_oss_info_register(int dev, int num, char *string)
43{ 43{
44 char *x; 44 char *x;
45 45
46 snd_assert(dev >= 0 && dev < SNDRV_OSS_INFO_DEV_COUNT, return -ENXIO); 46 if (snd_BUG_ON(dev < 0 || dev >= SNDRV_OSS_INFO_DEV_COUNT))
47 snd_assert(num >= 0 && num < SNDRV_CARDS, return -ENXIO); 47 return -ENXIO;
48 if (snd_BUG_ON(num < 0 || num >= SNDRV_CARDS))
49 return -ENXIO;
48 mutex_lock(&strings); 50 mutex_lock(&strings);
49 if (string == NULL) { 51 if (string == NULL) {
50 if ((x = snd_sndstat_strings[num][dev]) != NULL) { 52 if ((x = snd_sndstat_strings[num][dev]) != NULL) {
diff --git a/sound/core/init.c b/sound/core/init.c
index df46bbc25dc2..8af467df9245 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -545,7 +545,8 @@ int snd_card_register(struct snd_card *card)
545{ 545{
546 int err; 546 int err;
547 547
548 snd_assert(card != NULL, return -EINVAL); 548 if (snd_BUG_ON(!card))
549 return -EINVAL;
549#ifndef CONFIG_SYSFS_DEPRECATED 550#ifndef CONFIG_SYSFS_DEPRECATED
550 if (!card->card_dev) { 551 if (!card->card_dev) {
551 card->card_dev = device_create_drvdata(sound_class, card->dev, 552 card->card_dev = device_create_drvdata(sound_class, card->dev,
diff --git a/sound/core/jack.c b/sound/core/jack.c
new file mode 100644
index 000000000000..8133a2b173a5
--- /dev/null
+++ b/sound/core/jack.c
@@ -0,0 +1,163 @@
1/*
2 * Jack abstraction layer
3 *
4 * Copyright 2008 Wolfson Microelectronics
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
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22#include <linux/input.h>
23#include <sound/jack.h>
24#include <sound/core.h>
25
26static int snd_jack_dev_free(struct snd_device *device)
27{
28 struct snd_jack *jack = device->device_data;
29
30 /* If the input device is registered with the input subsystem
31 * then we need to use a different deallocator. */
32 if (jack->registered)
33 input_unregister_device(jack->input_dev);
34 else
35 input_free_device(jack->input_dev);
36
37 kfree(jack);
38
39 return 0;
40}
41
42static int snd_jack_dev_register(struct snd_device *device)
43{
44 struct snd_jack *jack = device->device_data;
45 struct snd_card *card = device->card;
46 int err;
47
48 snprintf(jack->name, sizeof(jack->name), "%s %s",
49 card->longname, jack->id);
50 jack->input_dev->name = jack->name;
51
52 /* Default to the sound card device. */
53 if (!jack->input_dev->dev.parent)
54 jack->input_dev->dev.parent = card->dev;
55
56 err = input_register_device(jack->input_dev);
57 if (err == 0)
58 jack->registered = 1;
59
60 return err;
61}
62
63/**
64 * snd_jack_new - Create a new jack
65 * @card: the card instance
66 * @id: an identifying string for this jack
67 * @type: a bitmask of enum snd_jack_type values that can be detected by
68 * this jack
69 * @jjack: Used to provide the allocated jack object to the caller.
70 *
71 * Creates a new jack object.
72 *
73 * Returns zero if successful, or a negative error code on failure.
74 * On success jjack will be initialised.
75 */
76int snd_jack_new(struct snd_card *card, const char *id, int type,
77 struct snd_jack **jjack)
78{
79 struct snd_jack *jack;
80 int err;
81 static struct snd_device_ops ops = {
82 .dev_free = snd_jack_dev_free,
83 .dev_register = snd_jack_dev_register,
84 };
85
86 jack = kzalloc(sizeof(struct snd_jack), GFP_KERNEL);
87 if (jack == NULL)
88 return -ENOMEM;
89
90 jack->id = id;
91
92 jack->input_dev = input_allocate_device();
93 if (jack->input_dev == NULL) {
94 err = -ENOMEM;
95 goto fail_input;
96 }
97
98 jack->input_dev->phys = "ALSA";
99
100 jack->type = type;
101
102 if (type & SND_JACK_HEADPHONE)
103 input_set_capability(jack->input_dev, EV_SW,
104 SW_HEADPHONE_INSERT);
105 if (type & SND_JACK_MICROPHONE)
106 input_set_capability(jack->input_dev, EV_SW,
107 SW_MICROPHONE_INSERT);
108
109 err = snd_device_new(card, SNDRV_DEV_JACK, jack, &ops);
110 if (err < 0)
111 goto fail_input;
112
113 *jjack = jack;
114
115 return 0;
116
117fail_input:
118 input_free_device(jack->input_dev);
119 kfree(jack);
120 return err;
121}
122EXPORT_SYMBOL(snd_jack_new);
123
124/**
125 * snd_jack_set_parent - Set the parent device for a jack
126 *
127 * @jack: The jack to configure
128 * @parent: The device to set as parent for the jack.
129 *
130 * Set the parent for the jack input device in the device tree. This
131 * function is only valid prior to registration of the jack. If no
132 * parent is configured then the parent device will be the sound card.
133 */
134void snd_jack_set_parent(struct snd_jack *jack, struct device *parent)
135{
136 WARN_ON(jack->registered);
137
138 jack->input_dev->dev.parent = parent;
139}
140EXPORT_SYMBOL(snd_jack_set_parent);
141
142/**
143 * snd_jack_report - Report the current status of a jack
144 *
145 * @jack: The jack to report status for
146 * @status: The current status of the jack
147 */
148void snd_jack_report(struct snd_jack *jack, int status)
149{
150 if (jack->type & SND_JACK_HEADPHONE)
151 input_report_switch(jack->input_dev, SW_HEADPHONE_INSERT,
152 status & SND_JACK_HEADPHONE);
153 if (jack->type & SND_JACK_MICROPHONE)
154 input_report_switch(jack->input_dev, SW_MICROPHONE_INSERT,
155 status & SND_JACK_MICROPHONE);
156
157 input_sync(jack->input_dev);
158}
159EXPORT_SYMBOL(snd_jack_report);
160
161MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
162MODULE_DESCRIPTION("Jack detection support for ALSA");
163MODULE_LICENSE("GPL");
diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c
index f5d6d8d12979..1b3534d67686 100644
--- a/sound/core/memalloc.c
+++ b/sound/core/memalloc.c
@@ -33,9 +33,6 @@
33#include <linux/moduleparam.h> 33#include <linux/moduleparam.h>
34#include <linux/mutex.h> 34#include <linux/mutex.h>
35#include <sound/memalloc.h> 35#include <sound/memalloc.h>
36#ifdef CONFIG_SBUS
37#include <asm/sbus.h>
38#endif
39 36
40 37
41MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>, Jaroslav Kysela <perex@perex.cz>"); 38MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>, Jaroslav Kysela <perex@perex.cz>");
@@ -46,14 +43,6 @@ MODULE_LICENSE("GPL");
46/* 43/*
47 */ 44 */
48 45
49void *snd_malloc_sgbuf_pages(struct device *device,
50 size_t size, struct snd_dma_buffer *dmab,
51 size_t *res_size);
52int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab);
53
54/*
55 */
56
57static DEFINE_MUTEX(list_mutex); 46static DEFINE_MUTEX(list_mutex);
58static LIST_HEAD(mem_list_head); 47static LIST_HEAD(mem_list_head);
59 48
@@ -67,18 +56,6 @@ struct snd_mem_list {
67/* id for pre-allocated buffers */ 56/* id for pre-allocated buffers */
68#define SNDRV_DMA_DEVICE_UNUSED (unsigned int)-1 57#define SNDRV_DMA_DEVICE_UNUSED (unsigned int)-1
69 58
70#ifdef CONFIG_SND_DEBUG
71#define __ASTRING__(x) #x
72#define snd_assert(expr, args...) do {\
73 if (!(expr)) {\
74 printk(KERN_ERR "snd-malloc: BUG? (%s) (called from %p)\n", __ASTRING__(expr), __builtin_return_address(0));\
75 args;\
76 }\
77} while (0)
78#else
79#define snd_assert(expr, args...) /**/
80#endif
81
82/* 59/*
83 * 60 *
84 * Generic memory allocators 61 * Generic memory allocators
@@ -111,8 +88,10 @@ void *snd_malloc_pages(size_t size, gfp_t gfp_flags)
111 int pg; 88 int pg;
112 void *res; 89 void *res;
113 90
114 snd_assert(size > 0, return NULL); 91 if (WARN_ON(!size))
115 snd_assert(gfp_flags != 0, return NULL); 92 return NULL;
93 if (WARN_ON(!gfp_flags))
94 return NULL;
116 gfp_flags |= __GFP_COMP; /* compound page lets parts be mapped */ 95 gfp_flags |= __GFP_COMP; /* compound page lets parts be mapped */
117 pg = get_order(size); 96 pg = get_order(size);
118 if ((res = (void *) __get_free_pages(gfp_flags, pg)) != NULL) 97 if ((res = (void *) __get_free_pages(gfp_flags, pg)) != NULL)
@@ -152,8 +131,8 @@ static void *snd_malloc_dev_pages(struct device *dev, size_t size, dma_addr_t *d
152 void *res; 131 void *res;
153 gfp_t gfp_flags; 132 gfp_t gfp_flags;
154 133
155 snd_assert(size > 0, return NULL); 134 if (WARN_ON(!dma))
156 snd_assert(dma != NULL, return NULL); 135 return NULL;
157 pg = get_order(size); 136 pg = get_order(size);
158 gfp_flags = GFP_KERNEL 137 gfp_flags = GFP_KERNEL
159 | __GFP_COMP /* compound page lets parts be mapped */ 138 | __GFP_COMP /* compound page lets parts be mapped */
@@ -180,39 +159,6 @@ static void snd_free_dev_pages(struct device *dev, size_t size, void *ptr,
180} 159}
181#endif /* CONFIG_HAS_DMA */ 160#endif /* CONFIG_HAS_DMA */
182 161
183#ifdef CONFIG_SBUS
184
185static void *snd_malloc_sbus_pages(struct device *dev, size_t size,
186 dma_addr_t *dma_addr)
187{
188 struct sbus_dev *sdev = (struct sbus_dev *)dev;
189 int pg;
190 void *res;
191
192 snd_assert(size > 0, return NULL);
193 snd_assert(dma_addr != NULL, return NULL);
194 pg = get_order(size);
195 res = sbus_alloc_consistent(sdev, PAGE_SIZE * (1 << pg), dma_addr);
196 if (res != NULL)
197 inc_snd_pages(pg);
198 return res;
199}
200
201static void snd_free_sbus_pages(struct device *dev, size_t size,
202 void *ptr, dma_addr_t dma_addr)
203{
204 struct sbus_dev *sdev = (struct sbus_dev *)dev;
205 int pg;
206
207 if (ptr == NULL)
208 return;
209 pg = get_order(size);
210 dec_snd_pages(pg);
211 sbus_free_consistent(sdev, PAGE_SIZE * (1 << pg), ptr, dma_addr);
212}
213
214#endif /* CONFIG_SBUS */
215
216/* 162/*
217 * 163 *
218 * ALSA generic memory management 164 * ALSA generic memory management
@@ -236,8 +182,10 @@ static void snd_free_sbus_pages(struct device *dev, size_t size,
236int snd_dma_alloc_pages(int type, struct device *device, size_t size, 182int snd_dma_alloc_pages(int type, struct device *device, size_t size,
237 struct snd_dma_buffer *dmab) 183 struct snd_dma_buffer *dmab)
238{ 184{
239 snd_assert(size > 0, return -ENXIO); 185 if (WARN_ON(!size))
240 snd_assert(dmab != NULL, return -ENXIO); 186 return -ENXIO;
187 if (WARN_ON(!dmab))
188 return -ENXIO;
241 189
242 dmab->dev.type = type; 190 dmab->dev.type = type;
243 dmab->dev.dev = device; 191 dmab->dev.dev = device;
@@ -247,11 +195,6 @@ int snd_dma_alloc_pages(int type, struct device *device, size_t size,
247 dmab->area = snd_malloc_pages(size, (unsigned long)device); 195 dmab->area = snd_malloc_pages(size, (unsigned long)device);
248 dmab->addr = 0; 196 dmab->addr = 0;
249 break; 197 break;
250#ifdef CONFIG_SBUS
251 case SNDRV_DMA_TYPE_SBUS:
252 dmab->area = snd_malloc_sbus_pages(device, size, &dmab->addr);
253 break;
254#endif
255#ifdef CONFIG_HAS_DMA 198#ifdef CONFIG_HAS_DMA
256 case SNDRV_DMA_TYPE_DEV: 199 case SNDRV_DMA_TYPE_DEV:
257 dmab->area = snd_malloc_dev_pages(device, size, &dmab->addr); 200 dmab->area = snd_malloc_dev_pages(device, size, &dmab->addr);
@@ -292,15 +235,17 @@ int snd_dma_alloc_pages_fallback(int type, struct device *device, size_t size,
292{ 235{
293 int err; 236 int err;
294 237
295 snd_assert(size > 0, return -ENXIO);
296 snd_assert(dmab != NULL, return -ENXIO);
297
298 while ((err = snd_dma_alloc_pages(type, device, size, dmab)) < 0) { 238 while ((err = snd_dma_alloc_pages(type, device, size, dmab)) < 0) {
239 size_t aligned_size;
299 if (err != -ENOMEM) 240 if (err != -ENOMEM)
300 return err; 241 return err;
301 size >>= 1;
302 if (size <= PAGE_SIZE) 242 if (size <= PAGE_SIZE)
303 return -ENOMEM; 243 return -ENOMEM;
244 aligned_size = PAGE_SIZE << get_order(size);
245 if (size != aligned_size)
246 size = aligned_size;
247 else
248 size >>= 1;
304 } 249 }
305 if (! dmab->area) 250 if (! dmab->area)
306 return -ENOMEM; 251 return -ENOMEM;
@@ -320,11 +265,6 @@ void snd_dma_free_pages(struct snd_dma_buffer *dmab)
320 case SNDRV_DMA_TYPE_CONTINUOUS: 265 case SNDRV_DMA_TYPE_CONTINUOUS:
321 snd_free_pages(dmab->area, dmab->bytes); 266 snd_free_pages(dmab->area, dmab->bytes);
322 break; 267 break;
323#ifdef CONFIG_SBUS
324 case SNDRV_DMA_TYPE_SBUS:
325 snd_free_sbus_pages(dmab->dev.dev, dmab->bytes, dmab->area, dmab->addr);
326 break;
327#endif
328#ifdef CONFIG_HAS_DMA 268#ifdef CONFIG_HAS_DMA
329 case SNDRV_DMA_TYPE_DEV: 269 case SNDRV_DMA_TYPE_DEV:
330 snd_free_dev_pages(dmab->dev.dev, dmab->bytes, dmab->area, dmab->addr); 270 snd_free_dev_pages(dmab->dev.dev, dmab->bytes, dmab->area, dmab->addr);
@@ -353,7 +293,8 @@ size_t snd_dma_get_reserved_buf(struct snd_dma_buffer *dmab, unsigned int id)
353{ 293{
354 struct snd_mem_list *mem; 294 struct snd_mem_list *mem;
355 295
356 snd_assert(dmab, return 0); 296 if (WARN_ON(!dmab))
297 return 0;
357 298
358 mutex_lock(&list_mutex); 299 mutex_lock(&list_mutex);
359 list_for_each_entry(mem, &mem_list_head, list) { 300 list_for_each_entry(mem, &mem_list_head, list) {
@@ -387,7 +328,8 @@ int snd_dma_reserve_buf(struct snd_dma_buffer *dmab, unsigned int id)
387{ 328{
388 struct snd_mem_list *mem; 329 struct snd_mem_list *mem;
389 330
390 snd_assert(dmab, return -EINVAL); 331 if (WARN_ON(!dmab))
332 return -EINVAL;
391 mem = kmalloc(sizeof(*mem), GFP_KERNEL); 333 mem = kmalloc(sizeof(*mem), GFP_KERNEL);
392 if (! mem) 334 if (! mem)
393 return -ENOMEM; 335 return -ENOMEM;
@@ -431,7 +373,7 @@ static int snd_mem_proc_read(struct seq_file *seq, void *offset)
431 long pages = snd_allocated_pages >> (PAGE_SHIFT-12); 373 long pages = snd_allocated_pages >> (PAGE_SHIFT-12);
432 struct snd_mem_list *mem; 374 struct snd_mem_list *mem;
433 int devno; 375 int devno;
434 static char *types[] = { "UNKNOWN", "CONT", "DEV", "DEV-SG", "SBUS" }; 376 static char *types[] = { "UNKNOWN", "CONT", "DEV", "DEV-SG" };
435 377
436 mutex_lock(&list_mutex); 378 mutex_lock(&list_mutex);
437 seq_printf(seq, "pages : %li bytes (%li pages per %likB)\n", 379 seq_printf(seq, "pages : %li bytes (%li pages per %likB)\n",
diff --git a/sound/core/oss/copy.c b/sound/core/oss/copy.c
index 9ded30d0e97d..05b58d4fc2b7 100644
--- a/sound/core/oss/copy.c
+++ b/sound/core/oss/copy.c
@@ -32,17 +32,18 @@ static snd_pcm_sframes_t copy_transfer(struct snd_pcm_plugin *plugin,
32 unsigned int channel; 32 unsigned int channel;
33 unsigned int nchannels; 33 unsigned int nchannels;
34 34
35 snd_assert(plugin != NULL && src_channels != NULL && dst_channels != NULL, return -ENXIO); 35 if (snd_BUG_ON(!plugin || !src_channels || !dst_channels))
36 return -ENXIO;
36 if (frames == 0) 37 if (frames == 0)
37 return 0; 38 return 0;
38 nchannels = plugin->src_format.channels; 39 nchannels = plugin->src_format.channels;
39 for (channel = 0; channel < nchannels; channel++) { 40 for (channel = 0; channel < nchannels; channel++) {
40 snd_assert(src_channels->area.first % 8 == 0 && 41 if (snd_BUG_ON(src_channels->area.first % 8 ||
41 src_channels->area.step % 8 == 0, 42 src_channels->area.step % 8))
42 return -ENXIO); 43 return -ENXIO;
43 snd_assert(dst_channels->area.first % 8 == 0 && 44 if (snd_BUG_ON(dst_channels->area.first % 8 ||
44 dst_channels->area.step % 8 == 0, 45 dst_channels->area.step % 8))
45 return -ENXIO); 46 return -ENXIO;
46 if (!src_channels->enabled) { 47 if (!src_channels->enabled) {
47 if (dst_channels->wanted) 48 if (dst_channels->wanted)
48 snd_pcm_area_silence(&dst_channels->area, 0, frames, plugin->dst_format.format); 49 snd_pcm_area_silence(&dst_channels->area, 0, frames, plugin->dst_format.format);
@@ -66,15 +67,20 @@ int snd_pcm_plugin_build_copy(struct snd_pcm_substream *plug,
66 struct snd_pcm_plugin *plugin; 67 struct snd_pcm_plugin *plugin;
67 int width; 68 int width;
68 69
69 snd_assert(r_plugin != NULL, return -ENXIO); 70 if (snd_BUG_ON(!r_plugin))
71 return -ENXIO;
70 *r_plugin = NULL; 72 *r_plugin = NULL;
71 73
72 snd_assert(src_format->format == dst_format->format, return -ENXIO); 74 if (snd_BUG_ON(src_format->format != dst_format->format))
73 snd_assert(src_format->rate == dst_format->rate, return -ENXIO); 75 return -ENXIO;
74 snd_assert(src_format->channels == dst_format->channels, return -ENXIO); 76 if (snd_BUG_ON(src_format->rate != dst_format->rate))
77 return -ENXIO;
78 if (snd_BUG_ON(src_format->channels != dst_format->channels))
79 return -ENXIO;
75 80
76 width = snd_pcm_format_physical_width(src_format->format); 81 width = snd_pcm_format_physical_width(src_format->format);
77 snd_assert(width > 0, return -ENXIO); 82 if (snd_BUG_ON(width <= 0))
83 return -ENXIO;
78 84
79 err = snd_pcm_plugin_build(plug, "copy", src_format, dst_format, 85 err = snd_pcm_plugin_build(plug, "copy", src_format, dst_format,
80 0, &plugin); 86 0, &plugin);
diff --git a/sound/core/oss/io.c b/sound/core/oss/io.c
index f874f6ca3657..6faa1d719206 100644
--- a/sound/core/oss/io.c
+++ b/sound/core/oss/io.c
@@ -39,14 +39,17 @@ static snd_pcm_sframes_t io_playback_transfer(struct snd_pcm_plugin *plugin,
39 struct snd_pcm_plugin_channel *dst_channels, 39 struct snd_pcm_plugin_channel *dst_channels,
40 snd_pcm_uframes_t frames) 40 snd_pcm_uframes_t frames)
41{ 41{
42 snd_assert(plugin != NULL, return -ENXIO); 42 if (snd_BUG_ON(!plugin))
43 snd_assert(src_channels != NULL, return -ENXIO); 43 return -ENXIO;
44 if (snd_BUG_ON(!src_channels))
45 return -ENXIO;
44 if (plugin->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED) { 46 if (plugin->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED) {
45 return pcm_write(plugin->plug, src_channels->area.addr, frames); 47 return pcm_write(plugin->plug, src_channels->area.addr, frames);
46 } else { 48 } else {
47 int channel, channels = plugin->dst_format.channels; 49 int channel, channels = plugin->dst_format.channels;
48 void **bufs = (void**)plugin->extra_data; 50 void **bufs = (void**)plugin->extra_data;
49 snd_assert(bufs != NULL, return -ENXIO); 51 if (snd_BUG_ON(!bufs))
52 return -ENXIO;
50 for (channel = 0; channel < channels; channel++) { 53 for (channel = 0; channel < channels; channel++) {
51 if (src_channels[channel].enabled) 54 if (src_channels[channel].enabled)
52 bufs[channel] = src_channels[channel].area.addr; 55 bufs[channel] = src_channels[channel].area.addr;
@@ -62,14 +65,17 @@ static snd_pcm_sframes_t io_capture_transfer(struct snd_pcm_plugin *plugin,
62 struct snd_pcm_plugin_channel *dst_channels, 65 struct snd_pcm_plugin_channel *dst_channels,
63 snd_pcm_uframes_t frames) 66 snd_pcm_uframes_t frames)
64{ 67{
65 snd_assert(plugin != NULL, return -ENXIO); 68 if (snd_BUG_ON(!plugin))
66 snd_assert(dst_channels != NULL, return -ENXIO); 69 return -ENXIO;
70 if (snd_BUG_ON(!dst_channels))
71 return -ENXIO;
67 if (plugin->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED) { 72 if (plugin->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED) {
68 return pcm_read(plugin->plug, dst_channels->area.addr, frames); 73 return pcm_read(plugin->plug, dst_channels->area.addr, frames);
69 } else { 74 } else {
70 int channel, channels = plugin->dst_format.channels; 75 int channel, channels = plugin->dst_format.channels;
71 void **bufs = (void**)plugin->extra_data; 76 void **bufs = (void**)plugin->extra_data;
72 snd_assert(bufs != NULL, return -ENXIO); 77 if (snd_BUG_ON(!bufs))
78 return -ENXIO;
73 for (channel = 0; channel < channels; channel++) { 79 for (channel = 0; channel < channels; channel++) {
74 if (dst_channels[channel].enabled) 80 if (dst_channels[channel].enabled)
75 bufs[channel] = dst_channels[channel].area.addr; 81 bufs[channel] = dst_channels[channel].area.addr;
@@ -107,9 +113,11 @@ int snd_pcm_plugin_build_io(struct snd_pcm_substream *plug,
107 struct snd_pcm_plugin_format format; 113 struct snd_pcm_plugin_format format;
108 struct snd_pcm_plugin *plugin; 114 struct snd_pcm_plugin *plugin;
109 115
110 snd_assert(r_plugin != NULL, return -ENXIO); 116 if (snd_BUG_ON(!r_plugin))
117 return -ENXIO;
111 *r_plugin = NULL; 118 *r_plugin = NULL;
112 snd_assert(plug != NULL && params != NULL, return -ENXIO); 119 if (snd_BUG_ON(!plug || !params))
120 return -ENXIO;
113 format.format = params_format(params); 121 format.format = params_format(params);
114 format.rate = params_rate(params); 122 format.rate = params_rate(params);
115 format.channels = params_channels(params); 123 format.channels = params_channels(params);
diff --git a/sound/core/oss/linear.c b/sound/core/oss/linear.c
index da3dbd41669e..4c1d16827199 100644
--- a/sound/core/oss/linear.c
+++ b/sound/core/oss/linear.c
@@ -92,7 +92,8 @@ static snd_pcm_sframes_t linear_transfer(struct snd_pcm_plugin *plugin,
92{ 92{
93 struct linear_priv *data; 93 struct linear_priv *data;
94 94
95 snd_assert(plugin != NULL && src_channels != NULL && dst_channels != NULL, return -ENXIO); 95 if (snd_BUG_ON(!plugin || !src_channels || !dst_channels))
96 return -ENXIO;
96 data = (struct linear_priv *)plugin->extra_data; 97 data = (struct linear_priv *)plugin->extra_data;
97 if (frames == 0) 98 if (frames == 0)
98 return 0; 99 return 0;
@@ -100,12 +101,12 @@ static snd_pcm_sframes_t linear_transfer(struct snd_pcm_plugin *plugin,
100 { 101 {
101 unsigned int channel; 102 unsigned int channel;
102 for (channel = 0; channel < plugin->src_format.channels; channel++) { 103 for (channel = 0; channel < plugin->src_format.channels; channel++) {
103 snd_assert(src_channels[channel].area.first % 8 == 0 && 104 if (snd_BUG_ON(src_channels[channel].area.first % 8 ||
104 src_channels[channel].area.step % 8 == 0, 105 src_channels[channel].area.step % 8))
105 return -ENXIO); 106 return -ENXIO;
106 snd_assert(dst_channels[channel].area.first % 8 == 0 && 107 if (snd_BUG_ON(dst_channels[channel].area.first % 8 ||
107 dst_channels[channel].area.step % 8 == 0, 108 dst_channels[channel].area.step % 8))
108 return -ENXIO); 109 return -ENXIO;
109 } 110 }
110 } 111 }
111#endif 112#endif
@@ -154,13 +155,17 @@ int snd_pcm_plugin_build_linear(struct snd_pcm_substream *plug,
154 struct linear_priv *data; 155 struct linear_priv *data;
155 struct snd_pcm_plugin *plugin; 156 struct snd_pcm_plugin *plugin;
156 157
157 snd_assert(r_plugin != NULL, return -ENXIO); 158 if (snd_BUG_ON(!r_plugin))
159 return -ENXIO;
158 *r_plugin = NULL; 160 *r_plugin = NULL;
159 161
160 snd_assert(src_format->rate == dst_format->rate, return -ENXIO); 162 if (snd_BUG_ON(src_format->rate != dst_format->rate))
161 snd_assert(src_format->channels == dst_format->channels, return -ENXIO); 163 return -ENXIO;
162 snd_assert(snd_pcm_format_linear(src_format->format) && 164 if (snd_BUG_ON(src_format->channels != dst_format->channels))
163 snd_pcm_format_linear(dst_format->format), return -ENXIO); 165 return -ENXIO;
166 if (snd_BUG_ON(!snd_pcm_format_linear(src_format->format) ||
167 !snd_pcm_format_linear(dst_format->format)))
168 return -ENXIO;
164 169
165 err = snd_pcm_plugin_build(plug, "linear format conversion", 170 err = snd_pcm_plugin_build(plug, "linear format conversion",
166 src_format, dst_format, 171 src_format, dst_format,
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
index 581aa2c60e65..4690b8b5681f 100644
--- a/sound/core/oss/mixer_oss.c
+++ b/sound/core/oss/mixer_oss.c
@@ -257,8 +257,10 @@ static int snd_mixer_oss_get_volume(struct snd_mixer_oss_file *fmixer, int slot)
257 result = pslot->get_volume(fmixer, pslot, &left, &right); 257 result = pslot->get_volume(fmixer, pslot, &left, &right);
258 if (!pslot->stereo) 258 if (!pslot->stereo)
259 right = left; 259 right = left;
260 snd_assert(left >= 0 && left <= 100, return -EIO); 260 if (snd_BUG_ON(left < 0 || left > 100))
261 snd_assert(right >= 0 && right <= 100, return -EIO); 261 return -EIO;
262 if (snd_BUG_ON(right < 0 || right > 100))
263 return -EIO;
262 if (result >= 0) { 264 if (result >= 0) {
263 pslot->volume[0] = left; 265 pslot->volume[0] = left;
264 pslot->volume[1] = right; 266 pslot->volume[1] = right;
@@ -298,7 +300,8 @@ static int snd_mixer_oss_ioctl1(struct snd_mixer_oss_file *fmixer, unsigned int
298 int __user *p = argp; 300 int __user *p = argp;
299 int tmp; 301 int tmp;
300 302
301 snd_assert(fmixer != NULL, return -ENXIO); 303 if (snd_BUG_ON(!fmixer))
304 return -ENXIO;
302 if (((cmd >> 8) & 0xff) == 'M') { 305 if (((cmd >> 8) & 0xff) == 'M') {
303 switch (cmd) { 306 switch (cmd) {
304 case SOUND_MIXER_INFO: 307 case SOUND_MIXER_INFO:
@@ -368,7 +371,8 @@ int snd_mixer_oss_ioctl_card(struct snd_card *card, unsigned int cmd, unsigned l
368{ 371{
369 struct snd_mixer_oss_file fmixer; 372 struct snd_mixer_oss_file fmixer;
370 373
371 snd_assert(card != NULL, return -ENXIO); 374 if (snd_BUG_ON(!card))
375 return -ENXIO;
372 if (card->mixer_oss == NULL) 376 if (card->mixer_oss == NULL)
373 return -ENXIO; 377 return -ENXIO;
374 memset(&fmixer, 0, sizeof(fmixer)); 378 memset(&fmixer, 0, sizeof(fmixer));
@@ -1284,9 +1288,11 @@ static int snd_mixer_oss_free1(void *private)
1284 struct snd_card *card; 1288 struct snd_card *card;
1285 int idx; 1289 int idx;
1286 1290
1287 snd_assert(mixer != NULL, return -ENXIO); 1291 if (!mixer)
1292 return 0;
1288 card = mixer->card; 1293 card = mixer->card;
1289 snd_assert(mixer == card->mixer_oss, return -ENXIO); 1294 if (snd_BUG_ON(mixer != card->mixer_oss))
1295 return -ENXIO;
1290 card->mixer_oss = NULL; 1296 card->mixer_oss = NULL;
1291 for (idx = 0; idx < SNDRV_OSS_MAX_MIXERS; idx++) { 1297 for (idx = 0; idx < SNDRV_OSS_MAX_MIXERS; idx++) {
1292 struct snd_mixer_oss_slot *chn = &mixer->slots[idx]; 1298 struct snd_mixer_oss_slot *chn = &mixer->slots[idx];
diff --git a/sound/core/oss/mulaw.c b/sound/core/oss/mulaw.c
index 77f96194a0ed..f7649d4d950b 100644
--- a/sound/core/oss/mulaw.c
+++ b/sound/core/oss/mulaw.c
@@ -252,19 +252,20 @@ static snd_pcm_sframes_t mulaw_transfer(struct snd_pcm_plugin *plugin,
252{ 252{
253 struct mulaw_priv *data; 253 struct mulaw_priv *data;
254 254
255 snd_assert(plugin != NULL && src_channels != NULL && dst_channels != NULL, return -ENXIO); 255 if (snd_BUG_ON(!plugin || !src_channels || !dst_channels))
256 return -ENXIO;
256 if (frames == 0) 257 if (frames == 0)
257 return 0; 258 return 0;
258#ifdef CONFIG_SND_DEBUG 259#ifdef CONFIG_SND_DEBUG
259 { 260 {
260 unsigned int channel; 261 unsigned int channel;
261 for (channel = 0; channel < plugin->src_format.channels; channel++) { 262 for (channel = 0; channel < plugin->src_format.channels; channel++) {
262 snd_assert(src_channels[channel].area.first % 8 == 0 && 263 if (snd_BUG_ON(src_channels[channel].area.first % 8 ||
263 src_channels[channel].area.step % 8 == 0, 264 src_channels[channel].area.step % 8))
264 return -ENXIO); 265 return -ENXIO;
265 snd_assert(dst_channels[channel].area.first % 8 == 0 && 266 if (snd_BUG_ON(dst_channels[channel].area.first % 8 ||
266 dst_channels[channel].area.step % 8 == 0, 267 dst_channels[channel].area.step % 8))
267 return -ENXIO); 268 return -ENXIO;
268 } 269 }
269 } 270 }
270#endif 271#endif
@@ -305,11 +306,14 @@ int snd_pcm_plugin_build_mulaw(struct snd_pcm_substream *plug,
305 struct snd_pcm_plugin_format *format; 306 struct snd_pcm_plugin_format *format;
306 mulaw_f func; 307 mulaw_f func;
307 308
308 snd_assert(r_plugin != NULL, return -ENXIO); 309 if (snd_BUG_ON(!r_plugin))
310 return -ENXIO;
309 *r_plugin = NULL; 311 *r_plugin = NULL;
310 312
311 snd_assert(src_format->rate == dst_format->rate, return -ENXIO); 313 if (snd_BUG_ON(src_format->rate != dst_format->rate))
312 snd_assert(src_format->channels == dst_format->channels, return -ENXIO); 314 return -ENXIO;
315 if (snd_BUG_ON(src_format->channels != dst_format->channels))
316 return -ENXIO;
313 317
314 if (dst_format->format == SNDRV_PCM_FORMAT_MU_LAW) { 318 if (dst_format->format == SNDRV_PCM_FORMAT_MU_LAW) {
315 format = src_format; 319 format = src_format;
@@ -323,7 +327,8 @@ int snd_pcm_plugin_build_mulaw(struct snd_pcm_substream *plug,
323 snd_BUG(); 327 snd_BUG();
324 return -EINVAL; 328 return -EINVAL;
325 } 329 }
326 snd_assert(snd_pcm_format_linear(format->format) != 0, return -ENXIO); 330 if (snd_BUG_ON(!snd_pcm_format_linear(format->format)))
331 return -ENXIO;
327 332
328 err = snd_pcm_plugin_build(plug, "Mu-Law<->linear conversion", 333 err = snd_pcm_plugin_build(plug, "Mu-Law<->linear conversion",
329 src_format, dst_format, 334 src_format, dst_format,
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index 4c601b192ddf..1af62b8b86c6 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -452,7 +452,8 @@ static int snd_pcm_hw_param_near(struct snd_pcm_substream *pcm,
452 } else { 452 } else {
453 *params = *save; 453 *params = *save;
454 max = snd_pcm_hw_param_max(pcm, params, var, max, &maxdir); 454 max = snd_pcm_hw_param_max(pcm, params, var, max, &maxdir);
455 snd_assert(max >= 0, return -EINVAL); 455 if (max < 0)
456 return max;
456 last = 1; 457 last = 1;
457 } 458 }
458 _end: 459 _end:
@@ -461,7 +462,7 @@ static int snd_pcm_hw_param_near(struct snd_pcm_substream *pcm,
461 v = snd_pcm_hw_param_last(pcm, params, var, dir); 462 v = snd_pcm_hw_param_last(pcm, params, var, dir);
462 else 463 else
463 v = snd_pcm_hw_param_first(pcm, params, var, dir); 464 v = snd_pcm_hw_param_first(pcm, params, var, dir);
464 snd_assert(v >= 0, return -EINVAL); 465 snd_BUG_ON(v < 0);
465 return v; 466 return v;
466} 467}
467 468
@@ -778,7 +779,8 @@ static int snd_pcm_oss_period_size(struct snd_pcm_substream *substream,
778 while (oss_period_size * oss_periods > oss_buffer_size) 779 while (oss_period_size * oss_periods > oss_buffer_size)
779 oss_period_size /= 2; 780 oss_period_size /= 2;
780 781
781 snd_assert(oss_period_size >= 16, return -EINVAL); 782 if (oss_period_size < 16)
783 return -EINVAL;
782 runtime->oss.period_bytes = oss_period_size; 784 runtime->oss.period_bytes = oss_period_size;
783 runtime->oss.period_frames = 1; 785 runtime->oss.period_frames = 1;
784 runtime->oss.periods = oss_periods; 786 runtime->oss.periods = oss_periods;
@@ -895,7 +897,8 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
895 } 897 }
896 } 898 }
897 err = _snd_pcm_hw_param_set(sparams, SNDRV_PCM_HW_PARAM_FORMAT, sformat, 0); 899 err = _snd_pcm_hw_param_set(sparams, SNDRV_PCM_HW_PARAM_FORMAT, sformat, 0);
898 snd_assert(err >= 0, goto failure); 900 if (err < 0)
901 goto failure;
899 902
900 if (direct) { 903 if (direct) {
901 memcpy(params, sparams, sizeof(*params)); 904 memcpy(params, sparams, sizeof(*params));
@@ -958,11 +961,13 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
958 961
959 n = snd_pcm_plug_slave_size(substream, runtime->oss.period_bytes / oss_frame_size); 962 n = snd_pcm_plug_slave_size(substream, runtime->oss.period_bytes / oss_frame_size);
960 err = snd_pcm_hw_param_near(substream, sparams, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, n, NULL); 963 err = snd_pcm_hw_param_near(substream, sparams, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, n, NULL);
961 snd_assert(err >= 0, goto failure); 964 if (err < 0)
965 goto failure;
962 966
963 err = snd_pcm_hw_param_near(substream, sparams, SNDRV_PCM_HW_PARAM_PERIODS, 967 err = snd_pcm_hw_param_near(substream, sparams, SNDRV_PCM_HW_PARAM_PERIODS,
964 runtime->oss.periods, NULL); 968 runtime->oss.periods, NULL);
965 snd_assert(err >= 0, goto failure); 969 if (err < 0)
970 goto failure;
966 971
967 snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL); 972 snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL);
968 973
@@ -1006,7 +1011,10 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
1006 1011
1007 runtime->oss.periods = params_periods(sparams); 1012 runtime->oss.periods = params_periods(sparams);
1008 oss_period_size = snd_pcm_plug_client_size(substream, params_period_size(sparams)); 1013 oss_period_size = snd_pcm_plug_client_size(substream, params_period_size(sparams));
1009 snd_assert(oss_period_size >= 0, err = -EINVAL; goto failure); 1014 if (oss_period_size < 0) {
1015 err = -EINVAL;
1016 goto failure;
1017 }
1010#ifdef CONFIG_SND_PCM_OSS_PLUGINS 1018#ifdef CONFIG_SND_PCM_OSS_PLUGINS
1011 if (runtime->oss.plugin_first) { 1019 if (runtime->oss.plugin_first) {
1012 err = snd_pcm_plug_alloc(substream, oss_period_size); 1020 err = snd_pcm_plug_alloc(substream, oss_period_size);
@@ -1017,7 +1025,10 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
1017 oss_period_size *= oss_frame_size; 1025 oss_period_size *= oss_frame_size;
1018 1026
1019 oss_buffer_size = oss_period_size * runtime->oss.periods; 1027 oss_buffer_size = oss_period_size * runtime->oss.periods;
1020 snd_assert(oss_buffer_size >= 0, err = -EINVAL; goto failure); 1028 if (oss_buffer_size < 0) {
1029 err = -EINVAL;
1030 goto failure;
1031 }
1021 1032
1022 runtime->oss.period_bytes = oss_period_size; 1033 runtime->oss.period_bytes = oss_period_size;
1023 runtime->oss.buffer_bytes = oss_buffer_size; 1034 runtime->oss.buffer_bytes = oss_buffer_size;
@@ -1069,7 +1080,8 @@ static int snd_pcm_oss_get_active_substream(struct snd_pcm_oss_file *pcm_oss_fil
1069 return err; 1080 return err;
1070 } 1081 }
1071 } 1082 }
1072 snd_assert(asubstream != NULL, return -EIO); 1083 if (!asubstream)
1084 return -EIO;
1073 if (r_substream) 1085 if (r_substream)
1074 *r_substream = asubstream; 1086 *r_substream = asubstream;
1075 return 0; 1087 return 0;
@@ -1764,7 +1776,8 @@ static int snd_pcm_oss_get_formats(struct snd_pcm_oss_file *pcm_oss_file)
1764 err = snd_pcm_hw_refine(substream, params); 1776 err = snd_pcm_hw_refine(substream, params);
1765 format_mask = *hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); 1777 format_mask = *hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
1766 kfree(params); 1778 kfree(params);
1767 snd_assert(err >= 0, return err); 1779 if (err < 0)
1780 return err;
1768 for (fmt = 0; fmt < 32; ++fmt) { 1781 for (fmt = 0; fmt < 32; ++fmt) {
1769 if (snd_mask_test(&format_mask, fmt)) { 1782 if (snd_mask_test(&format_mask, fmt)) {
1770 int f = snd_pcm_oss_format_to(fmt); 1783 int f = snd_pcm_oss_format_to(fmt);
@@ -2250,7 +2263,8 @@ static void snd_pcm_oss_init_substream(struct snd_pcm_substream *substream,
2250static int snd_pcm_oss_release_file(struct snd_pcm_oss_file *pcm_oss_file) 2263static int snd_pcm_oss_release_file(struct snd_pcm_oss_file *pcm_oss_file)
2251{ 2264{
2252 int cidx; 2265 int cidx;
2253 snd_assert(pcm_oss_file != NULL, return -ENXIO); 2266 if (!pcm_oss_file)
2267 return 0;
2254 for (cidx = 0; cidx < 2; ++cidx) { 2268 for (cidx = 0; cidx < 2; ++cidx) {
2255 struct snd_pcm_substream *substream = pcm_oss_file->streams[cidx]; 2269 struct snd_pcm_substream *substream = pcm_oss_file->streams[cidx];
2256 if (substream) 2270 if (substream)
@@ -2271,8 +2285,8 @@ static int snd_pcm_oss_open_file(struct file *file,
2271 struct snd_pcm_substream *substream; 2285 struct snd_pcm_substream *substream;
2272 unsigned int f_mode = file->f_mode; 2286 unsigned int f_mode = file->f_mode;
2273 2287
2274 snd_assert(rpcm_oss_file != NULL, return -EINVAL); 2288 if (rpcm_oss_file)
2275 *rpcm_oss_file = NULL; 2289 *rpcm_oss_file = NULL;
2276 2290
2277 pcm_oss_file = kzalloc(sizeof(*pcm_oss_file), GFP_KERNEL); 2291 pcm_oss_file = kzalloc(sizeof(*pcm_oss_file), GFP_KERNEL);
2278 if (pcm_oss_file == NULL) 2292 if (pcm_oss_file == NULL)
@@ -2312,7 +2326,8 @@ static int snd_pcm_oss_open_file(struct file *file,
2312 } 2326 }
2313 2327
2314 file->private_data = pcm_oss_file; 2328 file->private_data = pcm_oss_file;
2315 *rpcm_oss_file = pcm_oss_file; 2329 if (rpcm_oss_file)
2330 *rpcm_oss_file = pcm_oss_file;
2316 return 0; 2331 return 0;
2317} 2332}
2318 2333
@@ -2321,7 +2336,8 @@ static int snd_task_name(struct task_struct *task, char *name, size_t size)
2321{ 2336{
2322 unsigned int idx; 2337 unsigned int idx;
2323 2338
2324 snd_assert(task != NULL && name != NULL && size >= 2, return -EINVAL); 2339 if (snd_BUG_ON(!task || !name || size < 2))
2340 return -EINVAL;
2325 for (idx = 0; idx < sizeof(task->comm) && idx + 1 < size; idx++) 2341 for (idx = 0; idx < sizeof(task->comm) && idx + 1 < size; idx++)
2326 name[idx] = task->comm[idx]; 2342 name[idx] = task->comm[idx];
2327 name[idx] = '\0'; 2343 name[idx] = '\0';
@@ -2415,7 +2431,8 @@ static int snd_pcm_oss_release(struct inode *inode, struct file *file)
2415 substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK]; 2431 substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];
2416 if (substream == NULL) 2432 if (substream == NULL)
2417 substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE]; 2433 substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE];
2418 snd_assert(substream != NULL, return -ENXIO); 2434 if (snd_BUG_ON(!substream))
2435 return -ENXIO;
2419 pcm = substream->pcm; 2436 pcm = substream->pcm;
2420 if (!pcm->card->shutdown) 2437 if (!pcm->card->shutdown)
2421 snd_pcm_oss_sync(pcm_oss_file); 2438 snd_pcm_oss_sync(pcm_oss_file);
@@ -2448,7 +2465,8 @@ static long snd_pcm_oss_ioctl(struct file *file, unsigned int cmd, unsigned long
2448 if (substream != NULL) 2465 if (substream != NULL)
2449 break; 2466 break;
2450 } 2467 }
2451 snd_assert(substream != NULL, return -ENXIO); 2468 if (snd_BUG_ON(idx >= 2))
2469 return -ENXIO;
2452 return snd_mixer_oss_ioctl_card(substream->pcm->card, cmd, arg); 2470 return snd_mixer_oss_ioctl_card(substream->pcm->card, cmd, arg);
2453 } 2471 }
2454#endif 2472#endif
diff --git a/sound/core/oss/pcm_plugin.c b/sound/core/oss/pcm_plugin.c
index bec94138205e..6751daa3bb50 100644
--- a/sound/core/oss/pcm_plugin.c
+++ b/sound/core/oss/pcm_plugin.c
@@ -62,7 +62,8 @@ static int snd_pcm_plugin_alloc(struct snd_pcm_plugin *plugin, snd_pcm_uframes_t
62 if ((width = snd_pcm_format_physical_width(format->format)) < 0) 62 if ((width = snd_pcm_format_physical_width(format->format)) < 0)
63 return width; 63 return width;
64 size = frames * format->channels * width; 64 size = frames * format->channels * width;
65 snd_assert((size % 8) == 0, return -ENXIO); 65 if (snd_BUG_ON(size % 8))
66 return -ENXIO;
66 size /= 8; 67 size /= 8;
67 if (plugin->buf_frames < frames) { 68 if (plugin->buf_frames < frames) {
68 vfree(plugin->buf); 69 vfree(plugin->buf);
@@ -84,7 +85,8 @@ static int snd_pcm_plugin_alloc(struct snd_pcm_plugin *plugin, snd_pcm_uframes_t
84 c->area.step = format->channels * width; 85 c->area.step = format->channels * width;
85 } 86 }
86 } else if (plugin->access == SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) { 87 } else if (plugin->access == SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) {
87 snd_assert((size % format->channels) == 0,); 88 if (snd_BUG_ON(size % format->channels))
89 return -EINVAL;
88 size /= format->channels; 90 size /= format->channels;
89 for (channel = 0; channel < format->channels; channel++, c++) { 91 for (channel = 0; channel < format->channels; channel++, c++) {
90 c->frames = frames; 92 c->frames = frames;
@@ -102,13 +104,15 @@ static int snd_pcm_plugin_alloc(struct snd_pcm_plugin *plugin, snd_pcm_uframes_t
102int snd_pcm_plug_alloc(struct snd_pcm_substream *plug, snd_pcm_uframes_t frames) 104int snd_pcm_plug_alloc(struct snd_pcm_substream *plug, snd_pcm_uframes_t frames)
103{ 105{
104 int err; 106 int err;
105 snd_assert(snd_pcm_plug_first(plug) != NULL, return -ENXIO); 107 if (snd_BUG_ON(!snd_pcm_plug_first(plug)))
108 return -ENXIO;
106 if (snd_pcm_plug_stream(plug) == SNDRV_PCM_STREAM_PLAYBACK) { 109 if (snd_pcm_plug_stream(plug) == SNDRV_PCM_STREAM_PLAYBACK) {
107 struct snd_pcm_plugin *plugin = snd_pcm_plug_first(plug); 110 struct snd_pcm_plugin *plugin = snd_pcm_plug_first(plug);
108 while (plugin->next) { 111 while (plugin->next) {
109 if (plugin->dst_frames) 112 if (plugin->dst_frames)
110 frames = plugin->dst_frames(plugin, frames); 113 frames = plugin->dst_frames(plugin, frames);
111 snd_assert(frames > 0, return -ENXIO); 114 if (snd_BUG_ON(frames <= 0))
115 return -ENXIO;
112 plugin = plugin->next; 116 plugin = plugin->next;
113 err = snd_pcm_plugin_alloc(plugin, frames); 117 err = snd_pcm_plugin_alloc(plugin, frames);
114 if (err < 0) 118 if (err < 0)
@@ -119,7 +123,8 @@ int snd_pcm_plug_alloc(struct snd_pcm_substream *plug, snd_pcm_uframes_t frames)
119 while (plugin->prev) { 123 while (plugin->prev) {
120 if (plugin->src_frames) 124 if (plugin->src_frames)
121 frames = plugin->src_frames(plugin, frames); 125 frames = plugin->src_frames(plugin, frames);
122 snd_assert(frames > 0, return -ENXIO); 126 if (snd_BUG_ON(frames <= 0))
127 return -ENXIO;
123 plugin = plugin->prev; 128 plugin = plugin->prev;
124 err = snd_pcm_plugin_alloc(plugin, frames); 129 err = snd_pcm_plugin_alloc(plugin, frames);
125 if (err < 0) 130 if (err < 0)
@@ -148,8 +153,10 @@ int snd_pcm_plugin_build(struct snd_pcm_substream *plug,
148 struct snd_pcm_plugin *plugin; 153 struct snd_pcm_plugin *plugin;
149 unsigned int channels; 154 unsigned int channels;
150 155
151 snd_assert(plug != NULL, return -ENXIO); 156 if (snd_BUG_ON(!plug))
152 snd_assert(src_format != NULL && dst_format != NULL, return -ENXIO); 157 return -ENXIO;
158 if (snd_BUG_ON(!src_format || !dst_format))
159 return -ENXIO;
153 plugin = kzalloc(sizeof(*plugin) + extra, GFP_KERNEL); 160 plugin = kzalloc(sizeof(*plugin) + extra, GFP_KERNEL);
154 if (plugin == NULL) 161 if (plugin == NULL)
155 return -ENOMEM; 162 return -ENOMEM;
@@ -159,10 +166,10 @@ int snd_pcm_plugin_build(struct snd_pcm_substream *plug,
159 plugin->access = SNDRV_PCM_ACCESS_RW_INTERLEAVED; 166 plugin->access = SNDRV_PCM_ACCESS_RW_INTERLEAVED;
160 plugin->src_format = *src_format; 167 plugin->src_format = *src_format;
161 plugin->src_width = snd_pcm_format_physical_width(src_format->format); 168 plugin->src_width = snd_pcm_format_physical_width(src_format->format);
162 snd_assert(plugin->src_width > 0, ); 169 snd_BUG_ON(plugin->src_width <= 0);
163 plugin->dst_format = *dst_format; 170 plugin->dst_format = *dst_format;
164 plugin->dst_width = snd_pcm_format_physical_width(dst_format->format); 171 plugin->dst_width = snd_pcm_format_physical_width(dst_format->format);
165 snd_assert(plugin->dst_width > 0, ); 172 snd_BUG_ON(plugin->dst_width <= 0);
166 if (plugin->stream == SNDRV_PCM_STREAM_PLAYBACK) 173 if (plugin->stream == SNDRV_PCM_STREAM_PLAYBACK)
167 channels = src_format->channels; 174 channels = src_format->channels;
168 else 175 else
@@ -194,7 +201,8 @@ snd_pcm_sframes_t snd_pcm_plug_client_size(struct snd_pcm_substream *plug, snd_p
194 struct snd_pcm_plugin *plugin, *plugin_prev, *plugin_next; 201 struct snd_pcm_plugin *plugin, *plugin_prev, *plugin_next;
195 int stream = snd_pcm_plug_stream(plug); 202 int stream = snd_pcm_plug_stream(plug);
196 203
197 snd_assert(plug != NULL, return -ENXIO); 204 if (snd_BUG_ON(!plug))
205 return -ENXIO;
198 if (drv_frames == 0) 206 if (drv_frames == 0)
199 return 0; 207 return 0;
200 if (stream == SNDRV_PCM_STREAM_PLAYBACK) { 208 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
@@ -224,7 +232,8 @@ snd_pcm_sframes_t snd_pcm_plug_slave_size(struct snd_pcm_substream *plug, snd_pc
224 snd_pcm_sframes_t frames; 232 snd_pcm_sframes_t frames;
225 int stream = snd_pcm_plug_stream(plug); 233 int stream = snd_pcm_plug_stream(plug);
226 234
227 snd_assert(plug != NULL, return -ENXIO); 235 if (snd_BUG_ON(!plug))
236 return -ENXIO;
228 if (clt_frames == 0) 237 if (clt_frames == 0)
229 return 0; 238 return 0;
230 frames = clt_frames; 239 frames = clt_frames;
@@ -540,7 +549,8 @@ snd_pcm_sframes_t snd_pcm_plug_client_channels_buf(struct snd_pcm_substream *plu
540 int width, nchannels, channel; 549 int width, nchannels, channel;
541 int stream = snd_pcm_plug_stream(plug); 550 int stream = snd_pcm_plug_stream(plug);
542 551
543 snd_assert(buf != NULL, return -ENXIO); 552 if (snd_BUG_ON(!buf))
553 return -ENXIO;
544 if (stream == SNDRV_PCM_STREAM_PLAYBACK) { 554 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
545 plugin = snd_pcm_plug_first(plug); 555 plugin = snd_pcm_plug_first(plug);
546 format = &plugin->src_format; 556 format = &plugin->src_format;
@@ -553,7 +563,9 @@ snd_pcm_sframes_t snd_pcm_plug_client_channels_buf(struct snd_pcm_substream *plu
553 if ((width = snd_pcm_format_physical_width(format->format)) < 0) 563 if ((width = snd_pcm_format_physical_width(format->format)) < 0)
554 return width; 564 return width;
555 nchannels = format->channels; 565 nchannels = format->channels;
556 snd_assert(plugin->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED || format->channels <= 1, return -ENXIO); 566 if (snd_BUG_ON(plugin->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED &&
567 format->channels > 1))
568 return -ENXIO;
557 for (channel = 0; channel < nchannels; channel++, v++) { 569 for (channel = 0; channel < nchannels; channel++, v++) {
558 v->frames = count; 570 v->frames = count;
559 v->enabled = 1; 571 v->enabled = 1;
diff --git a/sound/core/oss/rate.c b/sound/core/oss/rate.c
index 14dfb3175d84..a466443c4a26 100644
--- a/sound/core/oss/rate.c
+++ b/sound/core/oss/rate.c
@@ -185,7 +185,8 @@ static snd_pcm_sframes_t rate_src_frames(struct snd_pcm_plugin *plugin, snd_pcm_
185 struct rate_priv *data; 185 struct rate_priv *data;
186 snd_pcm_sframes_t res; 186 snd_pcm_sframes_t res;
187 187
188 snd_assert(plugin != NULL, return -ENXIO); 188 if (snd_BUG_ON(!plugin))
189 return -ENXIO;
189 if (frames == 0) 190 if (frames == 0)
190 return 0; 191 return 0;
191 data = (struct rate_priv *)plugin->extra_data; 192 data = (struct rate_priv *)plugin->extra_data;
@@ -217,7 +218,8 @@ static snd_pcm_sframes_t rate_dst_frames(struct snd_pcm_plugin *plugin, snd_pcm_
217 struct rate_priv *data; 218 struct rate_priv *data;
218 snd_pcm_sframes_t res; 219 snd_pcm_sframes_t res;
219 220
220 snd_assert(plugin != NULL, return -ENXIO); 221 if (snd_BUG_ON(!plugin))
222 return -ENXIO;
221 if (frames == 0) 223 if (frames == 0)
222 return 0; 224 return 0;
223 data = (struct rate_priv *)plugin->extra_data; 225 data = (struct rate_priv *)plugin->extra_data;
@@ -252,19 +254,20 @@ static snd_pcm_sframes_t rate_transfer(struct snd_pcm_plugin *plugin,
252 snd_pcm_uframes_t dst_frames; 254 snd_pcm_uframes_t dst_frames;
253 struct rate_priv *data; 255 struct rate_priv *data;
254 256
255 snd_assert(plugin != NULL && src_channels != NULL && dst_channels != NULL, return -ENXIO); 257 if (snd_BUG_ON(!plugin || !src_channels || !dst_channels))
258 return -ENXIO;
256 if (frames == 0) 259 if (frames == 0)
257 return 0; 260 return 0;
258#ifdef CONFIG_SND_DEBUG 261#ifdef CONFIG_SND_DEBUG
259 { 262 {
260 unsigned int channel; 263 unsigned int channel;
261 for (channel = 0; channel < plugin->src_format.channels; channel++) { 264 for (channel = 0; channel < plugin->src_format.channels; channel++) {
262 snd_assert(src_channels[channel].area.first % 8 == 0 && 265 if (snd_BUG_ON(src_channels[channel].area.first % 8 ||
263 src_channels[channel].area.step % 8 == 0, 266 src_channels[channel].area.step % 8))
264 return -ENXIO); 267 return -ENXIO;
265 snd_assert(dst_channels[channel].area.first % 8 == 0 && 268 if (snd_BUG_ON(dst_channels[channel].area.first % 8 ||
266 dst_channels[channel].area.step % 8 == 0, 269 dst_channels[channel].area.step % 8))
267 return -ENXIO); 270 return -ENXIO;
268 } 271 }
269 } 272 }
270#endif 273#endif
@@ -281,7 +284,8 @@ static int rate_action(struct snd_pcm_plugin *plugin,
281 enum snd_pcm_plugin_action action, 284 enum snd_pcm_plugin_action action,
282 unsigned long udata) 285 unsigned long udata)
283{ 286{
284 snd_assert(plugin != NULL, return -ENXIO); 287 if (snd_BUG_ON(!plugin))
288 return -ENXIO;
285 switch (action) { 289 switch (action) {
286 case INIT: 290 case INIT:
287 case PREPARE: 291 case PREPARE:
@@ -302,14 +306,20 @@ int snd_pcm_plugin_build_rate(struct snd_pcm_substream *plug,
302 struct rate_priv *data; 306 struct rate_priv *data;
303 struct snd_pcm_plugin *plugin; 307 struct snd_pcm_plugin *plugin;
304 308
305 snd_assert(r_plugin != NULL, return -ENXIO); 309 if (snd_BUG_ON(!r_plugin))
310 return -ENXIO;
306 *r_plugin = NULL; 311 *r_plugin = NULL;
307 312
308 snd_assert(src_format->channels == dst_format->channels, return -ENXIO); 313 if (snd_BUG_ON(src_format->channels != dst_format->channels))
309 snd_assert(src_format->channels > 0, return -ENXIO); 314 return -ENXIO;
310 snd_assert(src_format->format == SNDRV_PCM_FORMAT_S16, return -ENXIO); 315 if (snd_BUG_ON(src_format->channels <= 0))
311 snd_assert(dst_format->format == SNDRV_PCM_FORMAT_S16, return -ENXIO); 316 return -ENXIO;
312 snd_assert(src_format->rate != dst_format->rate, return -ENXIO); 317 if (snd_BUG_ON(src_format->format != SNDRV_PCM_FORMAT_S16))
318 return -ENXIO;
319 if (snd_BUG_ON(dst_format->format != SNDRV_PCM_FORMAT_S16))
320 return -ENXIO;
321 if (snd_BUG_ON(src_format->rate == dst_format->rate))
322 return -ENXIO;
313 323
314 err = snd_pcm_plugin_build(plug, "rate conversion", 324 err = snd_pcm_plugin_build(plug, "rate conversion",
315 src_format, dst_format, 325 src_format, dst_format,
diff --git a/sound/core/oss/route.c b/sound/core/oss/route.c
index da7ab7a3e82c..0dcc2870d537 100644
--- a/sound/core/oss/route.c
+++ b/sound/core/oss/route.c
@@ -54,7 +54,8 @@ static snd_pcm_sframes_t route_transfer(struct snd_pcm_plugin *plugin,
54 struct snd_pcm_plugin_channel *dvp; 54 struct snd_pcm_plugin_channel *dvp;
55 int format; 55 int format;
56 56
57 snd_assert(plugin != NULL && src_channels != NULL && dst_channels != NULL, return -ENXIO); 57 if (snd_BUG_ON(!plugin || !src_channels || !dst_channels))
58 return -ENXIO;
58 if (frames == 0) 59 if (frames == 0)
59 return 0; 60 return 0;
60 61
@@ -90,10 +91,13 @@ int snd_pcm_plugin_build_route(struct snd_pcm_substream *plug,
90 struct snd_pcm_plugin *plugin; 91 struct snd_pcm_plugin *plugin;
91 int err; 92 int err;
92 93
93 snd_assert(r_plugin != NULL, return -ENXIO); 94 if (snd_BUG_ON(!r_plugin))
95 return -ENXIO;
94 *r_plugin = NULL; 96 *r_plugin = NULL;
95 snd_assert(src_format->rate == dst_format->rate, return -ENXIO); 97 if (snd_BUG_ON(src_format->rate != dst_format->rate))
96 snd_assert(src_format->format == dst_format->format, return -ENXIO); 98 return -ENXIO;
99 if (snd_BUG_ON(src_format->format != dst_format->format))
100 return -ENXIO;
97 101
98 err = snd_pcm_plugin_build(plug, "route conversion", 102 err = snd_pcm_plugin_build(plug, "route conversion",
99 src_format, dst_format, 0, &plugin); 103 src_format, dst_format, 0, &plugin);
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 9dd9bc73fe1d..192a433a2403 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -42,7 +42,7 @@ static int snd_pcm_dev_free(struct snd_device *device);
42static int snd_pcm_dev_register(struct snd_device *device); 42static int snd_pcm_dev_register(struct snd_device *device);
43static int snd_pcm_dev_disconnect(struct snd_device *device); 43static int snd_pcm_dev_disconnect(struct snd_device *device);
44 44
45static struct snd_pcm *snd_pcm_search(struct snd_card *card, int device) 45static struct snd_pcm *snd_pcm_get(struct snd_card *card, int device)
46{ 46{
47 struct snd_pcm *pcm; 47 struct snd_pcm *pcm;
48 48
@@ -53,6 +53,37 @@ static struct snd_pcm *snd_pcm_search(struct snd_card *card, int device)
53 return NULL; 53 return NULL;
54} 54}
55 55
56static int snd_pcm_next(struct snd_card *card, int device)
57{
58 struct snd_pcm *pcm;
59
60 list_for_each_entry(pcm, &snd_pcm_devices, list) {
61 if (pcm->card == card && pcm->device > device)
62 return pcm->device;
63 else if (pcm->card->number > card->number)
64 return -1;
65 }
66 return -1;
67}
68
69static int snd_pcm_add(struct snd_pcm *newpcm)
70{
71 struct snd_pcm *pcm;
72
73 list_for_each_entry(pcm, &snd_pcm_devices, list) {
74 if (pcm->card == newpcm->card && pcm->device == newpcm->device)
75 return -EBUSY;
76 if (pcm->card->number > newpcm->card->number ||
77 (pcm->card == newpcm->card &&
78 pcm->device > newpcm->device)) {
79 list_add(&newpcm->list, pcm->list.prev);
80 return 0;
81 }
82 }
83 list_add_tail(&newpcm->list, &snd_pcm_devices);
84 return 0;
85}
86
56static int snd_pcm_control_ioctl(struct snd_card *card, 87static int snd_pcm_control_ioctl(struct snd_card *card,
57 struct snd_ctl_file *control, 88 struct snd_ctl_file *control,
58 unsigned int cmd, unsigned long arg) 89 unsigned int cmd, unsigned long arg)
@@ -65,14 +96,7 @@ static int snd_pcm_control_ioctl(struct snd_card *card,
65 if (get_user(device, (int __user *)arg)) 96 if (get_user(device, (int __user *)arg))
66 return -EFAULT; 97 return -EFAULT;
67 mutex_lock(&register_mutex); 98 mutex_lock(&register_mutex);
68 device = device < 0 ? 0 : device + 1; 99 device = snd_pcm_next(card, device);
69 while (device < SNDRV_PCM_DEVICES) {
70 if (snd_pcm_search(card, device))
71 break;
72 device++;
73 }
74 if (device == SNDRV_PCM_DEVICES)
75 device = -1;
76 mutex_unlock(&register_mutex); 100 mutex_unlock(&register_mutex);
77 if (put_user(device, (int __user *)arg)) 101 if (put_user(device, (int __user *)arg))
78 return -EFAULT; 102 return -EFAULT;
@@ -98,7 +122,7 @@ static int snd_pcm_control_ioctl(struct snd_card *card,
98 if (get_user(subdevice, &info->subdevice)) 122 if (get_user(subdevice, &info->subdevice))
99 return -EFAULT; 123 return -EFAULT;
100 mutex_lock(&register_mutex); 124 mutex_lock(&register_mutex);
101 pcm = snd_pcm_search(card, device); 125 pcm = snd_pcm_get(card, device);
102 if (pcm == NULL) { 126 if (pcm == NULL) {
103 err = -ENXIO; 127 err = -ENXIO;
104 goto _error; 128 goto _error;
@@ -232,7 +256,6 @@ static char *snd_pcm_tstamp_mode_names[] = {
232 256
233static const char *snd_pcm_stream_name(int stream) 257static const char *snd_pcm_stream_name(int stream)
234{ 258{
235 snd_assert(stream <= SNDRV_PCM_STREAM_LAST, return NULL);
236 return snd_pcm_stream_names[stream]; 259 return snd_pcm_stream_names[stream];
237} 260}
238 261
@@ -248,7 +271,6 @@ static const char *snd_pcm_subformat_name(snd_pcm_subformat_t subformat)
248 271
249static const char *snd_pcm_tstamp_mode_name(int mode) 272static const char *snd_pcm_tstamp_mode_name(int mode)
250{ 273{
251 snd_assert(mode <= SNDRV_PCM_TSTAMP_LAST, return NULL);
252 return snd_pcm_tstamp_mode_names[mode]; 274 return snd_pcm_tstamp_mode_names[mode];
253} 275}
254 276
@@ -682,9 +704,10 @@ int snd_pcm_new(struct snd_card *card, char *id, int device,
682 .dev_disconnect = snd_pcm_dev_disconnect, 704 .dev_disconnect = snd_pcm_dev_disconnect,
683 }; 705 };
684 706
685 snd_assert(rpcm != NULL, return -EINVAL); 707 if (snd_BUG_ON(!card))
686 *rpcm = NULL; 708 return -ENXIO;
687 snd_assert(card != NULL, return -ENXIO); 709 if (rpcm)
710 *rpcm = NULL;
688 pcm = kzalloc(sizeof(*pcm), GFP_KERNEL); 711 pcm = kzalloc(sizeof(*pcm), GFP_KERNEL);
689 if (pcm == NULL) { 712 if (pcm == NULL) {
690 snd_printk(KERN_ERR "Cannot allocate PCM\n"); 713 snd_printk(KERN_ERR "Cannot allocate PCM\n");
@@ -708,7 +731,8 @@ int snd_pcm_new(struct snd_card *card, char *id, int device,
708 snd_pcm_free(pcm); 731 snd_pcm_free(pcm);
709 return err; 732 return err;
710 } 733 }
711 *rpcm = pcm; 734 if (rpcm)
735 *rpcm = pcm;
712 return 0; 736 return 0;
713} 737}
714 738
@@ -742,7 +766,8 @@ static int snd_pcm_free(struct snd_pcm *pcm)
742{ 766{
743 struct snd_pcm_notify *notify; 767 struct snd_pcm_notify *notify;
744 768
745 snd_assert(pcm != NULL, return -ENXIO); 769 if (!pcm)
770 return 0;
746 list_for_each_entry(notify, &snd_pcm_notify_list, list) { 771 list_for_each_entry(notify, &snd_pcm_notify_list, list) {
747 notify->n_unregister(pcm); 772 notify->n_unregister(pcm);
748 } 773 }
@@ -773,15 +798,15 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
773 int prefer_subdevice = -1; 798 int prefer_subdevice = -1;
774 size_t size; 799 size_t size;
775 800
776 snd_assert(rsubstream != NULL, return -EINVAL); 801 if (snd_BUG_ON(!pcm || !rsubstream))
802 return -ENXIO;
777 *rsubstream = NULL; 803 *rsubstream = NULL;
778 snd_assert(pcm != NULL, return -ENXIO);
779 pstr = &pcm->streams[stream]; 804 pstr = &pcm->streams[stream];
780 if (pstr->substream == NULL || pstr->substream_count == 0) 805 if (pstr->substream == NULL || pstr->substream_count == 0)
781 return -ENODEV; 806 return -ENODEV;
782 807
783 card = pcm->card; 808 card = pcm->card;
784 down_read(&card->controls_rwsem); 809 read_lock(&card->ctl_files_rwlock);
785 list_for_each_entry(kctl, &card->ctl_files, list) { 810 list_for_each_entry(kctl, &card->ctl_files, list) {
786 if (kctl->pid == current->pid) { 811 if (kctl->pid == current->pid) {
787 prefer_subdevice = kctl->prefer_pcm_subdevice; 812 prefer_subdevice = kctl->prefer_pcm_subdevice;
@@ -789,7 +814,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
789 break; 814 break;
790 } 815 }
791 } 816 }
792 up_read(&card->controls_rwsem); 817 read_unlock(&card->ctl_files_rwlock);
793 818
794 switch (stream) { 819 switch (stream) {
795 case SNDRV_PCM_STREAM_PLAYBACK: 820 case SNDRV_PCM_STREAM_PLAYBACK:
@@ -883,8 +908,9 @@ void snd_pcm_detach_substream(struct snd_pcm_substream *substream)
883{ 908{
884 struct snd_pcm_runtime *runtime; 909 struct snd_pcm_runtime *runtime;
885 910
911 if (PCM_RUNTIME_CHECK(substream))
912 return;
886 runtime = substream->runtime; 913 runtime = substream->runtime;
887 snd_assert(runtime != NULL, return);
888 if (runtime->private_free != NULL) 914 if (runtime->private_free != NULL)
889 runtime->private_free(runtime); 915 runtime->private_free(runtime);
890 snd_free_pages((void*)runtime->status, 916 snd_free_pages((void*)runtime->status,
@@ -929,13 +955,14 @@ static int snd_pcm_dev_register(struct snd_device *device)
929 struct snd_pcm *pcm = device->device_data; 955 struct snd_pcm *pcm = device->device_data;
930 struct device *dev; 956 struct device *dev;
931 957
932 snd_assert(pcm != NULL && device != NULL, return -ENXIO); 958 if (snd_BUG_ON(!pcm || !device))
959 return -ENXIO;
933 mutex_lock(&register_mutex); 960 mutex_lock(&register_mutex);
934 if (snd_pcm_search(pcm->card, pcm->device)) { 961 err = snd_pcm_add(pcm);
962 if (err) {
935 mutex_unlock(&register_mutex); 963 mutex_unlock(&register_mutex);
936 return -EBUSY; 964 return err;
937 } 965 }
938 list_add_tail(&pcm->list, &snd_pcm_devices);
939 for (cidx = 0; cidx < 2; cidx++) { 966 for (cidx = 0; cidx < 2; cidx++) {
940 int devtype = -1; 967 int devtype = -1;
941 if (pcm->streams[cidx].substream == NULL) 968 if (pcm->streams[cidx].substream == NULL)
@@ -1019,10 +1046,11 @@ int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree)
1019{ 1046{
1020 struct snd_pcm *pcm; 1047 struct snd_pcm *pcm;
1021 1048
1022 snd_assert(notify != NULL && 1049 if (snd_BUG_ON(!notify ||
1023 notify->n_register != NULL && 1050 !notify->n_register ||
1024 notify->n_unregister != NULL && 1051 !notify->n_unregister ||
1025 notify->n_disconnect, return -EINVAL); 1052 !notify->n_disconnect))
1053 return -EINVAL;
1026 mutex_lock(&register_mutex); 1054 mutex_lock(&register_mutex);
1027 if (nfree) { 1055 if (nfree) {
1028 list_del(&notify->list); 1056 list_del(&notify->list);
diff --git a/sound/core/pcm_compat.c b/sound/core/pcm_compat.c
index 49aa693fba8a..36d7a5998234 100644
--- a/sound/core/pcm_compat.c
+++ b/sound/core/pcm_compat.c
@@ -397,7 +397,8 @@ static int snd_pcm_ioctl_sync_ptr_compat(struct snd_pcm_substream *substream,
397 snd_pcm_uframes_t boundary; 397 snd_pcm_uframes_t boundary;
398 int err; 398 int err;
399 399
400 snd_assert(runtime, return -EINVAL); 400 if (snd_BUG_ON(!runtime))
401 return -EINVAL;
401 402
402 if (get_user(sflags, &src->flags) || 403 if (get_user(sflags, &src->flags) ||
403 get_user(scontrol.appl_ptr, &src->c.control.appl_ptr) || 404 get_user(scontrol.appl_ptr, &src->c.control.appl_ptr) ||
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 1533f0379e9d..6ea5cfb83998 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -85,7 +85,8 @@ void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_ufram
85 } 85 }
86 frames = runtime->buffer_size - runtime->silence_filled; 86 frames = runtime->buffer_size - runtime->silence_filled;
87 } 87 }
88 snd_assert(frames <= runtime->buffer_size, return); 88 if (snd_BUG_ON(frames > runtime->buffer_size))
89 return;
89 if (frames == 0) 90 if (frames == 0)
90 return; 91 return;
91 ofs = runtime->silence_start % runtime->buffer_size; 92 ofs = runtime->silence_start % runtime->buffer_size;
@@ -96,7 +97,7 @@ void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_ufram
96 if (substream->ops->silence) { 97 if (substream->ops->silence) {
97 int err; 98 int err;
98 err = substream->ops->silence(substream, -1, ofs, transfer); 99 err = substream->ops->silence(substream, -1, ofs, transfer);
99 snd_assert(err >= 0, ); 100 snd_BUG_ON(err < 0);
100 } else { 101 } else {
101 char *hwbuf = runtime->dma_area + frames_to_bytes(runtime, ofs); 102 char *hwbuf = runtime->dma_area + frames_to_bytes(runtime, ofs);
102 snd_pcm_format_set_silence(runtime->format, hwbuf, transfer * runtime->channels); 103 snd_pcm_format_set_silence(runtime->format, hwbuf, transfer * runtime->channels);
@@ -108,7 +109,7 @@ void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_ufram
108 for (c = 0; c < channels; ++c) { 109 for (c = 0; c < channels; ++c) {
109 int err; 110 int err;
110 err = substream->ops->silence(substream, c, ofs, transfer); 111 err = substream->ops->silence(substream, c, ofs, transfer);
111 snd_assert(err >= 0, ); 112 snd_BUG_ON(err < 0);
112 } 113 }
113 } else { 114 } else {
114 size_t dma_csize = runtime->dma_bytes / channels; 115 size_t dma_csize = runtime->dma_bytes / channels;
@@ -354,7 +355,7 @@ static inline unsigned int muldiv32(unsigned int a, unsigned int b,
354{ 355{
355 u_int64_t n = (u_int64_t) a * b; 356 u_int64_t n = (u_int64_t) a * b;
356 if (c == 0) { 357 if (c == 0) {
357 snd_assert(n > 0, ); 358 snd_BUG_ON(!n);
358 *r = 0; 359 *r = 0;
359 return UINT_MAX; 360 return UINT_MAX;
360 } 361 }
@@ -380,7 +381,8 @@ static inline unsigned int muldiv32(unsigned int a, unsigned int b,
380int snd_interval_refine(struct snd_interval *i, const struct snd_interval *v) 381int snd_interval_refine(struct snd_interval *i, const struct snd_interval *v)
381{ 382{
382 int changed = 0; 383 int changed = 0;
383 snd_assert(!snd_interval_empty(i), return -EINVAL); 384 if (snd_BUG_ON(snd_interval_empty(i)))
385 return -EINVAL;
384 if (i->min < v->min) { 386 if (i->min < v->min) {
385 i->min = v->min; 387 i->min = v->min;
386 i->openmin = v->openmin; 388 i->openmin = v->openmin;
@@ -423,7 +425,8 @@ EXPORT_SYMBOL(snd_interval_refine);
423 425
424static int snd_interval_refine_first(struct snd_interval *i) 426static int snd_interval_refine_first(struct snd_interval *i)
425{ 427{
426 snd_assert(!snd_interval_empty(i), return -EINVAL); 428 if (snd_BUG_ON(snd_interval_empty(i)))
429 return -EINVAL;
427 if (snd_interval_single(i)) 430 if (snd_interval_single(i))
428 return 0; 431 return 0;
429 i->max = i->min; 432 i->max = i->min;
@@ -435,7 +438,8 @@ static int snd_interval_refine_first(struct snd_interval *i)
435 438
436static int snd_interval_refine_last(struct snd_interval *i) 439static int snd_interval_refine_last(struct snd_interval *i)
437{ 440{
438 snd_assert(!snd_interval_empty(i), return -EINVAL); 441 if (snd_BUG_ON(snd_interval_empty(i)))
442 return -EINVAL;
439 if (snd_interval_single(i)) 443 if (snd_interval_single(i))
440 return 0; 444 return 0;
441 i->min = i->max; 445 i->min = i->max;
@@ -889,7 +893,8 @@ int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond,
889 c->private = private; 893 c->private = private;
890 k = 0; 894 k = 0;
891 while (1) { 895 while (1) {
892 snd_assert(k < ARRAY_SIZE(c->deps), return -EINVAL); 896 if (snd_BUG_ON(k >= ARRAY_SIZE(c->deps)))
897 return -EINVAL;
893 c->deps[k++] = dep; 898 c->deps[k++] = dep;
894 if (dep < 0) 899 if (dep < 0)
895 break; 900 break;
@@ -1285,7 +1290,8 @@ int snd_pcm_hw_param_first(struct snd_pcm_substream *pcm,
1285 return changed; 1290 return changed;
1286 if (params->rmask) { 1291 if (params->rmask) {
1287 int err = snd_pcm_hw_refine(pcm, params); 1292 int err = snd_pcm_hw_refine(pcm, params);
1288 snd_assert(err >= 0, return err); 1293 if (snd_BUG_ON(err < 0))
1294 return err;
1289 } 1295 }
1290 return snd_pcm_hw_param_value(params, var, dir); 1296 return snd_pcm_hw_param_value(params, var, dir);
1291} 1297}
@@ -1330,7 +1336,8 @@ int snd_pcm_hw_param_last(struct snd_pcm_substream *pcm,
1330 return changed; 1336 return changed;
1331 if (params->rmask) { 1337 if (params->rmask) {
1332 int err = snd_pcm_hw_refine(pcm, params); 1338 int err = snd_pcm_hw_refine(pcm, params);
1333 snd_assert(err >= 0, return err); 1339 if (snd_BUG_ON(err < 0))
1340 return err;
1334 } 1341 }
1335 return snd_pcm_hw_param_value(params, var, dir); 1342 return snd_pcm_hw_param_value(params, var, dir);
1336} 1343}
@@ -1368,7 +1375,8 @@ int snd_pcm_hw_params_choose(struct snd_pcm_substream *pcm,
1368 err = snd_pcm_hw_param_first(pcm, params, *v, NULL); 1375 err = snd_pcm_hw_param_first(pcm, params, *v, NULL);
1369 else 1376 else
1370 err = snd_pcm_hw_param_last(pcm, params, *v, NULL); 1377 err = snd_pcm_hw_param_last(pcm, params, *v, NULL);
1371 snd_assert(err >= 0, return err); 1378 if (snd_BUG_ON(err < 0))
1379 return err;
1372 } 1380 }
1373 return 0; 1381 return 0;
1374} 1382}
@@ -1466,9 +1474,9 @@ void snd_pcm_period_elapsed(struct snd_pcm_substream *substream)
1466 struct snd_pcm_runtime *runtime; 1474 struct snd_pcm_runtime *runtime;
1467 unsigned long flags; 1475 unsigned long flags;
1468 1476
1469 snd_assert(substream != NULL, return); 1477 if (PCM_RUNTIME_CHECK(substream))
1478 return;
1470 runtime = substream->runtime; 1479 runtime = substream->runtime;
1471 snd_assert(runtime != NULL, return);
1472 1480
1473 if (runtime->transfer_ack_begin) 1481 if (runtime->transfer_ack_begin)
1474 runtime->transfer_ack_begin(substream); 1482 runtime->transfer_ack_begin(substream);
@@ -1567,7 +1575,6 @@ static int snd_pcm_lib_write_transfer(struct snd_pcm_substream *substream,
1567 return err; 1575 return err;
1568 } else { 1576 } else {
1569 char *hwbuf = runtime->dma_area + frames_to_bytes(runtime, hwoff); 1577 char *hwbuf = runtime->dma_area + frames_to_bytes(runtime, hwoff);
1570 snd_assert(runtime->dma_area, return -EFAULT);
1571 if (copy_from_user(hwbuf, buf, frames_to_bytes(runtime, frames))) 1578 if (copy_from_user(hwbuf, buf, frames_to_bytes(runtime, frames)))
1572 return -EFAULT; 1579 return -EFAULT;
1573 } 1580 }
@@ -1629,7 +1636,10 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream,
1629 cont = runtime->buffer_size - runtime->control->appl_ptr % runtime->buffer_size; 1636 cont = runtime->buffer_size - runtime->control->appl_ptr % runtime->buffer_size;
1630 if (frames > cont) 1637 if (frames > cont)
1631 frames = cont; 1638 frames = cont;
1632 snd_assert(frames != 0, snd_pcm_stream_unlock_irq(substream); return -EINVAL); 1639 if (snd_BUG_ON(!frames)) {
1640 snd_pcm_stream_unlock_irq(substream);
1641 return -EINVAL;
1642 }
1633 appl_ptr = runtime->control->appl_ptr; 1643 appl_ptr = runtime->control->appl_ptr;
1634 appl_ofs = appl_ptr % runtime->buffer_size; 1644 appl_ofs = appl_ptr % runtime->buffer_size;
1635 snd_pcm_stream_unlock_irq(substream); 1645 snd_pcm_stream_unlock_irq(substream);
@@ -1669,18 +1679,30 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream,
1669 return xfer > 0 ? (snd_pcm_sframes_t)xfer : err; 1679 return xfer > 0 ? (snd_pcm_sframes_t)xfer : err;
1670} 1680}
1671 1681
1672snd_pcm_sframes_t snd_pcm_lib_write(struct snd_pcm_substream *substream, const void __user *buf, snd_pcm_uframes_t size) 1682/* sanity-check for read/write methods */
1683static int pcm_sanity_check(struct snd_pcm_substream *substream)
1673{ 1684{
1674 struct snd_pcm_runtime *runtime; 1685 struct snd_pcm_runtime *runtime;
1675 int nonblock; 1686 if (PCM_RUNTIME_CHECK(substream))
1676 1687 return -ENXIO;
1677 snd_assert(substream != NULL, return -ENXIO);
1678 runtime = substream->runtime; 1688 runtime = substream->runtime;
1679 snd_assert(runtime != NULL, return -ENXIO); 1689 if (snd_BUG_ON(!substream->ops->copy && !runtime->dma_area))
1680 snd_assert(substream->ops->copy != NULL || runtime->dma_area != NULL, return -EINVAL); 1690 return -EINVAL;
1681 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) 1691 if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
1682 return -EBADFD; 1692 return -EBADFD;
1693 return 0;
1694}
1695
1696snd_pcm_sframes_t snd_pcm_lib_write(struct snd_pcm_substream *substream, const void __user *buf, snd_pcm_uframes_t size)
1697{
1698 struct snd_pcm_runtime *runtime;
1699 int nonblock;
1700 int err;
1683 1701
1702 err = pcm_sanity_check(substream);
1703 if (err < 0)
1704 return err;
1705 runtime = substream->runtime;
1684 nonblock = !!(substream->f_flags & O_NONBLOCK); 1706 nonblock = !!(substream->f_flags & O_NONBLOCK);
1685 1707
1686 if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED && 1708 if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED &&
@@ -1703,7 +1725,8 @@ static int snd_pcm_lib_writev_transfer(struct snd_pcm_substream *substream,
1703 int channels = runtime->channels; 1725 int channels = runtime->channels;
1704 int c; 1726 int c;
1705 if (substream->ops->copy) { 1727 if (substream->ops->copy) {
1706 snd_assert(substream->ops->silence != NULL, return -EINVAL); 1728 if (snd_BUG_ON(!substream->ops->silence))
1729 return -EINVAL;
1707 for (c = 0; c < channels; ++c, ++bufs) { 1730 for (c = 0; c < channels; ++c, ++bufs) {
1708 if (*bufs == NULL) { 1731 if (*bufs == NULL) {
1709 if ((err = substream->ops->silence(substream, c, hwoff, frames)) < 0) 1732 if ((err = substream->ops->silence(substream, c, hwoff, frames)) < 0)
@@ -1717,7 +1740,6 @@ static int snd_pcm_lib_writev_transfer(struct snd_pcm_substream *substream,
1717 } else { 1740 } else {
1718 /* default transfer behaviour */ 1741 /* default transfer behaviour */
1719 size_t dma_csize = runtime->dma_bytes / channels; 1742 size_t dma_csize = runtime->dma_bytes / channels;
1720 snd_assert(runtime->dma_area, return -EFAULT);
1721 for (c = 0; c < channels; ++c, ++bufs) { 1743 for (c = 0; c < channels; ++c, ++bufs) {
1722 char *hwbuf = runtime->dma_area + (c * dma_csize) + samples_to_bytes(runtime, hwoff); 1744 char *hwbuf = runtime->dma_area + (c * dma_csize) + samples_to_bytes(runtime, hwoff);
1723 if (*bufs == NULL) { 1745 if (*bufs == NULL) {
@@ -1738,14 +1760,12 @@ snd_pcm_sframes_t snd_pcm_lib_writev(struct snd_pcm_substream *substream,
1738{ 1760{
1739 struct snd_pcm_runtime *runtime; 1761 struct snd_pcm_runtime *runtime;
1740 int nonblock; 1762 int nonblock;
1763 int err;
1741 1764
1742 snd_assert(substream != NULL, return -ENXIO); 1765 err = pcm_sanity_check(substream);
1766 if (err < 0)
1767 return err;
1743 runtime = substream->runtime; 1768 runtime = substream->runtime;
1744 snd_assert(runtime != NULL, return -ENXIO);
1745 snd_assert(substream->ops->copy != NULL || runtime->dma_area != NULL, return -EINVAL);
1746 if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
1747 return -EBADFD;
1748
1749 nonblock = !!(substream->f_flags & O_NONBLOCK); 1769 nonblock = !!(substream->f_flags & O_NONBLOCK);
1750 1770
1751 if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) 1771 if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED)
@@ -1769,7 +1789,6 @@ static int snd_pcm_lib_read_transfer(struct snd_pcm_substream *substream,
1769 return err; 1789 return err;
1770 } else { 1790 } else {
1771 char *hwbuf = runtime->dma_area + frames_to_bytes(runtime, hwoff); 1791 char *hwbuf = runtime->dma_area + frames_to_bytes(runtime, hwoff);
1772 snd_assert(runtime->dma_area, return -EFAULT);
1773 if (copy_to_user(buf, hwbuf, frames_to_bytes(runtime, frames))) 1792 if (copy_to_user(buf, hwbuf, frames_to_bytes(runtime, frames)))
1774 return -EFAULT; 1793 return -EFAULT;
1775 } 1794 }
@@ -1841,7 +1860,10 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream,
1841 cont = runtime->buffer_size - runtime->control->appl_ptr % runtime->buffer_size; 1860 cont = runtime->buffer_size - runtime->control->appl_ptr % runtime->buffer_size;
1842 if (frames > cont) 1861 if (frames > cont)
1843 frames = cont; 1862 frames = cont;
1844 snd_assert(frames != 0, snd_pcm_stream_unlock_irq(substream); return -EINVAL); 1863 if (snd_BUG_ON(!frames)) {
1864 snd_pcm_stream_unlock_irq(substream);
1865 return -EINVAL;
1866 }
1845 appl_ptr = runtime->control->appl_ptr; 1867 appl_ptr = runtime->control->appl_ptr;
1846 appl_ofs = appl_ptr % runtime->buffer_size; 1868 appl_ofs = appl_ptr % runtime->buffer_size;
1847 snd_pcm_stream_unlock_irq(substream); 1869 snd_pcm_stream_unlock_irq(substream);
@@ -1879,14 +1901,12 @@ snd_pcm_sframes_t snd_pcm_lib_read(struct snd_pcm_substream *substream, void __u
1879{ 1901{
1880 struct snd_pcm_runtime *runtime; 1902 struct snd_pcm_runtime *runtime;
1881 int nonblock; 1903 int nonblock;
1904 int err;
1882 1905
1883 snd_assert(substream != NULL, return -ENXIO); 1906 err = pcm_sanity_check(substream);
1907 if (err < 0)
1908 return err;
1884 runtime = substream->runtime; 1909 runtime = substream->runtime;
1885 snd_assert(runtime != NULL, return -ENXIO);
1886 snd_assert(substream->ops->copy != NULL || runtime->dma_area != NULL, return -EINVAL);
1887 if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
1888 return -EBADFD;
1889
1890 nonblock = !!(substream->f_flags & O_NONBLOCK); 1910 nonblock = !!(substream->f_flags & O_NONBLOCK);
1891 if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED) 1911 if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED)
1892 return -EINVAL; 1912 return -EINVAL;
@@ -1916,7 +1936,6 @@ static int snd_pcm_lib_readv_transfer(struct snd_pcm_substream *substream,
1916 } 1936 }
1917 } else { 1937 } else {
1918 snd_pcm_uframes_t dma_csize = runtime->dma_bytes / channels; 1938 snd_pcm_uframes_t dma_csize = runtime->dma_bytes / channels;
1919 snd_assert(runtime->dma_area, return -EFAULT);
1920 for (c = 0; c < channels; ++c, ++bufs) { 1939 for (c = 0; c < channels; ++c, ++bufs) {
1921 char *hwbuf; 1940 char *hwbuf;
1922 char __user *buf; 1941 char __user *buf;
@@ -1938,11 +1957,12 @@ snd_pcm_sframes_t snd_pcm_lib_readv(struct snd_pcm_substream *substream,
1938{ 1957{
1939 struct snd_pcm_runtime *runtime; 1958 struct snd_pcm_runtime *runtime;
1940 int nonblock; 1959 int nonblock;
1960 int err;
1941 1961
1942 snd_assert(substream != NULL, return -ENXIO); 1962 err = pcm_sanity_check(substream);
1963 if (err < 0)
1964 return err;
1943 runtime = substream->runtime; 1965 runtime = substream->runtime;
1944 snd_assert(runtime != NULL, return -ENXIO);
1945 snd_assert(substream->ops->copy != NULL || runtime->dma_area != NULL, return -EINVAL);
1946 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) 1966 if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
1947 return -EBADFD; 1967 return -EBADFD;
1948 1968
diff --git a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c
index ff07b4a9992e..a6d42808828c 100644
--- a/sound/core/pcm_memory.c
+++ b/sound/core/pcm_memory.c
@@ -50,8 +50,6 @@ static int preallocate_pcm_pages(struct snd_pcm_substream *substream, size_t siz
50 struct snd_dma_buffer *dmab = &substream->dma_buffer; 50 struct snd_dma_buffer *dmab = &substream->dma_buffer;
51 int err; 51 int err;
52 52
53 snd_assert(size > 0, return -EINVAL);
54
55 /* already reserved? */ 53 /* already reserved? */
56 if (snd_dma_get_reserved_buf(dmab, substream->dma_buf_id) > 0) { 54 if (snd_dma_get_reserved_buf(dmab, substream->dma_buf_id) > 0) {
57 if (dmab->bytes >= size) 55 if (dmab->bytes >= size)
@@ -326,6 +324,32 @@ struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream, unsigne
326 324
327EXPORT_SYMBOL(snd_pcm_sgbuf_ops_page); 325EXPORT_SYMBOL(snd_pcm_sgbuf_ops_page);
328 326
327/*
328 * compute the max chunk size with continuous pages on sg-buffer
329 */
330unsigned int snd_pcm_sgbuf_get_chunk_size(struct snd_pcm_substream *substream,
331 unsigned int ofs, unsigned int size)
332{
333 struct snd_sg_buf *sg = snd_pcm_substream_sgbuf(substream);
334 unsigned int start, end, pg;
335
336 start = ofs >> PAGE_SHIFT;
337 end = (ofs + size - 1) >> PAGE_SHIFT;
338 /* check page continuity */
339 pg = sg->table[start].addr >> PAGE_SHIFT;
340 for (;;) {
341 start++;
342 if (start > end)
343 break;
344 pg++;
345 if ((sg->table[start].addr >> PAGE_SHIFT) != pg)
346 return (start << PAGE_SHIFT) - ofs;
347 }
348 /* ok, all on continuous pages */
349 return size;
350}
351EXPORT_SYMBOL(snd_pcm_sgbuf_get_chunk_size);
352
329/** 353/**
330 * snd_pcm_lib_malloc_pages - allocate the DMA buffer 354 * snd_pcm_lib_malloc_pages - allocate the DMA buffer
331 * @substream: the substream to allocate the DMA buffer to 355 * @substream: the substream to allocate the DMA buffer to
@@ -342,10 +366,12 @@ int snd_pcm_lib_malloc_pages(struct snd_pcm_substream *substream, size_t size)
342 struct snd_pcm_runtime *runtime; 366 struct snd_pcm_runtime *runtime;
343 struct snd_dma_buffer *dmab = NULL; 367 struct snd_dma_buffer *dmab = NULL;
344 368
345 snd_assert(substream->dma_buffer.dev.type != SNDRV_DMA_TYPE_UNKNOWN, return -EINVAL); 369 if (PCM_RUNTIME_CHECK(substream))
346 snd_assert(substream != NULL, return -EINVAL); 370 return -EINVAL;
371 if (snd_BUG_ON(substream->dma_buffer.dev.type ==
372 SNDRV_DMA_TYPE_UNKNOWN))
373 return -EINVAL;
347 runtime = substream->runtime; 374 runtime = substream->runtime;
348 snd_assert(runtime != NULL, return -EINVAL);
349 375
350 if (runtime->dma_buffer_p) { 376 if (runtime->dma_buffer_p) {
351 /* perphaps, we might free the large DMA memory region 377 /* perphaps, we might free the large DMA memory region
@@ -391,9 +417,9 @@ int snd_pcm_lib_free_pages(struct snd_pcm_substream *substream)
391{ 417{
392 struct snd_pcm_runtime *runtime; 418 struct snd_pcm_runtime *runtime;
393 419
394 snd_assert(substream != NULL, return -EINVAL); 420 if (PCM_RUNTIME_CHECK(substream))
421 return -EINVAL;
395 runtime = substream->runtime; 422 runtime = substream->runtime;
396 snd_assert(runtime != NULL, return -EINVAL);
397 if (runtime->dma_area == NULL) 423 if (runtime->dma_area == NULL)
398 return 0; 424 return 0;
399 if (runtime->dma_buffer_p != &substream->dma_buffer) { 425 if (runtime->dma_buffer_p != &substream->dma_buffer) {
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index c49b9d9e303c..e61e12506ded 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -95,7 +95,6 @@ int snd_pcm_info(struct snd_pcm_substream *substream, struct snd_pcm_info *info)
95 struct snd_pcm *pcm = substream->pcm; 95 struct snd_pcm *pcm = substream->pcm;
96 struct snd_pcm_str *pstr = substream->pstr; 96 struct snd_pcm_str *pstr = substream->pstr;
97 97
98 snd_assert(substream != NULL, return -ENXIO);
99 memset(info, 0, sizeof(*info)); 98 memset(info, 0, sizeof(*info));
100 info->card = pcm->card->number; 99 info->card = pcm->card->number;
101 info->device = pcm->device; 100 info->device = pcm->device;
@@ -370,9 +369,9 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
370 unsigned int bits; 369 unsigned int bits;
371 snd_pcm_uframes_t frames; 370 snd_pcm_uframes_t frames;
372 371
373 snd_assert(substream != NULL, return -ENXIO); 372 if (PCM_RUNTIME_CHECK(substream))
373 return -ENXIO;
374 runtime = substream->runtime; 374 runtime = substream->runtime;
375 snd_assert(runtime != NULL, return -ENXIO);
376 snd_pcm_stream_lock_irq(substream); 375 snd_pcm_stream_lock_irq(substream);
377 switch (runtime->status->state) { 376 switch (runtime->status->state) {
378 case SNDRV_PCM_STATE_OPEN: 377 case SNDRV_PCM_STATE_OPEN:
@@ -490,9 +489,9 @@ static int snd_pcm_hw_free(struct snd_pcm_substream *substream)
490 struct snd_pcm_runtime *runtime; 489 struct snd_pcm_runtime *runtime;
491 int result = 0; 490 int result = 0;
492 491
493 snd_assert(substream != NULL, return -ENXIO); 492 if (PCM_RUNTIME_CHECK(substream))
493 return -ENXIO;
494 runtime = substream->runtime; 494 runtime = substream->runtime;
495 snd_assert(runtime != NULL, return -ENXIO);
496 snd_pcm_stream_lock_irq(substream); 495 snd_pcm_stream_lock_irq(substream);
497 switch (runtime->status->state) { 496 switch (runtime->status->state) {
498 case SNDRV_PCM_STATE_SETUP: 497 case SNDRV_PCM_STATE_SETUP:
@@ -518,9 +517,9 @@ static int snd_pcm_sw_params(struct snd_pcm_substream *substream,
518{ 517{
519 struct snd_pcm_runtime *runtime; 518 struct snd_pcm_runtime *runtime;
520 519
521 snd_assert(substream != NULL, return -ENXIO); 520 if (PCM_RUNTIME_CHECK(substream))
521 return -ENXIO;
522 runtime = substream->runtime; 522 runtime = substream->runtime;
523 snd_assert(runtime != NULL, return -ENXIO);
524 snd_pcm_stream_lock_irq(substream); 523 snd_pcm_stream_lock_irq(substream);
525 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) { 524 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) {
526 snd_pcm_stream_unlock_irq(substream); 525 snd_pcm_stream_unlock_irq(substream);
@@ -622,11 +621,8 @@ static int snd_pcm_status_user(struct snd_pcm_substream *substream,
622 struct snd_pcm_status __user * _status) 621 struct snd_pcm_status __user * _status)
623{ 622{
624 struct snd_pcm_status status; 623 struct snd_pcm_status status;
625 struct snd_pcm_runtime *runtime;
626 int res; 624 int res;
627 625
628 snd_assert(substream != NULL, return -ENXIO);
629 runtime = substream->runtime;
630 memset(&status, 0, sizeof(status)); 626 memset(&status, 0, sizeof(status));
631 res = snd_pcm_status(substream, &status); 627 res = snd_pcm_status(substream, &status);
632 if (res < 0) 628 if (res < 0)
@@ -642,7 +638,6 @@ static int snd_pcm_channel_info(struct snd_pcm_substream *substream,
642 struct snd_pcm_runtime *runtime; 638 struct snd_pcm_runtime *runtime;
643 unsigned int channel; 639 unsigned int channel;
644 640
645 snd_assert(substream != NULL, return -ENXIO);
646 channel = info->channel; 641 channel = info->channel;
647 runtime = substream->runtime; 642 runtime = substream->runtime;
648 snd_pcm_stream_lock_irq(substream); 643 snd_pcm_stream_lock_irq(substream);
@@ -1250,7 +1245,6 @@ static int snd_pcm_do_reset(struct snd_pcm_substream *substream, int state)
1250 int err = substream->ops->ioctl(substream, SNDRV_PCM_IOCTL1_RESET, NULL); 1245 int err = substream->ops->ioctl(substream, SNDRV_PCM_IOCTL1_RESET, NULL);
1251 if (err < 0) 1246 if (err < 0)
1252 return err; 1247 return err;
1253 // snd_assert(runtime->status->hw_ptr < runtime->buffer_size, );
1254 runtime->hw_ptr_base = 0; 1248 runtime->hw_ptr_base = 0;
1255 runtime->hw_ptr_interrupt = runtime->status->hw_ptr - 1249 runtime->hw_ptr_interrupt = runtime->status->hw_ptr -
1256 runtime->status->hw_ptr % runtime->period_size; 1250 runtime->status->hw_ptr % runtime->period_size;
@@ -1421,7 +1415,6 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream)
1421 int i, num_drecs; 1415 int i, num_drecs;
1422 struct drain_rec *drec, drec_tmp, *d; 1416 struct drain_rec *drec, drec_tmp, *d;
1423 1417
1424 snd_assert(substream != NULL, return -ENXIO);
1425 card = substream->pcm->card; 1418 card = substream->pcm->card;
1426 runtime = substream->runtime; 1419 runtime = substream->runtime;
1427 1420
@@ -1541,21 +1534,16 @@ static int snd_pcm_drop(struct snd_pcm_substream *substream)
1541 struct snd_card *card; 1534 struct snd_card *card;
1542 int result = 0; 1535 int result = 0;
1543 1536
1544 snd_assert(substream != NULL, return -ENXIO); 1537 if (PCM_RUNTIME_CHECK(substream))
1538 return -ENXIO;
1545 runtime = substream->runtime; 1539 runtime = substream->runtime;
1546 card = substream->pcm->card; 1540 card = substream->pcm->card;
1547 1541
1548 if (runtime->status->state == SNDRV_PCM_STATE_OPEN || 1542 if (runtime->status->state == SNDRV_PCM_STATE_OPEN ||
1549 runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED) 1543 runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED ||
1544 runtime->status->state == SNDRV_PCM_STATE_SUSPENDED)
1550 return -EBADFD; 1545 return -EBADFD;
1551 1546
1552 snd_power_lock(card);
1553 if (runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) {
1554 result = snd_power_wait(card, SNDRV_CTL_POWER_D0);
1555 if (result < 0)
1556 goto _unlock;
1557 }
1558
1559 snd_pcm_stream_lock_irq(substream); 1547 snd_pcm_stream_lock_irq(substream);
1560 /* resume pause */ 1548 /* resume pause */
1561 if (runtime->status->state == SNDRV_PCM_STATE_PAUSED) 1549 if (runtime->status->state == SNDRV_PCM_STATE_PAUSED)
@@ -1564,8 +1552,7 @@ static int snd_pcm_drop(struct snd_pcm_substream *substream)
1564 snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP); 1552 snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
1565 /* runtime->control->appl_ptr = runtime->status->hw_ptr; */ 1553 /* runtime->control->appl_ptr = runtime->status->hw_ptr; */
1566 snd_pcm_stream_unlock_irq(substream); 1554 snd_pcm_stream_unlock_irq(substream);
1567 _unlock: 1555
1568 snd_power_unlock(card);
1569 return result; 1556 return result;
1570} 1557}
1571 1558
@@ -1941,33 +1928,41 @@ int snd_pcm_hw_constraints_complete(struct snd_pcm_substream *substream)
1941 mask |= 1 << SNDRV_PCM_ACCESS_MMAP_COMPLEX; 1928 mask |= 1 << SNDRV_PCM_ACCESS_MMAP_COMPLEX;
1942 } 1929 }
1943 err = snd_pcm_hw_constraint_mask(runtime, SNDRV_PCM_HW_PARAM_ACCESS, mask); 1930 err = snd_pcm_hw_constraint_mask(runtime, SNDRV_PCM_HW_PARAM_ACCESS, mask);
1944 snd_assert(err >= 0, return -EINVAL); 1931 if (err < 0)
1932 return err;
1945 1933
1946 err = snd_pcm_hw_constraint_mask64(runtime, SNDRV_PCM_HW_PARAM_FORMAT, hw->formats); 1934 err = snd_pcm_hw_constraint_mask64(runtime, SNDRV_PCM_HW_PARAM_FORMAT, hw->formats);
1947 snd_assert(err >= 0, return -EINVAL); 1935 if (err < 0)
1936 return err;
1948 1937
1949 err = snd_pcm_hw_constraint_mask(runtime, SNDRV_PCM_HW_PARAM_SUBFORMAT, 1 << SNDRV_PCM_SUBFORMAT_STD); 1938 err = snd_pcm_hw_constraint_mask(runtime, SNDRV_PCM_HW_PARAM_SUBFORMAT, 1 << SNDRV_PCM_SUBFORMAT_STD);
1950 snd_assert(err >= 0, return -EINVAL); 1939 if (err < 0)
1940 return err;
1951 1941
1952 err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_CHANNELS, 1942 err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_CHANNELS,
1953 hw->channels_min, hw->channels_max); 1943 hw->channels_min, hw->channels_max);
1954 snd_assert(err >= 0, return -EINVAL); 1944 if (err < 0)
1945 return err;
1955 1946
1956 err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_RATE, 1947 err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_RATE,
1957 hw->rate_min, hw->rate_max); 1948 hw->rate_min, hw->rate_max);
1958 snd_assert(err >= 0, return -EINVAL); 1949 if (err < 0)
1950 return err;
1959 1951
1960 err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 1952 err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
1961 hw->period_bytes_min, hw->period_bytes_max); 1953 hw->period_bytes_min, hw->period_bytes_max);
1962 snd_assert(err >= 0, return -EINVAL); 1954 if (err < 0)
1955 return err;
1963 1956
1964 err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIODS, 1957 err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIODS,
1965 hw->periods_min, hw->periods_max); 1958 hw->periods_min, hw->periods_max);
1966 snd_assert(err >= 0, return -EINVAL); 1959 if (err < 0)
1960 return err;
1967 1961
1968 err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 1962 err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
1969 hw->period_bytes_min, hw->buffer_bytes_max); 1963 hw->period_bytes_min, hw->buffer_bytes_max);
1970 snd_assert(err >= 0, return -EINVAL); 1964 if (err < 0)
1965 return err;
1971 1966
1972 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 1967 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
1973 snd_pcm_hw_rule_buffer_bytes_max, substream, 1968 snd_pcm_hw_rule_buffer_bytes_max, substream,
@@ -1978,7 +1973,8 @@ int snd_pcm_hw_constraints_complete(struct snd_pcm_substream *substream)
1978 /* FIXME: remove */ 1973 /* FIXME: remove */
1979 if (runtime->dma_bytes) { 1974 if (runtime->dma_bytes) {
1980 err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 0, runtime->dma_bytes); 1975 err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 0, runtime->dma_bytes);
1981 snd_assert(err >= 0, return -EINVAL); 1976 if (err < 0)
1977 return -EINVAL;
1982 } 1978 }
1983 1979
1984 if (!(hw->rates & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))) { 1980 if (!(hw->rates & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))) {
@@ -2074,8 +2070,8 @@ static int snd_pcm_open_file(struct file *file,
2074 struct snd_pcm_str *str; 2070 struct snd_pcm_str *str;
2075 int err; 2071 int err;
2076 2072
2077 snd_assert(rpcm_file != NULL, return -EINVAL); 2073 if (rpcm_file)
2078 *rpcm_file = NULL; 2074 *rpcm_file = NULL;
2079 2075
2080 err = snd_pcm_open_substream(pcm, stream, file, &substream); 2076 err = snd_pcm_open_substream(pcm, stream, file, &substream);
2081 if (err < 0) 2077 if (err < 0)
@@ -2093,7 +2089,8 @@ static int snd_pcm_open_file(struct file *file,
2093 substream->pcm_release = pcm_release_private; 2089 substream->pcm_release = pcm_release_private;
2094 } 2090 }
2095 file->private_data = pcm_file; 2091 file->private_data = pcm_file;
2096 *rpcm_file = pcm_file; 2092 if (rpcm_file)
2093 *rpcm_file = pcm_file;
2097 return 0; 2094 return 0;
2098} 2095}
2099 2096
@@ -2177,7 +2174,8 @@ static int snd_pcm_release(struct inode *inode, struct file *file)
2177 2174
2178 pcm_file = file->private_data; 2175 pcm_file = file->private_data;
2179 substream = pcm_file->substream; 2176 substream = pcm_file->substream;
2180 snd_assert(substream != NULL, return -ENXIO); 2177 if (snd_BUG_ON(!substream))
2178 return -ENXIO;
2181 pcm = substream->pcm; 2179 pcm = substream->pcm;
2182 fasync_helper(-1, file, 0, &substream->runtime->fasync); 2180 fasync_helper(-1, file, 0, &substream->runtime->fasync);
2183 mutex_lock(&pcm->open_mutex); 2181 mutex_lock(&pcm->open_mutex);
@@ -2500,8 +2498,6 @@ static int snd_pcm_common_ioctl1(struct file *file,
2500 struct snd_pcm_substream *substream, 2498 struct snd_pcm_substream *substream,
2501 unsigned int cmd, void __user *arg) 2499 unsigned int cmd, void __user *arg)
2502{ 2500{
2503 snd_assert(substream != NULL, return -ENXIO);
2504
2505 switch (cmd) { 2501 switch (cmd) {
2506 case SNDRV_PCM_IOCTL_PVERSION: 2502 case SNDRV_PCM_IOCTL_PVERSION:
2507 return put_user(SNDRV_PCM_VERSION, (int __user *)arg) ? -EFAULT : 0; 2503 return put_user(SNDRV_PCM_VERSION, (int __user *)arg) ? -EFAULT : 0;
@@ -2570,8 +2566,10 @@ static int snd_pcm_playback_ioctl1(struct file *file,
2570 struct snd_pcm_substream *substream, 2566 struct snd_pcm_substream *substream,
2571 unsigned int cmd, void __user *arg) 2567 unsigned int cmd, void __user *arg)
2572{ 2568{
2573 snd_assert(substream != NULL, return -ENXIO); 2569 if (snd_BUG_ON(!substream))
2574 snd_assert(substream->stream == SNDRV_PCM_STREAM_PLAYBACK, return -EINVAL); 2570 return -ENXIO;
2571 if (snd_BUG_ON(substream->stream != SNDRV_PCM_STREAM_PLAYBACK))
2572 return -EINVAL;
2575 switch (cmd) { 2573 switch (cmd) {
2576 case SNDRV_PCM_IOCTL_WRITEI_FRAMES: 2574 case SNDRV_PCM_IOCTL_WRITEI_FRAMES:
2577 { 2575 {
@@ -2650,8 +2648,10 @@ static int snd_pcm_capture_ioctl1(struct file *file,
2650 struct snd_pcm_substream *substream, 2648 struct snd_pcm_substream *substream,
2651 unsigned int cmd, void __user *arg) 2649 unsigned int cmd, void __user *arg)
2652{ 2650{
2653 snd_assert(substream != NULL, return -ENXIO); 2651 if (snd_BUG_ON(!substream))
2654 snd_assert(substream->stream == SNDRV_PCM_STREAM_CAPTURE, return -EINVAL); 2652 return -ENXIO;
2653 if (snd_BUG_ON(substream->stream != SNDRV_PCM_STREAM_CAPTURE))
2654 return -EINVAL;
2655 switch (cmd) { 2655 switch (cmd) {
2656 case SNDRV_PCM_IOCTL_READI_FRAMES: 2656 case SNDRV_PCM_IOCTL_READI_FRAMES:
2657 { 2657 {
@@ -2790,7 +2790,8 @@ static ssize_t snd_pcm_read(struct file *file, char __user *buf, size_t count,
2790 2790
2791 pcm_file = file->private_data; 2791 pcm_file = file->private_data;
2792 substream = pcm_file->substream; 2792 substream = pcm_file->substream;
2793 snd_assert(substream != NULL, return -ENXIO); 2793 if (PCM_RUNTIME_CHECK(substream))
2794 return -ENXIO;
2794 runtime = substream->runtime; 2795 runtime = substream->runtime;
2795 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) 2796 if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
2796 return -EBADFD; 2797 return -EBADFD;
@@ -2813,21 +2814,17 @@ static ssize_t snd_pcm_write(struct file *file, const char __user *buf,
2813 2814
2814 pcm_file = file->private_data; 2815 pcm_file = file->private_data;
2815 substream = pcm_file->substream; 2816 substream = pcm_file->substream;
2816 snd_assert(substream != NULL, result = -ENXIO; goto end); 2817 if (PCM_RUNTIME_CHECK(substream))
2818 return -ENXIO;
2817 runtime = substream->runtime; 2819 runtime = substream->runtime;
2818 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) { 2820 if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
2819 result = -EBADFD; 2821 return -EBADFD;
2820 goto end; 2822 if (!frame_aligned(runtime, count))
2821 } 2823 return -EINVAL;
2822 if (!frame_aligned(runtime, count)) {
2823 result = -EINVAL;
2824 goto end;
2825 }
2826 count = bytes_to_frames(runtime, count); 2824 count = bytes_to_frames(runtime, count);
2827 result = snd_pcm_lib_write(substream, buf, count); 2825 result = snd_pcm_lib_write(substream, buf, count);
2828 if (result > 0) 2826 if (result > 0)
2829 result = frames_to_bytes(runtime, result); 2827 result = frames_to_bytes(runtime, result);
2830 end:
2831 return result; 2828 return result;
2832} 2829}
2833 2830
@@ -2845,7 +2842,8 @@ static ssize_t snd_pcm_aio_read(struct kiocb *iocb, const struct iovec *iov,
2845 2842
2846 pcm_file = iocb->ki_filp->private_data; 2843 pcm_file = iocb->ki_filp->private_data;
2847 substream = pcm_file->substream; 2844 substream = pcm_file->substream;
2848 snd_assert(substream != NULL, return -ENXIO); 2845 if (PCM_RUNTIME_CHECK(substream))
2846 return -ENXIO;
2849 runtime = substream->runtime; 2847 runtime = substream->runtime;
2850 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) 2848 if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
2851 return -EBADFD; 2849 return -EBADFD;
@@ -2879,17 +2877,14 @@ static ssize_t snd_pcm_aio_write(struct kiocb *iocb, const struct iovec *iov,
2879 2877
2880 pcm_file = iocb->ki_filp->private_data; 2878 pcm_file = iocb->ki_filp->private_data;
2881 substream = pcm_file->substream; 2879 substream = pcm_file->substream;
2882 snd_assert(substream != NULL, result = -ENXIO; goto end); 2880 if (PCM_RUNTIME_CHECK(substream))
2881 return -ENXIO;
2883 runtime = substream->runtime; 2882 runtime = substream->runtime;
2884 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) { 2883 if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
2885 result = -EBADFD; 2884 return -EBADFD;
2886 goto end;
2887 }
2888 if (nr_segs > 128 || nr_segs != runtime->channels || 2885 if (nr_segs > 128 || nr_segs != runtime->channels ||
2889 !frame_aligned(runtime, iov->iov_len)) { 2886 !frame_aligned(runtime, iov->iov_len))
2890 result = -EINVAL; 2887 return -EINVAL;
2891 goto end;
2892 }
2893 frames = bytes_to_samples(runtime, iov->iov_len); 2888 frames = bytes_to_samples(runtime, iov->iov_len);
2894 bufs = kmalloc(sizeof(void *) * nr_segs, GFP_KERNEL); 2889 bufs = kmalloc(sizeof(void *) * nr_segs, GFP_KERNEL);
2895 if (bufs == NULL) 2890 if (bufs == NULL)
@@ -2900,7 +2895,6 @@ static ssize_t snd_pcm_aio_write(struct kiocb *iocb, const struct iovec *iov,
2900 if (result > 0) 2895 if (result > 0)
2901 result = frames_to_bytes(runtime, result); 2896 result = frames_to_bytes(runtime, result);
2902 kfree(bufs); 2897 kfree(bufs);
2903 end:
2904 return result; 2898 return result;
2905} 2899}
2906 2900
@@ -2915,7 +2909,8 @@ static unsigned int snd_pcm_playback_poll(struct file *file, poll_table * wait)
2915 pcm_file = file->private_data; 2909 pcm_file = file->private_data;
2916 2910
2917 substream = pcm_file->substream; 2911 substream = pcm_file->substream;
2918 snd_assert(substream != NULL, return -ENXIO); 2912 if (PCM_RUNTIME_CHECK(substream))
2913 return -ENXIO;
2919 runtime = substream->runtime; 2914 runtime = substream->runtime;
2920 2915
2921 poll_wait(file, &runtime->sleep, wait); 2916 poll_wait(file, &runtime->sleep, wait);
@@ -2953,7 +2948,8 @@ static unsigned int snd_pcm_capture_poll(struct file *file, poll_table * wait)
2953 pcm_file = file->private_data; 2948 pcm_file = file->private_data;
2954 2949
2955 substream = pcm_file->substream; 2950 substream = pcm_file->substream;
2956 snd_assert(substream != NULL, return -ENXIO); 2951 if (PCM_RUNTIME_CHECK(substream))
2952 return -ENXIO;
2957 runtime = substream->runtime; 2953 runtime = substream->runtime;
2958 2954
2959 poll_wait(file, &runtime->sleep, wait); 2955 poll_wait(file, &runtime->sleep, wait);
@@ -3023,7 +3019,6 @@ static int snd_pcm_mmap_status(struct snd_pcm_substream *substream, struct file
3023 if (!(area->vm_flags & VM_READ)) 3019 if (!(area->vm_flags & VM_READ))
3024 return -EINVAL; 3020 return -EINVAL;
3025 runtime = substream->runtime; 3021 runtime = substream->runtime;
3026 snd_assert(runtime != NULL, return -EAGAIN);
3027 size = area->vm_end - area->vm_start; 3022 size = area->vm_end - area->vm_start;
3028 if (size != PAGE_ALIGN(sizeof(struct snd_pcm_mmap_status))) 3023 if (size != PAGE_ALIGN(sizeof(struct snd_pcm_mmap_status)))
3029 return -EINVAL; 3024 return -EINVAL;
@@ -3063,7 +3058,6 @@ static int snd_pcm_mmap_control(struct snd_pcm_substream *substream, struct file
3063 if (!(area->vm_flags & VM_READ)) 3058 if (!(area->vm_flags & VM_READ))
3064 return -EINVAL; 3059 return -EINVAL;
3065 runtime = substream->runtime; 3060 runtime = substream->runtime;
3066 snd_assert(runtime != NULL, return -EAGAIN);
3067 size = area->vm_end - area->vm_start; 3061 size = area->vm_end - area->vm_start;
3068 if (size != PAGE_ALIGN(sizeof(struct snd_pcm_mmap_control))) 3062 if (size != PAGE_ALIGN(sizeof(struct snd_pcm_mmap_control)))
3069 return -EINVAL; 3063 return -EINVAL;
@@ -3195,7 +3189,6 @@ int snd_pcm_mmap_data(struct snd_pcm_substream *substream, struct file *file,
3195 return -EINVAL; 3189 return -EINVAL;
3196 } 3190 }
3197 runtime = substream->runtime; 3191 runtime = substream->runtime;
3198 snd_assert(runtime != NULL, return -EAGAIN);
3199 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) 3192 if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
3200 return -EBADFD; 3193 return -EBADFD;
3201 if (!(runtime->info & SNDRV_PCM_INFO_MMAP)) 3194 if (!(runtime->info & SNDRV_PCM_INFO_MMAP))
@@ -3227,7 +3220,8 @@ static int snd_pcm_mmap(struct file *file, struct vm_area_struct *area)
3227 3220
3228 pcm_file = file->private_data; 3221 pcm_file = file->private_data;
3229 substream = pcm_file->substream; 3222 substream = pcm_file->substream;
3230 snd_assert(substream != NULL, return -ENXIO); 3223 if (PCM_RUNTIME_CHECK(substream))
3224 return -ENXIO;
3231 3225
3232 offset = area->vm_pgoff << PAGE_SHIFT; 3226 offset = area->vm_pgoff << PAGE_SHIFT;
3233 switch (offset) { 3227 switch (offset) {
@@ -3255,9 +3249,9 @@ static int snd_pcm_fasync(int fd, struct file * file, int on)
3255 lock_kernel(); 3249 lock_kernel();
3256 pcm_file = file->private_data; 3250 pcm_file = file->private_data;
3257 substream = pcm_file->substream; 3251 substream = pcm_file->substream;
3258 snd_assert(substream != NULL, goto out); 3252 if (PCM_RUNTIME_CHECK(substream))
3253 goto out;
3259 runtime = substream->runtime; 3254 runtime = substream->runtime;
3260
3261 err = fasync_helper(fd, file, on, &runtime->fasync); 3255 err = fasync_helper(fd, file, on, &runtime->fasync);
3262out: 3256out:
3263 unlock_kernel(); 3257 unlock_kernel();
@@ -3391,6 +3385,17 @@ out:
3391} 3385}
3392#endif /* CONFIG_SND_SUPPORT_OLD_API */ 3386#endif /* CONFIG_SND_SUPPORT_OLD_API */
3393 3387
3388#ifndef CONFIG_MMU
3389unsigned long dummy_get_unmapped_area(struct file *file, unsigned long addr,
3390 unsigned long len, unsigned long pgoff,
3391 unsigned long flags)
3392{
3393 return 0;
3394}
3395#else
3396# define dummy_get_unmapped_area NULL
3397#endif
3398
3394/* 3399/*
3395 * Register section 3400 * Register section
3396 */ 3401 */
@@ -3407,6 +3412,7 @@ const struct file_operations snd_pcm_f_ops[2] = {
3407 .compat_ioctl = snd_pcm_ioctl_compat, 3412 .compat_ioctl = snd_pcm_ioctl_compat,
3408 .mmap = snd_pcm_mmap, 3413 .mmap = snd_pcm_mmap,
3409 .fasync = snd_pcm_fasync, 3414 .fasync = snd_pcm_fasync,
3415 .get_unmapped_area = dummy_get_unmapped_area,
3410 }, 3416 },
3411 { 3417 {
3412 .owner = THIS_MODULE, 3418 .owner = THIS_MODULE,
@@ -3419,5 +3425,6 @@ const struct file_operations snd_pcm_f_ops[2] = {
3419 .compat_ioctl = snd_pcm_ioctl_compat, 3425 .compat_ioctl = snd_pcm_ioctl_compat,
3420 .mmap = snd_pcm_mmap, 3426 .mmap = snd_pcm_mmap,
3421 .fasync = snd_pcm_fasync, 3427 .fasync = snd_pcm_fasync,
3428 .get_unmapped_area = dummy_get_unmapped_area,
3422 } 3429 }
3423}; 3430};
diff --git a/sound/core/pcm_timer.c b/sound/core/pcm_timer.c
index 033a024d153a..2c89c04f2916 100644
--- a/sound/core/pcm_timer.c
+++ b/sound/core/pcm_timer.c
@@ -51,12 +51,14 @@ void snd_pcm_timer_resolution_change(struct snd_pcm_substream *substream)
51 51
52 mult = 1000000000; 52 mult = 1000000000;
53 rate = runtime->rate; 53 rate = runtime->rate;
54 snd_assert(rate != 0, return); 54 if (snd_BUG_ON(!rate))
55 return;
55 l = gcd(mult, rate); 56 l = gcd(mult, rate);
56 mult /= l; 57 mult /= l;
57 rate /= l; 58 rate /= l;
58 fsize = runtime->period_size; 59 fsize = runtime->period_size;
59 snd_assert(fsize != 0, return); 60 if (snd_BUG_ON(!fsize))
61 return;
60 l = gcd(rate, fsize); 62 l = gcd(rate, fsize);
61 rate /= l; 63 rate /= l;
62 fsize /= l; 64 fsize /= l;
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index f7ea7287c59c..c4995c9f5730 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -418,7 +418,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
418 mutex_lock(&rmidi->open_mutex); 418 mutex_lock(&rmidi->open_mutex);
419 while (1) { 419 while (1) {
420 subdevice = -1; 420 subdevice = -1;
421 down_read(&card->controls_rwsem); 421 read_lock(&card->ctl_files_rwlock);
422 list_for_each_entry(kctl, &card->ctl_files, list) { 422 list_for_each_entry(kctl, &card->ctl_files, list) {
423 if (kctl->pid == current->pid) { 423 if (kctl->pid == current->pid) {
424 subdevice = kctl->prefer_rawmidi_subdevice; 424 subdevice = kctl->prefer_rawmidi_subdevice;
@@ -426,7 +426,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
426 break; 426 break;
427 } 427 }
428 } 428 }
429 up_read(&card->controls_rwsem); 429 read_unlock(&card->ctl_files_rwlock);
430 err = snd_rawmidi_kernel_open(rmidi->card, rmidi->device, 430 err = snd_rawmidi_kernel_open(rmidi->card, rmidi->device,
431 subdevice, fflags, rawmidi_file); 431 subdevice, fflags, rawmidi_file);
432 if (err >= 0) 432 if (err >= 0)
@@ -470,8 +470,8 @@ int snd_rawmidi_kernel_release(struct snd_rawmidi_file * rfile)
470 struct snd_rawmidi_substream *substream; 470 struct snd_rawmidi_substream *substream;
471 struct snd_rawmidi_runtime *runtime; 471 struct snd_rawmidi_runtime *runtime;
472 472
473 snd_assert(rfile != NULL, return -ENXIO); 473 if (snd_BUG_ON(!rfile))
474 snd_assert(rfile->input != NULL || rfile->output != NULL, return -ENXIO); 474 return -ENXIO;
475 rmidi = rfile->rmidi; 475 rmidi = rfile->rmidi;
476 mutex_lock(&rmidi->open_mutex); 476 mutex_lock(&rmidi->open_mutex);
477 if (rfile->input != NULL) { 477 if (rfile->input != NULL) {
@@ -1100,7 +1100,7 @@ int snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int count)
1100 return -EINVAL; 1100 return -EINVAL;
1101 } 1101 }
1102 spin_lock_irqsave(&runtime->lock, flags); 1102 spin_lock_irqsave(&runtime->lock, flags);
1103 snd_assert(runtime->avail + count <= runtime->buffer_size, ); 1103 snd_BUG_ON(runtime->avail + count > runtime->buffer_size);
1104 runtime->hw_ptr += count; 1104 runtime->hw_ptr += count;
1105 runtime->hw_ptr %= runtime->buffer_size; 1105 runtime->hw_ptr %= runtime->buffer_size;
1106 runtime->avail += count; 1106 runtime->avail += count;
@@ -1141,8 +1141,10 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream,
1141 long count1, result; 1141 long count1, result;
1142 struct snd_rawmidi_runtime *runtime = substream->runtime; 1142 struct snd_rawmidi_runtime *runtime = substream->runtime;
1143 1143
1144 snd_assert(kernelbuf != NULL || userbuf != NULL, return -EINVAL); 1144 if (snd_BUG_ON(!kernelbuf && !userbuf))
1145 snd_assert(runtime->buffer != NULL, return -EINVAL); 1145 return -EINVAL;
1146 if (snd_BUG_ON(!runtime->buffer))
1147 return -EINVAL;
1146 1148
1147 result = 0; 1149 result = 0;
1148 spin_lock_irqsave(&runtime->lock, flags); 1150 spin_lock_irqsave(&runtime->lock, flags);
@@ -1420,9 +1422,10 @@ int snd_rawmidi_new(struct snd_card *card, char *id, int device,
1420 .dev_disconnect = snd_rawmidi_dev_disconnect, 1422 .dev_disconnect = snd_rawmidi_dev_disconnect,
1421 }; 1423 };
1422 1424
1423 snd_assert(rrawmidi != NULL, return -EINVAL); 1425 if (snd_BUG_ON(!card))
1424 *rrawmidi = NULL; 1426 return -ENXIO;
1425 snd_assert(card != NULL, return -ENXIO); 1427 if (rrawmidi)
1428 *rrawmidi = NULL;
1426 rmidi = kzalloc(sizeof(*rmidi), GFP_KERNEL); 1429 rmidi = kzalloc(sizeof(*rmidi), GFP_KERNEL);
1427 if (rmidi == NULL) { 1430 if (rmidi == NULL) {
1428 snd_printk(KERN_ERR "rawmidi: cannot allocate\n"); 1431 snd_printk(KERN_ERR "rawmidi: cannot allocate\n");
@@ -1455,7 +1458,8 @@ int snd_rawmidi_new(struct snd_card *card, char *id, int device,
1455 snd_rawmidi_free(rmidi); 1458 snd_rawmidi_free(rmidi);
1456 return err; 1459 return err;
1457 } 1460 }
1458 *rrawmidi = rmidi; 1461 if (rrawmidi)
1462 *rrawmidi = rmidi;
1459 return 0; 1463 return 0;
1460} 1464}
1461 1465
@@ -1472,7 +1476,8 @@ static void snd_rawmidi_free_substreams(struct snd_rawmidi_str *stream)
1472 1476
1473static int snd_rawmidi_free(struct snd_rawmidi *rmidi) 1477static int snd_rawmidi_free(struct snd_rawmidi *rmidi)
1474{ 1478{
1475 snd_assert(rmidi != NULL, return -ENXIO); 1479 if (!rmidi)
1480 return 0;
1476 1481
1477 snd_info_free_entry(rmidi->proc_entry); 1482 snd_info_free_entry(rmidi->proc_entry);
1478 rmidi->proc_entry = NULL; 1483 rmidi->proc_entry = NULL;
diff --git a/sound/core/rtctimer.c b/sound/core/rtctimer.c
index 97b30fb4c361..51e64e30dd3b 100644
--- a/sound/core/rtctimer.c
+++ b/sound/core/rtctimer.c
@@ -91,7 +91,8 @@ static int
91rtctimer_start(struct snd_timer *timer) 91rtctimer_start(struct snd_timer *timer)
92{ 92{
93 rtc_task_t *rtc = timer->private_data; 93 rtc_task_t *rtc = timer->private_data;
94 snd_assert(rtc != NULL, return -EINVAL); 94 if (snd_BUG_ON(!rtc))
95 return -EINVAL;
95 rtc_control(rtc, RTC_IRQP_SET, rtctimer_freq); 96 rtc_control(rtc, RTC_IRQP_SET, rtctimer_freq);
96 rtc_control(rtc, RTC_PIE_ON, 0); 97 rtc_control(rtc, RTC_PIE_ON, 0);
97 return 0; 98 return 0;
@@ -101,7 +102,8 @@ static int
101rtctimer_stop(struct snd_timer *timer) 102rtctimer_stop(struct snd_timer *timer)
102{ 103{
103 rtc_task_t *rtc = timer->private_data; 104 rtc_task_t *rtc = timer->private_data;
104 snd_assert(rtc != NULL, return -EINVAL); 105 if (snd_BUG_ON(!rtc))
106 return -EINVAL;
105 rtc_control(rtc, RTC_PIE_OFF, 0); 107 rtc_control(rtc, RTC_PIE_OFF, 0);
106 return 0; 108 return 0;
107} 109}
diff --git a/sound/core/seq/oss/seq_oss.c b/sound/core/seq/oss/seq_oss.c
index 777796e94490..f25e3cc7ddfa 100644
--- a/sound/core/seq/oss/seq_oss.c
+++ b/sound/core/seq/oss/seq_oss.c
@@ -164,7 +164,8 @@ odev_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
164{ 164{
165 struct seq_oss_devinfo *dp; 165 struct seq_oss_devinfo *dp;
166 dp = file->private_data; 166 dp = file->private_data;
167 snd_assert(dp != NULL, return -EIO); 167 if (snd_BUG_ON(!dp))
168 return -ENXIO;
168 return snd_seq_oss_read(dp, buf, count); 169 return snd_seq_oss_read(dp, buf, count);
169} 170}
170 171
@@ -174,7 +175,8 @@ odev_write(struct file *file, const char __user *buf, size_t count, loff_t *offs
174{ 175{
175 struct seq_oss_devinfo *dp; 176 struct seq_oss_devinfo *dp;
176 dp = file->private_data; 177 dp = file->private_data;
177 snd_assert(dp != NULL, return -EIO); 178 if (snd_BUG_ON(!dp))
179 return -ENXIO;
178 return snd_seq_oss_write(dp, buf, count, file); 180 return snd_seq_oss_write(dp, buf, count, file);
179} 181}
180 182
@@ -183,7 +185,8 @@ odev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
183{ 185{
184 struct seq_oss_devinfo *dp; 186 struct seq_oss_devinfo *dp;
185 dp = file->private_data; 187 dp = file->private_data;
186 snd_assert(dp != NULL, return -EIO); 188 if (snd_BUG_ON(!dp))
189 return -ENXIO;
187 return snd_seq_oss_ioctl(dp, cmd, arg); 190 return snd_seq_oss_ioctl(dp, cmd, arg);
188} 191}
189 192
@@ -198,7 +201,8 @@ odev_poll(struct file *file, poll_table * wait)
198{ 201{
199 struct seq_oss_devinfo *dp; 202 struct seq_oss_devinfo *dp;
200 dp = file->private_data; 203 dp = file->private_data;
201 snd_assert(dp != NULL, return 0); 204 if (snd_BUG_ON(!dp))
205 return -ENXIO;
202 return snd_seq_oss_poll(dp, file, wait); 206 return snd_seq_oss_poll(dp, file, wait);
203} 207}
204 208
diff --git a/sound/core/seq/oss/seq_oss_synth.c b/sound/core/seq/oss/seq_oss_synth.c
index e024e4588b82..945a27c34a9d 100644
--- a/sound/core/seq/oss/seq_oss_synth.c
+++ b/sound/core/seq/oss/seq_oss_synth.c
@@ -308,7 +308,8 @@ snd_seq_oss_synth_cleanup(struct seq_oss_devinfo *dp)
308 struct seq_oss_synth *rec; 308 struct seq_oss_synth *rec;
309 struct seq_oss_synthinfo *info; 309 struct seq_oss_synthinfo *info;
310 310
311 snd_assert(dp->max_synthdev <= SNDRV_SEQ_OSS_MAX_SYNTH_DEVS, return); 311 if (snd_BUG_ON(dp->max_synthdev >= SNDRV_SEQ_OSS_MAX_SYNTH_DEVS))
312 return;
312 for (i = 0; i < dp->max_synthdev; i++) { 313 for (i = 0; i < dp->max_synthdev; i++) {
313 info = &dp->synths[i]; 314 info = &dp->synths[i];
314 if (! info->opened) 315 if (! info->opened)
@@ -402,7 +403,8 @@ snd_seq_oss_synth_reset(struct seq_oss_devinfo *dp, int dev)
402 struct seq_oss_synth *rec; 403 struct seq_oss_synth *rec;
403 struct seq_oss_synthinfo *info; 404 struct seq_oss_synthinfo *info;
404 405
405 snd_assert(dev >= 0 && dev < dp->max_synthdev, return); 406 if (snd_BUG_ON(dev < 0 || dev >= dp->max_synthdev))
407 return;
406 info = &dp->synths[dev]; 408 info = &dp->synths[dev];
407 if (! info->opened) 409 if (! info->opened)
408 return; 410 return;
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
index 7a1545d2d953..8ca2be339f3b 100644
--- a/sound/core/seq/seq_clientmgr.c
+++ b/sound/core/seq/seq_clientmgr.c
@@ -266,7 +266,8 @@ static int seq_free_client1(struct snd_seq_client *client)
266{ 266{
267 unsigned long flags; 267 unsigned long flags;
268 268
269 snd_assert(client != NULL, return -EINVAL); 269 if (!client)
270 return 0;
270 snd_seq_delete_all_ports(client); 271 snd_seq_delete_all_ports(client);
271 snd_seq_queue_client_leave(client->number); 272 snd_seq_queue_client_leave(client->number);
272 spin_lock_irqsave(&clients_lock, flags); 273 spin_lock_irqsave(&clients_lock, flags);
@@ -403,7 +404,8 @@ static ssize_t snd_seq_read(struct file *file, char __user *buf, size_t count,
403 return -EFAULT; 404 return -EFAULT;
404 405
405 /* check client structures are in place */ 406 /* check client structures are in place */
406 snd_assert(client != NULL, return -ENXIO); 407 if (snd_BUG_ON(!client))
408 return -ENXIO;
407 409
408 if (!client->accept_input || (fifo = client->data.user.fifo) == NULL) 410 if (!client->accept_input || (fifo = client->data.user.fifo) == NULL)
409 return -ENXIO; 411 return -ENXIO;
@@ -825,7 +827,8 @@ int snd_seq_dispatch_event(struct snd_seq_event_cell *cell, int atomic, int hop)
825 struct snd_seq_client *client; 827 struct snd_seq_client *client;
826 int result; 828 int result;
827 829
828 snd_assert(cell != NULL, return -EINVAL); 830 if (snd_BUG_ON(!cell))
831 return -EINVAL;
829 832
830 client = snd_seq_client_use_ptr(cell->event.source.client); 833 client = snd_seq_client_use_ptr(cell->event.source.client);
831 if (client == NULL) { 834 if (client == NULL) {
@@ -994,7 +997,8 @@ static ssize_t snd_seq_write(struct file *file, const char __user *buf,
994 return -ENXIO; 997 return -ENXIO;
995 998
996 /* check client structures are in place */ 999 /* check client structures are in place */
997 snd_assert(client != NULL, return -ENXIO); 1000 if (snd_BUG_ON(!client))
1001 return -ENXIO;
998 1002
999 if (!client->accept_output || client->pool == NULL) 1003 if (!client->accept_output || client->pool == NULL)
1000 return -ENXIO; 1004 return -ENXIO;
@@ -1076,7 +1080,8 @@ static unsigned int snd_seq_poll(struct file *file, poll_table * wait)
1076 unsigned int mask = 0; 1080 unsigned int mask = 0;
1077 1081
1078 /* check client structures are in place */ 1082 /* check client structures are in place */
1079 snd_assert(client != NULL, return -ENXIO); 1083 if (snd_BUG_ON(!client))
1084 return -ENXIO;
1080 1085
1081 if ((snd_seq_file_flags(file) & SNDRV_SEQ_LFLG_INPUT) && 1086 if ((snd_seq_file_flags(file) & SNDRV_SEQ_LFLG_INPUT) &&
1082 client->data.user.fifo) { 1087 client->data.user.fifo) {
@@ -2195,7 +2200,8 @@ static long snd_seq_ioctl(struct file *file, unsigned int cmd, unsigned long arg
2195{ 2200{
2196 struct snd_seq_client *client = file->private_data; 2201 struct snd_seq_client *client = file->private_data;
2197 2202
2198 snd_assert(client != NULL, return -ENXIO); 2203 if (snd_BUG_ON(!client))
2204 return -ENXIO;
2199 2205
2200 return snd_seq_do_ioctl(client, cmd, (void __user *) arg); 2206 return snd_seq_do_ioctl(client, cmd, (void __user *) arg);
2201} 2207}
@@ -2216,7 +2222,8 @@ int snd_seq_create_kernel_client(struct snd_card *card, int client_index,
2216 struct snd_seq_client *client; 2222 struct snd_seq_client *client;
2217 va_list args; 2223 va_list args;
2218 2224
2219 snd_assert(! in_interrupt(), return -EBUSY); 2225 if (snd_BUG_ON(in_interrupt()))
2226 return -EBUSY;
2220 2227
2221 if (card && client_index >= SNDRV_SEQ_CLIENTS_PER_CARD) 2228 if (card && client_index >= SNDRV_SEQ_CLIENTS_PER_CARD)
2222 return -EINVAL; 2229 return -EINVAL;
@@ -2265,7 +2272,8 @@ int snd_seq_delete_kernel_client(int client)
2265{ 2272{
2266 struct snd_seq_client *ptr; 2273 struct snd_seq_client *ptr;
2267 2274
2268 snd_assert(! in_interrupt(), return -EBUSY); 2275 if (snd_BUG_ON(in_interrupt()))
2276 return -EBUSY;
2269 2277
2270 ptr = clientptr(client); 2278 ptr = clientptr(client);
2271 if (ptr == NULL) 2279 if (ptr == NULL)
@@ -2288,7 +2296,8 @@ static int kernel_client_enqueue(int client, struct snd_seq_event *ev,
2288 struct snd_seq_client *cptr; 2296 struct snd_seq_client *cptr;
2289 int result; 2297 int result;
2290 2298
2291 snd_assert(ev != NULL, return -EINVAL); 2299 if (snd_BUG_ON(!ev))
2300 return -EINVAL;
2292 2301
2293 if (ev->type == SNDRV_SEQ_EVENT_NONE) 2302 if (ev->type == SNDRV_SEQ_EVENT_NONE)
2294 return 0; /* ignore this */ 2303 return 0; /* ignore this */
@@ -2354,7 +2363,8 @@ int snd_seq_kernel_client_dispatch(int client, struct snd_seq_event * ev,
2354 struct snd_seq_client *cptr; 2363 struct snd_seq_client *cptr;
2355 int result; 2364 int result;
2356 2365
2357 snd_assert(ev != NULL, return -EINVAL); 2366 if (snd_BUG_ON(!ev))
2367 return -EINVAL;
2358 2368
2359 /* fill in client number */ 2369 /* fill in client number */
2360 ev->queue = SNDRV_SEQ_QUEUE_DIRECT; 2370 ev->queue = SNDRV_SEQ_QUEUE_DIRECT;
diff --git a/sound/core/seq/seq_compat.c b/sound/core/seq/seq_compat.c
index 9628c06e4eab..38693f47c262 100644
--- a/sound/core/seq/seq_compat.c
+++ b/sound/core/seq/seq_compat.c
@@ -92,7 +92,8 @@ static long snd_seq_ioctl_compat(struct file *file, unsigned int cmd, unsigned l
92 struct snd_seq_client *client = file->private_data; 92 struct snd_seq_client *client = file->private_data;
93 void __user *argp = compat_ptr(arg); 93 void __user *argp = compat_ptr(arg);
94 94
95 snd_assert(client != NULL, return -ENXIO); 95 if (snd_BUG_ON(!client))
96 return -ENXIO;
96 97
97 switch (cmd) { 98 switch (cmd) {
98 case SNDRV_SEQ_IOCTL_PVERSION: 99 case SNDRV_SEQ_IOCTL_PVERSION:
diff --git a/sound/core/seq/seq_device.c b/sound/core/seq/seq_device.c
index 05410e536a4f..1f997675c893 100644
--- a/sound/core/seq/seq_device.c
+++ b/sound/core/seq/seq_device.c
@@ -187,7 +187,8 @@ int snd_seq_device_new(struct snd_card *card, int device, char *id, int argsize,
187 if (result) 187 if (result)
188 *result = NULL; 188 *result = NULL;
189 189
190 snd_assert(id != NULL, return -EINVAL); 190 if (snd_BUG_ON(!id))
191 return -EINVAL;
191 192
192 ops = find_driver(id, 1); 193 ops = find_driver(id, 1);
193 if (ops == NULL) 194 if (ops == NULL)
@@ -232,7 +233,8 @@ static int snd_seq_device_free(struct snd_seq_device *dev)
232{ 233{
233 struct ops_list *ops; 234 struct ops_list *ops;
234 235
235 snd_assert(dev != NULL, return -EINVAL); 236 if (snd_BUG_ON(!dev))
237 return -EINVAL;
236 238
237 ops = find_driver(dev->id, 0); 239 ops = find_driver(dev->id, 0);
238 if (ops == NULL) 240 if (ops == NULL)
diff --git a/sound/core/seq/seq_fifo.c b/sound/core/seq/seq_fifo.c
index 3a94ed021bd9..0d75afa786bc 100644
--- a/sound/core/seq/seq_fifo.c
+++ b/sound/core/seq/seq_fifo.c
@@ -65,9 +65,11 @@ void snd_seq_fifo_delete(struct snd_seq_fifo **fifo)
65{ 65{
66 struct snd_seq_fifo *f; 66 struct snd_seq_fifo *f;
67 67
68 snd_assert(fifo != NULL, return); 68 if (snd_BUG_ON(!fifo))
69 return;
69 f = *fifo; 70 f = *fifo;
70 snd_assert(f != NULL, return); 71 if (snd_BUG_ON(!f))
72 return;
71 *fifo = NULL; 73 *fifo = NULL;
72 74
73 snd_seq_fifo_clear(f); 75 snd_seq_fifo_clear(f);
@@ -116,7 +118,8 @@ int snd_seq_fifo_event_in(struct snd_seq_fifo *f,
116 unsigned long flags; 118 unsigned long flags;
117 int err; 119 int err;
118 120
119 snd_assert(f != NULL, return -EINVAL); 121 if (snd_BUG_ON(!f))
122 return -EINVAL;
120 123
121 snd_use_lock_use(&f->use_lock); 124 snd_use_lock_use(&f->use_lock);
122 err = snd_seq_event_dup(f->pool, event, &cell, 1, NULL); /* always non-blocking */ 125 err = snd_seq_event_dup(f->pool, event, &cell, 1, NULL); /* always non-blocking */
@@ -174,7 +177,8 @@ int snd_seq_fifo_cell_out(struct snd_seq_fifo *f,
174 unsigned long flags; 177 unsigned long flags;
175 wait_queue_t wait; 178 wait_queue_t wait;
176 179
177 snd_assert(f != NULL, return -EINVAL); 180 if (snd_BUG_ON(!f))
181 return -EINVAL;
178 182
179 *cellp = NULL; 183 *cellp = NULL;
180 init_waitqueue_entry(&wait, current); 184 init_waitqueue_entry(&wait, current);
@@ -233,7 +237,8 @@ int snd_seq_fifo_resize(struct snd_seq_fifo *f, int poolsize)
233 struct snd_seq_pool *newpool, *oldpool; 237 struct snd_seq_pool *newpool, *oldpool;
234 struct snd_seq_event_cell *cell, *next, *oldhead; 238 struct snd_seq_event_cell *cell, *next, *oldhead;
235 239
236 snd_assert(f != NULL && f->pool != NULL, return -EINVAL); 240 if (snd_BUG_ON(!f || !f->pool))
241 return -EINVAL;
237 242
238 /* allocate new pool */ 243 /* allocate new pool */
239 newpool = snd_seq_pool_new(poolsize); 244 newpool = snd_seq_pool_new(poolsize);
diff --git a/sound/core/seq/seq_memory.c b/sound/core/seq/seq_memory.c
index 0cf6ac477318..7fb55436287f 100644
--- a/sound/core/seq/seq_memory.c
+++ b/sound/core/seq/seq_memory.c
@@ -187,9 +187,11 @@ void snd_seq_cell_free(struct snd_seq_event_cell * cell)
187 unsigned long flags; 187 unsigned long flags;
188 struct snd_seq_pool *pool; 188 struct snd_seq_pool *pool;
189 189
190 snd_assert(cell != NULL, return); 190 if (snd_BUG_ON(!cell))
191 return;
191 pool = cell->pool; 192 pool = cell->pool;
192 snd_assert(pool != NULL, return); 193 if (snd_BUG_ON(!pool))
194 return;
193 195
194 spin_lock_irqsave(&pool->lock, flags); 196 spin_lock_irqsave(&pool->lock, flags);
195 free_cell(pool, cell); 197 free_cell(pool, cell);
@@ -378,7 +380,8 @@ int snd_seq_pool_init(struct snd_seq_pool *pool)
378 struct snd_seq_event_cell *cellptr; 380 struct snd_seq_event_cell *cellptr;
379 unsigned long flags; 381 unsigned long flags;
380 382
381 snd_assert(pool != NULL, return -EINVAL); 383 if (snd_BUG_ON(!pool))
384 return -EINVAL;
382 if (pool->ptr) /* should be atomic? */ 385 if (pool->ptr) /* should be atomic? */
383 return 0; 386 return 0;
384 387
@@ -414,7 +417,8 @@ int snd_seq_pool_done(struct snd_seq_pool *pool)
414 struct snd_seq_event_cell *ptr; 417 struct snd_seq_event_cell *ptr;
415 int max_count = 5 * HZ; 418 int max_count = 5 * HZ;
416 419
417 snd_assert(pool != NULL, return -EINVAL); 420 if (snd_BUG_ON(!pool))
421 return -EINVAL;
418 422
419 /* wait for closing all threads */ 423 /* wait for closing all threads */
420 spin_lock_irqsave(&pool->lock, flags); 424 spin_lock_irqsave(&pool->lock, flags);
diff --git a/sound/core/seq/seq_midi.c b/sound/core/seq/seq_midi.c
index 99b35360c506..4d26146a62cc 100644
--- a/sound/core/seq/seq_midi.c
+++ b/sound/core/seq/seq_midi.c
@@ -116,7 +116,8 @@ static int dump_midi(struct snd_rawmidi_substream *substream, const char *buf, i
116 struct snd_rawmidi_runtime *runtime; 116 struct snd_rawmidi_runtime *runtime;
117 int tmp; 117 int tmp;
118 118
119 snd_assert(substream != NULL || buf != NULL, return -EINVAL); 119 if (snd_BUG_ON(!substream || !buf))
120 return -EINVAL;
120 runtime = substream->runtime; 121 runtime = substream->runtime;
121 if ((tmp = runtime->avail) < count) { 122 if ((tmp = runtime->avail) < count) {
122 snd_printd("warning, output event was lost (count = %i, available = %i)\n", count, tmp); 123 snd_printd("warning, output event was lost (count = %i, available = %i)\n", count, tmp);
@@ -135,7 +136,8 @@ static int event_process_midi(struct snd_seq_event *ev, int direct,
135 struct snd_rawmidi_substream *substream; 136 struct snd_rawmidi_substream *substream;
136 int len; 137 int len;
137 138
138 snd_assert(msynth != NULL, return -EINVAL); 139 if (snd_BUG_ON(!msynth))
140 return -EINVAL;
139 substream = msynth->output_rfile.output; 141 substream = msynth->output_rfile.output;
140 if (substream == NULL) 142 if (substream == NULL)
141 return -ENODEV; 143 return -ENODEV;
@@ -210,7 +212,8 @@ static int midisynth_unsubscribe(void *private_data, struct snd_seq_port_subscri
210 int err; 212 int err;
211 struct seq_midisynth *msynth = private_data; 213 struct seq_midisynth *msynth = private_data;
212 214
213 snd_assert(msynth->input_rfile.input != NULL, return -EINVAL); 215 if (snd_BUG_ON(!msynth->input_rfile.input))
216 return -EINVAL;
214 err = snd_rawmidi_kernel_release(&msynth->input_rfile); 217 err = snd_rawmidi_kernel_release(&msynth->input_rfile);
215 return err; 218 return err;
216} 219}
@@ -247,7 +250,8 @@ static int midisynth_unuse(void *private_data, struct snd_seq_port_subscribe *in
247 struct seq_midisynth *msynth = private_data; 250 struct seq_midisynth *msynth = private_data;
248 unsigned char buf = 0xff; /* MIDI reset */ 251 unsigned char buf = 0xff; /* MIDI reset */
249 252
250 snd_assert(msynth->output_rfile.output != NULL, return -EINVAL); 253 if (snd_BUG_ON(!msynth->output_rfile.output))
254 return -EINVAL;
251 /* sending single MIDI reset message to shut the device up */ 255 /* sending single MIDI reset message to shut the device up */
252 snd_rawmidi_kernel_write(msynth->output_rfile.output, &buf, 1); 256 snd_rawmidi_kernel_write(msynth->output_rfile.output, &buf, 1);
253 snd_rawmidi_drain_output(msynth->output_rfile.output); 257 snd_rawmidi_drain_output(msynth->output_rfile.output);
@@ -285,7 +289,8 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev)
285 int device = dev->device; 289 int device = dev->device;
286 unsigned int input_count = 0, output_count = 0; 290 unsigned int input_count = 0, output_count = 0;
287 291
288 snd_assert(card != NULL && device >= 0 && device < SNDRV_RAWMIDI_DEVICES, return -EINVAL); 292 if (snd_BUG_ON(!card || device < 0 || device >= SNDRV_RAWMIDI_DEVICES))
293 return -EINVAL;
289 info = kmalloc(sizeof(*info), GFP_KERNEL); 294 info = kmalloc(sizeof(*info), GFP_KERNEL);
290 if (! info) 295 if (! info)
291 return -ENOMEM; 296 return -ENOMEM;
diff --git a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c
index 1c32a53d6bd8..3bf7d73ac52e 100644
--- a/sound/core/seq/seq_ports.c
+++ b/sound/core/seq/seq_ports.c
@@ -130,7 +130,8 @@ struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client,
130 int num = -1; 130 int num = -1;
131 131
132 /* sanity check */ 132 /* sanity check */
133 snd_assert(client, return NULL); 133 if (snd_BUG_ON(!client))
134 return NULL;
134 135
135 if (client->num_ports >= SNDRV_SEQ_MAX_PORTS - 1) { 136 if (client->num_ports >= SNDRV_SEQ_MAX_PORTS - 1) {
136 snd_printk(KERN_WARNING "too many ports for client %d\n", client->number); 137 snd_printk(KERN_WARNING "too many ports for client %d\n", client->number);
@@ -268,8 +269,8 @@ static int port_delete(struct snd_seq_client *client,
268 if (port->private_free) 269 if (port->private_free)
269 port->private_free(port->private_data); 270 port->private_free(port->private_data);
270 271
271 snd_assert(port->c_src.count == 0,); 272 snd_BUG_ON(port->c_src.count != 0);
272 snd_assert(port->c_dest.count == 0,); 273 snd_BUG_ON(port->c_dest.count != 0);
273 274
274 kfree(port); 275 kfree(port);
275 return 0; 276 return 0;
@@ -336,7 +337,8 @@ int snd_seq_delete_all_ports(struct snd_seq_client *client)
336int snd_seq_set_port_info(struct snd_seq_client_port * port, 337int snd_seq_set_port_info(struct snd_seq_client_port * port,
337 struct snd_seq_port_info * info) 338 struct snd_seq_port_info * info)
338{ 339{
339 snd_assert(port && info, return -EINVAL); 340 if (snd_BUG_ON(!port || !info))
341 return -EINVAL;
340 342
341 /* set port name */ 343 /* set port name */
342 if (info->name[0]) 344 if (info->name[0])
@@ -365,7 +367,8 @@ int snd_seq_set_port_info(struct snd_seq_client_port * port,
365int snd_seq_get_port_info(struct snd_seq_client_port * port, 367int snd_seq_get_port_info(struct snd_seq_client_port * port,
366 struct snd_seq_port_info * info) 368 struct snd_seq_port_info * info)
367{ 369{
368 snd_assert(port && info, return -EINVAL); 370 if (snd_BUG_ON(!port || !info))
371 return -EINVAL;
369 372
370 /* get port name */ 373 /* get port name */
371 strlcpy(info->name, port->name, sizeof(info->name)); 374 strlcpy(info->name, port->name, sizeof(info->name));
diff --git a/sound/core/seq/seq_prioq.c b/sound/core/seq/seq_prioq.c
index 85969db576c9..0101a8b99b73 100644
--- a/sound/core/seq/seq_prioq.c
+++ b/sound/core/seq/seq_prioq.c
@@ -153,8 +153,8 @@ int snd_seq_prioq_cell_in(struct snd_seq_prioq * f,
153 int count; 153 int count;
154 int prior; 154 int prior;
155 155
156 snd_assert(f, return -EINVAL); 156 if (snd_BUG_ON(!f || !cell))
157 snd_assert(cell, return -EINVAL); 157 return -EINVAL;
158 158
159 /* check flags */ 159 /* check flags */
160 prior = (cell->event.flags & SNDRV_SEQ_PRIORITY_MASK); 160 prior = (cell->event.flags & SNDRV_SEQ_PRIORITY_MASK);
diff --git a/sound/core/seq/seq_queue.c b/sound/core/seq/seq_queue.c
index 4a48c6ee8ee8..e7a8e9e4edb2 100644
--- a/sound/core/seq/seq_queue.c
+++ b/sound/core/seq/seq_queue.c
@@ -315,7 +315,8 @@ int snd_seq_enqueue_event(struct snd_seq_event_cell *cell, int atomic, int hop)
315 int dest, err; 315 int dest, err;
316 struct snd_seq_queue *q; 316 struct snd_seq_queue *q;
317 317
318 snd_assert(cell != NULL, return -EINVAL); 318 if (snd_BUG_ON(!cell))
319 return -EINVAL;
319 dest = cell->event.queue; /* destination queue */ 320 dest = cell->event.queue; /* destination queue */
320 q = queueptr(dest); 321 q = queueptr(dest);
321 if (q == NULL) 322 if (q == NULL)
@@ -734,7 +735,8 @@ int snd_seq_control_queue(struct snd_seq_event *ev, int atomic, int hop)
734{ 735{
735 struct snd_seq_queue *q; 736 struct snd_seq_queue *q;
736 737
737 snd_assert(ev != NULL, return -EINVAL); 738 if (snd_BUG_ON(!ev))
739 return -EINVAL;
738 q = queueptr(ev->data.queue.queue); 740 q = queueptr(ev->data.queue.queue);
739 741
740 if (q == NULL) 742 if (q == NULL)
diff --git a/sound/core/seq/seq_timer.c b/sound/core/seq/seq_timer.c
index d8fcd62e400f..f745c317d6af 100644
--- a/sound/core/seq/seq_timer.c
+++ b/sound/core/seq/seq_timer.c
@@ -173,7 +173,8 @@ int snd_seq_timer_set_tempo(struct snd_seq_timer * tmr, int tempo)
173{ 173{
174 unsigned long flags; 174 unsigned long flags;
175 175
176 snd_assert(tmr, return -EINVAL); 176 if (snd_BUG_ON(!tmr))
177 return -EINVAL;
177 if (tempo <= 0) 178 if (tempo <= 0)
178 return -EINVAL; 179 return -EINVAL;
179 spin_lock_irqsave(&tmr->lock, flags); 180 spin_lock_irqsave(&tmr->lock, flags);
@@ -190,7 +191,8 @@ int snd_seq_timer_set_ppq(struct snd_seq_timer * tmr, int ppq)
190{ 191{
191 unsigned long flags; 192 unsigned long flags;
192 193
193 snd_assert(tmr, return -EINVAL); 194 if (snd_BUG_ON(!tmr))
195 return -EINVAL;
194 if (ppq <= 0) 196 if (ppq <= 0)
195 return -EINVAL; 197 return -EINVAL;
196 spin_lock_irqsave(&tmr->lock, flags); 198 spin_lock_irqsave(&tmr->lock, flags);
@@ -214,7 +216,8 @@ int snd_seq_timer_set_position_tick(struct snd_seq_timer *tmr,
214{ 216{
215 unsigned long flags; 217 unsigned long flags;
216 218
217 snd_assert(tmr, return -EINVAL); 219 if (snd_BUG_ON(!tmr))
220 return -EINVAL;
218 221
219 spin_lock_irqsave(&tmr->lock, flags); 222 spin_lock_irqsave(&tmr->lock, flags);
220 tmr->tick.cur_tick = position; 223 tmr->tick.cur_tick = position;
@@ -229,7 +232,8 @@ int snd_seq_timer_set_position_time(struct snd_seq_timer *tmr,
229{ 232{
230 unsigned long flags; 233 unsigned long flags;
231 234
232 snd_assert(tmr, return -EINVAL); 235 if (snd_BUG_ON(!tmr))
236 return -EINVAL;
233 237
234 snd_seq_sanity_real_time(&position); 238 snd_seq_sanity_real_time(&position);
235 spin_lock_irqsave(&tmr->lock, flags); 239 spin_lock_irqsave(&tmr->lock, flags);
@@ -244,7 +248,8 @@ int snd_seq_timer_set_skew(struct snd_seq_timer *tmr, unsigned int skew,
244{ 248{
245 unsigned long flags; 249 unsigned long flags;
246 250
247 snd_assert(tmr, return -EINVAL); 251 if (snd_BUG_ON(!tmr))
252 return -EINVAL;
248 253
249 /* FIXME */ 254 /* FIXME */
250 if (base != SKEW_BASE) { 255 if (base != SKEW_BASE) {
@@ -265,7 +270,8 @@ int snd_seq_timer_open(struct snd_seq_queue *q)
265 int err; 270 int err;
266 271
267 tmr = q->timer; 272 tmr = q->timer;
268 snd_assert(tmr != NULL, return -EINVAL); 273 if (snd_BUG_ON(!tmr))
274 return -EINVAL;
269 if (tmr->timeri) 275 if (tmr->timeri)
270 return -EBUSY; 276 return -EBUSY;
271 sprintf(str, "sequencer queue %i", q->queue); 277 sprintf(str, "sequencer queue %i", q->queue);
@@ -302,7 +308,8 @@ int snd_seq_timer_close(struct snd_seq_queue *q)
302 struct snd_seq_timer *tmr; 308 struct snd_seq_timer *tmr;
303 309
304 tmr = q->timer; 310 tmr = q->timer;
305 snd_assert(tmr != NULL, return -EINVAL); 311 if (snd_BUG_ON(!tmr))
312 return -EINVAL;
306 if (tmr->timeri) { 313 if (tmr->timeri) {
307 snd_timer_stop(tmr->timeri); 314 snd_timer_stop(tmr->timeri);
308 snd_timer_close(tmr->timeri); 315 snd_timer_close(tmr->timeri);
@@ -328,7 +335,8 @@ static int initialize_timer(struct snd_seq_timer *tmr)
328 unsigned long freq; 335 unsigned long freq;
329 336
330 t = tmr->timeri->timer; 337 t = tmr->timeri->timer;
331 snd_assert(t, return -EINVAL); 338 if (snd_BUG_ON(!t))
339 return -EINVAL;
332 340
333 freq = tmr->preferred_resolution; 341 freq = tmr->preferred_resolution;
334 if (!freq) 342 if (!freq)
diff --git a/sound/core/sgbuf.c b/sound/core/sgbuf.c
index cefd228cd2aa..d4564edd61d7 100644
--- a/sound/core/sgbuf.c
+++ b/sound/core/sgbuf.c
@@ -41,9 +41,11 @@ int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab)
41 tmpb.dev.type = SNDRV_DMA_TYPE_DEV; 41 tmpb.dev.type = SNDRV_DMA_TYPE_DEV;
42 tmpb.dev.dev = sgbuf->dev; 42 tmpb.dev.dev = sgbuf->dev;
43 for (i = 0; i < sgbuf->pages; i++) { 43 for (i = 0; i < sgbuf->pages; i++) {
44 if (!(sgbuf->table[i].addr & ~PAGE_MASK))
45 continue; /* continuous pages */
44 tmpb.area = sgbuf->table[i].buf; 46 tmpb.area = sgbuf->table[i].buf;
45 tmpb.addr = sgbuf->table[i].addr; 47 tmpb.addr = sgbuf->table[i].addr & PAGE_MASK;
46 tmpb.bytes = PAGE_SIZE; 48 tmpb.bytes = (sgbuf->table[i].addr & ~PAGE_MASK) << PAGE_SHIFT;
47 snd_dma_free_pages(&tmpb); 49 snd_dma_free_pages(&tmpb);
48 } 50 }
49 if (dmab->area) 51 if (dmab->area)
@@ -58,13 +60,17 @@ int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab)
58 return 0; 60 return 0;
59} 61}
60 62
63#define MAX_ALLOC_PAGES 32
64
61void *snd_malloc_sgbuf_pages(struct device *device, 65void *snd_malloc_sgbuf_pages(struct device *device,
62 size_t size, struct snd_dma_buffer *dmab, 66 size_t size, struct snd_dma_buffer *dmab,
63 size_t *res_size) 67 size_t *res_size)
64{ 68{
65 struct snd_sg_buf *sgbuf; 69 struct snd_sg_buf *sgbuf;
66 unsigned int i, pages; 70 unsigned int i, pages, chunk, maxpages;
67 struct snd_dma_buffer tmpb; 71 struct snd_dma_buffer tmpb;
72 struct snd_sg_page *table;
73 struct page **pgtable;
68 74
69 dmab->area = NULL; 75 dmab->area = NULL;
70 dmab->addr = 0; 76 dmab->addr = 0;
@@ -74,31 +80,55 @@ void *snd_malloc_sgbuf_pages(struct device *device,
74 sgbuf->dev = device; 80 sgbuf->dev = device;
75 pages = snd_sgbuf_aligned_pages(size); 81 pages = snd_sgbuf_aligned_pages(size);
76 sgbuf->tblsize = sgbuf_align_table(pages); 82 sgbuf->tblsize = sgbuf_align_table(pages);
77 sgbuf->table = kcalloc(sgbuf->tblsize, sizeof(*sgbuf->table), GFP_KERNEL); 83 table = kcalloc(sgbuf->tblsize, sizeof(*table), GFP_KERNEL);
78 if (! sgbuf->table) 84 if (!table)
79 goto _failed; 85 goto _failed;
80 sgbuf->page_table = kcalloc(sgbuf->tblsize, sizeof(*sgbuf->page_table), GFP_KERNEL); 86 sgbuf->table = table;
81 if (! sgbuf->page_table) 87 pgtable = kcalloc(sgbuf->tblsize, sizeof(*pgtable), GFP_KERNEL);
88 if (!pgtable)
82 goto _failed; 89 goto _failed;
90 sgbuf->page_table = pgtable;
83 91
84 /* allocate each page */ 92 /* allocate pages */
85 for (i = 0; i < pages; i++) { 93 maxpages = MAX_ALLOC_PAGES;
86 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, device, PAGE_SIZE, &tmpb) < 0) { 94 while (pages > 0) {
87 if (res_size == NULL) 95 chunk = pages;
96 /* don't be too eager to take a huge chunk */
97 if (chunk > maxpages)
98 chunk = maxpages;
99 chunk <<= PAGE_SHIFT;
100 if (snd_dma_alloc_pages_fallback(SNDRV_DMA_TYPE_DEV, device,
101 chunk, &tmpb) < 0) {
102 if (!sgbuf->pages)
103 return NULL;
104 if (!res_size)
88 goto _failed; 105 goto _failed;
89 *res_size = size = sgbuf->pages * PAGE_SIZE; 106 size = sgbuf->pages * PAGE_SIZE;
90 break; 107 break;
91 } 108 }
92 sgbuf->table[i].buf = tmpb.area; 109 chunk = tmpb.bytes >> PAGE_SHIFT;
93 sgbuf->table[i].addr = tmpb.addr; 110 for (i = 0; i < chunk; i++) {
94 sgbuf->page_table[i] = virt_to_page(tmpb.area); 111 table->buf = tmpb.area;
95 sgbuf->pages++; 112 table->addr = tmpb.addr;
113 if (!i)
114 table->addr |= chunk; /* mark head */
115 table++;
116 *pgtable++ = virt_to_page(tmpb.area);
117 tmpb.area += PAGE_SIZE;
118 tmpb.addr += PAGE_SIZE;
119 }
120 sgbuf->pages += chunk;
121 pages -= chunk;
122 if (chunk < maxpages)
123 maxpages = chunk;
96 } 124 }
97 125
98 sgbuf->size = size; 126 sgbuf->size = size;
99 dmab->area = vmap(sgbuf->page_table, sgbuf->pages, VM_MAP, PAGE_KERNEL); 127 dmab->area = vmap(sgbuf->page_table, sgbuf->pages, VM_MAP, PAGE_KERNEL);
100 if (! dmab->area) 128 if (! dmab->area)
101 goto _failed; 129 goto _failed;
130 if (res_size)
131 *res_size = sgbuf->size;
102 return dmab->area; 132 return dmab->area;
103 133
104 _failed: 134 _failed:
diff --git a/sound/core/sound.c b/sound/core/sound.c
index 1003ae375d47..c0685e2f0afa 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -34,8 +34,6 @@
34#include <linux/kmod.h> 34#include <linux/kmod.h>
35#include <linux/mutex.h> 35#include <linux/mutex.h>
36 36
37#define SNDRV_OS_MINORS 256
38
39static int major = CONFIG_SND_MAJOR; 37static int major = CONFIG_SND_MAJOR;
40int snd_major; 38int snd_major;
41EXPORT_SYMBOL(snd_major); 39EXPORT_SYMBOL(snd_major);
@@ -208,20 +206,23 @@ static int snd_kernel_minor(int type, struct snd_card *card, int dev)
208 minor = type; 206 minor = type;
209 break; 207 break;
210 case SNDRV_DEVICE_TYPE_CONTROL: 208 case SNDRV_DEVICE_TYPE_CONTROL:
211 snd_assert(card != NULL, return -EINVAL); 209 if (snd_BUG_ON(!card))
210 return -EINVAL;
212 minor = SNDRV_MINOR(card->number, type); 211 minor = SNDRV_MINOR(card->number, type);
213 break; 212 break;
214 case SNDRV_DEVICE_TYPE_HWDEP: 213 case SNDRV_DEVICE_TYPE_HWDEP:
215 case SNDRV_DEVICE_TYPE_RAWMIDI: 214 case SNDRV_DEVICE_TYPE_RAWMIDI:
216 case SNDRV_DEVICE_TYPE_PCM_PLAYBACK: 215 case SNDRV_DEVICE_TYPE_PCM_PLAYBACK:
217 case SNDRV_DEVICE_TYPE_PCM_CAPTURE: 216 case SNDRV_DEVICE_TYPE_PCM_CAPTURE:
218 snd_assert(card != NULL, return -EINVAL); 217 if (snd_BUG_ON(!card))
218 return -EINVAL;
219 minor = SNDRV_MINOR(card->number, type + dev); 219 minor = SNDRV_MINOR(card->number, type + dev);
220 break; 220 break;
221 default: 221 default:
222 return -EINVAL; 222 return -EINVAL;
223 } 223 }
224 snd_assert(minor >= 0 && minor < SNDRV_OS_MINORS, return -EINVAL); 224 if (snd_BUG_ON(minor < 0 || minor >= SNDRV_OS_MINORS))
225 return -EINVAL;
225 return minor; 226 return minor;
226} 227}
227#endif 228#endif
@@ -249,7 +250,8 @@ int snd_register_device_for_dev(int type, struct snd_card *card, int dev,
249 int minor; 250 int minor;
250 struct snd_minor *preg; 251 struct snd_minor *preg;
251 252
252 snd_assert(name, return -EINVAL); 253 if (snd_BUG_ON(!name))
254 return -EINVAL;
253 preg = kmalloc(sizeof *preg, GFP_KERNEL); 255 preg = kmalloc(sizeof *preg, GFP_KERNEL);
254 if (preg == NULL) 256 if (preg == NULL)
255 return -ENOMEM; 257 return -ENOMEM;
diff --git a/sound/core/sound_oss.c b/sound/core/sound_oss.c
index 7be51546eb9e..7fe12264ff80 100644
--- a/sound/core/sound_oss.c
+++ b/sound/core/sound_oss.c
@@ -64,7 +64,8 @@ static int snd_oss_kernel_minor(int type, struct snd_card *card, int dev)
64 64
65 switch (type) { 65 switch (type) {
66 case SNDRV_OSS_DEVICE_TYPE_MIXER: 66 case SNDRV_OSS_DEVICE_TYPE_MIXER:
67 snd_assert(card != NULL && dev <= 1, return -EINVAL); 67 if (snd_BUG_ON(!card || dev < 0 || dev > 1))
68 return -EINVAL;
68 minor = SNDRV_MINOR_OSS(card->number, (dev ? SNDRV_MINOR_OSS_MIXER1 : SNDRV_MINOR_OSS_MIXER)); 69 minor = SNDRV_MINOR_OSS(card->number, (dev ? SNDRV_MINOR_OSS_MIXER1 : SNDRV_MINOR_OSS_MIXER));
69 break; 70 break;
70 case SNDRV_OSS_DEVICE_TYPE_SEQUENCER: 71 case SNDRV_OSS_DEVICE_TYPE_SEQUENCER:
@@ -74,11 +75,13 @@ static int snd_oss_kernel_minor(int type, struct snd_card *card, int dev)
74 minor = SNDRV_MINOR_OSS_MUSIC; 75 minor = SNDRV_MINOR_OSS_MUSIC;
75 break; 76 break;
76 case SNDRV_OSS_DEVICE_TYPE_PCM: 77 case SNDRV_OSS_DEVICE_TYPE_PCM:
77 snd_assert(card != NULL && dev <= 1, return -EINVAL); 78 if (snd_BUG_ON(!card || dev < 0 || dev > 1))
79 return -EINVAL;
78 minor = SNDRV_MINOR_OSS(card->number, (dev ? SNDRV_MINOR_OSS_PCM1 : SNDRV_MINOR_OSS_PCM)); 80 minor = SNDRV_MINOR_OSS(card->number, (dev ? SNDRV_MINOR_OSS_PCM1 : SNDRV_MINOR_OSS_PCM));
79 break; 81 break;
80 case SNDRV_OSS_DEVICE_TYPE_MIDI: 82 case SNDRV_OSS_DEVICE_TYPE_MIDI:
81 snd_assert(card != NULL && dev <= 1, return -EINVAL); 83 if (snd_BUG_ON(!card || dev < 0 || dev > 1))
84 return -EINVAL;
82 minor = SNDRV_MINOR_OSS(card->number, (dev ? SNDRV_MINOR_OSS_MIDI1 : SNDRV_MINOR_OSS_MIDI)); 85 minor = SNDRV_MINOR_OSS(card->number, (dev ? SNDRV_MINOR_OSS_MIDI1 : SNDRV_MINOR_OSS_MIDI));
83 break; 86 break;
84 case SNDRV_OSS_DEVICE_TYPE_DMFM: 87 case SNDRV_OSS_DEVICE_TYPE_DMFM:
@@ -90,7 +93,8 @@ static int snd_oss_kernel_minor(int type, struct snd_card *card, int dev)
90 default: 93 default:
91 return -EINVAL; 94 return -EINVAL;
92 } 95 }
93 snd_assert(minor >= 0 && minor < SNDRV_OSS_MINORS, return -EINVAL); 96 if (snd_BUG_ON(minor < 0 || minor >= SNDRV_OSS_MINORS))
97 return -EINVAL;
94 return minor; 98 return minor;
95} 99}
96 100
diff --git a/sound/core/timer.c b/sound/core/timer.c
index 0af337efc64e..e582face89d2 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -306,7 +306,8 @@ int snd_timer_close(struct snd_timer_instance *timeri)
306 struct snd_timer *timer = NULL; 306 struct snd_timer *timer = NULL;
307 struct snd_timer_instance *slave, *tmp; 307 struct snd_timer_instance *slave, *tmp;
308 308
309 snd_assert(timeri != NULL, return -ENXIO); 309 if (snd_BUG_ON(!timeri))
310 return -ENXIO;
310 311
311 /* force to stop the timer */ 312 /* force to stop the timer */
312 snd_timer_stop(timeri); 313 snd_timer_stop(timeri);
@@ -385,8 +386,9 @@ static void snd_timer_notify1(struct snd_timer_instance *ti, int event)
385 do_posix_clock_monotonic_gettime(&tstamp); 386 do_posix_clock_monotonic_gettime(&tstamp);
386 else 387 else
387 getnstimeofday(&tstamp); 388 getnstimeofday(&tstamp);
388 snd_assert(event >= SNDRV_TIMER_EVENT_START && 389 if (snd_BUG_ON(event < SNDRV_TIMER_EVENT_START ||
389 event <= SNDRV_TIMER_EVENT_PAUSE, return); 390 event > SNDRV_TIMER_EVENT_PAUSE))
391 return;
390 if (event == SNDRV_TIMER_EVENT_START || 392 if (event == SNDRV_TIMER_EVENT_START ||
391 event == SNDRV_TIMER_EVENT_CONTINUE) 393 event == SNDRV_TIMER_EVENT_CONTINUE)
392 resolution = snd_timer_resolution(ti); 394 resolution = snd_timer_resolution(ti);
@@ -474,7 +476,8 @@ static int _snd_timer_stop(struct snd_timer_instance * timeri,
474 struct snd_timer *timer; 476 struct snd_timer *timer;
475 unsigned long flags; 477 unsigned long flags;
476 478
477 snd_assert(timeri != NULL, return -ENXIO); 479 if (snd_BUG_ON(!timeri))
480 return -ENXIO;
478 481
479 if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) { 482 if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) {
480 if (!keep_flag) { 483 if (!keep_flag) {
@@ -758,9 +761,10 @@ int snd_timer_new(struct snd_card *card, char *id, struct snd_timer_id *tid,
758 .dev_disconnect = snd_timer_dev_disconnect, 761 .dev_disconnect = snd_timer_dev_disconnect,
759 }; 762 };
760 763
761 snd_assert(tid != NULL, return -EINVAL); 764 if (snd_BUG_ON(!tid))
762 snd_assert(rtimer != NULL, return -EINVAL); 765 return -EINVAL;
763 *rtimer = NULL; 766 if (rtimer)
767 *rtimer = NULL;
764 timer = kzalloc(sizeof(*timer), GFP_KERNEL); 768 timer = kzalloc(sizeof(*timer), GFP_KERNEL);
765 if (timer == NULL) { 769 if (timer == NULL) {
766 snd_printk(KERN_ERR "timer: cannot allocate\n"); 770 snd_printk(KERN_ERR "timer: cannot allocate\n");
@@ -788,13 +792,15 @@ int snd_timer_new(struct snd_card *card, char *id, struct snd_timer_id *tid,
788 return err; 792 return err;
789 } 793 }
790 } 794 }
791 *rtimer = timer; 795 if (rtimer)
796 *rtimer = timer;
792 return 0; 797 return 0;
793} 798}
794 799
795static int snd_timer_free(struct snd_timer *timer) 800static int snd_timer_free(struct snd_timer *timer)
796{ 801{
797 snd_assert(timer != NULL, return -ENXIO); 802 if (!timer)
803 return 0;
798 804
799 mutex_lock(&register_mutex); 805 mutex_lock(&register_mutex);
800 if (! list_empty(&timer->open_list_head)) { 806 if (! list_empty(&timer->open_list_head)) {
@@ -827,8 +833,8 @@ static int snd_timer_dev_register(struct snd_device *dev)
827 struct snd_timer *timer = dev->device_data; 833 struct snd_timer *timer = dev->device_data;
828 struct snd_timer *timer1; 834 struct snd_timer *timer1;
829 835
830 snd_assert(timer != NULL && timer->hw.start != NULL && 836 if (snd_BUG_ON(!timer || !timer->hw.start || !timer->hw.stop))
831 timer->hw.stop != NULL, return -ENXIO); 837 return -ENXIO;
832 if (!(timer->hw.flags & SNDRV_TIMER_HW_SLAVE) && 838 if (!(timer->hw.flags & SNDRV_TIMER_HW_SLAVE) &&
833 !timer->hw.resolution && timer->hw.c_resolution == NULL) 839 !timer->hw.resolution && timer->hw.c_resolution == NULL)
834 return -EINVAL; 840 return -EINVAL;
@@ -879,8 +885,9 @@ void snd_timer_notify(struct snd_timer *timer, int event, struct timespec *tstam
879 885
880 if (! (timer->hw.flags & SNDRV_TIMER_HW_SLAVE)) 886 if (! (timer->hw.flags & SNDRV_TIMER_HW_SLAVE))
881 return; 887 return;
882 snd_assert(event >= SNDRV_TIMER_EVENT_MSTART && 888 if (snd_BUG_ON(event < SNDRV_TIMER_EVENT_MSTART ||
883 event <= SNDRV_TIMER_EVENT_MRESUME, return); 889 event > SNDRV_TIMER_EVENT_MRESUME))
890 return;
884 spin_lock_irqsave(&timer->lock, flags); 891 spin_lock_irqsave(&timer->lock, flags);
885 if (event == SNDRV_TIMER_EVENT_MSTART || 892 if (event == SNDRV_TIMER_EVENT_MSTART ||
886 event == SNDRV_TIMER_EVENT_MCONTINUE || 893 event == SNDRV_TIMER_EVENT_MCONTINUE ||
diff --git a/sound/core/timer_compat.c b/sound/core/timer_compat.c
index 5512f5373c52..e05802ae6e1b 100644
--- a/sound/core/timer_compat.c
+++ b/sound/core/timer_compat.c
@@ -40,9 +40,11 @@ static int snd_timer_user_info_compat(struct file *file,
40 struct snd_timer *t; 40 struct snd_timer *t;
41 41
42 tu = file->private_data; 42 tu = file->private_data;
43 snd_assert(tu->timeri != NULL, return -ENXIO); 43 if (snd_BUG_ON(!tu->timeri))
44 return -ENXIO;
44 t = tu->timeri->timer; 45 t = tu->timeri->timer;
45 snd_assert(t != NULL, return -ENXIO); 46 if (snd_BUG_ON(!t))
47 return -ENXIO;
46 memset(&info, 0, sizeof(info)); 48 memset(&info, 0, sizeof(info));
47 info.card = t->card ? t->card->number : -1; 49 info.card = t->card ? t->card->number : -1;
48 if (t->hw.flags & SNDRV_TIMER_HW_SLAVE) 50 if (t->hw.flags & SNDRV_TIMER_HW_SLAVE)
@@ -71,7 +73,8 @@ static int snd_timer_user_status_compat(struct file *file,
71 struct snd_timer_status status; 73 struct snd_timer_status status;
72 74
73 tu = file->private_data; 75 tu = file->private_data;
74 snd_assert(tu->timeri != NULL, return -ENXIO); 76 if (snd_BUG_ON(!tu->timeri))
77 return -ENXIO;
75 memset(&status, 0, sizeof(status)); 78 memset(&status, 0, sizeof(status));
76 status.tstamp = tu->tstamp; 79 status.tstamp = tu->tstamp;
77 status.resolution = snd_timer_resolution(tu->timeri); 80 status.resolution = snd_timer_resolution(tu->timeri);
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c
index 4e4c69e6cb4c..e5e749f3e0ef 100644
--- a/sound/drivers/dummy.c
+++ b/sound/drivers/dummy.c
@@ -47,9 +47,11 @@ MODULE_SUPPORTED_DEVICE("{{ALSA,Dummy soundcard}}");
47static int emu10k1_playback_constraints(struct snd_pcm_runtime *runtime) 47static int emu10k1_playback_constraints(struct snd_pcm_runtime *runtime)
48{ 48{
49 int err; 49 int err;
50 if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0) 50 err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
51 if (err < 0)
51 return err; 52 return err;
52 if ((err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 256, UINT_MAX)) < 0) 53 err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 256, UINT_MAX);
54 if (err) < 0)
53 return err; 55 return err;
54 return 0; 56 return 0;
55} 57}
@@ -354,6 +356,7 @@ static int snd_card_dummy_playback_open(struct snd_pcm_substream *substream)
354 if ((dpcm = new_pcm_stream(substream)) == NULL) 356 if ((dpcm = new_pcm_stream(substream)) == NULL)
355 return -ENOMEM; 357 return -ENOMEM;
356 runtime->private_data = dpcm; 358 runtime->private_data = dpcm;
359 /* makes the infrastructure responsible for freeing dpcm */
357 runtime->private_free = snd_card_dummy_runtime_free; 360 runtime->private_free = snd_card_dummy_runtime_free;
358 runtime->hw = snd_card_dummy_playback; 361 runtime->hw = snd_card_dummy_playback;
359 if (substream->pcm->device & 1) { 362 if (substream->pcm->device & 1) {
@@ -362,10 +365,9 @@ static int snd_card_dummy_playback_open(struct snd_pcm_substream *substream)
362 } 365 }
363 if (substream->pcm->device & 2) 366 if (substream->pcm->device & 2)
364 runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP|SNDRV_PCM_INFO_MMAP_VALID); 367 runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP|SNDRV_PCM_INFO_MMAP_VALID);
365 if ((err = add_playback_constraints(runtime)) < 0) { 368 err = add_playback_constraints(runtime);
366 kfree(dpcm); 369 if (err < 0)
367 return err; 370 return err;
368 }
369 371
370 return 0; 372 return 0;
371} 373}
@@ -379,6 +381,7 @@ static int snd_card_dummy_capture_open(struct snd_pcm_substream *substream)
379 if ((dpcm = new_pcm_stream(substream)) == NULL) 381 if ((dpcm = new_pcm_stream(substream)) == NULL)
380 return -ENOMEM; 382 return -ENOMEM;
381 runtime->private_data = dpcm; 383 runtime->private_data = dpcm;
384 /* makes the infrastructure responsible for freeing dpcm */
382 runtime->private_free = snd_card_dummy_runtime_free; 385 runtime->private_free = snd_card_dummy_runtime_free;
383 runtime->hw = snd_card_dummy_capture; 386 runtime->hw = snd_card_dummy_capture;
384 if (substream->pcm->device == 1) { 387 if (substream->pcm->device == 1) {
@@ -387,10 +390,9 @@ static int snd_card_dummy_capture_open(struct snd_pcm_substream *substream)
387 } 390 }
388 if (substream->pcm->device & 2) 391 if (substream->pcm->device & 2)
389 runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP|SNDRV_PCM_INFO_MMAP_VALID); 392 runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP|SNDRV_PCM_INFO_MMAP_VALID);
390 if ((err = add_capture_constraints(runtime)) < 0) { 393 err = add_capture_constraints(runtime);
391 kfree(dpcm); 394 if (err < 0)
392 return err; 395 return err;
393 }
394 396
395 return 0; 397 return 0;
396} 398}
@@ -433,8 +435,9 @@ static int __devinit snd_card_dummy_pcm(struct snd_dummy *dummy, int device,
433 struct snd_pcm *pcm; 435 struct snd_pcm *pcm;
434 int err; 436 int err;
435 437
436 if ((err = snd_pcm_new(dummy->card, "Dummy PCM", device, 438 err = snd_pcm_new(dummy->card, "Dummy PCM", device,
437 substreams, substreams, &pcm)) < 0) 439 substreams, substreams, &pcm);
440 if (err < 0)
438 return err; 441 return err;
439 dummy->pcm = pcm; 442 dummy->pcm = pcm;
440 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_card_dummy_playback_ops); 443 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_card_dummy_playback_ops);
@@ -565,12 +568,14 @@ static int __devinit snd_card_dummy_new_mixer(struct snd_dummy *dummy)
565 unsigned int idx; 568 unsigned int idx;
566 int err; 569 int err;
567 570
568 snd_assert(dummy != NULL, return -EINVAL); 571 if (snd_BUG_ON(!dummy))
572 return -EINVAL;
569 spin_lock_init(&dummy->mixer_lock); 573 spin_lock_init(&dummy->mixer_lock);
570 strcpy(card->mixername, "Dummy Mixer"); 574 strcpy(card->mixername, "Dummy Mixer");
571 575
572 for (idx = 0; idx < ARRAY_SIZE(snd_dummy_controls); idx++) { 576 for (idx = 0; idx < ARRAY_SIZE(snd_dummy_controls); idx++) {
573 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_dummy_controls[idx], dummy))) < 0) 577 err = snd_ctl_add(card, snd_ctl_new1(&snd_dummy_controls[idx], dummy));
578 if (err < 0)
574 return err; 579 return err;
575 } 580 }
576 return 0; 581 return 0;
@@ -594,10 +599,12 @@ static int __devinit snd_dummy_probe(struct platform_device *devptr)
594 pcm_substreams[dev] = 1; 599 pcm_substreams[dev] = 1;
595 if (pcm_substreams[dev] > MAX_PCM_SUBSTREAMS) 600 if (pcm_substreams[dev] > MAX_PCM_SUBSTREAMS)
596 pcm_substreams[dev] = MAX_PCM_SUBSTREAMS; 601 pcm_substreams[dev] = MAX_PCM_SUBSTREAMS;
597 if ((err = snd_card_dummy_pcm(dummy, idx, pcm_substreams[dev])) < 0) 602 err = snd_card_dummy_pcm(dummy, idx, pcm_substreams[dev]);
603 if (err < 0)
598 goto __nodev; 604 goto __nodev;
599 } 605 }
600 if ((err = snd_card_dummy_new_mixer(dummy)) < 0) 606 err = snd_card_dummy_new_mixer(dummy);
607 if (err < 0)
601 goto __nodev; 608 goto __nodev;
602 strcpy(card->driver, "Dummy"); 609 strcpy(card->driver, "Dummy");
603 strcpy(card->shortname, "Dummy"); 610 strcpy(card->shortname, "Dummy");
@@ -605,7 +612,8 @@ static int __devinit snd_dummy_probe(struct platform_device *devptr)
605 612
606 snd_card_set_dev(card, &devptr->dev); 613 snd_card_set_dev(card, &devptr->dev);
607 614
608 if ((err = snd_card_register(card)) == 0) { 615 err = snd_card_register(card);
616 if (err == 0) {
609 platform_set_drvdata(devptr, card); 617 platform_set_drvdata(devptr, card);
610 return 0; 618 return 0;
611 } 619 }
@@ -668,7 +676,8 @@ static int __init alsa_card_dummy_init(void)
668{ 676{
669 int i, cards, err; 677 int i, cards, err;
670 678
671 if ((err = platform_driver_register(&snd_dummy_driver)) < 0) 679 err = platform_driver_register(&snd_dummy_driver);
680 if (err < 0)
672 return err; 681 return err;
673 682
674 cards = 0; 683 cards = 0;
diff --git a/sound/drivers/mtpav.c b/sound/drivers/mtpav.c
index b5e1a71bb64b..5b89c0883d60 100644
--- a/sound/drivers/mtpav.c
+++ b/sound/drivers/mtpav.c
@@ -715,6 +715,10 @@ static int __devinit snd_mtpav_probe(struct platform_device *dev)
715 715
716 card->private_free = snd_mtpav_free; 716 card->private_free = snd_mtpav_free;
717 717
718 err = snd_mtpav_get_RAWMIDI(mtp_card);
719 if (err < 0)
720 goto __error;
721
718 err = snd_mtpav_get_ISA(mtp_card); 722 err = snd_mtpav_get_ISA(mtp_card);
719 if (err < 0) 723 if (err < 0)
720 goto __error; 724 goto __error;
@@ -724,10 +728,6 @@ static int __devinit snd_mtpav_probe(struct platform_device *dev)
724 snprintf(card->longname, sizeof(card->longname), 728 snprintf(card->longname, sizeof(card->longname),
725 "MTPAV on parallel port at 0x%lx", port); 729 "MTPAV on parallel port at 0x%lx", port);
726 730
727 err = snd_mtpav_get_RAWMIDI(mtp_card);
728 if (err < 0)
729 goto __error;
730
731 snd_mtpav_portscan(mtp_card); 731 snd_mtpav_portscan(mtp_card);
732 732
733 snd_card_set_dev(card, &dev->dev); 733 snd_card_set_dev(card, &dev->dev);
diff --git a/sound/drivers/opl3/opl3_lib.c b/sound/drivers/opl3/opl3_lib.c
index ebe4359047cb..780582340fef 100644
--- a/sound/drivers/opl3/opl3_lib.c
+++ b/sound/drivers/opl3/opl3_lib.c
@@ -139,7 +139,8 @@ static int snd_opl3_detect(struct snd_opl3 * opl3)
139 * If we had an OPL4 chip, opl3->hardware would have been set 139 * If we had an OPL4 chip, opl3->hardware would have been set
140 * by the OPL4 driver; so we can assume OPL3 here. 140 * by the OPL4 driver; so we can assume OPL3 here.
141 */ 141 */
142 snd_assert(opl3->r_port != 0, return -ENODEV); 142 if (snd_BUG_ON(!opl3->r_port))
143 return -ENODEV;
143 opl3->hardware = OPL3_HW_OPL3; 144 opl3->hardware = OPL3_HW_OPL3;
144 } 145 }
145 return 0; 146 return 0;
@@ -324,7 +325,8 @@ EXPORT_SYMBOL(snd_opl3_interrupt);
324 325
325static int snd_opl3_free(struct snd_opl3 *opl3) 326static int snd_opl3_free(struct snd_opl3 *opl3)
326{ 327{
327 snd_assert(opl3 != NULL, return -ENXIO); 328 if (snd_BUG_ON(!opl3))
329 return -ENXIO;
328 if (opl3->private_free) 330 if (opl3->private_free)
329 opl3->private_free(opl3); 331 opl3->private_free(opl3);
330 snd_opl3_clear_patches(opl3); 332 snd_opl3_clear_patches(opl3);
diff --git a/sound/drivers/opl3/opl3_midi.c b/sound/drivers/opl3/opl3_midi.c
index cebcb8b78acb..16feafa2c51e 100644
--- a/sound/drivers/opl3/opl3_midi.c
+++ b/sound/drivers/opl3/opl3_midi.c
@@ -617,7 +617,8 @@ static void snd_opl3_kill_voice(struct snd_opl3 *opl3, int voice)
617 617
618 struct snd_opl3_voice *vp, *vp2; 618 struct snd_opl3_voice *vp, *vp2;
619 619
620 snd_assert(voice < MAX_OPL3_VOICES, return); 620 if (snd_BUG_ON(voice >= MAX_OPL3_VOICES))
621 return;
621 622
622 vp = &opl3->voices[voice]; 623 vp = &opl3->voices[voice];
623 if (voice < MAX_OPL2_VOICES) { 624 if (voice < MAX_OPL2_VOICES) {
@@ -737,7 +738,8 @@ static void snd_opl3_update_pitch(struct snd_opl3 *opl3, int voice)
737 738
738 struct snd_opl3_voice *vp; 739 struct snd_opl3_voice *vp;
739 740
740 snd_assert(voice < MAX_OPL3_VOICES, return); 741 if (snd_BUG_ON(voice >= MAX_OPL3_VOICES))
742 return;
741 743
742 vp = &opl3->voices[voice]; 744 vp = &opl3->voices[voice];
743 if (vp->chan == NULL) 745 if (vp->chan == NULL)
diff --git a/sound/drivers/opl3/opl3_oss.c b/sound/drivers/opl3/opl3_oss.c
index 239347f26154..9a2271dc046a 100644
--- a/sound/drivers/opl3/opl3_oss.c
+++ b/sound/drivers/opl3/opl3_oss.c
@@ -162,7 +162,8 @@ static int snd_opl3_open_seq_oss(struct snd_seq_oss_arg *arg, void *closure)
162 struct snd_opl3 *opl3 = closure; 162 struct snd_opl3 *opl3 = closure;
163 int err; 163 int err;
164 164
165 snd_assert(arg != NULL, return -ENXIO); 165 if (snd_BUG_ON(!arg))
166 return -ENXIO;
166 167
167 if ((err = snd_opl3_synth_setup(opl3)) < 0) 168 if ((err = snd_opl3_synth_setup(opl3)) < 0)
168 return err; 169 return err;
@@ -184,7 +185,8 @@ static int snd_opl3_close_seq_oss(struct snd_seq_oss_arg *arg)
184{ 185{
185 struct snd_opl3 *opl3; 186 struct snd_opl3 *opl3;
186 187
187 snd_assert(arg != NULL, return -ENXIO); 188 if (snd_BUG_ON(!arg))
189 return -ENXIO;
188 opl3 = arg->private_data; 190 opl3 = arg->private_data;
189 191
190 snd_opl3_synth_cleanup(opl3); 192 snd_opl3_synth_cleanup(opl3);
@@ -206,7 +208,8 @@ static int snd_opl3_load_patch_seq_oss(struct snd_seq_oss_arg *arg, int format,
206 char name[32]; 208 char name[32];
207 int err, type; 209 int err, type;
208 210
209 snd_assert(arg != NULL, return -ENXIO); 211 if (snd_BUG_ON(!arg))
212 return -ENXIO;
210 opl3 = arg->private_data; 213 opl3 = arg->private_data;
211 214
212 if (format == FM_PATCH) 215 if (format == FM_PATCH)
@@ -246,7 +249,8 @@ static int snd_opl3_ioctl_seq_oss(struct snd_seq_oss_arg *arg, unsigned int cmd,
246{ 249{
247 struct snd_opl3 *opl3; 250 struct snd_opl3 *opl3;
248 251
249 snd_assert(arg != NULL, return -ENXIO); 252 if (snd_BUG_ON(!arg))
253 return -ENXIO;
250 opl3 = arg->private_data; 254 opl3 = arg->private_data;
251 switch (cmd) { 255 switch (cmd) {
252 case SNDCTL_FM_LOAD_INSTR: 256 case SNDCTL_FM_LOAD_INSTR:
@@ -271,7 +275,8 @@ static int snd_opl3_reset_seq_oss(struct snd_seq_oss_arg *arg)
271{ 275{
272 struct snd_opl3 *opl3; 276 struct snd_opl3 *opl3;
273 277
274 snd_assert(arg != NULL, return -ENXIO); 278 if (snd_BUG_ON(!arg))
279 return -ENXIO;
275 opl3 = arg->private_data; 280 opl3 = arg->private_data;
276 281
277 return 0; 282 return 0;
diff --git a/sound/drivers/opl3/opl3_synth.c b/sound/drivers/opl3/opl3_synth.c
index fb64c890109b..962bb9c8b9c8 100644
--- a/sound/drivers/opl3/opl3_synth.c
+++ b/sound/drivers/opl3/opl3_synth.c
@@ -92,7 +92,8 @@ int snd_opl3_ioctl(struct snd_hwdep * hw, struct file *file,
92 struct snd_opl3 *opl3 = hw->private_data; 92 struct snd_opl3 *opl3 = hw->private_data;
93 void __user *argp = (void __user *)arg; 93 void __user *argp = (void __user *)arg;
94 94
95 snd_assert(opl3 != NULL, return -EINVAL); 95 if (snd_BUG_ON(!opl3))
96 return -EINVAL;
96 97
97 switch (cmd) { 98 switch (cmd) {
98 /* get information */ 99 /* get information */
diff --git a/sound/drivers/opl4/opl4_synth.c b/sound/drivers/opl4/opl4_synth.c
index 74f6e53eae0d..49b9e240915c 100644
--- a/sound/drivers/opl4/opl4_synth.c
+++ b/sound/drivers/opl4/opl4_synth.c
@@ -467,7 +467,7 @@ static struct opl4_voice *snd_opl4_get_voice(struct snd_opl4 *opl4)
467 if (!list_empty(&opl4->off_voices)) 467 if (!list_empty(&opl4->off_voices))
468 return list_entry(opl4->off_voices.next, struct opl4_voice, list); 468 return list_entry(opl4->off_voices.next, struct opl4_voice, list);
469 /* then get the oldest key-on voice */ 469 /* then get the oldest key-on voice */
470 snd_assert(!list_empty(&opl4->on_voices), ); 470 snd_BUG_ON(list_empty(&opl4->on_voices));
471 return list_entry(opl4->on_voices.next, struct opl4_voice, list); 471 return list_entry(opl4->on_voices.next, struct opl4_voice, list);
472} 472}
473 473
diff --git a/sound/drivers/vx/vx_cmd.c b/sound/drivers/vx/vx_cmd.c
index 9529e3bf2866..23f4857f02c8 100644
--- a/sound/drivers/vx/vx_cmd.c
+++ b/sound/drivers/vx/vx_cmd.c
@@ -99,7 +99,8 @@ static struct vx_cmd_info vx_dsp_cmds[] = {
99 */ 99 */
100void vx_init_rmh(struct vx_rmh *rmh, unsigned int cmd) 100void vx_init_rmh(struct vx_rmh *rmh, unsigned int cmd)
101{ 101{
102 snd_assert(cmd < CMD_LAST_INDEX, return); 102 if (snd_BUG_ON(cmd >= CMD_LAST_INDEX))
103 return;
103 rmh->LgCmd = vx_dsp_cmds[cmd].length; 104 rmh->LgCmd = vx_dsp_cmds[cmd].length;
104 rmh->LgStat = vx_dsp_cmds[cmd].st_length; 105 rmh->LgStat = vx_dsp_cmds[cmd].st_length;
105 rmh->DspStat = vx_dsp_cmds[cmd].st_type; 106 rmh->DspStat = vx_dsp_cmds[cmd].st_type;
diff --git a/sound/drivers/vx/vx_core.c b/sound/drivers/vx/vx_core.c
index 585af2eb1438..473b07f6ae85 100644
--- a/sound/drivers/vx/vx_core.c
+++ b/sound/drivers/vx/vx_core.c
@@ -205,7 +205,8 @@ static int vx_read_status(struct vx_core *chip, struct vx_rmh *rmh)
205 205
206 if (size < 1) 206 if (size < 1)
207 return 0; 207 return 0;
208 snd_assert(size <= SIZE_MAX_STATUS, return -EINVAL); 208 if (snd_BUG_ON(size > SIZE_MAX_STATUS))
209 return -EINVAL;
209 210
210 for (i = 1; i <= size; i++) { 211 for (i = 1; i <= size; i++) {
211 /* trigger an irq MESS_WRITE_NEXT */ 212 /* trigger an irq MESS_WRITE_NEXT */
@@ -425,13 +426,16 @@ int snd_vx_load_boot_image(struct vx_core *chip, const struct firmware *boot)
425 int no_fillup = vx_has_new_dsp(chip); 426 int no_fillup = vx_has_new_dsp(chip);
426 427
427 /* check the length of boot image */ 428 /* check the length of boot image */
428 snd_assert(boot->size > 0, return -EINVAL); 429 if (boot->size <= 0)
429 snd_assert(boot->size % 3 == 0, return -EINVAL); 430 return -EINVAL;
431 if (boot->size % 3)
432 return -EINVAL;
430#if 0 433#if 0
431 { 434 {
432 /* more strict check */ 435 /* more strict check */
433 unsigned int c = ((u32)boot->data[0] << 16) | ((u32)boot->data[1] << 8) | boot->data[2]; 436 unsigned int c = ((u32)boot->data[0] << 16) | ((u32)boot->data[1] << 8) | boot->data[2];
434 snd_assert(boot->size == (c + 2) * 3, return -EINVAL); 437 if (boot->size != (c + 2) * 3)
438 return -EINVAL;
435 } 439 }
436#endif 440#endif
437 441
@@ -554,7 +558,8 @@ EXPORT_SYMBOL(snd_vx_irq_handler);
554 */ 558 */
555static void vx_reset_board(struct vx_core *chip, int cold_reset) 559static void vx_reset_board(struct vx_core *chip, int cold_reset)
556{ 560{
557 snd_assert(chip->ops->reset_board, return); 561 if (snd_BUG_ON(!chip->ops->reset_board))
562 return;
558 563
559 /* current source, later sync'ed with target */ 564 /* current source, later sync'ed with target */
560 chip->audio_source = VX_AUDIO_SRC_LINE; 565 chip->audio_source = VX_AUDIO_SRC_LINE;
@@ -673,7 +678,8 @@ int snd_vx_dsp_load(struct vx_core *chip, const struct firmware *dsp)
673 unsigned int csum = 0; 678 unsigned int csum = 0;
674 const unsigned char *image, *cptr; 679 const unsigned char *image, *cptr;
675 680
676 snd_assert(dsp->size % 3 == 0, return -EINVAL); 681 if (dsp->size % 3)
682 return -EINVAL;
677 683
678 vx_toggle_dac_mute(chip, 1); 684 vx_toggle_dac_mute(chip, 1);
679 685
@@ -775,7 +781,8 @@ struct vx_core *snd_vx_create(struct snd_card *card, struct snd_vx_hardware *hw,
775{ 781{
776 struct vx_core *chip; 782 struct vx_core *chip;
777 783
778 snd_assert(card && hw && ops, return NULL); 784 if (snd_BUG_ON(!card || !hw || !ops))
785 return NULL;
779 786
780 chip = kzalloc(sizeof(*chip) + extra_size, GFP_KERNEL); 787 chip = kzalloc(sizeof(*chip) + extra_size, GFP_KERNEL);
781 if (! chip) { 788 if (! chip) {
diff --git a/sound/drivers/vx/vx_hwdep.c b/sound/drivers/vx/vx_hwdep.c
index efd22e92bced..8d6362e2d4c9 100644
--- a/sound/drivers/vx/vx_hwdep.c
+++ b/sound/drivers/vx/vx_hwdep.c
@@ -141,7 +141,8 @@ static int vx_hwdep_dsp_status(struct snd_hwdep *hw,
141 }; 141 };
142 struct vx_core *vx = hw->private_data; 142 struct vx_core *vx = hw->private_data;
143 143
144 snd_assert(type_ids[vx->type], return -EINVAL); 144 if (snd_BUG_ON(!type_ids[vx->type]))
145 return -EINVAL;
145 strcpy(info->id, type_ids[vx->type]); 146 strcpy(info->id, type_ids[vx->type]);
146 if (vx_is_pcmcia(vx)) 147 if (vx_is_pcmcia(vx))
147 info->num_dsps = 4; 148 info->num_dsps = 4;
@@ -168,7 +169,8 @@ static int vx_hwdep_dsp_load(struct snd_hwdep *hw,
168 int index, err; 169 int index, err;
169 struct firmware *fw; 170 struct firmware *fw;
170 171
171 snd_assert(vx->ops->load_dsp, return -ENXIO); 172 if (snd_BUG_ON(!vx->ops->load_dsp))
173 return -ENXIO;
172 174
173 fw = kmalloc(sizeof(*fw), GFP_KERNEL); 175 fw = kmalloc(sizeof(*fw), GFP_KERNEL);
174 if (! fw) { 176 if (! fw) {
diff --git a/sound/drivers/vx/vx_mixer.c b/sound/drivers/vx/vx_mixer.c
index 5a347321f8c0..c71b8d148d7f 100644
--- a/sound/drivers/vx/vx_mixer.c
+++ b/sound/drivers/vx/vx_mixer.c
@@ -34,7 +34,8 @@ static void vx_write_codec_reg(struct vx_core *chip, int codec, unsigned int dat
34{ 34{
35 unsigned long flags; 35 unsigned long flags;
36 36
37 snd_assert(chip->ops->write_codec, return); 37 if (snd_BUG_ON(!chip->ops->write_codec))
38 return;
38 39
39 if (chip->chip_status & VX_STAT_IS_STALE) 40 if (chip->chip_status & VX_STAT_IS_STALE)
40 return; 41 return;
diff --git a/sound/drivers/vx/vx_pcm.c b/sound/drivers/vx/vx_pcm.c
index fdbf86571b1f..27de574c08f7 100644
--- a/sound/drivers/vx/vx_pcm.c
+++ b/sound/drivers/vx/vx_pcm.c
@@ -587,7 +587,8 @@ static int vx_pcm_playback_open(struct snd_pcm_substream *subs)
587 return -EBUSY; 587 return -EBUSY;
588 588
589 audio = subs->pcm->device * 2; 589 audio = subs->pcm->device * 2;
590 snd_assert(audio < chip->audio_outs, return -EINVAL); 590 if (snd_BUG_ON(audio >= chip->audio_outs))
591 return -EINVAL;
591 592
592 /* playback pipe may have been already allocated for monitoring */ 593 /* playback pipe may have been already allocated for monitoring */
593 pipe = chip->playback_pipes[audio]; 594 pipe = chip->playback_pipes[audio];
@@ -996,7 +997,8 @@ static int vx_pcm_capture_open(struct snd_pcm_substream *subs)
996 return -EBUSY; 997 return -EBUSY;
997 998
998 audio = subs->pcm->device * 2; 999 audio = subs->pcm->device * 2;
999 snd_assert(audio < chip->audio_ins, return -EINVAL); 1000 if (snd_BUG_ON(audio >= chip->audio_ins))
1001 return -EINVAL;
1000 err = vx_alloc_pipe(chip, 1, audio, 2, &pipe); 1002 err = vx_alloc_pipe(chip, 1, audio, 2, &pipe);
1001 if (err < 0) 1003 if (err < 0)
1002 return err; 1004 return err;
@@ -1214,7 +1216,8 @@ void vx_pcm_update_intr(struct vx_core *chip, unsigned int events)
1214 } 1216 }
1215 if (capture) 1217 if (capture)
1216 continue; 1218 continue;
1217 snd_assert(p >= 0 && (unsigned int)p < chip->audio_outs,); 1219 if (snd_BUG_ON(p < 0 || p >= chip->audio_outs))
1220 continue;
1218 pipe = chip->playback_pipes[p]; 1221 pipe = chip->playback_pipes[p];
1219 if (pipe && pipe->substream) { 1222 if (pipe && pipe->substream) {
1220 vx_pcm_playback_update(chip, pipe->substream, pipe); 1223 vx_pcm_playback_update(chip, pipe->substream, pipe);
diff --git a/sound/drivers/vx/vx_uer.c b/sound/drivers/vx/vx_uer.c
index fb8932af888d..0e1ba9b47904 100644
--- a/sound/drivers/vx/vx_uer.c
+++ b/sound/drivers/vx/vx_uer.c
@@ -163,13 +163,15 @@ static int vx_calc_clock_from_freq(struct vx_core *chip, int freq)
163{ 163{
164 int hexfreq; 164 int hexfreq;
165 165
166 snd_assert(freq > 0, return 0); 166 if (snd_BUG_ON(freq <= 0))
167 return 0;
167 168
168 hexfreq = (28224000 * 10) / freq; 169 hexfreq = (28224000 * 10) / freq;
169 hexfreq = (hexfreq + 5) / 10; 170 hexfreq = (hexfreq + 5) / 10;
170 171
171 /* max freq = 55125 Hz */ 172 /* max freq = 55125 Hz */
172 snd_assert(hexfreq > 0x00000200, return 0); 173 if (snd_BUG_ON(hexfreq <= 0x00000200))
174 return 0;
173 175
174 if (hexfreq <= 0x03ff) 176 if (hexfreq <= 0x03ff)
175 return hexfreq - 0x00000201; 177 return hexfreq - 0x00000201;
diff --git a/sound/i2c/cs8427.c b/sound/i2c/cs8427.c
index 9c3d361accfb..020a5d512472 100644
--- a/sound/i2c/cs8427.c
+++ b/sound/i2c/cs8427.c
@@ -314,7 +314,8 @@ static void snd_cs8427_reset(struct snd_i2c_device *cs8427)
314 unsigned long end_time; 314 unsigned long end_time;
315 int data, aes3input = 0; 315 int data, aes3input = 0;
316 316
317 snd_assert(cs8427, return); 317 if (snd_BUG_ON(!cs8427))
318 return;
318 chip = cs8427->private_data; 319 chip = cs8427->private_data;
319 snd_i2c_lock(cs8427->bus); 320 snd_i2c_lock(cs8427->bus);
320 if ((chip->regmap[CS8427_REG_CLOCKSOURCE] & CS8427_RXDAES3INPUT) == 321 if ((chip->regmap[CS8427_REG_CLOCKSOURCE] & CS8427_RXDAES3INPUT) ==
@@ -526,7 +527,8 @@ int snd_cs8427_iec958_build(struct snd_i2c_device *cs8427,
526 unsigned int idx; 527 unsigned int idx;
527 int err; 528 int err;
528 529
529 snd_assert(play_substream && cap_substream, return -EINVAL); 530 if (snd_BUG_ON(!play_substream || !cap_substream))
531 return -EINVAL;
530 for (idx = 0; idx < ARRAY_SIZE(snd_cs8427_iec958_controls); idx++) { 532 for (idx = 0; idx < ARRAY_SIZE(snd_cs8427_iec958_controls); idx++) {
531 kctl = snd_ctl_new1(&snd_cs8427_iec958_controls[idx], cs8427); 533 kctl = snd_ctl_new1(&snd_cs8427_iec958_controls[idx], cs8427);
532 if (kctl == NULL) 534 if (kctl == NULL)
@@ -543,7 +545,8 @@ int snd_cs8427_iec958_build(struct snd_i2c_device *cs8427,
543 545
544 chip->playback.substream = play_substream; 546 chip->playback.substream = play_substream;
545 chip->capture.substream = cap_substream; 547 chip->capture.substream = cap_substream;
546 snd_assert(chip->playback.pcm_ctl, return -EIO); 548 if (snd_BUG_ON(!chip->playback.pcm_ctl))
549 return -EIO;
547 return 0; 550 return 0;
548} 551}
549 552
@@ -553,7 +556,8 @@ int snd_cs8427_iec958_active(struct snd_i2c_device *cs8427, int active)
553{ 556{
554 struct cs8427 *chip; 557 struct cs8427 *chip;
555 558
556 snd_assert(cs8427, return -ENXIO); 559 if (snd_BUG_ON(!cs8427))
560 return -ENXIO;
557 chip = cs8427->private_data; 561 chip = cs8427->private_data;
558 if (active) 562 if (active)
559 memcpy(chip->playback.pcm_status, 563 memcpy(chip->playback.pcm_status,
@@ -573,7 +577,8 @@ int snd_cs8427_iec958_pcm(struct snd_i2c_device *cs8427, unsigned int rate)
573 char *status; 577 char *status;
574 int err, reset; 578 int err, reset;
575 579
576 snd_assert(cs8427, return -ENXIO); 580 if (snd_BUG_ON(!cs8427))
581 return -ENXIO;
577 chip = cs8427->private_data; 582 chip = cs8427->private_data;
578 status = chip->playback.pcm_status; 583 status = chip->playback.pcm_status;
579 snd_i2c_lock(cs8427->bus); 584 snd_i2c_lock(cs8427->bus);
diff --git a/sound/i2c/i2c.c b/sound/i2c/i2c.c
index b1e74e40cba0..5c0c77dd01c3 100644
--- a/sound/i2c/i2c.c
+++ b/sound/i2c/i2c.c
@@ -49,7 +49,8 @@ static int snd_i2c_bus_free(struct snd_i2c_bus *bus)
49 struct snd_i2c_bus *slave; 49 struct snd_i2c_bus *slave;
50 struct snd_i2c_device *device; 50 struct snd_i2c_device *device;
51 51
52 snd_assert(bus != NULL, return -EINVAL); 52 if (snd_BUG_ON(!bus))
53 return -EINVAL;
53 while (!list_empty(&bus->devices)) { 54 while (!list_empty(&bus->devices)) {
54 device = snd_i2c_device(bus->devices.next); 55 device = snd_i2c_device(bus->devices.next);
55 snd_i2c_device_free(device); 56 snd_i2c_device_free(device);
@@ -113,7 +114,8 @@ int snd_i2c_device_create(struct snd_i2c_bus *bus, const char *name,
113 struct snd_i2c_device *device; 114 struct snd_i2c_device *device;
114 115
115 *rdevice = NULL; 116 *rdevice = NULL;
116 snd_assert(bus != NULL, return -EINVAL); 117 if (snd_BUG_ON(!bus))
118 return -EINVAL;
117 device = kzalloc(sizeof(*device), GFP_KERNEL); 119 device = kzalloc(sizeof(*device), GFP_KERNEL);
118 if (device == NULL) 120 if (device == NULL)
119 return -ENOMEM; 121 return -ENOMEM;
diff --git a/sound/i2c/l3/uda1341.c b/sound/i2c/l3/uda1341.c
index 1f4942ea1414..9840eb43648d 100644
--- a/sound/i2c/l3/uda1341.c
+++ b/sound/i2c/l3/uda1341.c
@@ -771,7 +771,8 @@ int __init snd_chip_uda1341_mixer_new(struct snd_card *card, struct l3_client **
771 struct l3_client *clnt; 771 struct l3_client *clnt;
772 int idx, err; 772 int idx, err;
773 773
774 snd_assert(card != NULL, return -EINVAL); 774 if (snd_BUG_ON(!card))
775 return -EINVAL;
775 776
776 clnt = kzalloc(sizeof(*clnt), GFP_KERNEL); 777 clnt = kzalloc(sizeof(*clnt), GFP_KERNEL);
777 if (clnt == NULL) 778 if (clnt == NULL)
diff --git a/sound/i2c/other/ak4114.c b/sound/i2c/other/ak4114.c
index d20d893b3b60..0341451f814c 100644
--- a/sound/i2c/other/ak4114.c
+++ b/sound/i2c/other/ak4114.c
@@ -475,7 +475,8 @@ int snd_ak4114_build(struct ak4114 *ak4114,
475 unsigned int idx; 475 unsigned int idx;
476 int err; 476 int err;
477 477
478 snd_assert(cap_substream, return -EINVAL); 478 if (snd_BUG_ON(!cap_substream))
479 return -EINVAL;
479 ak4114->playback_substream = ply_substream; 480 ak4114->playback_substream = ply_substream;
480 ak4114->capture_substream = cap_substream; 481 ak4114->capture_substream = cap_substream;
481 for (idx = 0; idx < AK4114_CONTROLS; idx++) { 482 for (idx = 0; idx < AK4114_CONTROLS; idx++) {
diff --git a/sound/i2c/other/ak4117.c b/sound/i2c/other/ak4117.c
index f350835ade96..2cad2d612518 100644
--- a/sound/i2c/other/ak4117.c
+++ b/sound/i2c/other/ak4117.c
@@ -431,7 +431,8 @@ int snd_ak4117_build(struct ak4117 *ak4117, struct snd_pcm_substream *cap_substr
431 unsigned int idx; 431 unsigned int idx;
432 int err; 432 int err;
433 433
434 snd_assert(cap_substream, return -EINVAL); 434 if (snd_BUG_ON(!cap_substream))
435 return -EINVAL;
435 ak4117->substream = cap_substream; 436 ak4117->substream = cap_substream;
436 for (idx = 0; idx < AK4117_CONTROLS; idx++) { 437 for (idx = 0; idx < AK4117_CONTROLS; idx++) {
437 kctl = snd_ctl_new1(&snd_ak4117_iec958_controls[idx], ak4117); 438 kctl = snd_ctl_new1(&snd_ak4117_iec958_controls[idx], ak4117);
diff --git a/sound/i2c/other/ak4xxx-adda.c b/sound/i2c/other/ak4xxx-adda.c
index 288926d2e205..ee47abab764e 100644
--- a/sound/i2c/other/ak4xxx-adda.c
+++ b/sound/i2c/other/ak4xxx-adda.c
@@ -233,8 +233,8 @@ void snd_akm4xxx_init(struct snd_akm4xxx *ak)
233 0x01, 0x02, /* 1: reset and soft-mute */ 233 0x01, 0x02, /* 1: reset and soft-mute */
234 0x00, 0x06, /* 0: mode3(i2s), disable auto-clock detect, 234 0x00, 0x06, /* 0: mode3(i2s), disable auto-clock detect,
235 * disable DZF, sharp roll-off, RSTN#=0 */ 235 * disable DZF, sharp roll-off, RSTN#=0 */
236 0x02, 0x0e, /* 2: DA's power up, normal speed, RSTN#=0 */ 236 0x02, 0x4e, /* 2: DA's power up, normal speed, RSTN#=0 */
237 // 0x02, 0x2e, /* quad speed */ 237 /* 0x02, 0x6e,*/ /* quad speed */
238 0x03, 0x01, /* 3: de-emphasis off */ 238 0x03, 0x01, /* 3: de-emphasis off */
239 0x04, 0x00, /* 4: LOUT1 volume muted */ 239 0x04, 0x00, /* 4: LOUT1 volume muted */
240 0x05, 0x00, /* 5: ROUT1 volume muted */ 240 0x05, 0x00, /* 5: ROUT1 volume muted */
diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c
index 83e90057270e..c13a178383ba 100644
--- a/sound/i2c/other/tea575x-tuner.c
+++ b/sound/i2c/other/tea575x-tuner.c
@@ -87,8 +87,7 @@ static void snd_tea575x_set_freq(struct snd_tea575x *tea)
87static int snd_tea575x_ioctl(struct inode *inode, struct file *file, 87static int snd_tea575x_ioctl(struct inode *inode, struct file *file,
88 unsigned int cmd, unsigned long data) 88 unsigned int cmd, unsigned long data)
89{ 89{
90 struct video_device *dev = video_devdata(file); 90 struct snd_tea575x *tea = video_drvdata(file);
91 struct snd_tea575x *tea = video_get_drvdata(dev);
92 void __user *arg = (void __user *)data; 91 void __user *arg = (void __user *)data;
93 92
94 switch(cmd) { 93 switch(cmd) {
@@ -175,6 +174,21 @@ static void snd_tea575x_release(struct video_device *vfd)
175{ 174{
176} 175}
177 176
177static int snd_tea575x_exclusive_open(struct inode *inode, struct file *file)
178{
179 struct snd_tea575x *tea = video_drvdata(file);
180
181 return test_and_set_bit(0, &tea->in_use) ? -EBUSY : 0;
182}
183
184static int snd_tea575x_exclusive_release(struct inode *inode, struct file *file)
185{
186 struct snd_tea575x *tea = video_drvdata(file);
187
188 clear_bit(0, &tea->in_use);
189 return 0;
190}
191
178/* 192/*
179 * initialize all the tea575x chips 193 * initialize all the tea575x chips
180 */ 194 */
@@ -193,9 +207,10 @@ void snd_tea575x_init(struct snd_tea575x *tea)
193 tea->vd.release = snd_tea575x_release; 207 tea->vd.release = snd_tea575x_release;
194 video_set_drvdata(&tea->vd, tea); 208 video_set_drvdata(&tea->vd, tea);
195 tea->vd.fops = &tea->fops; 209 tea->vd.fops = &tea->fops;
210 tea->in_use = 0;
196 tea->fops.owner = tea->card->module; 211 tea->fops.owner = tea->card->module;
197 tea->fops.open = video_exclusive_open; 212 tea->fops.open = snd_tea575x_exclusive_open;
198 tea->fops.release = video_exclusive_release; 213 tea->fops.release = snd_tea575x_exclusive_release;
199 tea->fops.ioctl = snd_tea575x_ioctl; 214 tea->fops.ioctl = snd_tea575x_ioctl;
200 if (video_register_device(&tea->vd, VFL_TYPE_RADIO, tea->dev_nr - 1) < 0) { 215 if (video_register_device(&tea->vd, VFL_TYPE_RADIO, tea->dev_nr - 1) < 0) {
201 snd_printk(KERN_ERR "unable to register tea575x tuner\n"); 216 snd_printk(KERN_ERR "unable to register tea575x tuner\n");
diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig
index 5769a13c1d95..660beb41f767 100644
--- a/sound/isa/Kconfig
+++ b/sound/isa/Kconfig
@@ -1,10 +1,6 @@
1# ALSA ISA drivers 1# ALSA ISA drivers
2 2
3config SND_AD1848_LIB 3config SND_WSS_LIB
4 tristate
5 select SND_PCM
6
7config SND_CS4231_LIB
8 tristate 4 tristate
9 select SND_PCM 5 select SND_PCM
10 6
@@ -55,7 +51,7 @@ config SND_AD1816A
55 51
56config SND_AD1848 52config SND_AD1848
57 tristate "Generic AD1848/CS4248 driver" 53 tristate "Generic AD1848/CS4248 driver"
58 select SND_AD1848_LIB 54 select SND_WSS_LIB
59 help 55 help
60 Say Y here to include support for AD1848 (Analog Devices) or 56 Say Y here to include support for AD1848 (Analog Devices) or
61 CS4248 (Cirrus Logic - Crystal Semiconductors) chips. 57 CS4248 (Cirrus Logic - Crystal Semiconductors) chips.
@@ -86,7 +82,7 @@ config SND_AZT2320
86 select ISAPNP 82 select ISAPNP
87 select SND_OPL3_LIB 83 select SND_OPL3_LIB
88 select SND_MPU401_UART 84 select SND_MPU401_UART
89 select SND_CS4231_LIB 85 select SND_WSS_LIB
90 help 86 help
91 Say Y here to include support for soundcards based on the 87 Say Y here to include support for soundcards based on the
92 Aztech Systems AZT2320 chip. 88 Aztech Systems AZT2320 chip.
@@ -96,7 +92,7 @@ config SND_AZT2320
96 92
97config SND_CMI8330 93config SND_CMI8330
98 tristate "C-Media CMI8330" 94 tristate "C-Media CMI8330"
99 select SND_AD1848_LIB 95 select SND_WSS_LIB
100 select SND_SB16_DSP 96 select SND_SB16_DSP
101 help 97 help
102 Say Y here to include support for soundcards based on the 98 Say Y here to include support for soundcards based on the
@@ -108,7 +104,7 @@ config SND_CMI8330
108config SND_CS4231 104config SND_CS4231
109 tristate "Generic Cirrus Logic CS4231 driver" 105 tristate "Generic Cirrus Logic CS4231 driver"
110 select SND_MPU401_UART 106 select SND_MPU401_UART
111 select SND_CS4231_LIB 107 select SND_WSS_LIB
112 help 108 help
113 Say Y here to include support for CS4231 chips from Cirrus 109 Say Y here to include support for CS4231 chips from Cirrus
114 Logic - Crystal Semiconductors. 110 Logic - Crystal Semiconductors.
@@ -120,7 +116,7 @@ config SND_CS4232
120 tristate "Generic Cirrus Logic CS4232 driver" 116 tristate "Generic Cirrus Logic CS4232 driver"
121 select SND_OPL3_LIB 117 select SND_OPL3_LIB
122 select SND_MPU401_UART 118 select SND_MPU401_UART
123 select SND_CS4231_LIB 119 select SND_WSS_LIB
124 help 120 help
125 Say Y here to include support for CS4232 chips from Cirrus 121 Say Y here to include support for CS4232 chips from Cirrus
126 Logic - Crystal Semiconductors. 122 Logic - Crystal Semiconductors.
@@ -132,7 +128,7 @@ config SND_CS4236
132 tristate "Generic Cirrus Logic CS4236+ driver" 128 tristate "Generic Cirrus Logic CS4236+ driver"
133 select SND_OPL3_LIB 129 select SND_OPL3_LIB
134 select SND_MPU401_UART 130 select SND_MPU401_UART
135 select SND_CS4231_LIB 131 select SND_WSS_LIB
136 help 132 help
137 Say Y to include support for CS4235,CS4236,CS4237B,CS4238B, 133 Say Y to include support for CS4235,CS4236,CS4237B,CS4238B,
138 CS4239 chips from Cirrus Logic - Crystal Semiconductors. 134 CS4239 chips from Cirrus Logic - Crystal Semiconductors.
@@ -192,7 +188,7 @@ config SND_ES18XX
192config SND_SC6000 188config SND_SC6000
193 tristate "Gallant SC-6000, Audio Excel DSP 16" 189 tristate "Gallant SC-6000, Audio Excel DSP 16"
194 depends on HAS_IOPORT 190 depends on HAS_IOPORT
195 select SND_AD1848_LIB 191 select SND_WSS_LIB
196 select SND_OPL3_LIB 192 select SND_OPL3_LIB
197 select SND_MPU401_UART 193 select SND_MPU401_UART
198 help 194 help
@@ -228,7 +224,7 @@ config SND_GUSEXTREME
228config SND_GUSMAX 224config SND_GUSMAX
229 tristate "Gravis UltraSound MAX" 225 tristate "Gravis UltraSound MAX"
230 select SND_RAWMIDI 226 select SND_RAWMIDI
231 select SND_CS4231_LIB 227 select SND_WSS_LIB
232 help 228 help
233 Say Y here to include support for Gravis UltraSound MAX 229 Say Y here to include support for Gravis UltraSound MAX
234 soundcards. 230 soundcards.
@@ -240,7 +236,7 @@ config SND_INTERWAVE
240 tristate "AMD InterWave, Gravis UltraSound PnP" 236 tristate "AMD InterWave, Gravis UltraSound PnP"
241 depends on PNP 237 depends on PNP
242 select SND_RAWMIDI 238 select SND_RAWMIDI
243 select SND_CS4231_LIB 239 select SND_WSS_LIB
244 help 240 help
245 Say Y here to include support for AMD InterWave based 241 Say Y here to include support for AMD InterWave based
246 soundcards (Gravis UltraSound Plug & Play, STB SoundRage32, 242 soundcards (Gravis UltraSound Plug & Play, STB SoundRage32,
@@ -253,7 +249,7 @@ config SND_INTERWAVE_STB
253 tristate "AMD InterWave + TEA6330T (UltraSound 32-Pro)" 249 tristate "AMD InterWave + TEA6330T (UltraSound 32-Pro)"
254 depends on PNP 250 depends on PNP
255 select SND_RAWMIDI 251 select SND_RAWMIDI
256 select SND_CS4231_LIB 252 select SND_WSS_LIB
257 help 253 help
258 Say Y here to include support for AMD InterWave based 254 Say Y here to include support for AMD InterWave based
259 soundcards with a TEA6330T bass and treble regulator 255 soundcards with a TEA6330T bass and treble regulator
@@ -266,7 +262,7 @@ config SND_OPL3SA2
266 tristate "Yamaha OPL3-SA2/SA3" 262 tristate "Yamaha OPL3-SA2/SA3"
267 select SND_OPL3_LIB 263 select SND_OPL3_LIB
268 select SND_MPU401_UART 264 select SND_MPU401_UART
269 select SND_CS4231_LIB 265 select SND_WSS_LIB
270 help 266 help
271 Say Y here to include support for Yamaha OPL3-SA2 and OPL3-SA3 267 Say Y here to include support for Yamaha OPL3-SA2 and OPL3-SA3
272 chips. 268 chips.
@@ -279,7 +275,7 @@ config SND_OPTI92X_AD1848
279 select SND_OPL3_LIB 275 select SND_OPL3_LIB
280 select SND_OPL4_LIB 276 select SND_OPL4_LIB
281 select SND_MPU401_UART 277 select SND_MPU401_UART
282 select SND_AD1848_LIB 278 select SND_WSS_LIB
283 help 279 help
284 Say Y here to include support for soundcards based on Opti 280 Say Y here to include support for soundcards based on Opti
285 82C92x or OTI-601 chips and using an AD1848 codec. 281 82C92x or OTI-601 chips and using an AD1848 codec.
@@ -292,7 +288,7 @@ config SND_OPTI92X_CS4231
292 select SND_OPL3_LIB 288 select SND_OPL3_LIB
293 select SND_OPL4_LIB 289 select SND_OPL4_LIB
294 select SND_MPU401_UART 290 select SND_MPU401_UART
295 select SND_CS4231_LIB 291 select SND_WSS_LIB
296 help 292 help
297 Say Y here to include support for soundcards based on Opti 293 Say Y here to include support for soundcards based on Opti
298 82C92x chips and using a CS4231 codec. 294 82C92x chips and using a CS4231 codec.
@@ -304,7 +300,7 @@ config SND_OPTI93X
304 tristate "OPTi 82C93x" 300 tristate "OPTi 82C93x"
305 select SND_OPL3_LIB 301 select SND_OPL3_LIB
306 select SND_MPU401_UART 302 select SND_MPU401_UART
307 select SND_CS4231_LIB 303 select SND_WSS_LIB
308 help 304 help
309 Say Y here to include support for soundcards based on Opti 305 Say Y here to include support for soundcards based on Opti
310 82C93x chips. 306 82C93x chips.
@@ -315,7 +311,7 @@ config SND_OPTI93X
315config SND_MIRO 311config SND_MIRO
316 tristate "Miro miroSOUND PCM1pro/PCM12/PCM20radio driver" 312 tristate "Miro miroSOUND PCM1pro/PCM12/PCM20radio driver"
317 select SND_OPL4_LIB 313 select SND_OPL4_LIB
318 select SND_CS4231_LIB 314 select SND_WSS_LIB
319 select SND_MPU401_UART 315 select SND_MPU401_UART
320 select SND_PCM 316 select SND_PCM
321 help 317 help
@@ -364,7 +360,7 @@ config SND_SBAWE
364config SND_SB16_CSP 360config SND_SB16_CSP
365 bool "Sound Blaster 16/AWE CSP support" 361 bool "Sound Blaster 16/AWE CSP support"
366 depends on (SND_SB16 || SND_SBAWE) && (BROKEN || !PPC) 362 depends on (SND_SB16 || SND_SBAWE) && (BROKEN || !PPC)
367 select FW_LOADER if !SND_SB16_CSP_FIRMWARE_IN_KERNEL 363 select FW_LOADER
368 help 364 help
369 Say Y here to include support for the CSP core. This special 365 Say Y here to include support for the CSP core. This special
370 coprocessor can do variable tasks like various compression and 366 coprocessor can do variable tasks like various compression and
@@ -372,7 +368,7 @@ config SND_SB16_CSP
372 368
373config SND_SGALAXY 369config SND_SGALAXY
374 tristate "Aztech Sound Galaxy" 370 tristate "Aztech Sound Galaxy"
375 select SND_AD1848_LIB 371 select SND_WSS_LIB
376 help 372 help
377 Say Y here to include support for Aztech Sound Galaxy 373 Say Y here to include support for Aztech Sound Galaxy
378 soundcards. 374 soundcards.
@@ -384,7 +380,7 @@ config SND_SSCAPE
384 tristate "Ensoniq SoundScape PnP driver" 380 tristate "Ensoniq SoundScape PnP driver"
385 select SND_HWDEP 381 select SND_HWDEP
386 select SND_MPU401_UART 382 select SND_MPU401_UART
387 select SND_CS4231_LIB 383 select SND_WSS_LIB
388 help 384 help
389 Say Y here to include support for Ensoniq SoundScape PnP 385 Say Y here to include support for Ensoniq SoundScape PnP
390 soundcards. 386 soundcards.
@@ -397,7 +393,7 @@ config SND_WAVEFRONT
397 select FW_LOADER 393 select FW_LOADER
398 select SND_OPL3_LIB 394 select SND_OPL3_LIB
399 select SND_MPU401_UART 395 select SND_MPU401_UART
400 select SND_CS4231_LIB 396 select SND_WSS_LIB
401 help 397 help
402 Say Y here to include support for Turtle Beach Maui, Tropez 398 Say Y here to include support for Turtle Beach Maui, Tropez
403 and Tropez+ soundcards based on the Wavefront chip. 399 and Tropez+ soundcards based on the Wavefront chip.
diff --git a/sound/isa/Makefile b/sound/isa/Makefile
index c0ce7db2a1b5..63af13d901a5 100644
--- a/sound/isa/Makefile
+++ b/sound/isa/Makefile
@@ -27,4 +27,4 @@ obj-$(CONFIG_SND_SGALAXY) += snd-sgalaxy.o
27obj-$(CONFIG_SND_SSCAPE) += snd-sscape.o 27obj-$(CONFIG_SND_SSCAPE) += snd-sscape.o
28 28
29obj-$(CONFIG_SND) += ad1816a/ ad1848/ cs423x/ es1688/ gus/ opti9xx/ \ 29obj-$(CONFIG_SND) += ad1816a/ ad1848/ cs423x/ es1688/ gus/ opti9xx/ \
30 sb/ wavefront/ 30 sb/ wavefront/ wss/
diff --git a/sound/isa/ad1816a/ad1816a.c b/sound/isa/ad1816a/ad1816a.c
index 68f1260b5602..77524244a846 100644
--- a/sound/isa/ad1816a/ad1816a.c
+++ b/sound/isa/ad1816a/ad1816a.c
@@ -83,8 +83,10 @@ static struct pnp_card_device_id snd_ad1816a_pnpids[] = {
83 { .id = "MDK1605", .devs = { { .id = "ADS7180" }, { .id = "ADS7181" } } }, 83 { .id = "MDK1605", .devs = { { .id = "ADS7180" }, { .id = "ADS7181" } } },
84 /* Shark Predator ISA - added by Ken Arromdee */ 84 /* Shark Predator ISA - added by Ken Arromdee */
85 { .id = "SMM7180", .devs = { { .id = "ADS7180" }, { .id = "ADS7181" } } }, 85 { .id = "SMM7180", .devs = { { .id = "ADS7180" }, { .id = "ADS7181" } } },
86 /* Analog Devices AD1816A - Terratec AudioSystem EWS64S */ 86 /* Analog Devices AD1816A - Terratec AudioSystem EWS64 S */
87 { .id = "TER1112", .devs = { { .id = "ADS7180" }, { .id = "ADS7181" } } }, 87 { .id = "TER1112", .devs = { { .id = "ADS7180" }, { .id = "ADS7181" } } },
88 /* Analog Devices AD1816A - Terratec AudioSystem EWS64 S */
89 { .id = "TER1112", .devs = { { .id = "TER1100" }, { .id = "TER1101" } } },
88 /* Analog Devices AD1816A - Terratec Base 64 */ 90 /* Analog Devices AD1816A - Terratec Base 64 */
89 { .id = "TER1411", .devs = { { .id = "ADS7180" }, { .id = "ADS7181" } } }, 91 { .id = "TER1411", .devs = { { .id = "ADS7180" }, { .id = "ADS7181" } } },
90 /* end */ 92 /* end */
diff --git a/sound/isa/ad1816a/ad1816a_lib.c b/sound/isa/ad1816a/ad1816a_lib.c
index 4b8dfe2e3dcb..3bfca7c59baf 100644
--- a/sound/isa/ad1816a/ad1816a_lib.c
+++ b/sound/isa/ad1816a/ad1816a_lib.c
@@ -394,7 +394,8 @@ static int snd_ad1816a_timer_open(struct snd_timer *timer)
394 394
395static unsigned long snd_ad1816a_timer_resolution(struct snd_timer *timer) 395static unsigned long snd_ad1816a_timer_resolution(struct snd_timer *timer)
396{ 396{
397 snd_assert(timer != NULL, return 0); 397 if (snd_BUG_ON(!timer))
398 return 0;
398 399
399 return 10000; 400 return 10000;
400} 401}
@@ -961,7 +962,8 @@ int __devinit snd_ad1816a_mixer(struct snd_ad1816a *chip)
961 unsigned int idx; 962 unsigned int idx;
962 int err; 963 int err;
963 964
964 snd_assert(chip != NULL && chip->card != NULL, return -EINVAL); 965 if (snd_BUG_ON(!chip || !chip->card))
966 return -EINVAL;
965 967
966 card = chip->card; 968 card = chip->card;
967 969
diff --git a/sound/isa/ad1848/Makefile b/sound/isa/ad1848/Makefile
index ae23331e9200..3d6dea3ff927 100644
--- a/sound/isa/ad1848/Makefile
+++ b/sound/isa/ad1848/Makefile
@@ -3,10 +3,8 @@
3# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz> 3# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
4# 4#
5 5
6snd-ad1848-lib-objs := ad1848_lib.o
7snd-ad1848-objs := ad1848.o 6snd-ad1848-objs := ad1848.o
8 7
9# Toplevel Module Dependency 8# Toplevel Module Dependency
10obj-$(CONFIG_SND_AD1848) += snd-ad1848.o 9obj-$(CONFIG_SND_AD1848) += snd-ad1848.o
11obj-$(CONFIG_SND_AD1848_LIB) += snd-ad1848-lib.o
12 10
diff --git a/sound/isa/ad1848/ad1848.c b/sound/isa/ad1848/ad1848.c
index 5f5271efdc59..b68d20edc20f 100644
--- a/sound/isa/ad1848/ad1848.c
+++ b/sound/isa/ad1848/ad1848.c
@@ -28,7 +28,7 @@
28#include <linux/wait.h> 28#include <linux/wait.h>
29#include <linux/moduleparam.h> 29#include <linux/moduleparam.h>
30#include <sound/core.h> 30#include <sound/core.h>
31#include <sound/ad1848.h> 31#include <sound/wss.h>
32#include <sound/initval.h> 32#include <sound/initval.h>
33 33
34#define CRD_NAME "Generic AD1848/AD1847/CS4248" 34#define CRD_NAME "Generic AD1848/AD1847/CS4248"
@@ -87,7 +87,7 @@ static int __devinit snd_ad1848_match(struct device *dev, unsigned int n)
87static int __devinit snd_ad1848_probe(struct device *dev, unsigned int n) 87static int __devinit snd_ad1848_probe(struct device *dev, unsigned int n)
88{ 88{
89 struct snd_card *card; 89 struct snd_card *card;
90 struct snd_ad1848 *chip; 90 struct snd_wss *chip;
91 struct snd_pcm *pcm; 91 struct snd_pcm *pcm;
92 int error; 92 int error;
93 93
@@ -95,18 +95,19 @@ static int __devinit snd_ad1848_probe(struct device *dev, unsigned int n)
95 if (!card) 95 if (!card)
96 return -EINVAL; 96 return -EINVAL;
97 97
98 error = snd_ad1848_create(card, port[n], irq[n], dma1[n], 98 error = snd_wss_create(card, port[n], -1, irq[n], dma1[n], -1,
99 thinkpad[n] ? AD1848_HW_THINKPAD : AD1848_HW_DETECT, &chip); 99 thinkpad[n] ? WSS_HW_THINKPAD : WSS_HW_DETECT,
100 0, &chip);
100 if (error < 0) 101 if (error < 0)
101 goto out; 102 goto out;
102 103
103 card->private_data = chip; 104 card->private_data = chip;
104 105
105 error = snd_ad1848_pcm(chip, 0, &pcm); 106 error = snd_wss_pcm(chip, 0, &pcm);
106 if (error < 0) 107 if (error < 0)
107 goto out; 108 goto out;
108 109
109 error = snd_ad1848_mixer(chip); 110 error = snd_wss_mixer(chip);
110 if (error < 0) 111 if (error < 0)
111 goto out; 112 goto out;
112 113
@@ -142,7 +143,7 @@ static int __devexit snd_ad1848_remove(struct device *dev, unsigned int n)
142static int snd_ad1848_suspend(struct device *dev, unsigned int n, pm_message_t state) 143static int snd_ad1848_suspend(struct device *dev, unsigned int n, pm_message_t state)
143{ 144{
144 struct snd_card *card = dev_get_drvdata(dev); 145 struct snd_card *card = dev_get_drvdata(dev);
145 struct snd_ad1848 *chip = card->private_data; 146 struct snd_wss *chip = card->private_data;
146 147
147 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 148 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
148 chip->suspend(chip); 149 chip->suspend(chip);
@@ -152,7 +153,7 @@ static int snd_ad1848_suspend(struct device *dev, unsigned int n, pm_message_t s
152static int snd_ad1848_resume(struct device *dev, unsigned int n) 153static int snd_ad1848_resume(struct device *dev, unsigned int n)
153{ 154{
154 struct snd_card *card = dev_get_drvdata(dev); 155 struct snd_card *card = dev_get_drvdata(dev);
155 struct snd_ad1848 *chip = card->private_data; 156 struct snd_wss *chip = card->private_data;
156 157
157 chip->resume(chip); 158 chip->resume(chip);
158 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 159 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
diff --git a/sound/isa/ad1848/ad1848_lib.c b/sound/isa/ad1848/ad1848_lib.c
deleted file mode 100644
index 630c90f9ee50..000000000000
--- a/sound/isa/ad1848/ad1848_lib.c
+++ /dev/null
@@ -1,1267 +0,0 @@
1/*
2 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
3 * Routines for control of AD1848/AD1847/CS4248
4 *
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
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22#define SNDRV_MAIN_OBJECT_FILE
23#include <linux/delay.h>
24#include <linux/init.h>
25#include <linux/interrupt.h>
26#include <linux/slab.h>
27#include <linux/ioport.h>
28#include <sound/core.h>
29#include <sound/ad1848.h>
30#include <sound/control.h>
31#include <sound/tlv.h>
32#include <sound/pcm_params.h>
33
34#include <asm/io.h>
35#include <asm/dma.h>
36
37MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
38MODULE_DESCRIPTION("Routines for control of AD1848/AD1847/CS4248");
39MODULE_LICENSE("GPL");
40
41#if 0
42#define SNDRV_DEBUG_MCE
43#endif
44
45/*
46 * Some variables
47 */
48
49static unsigned char freq_bits[14] = {
50 /* 5510 */ 0x00 | AD1848_XTAL2,
51 /* 6620 */ 0x0E | AD1848_XTAL2,
52 /* 8000 */ 0x00 | AD1848_XTAL1,
53 /* 9600 */ 0x0E | AD1848_XTAL1,
54 /* 11025 */ 0x02 | AD1848_XTAL2,
55 /* 16000 */ 0x02 | AD1848_XTAL1,
56 /* 18900 */ 0x04 | AD1848_XTAL2,
57 /* 22050 */ 0x06 | AD1848_XTAL2,
58 /* 27042 */ 0x04 | AD1848_XTAL1,
59 /* 32000 */ 0x06 | AD1848_XTAL1,
60 /* 33075 */ 0x0C | AD1848_XTAL2,
61 /* 37800 */ 0x08 | AD1848_XTAL2,
62 /* 44100 */ 0x0A | AD1848_XTAL2,
63 /* 48000 */ 0x0C | AD1848_XTAL1
64};
65
66static unsigned int rates[14] = {
67 5510, 6620, 8000, 9600, 11025, 16000, 18900, 22050,
68 27042, 32000, 33075, 37800, 44100, 48000
69};
70
71static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
72 .count = ARRAY_SIZE(rates),
73 .list = rates,
74 .mask = 0,
75};
76
77static unsigned char snd_ad1848_original_image[16] =
78{
79 0x00, /* 00 - lic */
80 0x00, /* 01 - ric */
81 0x9f, /* 02 - la1ic */
82 0x9f, /* 03 - ra1ic */
83 0x9f, /* 04 - la2ic */
84 0x9f, /* 05 - ra2ic */
85 0xbf, /* 06 - loc */
86 0xbf, /* 07 - roc */
87 0x20, /* 08 - dfr */
88 AD1848_AUTOCALIB, /* 09 - ic */
89 0x00, /* 0a - pc */
90 0x00, /* 0b - ti */
91 0x00, /* 0c - mi */
92 0x00, /* 0d - lbc */
93 0x00, /* 0e - dru */
94 0x00, /* 0f - drl */
95};
96
97/*
98 * Basic I/O functions
99 */
100
101static void snd_ad1848_wait(struct snd_ad1848 *chip)
102{
103 int timeout;
104
105 for (timeout = 250; timeout > 0; timeout--) {
106 if ((inb(AD1848P(chip, REGSEL)) & AD1848_INIT) == 0)
107 break;
108 udelay(100);
109 }
110}
111
112void snd_ad1848_out(struct snd_ad1848 *chip,
113 unsigned char reg,
114 unsigned char value)
115{
116 snd_ad1848_wait(chip);
117#ifdef CONFIG_SND_DEBUG
118 if (inb(AD1848P(chip, REGSEL)) & AD1848_INIT)
119 snd_printk(KERN_WARNING "auto calibration time out - "
120 "reg = 0x%x, value = 0x%x\n", reg, value);
121#endif
122 outb(chip->mce_bit | reg, AD1848P(chip, REGSEL));
123 outb(chip->image[reg] = value, AD1848P(chip, REG));
124 mb();
125 snd_printdd("codec out - reg 0x%x = 0x%x\n",
126 chip->mce_bit | reg, value);
127}
128
129EXPORT_SYMBOL(snd_ad1848_out);
130
131static void snd_ad1848_dout(struct snd_ad1848 *chip,
132 unsigned char reg, unsigned char value)
133{
134 snd_ad1848_wait(chip);
135 outb(chip->mce_bit | reg, AD1848P(chip, REGSEL));
136 outb(value, AD1848P(chip, REG));
137 mb();
138}
139
140static unsigned char snd_ad1848_in(struct snd_ad1848 *chip, unsigned char reg)
141{
142 snd_ad1848_wait(chip);
143#ifdef CONFIG_SND_DEBUG
144 if (inb(AD1848P(chip, REGSEL)) & AD1848_INIT)
145 snd_printk(KERN_WARNING "auto calibration time out - "
146 "reg = 0x%x\n", reg);
147#endif
148 outb(chip->mce_bit | reg, AD1848P(chip, REGSEL));
149 mb();
150 return inb(AD1848P(chip, REG));
151}
152
153#if 0
154
155static void snd_ad1848_debug(struct snd_ad1848 *chip)
156{
157 printk("AD1848 REGS: INDEX = 0x%02x ", inb(AD1848P(chip, REGSEL)));
158 printk(" STATUS = 0x%02x\n", inb(AD1848P(chip, STATUS)));
159 printk(" 0x00: left input = 0x%02x ", snd_ad1848_in(chip, 0x00));
160 printk(" 0x08: playback format = 0x%02x\n", snd_ad1848_in(chip, 0x08));
161 printk(" 0x01: right input = 0x%02x ", snd_ad1848_in(chip, 0x01));
162 printk(" 0x09: iface (CFIG 1) = 0x%02x\n", snd_ad1848_in(chip, 0x09));
163 printk(" 0x02: AUXA left = 0x%02x ", snd_ad1848_in(chip, 0x02));
164 printk(" 0x0a: pin control = 0x%02x\n", snd_ad1848_in(chip, 0x0a));
165 printk(" 0x03: AUXA right = 0x%02x ", snd_ad1848_in(chip, 0x03));
166 printk(" 0x0b: init & status = 0x%02x\n", snd_ad1848_in(chip, 0x0b));
167 printk(" 0x04: AUXB left = 0x%02x ", snd_ad1848_in(chip, 0x04));
168 printk(" 0x0c: revision & mode = 0x%02x\n", snd_ad1848_in(chip, 0x0c));
169 printk(" 0x05: AUXB right = 0x%02x ", snd_ad1848_in(chip, 0x05));
170 printk(" 0x0d: loopback = 0x%02x\n", snd_ad1848_in(chip, 0x0d));
171 printk(" 0x06: left output = 0x%02x ", snd_ad1848_in(chip, 0x06));
172 printk(" 0x0e: data upr count = 0x%02x\n", snd_ad1848_in(chip, 0x0e));
173 printk(" 0x07: right output = 0x%02x ", snd_ad1848_in(chip, 0x07));
174 printk(" 0x0f: data lwr count = 0x%02x\n", snd_ad1848_in(chip, 0x0f));
175}
176
177#endif
178
179/*
180 * AD1848 detection / MCE routines
181 */
182
183static void snd_ad1848_mce_up(struct snd_ad1848 *chip)
184{
185 unsigned long flags;
186 int timeout;
187
188 snd_ad1848_wait(chip);
189#ifdef CONFIG_SND_DEBUG
190 if (inb(AD1848P(chip, REGSEL)) & AD1848_INIT)
191 snd_printk(KERN_WARNING "mce_up - auto calibration time out (0)\n");
192#endif
193 spin_lock_irqsave(&chip->reg_lock, flags);
194 chip->mce_bit |= AD1848_MCE;
195 timeout = inb(AD1848P(chip, REGSEL));
196 if (timeout == 0x80)
197 snd_printk(KERN_WARNING "mce_up [0x%lx]: serious init problem - codec still busy\n", chip->port);
198 if (!(timeout & AD1848_MCE))
199 outb(chip->mce_bit | (timeout & 0x1f), AD1848P(chip, REGSEL));
200 spin_unlock_irqrestore(&chip->reg_lock, flags);
201}
202
203static void snd_ad1848_mce_down(struct snd_ad1848 *chip)
204{
205 unsigned long flags, timeout;
206 int reg;
207
208 spin_lock_irqsave(&chip->reg_lock, flags);
209 for (timeout = 5; timeout > 0; timeout--)
210 inb(AD1848P(chip, REGSEL));
211 /* end of cleanup sequence */
212 for (timeout = 12000; timeout > 0 && (inb(AD1848P(chip, REGSEL)) & AD1848_INIT); timeout--)
213 udelay(100);
214
215 snd_printdd("(1) timeout = %ld\n", timeout);
216
217#ifdef CONFIG_SND_DEBUG
218 if (inb(AD1848P(chip, REGSEL)) & AD1848_INIT)
219 snd_printk(KERN_WARNING "mce_down [0x%lx] - auto calibration time out (0)\n", AD1848P(chip, REGSEL));
220#endif
221
222 chip->mce_bit &= ~AD1848_MCE;
223 reg = inb(AD1848P(chip, REGSEL));
224 outb(chip->mce_bit | (reg & 0x1f), AD1848P(chip, REGSEL));
225 if (reg == 0x80)
226 snd_printk(KERN_WARNING "mce_down [0x%lx]: serious init problem - codec still busy\n", chip->port);
227 if ((reg & AD1848_MCE) == 0) {
228 spin_unlock_irqrestore(&chip->reg_lock, flags);
229 return;
230 }
231
232 /*
233 * Wait for auto-calibration (AC) process to finish, i.e. ACI to go low.
234 * It may take up to 5 sample periods (at most 907 us @ 5.5125 kHz) for
235 * the process to _start_, so it is important to wait at least that long
236 * before checking. Otherwise we might think AC has finished when it
237 * has in fact not begun. It could take 128 (no AC) or 384 (AC) cycles
238 * for ACI to drop. This gives a wait of at most 70 ms with a more
239 * typical value of 3-9 ms.
240 */
241 timeout = jiffies + msecs_to_jiffies(250);
242 do {
243 spin_unlock_irqrestore(&chip->reg_lock, flags);
244 msleep(1);
245 spin_lock_irqsave(&chip->reg_lock, flags);
246 reg = snd_ad1848_in(chip, AD1848_TEST_INIT) &
247 AD1848_CALIB_IN_PROGRESS;
248 } while (reg && time_before(jiffies, timeout));
249 spin_unlock_irqrestore(&chip->reg_lock, flags);
250 if (reg)
251 snd_printk(KERN_ERR
252 "mce_down - auto calibration time out (2)\n");
253
254 snd_printdd("(4) jiffies = %lu\n", jiffies);
255 snd_printd("mce_down - exit = 0x%x\n", inb(AD1848P(chip, REGSEL)));
256}
257
258static unsigned int snd_ad1848_get_count(unsigned char format,
259 unsigned int size)
260{
261 switch (format & 0xe0) {
262 case AD1848_LINEAR_16:
263 size >>= 1;
264 break;
265 }
266 if (format & AD1848_STEREO)
267 size >>= 1;
268 return size;
269}
270
271static int snd_ad1848_trigger(struct snd_ad1848 *chip, unsigned char what,
272 int channel, int cmd)
273{
274 int result = 0;
275
276#if 0
277 printk("codec trigger!!! - what = %i, enable = %i, status = 0x%x\n", what, enable, inb(AD1848P(card, STATUS)));
278#endif
279 spin_lock(&chip->reg_lock);
280 if (cmd == SNDRV_PCM_TRIGGER_START) {
281 if (chip->image[AD1848_IFACE_CTRL] & what) {
282 spin_unlock(&chip->reg_lock);
283 return 0;
284 }
285 snd_ad1848_out(chip, AD1848_IFACE_CTRL, chip->image[AD1848_IFACE_CTRL] |= what);
286 chip->mode |= AD1848_MODE_RUNNING;
287 } else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
288 if (!(chip->image[AD1848_IFACE_CTRL] & what)) {
289 spin_unlock(&chip->reg_lock);
290 return 0;
291 }
292 snd_ad1848_out(chip, AD1848_IFACE_CTRL, chip->image[AD1848_IFACE_CTRL] &= ~what);
293 chip->mode &= ~AD1848_MODE_RUNNING;
294 } else {
295 result = -EINVAL;
296 }
297 spin_unlock(&chip->reg_lock);
298 return result;
299}
300
301/*
302 * CODEC I/O
303 */
304
305static unsigned char snd_ad1848_get_rate(unsigned int rate)
306{
307 int i;
308
309 for (i = 0; i < ARRAY_SIZE(rates); i++)
310 if (rate == rates[i])
311 return freq_bits[i];
312 snd_BUG();
313 return freq_bits[ARRAY_SIZE(rates) - 1];
314}
315
316static int snd_ad1848_ioctl(struct snd_pcm_substream *substream,
317 unsigned int cmd, void *arg)
318{
319 return snd_pcm_lib_ioctl(substream, cmd, arg);
320}
321
322static unsigned char snd_ad1848_get_format(int format, int channels)
323{
324 unsigned char rformat;
325
326 rformat = AD1848_LINEAR_8;
327 switch (format) {
328 case SNDRV_PCM_FORMAT_A_LAW: rformat = AD1848_ALAW_8; break;
329 case SNDRV_PCM_FORMAT_MU_LAW: rformat = AD1848_ULAW_8; break;
330 case SNDRV_PCM_FORMAT_S16_LE: rformat = AD1848_LINEAR_16; break;
331 }
332 if (channels > 1)
333 rformat |= AD1848_STEREO;
334#if 0
335 snd_printk("get_format: 0x%x (mode=0x%x)\n", format, mode);
336#endif
337 return rformat;
338}
339
340static void snd_ad1848_calibrate_mute(struct snd_ad1848 *chip, int mute)
341{
342 unsigned long flags;
343
344 mute = mute ? 1 : 0;
345 spin_lock_irqsave(&chip->reg_lock, flags);
346 if (chip->calibrate_mute == mute) {
347 spin_unlock_irqrestore(&chip->reg_lock, flags);
348 return;
349 }
350 if (!mute) {
351 snd_ad1848_dout(chip, AD1848_LEFT_INPUT, chip->image[AD1848_LEFT_INPUT]);
352 snd_ad1848_dout(chip, AD1848_RIGHT_INPUT, chip->image[AD1848_RIGHT_INPUT]);
353 }
354 snd_ad1848_dout(chip, AD1848_AUX1_LEFT_INPUT, mute ? 0x80 : chip->image[AD1848_AUX1_LEFT_INPUT]);
355 snd_ad1848_dout(chip, AD1848_AUX1_RIGHT_INPUT, mute ? 0x80 : chip->image[AD1848_AUX1_RIGHT_INPUT]);
356 snd_ad1848_dout(chip, AD1848_AUX2_LEFT_INPUT, mute ? 0x80 : chip->image[AD1848_AUX2_LEFT_INPUT]);
357 snd_ad1848_dout(chip, AD1848_AUX2_RIGHT_INPUT, mute ? 0x80 : chip->image[AD1848_AUX2_RIGHT_INPUT]);
358 snd_ad1848_dout(chip, AD1848_LEFT_OUTPUT, mute ? 0x80 : chip->image[AD1848_LEFT_OUTPUT]);
359 snd_ad1848_dout(chip, AD1848_RIGHT_OUTPUT, mute ? 0x80 : chip->image[AD1848_RIGHT_OUTPUT]);
360 chip->calibrate_mute = mute;
361 spin_unlock_irqrestore(&chip->reg_lock, flags);
362}
363
364static void snd_ad1848_set_data_format(struct snd_ad1848 *chip, struct snd_pcm_hw_params *hw_params)
365{
366 if (hw_params == NULL) {
367 chip->image[AD1848_DATA_FORMAT] = 0x20;
368 } else {
369 chip->image[AD1848_DATA_FORMAT] =
370 snd_ad1848_get_format(params_format(hw_params), params_channels(hw_params)) |
371 snd_ad1848_get_rate(params_rate(hw_params));
372 }
373 // snd_printk(">>> pmode = 0x%x, dfr = 0x%x\n", pstr->mode, chip->image[AD1848_DATA_FORMAT]);
374}
375
376static int snd_ad1848_open(struct snd_ad1848 *chip, unsigned int mode)
377{
378 unsigned long flags;
379
380 if (chip->mode & AD1848_MODE_OPEN)
381 return -EAGAIN;
382
383 snd_ad1848_mce_down(chip);
384
385#ifdef SNDRV_DEBUG_MCE
386 snd_printk("open: (1)\n");
387#endif
388 snd_ad1848_mce_up(chip);
389 spin_lock_irqsave(&chip->reg_lock, flags);
390 chip->image[AD1848_IFACE_CTRL] &= ~(AD1848_PLAYBACK_ENABLE | AD1848_PLAYBACK_PIO |
391 AD1848_CAPTURE_ENABLE | AD1848_CAPTURE_PIO |
392 AD1848_CALIB_MODE);
393 chip->image[AD1848_IFACE_CTRL] |= AD1848_AUTOCALIB;
394 snd_ad1848_out(chip, AD1848_IFACE_CTRL, chip->image[AD1848_IFACE_CTRL]);
395 spin_unlock_irqrestore(&chip->reg_lock, flags);
396 snd_ad1848_mce_down(chip);
397
398#ifdef SNDRV_DEBUG_MCE
399 snd_printk("open: (2)\n");
400#endif
401
402 snd_ad1848_set_data_format(chip, NULL);
403
404 snd_ad1848_mce_up(chip);
405 spin_lock_irqsave(&chip->reg_lock, flags);
406 snd_ad1848_out(chip, AD1848_DATA_FORMAT, chip->image[AD1848_DATA_FORMAT]);
407 spin_unlock_irqrestore(&chip->reg_lock, flags);
408 snd_ad1848_mce_down(chip);
409
410#ifdef SNDRV_DEBUG_MCE
411 snd_printk("open: (3)\n");
412#endif
413
414 /* ok. now enable and ack CODEC IRQ */
415 spin_lock_irqsave(&chip->reg_lock, flags);
416 outb(0, AD1848P(chip, STATUS)); /* clear IRQ */
417 outb(0, AD1848P(chip, STATUS)); /* clear IRQ */
418 chip->image[AD1848_PIN_CTRL] |= AD1848_IRQ_ENABLE;
419 snd_ad1848_out(chip, AD1848_PIN_CTRL, chip->image[AD1848_PIN_CTRL]);
420 spin_unlock_irqrestore(&chip->reg_lock, flags);
421
422 chip->mode = mode;
423
424 return 0;
425}
426
427static void snd_ad1848_close(struct snd_ad1848 *chip)
428{
429 unsigned long flags;
430
431 if (!chip->mode)
432 return;
433 /* disable IRQ */
434 spin_lock_irqsave(&chip->reg_lock, flags);
435 outb(0, AD1848P(chip, STATUS)); /* clear IRQ */
436 outb(0, AD1848P(chip, STATUS)); /* clear IRQ */
437 chip->image[AD1848_PIN_CTRL] &= ~AD1848_IRQ_ENABLE;
438 snd_ad1848_out(chip, AD1848_PIN_CTRL, chip->image[AD1848_PIN_CTRL]);
439 spin_unlock_irqrestore(&chip->reg_lock, flags);
440
441 /* now disable capture & playback */
442
443 snd_ad1848_mce_up(chip);
444 spin_lock_irqsave(&chip->reg_lock, flags);
445 chip->image[AD1848_IFACE_CTRL] &= ~(AD1848_PLAYBACK_ENABLE | AD1848_PLAYBACK_PIO |
446 AD1848_CAPTURE_ENABLE | AD1848_CAPTURE_PIO);
447 snd_ad1848_out(chip, AD1848_IFACE_CTRL, chip->image[AD1848_IFACE_CTRL]);
448 spin_unlock_irqrestore(&chip->reg_lock, flags);
449 snd_ad1848_mce_down(chip);
450
451 /* clear IRQ again */
452 spin_lock_irqsave(&chip->reg_lock, flags);
453 outb(0, AD1848P(chip, STATUS)); /* clear IRQ */
454 outb(0, AD1848P(chip, STATUS)); /* clear IRQ */
455 spin_unlock_irqrestore(&chip->reg_lock, flags);
456
457 chip->mode = 0;
458}
459
460/*
461 * ok.. exported functions..
462 */
463
464static int snd_ad1848_playback_trigger(struct snd_pcm_substream *substream,
465 int cmd)
466{
467 struct snd_ad1848 *chip = snd_pcm_substream_chip(substream);
468 return snd_ad1848_trigger(chip, AD1848_PLAYBACK_ENABLE, SNDRV_PCM_STREAM_PLAYBACK, cmd);
469}
470
471static int snd_ad1848_capture_trigger(struct snd_pcm_substream *substream,
472 int cmd)
473{
474 struct snd_ad1848 *chip = snd_pcm_substream_chip(substream);
475 return snd_ad1848_trigger(chip, AD1848_CAPTURE_ENABLE, SNDRV_PCM_STREAM_CAPTURE, cmd);
476}
477
478static int snd_ad1848_playback_hw_params(struct snd_pcm_substream *substream,
479 struct snd_pcm_hw_params *hw_params)
480{
481 struct snd_ad1848 *chip = snd_pcm_substream_chip(substream);
482 unsigned long flags;
483 int err;
484
485 if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
486 return err;
487 snd_ad1848_calibrate_mute(chip, 1);
488 snd_ad1848_set_data_format(chip, hw_params);
489 snd_ad1848_mce_up(chip);
490 spin_lock_irqsave(&chip->reg_lock, flags);
491 snd_ad1848_out(chip, AD1848_DATA_FORMAT, chip->image[AD1848_DATA_FORMAT]);
492 spin_unlock_irqrestore(&chip->reg_lock, flags);
493 snd_ad1848_mce_down(chip);
494 snd_ad1848_calibrate_mute(chip, 0);
495 return 0;
496}
497
498static int snd_ad1848_playback_hw_free(struct snd_pcm_substream *substream)
499{
500 return snd_pcm_lib_free_pages(substream);
501}
502
503static int snd_ad1848_playback_prepare(struct snd_pcm_substream *substream)
504{
505 struct snd_ad1848 *chip = snd_pcm_substream_chip(substream);
506 struct snd_pcm_runtime *runtime = substream->runtime;
507 unsigned long flags;
508 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
509 unsigned int count = snd_pcm_lib_period_bytes(substream);
510
511 chip->dma_size = size;
512 chip->image[AD1848_IFACE_CTRL] &= ~(AD1848_PLAYBACK_ENABLE | AD1848_PLAYBACK_PIO);
513 snd_dma_program(chip->dma, runtime->dma_addr, size, DMA_MODE_WRITE | DMA_AUTOINIT);
514 count = snd_ad1848_get_count(chip->image[AD1848_DATA_FORMAT], count) - 1;
515 spin_lock_irqsave(&chip->reg_lock, flags);
516 snd_ad1848_out(chip, AD1848_DATA_LWR_CNT, (unsigned char) count);
517 snd_ad1848_out(chip, AD1848_DATA_UPR_CNT, (unsigned char) (count >> 8));
518 spin_unlock_irqrestore(&chip->reg_lock, flags);
519 return 0;
520}
521
522static int snd_ad1848_capture_hw_params(struct snd_pcm_substream *substream,
523 struct snd_pcm_hw_params *hw_params)
524{
525 struct snd_ad1848 *chip = snd_pcm_substream_chip(substream);
526 unsigned long flags;
527 int err;
528
529 if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
530 return err;
531 snd_ad1848_calibrate_mute(chip, 1);
532 snd_ad1848_set_data_format(chip, hw_params);
533 snd_ad1848_mce_up(chip);
534 spin_lock_irqsave(&chip->reg_lock, flags);
535 snd_ad1848_out(chip, AD1848_DATA_FORMAT, chip->image[AD1848_DATA_FORMAT]);
536 spin_unlock_irqrestore(&chip->reg_lock, flags);
537 snd_ad1848_mce_down(chip);
538 snd_ad1848_calibrate_mute(chip, 0);
539 return 0;
540}
541
542static int snd_ad1848_capture_hw_free(struct snd_pcm_substream *substream)
543{
544 return snd_pcm_lib_free_pages(substream);
545}
546
547static int snd_ad1848_capture_prepare(struct snd_pcm_substream *substream)
548{
549 struct snd_ad1848 *chip = snd_pcm_substream_chip(substream);
550 struct snd_pcm_runtime *runtime = substream->runtime;
551 unsigned long flags;
552 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
553 unsigned int count = snd_pcm_lib_period_bytes(substream);
554
555 chip->dma_size = size;
556 chip->image[AD1848_IFACE_CTRL] &= ~(AD1848_CAPTURE_ENABLE | AD1848_CAPTURE_PIO);
557 snd_dma_program(chip->dma, runtime->dma_addr, size, DMA_MODE_READ | DMA_AUTOINIT);
558 count = snd_ad1848_get_count(chip->image[AD1848_DATA_FORMAT], count) - 1;
559 spin_lock_irqsave(&chip->reg_lock, flags);
560 snd_ad1848_out(chip, AD1848_DATA_LWR_CNT, (unsigned char) count);
561 snd_ad1848_out(chip, AD1848_DATA_UPR_CNT, (unsigned char) (count >> 8));
562 spin_unlock_irqrestore(&chip->reg_lock, flags);
563 return 0;
564}
565
566static irqreturn_t snd_ad1848_interrupt(int irq, void *dev_id)
567{
568 struct snd_ad1848 *chip = dev_id;
569
570 if ((chip->mode & AD1848_MODE_PLAY) && chip->playback_substream &&
571 (chip->mode & AD1848_MODE_RUNNING))
572 snd_pcm_period_elapsed(chip->playback_substream);
573 if ((chip->mode & AD1848_MODE_CAPTURE) && chip->capture_substream &&
574 (chip->mode & AD1848_MODE_RUNNING))
575 snd_pcm_period_elapsed(chip->capture_substream);
576 outb(0, AD1848P(chip, STATUS)); /* clear global interrupt bit */
577 return IRQ_HANDLED;
578}
579
580static snd_pcm_uframes_t snd_ad1848_playback_pointer(struct snd_pcm_substream *substream)
581{
582 struct snd_ad1848 *chip = snd_pcm_substream_chip(substream);
583 size_t ptr;
584
585 if (!(chip->image[AD1848_IFACE_CTRL] & AD1848_PLAYBACK_ENABLE))
586 return 0;
587 ptr = snd_dma_pointer(chip->dma, chip->dma_size);
588 return bytes_to_frames(substream->runtime, ptr);
589}
590
591static snd_pcm_uframes_t snd_ad1848_capture_pointer(struct snd_pcm_substream *substream)
592{
593 struct snd_ad1848 *chip = snd_pcm_substream_chip(substream);
594 size_t ptr;
595
596 if (!(chip->image[AD1848_IFACE_CTRL] & AD1848_CAPTURE_ENABLE))
597 return 0;
598 ptr = snd_dma_pointer(chip->dma, chip->dma_size);
599 return bytes_to_frames(substream->runtime, ptr);
600}
601
602/*
603
604 */
605
606static void snd_ad1848_thinkpad_twiddle(struct snd_ad1848 *chip, int on) {
607
608 int tmp;
609
610 if (!chip->thinkpad_flag) return;
611
612 outb(0x1c, AD1848_THINKPAD_CTL_PORT1);
613 tmp = inb(AD1848_THINKPAD_CTL_PORT2);
614
615 if (on)
616 /* turn it on */
617 tmp |= AD1848_THINKPAD_CS4248_ENABLE_BIT;
618 else
619 /* turn it off */
620 tmp &= ~AD1848_THINKPAD_CS4248_ENABLE_BIT;
621
622 outb(tmp, AD1848_THINKPAD_CTL_PORT2);
623
624}
625
626#ifdef CONFIG_PM
627static void snd_ad1848_suspend(struct snd_ad1848 *chip)
628{
629 snd_pcm_suspend_all(chip->pcm);
630 if (chip->thinkpad_flag)
631 snd_ad1848_thinkpad_twiddle(chip, 0);
632}
633
634static void snd_ad1848_resume(struct snd_ad1848 *chip)
635{
636 int i;
637
638 if (chip->thinkpad_flag)
639 snd_ad1848_thinkpad_twiddle(chip, 1);
640
641 /* clear any pendings IRQ */
642 inb(AD1848P(chip, STATUS));
643 outb(0, AD1848P(chip, STATUS));
644 mb();
645
646 snd_ad1848_mce_down(chip);
647 for (i = 0; i < 16; i++)
648 snd_ad1848_out(chip, i, chip->image[i]);
649 snd_ad1848_mce_up(chip);
650 snd_ad1848_mce_down(chip);
651}
652#endif /* CONFIG_PM */
653
654static int snd_ad1848_probe(struct snd_ad1848 * chip)
655{
656 unsigned long flags;
657 int i, id, rev, ad1847;
658 unsigned char *ptr;
659
660#if 0
661 snd_ad1848_debug(chip);
662#endif
663 id = ad1847 = 0;
664 for (i = 0; i < 1000; i++) {
665 mb();
666 if (inb(AD1848P(chip, REGSEL)) & AD1848_INIT)
667 udelay(500);
668 else {
669 spin_lock_irqsave(&chip->reg_lock, flags);
670 snd_ad1848_out(chip, AD1848_MISC_INFO, 0x00);
671 snd_ad1848_out(chip, AD1848_LEFT_INPUT, 0xaa);
672 snd_ad1848_out(chip, AD1848_RIGHT_INPUT, 0x45);
673 rev = snd_ad1848_in(chip, AD1848_RIGHT_INPUT);
674 if (rev == 0x65) {
675 spin_unlock_irqrestore(&chip->reg_lock, flags);
676 id = 1;
677 ad1847 = 1;
678 break;
679 }
680 if (snd_ad1848_in(chip, AD1848_LEFT_INPUT) == 0xaa && rev == 0x45) {
681 spin_unlock_irqrestore(&chip->reg_lock, flags);
682 id = 1;
683 break;
684 }
685 spin_unlock_irqrestore(&chip->reg_lock, flags);
686 }
687 }
688 if (id != 1)
689 return -ENODEV; /* no valid device found */
690 if (chip->hardware == AD1848_HW_DETECT) {
691 if (ad1847) {
692 chip->hardware = AD1848_HW_AD1847;
693 } else {
694 chip->hardware = AD1848_HW_AD1848;
695 rev = snd_ad1848_in(chip, AD1848_MISC_INFO);
696 if (rev & 0x80) {
697 chip->hardware = AD1848_HW_CS4248;
698 } else if ((rev & 0x0f) == 0x0a) {
699 snd_ad1848_out(chip, AD1848_MISC_INFO, 0x40);
700 for (i = 0; i < 16; ++i) {
701 if (snd_ad1848_in(chip, i) != snd_ad1848_in(chip, i + 16)) {
702 chip->hardware = AD1848_HW_CMI8330;
703 break;
704 }
705 }
706 snd_ad1848_out(chip, AD1848_MISC_INFO, 0x00);
707 }
708 }
709 }
710 spin_lock_irqsave(&chip->reg_lock, flags);
711 inb(AD1848P(chip, STATUS)); /* clear any pendings IRQ */
712 outb(0, AD1848P(chip, STATUS));
713 mb();
714 spin_unlock_irqrestore(&chip->reg_lock, flags);
715
716 chip->image[AD1848_MISC_INFO] = 0x00;
717 chip->image[AD1848_IFACE_CTRL] =
718 (chip->image[AD1848_IFACE_CTRL] & ~AD1848_SINGLE_DMA) | AD1848_SINGLE_DMA;
719 ptr = (unsigned char *) &chip->image;
720 snd_ad1848_mce_down(chip);
721 spin_lock_irqsave(&chip->reg_lock, flags);
722 for (i = 0; i < 16; i++) /* ok.. fill all AD1848 registers */
723 snd_ad1848_out(chip, i, *ptr++);
724 spin_unlock_irqrestore(&chip->reg_lock, flags);
725 snd_ad1848_mce_up(chip);
726 snd_ad1848_mce_down(chip);
727 return 0; /* all things are ok.. */
728}
729
730/*
731
732 */
733
734static struct snd_pcm_hardware snd_ad1848_playback =
735{
736 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
737 SNDRV_PCM_INFO_MMAP_VALID),
738 .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW |
739 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE),
740 .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
741 .rate_min = 5510,
742 .rate_max = 48000,
743 .channels_min = 1,
744 .channels_max = 2,
745 .buffer_bytes_max = (128*1024),
746 .period_bytes_min = 64,
747 .period_bytes_max = (128*1024),
748 .periods_min = 1,
749 .periods_max = 1024,
750 .fifo_size = 0,
751};
752
753static struct snd_pcm_hardware snd_ad1848_capture =
754{
755 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
756 SNDRV_PCM_INFO_MMAP_VALID),
757 .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW |
758 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE),
759 .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
760 .rate_min = 5510,
761 .rate_max = 48000,
762 .channels_min = 1,
763 .channels_max = 2,
764 .buffer_bytes_max = (128*1024),
765 .period_bytes_min = 64,
766 .period_bytes_max = (128*1024),
767 .periods_min = 1,
768 .periods_max = 1024,
769 .fifo_size = 0,
770};
771
772/*
773
774 */
775
776static int snd_ad1848_playback_open(struct snd_pcm_substream *substream)
777{
778 struct snd_ad1848 *chip = snd_pcm_substream_chip(substream);
779 struct snd_pcm_runtime *runtime = substream->runtime;
780 int err;
781
782 if ((err = snd_ad1848_open(chip, AD1848_MODE_PLAY)) < 0)
783 return err;
784 chip->playback_substream = substream;
785 runtime->hw = snd_ad1848_playback;
786 snd_pcm_limit_isa_dma_size(chip->dma, &runtime->hw.buffer_bytes_max);
787 snd_pcm_limit_isa_dma_size(chip->dma, &runtime->hw.period_bytes_max);
788 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
789 return 0;
790}
791
792static int snd_ad1848_capture_open(struct snd_pcm_substream *substream)
793{
794 struct snd_ad1848 *chip = snd_pcm_substream_chip(substream);
795 struct snd_pcm_runtime *runtime = substream->runtime;
796 int err;
797
798 if ((err = snd_ad1848_open(chip, AD1848_MODE_CAPTURE)) < 0)
799 return err;
800 chip->capture_substream = substream;
801 runtime->hw = snd_ad1848_capture;
802 snd_pcm_limit_isa_dma_size(chip->dma, &runtime->hw.buffer_bytes_max);
803 snd_pcm_limit_isa_dma_size(chip->dma, &runtime->hw.period_bytes_max);
804 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
805 return 0;
806}
807
808static int snd_ad1848_playback_close(struct snd_pcm_substream *substream)
809{
810 struct snd_ad1848 *chip = snd_pcm_substream_chip(substream);
811
812 chip->mode &= ~AD1848_MODE_PLAY;
813 chip->playback_substream = NULL;
814 snd_ad1848_close(chip);
815 return 0;
816}
817
818static int snd_ad1848_capture_close(struct snd_pcm_substream *substream)
819{
820 struct snd_ad1848 *chip = snd_pcm_substream_chip(substream);
821
822 chip->mode &= ~AD1848_MODE_CAPTURE;
823 chip->capture_substream = NULL;
824 snd_ad1848_close(chip);
825 return 0;
826}
827
828static int snd_ad1848_free(struct snd_ad1848 *chip)
829{
830 release_and_free_resource(chip->res_port);
831 if (chip->irq >= 0)
832 free_irq(chip->irq, (void *) chip);
833 if (chip->dma >= 0) {
834 snd_dma_disable(chip->dma);
835 free_dma(chip->dma);
836 }
837 kfree(chip);
838 return 0;
839}
840
841static int snd_ad1848_dev_free(struct snd_device *device)
842{
843 struct snd_ad1848 *chip = device->device_data;
844 return snd_ad1848_free(chip);
845}
846
847static const char *snd_ad1848_chip_id(struct snd_ad1848 *chip)
848{
849 switch (chip->hardware) {
850 case AD1848_HW_AD1847: return "AD1847";
851 case AD1848_HW_AD1848: return "AD1848";
852 case AD1848_HW_CS4248: return "CS4248";
853 case AD1848_HW_CMI8330: return "CMI8330/C3D";
854 default: return "???";
855 }
856}
857
858int snd_ad1848_create(struct snd_card *card,
859 unsigned long port,
860 int irq, int dma,
861 unsigned short hardware,
862 struct snd_ad1848 ** rchip)
863{
864 static struct snd_device_ops ops = {
865 .dev_free = snd_ad1848_dev_free,
866 };
867 struct snd_ad1848 *chip;
868 int err;
869
870 *rchip = NULL;
871 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
872 if (chip == NULL)
873 return -ENOMEM;
874 spin_lock_init(&chip->reg_lock);
875 chip->card = card;
876 chip->port = port;
877 chip->irq = -1;
878 chip->dma = -1;
879 chip->hardware = hardware;
880 memcpy(&chip->image, &snd_ad1848_original_image, sizeof(snd_ad1848_original_image));
881
882 if ((chip->res_port = request_region(port, 4, "AD1848")) == NULL) {
883 snd_printk(KERN_ERR "ad1848: can't grab port 0x%lx\n", port);
884 snd_ad1848_free(chip);
885 return -EBUSY;
886 }
887 if (request_irq(irq, snd_ad1848_interrupt, IRQF_DISABLED, "AD1848", (void *) chip)) {
888 snd_printk(KERN_ERR "ad1848: can't grab IRQ %d\n", irq);
889 snd_ad1848_free(chip);
890 return -EBUSY;
891 }
892 chip->irq = irq;
893 if (request_dma(dma, "AD1848")) {
894 snd_printk(KERN_ERR "ad1848: can't grab DMA %d\n", dma);
895 snd_ad1848_free(chip);
896 return -EBUSY;
897 }
898 chip->dma = dma;
899
900 if (hardware == AD1848_HW_THINKPAD) {
901 chip->thinkpad_flag = 1;
902 chip->hardware = AD1848_HW_DETECT; /* reset */
903 snd_ad1848_thinkpad_twiddle(chip, 1);
904 }
905
906 if (snd_ad1848_probe(chip) < 0) {
907 snd_ad1848_free(chip);
908 return -ENODEV;
909 }
910
911 /* Register device */
912 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
913 snd_ad1848_free(chip);
914 return err;
915 }
916
917#ifdef CONFIG_PM
918 chip->suspend = snd_ad1848_suspend;
919 chip->resume = snd_ad1848_resume;
920#endif
921
922 *rchip = chip;
923 return 0;
924}
925
926EXPORT_SYMBOL(snd_ad1848_create);
927
928static struct snd_pcm_ops snd_ad1848_playback_ops = {
929 .open = snd_ad1848_playback_open,
930 .close = snd_ad1848_playback_close,
931 .ioctl = snd_ad1848_ioctl,
932 .hw_params = snd_ad1848_playback_hw_params,
933 .hw_free = snd_ad1848_playback_hw_free,
934 .prepare = snd_ad1848_playback_prepare,
935 .trigger = snd_ad1848_playback_trigger,
936 .pointer = snd_ad1848_playback_pointer,
937};
938
939static struct snd_pcm_ops snd_ad1848_capture_ops = {
940 .open = snd_ad1848_capture_open,
941 .close = snd_ad1848_capture_close,
942 .ioctl = snd_ad1848_ioctl,
943 .hw_params = snd_ad1848_capture_hw_params,
944 .hw_free = snd_ad1848_capture_hw_free,
945 .prepare = snd_ad1848_capture_prepare,
946 .trigger = snd_ad1848_capture_trigger,
947 .pointer = snd_ad1848_capture_pointer,
948};
949
950int snd_ad1848_pcm(struct snd_ad1848 *chip, int device, struct snd_pcm **rpcm)
951{
952 struct snd_pcm *pcm;
953 int err;
954
955 if ((err = snd_pcm_new(chip->card, "AD1848", device, 1, 1, &pcm)) < 0)
956 return err;
957
958 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ad1848_playback_ops);
959 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ad1848_capture_ops);
960
961 pcm->private_data = chip;
962 pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX;
963 strcpy(pcm->name, snd_ad1848_chip_id(chip));
964
965 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
966 snd_dma_isa_data(),
967 64*1024, chip->dma > 3 ? 128*1024 : 64*1024);
968
969 chip->pcm = pcm;
970 if (rpcm)
971 *rpcm = pcm;
972 return 0;
973}
974
975EXPORT_SYMBOL(snd_ad1848_pcm);
976
977const struct snd_pcm_ops *snd_ad1848_get_pcm_ops(int direction)
978{
979 return direction == SNDRV_PCM_STREAM_PLAYBACK ?
980 &snd_ad1848_playback_ops : &snd_ad1848_capture_ops;
981}
982
983EXPORT_SYMBOL(snd_ad1848_get_pcm_ops);
984
985/*
986 * MIXER part
987 */
988
989static int snd_ad1848_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
990{
991 static char *texts[4] = {
992 "Line", "Aux", "Mic", "Mix"
993 };
994
995 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
996 uinfo->count = 2;
997 uinfo->value.enumerated.items = 4;
998 if (uinfo->value.enumerated.item > 3)
999 uinfo->value.enumerated.item = 3;
1000 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1001 return 0;
1002}
1003
1004static int snd_ad1848_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1005{
1006 struct snd_ad1848 *chip = snd_kcontrol_chip(kcontrol);
1007 unsigned long flags;
1008
1009 spin_lock_irqsave(&chip->reg_lock, flags);
1010 ucontrol->value.enumerated.item[0] = (chip->image[AD1848_LEFT_INPUT] & AD1848_MIXS_ALL) >> 6;
1011 ucontrol->value.enumerated.item[1] = (chip->image[AD1848_RIGHT_INPUT] & AD1848_MIXS_ALL) >> 6;
1012 spin_unlock_irqrestore(&chip->reg_lock, flags);
1013 return 0;
1014}
1015
1016static int snd_ad1848_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1017{
1018 struct snd_ad1848 *chip = snd_kcontrol_chip(kcontrol);
1019 unsigned long flags;
1020 unsigned short left, right;
1021 int change;
1022
1023 if (ucontrol->value.enumerated.item[0] > 3 ||
1024 ucontrol->value.enumerated.item[1] > 3)
1025 return -EINVAL;
1026 left = ucontrol->value.enumerated.item[0] << 6;
1027 right = ucontrol->value.enumerated.item[1] << 6;
1028 spin_lock_irqsave(&chip->reg_lock, flags);
1029 left = (chip->image[AD1848_LEFT_INPUT] & ~AD1848_MIXS_ALL) | left;
1030 right = (chip->image[AD1848_RIGHT_INPUT] & ~AD1848_MIXS_ALL) | right;
1031 change = left != chip->image[AD1848_LEFT_INPUT] ||
1032 right != chip->image[AD1848_RIGHT_INPUT];
1033 snd_ad1848_out(chip, AD1848_LEFT_INPUT, left);
1034 snd_ad1848_out(chip, AD1848_RIGHT_INPUT, right);
1035 spin_unlock_irqrestore(&chip->reg_lock, flags);
1036 return change;
1037}
1038
1039static int snd_ad1848_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1040{
1041 int mask = (kcontrol->private_value >> 16) & 0xff;
1042
1043 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
1044 uinfo->count = 1;
1045 uinfo->value.integer.min = 0;
1046 uinfo->value.integer.max = mask;
1047 return 0;
1048}
1049
1050static int snd_ad1848_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1051{
1052 struct snd_ad1848 *chip = snd_kcontrol_chip(kcontrol);
1053 unsigned long flags;
1054 int reg = kcontrol->private_value & 0xff;
1055 int shift = (kcontrol->private_value >> 8) & 0xff;
1056 int mask = (kcontrol->private_value >> 16) & 0xff;
1057 int invert = (kcontrol->private_value >> 24) & 0xff;
1058
1059 spin_lock_irqsave(&chip->reg_lock, flags);
1060 ucontrol->value.integer.value[0] = (chip->image[reg] >> shift) & mask;
1061 spin_unlock_irqrestore(&chip->reg_lock, flags);
1062 if (invert)
1063 ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
1064 return 0;
1065}
1066
1067static int snd_ad1848_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1068{
1069 struct snd_ad1848 *chip = snd_kcontrol_chip(kcontrol);
1070 unsigned long flags;
1071 int reg = kcontrol->private_value & 0xff;
1072 int shift = (kcontrol->private_value >> 8) & 0xff;
1073 int mask = (kcontrol->private_value >> 16) & 0xff;
1074 int invert = (kcontrol->private_value >> 24) & 0xff;
1075 int change;
1076 unsigned short val;
1077
1078 val = (ucontrol->value.integer.value[0] & mask);
1079 if (invert)
1080 val = mask - val;
1081 val <<= shift;
1082 spin_lock_irqsave(&chip->reg_lock, flags);
1083 val = (chip->image[reg] & ~(mask << shift)) | val;
1084 change = val != chip->image[reg];
1085 snd_ad1848_out(chip, reg, val);
1086 spin_unlock_irqrestore(&chip->reg_lock, flags);
1087 return change;
1088}
1089
1090static int snd_ad1848_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1091{
1092 int mask = (kcontrol->private_value >> 24) & 0xff;
1093
1094 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
1095 uinfo->count = 2;
1096 uinfo->value.integer.min = 0;
1097 uinfo->value.integer.max = mask;
1098 return 0;
1099}
1100
1101static int snd_ad1848_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1102{
1103 struct snd_ad1848 *chip = snd_kcontrol_chip(kcontrol);
1104 unsigned long flags;
1105 int left_reg = kcontrol->private_value & 0xff;
1106 int right_reg = (kcontrol->private_value >> 8) & 0xff;
1107 int shift_left = (kcontrol->private_value >> 16) & 0x07;
1108 int shift_right = (kcontrol->private_value >> 19) & 0x07;
1109 int mask = (kcontrol->private_value >> 24) & 0xff;
1110 int invert = (kcontrol->private_value >> 22) & 1;
1111
1112 spin_lock_irqsave(&chip->reg_lock, flags);
1113 ucontrol->value.integer.value[0] = (chip->image[left_reg] >> shift_left) & mask;
1114 ucontrol->value.integer.value[1] = (chip->image[right_reg] >> shift_right) & mask;
1115 spin_unlock_irqrestore(&chip->reg_lock, flags);
1116 if (invert) {
1117 ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
1118 ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1];
1119 }
1120 return 0;
1121}
1122
1123static int snd_ad1848_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1124{
1125 struct snd_ad1848 *chip = snd_kcontrol_chip(kcontrol);
1126 unsigned long flags;
1127 int left_reg = kcontrol->private_value & 0xff;
1128 int right_reg = (kcontrol->private_value >> 8) & 0xff;
1129 int shift_left = (kcontrol->private_value >> 16) & 0x07;
1130 int shift_right = (kcontrol->private_value >> 19) & 0x07;
1131 int mask = (kcontrol->private_value >> 24) & 0xff;
1132 int invert = (kcontrol->private_value >> 22) & 1;
1133 int change;
1134 unsigned short val1, val2;
1135
1136 val1 = ucontrol->value.integer.value[0] & mask;
1137 val2 = ucontrol->value.integer.value[1] & mask;
1138 if (invert) {
1139 val1 = mask - val1;
1140 val2 = mask - val2;
1141 }
1142 val1 <<= shift_left;
1143 val2 <<= shift_right;
1144 spin_lock_irqsave(&chip->reg_lock, flags);
1145 if (left_reg != right_reg) {
1146 val1 = (chip->image[left_reg] & ~(mask << shift_left)) | val1;
1147 val2 = (chip->image[right_reg] & ~(mask << shift_right)) | val2;
1148 change = val1 != chip->image[left_reg] || val2 != chip->image[right_reg];
1149 snd_ad1848_out(chip, left_reg, val1);
1150 snd_ad1848_out(chip, right_reg, val2);
1151 } else {
1152 val1 = (chip->image[left_reg] & ~((mask << shift_left) | (mask << shift_right))) | val1 | val2;
1153 change = val1 != chip->image[left_reg];
1154 snd_ad1848_out(chip, left_reg, val1);
1155 }
1156 spin_unlock_irqrestore(&chip->reg_lock, flags);
1157 return change;
1158}
1159
1160/*
1161 */
1162int snd_ad1848_add_ctl_elem(struct snd_ad1848 *chip,
1163 const struct ad1848_mix_elem *c)
1164{
1165 static struct snd_kcontrol_new newctls[] = {
1166 [AD1848_MIX_SINGLE] = {
1167 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1168 .info = snd_ad1848_info_single,
1169 .get = snd_ad1848_get_single,
1170 .put = snd_ad1848_put_single,
1171 },
1172 [AD1848_MIX_DOUBLE] = {
1173 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1174 .info = snd_ad1848_info_double,
1175 .get = snd_ad1848_get_double,
1176 .put = snd_ad1848_put_double,
1177 },
1178 [AD1848_MIX_CAPTURE] = {
1179 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1180 .info = snd_ad1848_info_mux,
1181 .get = snd_ad1848_get_mux,
1182 .put = snd_ad1848_put_mux,
1183 },
1184 };
1185 struct snd_kcontrol *ctl;
1186 int err;
1187
1188 ctl = snd_ctl_new1(&newctls[c->type], chip);
1189 if (! ctl)
1190 return -ENOMEM;
1191 strlcpy(ctl->id.name, c->name, sizeof(ctl->id.name));
1192 ctl->id.index = c->index;
1193 ctl->private_value = c->private_value;
1194 if (c->tlv) {
1195 ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
1196 ctl->tlv.p = c->tlv;
1197 }
1198 if ((err = snd_ctl_add(chip->card, ctl)) < 0)
1199 return err;
1200 return 0;
1201}
1202
1203EXPORT_SYMBOL(snd_ad1848_add_ctl_elem);
1204
1205static const DECLARE_TLV_DB_SCALE(db_scale_6bit, -9450, 150, 0);
1206static const DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0);
1207static const DECLARE_TLV_DB_SCALE(db_scale_rec_gain, 0, 150, 0);
1208
1209static struct ad1848_mix_elem snd_ad1848_controls[] = {
1210AD1848_DOUBLE("PCM Playback Switch", 0, AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 7, 7, 1, 1),
1211AD1848_DOUBLE_TLV("PCM Playback Volume", 0, AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 0, 0, 63, 1,
1212 db_scale_6bit),
1213AD1848_DOUBLE("Aux Playback Switch", 0, AD1848_AUX1_LEFT_INPUT, AD1848_AUX1_RIGHT_INPUT, 7, 7, 1, 1),
1214AD1848_DOUBLE_TLV("Aux Playback Volume", 0, AD1848_AUX1_LEFT_INPUT, AD1848_AUX1_RIGHT_INPUT, 0, 0, 31, 1,
1215 db_scale_5bit_12db_max),
1216AD1848_DOUBLE("Aux Playback Switch", 1, AD1848_AUX2_LEFT_INPUT, AD1848_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
1217AD1848_DOUBLE_TLV("Aux Playback Volume", 1, AD1848_AUX2_LEFT_INPUT, AD1848_AUX2_RIGHT_INPUT, 0, 0, 31, 1,
1218 db_scale_5bit_12db_max),
1219AD1848_DOUBLE_TLV("Capture Volume", 0, AD1848_LEFT_INPUT, AD1848_RIGHT_INPUT, 0, 0, 15, 0,
1220 db_scale_rec_gain),
1221{
1222 .name = "Capture Source",
1223 .type = AD1848_MIX_CAPTURE,
1224},
1225AD1848_SINGLE("Loopback Capture Switch", 0, AD1848_LOOPBACK, 0, 1, 0),
1226AD1848_SINGLE_TLV("Loopback Capture Volume", 0, AD1848_LOOPBACK, 1, 63, 0,
1227 db_scale_6bit),
1228};
1229
1230int snd_ad1848_mixer(struct snd_ad1848 *chip)
1231{
1232 struct snd_card *card;
1233 struct snd_pcm *pcm;
1234 unsigned int idx;
1235 int err;
1236
1237 snd_assert(chip != NULL && chip->pcm != NULL, return -EINVAL);
1238
1239 pcm = chip->pcm;
1240 card = chip->card;
1241
1242 strcpy(card->mixername, pcm->name);
1243
1244 for (idx = 0; idx < ARRAY_SIZE(snd_ad1848_controls); idx++)
1245 if ((err = snd_ad1848_add_ctl_elem(chip, &snd_ad1848_controls[idx])) < 0)
1246 return err;
1247
1248 return 0;
1249}
1250
1251EXPORT_SYMBOL(snd_ad1848_mixer);
1252
1253/*
1254 * INIT part
1255 */
1256
1257static int __init alsa_ad1848_init(void)
1258{
1259 return 0;
1260}
1261
1262static void __exit alsa_ad1848_exit(void)
1263{
1264}
1265
1266module_init(alsa_ad1848_init)
1267module_exit(alsa_ad1848_exit)
diff --git a/sound/isa/azt2320.c b/sound/isa/azt2320.c
index 154e728f592d..3e74d1a3928e 100644
--- a/sound/isa/azt2320.c
+++ b/sound/isa/azt2320.c
@@ -38,7 +38,7 @@
38#include <linux/moduleparam.h> 38#include <linux/moduleparam.h>
39#include <sound/core.h> 39#include <sound/core.h>
40#include <sound/initval.h> 40#include <sound/initval.h>
41#include <sound/cs4231.h> 41#include <sound/wss.h>
42#include <sound/mpu401.h> 42#include <sound/mpu401.h>
43#include <sound/opl3.h> 43#include <sound/opl3.h>
44 44
@@ -76,7 +76,7 @@ struct snd_card_azt2320 {
76 int dev_no; 76 int dev_no;
77 struct pnp_dev *dev; 77 struct pnp_dev *dev;
78 struct pnp_dev *devmpu; 78 struct pnp_dev *devmpu;
79 struct snd_cs4231 *chip; 79 struct snd_wss *chip;
80}; 80};
81 81
82static struct pnp_card_device_id snd_azt2320_pnpids[] = { 82static struct pnp_card_device_id snd_azt2320_pnpids[] = {
@@ -181,7 +181,7 @@ static int __devinit snd_card_azt2320_probe(int dev,
181 int error; 181 int error;
182 struct snd_card *card; 182 struct snd_card *card;
183 struct snd_card_azt2320 *acard; 183 struct snd_card_azt2320 *acard;
184 struct snd_cs4231 *chip; 184 struct snd_wss *chip;
185 struct snd_opl3 *opl3; 185 struct snd_opl3 *opl3;
186 186
187 if ((card = snd_card_new(index[dev], id[dev], THIS_MODULE, 187 if ((card = snd_card_new(index[dev], id[dev], THIS_MODULE,
@@ -200,11 +200,11 @@ static int __devinit snd_card_azt2320_probe(int dev,
200 return error; 200 return error;
201 } 201 }
202 202
203 if ((error = snd_cs4231_create(card, wss_port[dev], -1, 203 error = snd_wss_create(card, wss_port[dev], -1,
204 irq[dev], 204 irq[dev],
205 dma1[dev], 205 dma1[dev], dma2[dev],
206 dma2[dev], 206 WSS_HW_DETECT, 0, &chip);
207 CS4231_HW_DETECT, 0, &chip)) < 0) { 207 if (error < 0) {
208 snd_card_free(card); 208 snd_card_free(card);
209 return error; 209 return error;
210 } 210 }
@@ -214,15 +214,18 @@ static int __devinit snd_card_azt2320_probe(int dev,
214 sprintf(card->longname, "%s, WSS at 0x%lx, irq %i, dma %i&%i", 214 sprintf(card->longname, "%s, WSS at 0x%lx, irq %i, dma %i&%i",
215 card->shortname, chip->port, irq[dev], dma1[dev], dma2[dev]); 215 card->shortname, chip->port, irq[dev], dma1[dev], dma2[dev]);
216 216
217 if ((error = snd_cs4231_pcm(chip, 0, NULL)) < 0) { 217 error = snd_wss_pcm(chip, 0, NULL);
218 if (error < 0) {
218 snd_card_free(card); 219 snd_card_free(card);
219 return error; 220 return error;
220 } 221 }
221 if ((error = snd_cs4231_mixer(chip)) < 0) { 222 error = snd_wss_mixer(chip);
223 if (error < 0) {
222 snd_card_free(card); 224 snd_card_free(card);
223 return error; 225 return error;
224 } 226 }
225 if ((error = snd_cs4231_timer(chip, 0, NULL)) < 0) { 227 error = snd_wss_timer(chip, 0, NULL);
228 if (error < 0) {
226 snd_card_free(card); 229 snd_card_free(card);
227 return error; 230 return error;
228 } 231 }
@@ -293,7 +296,7 @@ static int snd_azt2320_pnp_suspend(struct pnp_card_link *pcard, pm_message_t sta
293{ 296{
294 struct snd_card *card = pnp_get_card_drvdata(pcard); 297 struct snd_card *card = pnp_get_card_drvdata(pcard);
295 struct snd_card_azt2320 *acard = card->private_data; 298 struct snd_card_azt2320 *acard = card->private_data;
296 struct snd_cs4231 *chip = acard->chip; 299 struct snd_wss *chip = acard->chip;
297 300
298 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 301 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
299 chip->suspend(chip); 302 chip->suspend(chip);
@@ -304,7 +307,7 @@ static int snd_azt2320_pnp_resume(struct pnp_card_link *pcard)
304{ 307{
305 struct snd_card *card = pnp_get_card_drvdata(pcard); 308 struct snd_card *card = pnp_get_card_drvdata(pcard);
306 struct snd_card_azt2320 *acard = card->private_data; 309 struct snd_card_azt2320 *acard = card->private_data;
307 struct snd_cs4231 *chip = acard->chip; 310 struct snd_wss *chip = acard->chip;
308 311
309 chip->resume(chip); 312 chip->resume(chip);
310 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 313 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c
index 4d198ec71e9b..e49aec700a55 100644
--- a/sound/isa/cmi8330.c
+++ b/sound/isa/cmi8330.c
@@ -50,7 +50,7 @@
50#include <linux/pnp.h> 50#include <linux/pnp.h>
51#include <linux/moduleparam.h> 51#include <linux/moduleparam.h>
52#include <sound/core.h> 52#include <sound/core.h>
53#include <sound/ad1848.h> 53#include <sound/wss.h>
54#include <sound/sb.h> 54#include <sound/sb.h>
55#include <sound/initval.h> 55#include <sound/initval.h>
56 56
@@ -151,7 +151,7 @@ struct snd_cmi8330 {
151 struct pnp_dev *play; 151 struct pnp_dev *play;
152#endif 152#endif
153 struct snd_card *card; 153 struct snd_card *card;
154 struct snd_ad1848 *wss; 154 struct snd_wss *wss;
155 struct snd_sb *sb; 155 struct snd_sb *sb;
156 156
157 struct snd_pcm *pcm; 157 struct snd_pcm *pcm;
@@ -174,32 +174,57 @@ MODULE_DEVICE_TABLE(pnp_card, snd_cmi8330_pnpids);
174#endif 174#endif
175 175
176 176
177static struct ad1848_mix_elem snd_cmi8330_controls[] __devinitdata = { 177static struct snd_kcontrol_new snd_cmi8330_controls[] __devinitdata = {
178AD1848_DOUBLE("Master Playback Volume", 0, CMI8330_MASTVOL, CMI8330_MASTVOL, 4, 0, 15, 0), 178WSS_DOUBLE("Master Playback Volume", 0,
179AD1848_SINGLE("Loud Playback Switch", 0, CMI8330_MUTEMUX, 6, 1, 1), 179 CMI8330_MASTVOL, CMI8330_MASTVOL, 4, 0, 15, 0),
180AD1848_DOUBLE("PCM Playback Switch", 0, AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 7, 7, 1, 1), 180WSS_SINGLE("Loud Playback Switch", 0,
181AD1848_DOUBLE("PCM Playback Volume", 0, AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 0, 0, 63, 1), 181 CMI8330_MUTEMUX, 6, 1, 1),
182AD1848_DOUBLE("Line Playback Switch", 0, CMI8330_MUTEMUX, CMI8330_MUTEMUX, 4, 3, 1, 0), 182WSS_DOUBLE("PCM Playback Switch", 0,
183AD1848_DOUBLE("Line Playback Volume", 0, CMI8330_LINVOL, CMI8330_LINVOL, 4, 0, 15, 0), 183 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1),
184AD1848_DOUBLE("Line Capture Switch", 0, CMI8330_RMUX3D, CMI8330_RMUX3D, 2, 1, 1, 0), 184WSS_DOUBLE("PCM Playback Volume", 0,
185AD1848_DOUBLE("Line Capture Volume", 0, CMI8330_LINGAIN, CMI8330_LINGAIN, 4, 0, 15, 0), 185 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1),
186AD1848_DOUBLE("CD Playback Switch", 0, CMI8330_MUTEMUX, CMI8330_MUTEMUX, 2, 1, 1, 0), 186WSS_DOUBLE("Line Playback Switch", 0,
187AD1848_DOUBLE("CD Capture Switch", 0, CMI8330_RMUX3D, CMI8330_RMUX3D, 4, 3, 1, 0), 187 CMI8330_MUTEMUX, CMI8330_MUTEMUX, 4, 3, 1, 0),
188AD1848_DOUBLE("CD Playback Volume", 0, CMI8330_CDINVOL, CMI8330_CDINVOL, 4, 0, 15, 0), 188WSS_DOUBLE("Line Playback Volume", 0,
189AD1848_DOUBLE("CD Capture Volume", 0, CMI8330_CDINGAIN, CMI8330_CDINGAIN, 4, 0, 15, 0), 189 CMI8330_LINVOL, CMI8330_LINVOL, 4, 0, 15, 0),
190AD1848_SINGLE("Mic Playback Switch", 0, CMI8330_MUTEMUX, 0, 1, 0), 190WSS_DOUBLE("Line Capture Switch", 0,
191AD1848_SINGLE("Mic Playback Volume", 0, CMI8330_OUTPUTVOL, 0, 7, 0), 191 CMI8330_RMUX3D, CMI8330_RMUX3D, 2, 1, 1, 0),
192AD1848_SINGLE("Mic Capture Switch", 0, CMI8330_RMUX3D, 0, 1, 0), 192WSS_DOUBLE("Line Capture Volume", 0,
193AD1848_SINGLE("Mic Capture Volume", 0, CMI8330_OUTPUTVOL, 5, 7, 0), 193 CMI8330_LINGAIN, CMI8330_LINGAIN, 4, 0, 15, 0),
194AD1848_DOUBLE("Wavetable Playback Switch", 0, CMI8330_RECMUX, CMI8330_RECMUX, 1, 0, 1, 0), 194WSS_DOUBLE("CD Playback Switch", 0,
195AD1848_DOUBLE("Wavetable Playback Volume", 0, CMI8330_WAVVOL, CMI8330_WAVVOL, 4, 0, 15, 0), 195 CMI8330_MUTEMUX, CMI8330_MUTEMUX, 2, 1, 1, 0),
196AD1848_DOUBLE("Wavetable Capture Switch", 0, CMI8330_RECMUX, CMI8330_RECMUX, 5, 4, 1, 0), 196WSS_DOUBLE("CD Capture Switch", 0,
197AD1848_DOUBLE("Wavetable Capture Volume", 0, CMI8330_WAVGAIN, CMI8330_WAVGAIN, 4, 0, 15, 0), 197 CMI8330_RMUX3D, CMI8330_RMUX3D, 4, 3, 1, 0),
198AD1848_SINGLE("3D Control - Switch", 0, CMI8330_RMUX3D, 5, 1, 1), 198WSS_DOUBLE("CD Playback Volume", 0,
199AD1848_SINGLE("PC Speaker Playback Volume", 0, CMI8330_OUTPUTVOL, 3, 3, 0), 199 CMI8330_CDINVOL, CMI8330_CDINVOL, 4, 0, 15, 0),
200AD1848_SINGLE("FM Playback Switch", 0, CMI8330_RECMUX, 3, 1, 1), 200WSS_DOUBLE("CD Capture Volume", 0,
201AD1848_SINGLE(SNDRV_CTL_NAME_IEC958("Input ",CAPTURE,SWITCH), 0, CMI8330_RMUX3D, 7, 1, 1), 201 CMI8330_CDINGAIN, CMI8330_CDINGAIN, 4, 0, 15, 0),
202AD1848_SINGLE(SNDRV_CTL_NAME_IEC958("Input ",PLAYBACK,SWITCH), 0, CMI8330_MUTEMUX, 7, 1, 1), 202WSS_SINGLE("Mic Playback Switch", 0,
203 CMI8330_MUTEMUX, 0, 1, 0),
204WSS_SINGLE("Mic Playback Volume", 0,
205 CMI8330_OUTPUTVOL, 0, 7, 0),
206WSS_SINGLE("Mic Capture Switch", 0,
207 CMI8330_RMUX3D, 0, 1, 0),
208WSS_SINGLE("Mic Capture Volume", 0,
209 CMI8330_OUTPUTVOL, 5, 7, 0),
210WSS_DOUBLE("Wavetable Playback Switch", 0,
211 CMI8330_RECMUX, CMI8330_RECMUX, 1, 0, 1, 0),
212WSS_DOUBLE("Wavetable Playback Volume", 0,
213 CMI8330_WAVVOL, CMI8330_WAVVOL, 4, 0, 15, 0),
214WSS_DOUBLE("Wavetable Capture Switch", 0,
215 CMI8330_RECMUX, CMI8330_RECMUX, 5, 4, 1, 0),
216WSS_DOUBLE("Wavetable Capture Volume", 0,
217 CMI8330_WAVGAIN, CMI8330_WAVGAIN, 4, 0, 15, 0),
218WSS_SINGLE("3D Control - Switch", 0,
219 CMI8330_RMUX3D, 5, 1, 1),
220WSS_SINGLE("PC Speaker Playback Volume", 0,
221 CMI8330_OUTPUTVOL, 3, 3, 0),
222WSS_SINGLE("FM Playback Switch", 0,
223 CMI8330_RECMUX, 3, 1, 1),
224WSS_SINGLE(SNDRV_CTL_NAME_IEC958("Input ", CAPTURE, SWITCH), 0,
225 CMI8330_RMUX3D, 7, 1, 1),
226WSS_SINGLE(SNDRV_CTL_NAME_IEC958("Input ", PLAYBACK, SWITCH), 0,
227 CMI8330_MUTEMUX, 7, 1, 1),
203}; 228};
204 229
205#ifdef ENABLE_SB_MIXER 230#ifdef ENABLE_SB_MIXER
@@ -268,7 +293,10 @@ static int __devinit snd_cmi8330_mixer(struct snd_card *card, struct snd_cmi8330
268 strcpy(card->mixername, "CMI8330/C3D"); 293 strcpy(card->mixername, "CMI8330/C3D");
269 294
270 for (idx = 0; idx < ARRAY_SIZE(snd_cmi8330_controls); idx++) { 295 for (idx = 0; idx < ARRAY_SIZE(snd_cmi8330_controls); idx++) {
271 if ((err = snd_ad1848_add_ctl_elem(acard->wss, &snd_cmi8330_controls[idx])) < 0) 296 err = snd_ctl_add(card,
297 snd_ctl_new1(&snd_cmi8330_controls[idx],
298 acard->wss));
299 if (err < 0)
272 return err; 300 return err;
273 } 301 }
274 302
@@ -385,7 +413,7 @@ static int __devinit snd_cmi8330_pcm(struct snd_card *card, struct snd_cmi8330 *
385 chip->streams[CMI_SB_STREAM].private_data = chip->sb; 413 chip->streams[CMI_SB_STREAM].private_data = chip->sb;
386 414
387 /* AD1848 */ 415 /* AD1848 */
388 ops = snd_ad1848_get_pcm_ops(CMI_AD_STREAM); 416 ops = snd_wss_get_pcm_ops(CMI_AD_STREAM);
389 chip->streams[CMI_AD_STREAM].ops = *ops; 417 chip->streams[CMI_AD_STREAM].ops = *ops;
390 chip->streams[CMI_AD_STREAM].open = ops->open; 418 chip->streams[CMI_AD_STREAM].open = ops->open;
391 chip->streams[CMI_AD_STREAM].ops.open = cmi_open_callbacks[CMI_AD_STREAM]; 419 chip->streams[CMI_AD_STREAM].ops.open = cmi_open_callbacks[CMI_AD_STREAM];
@@ -461,16 +489,15 @@ static int __devinit snd_cmi8330_probe(struct snd_card *card, int dev)
461 int i, err; 489 int i, err;
462 490
463 acard = card->private_data; 491 acard = card->private_data;
464 if ((err = snd_ad1848_create(card, 492 err = snd_wss_create(card, wssport[dev] + 4, -1,
465 wssport[dev] + 4, 493 wssirq[dev],
466 wssirq[dev], 494 wssdma[dev], -1,
467 wssdma[dev], 495 WSS_HW_DETECT, 0, &acard->wss);
468 AD1848_HW_DETECT, 496 if (err < 0) {
469 &acard->wss)) < 0) {
470 snd_printk(KERN_ERR PFX "(AD1848) device busy??\n"); 497 snd_printk(KERN_ERR PFX "(AD1848) device busy??\n");
471 return err; 498 return err;
472 } 499 }
473 if (acard->wss->hardware != AD1848_HW_CMI8330) { 500 if (acard->wss->hardware != WSS_HW_CMI8330) {
474 snd_printk(KERN_ERR PFX "(AD1848) not found during probe\n"); 501 snd_printk(KERN_ERR PFX "(AD1848) not found during probe\n");
475 return -ENODEV; 502 return -ENODEV;
476 } 503 }
@@ -489,9 +516,10 @@ static int __devinit snd_cmi8330_probe(struct snd_card *card, int dev)
489 return err; 516 return err;
490 } 517 }
491 518
492 snd_ad1848_out(acard->wss, AD1848_MISC_INFO, 0x40); /* switch on MODE2 */ 519 snd_wss_out(acard->wss, CS4231_MISC_INFO, 0x40); /* switch on MODE2 */
493 for (i = CMI8330_RMUX3D; i <= CMI8330_CDINGAIN; i++) 520 for (i = CMI8330_RMUX3D; i <= CMI8330_CDINGAIN; i++)
494 snd_ad1848_out(acard->wss, i, snd_cmi8330_image[i - CMI8330_RMUX3D]); 521 snd_wss_out(acard->wss, i,
522 snd_cmi8330_image[i - CMI8330_RMUX3D]);
495 523
496 if ((err = snd_cmi8330_mixer(card, acard)) < 0) { 524 if ((err = snd_cmi8330_mixer(card, acard)) < 0) {
497 snd_printk(KERN_ERR PFX "failed to create mixers\n"); 525 snd_printk(KERN_ERR PFX "failed to create mixers\n");
diff --git a/sound/isa/cs423x/Makefile b/sound/isa/cs423x/Makefile
index 5067ee001933..5870ca21ab59 100644
--- a/sound/isa/cs423x/Makefile
+++ b/sound/isa/cs423x/Makefile
@@ -3,14 +3,12 @@
3# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz> 3# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
4# 4#
5 5
6snd-cs4231-lib-objs := cs4231_lib.o
7snd-cs4236-lib-objs := cs4236_lib.o 6snd-cs4236-lib-objs := cs4236_lib.o
8snd-cs4231-objs := cs4231.o 7snd-cs4231-objs := cs4231.o
9snd-cs4232-objs := cs4232.o 8snd-cs4232-objs := cs4232.o
10snd-cs4236-objs := cs4236.o 9snd-cs4236-objs := cs4236.o
11 10
12# Toplevel Module Dependency 11# Toplevel Module Dependency
13obj-$(CONFIG_SND_CS4231_LIB) += snd-cs4231-lib.o
14obj-$(CONFIG_SND_CS4231) += snd-cs4231.o 12obj-$(CONFIG_SND_CS4231) += snd-cs4231.o
15obj-$(CONFIG_SND_CS4232) += snd-cs4232.o 13obj-$(CONFIG_SND_CS4232) += snd-cs4232.o
16obj-$(CONFIG_SND_CS4236) += snd-cs4236.o snd-cs4236-lib.o 14obj-$(CONFIG_SND_CS4236) += snd-cs4236.o snd-cs4236-lib.o
diff --git a/sound/isa/cs423x/cs4231.c b/sound/isa/cs423x/cs4231.c
index e9462b9944be..ddd289120aa8 100644
--- a/sound/isa/cs423x/cs4231.c
+++ b/sound/isa/cs423x/cs4231.c
@@ -27,7 +27,7 @@
27#include <linux/wait.h> 27#include <linux/wait.h>
28#include <linux/moduleparam.h> 28#include <linux/moduleparam.h>
29#include <sound/core.h> 29#include <sound/core.h>
30#include <sound/cs4231.h> 30#include <sound/wss.h>
31#include <sound/mpu401.h> 31#include <sound/mpu401.h>
32#include <sound/initval.h> 32#include <sound/initval.h>
33 33
@@ -91,7 +91,7 @@ static int __devinit snd_cs4231_match(struct device *dev, unsigned int n)
91static int __devinit snd_cs4231_probe(struct device *dev, unsigned int n) 91static int __devinit snd_cs4231_probe(struct device *dev, unsigned int n)
92{ 92{
93 struct snd_card *card; 93 struct snd_card *card;
94 struct snd_cs4231 *chip; 94 struct snd_wss *chip;
95 struct snd_pcm *pcm; 95 struct snd_pcm *pcm;
96 int error; 96 int error;
97 97
@@ -99,14 +99,14 @@ static int __devinit snd_cs4231_probe(struct device *dev, unsigned int n)
99 if (!card) 99 if (!card)
100 return -EINVAL; 100 return -EINVAL;
101 101
102 error = snd_cs4231_create(card, port[n], -1, irq[n], dma1[n], dma2[n], 102 error = snd_wss_create(card, port[n], -1, irq[n], dma1[n], dma2[n],
103 CS4231_HW_DETECT, 0, &chip); 103 WSS_HW_DETECT, 0, &chip);
104 if (error < 0) 104 if (error < 0)
105 goto out; 105 goto out;
106 106
107 card->private_data = chip; 107 card->private_data = chip;
108 108
109 error = snd_cs4231_pcm(chip, 0, &pcm); 109 error = snd_wss_pcm(chip, 0, &pcm);
110 if (error < 0) 110 if (error < 0)
111 goto out; 111 goto out;
112 112
@@ -118,11 +118,11 @@ static int __devinit snd_cs4231_probe(struct device *dev, unsigned int n)
118 if (dma2[n] >= 0) 118 if (dma2[n] >= 0)
119 sprintf(card->longname + strlen(card->longname), "&%d", dma2[n]); 119 sprintf(card->longname + strlen(card->longname), "&%d", dma2[n]);
120 120
121 error = snd_cs4231_mixer(chip); 121 error = snd_wss_mixer(chip);
122 if (error < 0) 122 if (error < 0)
123 goto out; 123 goto out;
124 124
125 error = snd_cs4231_timer(chip, 0, NULL); 125 error = snd_wss_timer(chip, 0, NULL);
126 if (error < 0) 126 if (error < 0)
127 goto out; 127 goto out;
128 128
@@ -160,7 +160,7 @@ static int __devexit snd_cs4231_remove(struct device *dev, unsigned int n)
160static int snd_cs4231_suspend(struct device *dev, unsigned int n, pm_message_t state) 160static int snd_cs4231_suspend(struct device *dev, unsigned int n, pm_message_t state)
161{ 161{
162 struct snd_card *card = dev_get_drvdata(dev); 162 struct snd_card *card = dev_get_drvdata(dev);
163 struct snd_cs4231 *chip = card->private_data; 163 struct snd_wss *chip = card->private_data;
164 164
165 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 165 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
166 chip->suspend(chip); 166 chip->suspend(chip);
@@ -170,7 +170,7 @@ static int snd_cs4231_suspend(struct device *dev, unsigned int n, pm_message_t s
170static int snd_cs4231_resume(struct device *dev, unsigned int n) 170static int snd_cs4231_resume(struct device *dev, unsigned int n)
171{ 171{
172 struct snd_card *card = dev_get_drvdata(dev); 172 struct snd_card *card = dev_get_drvdata(dev);
173 struct snd_cs4231 *chip = card->private_data; 173 struct snd_wss *chip = card->private_data;
174 174
175 chip->resume(chip); 175 chip->resume(chip);
176 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 176 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
diff --git a/sound/isa/cs423x/cs4231_lib.c b/sound/isa/cs423x/cs4231_lib.c
deleted file mode 100644
index 521db705d179..000000000000
--- a/sound/isa/cs423x/cs4231_lib.c
+++ /dev/null
@@ -1,1945 +0,0 @@
1/*
2 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
3 * Routines for control of CS4231(A)/CS4232/InterWave & compatible chips
4 *
5 * Bugs:
6 * - sometimes record brokes playback with WSS portion of
7 * Yamaha OPL3-SA3 chip
8 * - CS4231 (GUS MAX) - still trouble with occasional noises
9 * - broken initialization?
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 */
26
27#include <linux/delay.h>
28#include <linux/pm.h>
29#include <linux/init.h>
30#include <linux/interrupt.h>
31#include <linux/slab.h>
32#include <linux/ioport.h>
33#include <sound/core.h>
34#include <sound/cs4231.h>
35#include <sound/pcm_params.h>
36
37#include <asm/io.h>
38#include <asm/dma.h>
39#include <asm/irq.h>
40
41MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
42MODULE_DESCRIPTION("Routines for control of CS4231(A)/CS4232/InterWave & compatible chips");
43MODULE_LICENSE("GPL");
44
45#if 0
46#define SNDRV_DEBUG_MCE
47#endif
48
49/*
50 * Some variables
51 */
52
53static unsigned char freq_bits[14] = {
54 /* 5510 */ 0x00 | CS4231_XTAL2,
55 /* 6620 */ 0x0E | CS4231_XTAL2,
56 /* 8000 */ 0x00 | CS4231_XTAL1,
57 /* 9600 */ 0x0E | CS4231_XTAL1,
58 /* 11025 */ 0x02 | CS4231_XTAL2,
59 /* 16000 */ 0x02 | CS4231_XTAL1,
60 /* 18900 */ 0x04 | CS4231_XTAL2,
61 /* 22050 */ 0x06 | CS4231_XTAL2,
62 /* 27042 */ 0x04 | CS4231_XTAL1,
63 /* 32000 */ 0x06 | CS4231_XTAL1,
64 /* 33075 */ 0x0C | CS4231_XTAL2,
65 /* 37800 */ 0x08 | CS4231_XTAL2,
66 /* 44100 */ 0x0A | CS4231_XTAL2,
67 /* 48000 */ 0x0C | CS4231_XTAL1
68};
69
70static unsigned int rates[14] = {
71 5510, 6620, 8000, 9600, 11025, 16000, 18900, 22050,
72 27042, 32000, 33075, 37800, 44100, 48000
73};
74
75static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
76 .count = ARRAY_SIZE(rates),
77 .list = rates,
78 .mask = 0,
79};
80
81static int snd_cs4231_xrate(struct snd_pcm_runtime *runtime)
82{
83 return snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
84}
85
86static unsigned char snd_cs4231_original_image[32] =
87{
88 0x00, /* 00/00 - lic */
89 0x00, /* 01/01 - ric */
90 0x9f, /* 02/02 - la1ic */
91 0x9f, /* 03/03 - ra1ic */
92 0x9f, /* 04/04 - la2ic */
93 0x9f, /* 05/05 - ra2ic */
94 0xbf, /* 06/06 - loc */
95 0xbf, /* 07/07 - roc */
96 0x20, /* 08/08 - pdfr */
97 CS4231_AUTOCALIB, /* 09/09 - ic */
98 0x00, /* 0a/10 - pc */
99 0x00, /* 0b/11 - ti */
100 CS4231_MODE2, /* 0c/12 - mi */
101 0xfc, /* 0d/13 - lbc */
102 0x00, /* 0e/14 - pbru */
103 0x00, /* 0f/15 - pbrl */
104 0x80, /* 10/16 - afei */
105 0x01, /* 11/17 - afeii */
106 0x9f, /* 12/18 - llic */
107 0x9f, /* 13/19 - rlic */
108 0x00, /* 14/20 - tlb */
109 0x00, /* 15/21 - thb */
110 0x00, /* 16/22 - la3mic/reserved */
111 0x00, /* 17/23 - ra3mic/reserved */
112 0x00, /* 18/24 - afs */
113 0x00, /* 19/25 - lamoc/version */
114 0xcf, /* 1a/26 - mioc */
115 0x00, /* 1b/27 - ramoc/reserved */
116 0x20, /* 1c/28 - cdfr */
117 0x00, /* 1d/29 - res4 */
118 0x00, /* 1e/30 - cbru */
119 0x00, /* 1f/31 - cbrl */
120};
121
122static unsigned char snd_opti93x_original_image[32] =
123{
124 0x00, /* 00/00 - l_mixout_outctrl */
125 0x00, /* 01/01 - r_mixout_outctrl */
126 0x88, /* 02/02 - l_cd_inctrl */
127 0x88, /* 03/03 - r_cd_inctrl */
128 0x88, /* 04/04 - l_a1/fm_inctrl */
129 0x88, /* 05/05 - r_a1/fm_inctrl */
130 0x80, /* 06/06 - l_dac_inctrl */
131 0x80, /* 07/07 - r_dac_inctrl */
132 0x00, /* 08/08 - ply_dataform_reg */
133 0x00, /* 09/09 - if_conf */
134 0x00, /* 0a/10 - pin_ctrl */
135 0x00, /* 0b/11 - err_init_reg */
136 0x0a, /* 0c/12 - id_reg */
137 0x00, /* 0d/13 - reserved */
138 0x00, /* 0e/14 - ply_upcount_reg */
139 0x00, /* 0f/15 - ply_lowcount_reg */
140 0x88, /* 10/16 - reserved/l_a1_inctrl */
141 0x88, /* 11/17 - reserved/r_a1_inctrl */
142 0x88, /* 12/18 - l_line_inctrl */
143 0x88, /* 13/19 - r_line_inctrl */
144 0x88, /* 14/20 - l_mic_inctrl */
145 0x88, /* 15/21 - r_mic_inctrl */
146 0x80, /* 16/22 - l_out_outctrl */
147 0x80, /* 17/23 - r_out_outctrl */
148 0x00, /* 18/24 - reserved */
149 0x00, /* 19/25 - reserved */
150 0x00, /* 1a/26 - reserved */
151 0x00, /* 1b/27 - reserved */
152 0x00, /* 1c/28 - cap_dataform_reg */
153 0x00, /* 1d/29 - reserved */
154 0x00, /* 1e/30 - cap_upcount_reg */
155 0x00 /* 1f/31 - cap_lowcount_reg */
156};
157
158/*
159 * Basic I/O functions
160 */
161
162static inline void cs4231_outb(struct snd_cs4231 *chip, u8 offset, u8 val)
163{
164 outb(val, chip->port + offset);
165}
166
167static inline u8 cs4231_inb(struct snd_cs4231 *chip, u8 offset)
168{
169 return inb(chip->port + offset);
170}
171
172static void snd_cs4231_wait(struct snd_cs4231 *chip)
173{
174 int timeout;
175
176 for (timeout = 250;
177 timeout > 0 && (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT);
178 timeout--)
179 udelay(100);
180}
181
182static void snd_cs4231_outm(struct snd_cs4231 *chip, unsigned char reg,
183 unsigned char mask, unsigned char value)
184{
185 unsigned char tmp = (chip->image[reg] & mask) | value;
186
187 snd_cs4231_wait(chip);
188#ifdef CONFIG_SND_DEBUG
189 if (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
190 snd_printk("outm: auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value);
191#endif
192 chip->image[reg] = tmp;
193 if (!chip->calibrate_mute) {
194 cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg);
195 wmb();
196 cs4231_outb(chip, CS4231P(REG), tmp);
197 mb();
198 }
199}
200
201static void snd_cs4231_dout(struct snd_cs4231 *chip, unsigned char reg, unsigned char value)
202{
203 int timeout;
204
205 for (timeout = 250;
206 timeout > 0 && (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT);
207 timeout--)
208 udelay(10);
209 cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg);
210 cs4231_outb(chip, CS4231P(REG), value);
211 mb();
212}
213
214void snd_cs4231_out(struct snd_cs4231 *chip, unsigned char reg, unsigned char value)
215{
216 snd_cs4231_wait(chip);
217#ifdef CONFIG_SND_DEBUG
218 if (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
219 snd_printk("out: auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value);
220#endif
221 cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg);
222 cs4231_outb(chip, CS4231P(REG), value);
223 chip->image[reg] = value;
224 mb();
225 snd_printdd("codec out - reg 0x%x = 0x%x\n",
226 chip->mce_bit | reg, value);
227}
228
229unsigned char snd_cs4231_in(struct snd_cs4231 *chip, unsigned char reg)
230{
231 snd_cs4231_wait(chip);
232#ifdef CONFIG_SND_DEBUG
233 if (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
234 snd_printk("in: auto calibration time out - reg = 0x%x\n", reg);
235#endif
236 cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg);
237 mb();
238 return cs4231_inb(chip, CS4231P(REG));
239}
240
241void snd_cs4236_ext_out(struct snd_cs4231 *chip, unsigned char reg, unsigned char val)
242{
243 cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | 0x17);
244 cs4231_outb(chip, CS4231P(REG), reg | (chip->image[CS4236_EXT_REG] & 0x01));
245 cs4231_outb(chip, CS4231P(REG), val);
246 chip->eimage[CS4236_REG(reg)] = val;
247#if 0
248 printk("ext out : reg = 0x%x, val = 0x%x\n", reg, val);
249#endif
250}
251
252unsigned char snd_cs4236_ext_in(struct snd_cs4231 *chip, unsigned char reg)
253{
254 cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | 0x17);
255 cs4231_outb(chip, CS4231P(REG), reg | (chip->image[CS4236_EXT_REG] & 0x01));
256#if 1
257 return cs4231_inb(chip, CS4231P(REG));
258#else
259 {
260 unsigned char res;
261 res = cs4231_inb(chip, CS4231P(REG));
262 printk("ext in : reg = 0x%x, val = 0x%x\n", reg, res);
263 return res;
264 }
265#endif
266}
267
268#if 0
269
270static void snd_cs4231_debug(struct snd_cs4231 *chip)
271{
272 printk("CS4231 REGS: INDEX = 0x%02x ", cs4231_inb(chip, CS4231P(REGSEL)));
273 printk(" STATUS = 0x%02x\n", cs4231_inb(chip, CS4231P(STATUS)));
274 printk(" 0x00: left input = 0x%02x ", snd_cs4231_in(chip, 0x00));
275 printk(" 0x10: alt 1 (CFIG 2) = 0x%02x\n", snd_cs4231_in(chip, 0x10));
276 printk(" 0x01: right input = 0x%02x ", snd_cs4231_in(chip, 0x01));
277 printk(" 0x11: alt 2 (CFIG 3) = 0x%02x\n", snd_cs4231_in(chip, 0x11));
278 printk(" 0x02: GF1 left input = 0x%02x ", snd_cs4231_in(chip, 0x02));
279 printk(" 0x12: left line in = 0x%02x\n", snd_cs4231_in(chip, 0x12));
280 printk(" 0x03: GF1 right input = 0x%02x ", snd_cs4231_in(chip, 0x03));
281 printk(" 0x13: right line in = 0x%02x\n", snd_cs4231_in(chip, 0x13));
282 printk(" 0x04: CD left input = 0x%02x ", snd_cs4231_in(chip, 0x04));
283 printk(" 0x14: timer low = 0x%02x\n", snd_cs4231_in(chip, 0x14));
284 printk(" 0x05: CD right input = 0x%02x ", snd_cs4231_in(chip, 0x05));
285 printk(" 0x15: timer high = 0x%02x\n", snd_cs4231_in(chip, 0x15));
286 printk(" 0x06: left output = 0x%02x ", snd_cs4231_in(chip, 0x06));
287 printk(" 0x16: left MIC (PnP) = 0x%02x\n", snd_cs4231_in(chip, 0x16));
288 printk(" 0x07: right output = 0x%02x ", snd_cs4231_in(chip, 0x07));
289 printk(" 0x17: right MIC (PnP) = 0x%02x\n", snd_cs4231_in(chip, 0x17));
290 printk(" 0x08: playback format = 0x%02x ", snd_cs4231_in(chip, 0x08));
291 printk(" 0x18: IRQ status = 0x%02x\n", snd_cs4231_in(chip, 0x18));
292 printk(" 0x09: iface (CFIG 1) = 0x%02x ", snd_cs4231_in(chip, 0x09));
293 printk(" 0x19: left line out = 0x%02x\n", snd_cs4231_in(chip, 0x19));
294 printk(" 0x0a: pin control = 0x%02x ", snd_cs4231_in(chip, 0x0a));
295 printk(" 0x1a: mono control = 0x%02x\n", snd_cs4231_in(chip, 0x1a));
296 printk(" 0x0b: init & status = 0x%02x ", snd_cs4231_in(chip, 0x0b));
297 printk(" 0x1b: right line out = 0x%02x\n", snd_cs4231_in(chip, 0x1b));
298 printk(" 0x0c: revision & mode = 0x%02x ", snd_cs4231_in(chip, 0x0c));
299 printk(" 0x1c: record format = 0x%02x\n", snd_cs4231_in(chip, 0x1c));
300 printk(" 0x0d: loopback = 0x%02x ", snd_cs4231_in(chip, 0x0d));
301 printk(" 0x1d: var freq (PnP) = 0x%02x\n", snd_cs4231_in(chip, 0x1d));
302 printk(" 0x0e: ply upr count = 0x%02x ", snd_cs4231_in(chip, 0x0e));
303 printk(" 0x1e: ply lwr count = 0x%02x\n", snd_cs4231_in(chip, 0x1e));
304 printk(" 0x0f: rec upr count = 0x%02x ", snd_cs4231_in(chip, 0x0f));
305 printk(" 0x1f: rec lwr count = 0x%02x\n", snd_cs4231_in(chip, 0x1f));
306}
307
308#endif
309
310/*
311 * CS4231 detection / MCE routines
312 */
313
314static void snd_cs4231_busy_wait(struct snd_cs4231 *chip)
315{
316 int timeout;
317
318 /* huh.. looks like this sequence is proper for CS4231A chip (GUS MAX) */
319 for (timeout = 5; timeout > 0; timeout--)
320 cs4231_inb(chip, CS4231P(REGSEL));
321 /* end of cleanup sequence */
322 for (timeout = 250;
323 timeout > 0 && (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT);
324 timeout--)
325 udelay(10);
326}
327
328void snd_cs4231_mce_up(struct snd_cs4231 *chip)
329{
330 unsigned long flags;
331 int timeout;
332
333 snd_cs4231_wait(chip);
334#ifdef CONFIG_SND_DEBUG
335 if (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
336 snd_printk("mce_up - auto calibration time out (0)\n");
337#endif
338 spin_lock_irqsave(&chip->reg_lock, flags);
339 chip->mce_bit |= CS4231_MCE;
340 timeout = cs4231_inb(chip, CS4231P(REGSEL));
341 if (timeout == 0x80)
342 snd_printk("mce_up [0x%lx]: serious init problem - codec still busy\n", chip->port);
343 if (!(timeout & CS4231_MCE))
344 cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | (timeout & 0x1f));
345 spin_unlock_irqrestore(&chip->reg_lock, flags);
346}
347
348void snd_cs4231_mce_down(struct snd_cs4231 *chip)
349{
350 unsigned long flags;
351 unsigned long end_time;
352 int timeout;
353
354 snd_cs4231_busy_wait(chip);
355
356#ifdef CONFIG_SND_DEBUG
357 if (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
358 snd_printk("mce_down [0x%lx] - auto calibration time out (0)\n", (long)CS4231P(REGSEL));
359#endif
360 spin_lock_irqsave(&chip->reg_lock, flags);
361 chip->mce_bit &= ~CS4231_MCE;
362 timeout = cs4231_inb(chip, CS4231P(REGSEL));
363 cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | (timeout & 0x1f));
364 spin_unlock_irqrestore(&chip->reg_lock, flags);
365 if (timeout == 0x80)
366 snd_printk("mce_down [0x%lx]: serious init problem - codec still busy\n", chip->port);
367 if ((timeout & CS4231_MCE) == 0 ||
368 !(chip->hardware & (CS4231_HW_CS4231_MASK | CS4231_HW_CS4232_MASK))) {
369 return;
370 }
371
372 /*
373 * Wait for (possible -- during init auto-calibration may not be set)
374 * calibration process to start. Needs upto 5 sample periods on AD1848
375 * which at the slowest possible rate of 5.5125 kHz means 907 us.
376 */
377 msleep(1);
378
379 snd_printdd("(1) jiffies = %lu\n", jiffies);
380
381 /* check condition up to 250 ms */
382 end_time = jiffies + msecs_to_jiffies(250);
383 while (snd_cs4231_in(chip, CS4231_TEST_INIT) &
384 CS4231_CALIB_IN_PROGRESS) {
385
386 if (time_after(jiffies, end_time)) {
387 snd_printk(KERN_ERR "mce_down - "
388 "auto calibration time out (2)\n");
389 return;
390 }
391 msleep(1);
392 }
393
394 snd_printdd("(2) jiffies = %lu\n", jiffies);
395
396 /* check condition up to 100 ms */
397 end_time = jiffies + msecs_to_jiffies(100);
398 while (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) {
399 if (time_after(jiffies, end_time)) {
400 snd_printk(KERN_ERR "mce_down - auto calibration time out (3)\n");
401 return;
402 }
403 msleep(1);
404 }
405
406 snd_printdd("(3) jiffies = %lu\n", jiffies);
407 snd_printd("mce_down - exit = 0x%x\n", cs4231_inb(chip, CS4231P(REGSEL)));
408}
409
410static unsigned int snd_cs4231_get_count(unsigned char format, unsigned int size)
411{
412 switch (format & 0xe0) {
413 case CS4231_LINEAR_16:
414 case CS4231_LINEAR_16_BIG:
415 size >>= 1;
416 break;
417 case CS4231_ADPCM_16:
418 return size >> 2;
419 }
420 if (format & CS4231_STEREO)
421 size >>= 1;
422 return size;
423}
424
425static int snd_cs4231_trigger(struct snd_pcm_substream *substream,
426 int cmd)
427{
428 struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
429 int result = 0;
430 unsigned int what;
431 struct snd_pcm_substream *s;
432 int do_start;
433
434#if 0
435 printk("codec trigger!!! - what = %i, enable = %i, status = 0x%x\n", what, enable, cs4231_inb(chip, CS4231P(STATUS)));
436#endif
437
438 switch (cmd) {
439 case SNDRV_PCM_TRIGGER_START:
440 case SNDRV_PCM_TRIGGER_RESUME:
441 do_start = 1; break;
442 case SNDRV_PCM_TRIGGER_STOP:
443 case SNDRV_PCM_TRIGGER_SUSPEND:
444 do_start = 0; break;
445 default:
446 return -EINVAL;
447 }
448
449 what = 0;
450 snd_pcm_group_for_each_entry(s, substream) {
451 if (s == chip->playback_substream) {
452 what |= CS4231_PLAYBACK_ENABLE;
453 snd_pcm_trigger_done(s, substream);
454 } else if (s == chip->capture_substream) {
455 what |= CS4231_RECORD_ENABLE;
456 snd_pcm_trigger_done(s, substream);
457 }
458 }
459 spin_lock(&chip->reg_lock);
460 if (do_start) {
461 chip->image[CS4231_IFACE_CTRL] |= what;
462 if (chip->trigger)
463 chip->trigger(chip, what, 1);
464 } else {
465 chip->image[CS4231_IFACE_CTRL] &= ~what;
466 if (chip->trigger)
467 chip->trigger(chip, what, 0);
468 }
469 snd_cs4231_out(chip, CS4231_IFACE_CTRL, chip->image[CS4231_IFACE_CTRL]);
470 spin_unlock(&chip->reg_lock);
471#if 0
472 snd_cs4231_debug(chip);
473#endif
474 return result;
475}
476
477/*
478 * CODEC I/O
479 */
480
481static unsigned char snd_cs4231_get_rate(unsigned int rate)
482{
483 int i;
484
485 for (i = 0; i < ARRAY_SIZE(rates); i++)
486 if (rate == rates[i])
487 return freq_bits[i];
488 // snd_BUG();
489 return freq_bits[ARRAY_SIZE(rates) - 1];
490}
491
492static unsigned char snd_cs4231_get_format(struct snd_cs4231 *chip,
493 int format,
494 int channels)
495{
496 unsigned char rformat;
497
498 rformat = CS4231_LINEAR_8;
499 switch (format) {
500 case SNDRV_PCM_FORMAT_MU_LAW: rformat = CS4231_ULAW_8; break;
501 case SNDRV_PCM_FORMAT_A_LAW: rformat = CS4231_ALAW_8; break;
502 case SNDRV_PCM_FORMAT_S16_LE: rformat = CS4231_LINEAR_16; break;
503 case SNDRV_PCM_FORMAT_S16_BE: rformat = CS4231_LINEAR_16_BIG; break;
504 case SNDRV_PCM_FORMAT_IMA_ADPCM: rformat = CS4231_ADPCM_16; break;
505 }
506 if (channels > 1)
507 rformat |= CS4231_STEREO;
508#if 0
509 snd_printk("get_format: 0x%x (mode=0x%x)\n", format, mode);
510#endif
511 return rformat;
512}
513
514static void snd_cs4231_calibrate_mute(struct snd_cs4231 *chip, int mute)
515{
516 unsigned long flags;
517
518 mute = mute ? 1 : 0;
519 spin_lock_irqsave(&chip->reg_lock, flags);
520 if (chip->calibrate_mute == mute) {
521 spin_unlock_irqrestore(&chip->reg_lock, flags);
522 return;
523 }
524 if (!mute) {
525 snd_cs4231_dout(chip, CS4231_LEFT_INPUT, chip->image[CS4231_LEFT_INPUT]);
526 snd_cs4231_dout(chip, CS4231_RIGHT_INPUT, chip->image[CS4231_RIGHT_INPUT]);
527 snd_cs4231_dout(chip, CS4231_LOOPBACK, chip->image[CS4231_LOOPBACK]);
528 }
529 snd_cs4231_dout(chip, CS4231_AUX1_LEFT_INPUT, mute ? 0x80 : chip->image[CS4231_AUX1_LEFT_INPUT]);
530 snd_cs4231_dout(chip, CS4231_AUX1_RIGHT_INPUT, mute ? 0x80 : chip->image[CS4231_AUX1_RIGHT_INPUT]);
531 snd_cs4231_dout(chip, CS4231_AUX2_LEFT_INPUT, mute ? 0x80 : chip->image[CS4231_AUX2_LEFT_INPUT]);
532 snd_cs4231_dout(chip, CS4231_AUX2_RIGHT_INPUT, mute ? 0x80 : chip->image[CS4231_AUX2_RIGHT_INPUT]);
533 snd_cs4231_dout(chip, CS4231_LEFT_OUTPUT, mute ? 0x80 : chip->image[CS4231_LEFT_OUTPUT]);
534 snd_cs4231_dout(chip, CS4231_RIGHT_OUTPUT, mute ? 0x80 : chip->image[CS4231_RIGHT_OUTPUT]);
535 snd_cs4231_dout(chip, CS4231_LEFT_LINE_IN, mute ? 0x80 : chip->image[CS4231_LEFT_LINE_IN]);
536 snd_cs4231_dout(chip, CS4231_RIGHT_LINE_IN, mute ? 0x80 : chip->image[CS4231_RIGHT_LINE_IN]);
537 snd_cs4231_dout(chip, CS4231_MONO_CTRL, mute ? 0xc0 : chip->image[CS4231_MONO_CTRL]);
538 if (chip->hardware == CS4231_HW_INTERWAVE) {
539 snd_cs4231_dout(chip, CS4231_LEFT_MIC_INPUT, mute ? 0x80 : chip->image[CS4231_LEFT_MIC_INPUT]);
540 snd_cs4231_dout(chip, CS4231_RIGHT_MIC_INPUT, mute ? 0x80 : chip->image[CS4231_RIGHT_MIC_INPUT]);
541 snd_cs4231_dout(chip, CS4231_LINE_LEFT_OUTPUT, mute ? 0x80 : chip->image[CS4231_LINE_LEFT_OUTPUT]);
542 snd_cs4231_dout(chip, CS4231_LINE_RIGHT_OUTPUT, mute ? 0x80 : chip->image[CS4231_LINE_RIGHT_OUTPUT]);
543 }
544 chip->calibrate_mute = mute;
545 spin_unlock_irqrestore(&chip->reg_lock, flags);
546}
547
548static void snd_cs4231_playback_format(struct snd_cs4231 *chip,
549 struct snd_pcm_hw_params *params,
550 unsigned char pdfr)
551{
552 unsigned long flags;
553 int full_calib = 1;
554
555 mutex_lock(&chip->mce_mutex);
556 snd_cs4231_calibrate_mute(chip, 1);
557 if (chip->hardware == CS4231_HW_CS4231A ||
558 (chip->hardware & CS4231_HW_CS4232_MASK)) {
559 spin_lock_irqsave(&chip->reg_lock, flags);
560 if ((chip->image[CS4231_PLAYBK_FORMAT] & 0x0f) == (pdfr & 0x0f)) { /* rate is same? */
561 snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1] | 0x10);
562 snd_cs4231_out(chip, CS4231_PLAYBK_FORMAT, chip->image[CS4231_PLAYBK_FORMAT] = pdfr);
563 snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1] &= ~0x10);
564 udelay(100); /* Fixes audible clicks at least on GUS MAX */
565 full_calib = 0;
566 }
567 spin_unlock_irqrestore(&chip->reg_lock, flags);
568 }
569 if (full_calib) {
570 snd_cs4231_mce_up(chip);
571 spin_lock_irqsave(&chip->reg_lock, flags);
572 if (chip->hardware != CS4231_HW_INTERWAVE && !chip->single_dma) {
573 snd_cs4231_out(chip, CS4231_PLAYBK_FORMAT,
574 (chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE) ?
575 (pdfr & 0xf0) | (chip->image[CS4231_REC_FORMAT] & 0x0f) :
576 pdfr);
577 } else {
578 snd_cs4231_out(chip, CS4231_PLAYBK_FORMAT, chip->image[CS4231_PLAYBK_FORMAT] = pdfr);
579 }
580 spin_unlock_irqrestore(&chip->reg_lock, flags);
581 if (chip->hardware == CS4231_HW_OPL3SA2)
582 udelay(100); /* this seems to help */
583 snd_cs4231_mce_down(chip);
584 }
585 snd_cs4231_calibrate_mute(chip, 0);
586 mutex_unlock(&chip->mce_mutex);
587}
588
589static void snd_cs4231_capture_format(struct snd_cs4231 *chip,
590 struct snd_pcm_hw_params *params,
591 unsigned char cdfr)
592{
593 unsigned long flags;
594 int full_calib = 1;
595
596 mutex_lock(&chip->mce_mutex);
597 snd_cs4231_calibrate_mute(chip, 1);
598 if (chip->hardware == CS4231_HW_CS4231A ||
599 (chip->hardware & CS4231_HW_CS4232_MASK)) {
600 spin_lock_irqsave(&chip->reg_lock, flags);
601 if ((chip->image[CS4231_PLAYBK_FORMAT] & 0x0f) == (cdfr & 0x0f) || /* rate is same? */
602 (chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE)) {
603 snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1] | 0x20);
604 snd_cs4231_out(chip, CS4231_REC_FORMAT, chip->image[CS4231_REC_FORMAT] = cdfr);
605 snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1] &= ~0x20);
606 full_calib = 0;
607 }
608 spin_unlock_irqrestore(&chip->reg_lock, flags);
609 }
610 if (full_calib) {
611 snd_cs4231_mce_up(chip);
612 spin_lock_irqsave(&chip->reg_lock, flags);
613 if (chip->hardware != CS4231_HW_INTERWAVE) {
614 if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE)) {
615 snd_cs4231_out(chip, CS4231_PLAYBK_FORMAT,
616 ((chip->single_dma ? cdfr : chip->image[CS4231_PLAYBK_FORMAT]) & 0xf0) |
617 (cdfr & 0x0f));
618 spin_unlock_irqrestore(&chip->reg_lock, flags);
619 snd_cs4231_mce_down(chip);
620 snd_cs4231_mce_up(chip);
621 spin_lock_irqsave(&chip->reg_lock, flags);
622 }
623 }
624 snd_cs4231_out(chip, CS4231_REC_FORMAT, cdfr);
625 spin_unlock_irqrestore(&chip->reg_lock, flags);
626 snd_cs4231_mce_down(chip);
627 }
628 snd_cs4231_calibrate_mute(chip, 0);
629 mutex_unlock(&chip->mce_mutex);
630}
631
632/*
633 * Timer interface
634 */
635
636static unsigned long snd_cs4231_timer_resolution(struct snd_timer * timer)
637{
638 struct snd_cs4231 *chip = snd_timer_chip(timer);
639 if (chip->hardware & CS4231_HW_CS4236B_MASK)
640 return 14467;
641 else
642 return chip->image[CS4231_PLAYBK_FORMAT] & 1 ? 9969 : 9920;
643}
644
645static int snd_cs4231_timer_start(struct snd_timer * timer)
646{
647 unsigned long flags;
648 unsigned int ticks;
649 struct snd_cs4231 *chip = snd_timer_chip(timer);
650 spin_lock_irqsave(&chip->reg_lock, flags);
651 ticks = timer->sticks;
652 if ((chip->image[CS4231_ALT_FEATURE_1] & CS4231_TIMER_ENABLE) == 0 ||
653 (unsigned char)(ticks >> 8) != chip->image[CS4231_TIMER_HIGH] ||
654 (unsigned char)ticks != chip->image[CS4231_TIMER_LOW]) {
655 snd_cs4231_out(chip, CS4231_TIMER_HIGH, chip->image[CS4231_TIMER_HIGH] = (unsigned char) (ticks >> 8));
656 snd_cs4231_out(chip, CS4231_TIMER_LOW, chip->image[CS4231_TIMER_LOW] = (unsigned char) ticks);
657 snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1] | CS4231_TIMER_ENABLE);
658 }
659 spin_unlock_irqrestore(&chip->reg_lock, flags);
660 return 0;
661}
662
663static int snd_cs4231_timer_stop(struct snd_timer * timer)
664{
665 unsigned long flags;
666 struct snd_cs4231 *chip = snd_timer_chip(timer);
667 spin_lock_irqsave(&chip->reg_lock, flags);
668 snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1] &= ~CS4231_TIMER_ENABLE);
669 spin_unlock_irqrestore(&chip->reg_lock, flags);
670 return 0;
671}
672
673static void snd_cs4231_init(struct snd_cs4231 *chip)
674{
675 unsigned long flags;
676
677 snd_cs4231_mce_down(chip);
678
679#ifdef SNDRV_DEBUG_MCE
680 snd_printk("init: (1)\n");
681#endif
682 snd_cs4231_mce_up(chip);
683 spin_lock_irqsave(&chip->reg_lock, flags);
684 chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_PLAYBACK_ENABLE | CS4231_PLAYBACK_PIO |
685 CS4231_RECORD_ENABLE | CS4231_RECORD_PIO |
686 CS4231_CALIB_MODE);
687 chip->image[CS4231_IFACE_CTRL] |= CS4231_AUTOCALIB;
688 snd_cs4231_out(chip, CS4231_IFACE_CTRL, chip->image[CS4231_IFACE_CTRL]);
689 spin_unlock_irqrestore(&chip->reg_lock, flags);
690 snd_cs4231_mce_down(chip);
691
692#ifdef SNDRV_DEBUG_MCE
693 snd_printk("init: (2)\n");
694#endif
695
696 snd_cs4231_mce_up(chip);
697 spin_lock_irqsave(&chip->reg_lock, flags);
698 snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1]);
699 spin_unlock_irqrestore(&chip->reg_lock, flags);
700 snd_cs4231_mce_down(chip);
701
702#ifdef SNDRV_DEBUG_MCE
703 snd_printk("init: (3) - afei = 0x%x\n", chip->image[CS4231_ALT_FEATURE_1]);
704#endif
705
706 spin_lock_irqsave(&chip->reg_lock, flags);
707 snd_cs4231_out(chip, CS4231_ALT_FEATURE_2, chip->image[CS4231_ALT_FEATURE_2]);
708 spin_unlock_irqrestore(&chip->reg_lock, flags);
709
710 snd_cs4231_mce_up(chip);
711 spin_lock_irqsave(&chip->reg_lock, flags);
712 snd_cs4231_out(chip, CS4231_PLAYBK_FORMAT, chip->image[CS4231_PLAYBK_FORMAT]);
713 spin_unlock_irqrestore(&chip->reg_lock, flags);
714 snd_cs4231_mce_down(chip);
715
716#ifdef SNDRV_DEBUG_MCE
717 snd_printk("init: (4)\n");
718#endif
719
720 snd_cs4231_mce_up(chip);
721 spin_lock_irqsave(&chip->reg_lock, flags);
722 snd_cs4231_out(chip, CS4231_REC_FORMAT, chip->image[CS4231_REC_FORMAT]);
723 spin_unlock_irqrestore(&chip->reg_lock, flags);
724 snd_cs4231_mce_down(chip);
725
726#ifdef SNDRV_DEBUG_MCE
727 snd_printk("init: (5)\n");
728#endif
729}
730
731static int snd_cs4231_open(struct snd_cs4231 *chip, unsigned int mode)
732{
733 unsigned long flags;
734
735 mutex_lock(&chip->open_mutex);
736 if ((chip->mode & mode) ||
737 ((chip->mode & CS4231_MODE_OPEN) && chip->single_dma)) {
738 mutex_unlock(&chip->open_mutex);
739 return -EAGAIN;
740 }
741 if (chip->mode & CS4231_MODE_OPEN) {
742 chip->mode |= mode;
743 mutex_unlock(&chip->open_mutex);
744 return 0;
745 }
746 /* ok. now enable and ack CODEC IRQ */
747 spin_lock_irqsave(&chip->reg_lock, flags);
748 snd_cs4231_out(chip, CS4231_IRQ_STATUS, CS4231_PLAYBACK_IRQ |
749 CS4231_RECORD_IRQ |
750 CS4231_TIMER_IRQ);
751 snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0);
752 cs4231_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */
753 cs4231_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */
754 chip->image[CS4231_PIN_CTRL] |= CS4231_IRQ_ENABLE;
755 snd_cs4231_out(chip, CS4231_PIN_CTRL, chip->image[CS4231_PIN_CTRL]);
756 snd_cs4231_out(chip, CS4231_IRQ_STATUS, CS4231_PLAYBACK_IRQ |
757 CS4231_RECORD_IRQ |
758 CS4231_TIMER_IRQ);
759 snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0);
760 spin_unlock_irqrestore(&chip->reg_lock, flags);
761
762 chip->mode = mode;
763 mutex_unlock(&chip->open_mutex);
764 return 0;
765}
766
767static void snd_cs4231_close(struct snd_cs4231 *chip, unsigned int mode)
768{
769 unsigned long flags;
770
771 mutex_lock(&chip->open_mutex);
772 chip->mode &= ~mode;
773 if (chip->mode & CS4231_MODE_OPEN) {
774 mutex_unlock(&chip->open_mutex);
775 return;
776 }
777 snd_cs4231_calibrate_mute(chip, 1);
778
779 /* disable IRQ */
780 spin_lock_irqsave(&chip->reg_lock, flags);
781 snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0);
782 cs4231_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */
783 cs4231_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */
784 chip->image[CS4231_PIN_CTRL] &= ~CS4231_IRQ_ENABLE;
785 snd_cs4231_out(chip, CS4231_PIN_CTRL, chip->image[CS4231_PIN_CTRL]);
786
787 /* now disable record & playback */
788
789 if (chip->image[CS4231_IFACE_CTRL] & (CS4231_PLAYBACK_ENABLE | CS4231_PLAYBACK_PIO |
790 CS4231_RECORD_ENABLE | CS4231_RECORD_PIO)) {
791 spin_unlock_irqrestore(&chip->reg_lock, flags);
792 snd_cs4231_mce_up(chip);
793 spin_lock_irqsave(&chip->reg_lock, flags);
794 chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_PLAYBACK_ENABLE | CS4231_PLAYBACK_PIO |
795 CS4231_RECORD_ENABLE | CS4231_RECORD_PIO);
796 snd_cs4231_out(chip, CS4231_IFACE_CTRL, chip->image[CS4231_IFACE_CTRL]);
797 spin_unlock_irqrestore(&chip->reg_lock, flags);
798 snd_cs4231_mce_down(chip);
799 spin_lock_irqsave(&chip->reg_lock, flags);
800 }
801
802 /* clear IRQ again */
803 snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0);
804 cs4231_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */
805 cs4231_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */
806 spin_unlock_irqrestore(&chip->reg_lock, flags);
807
808 snd_cs4231_calibrate_mute(chip, 0);
809
810 chip->mode = 0;
811 mutex_unlock(&chip->open_mutex);
812}
813
814/*
815 * timer open/close
816 */
817
818static int snd_cs4231_timer_open(struct snd_timer * timer)
819{
820 struct snd_cs4231 *chip = snd_timer_chip(timer);
821 snd_cs4231_open(chip, CS4231_MODE_TIMER);
822 return 0;
823}
824
825static int snd_cs4231_timer_close(struct snd_timer * timer)
826{
827 struct snd_cs4231 *chip = snd_timer_chip(timer);
828 snd_cs4231_close(chip, CS4231_MODE_TIMER);
829 return 0;
830}
831
832static struct snd_timer_hardware snd_cs4231_timer_table =
833{
834 .flags = SNDRV_TIMER_HW_AUTO,
835 .resolution = 9945,
836 .ticks = 65535,
837 .open = snd_cs4231_timer_open,
838 .close = snd_cs4231_timer_close,
839 .c_resolution = snd_cs4231_timer_resolution,
840 .start = snd_cs4231_timer_start,
841 .stop = snd_cs4231_timer_stop,
842};
843
844/*
845 * ok.. exported functions..
846 */
847
848static int snd_cs4231_playback_hw_params(struct snd_pcm_substream *substream,
849 struct snd_pcm_hw_params *hw_params)
850{
851 struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
852 unsigned char new_pdfr;
853 int err;
854
855 if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
856 return err;
857 new_pdfr = snd_cs4231_get_format(chip, params_format(hw_params), params_channels(hw_params)) |
858 snd_cs4231_get_rate(params_rate(hw_params));
859 chip->set_playback_format(chip, hw_params, new_pdfr);
860 return 0;
861}
862
863static int snd_cs4231_playback_hw_free(struct snd_pcm_substream *substream)
864{
865 return snd_pcm_lib_free_pages(substream);
866}
867
868static int snd_cs4231_playback_prepare(struct snd_pcm_substream *substream)
869{
870 struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
871 struct snd_pcm_runtime *runtime = substream->runtime;
872 unsigned long flags;
873 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
874 unsigned int count = snd_pcm_lib_period_bytes(substream);
875
876 spin_lock_irqsave(&chip->reg_lock, flags);
877 chip->p_dma_size = size;
878 chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_PLAYBACK_ENABLE | CS4231_PLAYBACK_PIO);
879 snd_dma_program(chip->dma1, runtime->dma_addr, size, DMA_MODE_WRITE | DMA_AUTOINIT);
880 count = snd_cs4231_get_count(chip->image[CS4231_PLAYBK_FORMAT], count) - 1;
881 snd_cs4231_out(chip, CS4231_PLY_LWR_CNT, (unsigned char) count);
882 snd_cs4231_out(chip, CS4231_PLY_UPR_CNT, (unsigned char) (count >> 8));
883 spin_unlock_irqrestore(&chip->reg_lock, flags);
884#if 0
885 snd_cs4231_debug(chip);
886#endif
887 return 0;
888}
889
890static int snd_cs4231_capture_hw_params(struct snd_pcm_substream *substream,
891 struct snd_pcm_hw_params *hw_params)
892{
893 struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
894 unsigned char new_cdfr;
895 int err;
896
897 if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
898 return err;
899 new_cdfr = snd_cs4231_get_format(chip, params_format(hw_params), params_channels(hw_params)) |
900 snd_cs4231_get_rate(params_rate(hw_params));
901 chip->set_capture_format(chip, hw_params, new_cdfr);
902 return 0;
903}
904
905static int snd_cs4231_capture_hw_free(struct snd_pcm_substream *substream)
906{
907 return snd_pcm_lib_free_pages(substream);
908}
909
910static int snd_cs4231_capture_prepare(struct snd_pcm_substream *substream)
911{
912 struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
913 struct snd_pcm_runtime *runtime = substream->runtime;
914 unsigned long flags;
915 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
916 unsigned int count = snd_pcm_lib_period_bytes(substream);
917
918 spin_lock_irqsave(&chip->reg_lock, flags);
919 chip->c_dma_size = size;
920 chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_RECORD_ENABLE | CS4231_RECORD_PIO);
921 snd_dma_program(chip->dma2, runtime->dma_addr, size, DMA_MODE_READ | DMA_AUTOINIT);
922 count = snd_cs4231_get_count(chip->image[CS4231_REC_FORMAT], count) - 1;
923 if (chip->single_dma && chip->hardware != CS4231_HW_INTERWAVE) {
924 snd_cs4231_out(chip, CS4231_PLY_LWR_CNT, (unsigned char) count);
925 snd_cs4231_out(chip, CS4231_PLY_UPR_CNT, (unsigned char) (count >> 8));
926 } else {
927 snd_cs4231_out(chip, CS4231_REC_LWR_CNT, (unsigned char) count);
928 snd_cs4231_out(chip, CS4231_REC_UPR_CNT, (unsigned char) (count >> 8));
929 }
930 spin_unlock_irqrestore(&chip->reg_lock, flags);
931 return 0;
932}
933
934void snd_cs4231_overrange(struct snd_cs4231 *chip)
935{
936 unsigned long flags;
937 unsigned char res;
938
939 spin_lock_irqsave(&chip->reg_lock, flags);
940 res = snd_cs4231_in(chip, CS4231_TEST_INIT);
941 spin_unlock_irqrestore(&chip->reg_lock, flags);
942 if (res & (0x08 | 0x02)) /* detect overrange only above 0dB; may be user selectable? */
943 chip->capture_substream->runtime->overrange++;
944}
945
946irqreturn_t snd_cs4231_interrupt(int irq, void *dev_id)
947{
948 struct snd_cs4231 *chip = dev_id;
949 unsigned char status;
950
951 status = snd_cs4231_in(chip, CS4231_IRQ_STATUS);
952 if (status & CS4231_TIMER_IRQ) {
953 if (chip->timer)
954 snd_timer_interrupt(chip->timer, chip->timer->sticks);
955 }
956 if (chip->single_dma && chip->hardware != CS4231_HW_INTERWAVE) {
957 if (status & CS4231_PLAYBACK_IRQ) {
958 if (chip->mode & CS4231_MODE_PLAY) {
959 if (chip->playback_substream)
960 snd_pcm_period_elapsed(chip->playback_substream);
961 }
962 if (chip->mode & CS4231_MODE_RECORD) {
963 if (chip->capture_substream) {
964 snd_cs4231_overrange(chip);
965 snd_pcm_period_elapsed(chip->capture_substream);
966 }
967 }
968 }
969 } else {
970 if (status & CS4231_PLAYBACK_IRQ) {
971 if (chip->playback_substream)
972 snd_pcm_period_elapsed(chip->playback_substream);
973 }
974 if (status & CS4231_RECORD_IRQ) {
975 if (chip->capture_substream) {
976 snd_cs4231_overrange(chip);
977 snd_pcm_period_elapsed(chip->capture_substream);
978 }
979 }
980 }
981
982 spin_lock(&chip->reg_lock);
983 snd_cs4231_outm(chip, CS4231_IRQ_STATUS, ~CS4231_ALL_IRQS | ~status, 0);
984 spin_unlock(&chip->reg_lock);
985 return IRQ_HANDLED;
986}
987
988static snd_pcm_uframes_t snd_cs4231_playback_pointer(struct snd_pcm_substream *substream)
989{
990 struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
991 size_t ptr;
992
993 if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE))
994 return 0;
995 ptr = snd_dma_pointer(chip->dma1, chip->p_dma_size);
996 return bytes_to_frames(substream->runtime, ptr);
997}
998
999static snd_pcm_uframes_t snd_cs4231_capture_pointer(struct snd_pcm_substream *substream)
1000{
1001 struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
1002 size_t ptr;
1003
1004 if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE))
1005 return 0;
1006 ptr = snd_dma_pointer(chip->dma2, chip->c_dma_size);
1007 return bytes_to_frames(substream->runtime, ptr);
1008}
1009
1010/*
1011
1012 */
1013
1014static int snd_cs4231_probe(struct snd_cs4231 *chip)
1015{
1016 unsigned long flags;
1017 int i, id, rev;
1018 unsigned char *ptr;
1019 unsigned int hw;
1020
1021#if 0
1022 snd_cs4231_debug(chip);
1023#endif
1024 id = 0;
1025 for (i = 0; i < 50; i++) {
1026 mb();
1027 if (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
1028 udelay(2000);
1029 else {
1030 spin_lock_irqsave(&chip->reg_lock, flags);
1031 snd_cs4231_out(chip, CS4231_MISC_INFO, CS4231_MODE2);
1032 id = snd_cs4231_in(chip, CS4231_MISC_INFO) & 0x0f;
1033 spin_unlock_irqrestore(&chip->reg_lock, flags);
1034 if (id == 0x0a)
1035 break; /* this is valid value */
1036 }
1037 }
1038 snd_printdd("cs4231: port = 0x%lx, id = 0x%x\n", chip->port, id);
1039 if (id != 0x0a)
1040 return -ENODEV; /* no valid device found */
1041
1042 if (((hw = chip->hardware) & CS4231_HW_TYPE_MASK) == CS4231_HW_DETECT) {
1043 rev = snd_cs4231_in(chip, CS4231_VERSION) & 0xe7;
1044 snd_printdd("CS4231: VERSION (I25) = 0x%x\n", rev);
1045 if (rev == 0x80) {
1046 unsigned char tmp = snd_cs4231_in(chip, 23);
1047 snd_cs4231_out(chip, 23, ~tmp);
1048 if (snd_cs4231_in(chip, 23) != tmp)
1049 chip->hardware = CS4231_HW_AD1845;
1050 else
1051 chip->hardware = CS4231_HW_CS4231;
1052 } else if (rev == 0xa0) {
1053 chip->hardware = CS4231_HW_CS4231A;
1054 } else if (rev == 0xa2) {
1055 chip->hardware = CS4231_HW_CS4232;
1056 } else if (rev == 0xb2) {
1057 chip->hardware = CS4231_HW_CS4232A;
1058 } else if (rev == 0x83) {
1059 chip->hardware = CS4231_HW_CS4236;
1060 } else if (rev == 0x03) {
1061 chip->hardware = CS4231_HW_CS4236B;
1062 } else {
1063 snd_printk("unknown CS chip with version 0x%x\n", rev);
1064 return -ENODEV; /* unknown CS4231 chip? */
1065 }
1066 }
1067 spin_lock_irqsave(&chip->reg_lock, flags);
1068 cs4231_inb(chip, CS4231P(STATUS)); /* clear any pendings IRQ */
1069 cs4231_outb(chip, CS4231P(STATUS), 0);
1070 mb();
1071 spin_unlock_irqrestore(&chip->reg_lock, flags);
1072
1073 chip->image[CS4231_MISC_INFO] = CS4231_MODE2;
1074 switch (chip->hardware) {
1075 case CS4231_HW_INTERWAVE:
1076 chip->image[CS4231_MISC_INFO] = CS4231_IW_MODE3;
1077 break;
1078 case CS4231_HW_CS4235:
1079 case CS4231_HW_CS4236B:
1080 case CS4231_HW_CS4237B:
1081 case CS4231_HW_CS4238B:
1082 case CS4231_HW_CS4239:
1083 if (hw == CS4231_HW_DETECT3)
1084 chip->image[CS4231_MISC_INFO] = CS4231_4236_MODE3;
1085 else
1086 chip->hardware = CS4231_HW_CS4236;
1087 break;
1088 }
1089
1090 chip->image[CS4231_IFACE_CTRL] =
1091 (chip->image[CS4231_IFACE_CTRL] & ~CS4231_SINGLE_DMA) |
1092 (chip->single_dma ? CS4231_SINGLE_DMA : 0);
1093 if (chip->hardware != CS4231_HW_OPTI93X) {
1094 chip->image[CS4231_ALT_FEATURE_1] = 0x80;
1095 chip->image[CS4231_ALT_FEATURE_2] =
1096 chip->hardware == CS4231_HW_INTERWAVE ? 0xc2 : 0x01;
1097 }
1098 ptr = (unsigned char *) &chip->image;
1099 snd_cs4231_mce_down(chip);
1100 spin_lock_irqsave(&chip->reg_lock, flags);
1101 for (i = 0; i < 32; i++) /* ok.. fill all CS4231 registers */
1102 snd_cs4231_out(chip, i, *ptr++);
1103 spin_unlock_irqrestore(&chip->reg_lock, flags);
1104 snd_cs4231_mce_up(chip);
1105 snd_cs4231_mce_down(chip);
1106
1107 mdelay(2);
1108
1109 /* ok.. try check hardware version for CS4236+ chips */
1110 if ((hw & CS4231_HW_TYPE_MASK) == CS4231_HW_DETECT) {
1111 if (chip->hardware == CS4231_HW_CS4236B) {
1112 rev = snd_cs4236_ext_in(chip, CS4236_VERSION);
1113 snd_cs4236_ext_out(chip, CS4236_VERSION, 0xff);
1114 id = snd_cs4236_ext_in(chip, CS4236_VERSION);
1115 snd_cs4236_ext_out(chip, CS4236_VERSION, rev);
1116 snd_printdd("CS4231: ext version; rev = 0x%x, id = 0x%x\n", rev, id);
1117 if ((id & 0x1f) == 0x1d) { /* CS4235 */
1118 chip->hardware = CS4231_HW_CS4235;
1119 switch (id >> 5) {
1120 case 4:
1121 case 5:
1122 case 6:
1123 break;
1124 default:
1125 snd_printk("unknown CS4235 chip (enhanced version = 0x%x)\n", id);
1126 }
1127 } else if ((id & 0x1f) == 0x0b) { /* CS4236/B */
1128 switch (id >> 5) {
1129 case 4:
1130 case 5:
1131 case 6:
1132 case 7:
1133 chip->hardware = CS4231_HW_CS4236B;
1134 break;
1135 default:
1136 snd_printk("unknown CS4236 chip (enhanced version = 0x%x)\n", id);
1137 }
1138 } else if ((id & 0x1f) == 0x08) { /* CS4237B */
1139 chip->hardware = CS4231_HW_CS4237B;
1140 switch (id >> 5) {
1141 case 4:
1142 case 5:
1143 case 6:
1144 case 7:
1145 break;
1146 default:
1147 snd_printk("unknown CS4237B chip (enhanced version = 0x%x)\n", id);
1148 }
1149 } else if ((id & 0x1f) == 0x09) { /* CS4238B */
1150 chip->hardware = CS4231_HW_CS4238B;
1151 switch (id >> 5) {
1152 case 5:
1153 case 6:
1154 case 7:
1155 break;
1156 default:
1157 snd_printk("unknown CS4238B chip (enhanced version = 0x%x)\n", id);
1158 }
1159 } else if ((id & 0x1f) == 0x1e) { /* CS4239 */
1160 chip->hardware = CS4231_HW_CS4239;
1161 switch (id >> 5) {
1162 case 4:
1163 case 5:
1164 case 6:
1165 break;
1166 default:
1167 snd_printk("unknown CS4239 chip (enhanced version = 0x%x)\n", id);
1168 }
1169 } else {
1170 snd_printk("unknown CS4236/CS423xB chip (enhanced version = 0x%x)\n", id);
1171 }
1172 }
1173 }
1174 return 0; /* all things are ok.. */
1175}
1176
1177/*
1178
1179 */
1180
1181static struct snd_pcm_hardware snd_cs4231_playback =
1182{
1183 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1184 SNDRV_PCM_INFO_MMAP_VALID |
1185 SNDRV_PCM_INFO_RESUME |
1186 SNDRV_PCM_INFO_SYNC_START),
1187 .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | SNDRV_PCM_FMTBIT_IMA_ADPCM |
1188 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE),
1189 .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
1190 .rate_min = 5510,
1191 .rate_max = 48000,
1192 .channels_min = 1,
1193 .channels_max = 2,
1194 .buffer_bytes_max = (128*1024),
1195 .period_bytes_min = 64,
1196 .period_bytes_max = (128*1024),
1197 .periods_min = 1,
1198 .periods_max = 1024,
1199 .fifo_size = 0,
1200};
1201
1202static struct snd_pcm_hardware snd_cs4231_capture =
1203{
1204 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1205 SNDRV_PCM_INFO_MMAP_VALID |
1206 SNDRV_PCM_INFO_RESUME |
1207 SNDRV_PCM_INFO_SYNC_START),
1208 .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | SNDRV_PCM_FMTBIT_IMA_ADPCM |
1209 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE),
1210 .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
1211 .rate_min = 5510,
1212 .rate_max = 48000,
1213 .channels_min = 1,
1214 .channels_max = 2,
1215 .buffer_bytes_max = (128*1024),
1216 .period_bytes_min = 64,
1217 .period_bytes_max = (128*1024),
1218 .periods_min = 1,
1219 .periods_max = 1024,
1220 .fifo_size = 0,
1221};
1222
1223/*
1224
1225 */
1226
1227static int snd_cs4231_playback_open(struct snd_pcm_substream *substream)
1228{
1229 struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
1230 struct snd_pcm_runtime *runtime = substream->runtime;
1231 int err;
1232
1233 runtime->hw = snd_cs4231_playback;
1234
1235 /* hardware bug in InterWave chipset */
1236 if (chip->hardware == CS4231_HW_INTERWAVE && chip->dma1 > 3)
1237 runtime->hw.formats &= ~SNDRV_PCM_FMTBIT_MU_LAW;
1238
1239 /* hardware limitation of cheap chips */
1240 if (chip->hardware == CS4231_HW_CS4235 ||
1241 chip->hardware == CS4231_HW_CS4239)
1242 runtime->hw.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE;
1243
1244 snd_pcm_limit_isa_dma_size(chip->dma1, &runtime->hw.buffer_bytes_max);
1245 snd_pcm_limit_isa_dma_size(chip->dma1, &runtime->hw.period_bytes_max);
1246
1247 if (chip->claim_dma) {
1248 if ((err = chip->claim_dma(chip, chip->dma_private_data, chip->dma1)) < 0)
1249 return err;
1250 }
1251
1252 if ((err = snd_cs4231_open(chip, CS4231_MODE_PLAY)) < 0) {
1253 if (chip->release_dma)
1254 chip->release_dma(chip, chip->dma_private_data, chip->dma1);
1255 snd_free_pages(runtime->dma_area, runtime->dma_bytes);
1256 return err;
1257 }
1258 chip->playback_substream = substream;
1259 snd_pcm_set_sync(substream);
1260 chip->rate_constraint(runtime);
1261 return 0;
1262}
1263
1264static int snd_cs4231_capture_open(struct snd_pcm_substream *substream)
1265{
1266 struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
1267 struct snd_pcm_runtime *runtime = substream->runtime;
1268 int err;
1269
1270 runtime->hw = snd_cs4231_capture;
1271
1272 /* hardware limitation of cheap chips */
1273 if (chip->hardware == CS4231_HW_CS4235 ||
1274 chip->hardware == CS4231_HW_CS4239)
1275 runtime->hw.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE;
1276
1277 snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.buffer_bytes_max);
1278 snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.period_bytes_max);
1279
1280 if (chip->claim_dma) {
1281 if ((err = chip->claim_dma(chip, chip->dma_private_data, chip->dma2)) < 0)
1282 return err;
1283 }
1284
1285 if ((err = snd_cs4231_open(chip, CS4231_MODE_RECORD)) < 0) {
1286 if (chip->release_dma)
1287 chip->release_dma(chip, chip->dma_private_data, chip->dma2);
1288 snd_free_pages(runtime->dma_area, runtime->dma_bytes);
1289 return err;
1290 }
1291 chip->capture_substream = substream;
1292 snd_pcm_set_sync(substream);
1293 chip->rate_constraint(runtime);
1294 return 0;
1295}
1296
1297static int snd_cs4231_playback_close(struct snd_pcm_substream *substream)
1298{
1299 struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
1300
1301 chip->playback_substream = NULL;
1302 snd_cs4231_close(chip, CS4231_MODE_PLAY);
1303 return 0;
1304}
1305
1306static int snd_cs4231_capture_close(struct snd_pcm_substream *substream)
1307{
1308 struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
1309
1310 chip->capture_substream = NULL;
1311 snd_cs4231_close(chip, CS4231_MODE_RECORD);
1312 return 0;
1313}
1314
1315#ifdef CONFIG_PM
1316
1317/* lowlevel suspend callback for CS4231 */
1318static void snd_cs4231_suspend(struct snd_cs4231 *chip)
1319{
1320 int reg;
1321 unsigned long flags;
1322
1323 snd_pcm_suspend_all(chip->pcm);
1324 spin_lock_irqsave(&chip->reg_lock, flags);
1325 for (reg = 0; reg < 32; reg++)
1326 chip->image[reg] = snd_cs4231_in(chip, reg);
1327 spin_unlock_irqrestore(&chip->reg_lock, flags);
1328}
1329
1330/* lowlevel resume callback for CS4231 */
1331static void snd_cs4231_resume(struct snd_cs4231 *chip)
1332{
1333 int reg;
1334 unsigned long flags;
1335 /* int timeout; */
1336
1337 snd_cs4231_mce_up(chip);
1338 spin_lock_irqsave(&chip->reg_lock, flags);
1339 for (reg = 0; reg < 32; reg++) {
1340 switch (reg) {
1341 case CS4231_VERSION:
1342 break;
1343 default:
1344 snd_cs4231_out(chip, reg, chip->image[reg]);
1345 break;
1346 }
1347 }
1348 spin_unlock_irqrestore(&chip->reg_lock, flags);
1349#if 1
1350 snd_cs4231_mce_down(chip);
1351#else
1352 /* The following is a workaround to avoid freeze after resume on TP600E.
1353 This is the first half of copy of snd_cs4231_mce_down(), but doesn't
1354 include rescheduling. -- iwai
1355 */
1356 snd_cs4231_busy_wait(chip);
1357 spin_lock_irqsave(&chip->reg_lock, flags);
1358 chip->mce_bit &= ~CS4231_MCE;
1359 timeout = cs4231_inb(chip, CS4231P(REGSEL));
1360 cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | (timeout & 0x1f));
1361 spin_unlock_irqrestore(&chip->reg_lock, flags);
1362 if (timeout == 0x80)
1363 snd_printk("down [0x%lx]: serious init problem - codec still busy\n", chip->port);
1364 if ((timeout & CS4231_MCE) == 0 ||
1365 !(chip->hardware & (CS4231_HW_CS4231_MASK | CS4231_HW_CS4232_MASK))) {
1366 return;
1367 }
1368 snd_cs4231_busy_wait(chip);
1369#endif
1370}
1371#endif /* CONFIG_PM */
1372
1373static int snd_cs4231_free(struct snd_cs4231 *chip)
1374{
1375 release_and_free_resource(chip->res_port);
1376 release_and_free_resource(chip->res_cport);
1377 if (chip->irq >= 0) {
1378 disable_irq(chip->irq);
1379 if (!(chip->hwshare & CS4231_HWSHARE_IRQ))
1380 free_irq(chip->irq, (void *) chip);
1381 }
1382 if (!(chip->hwshare & CS4231_HWSHARE_DMA1) && chip->dma1 >= 0) {
1383 snd_dma_disable(chip->dma1);
1384 free_dma(chip->dma1);
1385 }
1386 if (!(chip->hwshare & CS4231_HWSHARE_DMA2) && chip->dma2 >= 0 && chip->dma2 != chip->dma1) {
1387 snd_dma_disable(chip->dma2);
1388 free_dma(chip->dma2);
1389 }
1390 if (chip->timer)
1391 snd_device_free(chip->card, chip->timer);
1392 kfree(chip);
1393 return 0;
1394}
1395
1396static int snd_cs4231_dev_free(struct snd_device *device)
1397{
1398 struct snd_cs4231 *chip = device->device_data;
1399 return snd_cs4231_free(chip);
1400}
1401
1402const char *snd_cs4231_chip_id(struct snd_cs4231 *chip)
1403{
1404 switch (chip->hardware) {
1405 case CS4231_HW_CS4231: return "CS4231";
1406 case CS4231_HW_CS4231A: return "CS4231A";
1407 case CS4231_HW_CS4232: return "CS4232";
1408 case CS4231_HW_CS4232A: return "CS4232A";
1409 case CS4231_HW_CS4235: return "CS4235";
1410 case CS4231_HW_CS4236: return "CS4236";
1411 case CS4231_HW_CS4236B: return "CS4236B";
1412 case CS4231_HW_CS4237B: return "CS4237B";
1413 case CS4231_HW_CS4238B: return "CS4238B";
1414 case CS4231_HW_CS4239: return "CS4239";
1415 case CS4231_HW_INTERWAVE: return "AMD InterWave";
1416 case CS4231_HW_OPL3SA2: return chip->card->shortname;
1417 case CS4231_HW_AD1845: return "AD1845";
1418 case CS4231_HW_OPTI93X: return "OPTi 93x";
1419 default: return "???";
1420 }
1421}
1422
1423static int snd_cs4231_new(struct snd_card *card,
1424 unsigned short hardware,
1425 unsigned short hwshare,
1426 struct snd_cs4231 ** rchip)
1427{
1428 struct snd_cs4231 *chip;
1429
1430 *rchip = NULL;
1431 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
1432 if (chip == NULL)
1433 return -ENOMEM;
1434 chip->hardware = hardware;
1435 chip->hwshare = hwshare;
1436
1437 spin_lock_init(&chip->reg_lock);
1438 mutex_init(&chip->mce_mutex);
1439 mutex_init(&chip->open_mutex);
1440 chip->card = card;
1441 chip->rate_constraint = snd_cs4231_xrate;
1442 chip->set_playback_format = snd_cs4231_playback_format;
1443 chip->set_capture_format = snd_cs4231_capture_format;
1444 if (chip->hardware == CS4231_HW_OPTI93X)
1445 memcpy(&chip->image, &snd_opti93x_original_image,
1446 sizeof(snd_opti93x_original_image));
1447 else
1448 memcpy(&chip->image, &snd_cs4231_original_image,
1449 sizeof(snd_cs4231_original_image));
1450
1451 *rchip = chip;
1452 return 0;
1453}
1454
1455int snd_cs4231_create(struct snd_card *card,
1456 unsigned long port,
1457 unsigned long cport,
1458 int irq, int dma1, int dma2,
1459 unsigned short hardware,
1460 unsigned short hwshare,
1461 struct snd_cs4231 ** rchip)
1462{
1463 static struct snd_device_ops ops = {
1464 .dev_free = snd_cs4231_dev_free,
1465 };
1466 struct snd_cs4231 *chip;
1467 int err;
1468
1469 err = snd_cs4231_new(card, hardware, hwshare, &chip);
1470 if (err < 0)
1471 return err;
1472
1473 chip->irq = -1;
1474 chip->dma1 = -1;
1475 chip->dma2 = -1;
1476
1477 if ((chip->res_port = request_region(port, 4, "CS4231")) == NULL) {
1478 snd_printk(KERN_ERR "cs4231: can't grab port 0x%lx\n", port);
1479 snd_cs4231_free(chip);
1480 return -EBUSY;
1481 }
1482 chip->port = port;
1483 if ((long)cport >= 0 && (chip->res_cport = request_region(cport, 8, "CS4232 Control")) == NULL) {
1484 snd_printk(KERN_ERR "cs4231: can't grab control port 0x%lx\n", cport);
1485 snd_cs4231_free(chip);
1486 return -ENODEV;
1487 }
1488 chip->cport = cport;
1489 if (!(hwshare & CS4231_HWSHARE_IRQ) && request_irq(irq, snd_cs4231_interrupt, IRQF_DISABLED, "CS4231", (void *) chip)) {
1490 snd_printk(KERN_ERR "cs4231: can't grab IRQ %d\n", irq);
1491 snd_cs4231_free(chip);
1492 return -EBUSY;
1493 }
1494 chip->irq = irq;
1495 if (!(hwshare & CS4231_HWSHARE_DMA1) && request_dma(dma1, "CS4231 - 1")) {
1496 snd_printk(KERN_ERR "cs4231: can't grab DMA1 %d\n", dma1);
1497 snd_cs4231_free(chip);
1498 return -EBUSY;
1499 }
1500 chip->dma1 = dma1;
1501 if (!(hwshare & CS4231_HWSHARE_DMA2) && dma1 != dma2 && dma2 >= 0 && request_dma(dma2, "CS4231 - 2")) {
1502 snd_printk(KERN_ERR "cs4231: can't grab DMA2 %d\n", dma2);
1503 snd_cs4231_free(chip);
1504 return -EBUSY;
1505 }
1506 if (dma1 == dma2 || dma2 < 0) {
1507 chip->single_dma = 1;
1508 chip->dma2 = chip->dma1;
1509 } else
1510 chip->dma2 = dma2;
1511
1512 /* global setup */
1513 if (snd_cs4231_probe(chip) < 0) {
1514 snd_cs4231_free(chip);
1515 return -ENODEV;
1516 }
1517 snd_cs4231_init(chip);
1518
1519#if 0
1520 if (chip->hardware & CS4231_HW_CS4232_MASK) {
1521 if (chip->res_cport == NULL)
1522 snd_printk("CS4232 control port features are not accessible\n");
1523 }
1524#endif
1525
1526 /* Register device */
1527 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
1528 snd_cs4231_free(chip);
1529 return err;
1530 }
1531
1532#ifdef CONFIG_PM
1533 /* Power Management */
1534 chip->suspend = snd_cs4231_suspend;
1535 chip->resume = snd_cs4231_resume;
1536#endif
1537
1538 *rchip = chip;
1539 return 0;
1540}
1541
1542static struct snd_pcm_ops snd_cs4231_playback_ops = {
1543 .open = snd_cs4231_playback_open,
1544 .close = snd_cs4231_playback_close,
1545 .ioctl = snd_pcm_lib_ioctl,
1546 .hw_params = snd_cs4231_playback_hw_params,
1547 .hw_free = snd_cs4231_playback_hw_free,
1548 .prepare = snd_cs4231_playback_prepare,
1549 .trigger = snd_cs4231_trigger,
1550 .pointer = snd_cs4231_playback_pointer,
1551};
1552
1553static struct snd_pcm_ops snd_cs4231_capture_ops = {
1554 .open = snd_cs4231_capture_open,
1555 .close = snd_cs4231_capture_close,
1556 .ioctl = snd_pcm_lib_ioctl,
1557 .hw_params = snd_cs4231_capture_hw_params,
1558 .hw_free = snd_cs4231_capture_hw_free,
1559 .prepare = snd_cs4231_capture_prepare,
1560 .trigger = snd_cs4231_trigger,
1561 .pointer = snd_cs4231_capture_pointer,
1562};
1563
1564int snd_cs4231_pcm(struct snd_cs4231 *chip, int device, struct snd_pcm **rpcm)
1565{
1566 struct snd_pcm *pcm;
1567 int err;
1568
1569 if ((err = snd_pcm_new(chip->card, "CS4231", device, 1, 1, &pcm)) < 0)
1570 return err;
1571
1572 spin_lock_init(&chip->reg_lock);
1573 mutex_init(&chip->mce_mutex);
1574 mutex_init(&chip->open_mutex);
1575
1576 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs4231_playback_ops);
1577 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cs4231_capture_ops);
1578
1579 /* global setup */
1580 pcm->private_data = chip;
1581 pcm->info_flags = 0;
1582 if (chip->single_dma)
1583 pcm->info_flags |= SNDRV_PCM_INFO_HALF_DUPLEX;
1584 if (chip->hardware != CS4231_HW_INTERWAVE)
1585 pcm->info_flags |= SNDRV_PCM_INFO_JOINT_DUPLEX;
1586 strcpy(pcm->name, snd_cs4231_chip_id(chip));
1587
1588 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1589 snd_dma_isa_data(),
1590 64*1024, chip->dma1 > 3 || chip->dma2 > 3 ? 128*1024 : 64*1024);
1591
1592 chip->pcm = pcm;
1593 if (rpcm)
1594 *rpcm = pcm;
1595 return 0;
1596}
1597
1598static void snd_cs4231_timer_free(struct snd_timer *timer)
1599{
1600 struct snd_cs4231 *chip = timer->private_data;
1601 chip->timer = NULL;
1602}
1603
1604int snd_cs4231_timer(struct snd_cs4231 *chip, int device, struct snd_timer **rtimer)
1605{
1606 struct snd_timer *timer;
1607 struct snd_timer_id tid;
1608 int err;
1609
1610 /* Timer initialization */
1611 tid.dev_class = SNDRV_TIMER_CLASS_CARD;
1612 tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
1613 tid.card = chip->card->number;
1614 tid.device = device;
1615 tid.subdevice = 0;
1616 if ((err = snd_timer_new(chip->card, "CS4231", &tid, &timer)) < 0)
1617 return err;
1618 strcpy(timer->name, snd_cs4231_chip_id(chip));
1619 timer->private_data = chip;
1620 timer->private_free = snd_cs4231_timer_free;
1621 timer->hw = snd_cs4231_timer_table;
1622 chip->timer = timer;
1623 if (rtimer)
1624 *rtimer = timer;
1625 return 0;
1626}
1627
1628/*
1629 * MIXER part
1630 */
1631
1632static int snd_cs4231_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1633{
1634 static char *texts[4] = {
1635 "Line", "Aux", "Mic", "Mix"
1636 };
1637 static char *opl3sa_texts[4] = {
1638 "Line", "CD", "Mic", "Mix"
1639 };
1640 static char *gusmax_texts[4] = {
1641 "Line", "Synth", "Mic", "Mix"
1642 };
1643 char **ptexts = texts;
1644 struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
1645
1646 snd_assert(chip->card != NULL, return -EINVAL);
1647 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1648 uinfo->count = 2;
1649 uinfo->value.enumerated.items = 4;
1650 if (uinfo->value.enumerated.item > 3)
1651 uinfo->value.enumerated.item = 3;
1652 if (!strcmp(chip->card->driver, "GUS MAX"))
1653 ptexts = gusmax_texts;
1654 switch (chip->hardware) {
1655 case CS4231_HW_INTERWAVE: ptexts = gusmax_texts; break;
1656 case CS4231_HW_OPL3SA2: ptexts = opl3sa_texts; break;
1657 }
1658 strcpy(uinfo->value.enumerated.name, ptexts[uinfo->value.enumerated.item]);
1659 return 0;
1660}
1661
1662static int snd_cs4231_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1663{
1664 struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
1665 unsigned long flags;
1666
1667 spin_lock_irqsave(&chip->reg_lock, flags);
1668 ucontrol->value.enumerated.item[0] = (chip->image[CS4231_LEFT_INPUT] & CS4231_MIXS_ALL) >> 6;
1669 ucontrol->value.enumerated.item[1] = (chip->image[CS4231_RIGHT_INPUT] & CS4231_MIXS_ALL) >> 6;
1670 spin_unlock_irqrestore(&chip->reg_lock, flags);
1671 return 0;
1672}
1673
1674static int snd_cs4231_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1675{
1676 struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
1677 unsigned long flags;
1678 unsigned short left, right;
1679 int change;
1680
1681 if (ucontrol->value.enumerated.item[0] > 3 ||
1682 ucontrol->value.enumerated.item[1] > 3)
1683 return -EINVAL;
1684 left = ucontrol->value.enumerated.item[0] << 6;
1685 right = ucontrol->value.enumerated.item[1] << 6;
1686 spin_lock_irqsave(&chip->reg_lock, flags);
1687 left = (chip->image[CS4231_LEFT_INPUT] & ~CS4231_MIXS_ALL) | left;
1688 right = (chip->image[CS4231_RIGHT_INPUT] & ~CS4231_MIXS_ALL) | right;
1689 change = left != chip->image[CS4231_LEFT_INPUT] ||
1690 right != chip->image[CS4231_RIGHT_INPUT];
1691 snd_cs4231_out(chip, CS4231_LEFT_INPUT, left);
1692 snd_cs4231_out(chip, CS4231_RIGHT_INPUT, right);
1693 spin_unlock_irqrestore(&chip->reg_lock, flags);
1694 return change;
1695}
1696
1697int snd_cs4231_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1698{
1699 int mask = (kcontrol->private_value >> 16) & 0xff;
1700
1701 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
1702 uinfo->count = 1;
1703 uinfo->value.integer.min = 0;
1704 uinfo->value.integer.max = mask;
1705 return 0;
1706}
1707
1708int snd_cs4231_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1709{
1710 struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
1711 unsigned long flags;
1712 int reg = kcontrol->private_value & 0xff;
1713 int shift = (kcontrol->private_value >> 8) & 0xff;
1714 int mask = (kcontrol->private_value >> 16) & 0xff;
1715 int invert = (kcontrol->private_value >> 24) & 0xff;
1716
1717 spin_lock_irqsave(&chip->reg_lock, flags);
1718 ucontrol->value.integer.value[0] = (chip->image[reg] >> shift) & mask;
1719 spin_unlock_irqrestore(&chip->reg_lock, flags);
1720 if (invert)
1721 ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
1722 return 0;
1723}
1724
1725int snd_cs4231_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1726{
1727 struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
1728 unsigned long flags;
1729 int reg = kcontrol->private_value & 0xff;
1730 int shift = (kcontrol->private_value >> 8) & 0xff;
1731 int mask = (kcontrol->private_value >> 16) & 0xff;
1732 int invert = (kcontrol->private_value >> 24) & 0xff;
1733 int change;
1734 unsigned short val;
1735
1736 val = (ucontrol->value.integer.value[0] & mask);
1737 if (invert)
1738 val = mask - val;
1739 val <<= shift;
1740 spin_lock_irqsave(&chip->reg_lock, flags);
1741 val = (chip->image[reg] & ~(mask << shift)) | val;
1742 change = val != chip->image[reg];
1743 snd_cs4231_out(chip, reg, val);
1744 spin_unlock_irqrestore(&chip->reg_lock, flags);
1745 return change;
1746}
1747
1748int snd_cs4231_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1749{
1750 int mask = (kcontrol->private_value >> 24) & 0xff;
1751
1752 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
1753 uinfo->count = 2;
1754 uinfo->value.integer.min = 0;
1755 uinfo->value.integer.max = mask;
1756 return 0;
1757}
1758
1759int snd_cs4231_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1760{
1761 struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
1762 unsigned long flags;
1763 int left_reg = kcontrol->private_value & 0xff;
1764 int right_reg = (kcontrol->private_value >> 8) & 0xff;
1765 int shift_left = (kcontrol->private_value >> 16) & 0x07;
1766 int shift_right = (kcontrol->private_value >> 19) & 0x07;
1767 int mask = (kcontrol->private_value >> 24) & 0xff;
1768 int invert = (kcontrol->private_value >> 22) & 1;
1769
1770 spin_lock_irqsave(&chip->reg_lock, flags);
1771 ucontrol->value.integer.value[0] = (chip->image[left_reg] >> shift_left) & mask;
1772 ucontrol->value.integer.value[1] = (chip->image[right_reg] >> shift_right) & mask;
1773 spin_unlock_irqrestore(&chip->reg_lock, flags);
1774 if (invert) {
1775 ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
1776 ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1];
1777 }
1778 return 0;
1779}
1780
1781int snd_cs4231_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1782{
1783 struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
1784 unsigned long flags;
1785 int left_reg = kcontrol->private_value & 0xff;
1786 int right_reg = (kcontrol->private_value >> 8) & 0xff;
1787 int shift_left = (kcontrol->private_value >> 16) & 0x07;
1788 int shift_right = (kcontrol->private_value >> 19) & 0x07;
1789 int mask = (kcontrol->private_value >> 24) & 0xff;
1790 int invert = (kcontrol->private_value >> 22) & 1;
1791 int change;
1792 unsigned short val1, val2;
1793
1794 val1 = ucontrol->value.integer.value[0] & mask;
1795 val2 = ucontrol->value.integer.value[1] & mask;
1796 if (invert) {
1797 val1 = mask - val1;
1798 val2 = mask - val2;
1799 }
1800 val1 <<= shift_left;
1801 val2 <<= shift_right;
1802 spin_lock_irqsave(&chip->reg_lock, flags);
1803 val1 = (chip->image[left_reg] & ~(mask << shift_left)) | val1;
1804 val2 = (chip->image[right_reg] & ~(mask << shift_right)) | val2;
1805 change = val1 != chip->image[left_reg] || val2 != chip->image[right_reg];
1806 snd_cs4231_out(chip, left_reg, val1);
1807 snd_cs4231_out(chip, right_reg, val2);
1808 spin_unlock_irqrestore(&chip->reg_lock, flags);
1809 return change;
1810}
1811
1812static struct snd_kcontrol_new snd_cs4231_controls[] = {
1813CS4231_DOUBLE("PCM Playback Switch", 0, CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1),
1814CS4231_DOUBLE("PCM Playback Volume", 0, CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1),
1815CS4231_DOUBLE("Line Playback Switch", 0, CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
1816CS4231_DOUBLE("Line Playback Volume", 0, CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1),
1817CS4231_DOUBLE("Aux Playback Switch", 0, CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1),
1818CS4231_DOUBLE("Aux Playback Volume", 0, CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1),
1819CS4231_DOUBLE("Aux Playback Switch", 1, CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
1820CS4231_DOUBLE("Aux Playback Volume", 1, CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1),
1821CS4231_SINGLE("Mono Playback Switch", 0, CS4231_MONO_CTRL, 7, 1, 1),
1822CS4231_SINGLE("Mono Playback Volume", 0, CS4231_MONO_CTRL, 0, 15, 1),
1823CS4231_SINGLE("Mono Output Playback Switch", 0, CS4231_MONO_CTRL, 6, 1, 1),
1824CS4231_SINGLE("Mono Output Playback Bypass", 0, CS4231_MONO_CTRL, 5, 1, 0),
1825CS4231_DOUBLE("Capture Volume", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 0, 0, 15, 0),
1826{
1827 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1828 .name = "Capture Source",
1829 .info = snd_cs4231_info_mux,
1830 .get = snd_cs4231_get_mux,
1831 .put = snd_cs4231_put_mux,
1832},
1833CS4231_DOUBLE("Mic Boost", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 5, 5, 1, 0),
1834CS4231_SINGLE("Loopback Capture Switch", 0, CS4231_LOOPBACK, 0, 1, 0),
1835CS4231_SINGLE("Loopback Capture Volume", 0, CS4231_LOOPBACK, 2, 63, 1)
1836};
1837
1838static struct snd_kcontrol_new snd_opti93x_controls[] = {
1839CS4231_DOUBLE("Master Playback Switch", 0,
1840 OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 7, 7, 1, 1),
1841CS4231_DOUBLE("Master Playback Volume", 0,
1842 OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 1, 1, 31, 1),
1843CS4231_DOUBLE("PCM Playback Switch", 0,
1844 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1),
1845CS4231_DOUBLE("PCM Playback Volume", 0,
1846 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 31, 1),
1847CS4231_DOUBLE("FM Playback Switch", 0,
1848 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
1849CS4231_DOUBLE("FM Playback Volume", 0,
1850 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 1, 1, 15, 1),
1851CS4231_DOUBLE("Line Playback Switch", 0,
1852 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
1853CS4231_DOUBLE("Line Playback Volume", 0,
1854 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 15, 1),
1855CS4231_DOUBLE("Mic Playback Switch", 0,
1856 OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 7, 7, 1, 1),
1857CS4231_DOUBLE("Mic Playback Volume", 0,
1858 OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 1, 1, 15, 1),
1859CS4231_DOUBLE("Mic Boost", 0,
1860 CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 5, 5, 1, 0),
1861CS4231_DOUBLE("CD Playback Switch", 0,
1862 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1),
1863CS4231_DOUBLE("CD Playback Volume", 0,
1864 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 1, 1, 15, 1),
1865CS4231_DOUBLE("Aux Playback Switch", 0,
1866 OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 7, 7, 1, 1),
1867CS4231_DOUBLE("Aux Playback Volume", 0,
1868 OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 1, 1, 15, 1),
1869CS4231_DOUBLE("Capture Volume", 0,
1870 CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 0, 0, 15, 0),
1871{
1872 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1873 .name = "Capture Source",
1874 .info = snd_cs4231_info_mux,
1875 .get = snd_cs4231_get_mux,
1876 .put = snd_cs4231_put_mux,
1877}
1878};
1879
1880int snd_cs4231_mixer(struct snd_cs4231 *chip)
1881{
1882 struct snd_card *card;
1883 unsigned int idx;
1884 int err;
1885
1886 snd_assert(chip != NULL && chip->pcm != NULL, return -EINVAL);
1887
1888 card = chip->card;
1889
1890 strcpy(card->mixername, chip->pcm->name);
1891
1892 if (chip->hardware == CS4231_HW_OPTI93X)
1893 for (idx = 0; idx < ARRAY_SIZE(snd_opti93x_controls); idx++) {
1894 err = snd_ctl_add(card,
1895 snd_ctl_new1(&snd_opti93x_controls[idx],
1896 chip));
1897 if (err < 0)
1898 return err;
1899 }
1900 else
1901 for (idx = 0; idx < ARRAY_SIZE(snd_cs4231_controls); idx++) {
1902 err = snd_ctl_add(card,
1903 snd_ctl_new1(&snd_cs4231_controls[idx],
1904 chip));
1905 if (err < 0)
1906 return err;
1907 }
1908 return 0;
1909}
1910
1911EXPORT_SYMBOL(snd_cs4231_out);
1912EXPORT_SYMBOL(snd_cs4231_in);
1913EXPORT_SYMBOL(snd_cs4236_ext_out);
1914EXPORT_SYMBOL(snd_cs4236_ext_in);
1915EXPORT_SYMBOL(snd_cs4231_mce_up);
1916EXPORT_SYMBOL(snd_cs4231_mce_down);
1917EXPORT_SYMBOL(snd_cs4231_overrange);
1918EXPORT_SYMBOL(snd_cs4231_interrupt);
1919EXPORT_SYMBOL(snd_cs4231_chip_id);
1920EXPORT_SYMBOL(snd_cs4231_create);
1921EXPORT_SYMBOL(snd_cs4231_pcm);
1922EXPORT_SYMBOL(snd_cs4231_mixer);
1923EXPORT_SYMBOL(snd_cs4231_timer);
1924EXPORT_SYMBOL(snd_cs4231_info_single);
1925EXPORT_SYMBOL(snd_cs4231_get_single);
1926EXPORT_SYMBOL(snd_cs4231_put_single);
1927EXPORT_SYMBOL(snd_cs4231_info_double);
1928EXPORT_SYMBOL(snd_cs4231_get_double);
1929EXPORT_SYMBOL(snd_cs4231_put_double);
1930
1931/*
1932 * INIT part
1933 */
1934
1935static int __init alsa_cs4231_init(void)
1936{
1937 return 0;
1938}
1939
1940static void __exit alsa_cs4231_exit(void)
1941{
1942}
1943
1944module_init(alsa_cs4231_init)
1945module_exit(alsa_cs4231_exit)
diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c
index 4d4b8ddc26ba..91f9c15d3e30 100644
--- a/sound/isa/cs423x/cs4236.c
+++ b/sound/isa/cs423x/cs4236.c
@@ -26,7 +26,7 @@
26#include <linux/pnp.h> 26#include <linux/pnp.h>
27#include <linux/moduleparam.h> 27#include <linux/moduleparam.h>
28#include <sound/core.h> 28#include <sound/core.h>
29#include <sound/cs4231.h> 29#include <sound/wss.h>
30#include <sound/mpu401.h> 30#include <sound/mpu401.h>
31#include <sound/opl3.h> 31#include <sound/opl3.h>
32#include <sound/initval.h> 32#include <sound/initval.h>
@@ -134,7 +134,7 @@ static int pnp_registered;
134#endif /* CONFIG_PNP */ 134#endif /* CONFIG_PNP */
135 135
136struct snd_card_cs4236 { 136struct snd_card_cs4236 {
137 struct snd_cs4231 *chip; 137 struct snd_wss *chip;
138 struct resource *res_sb_port; 138 struct resource *res_sb_port;
139#ifdef CONFIG_PNP 139#ifdef CONFIG_PNP
140 struct pnp_dev *wss; 140 struct pnp_dev *wss;
@@ -239,6 +239,8 @@ static struct pnp_card_device_id snd_cs423x_pnpids[] = {
239 { .id = "CSC9836", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } }, 239 { .id = "CSC9836", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } },
240 /* Gallant SC-70P */ 240 /* Gallant SC-70P */
241 { .id = "CSC9837", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } }, 241 { .id = "CSC9837", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } },
242 /* Techmakers MF-4236PW */
243 { .id = "CSCa736", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } },
242 /* TerraTec AudioSystem EWS64XL - CS4236B */ 244 /* TerraTec AudioSystem EWS64XL - CS4236B */
243 { .id = "CSCa836", .devs = { { "CSCa800" }, { "CSCa810" }, { "CSCa803" } } }, 245 { .id = "CSCa836", .devs = { { "CSCa800" }, { "CSCa810" }, { "CSCa803" } } },
244 /* TerraTec AudioSystem EWS64XL - CS4236B */ 246 /* TerraTec AudioSystem EWS64XL - CS4236B */
@@ -396,7 +398,7 @@ static int __devinit snd_cs423x_probe(struct snd_card *card, int dev)
396{ 398{
397 struct snd_card_cs4236 *acard; 399 struct snd_card_cs4236 *acard;
398 struct snd_pcm *pcm; 400 struct snd_pcm *pcm;
399 struct snd_cs4231 *chip; 401 struct snd_wss *chip;
400 struct snd_opl3 *opl3; 402 struct snd_opl3 *opl3;
401 int err; 403 int err;
402 404
@@ -408,41 +410,37 @@ static int __devinit snd_cs423x_probe(struct snd_card *card, int dev)
408 } 410 }
409 411
410#ifdef CS4232 412#ifdef CS4232
411 if ((err = snd_cs4231_create(card, 413 err = snd_wss_create(card, port[dev], cport[dev],
412 port[dev], 414 irq[dev],
413 cport[dev], 415 dma1[dev], dma2[dev],
414 irq[dev], 416 WSS_HW_DETECT, 0, &chip);
415 dma1[dev], 417 if (err < 0)
416 dma2[dev],
417 CS4231_HW_DETECT,
418 0,
419 &chip)) < 0)
420 return err; 418 return err;
421 acard->chip = chip; 419 acard->chip = chip;
422 420
423 if ((err = snd_cs4231_pcm(chip, 0, &pcm)) < 0) 421 err = snd_wss_pcm(chip, 0, &pcm);
422 if (err < 0)
424 return err; 423 return err;
425 424
426 if ((err = snd_cs4231_mixer(chip)) < 0) 425 err = snd_wss_mixer(chip);
426 if (err < 0)
427 return err; 427 return err;
428 428
429#else /* CS4236 */ 429#else /* CS4236 */
430 if ((err = snd_cs4236_create(card, 430 err = snd_cs4236_create(card,
431 port[dev], 431 port[dev], cport[dev],
432 cport[dev], 432 irq[dev], dma1[dev], dma2[dev],
433 irq[dev], 433 WSS_HW_DETECT, 0, &chip);
434 dma1[dev], 434 if (err < 0)
435 dma2[dev],
436 CS4231_HW_DETECT,
437 0,
438 &chip)) < 0)
439 return err; 435 return err;
440 acard->chip = chip; 436 acard->chip = chip;
441 437
442 if ((err = snd_cs4236_pcm(chip, 0, &pcm)) < 0) 438 err = snd_cs4236_pcm(chip, 0, &pcm);
439 if (err < 0)
443 return err; 440 return err;
444 441
445 if ((err = snd_cs4236_mixer(chip)) < 0) 442 err = snd_cs4236_mixer(chip);
443 if (err < 0)
446 return err; 444 return err;
447#endif 445#endif
448 strcpy(card->driver, pcm->name); 446 strcpy(card->driver, pcm->name);
@@ -455,7 +453,8 @@ static int __devinit snd_cs423x_probe(struct snd_card *card, int dev)
455 if (dma2[dev] >= 0) 453 if (dma2[dev] >= 0)
456 sprintf(card->longname + strlen(card->longname), "&%d", dma2[dev]); 454 sprintf(card->longname + strlen(card->longname), "&%d", dma2[dev]);
457 455
458 if ((err = snd_cs4231_timer(chip, 0, NULL)) < 0) 456 err = snd_wss_timer(chip, 0, NULL);
457 if (err < 0)
459 return err; 458 return err;
460 459
461 if (fm_port[dev] > 0 && fm_port[dev] != SNDRV_AUTO_PORT) { 460 if (fm_port[dev] > 0 && fm_port[dev] != SNDRV_AUTO_PORT) {
diff --git a/sound/isa/cs423x/cs4236_lib.c b/sound/isa/cs423x/cs4236_lib.c
index de71910401ea..6a85fdc53b60 100644
--- a/sound/isa/cs423x/cs4236_lib.c
+++ b/sound/isa/cs423x/cs4236_lib.c
@@ -85,7 +85,7 @@
85#include <linux/time.h> 85#include <linux/time.h>
86#include <linux/wait.h> 86#include <linux/wait.h>
87#include <sound/core.h> 87#include <sound/core.h>
88#include <sound/cs4231.h> 88#include <sound/wss.h>
89#include <sound/asoundef.h> 89#include <sound/asoundef.h>
90 90
91MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); 91MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
@@ -121,13 +121,14 @@ static unsigned char snd_cs4236_ext_map[18] = {
121 * 121 *
122 */ 122 */
123 123
124static void snd_cs4236_ctrl_out(struct snd_cs4231 *chip, unsigned char reg, unsigned char val) 124static void snd_cs4236_ctrl_out(struct snd_wss *chip,
125 unsigned char reg, unsigned char val)
125{ 126{
126 outb(reg, chip->cport + 3); 127 outb(reg, chip->cport + 3);
127 outb(chip->cimage[reg] = val, chip->cport + 4); 128 outb(chip->cimage[reg] = val, chip->cport + 4);
128} 129}
129 130
130static unsigned char snd_cs4236_ctrl_in(struct snd_cs4231 *chip, unsigned char reg) 131static unsigned char snd_cs4236_ctrl_in(struct snd_wss *chip, unsigned char reg)
131{ 132{
132 outb(reg, chip->cport + 3); 133 outb(reg, chip->cport + 3);
133 return inb(chip->cport + 4); 134 return inb(chip->cport + 4);
@@ -180,44 +181,52 @@ static unsigned char divisor_to_rate_register(unsigned int divisor)
180 } 181 }
181} 182}
182 183
183static void snd_cs4236_playback_format(struct snd_cs4231 *chip, struct snd_pcm_hw_params *params, unsigned char pdfr) 184static void snd_cs4236_playback_format(struct snd_wss *chip,
185 struct snd_pcm_hw_params *params,
186 unsigned char pdfr)
184{ 187{
185 unsigned long flags; 188 unsigned long flags;
186 unsigned char rate = divisor_to_rate_register(params->rate_den); 189 unsigned char rate = divisor_to_rate_register(params->rate_den);
187 190
188 spin_lock_irqsave(&chip->reg_lock, flags); 191 spin_lock_irqsave(&chip->reg_lock, flags);
189 /* set fast playback format change and clean playback FIFO */ 192 /* set fast playback format change and clean playback FIFO */
190 snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1] | 0x10); 193 snd_wss_out(chip, CS4231_ALT_FEATURE_1,
191 snd_cs4231_out(chip, CS4231_PLAYBK_FORMAT, pdfr & 0xf0); 194 chip->image[CS4231_ALT_FEATURE_1] | 0x10);
192 snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1] & ~0x10); 195 snd_wss_out(chip, CS4231_PLAYBK_FORMAT, pdfr & 0xf0);
196 snd_wss_out(chip, CS4231_ALT_FEATURE_1,
197 chip->image[CS4231_ALT_FEATURE_1] & ~0x10);
193 snd_cs4236_ext_out(chip, CS4236_DAC_RATE, rate); 198 snd_cs4236_ext_out(chip, CS4236_DAC_RATE, rate);
194 spin_unlock_irqrestore(&chip->reg_lock, flags); 199 spin_unlock_irqrestore(&chip->reg_lock, flags);
195} 200}
196 201
197static void snd_cs4236_capture_format(struct snd_cs4231 *chip, struct snd_pcm_hw_params *params, unsigned char cdfr) 202static void snd_cs4236_capture_format(struct snd_wss *chip,
203 struct snd_pcm_hw_params *params,
204 unsigned char cdfr)
198{ 205{
199 unsigned long flags; 206 unsigned long flags;
200 unsigned char rate = divisor_to_rate_register(params->rate_den); 207 unsigned char rate = divisor_to_rate_register(params->rate_den);
201 208
202 spin_lock_irqsave(&chip->reg_lock, flags); 209 spin_lock_irqsave(&chip->reg_lock, flags);
203 /* set fast capture format change and clean capture FIFO */ 210 /* set fast capture format change and clean capture FIFO */
204 snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1] | 0x20); 211 snd_wss_out(chip, CS4231_ALT_FEATURE_1,
205 snd_cs4231_out(chip, CS4231_REC_FORMAT, cdfr & 0xf0); 212 chip->image[CS4231_ALT_FEATURE_1] | 0x20);
206 snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1] & ~0x20); 213 snd_wss_out(chip, CS4231_REC_FORMAT, cdfr & 0xf0);
214 snd_wss_out(chip, CS4231_ALT_FEATURE_1,
215 chip->image[CS4231_ALT_FEATURE_1] & ~0x20);
207 snd_cs4236_ext_out(chip, CS4236_ADC_RATE, rate); 216 snd_cs4236_ext_out(chip, CS4236_ADC_RATE, rate);
208 spin_unlock_irqrestore(&chip->reg_lock, flags); 217 spin_unlock_irqrestore(&chip->reg_lock, flags);
209} 218}
210 219
211#ifdef CONFIG_PM 220#ifdef CONFIG_PM
212 221
213static void snd_cs4236_suspend(struct snd_cs4231 *chip) 222static void snd_cs4236_suspend(struct snd_wss *chip)
214{ 223{
215 int reg; 224 int reg;
216 unsigned long flags; 225 unsigned long flags;
217 226
218 spin_lock_irqsave(&chip->reg_lock, flags); 227 spin_lock_irqsave(&chip->reg_lock, flags);
219 for (reg = 0; reg < 32; reg++) 228 for (reg = 0; reg < 32; reg++)
220 chip->image[reg] = snd_cs4231_in(chip, reg); 229 chip->image[reg] = snd_wss_in(chip, reg);
221 for (reg = 0; reg < 18; reg++) 230 for (reg = 0; reg < 18; reg++)
222 chip->eimage[reg] = snd_cs4236_ext_in(chip, CS4236_I23VAL(reg)); 231 chip->eimage[reg] = snd_cs4236_ext_in(chip, CS4236_I23VAL(reg));
223 for (reg = 2; reg < 9; reg++) 232 for (reg = 2; reg < 9; reg++)
@@ -225,12 +234,12 @@ static void snd_cs4236_suspend(struct snd_cs4231 *chip)
225 spin_unlock_irqrestore(&chip->reg_lock, flags); 234 spin_unlock_irqrestore(&chip->reg_lock, flags);
226} 235}
227 236
228static void snd_cs4236_resume(struct snd_cs4231 *chip) 237static void snd_cs4236_resume(struct snd_wss *chip)
229{ 238{
230 int reg; 239 int reg;
231 unsigned long flags; 240 unsigned long flags;
232 241
233 snd_cs4231_mce_up(chip); 242 snd_wss_mce_up(chip);
234 spin_lock_irqsave(&chip->reg_lock, flags); 243 spin_lock_irqsave(&chip->reg_lock, flags);
235 for (reg = 0; reg < 32; reg++) { 244 for (reg = 0; reg < 32; reg++) {
236 switch (reg) { 245 switch (reg) {
@@ -240,7 +249,7 @@ static void snd_cs4236_resume(struct snd_cs4231 *chip)
240 case 29: /* why? CS4235 - master right */ 249 case 29: /* why? CS4235 - master right */
241 break; 250 break;
242 default: 251 default:
243 snd_cs4231_out(chip, reg, chip->image[reg]); 252 snd_wss_out(chip, reg, chip->image[reg]);
244 break; 253 break;
245 } 254 }
246 } 255 }
@@ -255,7 +264,7 @@ static void snd_cs4236_resume(struct snd_cs4231 *chip)
255 } 264 }
256 } 265 }
257 spin_unlock_irqrestore(&chip->reg_lock, flags); 266 spin_unlock_irqrestore(&chip->reg_lock, flags);
258 snd_cs4231_mce_down(chip); 267 snd_wss_mce_down(chip);
259} 268}
260 269
261#endif /* CONFIG_PM */ 270#endif /* CONFIG_PM */
@@ -266,24 +275,26 @@ int snd_cs4236_create(struct snd_card *card,
266 int irq, int dma1, int dma2, 275 int irq, int dma1, int dma2,
267 unsigned short hardware, 276 unsigned short hardware,
268 unsigned short hwshare, 277 unsigned short hwshare,
269 struct snd_cs4231 ** rchip) 278 struct snd_wss **rchip)
270{ 279{
271 struct snd_cs4231 *chip; 280 struct snd_wss *chip;
272 unsigned char ver1, ver2; 281 unsigned char ver1, ver2;
273 unsigned int reg; 282 unsigned int reg;
274 int err; 283 int err;
275 284
276 *rchip = NULL; 285 *rchip = NULL;
277 if (hardware == CS4231_HW_DETECT) 286 if (hardware == WSS_HW_DETECT)
278 hardware = CS4231_HW_DETECT3; 287 hardware = WSS_HW_DETECT3;
279 if (cport < 0x100) { 288 if (cport < 0x100) {
280 snd_printk("please, specify control port for CS4236+ chips\n"); 289 snd_printk("please, specify control port for CS4236+ chips\n");
281 return -ENODEV; 290 return -ENODEV;
282 } 291 }
283 if ((err = snd_cs4231_create(card, port, cport, irq, dma1, dma2, hardware, hwshare, &chip)) < 0) 292 err = snd_wss_create(card, port, cport,
293 irq, dma1, dma2, hardware, hwshare, &chip);
294 if (err < 0)
284 return err; 295 return err;
285 296
286 if (!(chip->hardware & CS4231_HW_CS4236B_MASK)) { 297 if (!(chip->hardware & WSS_HW_CS4236B_MASK)) {
287 snd_printk("CS4236+: MODE3 and extended registers not available, hardware=0x%x\n",chip->hardware); 298 snd_printk("CS4236+: MODE3 and extended registers not available, hardware=0x%x\n",chip->hardware);
288 snd_device_free(card, chip); 299 snd_device_free(card, chip);
289 return -ENODEV; 300 return -ENODEV;
@@ -330,20 +341,20 @@ int snd_cs4236_create(struct snd_card *card,
330 snd_cs4236_ext_out(chip, CS4236_I23VAL(reg), snd_cs4236_ext_map[reg]); 341 snd_cs4236_ext_out(chip, CS4236_I23VAL(reg), snd_cs4236_ext_map[reg]);
331 342
332 /* initialize compatible but more featured registers */ 343 /* initialize compatible but more featured registers */
333 snd_cs4231_out(chip, CS4231_LEFT_INPUT, 0x40); 344 snd_wss_out(chip, CS4231_LEFT_INPUT, 0x40);
334 snd_cs4231_out(chip, CS4231_RIGHT_INPUT, 0x40); 345 snd_wss_out(chip, CS4231_RIGHT_INPUT, 0x40);
335 snd_cs4231_out(chip, CS4231_AUX1_LEFT_INPUT, 0xff); 346 snd_wss_out(chip, CS4231_AUX1_LEFT_INPUT, 0xff);
336 snd_cs4231_out(chip, CS4231_AUX1_RIGHT_INPUT, 0xff); 347 snd_wss_out(chip, CS4231_AUX1_RIGHT_INPUT, 0xff);
337 snd_cs4231_out(chip, CS4231_AUX2_LEFT_INPUT, 0xdf); 348 snd_wss_out(chip, CS4231_AUX2_LEFT_INPUT, 0xdf);
338 snd_cs4231_out(chip, CS4231_AUX2_RIGHT_INPUT, 0xdf); 349 snd_wss_out(chip, CS4231_AUX2_RIGHT_INPUT, 0xdf);
339 snd_cs4231_out(chip, CS4231_RIGHT_LINE_IN, 0xff); 350 snd_wss_out(chip, CS4231_RIGHT_LINE_IN, 0xff);
340 snd_cs4231_out(chip, CS4231_LEFT_LINE_IN, 0xff); 351 snd_wss_out(chip, CS4231_LEFT_LINE_IN, 0xff);
341 snd_cs4231_out(chip, CS4231_RIGHT_LINE_IN, 0xff); 352 snd_wss_out(chip, CS4231_RIGHT_LINE_IN, 0xff);
342 switch (chip->hardware) { 353 switch (chip->hardware) {
343 case CS4231_HW_CS4235: 354 case WSS_HW_CS4235:
344 case CS4231_HW_CS4239: 355 case WSS_HW_CS4239:
345 snd_cs4231_out(chip, CS4235_LEFT_MASTER, 0xff); 356 snd_wss_out(chip, CS4235_LEFT_MASTER, 0xff);
346 snd_cs4231_out(chip, CS4235_RIGHT_MASTER, 0xff); 357 snd_wss_out(chip, CS4235_RIGHT_MASTER, 0xff);
347 break; 358 break;
348 } 359 }
349 360
@@ -351,12 +362,13 @@ int snd_cs4236_create(struct snd_card *card,
351 return 0; 362 return 0;
352} 363}
353 364
354int snd_cs4236_pcm(struct snd_cs4231 *chip, int device, struct snd_pcm **rpcm) 365int snd_cs4236_pcm(struct snd_wss *chip, int device, struct snd_pcm **rpcm)
355{ 366{
356 struct snd_pcm *pcm; 367 struct snd_pcm *pcm;
357 int err; 368 int err;
358 369
359 if ((err = snd_cs4231_pcm(chip, device, &pcm)) < 0) 370 err = snd_wss_pcm(chip, device, &pcm);
371 if (err < 0)
360 return err; 372 return err;
361 pcm->info_flags &= ~SNDRV_PCM_INFO_JOINT_DUPLEX; 373 pcm->info_flags &= ~SNDRV_PCM_INFO_JOINT_DUPLEX;
362 if (rpcm) 374 if (rpcm)
@@ -387,7 +399,7 @@ static int snd_cs4236_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_
387 399
388static int snd_cs4236_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 400static int snd_cs4236_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
389{ 401{
390 struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); 402 struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
391 unsigned long flags; 403 unsigned long flags;
392 int reg = kcontrol->private_value & 0xff; 404 int reg = kcontrol->private_value & 0xff;
393 int shift = (kcontrol->private_value >> 8) & 0xff; 405 int shift = (kcontrol->private_value >> 8) & 0xff;
@@ -404,7 +416,7 @@ static int snd_cs4236_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_e
404 416
405static int snd_cs4236_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 417static int snd_cs4236_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
406{ 418{
407 struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); 419 struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
408 unsigned long flags; 420 unsigned long flags;
409 int reg = kcontrol->private_value & 0xff; 421 int reg = kcontrol->private_value & 0xff;
410 int shift = (kcontrol->private_value >> 8) & 0xff; 422 int shift = (kcontrol->private_value >> 8) & 0xff;
@@ -433,7 +445,7 @@ static int snd_cs4236_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_e
433 445
434static int snd_cs4236_get_singlec(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 446static int snd_cs4236_get_singlec(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
435{ 447{
436 struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); 448 struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
437 unsigned long flags; 449 unsigned long flags;
438 int reg = kcontrol->private_value & 0xff; 450 int reg = kcontrol->private_value & 0xff;
439 int shift = (kcontrol->private_value >> 8) & 0xff; 451 int shift = (kcontrol->private_value >> 8) & 0xff;
@@ -450,7 +462,7 @@ static int snd_cs4236_get_singlec(struct snd_kcontrol *kcontrol, struct snd_ctl_
450 462
451static int snd_cs4236_put_singlec(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 463static int snd_cs4236_put_singlec(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
452{ 464{
453 struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); 465 struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
454 unsigned long flags; 466 unsigned long flags;
455 int reg = kcontrol->private_value & 0xff; 467 int reg = kcontrol->private_value & 0xff;
456 int shift = (kcontrol->private_value >> 8) & 0xff; 468 int shift = (kcontrol->private_value >> 8) & 0xff;
@@ -490,7 +502,7 @@ static int snd_cs4236_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_
490 502
491static int snd_cs4236_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 503static int snd_cs4236_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
492{ 504{
493 struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); 505 struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
494 unsigned long flags; 506 unsigned long flags;
495 int left_reg = kcontrol->private_value & 0xff; 507 int left_reg = kcontrol->private_value & 0xff;
496 int right_reg = (kcontrol->private_value >> 8) & 0xff; 508 int right_reg = (kcontrol->private_value >> 8) & 0xff;
@@ -512,7 +524,7 @@ static int snd_cs4236_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_e
512 524
513static int snd_cs4236_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 525static int snd_cs4236_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
514{ 526{
515 struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); 527 struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
516 unsigned long flags; 528 unsigned long flags;
517 int left_reg = kcontrol->private_value & 0xff; 529 int left_reg = kcontrol->private_value & 0xff;
518 int right_reg = (kcontrol->private_value >> 8) & 0xff; 530 int right_reg = (kcontrol->private_value >> 8) & 0xff;
@@ -555,7 +567,7 @@ static int snd_cs4236_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_e
555 567
556static int snd_cs4236_get_double1(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 568static int snd_cs4236_get_double1(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
557{ 569{
558 struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); 570 struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
559 unsigned long flags; 571 unsigned long flags;
560 int left_reg = kcontrol->private_value & 0xff; 572 int left_reg = kcontrol->private_value & 0xff;
561 int right_reg = (kcontrol->private_value >> 8) & 0xff; 573 int right_reg = (kcontrol->private_value >> 8) & 0xff;
@@ -577,7 +589,7 @@ static int snd_cs4236_get_double1(struct snd_kcontrol *kcontrol, struct snd_ctl_
577 589
578static int snd_cs4236_put_double1(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 590static int snd_cs4236_put_double1(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
579{ 591{
580 struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); 592 struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
581 unsigned long flags; 593 unsigned long flags;
582 int left_reg = kcontrol->private_value & 0xff; 594 int left_reg = kcontrol->private_value & 0xff;
583 int right_reg = (kcontrol->private_value >> 8) & 0xff; 595 int right_reg = (kcontrol->private_value >> 8) & 0xff;
@@ -600,7 +612,7 @@ static int snd_cs4236_put_double1(struct snd_kcontrol *kcontrol, struct snd_ctl_
600 val1 = (chip->image[left_reg] & ~(mask << shift_left)) | val1; 612 val1 = (chip->image[left_reg] & ~(mask << shift_left)) | val1;
601 val2 = (chip->eimage[CS4236_REG(right_reg)] & ~(mask << shift_right)) | val2; 613 val2 = (chip->eimage[CS4236_REG(right_reg)] & ~(mask << shift_right)) | val2;
602 change = val1 != chip->image[left_reg] || val2 != chip->eimage[CS4236_REG(right_reg)]; 614 change = val1 != chip->image[left_reg] || val2 != chip->eimage[CS4236_REG(right_reg)];
603 snd_cs4231_out(chip, left_reg, val1); 615 snd_wss_out(chip, left_reg, val1);
604 snd_cs4236_ext_out(chip, right_reg, val2); 616 snd_cs4236_ext_out(chip, right_reg, val2);
605 spin_unlock_irqrestore(&chip->reg_lock, flags); 617 spin_unlock_irqrestore(&chip->reg_lock, flags);
606 return change; 618 return change;
@@ -619,7 +631,7 @@ static inline int snd_cs4236_mixer_master_digital_invert_volume(int vol)
619 631
620static int snd_cs4236_get_master_digital(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 632static int snd_cs4236_get_master_digital(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
621{ 633{
622 struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); 634 struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
623 unsigned long flags; 635 unsigned long flags;
624 636
625 spin_lock_irqsave(&chip->reg_lock, flags); 637 spin_lock_irqsave(&chip->reg_lock, flags);
@@ -631,7 +643,7 @@ static int snd_cs4236_get_master_digital(struct snd_kcontrol *kcontrol, struct s
631 643
632static int snd_cs4236_put_master_digital(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 644static int snd_cs4236_put_master_digital(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
633{ 645{
634 struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); 646 struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
635 unsigned long flags; 647 unsigned long flags;
636 int change; 648 int change;
637 unsigned short val1, val2; 649 unsigned short val1, val2;
@@ -678,7 +690,7 @@ static inline int snd_cs4235_mixer_output_accu_set_volume(int vol)
678 690
679static int snd_cs4235_get_output_accu(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 691static int snd_cs4235_get_output_accu(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
680{ 692{
681 struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); 693 struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
682 unsigned long flags; 694 unsigned long flags;
683 695
684 spin_lock_irqsave(&chip->reg_lock, flags); 696 spin_lock_irqsave(&chip->reg_lock, flags);
@@ -690,7 +702,7 @@ static int snd_cs4235_get_output_accu(struct snd_kcontrol *kcontrol, struct snd_
690 702
691static int snd_cs4235_put_output_accu(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 703static int snd_cs4235_put_output_accu(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
692{ 704{
693 struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); 705 struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
694 unsigned long flags; 706 unsigned long flags;
695 int change; 707 int change;
696 unsigned short val1, val2; 708 unsigned short val1, val2;
@@ -701,108 +713,160 @@ static int snd_cs4235_put_output_accu(struct snd_kcontrol *kcontrol, struct snd_
701 val1 = (chip->image[CS4235_LEFT_MASTER] & ~(3 << 5)) | val1; 713 val1 = (chip->image[CS4235_LEFT_MASTER] & ~(3 << 5)) | val1;
702 val2 = (chip->image[CS4235_RIGHT_MASTER] & ~(3 << 5)) | val2; 714 val2 = (chip->image[CS4235_RIGHT_MASTER] & ~(3 << 5)) | val2;
703 change = val1 != chip->image[CS4235_LEFT_MASTER] || val2 != chip->image[CS4235_RIGHT_MASTER]; 715 change = val1 != chip->image[CS4235_LEFT_MASTER] || val2 != chip->image[CS4235_RIGHT_MASTER];
704 snd_cs4231_out(chip, CS4235_LEFT_MASTER, val1); 716 snd_wss_out(chip, CS4235_LEFT_MASTER, val1);
705 snd_cs4231_out(chip, CS4235_RIGHT_MASTER, val2); 717 snd_wss_out(chip, CS4235_RIGHT_MASTER, val2);
706 spin_unlock_irqrestore(&chip->reg_lock, flags); 718 spin_unlock_irqrestore(&chip->reg_lock, flags);
707 return change; 719 return change;
708} 720}
709 721
710static struct snd_kcontrol_new snd_cs4236_controls[] = { 722static struct snd_kcontrol_new snd_cs4236_controls[] = {
711 723
712CS4236_DOUBLE("Master Digital Playback Switch", 0, CS4236_LEFT_MASTER, CS4236_RIGHT_MASTER, 7, 7, 1, 1), 724CS4236_DOUBLE("Master Digital Playback Switch", 0,
713CS4236_DOUBLE("Master Digital Capture Switch", 0, CS4236_DAC_MUTE, CS4236_DAC_MUTE, 7, 6, 1, 1), 725 CS4236_LEFT_MASTER, CS4236_RIGHT_MASTER, 7, 7, 1, 1),
726CS4236_DOUBLE("Master Digital Capture Switch", 0,
727 CS4236_DAC_MUTE, CS4236_DAC_MUTE, 7, 6, 1, 1),
714CS4236_MASTER_DIGITAL("Master Digital Volume", 0), 728CS4236_MASTER_DIGITAL("Master Digital Volume", 0),
715 729
716CS4236_DOUBLE("Capture Boost Volume", 0, CS4236_LEFT_MIX_CTRL, CS4236_RIGHT_MIX_CTRL, 5, 5, 3, 1), 730CS4236_DOUBLE("Capture Boost Volume", 0,
717 731 CS4236_LEFT_MIX_CTRL, CS4236_RIGHT_MIX_CTRL, 5, 5, 3, 1),
718CS4231_DOUBLE("PCM Playback Switch", 0, CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1), 732
719CS4231_DOUBLE("PCM Playback Volume", 0, CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1), 733WSS_DOUBLE("PCM Playback Switch", 0,
720 734 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1),
721CS4236_DOUBLE("DSP Playback Switch", 0, CS4236_LEFT_DSP, CS4236_RIGHT_DSP, 7, 7, 1, 1), 735WSS_DOUBLE("PCM Playback Volume", 0,
722CS4236_DOUBLE("DSP Playback Volume", 0, CS4236_LEFT_DSP, CS4236_RIGHT_DSP, 0, 0, 63, 1), 736 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1),
723 737
724CS4236_DOUBLE("FM Playback Switch", 0, CS4236_LEFT_FM, CS4236_RIGHT_FM, 7, 7, 1, 1), 738CS4236_DOUBLE("DSP Playback Switch", 0,
725CS4236_DOUBLE("FM Playback Volume", 0, CS4236_LEFT_FM, CS4236_RIGHT_FM, 0, 0, 63, 1), 739 CS4236_LEFT_DSP, CS4236_RIGHT_DSP, 7, 7, 1, 1),
726 740CS4236_DOUBLE("DSP Playback Volume", 0,
727CS4236_DOUBLE("Wavetable Playback Switch", 0, CS4236_LEFT_WAVE, CS4236_RIGHT_WAVE, 7, 7, 1, 1), 741 CS4236_LEFT_DSP, CS4236_RIGHT_DSP, 0, 0, 63, 1),
728CS4236_DOUBLE("Wavetable Playback Volume", 0, CS4236_LEFT_WAVE, CS4236_RIGHT_WAVE, 0, 0, 63, 1), 742
729 743CS4236_DOUBLE("FM Playback Switch", 0,
730CS4231_DOUBLE("Synth Playback Switch", 0, CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1), 744 CS4236_LEFT_FM, CS4236_RIGHT_FM, 7, 7, 1, 1),
731CS4231_DOUBLE("Synth Volume", 0, CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1), 745CS4236_DOUBLE("FM Playback Volume", 0,
732CS4231_DOUBLE("Synth Capture Switch", 0, CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 6, 6, 1, 1), 746 CS4236_LEFT_FM, CS4236_RIGHT_FM, 0, 0, 63, 1),
733CS4231_DOUBLE("Synth Capture Bypass", 0, CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 5, 5, 1, 1), 747
734 748CS4236_DOUBLE("Wavetable Playback Switch", 0,
735CS4236_DOUBLE("Mic Playback Switch", 0, CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 6, 6, 1, 1), 749 CS4236_LEFT_WAVE, CS4236_RIGHT_WAVE, 7, 7, 1, 1),
736CS4236_DOUBLE("Mic Capture Switch", 0, CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 7, 7, 1, 1), 750CS4236_DOUBLE("Wavetable Playback Volume", 0,
751 CS4236_LEFT_WAVE, CS4236_RIGHT_WAVE, 0, 0, 63, 1),
752
753WSS_DOUBLE("Synth Playback Switch", 0,
754 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
755WSS_DOUBLE("Synth Volume", 0,
756 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1),
757WSS_DOUBLE("Synth Capture Switch", 0,
758 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 6, 6, 1, 1),
759WSS_DOUBLE("Synth Capture Bypass", 0,
760 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 5, 5, 1, 1),
761
762CS4236_DOUBLE("Mic Playback Switch", 0,
763 CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 6, 6, 1, 1),
764CS4236_DOUBLE("Mic Capture Switch", 0,
765 CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 7, 7, 1, 1),
737CS4236_DOUBLE("Mic Volume", 0, CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 0, 0, 31, 1), 766CS4236_DOUBLE("Mic Volume", 0, CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 0, 0, 31, 1),
738CS4236_DOUBLE("Mic Playback Boost", 0, CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 5, 5, 1, 0), 767CS4236_DOUBLE("Mic Playback Boost", 0,
739 768 CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 5, 5, 1, 0),
740CS4231_DOUBLE("Line Playback Switch", 0, CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1), 769
741CS4231_DOUBLE("Line Volume", 0, CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1), 770WSS_DOUBLE("Line Playback Switch", 0,
742CS4231_DOUBLE("Line Capture Switch", 0, CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 6, 6, 1, 1), 771 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1),
743CS4231_DOUBLE("Line Capture Bypass", 0, CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 5, 5, 1, 1), 772WSS_DOUBLE("Line Volume", 0,
744 773 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1),
745CS4231_DOUBLE("CD Playback Switch", 0, CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1), 774WSS_DOUBLE("Line Capture Switch", 0,
746CS4231_DOUBLE("CD Volume", 0, CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1), 775 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 6, 6, 1, 1),
747CS4231_DOUBLE("CD Capture Switch", 0, CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 6, 6, 1, 1), 776WSS_DOUBLE("Line Capture Bypass", 0,
748 777 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 5, 5, 1, 1),
749CS4236_DOUBLE1("Mono Output Playback Switch", 0, CS4231_MONO_CTRL, CS4236_RIGHT_MIX_CTRL, 6, 7, 1, 1), 778
750CS4236_DOUBLE1("Mono Playback Switch", 0, CS4231_MONO_CTRL, CS4236_LEFT_MIX_CTRL, 7, 7, 1, 1), 779WSS_DOUBLE("CD Playback Switch", 0,
751CS4231_SINGLE("Mono Playback Volume", 0, CS4231_MONO_CTRL, 0, 15, 1), 780 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
752CS4231_SINGLE("Mono Playback Bypass", 0, CS4231_MONO_CTRL, 5, 1, 0), 781WSS_DOUBLE("CD Volume", 0,
753 782 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1),
754CS4231_DOUBLE("Capture Volume", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 0, 0, 15, 0), 783WSS_DOUBLE("CD Capture Switch", 0,
755CS4231_DOUBLE("Analog Loopback Capture Switch", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 7, 7, 1, 0), 784 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 6, 6, 1, 1),
756 785
757CS4231_SINGLE("Digital Loopback Playback Switch", 0, CS4231_LOOPBACK, 0, 1, 0), 786CS4236_DOUBLE1("Mono Output Playback Switch", 0,
758CS4236_DOUBLE1("Digital Loopback Playback Volume", 0, CS4231_LOOPBACK, CS4236_RIGHT_LOOPBACK, 2, 0, 63, 1) 787 CS4231_MONO_CTRL, CS4236_RIGHT_MIX_CTRL, 6, 7, 1, 1),
788CS4236_DOUBLE1("Mono Playback Switch", 0,
789 CS4231_MONO_CTRL, CS4236_LEFT_MIX_CTRL, 7, 7, 1, 1),
790WSS_SINGLE("Mono Playback Volume", 0, CS4231_MONO_CTRL, 0, 15, 1),
791WSS_SINGLE("Mono Playback Bypass", 0, CS4231_MONO_CTRL, 5, 1, 0),
792
793WSS_DOUBLE("Capture Volume", 0,
794 CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 0, 0, 15, 0),
795WSS_DOUBLE("Analog Loopback Capture Switch", 0,
796 CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 7, 7, 1, 0),
797
798WSS_SINGLE("Digital Loopback Playback Switch", 0, CS4231_LOOPBACK, 0, 1, 0),
799CS4236_DOUBLE1("Digital Loopback Playback Volume", 0,
800 CS4231_LOOPBACK, CS4236_RIGHT_LOOPBACK, 2, 0, 63, 1)
759}; 801};
760 802
761static struct snd_kcontrol_new snd_cs4235_controls[] = { 803static struct snd_kcontrol_new snd_cs4235_controls[] = {
762 804
763CS4231_DOUBLE("Master Switch", 0, CS4235_LEFT_MASTER, CS4235_RIGHT_MASTER, 7, 7, 1, 1), 805WSS_DOUBLE("Master Switch", 0,
764CS4231_DOUBLE("Master Volume", 0, CS4235_LEFT_MASTER, CS4235_RIGHT_MASTER, 0, 0, 31, 1), 806 CS4235_LEFT_MASTER, CS4235_RIGHT_MASTER, 7, 7, 1, 1),
807WSS_DOUBLE("Master Volume", 0,
808 CS4235_LEFT_MASTER, CS4235_RIGHT_MASTER, 0, 0, 31, 1),
765 809
766CS4235_OUTPUT_ACCU("Playback Volume", 0), 810CS4235_OUTPUT_ACCU("Playback Volume", 0),
767 811
768CS4236_DOUBLE("Master Digital Playback Switch", 0, CS4236_LEFT_MASTER, CS4236_RIGHT_MASTER, 7, 7, 1, 1), 812CS4236_DOUBLE("Master Digital Playback Switch", 0,
769CS4236_DOUBLE("Master Digital Capture Switch", 0, CS4236_DAC_MUTE, CS4236_DAC_MUTE, 7, 6, 1, 1), 813 CS4236_LEFT_MASTER, CS4236_RIGHT_MASTER, 7, 7, 1, 1),
814CS4236_DOUBLE("Master Digital Capture Switch", 0,
815 CS4236_DAC_MUTE, CS4236_DAC_MUTE, 7, 6, 1, 1),
770CS4236_MASTER_DIGITAL("Master Digital Volume", 0), 816CS4236_MASTER_DIGITAL("Master Digital Volume", 0),
771 817
772CS4231_DOUBLE("Master Digital Playback Switch", 1, CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1), 818WSS_DOUBLE("Master Digital Playback Switch", 1,
773CS4231_DOUBLE("Master Digital Capture Switch", 1, CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 6, 6, 1, 1), 819 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
774CS4231_DOUBLE("Master Digital Volume", 1, CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1), 820WSS_DOUBLE("Master Digital Capture Switch", 1,
821 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 6, 6, 1, 1),
822WSS_DOUBLE("Master Digital Volume", 1,
823 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1),
775 824
776CS4236_DOUBLE("Capture Volume", 0, CS4236_LEFT_MIX_CTRL, CS4236_RIGHT_MIX_CTRL, 5, 5, 3, 1), 825CS4236_DOUBLE("Capture Volume", 0,
826 CS4236_LEFT_MIX_CTRL, CS4236_RIGHT_MIX_CTRL, 5, 5, 3, 1),
777 827
778CS4231_DOUBLE("PCM Switch", 0, CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1), 828WSS_DOUBLE("PCM Switch", 0,
779CS4231_DOUBLE("PCM Volume", 0, CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1), 829 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1),
830WSS_DOUBLE("PCM Volume", 0,
831 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1),
780 832
781CS4236_DOUBLE("DSP Switch", 0, CS4236_LEFT_DSP, CS4236_RIGHT_DSP, 7, 7, 1, 1), 833CS4236_DOUBLE("DSP Switch", 0, CS4236_LEFT_DSP, CS4236_RIGHT_DSP, 7, 7, 1, 1),
782 834
783CS4236_DOUBLE("FM Switch", 0, CS4236_LEFT_FM, CS4236_RIGHT_FM, 7, 7, 1, 1), 835CS4236_DOUBLE("FM Switch", 0, CS4236_LEFT_FM, CS4236_RIGHT_FM, 7, 7, 1, 1),
784 836
785CS4236_DOUBLE("Wavetable Switch", 0, CS4236_LEFT_WAVE, CS4236_RIGHT_WAVE, 7, 7, 1, 1), 837CS4236_DOUBLE("Wavetable Switch", 0,
838 CS4236_LEFT_WAVE, CS4236_RIGHT_WAVE, 7, 7, 1, 1),
786 839
787CS4236_DOUBLE("Mic Capture Switch", 0, CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 7, 7, 1, 1), 840CS4236_DOUBLE("Mic Capture Switch", 0,
788CS4236_DOUBLE("Mic Playback Switch", 0, CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 6, 6, 1, 1), 841 CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 7, 7, 1, 1),
842CS4236_DOUBLE("Mic Playback Switch", 0,
843 CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 6, 6, 1, 1),
789CS4236_SINGLE("Mic Volume", 0, CS4236_LEFT_MIC, 0, 31, 1), 844CS4236_SINGLE("Mic Volume", 0, CS4236_LEFT_MIC, 0, 31, 1),
790CS4236_SINGLE("Mic Playback Boost", 0, CS4236_LEFT_MIC, 5, 1, 0), 845CS4236_SINGLE("Mic Playback Boost", 0, CS4236_LEFT_MIC, 5, 1, 0),
791 846
792CS4231_DOUBLE("Aux Playback Switch", 0, CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1), 847WSS_DOUBLE("Aux Playback Switch", 0,
793CS4231_DOUBLE("Aux Capture Switch", 0, CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 6, 6, 1, 1), 848 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1),
794CS4231_DOUBLE("Aux Volume", 0, CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1), 849WSS_DOUBLE("Aux Capture Switch", 0,
795 850 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 6, 6, 1, 1),
796CS4231_DOUBLE("Aux Playback Switch", 1, CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1), 851WSS_DOUBLE("Aux Volume", 0,
797CS4231_DOUBLE("Aux Capture Switch", 1, CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 6, 6, 1, 1), 852 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1),
798CS4231_DOUBLE("Aux Volume", 1, CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1), 853
799 854WSS_DOUBLE("Aux Playback Switch", 1,
800CS4236_DOUBLE1("Master Mono Switch", 0, CS4231_MONO_CTRL, CS4236_RIGHT_MIX_CTRL, 6, 7, 1, 1), 855 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
801 856WSS_DOUBLE("Aux Capture Switch", 1,
802CS4236_DOUBLE1("Mono Switch", 0, CS4231_MONO_CTRL, CS4236_LEFT_MIX_CTRL, 7, 7, 1, 1), 857 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 6, 6, 1, 1),
803CS4231_SINGLE("Mono Volume", 0, CS4231_MONO_CTRL, 0, 15, 1), 858WSS_DOUBLE("Aux Volume", 1,
804 859 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1),
805CS4231_DOUBLE("Analog Loopback Switch", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 7, 7, 1, 0), 860
861CS4236_DOUBLE1("Master Mono Switch", 0,
862 CS4231_MONO_CTRL, CS4236_RIGHT_MIX_CTRL, 6, 7, 1, 1),
863
864CS4236_DOUBLE1("Mono Switch", 0,
865 CS4231_MONO_CTRL, CS4236_LEFT_MIX_CTRL, 7, 7, 1, 1),
866WSS_SINGLE("Mono Volume", 0, CS4231_MONO_CTRL, 0, 15, 1),
867
868WSS_DOUBLE("Analog Loopback Switch", 0,
869 CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 7, 7, 1, 0),
806}; 870};
807 871
808#define CS4236_IEC958_ENABLE(xname, xindex) \ 872#define CS4236_IEC958_ENABLE(xname, xindex) \
@@ -813,14 +877,14 @@ CS4231_DOUBLE("Analog Loopback Switch", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT
813 877
814static int snd_cs4236_get_iec958_switch(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 878static int snd_cs4236_get_iec958_switch(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
815{ 879{
816 struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); 880 struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
817 unsigned long flags; 881 unsigned long flags;
818 882
819 spin_lock_irqsave(&chip->reg_lock, flags); 883 spin_lock_irqsave(&chip->reg_lock, flags);
820 ucontrol->value.integer.value[0] = chip->image[CS4231_ALT_FEATURE_1] & 0x02 ? 1 : 0; 884 ucontrol->value.integer.value[0] = chip->image[CS4231_ALT_FEATURE_1] & 0x02 ? 1 : 0;
821#if 0 885#if 0
822 printk("get valid: ALT = 0x%x, C3 = 0x%x, C4 = 0x%x, C5 = 0x%x, C6 = 0x%x, C8 = 0x%x\n", 886 printk("get valid: ALT = 0x%x, C3 = 0x%x, C4 = 0x%x, C5 = 0x%x, C6 = 0x%x, C8 = 0x%x\n",
823 snd_cs4231_in(chip, CS4231_ALT_FEATURE_1), 887 snd_wss_in(chip, CS4231_ALT_FEATURE_1),
824 snd_cs4236_ctrl_in(chip, 3), 888 snd_cs4236_ctrl_in(chip, 3),
825 snd_cs4236_ctrl_in(chip, 4), 889 snd_cs4236_ctrl_in(chip, 4),
826 snd_cs4236_ctrl_in(chip, 5), 890 snd_cs4236_ctrl_in(chip, 5),
@@ -833,7 +897,7 @@ static int snd_cs4236_get_iec958_switch(struct snd_kcontrol *kcontrol, struct sn
833 897
834static int snd_cs4236_put_iec958_switch(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 898static int snd_cs4236_put_iec958_switch(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
835{ 899{
836 struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); 900 struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
837 unsigned long flags; 901 unsigned long flags;
838 int change; 902 int change;
839 unsigned short enable, val; 903 unsigned short enable, val;
@@ -841,23 +905,23 @@ static int snd_cs4236_put_iec958_switch(struct snd_kcontrol *kcontrol, struct sn
841 enable = ucontrol->value.integer.value[0] & 1; 905 enable = ucontrol->value.integer.value[0] & 1;
842 906
843 mutex_lock(&chip->mce_mutex); 907 mutex_lock(&chip->mce_mutex);
844 snd_cs4231_mce_up(chip); 908 snd_wss_mce_up(chip);
845 spin_lock_irqsave(&chip->reg_lock, flags); 909 spin_lock_irqsave(&chip->reg_lock, flags);
846 val = (chip->image[CS4231_ALT_FEATURE_1] & ~0x0e) | (0<<2) | (enable << 1); 910 val = (chip->image[CS4231_ALT_FEATURE_1] & ~0x0e) | (0<<2) | (enable << 1);
847 change = val != chip->image[CS4231_ALT_FEATURE_1]; 911 change = val != chip->image[CS4231_ALT_FEATURE_1];
848 snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, val); 912 snd_wss_out(chip, CS4231_ALT_FEATURE_1, val);
849 val = snd_cs4236_ctrl_in(chip, 4) | 0xc0; 913 val = snd_cs4236_ctrl_in(chip, 4) | 0xc0;
850 snd_cs4236_ctrl_out(chip, 4, val); 914 snd_cs4236_ctrl_out(chip, 4, val);
851 udelay(100); 915 udelay(100);
852 val &= ~0x40; 916 val &= ~0x40;
853 snd_cs4236_ctrl_out(chip, 4, val); 917 snd_cs4236_ctrl_out(chip, 4, val);
854 spin_unlock_irqrestore(&chip->reg_lock, flags); 918 spin_unlock_irqrestore(&chip->reg_lock, flags);
855 snd_cs4231_mce_down(chip); 919 snd_wss_mce_down(chip);
856 mutex_unlock(&chip->mce_mutex); 920 mutex_unlock(&chip->mce_mutex);
857 921
858#if 0 922#if 0
859 printk("set valid: ALT = 0x%x, C3 = 0x%x, C4 = 0x%x, C5 = 0x%x, C6 = 0x%x, C8 = 0x%x\n", 923 printk("set valid: ALT = 0x%x, C3 = 0x%x, C4 = 0x%x, C5 = 0x%x, C6 = 0x%x, C8 = 0x%x\n",
860 snd_cs4231_in(chip, CS4231_ALT_FEATURE_1), 924 snd_wss_in(chip, CS4231_ALT_FEATURE_1),
861 snd_cs4236_ctrl_in(chip, 3), 925 snd_cs4236_ctrl_in(chip, 3),
862 snd_cs4236_ctrl_in(chip, 4), 926 snd_cs4236_ctrl_in(chip, 4),
863 snd_cs4236_ctrl_in(chip, 5), 927 snd_cs4236_ctrl_in(chip, 5),
@@ -896,19 +960,20 @@ CS4236_SINGLEC("3D Control - Volume", 0, 2, 0, 15, 1),
896CS4236_SINGLEC("3D Control - IEC958", 0, 3, 5, 1, 0) 960CS4236_SINGLEC("3D Control - IEC958", 0, 3, 5, 1, 0)
897}; 961};
898 962
899int snd_cs4236_mixer(struct snd_cs4231 *chip) 963int snd_cs4236_mixer(struct snd_wss *chip)
900{ 964{
901 struct snd_card *card; 965 struct snd_card *card;
902 unsigned int idx, count; 966 unsigned int idx, count;
903 int err; 967 int err;
904 struct snd_kcontrol_new *kcontrol; 968 struct snd_kcontrol_new *kcontrol;
905 969
906 snd_assert(chip != NULL && chip->card != NULL, return -EINVAL); 970 if (snd_BUG_ON(!chip || !chip->card))
971 return -EINVAL;
907 card = chip->card; 972 card = chip->card;
908 strcpy(card->mixername, snd_cs4231_chip_id(chip)); 973 strcpy(card->mixername, snd_wss_chip_id(chip));
909 974
910 if (chip->hardware == CS4231_HW_CS4235 || 975 if (chip->hardware == WSS_HW_CS4235 ||
911 chip->hardware == CS4231_HW_CS4239) { 976 chip->hardware == WSS_HW_CS4239) {
912 for (idx = 0; idx < ARRAY_SIZE(snd_cs4235_controls); idx++) { 977 for (idx = 0; idx < ARRAY_SIZE(snd_cs4235_controls); idx++) {
913 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_cs4235_controls[idx], chip))) < 0) 978 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_cs4235_controls[idx], chip))) < 0)
914 return err; 979 return err;
@@ -920,16 +985,16 @@ int snd_cs4236_mixer(struct snd_cs4231 *chip)
920 } 985 }
921 } 986 }
922 switch (chip->hardware) { 987 switch (chip->hardware) {
923 case CS4231_HW_CS4235: 988 case WSS_HW_CS4235:
924 case CS4231_HW_CS4239: 989 case WSS_HW_CS4239:
925 count = ARRAY_SIZE(snd_cs4236_3d_controls_cs4235); 990 count = ARRAY_SIZE(snd_cs4236_3d_controls_cs4235);
926 kcontrol = snd_cs4236_3d_controls_cs4235; 991 kcontrol = snd_cs4236_3d_controls_cs4235;
927 break; 992 break;
928 case CS4231_HW_CS4237B: 993 case WSS_HW_CS4237B:
929 count = ARRAY_SIZE(snd_cs4236_3d_controls_cs4237); 994 count = ARRAY_SIZE(snd_cs4236_3d_controls_cs4237);
930 kcontrol = snd_cs4236_3d_controls_cs4237; 995 kcontrol = snd_cs4236_3d_controls_cs4237;
931 break; 996 break;
932 case CS4231_HW_CS4238B: 997 case WSS_HW_CS4238B:
933 count = ARRAY_SIZE(snd_cs4236_3d_controls_cs4238); 998 count = ARRAY_SIZE(snd_cs4236_3d_controls_cs4238);
934 kcontrol = snd_cs4236_3d_controls_cs4238; 999 kcontrol = snd_cs4236_3d_controls_cs4238;
935 break; 1000 break;
@@ -941,8 +1006,8 @@ int snd_cs4236_mixer(struct snd_cs4231 *chip)
941 if ((err = snd_ctl_add(card, snd_ctl_new1(kcontrol, chip))) < 0) 1006 if ((err = snd_ctl_add(card, snd_ctl_new1(kcontrol, chip))) < 0)
942 return err; 1007 return err;
943 } 1008 }
944 if (chip->hardware == CS4231_HW_CS4237B || 1009 if (chip->hardware == WSS_HW_CS4237B ||
945 chip->hardware == CS4231_HW_CS4238B) { 1010 chip->hardware == WSS_HW_CS4238B) {
946 for (idx = 0; idx < ARRAY_SIZE(snd_cs4236_iec958_controls); idx++) { 1011 for (idx = 0; idx < ARRAY_SIZE(snd_cs4236_iec958_controls); idx++) {
947 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_cs4236_iec958_controls[idx], chip))) < 0) 1012 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_cs4236_iec958_controls[idx], chip))) < 0)
948 return err; 1013 return err;
diff --git a/sound/isa/es1688/es1688_lib.c b/sound/isa/es1688/es1688_lib.c
index 1e1e575b1db3..4fbb508a817f 100644
--- a/sound/isa/es1688/es1688_lib.c
+++ b/sound/isa/es1688/es1688_lib.c
@@ -1009,7 +1009,8 @@ int snd_es1688_mixer(struct snd_es1688 *chip)
1009 int err; 1009 int err;
1010 unsigned char reg, val; 1010 unsigned char reg, val;
1011 1011
1012 snd_assert(chip != NULL && chip->card != NULL, return -EINVAL); 1012 if (snd_BUG_ON(!chip || !chip->card))
1013 return -EINVAL;
1013 1014
1014 card = chip->card; 1015 card = chip->card;
1015 1016
diff --git a/sound/isa/gus/gus_main.c b/sound/isa/gus/gus_main.c
index cccc16c8113f..12eb98f2f931 100644
--- a/sound/isa/gus/gus_main.c
+++ b/sound/isa/gus/gus_main.c
@@ -276,9 +276,11 @@ static int snd_gus_init_dma_irq(struct snd_gus_card * gus, int latches)
276 static unsigned char dmas[8] = 276 static unsigned char dmas[8] =
277 {6, 1, 0, 2, 0, 3, 4, 5}; 277 {6, 1, 0, 2, 0, 3, 4, 5};
278 278
279 snd_assert(gus != NULL, return -EINVAL); 279 if (snd_BUG_ON(!gus))
280 return -EINVAL;
280 card = gus->card; 281 card = gus->card;
281 snd_assert(card != NULL, return -EINVAL); 282 if (snd_BUG_ON(!card))
283 return -EINVAL;
282 284
283 gus->mix_cntrl_reg &= 0xf8; 285 gus->mix_cntrl_reg &= 0xf8;
284 gus->mix_cntrl_reg |= 0x01; /* disable MIC, LINE IN, enable LINE OUT */ 286 gus->mix_cntrl_reg |= 0x01; /* disable MIC, LINE IN, enable LINE OUT */
diff --git a/sound/isa/gus/gus_mixer.c b/sound/isa/gus/gus_mixer.c
index ebdb33469306..0dd43414016e 100644
--- a/sound/isa/gus/gus_mixer.c
+++ b/sound/isa/gus/gus_mixer.c
@@ -161,9 +161,11 @@ int snd_gf1_new_mixer(struct snd_gus_card * gus)
161 unsigned int idx, max; 161 unsigned int idx, max;
162 int err; 162 int err;
163 163
164 snd_assert(gus != NULL, return -EINVAL); 164 if (snd_BUG_ON(!gus))
165 return -EINVAL;
165 card = gus->card; 166 card = gus->card;
166 snd_assert(card != NULL, return -EINVAL); 167 if (snd_BUG_ON(!card))
168 return -EINVAL;
167 169
168 if (gus->ics_flag) 170 if (gus->ics_flag)
169 snd_component_add(card, "ICS2101"); 171 snd_component_add(card, "ICS2101");
diff --git a/sound/isa/gus/gus_pcm.c b/sound/isa/gus/gus_pcm.c
index 99731dc97325..38510aeb21c6 100644
--- a/sound/isa/gus/gus_pcm.c
+++ b/sound/isa/gus/gus_pcm.c
@@ -352,8 +352,10 @@ static int snd_gf1_pcm_playback_copy(struct snd_pcm_substream *substream,
352 352
353 bpos = samples_to_bytes(runtime, pos) + (voice * (pcmp->dma_size / 2)); 353 bpos = samples_to_bytes(runtime, pos) + (voice * (pcmp->dma_size / 2));
354 len = samples_to_bytes(runtime, count); 354 len = samples_to_bytes(runtime, count);
355 snd_assert(bpos <= pcmp->dma_size, return -EIO); 355 if (snd_BUG_ON(bpos > pcmp->dma_size))
356 snd_assert(bpos + len <= pcmp->dma_size, return -EIO); 356 return -EIO;
357 if (snd_BUG_ON(bpos + len > pcmp->dma_size))
358 return -EIO;
357 if (copy_from_user(runtime->dma_area + bpos, src, len)) 359 if (copy_from_user(runtime->dma_area + bpos, src, len))
358 return -EFAULT; 360 return -EFAULT;
359 if (snd_gf1_pcm_use_dma && len > 32) { 361 if (snd_gf1_pcm_use_dma && len > 32) {
@@ -381,8 +383,10 @@ static int snd_gf1_pcm_playback_silence(struct snd_pcm_substream *substream,
381 383
382 bpos = samples_to_bytes(runtime, pos) + (voice * (pcmp->dma_size / 2)); 384 bpos = samples_to_bytes(runtime, pos) + (voice * (pcmp->dma_size / 2));
383 len = samples_to_bytes(runtime, count); 385 len = samples_to_bytes(runtime, count);
384 snd_assert(bpos <= pcmp->dma_size, return -EIO); 386 if (snd_BUG_ON(bpos > pcmp->dma_size))
385 snd_assert(bpos + len <= pcmp->dma_size, return -EIO); 387 return -EIO;
388 if (snd_BUG_ON(bpos + len > pcmp->dma_size))
389 return -EIO;
386 snd_pcm_format_set_silence(runtime->format, runtime->dma_area + bpos, count); 390 snd_pcm_format_set_silence(runtime->format, runtime->dma_area + bpos, count);
387 if (snd_gf1_pcm_use_dma && len > 32) { 391 if (snd_gf1_pcm_use_dma && len > 32) {
388 return snd_gf1_pcm_block_change(substream, bpos, pcmp->memory + bpos, len); 392 return snd_gf1_pcm_block_change(substream, bpos, pcmp->memory + bpos, len);
diff --git a/sound/isa/gus/gusmax.c b/sound/isa/gus/gusmax.c
index f87c6236661c..f94c1976e632 100644
--- a/sound/isa/gus/gusmax.c
+++ b/sound/isa/gus/gusmax.c
@@ -28,7 +28,7 @@
28#include <asm/dma.h> 28#include <asm/dma.h>
29#include <sound/core.h> 29#include <sound/core.h>
30#include <sound/gus.h> 30#include <sound/gus.h>
31#include <sound/cs4231.h> 31#include <sound/wss.h>
32#define SNDRV_LEGACY_FIND_FREE_IRQ 32#define SNDRV_LEGACY_FIND_FREE_IRQ
33#define SNDRV_LEGACY_FIND_FREE_DMA 33#define SNDRV_LEGACY_FIND_FREE_DMA
34#include <sound/initval.h> 34#include <sound/initval.h>
@@ -75,7 +75,7 @@ struct snd_gusmax {
75 int irq; 75 int irq;
76 struct snd_card *card; 76 struct snd_card *card;
77 struct snd_gus_card *gus; 77 struct snd_gus_card *gus;
78 struct snd_cs4231 *cs4231; 78 struct snd_wss *wss;
79 unsigned short gus_status_reg; 79 unsigned short gus_status_reg;
80 unsigned short pcm_status_reg; 80 unsigned short pcm_status_reg;
81}; 81};
@@ -117,7 +117,7 @@ static irqreturn_t snd_gusmax_interrupt(int irq, void *dev_id)
117 } 117 }
118 if (inb(maxcard->pcm_status_reg) & 0x01) { /* IRQ bit is set? */ 118 if (inb(maxcard->pcm_status_reg) & 0x01) { /* IRQ bit is set? */
119 handled = 1; 119 handled = 1;
120 snd_cs4231_interrupt(irq, maxcard->cs4231); 120 snd_wss_interrupt(irq, maxcard->wss);
121 loop++; 121 loop++;
122 } 122 }
123 } while (loop && --max > 0); 123 } while (loop && --max > 0);
@@ -140,10 +140,7 @@ static void __devinit snd_gusmax_init(int dev, struct snd_card *card,
140 outb(gus->max_cntrl_val, GUSP(gus, MAXCNTRLPORT)); 140 outb(gus->max_cntrl_val, GUSP(gus, MAXCNTRLPORT));
141} 141}
142 142
143#define CS4231_PRIVATE( left, right, shift, mute ) \ 143static int __devinit snd_gusmax_mixer(struct snd_wss *chip)
144 ((left << 24)|(right << 16)|(shift<<8)|mute)
145
146static int __devinit snd_gusmax_mixer(struct snd_cs4231 *chip)
147{ 144{
148 struct snd_card *card = chip->card; 145 struct snd_card *card = chip->card;
149 struct snd_ctl_elem_id id1, id2; 146 struct snd_ctl_elem_id id1, id2;
@@ -214,7 +211,7 @@ static int __devinit snd_gusmax_probe(struct device *pdev, unsigned int dev)
214 int xirq, xdma1, xdma2, err; 211 int xirq, xdma1, xdma2, err;
215 struct snd_card *card; 212 struct snd_card *card;
216 struct snd_gus_card *gus = NULL; 213 struct snd_gus_card *gus = NULL;
217 struct snd_cs4231 *cs4231; 214 struct snd_wss *wss;
218 struct snd_gusmax *maxcard; 215 struct snd_gusmax *maxcard;
219 216
220 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 217 card = snd_card_new(index[dev], id[dev], THIS_MODULE,
@@ -301,33 +298,39 @@ static int __devinit snd_gusmax_probe(struct device *pdev, unsigned int dev)
301 } 298 }
302 maxcard->irq = xirq; 299 maxcard->irq = xirq;
303 300
304 if ((err = snd_cs4231_create(card, 301 err = snd_wss_create(card,
305 gus->gf1.port + 0x10c, -1, xirq, 302 gus->gf1.port + 0x10c, -1, xirq,
306 xdma2 < 0 ? xdma1 : xdma2, xdma1, 303 xdma2 < 0 ? xdma1 : xdma2, xdma1,
307 CS4231_HW_DETECT, 304 WSS_HW_DETECT,
308 CS4231_HWSHARE_IRQ | 305 WSS_HWSHARE_IRQ |
309 CS4231_HWSHARE_DMA1 | 306 WSS_HWSHARE_DMA1 |
310 CS4231_HWSHARE_DMA2, 307 WSS_HWSHARE_DMA2,
311 &cs4231)) < 0) 308 &wss);
309 if (err < 0)
312 goto _err; 310 goto _err;
313 311
314 if ((err = snd_cs4231_pcm(cs4231, 0, NULL)) < 0) 312 err = snd_wss_pcm(wss, 0, NULL);
313 if (err < 0)
315 goto _err; 314 goto _err;
316 315
317 if ((err = snd_cs4231_mixer(cs4231)) < 0) 316 err = snd_wss_mixer(wss);
317 if (err < 0)
318 goto _err; 318 goto _err;
319 319
320 if ((err = snd_cs4231_timer(cs4231, 2, NULL)) < 0) 320 err = snd_wss_timer(wss, 2, NULL);
321 if (err < 0)
321 goto _err; 322 goto _err;
322 323
323 if (pcm_channels[dev] > 0) { 324 if (pcm_channels[dev] > 0) {
324 if ((err = snd_gf1_pcm_new(gus, 1, 1, NULL)) < 0) 325 if ((err = snd_gf1_pcm_new(gus, 1, 1, NULL)) < 0)
325 goto _err; 326 goto _err;
326 } 327 }
327 if ((err = snd_gusmax_mixer(cs4231)) < 0) 328 err = snd_gusmax_mixer(wss);
329 if (err < 0)
328 goto _err; 330 goto _err;
329 331
330 if ((err = snd_gf1_rawmidi_new(gus, 0, NULL)) < 0) 332 err = snd_gf1_rawmidi_new(gus, 0, NULL);
333 if (err < 0)
331 goto _err; 334 goto _err;
332 335
333 sprintf(card->longname + strlen(card->longname), " at 0x%lx, irq %i, dma %i", gus->gf1.port, xirq, xdma1); 336 sprintf(card->longname + strlen(card->longname), " at 0x%lx, irq %i, dma %i", gus->gf1.port, xirq, xdma1);
@@ -336,11 +339,12 @@ static int __devinit snd_gusmax_probe(struct device *pdev, unsigned int dev)
336 339
337 snd_card_set_dev(card, pdev); 340 snd_card_set_dev(card, pdev);
338 341
339 if ((err = snd_card_register(card)) < 0) 342 err = snd_card_register(card);
343 if (err < 0)
340 goto _err; 344 goto _err;
341 345
342 maxcard->gus = gus; 346 maxcard->gus = gus;
343 maxcard->cs4231 = cs4231; 347 maxcard->wss = wss;
344 348
345 dev_set_drvdata(pdev, card); 349 dev_set_drvdata(pdev, card);
346 return 0; 350 return 0;
diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c
index ca0d7ace0c75..5faecfb602d3 100644
--- a/sound/isa/gus/interwave.c
+++ b/sound/isa/gus/interwave.c
@@ -32,7 +32,7 @@
32#include <asm/dma.h> 32#include <asm/dma.h>
33#include <sound/core.h> 33#include <sound/core.h>
34#include <sound/gus.h> 34#include <sound/gus.h>
35#include <sound/cs4231.h> 35#include <sound/wss.h>
36#ifdef SNDRV_STB 36#ifdef SNDRV_STB
37#include <sound/tea6330t.h> 37#include <sound/tea6330t.h>
38#endif 38#endif
@@ -118,7 +118,7 @@ struct snd_interwave {
118 int irq; 118 int irq;
119 struct snd_card *card; 119 struct snd_card *card;
120 struct snd_gus_card *gus; 120 struct snd_gus_card *gus;
121 struct snd_cs4231 *cs4231; 121 struct snd_wss *wss;
122#ifdef SNDRV_STB 122#ifdef SNDRV_STB
123 struct resource *i2c_res; 123 struct resource *i2c_res;
124#endif 124#endif
@@ -312,7 +312,7 @@ static irqreturn_t snd_interwave_interrupt(int irq, void *dev_id)
312 } 312 }
313 if (inb(iwcard->pcm_status_reg) & 0x01) { /* IRQ bit is set? */ 313 if (inb(iwcard->pcm_status_reg) & 0x01) { /* IRQ bit is set? */
314 handled = 1; 314 handled = 1;
315 snd_cs4231_interrupt(irq, iwcard->cs4231); 315 snd_wss_interrupt(irq, iwcard->wss);
316 loop++; 316 loop++;
317 } 317 }
318 } while (loop && --max > 0); 318 } while (loop && --max > 0);
@@ -498,13 +498,17 @@ static void __devinit snd_interwave_init(int dev, struct snd_gus_card * gus)
498} 498}
499 499
500static struct snd_kcontrol_new snd_interwave_controls[] = { 500static struct snd_kcontrol_new snd_interwave_controls[] = {
501CS4231_DOUBLE("Master Playback Switch", 0, CS4231_LINE_LEFT_OUTPUT, CS4231_LINE_RIGHT_OUTPUT, 7, 7, 1, 1), 501WSS_DOUBLE("Master Playback Switch", 0,
502CS4231_DOUBLE("Master Playback Volume", 0, CS4231_LINE_LEFT_OUTPUT, CS4231_LINE_RIGHT_OUTPUT, 0, 0, 31, 1), 502 CS4231_LINE_LEFT_OUTPUT, CS4231_LINE_RIGHT_OUTPUT, 7, 7, 1, 1),
503CS4231_DOUBLE("Mic Playback Switch", 0, CS4231_LEFT_MIC_INPUT, CS4231_RIGHT_MIC_INPUT, 7, 7, 1, 1), 503WSS_DOUBLE("Master Playback Volume", 0,
504CS4231_DOUBLE("Mic Playback Volume", 0, CS4231_LEFT_MIC_INPUT, CS4231_RIGHT_MIC_INPUT, 0, 0, 31, 1) 504 CS4231_LINE_LEFT_OUTPUT, CS4231_LINE_RIGHT_OUTPUT, 0, 0, 31, 1),
505WSS_DOUBLE("Mic Playback Switch", 0,
506 CS4231_LEFT_MIC_INPUT, CS4231_RIGHT_MIC_INPUT, 7, 7, 1, 1),
507WSS_DOUBLE("Mic Playback Volume", 0,
508 CS4231_LEFT_MIC_INPUT, CS4231_RIGHT_MIC_INPUT, 0, 0, 31, 1)
505}; 509};
506 510
507static int __devinit snd_interwave_mixer(struct snd_cs4231 *chip) 511static int __devinit snd_interwave_mixer(struct snd_wss *chip)
508{ 512{
509 struct snd_card *card = chip->card; 513 struct snd_card *card = chip->card;
510 struct snd_ctl_elem_id id1, id2; 514 struct snd_ctl_elem_id id1, id2;
@@ -527,10 +531,10 @@ static int __devinit snd_interwave_mixer(struct snd_cs4231 *chip)
527 for (idx = 0; idx < ARRAY_SIZE(snd_interwave_controls); idx++) 531 for (idx = 0; idx < ARRAY_SIZE(snd_interwave_controls); idx++)
528 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_interwave_controls[idx], chip))) < 0) 532 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_interwave_controls[idx], chip))) < 0)
529 return err; 533 return err;
530 snd_cs4231_out(chip, CS4231_LINE_LEFT_OUTPUT, 0x9f); 534 snd_wss_out(chip, CS4231_LINE_LEFT_OUTPUT, 0x9f);
531 snd_cs4231_out(chip, CS4231_LINE_RIGHT_OUTPUT, 0x9f); 535 snd_wss_out(chip, CS4231_LINE_RIGHT_OUTPUT, 0x9f);
532 snd_cs4231_out(chip, CS4231_LEFT_MIC_INPUT, 0x9f); 536 snd_wss_out(chip, CS4231_LEFT_MIC_INPUT, 0x9f);
533 snd_cs4231_out(chip, CS4231_RIGHT_MIC_INPUT, 0x9f); 537 snd_wss_out(chip, CS4231_RIGHT_MIC_INPUT, 0x9f);
534 /* reassign AUXA to SYNTHESIZER */ 538 /* reassign AUXA to SYNTHESIZER */
535 strcpy(id1.name, "Aux Playback Switch"); 539 strcpy(id1.name, "Aux Playback Switch");
536 strcpy(id2.name, "Synth Playback Switch"); 540 strcpy(id2.name, "Synth Playback Switch");
@@ -642,7 +646,7 @@ static int __devinit snd_interwave_probe(struct snd_card *card, int dev)
642{ 646{
643 int xirq, xdma1, xdma2; 647 int xirq, xdma1, xdma2;
644 struct snd_interwave *iwcard = card->private_data; 648 struct snd_interwave *iwcard = card->private_data;
645 struct snd_cs4231 *cs4231; 649 struct snd_wss *wss;
646 struct snd_gus_card *gus; 650 struct snd_gus_card *gus;
647#ifdef SNDRV_STB 651#ifdef SNDRV_STB
648 struct snd_i2c_bus *i2c_bus; 652 struct snd_i2c_bus *i2c_bus;
@@ -684,33 +688,39 @@ static int __devinit snd_interwave_probe(struct snd_card *card, int dev)
684 } 688 }
685 iwcard->irq = xirq; 689 iwcard->irq = xirq;
686 690
687 if ((err = snd_cs4231_create(card, 691 err = snd_wss_create(card,
688 gus->gf1.port + 0x10c, -1, xirq, 692 gus->gf1.port + 0x10c, -1, xirq,
689 xdma2 < 0 ? xdma1 : xdma2, xdma1, 693 xdma2 < 0 ? xdma1 : xdma2, xdma1,
690 CS4231_HW_INTERWAVE, 694 WSS_HW_INTERWAVE,
691 CS4231_HWSHARE_IRQ | 695 WSS_HWSHARE_IRQ |
692 CS4231_HWSHARE_DMA1 | 696 WSS_HWSHARE_DMA1 |
693 CS4231_HWSHARE_DMA2, 697 WSS_HWSHARE_DMA2,
694 &cs4231)) < 0) 698 &wss);
699 if (err < 0)
695 return err; 700 return err;
696 701
697 if ((err = snd_cs4231_pcm(cs4231, 0, &pcm)) < 0) 702 err = snd_wss_pcm(wss, 0, &pcm);
703 if (err < 0)
698 return err; 704 return err;
699 705
700 sprintf(pcm->name + strlen(pcm->name), " rev %c", gus->revision + 'A'); 706 sprintf(pcm->name + strlen(pcm->name), " rev %c", gus->revision + 'A');
701 strcat(pcm->name, " (codec)"); 707 strcat(pcm->name, " (codec)");
702 708
703 if ((err = snd_cs4231_timer(cs4231, 2, NULL)) < 0) 709 err = snd_wss_timer(wss, 2, NULL);
710 if (err < 0)
704 return err; 711 return err;
705 712
706 if ((err = snd_cs4231_mixer(cs4231)) < 0) 713 err = snd_wss_mixer(wss);
714 if (err < 0)
707 return err; 715 return err;
708 716
709 if (pcm_channels[dev] > 0) { 717 if (pcm_channels[dev] > 0) {
710 if ((err = snd_gf1_pcm_new(gus, 1, 1, NULL)) < 0) 718 err = snd_gf1_pcm_new(gus, 1, 1, NULL);
719 if (err < 0)
711 return err; 720 return err;
712 } 721 }
713 if ((err = snd_interwave_mixer(cs4231)) < 0) 722 err = snd_interwave_mixer(wss);
723 if (err < 0)
714 return err; 724 return err;
715 725
716#ifdef SNDRV_STB 726#ifdef SNDRV_STB
@@ -754,10 +764,11 @@ static int __devinit snd_interwave_probe(struct snd_card *card, int dev)
754 if (xdma2 >= 0) 764 if (xdma2 >= 0)
755 sprintf(card->longname + strlen(card->longname), "&%d", xdma2); 765 sprintf(card->longname + strlen(card->longname), "&%d", xdma2);
756 766
757 if ((err = snd_card_register(card)) < 0) 767 err = snd_card_register(card);
768 if (err < 0)
758 return err; 769 return err;
759 770
760 iwcard->cs4231 = cs4231; 771 iwcard->wss = wss;
761 iwcard->gus = gus; 772 iwcard->gus = gus;
762 return 0; 773 return 0;
763} 774}
diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c
index 854a9f74b466..58c972b2af03 100644
--- a/sound/isa/opl3sa2.c
+++ b/sound/isa/opl3sa2.c
@@ -28,7 +28,7 @@
28#include <linux/pnp.h> 28#include <linux/pnp.h>
29#include <linux/moduleparam.h> 29#include <linux/moduleparam.h>
30#include <sound/core.h> 30#include <sound/core.h>
31#include <sound/cs4231.h> 31#include <sound/wss.h>
32#include <sound/mpu401.h> 32#include <sound/mpu401.h>
33#include <sound/opl3.h> 33#include <sound/opl3.h>
34#include <sound/initval.h> 34#include <sound/initval.h>
@@ -124,7 +124,6 @@ static int pnpc_registered;
124#define OPL3SA2_PM_D3 (OPL3SA2_PM_ADOWN|OPL3SA2_PM_PSV|OPL3SA2_PM_PDN|OPL3SA2_PM_PDX) 124#define OPL3SA2_PM_D3 (OPL3SA2_PM_ADOWN|OPL3SA2_PM_PSV|OPL3SA2_PM_PDN|OPL3SA2_PM_PDX)
125 125
126struct snd_opl3sa2 { 126struct snd_opl3sa2 {
127 struct snd_card *card;
128 int version; /* 2 or 3 */ 127 int version; /* 2 or 3 */
129 unsigned long port; /* control port */ 128 unsigned long port; /* control port */
130 struct resource *res_port; /* control port resource */ 129 struct resource *res_port; /* control port resource */
@@ -133,7 +132,7 @@ struct snd_opl3sa2 {
133 spinlock_t reg_lock; 132 spinlock_t reg_lock;
134 struct snd_hwdep *synth; 133 struct snd_hwdep *synth;
135 struct snd_rawmidi *rmidi; 134 struct snd_rawmidi *rmidi;
136 struct snd_cs4231 *cs4231; 135 struct snd_wss *wss;
137 unsigned char ctlregs[0x20]; 136 unsigned char ctlregs[0x20];
138 int ymode; /* SL added */ 137 int ymode; /* SL added */
139 struct snd_kcontrol *master_switch; 138 struct snd_kcontrol *master_switch;
@@ -222,14 +221,13 @@ static void snd_opl3sa2_write(struct snd_opl3sa2 *chip, unsigned char reg, unsig
222 spin_unlock_irqrestore(&chip->reg_lock, flags); 221 spin_unlock_irqrestore(&chip->reg_lock, flags);
223} 222}
224 223
225static int __devinit snd_opl3sa2_detect(struct snd_opl3sa2 *chip) 224static int __devinit snd_opl3sa2_detect(struct snd_card *card)
226{ 225{
227 struct snd_card *card; 226 struct snd_opl3sa2 *chip = card->private_data;
228 unsigned long port; 227 unsigned long port;
229 unsigned char tmp, tmp1; 228 unsigned char tmp, tmp1;
230 char str[2]; 229 char str[2];
231 230
232 card = chip->card;
233 port = chip->port; 231 port = chip->port;
234 if ((chip->res_port = request_region(port, 2, "OPL3-SA control")) == NULL) { 232 if ((chip->res_port = request_region(port, 2, "OPL3-SA control")) == NULL) {
235 snd_printk(KERN_ERR PFX "can't grab port 0x%lx\n", port); 233 snd_printk(KERN_ERR PFX "can't grab port 0x%lx\n", port);
@@ -298,12 +296,14 @@ static int __devinit snd_opl3sa2_detect(struct snd_opl3sa2 *chip)
298static irqreturn_t snd_opl3sa2_interrupt(int irq, void *dev_id) 296static irqreturn_t snd_opl3sa2_interrupt(int irq, void *dev_id)
299{ 297{
300 unsigned short status; 298 unsigned short status;
301 struct snd_opl3sa2 *chip = dev_id; 299 struct snd_card *card = dev_id;
300 struct snd_opl3sa2 *chip;
302 int handled = 0; 301 int handled = 0;
303 302
304 if (chip == NULL || chip->card == NULL) 303 if (card == NULL)
305 return IRQ_NONE; 304 return IRQ_NONE;
306 305
306 chip = card->private_data;
307 status = snd_opl3sa2_read(chip, OPL3SA2_IRQ_STATUS); 307 status = snd_opl3sa2_read(chip, OPL3SA2_IRQ_STATUS);
308 308
309 if (status & 0x20) { 309 if (status & 0x20) {
@@ -318,7 +318,7 @@ static irqreturn_t snd_opl3sa2_interrupt(int irq, void *dev_id)
318 318
319 if (status & 0x07) { /* TI,CI,PI */ 319 if (status & 0x07) { /* TI,CI,PI */
320 handled = 1; 320 handled = 1;
321 snd_cs4231_interrupt(irq, chip->cs4231); 321 snd_wss_interrupt(irq, chip->wss);
322 } 322 }
323 323
324 if (status & 0x40) { /* hardware volume change */ 324 if (status & 0x40) { /* hardware volume change */
@@ -327,8 +327,10 @@ static irqreturn_t snd_opl3sa2_interrupt(int irq, void *dev_id)
327 snd_opl3sa2_read(chip, OPL3SA2_MASTER_RIGHT); 327 snd_opl3sa2_read(chip, OPL3SA2_MASTER_RIGHT);
328 snd_opl3sa2_read(chip, OPL3SA2_MASTER_LEFT); 328 snd_opl3sa2_read(chip, OPL3SA2_MASTER_LEFT);
329 if (chip->master_switch && chip->master_volume) { 329 if (chip->master_switch && chip->master_volume) {
330 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->master_switch->id); 330 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
331 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->master_volume->id); 331 &chip->master_switch->id);
332 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
333 &chip->master_volume->id);
332 } 334 }
333 } 335 }
334 return IRQ_RETVAL(handled); 336 return IRQ_RETVAL(handled);
@@ -336,29 +338,18 @@ static irqreturn_t snd_opl3sa2_interrupt(int irq, void *dev_id)
336 338
337#define OPL3SA2_SINGLE(xname, xindex, reg, shift, mask, invert) \ 339#define OPL3SA2_SINGLE(xname, xindex, reg, shift, mask, invert) \
338{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ 340{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
339 .info = snd_opl3sa2_info_single, \ 341 .info = snd_wss_info_single, \
340 .get = snd_opl3sa2_get_single, .put = snd_opl3sa2_put_single, \ 342 .get = snd_opl3sa2_get_single, .put = snd_opl3sa2_put_single, \
341 .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) } 343 .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
342#define OPL3SA2_SINGLE_TLV(xname, xindex, reg, shift, mask, invert, xtlv) \ 344#define OPL3SA2_SINGLE_TLV(xname, xindex, reg, shift, mask, invert, xtlv) \
343{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 345{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
344 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \ 346 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
345 .name = xname, .index = xindex, \ 347 .name = xname, .index = xindex, \
346 .info = snd_opl3sa2_info_single, \ 348 .info = snd_wss_info_single, \
347 .get = snd_opl3sa2_get_single, .put = snd_opl3sa2_put_single, \ 349 .get = snd_opl3sa2_get_single, .put = snd_opl3sa2_put_single, \
348 .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24), \ 350 .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24), \
349 .tlv = { .p = (xtlv) } } 351 .tlv = { .p = (xtlv) } }
350 352
351static int snd_opl3sa2_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
352{
353 int mask = (kcontrol->private_value >> 16) & 0xff;
354
355 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
356 uinfo->count = 1;
357 uinfo->value.integer.min = 0;
358 uinfo->value.integer.max = mask;
359 return 0;
360}
361
362static int snd_opl3sa2_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 353static int snd_opl3sa2_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
363{ 354{
364 struct snd_opl3sa2 *chip = snd_kcontrol_chip(kcontrol); 355 struct snd_opl3sa2 *chip = snd_kcontrol_chip(kcontrol);
@@ -402,29 +393,18 @@ static int snd_opl3sa2_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_
402 393
403#define OPL3SA2_DOUBLE(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \ 394#define OPL3SA2_DOUBLE(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \
404{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ 395{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
405 .info = snd_opl3sa2_info_double, \ 396 .info = snd_wss_info_double, \
406 .get = snd_opl3sa2_get_double, .put = snd_opl3sa2_put_double, \ 397 .get = snd_opl3sa2_get_double, .put = snd_opl3sa2_put_double, \
407 .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) } 398 .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) }
408#define OPL3SA2_DOUBLE_TLV(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert, xtlv) \ 399#define OPL3SA2_DOUBLE_TLV(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert, xtlv) \
409{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 400{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
410 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \ 401 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
411 .name = xname, .index = xindex, \ 402 .name = xname, .index = xindex, \
412 .info = snd_opl3sa2_info_double, \ 403 .info = snd_wss_info_double, \
413 .get = snd_opl3sa2_get_double, .put = snd_opl3sa2_put_double, \ 404 .get = snd_opl3sa2_get_double, .put = snd_opl3sa2_put_double, \
414 .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22), \ 405 .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22), \
415 .tlv = { .p = (xtlv) } } 406 .tlv = { .p = (xtlv) } }
416 407
417static int snd_opl3sa2_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
418{
419 int mask = (kcontrol->private_value >> 24) & 0xff;
420
421 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
422 uinfo->count = 2;
423 uinfo->value.integer.min = 0;
424 uinfo->value.integer.max = mask;
425 return 0;
426}
427
428static int snd_opl3sa2_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 408static int snd_opl3sa2_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
429{ 409{
430 struct snd_opl3sa2 *chip = snd_kcontrol_chip(kcontrol); 410 struct snd_opl3sa2 *chip = snd_kcontrol_chip(kcontrol);
@@ -512,9 +492,9 @@ static void snd_opl3sa2_master_free(struct snd_kcontrol *kcontrol)
512 chip->master_volume = NULL; 492 chip->master_volume = NULL;
513} 493}
514 494
515static int __devinit snd_opl3sa2_mixer(struct snd_opl3sa2 *chip) 495static int __devinit snd_opl3sa2_mixer(struct snd_card *card)
516{ 496{
517 struct snd_card *card = chip->card; 497 struct snd_opl3sa2 *chip = card->private_data;
518 struct snd_ctl_elem_id id1, id2; 498 struct snd_ctl_elem_id id1, id2;
519 struct snd_kcontrol *kctl; 499 struct snd_kcontrol *kctl;
520 unsigned int idx; 500 unsigned int idx;
@@ -573,7 +553,7 @@ static int snd_opl3sa2_suspend(struct snd_card *card, pm_message_t state)
573 struct snd_opl3sa2 *chip = card->private_data; 553 struct snd_opl3sa2 *chip = card->private_data;
574 554
575 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 555 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
576 chip->cs4231->suspend(chip->cs4231); 556 chip->wss->suspend(chip->wss);
577 /* power down */ 557 /* power down */
578 snd_opl3sa2_write(chip, OPL3SA2_PM_CTRL, OPL3SA2_PM_D3); 558 snd_opl3sa2_write(chip, OPL3SA2_PM_CTRL, OPL3SA2_PM_D3);
579 559
@@ -597,8 +577,8 @@ static int snd_opl3sa2_resume(struct snd_card *card)
597 for (i = 0x12; i <= 0x16; i++) 577 for (i = 0x12; i <= 0x16; i++)
598 snd_opl3sa2_write(chip, i, chip->ctlregs[i]); 578 snd_opl3sa2_write(chip, i, chip->ctlregs[i]);
599 } 579 }
600 /* restore cs4231 */ 580 /* restore wss */
601 chip->cs4231->resume(chip->cs4231); 581 chip->wss->resume(chip->wss);
602 582
603 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 583 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
604 return 0; 584 return 0;
@@ -650,7 +630,6 @@ static struct snd_card *snd_opl3sa2_card_new(int dev)
650 chip = card->private_data; 630 chip = card->private_data;
651 spin_lock_init(&chip->reg_lock); 631 spin_lock_init(&chip->reg_lock);
652 chip->irq = -1; 632 chip->irq = -1;
653 chip->card = card;
654 card->private_free = snd_opl3sa2_free; 633 card->private_free = snd_opl3sa2_free;
655 return card; 634 return card;
656} 635}
@@ -659,7 +638,7 @@ static int __devinit snd_opl3sa2_probe(struct snd_card *card, int dev)
659{ 638{
660 int xirq, xdma1, xdma2; 639 int xirq, xdma1, xdma2;
661 struct snd_opl3sa2 *chip; 640 struct snd_opl3sa2 *chip;
662 struct snd_cs4231 *cs4231; 641 struct snd_wss *wss;
663 struct snd_opl3 *opl3; 642 struct snd_opl3 *opl3;
664 int err; 643 int err;
665 644
@@ -672,30 +651,36 @@ static int __devinit snd_opl3sa2_probe(struct snd_card *card, int dev)
672 xdma2 = dma2[dev]; 651 xdma2 = dma2[dev];
673 if (xdma2 < 0) 652 if (xdma2 < 0)
674 chip->single_dma = 1; 653 chip->single_dma = 1;
675 if ((err = snd_opl3sa2_detect(chip)) < 0) 654 err = snd_opl3sa2_detect(card);
655 if (err < 0)
676 return err; 656 return err;
677 if (request_irq(xirq, snd_opl3sa2_interrupt, IRQF_DISABLED, "OPL3-SA2", chip)) { 657 err = request_irq(xirq, snd_opl3sa2_interrupt, IRQF_DISABLED,
658 "OPL3-SA2", card);
659 if (err) {
678 snd_printk(KERN_ERR PFX "can't grab IRQ %d\n", xirq); 660 snd_printk(KERN_ERR PFX "can't grab IRQ %d\n", xirq);
679 return -ENODEV; 661 return -ENODEV;
680 } 662 }
681 chip->irq = xirq; 663 chip->irq = xirq;
682 if ((err = snd_cs4231_create(card, 664 err = snd_wss_create(card,
683 wss_port[dev] + 4, -1, 665 wss_port[dev] + 4, -1,
684 xirq, xdma1, xdma2, 666 xirq, xdma1, xdma2,
685 CS4231_HW_OPL3SA2, 667 WSS_HW_OPL3SA2, WSS_HWSHARE_IRQ, &wss);
686 CS4231_HWSHARE_IRQ, 668 if (err < 0) {
687 &cs4231)) < 0) {
688 snd_printd("Oops, WSS not detected at 0x%lx\n", wss_port[dev] + 4); 669 snd_printd("Oops, WSS not detected at 0x%lx\n", wss_port[dev] + 4);
689 return err; 670 return err;
690 } 671 }
691 chip->cs4231 = cs4231; 672 chip->wss = wss;
692 if ((err = snd_cs4231_pcm(cs4231, 0, NULL)) < 0) 673 err = snd_wss_pcm(wss, 0, NULL);
674 if (err < 0)
693 return err; 675 return err;
694 if ((err = snd_cs4231_mixer(cs4231)) < 0) 676 err = snd_wss_mixer(wss);
677 if (err < 0)
695 return err; 678 return err;
696 if ((err = snd_opl3sa2_mixer(chip)) < 0) 679 err = snd_opl3sa2_mixer(card);
680 if (err < 0)
697 return err; 681 return err;
698 if ((err = snd_cs4231_timer(cs4231, 0, NULL)) < 0) 682 err = snd_wss_timer(wss, 0, NULL);
683 if (err < 0)
699 return err; 684 return err;
700 if (fm_port[dev] >= 0x340 && fm_port[dev] < 0x400) { 685 if (fm_port[dev] >= 0x340 && fm_port[dev] < 0x400) {
701 if ((err = snd_opl3_create(card, fm_port[dev], 686 if ((err = snd_opl3_create(card, fm_port[dev],
diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c
index 2a1e2f5d12c2..440755cc0013 100644
--- a/sound/isa/opti9xx/miro.c
+++ b/sound/isa/opti9xx/miro.c
@@ -32,7 +32,7 @@
32#include <asm/io.h> 32#include <asm/io.h>
33#include <asm/dma.h> 33#include <asm/dma.h>
34#include <sound/core.h> 34#include <sound/core.h>
35#include <sound/cs4231.h> 35#include <sound/wss.h>
36#include <sound/mpu401.h> 36#include <sound/mpu401.h>
37#include <sound/opl4.h> 37#include <sound/opl4.h>
38#include <sound/control.h> 38#include <sound/control.h>
@@ -675,7 +675,8 @@ static int __devinit snd_miro_mixer(struct snd_miro *miro)
675 unsigned int idx; 675 unsigned int idx;
676 int err; 676 int err;
677 677
678 snd_assert(miro != NULL && miro->card != NULL, return -EINVAL); 678 if (snd_BUG_ON(!miro || !miro->card))
679 return -EINVAL;
679 680
680 card = miro->card; 681 card = miro->card;
681 682
@@ -1221,7 +1222,7 @@ static int __devinit snd_miro_probe(struct device *devptr, unsigned int n)
1221 1222
1222 int error; 1223 int error;
1223 struct snd_miro *miro; 1224 struct snd_miro *miro;
1224 struct snd_cs4231 *codec; 1225 struct snd_wss *codec;
1225 struct snd_timer *timer; 1226 struct snd_timer *timer;
1226 struct snd_card *card; 1227 struct snd_card *card;
1227 struct snd_pcm *pcm; 1228 struct snd_pcm *pcm;
@@ -1310,29 +1311,32 @@ static int __devinit snd_miro_probe(struct device *devptr, unsigned int n)
1310 } 1311 }
1311 } 1312 }
1312 1313
1313 if ((error = snd_miro_configure(miro))) { 1314 error = snd_miro_configure(miro);
1315 if (error) {
1314 snd_card_free(card); 1316 snd_card_free(card);
1315 return error; 1317 return error;
1316 } 1318 }
1317 1319
1318 if ((error = snd_cs4231_create(card, miro->wss_base + 4, -1, 1320 error = snd_wss_create(card, miro->wss_base + 4, -1,
1319 miro->irq, miro->dma1, miro->dma2, 1321 miro->irq, miro->dma1, miro->dma2,
1320 CS4231_HW_AD1845, 1322 WSS_HW_AD1845, 0, &codec);
1321 0, 1323 if (error < 0) {
1322 &codec)) < 0) {
1323 snd_card_free(card); 1324 snd_card_free(card);
1324 return error; 1325 return error;
1325 } 1326 }
1326 1327
1327 if ((error = snd_cs4231_pcm(codec, 0, &pcm)) < 0) { 1328 error = snd_wss_pcm(codec, 0, &pcm);
1329 if (error < 0) {
1328 snd_card_free(card); 1330 snd_card_free(card);
1329 return error; 1331 return error;
1330 } 1332 }
1331 if ((error = snd_cs4231_mixer(codec)) < 0) { 1333 error = snd_wss_mixer(codec);
1334 if (error < 0) {
1332 snd_card_free(card); 1335 snd_card_free(card);
1333 return error; 1336 return error;
1334 } 1337 }
1335 if ((error = snd_cs4231_timer(codec, 0, &timer)) < 0) { 1338 error = snd_wss_timer(codec, 0, &timer);
1339 if (error < 0) {
1336 snd_card_free(card); 1340 snd_card_free(card);
1337 return error; 1341 return error;
1338 } 1342 }
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c
index 0797ca441a37..19706b0d8497 100644
--- a/sound/isa/opti9xx/opti92x-ad1848.c
+++ b/sound/isa/opti9xx/opti92x-ad1848.c
@@ -33,11 +33,7 @@
33#include <asm/io.h> 33#include <asm/io.h>
34#include <asm/dma.h> 34#include <asm/dma.h>
35#include <sound/core.h> 35#include <sound/core.h>
36#if defined(CS4231) || defined(OPTi93X) 36#include <sound/wss.h>
37#include <sound/cs4231.h>
38#else
39#include <sound/ad1848.h>
40#endif /* CS4231 */
41#include <sound/mpu401.h> 37#include <sound/mpu401.h>
42#include <sound/opl3.h> 38#include <sound/opl3.h>
43#ifndef OPTi93X 39#ifndef OPTi93X
@@ -139,7 +135,7 @@ struct snd_opti9xx {
139 unsigned long mc_base_size; 135 unsigned long mc_base_size;
140#ifdef OPTi93X 136#ifdef OPTi93X
141 unsigned long mc_indir_index; 137 unsigned long mc_indir_index;
142 struct snd_cs4231 *codec; 138 struct snd_wss *codec;
143#endif /* OPTi93X */ 139#endif /* OPTi93X */
144 unsigned long pwd_reg; 140 unsigned long pwd_reg;
145 141
@@ -148,9 +144,7 @@ struct snd_opti9xx {
148 long wss_base; 144 long wss_base;
149 int irq; 145 int irq;
150 int dma1; 146 int dma1;
151#if defined(CS4231) || defined(OPTi93X)
152 int dma2; 147 int dma2;
153#endif /* CS4231 || OPTi93X */
154 148
155 long fm_port; 149 long fm_port;
156 150
@@ -225,9 +219,7 @@ static int __devinit snd_opti9xx_init(struct snd_opti9xx *chip,
225 chip->wss_base = -1; 219 chip->wss_base = -1;
226 chip->irq = -1; 220 chip->irq = -1;
227 chip->dma1 = -1; 221 chip->dma1 = -1;
228#if defined(CS4231) || defined (OPTi93X)
229 chip->dma2 = -1; 222 chip->dma2 = -1;
230#endif /* CS4231 || OPTi93X */
231 chip->fm_port = -1; 223 chip->fm_port = -1;
232 chip->mpu_port = -1; 224 chip->mpu_port = -1;
233 chip->mpu_irq = -1; 225 chip->mpu_irq = -1;
@@ -562,7 +554,7 @@ __skip_mpu:
562 554
563static irqreturn_t snd_opti93x_interrupt(int irq, void *dev_id) 555static irqreturn_t snd_opti93x_interrupt(int irq, void *dev_id)
564{ 556{
565 struct snd_cs4231 *codec = dev_id; 557 struct snd_wss *codec = dev_id;
566 struct snd_opti9xx *chip = codec->card->private_data; 558 struct snd_opti9xx *chip = codec->card->private_data;
567 unsigned char status; 559 unsigned char status;
568 560
@@ -570,7 +562,7 @@ static irqreturn_t snd_opti93x_interrupt(int irq, void *dev_id)
570 if ((status & OPTi93X_IRQ_PLAYBACK) && codec->playback_substream) 562 if ((status & OPTi93X_IRQ_PLAYBACK) && codec->playback_substream)
571 snd_pcm_period_elapsed(codec->playback_substream); 563 snd_pcm_period_elapsed(codec->playback_substream);
572 if ((status & OPTi93X_IRQ_CAPTURE) && codec->capture_substream) { 564 if ((status & OPTi93X_IRQ_CAPTURE) && codec->capture_substream) {
573 snd_cs4231_overrange(codec); 565 snd_wss_overrange(codec);
574 snd_pcm_period_elapsed(codec->capture_substream); 566 snd_pcm_period_elapsed(codec->capture_substream);
575 } 567 }
576 outb(0x00, OPTi93X_PORT(codec, STATUS)); 568 outb(0x00, OPTi93X_PORT(codec, STATUS));
@@ -691,7 +683,7 @@ static void snd_card_opti9xx_free(struct snd_card *card)
691 683
692 if (chip) { 684 if (chip) {
693#ifdef OPTi93X 685#ifdef OPTi93X
694 struct snd_cs4231 *codec = chip->codec; 686 struct snd_wss *codec = chip->codec;
695 if (codec && codec->irq > 0) { 687 if (codec && codec->irq > 0) {
696 disable_irq(codec->irq); 688 disable_irq(codec->irq);
697 free_irq(codec->irq, codec); 689 free_irq(codec->irq, codec);
@@ -706,14 +698,10 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card)
706 static long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1}; 698 static long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1};
707 int error; 699 int error;
708 struct snd_opti9xx *chip = card->private_data; 700 struct snd_opti9xx *chip = card->private_data;
709#if defined(CS4231) || defined(OPTi93X) 701 struct snd_wss *codec;
710 struct snd_cs4231 *codec;
711#ifdef CS4231 702#ifdef CS4231
712 struct snd_timer *timer; 703 struct snd_timer *timer;
713#endif 704#endif
714#else
715 struct snd_ad1848 *codec;
716#endif
717 struct snd_pcm *pcm; 705 struct snd_pcm *pcm;
718 struct snd_rawmidi *rmidi; 706 struct snd_rawmidi *rmidi;
719 struct snd_hwdep *synth; 707 struct snd_hwdep *synth;
@@ -731,38 +719,46 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card)
731 chip->dma1 = dma1; 719 chip->dma1 = dma1;
732#if defined(CS4231) || defined(OPTi93X) 720#if defined(CS4231) || defined(OPTi93X)
733 chip->dma2 = dma2; 721 chip->dma2 = dma2;
722#else
723 chip->dma2 = -1;
734#endif 724#endif
735 725
736 if (chip->wss_base == SNDRV_AUTO_PORT) { 726 if (chip->wss_base == SNDRV_AUTO_PORT) {
737 if ((chip->wss_base = snd_legacy_find_free_ioport(possible_ports, 4)) < 0) { 727 chip->wss_base = snd_legacy_find_free_ioport(possible_ports, 4);
728 if (chip->wss_base < 0) {
738 snd_printk("unable to find a free WSS port\n"); 729 snd_printk("unable to find a free WSS port\n");
739 return -EBUSY; 730 return -EBUSY;
740 } 731 }
741 } 732 }
742 if ((error = snd_opti9xx_configure(chip))) 733 error = snd_opti9xx_configure(chip);
734 if (error)
743 return error; 735 return error;
744 736
745#if defined(CS4231) || defined(OPTi93X) 737 error = snd_wss_create(card, chip->wss_base + 4, -1,
746 if ((error = snd_cs4231_create(card, chip->wss_base + 4, -1, 738 chip->irq, chip->dma1, chip->dma2,
747 chip->irq, chip->dma1, chip->dma2, 739#ifdef OPTi93X
748#ifdef CS4231 740 WSS_HW_OPTI93X, WSS_HWSHARE_IRQ,
749 CS4231_HW_DETECT, 0, 741#else
750#else /* OPTi93x */ 742 WSS_HW_DETECT, 0,
751 CS4231_HW_OPTI93X, CS4231_HWSHARE_IRQ,
752#endif 743#endif
753 &codec)) < 0) 744 &codec);
745 if (error < 0)
754 return error; 746 return error;
755#ifdef OPTi93X 747#ifdef OPTi93X
756 chip->codec = codec; 748 chip->codec = codec;
757#endif 749#endif
758 if ((error = snd_cs4231_pcm(codec, 0, &pcm)) < 0) 750 error = snd_wss_pcm(codec, 0, &pcm);
751 if (error < 0)
759 return error; 752 return error;
760 if ((error = snd_cs4231_mixer(codec)) < 0) 753 error = snd_wss_mixer(codec);
754 if (error < 0)
761 return error; 755 return error;
762#ifdef CS4231 756#ifdef CS4231
763 if ((error = snd_cs4231_timer(codec, 0, &timer)) < 0) 757 error = snd_wss_timer(codec, 0, &timer);
758 if (error < 0)
764 return error; 759 return error;
765#else /* OPTI93X */ 760#endif
761#ifdef OPTi93X
766 error = request_irq(chip->irq, snd_opti93x_interrupt, 762 error = request_irq(chip->irq, snd_opti93x_interrupt,
767 IRQF_DISABLED, DEV_NAME" - WSS", codec); 763 IRQF_DISABLED, DEV_NAME" - WSS", codec);
768 if (error < 0) { 764 if (error < 0) {
@@ -770,16 +766,6 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card)
770 return error; 766 return error;
771 } 767 }
772#endif 768#endif
773#else
774 if ((error = snd_ad1848_create(card, chip->wss_base + 4,
775 chip->irq, chip->dma1,
776 AD1848_HW_DETECT, &codec)) < 0)
777 return error;
778 if ((error = snd_ad1848_pcm(codec, 0, &pcm)) < 0)
779 return error;
780 if ((error = snd_ad1848_mixer(codec)) < 0)
781 return error;
782#endif
783 strcpy(card->driver, chip->name); 769 strcpy(card->driver, chip->name);
784 sprintf(card->shortname, "OPTi %s", card->driver); 770 sprintf(card->shortname, "OPTi %s", card->driver);
785#if defined(CS4231) || defined(OPTi93X) 771#if defined(CS4231) || defined(OPTi93X)
diff --git a/sound/isa/sb/emu8000.c b/sound/isa/sb/emu8000.c
index b35be7d9a9fa..96678d5d3834 100644
--- a/sound/isa/sb/emu8000.c
+++ b/sound/isa/sb/emu8000.c
@@ -1023,7 +1023,8 @@ snd_emu8000_create_mixer(struct snd_card *card, struct snd_emu8000 *emu)
1023{ 1023{
1024 int i, err = 0; 1024 int i, err = 0;
1025 1025
1026 snd_assert(emu != NULL && card != NULL, return -EINVAL); 1026 if (snd_BUG_ON(!emu || !card))
1027 return -EINVAL;
1027 1028
1028 spin_lock_init(&emu->control_lock); 1029 spin_lock_init(&emu->control_lock);
1029 1030
diff --git a/sound/isa/sb/emu8000_patch.c b/sound/isa/sb/emu8000_patch.c
index 1be16c9700f0..c99c6078be33 100644
--- a/sound/isa/sb/emu8000_patch.c
+++ b/sound/isa/sb/emu8000_patch.c
@@ -156,7 +156,8 @@ snd_emu8000_sample_new(struct snd_emux *rec, struct snd_sf_sample *sp,
156 struct snd_emu8000 *emu; 156 struct snd_emu8000 *emu;
157 157
158 emu = rec->hw; 158 emu = rec->hw;
159 snd_assert(sp != NULL, return -EINVAL); 159 if (snd_BUG_ON(!sp))
160 return -EINVAL;
160 161
161 if (sp->v.size == 0) 162 if (sp->v.size == 0)
162 return 0; 163 return 0;
diff --git a/sound/isa/sb/sb16_csp.c b/sound/isa/sb/sb16_csp.c
index 35f3d7b16536..49037d074c71 100644
--- a/sound/isa/sb/sb16_csp.c
+++ b/sound/isa/sb/sb16_csp.c
@@ -198,7 +198,8 @@ static int snd_sb_csp_ioctl(struct snd_hwdep * hw, struct file *file, unsigned i
198 struct snd_sb_csp_start start_info; 198 struct snd_sb_csp_start start_info;
199 int err; 199 int err;
200 200
201 snd_assert(p != NULL, return -EINVAL); 201 if (snd_BUG_ON(!p))
202 return -EINVAL;
202 203
203 if (snd_sb_csp_check_version(p)) 204 if (snd_sb_csp_check_version(p))
204 return -ENODEV; 205 return -ENODEV;
@@ -1046,7 +1047,8 @@ static int snd_sb_qsound_build(struct snd_sb_csp * p)
1046 struct snd_card *card; 1047 struct snd_card *card;
1047 int err; 1048 int err;
1048 1049
1049 snd_assert(p != NULL, return -EINVAL); 1050 if (snd_BUG_ON(!p))
1051 return -EINVAL;
1050 1052
1051 card = p->chip->card; 1053 card = p->chip->card;
1052 p->qpos_left = p->qpos_right = SNDRV_SB_CSP_QSOUND_MAX_RIGHT / 2; 1054 p->qpos_left = p->qpos_right = SNDRV_SB_CSP_QSOUND_MAX_RIGHT / 2;
@@ -1071,7 +1073,8 @@ static void snd_sb_qsound_destroy(struct snd_sb_csp * p)
1071 struct snd_card *card; 1073 struct snd_card *card;
1072 unsigned long flags; 1074 unsigned long flags;
1073 1075
1074 snd_assert(p != NULL, return); 1076 if (snd_BUG_ON(!p))
1077 return;
1075 1078
1076 card = p->chip->card; 1079 card = p->chip->card;
1077 1080
diff --git a/sound/isa/sb/sb16_main.c b/sound/isa/sb/sb16_main.c
index f7e8192270ae..2a6cc1cfe945 100644
--- a/sound/isa/sb/sb16_main.c
+++ b/sound/isa/sb/sb16_main.c
@@ -669,7 +669,8 @@ static int snd_sb16_capture_close(struct snd_pcm_substream *substream)
669static int snd_sb16_set_dma_mode(struct snd_sb *chip, int what) 669static int snd_sb16_set_dma_mode(struct snd_sb *chip, int what)
670{ 670{
671 if (chip->dma8 < 0 || chip->dma16 < 0) { 671 if (chip->dma8 < 0 || chip->dma16 < 0) {
672 snd_assert(what == 0, return -EINVAL); 672 if (snd_BUG_ON(what))
673 return -EINVAL;
673 return 0; 674 return 0;
674 } 675 }
675 if (what == 0) { 676 if (what == 0) {
diff --git a/sound/isa/sb/sb8_main.c b/sound/isa/sb/sb8_main.c
index fe03bb820532..658d55769c9c 100644
--- a/sound/isa/sb/sb8_main.c
+++ b/sound/isa/sb/sb8_main.c
@@ -111,7 +111,9 @@ static int snd_sb8_playback_prepare(struct snd_pcm_substream *substream)
111 switch (chip->hardware) { 111 switch (chip->hardware) {
112 case SB_HW_PRO: 112 case SB_HW_PRO:
113 if (runtime->channels > 1) { 113 if (runtime->channels > 1) {
114 snd_assert(rate == SB8_RATE(11025) || rate == SB8_RATE(22050), return -EINVAL); 114 if (snd_BUG_ON(rate != SB8_RATE(11025) &&
115 rate != SB8_RATE(22050)))
116 return -EINVAL;
115 chip->playback_format = SB_DSP_HI_OUTPUT_AUTO; 117 chip->playback_format = SB_DSP_HI_OUTPUT_AUTO;
116 break; 118 break;
117 } 119 }
@@ -237,7 +239,9 @@ static int snd_sb8_capture_prepare(struct snd_pcm_substream *substream)
237 switch (chip->hardware) { 239 switch (chip->hardware) {
238 case SB_HW_PRO: 240 case SB_HW_PRO:
239 if (runtime->channels > 1) { 241 if (runtime->channels > 1) {
240 snd_assert(rate == SB8_RATE(11025) || rate == SB8_RATE(22050), return -EINVAL); 242 if (snd_BUG_ON(rate != SB8_RATE(11025) &&
243 rate != SB8_RATE(22050)))
244 return -EINVAL;
241 chip->capture_format = SB_DSP_HI_INPUT_AUTO; 245 chip->capture_format = SB_DSP_HI_INPUT_AUTO;
242 break; 246 break;
243 } 247 }
diff --git a/sound/isa/sb/sb_common.c b/sound/isa/sb/sb_common.c
index b432d9ae874b..27a651502251 100644
--- a/sound/isa/sb/sb_common.c
+++ b/sound/isa/sb/sb_common.c
@@ -219,7 +219,8 @@ int snd_sbdsp_create(struct snd_card *card,
219 .dev_free = snd_sbdsp_dev_free, 219 .dev_free = snd_sbdsp_dev_free,
220 }; 220 };
221 221
222 snd_assert(r_chip != NULL, return -EINVAL); 222 if (snd_BUG_ON(!r_chip))
223 return -EINVAL;
223 *r_chip = NULL; 224 *r_chip = NULL;
224 chip = kzalloc(sizeof(*chip), GFP_KERNEL); 225 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
225 if (chip == NULL) 226 if (chip == NULL)
diff --git a/sound/isa/sb/sb_mixer.c b/sound/isa/sb/sb_mixer.c
index 73d4572d136b..406a431af91e 100644
--- a/sound/isa/sb/sb_mixer.c
+++ b/sound/isa/sb/sb_mixer.c
@@ -792,7 +792,8 @@ int snd_sbmixer_new(struct snd_sb *chip)
792 struct snd_card *card; 792 struct snd_card *card;
793 int err; 793 int err;
794 794
795 snd_assert(chip != NULL && chip->card != NULL, return -EINVAL); 795 if (snd_BUG_ON(!chip || !chip->card))
796 return -EINVAL;
796 797
797 card = chip->card; 798 card = chip->card;
798 799
@@ -925,7 +926,8 @@ static unsigned char als4000_saved_regs[] = {
925static void save_mixer(struct snd_sb *chip, unsigned char *regs, int num_regs) 926static void save_mixer(struct snd_sb *chip, unsigned char *regs, int num_regs)
926{ 927{
927 unsigned char *val = chip->saved_regs; 928 unsigned char *val = chip->saved_regs;
928 snd_assert(num_regs <= ARRAY_SIZE(chip->saved_regs), return); 929 if (snd_BUG_ON(num_regs > ARRAY_SIZE(chip->saved_regs)))
930 return;
929 for (; num_regs; num_regs--) 931 for (; num_regs; num_regs--)
930 *val++ = snd_sbmixer_read(chip, *regs++); 932 *val++ = snd_sbmixer_read(chip, *regs++);
931} 933}
@@ -933,7 +935,8 @@ static void save_mixer(struct snd_sb *chip, unsigned char *regs, int num_regs)
933static void restore_mixer(struct snd_sb *chip, unsigned char *regs, int num_regs) 935static void restore_mixer(struct snd_sb *chip, unsigned char *regs, int num_regs)
934{ 936{
935 unsigned char *val = chip->saved_regs; 937 unsigned char *val = chip->saved_regs;
936 snd_assert(num_regs <= ARRAY_SIZE(chip->saved_regs), return); 938 if (snd_BUG_ON(num_regs > ARRAY_SIZE(chip->saved_regs)))
939 return;
937 for (; num_regs; num_regs--) 940 for (; num_regs; num_regs--)
938 snd_sbmixer_write(chip, *regs++, *val++); 941 snd_sbmixer_write(chip, *regs++, *val++);
939} 942}
diff --git a/sound/isa/sc6000.c b/sound/isa/sc6000.c
index da3d152bcad4..ca35924dc3b3 100644
--- a/sound/isa/sc6000.c
+++ b/sound/isa/sc6000.c
@@ -29,7 +29,7 @@
29#include <linux/io.h> 29#include <linux/io.h>
30#include <asm/dma.h> 30#include <asm/dma.h>
31#include <sound/core.h> 31#include <sound/core.h>
32#include <sound/ad1848.h> 32#include <sound/wss.h>
33#include <sound/opl3.h> 33#include <sound/opl3.h>
34#include <sound/mpu401.h> 34#include <sound/mpu401.h>
35#include <sound/control.h> 35#include <sound/control.h>
@@ -397,7 +397,7 @@ static int __devinit sc6000_init_board(char __iomem *vport, int irq, int dma,
397 return 0; 397 return 0;
398} 398}
399 399
400static int __devinit snd_sc6000_mixer(struct snd_ad1848 *chip) 400static int __devinit snd_sc6000_mixer(struct snd_wss *chip)
401{ 401{
402 struct snd_card *card = chip->card; 402 struct snd_card *card = chip->card;
403 struct snd_ctl_elem_id id1, id2; 403 struct snd_ctl_elem_id id1, id2;
@@ -483,7 +483,7 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev)
483 int xirq = irq[dev]; 483 int xirq = irq[dev];
484 int xdma = dma[dev]; 484 int xdma = dma[dev];
485 struct snd_card *card; 485 struct snd_card *card;
486 struct snd_ad1848 *chip; 486 struct snd_wss *chip;
487 struct snd_opl3 *opl3; 487 struct snd_opl3 *opl3;
488 char __iomem *vport; 488 char __iomem *vport;
489 char __iomem *vmss_port; 489 char __iomem *vmss_port;
@@ -548,21 +548,21 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev)
548 if (err < 0) 548 if (err < 0)
549 goto err_unmap2; 549 goto err_unmap2;
550 550
551 err = snd_ad1848_create(card, mss_port[dev] + 4, xirq, xdma, 551 err = snd_wss_create(card, mss_port[dev] + 4, -1, xirq, xdma, -1,
552 AD1848_HW_DETECT, &chip); 552 WSS_HW_DETECT, 0, &chip);
553 if (err < 0) 553 if (err < 0)
554 goto err_unmap2; 554 goto err_unmap2;
555 card->private_data = chip; 555 card->private_data = chip;
556 556
557 err = snd_ad1848_pcm(chip, 0, NULL); 557 err = snd_wss_pcm(chip, 0, NULL);
558 if (err < 0) { 558 if (err < 0) {
559 snd_printk(KERN_ERR PFX 559 snd_printk(KERN_ERR PFX
560 "error creating new ad1848 PCM device\n"); 560 "error creating new WSS PCM device\n");
561 goto err_unmap2; 561 goto err_unmap2;
562 } 562 }
563 err = snd_ad1848_mixer(chip); 563 err = snd_wss_mixer(chip);
564 if (err < 0) { 564 if (err < 0) {
565 snd_printk(KERN_ERR PFX "error creating new ad1848 mixer\n"); 565 snd_printk(KERN_ERR PFX "error creating new WSS mixer\n");
566 goto err_unmap2; 566 goto err_unmap2;
567 } 567 }
568 err = snd_sc6000_mixer(chip); 568 err = snd_sc6000_mixer(chip);
diff --git a/sound/isa/sgalaxy.c b/sound/isa/sgalaxy.c
index a07274ecb149..2c7503bf1271 100644
--- a/sound/isa/sgalaxy.c
+++ b/sound/isa/sgalaxy.c
@@ -31,7 +31,7 @@
31#include <asm/dma.h> 31#include <asm/dma.h>
32#include <sound/core.h> 32#include <sound/core.h>
33#include <sound/sb.h> 33#include <sound/sb.h>
34#include <sound/ad1848.h> 34#include <sound/wss.h>
35#include <sound/control.h> 35#include <sound/control.h>
36#define SNDRV_LEGACY_FIND_FREE_IRQ 36#define SNDRV_LEGACY_FIND_FREE_IRQ
37#define SNDRV_LEGACY_FIND_FREE_DMA 37#define SNDRV_LEGACY_FIND_FREE_DMA
@@ -175,12 +175,14 @@ static int __devinit snd_sgalaxy_detect(int dev, int irq, int dma)
175 return snd_sgalaxy_setup_wss(wssport[dev], irq, dma); 175 return snd_sgalaxy_setup_wss(wssport[dev], irq, dma);
176} 176}
177 177
178static struct ad1848_mix_elem snd_sgalaxy_controls[] = { 178static struct snd_kcontrol_new snd_sgalaxy_controls[] = {
179AD1848_DOUBLE("Aux Playback Switch", 0, SGALAXY_AUXC_LEFT, SGALAXY_AUXC_RIGHT, 7, 7, 1, 1), 179WSS_DOUBLE("Aux Playback Switch", 0,
180AD1848_DOUBLE("Aux Playback Volume", 0, SGALAXY_AUXC_LEFT, SGALAXY_AUXC_RIGHT, 0, 0, 31, 0) 180 SGALAXY_AUXC_LEFT, SGALAXY_AUXC_RIGHT, 7, 7, 1, 1),
181WSS_DOUBLE("Aux Playback Volume", 0,
182 SGALAXY_AUXC_LEFT, SGALAXY_AUXC_RIGHT, 0, 0, 31, 0)
181}; 183};
182 184
183static int __devinit snd_sgalaxy_mixer(struct snd_ad1848 *chip) 185static int __devinit snd_sgalaxy_mixer(struct snd_wss *chip)
184{ 186{
185 struct snd_card *card = chip->card; 187 struct snd_card *card = chip->card;
186 struct snd_ctl_elem_id id1, id2; 188 struct snd_ctl_elem_id id1, id2;
@@ -210,7 +212,9 @@ static int __devinit snd_sgalaxy_mixer(struct snd_ad1848 *chip)
210 return err; 212 return err;
211 /* build AUX2 input */ 213 /* build AUX2 input */
212 for (idx = 0; idx < ARRAY_SIZE(snd_sgalaxy_controls); idx++) { 214 for (idx = 0; idx < ARRAY_SIZE(snd_sgalaxy_controls); idx++) {
213 if ((err = snd_ad1848_add_ctl_elem(chip, &snd_sgalaxy_controls[idx])) < 0) 215 err = snd_ctl_add(card,
216 snd_ctl_new1(&snd_sgalaxy_controls[idx], chip));
217 if (err < 0)
214 return err; 218 return err;
215 } 219 }
216 return 0; 220 return 0;
@@ -237,7 +241,7 @@ static int __devinit snd_sgalaxy_probe(struct device *devptr, unsigned int dev)
237 static int possible_dmas[] = {1, 3, 0, -1}; 241 static int possible_dmas[] = {1, 3, 0, -1};
238 int err, xirq, xdma1; 242 int err, xirq, xdma1;
239 struct snd_card *card; 243 struct snd_card *card;
240 struct snd_ad1848 *chip; 244 struct snd_wss *chip;
241 245
242 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); 246 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
243 if (card == NULL) 247 if (card == NULL)
@@ -263,18 +267,21 @@ static int __devinit snd_sgalaxy_probe(struct device *devptr, unsigned int dev)
263 if ((err = snd_sgalaxy_detect(dev, xirq, xdma1)) < 0) 267 if ((err = snd_sgalaxy_detect(dev, xirq, xdma1)) < 0)
264 goto _err; 268 goto _err;
265 269
266 if ((err = snd_ad1848_create(card, wssport[dev] + 4, 270 err = snd_wss_create(card, wssport[dev] + 4, -1,
267 xirq, xdma1, 271 xirq, xdma1, -1,
268 AD1848_HW_DETECT, &chip)) < 0) 272 WSS_HW_DETECT, 0, &chip);
273 if (err < 0)
269 goto _err; 274 goto _err;
270 card->private_data = chip; 275 card->private_data = chip;
271 276
272 if ((err = snd_ad1848_pcm(chip, 0, NULL)) < 0) { 277 err = snd_wss_pcm(chip, 0, NULL);
273 snd_printdd(PFX "error creating new ad1848 PCM device\n"); 278 if (err < 0) {
279 snd_printdd(PFX "error creating new WSS PCM device\n");
274 goto _err; 280 goto _err;
275 } 281 }
276 if ((err = snd_ad1848_mixer(chip)) < 0) { 282 err = snd_wss_mixer(chip);
277 snd_printdd(PFX "error creating new ad1848 mixer\n"); 283 if (err < 0) {
284 snd_printdd(PFX "error creating new WSS mixer\n");
278 goto _err; 285 goto _err;
279 } 286 }
280 if ((err = snd_sgalaxy_mixer(chip)) < 0) { 287 if ((err = snd_sgalaxy_mixer(chip)) < 0) {
@@ -312,7 +319,7 @@ static int snd_sgalaxy_suspend(struct device *pdev, unsigned int n,
312 pm_message_t state) 319 pm_message_t state)
313{ 320{
314 struct snd_card *card = dev_get_drvdata(pdev); 321 struct snd_card *card = dev_get_drvdata(pdev);
315 struct snd_ad1848 *chip = card->private_data; 322 struct snd_wss *chip = card->private_data;
316 323
317 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 324 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
318 chip->suspend(chip); 325 chip->suspend(chip);
@@ -322,11 +329,11 @@ static int snd_sgalaxy_suspend(struct device *pdev, unsigned int n,
322static int snd_sgalaxy_resume(struct device *pdev, unsigned int n) 329static int snd_sgalaxy_resume(struct device *pdev, unsigned int n)
323{ 330{
324 struct snd_card *card = dev_get_drvdata(pdev); 331 struct snd_card *card = dev_get_drvdata(pdev);
325 struct snd_ad1848 *chip = card->private_data; 332 struct snd_wss *chip = card->private_data;
326 333
327 chip->resume(chip); 334 chip->resume(chip);
328 snd_ad1848_out(chip, SGALAXY_AUXC_LEFT, chip->image[SGALAXY_AUXC_LEFT]); 335 snd_wss_out(chip, SGALAXY_AUXC_LEFT, chip->image[SGALAXY_AUXC_LEFT]);
329 snd_ad1848_out(chip, SGALAXY_AUXC_RIGHT, chip->image[SGALAXY_AUXC_RIGHT]); 336 snd_wss_out(chip, SGALAXY_AUXC_RIGHT, chip->image[SGALAXY_AUXC_RIGHT]);
330 337
331 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 338 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
332 return 0; 339 return 0;
diff --git a/sound/isa/sscape.c b/sound/isa/sscape.c
index 06ad7863dff5..48a16d865834 100644
--- a/sound/isa/sscape.c
+++ b/sound/isa/sscape.c
@@ -31,7 +31,7 @@
31#include <asm/dma.h> 31#include <asm/dma.h>
32#include <sound/core.h> 32#include <sound/core.h>
33#include <sound/hwdep.h> 33#include <sound/hwdep.h>
34#include <sound/cs4231.h> 34#include <sound/wss.h>
35#include <sound/mpu401.h> 35#include <sound/mpu401.h>
36#include <sound/initval.h> 36#include <sound/initval.h>
37 37
@@ -147,7 +147,7 @@ struct soundscape {
147 enum card_type type; 147 enum card_type type;
148 struct resource *io_res; 148 struct resource *io_res;
149 struct resource *wss_res; 149 struct resource *wss_res;
150 struct snd_cs4231 *chip; 150 struct snd_wss *chip;
151 struct snd_mpu401 *mpu; 151 struct snd_mpu401 *mpu;
152 struct snd_hwdep *hw; 152 struct snd_hwdep *hw;
153 153
@@ -726,7 +726,7 @@ static int sscape_midi_info(struct snd_kcontrol *ctl,
726static int sscape_midi_get(struct snd_kcontrol *kctl, 726static int sscape_midi_get(struct snd_kcontrol *kctl,
727 struct snd_ctl_elem_value *uctl) 727 struct snd_ctl_elem_value *uctl)
728{ 728{
729 struct snd_cs4231 *chip = snd_kcontrol_chip(kctl); 729 struct snd_wss *chip = snd_kcontrol_chip(kctl);
730 struct snd_card *card = chip->card; 730 struct snd_card *card = chip->card;
731 register struct soundscape *s = get_card_soundscape(card); 731 register struct soundscape *s = get_card_soundscape(card);
732 unsigned long flags; 732 unsigned long flags;
@@ -746,7 +746,7 @@ static int sscape_midi_get(struct snd_kcontrol *kctl,
746static int sscape_midi_put(struct snd_kcontrol *kctl, 746static int sscape_midi_put(struct snd_kcontrol *kctl,
747 struct snd_ctl_elem_value *uctl) 747 struct snd_ctl_elem_value *uctl)
748{ 748{
749 struct snd_cs4231 *chip = snd_kcontrol_chip(kctl); 749 struct snd_wss *chip = snd_kcontrol_chip(kctl);
750 struct snd_card *card = chip->card; 750 struct snd_card *card = chip->card;
751 register struct soundscape *s = get_card_soundscape(card); 751 register struct soundscape *s = get_card_soundscape(card);
752 unsigned long flags; 752 unsigned long flags;
@@ -958,7 +958,9 @@ static int __devinit create_mpu401(struct snd_card *card, int devnum, unsigned l
958 * Override for the CS4231 playback format function. 958 * Override for the CS4231 playback format function.
959 * The AD1845 has much simpler format and rate selection. 959 * The AD1845 has much simpler format and rate selection.
960 */ 960 */
961static void ad1845_playback_format(struct snd_cs4231 * chip, struct snd_pcm_hw_params *params, unsigned char format) 961static void ad1845_playback_format(struct snd_wss *chip,
962 struct snd_pcm_hw_params *params,
963 unsigned char format)
962{ 964{
963 unsigned long flags; 965 unsigned long flags;
964 unsigned rate = params_rate(params); 966 unsigned rate = params_rate(params);
@@ -983,9 +985,9 @@ static void ad1845_playback_format(struct snd_cs4231 * chip, struct snd_pcm_hw_p
983 * NOTE: We seem to need to write to the MSB before the LSB 985 * NOTE: We seem to need to write to the MSB before the LSB
984 * to get the correct sample frequency. 986 * to get the correct sample frequency.
985 */ 987 */
986 snd_cs4231_out(chip, CS4231_PLAYBK_FORMAT, (format & 0xf0)); 988 snd_wss_out(chip, CS4231_PLAYBK_FORMAT, (format & 0xf0));
987 snd_cs4231_out(chip, AD1845_FREQ_SEL_MSB, (unsigned char) (rate >> 8)); 989 snd_wss_out(chip, AD1845_FREQ_SEL_MSB, (unsigned char) (rate >> 8));
988 snd_cs4231_out(chip, AD1845_FREQ_SEL_LSB, (unsigned char) rate); 990 snd_wss_out(chip, AD1845_FREQ_SEL_LSB, (unsigned char) rate);
989 991
990 spin_unlock_irqrestore(&chip->reg_lock, flags); 992 spin_unlock_irqrestore(&chip->reg_lock, flags);
991} 993}
@@ -994,7 +996,9 @@ static void ad1845_playback_format(struct snd_cs4231 * chip, struct snd_pcm_hw_p
994 * Override for the CS4231 capture format function. 996 * Override for the CS4231 capture format function.
995 * The AD1845 has much simpler format and rate selection. 997 * The AD1845 has much simpler format and rate selection.
996 */ 998 */
997static void ad1845_capture_format(struct snd_cs4231 * chip, struct snd_pcm_hw_params *params, unsigned char format) 999static void ad1845_capture_format(struct snd_wss *chip,
1000 struct snd_pcm_hw_params *params,
1001 unsigned char format)
998{ 1002{
999 unsigned long flags; 1003 unsigned long flags;
1000 unsigned rate = params_rate(params); 1004 unsigned rate = params_rate(params);
@@ -1019,9 +1023,9 @@ static void ad1845_capture_format(struct snd_cs4231 * chip, struct snd_pcm_hw_pa
1019 * NOTE: We seem to need to write to the MSB before the LSB 1023 * NOTE: We seem to need to write to the MSB before the LSB
1020 * to get the correct sample frequency. 1024 * to get the correct sample frequency.
1021 */ 1025 */
1022 snd_cs4231_out(chip, CS4231_REC_FORMAT, (format & 0xf0)); 1026 snd_wss_out(chip, CS4231_REC_FORMAT, (format & 0xf0));
1023 snd_cs4231_out(chip, AD1845_FREQ_SEL_MSB, (unsigned char) (rate >> 8)); 1027 snd_wss_out(chip, AD1845_FREQ_SEL_MSB, (unsigned char) (rate >> 8));
1024 snd_cs4231_out(chip, AD1845_FREQ_SEL_LSB, (unsigned char) rate); 1028 snd_wss_out(chip, AD1845_FREQ_SEL_LSB, (unsigned char) rate);
1025 1029
1026 spin_unlock_irqrestore(&chip->reg_lock, flags); 1030 spin_unlock_irqrestore(&chip->reg_lock, flags);
1027} 1031}
@@ -1036,7 +1040,7 @@ static int __devinit create_ad1845(struct snd_card *card, unsigned port,
1036 int irq, int dma1, int dma2) 1040 int irq, int dma1, int dma2)
1037{ 1041{
1038 register struct soundscape *sscape = get_card_soundscape(card); 1042 register struct soundscape *sscape = get_card_soundscape(card);
1039 struct snd_cs4231 *chip; 1043 struct snd_wss *chip;
1040 int err; 1044 int err;
1041 1045
1042 if (sscape->type == SSCAPE_VIVO) 1046 if (sscape->type == SSCAPE_VIVO)
@@ -1045,9 +1049,8 @@ static int __devinit create_ad1845(struct snd_card *card, unsigned port,
1045 if (dma1 == dma2) 1049 if (dma1 == dma2)
1046 dma2 = -1; 1050 dma2 = -1;
1047 1051
1048 err = snd_cs4231_create(card, 1052 err = snd_wss_create(card, port, -1, irq, dma1, dma2,
1049 port, -1, irq, dma1, dma2, 1053 WSS_HW_DETECT, WSS_HWSHARE_DMA1, &chip);
1050 CS4231_HW_DETECT, CS4231_HWSHARE_DMA1, &chip);
1051 if (!err) { 1054 if (!err) {
1052 unsigned long flags; 1055 unsigned long flags;
1053 struct snd_pcm *pcm; 1056 struct snd_pcm *pcm;
@@ -1063,11 +1066,11 @@ static int __devinit create_ad1845(struct snd_card *card, unsigned port,
1063 * 1066 *
1064#define AD1845_IFACE_CONFIG \ 1067#define AD1845_IFACE_CONFIG \
1065 (CS4231_AUTOCALIB | CS4231_RECORD_ENABLE | CS4231_PLAYBACK_ENABLE) 1068 (CS4231_AUTOCALIB | CS4231_RECORD_ENABLE | CS4231_PLAYBACK_ENABLE)
1066 snd_cs4231_mce_up(chip); 1069 snd_wss_mce_up(chip);
1067 spin_lock_irqsave(&chip->reg_lock, flags); 1070 spin_lock_irqsave(&chip->reg_lock, flags);
1068 snd_cs4231_out(chip, CS4231_IFACE_CTRL, AD1845_IFACE_CONFIG); 1071 snd_wss_out(chip, CS4231_IFACE_CTRL, AD1845_IFACE_CONFIG);
1069 spin_unlock_irqrestore(&chip->reg_lock, flags); 1072 spin_unlock_irqrestore(&chip->reg_lock, flags);
1070 snd_cs4231_mce_down(chip); 1073 snd_wss_mce_down(chip);
1071 */ 1074 */
1072 1075
1073 if (sscape->type != SSCAPE_VIVO) { 1076 if (sscape->type != SSCAPE_VIVO) {
@@ -1077,11 +1080,11 @@ static int __devinit create_ad1845(struct snd_card *card, unsigned port,
1077 * be 14.31818 MHz, because we must set this register 1080 * be 14.31818 MHz, because we must set this register
1078 * to get the playback to sound correct ... 1081 * to get the playback to sound correct ...
1079 */ 1082 */
1080 snd_cs4231_mce_up(chip); 1083 snd_wss_mce_up(chip);
1081 spin_lock_irqsave(&chip->reg_lock, flags); 1084 spin_lock_irqsave(&chip->reg_lock, flags);
1082 snd_cs4231_out(chip, AD1845_CRYS_CLOCK_SEL, 0x20); 1085 snd_wss_out(chip, AD1845_CRYS_CLOCK_SEL, 0x20);
1083 spin_unlock_irqrestore(&chip->reg_lock, flags); 1086 spin_unlock_irqrestore(&chip->reg_lock, flags);
1084 snd_cs4231_mce_down(chip); 1087 snd_wss_mce_down(chip);
1085 1088
1086 /* 1089 /*
1087 * More custom configuration: 1090 * More custom configuration:
@@ -1089,28 +1092,28 @@ static int __devinit create_ad1845(struct snd_card *card, unsigned port,
1089 * b) enable frequency selection (for capture/playback) 1092 * b) enable frequency selection (for capture/playback)
1090 */ 1093 */
1091 spin_lock_irqsave(&chip->reg_lock, flags); 1094 spin_lock_irqsave(&chip->reg_lock, flags);
1092 snd_cs4231_out(chip, CS4231_MISC_INFO, 1095 snd_wss_out(chip, CS4231_MISC_INFO,
1093 CS4231_MODE2 | 0x10); 1096 CS4231_MODE2 | 0x10);
1094 val = snd_cs4231_in(chip, AD1845_PWR_DOWN_CTRL); 1097 val = snd_wss_in(chip, AD1845_PWR_DOWN_CTRL);
1095 snd_cs4231_out(chip, AD1845_PWR_DOWN_CTRL, 1098 snd_wss_out(chip, AD1845_PWR_DOWN_CTRL,
1096 val | AD1845_FREQ_SEL_ENABLE); 1099 val | AD1845_FREQ_SEL_ENABLE);
1097 spin_unlock_irqrestore(&chip->reg_lock, flags); 1100 spin_unlock_irqrestore(&chip->reg_lock, flags);
1098 } 1101 }
1099 1102
1100 err = snd_cs4231_pcm(chip, 0, &pcm); 1103 err = snd_wss_pcm(chip, 0, &pcm);
1101 if (err < 0) { 1104 if (err < 0) {
1102 snd_printk(KERN_ERR "sscape: No PCM device " 1105 snd_printk(KERN_ERR "sscape: No PCM device "
1103 "for AD1845 chip\n"); 1106 "for AD1845 chip\n");
1104 goto _error; 1107 goto _error;
1105 } 1108 }
1106 1109
1107 err = snd_cs4231_mixer(chip); 1110 err = snd_wss_mixer(chip);
1108 if (err < 0) { 1111 if (err < 0) {
1109 snd_printk(KERN_ERR "sscape: No mixer device " 1112 snd_printk(KERN_ERR "sscape: No mixer device "
1110 "for AD1845 chip\n"); 1113 "for AD1845 chip\n");
1111 goto _error; 1114 goto _error;
1112 } 1115 }
1113 err = snd_cs4231_timer(chip, 0, NULL); 1116 err = snd_wss_timer(chip, 0, NULL);
1114 if (err < 0) { 1117 if (err < 0) {
1115 snd_printk(KERN_ERR "sscape: No timer device " 1118 snd_printk(KERN_ERR "sscape: No timer device "
1116 "for AD1845 chip\n"); 1119 "for AD1845 chip\n");
diff --git a/sound/isa/wavefront/wavefront.c b/sound/isa/wavefront/wavefront.c
index 3a6c6fe1ec4d..4c095bc7c729 100644
--- a/sound/isa/wavefront/wavefront.c
+++ b/sound/isa/wavefront/wavefront.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * ALSA card-level driver for Turtle Beach Wavefront cards 2 * ALSA card-level driver for Turtle Beach Wavefront cards
3 * (Maui,Tropez,Tropez+) 3 * (Maui,Tropez,Tropez+)
4 * 4 *
5 * Copyright (c) 1997-1999 by Paul Barton-Davis <pbd@op.net> 5 * Copyright (c) 1997-1999 by Paul Barton-Davis <pbd@op.net>
6 * 6 *
@@ -29,6 +29,7 @@
29#include <sound/core.h> 29#include <sound/core.h>
30#include <sound/initval.h> 30#include <sound/initval.h>
31#include <sound/opl3.h> 31#include <sound/opl3.h>
32#include <sound/wss.h>
32#include <sound/snd_wavefront.h> 33#include <sound/snd_wavefront.h>
33 34
34MODULE_AUTHOR("Paul Barton-Davis <pbd@op.net>"); 35MODULE_AUTHOR("Paul Barton-Davis <pbd@op.net>");
@@ -319,8 +320,8 @@ snd_wavefront_new_midi (struct snd_card *card,
319 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_wavefront_midi_input); 320 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_wavefront_midi_input);
320 321
321 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | 322 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT |
322 SNDRV_RAWMIDI_INFO_INPUT | 323 SNDRV_RAWMIDI_INFO_INPUT |
323 SNDRV_RAWMIDI_INFO_DUPLEX; 324 SNDRV_RAWMIDI_INFO_DUPLEX;
324 325
325 return rmidi; 326 return rmidi;
326} 327}
@@ -363,7 +364,7 @@ static int __devinit
363snd_wavefront_probe (struct snd_card *card, int dev) 364snd_wavefront_probe (struct snd_card *card, int dev)
364{ 365{
365 snd_wavefront_card_t *acard = card->private_data; 366 snd_wavefront_card_t *acard = card->private_data;
366 struct snd_cs4231 *chip; 367 struct snd_wss *chip;
367 struct snd_hwdep *wavefront_synth; 368 struct snd_hwdep *wavefront_synth;
368 struct snd_rawmidi *ics2115_internal_rmidi = NULL; 369 struct snd_rawmidi *ics2115_internal_rmidi = NULL;
369 struct snd_rawmidi *ics2115_external_rmidi = NULL; 370 struct snd_rawmidi *ics2115_external_rmidi = NULL;
@@ -372,21 +373,20 @@ snd_wavefront_probe (struct snd_card *card, int dev)
372 373
373 /* --------- PCM --------------- */ 374 /* --------- PCM --------------- */
374 375
375 if ((err = snd_cs4231_create (card, 376 err = snd_wss_create(card, cs4232_pcm_port[dev], -1,
376 cs4232_pcm_port[dev], 377 cs4232_pcm_irq[dev], dma1[dev], dma2[dev],
377 -1, 378 WSS_HW_DETECT, 0, &chip);
378 cs4232_pcm_irq[dev], 379 if (err < 0) {
379 dma1[dev], 380 snd_printk(KERN_ERR "can't allocate WSS device\n");
380 dma2[dev],
381 CS4231_HW_DETECT, 0, &chip)) < 0) {
382 snd_printk (KERN_ERR "can't allocate CS4231 device\n");
383 return err; 381 return err;
384 } 382 }
385 383
386 if ((err = snd_cs4231_pcm (chip, 0, NULL)) < 0) 384 err = snd_wss_pcm(chip, 0, NULL);
385 if (err < 0)
387 return err; 386 return err;
388 387
389 if ((err = snd_cs4231_timer (chip, 0, NULL)) < 0) 388 err = snd_wss_timer(chip, 0, NULL);
389 if (err < 0)
390 return err; 390 return err;
391 391
392 /* ---------- OPL3 synth --------- */ 392 /* ---------- OPL3 synth --------- */
@@ -394,24 +394,24 @@ snd_wavefront_probe (struct snd_card *card, int dev)
394 if (fm_port[dev] > 0 && fm_port[dev] != SNDRV_AUTO_PORT) { 394 if (fm_port[dev] > 0 && fm_port[dev] != SNDRV_AUTO_PORT) {
395 struct snd_opl3 *opl3; 395 struct snd_opl3 *opl3;
396 396
397 if ((err = snd_opl3_create(card, 397 err = snd_opl3_create(card, fm_port[dev], fm_port[dev] + 2,
398 fm_port[dev], 398 OPL3_HW_OPL3_CS, 0, &opl3);
399 fm_port[dev] + 2, 399 if (err < 0) {
400 OPL3_HW_OPL3_CS,
401 0, &opl3)) < 0) {
402 snd_printk (KERN_ERR "can't allocate or detect OPL3 synth\n"); 400 snd_printk (KERN_ERR "can't allocate or detect OPL3 synth\n");
403 return err; 401 return err;
404 } 402 }
405 403
406 if ((err = snd_opl3_hwdep_new(opl3, hw_dev, 1, NULL)) < 0) 404 err = snd_opl3_hwdep_new(opl3, hw_dev, 1, NULL);
405 if (err < 0)
407 return err; 406 return err;
408 hw_dev++; 407 hw_dev++;
409 } 408 }
410 409
411 /* ------- ICS2115 Wavetable synth ------- */ 410 /* ------- ICS2115 Wavetable synth ------- */
412 411
413 if ((acard->wavefront.res_base = request_region(ics2115_port[dev], 16, 412 acard->wavefront.res_base = request_region(ics2115_port[dev], 16,
414 "ICS2115")) == NULL) { 413 "ICS2115");
414 if (acard->wavefront.res_base == NULL) {
415 snd_printk(KERN_ERR "unable to grab ICS2115 i/o region 0x%lx-0x%lx\n", 415 snd_printk(KERN_ERR "unable to grab ICS2115 i/o region 0x%lx-0x%lx\n",
416 ics2115_port[dev], ics2115_port[dev] + 16 - 1); 416 ics2115_port[dev], ics2115_port[dev] + 16 - 1);
417 return -EBUSY; 417 return -EBUSY;
@@ -425,7 +425,8 @@ snd_wavefront_probe (struct snd_card *card, int dev)
425 acard->wavefront.irq = ics2115_irq[dev]; 425 acard->wavefront.irq = ics2115_irq[dev];
426 acard->wavefront.base = ics2115_port[dev]; 426 acard->wavefront.base = ics2115_port[dev];
427 427
428 if ((wavefront_synth = snd_wavefront_new_synth (card, hw_dev, acard)) == NULL) { 428 wavefront_synth = snd_wavefront_new_synth(card, hw_dev, acard);
429 if (wavefront_synth == NULL) {
429 snd_printk (KERN_ERR "can't create WaveFront synth device\n"); 430 snd_printk (KERN_ERR "can't create WaveFront synth device\n");
430 return -ENOMEM; 431 return -ENOMEM;
431 } 432 }
@@ -436,7 +437,8 @@ snd_wavefront_probe (struct snd_card *card, int dev)
436 437
437 /* --------- Mixer ------------ */ 438 /* --------- Mixer ------------ */
438 439
439 if ((err = snd_cs4231_mixer(chip)) < 0) { 440 err = snd_wss_mixer(chip);
441 if (err < 0) {
440 snd_printk (KERN_ERR "can't allocate mixer device\n"); 442 snd_printk (KERN_ERR "can't allocate mixer device\n");
441 return err; 443 return err;
442 } 444 }
@@ -444,11 +446,11 @@ snd_wavefront_probe (struct snd_card *card, int dev)
444 /* -------- CS4232 MPU-401 interface -------- */ 446 /* -------- CS4232 MPU-401 interface -------- */
445 447
446 if (cs4232_mpu_port[dev] > 0 && cs4232_mpu_port[dev] != SNDRV_AUTO_PORT) { 448 if (cs4232_mpu_port[dev] > 0 && cs4232_mpu_port[dev] != SNDRV_AUTO_PORT) {
447 if ((err = snd_mpu401_uart_new(card, midi_dev, MPU401_HW_CS4232, 449 err = snd_mpu401_uart_new(card, midi_dev, MPU401_HW_CS4232,
448 cs4232_mpu_port[dev], 0, 450 cs4232_mpu_port[dev], 0,
449 cs4232_mpu_irq[dev], 451 cs4232_mpu_irq[dev], IRQF_DISABLED,
450 IRQF_DISABLED, 452 NULL);
451 NULL)) < 0) { 453 if (err < 0) {
452 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");
453 return err; 455 return err;
454 } 456 }
@@ -601,7 +603,7 @@ static struct isa_driver snd_wavefront_driver = {
601 603
602#ifdef CONFIG_PNP 604#ifdef CONFIG_PNP
603static int __devinit snd_wavefront_pnp_detect(struct pnp_card_link *pcard, 605static int __devinit snd_wavefront_pnp_detect(struct pnp_card_link *pcard,
604 const struct pnp_card_device_id *pid) 606 const struct pnp_card_device_id *pid)
605{ 607{
606 static int dev; 608 static int dev;
607 struct snd_card *card; 609 struct snd_card *card;
diff --git a/sound/isa/wavefront/wavefront_fx.c b/sound/isa/wavefront/wavefront_fx.c
index 2efaa7f205aa..dfc449a2194e 100644
--- a/sound/isa/wavefront/wavefront_fx.c
+++ b/sound/isa/wavefront/wavefront_fx.c
@@ -180,11 +180,11 @@ snd_wavefront_fx_ioctl (struct snd_hwdep *sdev, struct file *file,
180 unsigned short *pd; 180 unsigned short *pd;
181 int err = 0; 181 int err = 0;
182 182
183 snd_assert(sdev->card != NULL, return -ENODEV);
184
185 card = sdev->card; 183 card = sdev->card;
186 184 if (snd_BUG_ON(!card))
187 snd_assert(card->private_data != NULL, return -ENODEV); 185 return -ENODEV;
186 if (snd_BUG_ON(!card->private_data))
187 return -ENODEV;
188 188
189 acard = card->private_data; 189 acard = card->private_data;
190 dev = &acard->wavefront; 190 dev = &acard->wavefront;
diff --git a/sound/isa/wavefront/wavefront_midi.c b/sound/isa/wavefront/wavefront_midi.c
index a33384a55b0f..f14a7c0b6998 100644
--- a/sound/isa/wavefront/wavefront_midi.c
+++ b/sound/isa/wavefront/wavefront_midi.c
@@ -235,8 +235,10 @@ static int snd_wavefront_midi_input_open(struct snd_rawmidi_substream *substream
235 snd_wavefront_midi_t *midi; 235 snd_wavefront_midi_t *midi;
236 snd_wavefront_mpu_id mpu; 236 snd_wavefront_mpu_id mpu;
237 237
238 snd_assert(substream != NULL && substream->rmidi != NULL, return -EIO); 238 if (snd_BUG_ON(!substream || !substream->rmidi))
239 snd_assert(substream->rmidi->private_data != NULL, return -EIO); 239 return -ENXIO;
240 if (snd_BUG_ON(!substream->rmidi->private_data))
241 return -ENXIO;
240 242
241 mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data); 243 mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data);
242 244
@@ -257,8 +259,10 @@ static int snd_wavefront_midi_output_open(struct snd_rawmidi_substream *substrea
257 snd_wavefront_midi_t *midi; 259 snd_wavefront_midi_t *midi;
258 snd_wavefront_mpu_id mpu; 260 snd_wavefront_mpu_id mpu;
259 261
260 snd_assert(substream != NULL && substream->rmidi != NULL, return -EIO); 262 if (snd_BUG_ON(!substream || !substream->rmidi))
261 snd_assert(substream->rmidi->private_data != NULL, return -EIO); 263 return -ENXIO;
264 if (snd_BUG_ON(!substream->rmidi->private_data))
265 return -ENXIO;
262 266
263 mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data); 267 mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data);
264 268
@@ -279,8 +283,10 @@ static int snd_wavefront_midi_input_close(struct snd_rawmidi_substream *substrea
279 snd_wavefront_midi_t *midi; 283 snd_wavefront_midi_t *midi;
280 snd_wavefront_mpu_id mpu; 284 snd_wavefront_mpu_id mpu;
281 285
282 snd_assert(substream != NULL && substream->rmidi != NULL, return -EIO); 286 if (snd_BUG_ON(!substream || !substream->rmidi))
283 snd_assert(substream->rmidi->private_data != NULL, return -EIO); 287 return -ENXIO;
288 if (snd_BUG_ON(!substream->rmidi->private_data))
289 return -ENXIO;
284 290
285 mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data); 291 mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data);
286 292
@@ -300,8 +306,10 @@ static int snd_wavefront_midi_output_close(struct snd_rawmidi_substream *substre
300 snd_wavefront_midi_t *midi; 306 snd_wavefront_midi_t *midi;
301 snd_wavefront_mpu_id mpu; 307 snd_wavefront_mpu_id mpu;
302 308
303 snd_assert(substream != NULL && substream->rmidi != NULL, return -EIO); 309 if (snd_BUG_ON(!substream || !substream->rmidi))
304 snd_assert(substream->rmidi->private_data != NULL, return -EIO); 310 return -ENXIO;
311 if (snd_BUG_ON(!substream->rmidi->private_data))
312 return -ENXIO;
305 313
306 mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data); 314 mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data);
307 315
diff --git a/sound/isa/wavefront/wavefront_synth.c b/sound/isa/wavefront/wavefront_synth.c
index 0bb9b9256601..4c410820a994 100644
--- a/sound/isa/wavefront/wavefront_synth.c
+++ b/sound/isa/wavefront/wavefront_synth.c
@@ -1648,9 +1648,10 @@ snd_wavefront_synth_ioctl (struct snd_hwdep *hw, struct file *file,
1648 1648
1649 card = (struct snd_card *) hw->card; 1649 card = (struct snd_card *) hw->card;
1650 1650
1651 snd_assert(card != NULL, return -ENODEV); 1651 if (snd_BUG_ON(!card))
1652 1652 return -ENODEV;
1653 snd_assert(card->private_data != NULL, return -ENODEV); 1653 if (snd_BUG_ON(!card->private_data))
1654 return -ENODEV;
1654 1655
1655 acard = card->private_data; 1656 acard = card->private_data;
1656 dev = &acard->wavefront; 1657 dev = &acard->wavefront;
diff --git a/sound/isa/wss/Makefile b/sound/isa/wss/Makefile
new file mode 100644
index 000000000000..454fee769a31
--- /dev/null
+++ b/sound/isa/wss/Makefile
@@ -0,0 +1,10 @@
1#
2# Makefile for ALSA
3# Copyright (c) 2008 by Jaroslav Kysela <perex@perex.cz>
4#
5
6snd-wss-lib-objs := wss_lib.o
7
8# Toplevel Module Dependency
9obj-$(CONFIG_SND_WSS_LIB) += snd-wss-lib.o
10
diff --git a/sound/isa/wss/wss_lib.c b/sound/isa/wss/wss_lib.c
new file mode 100644
index 000000000000..3d6c5f2838af
--- /dev/null
+++ b/sound/isa/wss/wss_lib.c
@@ -0,0 +1,2322 @@
1/*
2 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
3 * Routines for control of CS4231(A)/CS4232/InterWave & compatible chips
4 *
5 * Bugs:
6 * - sometimes record brokes playback with WSS portion of
7 * Yamaha OPL3-SA3 chip
8 * - CS4231 (GUS MAX) - still trouble with occasional noises
9 * - broken initialization?
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 */
26
27#include <linux/delay.h>
28#include <linux/pm.h>
29#include <linux/init.h>
30#include <linux/interrupt.h>
31#include <linux/slab.h>
32#include <linux/ioport.h>
33#include <sound/core.h>
34#include <sound/wss.h>
35#include <sound/pcm_params.h>
36#include <sound/tlv.h>
37
38#include <asm/io.h>
39#include <asm/dma.h>
40#include <asm/irq.h>
41
42MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
43MODULE_DESCRIPTION("Routines for control of CS4231(A)/CS4232/InterWave & compatible chips");
44MODULE_LICENSE("GPL");
45
46#if 0
47#define SNDRV_DEBUG_MCE
48#endif
49
50/*
51 * Some variables
52 */
53
54static unsigned char freq_bits[14] = {
55 /* 5510 */ 0x00 | CS4231_XTAL2,
56 /* 6620 */ 0x0E | CS4231_XTAL2,
57 /* 8000 */ 0x00 | CS4231_XTAL1,
58 /* 9600 */ 0x0E | CS4231_XTAL1,
59 /* 11025 */ 0x02 | CS4231_XTAL2,
60 /* 16000 */ 0x02 | CS4231_XTAL1,
61 /* 18900 */ 0x04 | CS4231_XTAL2,
62 /* 22050 */ 0x06 | CS4231_XTAL2,
63 /* 27042 */ 0x04 | CS4231_XTAL1,
64 /* 32000 */ 0x06 | CS4231_XTAL1,
65 /* 33075 */ 0x0C | CS4231_XTAL2,
66 /* 37800 */ 0x08 | CS4231_XTAL2,
67 /* 44100 */ 0x0A | CS4231_XTAL2,
68 /* 48000 */ 0x0C | CS4231_XTAL1
69};
70
71static unsigned int rates[14] = {
72 5510, 6620, 8000, 9600, 11025, 16000, 18900, 22050,
73 27042, 32000, 33075, 37800, 44100, 48000
74};
75
76static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
77 .count = ARRAY_SIZE(rates),
78 .list = rates,
79 .mask = 0,
80};
81
82static int snd_wss_xrate(struct snd_pcm_runtime *runtime)
83{
84 return snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
85 &hw_constraints_rates);
86}
87
88static unsigned char snd_wss_original_image[32] =
89{
90 0x00, /* 00/00 - lic */
91 0x00, /* 01/01 - ric */
92 0x9f, /* 02/02 - la1ic */
93 0x9f, /* 03/03 - ra1ic */
94 0x9f, /* 04/04 - la2ic */
95 0x9f, /* 05/05 - ra2ic */
96 0xbf, /* 06/06 - loc */
97 0xbf, /* 07/07 - roc */
98 0x20, /* 08/08 - pdfr */
99 CS4231_AUTOCALIB, /* 09/09 - ic */
100 0x00, /* 0a/10 - pc */
101 0x00, /* 0b/11 - ti */
102 CS4231_MODE2, /* 0c/12 - mi */
103 0xfc, /* 0d/13 - lbc */
104 0x00, /* 0e/14 - pbru */
105 0x00, /* 0f/15 - pbrl */
106 0x80, /* 10/16 - afei */
107 0x01, /* 11/17 - afeii */
108 0x9f, /* 12/18 - llic */
109 0x9f, /* 13/19 - rlic */
110 0x00, /* 14/20 - tlb */
111 0x00, /* 15/21 - thb */
112 0x00, /* 16/22 - la3mic/reserved */
113 0x00, /* 17/23 - ra3mic/reserved */
114 0x00, /* 18/24 - afs */
115 0x00, /* 19/25 - lamoc/version */
116 0xcf, /* 1a/26 - mioc */
117 0x00, /* 1b/27 - ramoc/reserved */
118 0x20, /* 1c/28 - cdfr */
119 0x00, /* 1d/29 - res4 */
120 0x00, /* 1e/30 - cbru */
121 0x00, /* 1f/31 - cbrl */
122};
123
124static unsigned char snd_opti93x_original_image[32] =
125{
126 0x00, /* 00/00 - l_mixout_outctrl */
127 0x00, /* 01/01 - r_mixout_outctrl */
128 0x88, /* 02/02 - l_cd_inctrl */
129 0x88, /* 03/03 - r_cd_inctrl */
130 0x88, /* 04/04 - l_a1/fm_inctrl */
131 0x88, /* 05/05 - r_a1/fm_inctrl */
132 0x80, /* 06/06 - l_dac_inctrl */
133 0x80, /* 07/07 - r_dac_inctrl */
134 0x00, /* 08/08 - ply_dataform_reg */
135 0x00, /* 09/09 - if_conf */
136 0x00, /* 0a/10 - pin_ctrl */
137 0x00, /* 0b/11 - err_init_reg */
138 0x0a, /* 0c/12 - id_reg */
139 0x00, /* 0d/13 - reserved */
140 0x00, /* 0e/14 - ply_upcount_reg */
141 0x00, /* 0f/15 - ply_lowcount_reg */
142 0x88, /* 10/16 - reserved/l_a1_inctrl */
143 0x88, /* 11/17 - reserved/r_a1_inctrl */
144 0x88, /* 12/18 - l_line_inctrl */
145 0x88, /* 13/19 - r_line_inctrl */
146 0x88, /* 14/20 - l_mic_inctrl */
147 0x88, /* 15/21 - r_mic_inctrl */
148 0x80, /* 16/22 - l_out_outctrl */
149 0x80, /* 17/23 - r_out_outctrl */
150 0x00, /* 18/24 - reserved */
151 0x00, /* 19/25 - reserved */
152 0x00, /* 1a/26 - reserved */
153 0x00, /* 1b/27 - reserved */
154 0x00, /* 1c/28 - cap_dataform_reg */
155 0x00, /* 1d/29 - reserved */
156 0x00, /* 1e/30 - cap_upcount_reg */
157 0x00 /* 1f/31 - cap_lowcount_reg */
158};
159
160/*
161 * Basic I/O functions
162 */
163
164static inline void wss_outb(struct snd_wss *chip, u8 offset, u8 val)
165{
166 outb(val, chip->port + offset);
167}
168
169static inline u8 wss_inb(struct snd_wss *chip, u8 offset)
170{
171 return inb(chip->port + offset);
172}
173
174static void snd_wss_wait(struct snd_wss *chip)
175{
176 int timeout;
177
178 for (timeout = 250;
179 timeout > 0 && (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT);
180 timeout--)
181 udelay(100);
182}
183
184static void snd_wss_outm(struct snd_wss *chip, unsigned char reg,
185 unsigned char mask, unsigned char value)
186{
187 unsigned char tmp = (chip->image[reg] & mask) | value;
188
189 snd_wss_wait(chip);
190#ifdef CONFIG_SND_DEBUG
191 if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
192 snd_printk("outm: auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value);
193#endif
194 chip->image[reg] = tmp;
195 if (!chip->calibrate_mute) {
196 wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg);
197 wmb();
198 wss_outb(chip, CS4231P(REG), tmp);
199 mb();
200 }
201}
202
203static void snd_wss_dout(struct snd_wss *chip, unsigned char reg,
204 unsigned char value)
205{
206 int timeout;
207
208 for (timeout = 250;
209 timeout > 0 && (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT);
210 timeout--)
211 udelay(10);
212 wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg);
213 wss_outb(chip, CS4231P(REG), value);
214 mb();
215}
216
217void snd_wss_out(struct snd_wss *chip, unsigned char reg, unsigned char value)
218{
219 snd_wss_wait(chip);
220#ifdef CONFIG_SND_DEBUG
221 if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
222 snd_printk("out: auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value);
223#endif
224 wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg);
225 wss_outb(chip, CS4231P(REG), value);
226 chip->image[reg] = value;
227 mb();
228 snd_printdd("codec out - reg 0x%x = 0x%x\n",
229 chip->mce_bit | reg, value);
230}
231EXPORT_SYMBOL(snd_wss_out);
232
233unsigned char snd_wss_in(struct snd_wss *chip, unsigned char reg)
234{
235 snd_wss_wait(chip);
236#ifdef CONFIG_SND_DEBUG
237 if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
238 snd_printk("in: auto calibration time out - reg = 0x%x\n", reg);
239#endif
240 wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg);
241 mb();
242 return wss_inb(chip, CS4231P(REG));
243}
244EXPORT_SYMBOL(snd_wss_in);
245
246void snd_cs4236_ext_out(struct snd_wss *chip, unsigned char reg,
247 unsigned char val)
248{
249 wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | 0x17);
250 wss_outb(chip, CS4231P(REG),
251 reg | (chip->image[CS4236_EXT_REG] & 0x01));
252 wss_outb(chip, CS4231P(REG), val);
253 chip->eimage[CS4236_REG(reg)] = val;
254#if 0
255 printk("ext out : reg = 0x%x, val = 0x%x\n", reg, val);
256#endif
257}
258EXPORT_SYMBOL(snd_cs4236_ext_out);
259
260unsigned char snd_cs4236_ext_in(struct snd_wss *chip, unsigned char reg)
261{
262 wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | 0x17);
263 wss_outb(chip, CS4231P(REG),
264 reg | (chip->image[CS4236_EXT_REG] & 0x01));
265#if 1
266 return wss_inb(chip, CS4231P(REG));
267#else
268 {
269 unsigned char res;
270 res = wss_inb(chip, CS4231P(REG));
271 printk("ext in : reg = 0x%x, val = 0x%x\n", reg, res);
272 return res;
273 }
274#endif
275}
276EXPORT_SYMBOL(snd_cs4236_ext_in);
277
278#if 0
279
280static void snd_wss_debug(struct snd_wss *chip)
281{
282 printk(KERN_DEBUG
283 "CS4231 REGS: INDEX = 0x%02x "
284 " STATUS = 0x%02x\n",
285 wss_inb(chip, CS4231P(REGSEL)),
286 wss_inb(chip, CS4231P(STATUS)));
287 printk(KERN_DEBUG
288 " 0x00: left input = 0x%02x "
289 " 0x10: alt 1 (CFIG 2) = 0x%02x\n",
290 snd_wss_in(chip, 0x00),
291 snd_wss_in(chip, 0x10));
292 printk(KERN_DEBUG
293 " 0x01: right input = 0x%02x "
294 " 0x11: alt 2 (CFIG 3) = 0x%02x\n",
295 snd_wss_in(chip, 0x01),
296 snd_wss_in(chip, 0x11));
297 printk(KERN_DEBUG
298 " 0x02: GF1 left input = 0x%02x "
299 " 0x12: left line in = 0x%02x\n",
300 snd_wss_in(chip, 0x02),
301 snd_wss_in(chip, 0x12));
302 printk(KERN_DEBUG
303 " 0x03: GF1 right input = 0x%02x "
304 " 0x13: right line in = 0x%02x\n",
305 snd_wss_in(chip, 0x03),
306 snd_wss_in(chip, 0x13));
307 printk(KERN_DEBUG
308 " 0x04: CD left input = 0x%02x "
309 " 0x14: timer low = 0x%02x\n",
310 snd_wss_in(chip, 0x04),
311 snd_wss_in(chip, 0x14));
312 printk(KERN_DEBUG
313 " 0x05: CD right input = 0x%02x "
314 " 0x15: timer high = 0x%02x\n",
315 snd_wss_in(chip, 0x05),
316 snd_wss_in(chip, 0x15));
317 printk(KERN_DEBUG
318 " 0x06: left output = 0x%02x "
319 " 0x16: left MIC (PnP) = 0x%02x\n",
320 snd_wss_in(chip, 0x06),
321 snd_wss_in(chip, 0x16));
322 printk(KERN_DEBUG
323 " 0x07: right output = 0x%02x "
324 " 0x17: right MIC (PnP) = 0x%02x\n",
325 snd_wss_in(chip, 0x07),
326 snd_wss_in(chip, 0x17));
327 printk(KERN_DEBUG
328 " 0x08: playback format = 0x%02x "
329 " 0x18: IRQ status = 0x%02x\n",
330 snd_wss_in(chip, 0x08),
331 snd_wss_in(chip, 0x18));
332 printk(KERN_DEBUG
333 " 0x09: iface (CFIG 1) = 0x%02x "
334 " 0x19: left line out = 0x%02x\n",
335 snd_wss_in(chip, 0x09),
336 snd_wss_in(chip, 0x19));
337 printk(KERN_DEBUG
338 " 0x0a: pin control = 0x%02x "
339 " 0x1a: mono control = 0x%02x\n",
340 snd_wss_in(chip, 0x0a),
341 snd_wss_in(chip, 0x1a));
342 printk(KERN_DEBUG
343 " 0x0b: init & status = 0x%02x "
344 " 0x1b: right line out = 0x%02x\n",
345 snd_wss_in(chip, 0x0b),
346 snd_wss_in(chip, 0x1b));
347 printk(KERN_DEBUG
348 " 0x0c: revision & mode = 0x%02x "
349 " 0x1c: record format = 0x%02x\n",
350 snd_wss_in(chip, 0x0c),
351 snd_wss_in(chip, 0x1c));
352 printk(KERN_DEBUG
353 " 0x0d: loopback = 0x%02x "
354 " 0x1d: var freq (PnP) = 0x%02x\n",
355 snd_wss_in(chip, 0x0d),
356 snd_wss_in(chip, 0x1d));
357 printk(KERN_DEBUG
358 " 0x0e: ply upr count = 0x%02x "
359 " 0x1e: ply lwr count = 0x%02x\n",
360 snd_wss_in(chip, 0x0e),
361 snd_wss_in(chip, 0x1e));
362 printk(KERN_DEBUG
363 " 0x0f: rec upr count = 0x%02x "
364 " 0x1f: rec lwr count = 0x%02x\n",
365 snd_wss_in(chip, 0x0f),
366 snd_wss_in(chip, 0x1f));
367}
368
369#endif
370
371/*
372 * CS4231 detection / MCE routines
373 */
374
375static void snd_wss_busy_wait(struct snd_wss *chip)
376{
377 int timeout;
378
379 /* huh.. looks like this sequence is proper for CS4231A chip (GUS MAX) */
380 for (timeout = 5; timeout > 0; timeout--)
381 wss_inb(chip, CS4231P(REGSEL));
382 /* end of cleanup sequence */
383 for (timeout = 25000;
384 timeout > 0 && (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT);
385 timeout--)
386 udelay(10);
387}
388
389void snd_wss_mce_up(struct snd_wss *chip)
390{
391 unsigned long flags;
392 int timeout;
393
394 snd_wss_wait(chip);
395#ifdef CONFIG_SND_DEBUG
396 if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
397 snd_printk("mce_up - auto calibration time out (0)\n");
398#endif
399 spin_lock_irqsave(&chip->reg_lock, flags);
400 chip->mce_bit |= CS4231_MCE;
401 timeout = wss_inb(chip, CS4231P(REGSEL));
402 if (timeout == 0x80)
403 snd_printk("mce_up [0x%lx]: serious init problem - codec still busy\n", chip->port);
404 if (!(timeout & CS4231_MCE))
405 wss_outb(chip, CS4231P(REGSEL),
406 chip->mce_bit | (timeout & 0x1f));
407 spin_unlock_irqrestore(&chip->reg_lock, flags);
408}
409EXPORT_SYMBOL(snd_wss_mce_up);
410
411void snd_wss_mce_down(struct snd_wss *chip)
412{
413 unsigned long flags;
414 unsigned long end_time;
415 int timeout;
416 int hw_mask = WSS_HW_CS4231_MASK | WSS_HW_CS4232_MASK | WSS_HW_AD1848;
417
418 snd_wss_busy_wait(chip);
419
420#ifdef CONFIG_SND_DEBUG
421 if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
422 snd_printk("mce_down [0x%lx] - auto calibration time out (0)\n", (long)CS4231P(REGSEL));
423#endif
424 spin_lock_irqsave(&chip->reg_lock, flags);
425 chip->mce_bit &= ~CS4231_MCE;
426 timeout = wss_inb(chip, CS4231P(REGSEL));
427 wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | (timeout & 0x1f));
428 spin_unlock_irqrestore(&chip->reg_lock, flags);
429 if (timeout == 0x80)
430 snd_printk("mce_down [0x%lx]: serious init problem - codec still busy\n", chip->port);
431 if ((timeout & CS4231_MCE) == 0 || !(chip->hardware & hw_mask))
432 return;
433
434 /*
435 * Wait for (possible -- during init auto-calibration may not be set)
436 * calibration process to start. Needs upto 5 sample periods on AD1848
437 * which at the slowest possible rate of 5.5125 kHz means 907 us.
438 */
439 msleep(1);
440
441 snd_printdd("(1) jiffies = %lu\n", jiffies);
442
443 /* check condition up to 250 ms */
444 end_time = jiffies + msecs_to_jiffies(250);
445 while (snd_wss_in(chip, CS4231_TEST_INIT) &
446 CS4231_CALIB_IN_PROGRESS) {
447
448 if (time_after(jiffies, end_time)) {
449 snd_printk(KERN_ERR "mce_down - "
450 "auto calibration time out (2)\n");
451 return;
452 }
453 msleep(1);
454 }
455
456 snd_printdd("(2) jiffies = %lu\n", jiffies);
457
458 /* check condition up to 100 ms */
459 end_time = jiffies + msecs_to_jiffies(100);
460 while (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) {
461 if (time_after(jiffies, end_time)) {
462 snd_printk(KERN_ERR "mce_down - auto calibration time out (3)\n");
463 return;
464 }
465 msleep(1);
466 }
467
468 snd_printdd("(3) jiffies = %lu\n", jiffies);
469 snd_printd("mce_down - exit = 0x%x\n", wss_inb(chip, CS4231P(REGSEL)));
470}
471EXPORT_SYMBOL(snd_wss_mce_down);
472
473static unsigned int snd_wss_get_count(unsigned char format, unsigned int size)
474{
475 switch (format & 0xe0) {
476 case CS4231_LINEAR_16:
477 case CS4231_LINEAR_16_BIG:
478 size >>= 1;
479 break;
480 case CS4231_ADPCM_16:
481 return size >> 2;
482 }
483 if (format & CS4231_STEREO)
484 size >>= 1;
485 return size;
486}
487
488static int snd_wss_trigger(struct snd_pcm_substream *substream,
489 int cmd)
490{
491 struct snd_wss *chip = snd_pcm_substream_chip(substream);
492 int result = 0;
493 unsigned int what;
494 struct snd_pcm_substream *s;
495 int do_start;
496
497 switch (cmd) {
498 case SNDRV_PCM_TRIGGER_START:
499 case SNDRV_PCM_TRIGGER_RESUME:
500 do_start = 1; break;
501 case SNDRV_PCM_TRIGGER_STOP:
502 case SNDRV_PCM_TRIGGER_SUSPEND:
503 do_start = 0; break;
504 default:
505 return -EINVAL;
506 }
507
508 what = 0;
509 snd_pcm_group_for_each_entry(s, substream) {
510 if (s == chip->playback_substream) {
511 what |= CS4231_PLAYBACK_ENABLE;
512 snd_pcm_trigger_done(s, substream);
513 } else if (s == chip->capture_substream) {
514 what |= CS4231_RECORD_ENABLE;
515 snd_pcm_trigger_done(s, substream);
516 }
517 }
518 spin_lock(&chip->reg_lock);
519 if (do_start) {
520 chip->image[CS4231_IFACE_CTRL] |= what;
521 if (chip->trigger)
522 chip->trigger(chip, what, 1);
523 } else {
524 chip->image[CS4231_IFACE_CTRL] &= ~what;
525 if (chip->trigger)
526 chip->trigger(chip, what, 0);
527 }
528 snd_wss_out(chip, CS4231_IFACE_CTRL, chip->image[CS4231_IFACE_CTRL]);
529 spin_unlock(&chip->reg_lock);
530#if 0
531 snd_wss_debug(chip);
532#endif
533 return result;
534}
535
536/*
537 * CODEC I/O
538 */
539
540static unsigned char snd_wss_get_rate(unsigned int rate)
541{
542 int i;
543
544 for (i = 0; i < ARRAY_SIZE(rates); i++)
545 if (rate == rates[i])
546 return freq_bits[i];
547 // snd_BUG();
548 return freq_bits[ARRAY_SIZE(rates) - 1];
549}
550
551static unsigned char snd_wss_get_format(struct snd_wss *chip,
552 int format,
553 int channels)
554{
555 unsigned char rformat;
556
557 rformat = CS4231_LINEAR_8;
558 switch (format) {
559 case SNDRV_PCM_FORMAT_MU_LAW: rformat = CS4231_ULAW_8; break;
560 case SNDRV_PCM_FORMAT_A_LAW: rformat = CS4231_ALAW_8; break;
561 case SNDRV_PCM_FORMAT_S16_LE: rformat = CS4231_LINEAR_16; break;
562 case SNDRV_PCM_FORMAT_S16_BE: rformat = CS4231_LINEAR_16_BIG; break;
563 case SNDRV_PCM_FORMAT_IMA_ADPCM: rformat = CS4231_ADPCM_16; break;
564 }
565 if (channels > 1)
566 rformat |= CS4231_STEREO;
567#if 0
568 snd_printk("get_format: 0x%x (mode=0x%x)\n", format, mode);
569#endif
570 return rformat;
571}
572
573static void snd_wss_calibrate_mute(struct snd_wss *chip, int mute)
574{
575 unsigned long flags;
576
577 mute = mute ? 0x80 : 0;
578 spin_lock_irqsave(&chip->reg_lock, flags);
579 if (chip->calibrate_mute == mute) {
580 spin_unlock_irqrestore(&chip->reg_lock, flags);
581 return;
582 }
583 if (!mute) {
584 snd_wss_dout(chip, CS4231_LEFT_INPUT,
585 chip->image[CS4231_LEFT_INPUT]);
586 snd_wss_dout(chip, CS4231_RIGHT_INPUT,
587 chip->image[CS4231_RIGHT_INPUT]);
588 snd_wss_dout(chip, CS4231_LOOPBACK,
589 chip->image[CS4231_LOOPBACK]);
590 }
591 snd_wss_dout(chip, CS4231_AUX1_LEFT_INPUT,
592 mute | chip->image[CS4231_AUX1_LEFT_INPUT]);
593 snd_wss_dout(chip, CS4231_AUX1_RIGHT_INPUT,
594 mute | chip->image[CS4231_AUX1_RIGHT_INPUT]);
595 snd_wss_dout(chip, CS4231_AUX2_LEFT_INPUT,
596 mute | chip->image[CS4231_AUX2_LEFT_INPUT]);
597 snd_wss_dout(chip, CS4231_AUX2_RIGHT_INPUT,
598 mute | chip->image[CS4231_AUX2_RIGHT_INPUT]);
599 snd_wss_dout(chip, CS4231_LEFT_OUTPUT,
600 mute | chip->image[CS4231_LEFT_OUTPUT]);
601 snd_wss_dout(chip, CS4231_RIGHT_OUTPUT,
602 mute | chip->image[CS4231_RIGHT_OUTPUT]);
603 if (!(chip->hardware & WSS_HW_AD1848_MASK)) {
604 snd_wss_dout(chip, CS4231_LEFT_LINE_IN,
605 mute | chip->image[CS4231_LEFT_LINE_IN]);
606 snd_wss_dout(chip, CS4231_RIGHT_LINE_IN,
607 mute | chip->image[CS4231_RIGHT_LINE_IN]);
608 snd_wss_dout(chip, CS4231_MONO_CTRL,
609 mute ? 0xc0 : chip->image[CS4231_MONO_CTRL]);
610 }
611 if (chip->hardware == WSS_HW_INTERWAVE) {
612 snd_wss_dout(chip, CS4231_LEFT_MIC_INPUT,
613 mute | chip->image[CS4231_LEFT_MIC_INPUT]);
614 snd_wss_dout(chip, CS4231_RIGHT_MIC_INPUT,
615 mute | chip->image[CS4231_RIGHT_MIC_INPUT]);
616 snd_wss_dout(chip, CS4231_LINE_LEFT_OUTPUT,
617 mute | chip->image[CS4231_LINE_LEFT_OUTPUT]);
618 snd_wss_dout(chip, CS4231_LINE_RIGHT_OUTPUT,
619 mute | chip->image[CS4231_LINE_RIGHT_OUTPUT]);
620 }
621 chip->calibrate_mute = mute;
622 spin_unlock_irqrestore(&chip->reg_lock, flags);
623}
624
625static void snd_wss_playback_format(struct snd_wss *chip,
626 struct snd_pcm_hw_params *params,
627 unsigned char pdfr)
628{
629 unsigned long flags;
630 int full_calib = 1;
631
632 mutex_lock(&chip->mce_mutex);
633 snd_wss_calibrate_mute(chip, 1);
634 if (chip->hardware == WSS_HW_CS4231A ||
635 (chip->hardware & WSS_HW_CS4232_MASK)) {
636 spin_lock_irqsave(&chip->reg_lock, flags);
637 if ((chip->image[CS4231_PLAYBK_FORMAT] & 0x0f) == (pdfr & 0x0f)) { /* rate is same? */
638 snd_wss_out(chip, CS4231_ALT_FEATURE_1,
639 chip->image[CS4231_ALT_FEATURE_1] | 0x10);
640 chip->image[CS4231_PLAYBK_FORMAT] = pdfr;
641 snd_wss_out(chip, CS4231_PLAYBK_FORMAT,
642 chip->image[CS4231_PLAYBK_FORMAT]);
643 snd_wss_out(chip, CS4231_ALT_FEATURE_1,
644 chip->image[CS4231_ALT_FEATURE_1] &= ~0x10);
645 udelay(100); /* Fixes audible clicks at least on GUS MAX */
646 full_calib = 0;
647 }
648 spin_unlock_irqrestore(&chip->reg_lock, flags);
649 }
650 if (full_calib) {
651 snd_wss_mce_up(chip);
652 spin_lock_irqsave(&chip->reg_lock, flags);
653 if (chip->hardware != WSS_HW_INTERWAVE && !chip->single_dma) {
654 if (chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE)
655 pdfr = (pdfr & 0xf0) |
656 (chip->image[CS4231_REC_FORMAT] & 0x0f);
657 } else {
658 chip->image[CS4231_PLAYBK_FORMAT] = pdfr;
659 }
660 snd_wss_out(chip, CS4231_PLAYBK_FORMAT, pdfr);
661 spin_unlock_irqrestore(&chip->reg_lock, flags);
662 if (chip->hardware == WSS_HW_OPL3SA2)
663 udelay(100); /* this seems to help */
664 snd_wss_mce_down(chip);
665 }
666 snd_wss_calibrate_mute(chip, 0);
667 mutex_unlock(&chip->mce_mutex);
668}
669
670static void snd_wss_capture_format(struct snd_wss *chip,
671 struct snd_pcm_hw_params *params,
672 unsigned char cdfr)
673{
674 unsigned long flags;
675 int full_calib = 1;
676
677 mutex_lock(&chip->mce_mutex);
678 snd_wss_calibrate_mute(chip, 1);
679 if (chip->hardware == WSS_HW_CS4231A ||
680 (chip->hardware & WSS_HW_CS4232_MASK)) {
681 spin_lock_irqsave(&chip->reg_lock, flags);
682 if ((chip->image[CS4231_PLAYBK_FORMAT] & 0x0f) == (cdfr & 0x0f) || /* rate is same? */
683 (chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE)) {
684 snd_wss_out(chip, CS4231_ALT_FEATURE_1,
685 chip->image[CS4231_ALT_FEATURE_1] | 0x20);
686 snd_wss_out(chip, CS4231_REC_FORMAT,
687 chip->image[CS4231_REC_FORMAT] = cdfr);
688 snd_wss_out(chip, CS4231_ALT_FEATURE_1,
689 chip->image[CS4231_ALT_FEATURE_1] &= ~0x20);
690 full_calib = 0;
691 }
692 spin_unlock_irqrestore(&chip->reg_lock, flags);
693 }
694 if (full_calib) {
695 snd_wss_mce_up(chip);
696 spin_lock_irqsave(&chip->reg_lock, flags);
697 if (chip->hardware != WSS_HW_INTERWAVE &&
698 !(chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE)) {
699 if (chip->single_dma)
700 snd_wss_out(chip, CS4231_PLAYBK_FORMAT, cdfr);
701 else
702 snd_wss_out(chip, CS4231_PLAYBK_FORMAT,
703 (chip->image[CS4231_PLAYBK_FORMAT] & 0xf0) |
704 (cdfr & 0x0f));
705 spin_unlock_irqrestore(&chip->reg_lock, flags);
706 snd_wss_mce_down(chip);
707 snd_wss_mce_up(chip);
708 spin_lock_irqsave(&chip->reg_lock, flags);
709 }
710 if (chip->hardware & WSS_HW_AD1848_MASK)
711 snd_wss_out(chip, CS4231_PLAYBK_FORMAT, cdfr);
712 else
713 snd_wss_out(chip, CS4231_REC_FORMAT, cdfr);
714 spin_unlock_irqrestore(&chip->reg_lock, flags);
715 snd_wss_mce_down(chip);
716 }
717 snd_wss_calibrate_mute(chip, 0);
718 mutex_unlock(&chip->mce_mutex);
719}
720
721/*
722 * Timer interface
723 */
724
725static unsigned long snd_wss_timer_resolution(struct snd_timer *timer)
726{
727 struct snd_wss *chip = snd_timer_chip(timer);
728 if (chip->hardware & WSS_HW_CS4236B_MASK)
729 return 14467;
730 else
731 return chip->image[CS4231_PLAYBK_FORMAT] & 1 ? 9969 : 9920;
732}
733
734static int snd_wss_timer_start(struct snd_timer *timer)
735{
736 unsigned long flags;
737 unsigned int ticks;
738 struct snd_wss *chip = snd_timer_chip(timer);
739 spin_lock_irqsave(&chip->reg_lock, flags);
740 ticks = timer->sticks;
741 if ((chip->image[CS4231_ALT_FEATURE_1] & CS4231_TIMER_ENABLE) == 0 ||
742 (unsigned char)(ticks >> 8) != chip->image[CS4231_TIMER_HIGH] ||
743 (unsigned char)ticks != chip->image[CS4231_TIMER_LOW]) {
744 chip->image[CS4231_TIMER_HIGH] = (unsigned char) (ticks >> 8);
745 snd_wss_out(chip, CS4231_TIMER_HIGH,
746 chip->image[CS4231_TIMER_HIGH]);
747 chip->image[CS4231_TIMER_LOW] = (unsigned char) ticks;
748 snd_wss_out(chip, CS4231_TIMER_LOW,
749 chip->image[CS4231_TIMER_LOW]);
750 snd_wss_out(chip, CS4231_ALT_FEATURE_1,
751 chip->image[CS4231_ALT_FEATURE_1] |
752 CS4231_TIMER_ENABLE);
753 }
754 spin_unlock_irqrestore(&chip->reg_lock, flags);
755 return 0;
756}
757
758static int snd_wss_timer_stop(struct snd_timer *timer)
759{
760 unsigned long flags;
761 struct snd_wss *chip = snd_timer_chip(timer);
762 spin_lock_irqsave(&chip->reg_lock, flags);
763 chip->image[CS4231_ALT_FEATURE_1] &= ~CS4231_TIMER_ENABLE;
764 snd_wss_out(chip, CS4231_ALT_FEATURE_1,
765 chip->image[CS4231_ALT_FEATURE_1]);
766 spin_unlock_irqrestore(&chip->reg_lock, flags);
767 return 0;
768}
769
770static void snd_wss_init(struct snd_wss *chip)
771{
772 unsigned long flags;
773
774 snd_wss_mce_down(chip);
775
776#ifdef SNDRV_DEBUG_MCE
777 snd_printk("init: (1)\n");
778#endif
779 snd_wss_mce_up(chip);
780 spin_lock_irqsave(&chip->reg_lock, flags);
781 chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_PLAYBACK_ENABLE |
782 CS4231_PLAYBACK_PIO |
783 CS4231_RECORD_ENABLE |
784 CS4231_RECORD_PIO |
785 CS4231_CALIB_MODE);
786 chip->image[CS4231_IFACE_CTRL] |= CS4231_AUTOCALIB;
787 snd_wss_out(chip, CS4231_IFACE_CTRL, chip->image[CS4231_IFACE_CTRL]);
788 spin_unlock_irqrestore(&chip->reg_lock, flags);
789 snd_wss_mce_down(chip);
790
791#ifdef SNDRV_DEBUG_MCE
792 snd_printk("init: (2)\n");
793#endif
794
795 snd_wss_mce_up(chip);
796 spin_lock_irqsave(&chip->reg_lock, flags);
797 snd_wss_out(chip,
798 CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1]);
799 spin_unlock_irqrestore(&chip->reg_lock, flags);
800 snd_wss_mce_down(chip);
801
802#ifdef SNDRV_DEBUG_MCE
803 snd_printk("init: (3) - afei = 0x%x\n",
804 chip->image[CS4231_ALT_FEATURE_1]);
805#endif
806
807 spin_lock_irqsave(&chip->reg_lock, flags);
808 snd_wss_out(chip, CS4231_ALT_FEATURE_2,
809 chip->image[CS4231_ALT_FEATURE_2]);
810 spin_unlock_irqrestore(&chip->reg_lock, flags);
811
812 snd_wss_mce_up(chip);
813 spin_lock_irqsave(&chip->reg_lock, flags);
814 snd_wss_out(chip, CS4231_PLAYBK_FORMAT,
815 chip->image[CS4231_PLAYBK_FORMAT]);
816 spin_unlock_irqrestore(&chip->reg_lock, flags);
817 snd_wss_mce_down(chip);
818
819#ifdef SNDRV_DEBUG_MCE
820 snd_printk("init: (4)\n");
821#endif
822
823 snd_wss_mce_up(chip);
824 spin_lock_irqsave(&chip->reg_lock, flags);
825 if (!(chip->hardware & WSS_HW_AD1848_MASK))
826 snd_wss_out(chip, CS4231_REC_FORMAT,
827 chip->image[CS4231_REC_FORMAT]);
828 spin_unlock_irqrestore(&chip->reg_lock, flags);
829 snd_wss_mce_down(chip);
830
831#ifdef SNDRV_DEBUG_MCE
832 snd_printk("init: (5)\n");
833#endif
834}
835
836static int snd_wss_open(struct snd_wss *chip, unsigned int mode)
837{
838 unsigned long flags;
839
840 mutex_lock(&chip->open_mutex);
841 if ((chip->mode & mode) ||
842 ((chip->mode & WSS_MODE_OPEN) && chip->single_dma)) {
843 mutex_unlock(&chip->open_mutex);
844 return -EAGAIN;
845 }
846 if (chip->mode & WSS_MODE_OPEN) {
847 chip->mode |= mode;
848 mutex_unlock(&chip->open_mutex);
849 return 0;
850 }
851 /* ok. now enable and ack CODEC IRQ */
852 spin_lock_irqsave(&chip->reg_lock, flags);
853 if (!(chip->hardware & WSS_HW_AD1848_MASK)) {
854 snd_wss_out(chip, CS4231_IRQ_STATUS,
855 CS4231_PLAYBACK_IRQ |
856 CS4231_RECORD_IRQ |
857 CS4231_TIMER_IRQ);
858 snd_wss_out(chip, CS4231_IRQ_STATUS, 0);
859 }
860 wss_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */
861 wss_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */
862 chip->image[CS4231_PIN_CTRL] |= CS4231_IRQ_ENABLE;
863 snd_wss_out(chip, CS4231_PIN_CTRL, chip->image[CS4231_PIN_CTRL]);
864 if (!(chip->hardware & WSS_HW_AD1848_MASK)) {
865 snd_wss_out(chip, CS4231_IRQ_STATUS,
866 CS4231_PLAYBACK_IRQ |
867 CS4231_RECORD_IRQ |
868 CS4231_TIMER_IRQ);
869 snd_wss_out(chip, CS4231_IRQ_STATUS, 0);
870 }
871 spin_unlock_irqrestore(&chip->reg_lock, flags);
872
873 chip->mode = mode;
874 mutex_unlock(&chip->open_mutex);
875 return 0;
876}
877
878static void snd_wss_close(struct snd_wss *chip, unsigned int mode)
879{
880 unsigned long flags;
881
882 mutex_lock(&chip->open_mutex);
883 chip->mode &= ~mode;
884 if (chip->mode & WSS_MODE_OPEN) {
885 mutex_unlock(&chip->open_mutex);
886 return;
887 }
888 snd_wss_calibrate_mute(chip, 1);
889
890 /* disable IRQ */
891 spin_lock_irqsave(&chip->reg_lock, flags);
892 if (!(chip->hardware & WSS_HW_AD1848_MASK))
893 snd_wss_out(chip, CS4231_IRQ_STATUS, 0);
894 wss_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */
895 wss_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */
896 chip->image[CS4231_PIN_CTRL] &= ~CS4231_IRQ_ENABLE;
897 snd_wss_out(chip, CS4231_PIN_CTRL, chip->image[CS4231_PIN_CTRL]);
898
899 /* now disable record & playback */
900
901 if (chip->image[CS4231_IFACE_CTRL] & (CS4231_PLAYBACK_ENABLE | CS4231_PLAYBACK_PIO |
902 CS4231_RECORD_ENABLE | CS4231_RECORD_PIO)) {
903 spin_unlock_irqrestore(&chip->reg_lock, flags);
904 snd_wss_mce_up(chip);
905 spin_lock_irqsave(&chip->reg_lock, flags);
906 chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_PLAYBACK_ENABLE | CS4231_PLAYBACK_PIO |
907 CS4231_RECORD_ENABLE | CS4231_RECORD_PIO);
908 snd_wss_out(chip, CS4231_IFACE_CTRL,
909 chip->image[CS4231_IFACE_CTRL]);
910 spin_unlock_irqrestore(&chip->reg_lock, flags);
911 snd_wss_mce_down(chip);
912 spin_lock_irqsave(&chip->reg_lock, flags);
913 }
914
915 /* clear IRQ again */
916 if (!(chip->hardware & WSS_HW_AD1848_MASK))
917 snd_wss_out(chip, CS4231_IRQ_STATUS, 0);
918 wss_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */
919 wss_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */
920 spin_unlock_irqrestore(&chip->reg_lock, flags);
921
922 snd_wss_calibrate_mute(chip, 0);
923
924 chip->mode = 0;
925 mutex_unlock(&chip->open_mutex);
926}
927
928/*
929 * timer open/close
930 */
931
932static int snd_wss_timer_open(struct snd_timer *timer)
933{
934 struct snd_wss *chip = snd_timer_chip(timer);
935 snd_wss_open(chip, WSS_MODE_TIMER);
936 return 0;
937}
938
939static int snd_wss_timer_close(struct snd_timer *timer)
940{
941 struct snd_wss *chip = snd_timer_chip(timer);
942 snd_wss_close(chip, WSS_MODE_TIMER);
943 return 0;
944}
945
946static struct snd_timer_hardware snd_wss_timer_table =
947{
948 .flags = SNDRV_TIMER_HW_AUTO,
949 .resolution = 9945,
950 .ticks = 65535,
951 .open = snd_wss_timer_open,
952 .close = snd_wss_timer_close,
953 .c_resolution = snd_wss_timer_resolution,
954 .start = snd_wss_timer_start,
955 .stop = snd_wss_timer_stop,
956};
957
958/*
959 * ok.. exported functions..
960 */
961
962static int snd_wss_playback_hw_params(struct snd_pcm_substream *substream,
963 struct snd_pcm_hw_params *hw_params)
964{
965 struct snd_wss *chip = snd_pcm_substream_chip(substream);
966 unsigned char new_pdfr;
967 int err;
968
969 if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
970 return err;
971 new_pdfr = snd_wss_get_format(chip, params_format(hw_params),
972 params_channels(hw_params)) |
973 snd_wss_get_rate(params_rate(hw_params));
974 chip->set_playback_format(chip, hw_params, new_pdfr);
975 return 0;
976}
977
978static int snd_wss_playback_hw_free(struct snd_pcm_substream *substream)
979{
980 return snd_pcm_lib_free_pages(substream);
981}
982
983static int snd_wss_playback_prepare(struct snd_pcm_substream *substream)
984{
985 struct snd_wss *chip = snd_pcm_substream_chip(substream);
986 struct snd_pcm_runtime *runtime = substream->runtime;
987 unsigned long flags;
988 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
989 unsigned int count = snd_pcm_lib_period_bytes(substream);
990
991 spin_lock_irqsave(&chip->reg_lock, flags);
992 chip->p_dma_size = size;
993 chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_PLAYBACK_ENABLE | CS4231_PLAYBACK_PIO);
994 snd_dma_program(chip->dma1, runtime->dma_addr, size, DMA_MODE_WRITE | DMA_AUTOINIT);
995 count = snd_wss_get_count(chip->image[CS4231_PLAYBK_FORMAT], count) - 1;
996 snd_wss_out(chip, CS4231_PLY_LWR_CNT, (unsigned char) count);
997 snd_wss_out(chip, CS4231_PLY_UPR_CNT, (unsigned char) (count >> 8));
998 spin_unlock_irqrestore(&chip->reg_lock, flags);
999#if 0
1000 snd_wss_debug(chip);
1001#endif
1002 return 0;
1003}
1004
1005static int snd_wss_capture_hw_params(struct snd_pcm_substream *substream,
1006 struct snd_pcm_hw_params *hw_params)
1007{
1008 struct snd_wss *chip = snd_pcm_substream_chip(substream);
1009 unsigned char new_cdfr;
1010 int err;
1011
1012 if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
1013 return err;
1014 new_cdfr = snd_wss_get_format(chip, params_format(hw_params),
1015 params_channels(hw_params)) |
1016 snd_wss_get_rate(params_rate(hw_params));
1017 chip->set_capture_format(chip, hw_params, new_cdfr);
1018 return 0;
1019}
1020
1021static int snd_wss_capture_hw_free(struct snd_pcm_substream *substream)
1022{
1023 return snd_pcm_lib_free_pages(substream);
1024}
1025
1026static int snd_wss_capture_prepare(struct snd_pcm_substream *substream)
1027{
1028 struct snd_wss *chip = snd_pcm_substream_chip(substream);
1029 struct snd_pcm_runtime *runtime = substream->runtime;
1030 unsigned long flags;
1031 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
1032 unsigned int count = snd_pcm_lib_period_bytes(substream);
1033
1034 spin_lock_irqsave(&chip->reg_lock, flags);
1035 chip->c_dma_size = size;
1036 chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_RECORD_ENABLE | CS4231_RECORD_PIO);
1037 snd_dma_program(chip->dma2, runtime->dma_addr, size, DMA_MODE_READ | DMA_AUTOINIT);
1038 if (chip->hardware & WSS_HW_AD1848_MASK)
1039 count = snd_wss_get_count(chip->image[CS4231_PLAYBK_FORMAT],
1040 count);
1041 else
1042 count = snd_wss_get_count(chip->image[CS4231_REC_FORMAT],
1043 count);
1044 count--;
1045 if (chip->single_dma && chip->hardware != WSS_HW_INTERWAVE) {
1046 snd_wss_out(chip, CS4231_PLY_LWR_CNT, (unsigned char) count);
1047 snd_wss_out(chip, CS4231_PLY_UPR_CNT,
1048 (unsigned char) (count >> 8));
1049 } else {
1050 snd_wss_out(chip, CS4231_REC_LWR_CNT, (unsigned char) count);
1051 snd_wss_out(chip, CS4231_REC_UPR_CNT,
1052 (unsigned char) (count >> 8));
1053 }
1054 spin_unlock_irqrestore(&chip->reg_lock, flags);
1055 return 0;
1056}
1057
1058void snd_wss_overrange(struct snd_wss *chip)
1059{
1060 unsigned long flags;
1061 unsigned char res;
1062
1063 spin_lock_irqsave(&chip->reg_lock, flags);
1064 res = snd_wss_in(chip, CS4231_TEST_INIT);
1065 spin_unlock_irqrestore(&chip->reg_lock, flags);
1066 if (res & (0x08 | 0x02)) /* detect overrange only above 0dB; may be user selectable? */
1067 chip->capture_substream->runtime->overrange++;
1068}
1069EXPORT_SYMBOL(snd_wss_overrange);
1070
1071irqreturn_t snd_wss_interrupt(int irq, void *dev_id)
1072{
1073 struct snd_wss *chip = dev_id;
1074 unsigned char status;
1075
1076 if (chip->hardware & WSS_HW_AD1848_MASK)
1077 /* pretend it was the only possible irq for AD1848 */
1078 status = CS4231_PLAYBACK_IRQ;
1079 else
1080 status = snd_wss_in(chip, CS4231_IRQ_STATUS);
1081 if (status & CS4231_TIMER_IRQ) {
1082 if (chip->timer)
1083 snd_timer_interrupt(chip->timer, chip->timer->sticks);
1084 }
1085 if (chip->single_dma && chip->hardware != WSS_HW_INTERWAVE) {
1086 if (status & CS4231_PLAYBACK_IRQ) {
1087 if (chip->mode & WSS_MODE_PLAY) {
1088 if (chip->playback_substream)
1089 snd_pcm_period_elapsed(chip->playback_substream);
1090 }
1091 if (chip->mode & WSS_MODE_RECORD) {
1092 if (chip->capture_substream) {
1093 snd_wss_overrange(chip);
1094 snd_pcm_period_elapsed(chip->capture_substream);
1095 }
1096 }
1097 }
1098 } else {
1099 if (status & CS4231_PLAYBACK_IRQ) {
1100 if (chip->playback_substream)
1101 snd_pcm_period_elapsed(chip->playback_substream);
1102 }
1103 if (status & CS4231_RECORD_IRQ) {
1104 if (chip->capture_substream) {
1105 snd_wss_overrange(chip);
1106 snd_pcm_period_elapsed(chip->capture_substream);
1107 }
1108 }
1109 }
1110
1111 spin_lock(&chip->reg_lock);
1112 status = ~CS4231_ALL_IRQS | ~status;
1113 if (chip->hardware & WSS_HW_AD1848_MASK)
1114 wss_outb(chip, CS4231P(STATUS), 0);
1115 else
1116 snd_wss_outm(chip, CS4231_IRQ_STATUS, status, 0);
1117 spin_unlock(&chip->reg_lock);
1118 return IRQ_HANDLED;
1119}
1120EXPORT_SYMBOL(snd_wss_interrupt);
1121
1122static snd_pcm_uframes_t snd_wss_playback_pointer(struct snd_pcm_substream *substream)
1123{
1124 struct snd_wss *chip = snd_pcm_substream_chip(substream);
1125 size_t ptr;
1126
1127 if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE))
1128 return 0;
1129 ptr = snd_dma_pointer(chip->dma1, chip->p_dma_size);
1130 return bytes_to_frames(substream->runtime, ptr);
1131}
1132
1133static snd_pcm_uframes_t snd_wss_capture_pointer(struct snd_pcm_substream *substream)
1134{
1135 struct snd_wss *chip = snd_pcm_substream_chip(substream);
1136 size_t ptr;
1137
1138 if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE))
1139 return 0;
1140 ptr = snd_dma_pointer(chip->dma2, chip->c_dma_size);
1141 return bytes_to_frames(substream->runtime, ptr);
1142}
1143
1144/*
1145
1146 */
1147
1148static int snd_ad1848_probe(struct snd_wss *chip)
1149{
1150 unsigned long timeout = jiffies + msecs_to_jiffies(1000);
1151 unsigned long flags;
1152 unsigned char r;
1153 unsigned short hardware = 0;
1154 int err = 0;
1155 int i;
1156
1157 while (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) {
1158 if (time_after(jiffies, timeout))
1159 return -ENODEV;
1160 cond_resched();
1161 }
1162 spin_lock_irqsave(&chip->reg_lock, flags);
1163
1164 /* set CS423x MODE 1 */
1165 snd_wss_dout(chip, CS4231_MISC_INFO, 0);
1166
1167 snd_wss_dout(chip, CS4231_RIGHT_INPUT, 0x45); /* 0x55 & ~0x10 */
1168 r = snd_wss_in(chip, CS4231_RIGHT_INPUT);
1169 if (r != 0x45) {
1170 /* RMGE always high on AD1847 */
1171 if ((r & ~CS4231_ENABLE_MIC_GAIN) != 0x45) {
1172 err = -ENODEV;
1173 goto out;
1174 }
1175 hardware = WSS_HW_AD1847;
1176 } else {
1177 snd_wss_dout(chip, CS4231_LEFT_INPUT, 0xaa);
1178 r = snd_wss_in(chip, CS4231_LEFT_INPUT);
1179 /* L/RMGE always low on AT2320 */
1180 if ((r | CS4231_ENABLE_MIC_GAIN) != 0xaa) {
1181 err = -ENODEV;
1182 goto out;
1183 }
1184 }
1185
1186 /* clear pending IRQ */
1187 wss_inb(chip, CS4231P(STATUS));
1188 wss_outb(chip, CS4231P(STATUS), 0);
1189 mb();
1190
1191 if ((chip->hardware & WSS_HW_TYPE_MASK) != WSS_HW_DETECT)
1192 goto out;
1193
1194 if (hardware) {
1195 chip->hardware = hardware;
1196 goto out;
1197 }
1198
1199 r = snd_wss_in(chip, CS4231_MISC_INFO);
1200
1201 /* set CS423x MODE 2 */
1202 snd_wss_dout(chip, CS4231_MISC_INFO, CS4231_MODE2);
1203 for (i = 0; i < 16; i++) {
1204 if (snd_wss_in(chip, i) != snd_wss_in(chip, 16 + i)) {
1205 /* we have more than 16 registers: check ID */
1206 if ((r & 0xf) != 0xa)
1207 goto out_mode;
1208 /*
1209 * on CMI8330, CS4231_VERSION is volume control and
1210 * can be set to 0
1211 */
1212 snd_wss_dout(chip, CS4231_VERSION, 0);
1213 r = snd_wss_in(chip, CS4231_VERSION) & 0xe7;
1214 if (!r)
1215 chip->hardware = WSS_HW_CMI8330;
1216 goto out_mode;
1217 }
1218 }
1219 if (r & 0x80)
1220 chip->hardware = WSS_HW_CS4248;
1221 else
1222 chip->hardware = WSS_HW_AD1848;
1223out_mode:
1224 snd_wss_dout(chip, CS4231_MISC_INFO, 0);
1225out:
1226 spin_unlock_irqrestore(&chip->reg_lock, flags);
1227 return err;
1228}
1229
1230static int snd_wss_probe(struct snd_wss *chip)
1231{
1232 unsigned long flags;
1233 int i, id, rev, regnum;
1234 unsigned char *ptr;
1235 unsigned int hw;
1236
1237 id = snd_ad1848_probe(chip);
1238 if (id < 0)
1239 return id;
1240
1241 hw = chip->hardware;
1242 if ((hw & WSS_HW_TYPE_MASK) == WSS_HW_DETECT) {
1243 for (i = 0; i < 50; i++) {
1244 mb();
1245 if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
1246 msleep(2);
1247 else {
1248 spin_lock_irqsave(&chip->reg_lock, flags);
1249 snd_wss_out(chip, CS4231_MISC_INFO,
1250 CS4231_MODE2);
1251 id = snd_wss_in(chip, CS4231_MISC_INFO) & 0x0f;
1252 spin_unlock_irqrestore(&chip->reg_lock, flags);
1253 if (id == 0x0a)
1254 break; /* this is valid value */
1255 }
1256 }
1257 snd_printdd("wss: port = 0x%lx, id = 0x%x\n", chip->port, id);
1258 if (id != 0x0a)
1259 return -ENODEV; /* no valid device found */
1260
1261 rev = snd_wss_in(chip, CS4231_VERSION) & 0xe7;
1262 snd_printdd("CS4231: VERSION (I25) = 0x%x\n", rev);
1263 if (rev == 0x80) {
1264 unsigned char tmp = snd_wss_in(chip, 23);
1265 snd_wss_out(chip, 23, ~tmp);
1266 if (snd_wss_in(chip, 23) != tmp)
1267 chip->hardware = WSS_HW_AD1845;
1268 else
1269 chip->hardware = WSS_HW_CS4231;
1270 } else if (rev == 0xa0) {
1271 chip->hardware = WSS_HW_CS4231A;
1272 } else if (rev == 0xa2) {
1273 chip->hardware = WSS_HW_CS4232;
1274 } else if (rev == 0xb2) {
1275 chip->hardware = WSS_HW_CS4232A;
1276 } else if (rev == 0x83) {
1277 chip->hardware = WSS_HW_CS4236;
1278 } else if (rev == 0x03) {
1279 chip->hardware = WSS_HW_CS4236B;
1280 } else {
1281 snd_printk("unknown CS chip with version 0x%x\n", rev);
1282 return -ENODEV; /* unknown CS4231 chip? */
1283 }
1284 }
1285 spin_lock_irqsave(&chip->reg_lock, flags);
1286 wss_inb(chip, CS4231P(STATUS)); /* clear any pendings IRQ */
1287 wss_outb(chip, CS4231P(STATUS), 0);
1288 mb();
1289 spin_unlock_irqrestore(&chip->reg_lock, flags);
1290
1291 if (!(chip->hardware & WSS_HW_AD1848_MASK))
1292 chip->image[CS4231_MISC_INFO] = CS4231_MODE2;
1293 switch (chip->hardware) {
1294 case WSS_HW_INTERWAVE:
1295 chip->image[CS4231_MISC_INFO] = CS4231_IW_MODE3;
1296 break;
1297 case WSS_HW_CS4235:
1298 case WSS_HW_CS4236B:
1299 case WSS_HW_CS4237B:
1300 case WSS_HW_CS4238B:
1301 case WSS_HW_CS4239:
1302 if (hw == WSS_HW_DETECT3)
1303 chip->image[CS4231_MISC_INFO] = CS4231_4236_MODE3;
1304 else
1305 chip->hardware = WSS_HW_CS4236;
1306 break;
1307 }
1308
1309 chip->image[CS4231_IFACE_CTRL] =
1310 (chip->image[CS4231_IFACE_CTRL] & ~CS4231_SINGLE_DMA) |
1311 (chip->single_dma ? CS4231_SINGLE_DMA : 0);
1312 if (chip->hardware != WSS_HW_OPTI93X) {
1313 chip->image[CS4231_ALT_FEATURE_1] = 0x80;
1314 chip->image[CS4231_ALT_FEATURE_2] =
1315 chip->hardware == WSS_HW_INTERWAVE ? 0xc2 : 0x01;
1316 }
1317 ptr = (unsigned char *) &chip->image;
1318 regnum = (chip->hardware & WSS_HW_AD1848_MASK) ? 16 : 32;
1319 snd_wss_mce_down(chip);
1320 spin_lock_irqsave(&chip->reg_lock, flags);
1321 for (i = 0; i < regnum; i++) /* ok.. fill all registers */
1322 snd_wss_out(chip, i, *ptr++);
1323 spin_unlock_irqrestore(&chip->reg_lock, flags);
1324 snd_wss_mce_up(chip);
1325 snd_wss_mce_down(chip);
1326
1327 mdelay(2);
1328
1329 /* ok.. try check hardware version for CS4236+ chips */
1330 if ((hw & WSS_HW_TYPE_MASK) == WSS_HW_DETECT) {
1331 if (chip->hardware == WSS_HW_CS4236B) {
1332 rev = snd_cs4236_ext_in(chip, CS4236_VERSION);
1333 snd_cs4236_ext_out(chip, CS4236_VERSION, 0xff);
1334 id = snd_cs4236_ext_in(chip, CS4236_VERSION);
1335 snd_cs4236_ext_out(chip, CS4236_VERSION, rev);
1336 snd_printdd("CS4231: ext version; rev = 0x%x, id = 0x%x\n", rev, id);
1337 if ((id & 0x1f) == 0x1d) { /* CS4235 */
1338 chip->hardware = WSS_HW_CS4235;
1339 switch (id >> 5) {
1340 case 4:
1341 case 5:
1342 case 6:
1343 break;
1344 default:
1345 snd_printk("unknown CS4235 chip (enhanced version = 0x%x)\n", id);
1346 }
1347 } else if ((id & 0x1f) == 0x0b) { /* CS4236/B */
1348 switch (id >> 5) {
1349 case 4:
1350 case 5:
1351 case 6:
1352 case 7:
1353 chip->hardware = WSS_HW_CS4236B;
1354 break;
1355 default:
1356 snd_printk("unknown CS4236 chip (enhanced version = 0x%x)\n", id);
1357 }
1358 } else if ((id & 0x1f) == 0x08) { /* CS4237B */
1359 chip->hardware = WSS_HW_CS4237B;
1360 switch (id >> 5) {
1361 case 4:
1362 case 5:
1363 case 6:
1364 case 7:
1365 break;
1366 default:
1367 snd_printk("unknown CS4237B chip (enhanced version = 0x%x)\n", id);
1368 }
1369 } else if ((id & 0x1f) == 0x09) { /* CS4238B */
1370 chip->hardware = WSS_HW_CS4238B;
1371 switch (id >> 5) {
1372 case 5:
1373 case 6:
1374 case 7:
1375 break;
1376 default:
1377 snd_printk("unknown CS4238B chip (enhanced version = 0x%x)\n", id);
1378 }
1379 } else if ((id & 0x1f) == 0x1e) { /* CS4239 */
1380 chip->hardware = WSS_HW_CS4239;
1381 switch (id >> 5) {
1382 case 4:
1383 case 5:
1384 case 6:
1385 break;
1386 default:
1387 snd_printk("unknown CS4239 chip (enhanced version = 0x%x)\n", id);
1388 }
1389 } else {
1390 snd_printk("unknown CS4236/CS423xB chip (enhanced version = 0x%x)\n", id);
1391 }
1392 }
1393 }
1394 return 0; /* all things are ok.. */
1395}
1396
1397/*
1398
1399 */
1400
1401static struct snd_pcm_hardware snd_wss_playback =
1402{
1403 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1404 SNDRV_PCM_INFO_MMAP_VALID |
1405 SNDRV_PCM_INFO_RESUME |
1406 SNDRV_PCM_INFO_SYNC_START),
1407 .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | SNDRV_PCM_FMTBIT_IMA_ADPCM |
1408 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE),
1409 .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
1410 .rate_min = 5510,
1411 .rate_max = 48000,
1412 .channels_min = 1,
1413 .channels_max = 2,
1414 .buffer_bytes_max = (128*1024),
1415 .period_bytes_min = 64,
1416 .period_bytes_max = (128*1024),
1417 .periods_min = 1,
1418 .periods_max = 1024,
1419 .fifo_size = 0,
1420};
1421
1422static struct snd_pcm_hardware snd_wss_capture =
1423{
1424 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1425 SNDRV_PCM_INFO_MMAP_VALID |
1426 SNDRV_PCM_INFO_RESUME |
1427 SNDRV_PCM_INFO_SYNC_START),
1428 .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | SNDRV_PCM_FMTBIT_IMA_ADPCM |
1429 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE),
1430 .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
1431 .rate_min = 5510,
1432 .rate_max = 48000,
1433 .channels_min = 1,
1434 .channels_max = 2,
1435 .buffer_bytes_max = (128*1024),
1436 .period_bytes_min = 64,
1437 .period_bytes_max = (128*1024),
1438 .periods_min = 1,
1439 .periods_max = 1024,
1440 .fifo_size = 0,
1441};
1442
1443/*
1444
1445 */
1446
1447static int snd_wss_playback_open(struct snd_pcm_substream *substream)
1448{
1449 struct snd_wss *chip = snd_pcm_substream_chip(substream);
1450 struct snd_pcm_runtime *runtime = substream->runtime;
1451 int err;
1452
1453 runtime->hw = snd_wss_playback;
1454
1455 /* hardware limitation of older chipsets */
1456 if (chip->hardware & WSS_HW_AD1848_MASK)
1457 runtime->hw.formats &= ~(SNDRV_PCM_FMTBIT_IMA_ADPCM |
1458 SNDRV_PCM_FMTBIT_S16_BE);
1459
1460 /* hardware bug in InterWave chipset */
1461 if (chip->hardware == WSS_HW_INTERWAVE && chip->dma1 > 3)
1462 runtime->hw.formats &= ~SNDRV_PCM_FMTBIT_MU_LAW;
1463
1464 /* hardware limitation of cheap chips */
1465 if (chip->hardware == WSS_HW_CS4235 ||
1466 chip->hardware == WSS_HW_CS4239)
1467 runtime->hw.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE;
1468
1469 snd_pcm_limit_isa_dma_size(chip->dma1, &runtime->hw.buffer_bytes_max);
1470 snd_pcm_limit_isa_dma_size(chip->dma1, &runtime->hw.period_bytes_max);
1471
1472 if (chip->claim_dma) {
1473 if ((err = chip->claim_dma(chip, chip->dma_private_data, chip->dma1)) < 0)
1474 return err;
1475 }
1476
1477 err = snd_wss_open(chip, WSS_MODE_PLAY);
1478 if (err < 0) {
1479 if (chip->release_dma)
1480 chip->release_dma(chip, chip->dma_private_data, chip->dma1);
1481 snd_free_pages(runtime->dma_area, runtime->dma_bytes);
1482 return err;
1483 }
1484 chip->playback_substream = substream;
1485 snd_pcm_set_sync(substream);
1486 chip->rate_constraint(runtime);
1487 return 0;
1488}
1489
1490static int snd_wss_capture_open(struct snd_pcm_substream *substream)
1491{
1492 struct snd_wss *chip = snd_pcm_substream_chip(substream);
1493 struct snd_pcm_runtime *runtime = substream->runtime;
1494 int err;
1495
1496 runtime->hw = snd_wss_capture;
1497
1498 /* hardware limitation of older chipsets */
1499 if (chip->hardware & WSS_HW_AD1848_MASK)
1500 runtime->hw.formats &= ~(SNDRV_PCM_FMTBIT_IMA_ADPCM |
1501 SNDRV_PCM_FMTBIT_S16_BE);
1502
1503 /* hardware limitation of cheap chips */
1504 if (chip->hardware == WSS_HW_CS4235 ||
1505 chip->hardware == WSS_HW_CS4239 ||
1506 chip->hardware == WSS_HW_OPTI93X)
1507 runtime->hw.formats = SNDRV_PCM_FMTBIT_U8 |
1508 SNDRV_PCM_FMTBIT_S16_LE;
1509
1510 snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.buffer_bytes_max);
1511 snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.period_bytes_max);
1512
1513 if (chip->claim_dma) {
1514 if ((err = chip->claim_dma(chip, chip->dma_private_data, chip->dma2)) < 0)
1515 return err;
1516 }
1517
1518 err = snd_wss_open(chip, WSS_MODE_RECORD);
1519 if (err < 0) {
1520 if (chip->release_dma)
1521 chip->release_dma(chip, chip->dma_private_data, chip->dma2);
1522 snd_free_pages(runtime->dma_area, runtime->dma_bytes);
1523 return err;
1524 }
1525 chip->capture_substream = substream;
1526 snd_pcm_set_sync(substream);
1527 chip->rate_constraint(runtime);
1528 return 0;
1529}
1530
1531static int snd_wss_playback_close(struct snd_pcm_substream *substream)
1532{
1533 struct snd_wss *chip = snd_pcm_substream_chip(substream);
1534
1535 chip->playback_substream = NULL;
1536 snd_wss_close(chip, WSS_MODE_PLAY);
1537 return 0;
1538}
1539
1540static int snd_wss_capture_close(struct snd_pcm_substream *substream)
1541{
1542 struct snd_wss *chip = snd_pcm_substream_chip(substream);
1543
1544 chip->capture_substream = NULL;
1545 snd_wss_close(chip, WSS_MODE_RECORD);
1546 return 0;
1547}
1548
1549static void snd_wss_thinkpad_twiddle(struct snd_wss *chip, int on)
1550{
1551 int tmp;
1552
1553 if (!chip->thinkpad_flag)
1554 return;
1555
1556 outb(0x1c, AD1848_THINKPAD_CTL_PORT1);
1557 tmp = inb(AD1848_THINKPAD_CTL_PORT2);
1558
1559 if (on)
1560 /* turn it on */
1561 tmp |= AD1848_THINKPAD_CS4248_ENABLE_BIT;
1562 else
1563 /* turn it off */
1564 tmp &= ~AD1848_THINKPAD_CS4248_ENABLE_BIT;
1565
1566 outb(tmp, AD1848_THINKPAD_CTL_PORT2);
1567}
1568
1569#ifdef CONFIG_PM
1570
1571/* lowlevel suspend callback for CS4231 */
1572static void snd_wss_suspend(struct snd_wss *chip)
1573{
1574 int reg;
1575 unsigned long flags;
1576
1577 snd_pcm_suspend_all(chip->pcm);
1578 spin_lock_irqsave(&chip->reg_lock, flags);
1579 for (reg = 0; reg < 32; reg++)
1580 chip->image[reg] = snd_wss_in(chip, reg);
1581 spin_unlock_irqrestore(&chip->reg_lock, flags);
1582 if (chip->thinkpad_flag)
1583 snd_wss_thinkpad_twiddle(chip, 0);
1584}
1585
1586/* lowlevel resume callback for CS4231 */
1587static void snd_wss_resume(struct snd_wss *chip)
1588{
1589 int reg;
1590 unsigned long flags;
1591 /* int timeout; */
1592
1593 if (chip->thinkpad_flag)
1594 snd_wss_thinkpad_twiddle(chip, 1);
1595 snd_wss_mce_up(chip);
1596 spin_lock_irqsave(&chip->reg_lock, flags);
1597 for (reg = 0; reg < 32; reg++) {
1598 switch (reg) {
1599 case CS4231_VERSION:
1600 break;
1601 default:
1602 snd_wss_out(chip, reg, chip->image[reg]);
1603 break;
1604 }
1605 }
1606 spin_unlock_irqrestore(&chip->reg_lock, flags);
1607#if 1
1608 snd_wss_mce_down(chip);
1609#else
1610 /* The following is a workaround to avoid freeze after resume on TP600E.
1611 This is the first half of copy of snd_wss_mce_down(), but doesn't
1612 include rescheduling. -- iwai
1613 */
1614 snd_wss_busy_wait(chip);
1615 spin_lock_irqsave(&chip->reg_lock, flags);
1616 chip->mce_bit &= ~CS4231_MCE;
1617 timeout = wss_inb(chip, CS4231P(REGSEL));
1618 wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | (timeout & 0x1f));
1619 spin_unlock_irqrestore(&chip->reg_lock, flags);
1620 if (timeout == 0x80)
1621 snd_printk("down [0x%lx]: serious init problem - codec still busy\n", chip->port);
1622 if ((timeout & CS4231_MCE) == 0 ||
1623 !(chip->hardware & (WSS_HW_CS4231_MASK | WSS_HW_CS4232_MASK))) {
1624 return;
1625 }
1626 snd_wss_busy_wait(chip);
1627#endif
1628}
1629#endif /* CONFIG_PM */
1630
1631static int snd_wss_free(struct snd_wss *chip)
1632{
1633 release_and_free_resource(chip->res_port);
1634 release_and_free_resource(chip->res_cport);
1635 if (chip->irq >= 0) {
1636 disable_irq(chip->irq);
1637 if (!(chip->hwshare & WSS_HWSHARE_IRQ))
1638 free_irq(chip->irq, (void *) chip);
1639 }
1640 if (!(chip->hwshare & WSS_HWSHARE_DMA1) && chip->dma1 >= 0) {
1641 snd_dma_disable(chip->dma1);
1642 free_dma(chip->dma1);
1643 }
1644 if (!(chip->hwshare & WSS_HWSHARE_DMA2) &&
1645 chip->dma2 >= 0 && chip->dma2 != chip->dma1) {
1646 snd_dma_disable(chip->dma2);
1647 free_dma(chip->dma2);
1648 }
1649 if (chip->timer)
1650 snd_device_free(chip->card, chip->timer);
1651 kfree(chip);
1652 return 0;
1653}
1654
1655static int snd_wss_dev_free(struct snd_device *device)
1656{
1657 struct snd_wss *chip = device->device_data;
1658 return snd_wss_free(chip);
1659}
1660
1661const char *snd_wss_chip_id(struct snd_wss *chip)
1662{
1663 switch (chip->hardware) {
1664 case WSS_HW_CS4231:
1665 return "CS4231";
1666 case WSS_HW_CS4231A:
1667 return "CS4231A";
1668 case WSS_HW_CS4232:
1669 return "CS4232";
1670 case WSS_HW_CS4232A:
1671 return "CS4232A";
1672 case WSS_HW_CS4235:
1673 return "CS4235";
1674 case WSS_HW_CS4236:
1675 return "CS4236";
1676 case WSS_HW_CS4236B:
1677 return "CS4236B";
1678 case WSS_HW_CS4237B:
1679 return "CS4237B";
1680 case WSS_HW_CS4238B:
1681 return "CS4238B";
1682 case WSS_HW_CS4239:
1683 return "CS4239";
1684 case WSS_HW_INTERWAVE:
1685 return "AMD InterWave";
1686 case WSS_HW_OPL3SA2:
1687 return chip->card->shortname;
1688 case WSS_HW_AD1845:
1689 return "AD1845";
1690 case WSS_HW_OPTI93X:
1691 return "OPTi 93x";
1692 case WSS_HW_AD1847:
1693 return "AD1847";
1694 case WSS_HW_AD1848:
1695 return "AD1848";
1696 case WSS_HW_CS4248:
1697 return "CS4248";
1698 case WSS_HW_CMI8330:
1699 return "CMI8330/C3D";
1700 default:
1701 return "???";
1702 }
1703}
1704EXPORT_SYMBOL(snd_wss_chip_id);
1705
1706static int snd_wss_new(struct snd_card *card,
1707 unsigned short hardware,
1708 unsigned short hwshare,
1709 struct snd_wss **rchip)
1710{
1711 struct snd_wss *chip;
1712
1713 *rchip = NULL;
1714 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
1715 if (chip == NULL)
1716 return -ENOMEM;
1717 chip->hardware = hardware;
1718 chip->hwshare = hwshare;
1719
1720 spin_lock_init(&chip->reg_lock);
1721 mutex_init(&chip->mce_mutex);
1722 mutex_init(&chip->open_mutex);
1723 chip->card = card;
1724 chip->rate_constraint = snd_wss_xrate;
1725 chip->set_playback_format = snd_wss_playback_format;
1726 chip->set_capture_format = snd_wss_capture_format;
1727 if (chip->hardware == WSS_HW_OPTI93X)
1728 memcpy(&chip->image, &snd_opti93x_original_image,
1729 sizeof(snd_opti93x_original_image));
1730 else
1731 memcpy(&chip->image, &snd_wss_original_image,
1732 sizeof(snd_wss_original_image));
1733 if (chip->hardware & WSS_HW_AD1848_MASK) {
1734 chip->image[CS4231_PIN_CTRL] = 0;
1735 chip->image[CS4231_TEST_INIT] = 0;
1736 }
1737
1738 *rchip = chip;
1739 return 0;
1740}
1741
1742int snd_wss_create(struct snd_card *card,
1743 unsigned long port,
1744 unsigned long cport,
1745 int irq, int dma1, int dma2,
1746 unsigned short hardware,
1747 unsigned short hwshare,
1748 struct snd_wss **rchip)
1749{
1750 static struct snd_device_ops ops = {
1751 .dev_free = snd_wss_dev_free,
1752 };
1753 struct snd_wss *chip;
1754 int err;
1755
1756 err = snd_wss_new(card, hardware, hwshare, &chip);
1757 if (err < 0)
1758 return err;
1759
1760 chip->irq = -1;
1761 chip->dma1 = -1;
1762 chip->dma2 = -1;
1763
1764 chip->res_port = request_region(port, 4, "WSS");
1765 if (!chip->res_port) {
1766 snd_printk(KERN_ERR "wss: can't grab port 0x%lx\n", port);
1767 snd_wss_free(chip);
1768 return -EBUSY;
1769 }
1770 chip->port = port;
1771 if ((long)cport >= 0) {
1772 chip->res_cport = request_region(cport, 8, "CS4232 Control");
1773 if (!chip->res_cport) {
1774 snd_printk(KERN_ERR
1775 "wss: can't grab control port 0x%lx\n", cport);
1776 snd_wss_free(chip);
1777 return -ENODEV;
1778 }
1779 }
1780 chip->cport = cport;
1781 if (!(hwshare & WSS_HWSHARE_IRQ))
1782 if (request_irq(irq, snd_wss_interrupt, IRQF_DISABLED,
1783 "WSS", (void *) chip)) {
1784 snd_printk(KERN_ERR "wss: can't grab IRQ %d\n", irq);
1785 snd_wss_free(chip);
1786 return -EBUSY;
1787 }
1788 chip->irq = irq;
1789 if (!(hwshare & WSS_HWSHARE_DMA1) && request_dma(dma1, "WSS - 1")) {
1790 snd_printk(KERN_ERR "wss: can't grab DMA1 %d\n", dma1);
1791 snd_wss_free(chip);
1792 return -EBUSY;
1793 }
1794 chip->dma1 = dma1;
1795 if (!(hwshare & WSS_HWSHARE_DMA2) && dma1 != dma2 &&
1796 dma2 >= 0 && request_dma(dma2, "WSS - 2")) {
1797 snd_printk(KERN_ERR "wss: can't grab DMA2 %d\n", dma2);
1798 snd_wss_free(chip);
1799 return -EBUSY;
1800 }
1801 if (dma1 == dma2 || dma2 < 0) {
1802 chip->single_dma = 1;
1803 chip->dma2 = chip->dma1;
1804 } else
1805 chip->dma2 = dma2;
1806
1807 if (hardware == WSS_HW_THINKPAD) {
1808 chip->thinkpad_flag = 1;
1809 chip->hardware = WSS_HW_DETECT; /* reset */
1810 snd_wss_thinkpad_twiddle(chip, 1);
1811 }
1812
1813 /* global setup */
1814 if (snd_wss_probe(chip) < 0) {
1815 snd_wss_free(chip);
1816 return -ENODEV;
1817 }
1818 snd_wss_init(chip);
1819
1820#if 0
1821 if (chip->hardware & WSS_HW_CS4232_MASK) {
1822 if (chip->res_cport == NULL)
1823 snd_printk("CS4232 control port features are not accessible\n");
1824 }
1825#endif
1826
1827 /* Register device */
1828 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
1829 if (err < 0) {
1830 snd_wss_free(chip);
1831 return err;
1832 }
1833
1834#ifdef CONFIG_PM
1835 /* Power Management */
1836 chip->suspend = snd_wss_suspend;
1837 chip->resume = snd_wss_resume;
1838#endif
1839
1840 *rchip = chip;
1841 return 0;
1842}
1843EXPORT_SYMBOL(snd_wss_create);
1844
1845static struct snd_pcm_ops snd_wss_playback_ops = {
1846 .open = snd_wss_playback_open,
1847 .close = snd_wss_playback_close,
1848 .ioctl = snd_pcm_lib_ioctl,
1849 .hw_params = snd_wss_playback_hw_params,
1850 .hw_free = snd_wss_playback_hw_free,
1851 .prepare = snd_wss_playback_prepare,
1852 .trigger = snd_wss_trigger,
1853 .pointer = snd_wss_playback_pointer,
1854};
1855
1856static struct snd_pcm_ops snd_wss_capture_ops = {
1857 .open = snd_wss_capture_open,
1858 .close = snd_wss_capture_close,
1859 .ioctl = snd_pcm_lib_ioctl,
1860 .hw_params = snd_wss_capture_hw_params,
1861 .hw_free = snd_wss_capture_hw_free,
1862 .prepare = snd_wss_capture_prepare,
1863 .trigger = snd_wss_trigger,
1864 .pointer = snd_wss_capture_pointer,
1865};
1866
1867int snd_wss_pcm(struct snd_wss *chip, int device, struct snd_pcm **rpcm)
1868{
1869 struct snd_pcm *pcm;
1870 int err;
1871
1872 err = snd_pcm_new(chip->card, "WSS", device, 1, 1, &pcm);
1873 if (err < 0)
1874 return err;
1875
1876 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_wss_playback_ops);
1877 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_wss_capture_ops);
1878
1879 /* global setup */
1880 pcm->private_data = chip;
1881 pcm->info_flags = 0;
1882 if (chip->single_dma)
1883 pcm->info_flags |= SNDRV_PCM_INFO_HALF_DUPLEX;
1884 if (chip->hardware != WSS_HW_INTERWAVE)
1885 pcm->info_flags |= SNDRV_PCM_INFO_JOINT_DUPLEX;
1886 strcpy(pcm->name, snd_wss_chip_id(chip));
1887
1888 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1889 snd_dma_isa_data(),
1890 64*1024, chip->dma1 > 3 || chip->dma2 > 3 ? 128*1024 : 64*1024);
1891
1892 chip->pcm = pcm;
1893 if (rpcm)
1894 *rpcm = pcm;
1895 return 0;
1896}
1897EXPORT_SYMBOL(snd_wss_pcm);
1898
1899static void snd_wss_timer_free(struct snd_timer *timer)
1900{
1901 struct snd_wss *chip = timer->private_data;
1902 chip->timer = NULL;
1903}
1904
1905int snd_wss_timer(struct snd_wss *chip, int device, struct snd_timer **rtimer)
1906{
1907 struct snd_timer *timer;
1908 struct snd_timer_id tid;
1909 int err;
1910
1911 /* Timer initialization */
1912 tid.dev_class = SNDRV_TIMER_CLASS_CARD;
1913 tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
1914 tid.card = chip->card->number;
1915 tid.device = device;
1916 tid.subdevice = 0;
1917 if ((err = snd_timer_new(chip->card, "CS4231", &tid, &timer)) < 0)
1918 return err;
1919 strcpy(timer->name, snd_wss_chip_id(chip));
1920 timer->private_data = chip;
1921 timer->private_free = snd_wss_timer_free;
1922 timer->hw = snd_wss_timer_table;
1923 chip->timer = timer;
1924 if (rtimer)
1925 *rtimer = timer;
1926 return 0;
1927}
1928EXPORT_SYMBOL(snd_wss_timer);
1929
1930/*
1931 * MIXER part
1932 */
1933
1934static int snd_wss_info_mux(struct snd_kcontrol *kcontrol,
1935 struct snd_ctl_elem_info *uinfo)
1936{
1937 static char *texts[4] = {
1938 "Line", "Aux", "Mic", "Mix"
1939 };
1940 static char *opl3sa_texts[4] = {
1941 "Line", "CD", "Mic", "Mix"
1942 };
1943 static char *gusmax_texts[4] = {
1944 "Line", "Synth", "Mic", "Mix"
1945 };
1946 char **ptexts = texts;
1947 struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
1948
1949 if (snd_BUG_ON(!chip->card))
1950 return -EINVAL;
1951 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1952 uinfo->count = 2;
1953 uinfo->value.enumerated.items = 4;
1954 if (uinfo->value.enumerated.item > 3)
1955 uinfo->value.enumerated.item = 3;
1956 if (!strcmp(chip->card->driver, "GUS MAX"))
1957 ptexts = gusmax_texts;
1958 switch (chip->hardware) {
1959 case WSS_HW_INTERWAVE:
1960 ptexts = gusmax_texts;
1961 break;
1962 case WSS_HW_OPL3SA2:
1963 ptexts = opl3sa_texts;
1964 break;
1965 }
1966 strcpy(uinfo->value.enumerated.name, ptexts[uinfo->value.enumerated.item]);
1967 return 0;
1968}
1969
1970static int snd_wss_get_mux(struct snd_kcontrol *kcontrol,
1971 struct snd_ctl_elem_value *ucontrol)
1972{
1973 struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
1974 unsigned long flags;
1975
1976 spin_lock_irqsave(&chip->reg_lock, flags);
1977 ucontrol->value.enumerated.item[0] = (chip->image[CS4231_LEFT_INPUT] & CS4231_MIXS_ALL) >> 6;
1978 ucontrol->value.enumerated.item[1] = (chip->image[CS4231_RIGHT_INPUT] & CS4231_MIXS_ALL) >> 6;
1979 spin_unlock_irqrestore(&chip->reg_lock, flags);
1980 return 0;
1981}
1982
1983static int snd_wss_put_mux(struct snd_kcontrol *kcontrol,
1984 struct snd_ctl_elem_value *ucontrol)
1985{
1986 struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
1987 unsigned long flags;
1988 unsigned short left, right;
1989 int change;
1990
1991 if (ucontrol->value.enumerated.item[0] > 3 ||
1992 ucontrol->value.enumerated.item[1] > 3)
1993 return -EINVAL;
1994 left = ucontrol->value.enumerated.item[0] << 6;
1995 right = ucontrol->value.enumerated.item[1] << 6;
1996 spin_lock_irqsave(&chip->reg_lock, flags);
1997 left = (chip->image[CS4231_LEFT_INPUT] & ~CS4231_MIXS_ALL) | left;
1998 right = (chip->image[CS4231_RIGHT_INPUT] & ~CS4231_MIXS_ALL) | right;
1999 change = left != chip->image[CS4231_LEFT_INPUT] ||
2000 right != chip->image[CS4231_RIGHT_INPUT];
2001 snd_wss_out(chip, CS4231_LEFT_INPUT, left);
2002 snd_wss_out(chip, CS4231_RIGHT_INPUT, right);
2003 spin_unlock_irqrestore(&chip->reg_lock, flags);
2004 return change;
2005}
2006
2007int snd_wss_info_single(struct snd_kcontrol *kcontrol,
2008 struct snd_ctl_elem_info *uinfo)
2009{
2010 int mask = (kcontrol->private_value >> 16) & 0xff;
2011
2012 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
2013 uinfo->count = 1;
2014 uinfo->value.integer.min = 0;
2015 uinfo->value.integer.max = mask;
2016 return 0;
2017}
2018EXPORT_SYMBOL(snd_wss_info_single);
2019
2020int snd_wss_get_single(struct snd_kcontrol *kcontrol,
2021 struct snd_ctl_elem_value *ucontrol)
2022{
2023 struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
2024 unsigned long flags;
2025 int reg = kcontrol->private_value & 0xff;
2026 int shift = (kcontrol->private_value >> 8) & 0xff;
2027 int mask = (kcontrol->private_value >> 16) & 0xff;
2028 int invert = (kcontrol->private_value >> 24) & 0xff;
2029
2030 spin_lock_irqsave(&chip->reg_lock, flags);
2031 ucontrol->value.integer.value[0] = (chip->image[reg] >> shift) & mask;
2032 spin_unlock_irqrestore(&chip->reg_lock, flags);
2033 if (invert)
2034 ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
2035 return 0;
2036}
2037EXPORT_SYMBOL(snd_wss_get_single);
2038
2039int snd_wss_put_single(struct snd_kcontrol *kcontrol,
2040 struct snd_ctl_elem_value *ucontrol)
2041{
2042 struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
2043 unsigned long flags;
2044 int reg = kcontrol->private_value & 0xff;
2045 int shift = (kcontrol->private_value >> 8) & 0xff;
2046 int mask = (kcontrol->private_value >> 16) & 0xff;
2047 int invert = (kcontrol->private_value >> 24) & 0xff;
2048 int change;
2049 unsigned short val;
2050
2051 val = (ucontrol->value.integer.value[0] & mask);
2052 if (invert)
2053 val = mask - val;
2054 val <<= shift;
2055 spin_lock_irqsave(&chip->reg_lock, flags);
2056 val = (chip->image[reg] & ~(mask << shift)) | val;
2057 change = val != chip->image[reg];
2058 snd_wss_out(chip, reg, val);
2059 spin_unlock_irqrestore(&chip->reg_lock, flags);
2060 return change;
2061}
2062EXPORT_SYMBOL(snd_wss_put_single);
2063
2064int snd_wss_info_double(struct snd_kcontrol *kcontrol,
2065 struct snd_ctl_elem_info *uinfo)
2066{
2067 int mask = (kcontrol->private_value >> 24) & 0xff;
2068
2069 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
2070 uinfo->count = 2;
2071 uinfo->value.integer.min = 0;
2072 uinfo->value.integer.max = mask;
2073 return 0;
2074}
2075EXPORT_SYMBOL(snd_wss_info_double);
2076
2077int snd_wss_get_double(struct snd_kcontrol *kcontrol,
2078 struct snd_ctl_elem_value *ucontrol)
2079{
2080 struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
2081 unsigned long flags;
2082 int left_reg = kcontrol->private_value & 0xff;
2083 int right_reg = (kcontrol->private_value >> 8) & 0xff;
2084 int shift_left = (kcontrol->private_value >> 16) & 0x07;
2085 int shift_right = (kcontrol->private_value >> 19) & 0x07;
2086 int mask = (kcontrol->private_value >> 24) & 0xff;
2087 int invert = (kcontrol->private_value >> 22) & 1;
2088
2089 spin_lock_irqsave(&chip->reg_lock, flags);
2090 ucontrol->value.integer.value[0] = (chip->image[left_reg] >> shift_left) & mask;
2091 ucontrol->value.integer.value[1] = (chip->image[right_reg] >> shift_right) & mask;
2092 spin_unlock_irqrestore(&chip->reg_lock, flags);
2093 if (invert) {
2094 ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
2095 ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1];
2096 }
2097 return 0;
2098}
2099EXPORT_SYMBOL(snd_wss_get_double);
2100
2101int snd_wss_put_double(struct snd_kcontrol *kcontrol,
2102 struct snd_ctl_elem_value *ucontrol)
2103{
2104 struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
2105 unsigned long flags;
2106 int left_reg = kcontrol->private_value & 0xff;
2107 int right_reg = (kcontrol->private_value >> 8) & 0xff;
2108 int shift_left = (kcontrol->private_value >> 16) & 0x07;
2109 int shift_right = (kcontrol->private_value >> 19) & 0x07;
2110 int mask = (kcontrol->private_value >> 24) & 0xff;
2111 int invert = (kcontrol->private_value >> 22) & 1;
2112 int change;
2113 unsigned short val1, val2;
2114
2115 val1 = ucontrol->value.integer.value[0] & mask;
2116 val2 = ucontrol->value.integer.value[1] & mask;
2117 if (invert) {
2118 val1 = mask - val1;
2119 val2 = mask - val2;
2120 }
2121 val1 <<= shift_left;
2122 val2 <<= shift_right;
2123 spin_lock_irqsave(&chip->reg_lock, flags);
2124 if (left_reg != right_reg) {
2125 val1 = (chip->image[left_reg] & ~(mask << shift_left)) | val1;
2126 val2 = (chip->image[right_reg] & ~(mask << shift_right)) | val2;
2127 change = val1 != chip->image[left_reg] ||
2128 val2 != chip->image[right_reg];
2129 snd_wss_out(chip, left_reg, val1);
2130 snd_wss_out(chip, right_reg, val2);
2131 } else {
2132 mask = (mask << shift_left) | (mask << shift_right);
2133 val1 = (chip->image[left_reg] & ~mask) | val1 | val2;
2134 change = val1 != chip->image[left_reg];
2135 snd_wss_out(chip, left_reg, val1);
2136 }
2137 spin_unlock_irqrestore(&chip->reg_lock, flags);
2138 return change;
2139}
2140EXPORT_SYMBOL(snd_wss_put_double);
2141
2142static const DECLARE_TLV_DB_SCALE(db_scale_6bit, -9450, 150, 0);
2143static const DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0);
2144static const DECLARE_TLV_DB_SCALE(db_scale_rec_gain, 0, 150, 0);
2145
2146static struct snd_kcontrol_new snd_ad1848_controls[] = {
2147WSS_DOUBLE("PCM Playback Switch", 0, CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT,
2148 7, 7, 1, 1),
2149WSS_DOUBLE_TLV("PCM Playback Volume", 0,
2150 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1,
2151 db_scale_6bit),
2152WSS_DOUBLE("Aux Playback Switch", 0,
2153 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1),
2154WSS_DOUBLE_TLV("Aux Playback Volume", 0,
2155 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1,
2156 db_scale_5bit_12db_max),
2157WSS_DOUBLE("Aux Playback Switch", 1,
2158 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
2159WSS_DOUBLE_TLV("Aux Playback Volume", 1,
2160 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1,
2161 db_scale_5bit_12db_max),
2162WSS_DOUBLE_TLV("Capture Volume", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT,
2163 0, 0, 15, 0, db_scale_rec_gain),
2164{
2165 .name = "Capture Source",
2166 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2167 .info = snd_wss_info_mux,
2168 .get = snd_wss_get_mux,
2169 .put = snd_wss_put_mux,
2170},
2171WSS_SINGLE("Loopback Capture Switch", 0, CS4231_LOOPBACK, 0, 1, 0),
2172WSS_SINGLE_TLV("Loopback Capture Volume", 0, CS4231_LOOPBACK, 1, 63, 0,
2173 db_scale_6bit),
2174};
2175
2176static struct snd_kcontrol_new snd_wss_controls[] = {
2177WSS_DOUBLE("PCM Playback Switch", 0,
2178 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1),
2179WSS_DOUBLE("PCM Playback Volume", 0,
2180 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1),
2181WSS_DOUBLE("Line Playback Switch", 0,
2182 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
2183WSS_DOUBLE("Line Playback Volume", 0,
2184 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1),
2185WSS_DOUBLE("Aux Playback Switch", 0,
2186 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1),
2187WSS_DOUBLE("Aux Playback Volume", 0,
2188 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1),
2189WSS_DOUBLE("Aux Playback Switch", 1,
2190 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
2191WSS_DOUBLE("Aux Playback Volume", 1,
2192 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1),
2193WSS_SINGLE("Mono Playback Switch", 0,
2194 CS4231_MONO_CTRL, 7, 1, 1),
2195WSS_SINGLE("Mono Playback Volume", 0,
2196 CS4231_MONO_CTRL, 0, 15, 1),
2197WSS_SINGLE("Mono Output Playback Switch", 0,
2198 CS4231_MONO_CTRL, 6, 1, 1),
2199WSS_SINGLE("Mono Output Playback Bypass", 0,
2200 CS4231_MONO_CTRL, 5, 1, 0),
2201WSS_DOUBLE("Capture Volume", 0,
2202 CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 0, 0, 15, 0),
2203{
2204 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2205 .name = "Capture Source",
2206 .info = snd_wss_info_mux,
2207 .get = snd_wss_get_mux,
2208 .put = snd_wss_put_mux,
2209},
2210WSS_DOUBLE("Mic Boost", 0,
2211 CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 5, 5, 1, 0),
2212WSS_SINGLE("Loopback Capture Switch", 0,
2213 CS4231_LOOPBACK, 0, 1, 0),
2214WSS_SINGLE("Loopback Capture Volume", 0,
2215 CS4231_LOOPBACK, 2, 63, 1)
2216};
2217
2218static struct snd_kcontrol_new snd_opti93x_controls[] = {
2219WSS_DOUBLE("Master Playback Switch", 0,
2220 OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 7, 7, 1, 1),
2221WSS_DOUBLE("Master Playback Volume", 0,
2222 OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 1, 1, 31, 1),
2223WSS_DOUBLE("PCM Playback Switch", 0,
2224 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1),
2225WSS_DOUBLE("PCM Playback Volume", 0,
2226 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 31, 1),
2227WSS_DOUBLE("FM Playback Switch", 0,
2228 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
2229WSS_DOUBLE("FM Playback Volume", 0,
2230 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 1, 1, 15, 1),
2231WSS_DOUBLE("Line Playback Switch", 0,
2232 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
2233WSS_DOUBLE("Line Playback Volume", 0,
2234 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 15, 1),
2235WSS_DOUBLE("Mic Playback Switch", 0,
2236 OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 7, 7, 1, 1),
2237WSS_DOUBLE("Mic Playback Volume", 0,
2238 OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 1, 1, 15, 1),
2239WSS_DOUBLE("Mic Boost", 0,
2240 CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 5, 5, 1, 0),
2241WSS_DOUBLE("CD Playback Switch", 0,
2242 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1),
2243WSS_DOUBLE("CD Playback Volume", 0,
2244 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 1, 1, 15, 1),
2245WSS_DOUBLE("Aux Playback Switch", 0,
2246 OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 7, 7, 1, 1),
2247WSS_DOUBLE("Aux Playback Volume", 0,
2248 OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 1, 1, 15, 1),
2249WSS_DOUBLE("Capture Volume", 0,
2250 CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 0, 0, 15, 0),
2251{
2252 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2253 .name = "Capture Source",
2254 .info = snd_wss_info_mux,
2255 .get = snd_wss_get_mux,
2256 .put = snd_wss_put_mux,
2257}
2258};
2259
2260int snd_wss_mixer(struct snd_wss *chip)
2261{
2262 struct snd_card *card;
2263 unsigned int idx;
2264 int err;
2265
2266 if (snd_BUG_ON(!chip || !chip->pcm))
2267 return -EINVAL;
2268
2269 card = chip->card;
2270
2271 strcpy(card->mixername, chip->pcm->name);
2272
2273 if (chip->hardware == WSS_HW_OPTI93X)
2274 for (idx = 0; idx < ARRAY_SIZE(snd_opti93x_controls); idx++) {
2275 err = snd_ctl_add(card,
2276 snd_ctl_new1(&snd_opti93x_controls[idx],
2277 chip));
2278 if (err < 0)
2279 return err;
2280 }
2281 else if (chip->hardware & WSS_HW_AD1848_MASK)
2282 for (idx = 0; idx < ARRAY_SIZE(snd_ad1848_controls); idx++) {
2283 err = snd_ctl_add(card,
2284 snd_ctl_new1(&snd_ad1848_controls[idx],
2285 chip));
2286 if (err < 0)
2287 return err;
2288 }
2289 else
2290 for (idx = 0; idx < ARRAY_SIZE(snd_wss_controls); idx++) {
2291 err = snd_ctl_add(card,
2292 snd_ctl_new1(&snd_wss_controls[idx],
2293 chip));
2294 if (err < 0)
2295 return err;
2296 }
2297 return 0;
2298}
2299EXPORT_SYMBOL(snd_wss_mixer);
2300
2301const struct snd_pcm_ops *snd_wss_get_pcm_ops(int direction)
2302{
2303 return direction == SNDRV_PCM_STREAM_PLAYBACK ?
2304 &snd_wss_playback_ops : &snd_wss_capture_ops;
2305}
2306EXPORT_SYMBOL(snd_wss_get_pcm_ops);
2307
2308/*
2309 * INIT part
2310 */
2311
2312static int __init alsa_wss_init(void)
2313{
2314 return 0;
2315}
2316
2317static void __exit alsa_wss_exit(void)
2318{
2319}
2320
2321module_init(alsa_wss_init);
2322module_exit(alsa_wss_exit);
diff --git a/sound/mips/au1x00.c b/sound/mips/au1x00.c
index fbef38a9604a..1881cec11e78 100644
--- a/sound/mips/au1x00.c
+++ b/sound/mips/au1x00.c
@@ -190,14 +190,16 @@ au1000_setup_dma_link(struct audio_stream *stream, unsigned int period_bytes,
190static void 190static void
191au1000_dma_stop(struct audio_stream *stream) 191au1000_dma_stop(struct audio_stream *stream)
192{ 192{
193 snd_assert(stream->buffer, return); 193 if (snd_BUG_ON(!stream->buffer))
194 return;
194 disable_dma(stream->dma); 195 disable_dma(stream->dma);
195} 196}
196 197
197static void 198static void
198au1000_dma_start(struct audio_stream *stream) 199au1000_dma_start(struct audio_stream *stream)
199{ 200{
200 snd_assert(stream->buffer, return); 201 if (snd_BUG_ON(!stream->buffer))
202 return;
201 203
202 init_dma(stream->dma); 204 init_dma(stream->dma);
203 if (get_dma_active_buffer(stream->dma) == 0) { 205 if (get_dma_active_buffer(stream->dma) == 0) {
diff --git a/sound/oss/Kconfig b/sound/oss/Kconfig
index d4fafb6eec6c..1ca7427c4b6d 100644
--- a/sound/oss/Kconfig
+++ b/sound/oss/Kconfig
@@ -24,13 +24,6 @@ config SOUND_VWSND
24 <file:Documentation/sound/oss/vwsnd> for more info on this driver's 24 <file:Documentation/sound/oss/vwsnd> for more info on this driver's
25 capabilities. 25 capabilities.
26 26
27config SOUND_HAL2
28 tristate "SGI HAL2 sound (EXPERIMENTAL)"
29 depends on SGI_IP22 && EXPERIMENTAL
30 help
31 Say Y or M if you have an SGI Indy or Indigo2 system and want to be able to
32 use its on-board A2 audio system.
33
34config SOUND_AU1550_AC97 27config SOUND_AU1550_AC97
35 tristate "Au1550/Au1200 AC97 Sound" 28 tristate "Au1550/Au1200 AC97 Sound"
36 depends on SOC_AU1550 || SOC_AU1200 29 depends on SOC_AU1550 || SOC_AU1200
@@ -546,34 +539,6 @@ config SC6600_CDROMBASE
546 Base I/O port address for the CD-ROM interface of the Audio Excel 539 Base I/O port address for the CD-ROM interface of the Audio Excel
547 DSP 16 card. 540 DSP 16 card.
548 541
549choice
550 prompt "Audio Excel DSP 16"
551 optional
552 depends on SOUND_AEDSP16
553
554config AEDSP16_MSS
555 bool "MSS emulation"
556 depends on SOUND_MSS
557 help
558 Answer Y if you want your audio card to emulate Microsoft Sound
559 System. You should then say Y to "Microsoft Sound System support"
560 and say N to "Audio Excel DSP 16 (SBPro emulation)".
561
562config AEDSP16_SBPRO
563 bool "SBPro emulation"
564 depends on SOUND_SB
565 help
566 Answer Y if you want your audio card to emulate Sound Blaster Pro.
567 You should then say Y to "100% Sound Blaster compatibles
568 (SB16/32/64, ESS, Jazz16) support" and N to "Audio Excel DSP 16 (MSS
569 emulation)".
570
571 If you compile the driver into the kernel, you have to add
572 "aedsp16=<io>,<irq>,<dma>,<mssio>,<mpuio>,<mouirq>" to the kernel
573 command line.
574
575endchoice
576
577config SOUND_VIDC 542config SOUND_VIDC
578 tristate "VIDC 16-bit sound" 543 tristate "VIDC 16-bit sound"
579 depends on ARM && (ARCH_ACORN || ARCH_CLPS7500) 544 depends on ARM && (ARCH_ACORN || ARCH_CLPS7500)
diff --git a/sound/oss/Makefile b/sound/oss/Makefile
index c611514f7ff1..e0ae4d4d6a5c 100644
--- a/sound/oss/Makefile
+++ b/sound/oss/Makefile
@@ -10,7 +10,6 @@ obj-$(CONFIG_SOUND_OSS) += sound.o
10# Please leave it as is, cause the link order is significant ! 10# Please leave it as is, cause the link order is significant !
11 11
12obj-$(CONFIG_SOUND_SH_DAC_AUDIO) += sh_dac_audio.o 12obj-$(CONFIG_SOUND_SH_DAC_AUDIO) += sh_dac_audio.o
13obj-$(CONFIG_SOUND_HAL2) += hal2.o
14obj-$(CONFIG_SOUND_AEDSP16) += aedsp16.o 13obj-$(CONFIG_SOUND_AEDSP16) += aedsp16.o
15obj-$(CONFIG_SOUND_PSS) += pss.o ad1848.o mpu401.o 14obj-$(CONFIG_SOUND_PSS) += pss.o ad1848.o mpu401.o
16obj-$(CONFIG_SOUND_TRIX) += trix.o ad1848.o sb_lib.o uart401.o 15obj-$(CONFIG_SOUND_TRIX) += trix.o ad1848.o sb_lib.o uart401.o
diff --git a/sound/oss/ac97_codec.c b/sound/oss/ac97_codec.c
index b63839e8f9bd..456a1b4d7832 100644
--- a/sound/oss/ac97_codec.c
+++ b/sound/oss/ac97_codec.c
@@ -30,7 +30,7 @@
30 ************************************************************************** 30 **************************************************************************
31 * 31 *
32 * History 32 * History
33 * May 02, 2003 Liam Girdwood <liam.girdwood@wolfsonmicro.com> 33 * May 02, 2003 Liam Girdwood <lrg@slimlogic.co.uk>
34 * Removed non existant WM9700 34 * Removed non existant WM9700
35 * Added support for WM9705, WM9708, WM9709, WM9710, WM9711 35 * Added support for WM9705, WM9708, WM9709, WM9710, WM9711
36 * WM9712 and WM9717 36 * WM9712 and WM9717
diff --git a/sound/oss/aedsp16.c b/sound/oss/aedsp16.c
index 51e1fde62e8d..a0274f3dac08 100644
--- a/sound/oss/aedsp16.c
+++ b/sound/oss/aedsp16.c
@@ -29,14 +29,6 @@
29#include "sound_config.h" 29#include "sound_config.h"
30 30
31/* 31/*
32 * Sanity checks
33 */
34
35#if defined(CONFIG_SOUND_AEDSP16_SBPRO) && defined(CONFIG_SOUND_AEDSP16_MSS)
36#error You have to enable only one of the MSS and SBPRO emulations.
37#endif
38
39/*
40 32
41 READ THIS 33 READ THIS
42 34
diff --git a/sound/oss/dmasound/Kconfig b/sound/oss/dmasound/Kconfig
index 3eb782720e58..f456574a964d 100644
--- a/sound/oss/dmasound/Kconfig
+++ b/sound/oss/dmasound/Kconfig
@@ -42,3 +42,4 @@ config DMASOUND_Q40
42 42
43config DMASOUND 43config DMASOUND
44 tristate 44 tristate
45 select SOUND_OSS_CORE
diff --git a/sound/oss/hal2.c b/sound/oss/hal2.c
deleted file mode 100644
index a94b9df489dc..000000000000
--- a/sound/oss/hal2.c
+++ /dev/null
@@ -1,1558 +0,0 @@
1/*
2 * Driver for A2 audio system used in SGI machines
3 * Copyright (c) 2001, 2002, 2003 Ladislav Michl <ladis@linux-mips.org>
4 *
5 * Based on Ulf Carlsson's code.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * 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
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 * Supported devices:
21 * /dev/dsp standard dsp device, (mostly) OSS compatible
22 * /dev/mixer standard mixer device, (mostly) OSS compatible
23 *
24 */
25#include <linux/kernel.h>
26#include <linux/module.h>
27#include <linux/sched.h>
28#include <linux/init.h>
29#include <linux/slab.h>
30#include <linux/poll.h>
31#include <linux/interrupt.h>
32#include <linux/dma-mapping.h>
33#include <linux/sound.h>
34#include <linux/soundcard.h>
35#include <linux/mutex.h>
36
37
38#include <asm/io.h>
39#include <asm/sgi/hpc3.h>
40#include <asm/sgi/ip22.h>
41
42#include "hal2.h"
43
44#if 0
45#define DEBUG(args...) printk(args)
46#else
47#define DEBUG(args...)
48#endif
49
50#if 0
51#define DEBUG_MIX(args...) printk(args)
52#else
53#define DEBUG_MIX(args...)
54#endif
55
56/*
57 * Before touching these look how it works. It is a bit unusual I know,
58 * but it helps to keep things simple. This driver is considered complete
59 * and I won't add any new features although hardware has many cool
60 * capabilities.
61 * (Historical note: HAL2 driver was first written by Ulf Carlsson - ALSA
62 * 0.3 running with 2.2.x kernel. Then ALSA changed completely and it
63 * seemed easier to me to write OSS driver from scratch - this one. Now
64 * when ALSA is official part of 2.6 kernel it's time to write ALSA driver
65 * using (hopefully) final version of ALSA interface)
66 */
67#define H2_BLOCK_SIZE 1024
68#define H2_ADC_BUFSIZE 8192
69#define H2_DAC_BUFSIZE 16834
70
71struct hal2_pbus {
72 struct hpc3_pbus_dmacregs *pbus;
73 int pbusnr;
74 unsigned int ctrl; /* Current state of pbus->pbdma_ctrl */
75};
76
77struct hal2_desc {
78 struct hpc_dma_desc desc;
79 u32 cnt; /* don't touch, it is also padding */
80};
81
82struct hal2_codec {
83 unsigned char *buffer;
84 struct hal2_desc *desc;
85 int desc_count;
86 int tail, head; /* tail index, head index */
87 struct hal2_pbus pbus;
88 unsigned int format; /* Audio data format */
89 int voices; /* mono/stereo */
90 unsigned int sample_rate;
91 unsigned int master; /* Master frequency */
92 unsigned short mod; /* MOD value */
93 unsigned short inc; /* INC value */
94
95 wait_queue_head_t dma_wait;
96 spinlock_t lock;
97 struct mutex sem;
98
99 int usecount; /* recording and playback are
100 * independent */
101};
102
103#define H2_MIX_OUTPUT_ATT 0
104#define H2_MIX_INPUT_GAIN 1
105#define H2_MIXERS 2
106struct hal2_mixer {
107 int modcnt;
108 unsigned int master;
109 unsigned int volume[H2_MIXERS];
110};
111
112struct hal2_card {
113 int dev_dsp; /* audio device */
114 int dev_mixer; /* mixer device */
115 int dev_midi; /* midi device */
116
117 struct hal2_ctl_regs *ctl_regs; /* HAL2 ctl registers */
118 struct hal2_aes_regs *aes_regs; /* HAL2 aes registers */
119 struct hal2_vol_regs *vol_regs; /* HAL2 vol registers */
120 struct hal2_syn_regs *syn_regs; /* HAL2 syn registers */
121
122 struct hal2_codec dac;
123 struct hal2_codec adc;
124 struct hal2_mixer mixer;
125};
126
127#define H2_INDIRECT_WAIT(regs) while (regs->isr & H2_ISR_TSTATUS);
128
129#define H2_READ_ADDR(addr) (addr | (1<<7))
130#define H2_WRITE_ADDR(addr) (addr)
131
132static char *hal2str = "HAL2";
133
134/*
135 * I doubt anyone has a machine with two HAL2 cards. It's possible to
136 * have two HPC's, so it is probably possible to have two HAL2 cards.
137 * Try to deal with it, but note that it is not tested.
138 */
139#define MAXCARDS 2
140static struct hal2_card* hal2_card[MAXCARDS];
141
142static const struct {
143 unsigned char idx:4, avail:1;
144} mixtable[SOUND_MIXER_NRDEVICES] = {
145 [SOUND_MIXER_PCM] = { H2_MIX_OUTPUT_ATT, 1 }, /* voice */
146 [SOUND_MIXER_MIC] = { H2_MIX_INPUT_GAIN, 1 }, /* mic */
147};
148
149#define H2_SUPPORTED_FORMATS (AFMT_S16_LE | AFMT_S16_BE)
150
151static inline void hal2_isr_write(struct hal2_card *hal2, u16 val)
152{
153 hal2->ctl_regs->isr = val;
154}
155
156static inline u16 hal2_isr_look(struct hal2_card *hal2)
157{
158 return hal2->ctl_regs->isr;
159}
160
161static inline u16 hal2_rev_look(struct hal2_card *hal2)
162{
163 return hal2->ctl_regs->rev;
164}
165
166#ifdef HAL2_DUMP_REGS
167static u16 hal2_i_look16(struct hal2_card *hal2, u16 addr)
168{
169 struct hal2_ctl_regs *regs = hal2->ctl_regs;
170
171 regs->iar = H2_READ_ADDR(addr);
172 H2_INDIRECT_WAIT(regs);
173 return regs->idr0;
174}
175#endif
176
177static u32 hal2_i_look32(struct hal2_card *hal2, u16 addr)
178{
179 u32 ret;
180 struct hal2_ctl_regs *regs = hal2->ctl_regs;
181
182 regs->iar = H2_READ_ADDR(addr);
183 H2_INDIRECT_WAIT(regs);
184 ret = regs->idr0 & 0xffff;
185 regs->iar = H2_READ_ADDR(addr | 0x1);
186 H2_INDIRECT_WAIT(regs);
187 ret |= (regs->idr0 & 0xffff) << 16;
188 return ret;
189}
190
191static void hal2_i_write16(struct hal2_card *hal2, u16 addr, u16 val)
192{
193 struct hal2_ctl_regs *regs = hal2->ctl_regs;
194
195 regs->idr0 = val;
196 regs->idr1 = 0;
197 regs->idr2 = 0;
198 regs->idr3 = 0;
199 regs->iar = H2_WRITE_ADDR(addr);
200 H2_INDIRECT_WAIT(regs);
201}
202
203static void hal2_i_write32(struct hal2_card *hal2, u16 addr, u32 val)
204{
205 struct hal2_ctl_regs *regs = hal2->ctl_regs;
206
207 regs->idr0 = val & 0xffff;
208 regs->idr1 = val >> 16;
209 regs->idr2 = 0;
210 regs->idr3 = 0;
211 regs->iar = H2_WRITE_ADDR(addr);
212 H2_INDIRECT_WAIT(regs);
213}
214
215static void hal2_i_setbit16(struct hal2_card *hal2, u16 addr, u16 bit)
216{
217 struct hal2_ctl_regs *regs = hal2->ctl_regs;
218
219 regs->iar = H2_READ_ADDR(addr);
220 H2_INDIRECT_WAIT(regs);
221 regs->idr0 = (regs->idr0 & 0xffff) | bit;
222 regs->idr1 = 0;
223 regs->idr2 = 0;
224 regs->idr3 = 0;
225 regs->iar = H2_WRITE_ADDR(addr);
226 H2_INDIRECT_WAIT(regs);
227}
228
229static void hal2_i_setbit32(struct hal2_card *hal2, u16 addr, u32 bit)
230{
231 u32 tmp;
232 struct hal2_ctl_regs *regs = hal2->ctl_regs;
233
234 regs->iar = H2_READ_ADDR(addr);
235 H2_INDIRECT_WAIT(regs);
236 tmp = (regs->idr0 & 0xffff) | (regs->idr1 << 16) | bit;
237 regs->idr0 = tmp & 0xffff;
238 regs->idr1 = tmp >> 16;
239 regs->idr2 = 0;
240 regs->idr3 = 0;
241 regs->iar = H2_WRITE_ADDR(addr);
242 H2_INDIRECT_WAIT(regs);
243}
244
245static void hal2_i_clearbit16(struct hal2_card *hal2, u16 addr, u16 bit)
246{
247 struct hal2_ctl_regs *regs = hal2->ctl_regs;
248
249 regs->iar = H2_READ_ADDR(addr);
250 H2_INDIRECT_WAIT(regs);
251 regs->idr0 = (regs->idr0 & 0xffff) & ~bit;
252 regs->idr1 = 0;
253 regs->idr2 = 0;
254 regs->idr3 = 0;
255 regs->iar = H2_WRITE_ADDR(addr);
256 H2_INDIRECT_WAIT(regs);
257}
258
259#if 0
260static void hal2_i_clearbit32(struct hal2_card *hal2, u16 addr, u32 bit)
261{
262 u32 tmp;
263 hal2_ctl_regs_t *regs = hal2->ctl_regs;
264
265 regs->iar = H2_READ_ADDR(addr);
266 H2_INDIRECT_WAIT(regs);
267 tmp = ((regs->idr0 & 0xffff) | (regs->idr1 << 16)) & ~bit;
268 regs->idr0 = tmp & 0xffff;
269 regs->idr1 = tmp >> 16;
270 regs->idr2 = 0;
271 regs->idr3 = 0;
272 regs->iar = H2_WRITE_ADDR(addr);
273 H2_INDIRECT_WAIT(regs);
274}
275#endif
276
277#ifdef HAL2_DUMP_REGS
278static void hal2_dump_regs(struct hal2_card *hal2)
279{
280 DEBUG("isr: %08hx ", hal2_isr_look(hal2));
281 DEBUG("rev: %08hx\n", hal2_rev_look(hal2));
282 DEBUG("relay: %04hx\n", hal2_i_look16(hal2, H2I_RELAY_C));
283 DEBUG("port en: %04hx ", hal2_i_look16(hal2, H2I_DMA_PORT_EN));
284 DEBUG("dma end: %04hx ", hal2_i_look16(hal2, H2I_DMA_END));
285 DEBUG("dma drv: %04hx\n", hal2_i_look16(hal2, H2I_DMA_DRV));
286 DEBUG("syn ctl: %04hx ", hal2_i_look16(hal2, H2I_SYNTH_C));
287 DEBUG("aesrx ctl: %04hx ", hal2_i_look16(hal2, H2I_AESRX_C));
288 DEBUG("aestx ctl: %04hx ", hal2_i_look16(hal2, H2I_AESTX_C));
289 DEBUG("dac ctl1: %04hx ", hal2_i_look16(hal2, H2I_ADC_C1));
290 DEBUG("dac ctl2: %08x ", hal2_i_look32(hal2, H2I_ADC_C2));
291 DEBUG("adc ctl1: %04hx ", hal2_i_look16(hal2, H2I_DAC_C1));
292 DEBUG("adc ctl2: %08x ", hal2_i_look32(hal2, H2I_DAC_C2));
293 DEBUG("syn map: %04hx\n", hal2_i_look16(hal2, H2I_SYNTH_MAP_C));
294 DEBUG("bres1 ctl1: %04hx ", hal2_i_look16(hal2, H2I_BRES1_C1));
295 DEBUG("bres1 ctl2: %04x ", hal2_i_look32(hal2, H2I_BRES1_C2));
296 DEBUG("bres2 ctl1: %04hx ", hal2_i_look16(hal2, H2I_BRES2_C1));
297 DEBUG("bres2 ctl2: %04x ", hal2_i_look32(hal2, H2I_BRES2_C2));
298 DEBUG("bres3 ctl1: %04hx ", hal2_i_look16(hal2, H2I_BRES3_C1));
299 DEBUG("bres3 ctl2: %04x\n", hal2_i_look32(hal2, H2I_BRES3_C2));
300}
301#endif
302
303static struct hal2_card* hal2_dsp_find_card(int minor)
304{
305 int i;
306
307 for (i = 0; i < MAXCARDS; i++)
308 if (hal2_card[i] != NULL && hal2_card[i]->dev_dsp == minor)
309 return hal2_card[i];
310 return NULL;
311}
312
313static struct hal2_card* hal2_mixer_find_card(int minor)
314{
315 int i;
316
317 for (i = 0; i < MAXCARDS; i++)
318 if (hal2_card[i] != NULL && hal2_card[i]->dev_mixer == minor)
319 return hal2_card[i];
320 return NULL;
321}
322
323static void hal2_inc_head(struct hal2_codec *codec)
324{
325 codec->head++;
326 if (codec->head == codec->desc_count)
327 codec->head = 0;
328}
329
330static void hal2_inc_tail(struct hal2_codec *codec)
331{
332 codec->tail++;
333 if (codec->tail == codec->desc_count)
334 codec->tail = 0;
335}
336
337static void hal2_dac_interrupt(struct hal2_codec *dac)
338{
339 int running;
340
341 spin_lock(&dac->lock);
342 /* if tail buffer contains zero samples DMA stream was already
343 * stopped */
344 running = dac->desc[dac->tail].cnt;
345 dac->desc[dac->tail].cnt = 0;
346 dac->desc[dac->tail].desc.cntinfo = HPCDMA_XIE | HPCDMA_EOX;
347 /* we just proccessed empty buffer, don't update tail pointer */
348 if (running)
349 hal2_inc_tail(dac);
350 spin_unlock(&dac->lock);
351
352 wake_up(&dac->dma_wait);
353}
354
355static void hal2_adc_interrupt(struct hal2_codec *adc)
356{
357 int running;
358
359 spin_lock(&adc->lock);
360 /* if head buffer contains nonzero samples DMA stream was already
361 * stopped */
362 running = !adc->desc[adc->head].cnt;
363 adc->desc[adc->head].cnt = H2_BLOCK_SIZE;
364 adc->desc[adc->head].desc.cntinfo = HPCDMA_XIE | HPCDMA_EOR;
365 /* we just proccessed empty buffer, don't update head pointer */
366 if (running)
367 hal2_inc_head(adc);
368 spin_unlock(&adc->lock);
369
370 wake_up(&adc->dma_wait);
371}
372
373static irqreturn_t hal2_interrupt(int irq, void *dev_id)
374{
375 struct hal2_card *hal2 = dev_id;
376 irqreturn_t ret = IRQ_NONE;
377
378 /* decide what caused this interrupt */
379 if (hal2->dac.pbus.pbus->pbdma_ctrl & HPC3_PDMACTRL_INT) {
380 hal2_dac_interrupt(&hal2->dac);
381 ret = IRQ_HANDLED;
382 }
383 if (hal2->adc.pbus.pbus->pbdma_ctrl & HPC3_PDMACTRL_INT) {
384 hal2_adc_interrupt(&hal2->adc);
385 ret = IRQ_HANDLED;
386 }
387 return ret;
388}
389
390static int hal2_compute_rate(struct hal2_codec *codec, unsigned int rate)
391{
392 unsigned short mod;
393
394 DEBUG("rate: %d\n", rate);
395
396 if (rate < 4000) rate = 4000;
397 else if (rate > 48000) rate = 48000;
398
399 if (44100 % rate < 48000 % rate) {
400 mod = 4 * 44100 / rate;
401 codec->master = 44100;
402 } else {
403 mod = 4 * 48000 / rate;
404 codec->master = 48000;
405 }
406
407 codec->inc = 4;
408 codec->mod = mod;
409 rate = 4 * codec->master / mod;
410
411 DEBUG("real_rate: %d\n", rate);
412
413 return rate;
414}
415
416static void hal2_set_dac_rate(struct hal2_card *hal2)
417{
418 unsigned int master = hal2->dac.master;
419 int inc = hal2->dac.inc;
420 int mod = hal2->dac.mod;
421
422 DEBUG("master: %d inc: %d mod: %d\n", master, inc, mod);
423
424 hal2_i_write16(hal2, H2I_BRES1_C1, (master == 44100) ? 1 : 0);
425 hal2_i_write32(hal2, H2I_BRES1_C2, ((0xffff & (inc - mod - 1)) << 16) | inc);
426}
427
428static void hal2_set_adc_rate(struct hal2_card *hal2)
429{
430 unsigned int master = hal2->adc.master;
431 int inc = hal2->adc.inc;
432 int mod = hal2->adc.mod;
433
434 DEBUG("master: %d inc: %d mod: %d\n", master, inc, mod);
435
436 hal2_i_write16(hal2, H2I_BRES2_C1, (master == 44100) ? 1 : 0);
437 hal2_i_write32(hal2, H2I_BRES2_C2, ((0xffff & (inc - mod - 1)) << 16) | inc);
438}
439
440static void hal2_setup_dac(struct hal2_card *hal2)
441{
442 unsigned int fifobeg, fifoend, highwater, sample_size;
443 struct hal2_pbus *pbus = &hal2->dac.pbus;
444
445 DEBUG("hal2_setup_dac\n");
446
447 /* Now we set up some PBUS information. The PBUS needs information about
448 * what portion of the fifo it will use. If it's receiving or
449 * transmitting, and finally whether the stream is little endian or big
450 * endian. The information is written later, on the start call.
451 */
452 sample_size = 2 * hal2->dac.voices;
453 /* Fifo should be set to hold exactly four samples. Highwater mark
454 * should be set to two samples. */
455 highwater = (sample_size * 2) >> 1; /* halfwords */
456 fifobeg = 0; /* playback is first */
457 fifoend = (sample_size * 4) >> 3; /* doublewords */
458 pbus->ctrl = HPC3_PDMACTRL_RT | HPC3_PDMACTRL_LD |
459 (highwater << 8) | (fifobeg << 16) | (fifoend << 24) |
460 (hal2->dac.format & AFMT_S16_LE ? HPC3_PDMACTRL_SEL : 0);
461 /* We disable everything before we do anything at all */
462 pbus->pbus->pbdma_ctrl = HPC3_PDMACTRL_LD;
463 hal2_i_clearbit16(hal2, H2I_DMA_PORT_EN, H2I_DMA_PORT_EN_CODECTX);
464 /* Setup the HAL2 for playback */
465 hal2_set_dac_rate(hal2);
466 /* Set endianess */
467 if (hal2->dac.format & AFMT_S16_LE)
468 hal2_i_setbit16(hal2, H2I_DMA_END, H2I_DMA_END_CODECTX);
469 else
470 hal2_i_clearbit16(hal2, H2I_DMA_END, H2I_DMA_END_CODECTX);
471 /* Set DMA bus */
472 hal2_i_setbit16(hal2, H2I_DMA_DRV, (1 << pbus->pbusnr));
473 /* We are using 1st Bresenham clock generator for playback */
474 hal2_i_write16(hal2, H2I_DAC_C1, (pbus->pbusnr << H2I_C1_DMA_SHIFT)
475 | (1 << H2I_C1_CLKID_SHIFT)
476 | (hal2->dac.voices << H2I_C1_DATAT_SHIFT));
477}
478
479static void hal2_setup_adc(struct hal2_card *hal2)
480{
481 unsigned int fifobeg, fifoend, highwater, sample_size;
482 struct hal2_pbus *pbus = &hal2->adc.pbus;
483
484 DEBUG("hal2_setup_adc\n");
485
486 sample_size = 2 * hal2->adc.voices;
487 highwater = (sample_size * 2) >> 1; /* halfwords */
488 fifobeg = (4 * 4) >> 3; /* record is second */
489 fifoend = (4 * 4 + sample_size * 4) >> 3; /* doublewords */
490 pbus->ctrl = HPC3_PDMACTRL_RT | HPC3_PDMACTRL_RCV | HPC3_PDMACTRL_LD |
491 (highwater << 8) | (fifobeg << 16) | (fifoend << 24) |
492 (hal2->adc.format & AFMT_S16_LE ? HPC3_PDMACTRL_SEL : 0);
493 pbus->pbus->pbdma_ctrl = HPC3_PDMACTRL_LD;
494 hal2_i_clearbit16(hal2, H2I_DMA_PORT_EN, H2I_DMA_PORT_EN_CODECR);
495 /* Setup the HAL2 for record */
496 hal2_set_adc_rate(hal2);
497 /* Set endianess */
498 if (hal2->adc.format & AFMT_S16_LE)
499 hal2_i_setbit16(hal2, H2I_DMA_END, H2I_DMA_END_CODECR);
500 else
501 hal2_i_clearbit16(hal2, H2I_DMA_END, H2I_DMA_END_CODECR);
502 /* Set DMA bus */
503 hal2_i_setbit16(hal2, H2I_DMA_DRV, (1 << pbus->pbusnr));
504 /* We are using 2nd Bresenham clock generator for record */
505 hal2_i_write16(hal2, H2I_ADC_C1, (pbus->pbusnr << H2I_C1_DMA_SHIFT)
506 | (2 << H2I_C1_CLKID_SHIFT)
507 | (hal2->adc.voices << H2I_C1_DATAT_SHIFT));
508}
509
510static dma_addr_t hal2_desc_addr(struct hal2_codec *codec, int i)
511{
512 if (--i < 0)
513 i = codec->desc_count - 1;
514 return codec->desc[i].desc.pnext;
515}
516
517static void hal2_start_dac(struct hal2_card *hal2)
518{
519 struct hal2_codec *dac = &hal2->dac;
520 struct hal2_pbus *pbus = &dac->pbus;
521
522 pbus->pbus->pbdma_dptr = hal2_desc_addr(dac, dac->tail);
523 pbus->pbus->pbdma_ctrl = pbus->ctrl | HPC3_PDMACTRL_ACT;
524 /* enable DAC */
525 hal2_i_setbit16(hal2, H2I_DMA_PORT_EN, H2I_DMA_PORT_EN_CODECTX);
526}
527
528static void hal2_start_adc(struct hal2_card *hal2)
529{
530 struct hal2_codec *adc = &hal2->adc;
531 struct hal2_pbus *pbus = &adc->pbus;
532
533 pbus->pbus->pbdma_dptr = hal2_desc_addr(adc, adc->head);
534 pbus->pbus->pbdma_ctrl = pbus->ctrl | HPC3_PDMACTRL_ACT;
535 /* enable ADC */
536 hal2_i_setbit16(hal2, H2I_DMA_PORT_EN, H2I_DMA_PORT_EN_CODECR);
537}
538
539static inline void hal2_stop_dac(struct hal2_card *hal2)
540{
541 hal2->dac.pbus.pbus->pbdma_ctrl = HPC3_PDMACTRL_LD;
542 /* The HAL2 itself may remain enabled safely */
543}
544
545static inline void hal2_stop_adc(struct hal2_card *hal2)
546{
547 hal2->adc.pbus.pbus->pbdma_ctrl = HPC3_PDMACTRL_LD;
548}
549
550static int hal2_alloc_dmabuf(struct hal2_codec *codec, int size,
551 int count, int cntinfo, int dir)
552{
553 struct hal2_desc *desc, *dma_addr;
554 int i;
555
556 DEBUG("allocating %dk DMA buffer.\n", size / 1024);
557
558 codec->buffer = (unsigned char *)__get_free_pages(GFP_KERNEL | GFP_DMA,
559 get_order(size));
560 if (!codec->buffer)
561 return -ENOMEM;
562 desc = dma_alloc_coherent(NULL, count * sizeof(struct hal2_desc),
563 (dma_addr_t *)&dma_addr, GFP_KERNEL);
564 if (!desc) {
565 free_pages((unsigned long)codec->buffer, get_order(size));
566 return -ENOMEM;
567 }
568 codec->desc = desc;
569 for (i = 0; i < count; i++) {
570 desc->desc.pbuf = dma_map_single(NULL,
571 (void *)(codec->buffer + i * H2_BLOCK_SIZE),
572 H2_BLOCK_SIZE, dir);
573 desc->desc.cntinfo = cntinfo;
574 desc->desc.pnext = (i == count - 1) ?
575 (u32)dma_addr : (u32)(dma_addr + i + 1);
576 desc->cnt = 0;
577 desc++;
578 }
579 codec->desc_count = count;
580 codec->head = codec->tail = 0;
581 return 0;
582}
583
584static int hal2_alloc_dac_dmabuf(struct hal2_codec *codec)
585{
586 return hal2_alloc_dmabuf(codec, H2_DAC_BUFSIZE,
587 H2_DAC_BUFSIZE / H2_BLOCK_SIZE,
588 HPCDMA_XIE | HPCDMA_EOX,
589 DMA_TO_DEVICE);
590}
591
592static int hal2_alloc_adc_dmabuf(struct hal2_codec *codec)
593{
594 return hal2_alloc_dmabuf(codec, H2_ADC_BUFSIZE,
595 H2_ADC_BUFSIZE / H2_BLOCK_SIZE,
596 HPCDMA_XIE | H2_BLOCK_SIZE,
597 DMA_TO_DEVICE);
598}
599
600static void hal2_free_dmabuf(struct hal2_codec *codec, int size, int dir)
601{
602 dma_addr_t dma_addr;
603 int i;
604
605 dma_addr = codec->desc[codec->desc_count - 1].desc.pnext;
606 for (i = 0; i < codec->desc_count; i++)
607 dma_unmap_single(NULL, codec->desc[i].desc.pbuf,
608 H2_BLOCK_SIZE, dir);
609 dma_free_coherent(NULL, codec->desc_count * sizeof(struct hal2_desc),
610 (void *)codec->desc, dma_addr);
611 free_pages((unsigned long)codec->buffer, get_order(size));
612}
613
614static void hal2_free_dac_dmabuf(struct hal2_codec *codec)
615{
616 return hal2_free_dmabuf(codec, H2_DAC_BUFSIZE, DMA_TO_DEVICE);
617}
618
619static void hal2_free_adc_dmabuf(struct hal2_codec *codec)
620{
621 return hal2_free_dmabuf(codec, H2_ADC_BUFSIZE, DMA_FROM_DEVICE);
622}
623
624/*
625 * Add 'count' bytes to 'buffer' from DMA ring buffers. Return number of
626 * bytes added or -EFAULT if copy_from_user failed.
627 */
628static int hal2_get_buffer(struct hal2_card *hal2, char *buffer, int count)
629{
630 unsigned long flags;
631 int size, ret = 0;
632 unsigned char *buf;
633 struct hal2_desc *tail;
634 struct hal2_codec *adc = &hal2->adc;
635
636 DEBUG("getting %d bytes ", count);
637
638 spin_lock_irqsave(&adc->lock, flags);
639 tail = &adc->desc[adc->tail];
640 /* enable DMA stream if there are no data */
641 if (!tail->cnt && !(adc->pbus.pbus->pbdma_ctrl & HPC3_PDMACTRL_ISACT))
642 hal2_start_adc(hal2);
643 while (tail->cnt > 0 && count > 0) {
644 size = min((int)tail->cnt, count);
645 buf = &adc->buffer[(adc->tail + 1) * H2_BLOCK_SIZE - tail->cnt];
646 spin_unlock_irqrestore(&adc->lock, flags);
647 dma_sync_single(NULL, tail->desc.pbuf, size, DMA_FROM_DEVICE);
648 if (copy_to_user(buffer, buf, size)) {
649 ret = -EFAULT;
650 goto out;
651 }
652 spin_lock_irqsave(&adc->lock, flags);
653 tail->cnt -= size;
654 /* buffer is empty, update tail pointer */
655 if (tail->cnt == 0) {
656 tail->desc.cntinfo = HPCDMA_XIE | H2_BLOCK_SIZE;
657 hal2_inc_tail(adc);
658 tail = &adc->desc[adc->tail];
659 /* enable DMA stream again if needed */
660 if (!(adc->pbus.pbus->pbdma_ctrl & HPC3_PDMACTRL_ISACT))
661 hal2_start_adc(hal2);
662 }
663 buffer += size;
664 ret += size;
665 count -= size;
666
667 DEBUG("(%d) ", size);
668 }
669 spin_unlock_irqrestore(&adc->lock, flags);
670out:
671 DEBUG("\n");
672
673 return ret;
674}
675
676/*
677 * Add 'count' bytes from 'buffer' to DMA ring buffers. Return number of
678 * bytes added or -EFAULT if copy_from_user failed.
679 */
680static int hal2_add_buffer(struct hal2_card *hal2, char *buffer, int count)
681{
682 unsigned long flags;
683 unsigned char *buf;
684 int size, ret = 0;
685 struct hal2_desc *head;
686 struct hal2_codec *dac = &hal2->dac;
687
688 DEBUG("adding %d bytes ", count);
689
690 spin_lock_irqsave(&dac->lock, flags);
691 head = &dac->desc[dac->head];
692 while (head->cnt == 0 && count > 0) {
693 size = min((int)H2_BLOCK_SIZE, count);
694 buf = &dac->buffer[dac->head * H2_BLOCK_SIZE];
695 spin_unlock_irqrestore(&dac->lock, flags);
696 if (copy_from_user(buf, buffer, size)) {
697 ret = -EFAULT;
698 goto out;
699 }
700 dma_sync_single(NULL, head->desc.pbuf, size, DMA_TO_DEVICE);
701 spin_lock_irqsave(&dac->lock, flags);
702 head->desc.cntinfo = size | HPCDMA_XIE;
703 head->cnt = size;
704 buffer += size;
705 ret += size;
706 count -= size;
707 hal2_inc_head(dac);
708 head = &dac->desc[dac->head];
709
710 DEBUG("(%d) ", size);
711 }
712 if (!(dac->pbus.pbus->pbdma_ctrl & HPC3_PDMACTRL_ISACT) && ret > 0)
713 hal2_start_dac(hal2);
714 spin_unlock_irqrestore(&dac->lock, flags);
715out:
716 DEBUG("\n");
717
718 return ret;
719}
720
721#define hal2_reset_dac_pointer(hal2) hal2_reset_pointer(hal2, 1)
722#define hal2_reset_adc_pointer(hal2) hal2_reset_pointer(hal2, 0)
723static void hal2_reset_pointer(struct hal2_card *hal2, int is_dac)
724{
725 int i;
726 struct hal2_codec *codec = (is_dac) ? &hal2->dac : &hal2->adc;
727
728 DEBUG("hal2_reset_pointer\n");
729
730 for (i = 0; i < codec->desc_count; i++) {
731 codec->desc[i].cnt = 0;
732 codec->desc[i].desc.cntinfo = HPCDMA_XIE | (is_dac) ?
733 HPCDMA_EOX : H2_BLOCK_SIZE;
734 }
735 codec->head = codec->tail = 0;
736}
737
738static int hal2_sync_dac(struct hal2_card *hal2)
739{
740 DECLARE_WAITQUEUE(wait, current);
741 struct hal2_codec *dac = &hal2->dac;
742 int ret = 0;
743 unsigned long flags;
744 signed long timeout = 1000 * H2_BLOCK_SIZE * 2 * dac->voices *
745 HZ / dac->sample_rate / 900;
746
747 while (dac->pbus.pbus->pbdma_ctrl & HPC3_PDMACTRL_ISACT) {
748 add_wait_queue(&dac->dma_wait, &wait);
749 set_current_state(TASK_INTERRUPTIBLE);
750 schedule_timeout(timeout);
751 spin_lock_irqsave(&dac->lock, flags);
752 if (dac->desc[dac->tail].cnt)
753 ret = -ETIME;
754 spin_unlock_irqrestore(&dac->lock, flags);
755 if (signal_pending(current))
756 ret = -ERESTARTSYS;
757 if (ret) {
758 hal2_stop_dac(hal2);
759 hal2_reset_dac_pointer(hal2);
760 }
761 remove_wait_queue(&dac->dma_wait, &wait);
762 }
763
764 return ret;
765}
766
767static int hal2_write_mixer(struct hal2_card *hal2, int index, int vol)
768{
769 unsigned int l, r, tmp;
770
771 DEBUG_MIX("mixer %d write\n", index);
772
773 if (index >= SOUND_MIXER_NRDEVICES || !mixtable[index].avail)
774 return -EINVAL;
775
776 r = (vol >> 8) & 0xff;
777 if (r > 100)
778 r = 100;
779 l = vol & 0xff;
780 if (l > 100)
781 l = 100;
782
783 hal2->mixer.volume[mixtable[index].idx] = l | (r << 8);
784
785 switch (mixtable[index].idx) {
786 case H2_MIX_OUTPUT_ATT:
787
788 DEBUG_MIX("output attenuator %d,%d\n", l, r);
789
790 if (r | l) {
791 tmp = hal2_i_look32(hal2, H2I_DAC_C2);
792 tmp &= ~(H2I_C2_L_ATT_M | H2I_C2_R_ATT_M | H2I_C2_MUTE);
793
794 /* Attenuator has five bits */
795 l = 31 * (100 - l) / 99;
796 r = 31 * (100 - r) / 99;
797
798 DEBUG_MIX("left: %d, right %d\n", l, r);
799
800 tmp |= (l << H2I_C2_L_ATT_SHIFT) & H2I_C2_L_ATT_M;
801 tmp |= (r << H2I_C2_R_ATT_SHIFT) & H2I_C2_R_ATT_M;
802 hal2_i_write32(hal2, H2I_DAC_C2, tmp);
803 } else
804 hal2_i_setbit32(hal2, H2I_DAC_C2, H2I_C2_MUTE);
805 break;
806 case H2_MIX_INPUT_GAIN:
807
808 DEBUG_MIX("input gain %d,%d\n", l, r);
809
810 tmp = hal2_i_look32(hal2, H2I_ADC_C2);
811 tmp &= ~(H2I_C2_L_GAIN_M | H2I_C2_R_GAIN_M);
812
813 /* Gain control has four bits */
814 l = 16 * l / 100;
815 r = 16 * r / 100;
816
817 DEBUG_MIX("left: %d, right %d\n", l, r);
818
819 tmp |= (l << H2I_C2_L_GAIN_SHIFT) & H2I_C2_L_GAIN_M;
820 tmp |= (r << H2I_C2_R_GAIN_SHIFT) & H2I_C2_R_GAIN_M;
821 hal2_i_write32(hal2, H2I_ADC_C2, tmp);
822
823 break;
824 }
825
826 return 0;
827}
828
829static void hal2_init_mixer(struct hal2_card *hal2)
830{
831 int i;
832
833 for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
834 if (mixtable[i].avail)
835 hal2->mixer.volume[mixtable[i].idx] = 100 | (100 << 8);
836
837 /* disable attenuator */
838 hal2_i_write32(hal2, H2I_DAC_C2, 0);
839 /* set max input gain */
840 hal2_i_write32(hal2, H2I_ADC_C2, H2I_C2_MUTE |
841 (H2I_C2_L_GAIN_M << H2I_C2_L_GAIN_SHIFT) |
842 (H2I_C2_R_GAIN_M << H2I_C2_R_GAIN_SHIFT));
843 /* set max volume */
844 hal2->mixer.master = 0xff;
845 hal2->vol_regs->left = 0xff;
846 hal2->vol_regs->right = 0xff;
847}
848
849/*
850 * XXX: later i'll implement mixer for main volume which will be disabled
851 * by default. enabling it users will be allowed to have master volume level
852 * control on panel in their favourite X desktop
853 */
854static void hal2_volume_control(int direction)
855{
856 unsigned int master = hal2_card[0]->mixer.master;
857 struct hal2_vol_regs *vol = hal2_card[0]->vol_regs;
858
859 /* volume up */
860 if (direction > 0 && master < 0xff)
861 master++;
862 /* volume down */
863 else if (direction < 0 && master > 0)
864 master--;
865 /* TODO: mute/unmute */
866 vol->left = master;
867 vol->right = master;
868 hal2_card[0]->mixer.master = master;
869}
870
871static int hal2_mixer_ioctl(struct hal2_card *hal2, unsigned int cmd,
872 unsigned long arg)
873{
874 int val;
875
876 if (cmd == SOUND_MIXER_INFO) {
877 mixer_info info;
878
879 memset(&info, 0, sizeof(info));
880 strlcpy(info.id, hal2str, sizeof(info.id));
881 strlcpy(info.name, hal2str, sizeof(info.name));
882 info.modify_counter = hal2->mixer.modcnt;
883 if (copy_to_user((void *)arg, &info, sizeof(info)))
884 return -EFAULT;
885 return 0;
886 }
887 if (cmd == SOUND_OLD_MIXER_INFO) {
888 _old_mixer_info info;
889
890 memset(&info, 0, sizeof(info));
891 strlcpy(info.id, hal2str, sizeof(info.id));
892 strlcpy(info.name, hal2str, sizeof(info.name));
893 if (copy_to_user((void *)arg, &info, sizeof(info)))
894 return -EFAULT;
895 return 0;
896 }
897 if (cmd == OSS_GETVERSION)
898 return put_user(SOUND_VERSION, (int *)arg);
899
900 if (_IOC_TYPE(cmd) != 'M' || _IOC_SIZE(cmd) != sizeof(int))
901 return -EINVAL;
902
903 if (_IOC_DIR(cmd) == _IOC_READ) {
904 switch (_IOC_NR(cmd)) {
905 /* Give the current record source */
906 case SOUND_MIXER_RECSRC:
907 val = 0; /* FIXME */
908 break;
909 /* Give the supported mixers, all of them support stereo */
910 case SOUND_MIXER_DEVMASK:
911 case SOUND_MIXER_STEREODEVS: {
912 int i;
913
914 for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
915 if (mixtable[i].avail)
916 val |= 1 << i;
917 break;
918 }
919 /* Arg contains a bit for each supported recording source */
920 case SOUND_MIXER_RECMASK:
921 val = 0;
922 break;
923 case SOUND_MIXER_CAPS:
924 val = 0;
925 break;
926 /* Read a specific mixer */
927 default: {
928 int i = _IOC_NR(cmd);
929
930 if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].avail)
931 return -EINVAL;
932 val = hal2->mixer.volume[mixtable[i].idx];
933 break;
934 }
935 }
936 return put_user(val, (int *)arg);
937 }
938
939 if (_IOC_DIR(cmd) != (_IOC_WRITE|_IOC_READ))
940 return -EINVAL;
941
942 hal2->mixer.modcnt++;
943
944 if (get_user(val, (int *)arg))
945 return -EFAULT;
946
947 switch (_IOC_NR(cmd)) {
948 /* Arg contains a bit for each recording source */
949 case SOUND_MIXER_RECSRC:
950 return 0; /* FIXME */
951 default:
952 return hal2_write_mixer(hal2, _IOC_NR(cmd), val);
953 }
954
955 return 0;
956}
957
958static int hal2_open_mixdev(struct inode *inode, struct file *file)
959{
960 struct hal2_card *hal2 = hal2_mixer_find_card(iminor(inode));
961
962 if (hal2) {
963 file->private_data = hal2;
964 return nonseekable_open(inode, file);
965 }
966 return -ENODEV;
967}
968
969static int hal2_release_mixdev(struct inode *inode, struct file *file)
970{
971 return 0;
972}
973
974static int hal2_ioctl_mixdev(struct inode *inode, struct file *file,
975 unsigned int cmd, unsigned long arg)
976{
977 return hal2_mixer_ioctl((struct hal2_card *)file->private_data, cmd, arg);
978}
979
980static int hal2_ioctl(struct inode *inode, struct file *file,
981 unsigned int cmd, unsigned long arg)
982{
983 int val;
984 struct hal2_card *hal2 = (struct hal2_card *) file->private_data;
985
986 switch (cmd) {
987 case OSS_GETVERSION:
988 return put_user(SOUND_VERSION, (int *)arg);
989
990 case SNDCTL_DSP_SYNC:
991 if (file->f_mode & FMODE_WRITE)
992 return hal2_sync_dac(hal2);
993 return 0;
994
995 case SNDCTL_DSP_SETDUPLEX:
996 return 0;
997
998 case SNDCTL_DSP_GETCAPS:
999 return put_user(DSP_CAP_DUPLEX | DSP_CAP_MULTI, (int *)arg);
1000
1001 case SNDCTL_DSP_RESET:
1002 if (file->f_mode & FMODE_READ) {
1003 hal2_stop_adc(hal2);
1004 hal2_reset_adc_pointer(hal2);
1005 }
1006 if (file->f_mode & FMODE_WRITE) {
1007 hal2_stop_dac(hal2);
1008 hal2_reset_dac_pointer(hal2);
1009 }
1010 return 0;
1011
1012 case SNDCTL_DSP_SPEED:
1013 if (get_user(val, (int *)arg))
1014 return -EFAULT;
1015 if (file->f_mode & FMODE_READ) {
1016 hal2_stop_adc(hal2);
1017 val = hal2_compute_rate(&hal2->adc, val);
1018 hal2->adc.sample_rate = val;
1019 hal2_set_adc_rate(hal2);
1020 }
1021 if (file->f_mode & FMODE_WRITE) {
1022 hal2_stop_dac(hal2);
1023 val = hal2_compute_rate(&hal2->dac, val);
1024 hal2->dac.sample_rate = val;
1025 hal2_set_dac_rate(hal2);
1026 }
1027 return put_user(val, (int *)arg);
1028
1029 case SNDCTL_DSP_STEREO:
1030 if (get_user(val, (int *)arg))
1031 return -EFAULT;
1032 if (file->f_mode & FMODE_READ) {
1033 hal2_stop_adc(hal2);
1034 hal2->adc.voices = (val) ? 2 : 1;
1035 hal2_setup_adc(hal2);
1036 }
1037 if (file->f_mode & FMODE_WRITE) {
1038 hal2_stop_dac(hal2);
1039 hal2->dac.voices = (val) ? 2 : 1;
1040 hal2_setup_dac(hal2);
1041 }
1042 return 0;
1043
1044 case SNDCTL_DSP_CHANNELS:
1045 if (get_user(val, (int *)arg))
1046 return -EFAULT;
1047 if (val != 0) {
1048 if (file->f_mode & FMODE_READ) {
1049 hal2_stop_adc(hal2);
1050 hal2->adc.voices = (val == 1) ? 1 : 2;
1051 hal2_setup_adc(hal2);
1052 }
1053 if (file->f_mode & FMODE_WRITE) {
1054 hal2_stop_dac(hal2);
1055 hal2->dac.voices = (val == 1) ? 1 : 2;
1056 hal2_setup_dac(hal2);
1057 }
1058 }
1059 val = -EINVAL;
1060 if (file->f_mode & FMODE_READ)
1061 val = hal2->adc.voices;
1062 if (file->f_mode & FMODE_WRITE)
1063 val = hal2->dac.voices;
1064 return put_user(val, (int *)arg);
1065
1066 case SNDCTL_DSP_GETFMTS: /* Returns a mask */
1067 return put_user(H2_SUPPORTED_FORMATS, (int *)arg);
1068
1069 case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
1070 if (get_user(val, (int *)arg))
1071 return -EFAULT;
1072 if (val != AFMT_QUERY) {
1073 if (!(val & H2_SUPPORTED_FORMATS))
1074 return -EINVAL;
1075 if (file->f_mode & FMODE_READ) {
1076 hal2_stop_adc(hal2);
1077 hal2->adc.format = val;
1078 hal2_setup_adc(hal2);
1079 }
1080 if (file->f_mode & FMODE_WRITE) {
1081 hal2_stop_dac(hal2);
1082 hal2->dac.format = val;
1083 hal2_setup_dac(hal2);
1084 }
1085 } else {
1086 val = -EINVAL;
1087 if (file->f_mode & FMODE_READ)
1088 val = hal2->adc.format;
1089 if (file->f_mode & FMODE_WRITE)
1090 val = hal2->dac.format;
1091 }
1092 return put_user(val, (int *)arg);
1093
1094 case SNDCTL_DSP_POST:
1095 return 0;
1096
1097 case SNDCTL_DSP_GETOSPACE: {
1098 audio_buf_info info;
1099 int i;
1100 unsigned long flags;
1101 struct hal2_codec *dac = &hal2->dac;
1102
1103 if (!(file->f_mode & FMODE_WRITE))
1104 return -EINVAL;
1105 info.fragments = 0;
1106 spin_lock_irqsave(&dac->lock, flags);
1107 for (i = 0; i < dac->desc_count; i++)
1108 if (dac->desc[i].cnt == 0)
1109 info.fragments++;
1110 spin_unlock_irqrestore(&dac->lock, flags);
1111 info.fragstotal = dac->desc_count;
1112 info.fragsize = H2_BLOCK_SIZE;
1113 info.bytes = info.fragsize * info.fragments;
1114
1115 return copy_to_user((void *)arg, &info, sizeof(info)) ? -EFAULT : 0;
1116 }
1117
1118 case SNDCTL_DSP_GETISPACE: {
1119 audio_buf_info info;
1120 int i;
1121 unsigned long flags;
1122 struct hal2_codec *adc = &hal2->adc;
1123
1124 if (!(file->f_mode & FMODE_READ))
1125 return -EINVAL;
1126 info.fragments = 0;
1127 info.bytes = 0;
1128 spin_lock_irqsave(&adc->lock, flags);
1129 for (i = 0; i < adc->desc_count; i++)
1130 if (adc->desc[i].cnt > 0) {
1131 info.fragments++;
1132 info.bytes += adc->desc[i].cnt;
1133 }
1134 spin_unlock_irqrestore(&adc->lock, flags);
1135 info.fragstotal = adc->desc_count;
1136 info.fragsize = H2_BLOCK_SIZE;
1137
1138 return copy_to_user((void *)arg, &info, sizeof(info)) ? -EFAULT : 0;
1139 }
1140
1141 case SNDCTL_DSP_NONBLOCK:
1142 file->f_flags |= O_NONBLOCK;
1143 return 0;
1144
1145 case SNDCTL_DSP_GETBLKSIZE:
1146 return put_user(H2_BLOCK_SIZE, (int *)arg);
1147
1148 case SNDCTL_DSP_SETFRAGMENT:
1149 return 0;
1150
1151 case SOUND_PCM_READ_RATE:
1152 val = -EINVAL;
1153 if (file->f_mode & FMODE_READ)
1154 val = hal2->adc.sample_rate;
1155 if (file->f_mode & FMODE_WRITE)
1156 val = hal2->dac.sample_rate;
1157 return put_user(val, (int *)arg);
1158
1159 case SOUND_PCM_READ_CHANNELS:
1160 val = -EINVAL;
1161 if (file->f_mode & FMODE_READ)
1162 val = hal2->adc.voices;
1163 if (file->f_mode & FMODE_WRITE)
1164 val = hal2->dac.voices;
1165 return put_user(val, (int *)arg);
1166
1167 case SOUND_PCM_READ_BITS:
1168 return put_user(16, (int *)arg);
1169 }
1170
1171 return hal2_mixer_ioctl(hal2, cmd, arg);
1172}
1173
1174static ssize_t hal2_read(struct file *file, char *buffer,
1175 size_t count, loff_t *ppos)
1176{
1177 ssize_t err;
1178 struct hal2_card *hal2 = (struct hal2_card *) file->private_data;
1179 struct hal2_codec *adc = &hal2->adc;
1180
1181 if (!count)
1182 return 0;
1183 if (mutex_lock_interruptible(&adc->sem))
1184 return -EINTR;
1185 if (file->f_flags & O_NONBLOCK) {
1186 err = hal2_get_buffer(hal2, buffer, count);
1187 err = err == 0 ? -EAGAIN : err;
1188 } else {
1189 do {
1190 /* ~10% longer */
1191 signed long timeout = 1000 * H2_BLOCK_SIZE *
1192 2 * adc->voices * HZ / adc->sample_rate / 900;
1193 unsigned long flags;
1194 DECLARE_WAITQUEUE(wait, current);
1195 ssize_t cnt = 0;
1196
1197 err = hal2_get_buffer(hal2, buffer, count);
1198 if (err > 0) {
1199 count -= err;
1200 cnt += err;
1201 buffer += err;
1202 err = cnt;
1203 }
1204 if (count > 0 && err >= 0) {
1205 add_wait_queue(&adc->dma_wait, &wait);
1206 set_current_state(TASK_INTERRUPTIBLE);
1207 schedule_timeout(timeout);
1208 spin_lock_irqsave(&adc->lock, flags);
1209 if (!adc->desc[adc->tail].cnt)
1210 err = -EAGAIN;
1211 spin_unlock_irqrestore(&adc->lock, flags);
1212 if (signal_pending(current))
1213 err = -ERESTARTSYS;
1214 remove_wait_queue(&adc->dma_wait, &wait);
1215 if (err < 0) {
1216 hal2_stop_adc(hal2);
1217 hal2_reset_adc_pointer(hal2);
1218 }
1219 }
1220 } while (count > 0 && err >= 0);
1221 }
1222 mutex_unlock(&adc->sem);
1223
1224 return err;
1225}
1226
1227static ssize_t hal2_write(struct file *file, const char *buffer,
1228 size_t count, loff_t *ppos)
1229{
1230 ssize_t err;
1231 char *buf = (char*) buffer;
1232 struct hal2_card *hal2 = (struct hal2_card *) file->private_data;
1233 struct hal2_codec *dac = &hal2->dac;
1234
1235 if (!count)
1236 return 0;
1237 if (mutex_lock_interruptible(&dac->sem))
1238 return -EINTR;
1239 if (file->f_flags & O_NONBLOCK) {
1240 err = hal2_add_buffer(hal2, buf, count);
1241 err = err == 0 ? -EAGAIN : err;
1242 } else {
1243 do {
1244 /* ~10% longer */
1245 signed long timeout = 1000 * H2_BLOCK_SIZE *
1246 2 * dac->voices * HZ / dac->sample_rate / 900;
1247 unsigned long flags;
1248 DECLARE_WAITQUEUE(wait, current);
1249 ssize_t cnt = 0;
1250
1251 err = hal2_add_buffer(hal2, buf, count);
1252 if (err > 0) {
1253 count -= err;
1254 cnt += err;
1255 buf += err;
1256 err = cnt;
1257 }
1258 if (count > 0 && err >= 0) {
1259 add_wait_queue(&dac->dma_wait, &wait);
1260 set_current_state(TASK_INTERRUPTIBLE);
1261 schedule_timeout(timeout);
1262 spin_lock_irqsave(&dac->lock, flags);
1263 if (dac->desc[dac->head].cnt)
1264 err = -EAGAIN;
1265 spin_unlock_irqrestore(&dac->lock, flags);
1266 if (signal_pending(current))
1267 err = -ERESTARTSYS;
1268 remove_wait_queue(&dac->dma_wait, &wait);
1269 if (err < 0) {
1270 hal2_stop_dac(hal2);
1271 hal2_reset_dac_pointer(hal2);
1272 }
1273 }
1274 } while (count > 0 && err >= 0);
1275 }
1276 mutex_unlock(&dac->sem);
1277
1278 return err;
1279}
1280
1281static unsigned int hal2_poll(struct file *file, struct poll_table_struct *wait)
1282{
1283 unsigned long flags;
1284 unsigned int mask = 0;
1285 struct hal2_card *hal2 = (struct hal2_card *) file->private_data;
1286
1287 if (file->f_mode & FMODE_READ) {
1288 struct hal2_codec *adc = &hal2->adc;
1289
1290 poll_wait(file, &adc->dma_wait, wait);
1291 spin_lock_irqsave(&adc->lock, flags);
1292 if (adc->desc[adc->tail].cnt > 0)
1293 mask |= POLLIN;
1294 spin_unlock_irqrestore(&adc->lock, flags);
1295 }
1296
1297 if (file->f_mode & FMODE_WRITE) {
1298 struct hal2_codec *dac = &hal2->dac;
1299
1300 poll_wait(file, &dac->dma_wait, wait);
1301 spin_lock_irqsave(&dac->lock, flags);
1302 if (dac->desc[dac->head].cnt == 0)
1303 mask |= POLLOUT;
1304 spin_unlock_irqrestore(&dac->lock, flags);
1305 }
1306
1307 return mask;
1308}
1309
1310static int hal2_open(struct inode *inode, struct file *file)
1311{
1312 int err;
1313 struct hal2_card *hal2 = hal2_dsp_find_card(iminor(inode));
1314
1315 if (!hal2)
1316 return -ENODEV;
1317 file->private_data = hal2;
1318 if (file->f_mode & FMODE_READ) {
1319 struct hal2_codec *adc = &hal2->adc;
1320
1321 if (adc->usecount)
1322 return -EBUSY;
1323 /* OSS spec wanted us to use 8 bit, 8 kHz mono by default,
1324 * but HAL2 can't do 8bit audio */
1325 adc->format = AFMT_S16_BE;
1326 adc->voices = 1;
1327 adc->sample_rate = hal2_compute_rate(adc, 8000);
1328 hal2_set_adc_rate(hal2);
1329 err = hal2_alloc_adc_dmabuf(adc);
1330 if (err)
1331 return err;
1332 hal2_setup_adc(hal2);
1333 adc->usecount++;
1334 }
1335 if (file->f_mode & FMODE_WRITE) {
1336 struct hal2_codec *dac = &hal2->dac;
1337
1338 if (dac->usecount)
1339 return -EBUSY;
1340 dac->format = AFMT_S16_BE;
1341 dac->voices = 1;
1342 dac->sample_rate = hal2_compute_rate(dac, 8000);
1343 hal2_set_dac_rate(hal2);
1344 err = hal2_alloc_dac_dmabuf(dac);
1345 if (err)
1346 return err;
1347 hal2_setup_dac(hal2);
1348 dac->usecount++;
1349 }
1350
1351 return nonseekable_open(inode, file);
1352}
1353
1354static int hal2_release(struct inode *inode, struct file *file)
1355{
1356 struct hal2_card *hal2 = (struct hal2_card *) file->private_data;
1357
1358 if (file->f_mode & FMODE_READ) {
1359 struct hal2_codec *adc = &hal2->adc;
1360
1361 mutex_lock(&adc->sem);
1362 hal2_stop_adc(hal2);
1363 hal2_free_adc_dmabuf(adc);
1364 adc->usecount--;
1365 mutex_unlock(&adc->sem);
1366 }
1367 if (file->f_mode & FMODE_WRITE) {
1368 struct hal2_codec *dac = &hal2->dac;
1369
1370 mutex_lock(&dac->sem);
1371 hal2_sync_dac(hal2);
1372 hal2_free_dac_dmabuf(dac);
1373 dac->usecount--;
1374 mutex_unlock(&dac->sem);
1375 }
1376
1377 return 0;
1378}
1379
1380static const struct file_operations hal2_audio_fops = {
1381 .owner = THIS_MODULE,
1382 .llseek = no_llseek,
1383 .read = hal2_read,
1384 .write = hal2_write,
1385 .poll = hal2_poll,
1386 .ioctl = hal2_ioctl,
1387 .open = hal2_open,
1388 .release = hal2_release,
1389};
1390
1391static const struct file_operations hal2_mixer_fops = {
1392 .owner = THIS_MODULE,
1393 .llseek = no_llseek,
1394 .ioctl = hal2_ioctl_mixdev,
1395 .open = hal2_open_mixdev,
1396 .release = hal2_release_mixdev,
1397};
1398
1399static void hal2_init_codec(struct hal2_codec *codec, struct hpc3_regs *hpc3,
1400 int index)
1401{
1402 codec->pbus.pbusnr = index;
1403 codec->pbus.pbus = &hpc3->pbdma[index];
1404 init_waitqueue_head(&codec->dma_wait);
1405 mutex_init(&codec->sem);
1406 spin_lock_init(&codec->lock);
1407}
1408
1409static int hal2_detect(struct hal2_card *hal2)
1410{
1411 unsigned short board, major, minor;
1412 unsigned short rev;
1413
1414 /* reset HAL2 */
1415 hal2_isr_write(hal2, 0);
1416 /* release reset */
1417 hal2_isr_write(hal2, H2_ISR_GLOBAL_RESET_N | H2_ISR_CODEC_RESET_N);
1418
1419 hal2_i_write16(hal2, H2I_RELAY_C, H2I_RELAY_C_STATE);
1420 if ((rev = hal2_rev_look(hal2)) & H2_REV_AUDIO_PRESENT)
1421 return -ENODEV;
1422
1423 board = (rev & H2_REV_BOARD_M) >> 12;
1424 major = (rev & H2_REV_MAJOR_CHIP_M) >> 4;
1425 minor = (rev & H2_REV_MINOR_CHIP_M);
1426
1427 printk(KERN_INFO "SGI HAL2 revision %i.%i.%i\n",
1428 board, major, minor);
1429
1430 return 0;
1431}
1432
1433static int hal2_init_card(struct hal2_card **phal2, struct hpc3_regs *hpc3)
1434{
1435 int ret = 0;
1436 struct hal2_card *hal2;
1437
1438 hal2 = kzalloc(sizeof(struct hal2_card), GFP_KERNEL);
1439 if (!hal2)
1440 return -ENOMEM;
1441
1442 hal2->ctl_regs = (struct hal2_ctl_regs *)hpc3->pbus_extregs[0];
1443 hal2->aes_regs = (struct hal2_aes_regs *)hpc3->pbus_extregs[1];
1444 hal2->vol_regs = (struct hal2_vol_regs *)hpc3->pbus_extregs[2];
1445 hal2->syn_regs = (struct hal2_syn_regs *)hpc3->pbus_extregs[3];
1446
1447 if (hal2_detect(hal2) < 0) {
1448 ret = -ENODEV;
1449 goto free_card;
1450 }
1451
1452 hal2_init_codec(&hal2->dac, hpc3, 0);
1453 hal2_init_codec(&hal2->adc, hpc3, 1);
1454
1455 /*
1456 * All DMA channel interfaces in HAL2 are designed to operate with
1457 * PBUS programmed for 2 cycles in D3, 2 cycles in D4 and 2 cycles
1458 * in D5. HAL2 is a 16-bit device which can accept both big and little
1459 * endian format. It assumes that even address bytes are on high
1460 * portion of PBUS (15:8) and assumes that HPC3 is programmed to
1461 * accept a live (unsynchronized) version of P_DREQ_N from HAL2.
1462 */
1463#define HAL2_PBUS_DMACFG ((0 << HPC3_DMACFG_D3R_SHIFT) | \
1464 (2 << HPC3_DMACFG_D4R_SHIFT) | \
1465 (2 << HPC3_DMACFG_D5R_SHIFT) | \
1466 (0 << HPC3_DMACFG_D3W_SHIFT) | \
1467 (2 << HPC3_DMACFG_D4W_SHIFT) | \
1468 (2 << HPC3_DMACFG_D5W_SHIFT) | \
1469 HPC3_DMACFG_DS16 | \
1470 HPC3_DMACFG_EVENHI | \
1471 HPC3_DMACFG_RTIME | \
1472 (8 << HPC3_DMACFG_BURST_SHIFT) | \
1473 HPC3_DMACFG_DRQLIVE)
1474 /*
1475 * Ignore what's mentioned in the specification and write value which
1476 * works in The Real World (TM)
1477 */
1478 hpc3->pbus_dmacfg[hal2->dac.pbus.pbusnr][0] = 0x8208844;
1479 hpc3->pbus_dmacfg[hal2->adc.pbus.pbusnr][0] = 0x8208844;
1480
1481 if (request_irq(SGI_HPCDMA_IRQ, hal2_interrupt, IRQF_SHARED,
1482 hal2str, hal2)) {
1483 printk(KERN_ERR "HAL2: Can't get irq %d\n", SGI_HPCDMA_IRQ);
1484 ret = -EAGAIN;
1485 goto free_card;
1486 }
1487
1488 hal2->dev_dsp = register_sound_dsp(&hal2_audio_fops, -1);
1489 if (hal2->dev_dsp < 0) {
1490 ret = hal2->dev_dsp;
1491 goto free_irq;
1492 }
1493
1494 hal2->dev_mixer = register_sound_mixer(&hal2_mixer_fops, -1);
1495 if (hal2->dev_mixer < 0) {
1496 ret = hal2->dev_mixer;
1497 goto unregister_dsp;
1498 }
1499
1500 hal2_init_mixer(hal2);
1501
1502 *phal2 = hal2;
1503 return 0;
1504unregister_dsp:
1505 unregister_sound_dsp(hal2->dev_dsp);
1506free_irq:
1507 free_irq(SGI_HPCDMA_IRQ, hal2);
1508free_card:
1509 kfree(hal2);
1510
1511 return ret;
1512}
1513
1514extern void (*indy_volume_button)(int);
1515
1516/*
1517 * Assuming only one HAL2 card. Mail me if you ever meet machine with
1518 * more than one.
1519 */
1520static int __init init_hal2(void)
1521{
1522 int i, error;
1523
1524 for (i = 0; i < MAXCARDS; i++)
1525 hal2_card[i] = NULL;
1526
1527 error = hal2_init_card(&hal2_card[0], hpc3c0);
1528
1529 /* let Indy's volume buttons work */
1530 if (!error && !ip22_is_fullhouse())
1531 indy_volume_button = hal2_volume_control;
1532
1533 return error;
1534
1535}
1536
1537static void __exit exit_hal2(void)
1538{
1539 int i;
1540
1541 /* unregister volume butons callback function */
1542 indy_volume_button = NULL;
1543
1544 for (i = 0; i < MAXCARDS; i++)
1545 if (hal2_card[i]) {
1546 free_irq(SGI_HPCDMA_IRQ, hal2_card[i]);
1547 unregister_sound_dsp(hal2_card[i]->dev_dsp);
1548 unregister_sound_mixer(hal2_card[i]->dev_mixer);
1549 kfree(hal2_card[i]);
1550 }
1551}
1552
1553module_init(init_hal2);
1554module_exit(exit_hal2);
1555
1556MODULE_DESCRIPTION("OSS compatible driver for SGI HAL2 audio");
1557MODULE_AUTHOR("Ladislav Michl");
1558MODULE_LICENSE("GPL");
diff --git a/sound/oss/hal2.h b/sound/oss/hal2.h
deleted file mode 100644
index 2bd3b52d8a37..000000000000
--- a/sound/oss/hal2.h
+++ /dev/null
@@ -1,248 +0,0 @@
1#ifndef __HAL2_H
2#define __HAL2_H
3
4/*
5 * Driver for HAL2 sound processors
6 * Copyright (c) 1999 Ulf Carlsson <ulfc@bun.falkenberg.se>
7 * Copyright (c) 2001, 2002, 2003 Ladislav Michl <ladis@linux-mips.org>
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 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 */
23
24#include <asm/addrspace.h>
25#include <asm/sgi/hpc3.h>
26#include <linux/spinlock.h>
27#include <linux/types.h>
28
29/* Indirect status register */
30
31#define H2_ISR_TSTATUS 0x01 /* RO: transaction status 1=busy */
32#define H2_ISR_USTATUS 0x02 /* RO: utime status bit 1=armed */
33#define H2_ISR_QUAD_MODE 0x04 /* codec mode 0=indigo 1=quad */
34#define H2_ISR_GLOBAL_RESET_N 0x08 /* chip global reset 0=reset */
35#define H2_ISR_CODEC_RESET_N 0x10 /* codec/synth reset 0=reset */
36
37/* Revision register */
38
39#define H2_REV_AUDIO_PRESENT 0x8000 /* RO: audio present 0=present */
40#define H2_REV_BOARD_M 0x7000 /* RO: bits 14:12, board revision */
41#define H2_REV_MAJOR_CHIP_M 0x00F0 /* RO: bits 7:4, major chip revision */
42#define H2_REV_MINOR_CHIP_M 0x000F /* RO: bits 3:0, minor chip revision */
43
44/* Indirect address register */
45
46/*
47 * Address of indirect internal register to be accessed. A write to this
48 * register initiates read or write access to the indirect registers in the
49 * HAL2. Note that there af four indirect data registers for write access to
50 * registers larger than 16 byte.
51 */
52
53#define H2_IAR_TYPE_M 0xF000 /* bits 15:12, type of functional */
54 /* block the register resides in */
55 /* 1=DMA Port */
56 /* 9=Global DMA Control */
57 /* 2=Bresenham */
58 /* 3=Unix Timer */
59#define H2_IAR_NUM_M 0x0F00 /* bits 11:8 instance of the */
60 /* blockin which the indirect */
61 /* register resides */
62 /* If IAR_TYPE_M=DMA Port: */
63 /* 1=Synth In */
64 /* 2=AES In */
65 /* 3=AES Out */
66 /* 4=DAC Out */
67 /* 5=ADC Out */
68 /* 6=Synth Control */
69 /* If IAR_TYPE_M=Global DMA Control: */
70 /* 1=Control */
71 /* If IAR_TYPE_M=Bresenham: */
72 /* 1=Bresenham Clock Gen 1 */
73 /* 2=Bresenham Clock Gen 2 */
74 /* 3=Bresenham Clock Gen 3 */
75 /* If IAR_TYPE_M=Unix Timer: */
76 /* 1=Unix Timer */
77#define H2_IAR_ACCESS_SELECT 0x0080 /* 1=read 0=write */
78#define H2_IAR_PARAM 0x000C /* Parameter Select */
79#define H2_IAR_RB_INDEX_M 0x0003 /* Read Back Index */
80 /* 00:word0 */
81 /* 01:word1 */
82 /* 10:word2 */
83 /* 11:word3 */
84/*
85 * HAL2 internal addressing
86 *
87 * The HAL2 has "indirect registers" (idr) which are accessed by writing to the
88 * Indirect Data registers. Write the address to the Indirect Address register
89 * to transfer the data.
90 *
91 * We define the H2IR_* to the read address and H2IW_* to the write address and
92 * H2I_* to be fields in whatever register is referred to.
93 *
94 * When we write to indirect registers which are larger than one word (16 bit)
95 * we have to fill more than one indirect register before writing. When we read
96 * back however we have to read several times, each time with different Read
97 * Back Indexes (there are defs for doing this easily).
98 */
99
100/*
101 * Relay Control
102 */
103#define H2I_RELAY_C 0x9100
104#define H2I_RELAY_C_STATE 0x01 /* state of RELAY pin signal */
105
106/* DMA port enable */
107
108#define H2I_DMA_PORT_EN 0x9104
109#define H2I_DMA_PORT_EN_SY_IN 0x01 /* Synth_in DMA port */
110#define H2I_DMA_PORT_EN_AESRX 0x02 /* AES receiver DMA port */
111#define H2I_DMA_PORT_EN_AESTX 0x04 /* AES transmitter DMA port */
112#define H2I_DMA_PORT_EN_CODECTX 0x08 /* CODEC transmit DMA port */
113#define H2I_DMA_PORT_EN_CODECR 0x10 /* CODEC receive DMA port */
114
115#define H2I_DMA_END 0x9108 /* global dma endian select */
116#define H2I_DMA_END_SY_IN 0x01 /* Synth_in DMA port */
117#define H2I_DMA_END_AESRX 0x02 /* AES receiver DMA port */
118#define H2I_DMA_END_AESTX 0x04 /* AES transmitter DMA port */
119#define H2I_DMA_END_CODECTX 0x08 /* CODEC transmit DMA port */
120#define H2I_DMA_END_CODECR 0x10 /* CODEC receive DMA port */
121 /* 0=b_end 1=l_end */
122
123#define H2I_DMA_DRV 0x910C /* global PBUS DMA enable */
124
125#define H2I_SYNTH_C 0x1104 /* Synth DMA control */
126
127#define H2I_AESRX_C 0x1204 /* AES RX dma control */
128
129#define H2I_C_TS_EN 0x20 /* Timestamp enable */
130#define H2I_C_TS_FRMT 0x40 /* Timestamp format */
131#define H2I_C_NAUDIO 0x80 /* Sign extend */
132
133/* AESRX CTL, 16 bit */
134
135#define H2I_AESTX_C 0x1304 /* AES TX DMA control */
136#define H2I_AESTX_C_CLKID_SHIFT 3 /* Bresenham Clock Gen 1-3 */
137#define H2I_AESTX_C_CLKID_M 0x18
138#define H2I_AESTX_C_DATAT_SHIFT 8 /* 1=mono 2=stereo (3=quad) */
139#define H2I_AESTX_C_DATAT_M 0x300
140
141/* CODEC registers */
142
143#define H2I_DAC_C1 0x1404 /* DAC DMA control, 16 bit */
144#define H2I_DAC_C2 0x1408 /* DAC DMA control, 32 bit */
145#define H2I_ADC_C1 0x1504 /* ADC DMA control, 16 bit */
146#define H2I_ADC_C2 0x1508 /* ADC DMA control, 32 bit */
147
148/* Bits in CTL1 register */
149
150#define H2I_C1_DMA_SHIFT 0 /* DMA channel */
151#define H2I_C1_DMA_M 0x7
152#define H2I_C1_CLKID_SHIFT 3 /* Bresenham Clock Gen 1-3 */
153#define H2I_C1_CLKID_M 0x18
154#define H2I_C1_DATAT_SHIFT 8 /* 1=mono 2=stereo (3=quad) */
155#define H2I_C1_DATAT_M 0x300
156
157/* Bits in CTL2 register */
158
159#define H2I_C2_R_GAIN_SHIFT 0 /* right a/d input gain */
160#define H2I_C2_R_GAIN_M 0xf
161#define H2I_C2_L_GAIN_SHIFT 4 /* left a/d input gain */
162#define H2I_C2_L_GAIN_M 0xf0
163#define H2I_C2_R_SEL 0x100 /* right input select */
164#define H2I_C2_L_SEL 0x200 /* left input select */
165#define H2I_C2_MUTE 0x400 /* mute */
166#define H2I_C2_DO1 0x00010000 /* digital output port bit 0 */
167#define H2I_C2_DO2 0x00020000 /* digital output port bit 1 */
168#define H2I_C2_R_ATT_SHIFT 18 /* right d/a output - */
169#define H2I_C2_R_ATT_M 0x007c0000 /* attenuation */
170#define H2I_C2_L_ATT_SHIFT 23 /* left d/a output - */
171#define H2I_C2_L_ATT_M 0x0f800000 /* attenuation */
172
173#define H2I_SYNTH_MAP_C 0x1104 /* synth dma handshake ctrl */
174
175/* Clock generator CTL 1, 16 bit */
176
177#define H2I_BRES1_C1 0x2104
178#define H2I_BRES2_C1 0x2204
179#define H2I_BRES3_C1 0x2304
180
181#define H2I_BRES_C1_SHIFT 0 /* 0=48.0 1=44.1 2=aes_rx */
182#define H2I_BRES_C1_M 0x03
183
184/* Clock generator CTL 2, 32 bit */
185
186#define H2I_BRES1_C2 0x2108
187#define H2I_BRES2_C2 0x2208
188#define H2I_BRES3_C2 0x2308
189
190#define H2I_BRES_C2_INC_SHIFT 0 /* increment value */
191#define H2I_BRES_C2_INC_M 0xffff
192#define H2I_BRES_C2_MOD_SHIFT 16 /* modcontrol value */
193#define H2I_BRES_C2_MOD_M 0xffff0000 /* modctrl=0xffff&(modinc-1) */
194
195/* Unix timer, 64 bit */
196
197#define H2I_UTIME 0x3104
198#define H2I_UTIME_0_LD 0xffff /* microseconds, LSB's */
199#define H2I_UTIME_1_LD0 0x0f /* microseconds, MSB's */
200#define H2I_UTIME_1_LD1 0xf0 /* tenths of microseconds */
201#define H2I_UTIME_2_LD 0xffff /* seconds, LSB's */
202#define H2I_UTIME_3_LD 0xffff /* seconds, MSB's */
203
204struct hal2_ctl_regs {
205 u32 _unused0[4];
206 volatile u32 isr; /* 0x10 Status Register */
207 u32 _unused1[3];
208 volatile u32 rev; /* 0x20 Revision Register */
209 u32 _unused2[3];
210 volatile u32 iar; /* 0x30 Indirect Address Register */
211 u32 _unused3[3];
212 volatile u32 idr0; /* 0x40 Indirect Data Register 0 */
213 u32 _unused4[3];
214 volatile u32 idr1; /* 0x50 Indirect Data Register 1 */
215 u32 _unused5[3];
216 volatile u32 idr2; /* 0x60 Indirect Data Register 2 */
217 u32 _unused6[3];
218 volatile u32 idr3; /* 0x70 Indirect Data Register 3 */
219};
220
221struct hal2_aes_regs {
222 volatile u32 rx_stat[2]; /* Status registers */
223 volatile u32 rx_cr[2]; /* Control registers */
224 volatile u32 rx_ud[4]; /* User data window */
225 volatile u32 rx_st[24]; /* Channel status data */
226
227 volatile u32 tx_stat[1]; /* Status register */
228 volatile u32 tx_cr[3]; /* Control registers */
229 volatile u32 tx_ud[4]; /* User data window */
230 volatile u32 tx_st[24]; /* Channel status data */
231};
232
233struct hal2_vol_regs {
234 volatile u32 right; /* Right volume */
235 volatile u32 left; /* Left volume */
236};
237
238struct hal2_syn_regs {
239 u32 _unused0[2];
240 volatile u32 page; /* DOC Page register */
241 volatile u32 regsel; /* DOC Register selection */
242 volatile u32 dlow; /* DOC Data low */
243 volatile u32 dhigh; /* DOC Data high */
244 volatile u32 irq; /* IRQ Status */
245 volatile u32 dram; /* DRAM Access */
246};
247
248#endif /* __HAL2_H */
diff --git a/sound/oss/mpu401.c b/sound/oss/mpu401.c
index a690ca57adb5..6c0a770ed054 100644
--- a/sound/oss/mpu401.c
+++ b/sound/oss/mpu401.c
@@ -1015,7 +1015,7 @@ int attach_mpu401(struct address_info *hw_config, struct module *owner)
1015 mpu401_chk_version(m, devc); 1015 mpu401_chk_version(m, devc);
1016 if (devc->version == 0) 1016 if (devc->version == 0)
1017 mpu401_chk_version(m, devc); 1017 mpu401_chk_version(m, devc);
1018 spin_unlock_irqrestore(&devc->lock,flags); 1018 spin_unlock_irqrestore(&devc->lock, flags);
1019 } 1019 }
1020 1020
1021 if (devc->version != 0) 1021 if (devc->version != 0)
diff --git a/sound/parisc/harmony.c b/sound/parisc/harmony.c
index 99f5483abf2e..41f870f8a11d 100644
--- a/sound/parisc/harmony.c
+++ b/sound/parisc/harmony.c
@@ -868,7 +868,8 @@ snd_harmony_mixer_init(struct snd_harmony *h)
868 struct snd_card *card = h->card; 868 struct snd_card *card = h->card;
869 int idx, err; 869 int idx, err;
870 870
871 snd_assert(h != NULL, return -EINVAL); 871 if (snd_BUG_ON(!h))
872 return -EINVAL;
872 strcpy(card->mixername, "Harmony Gain control interface"); 873 strcpy(card->mixername, "Harmony Gain control interface");
873 874
874 for (idx = 0; idx < HARMONY_CONTROLS; idx++) { 875 for (idx = 0; idx < HARMONY_CONTROLS; idx++) {
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index 31f52d3fc21f..7003711f4fcc 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -517,6 +517,14 @@ config SND_HDA_HWDEP
517 This interface can be used for out-of-band communication 517 This interface can be used for out-of-band communication
518 with codecs for debugging purposes. 518 with codecs for debugging purposes.
519 519
520config SND_HDA_INPUT_BEEP
521 bool "Support digital beep via input layer"
522 depends on SND_HDA_INTEL
523 depends on INPUT=y || INPUT=SND_HDA_INTEL
524 help
525 Say Y here to build a digital beep interface for HD-audio
526 driver. This interface is used to generate digital beeps.
527
520config SND_HDA_CODEC_REALTEK 528config SND_HDA_CODEC_REALTEK
521 bool "Build Realtek HD-audio codec support" 529 bool "Build Realtek HD-audio codec support"
522 depends on SND_HDA_INTEL 530 depends on SND_HDA_INTEL
@@ -557,6 +565,14 @@ config SND_HDA_CODEC_ATIHDMI
557 Say Y here to include ATI HDMI HD-audio codec support in 565 Say Y here to include ATI HDMI HD-audio codec support in
558 snd-hda-intel driver, such as ATI RS600 HDMI. 566 snd-hda-intel driver, such as ATI RS600 HDMI.
559 567
568config SND_HDA_CODEC_NVHDMI
569 bool "Build NVIDIA HDMI HD-audio codec support"
570 depends on SND_HDA_INTEL
571 default y
572 help
573 Say Y here to include NVIDIA HDMI HD-audio codec support in
574 snd-hda-intel driver, such as NVIDIA MCP78 HDMI.
575
560config SND_HDA_CODEC_CONEXANT 576config SND_HDA_CODEC_CONEXANT
561 bool "Build Conexant HD-audio codec support" 577 bool "Build Conexant HD-audio codec support"
562 depends on SND_HDA_INTEL 578 depends on SND_HDA_INTEL
@@ -649,8 +665,9 @@ config SND_ICE1712
649 665
650 Currently supported hardware is: M-Audio Delta 1010(LT), 666 Currently supported hardware is: M-Audio Delta 1010(LT),
651 DiO 2496, 66, 44, 410, Audiophile 24/96; Digigram VX442; 667 DiO 2496, 66, 44, 410, Audiophile 24/96; Digigram VX442;
652 TerraTec EWX 24/96, EWS 88MT, 88D, DMX 6Fire, Phase 88; 668 TerraTec EWX 24/96, EWS 88MT/D, DMX 6Fire, Phase 88;
653 Hoontech SoundTrack DSP 24/Value/Media7.1; Event EZ8. 669 Hoontech SoundTrack DSP 24/Value/Media7.1; Event EZ8;
670 Lionstracs Mediastation, Terrasoniq TS 88.
654 671
655 To compile this driver as a module, choose M here: the module 672 To compile this driver as a module, choose M here: the module
656 will be called snd-ice1712. 673 will be called snd-ice1712.
@@ -665,9 +682,12 @@ config SND_ICE1724
665 ICE/VT1724/1720 (Envy24HT/PT) chips. 682 ICE/VT1724/1720 (Envy24HT/PT) chips.
666 683
667 Currently supported hardware is: AMP AUDIO2000; M-Audio 684 Currently supported hardware is: AMP AUDIO2000; M-Audio
668 Revolution 7.1; TerraTec Aureon 5.1 Sky, 7.1 Space/Universe; 685 Revolution 5.1, 7.1, Audiophile 192; TerraTec Aureon 5.1 Sky,
669 AudioTrak Prodigy 7.1; Pontis MS300; Albatron K8X800 Pro II; 686 7.1 Space/Universe, Phase 22/28; Onkyo SE-90PCI, SE-200PCI;
670 Chaintech ZNF3-150/250. 687 AudioTrak Prodigy 192, 7.1 (HIFI/LT/XT), HD2; Hercules
688 Fortissimo IV; ESI Juli@; Pontis MS300; EGO-SYS WaveTerminal
689 192M; Albatron K8X800 Pro II; Chaintech ZNF3-150/250, 9CJS,
690 AV-710; Shuttle SN25P.
671 691
672 To compile this driver as a module, choose M here: the module 692 To compile this driver as a module, choose M here: the module
673 will be called snd-ice1724. 693 will be called snd-ice1724.
@@ -845,7 +865,8 @@ config SND_VIRTUOSO
845 select SND_OXYGEN_LIB 865 select SND_OXYGEN_LIB
846 help 866 help
847 Say Y here to include support for sound cards based on the 867 Say Y here to include support for sound cards based on the
848 Asus AV100/AV200 chips, i.e., Xonar D1, DX, D2 and D2X. 868 Asus AV100/AV200 chips, i.e., Xonar D1, DX, D2, D2X and
869 HDAV1.3 (Deluxe).
849 870
850 To compile this driver as a module, choose M here: the module 871 To compile this driver as a module, choose M here: the module
851 will be called snd-virtuoso. 872 will be called snd-virtuoso.
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
index 8c49a00a5e39..6704acbca8c0 100644
--- a/sound/pci/ac97/ac97_codec.c
+++ b/sound/pci/ac97/ac97_codec.c
@@ -67,8 +67,8 @@ struct ac97_codec_id {
67}; 67};
68 68
69static const struct ac97_codec_id snd_ac97_codec_id_vendors[] = { 69static const struct ac97_codec_id snd_ac97_codec_id_vendors[] = {
70{ 0x414b4d00, 0xffffff00, "Asahi Kasei", NULL, NULL },
71{ 0x41445300, 0xffffff00, "Analog Devices", NULL, NULL }, 70{ 0x41445300, 0xffffff00, "Analog Devices", NULL, NULL },
71{ 0x414b4d00, 0xffffff00, "Asahi Kasei", NULL, NULL },
72{ 0x414c4300, 0xffffff00, "Realtek", NULL, NULL }, 72{ 0x414c4300, 0xffffff00, "Realtek", NULL, NULL },
73{ 0x414c4700, 0xffffff00, "Realtek", NULL, NULL }, 73{ 0x414c4700, 0xffffff00, "Realtek", NULL, NULL },
74{ 0x434d4900, 0xffffff00, "C-Media Electronics", NULL, NULL }, 74{ 0x434d4900, 0xffffff00, "C-Media Electronics", NULL, NULL },
@@ -94,11 +94,6 @@ static const struct ac97_codec_id snd_ac97_codec_id_vendors[] = {
94}; 94};
95 95
96static const struct ac97_codec_id snd_ac97_codec_ids[] = { 96static const struct ac97_codec_id snd_ac97_codec_ids[] = {
97{ 0x414b4d00, 0xffffffff, "AK4540", NULL, NULL },
98{ 0x414b4d01, 0xffffffff, "AK4542", NULL, NULL },
99{ 0x414b4d02, 0xffffffff, "AK4543", NULL, NULL },
100{ 0x414b4d06, 0xffffffff, "AK4544A", NULL, NULL },
101{ 0x414b4d07, 0xffffffff, "AK4545", NULL, NULL },
102{ 0x41445303, 0xffffffff, "AD1819", patch_ad1819, NULL }, 97{ 0x41445303, 0xffffffff, "AD1819", patch_ad1819, NULL },
103{ 0x41445340, 0xffffffff, "AD1881", patch_ad1881, NULL }, 98{ 0x41445340, 0xffffffff, "AD1881", patch_ad1881, NULL },
104{ 0x41445348, 0xffffffff, "AD1881A", patch_ad1881, NULL }, 99{ 0x41445348, 0xffffffff, "AD1881A", patch_ad1881, NULL },
@@ -112,20 +107,25 @@ static const struct ac97_codec_id snd_ac97_codec_ids[] = {
112{ 0x41445374, 0xffffffff, "AD1981B", patch_ad1981b, NULL }, 107{ 0x41445374, 0xffffffff, "AD1981B", patch_ad1981b, NULL },
113{ 0x41445375, 0xffffffff, "AD1985", patch_ad1985, NULL }, 108{ 0x41445375, 0xffffffff, "AD1985", patch_ad1985, NULL },
114{ 0x41445378, 0xffffffff, "AD1986", patch_ad1986, NULL }, 109{ 0x41445378, 0xffffffff, "AD1986", patch_ad1986, NULL },
110{ 0x414b4d00, 0xffffffff, "AK4540", NULL, NULL },
111{ 0x414b4d01, 0xffffffff, "AK4542", NULL, NULL },
112{ 0x414b4d02, 0xffffffff, "AK4543", NULL, NULL },
113{ 0x414b4d06, 0xffffffff, "AK4544A", NULL, NULL },
114{ 0x414b4d07, 0xffffffff, "AK4545", NULL, NULL },
115{ 0x414c4300, 0xffffff00, "ALC100,100P", NULL, NULL }, 115{ 0x414c4300, 0xffffff00, "ALC100,100P", NULL, NULL },
116{ 0x414c4710, 0xfffffff0, "ALC200,200P", NULL, NULL }, 116{ 0x414c4710, 0xfffffff0, "ALC200,200P", NULL, NULL },
117{ 0x414c4721, 0xffffffff, "ALC650D", NULL, NULL }, /* already patched */ 117{ 0x414c4721, 0xffffffff, "ALC650D", NULL, NULL }, /* already patched */
118{ 0x414c4722, 0xffffffff, "ALC650E", NULL, NULL }, /* already patched */ 118{ 0x414c4722, 0xffffffff, "ALC650E", NULL, NULL }, /* already patched */
119{ 0x414c4723, 0xffffffff, "ALC650F", NULL, NULL }, /* already patched */ 119{ 0x414c4723, 0xffffffff, "ALC650F", NULL, NULL }, /* already patched */
120{ 0x414c4720, 0xfffffff0, "ALC650", patch_alc650, NULL }, 120{ 0x414c4720, 0xfffffff0, "ALC650", patch_alc650, NULL },
121{ 0x414c4730, 0xffffffff, "ALC101", NULL, NULL },
122{ 0x414c4740, 0xfffffff0, "ALC202", NULL, NULL },
123{ 0x414c4750, 0xfffffff0, "ALC250", NULL, NULL },
121{ 0x414c4760, 0xfffffff0, "ALC655", patch_alc655, NULL }, 124{ 0x414c4760, 0xfffffff0, "ALC655", patch_alc655, NULL },
125{ 0x414c4770, 0xfffffff0, "ALC203", patch_alc203, NULL },
122{ 0x414c4781, 0xffffffff, "ALC658D", NULL, NULL }, /* already patched */ 126{ 0x414c4781, 0xffffffff, "ALC658D", NULL, NULL }, /* already patched */
123{ 0x414c4780, 0xfffffff0, "ALC658", patch_alc655, NULL }, 127{ 0x414c4780, 0xfffffff0, "ALC658", patch_alc655, NULL },
124{ 0x414c4790, 0xfffffff0, "ALC850", patch_alc850, NULL }, 128{ 0x414c4790, 0xfffffff0, "ALC850", patch_alc850, NULL },
125{ 0x414c4730, 0xffffffff, "ALC101", NULL, NULL },
126{ 0x414c4740, 0xfffffff0, "ALC202", NULL, NULL },
127{ 0x414c4750, 0xfffffff0, "ALC250", NULL, NULL },
128{ 0x414c4770, 0xfffffff0, "ALC203", NULL, NULL },
129{ 0x434d4941, 0xffffffff, "CMI9738", patch_cm9738, NULL }, 129{ 0x434d4941, 0xffffffff, "CMI9738", patch_cm9738, NULL },
130{ 0x434d4961, 0xffffffff, "CMI9739", patch_cm9739, NULL }, 130{ 0x434d4961, 0xffffffff, "CMI9739", patch_cm9739, NULL },
131{ 0x434d4969, 0xffffffff, "CMI9780", patch_cm9780, NULL }, 131{ 0x434d4969, 0xffffffff, "CMI9780", patch_cm9780, NULL },
@@ -168,7 +168,7 @@ static const struct ac97_codec_id snd_ac97_codec_ids[] = {
168{ 0x54584e20, 0xffffffff, "TLC320AD9xC", NULL, NULL }, 168{ 0x54584e20, 0xffffffff, "TLC320AD9xC", NULL, NULL },
169{ 0x56494161, 0xffffffff, "VIA1612A", NULL, NULL }, // modified ICE1232 with S/PDIF 169{ 0x56494161, 0xffffffff, "VIA1612A", NULL, NULL }, // modified ICE1232 with S/PDIF
170{ 0x56494170, 0xffffffff, "VIA1617A", patch_vt1617a, NULL }, // modified VT1616 with S/PDIF 170{ 0x56494170, 0xffffffff, "VIA1617A", patch_vt1617a, NULL }, // modified VT1616 with S/PDIF
171{ 0x56494182, 0xffffffff, "VIA1618", NULL, NULL }, 171{ 0x56494182, 0xffffffff, "VIA1618", patch_vt1618, NULL },
172{ 0x57454301, 0xffffffff, "W83971D", NULL, NULL }, 172{ 0x57454301, 0xffffffff, "W83971D", NULL, NULL },
173{ 0x574d4c00, 0xffffffff, "WM9701,WM9701A", NULL, NULL }, 173{ 0x574d4c00, 0xffffffff, "WM9701,WM9701A", NULL, NULL },
174{ 0x574d4C03, 0xffffffff, "WM9703,WM9707,WM9708,WM9717", patch_wolfson03, NULL}, 174{ 0x574d4C03, 0xffffffff, "WM9703,WM9707,WM9708,WM9717", patch_wolfson03, NULL},
@@ -1890,8 +1890,8 @@ int snd_ac97_bus(struct snd_card *card, int num, struct snd_ac97_bus_ops *ops,
1890 .dev_free = snd_ac97_bus_dev_free, 1890 .dev_free = snd_ac97_bus_dev_free,
1891 }; 1891 };
1892 1892
1893 snd_assert(card != NULL, return -EINVAL); 1893 if (snd_BUG_ON(!card))
1894 snd_assert(rbus != NULL, return -EINVAL); 1894 return -EINVAL;
1895 bus = kzalloc(sizeof(*bus), GFP_KERNEL); 1895 bus = kzalloc(sizeof(*bus), GFP_KERNEL);
1896 if (bus == NULL) 1896 if (bus == NULL)
1897 return -ENOMEM; 1897 return -ENOMEM;
@@ -1906,7 +1906,8 @@ int snd_ac97_bus(struct snd_card *card, int num, struct snd_ac97_bus_ops *ops,
1906 snd_ac97_bus_free(bus); 1906 snd_ac97_bus_free(bus);
1907 return err; 1907 return err;
1908 } 1908 }
1909 *rbus = bus; 1909 if (rbus)
1910 *rbus = bus;
1910 return 0; 1911 return 0;
1911} 1912}
1912 1913
@@ -1991,10 +1992,14 @@ int snd_ac97_mixer(struct snd_ac97_bus *bus, struct snd_ac97_template *template,
1991 .dev_disconnect = snd_ac97_dev_disconnect, 1992 .dev_disconnect = snd_ac97_dev_disconnect,
1992 }; 1993 };
1993 1994
1994 snd_assert(rac97 != NULL, return -EINVAL); 1995 if (rac97)
1995 *rac97 = NULL; 1996 *rac97 = NULL;
1996 snd_assert(bus != NULL && template != NULL, return -EINVAL); 1997 if (snd_BUG_ON(!bus || !template))
1997 snd_assert(template->num < 4 && bus->codec[template->num] == NULL, return -EINVAL); 1998 return -EINVAL;
1999 if (snd_BUG_ON(template->num >= 4))
2000 return -EINVAL;
2001 if (bus->codec[template->num])
2002 return -EBUSY;
1998 2003
1999 card = bus->card; 2004 card = bus->card;
2000 ac97 = kzalloc(sizeof(*ac97), GFP_KERNEL); 2005 ac97 = kzalloc(sizeof(*ac97), GFP_KERNEL);
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index f4fbc795ee81..6e831aff1bd0 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -476,7 +476,7 @@ static int patch_yamaha_ymf753(struct snd_ac97 * ac97)
476} 476}
477 477
478/* 478/*
479 * May 2, 2003 Liam Girdwood <liam.girdwood@wolfsonmicro.com> 479 * May 2, 2003 Liam Girdwood <lrg@slimlogic.co.uk>
480 * removed broken wolfson00 patch. 480 * removed broken wolfson00 patch.
481 * added support for WM9705,WM9708,WM9709,WM9710,WM9711,WM9712 and WM9717. 481 * added support for WM9705,WM9708,WM9709,WM9710,WM9711,WM9712 and WM9717.
482 */ 482 */
@@ -2560,6 +2560,14 @@ static int patch_ad1986(struct snd_ac97 * ac97)
2560 return 0; 2560 return 0;
2561} 2561}
2562 2562
2563/*
2564 * realtek ALC203: use mono-out for pin 37
2565 */
2566static int patch_alc203(struct snd_ac97 *ac97)
2567{
2568 snd_ac97_update_bits(ac97, 0x7a, 0x400, 0x400);
2569 return 0;
2570}
2563 2571
2564/* 2572/*
2565 * realtek ALC65x/850 codecs 2573 * realtek ALC65x/850 codecs
@@ -3457,7 +3465,7 @@ static int patch_vt1616(struct snd_ac97 * ac97)
3457 3465
3458/* 3466/*
3459 * unfortunately, the vt1617a stashes the twiddlers required for 3467 * unfortunately, the vt1617a stashes the twiddlers required for
3460 * nooding the i/o jacks on 2 different regs. * thameans that we cant 3468 * noodling the i/o jacks on 2 different regs. that means that we can't
3461 * use the easy way provided by AC97_ENUM_DOUBLE() we have to write 3469 * use the easy way provided by AC97_ENUM_DOUBLE() we have to write
3462 * are own funcs. 3470 * are own funcs.
3463 * 3471 *
@@ -3490,7 +3498,7 @@ static int snd_ac97_vt1617a_smart51_get(struct snd_kcontrol *kcontrol,
3490 3498
3491 pac97 = snd_kcontrol_chip(kcontrol); /* grab codec handle */ 3499 pac97 = snd_kcontrol_chip(kcontrol); /* grab codec handle */
3492 3500
3493 /* grab our desirec bits, then mash them together in a manner 3501 /* grab our desired bits, then mash them together in a manner
3494 * consistent with Table 6 on page 17 in the 1617a docs */ 3502 * consistent with Table 6 on page 17 in the 1617a docs */
3495 3503
3496 usSM51 = snd_ac97_read(pac97, 0x7a) >> 14; 3504 usSM51 = snd_ac97_read(pac97, 0x7a) >> 14;
@@ -3540,7 +3548,7 @@ static const struct snd_kcontrol_new snd_ac97_controls_vt1617a[] = {
3540 }, 3548 },
3541}; 3549};
3542 3550
3543int patch_vt1617a(struct snd_ac97 * ac97) 3551static int patch_vt1617a(struct snd_ac97 * ac97)
3544{ 3552{
3545 int err = 0; 3553 int err = 0;
3546 int val; 3554 int val;
@@ -3568,6 +3576,200 @@ int patch_vt1617a(struct snd_ac97 * ac97)
3568 return err; 3576 return err;
3569} 3577}
3570 3578
3579/* VIA VT1618 8 CHANNEL AC97 CODEC
3580 *
3581 * VIA implements 'Smart 5.1' completely differently on the 1618 than
3582 * it does on the 1617a. awesome! They seem to have sourced this
3583 * particular revision of the technology from somebody else, it's
3584 * called Universal Audio Jack and it shows up on some other folk's chips
3585 * as well.
3586 *
3587 * ordering in this list reflects vt1618 docs for Reg 60h and
3588 * the block diagram, DACs are as follows:
3589 *
3590 * OUT_O -> Front,
3591 * OUT_1 -> Surround,
3592 * OUT_2 -> C/LFE
3593 *
3594 * Unlike the 1617a, each OUT has a consistent set of mappings
3595 * for all bitpatterns other than 00:
3596 *
3597 * 01 Unmixed Output
3598 * 10 Line In
3599 * 11 Mic In
3600 *
3601 * Special Case of 00:
3602 *
3603 * OUT_0 Mixed Output
3604 * OUT_1 Reserved
3605 * OUT_2 Reserved
3606 *
3607 * I have no idea what the hell Reserved does, but on an MSI
3608 * CN700T, i have to set it to get 5.1 output - YMMV, bad
3609 * shit may happen.
3610 *
3611 * If other chips use Universal Audio Jack, then this code might be applicable
3612 * to them.
3613 */
3614
3615struct vt1618_uaj_item {
3616 unsigned short mask;
3617 unsigned short shift;
3618 const char *items[4];
3619};
3620
3621/* This list reflects the vt1618 docs for Vendor Defined Register 0x60. */
3622
3623static struct vt1618_uaj_item vt1618_uaj[3] = {
3624 {
3625 /* speaker jack */
3626 .mask = 0x03,
3627 .shift = 0,
3628 .items = {
3629 "Speaker Out", "DAC Unmixed Out", "Line In", "Mic In"
3630 }
3631 },
3632 {
3633 /* line jack */
3634 .mask = 0x0c,
3635 .shift = 2,
3636 .items = {
3637 "Surround Out", "DAC Unmixed Out", "Line In", "Mic In"
3638 }
3639 },
3640 {
3641 /* mic jack */
3642 .mask = 0x30,
3643 .shift = 4,
3644 .items = {
3645 "Center LFE Out", "DAC Unmixed Out", "Line In", "Mic In"
3646 },
3647 },
3648};
3649
3650static int snd_ac97_vt1618_UAJ_info(struct snd_kcontrol *kcontrol,
3651 struct snd_ctl_elem_info *uinfo)
3652{
3653 return ac97_enum_text_info(kcontrol, uinfo,
3654 vt1618_uaj[kcontrol->private_value].items,
3655 4);
3656}
3657
3658/* All of the vt1618 Universal Audio Jack twiddlers are on
3659 * Vendor Defined Register 0x60, page 0. The bits, and thus
3660 * the mask, are the only thing that changes
3661 */
3662static int snd_ac97_vt1618_UAJ_get(struct snd_kcontrol *kcontrol,
3663 struct snd_ctl_elem_value *ucontrol)
3664{
3665 unsigned short datpag, uaj;
3666 struct snd_ac97 *pac97 = snd_kcontrol_chip(kcontrol);
3667
3668 mutex_lock(&pac97->page_mutex);
3669
3670 datpag = snd_ac97_read(pac97, AC97_INT_PAGING) & AC97_PAGE_MASK;
3671 snd_ac97_update_bits(pac97, AC97_INT_PAGING, AC97_PAGE_MASK, 0);
3672
3673 uaj = snd_ac97_read(pac97, 0x60) &
3674 vt1618_uaj[kcontrol->private_value].mask;
3675
3676 snd_ac97_update_bits(pac97, AC97_INT_PAGING, AC97_PAGE_MASK, datpag);
3677 mutex_unlock(&pac97->page_mutex);
3678
3679 ucontrol->value.enumerated.item[0] = uaj >>
3680 vt1618_uaj[kcontrol->private_value].shift;
3681
3682 return 0;
3683}
3684
3685static int snd_ac97_vt1618_UAJ_put(struct snd_kcontrol *kcontrol,
3686 struct snd_ctl_elem_value *ucontrol)
3687{
3688 return ac97_update_bits_page(snd_kcontrol_chip(kcontrol), 0x60,
3689 vt1618_uaj[kcontrol->private_value].mask,
3690 ucontrol->value.enumerated.item[0]<<
3691 vt1618_uaj[kcontrol->private_value].shift,
3692 0);
3693}
3694
3695/* config aux in jack - not found on 3 jack motherboards or soundcards */
3696
3697static int snd_ac97_vt1618_aux_info(struct snd_kcontrol *kcontrol,
3698 struct snd_ctl_elem_info *uinfo)
3699{
3700 static const char *txt_aux[] = {"Aux In", "Back Surr Out"};
3701
3702 return ac97_enum_text_info(kcontrol, uinfo, txt_aux, 2);
3703}
3704
3705static int snd_ac97_vt1618_aux_get(struct snd_kcontrol *kcontrol,
3706 struct snd_ctl_elem_value *ucontrol)
3707{
3708 ucontrol->value.enumerated.item[0] =
3709 (snd_ac97_read(snd_kcontrol_chip(kcontrol), 0x5c) & 0x0008)>>3;
3710 return 0;
3711}
3712
3713static int snd_ac97_vt1618_aux_put(struct snd_kcontrol *kcontrol,
3714 struct snd_ctl_elem_value *ucontrol)
3715{
3716 /* toggle surround rear dac power */
3717
3718 snd_ac97_update_bits(snd_kcontrol_chip(kcontrol), 0x5c, 0x0008,
3719 ucontrol->value.enumerated.item[0] << 3);
3720
3721 /* toggle aux in surround rear out jack */
3722
3723 return snd_ac97_update_bits(snd_kcontrol_chip(kcontrol), 0x76, 0x0008,
3724 ucontrol->value.enumerated.item[0] << 3);
3725}
3726
3727static const struct snd_kcontrol_new snd_ac97_controls_vt1618[] = {
3728 AC97_SINGLE("Exchange Center/LFE", 0x5a, 8, 1, 0),
3729 AC97_SINGLE("DC Offset", 0x5a, 10, 1, 0),
3730 AC97_SINGLE("Soft Mute", 0x5c, 0, 1, 1),
3731 AC97_SINGLE("Headphone Amp", 0x5c, 5, 1, 1),
3732 AC97_DOUBLE("Back Surr Volume", 0x5e, 8, 0, 31, 1),
3733 AC97_SINGLE("Back Surr Switch", 0x5e, 15, 1, 1),
3734 {
3735 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3736 .name = "Speaker Jack Mode",
3737 .info = snd_ac97_vt1618_UAJ_info,
3738 .get = snd_ac97_vt1618_UAJ_get,
3739 .put = snd_ac97_vt1618_UAJ_put,
3740 .private_value = 0
3741 },
3742 {
3743 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3744 .name = "Line Jack Mode",
3745 .info = snd_ac97_vt1618_UAJ_info,
3746 .get = snd_ac97_vt1618_UAJ_get,
3747 .put = snd_ac97_vt1618_UAJ_put,
3748 .private_value = 1
3749 },
3750 {
3751 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3752 .name = "Mic Jack Mode",
3753 .info = snd_ac97_vt1618_UAJ_info,
3754 .get = snd_ac97_vt1618_UAJ_get,
3755 .put = snd_ac97_vt1618_UAJ_put,
3756 .private_value = 2
3757 },
3758 {
3759 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3760 .name = "Aux Jack Mode",
3761 .info = snd_ac97_vt1618_aux_info,
3762 .get = snd_ac97_vt1618_aux_get,
3763 .put = snd_ac97_vt1618_aux_put,
3764 }
3765};
3766
3767static int patch_vt1618(struct snd_ac97 *ac97)
3768{
3769 return patch_build_controls(ac97, snd_ac97_controls_vt1618,
3770 ARRAY_SIZE(snd_ac97_controls_vt1618));
3771}
3772
3571/* 3773/*
3572 */ 3774 */
3573static void it2646_update_jacks(struct snd_ac97 *ac97) 3775static void it2646_update_jacks(struct snd_ac97 *ac97)
diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c
index 39ec55b57b1e..92f3a976ef2e 100644
--- a/sound/pci/ad1889.c
+++ b/sound/pci/ad1889.c
@@ -549,7 +549,8 @@ snd_ad1889_playback_pointer(struct snd_pcm_substream *ss)
549 ptr = ad1889_readl(chip, AD_DMA_WAVCA); 549 ptr = ad1889_readl(chip, AD_DMA_WAVCA);
550 ptr -= chip->wave.addr; 550 ptr -= chip->wave.addr;
551 551
552 snd_assert((ptr >= 0) && (ptr < chip->wave.size), return 0); 552 if (snd_BUG_ON(ptr >= chip->wave.size))
553 return 0;
553 554
554 return bytes_to_frames(ss->runtime, ptr); 555 return bytes_to_frames(ss->runtime, ptr);
555} 556}
@@ -567,7 +568,8 @@ snd_ad1889_capture_pointer(struct snd_pcm_substream *ss)
567 ptr = ad1889_readl(chip, AD_DMA_ADCCA); 568 ptr = ad1889_readl(chip, AD_DMA_ADCCA);
568 ptr -= chip->ramc.addr; 569 ptr -= chip->ramc.addr;
569 570
570 snd_assert((ptr >= 0) && (ptr < chip->ramc.size), return 0); 571 if (snd_BUG_ON(ptr >= chip->ramc.size))
572 return 0;
571 573
572 return bytes_to_frames(ss->runtime, ptr); 574 return bytes_to_frames(ss->runtime, ptr);
573} 575}
diff --git a/sound/pci/ak4531_codec.c b/sound/pci/ak4531_codec.c
index 33d37b1c42fc..0f819ddb3ebf 100644
--- a/sound/pci/ak4531_codec.c
+++ b/sound/pci/ak4531_codec.c
@@ -392,9 +392,10 @@ int __devinit snd_ak4531_mixer(struct snd_card *card,
392 .dev_free = snd_ak4531_dev_free, 392 .dev_free = snd_ak4531_dev_free,
393 }; 393 };
394 394
395 snd_assert(rak4531 != NULL, return -EINVAL); 395 if (snd_BUG_ON(!card || !_ak4531))
396 *rak4531 = NULL; 396 return -EINVAL;
397 snd_assert(card != NULL && _ak4531 != NULL, return -EINVAL); 397 if (rak4531)
398 *rak4531 = NULL;
398 ak4531 = kzalloc(sizeof(*ak4531), GFP_KERNEL); 399 ak4531 = kzalloc(sizeof(*ak4531), GFP_KERNEL);
399 if (ak4531 == NULL) 400 if (ak4531 == NULL)
400 return -ENOMEM; 401 return -ENOMEM;
@@ -428,7 +429,8 @@ int __devinit snd_ak4531_mixer(struct snd_card *card,
428#if 0 429#if 0
429 snd_ak4531_dump(ak4531); 430 snd_ak4531_dump(ak4531);
430#endif 431#endif
431 *rak4531 = ak4531; 432 if (rak4531)
433 *rak4531 = ak4531;
432 return 0; 434 return 0;
433} 435}
434 436
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c
index 27ce6136ab00..ba570053d4d5 100644
--- a/sound/pci/als4000.c
+++ b/sound/pci/als4000.c
@@ -2,7 +2,7 @@
2 * card-als4000.c - driver for Avance Logic ALS4000 based soundcards. 2 * card-als4000.c - driver for Avance Logic ALS4000 based soundcards.
3 * Copyright (C) 2000 by Bart Hartgers <bart@etpmod.phys.tue.nl>, 3 * Copyright (C) 2000 by Bart Hartgers <bart@etpmod.phys.tue.nl>,
4 * Jaroslav Kysela <perex@perex.cz> 4 * Jaroslav Kysela <perex@perex.cz>
5 * Copyright (C) 2002 by Andreas Mohr <hw7oshyuv3001@sneakemail.com> 5 * Copyright (C) 2002, 2008 by Andreas Mohr <hw7oshyuv3001@sneakemail.com>
6 * 6 *
7 * Framework borrowed from Massimo Piccioni's card-als100.c. 7 * Framework borrowed from Massimo Piccioni's card-als100.c.
8 * 8 *
@@ -27,8 +27,10 @@
27 * bought an ALS4000 based soundcard, I was forced to base this driver 27 * bought an ALS4000 based soundcard, I was forced to base this driver
28 * on reverse engineering. 28 * on reverse engineering.
29 * 29 *
30 * Note: this is no longer true. Pretty verbose chip docu (ALS4000a.PDF) 30 * Note: this is no longer true (thank you!):
31 * can be found on the ALSA web site. 31 * pretty verbose chip docu (ALS4000a.PDF) can be found on the ALSA web site.
32 * Page numbers stated anywhere below with the "SPECS_PAGE:" tag
33 * refer to: ALS4000a.PDF specs Ver 1.0, May 28th, 1998.
32 * 34 *
33 * The ALS4000 seems to be the PCI-cousin of the ALS100. It contains an 35 * The ALS4000 seems to be the PCI-cousin of the ALS100. It contains an
34 * ALS100-like SB DSP/mixer, an OPL3 synth, a MPU401 and a gameport 36 * ALS100-like SB DSP/mixer, an OPL3 synth, a MPU401 and a gameport
@@ -59,7 +61,7 @@
59 * - value -> some port 0x0c0d 61 * - value -> some port 0x0c0d
60 * 62 *
61 * ToDo: 63 * ToDo:
62 * - Proper shared IRQ handling? 64 * - by default, don't enable legacy game and use PCI game I/O
63 * - power management? (card can do voice wakeup according to datasheet!!) 65 * - power management? (card can do voice wakeup according to datasheet!!)
64 */ 66 */
65 67
@@ -78,7 +80,7 @@
78#include <sound/sb.h> 80#include <sound/sb.h>
79#include <sound/initval.h> 81#include <sound/initval.h>
80 82
81MODULE_AUTHOR("Bart Hartgers <bart@etpmod.phys.tue.nl>"); 83MODULE_AUTHOR("Bart Hartgers <bart@etpmod.phys.tue.nl>, Andreas Mohr");
82MODULE_DESCRIPTION("Avance Logic ALS4000"); 84MODULE_DESCRIPTION("Avance Logic ALS4000");
83MODULE_LICENSE("GPL"); 85MODULE_LICENSE("GPL");
84MODULE_SUPPORTED_DEVICE("{{Avance Logic,ALS4000}}"); 86MODULE_SUPPORTED_DEVICE("{{Avance Logic,ALS4000}}");
@@ -107,7 +109,7 @@ MODULE_PARM_DESC(joystick_port, "Joystick port address for ALS4000 soundcard. (0
107 109
108struct snd_card_als4000 { 110struct snd_card_als4000 {
109 /* most frequent access first */ 111 /* most frequent access first */
110 unsigned long gcr; 112 unsigned long iobase;
111 struct pci_dev *pci; 113 struct pci_dev *pci;
112 struct snd_sb *chip; 114 struct snd_sb *chip;
113#ifdef SUPPORT_JOYSTICK 115#ifdef SUPPORT_JOYSTICK
@@ -122,28 +124,168 @@ static struct pci_device_id snd_als4000_ids[] = {
122 124
123MODULE_DEVICE_TABLE(pci, snd_als4000_ids); 125MODULE_DEVICE_TABLE(pci, snd_als4000_ids);
124 126
125static inline void snd_als4000_gcr_write_addr(unsigned long port, u32 reg, u32 val) 127enum als4k_iobase_t {
128 /* IOx: B == Byte, W = Word, D = DWord; SPECS_PAGE: 37 */
129 ALS4K_IOD_00_AC97_ACCESS = 0x00,
130 ALS4K_IOW_04_AC97_READ = 0x04,
131 ALS4K_IOB_06_AC97_STATUS = 0x06,
132 ALS4K_IOB_07_IRQSTATUS = 0x07,
133 ALS4K_IOD_08_GCR_DATA = 0x08,
134 ALS4K_IOB_0C_GCR_INDEX = 0x0c,
135 ALS4K_IOB_0E_IRQTYPE_SB_CR1E_MPU = 0x0e,
136 ALS4K_IOB_10_ADLIB_ADDR0 = 0x10,
137 ALS4K_IOB_11_ADLIB_ADDR1 = 0x11,
138 ALS4K_IOB_12_ADLIB_ADDR2 = 0x12,
139 ALS4K_IOB_13_ADLIB_ADDR3 = 0x13,
140 ALS4K_IOB_14_MIXER_INDEX = 0x14,
141 ALS4K_IOB_15_MIXER_DATA = 0x15,
142 ALS4K_IOB_16_ESP_RESET = 0x16,
143 ALS4K_IOB_16_ACK_FOR_CR1E = 0x16, /* 2nd function */
144 ALS4K_IOB_18_OPL_ADDR0 = 0x18,
145 ALS4K_IOB_19_OPL_ADDR1 = 0x19,
146 ALS4K_IOB_1A_ESP_RD_DATA = 0x1a,
147 ALS4K_IOB_1C_ESP_CMD_DATA = 0x1c,
148 ALS4K_IOB_1C_ESP_WR_STATUS = 0x1c, /* 2nd function */
149 ALS4K_IOB_1E_ESP_RD_STATUS8 = 0x1e,
150 ALS4K_IOB_1F_ESP_RD_STATUS16 = 0x1f,
151 ALS4K_IOB_20_ESP_GAMEPORT_200 = 0x20,
152 ALS4K_IOB_21_ESP_GAMEPORT_201 = 0x21,
153 ALS4K_IOB_30_MIDI_DATA = 0x30,
154 ALS4K_IOB_31_MIDI_STATUS = 0x31,
155 ALS4K_IOB_31_MIDI_COMMAND = 0x31, /* 2nd function */
156};
157
158enum als4k_iobase_0e_t {
159 ALS4K_IOB_0E_MPU_IRQ = 0x10,
160 ALS4K_IOB_0E_CR1E_IRQ = 0x40,
161 ALS4K_IOB_0E_SB_DMA_IRQ = 0x80,
162};
163
164enum als4k_gcr_t { /* all registers 32bit wide; SPECS_PAGE: 38 to 42 */
165 ALS4K_GCR8C_MISC_CTRL = 0x8c,
166 ALS4K_GCR90_TEST_MODE_REG = 0x90,
167 ALS4K_GCR91_DMA0_ADDR = 0x91,
168 ALS4K_GCR92_DMA0_MODE_COUNT = 0x92,
169 ALS4K_GCR93_DMA1_ADDR = 0x93,
170 ALS4K_GCR94_DMA1_MODE_COUNT = 0x94,
171 ALS4K_GCR95_DMA3_ADDR = 0x95,
172 ALS4K_GCR96_DMA3_MODE_COUNT = 0x96,
173 ALS4K_GCR99_DMA_EMULATION_CTRL = 0x99,
174 ALS4K_GCRA0_FIFO1_CURRENT_ADDR = 0xa0,
175 ALS4K_GCRA1_FIFO1_STATUS_BYTECOUNT = 0xa1,
176 ALS4K_GCRA2_FIFO2_PCIADDR = 0xa2,
177 ALS4K_GCRA3_FIFO2_COUNT = 0xa3,
178 ALS4K_GCRA4_FIFO2_CURRENT_ADDR = 0xa4,
179 ALS4K_GCRA5_FIFO1_STATUS_BYTECOUNT = 0xa5,
180 ALS4K_GCRA6_PM_CTRL = 0xa6,
181 ALS4K_GCRA7_PCI_ACCESS_STORAGE = 0xa7,
182 ALS4K_GCRA8_LEGACY_CFG1 = 0xa8,
183 ALS4K_GCRA9_LEGACY_CFG2 = 0xa9,
184 ALS4K_GCRFF_DUMMY_SCRATCH = 0xff,
185};
186
187enum als4k_gcr8c_t {
188 ALS4K_GCR8C_IRQ_MASK_CTRL_ENABLE = 0x8000,
189 ALS4K_GCR8C_CHIP_REV_MASK = 0xf0000
190};
191
192static inline void snd_als4k_iobase_writeb(unsigned long iobase,
193 enum als4k_iobase_t reg,
194 u8 val)
195{
196 outb(val, iobase + reg);
197}
198
199static inline void snd_als4k_iobase_writel(unsigned long iobase,
200 enum als4k_iobase_t reg,
201 u32 val)
202{
203 outl(val, iobase + reg);
204}
205
206static inline u8 snd_als4k_iobase_readb(unsigned long iobase,
207 enum als4k_iobase_t reg)
208{
209 return inb(iobase + reg);
210}
211
212static inline u32 snd_als4k_iobase_readl(unsigned long iobase,
213 enum als4k_iobase_t reg)
214{
215 return inl(iobase + reg);
216}
217
218static inline void snd_als4k_gcr_write_addr(unsigned long iobase,
219 enum als4k_gcr_t reg,
220 u32 val)
126{ 221{
127 outb(reg, port+0x0c); 222 snd_als4k_iobase_writeb(iobase, ALS4K_IOB_0C_GCR_INDEX, reg);
128 outl(val, port+0x08); 223 snd_als4k_iobase_writel(iobase, ALS4K_IOD_08_GCR_DATA, val);
129} 224}
130 225
131static inline void snd_als4000_gcr_write(struct snd_sb *sb, u32 reg, u32 val) 226static inline void snd_als4k_gcr_write(struct snd_sb *sb,
227 enum als4k_gcr_t reg,
228 u32 val)
132{ 229{
133 snd_als4000_gcr_write_addr(sb->alt_port, reg, val); 230 snd_als4k_gcr_write_addr(sb->alt_port, reg, val);
134} 231}
135 232
136static inline u32 snd_als4000_gcr_read_addr(unsigned long port, u32 reg) 233static inline u32 snd_als4k_gcr_read_addr(unsigned long iobase,
234 enum als4k_gcr_t reg)
137{ 235{
138 outb(reg, port+0x0c); 236 /* SPECS_PAGE: 37/38 */
139 return inl(port+0x08); 237 snd_als4k_iobase_writeb(iobase, ALS4K_IOB_0C_GCR_INDEX, reg);
238 return snd_als4k_iobase_readl(iobase, ALS4K_IOD_08_GCR_DATA);
140} 239}
141 240
142static inline u32 snd_als4000_gcr_read(struct snd_sb *sb, u32 reg) 241static inline u32 snd_als4k_gcr_read(struct snd_sb *sb, enum als4k_gcr_t reg)
143{ 242{
144 return snd_als4000_gcr_read_addr(sb->alt_port, reg); 243 return snd_als4k_gcr_read_addr(sb->alt_port, reg);
145} 244}
146 245
246enum als4k_cr_t { /* all registers 8bit wide; SPECS_PAGE: 20 to 23 */
247 ALS4K_CR0_SB_CONFIG = 0x00,
248 ALS4K_CR2_MISC_CONTROL = 0x02,
249 ALS4K_CR3_CONFIGURATION = 0x03,
250 ALS4K_CR17_FIFO_STATUS = 0x17,
251 ALS4K_CR18_ESP_MAJOR_VERSION = 0x18,
252 ALS4K_CR19_ESP_MINOR_VERSION = 0x19,
253 ALS4K_CR1A_MPU401_UART_MODE_CONTROL = 0x1a,
254 ALS4K_CR1C_FIFO2_BLOCK_LENGTH_LO = 0x1c,
255 ALS4K_CR1D_FIFO2_BLOCK_LENGTH_HI = 0x1d,
256 ALS4K_CR1E_FIFO2_CONTROL = 0x1e, /* secondary PCM FIFO (recording) */
257 ALS4K_CR3A_MISC_CONTROL = 0x3a,
258 ALS4K_CR3B_CRC32_BYTE0 = 0x3b, /* for testing, activate via CR3A */
259 ALS4K_CR3C_CRC32_BYTE1 = 0x3c,
260 ALS4K_CR3D_CRC32_BYTE2 = 0x3d,
261 ALS4K_CR3E_CRC32_BYTE3 = 0x3e,
262};
263
264enum als4k_cr0_t {
265 ALS4K_CR0_DMA_CONTIN_MODE_CTRL = 0x02, /* IRQ/FIFO controlled for 0/1 */
266 ALS4K_CR0_DMA_90H_MODE_CTRL = 0x04, /* IRQ/FIFO controlled for 0/1 */
267 ALS4K_CR0_MX80_81_REG_WRITE_ENABLE = 0x80,
268};
269
270static inline void snd_als4_cr_write(struct snd_sb *chip,
271 enum als4k_cr_t reg,
272 u8 data)
273{
274 /* Control Register is reg | 0xc0 (bit 7, 6 set) on sbmixer_index
275 * NOTE: assumes chip->mixer_lock to be locked externally already!
276 * SPECS_PAGE: 6 */
277 snd_sbmixer_write(chip, reg | 0xc0, data);
278}
279
280static inline u8 snd_als4_cr_read(struct snd_sb *chip,
281 enum als4k_cr_t reg)
282{
283 /* NOTE: assumes chip->mixer_lock to be locked externally already! */
284 return snd_sbmixer_read(chip, reg | 0xc0);
285}
286
287
288
147static void snd_als4000_set_rate(struct snd_sb *chip, unsigned int rate) 289static void snd_als4000_set_rate(struct snd_sb *chip, unsigned int rate)
148{ 290{
149 if (!(chip->mode & SB_RATE_LOCK)) { 291 if (!(chip->mode & SB_RATE_LOCK)) {
@@ -156,15 +298,19 @@ static void snd_als4000_set_rate(struct snd_sb *chip, unsigned int rate)
156static inline void snd_als4000_set_capture_dma(struct snd_sb *chip, 298static inline void snd_als4000_set_capture_dma(struct snd_sb *chip,
157 dma_addr_t addr, unsigned size) 299 dma_addr_t addr, unsigned size)
158{ 300{
159 snd_als4000_gcr_write(chip, 0xa2, addr); 301 /* SPECS_PAGE: 40 */
160 snd_als4000_gcr_write(chip, 0xa3, (size-1)); 302 snd_als4k_gcr_write(chip, ALS4K_GCRA2_FIFO2_PCIADDR, addr);
303 snd_als4k_gcr_write(chip, ALS4K_GCRA3_FIFO2_COUNT, (size-1));
161} 304}
162 305
163static inline void snd_als4000_set_playback_dma(struct snd_sb *chip, 306static inline void snd_als4000_set_playback_dma(struct snd_sb *chip,
164 dma_addr_t addr, unsigned size) 307 dma_addr_t addr,
308 unsigned size)
165{ 309{
166 snd_als4000_gcr_write(chip, 0x91, addr); 310 /* SPECS_PAGE: 38 */
167 snd_als4000_gcr_write(chip, 0x92, (size-1)|0x180000); 311 snd_als4k_gcr_write(chip, ALS4K_GCR91_DMA0_ADDR, addr);
312 snd_als4k_gcr_write(chip, ALS4K_GCR92_DMA0_MODE_COUNT,
313 (size-1)|0x180000);
168} 314}
169 315
170#define ALS4000_FORMAT_SIGNED (1<<0) 316#define ALS4000_FORMAT_SIGNED (1<<0)
@@ -248,7 +394,7 @@ static int snd_als4000_capture_prepare(struct snd_pcm_substream *substream)
248 count = snd_pcm_lib_period_bytes(substream); 394 count = snd_pcm_lib_period_bytes(substream);
249 395
250 if (chip->capture_format & ALS4000_FORMAT_16BIT) 396 if (chip->capture_format & ALS4000_FORMAT_16BIT)
251 count >>=1; 397 count >>= 1;
252 count--; 398 count--;
253 399
254 spin_lock_irq(&chip->reg_lock); 400 spin_lock_irq(&chip->reg_lock);
@@ -256,8 +402,8 @@ static int snd_als4000_capture_prepare(struct snd_pcm_substream *substream)
256 snd_als4000_set_capture_dma(chip, runtime->dma_addr, size); 402 snd_als4000_set_capture_dma(chip, runtime->dma_addr, size);
257 spin_unlock_irq(&chip->reg_lock); 403 spin_unlock_irq(&chip->reg_lock);
258 spin_lock_irq(&chip->mixer_lock); 404 spin_lock_irq(&chip->mixer_lock);
259 snd_sbmixer_write(chip, 0xdc, count); 405 snd_als4_cr_write(chip, ALS4K_CR1C_FIFO2_BLOCK_LENGTH_LO, count & 0xff);
260 snd_sbmixer_write(chip, 0xdd, count>>8); 406 snd_als4_cr_write(chip, ALS4K_CR1D_FIFO2_BLOCK_LENGTH_HI, count >> 8);
261 spin_unlock_irq(&chip->mixer_lock); 407 spin_unlock_irq(&chip->mixer_lock);
262 return 0; 408 return 0;
263} 409}
@@ -275,7 +421,7 @@ static int snd_als4000_playback_prepare(struct snd_pcm_substream *substream)
275 count = snd_pcm_lib_period_bytes(substream); 421 count = snd_pcm_lib_period_bytes(substream);
276 422
277 if (chip->playback_format & ALS4000_FORMAT_16BIT) 423 if (chip->playback_format & ALS4000_FORMAT_16BIT)
278 count >>=1; 424 count >>= 1;
279 count--; 425 count--;
280 426
281 /* FIXME: from second playback on, there's a lot more clicks and pops 427 /* FIXME: from second playback on, there's a lot more clicks and pops
@@ -292,8 +438,8 @@ static int snd_als4000_playback_prepare(struct snd_pcm_substream *substream)
292 /* snd_sbdsp_command(chip, SB_DSP_SPEAKER_ON); */ 438 /* snd_sbdsp_command(chip, SB_DSP_SPEAKER_ON); */
293 snd_sbdsp_command(chip, playback_cmd(chip).dsp_cmd); 439 snd_sbdsp_command(chip, playback_cmd(chip).dsp_cmd);
294 snd_sbdsp_command(chip, playback_cmd(chip).format); 440 snd_sbdsp_command(chip, playback_cmd(chip).format);
295 snd_sbdsp_command(chip, count); 441 snd_sbdsp_command(chip, count & 0xff);
296 snd_sbdsp_command(chip, count>>8); 442 snd_sbdsp_command(chip, count >> 8);
297 snd_sbdsp_command(chip, playback_cmd(chip).dma_off); 443 snd_sbdsp_command(chip, playback_cmd(chip).dma_off);
298 spin_unlock_irq(&chip->reg_lock); 444 spin_unlock_irq(&chip->reg_lock);
299 445
@@ -305,17 +451,25 @@ static int snd_als4000_capture_trigger(struct snd_pcm_substream *substream, int
305 struct snd_sb *chip = snd_pcm_substream_chip(substream); 451 struct snd_sb *chip = snd_pcm_substream_chip(substream);
306 int result = 0; 452 int result = 0;
307 453
454 /* FIXME race condition in here!!!
455 chip->mode non-atomic update gets consistently protected
456 by reg_lock always, _except_ for this place!!
457 Probably need to take reg_lock as outer (or inner??) lock, too.
458 (or serialize both lock operations? probably not, though... - racy?)
459 */
308 spin_lock(&chip->mixer_lock); 460 spin_lock(&chip->mixer_lock);
309 switch (cmd) { 461 switch (cmd) {
310 case SNDRV_PCM_TRIGGER_START: 462 case SNDRV_PCM_TRIGGER_START:
311 case SNDRV_PCM_TRIGGER_RESUME: 463 case SNDRV_PCM_TRIGGER_RESUME:
312 chip->mode |= SB_RATE_LOCK_CAPTURE; 464 chip->mode |= SB_RATE_LOCK_CAPTURE;
313 snd_sbmixer_write(chip, 0xde, capture_cmd(chip)); 465 snd_als4_cr_write(chip, ALS4K_CR1E_FIFO2_CONTROL,
466 capture_cmd(chip));
314 break; 467 break;
315 case SNDRV_PCM_TRIGGER_STOP: 468 case SNDRV_PCM_TRIGGER_STOP:
316 case SNDRV_PCM_TRIGGER_SUSPEND: 469 case SNDRV_PCM_TRIGGER_SUSPEND:
317 chip->mode &= ~SB_RATE_LOCK_CAPTURE; 470 chip->mode &= ~SB_RATE_LOCK_CAPTURE;
318 snd_sbmixer_write(chip, 0xde, 0); 471 snd_als4_cr_write(chip, ALS4K_CR1E_FIFO2_CONTROL,
472 capture_cmd(chip));
319 break; 473 break;
320 default: 474 default:
321 result = -EINVAL; 475 result = -EINVAL;
@@ -356,8 +510,9 @@ static snd_pcm_uframes_t snd_als4000_capture_pointer(struct snd_pcm_substream *s
356 unsigned int result; 510 unsigned int result;
357 511
358 spin_lock(&chip->reg_lock); 512 spin_lock(&chip->reg_lock);
359 result = snd_als4000_gcr_read(chip, 0xa4) & 0xffff; 513 result = snd_als4k_gcr_read(chip, ALS4K_GCRA4_FIFO2_CURRENT_ADDR);
360 spin_unlock(&chip->reg_lock); 514 spin_unlock(&chip->reg_lock);
515 result &= 0xffff;
361 return bytes_to_frames( substream->runtime, result ); 516 return bytes_to_frames( substream->runtime, result );
362} 517}
363 518
@@ -367,8 +522,9 @@ static snd_pcm_uframes_t snd_als4000_playback_pointer(struct snd_pcm_substream *
367 unsigned result; 522 unsigned result;
368 523
369 spin_lock(&chip->reg_lock); 524 spin_lock(&chip->reg_lock);
370 result = snd_als4000_gcr_read(chip, 0xa0) & 0xffff; 525 result = snd_als4k_gcr_read(chip, ALS4K_GCRA0_FIFO1_CURRENT_ADDR);
371 spin_unlock(&chip->reg_lock); 526 spin_unlock(&chip->reg_lock);
527 result &= 0xffff;
372 return bytes_to_frames( substream->runtime, result ); 528 return bytes_to_frames( substream->runtime, result );
373} 529}
374 530
@@ -376,45 +532,63 @@ static snd_pcm_uframes_t snd_als4000_playback_pointer(struct snd_pcm_substream *
376 * return IRQ_HANDLED no matter whether we actually had an IRQ flag or not). 532 * return IRQ_HANDLED no matter whether we actually had an IRQ flag or not).
377 * ALS4000a.PDF writes that while ACKing IRQ in PCI block will *not* ACK 533 * ALS4000a.PDF writes that while ACKing IRQ in PCI block will *not* ACK
378 * the IRQ in the SB core, ACKing IRQ in SB block *will* ACK the PCI IRQ 534 * the IRQ in the SB core, ACKing IRQ in SB block *will* ACK the PCI IRQ
379 * register (alt_port + 0x0e). Probably something could be optimized here to 535 * register (alt_port + ALS4K_IOB_0E_IRQTYPE_SB_CR1E_MPU). Probably something
380 * query/write one register only... 536 * could be optimized here to query/write one register only...
381 * And even if both registers need to be queried, then there's still the 537 * And even if both registers need to be queried, then there's still the
382 * question of whether it's actually correct to ACK PCI IRQ before reading 538 * question of whether it's actually correct to ACK PCI IRQ before reading
383 * SB IRQ like we do now, since ALS4000a.PDF mentions that PCI IRQ will *clear* 539 * SB IRQ like we do now, since ALS4000a.PDF mentions that PCI IRQ will *clear*
384 * SB IRQ status. 540 * SB IRQ status.
541 * (hmm, SPECS_PAGE: 38 mentions it the other way around!)
385 * And do we *really* need the lock here for *reading* SB_DSP4_IRQSTATUS?? 542 * And do we *really* need the lock here for *reading* SB_DSP4_IRQSTATUS??
386 * */ 543 * */
387static irqreturn_t snd_als4000_interrupt(int irq, void *dev_id) 544static irqreturn_t snd_als4000_interrupt(int irq, void *dev_id)
388{ 545{
389 struct snd_sb *chip = dev_id; 546 struct snd_sb *chip = dev_id;
390 unsigned gcr_status; 547 unsigned pci_irqstatus;
391 unsigned sb_status; 548 unsigned sb_irqstatus;
392 549
393 /* find out which bit of the ALS4000 produced the interrupt */ 550 /* find out which bit of the ALS4000 PCI block produced the interrupt,
394 gcr_status = inb(chip->alt_port + 0xe); 551 SPECS_PAGE: 38, 5 */
395 552 pci_irqstatus = snd_als4k_iobase_readb(chip->alt_port,
396 if ((gcr_status & 0x80) && (chip->playback_substream)) /* playback */ 553 ALS4K_IOB_0E_IRQTYPE_SB_CR1E_MPU);
554 if ((pci_irqstatus & ALS4K_IOB_0E_SB_DMA_IRQ)
555 && (chip->playback_substream)) /* playback */
397 snd_pcm_period_elapsed(chip->playback_substream); 556 snd_pcm_period_elapsed(chip->playback_substream);
398 if ((gcr_status & 0x40) && (chip->capture_substream)) /* capturing */ 557 if ((pci_irqstatus & ALS4K_IOB_0E_CR1E_IRQ)
558 && (chip->capture_substream)) /* capturing */
399 snd_pcm_period_elapsed(chip->capture_substream); 559 snd_pcm_period_elapsed(chip->capture_substream);
400 if ((gcr_status & 0x10) && (chip->rmidi)) /* MPU401 interrupt */ 560 if ((pci_irqstatus & ALS4K_IOB_0E_MPU_IRQ)
561 && (chip->rmidi)) /* MPU401 interrupt */
401 snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data); 562 snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data);
402 /* release the gcr */ 563 /* ACK the PCI block IRQ */
403 outb(gcr_status, chip->alt_port + 0xe); 564 snd_als4k_iobase_writeb(chip->alt_port,
565 ALS4K_IOB_0E_IRQTYPE_SB_CR1E_MPU, pci_irqstatus);
404 566
405 spin_lock(&chip->mixer_lock); 567 spin_lock(&chip->mixer_lock);
406 sb_status = snd_sbmixer_read(chip, SB_DSP4_IRQSTATUS); 568 /* SPECS_PAGE: 20 */
569 sb_irqstatus = snd_sbmixer_read(chip, SB_DSP4_IRQSTATUS);
407 spin_unlock(&chip->mixer_lock); 570 spin_unlock(&chip->mixer_lock);
408 571
409 if (sb_status & SB_IRQTYPE_8BIT) 572 if (sb_irqstatus & SB_IRQTYPE_8BIT)
410 snd_sb_ack_8bit(chip); 573 snd_sb_ack_8bit(chip);
411 if (sb_status & SB_IRQTYPE_16BIT) 574 if (sb_irqstatus & SB_IRQTYPE_16BIT)
412 snd_sb_ack_16bit(chip); 575 snd_sb_ack_16bit(chip);
413 if (sb_status & SB_IRQTYPE_MPUIN) 576 if (sb_irqstatus & SB_IRQTYPE_MPUIN)
414 inb(chip->mpu_port); 577 inb(chip->mpu_port);
415 if (sb_status & 0x20) 578 if (sb_irqstatus & ALS4K_IRQTYPE_CR1E_DMA)
416 inb(SBP(chip, RESET)); 579 snd_als4k_iobase_readb(chip->alt_port,
417 return IRQ_HANDLED; 580 ALS4K_IOB_16_ACK_FOR_CR1E);
581
582 /* printk(KERN_INFO "als4000: irq 0x%04x 0x%04x\n",
583 pci_irqstatus, sb_irqstatus); */
584
585 /* only ack the things we actually handled above */
586 return IRQ_RETVAL(
587 (pci_irqstatus & (ALS4K_IOB_0E_SB_DMA_IRQ|ALS4K_IOB_0E_CR1E_IRQ|
588 ALS4K_IOB_0E_MPU_IRQ))
589 || (sb_irqstatus & (SB_IRQTYPE_8BIT|SB_IRQTYPE_16BIT|
590 SB_IRQTYPE_MPUIN|ALS4K_IRQTYPE_CR1E_DMA))
591 );
418} 592}
419 593
420/*****************************************************************/ 594/*****************************************************************/
@@ -526,7 +700,8 @@ static int __devinit snd_als4000_pcm(struct snd_sb *chip, int device)
526 struct snd_pcm *pcm; 700 struct snd_pcm *pcm;
527 int err; 701 int err;
528 702
529 if ((err = snd_pcm_new(chip->card, "ALS4000 DSP", device, 1, 1, &pcm)) < 0) 703 err = snd_pcm_new(chip->card, "ALS4000 DSP", device, 1, 1, &pcm);
704 if (err < 0)
530 return err; 705 return err;
531 pcm->private_data = chip; 706 pcm->private_data = chip;
532 pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX; 707 pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
@@ -543,48 +718,55 @@ static int __devinit snd_als4000_pcm(struct snd_sb *chip, int device)
543 718
544/******************************************************************/ 719/******************************************************************/
545 720
546static void snd_als4000_set_addr(unsigned long gcr, 721static void snd_als4000_set_addr(unsigned long iobase,
547 unsigned int sb, 722 unsigned int sb_io,
548 unsigned int mpu, 723 unsigned int mpu_io,
549 unsigned int opl, 724 unsigned int opl_io,
550 unsigned int game) 725 unsigned int game_io)
551{ 726{
552 u32 confA = 0; 727 u32 cfg1 = 0;
553 u32 confB = 0; 728 u32 cfg2 = 0;
554 729
555 if (mpu > 0) 730 if (mpu_io > 0)
556 confB |= (mpu | 1) << 16; 731 cfg2 |= (mpu_io | 1) << 16;
557 if (sb > 0) 732 if (sb_io > 0)
558 confB |= (sb | 1); 733 cfg2 |= (sb_io | 1);
559 if (game > 0) 734 if (game_io > 0)
560 confA |= (game | 1) << 16; 735 cfg1 |= (game_io | 1) << 16;
561 if (opl > 0) 736 if (opl_io > 0)
562 confA |= (opl | 1); 737 cfg1 |= (opl_io | 1);
563 snd_als4000_gcr_write_addr(gcr, 0xa8, confA); 738 snd_als4k_gcr_write_addr(iobase, ALS4K_GCRA8_LEGACY_CFG1, cfg1);
564 snd_als4000_gcr_write_addr(gcr, 0xa9, confB); 739 snd_als4k_gcr_write_addr(iobase, ALS4K_GCRA9_LEGACY_CFG2, cfg2);
565} 740}
566 741
567static void snd_als4000_configure(struct snd_sb *chip) 742static void snd_als4000_configure(struct snd_sb *chip)
568{ 743{
569 unsigned tmp; 744 u8 tmp;
570 int i; 745 int i;
571 746
572 /* do some more configuration */ 747 /* do some more configuration */
573 spin_lock_irq(&chip->mixer_lock); 748 spin_lock_irq(&chip->mixer_lock);
574 tmp = snd_sbmixer_read(chip, 0xc0); 749 tmp = snd_als4_cr_read(chip, ALS4K_CR0_SB_CONFIG);
575 snd_sbmixer_write(chip, 0xc0, tmp|0x80); 750 snd_als4_cr_write(chip, ALS4K_CR0_SB_CONFIG,
576 /* always select DMA channel 0, since we do not actually use DMA */ 751 tmp|ALS4K_CR0_MX80_81_REG_WRITE_ENABLE);
752 /* always select DMA channel 0, since we do not actually use DMA
753 * SPECS_PAGE: 19/20 */
577 snd_sbmixer_write(chip, SB_DSP4_DMASETUP, SB_DMASETUP_DMA0); 754 snd_sbmixer_write(chip, SB_DSP4_DMASETUP, SB_DMASETUP_DMA0);
578 snd_sbmixer_write(chip, 0xc0, tmp&0x7f); 755 snd_als4_cr_write(chip, ALS4K_CR0_SB_CONFIG,
756 tmp & ~ALS4K_CR0_MX80_81_REG_WRITE_ENABLE);
579 spin_unlock_irq(&chip->mixer_lock); 757 spin_unlock_irq(&chip->mixer_lock);
580 758
581 spin_lock_irq(&chip->reg_lock); 759 spin_lock_irq(&chip->reg_lock);
582 /* magic number. Enables interrupts(?) */ 760 /* enable interrupts */
583 snd_als4000_gcr_write(chip, 0x8c, 0x28000); 761 snd_als4k_gcr_write(chip, ALS4K_GCR8C_MISC_CTRL,
584 for(i = 0x91; i <= 0x96; ++i) 762 ALS4K_GCR8C_IRQ_MASK_CTRL_ENABLE);
585 snd_als4000_gcr_write(chip, i, 0); 763
764 /* SPECS_PAGE: 39 */
765 for (i = ALS4K_GCR91_DMA0_ADDR; i <= ALS4K_GCR96_DMA3_MODE_COUNT; ++i)
766 snd_als4k_gcr_write(chip, i, 0);
586 767
587 snd_als4000_gcr_write(chip, 0x99, snd_als4000_gcr_read(chip, 0x99)); 768 snd_als4k_gcr_write(chip, ALS4K_GCR99_DMA_EMULATION_CTRL,
769 snd_als4k_gcr_read(chip, ALS4K_GCR99_DMA_EMULATION_CTRL));
588 spin_unlock_irq(&chip->reg_lock); 770 spin_unlock_irq(&chip->reg_lock);
589} 771}
590 772
@@ -628,7 +810,7 @@ static int __devinit snd_als4000_create_gameport(struct snd_card_als4000 *acard,
628 gameport_set_port_data(gp, r); 810 gameport_set_port_data(gp, r);
629 811
630 /* Enable legacy joystick port */ 812 /* Enable legacy joystick port */
631 snd_als4000_set_addr(acard->gcr, 0, 0, 0, 1); 813 snd_als4000_set_addr(acard->iobase, 0, 0, 0, 1);
632 814
633 gameport_register_port(acard->gameport); 815 gameport_register_port(acard->gameport);
634 816
@@ -643,7 +825,9 @@ static void snd_als4000_free_gameport(struct snd_card_als4000 *acard)
643 gameport_unregister_port(acard->gameport); 825 gameport_unregister_port(acard->gameport);
644 acard->gameport = NULL; 826 acard->gameport = NULL;
645 827
646 snd_als4000_set_addr(acard->gcr, 0, 0, 0, 0); /* disable joystick */ 828 /* disable joystick */
829 snd_als4000_set_addr(acard->iobase, 0, 0, 0, 0);
830
647 release_and_free_resource(r); 831 release_and_free_resource(r);
648 } 832 }
649} 833}
@@ -654,10 +838,10 @@ static inline void snd_als4000_free_gameport(struct snd_card_als4000 *acard) { }
654 838
655static void snd_card_als4000_free( struct snd_card *card ) 839static void snd_card_als4000_free( struct snd_card *card )
656{ 840{
657 struct snd_card_als4000 * acard = (struct snd_card_als4000 *)card->private_data; 841 struct snd_card_als4000 *acard = card->private_data;
658 842
659 /* make sure that interrupts are disabled */ 843 /* make sure that interrupts are disabled */
660 snd_als4000_gcr_write_addr( acard->gcr, 0x8c, 0); 844 snd_als4k_gcr_write_addr(acard->iobase, ALS4K_GCR8C_MISC_CTRL, 0);
661 /* free resources */ 845 /* free resources */
662 snd_als4000_free_gameport(acard); 846 snd_als4000_free_gameport(acard);
663 pci_release_regions(acard->pci); 847 pci_release_regions(acard->pci);
@@ -670,7 +854,7 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci,
670 static int dev; 854 static int dev;
671 struct snd_card *card; 855 struct snd_card *card;
672 struct snd_card_als4000 *acard; 856 struct snd_card_als4000 *acard;
673 unsigned long gcr; 857 unsigned long iobase;
674 struct snd_sb *chip; 858 struct snd_sb *chip;
675 struct snd_opl3 *opl3; 859 struct snd_opl3 *opl3;
676 unsigned short word; 860 unsigned short word;
@@ -699,31 +883,32 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci,
699 pci_disable_device(pci); 883 pci_disable_device(pci);
700 return err; 884 return err;
701 } 885 }
702 gcr = pci_resource_start(pci, 0); 886 iobase = pci_resource_start(pci, 0);
703 887
704 pci_read_config_word(pci, PCI_COMMAND, &word); 888 pci_read_config_word(pci, PCI_COMMAND, &word);
705 pci_write_config_word(pci, PCI_COMMAND, word | PCI_COMMAND_IO); 889 pci_write_config_word(pci, PCI_COMMAND, word | PCI_COMMAND_IO);
706 pci_set_master(pci); 890 pci_set_master(pci);
707 891
708 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 892 card = snd_card_new(index[dev], id[dev], THIS_MODULE,
709 sizeof( struct snd_card_als4000 ) ); 893 sizeof(*acard) /* private_data: acard */);
710 if (card == NULL) { 894 if (card == NULL) {
711 pci_release_regions(pci); 895 pci_release_regions(pci);
712 pci_disable_device(pci); 896 pci_disable_device(pci);
713 return -ENOMEM; 897 return -ENOMEM;
714 } 898 }
715 899
716 acard = (struct snd_card_als4000 *)card->private_data; 900 acard = card->private_data;
717 acard->pci = pci; 901 acard->pci = pci;
718 acard->gcr = gcr; 902 acard->iobase = iobase;
719 card->private_free = snd_card_als4000_free; 903 card->private_free = snd_card_als4000_free;
720 904
721 /* disable all legacy ISA stuff */ 905 /* disable all legacy ISA stuff */
722 snd_als4000_set_addr(acard->gcr, 0, 0, 0, 0); 906 snd_als4000_set_addr(acard->iobase, 0, 0, 0, 0);
723 907
724 if ((err = snd_sbdsp_create(card, 908 if ((err = snd_sbdsp_create(card,
725 gcr + 0x10, 909 iobase + ALS4K_IOB_10_ADLIB_ADDR0,
726 pci->irq, 910 pci->irq,
911 /* internally registered as IRQF_SHARED in case of ALS4000 SB */
727 snd_als4000_interrupt, 912 snd_als4000_interrupt,
728 -1, 913 -1,
729 -1, 914 -1,
@@ -734,7 +919,7 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci,
734 acard->chip = chip; 919 acard->chip = chip;
735 920
736 chip->pci = pci; 921 chip->pci = pci;
737 chip->alt_port = gcr; 922 chip->alt_port = iobase;
738 snd_card_set_dev(card, &pci->dev); 923 snd_card_set_dev(card, &pci->dev);
739 924
740 snd_als4000_configure(chip); 925 snd_als4000_configure(chip);
@@ -745,11 +930,18 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci,
745 card->shortname, chip->alt_port, chip->irq); 930 card->shortname, chip->alt_port, chip->irq);
746 931
747 if ((err = snd_mpu401_uart_new( card, 0, MPU401_HW_ALS4000, 932 if ((err = snd_mpu401_uart_new( card, 0, MPU401_HW_ALS4000,
748 gcr+0x30, MPU401_INFO_INTEGRATED, 933 iobase + ALS4K_IOB_30_MIDI_DATA,
934 MPU401_INFO_INTEGRATED,
749 pci->irq, 0, &chip->rmidi)) < 0) { 935 pci->irq, 0, &chip->rmidi)) < 0) {
750 printk(KERN_ERR "als4000: no MPU-401 device at 0x%lx?\n", gcr+0x30); 936 printk(KERN_ERR "als4000: no MPU-401 device at 0x%lx?\n",
937 iobase + ALS4K_IOB_30_MIDI_DATA);
751 goto out_err; 938 goto out_err;
752 } 939 }
940 /* FIXME: ALS4000 has interesting MPU401 configuration features
941 * at ALS4K_CR1A_MPU401_UART_MODE_CONTROL
942 * (pass-thru / UART switching, fast MIDI clock, etc.),
943 * however there doesn't seem to be an ALSA API for this...
944 * SPECS_PAGE: 21 */
753 945
754 if ((err = snd_als4000_pcm(chip, 0)) < 0) { 946 if ((err = snd_als4000_pcm(chip, 0)) < 0) {
755 goto out_err; 947 goto out_err;
@@ -758,10 +950,13 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci,
758 goto out_err; 950 goto out_err;
759 } 951 }
760 952
761 if (snd_opl3_create(card, gcr+0x10, gcr+0x12, 953 if (snd_opl3_create(card,
954 iobase + ALS4K_IOB_10_ADLIB_ADDR0,
955 iobase + ALS4K_IOB_12_ADLIB_ADDR2,
762 OPL3_HW_AUTO, 1, &opl3) < 0) { 956 OPL3_HW_AUTO, 1, &opl3) < 0) {
763 printk(KERN_ERR "als4000: no OPL device at 0x%lx-0x%lx?\n", 957 printk(KERN_ERR "als4000: no OPL device at 0x%lx-0x%lx?\n",
764 gcr+0x10, gcr+0x12 ); 958 iobase + ALS4K_IOB_10_ADLIB_ADDR0,
959 iobase + ALS4K_IOB_12_ADLIB_ADDR2);
765 } else { 960 } else {
766 if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) { 961 if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
767 goto out_err; 962 goto out_err;
@@ -831,13 +1026,13 @@ static int snd_als4000_resume(struct pci_dev *pci)
831 1026
832#ifdef SUPPORT_JOYSTICK 1027#ifdef SUPPORT_JOYSTICK
833 if (acard->gameport) 1028 if (acard->gameport)
834 snd_als4000_set_addr(acard->gcr, 0, 0, 0, 1); 1029 snd_als4000_set_addr(acard->iobase, 0, 0, 0, 1);
835#endif 1030#endif
836 1031
837 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 1032 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
838 return 0; 1033 return 0;
839} 1034}
840#endif 1035#endif /* CONFIG_PM */
841 1036
842 1037
843static struct pci_driver driver = { 1038static struct pci_driver driver = {
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c
index 457228fb22aa..085a52b8c807 100644
--- a/sound/pci/atiixp.c
+++ b/sound/pci/atiixp.c
@@ -37,7 +37,7 @@
37MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>"); 37MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
38MODULE_DESCRIPTION("ATI IXP AC97 controller"); 38MODULE_DESCRIPTION("ATI IXP AC97 controller");
39MODULE_LICENSE("GPL"); 39MODULE_LICENSE("GPL");
40MODULE_SUPPORTED_DEVICE("{{ATI,IXP150/200/250/300/400}}"); 40MODULE_SUPPORTED_DEVICE("{{ATI,IXP150/200/250/300/400/600}}");
41 41
42static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */ 42static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
43static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ 43static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
@@ -290,6 +290,7 @@ static struct pci_device_id snd_atiixp_ids[] = {
290 { 0x1002, 0x4341, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SB200 */ 290 { 0x1002, 0x4341, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SB200 */
291 { 0x1002, 0x4361, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SB300 */ 291 { 0x1002, 0x4361, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SB300 */
292 { 0x1002, 0x4370, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SB400 */ 292 { 0x1002, 0x4370, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SB400 */
293 { 0x1002, 0x4382, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SB600 */
293 { 0, } 294 { 0, }
294}; 295};
295 296
@@ -722,7 +723,9 @@ static int snd_atiixp_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
722 struct atiixp_dma *dma = substream->runtime->private_data; 723 struct atiixp_dma *dma = substream->runtime->private_data;
723 int err = 0; 724 int err = 0;
724 725
725 snd_assert(dma->ops->enable_transfer && dma->ops->flush_dma, return -EINVAL); 726 if (snd_BUG_ON(!dma->ops->enable_transfer ||
727 !dma->ops->flush_dma))
728 return -EINVAL;
726 729
727 spin_lock(&chip->reg_lock); 730 spin_lock(&chip->reg_lock);
728 switch (cmd) { 731 switch (cmd) {
@@ -1032,7 +1035,8 @@ static int snd_atiixp_pcm_open(struct snd_pcm_substream *substream,
1032 struct snd_pcm_runtime *runtime = substream->runtime; 1035 struct snd_pcm_runtime *runtime = substream->runtime;
1033 int err; 1036 int err;
1034 1037
1035 snd_assert(dma->ops && dma->ops->enable_dma, return -EINVAL); 1038 if (snd_BUG_ON(!dma->ops || !dma->ops->enable_dma))
1039 return -EINVAL;
1036 1040
1037 if (dma->opened) 1041 if (dma->opened)
1038 return -EBUSY; 1042 return -EBUSY;
@@ -1064,7 +1068,8 @@ static int snd_atiixp_pcm_close(struct snd_pcm_substream *substream,
1064{ 1068{
1065 struct atiixp *chip = snd_pcm_substream_chip(substream); 1069 struct atiixp *chip = snd_pcm_substream_chip(substream);
1066 /* disable DMA bits */ 1070 /* disable DMA bits */
1067 snd_assert(dma->ops && dma->ops->enable_dma, return -EINVAL); 1071 if (snd_BUG_ON(!dma->ops || !dma->ops->enable_dma))
1072 return -EINVAL;
1068 spin_lock_irq(&chip->reg_lock); 1073 spin_lock_irq(&chip->reg_lock);
1069 dma->ops->enable_dma(chip, 0); 1074 dma->ops->enable_dma(chip, 0);
1070 spin_unlock_irq(&chip->reg_lock); 1075 spin_unlock_irq(&chip->reg_lock);
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c
index d457a32a7939..2f106306c7fe 100644
--- a/sound/pci/atiixp_modem.c
+++ b/sound/pci/atiixp_modem.c
@@ -674,7 +674,9 @@ static int snd_atiixp_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
674 struct atiixp_dma *dma = substream->runtime->private_data; 674 struct atiixp_dma *dma = substream->runtime->private_data;
675 int err = 0; 675 int err = 0;
676 676
677 snd_assert(dma->ops->enable_transfer && dma->ops->flush_dma, return -EINVAL); 677 if (snd_BUG_ON(!dma->ops->enable_transfer ||
678 !dma->ops->flush_dma))
679 return -EINVAL;
678 680
679 spin_lock(&chip->reg_lock); 681 spin_lock(&chip->reg_lock);
680 switch(cmd) { 682 switch(cmd) {
@@ -865,7 +867,8 @@ static int snd_atiixp_pcm_open(struct snd_pcm_substream *substream,
865 .mask = 0, 867 .mask = 0,
866 }; 868 };
867 869
868 snd_assert(dma->ops && dma->ops->enable_dma, return -EINVAL); 870 if (snd_BUG_ON(!dma->ops || !dma->ops->enable_dma))
871 return -EINVAL;
869 872
870 if (dma->opened) 873 if (dma->opened)
871 return -EBUSY; 874 return -EBUSY;
@@ -895,7 +898,8 @@ static int snd_atiixp_pcm_close(struct snd_pcm_substream *substream,
895{ 898{
896 struct atiixp_modem *chip = snd_pcm_substream_chip(substream); 899 struct atiixp_modem *chip = snd_pcm_substream_chip(substream);
897 /* disable DMA bits */ 900 /* disable DMA bits */
898 snd_assert(dma->ops && dma->ops->enable_dma, return -EINVAL); 901 if (snd_BUG_ON(!dma->ops || !dma->ops->enable_dma))
902 return -EINVAL;
899 spin_lock_irq(&chip->reg_lock); 903 spin_lock_irq(&chip->reg_lock);
900 dma->ops->enable_dma(chip, 0); 904 dma->ops->enable_dma(chip, 0);
901 spin_unlock_irq(&chip->reg_lock); 905 spin_unlock_irq(&chip->reg_lock);
diff --git a/sound/pci/au88x0/au88x0.h b/sound/pci/au88x0/au88x0.h
index 4aad35bba11a..cf46bba563cf 100644
--- a/sound/pci/au88x0/au88x0.h
+++ b/sound/pci/au88x0/au88x0.h
@@ -125,7 +125,6 @@ typedef struct {
125 /* Virtual page extender stuff */ 125 /* Virtual page extender stuff */
126 int nr_periods; 126 int nr_periods;
127 int period_bytes; 127 int period_bytes;
128 struct snd_sg_buf *sgbuf; /* DMA Scatter Gather struct */
129 int period_real; 128 int period_real;
130 int period_virt; 129 int period_virt;
131 130
@@ -195,16 +194,14 @@ static void vortex_adb_setsrc(vortex_t * vortex, int adbdma,
195 194
196/* DMA Engines. */ 195/* DMA Engines. */
197static void vortex_adbdma_setbuffers(vortex_t * vortex, int adbdma, 196static void vortex_adbdma_setbuffers(vortex_t * vortex, int adbdma,
198 struct snd_sg_buf * sgbuf, int size, 197 int size, int count);
199 int count);
200static void vortex_adbdma_setmode(vortex_t * vortex, int adbdma, int ie, 198static void vortex_adbdma_setmode(vortex_t * vortex, int adbdma, int ie,
201 int dir, int fmt, int d, 199 int dir, int fmt, int d,
202 u32 offset); 200 u32 offset);
203static void vortex_adbdma_setstartbuffer(vortex_t * vortex, int adbdma, int sb); 201static void vortex_adbdma_setstartbuffer(vortex_t * vortex, int adbdma, int sb);
204#ifndef CHIP_AU8810 202#ifndef CHIP_AU8810
205static void vortex_wtdma_setbuffers(vortex_t * vortex, int wtdma, 203static void vortex_wtdma_setbuffers(vortex_t * vortex, int wtdma,
206 struct snd_sg_buf * sgbuf, int size, 204 int size, int count);
207 int count);
208static void vortex_wtdma_setmode(vortex_t * vortex, int wtdma, int ie, int fmt, int d, /*int e, */ 205static void vortex_wtdma_setmode(vortex_t * vortex, int wtdma, int ie, int fmt, int d, /*int e, */
209 u32 offset); 206 u32 offset);
210static void vortex_wtdma_setstartbuffer(vortex_t * vortex, int wtdma, int sb); 207static void vortex_wtdma_setstartbuffer(vortex_t * vortex, int wtdma, int sb);
diff --git a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c
index 333c62de8620..b070e5714514 100644
--- a/sound/pci/au88x0/au88x0_core.c
+++ b/sound/pci/au88x0/au88x0_core.c
@@ -427,7 +427,7 @@ static void vortex_mixer_init(vortex_t * vortex)
427 427
428 /* Set clipping ceiling (this may be all wrong). */ 428 /* Set clipping ceiling (this may be all wrong). */
429 /* 429 /*
430 for (x = 0; x > 0x80; x++) { 430 for (x = 0; x < 0x80; x++) {
431 hwwrite(vortex->mmio, VORTEX_MIXER_CLIP + (x << 2), 0x3ffff); 431 hwwrite(vortex->mmio, VORTEX_MIXER_CLIP + (x << 2), 0x3ffff);
432 } 432 }
433 */ 433 */
@@ -1097,19 +1097,12 @@ static void vortex_adbdma_setstartbuffer(vortex_t * vortex, int adbdma, int sb)
1097 1097
1098static void 1098static void
1099vortex_adbdma_setbuffers(vortex_t * vortex, int adbdma, 1099vortex_adbdma_setbuffers(vortex_t * vortex, int adbdma,
1100 struct snd_sg_buf * sgbuf, int psize, int count) 1100 int psize, int count)
1101{ 1101{
1102 stream_t *dma = &vortex->dma_adb[adbdma]; 1102 stream_t *dma = &vortex->dma_adb[adbdma];
1103 1103
1104 if (sgbuf == NULL) {
1105 printk(KERN_INFO "vortex: FATAL: sgbuf is NULL!\n");
1106 return;
1107 }
1108 //printk(KERN_INFO "vortex: page count = %d, tblcount = %d\n", count, sgbuf->tblsize);
1109
1110 dma->period_bytes = psize; 1104 dma->period_bytes = psize;
1111 dma->nr_periods = count; 1105 dma->nr_periods = count;
1112 dma->sgbuf = sgbuf;
1113 1106
1114 dma->cfg0 = 0; 1107 dma->cfg0 = 0;
1115 dma->cfg1 = 0; 1108 dma->cfg1 = 0;
@@ -1120,26 +1113,26 @@ vortex_adbdma_setbuffers(vortex_t * vortex, int adbdma,
1120 dma->cfg1 |= 0x88000000 | 0x44000000 | 0x30000000 | (psize - 1); 1113 dma->cfg1 |= 0x88000000 | 0x44000000 | 0x30000000 | (psize - 1);
1121 hwwrite(vortex->mmio, 1114 hwwrite(vortex->mmio,
1122 VORTEX_ADBDMA_BUFBASE + (adbdma << 4) + 0xc, 1115 VORTEX_ADBDMA_BUFBASE + (adbdma << 4) + 0xc,
1123 snd_sgbuf_get_addr(sgbuf, psize * 3)); 1116 snd_pcm_sgbuf_get_addr(dma->substream, psize * 3));
1124 /* 3 pages */ 1117 /* 3 pages */
1125 case 3: 1118 case 3:
1126 dma->cfg0 |= 0x12000000; 1119 dma->cfg0 |= 0x12000000;
1127 dma->cfg1 |= 0x80000000 | 0x40000000 | ((psize - 1) << 0xc); 1120 dma->cfg1 |= 0x80000000 | 0x40000000 | ((psize - 1) << 0xc);
1128 hwwrite(vortex->mmio, 1121 hwwrite(vortex->mmio,
1129 VORTEX_ADBDMA_BUFBASE + (adbdma << 4) + 0x8, 1122 VORTEX_ADBDMA_BUFBASE + (adbdma << 4) + 0x8,
1130 snd_sgbuf_get_addr(sgbuf, psize * 2)); 1123 snd_pcm_sgbuf_get_addr(dma->substream, psize * 2));
1131 /* 2 pages */ 1124 /* 2 pages */
1132 case 2: 1125 case 2:
1133 dma->cfg0 |= 0x88000000 | 0x44000000 | 0x10000000 | (psize - 1); 1126 dma->cfg0 |= 0x88000000 | 0x44000000 | 0x10000000 | (psize - 1);
1134 hwwrite(vortex->mmio, 1127 hwwrite(vortex->mmio,
1135 VORTEX_ADBDMA_BUFBASE + (adbdma << 4) + 0x4, 1128 VORTEX_ADBDMA_BUFBASE + (adbdma << 4) + 0x4,
1136 snd_sgbuf_get_addr(sgbuf, psize)); 1129 snd_pcm_sgbuf_get_addr(dma->substream, psize));
1137 /* 1 page */ 1130 /* 1 page */
1138 case 1: 1131 case 1:
1139 dma->cfg0 |= 0x80000000 | 0x40000000 | ((psize - 1) << 0xc); 1132 dma->cfg0 |= 0x80000000 | 0x40000000 | ((psize - 1) << 0xc);
1140 hwwrite(vortex->mmio, 1133 hwwrite(vortex->mmio,
1141 VORTEX_ADBDMA_BUFBASE + (adbdma << 4), 1134 VORTEX_ADBDMA_BUFBASE + (adbdma << 4),
1142 snd_sgbuf_get_addr(sgbuf, 0)); 1135 snd_pcm_sgbuf_get_addr(dma->substream, 0));
1143 break; 1136 break;
1144 } 1137 }
1145 //printk("vortex: cfg0 = 0x%x\nvortex: cfg1=0x%x\n", dma->cfg0, dma->cfg1); 1138 //printk("vortex: cfg0 = 0x%x\nvortex: cfg1=0x%x\n", dma->cfg0, dma->cfg1);
@@ -1205,7 +1198,7 @@ static int vortex_adbdma_bufshift(vortex_t * vortex, int adbdma)
1205 //hwwrite(vortex->mmio, VORTEX_ADBDMA_BUFBASE+(((adbdma << 2)+pp) << 2), dma->table[p].addr); 1198 //hwwrite(vortex->mmio, VORTEX_ADBDMA_BUFBASE+(((adbdma << 2)+pp) << 2), dma->table[p].addr);
1206 hwwrite(vortex->mmio, 1199 hwwrite(vortex->mmio,
1207 VORTEX_ADBDMA_BUFBASE + (((adbdma << 2) + pp) << 2), 1200 VORTEX_ADBDMA_BUFBASE + (((adbdma << 2) + pp) << 2),
1208 snd_sgbuf_get_addr(dma->sgbuf, 1201 snd_pcm_sgbuf_get_addr(dma->substream,
1209 dma->period_bytes * p)); 1202 dma->period_bytes * p));
1210 /* Force write thru cache. */ 1203 /* Force write thru cache. */
1211 hwread(vortex->mmio, VORTEX_ADBDMA_BUFBASE + 1204 hwread(vortex->mmio, VORTEX_ADBDMA_BUFBASE +
@@ -1244,7 +1237,10 @@ static void vortex_adbdma_resetup(vortex_t *vortex, int adbdma) {
1244 if (pp >= 4) 1237 if (pp >= 4)
1245 pp -= 4; 1238 pp -= 4;
1246 } 1239 }
1247 hwwrite(vortex->mmio, VORTEX_ADBDMA_BUFBASE+(((adbdma << 2)+pp) << 2), snd_sgbuf_get_addr(dma->sgbuf, dma->period_bytes * p)); 1240 hwwrite(vortex->mmio,
1241 VORTEX_ADBDMA_BUFBASE + (((adbdma << 2) + pp) << 2),
1242 snd_pcm_sgbuf_get_addr(dma->substream,
1243 dma->period_bytes * p));
1248 /* Force write thru cache. */ 1244 /* Force write thru cache. */
1249 hwread(vortex->mmio, VORTEX_ADBDMA_BUFBASE + (((adbdma << 2)+pp) << 2)); 1245 hwread(vortex->mmio, VORTEX_ADBDMA_BUFBASE + (((adbdma << 2)+pp) << 2));
1250 } 1246 }
@@ -1367,13 +1363,12 @@ static void vortex_wtdma_setstartbuffer(vortex_t * vortex, int wtdma, int sb)
1367 1363
1368static void 1364static void
1369vortex_wtdma_setbuffers(vortex_t * vortex, int wtdma, 1365vortex_wtdma_setbuffers(vortex_t * vortex, int wtdma,
1370 struct snd_sg_buf * sgbuf, int psize, int count) 1366 int psize, int count)
1371{ 1367{
1372 stream_t *dma = &vortex->dma_wt[wtdma]; 1368 stream_t *dma = &vortex->dma_wt[wtdma];
1373 1369
1374 dma->period_bytes = psize; 1370 dma->period_bytes = psize;
1375 dma->nr_periods = count; 1371 dma->nr_periods = count;
1376 dma->sgbuf = sgbuf;
1377 1372
1378 dma->cfg0 = 0; 1373 dma->cfg0 = 0;
1379 dma->cfg1 = 0; 1374 dma->cfg1 = 0;
@@ -1383,23 +1378,23 @@ vortex_wtdma_setbuffers(vortex_t * vortex, int wtdma,
1383 case 4: 1378 case 4:
1384 dma->cfg1 |= 0x88000000 | 0x44000000 | 0x30000000 | (psize-1); 1379 dma->cfg1 |= 0x88000000 | 0x44000000 | 0x30000000 | (psize-1);
1385 hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4) + 0xc, 1380 hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4) + 0xc,
1386 snd_sgbuf_get_addr(sgbuf, psize * 3)); 1381 snd_pcm_sgbuf_get_addr(dma->substream, psize * 3));
1387 /* 3 pages */ 1382 /* 3 pages */
1388 case 3: 1383 case 3:
1389 dma->cfg0 |= 0x12000000; 1384 dma->cfg0 |= 0x12000000;
1390 dma->cfg1 |= 0x80000000 | 0x40000000 | ((psize-1) << 0xc); 1385 dma->cfg1 |= 0x80000000 | 0x40000000 | ((psize-1) << 0xc);
1391 hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4) + 0x8, 1386 hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4) + 0x8,
1392 snd_sgbuf_get_addr(sgbuf, psize * 2)); 1387 snd_pcm_sgbuf_get_addr(dma->substream, psize * 2));
1393 /* 2 pages */ 1388 /* 2 pages */
1394 case 2: 1389 case 2:
1395 dma->cfg0 |= 0x88000000 | 0x44000000 | 0x10000000 | (psize-1); 1390 dma->cfg0 |= 0x88000000 | 0x44000000 | 0x10000000 | (psize-1);
1396 hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4) + 0x4, 1391 hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4) + 0x4,
1397 snd_sgbuf_get_addr(sgbuf, psize)); 1392 snd_pcm_sgbuf_get_addr(dma->substream, psize));
1398 /* 1 page */ 1393 /* 1 page */
1399 case 1: 1394 case 1:
1400 dma->cfg0 |= 0x80000000 | 0x40000000 | ((psize-1) << 0xc); 1395 dma->cfg0 |= 0x80000000 | 0x40000000 | ((psize-1) << 0xc);
1401 hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4), 1396 hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4),
1402 snd_sgbuf_get_addr(sgbuf, 0)); 1397 snd_pcm_sgbuf_get_addr(dma->substream, 0));
1403 break; 1398 break;
1404 } 1399 }
1405 hwwrite(vortex->mmio, VORTEX_WTDMA_BUFCFG0 + (wtdma << 3), dma->cfg0); 1400 hwwrite(vortex->mmio, VORTEX_WTDMA_BUFCFG0 + (wtdma << 3), dma->cfg0);
@@ -1465,7 +1460,8 @@ static int vortex_wtdma_bufshift(vortex_t * vortex, int wtdma)
1465 hwwrite(vortex->mmio, 1460 hwwrite(vortex->mmio,
1466 VORTEX_WTDMA_BUFBASE + 1461 VORTEX_WTDMA_BUFBASE +
1467 (((wtdma << 2) + pp) << 2), 1462 (((wtdma << 2) + pp) << 2),
1468 snd_sgbuf_get_addr(dma->sgbuf, dma->period_bytes * p)); 1463 snd_pcm_sgbuf_get_addr(dma->substream,
1464 dma->period_bytes * p));
1469 /* Force write thru cache. */ 1465 /* Force write thru cache. */
1470 hwread(vortex->mmio, VORTEX_WTDMA_BUFBASE + 1466 hwread(vortex->mmio, VORTEX_WTDMA_BUFBASE +
1471 (((wtdma << 2) + pp) << 2)); 1467 (((wtdma << 2) + pp) << 2));
diff --git a/sound/pci/au88x0/au88x0_pcm.c b/sound/pci/au88x0/au88x0_pcm.c
index f9a58b4a30eb..b9d2f202cf9b 100644
--- a/sound/pci/au88x0/au88x0_pcm.c
+++ b/sound/pci/au88x0/au88x0_pcm.c
@@ -189,7 +189,6 @@ snd_vortex_pcm_hw_params(struct snd_pcm_substream *substream,
189{ 189{
190 vortex_t *chip = snd_pcm_substream_chip(substream); 190 vortex_t *chip = snd_pcm_substream_chip(substream);
191 stream_t *stream = (stream_t *) (substream->runtime->private_data); 191 stream_t *stream = (stream_t *) (substream->runtime->private_data);
192 struct snd_sg_buf *sgbuf;
193 int err; 192 int err;
194 193
195 // Alloc buffer memory. 194 // Alloc buffer memory.
@@ -199,8 +198,6 @@ snd_vortex_pcm_hw_params(struct snd_pcm_substream *substream,
199 printk(KERN_ERR "Vortex: pcm page alloc failed!\n"); 198 printk(KERN_ERR "Vortex: pcm page alloc failed!\n");
200 return err; 199 return err;
201 } 200 }
202 //sgbuf = (struct snd_sg_buf *) substream->runtime->dma_private;
203 sgbuf = snd_pcm_substream_sgbuf(substream);
204 /* 201 /*
205 printk(KERN_INFO "Vortex: periods %d, period_bytes %d, channels = %d\n", params_periods(hw_params), 202 printk(KERN_INFO "Vortex: periods %d, period_bytes %d, channels = %d\n", params_periods(hw_params),
206 params_period_bytes(hw_params), params_channels(hw_params)); 203 params_period_bytes(hw_params), params_channels(hw_params));
@@ -226,7 +223,7 @@ snd_vortex_pcm_hw_params(struct snd_pcm_substream *substream,
226 stream = substream->runtime->private_data = &chip->dma_adb[dma]; 223 stream = substream->runtime->private_data = &chip->dma_adb[dma];
227 stream->substream = substream; 224 stream->substream = substream;
228 /* Setup Buffers. */ 225 /* Setup Buffers. */
229 vortex_adbdma_setbuffers(chip, dma, sgbuf, 226 vortex_adbdma_setbuffers(chip, dma,
230 params_period_bytes(hw_params), 227 params_period_bytes(hw_params),
231 params_periods(hw_params)); 228 params_periods(hw_params));
232 } 229 }
@@ -240,7 +237,7 @@ snd_vortex_pcm_hw_params(struct snd_pcm_substream *substream,
240 &chip->dma_wt[substream->number]; 237 &chip->dma_wt[substream->number];
241 stream->dma = substream->number; 238 stream->dma = substream->number;
242 stream->substream = substream; 239 stream->substream = substream;
243 vortex_wtdma_setbuffers(chip, substream->number, sgbuf, 240 vortex_wtdma_setbuffers(chip, substream->number,
244 params_period_bytes(hw_params), 241 params_period_bytes(hw_params),
245 params_periods(hw_params)); 242 params_periods(hw_params));
246 } 243 }
@@ -392,13 +389,6 @@ static snd_pcm_uframes_t snd_vortex_pcm_pointer(struct snd_pcm_substream *substr
392 return (bytes_to_frames(substream->runtime, current_ptr)); 389 return (bytes_to_frames(substream->runtime, current_ptr));
393} 390}
394 391
395/* Page callback. */
396/*
397static struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream, unsigned long offset) {
398
399
400}
401*/
402/* operators */ 392/* operators */
403static struct snd_pcm_ops snd_vortex_playback_ops = { 393static struct snd_pcm_ops snd_vortex_playback_ops = {
404 .open = snd_vortex_pcm_open, 394 .open = snd_vortex_pcm_open,
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index 22f18f3cfbc9..333007c523a1 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -816,7 +816,8 @@ snd_azf3328_mixer_new(struct snd_azf3328 *chip)
816 int err; 816 int err;
817 817
818 snd_azf3328_dbgcallenter(); 818 snd_azf3328_dbgcallenter();
819 snd_assert(chip != NULL && chip->card != NULL, return -EINVAL); 819 if (snd_BUG_ON(!chip || !chip->card))
820 return -EINVAL;
820 821
821 card = chip->card; 822 card = chip->card;
822 823
@@ -1471,7 +1472,8 @@ snd_azf3328_gameport_cooked_read(struct gameport *gameport,
1471 u8 val; 1472 u8 val;
1472 unsigned long flags; 1473 unsigned long flags;
1473 1474
1474 snd_assert(chip, return 0); 1475 if (snd_BUG_ON(!chip))
1476 return 0;
1475 1477
1476 spin_lock_irqsave(&chip->reg_lock, flags); 1478 spin_lock_irqsave(&chip->reg_lock, flags);
1477 val = snd_azf3328_game_inb(chip, IDX_GAME_LEGACY_COMPATIBLE); 1479 val = snd_azf3328_game_inb(chip, IDX_GAME_LEGACY_COMPATIBLE);
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c
index 4ecdd635ed1d..3aa8d973540a 100644
--- a/sound/pci/bt87x.c
+++ b/sound/pci/bt87x.c
@@ -227,7 +227,6 @@ static inline void snd_bt87x_writel(struct snd_bt87x *chip, u32 reg, u32 value)
227static int snd_bt87x_create_risc(struct snd_bt87x *chip, struct snd_pcm_substream *substream, 227static int snd_bt87x_create_risc(struct snd_bt87x *chip, struct snd_pcm_substream *substream,
228 unsigned int periods, unsigned int period_bytes) 228 unsigned int periods, unsigned int period_bytes)
229{ 229{
230 struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream);
231 unsigned int i, offset; 230 unsigned int i, offset;
232 u32 *risc; 231 u32 *risc;
233 232
@@ -246,6 +245,7 @@ static int snd_bt87x_create_risc(struct snd_bt87x *chip, struct snd_pcm_substrea
246 rest = period_bytes; 245 rest = period_bytes;
247 do { 246 do {
248 u32 cmd, len; 247 u32 cmd, len;
248 unsigned int addr;
249 249
250 len = PAGE_SIZE - (offset % PAGE_SIZE); 250 len = PAGE_SIZE - (offset % PAGE_SIZE);
251 if (len > rest) 251 if (len > rest)
@@ -260,7 +260,8 @@ static int snd_bt87x_create_risc(struct snd_bt87x *chip, struct snd_pcm_substrea
260 if (len == rest) 260 if (len == rest)
261 cmd |= RISC_EOL | RISC_IRQ; 261 cmd |= RISC_EOL | RISC_IRQ;
262 *risc++ = cpu_to_le32(cmd); 262 *risc++ = cpu_to_le32(cmd);
263 *risc++ = cpu_to_le32((u32)snd_pcm_sgbuf_get_addr(sgbuf, offset)); 263 addr = snd_pcm_sgbuf_get_addr(substream, offset);
264 *risc++ = cpu_to_le32(addr);
264 offset += len; 265 offset += len;
265 rest -= len; 266 rest -= len;
266 } while (rest > 0); 267 } while (rest > 0);
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index 6abe8a3bd365..a7d89662acf6 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -254,7 +254,7 @@ static struct snd_ca0106_details ca0106_chip_details[] = {
254 .name = "MSI K8N Diamond MB", 254 .name = "MSI K8N Diamond MB",
255 .gpio_type = 2, 255 .gpio_type = 2,
256 .i2c_adc = 1, 256 .i2c_adc = 1,
257 .spi_dac = 2 }, 257 .spi_dac = 2 } ,
258 /* Shuttle XPC SD31P which has an onboard Creative Labs 258 /* Shuttle XPC SD31P which has an onboard Creative Labs
259 * Sound Blaster Live! 24-bit EAX 259 * Sound Blaster Live! 24-bit EAX
260 * high-definition 7.1 audio processor". 260 * high-definition 7.1 audio processor".
diff --git a/sound/pci/ca0106/ca_midi.c b/sound/pci/ca0106/ca_midi.c
index 893ee4f1ea77..c7885117da33 100644
--- a/sound/pci/ca0106/ca_midi.c
+++ b/sound/pci/ca0106/ca_midi.c
@@ -125,7 +125,8 @@ static int ca_midi_input_open(struct snd_rawmidi_substream *substream)
125 struct snd_ca_midi *midi = substream->rmidi->private_data; 125 struct snd_ca_midi *midi = substream->rmidi->private_data;
126 unsigned long flags; 126 unsigned long flags;
127 127
128 snd_assert(midi->dev_id, return -ENXIO); 128 if (snd_BUG_ON(!midi->dev_id))
129 return -ENXIO;
129 spin_lock_irqsave(&midi->open_lock, flags); 130 spin_lock_irqsave(&midi->open_lock, flags);
130 midi->midi_mode |= CA_MIDI_MODE_INPUT; 131 midi->midi_mode |= CA_MIDI_MODE_INPUT;
131 midi->substream_input = substream; 132 midi->substream_input = substream;
@@ -144,7 +145,8 @@ static int ca_midi_output_open(struct snd_rawmidi_substream *substream)
144 struct snd_ca_midi *midi = substream->rmidi->private_data; 145 struct snd_ca_midi *midi = substream->rmidi->private_data;
145 unsigned long flags; 146 unsigned long flags;
146 147
147 snd_assert(midi->dev_id, return -ENXIO); 148 if (snd_BUG_ON(!midi->dev_id))
149 return -ENXIO;
148 spin_lock_irqsave(&midi->open_lock, flags); 150 spin_lock_irqsave(&midi->open_lock, flags);
149 midi->midi_mode |= CA_MIDI_MODE_OUTPUT; 151 midi->midi_mode |= CA_MIDI_MODE_OUTPUT;
150 midi->substream_output = substream; 152 midi->substream_output = substream;
@@ -163,7 +165,8 @@ static int ca_midi_input_close(struct snd_rawmidi_substream *substream)
163 struct snd_ca_midi *midi = substream->rmidi->private_data; 165 struct snd_ca_midi *midi = substream->rmidi->private_data;
164 unsigned long flags; 166 unsigned long flags;
165 167
166 snd_assert(midi->dev_id, return -ENXIO); 168 if (snd_BUG_ON(!midi->dev_id))
169 return -ENXIO;
167 spin_lock_irqsave(&midi->open_lock, flags); 170 spin_lock_irqsave(&midi->open_lock, flags);
168 midi->interrupt_disable(midi,midi->rx_enable); 171 midi->interrupt_disable(midi,midi->rx_enable);
169 midi->midi_mode &= ~CA_MIDI_MODE_INPUT; 172 midi->midi_mode &= ~CA_MIDI_MODE_INPUT;
@@ -181,7 +184,9 @@ static int ca_midi_output_close(struct snd_rawmidi_substream *substream)
181{ 184{
182 struct snd_ca_midi *midi = substream->rmidi->private_data; 185 struct snd_ca_midi *midi = substream->rmidi->private_data;
183 unsigned long flags; 186 unsigned long flags;
184 snd_assert(midi->dev_id, return -ENXIO); 187
188 if (snd_BUG_ON(!midi->dev_id))
189 return -ENXIO;
185 190
186 spin_lock_irqsave(&midi->open_lock, flags); 191 spin_lock_irqsave(&midi->open_lock, flags);
187 192
@@ -201,7 +206,9 @@ static int ca_midi_output_close(struct snd_rawmidi_substream *substream)
201static void ca_midi_input_trigger(struct snd_rawmidi_substream *substream, int up) 206static void ca_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
202{ 207{
203 struct snd_ca_midi *midi = substream->rmidi->private_data; 208 struct snd_ca_midi *midi = substream->rmidi->private_data;
204 snd_assert(midi->dev_id, return); 209
210 if (snd_BUG_ON(!midi->dev_id))
211 return;
205 212
206 if (up) { 213 if (up) {
207 midi->interrupt_enable(midi,midi->rx_enable); 214 midi->interrupt_enable(midi,midi->rx_enable);
@@ -215,7 +222,8 @@ static void ca_midi_output_trigger(struct snd_rawmidi_substream *substream, int
215 struct snd_ca_midi *midi = substream->rmidi->private_data; 222 struct snd_ca_midi *midi = substream->rmidi->private_data;
216 unsigned long flags; 223 unsigned long flags;
217 224
218 snd_assert(midi->dev_id, return); 225 if (snd_BUG_ON(!midi->dev_id))
226 return;
219 227
220 if (up) { 228 if (up) {
221 int max = 4; 229 int max = 4;
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
index 9971b5b7735b..1a74ca62c314 100644
--- a/sound/pci/cmipci.c
+++ b/sound/pci/cmipci.c
@@ -2357,7 +2357,8 @@ static int snd_cmipci_uswitch_get(struct snd_kcontrol *kcontrol,
2357{ 2357{
2358 struct cmipci_switch_args *args; 2358 struct cmipci_switch_args *args;
2359 args = (struct cmipci_switch_args *)kcontrol->private_value; 2359 args = (struct cmipci_switch_args *)kcontrol->private_value;
2360 snd_assert(args != NULL, return -EINVAL); 2360 if (snd_BUG_ON(!args))
2361 return -EINVAL;
2361 return _snd_cmipci_uswitch_get(kcontrol, ucontrol, args); 2362 return _snd_cmipci_uswitch_get(kcontrol, ucontrol, args);
2362} 2363}
2363 2364
@@ -2401,7 +2402,8 @@ static int snd_cmipci_uswitch_put(struct snd_kcontrol *kcontrol,
2401{ 2402{
2402 struct cmipci_switch_args *args; 2403 struct cmipci_switch_args *args;
2403 args = (struct cmipci_switch_args *)kcontrol->private_value; 2404 args = (struct cmipci_switch_args *)kcontrol->private_value;
2404 snd_assert(args != NULL, return -EINVAL); 2405 if (snd_BUG_ON(!args))
2406 return -EINVAL;
2405 return _snd_cmipci_uswitch_put(kcontrol, ucontrol, args); 2407 return _snd_cmipci_uswitch_put(kcontrol, ucontrol, args);
2406} 2408}
2407 2409
@@ -2662,7 +2664,8 @@ static int __devinit snd_cmipci_mixer_new(struct cmipci *cm, int pcm_spdif_devic
2662 unsigned int idx; 2664 unsigned int idx;
2663 int err; 2665 int err;
2664 2666
2665 snd_assert(cm != NULL && cm->card != NULL, return -EINVAL); 2667 if (snd_BUG_ON(!cm || !cm->card))
2668 return -EINVAL;
2666 2669
2667 card = cm->card; 2670 card = cm->card;
2668 2671
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c
index 7556fd90d0eb..ef9308f7c45b 100644
--- a/sound/pci/cs4281.c
+++ b/sound/pci/cs4281.c
@@ -766,13 +766,13 @@ static void snd_cs4281_mode(struct cs4281 *chip, struct cs4281_dma *dma,
766 if (!capture) { 766 if (!capture) {
767 if (dma->left_slot == chip->src_left_play_slot) { 767 if (dma->left_slot == chip->src_left_play_slot) {
768 unsigned int val = snd_cs4281_rate(runtime->rate, NULL); 768 unsigned int val = snd_cs4281_rate(runtime->rate, NULL);
769 snd_assert(dma->right_slot == chip->src_right_play_slot, ); 769 snd_BUG_ON(dma->right_slot != chip->src_right_play_slot);
770 snd_cs4281_pokeBA0(chip, BA0_DACSR, val); 770 snd_cs4281_pokeBA0(chip, BA0_DACSR, val);
771 } 771 }
772 } else { 772 } else {
773 if (dma->left_slot == chip->src_left_rec_slot) { 773 if (dma->left_slot == chip->src_left_rec_slot) {
774 unsigned int val = snd_cs4281_rate(runtime->rate, NULL); 774 unsigned int val = snd_cs4281_rate(runtime->rate, NULL);
775 snd_assert(dma->right_slot == chip->src_right_rec_slot, ); 775 snd_BUG_ON(dma->right_slot != chip->src_right_rec_slot);
776 snd_cs4281_pokeBA0(chip, BA0_ADCSR, val); 776 snd_cs4281_pokeBA0(chip, BA0_ADCSR, val);
777 } 777 }
778 } 778 }
@@ -1209,7 +1209,8 @@ static void snd_cs4281_gameport_trigger(struct gameport *gameport)
1209{ 1209{
1210 struct cs4281 *chip = gameport_get_port_data(gameport); 1210 struct cs4281 *chip = gameport_get_port_data(gameport);
1211 1211
1212 snd_assert(chip, return); 1212 if (snd_BUG_ON(!chip))
1213 return;
1213 snd_cs4281_pokeBA0(chip, BA0_JSPT, 0xff); 1214 snd_cs4281_pokeBA0(chip, BA0_JSPT, 0xff);
1214} 1215}
1215 1216
@@ -1217,7 +1218,8 @@ static unsigned char snd_cs4281_gameport_read(struct gameport *gameport)
1217{ 1218{
1218 struct cs4281 *chip = gameport_get_port_data(gameport); 1219 struct cs4281 *chip = gameport_get_port_data(gameport);
1219 1220
1220 snd_assert(chip, return 0); 1221 if (snd_BUG_ON(!chip))
1222 return 0;
1221 return snd_cs4281_peekBA0(chip, BA0_JSPT); 1223 return snd_cs4281_peekBA0(chip, BA0_JSPT);
1222} 1224}
1223 1225
@@ -1228,7 +1230,8 @@ static int snd_cs4281_gameport_cooked_read(struct gameport *gameport,
1228 struct cs4281 *chip = gameport_get_port_data(gameport); 1230 struct cs4281 *chip = gameport_get_port_data(gameport);
1229 unsigned js1, js2, jst; 1231 unsigned js1, js2, jst;
1230 1232
1231 snd_assert(chip, return 0); 1233 if (snd_BUG_ON(!chip))
1234 return 0;
1232 1235
1233 js1 = snd_cs4281_peekBA0(chip, BA0_JSC1); 1236 js1 = snd_cs4281_peekBA0(chip, BA0_JSC1);
1234 js2 = snd_cs4281_peekBA0(chip, BA0_JSC2); 1237 js2 = snd_cs4281_peekBA0(chip, BA0_JSC2);
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
index e214e567dec8..fb6dc3980257 100644
--- a/sound/pci/cs46xx/cs46xx_lib.c
+++ b/sound/pci/cs46xx/cs46xx_lib.c
@@ -90,9 +90,10 @@ static unsigned short snd_cs46xx_codec_read(struct snd_cs46xx *chip,
90 int count; 90 int count;
91 unsigned short result,tmp; 91 unsigned short result,tmp;
92 u32 offset = 0; 92 u32 offset = 0;
93 snd_assert ( (codec_index == CS46XX_PRIMARY_CODEC_INDEX) || 93
94 (codec_index == CS46XX_SECONDARY_CODEC_INDEX), 94 if (snd_BUG_ON(codec_index != CS46XX_PRIMARY_CODEC_INDEX &&
95 return -EINVAL); 95 codec_index != CS46XX_SECONDARY_CODEC_INDEX))
96 return -EINVAL;
96 97
97 chip->active_ctrl(chip, 1); 98 chip->active_ctrl(chip, 1);
98 99
@@ -212,9 +213,9 @@ static unsigned short snd_cs46xx_ac97_read(struct snd_ac97 * ac97,
212 unsigned short val; 213 unsigned short val;
213 int codec_index = ac97->num; 214 int codec_index = ac97->num;
214 215
215 snd_assert(codec_index == CS46XX_PRIMARY_CODEC_INDEX || 216 if (snd_BUG_ON(codec_index != CS46XX_PRIMARY_CODEC_INDEX &&
216 codec_index == CS46XX_SECONDARY_CODEC_INDEX, 217 codec_index != CS46XX_SECONDARY_CODEC_INDEX))
217 return 0xffff); 218 return 0xffff;
218 219
219 val = snd_cs46xx_codec_read(chip, reg, codec_index); 220 val = snd_cs46xx_codec_read(chip, reg, codec_index);
220 221
@@ -229,9 +230,9 @@ static void snd_cs46xx_codec_write(struct snd_cs46xx *chip,
229{ 230{
230 int count; 231 int count;
231 232
232 snd_assert ((codec_index == CS46XX_PRIMARY_CODEC_INDEX) || 233 if (snd_BUG_ON(codec_index != CS46XX_PRIMARY_CODEC_INDEX &&
233 (codec_index == CS46XX_SECONDARY_CODEC_INDEX), 234 codec_index != CS46XX_SECONDARY_CODEC_INDEX))
234 return); 235 return;
235 236
236 chip->active_ctrl(chip, 1); 237 chip->active_ctrl(chip, 1);
237 238
@@ -294,9 +295,9 @@ static void snd_cs46xx_ac97_write(struct snd_ac97 *ac97,
294 struct snd_cs46xx *chip = ac97->private_data; 295 struct snd_cs46xx *chip = ac97->private_data;
295 int codec_index = ac97->num; 296 int codec_index = ac97->num;
296 297
297 snd_assert(codec_index == CS46XX_PRIMARY_CODEC_INDEX || 298 if (snd_BUG_ON(codec_index != CS46XX_PRIMARY_CODEC_INDEX &&
298 codec_index == CS46XX_SECONDARY_CODEC_INDEX, 299 codec_index != CS46XX_SECONDARY_CODEC_INDEX))
299 return); 300 return;
300 301
301 snd_cs46xx_codec_write(chip, reg, val, codec_index); 302 snd_cs46xx_codec_write(chip, reg, val, codec_index);
302} 303}
@@ -315,7 +316,8 @@ int snd_cs46xx_download(struct snd_cs46xx *chip,
315 unsigned int bank = offset >> 16; 316 unsigned int bank = offset >> 16;
316 offset = offset & 0xffff; 317 offset = offset & 0xffff;
317 318
318 snd_assert(!(offset & 3) && !(len & 3), return -EINVAL); 319 if (snd_BUG_ON((offset & 3) || (len & 3)))
320 return -EINVAL;
319 dst = chip->region.idx[bank+1].remap_addr + offset; 321 dst = chip->region.idx[bank+1].remap_addr + offset;
320 len /= sizeof(u32); 322 len /= sizeof(u32);
321 323
@@ -343,7 +345,8 @@ int snd_cs46xx_clear_BA1(struct snd_cs46xx *chip,
343 unsigned int bank = offset >> 16; 345 unsigned int bank = offset >> 16;
344 offset = offset & 0xffff; 346 offset = offset & 0xffff;
345 347
346 snd_assert(!(offset & 3) && !(len & 3), return -EINVAL); 348 if (snd_BUG_ON((offset & 3) || (len & 3)))
349 return -EINVAL;
347 dst = chip->region.idx[bank+1].remap_addr + offset; 350 dst = chip->region.idx[bank+1].remap_addr + offset;
348 len /= sizeof(u32); 351 len /= sizeof(u32);
349 352
@@ -722,7 +725,9 @@ static snd_pcm_uframes_t snd_cs46xx_playback_direct_pointer(struct snd_pcm_subst
722 struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); 725 struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
723 size_t ptr; 726 size_t ptr;
724 struct snd_cs46xx_pcm *cpcm = substream->runtime->private_data; 727 struct snd_cs46xx_pcm *cpcm = substream->runtime->private_data;
725 snd_assert (cpcm->pcm_channel,return -ENXIO); 728
729 if (snd_BUG_ON(!cpcm->pcm_channel))
730 return -ENXIO;
726 731
727#ifdef CONFIG_SND_CS46XX_NEW_DSP 732#ifdef CONFIG_SND_CS46XX_NEW_DSP
728 ptr = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 2) << 2); 733 ptr = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 2) << 2);
@@ -740,7 +745,8 @@ static snd_pcm_uframes_t snd_cs46xx_playback_indirect_pointer(struct snd_pcm_sub
740 struct snd_cs46xx_pcm *cpcm = substream->runtime->private_data; 745 struct snd_cs46xx_pcm *cpcm = substream->runtime->private_data;
741 746
742#ifdef CONFIG_SND_CS46XX_NEW_DSP 747#ifdef CONFIG_SND_CS46XX_NEW_DSP
743 snd_assert (cpcm->pcm_channel,return -ENXIO); 748 if (snd_BUG_ON(!cpcm->pcm_channel))
749 return -ENXIO;
744 ptr = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 2) << 2); 750 ptr = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 2) << 2);
745#else 751#else
746 ptr = snd_cs46xx_peek(chip, BA1_PBA); 752 ptr = snd_cs46xx_peek(chip, BA1_PBA);
@@ -908,7 +914,8 @@ static int snd_cs46xx_playback_hw_params(struct snd_pcm_substream *substream,
908 cpcm = runtime->private_data; 914 cpcm = runtime->private_data;
909 915
910#ifdef CONFIG_SND_CS46XX_NEW_DSP 916#ifdef CONFIG_SND_CS46XX_NEW_DSP
911 snd_assert (sample_rate != 0, return -ENXIO); 917 if (snd_BUG_ON(!sample_rate))
918 return -ENXIO;
912 919
913 mutex_lock(&chip->spos_mutex); 920 mutex_lock(&chip->spos_mutex);
914 921
@@ -917,7 +924,7 @@ static int snd_cs46xx_playback_hw_params(struct snd_pcm_substream *substream,
917 return -ENXIO; 924 return -ENXIO;
918 } 925 }
919 926
920 snd_assert (cpcm->pcm_channel != NULL); 927 snd_BUG_ON(!cpcm->pcm_channel);
921 if (!cpcm->pcm_channel) { 928 if (!cpcm->pcm_channel) {
922 mutex_unlock(&chip->spos_mutex); 929 mutex_unlock(&chip->spos_mutex);
923 return -ENXIO; 930 return -ENXIO;
@@ -952,7 +959,7 @@ static int snd_cs46xx_playback_hw_params(struct snd_pcm_substream *substream,
952 } else if (cpcm->pcm_channel_id == DSP_IEC958_CHANNEL) { 959 } else if (cpcm->pcm_channel_id == DSP_IEC958_CHANNEL) {
953 substream->ops = &snd_cs46xx_playback_iec958_ops; 960 substream->ops = &snd_cs46xx_playback_iec958_ops;
954 } else { 961 } else {
955 snd_assert(0); 962 snd_BUG();
956 } 963 }
957#else 964#else
958 substream->ops = &snd_cs46xx_playback_ops; 965 substream->ops = &snd_cs46xx_playback_ops;
@@ -981,7 +988,7 @@ static int snd_cs46xx_playback_hw_params(struct snd_pcm_substream *substream,
981 } else if (cpcm->pcm_channel_id == DSP_IEC958_CHANNEL) { 988 } else if (cpcm->pcm_channel_id == DSP_IEC958_CHANNEL) {
982 substream->ops = &snd_cs46xx_playback_indirect_iec958_ops; 989 substream->ops = &snd_cs46xx_playback_indirect_iec958_ops;
983 } else { 990 } else {
984 snd_assert(0); 991 snd_BUG();
985 } 992 }
986#else 993#else
987 substream->ops = &snd_cs46xx_playback_indirect_ops; 994 substream->ops = &snd_cs46xx_playback_indirect_ops;
@@ -1029,7 +1036,8 @@ static int snd_cs46xx_playback_prepare(struct snd_pcm_substream *substream)
1029 cpcm = runtime->private_data; 1036 cpcm = runtime->private_data;
1030 1037
1031#ifdef CONFIG_SND_CS46XX_NEW_DSP 1038#ifdef CONFIG_SND_CS46XX_NEW_DSP
1032 snd_assert (cpcm->pcm_channel != NULL, return -ENXIO); 1039 if (snd_BUG_ON(!cpcm->pcm_channel))
1040 return -ENXIO;
1033 1041
1034 pfie = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 1) << 2 ); 1042 pfie = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 1) << 2 );
1035 pfie &= ~0x0000f03f; 1043 pfie &= ~0x0000f03f;
@@ -1714,9 +1722,9 @@ static void snd_cs46xx_mixer_free_ac97(struct snd_ac97 *ac97)
1714{ 1722{
1715 struct snd_cs46xx *chip = ac97->private_data; 1723 struct snd_cs46xx *chip = ac97->private_data;
1716 1724
1717 snd_assert ((ac97 == chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]) || 1725 if (snd_BUG_ON(ac97 != chip->ac97[CS46XX_PRIMARY_CODEC_INDEX] &&
1718 (ac97 == chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]), 1726 ac97 != chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]))
1719 return); 1727 return;
1720 1728
1721 if (ac97 == chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]) { 1729 if (ac97 == chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]) {
1722 chip->ac97[CS46XX_PRIMARY_CODEC_INDEX] = NULL; 1730 chip->ac97[CS46XX_PRIMARY_CODEC_INDEX] = NULL;
@@ -1864,7 +1872,7 @@ static int snd_cs46xx_iec958_put(struct snd_kcontrol *kcontrol,
1864 break; 1872 break;
1865 default: 1873 default:
1866 res = -EINVAL; 1874 res = -EINVAL;
1867 snd_assert(0, (void)0); 1875 snd_BUG(); /* should never happen ... */
1868 } 1876 }
1869 1877
1870 return res; 1878 return res;
@@ -2236,7 +2244,7 @@ static void snd_cs46xx_codec_reset (struct snd_ac97 * ac97)
2236 snd_printdd("cs46xx: CODOEC2 mode %04x\n",0x3); 2244 snd_printdd("cs46xx: CODOEC2 mode %04x\n",0x3);
2237 snd_cs46xx_ac97_write(ac97,AC97_CSR_ACMODE,0x3); 2245 snd_cs46xx_ac97_write(ac97,AC97_CSR_ACMODE,0x3);
2238 } else { 2246 } else {
2239 snd_assert(0); /* should never happen ... */ 2247 snd_BUG(); /* should never happen ... */
2240 } 2248 }
2241 2249
2242 udelay(50); 2250 udelay(50);
@@ -2553,7 +2561,8 @@ static void snd_cs46xx_gameport_trigger(struct gameport *gameport)
2553{ 2561{
2554 struct snd_cs46xx *chip = gameport_get_port_data(gameport); 2562 struct snd_cs46xx *chip = gameport_get_port_data(gameport);
2555 2563
2556 snd_assert(chip, return); 2564 if (snd_BUG_ON(!chip))
2565 return;
2557 snd_cs46xx_pokeBA0(chip, BA0_JSPT, 0xFF); //outb(gameport->io, 0xFF); 2566 snd_cs46xx_pokeBA0(chip, BA0_JSPT, 0xFF); //outb(gameport->io, 0xFF);
2558} 2567}
2559 2568
@@ -2561,7 +2570,8 @@ static unsigned char snd_cs46xx_gameport_read(struct gameport *gameport)
2561{ 2570{
2562 struct snd_cs46xx *chip = gameport_get_port_data(gameport); 2571 struct snd_cs46xx *chip = gameport_get_port_data(gameport);
2563 2572
2564 snd_assert(chip, return 0); 2573 if (snd_BUG_ON(!chip))
2574 return 0;
2565 return snd_cs46xx_peekBA0(chip, BA0_JSPT); //inb(gameport->io); 2575 return snd_cs46xx_peekBA0(chip, BA0_JSPT); //inb(gameport->io);
2566} 2576}
2567 2577
@@ -2570,7 +2580,8 @@ static int snd_cs46xx_gameport_cooked_read(struct gameport *gameport, int *axes,
2570 struct snd_cs46xx *chip = gameport_get_port_data(gameport); 2580 struct snd_cs46xx *chip = gameport_get_port_data(gameport);
2571 unsigned js1, js2, jst; 2581 unsigned js1, js2, jst;
2572 2582
2573 snd_assert(chip, return 0); 2583 if (snd_BUG_ON(!chip))
2584 return 0;
2574 2585
2575 js1 = snd_cs46xx_peekBA0(chip, BA0_JSC1); 2586 js1 = snd_cs46xx_peekBA0(chip, BA0_JSC1);
2576 js2 = snd_cs46xx_peekBA0(chip, BA0_JSC2); 2587 js2 = snd_cs46xx_peekBA0(chip, BA0_JSC2);
@@ -2754,7 +2765,8 @@ static int snd_cs46xx_free(struct snd_cs46xx *chip)
2754{ 2765{
2755 int idx; 2766 int idx;
2756 2767
2757 snd_assert(chip != NULL, return -EINVAL); 2768 if (snd_BUG_ON(!chip))
2769 return -EINVAL;
2758 2770
2759 if (chip->active_ctrl) 2771 if (chip->active_ctrl)
2760 chip->active_ctrl(chip, 1); 2772 chip->active_ctrl(chip, 1);
@@ -3489,8 +3501,9 @@ static struct cs_card_type __devinitdata cards[] = {
3489 .name = "Mitac MI6020/21", 3501 .name = "Mitac MI6020/21",
3490 .amp = amp_voyetra, 3502 .amp = amp_voyetra,
3491 }, 3503 },
3504 /* Hercules Game Theatre XP */
3492 { 3505 {
3493 .vendor = 0x14AF, 3506 .vendor = 0x14af, /* Guillemot Corporation */
3494 .id = 0x0050, 3507 .id = 0x0050,
3495 .name = "Hercules Game Theatre XP", 3508 .name = "Hercules Game Theatre XP",
3496 .amp = amp_hercules, 3509 .amp = amp_hercules,
@@ -3532,9 +3545,25 @@ static struct cs_card_type __devinitdata cards[] = {
3532 .amp = amp_hercules, 3545 .amp = amp_hercules,
3533 .mixer_init = hercules_mixer_init, 3546 .mixer_init = hercules_mixer_init,
3534 }, 3547 },
3548 /* Herculess Fortissimo */
3549 {
3550 .vendor = 0x1681,
3551 .id = 0xa010,
3552 .name = "Hercules Gamesurround Fortissimo II",
3553 },
3554 {
3555 .vendor = 0x1681,
3556 .id = 0xa011,
3557 .name = "Hercules Gamesurround Fortissimo III 7.1",
3558 },
3535 /* Teratec */ 3559 /* Teratec */
3536 { 3560 {
3537 .vendor = 0x153b, 3561 .vendor = 0x153b,
3562 .id = 0x112e,
3563 .name = "Terratec DMX XFire 1024",
3564 },
3565 {
3566 .vendor = 0x153b,
3538 .id = 0x1136, 3567 .id = 0x1136,
3539 .name = "Terratec SiXPack 5.1", 3568 .name = "Terratec SiXPack 5.1",
3540 }, 3569 },
diff --git a/sound/pci/cs46xx/dsp_spos.c b/sound/pci/cs46xx/dsp_spos.c
index ccc8bedb5b1a..f4f0c8f5dad7 100644
--- a/sound/pci/cs46xx/dsp_spos.c
+++ b/sound/pci/cs46xx/dsp_spos.c
@@ -63,7 +63,8 @@ static int shadow_and_reallocate_code (struct snd_cs46xx * chip, u32 * data, u32
63 u32 mop_operands,mop_type,wide_op; 63 u32 mop_operands,mop_type,wide_op;
64 struct dsp_spos_instance * ins = chip->dsp_spos_instance; 64 struct dsp_spos_instance * ins = chip->dsp_spos_instance;
65 65
66 snd_assert( ((size % 2) == 0), return -EINVAL); 66 if (snd_BUG_ON(size %2))
67 return -EINVAL;
67 68
68 while (i < size) { 69 while (i < size) {
69 loval = data[i++]; 70 loval = data[i++];
@@ -289,7 +290,8 @@ void cs46xx_dsp_spos_destroy (struct snd_cs46xx * chip)
289 int i; 290 int i;
290 struct dsp_spos_instance * ins = chip->dsp_spos_instance; 291 struct dsp_spos_instance * ins = chip->dsp_spos_instance;
291 292
292 snd_assert(ins != NULL, return); 293 if (snd_BUG_ON(!ins))
294 return;
293 295
294 mutex_lock(&chip->spos_mutex); 296 mutex_lock(&chip->spos_mutex);
295 for (i = 0; i < ins->nscb; ++i) { 297 for (i = 0; i < ins->nscb; ++i) {
@@ -404,7 +406,8 @@ int cs46xx_dsp_load_module (struct snd_cs46xx * chip, struct dsp_module_desc * m
404 406
405 /* if module has a code segment it must have 407 /* if module has a code segment it must have
406 symbol table */ 408 symbol table */
407 snd_assert(module->symbol_table.symbols != NULL ,return -ENOMEM); 409 if (snd_BUG_ON(!module->symbol_table.symbols))
410 return -ENOMEM;
408 if (add_symbols(chip,module)) { 411 if (add_symbols(chip,module)) {
409 snd_printk(KERN_ERR "dsp_spos: failed to load symbol table\n"); 412 snd_printk(KERN_ERR "dsp_spos: failed to load symbol table\n");
410 return -ENOMEM; 413 return -ENOMEM;
@@ -1369,7 +1372,8 @@ int cs46xx_dsp_scb_and_task_init (struct snd_cs46xx *chip)
1369 1372
1370 valid_slots = snd_cs46xx_peekBA0(chip, BA0_ACOSV); 1373 valid_slots = snd_cs46xx_peekBA0(chip, BA0_ACOSV);
1371 1374
1372 snd_assert (chip->nr_ac97_codecs == 1 || chip->nr_ac97_codecs == 2); 1375 if (snd_BUG_ON(chip->nr_ac97_codecs != 1 && chip->nr_ac97_codecs != 2))
1376 goto _fail_end;
1373 1377
1374 if (chip->nr_ac97_codecs == 1) { 1378 if (chip->nr_ac97_codecs == 1) {
1375 /* output on slot 5 and 11 1379 /* output on slot 5 and 11
@@ -1609,11 +1613,14 @@ static int cs46xx_dsp_async_init (struct snd_cs46xx *chip,
1609 1613
1610 spdifo_scb_desc = cs46xx_dsp_create_scb(chip,"SPDIFOSCB",(u32 *)&spdifo_scb,SPDIFO_SCB_INST); 1614 spdifo_scb_desc = cs46xx_dsp_create_scb(chip,"SPDIFOSCB",(u32 *)&spdifo_scb,SPDIFO_SCB_INST);
1611 1615
1612 snd_assert(spdifo_scb_desc, return -EIO); 1616 if (snd_BUG_ON(!spdifo_scb_desc))
1617 return -EIO;
1613 spdifi_scb_desc = cs46xx_dsp_create_scb(chip,"SPDIFISCB",(u32 *)&spdifi_scb,SPDIFI_SCB_INST); 1618 spdifi_scb_desc = cs46xx_dsp_create_scb(chip,"SPDIFISCB",(u32 *)&spdifi_scb,SPDIFI_SCB_INST);
1614 snd_assert(spdifi_scb_desc, return -EIO); 1619 if (snd_BUG_ON(!spdifi_scb_desc))
1620 return -EIO;
1615 async_codec_scb_desc = cs46xx_dsp_create_scb(chip,"AsynCodecInputSCB",(u32 *)&async_codec_input_scb, HFG_TREE_SCB); 1621 async_codec_scb_desc = cs46xx_dsp_create_scb(chip,"AsynCodecInputSCB",(u32 *)&async_codec_input_scb, HFG_TREE_SCB);
1616 snd_assert(async_codec_scb_desc, return -EIO); 1622 if (snd_BUG_ON(!async_codec_scb_desc))
1623 return -EIO;
1617 1624
1618 async_codec_scb_desc->parent_scb_ptr = NULL; 1625 async_codec_scb_desc->parent_scb_ptr = NULL;
1619 async_codec_scb_desc->next_scb_ptr = spdifi_scb_desc; 1626 async_codec_scb_desc->next_scb_ptr = spdifi_scb_desc;
@@ -1698,8 +1705,10 @@ int cs46xx_dsp_enable_spdif_in (struct snd_cs46xx *chip)
1698 chip->active_ctrl(chip, 1); 1705 chip->active_ctrl(chip, 1);
1699 chip->amplifier_ctrl(chip, 1); 1706 chip->amplifier_ctrl(chip, 1);
1700 1707
1701 snd_assert (ins->asynch_rx_scb == NULL,return -EINVAL); 1708 if (snd_BUG_ON(ins->asynch_rx_scb))
1702 snd_assert (ins->spdif_in_src != NULL,return -EINVAL); 1709 return -EINVAL;
1710 if (snd_BUG_ON(!ins->spdif_in_src))
1711 return -EINVAL;
1703 1712
1704 mutex_lock(&chip->spos_mutex); 1713 mutex_lock(&chip->spos_mutex);
1705 1714
@@ -1754,8 +1763,10 @@ int cs46xx_dsp_disable_spdif_in (struct snd_cs46xx *chip)
1754{ 1763{
1755 struct dsp_spos_instance * ins = chip->dsp_spos_instance; 1764 struct dsp_spos_instance * ins = chip->dsp_spos_instance;
1756 1765
1757 snd_assert (ins->asynch_rx_scb != NULL, return -EINVAL); 1766 if (snd_BUG_ON(!ins->asynch_rx_scb))
1758 snd_assert (ins->spdif_in_src != NULL,return -EINVAL); 1767 return -EINVAL;
1768 if (snd_BUG_ON(!ins->spdif_in_src))
1769 return -EINVAL;
1759 1770
1760 mutex_lock(&chip->spos_mutex); 1771 mutex_lock(&chip->spos_mutex);
1761 1772
@@ -1780,8 +1791,10 @@ int cs46xx_dsp_enable_pcm_capture (struct snd_cs46xx *chip)
1780{ 1791{
1781 struct dsp_spos_instance * ins = chip->dsp_spos_instance; 1792 struct dsp_spos_instance * ins = chip->dsp_spos_instance;
1782 1793
1783 snd_assert (ins->pcm_input == NULL,return -EINVAL); 1794 if (snd_BUG_ON(ins->pcm_input))
1784 snd_assert (ins->ref_snoop_scb != NULL,return -EINVAL); 1795 return -EINVAL;
1796 if (snd_BUG_ON(!ins->ref_snoop_scb))
1797 return -EINVAL;
1785 1798
1786 mutex_lock(&chip->spos_mutex); 1799 mutex_lock(&chip->spos_mutex);
1787 ins->pcm_input = cs46xx_add_record_source(chip,ins->ref_snoop_scb,PCMSERIALIN_PCM_SCB_ADDR, 1800 ins->pcm_input = cs46xx_add_record_source(chip,ins->ref_snoop_scb,PCMSERIALIN_PCM_SCB_ADDR,
@@ -1795,7 +1808,8 @@ int cs46xx_dsp_disable_pcm_capture (struct snd_cs46xx *chip)
1795{ 1808{
1796 struct dsp_spos_instance * ins = chip->dsp_spos_instance; 1809 struct dsp_spos_instance * ins = chip->dsp_spos_instance;
1797 1810
1798 snd_assert (ins->pcm_input != NULL,return -EINVAL); 1811 if (snd_BUG_ON(!ins->pcm_input))
1812 return -EINVAL;
1799 1813
1800 mutex_lock(&chip->spos_mutex); 1814 mutex_lock(&chip->spos_mutex);
1801 cs46xx_dsp_remove_scb (chip,ins->pcm_input); 1815 cs46xx_dsp_remove_scb (chip,ins->pcm_input);
@@ -1809,8 +1823,10 @@ int cs46xx_dsp_enable_adc_capture (struct snd_cs46xx *chip)
1809{ 1823{
1810 struct dsp_spos_instance * ins = chip->dsp_spos_instance; 1824 struct dsp_spos_instance * ins = chip->dsp_spos_instance;
1811 1825
1812 snd_assert (ins->adc_input == NULL,return -EINVAL); 1826 if (snd_BUG_ON(ins->adc_input))
1813 snd_assert (ins->codec_in_scb != NULL,return -EINVAL); 1827 return -EINVAL;
1828 if (snd_BUG_ON(!ins->codec_in_scb))
1829 return -EINVAL;
1814 1830
1815 mutex_lock(&chip->spos_mutex); 1831 mutex_lock(&chip->spos_mutex);
1816 ins->adc_input = cs46xx_add_record_source(chip,ins->codec_in_scb,PCMSERIALIN_SCB_ADDR, 1832 ins->adc_input = cs46xx_add_record_source(chip,ins->codec_in_scb,PCMSERIALIN_SCB_ADDR,
@@ -1824,7 +1840,8 @@ int cs46xx_dsp_disable_adc_capture (struct snd_cs46xx *chip)
1824{ 1840{
1825 struct dsp_spos_instance * ins = chip->dsp_spos_instance; 1841 struct dsp_spos_instance * ins = chip->dsp_spos_instance;
1826 1842
1827 snd_assert (ins->adc_input != NULL,return -EINVAL); 1843 if (snd_BUG_ON(!ins->adc_input))
1844 return -EINVAL;
1828 1845
1829 mutex_lock(&chip->spos_mutex); 1846 mutex_lock(&chip->spos_mutex);
1830 cs46xx_dsp_remove_scb (chip,ins->adc_input); 1847 cs46xx_dsp_remove_scb (chip,ins->adc_input);
diff --git a/sound/pci/cs46xx/dsp_spos_scb_lib.c b/sound/pci/cs46xx/dsp_spos_scb_lib.c
index 2873cfe48c33..dd7c41b037b4 100644
--- a/sound/pci/cs46xx/dsp_spos_scb_lib.c
+++ b/sound/pci/cs46xx/dsp_spos_scb_lib.c
@@ -46,8 +46,11 @@ static void remove_symbol (struct snd_cs46xx * chip, struct dsp_symbol_entry * s
46 struct dsp_spos_instance * ins = chip->dsp_spos_instance; 46 struct dsp_spos_instance * ins = chip->dsp_spos_instance;
47 int symbol_index = (int)(symbol - ins->symbol_table.symbols); 47 int symbol_index = (int)(symbol - ins->symbol_table.symbols);
48 48
49 snd_assert(ins->symbol_table.nsymbols > 0,return); 49 if (snd_BUG_ON(ins->symbol_table.nsymbols <= 0))
50 snd_assert(symbol_index >= 0 && symbol_index < ins->symbol_table.nsymbols, return); 50 return;
51 if (snd_BUG_ON(symbol_index < 0 ||
52 symbol_index >= ins->symbol_table.nsymbols))
53 return;
51 54
52 ins->symbol_table.symbols[symbol_index].deleted = 1; 55 ins->symbol_table.symbols[symbol_index].deleted = 1;
53 56
@@ -116,8 +119,9 @@ static void _dsp_unlink_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor
116 119
117 if ( scb->parent_scb_ptr ) { 120 if ( scb->parent_scb_ptr ) {
118 /* unlink parent SCB */ 121 /* unlink parent SCB */
119 snd_assert ((scb->parent_scb_ptr->sub_list_ptr == scb || 122 if (snd_BUG_ON(scb->parent_scb_ptr->sub_list_ptr != scb &&
120 scb->parent_scb_ptr->next_scb_ptr == scb),return); 123 scb->parent_scb_ptr->next_scb_ptr != scb))
124 return;
121 125
122 if (scb->parent_scb_ptr->sub_list_ptr == scb) { 126 if (scb->parent_scb_ptr->sub_list_ptr == scb) {
123 127
@@ -140,7 +144,6 @@ static void _dsp_unlink_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor
140 scb->next_scb_ptr = ins->the_null_scb; 144 scb->next_scb_ptr = ins->the_null_scb;
141 } 145 }
142 } else { 146 } else {
143 /* snd_assert ( (scb->sub_list_ptr == ins->the_null_scb), return); */
144 scb->parent_scb_ptr->next_scb_ptr = scb->next_scb_ptr; 147 scb->parent_scb_ptr->next_scb_ptr = scb->next_scb_ptr;
145 148
146 if (scb->next_scb_ptr != ins->the_null_scb) { 149 if (scb->next_scb_ptr != ins->the_null_scb) {
@@ -181,16 +184,17 @@ void cs46xx_dsp_remove_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor *
181 unsigned long flags; 184 unsigned long flags;
182 185
183 /* check integrety */ 186 /* check integrety */
184 snd_assert ( (scb->index >= 0 && 187 if (snd_BUG_ON(scb->index < 0 ||
185 scb->index < ins->nscb && 188 scb->index >= ins->nscb ||
186 (ins->scbs + scb->index) == scb), return ); 189 (ins->scbs + scb->index) != scb))
190 return;
187 191
188#if 0 192#if 0
189 /* can't remove a SCB with childs before 193 /* can't remove a SCB with childs before
190 removing childs first */ 194 removing childs first */
191 snd_assert ( (scb->sub_list_ptr == ins->the_null_scb && 195 if (snd_BUG_ON(scb->sub_list_ptr != ins->the_null_scb ||
192 scb->next_scb_ptr == ins->the_null_scb), 196 scb->next_scb_ptr != ins->the_null_scb))
193 goto _end); 197 goto _end;
194#endif 198#endif
195 199
196 spin_lock_irqsave(&scb->lock, flags); 200 spin_lock_irqsave(&scb->lock, flags);
@@ -198,7 +202,8 @@ void cs46xx_dsp_remove_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor *
198 spin_unlock_irqrestore(&scb->lock, flags); 202 spin_unlock_irqrestore(&scb->lock, flags);
199 203
200 cs46xx_dsp_proc_free_scb_desc(scb); 204 cs46xx_dsp_proc_free_scb_desc(scb);
201 snd_assert (scb->scb_symbol != NULL, return ); 205 if (snd_BUG_ON(!scb->scb_symbol))
206 return;
202 remove_symbol (chip,scb->scb_symbol); 207 remove_symbol (chip,scb->scb_symbol);
203 208
204 ins->scbs[scb->index].deleted = 1; 209 ins->scbs[scb->index].deleted = 1;
@@ -234,7 +239,6 @@ void cs46xx_dsp_proc_free_scb_desc (struct dsp_scb_descriptor * scb)
234 snd_info_free_entry(scb->proc_info); 239 snd_info_free_entry(scb->proc_info);
235 scb->proc_info = NULL; 240 scb->proc_info = NULL;
236 241
237 snd_assert (scb_info != NULL, return);
238 kfree (scb_info); 242 kfree (scb_info);
239 } 243 }
240} 244}
@@ -291,7 +295,8 @@ _dsp_create_generic_scb (struct snd_cs46xx *chip, char * name, u32 * scb_data, u
291 295
292 unsigned long flags; 296 unsigned long flags;
293 297
294 snd_assert (ins->the_null_scb != NULL,return NULL); 298 if (snd_BUG_ON(!ins->the_null_scb))
299 return NULL;
295 300
296 /* fill the data that will be wroten to DSP */ 301 /* fill the data that will be wroten to DSP */
297 scb_data[SCBsubListPtr] = 302 scb_data[SCBsubListPtr] =
@@ -321,18 +326,20 @@ _dsp_create_generic_scb (struct snd_cs46xx *chip, char * name, u32 * scb_data, u
321#endif 326#endif
322 /* link to parent SCB */ 327 /* link to parent SCB */
323 if (scb_child_type == SCB_ON_PARENT_NEXT_SCB) { 328 if (scb_child_type == SCB_ON_PARENT_NEXT_SCB) {
324 snd_assert ( (scb->parent_scb_ptr->next_scb_ptr == ins->the_null_scb), 329 if (snd_BUG_ON(scb->parent_scb_ptr->next_scb_ptr !=
325 return NULL); 330 ins->the_null_scb))
331 return NULL;
326 332
327 scb->parent_scb_ptr->next_scb_ptr = scb; 333 scb->parent_scb_ptr->next_scb_ptr = scb;
328 334
329 } else if (scb_child_type == SCB_ON_PARENT_SUBLIST_SCB) { 335 } else if (scb_child_type == SCB_ON_PARENT_SUBLIST_SCB) {
330 snd_assert ( (scb->parent_scb_ptr->sub_list_ptr == ins->the_null_scb), 336 if (snd_BUG_ON(scb->parent_scb_ptr->sub_list_ptr !=
331 return NULL); 337 ins->the_null_scb))
338 return NULL;
332 339
333 scb->parent_scb_ptr->sub_list_ptr = scb; 340 scb->parent_scb_ptr->sub_list_ptr = scb;
334 } else { 341 } else {
335 snd_assert (0,return NULL); 342 snd_BUG();
336 } 343 }
337 344
338 spin_lock_irqsave(&chip->reg_lock, flags); 345 spin_lock_irqsave(&chip->reg_lock, flags);
@@ -675,7 +682,7 @@ cs46xx_dsp_create_src_task_scb(struct snd_cs46xx * chip, char * scb_name,
675 if (pass_through) { 682 if (pass_through) {
676 /* wont work with any other rate than 683 /* wont work with any other rate than
677 the native DSP rate */ 684 the native DSP rate */
678 snd_assert (rate == 48000); 685 snd_BUG_ON(rate != 48000);
679 686
680 scb = cs46xx_dsp_create_generic_scb(chip,scb_name,(u32 *)&src_task_scb, 687 scb = cs46xx_dsp_create_generic_scb(chip,scb_name,(u32 *)&src_task_scb,
681 dest,"DMAREADER",parent_scb, 688 dest,"DMAREADER",parent_scb,
@@ -1142,7 +1149,8 @@ find_next_free_scb (struct snd_cs46xx * chip, struct dsp_scb_descriptor * from)
1142 struct dsp_scb_descriptor * scb = from; 1149 struct dsp_scb_descriptor * scb = from;
1143 1150
1144 while (scb->next_scb_ptr != ins->the_null_scb) { 1151 while (scb->next_scb_ptr != ins->the_null_scb) {
1145 snd_assert (scb->next_scb_ptr != NULL, return NULL); 1152 if (snd_BUG_ON(!scb->next_scb_ptr))
1153 return NULL;
1146 1154
1147 scb = scb->next_scb_ptr; 1155 scb = scb->next_scb_ptr;
1148 } 1156 }
@@ -1246,10 +1254,11 @@ cs46xx_dsp_create_pcm_channel (struct snd_cs46xx * chip,
1246 break; 1254 break;
1247 case DSP_PCM_S71_CHANNEL: 1255 case DSP_PCM_S71_CHANNEL:
1248 /* TODO */ 1256 /* TODO */
1249 snd_assert(0); 1257 snd_BUG();
1250 break; 1258 break;
1251 case DSP_IEC958_CHANNEL: 1259 case DSP_IEC958_CHANNEL:
1252 snd_assert (ins->asynch_tx_scb != NULL, return NULL); 1260 if (snd_BUG_ON(!ins->asynch_tx_scb))
1261 return NULL;
1253 mixer_scb = ins->asynch_tx_scb; 1262 mixer_scb = ins->asynch_tx_scb;
1254 1263
1255 /* if sample rate is set to 48khz we pass 1264 /* if sample rate is set to 48khz we pass
@@ -1262,7 +1271,7 @@ cs46xx_dsp_create_pcm_channel (struct snd_cs46xx * chip,
1262 } 1271 }
1263 break; 1272 break;
1264 default: 1273 default:
1265 snd_assert (0); 1274 snd_BUG();
1266 return NULL; 1275 return NULL;
1267 } 1276 }
1268 /* default sample rate is 44100 */ 1277 /* default sample rate is 44100 */
@@ -1308,7 +1317,8 @@ cs46xx_dsp_create_pcm_channel (struct snd_cs46xx * chip,
1308 break; 1317 break;
1309 } 1318 }
1310 } 1319 }
1311 snd_assert (src_index != -1,return NULL); 1320 if (snd_BUG_ON(src_index == -1))
1321 return NULL;
1312 1322
1313 /* we need to create a new SRC SCB */ 1323 /* we need to create a new SRC SCB */
1314 if (mixer_scb->sub_list_ptr == ins->the_null_scb) { 1324 if (mixer_scb->sub_list_ptr == ins->the_null_scb) {
@@ -1462,9 +1472,10 @@ void cs46xx_dsp_destroy_pcm_channel (struct snd_cs46xx * chip,
1462 struct dsp_spos_instance * ins = chip->dsp_spos_instance; 1472 struct dsp_spos_instance * ins = chip->dsp_spos_instance;
1463 unsigned long flags; 1473 unsigned long flags;
1464 1474
1465 snd_assert(pcm_channel->active, return ); 1475 if (snd_BUG_ON(!pcm_channel->active ||
1466 snd_assert(ins->npcm_channels > 0, return ); 1476 ins->npcm_channels <= 0 ||
1467 snd_assert(pcm_channel->src_scb->ref_count > 0, return ); 1477 pcm_channel->src_scb->ref_count <= 0))
1478 return;
1468 1479
1469 spin_lock_irqsave(&chip->reg_lock, flags); 1480 spin_lock_irqsave(&chip->reg_lock, flags);
1470 pcm_channel->unlinked = 1; 1481 pcm_channel->unlinked = 1;
@@ -1479,8 +1490,9 @@ void cs46xx_dsp_destroy_pcm_channel (struct snd_cs46xx * chip,
1479 if (!pcm_channel->src_scb->ref_count) { 1490 if (!pcm_channel->src_scb->ref_count) {
1480 cs46xx_dsp_remove_scb(chip,pcm_channel->src_scb); 1491 cs46xx_dsp_remove_scb(chip,pcm_channel->src_scb);
1481 1492
1482 snd_assert (pcm_channel->src_slot >= 0 && pcm_channel->src_slot < DSP_MAX_SRC_NR, 1493 if (snd_BUG_ON(pcm_channel->src_slot < 0 ||
1483 return ); 1494 pcm_channel->src_slot >= DSP_MAX_SRC_NR))
1495 return;
1484 1496
1485 ins->src_scb_slots[pcm_channel->src_slot] = 0; 1497 ins->src_scb_slots[pcm_channel->src_slot] = 0;
1486 ins->nsrc_scb --; 1498 ins->nsrc_scb --;
@@ -1490,11 +1502,11 @@ void cs46xx_dsp_destroy_pcm_channel (struct snd_cs46xx * chip,
1490int cs46xx_dsp_pcm_unlink (struct snd_cs46xx * chip, 1502int cs46xx_dsp_pcm_unlink (struct snd_cs46xx * chip,
1491 struct dsp_pcm_channel_descriptor * pcm_channel) 1503 struct dsp_pcm_channel_descriptor * pcm_channel)
1492{ 1504{
1493 struct dsp_spos_instance * ins = chip->dsp_spos_instance;
1494 unsigned long flags; 1505 unsigned long flags;
1495 1506
1496 snd_assert(pcm_channel->active,return -EIO); 1507 if (snd_BUG_ON(!pcm_channel->active ||
1497 snd_assert(ins->npcm_channels > 0,return -EIO); 1508 chip->dsp_spos_instance->npcm_channels <= 0))
1509 return -EIO;
1498 1510
1499 spin_lock(&pcm_channel->src_scb->lock); 1511 spin_lock(&pcm_channel->src_scb->lock);
1500 1512
@@ -1537,7 +1549,7 @@ int cs46xx_dsp_pcm_link (struct snd_cs46xx * chip,
1537 1549
1538 src_scb->sub_list_ptr = pcm_channel->pcm_reader_scb; 1550 src_scb->sub_list_ptr = pcm_channel->pcm_reader_scb;
1539 1551
1540 snd_assert (pcm_channel->pcm_reader_scb->parent_scb_ptr == NULL, ; ); 1552 snd_BUG_ON(pcm_channel->pcm_reader_scb->parent_scb_ptr);
1541 pcm_channel->pcm_reader_scb->parent_scb_ptr = parent_scb; 1553 pcm_channel->pcm_reader_scb->parent_scb_ptr = parent_scb;
1542 1554
1543 spin_lock_irqsave(&chip->reg_lock, flags); 1555 spin_lock_irqsave(&chip->reg_lock, flags);
@@ -1564,7 +1576,8 @@ cs46xx_add_record_source (struct snd_cs46xx *chip, struct dsp_scb_descriptor * s
1564 struct dsp_scb_descriptor * pcm_input; 1576 struct dsp_scb_descriptor * pcm_input;
1565 int insert_point; 1577 int insert_point;
1566 1578
1567 snd_assert (ins->record_mixer_scb != NULL,return NULL); 1579 if (snd_BUG_ON(!ins->record_mixer_scb))
1580 return NULL;
1568 1581
1569 if (ins->record_mixer_scb->sub_list_ptr != ins->the_null_scb) { 1582 if (ins->record_mixer_scb->sub_list_ptr != ins->the_null_scb) {
1570 parent = find_next_free_scb (chip,ins->record_mixer_scb->sub_list_ptr); 1583 parent = find_next_free_scb (chip,ins->record_mixer_scb->sub_list_ptr);
@@ -1583,7 +1596,8 @@ cs46xx_add_record_source (struct snd_cs46xx *chip, struct dsp_scb_descriptor * s
1583 1596
1584int cs46xx_src_unlink(struct snd_cs46xx *chip, struct dsp_scb_descriptor * src) 1597int cs46xx_src_unlink(struct snd_cs46xx *chip, struct dsp_scb_descriptor * src)
1585{ 1598{
1586 snd_assert (src->parent_scb_ptr != NULL, return -EINVAL ); 1599 if (snd_BUG_ON(!src->parent_scb_ptr))
1600 return -EINVAL;
1587 1601
1588 /* mute SCB */ 1602 /* mute SCB */
1589 cs46xx_dsp_scb_set_volume (chip,src,0,0); 1603 cs46xx_dsp_scb_set_volume (chip,src,0,0);
@@ -1598,8 +1612,10 @@ int cs46xx_src_link(struct snd_cs46xx *chip, struct dsp_scb_descriptor * src)
1598 struct dsp_spos_instance * ins = chip->dsp_spos_instance; 1612 struct dsp_spos_instance * ins = chip->dsp_spos_instance;
1599 struct dsp_scb_descriptor * parent_scb; 1613 struct dsp_scb_descriptor * parent_scb;
1600 1614
1601 snd_assert (src->parent_scb_ptr == NULL, return -EINVAL ); 1615 if (snd_BUG_ON(src->parent_scb_ptr))
1602 snd_assert(ins->master_mix_scb !=NULL, return -EINVAL ); 1616 return -EINVAL;
1617 if (snd_BUG_ON(!ins->master_mix_scb))
1618 return -EINVAL;
1603 1619
1604 if (ins->master_mix_scb->sub_list_ptr != ins->the_null_scb) { 1620 if (ins->master_mix_scb->sub_list_ptr != ins->the_null_scb) {
1605 parent_scb = find_next_free_scb (chip,ins->master_mix_scb->sub_list_ptr); 1621 parent_scb = find_next_free_scb (chip,ins->master_mix_scb->sub_list_ptr);
@@ -1635,8 +1651,11 @@ int cs46xx_dsp_enable_spdif_out (struct snd_cs46xx *chip)
1635 return -EBUSY; 1651 return -EBUSY;
1636 } 1652 }
1637 1653
1638 snd_assert (ins->asynch_tx_scb == NULL, return -EINVAL); 1654 if (snd_BUG_ON(ins->asynch_tx_scb))
1639 snd_assert (ins->master_mix_scb->next_scb_ptr == ins->the_null_scb, return -EINVAL); 1655 return -EINVAL;
1656 if (snd_BUG_ON(ins->master_mix_scb->next_scb_ptr !=
1657 ins->the_null_scb))
1658 return -EINVAL;
1640 1659
1641 /* reset output snooper sample buffer pointer */ 1660 /* reset output snooper sample buffer pointer */
1642 snd_cs46xx_poke (chip, (ins->ref_snoop_scb->address + 2) << 2, 1661 snd_cs46xx_poke (chip, (ins->ref_snoop_scb->address + 2) << 2,
@@ -1676,10 +1695,15 @@ int cs46xx_dsp_disable_spdif_out (struct snd_cs46xx *chip)
1676 } 1695 }
1677 1696
1678 /* check integrety */ 1697 /* check integrety */
1679 snd_assert (ins->asynch_tx_scb != NULL, return -EINVAL); 1698 if (snd_BUG_ON(!ins->asynch_tx_scb))
1680 snd_assert (ins->spdif_pcm_input_scb != NULL,return -EINVAL); 1699 return -EINVAL;
1681 snd_assert (ins->master_mix_scb->next_scb_ptr == ins->asynch_tx_scb, return -EINVAL); 1700 if (snd_BUG_ON(!ins->spdif_pcm_input_scb))
1682 snd_assert (ins->asynch_tx_scb->parent_scb_ptr == ins->master_mix_scb, return -EINVAL); 1701 return -EINVAL;
1702 if (snd_BUG_ON(ins->master_mix_scb->next_scb_ptr != ins->asynch_tx_scb))
1703 return -EINVAL;
1704 if (snd_BUG_ON(ins->asynch_tx_scb->parent_scb_ptr !=
1705 ins->master_mix_scb))
1706 return -EINVAL;
1683 1707
1684 cs46xx_dsp_remove_scb (chip,ins->spdif_pcm_input_scb); 1708 cs46xx_dsp_remove_scb (chip,ins->spdif_pcm_input_scb);
1685 cs46xx_dsp_remove_scb (chip,ins->asynch_tx_scb); 1709 cs46xx_dsp_remove_scb (chip,ins->asynch_tx_scb);
@@ -1734,7 +1758,8 @@ int cs46xx_iec958_post_close (struct snd_cs46xx *chip)
1734{ 1758{
1735 struct dsp_spos_instance * ins = chip->dsp_spos_instance; 1759 struct dsp_spos_instance * ins = chip->dsp_spos_instance;
1736 1760
1737 snd_assert (ins->asynch_tx_scb != NULL, return -EINVAL); 1761 if (snd_BUG_ON(!ins->asynch_tx_scb))
1762 return -EINVAL;
1738 1763
1739 ins->spdif_status_out &= ~DSP_SPDIF_STATUS_PLAYBACK_OPEN; 1764 ins->spdif_status_out &= ~DSP_SPDIF_STATUS_PLAYBACK_OPEN;
1740 1765
diff --git a/sound/pci/echoaudio/darla20_dsp.c b/sound/pci/echoaudio/darla20_dsp.c
index 4159e3bc186f..29043301ebb8 100644
--- a/sound/pci/echoaudio/darla20_dsp.c
+++ b/sound/pci/echoaudio/darla20_dsp.c
@@ -34,7 +34,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
34 int err; 34 int err;
35 35
36 DE_INIT(("init_hw() - Darla20\n")); 36 DE_INIT(("init_hw() - Darla20\n"));
37 snd_assert((subdevice_id & 0xfff0) == DARLA20, return -ENODEV); 37 if (snd_BUG_ON((subdevice_id & 0xfff0) != DARLA20))
38 return -ENODEV;
38 39
39 if ((err = init_dsp_comm_page(chip))) { 40 if ((err = init_dsp_comm_page(chip))) {
40 DE_INIT(("init_hw - could not initialize DSP comm page\n")); 41 DE_INIT(("init_hw - could not initialize DSP comm page\n"));
diff --git a/sound/pci/echoaudio/darla24_dsp.c b/sound/pci/echoaudio/darla24_dsp.c
index 79938eed7e9c..60228731841f 100644
--- a/sound/pci/echoaudio/darla24_dsp.c
+++ b/sound/pci/echoaudio/darla24_dsp.c
@@ -34,7 +34,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
34 int err; 34 int err;
35 35
36 DE_INIT(("init_hw() - Darla24\n")); 36 DE_INIT(("init_hw() - Darla24\n"));
37 snd_assert((subdevice_id & 0xfff0) == DARLA24, return -ENODEV); 37 if (snd_BUG_ON((subdevice_id & 0xfff0) != DARLA24))
38 return -ENODEV;
38 39
39 if ((err = init_dsp_comm_page(chip))) { 40 if ((err = init_dsp_comm_page(chip))) {
40 DE_INIT(("init_hw - could not initialize DSP comm page\n")); 41 DE_INIT(("init_hw - could not initialize DSP comm page\n"));
@@ -148,8 +149,9 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate)
148 149
149static int set_input_clock(struct echoaudio *chip, u16 clock) 150static int set_input_clock(struct echoaudio *chip, u16 clock)
150{ 151{
151 snd_assert(clock == ECHO_CLOCK_INTERNAL || 152 if (snd_BUG_ON(clock != ECHO_CLOCK_INTERNAL &&
152 clock == ECHO_CLOCK_ESYNC, return -EINVAL); 153 clock != ECHO_CLOCK_ESYNC))
154 return -EINVAL;
153 chip->input_clock = clock; 155 chip->input_clock = clock;
154 return set_sample_rate(chip, chip->sample_rate); 156 return set_sample_rate(chip, chip->sample_rate);
155} 157}
diff --git a/sound/pci/echoaudio/echo3g_dsp.c b/sound/pci/echoaudio/echo3g_dsp.c
index 48eb7c599111..417e25add82b 100644
--- a/sound/pci/echoaudio/echo3g_dsp.c
+++ b/sound/pci/echoaudio/echo3g_dsp.c
@@ -47,7 +47,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
47 47
48 local_irq_enable(); 48 local_irq_enable();
49 DE_INIT(("init_hw() - Echo3G\n")); 49 DE_INIT(("init_hw() - Echo3G\n"));
50 snd_assert((subdevice_id & 0xfff0) == ECHO3G, return -ENODEV); 50 if (snd_BUG_ON((subdevice_id & 0xfff0) != ECHO3G))
51 return -ENODEV;
51 52
52 if ((err = init_dsp_comm_page(chip))) { 53 if ((err = init_dsp_comm_page(chip))) {
53 DE_INIT(("init_hw - could not initialize DSP comm page\n")); 54 DE_INIT(("init_hw - could not initialize DSP comm page\n"));
@@ -104,9 +105,11 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
104 if ((err = init_line_levels(chip)) < 0) 105 if ((err = init_line_levels(chip)) < 0)
105 return err; 106 return err;
106 err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA); 107 err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA);
107 snd_assert(err >= 0, return err); 108 if (err < 0)
109 return err;
108 err = set_phantom_power(chip, 0); 110 err = set_phantom_power(chip, 0);
109 snd_assert(err >= 0, return err); 111 if (err < 0)
112 return err;
110 err = set_professional_spdif(chip, TRUE); 113 err = set_professional_spdif(chip, TRUE);
111 114
112 DE_INIT(("init_hw done\n")); 115 DE_INIT(("init_hw done\n"));
diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c
index e16dc92e82fb..8dbc5c4ba421 100644
--- a/sound/pci/echoaudio/echoaudio.c
+++ b/sound/pci/echoaudio/echoaudio.c
@@ -490,7 +490,6 @@ static int init_engine(struct snd_pcm_substream *substream,
490{ 490{
491 struct echoaudio *chip; 491 struct echoaudio *chip;
492 int err, per, rest, page, edge, offs; 492 int err, per, rest, page, edge, offs;
493 struct snd_sg_buf *sgbuf;
494 struct audiopipe *pipe; 493 struct audiopipe *pipe;
495 494
496 chip = snd_pcm_substream_chip(substream); 495 chip = snd_pcm_substream_chip(substream);
@@ -503,7 +502,7 @@ static int init_engine(struct snd_pcm_substream *substream,
503 if (pipe->index >= 0) { 502 if (pipe->index >= 0) {
504 DE_HWP(("hwp_ie free(%d)\n", pipe->index)); 503 DE_HWP(("hwp_ie free(%d)\n", pipe->index));
505 err = free_pipes(chip, pipe); 504 err = free_pipes(chip, pipe);
506 snd_assert(!err); 505 snd_BUG_ON(err);
507 chip->substream[pipe->index] = NULL; 506 chip->substream[pipe->index] = NULL;
508 } 507 }
509 508
@@ -531,10 +530,6 @@ static int init_engine(struct snd_pcm_substream *substream,
531 return err; 530 return err;
532 } 531 }
533 532
534 sgbuf = snd_pcm_substream_sgbuf(substream);
535
536 DE_HWP(("pcm_hw_params table size=%d pages=%d\n",
537 sgbuf->size, sgbuf->pages));
538 sglist_init(chip, pipe); 533 sglist_init(chip, pipe);
539 edge = PAGE_SIZE; 534 edge = PAGE_SIZE;
540 for (offs = page = per = 0; offs < params_buffer_bytes(hw_params); 535 for (offs = page = per = 0; offs < params_buffer_bytes(hw_params);
@@ -543,16 +538,15 @@ static int init_engine(struct snd_pcm_substream *substream,
543 if (offs + rest > params_buffer_bytes(hw_params)) 538 if (offs + rest > params_buffer_bytes(hw_params))
544 rest = params_buffer_bytes(hw_params) - offs; 539 rest = params_buffer_bytes(hw_params) - offs;
545 while (rest) { 540 while (rest) {
541 dma_addr_t addr;
542 addr = snd_pcm_sgbuf_get_addr(substream, offs);
546 if (rest <= edge - offs) { 543 if (rest <= edge - offs) {
547 sglist_add_mapping(chip, pipe, 544 sglist_add_mapping(chip, pipe, addr, rest);
548 snd_sgbuf_get_addr(sgbuf, offs),
549 rest);
550 sglist_add_irq(chip, pipe); 545 sglist_add_irq(chip, pipe);
551 offs += rest; 546 offs += rest;
552 rest = 0; 547 rest = 0;
553 } else { 548 } else {
554 sglist_add_mapping(chip, pipe, 549 sglist_add_mapping(chip, pipe, addr,
555 snd_sgbuf_get_addr(sgbuf, offs),
556 edge - offs); 550 edge - offs);
557 rest -= edge - offs; 551 rest -= edge - offs;
558 offs = edge; 552 offs = edge;
@@ -690,8 +684,10 @@ static int pcm_prepare(struct snd_pcm_substream *substream)
690 return -EINVAL; 684 return -EINVAL;
691 } 685 }
692 686
693 snd_assert(pipe_index < px_num(chip), return -EINVAL); 687 if (snd_BUG_ON(pipe_index >= px_num(chip)))
694 snd_assert(is_pipe_allocated(chip, pipe_index), return -EINVAL); 688 return -EINVAL;
689 if (snd_BUG_ON(!is_pipe_allocated(chip, pipe_index)))
690 return -EINVAL;
695 set_audio_format(chip, pipe_index, &format); 691 set_audio_format(chip, pipe_index, &format);
696 return 0; 692 return 0;
697} 693}
diff --git a/sound/pci/echoaudio/echoaudio_3g.c b/sound/pci/echoaudio/echoaudio_3g.c
index 52a933189576..c3736bbd819e 100644
--- a/sound/pci/echoaudio/echoaudio_3g.c
+++ b/sound/pci/echoaudio/echoaudio_3g.c
@@ -103,9 +103,11 @@ static int set_digital_mode(struct echoaudio *chip, u8 mode)
103 int err, i, o; 103 int err, i, o;
104 104
105 /* All audio channels must be closed before changing the digital mode */ 105 /* All audio channels must be closed before changing the digital mode */
106 snd_assert(!chip->pipe_alloc_mask, return -EAGAIN); 106 if (snd_BUG_ON(chip->pipe_alloc_mask))
107 return -EAGAIN;
107 108
108 snd_assert(chip->digital_modes & (1 << mode), return -EINVAL); 109 if (snd_BUG_ON(!(chip->digital_modes & (1 << mode))))
110 return -EINVAL;
109 111
110 previous_mode = chip->digital_mode; 112 previous_mode = chip->digital_mode;
111 err = dsp_set_digital_mode(chip, mode); 113 err = dsp_set_digital_mode(chip, mode);
@@ -267,8 +269,9 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate)
267 return 0; 269 return 0;
268 } 270 }
269 271
270 snd_assert(rate < 50000 || chip->digital_mode != DIGITAL_MODE_ADAT, 272 if (snd_BUG_ON(rate >= 50000 &&
271 return -EINVAL); 273 chip->digital_mode == DIGITAL_MODE_ADAT))
274 return -EINVAL;
272 275
273 clock = 0; 276 clock = 0;
274 control_reg = le32_to_cpu(chip->comm_page->control_register); 277 control_reg = le32_to_cpu(chip->comm_page->control_register);
diff --git a/sound/pci/echoaudio/echoaudio_dsp.c b/sound/pci/echoaudio/echoaudio_dsp.c
index e6c100770392..be0e18192de3 100644
--- a/sound/pci/echoaudio/echoaudio_dsp.c
+++ b/sound/pci/echoaudio/echoaudio_dsp.c
@@ -474,7 +474,8 @@ static int load_firmware(struct echoaudio *chip)
474 const struct firmware *fw; 474 const struct firmware *fw;
475 int box_type, err; 475 int box_type, err;
476 476
477 snd_assert(chip->dsp_code_to_load && chip->comm_page, return -EPERM); 477 if (snd_BUG_ON(!chip->dsp_code_to_load || !chip->comm_page))
478 return -EPERM;
478 479
479 /* See if the ASIC is present and working - only if the DSP is already loaded */ 480 /* See if the ASIC is present and working - only if the DSP is already loaded */
480 if (chip->dsp_code) { 481 if (chip->dsp_code) {
@@ -512,8 +513,8 @@ static int load_firmware(struct echoaudio *chip)
512/* Set the nominal level for an input or output bus (true = -10dBV, false = +4dBu) */ 513/* Set the nominal level for an input or output bus (true = -10dBV, false = +4dBu) */
513static int set_nominal_level(struct echoaudio *chip, u16 index, char consumer) 514static int set_nominal_level(struct echoaudio *chip, u16 index, char consumer)
514{ 515{
515 snd_assert(index < num_busses_out(chip) + num_busses_in(chip), 516 if (snd_BUG_ON(index >= num_busses_out(chip) + num_busses_in(chip)))
516 return -EINVAL); 517 return -EINVAL;
517 518
518 /* Wait for the handshake (OK even if ASIC is not loaded) */ 519 /* Wait for the handshake (OK even if ASIC is not loaded) */
519 if (wait_handshake(chip)) 520 if (wait_handshake(chip))
@@ -536,7 +537,8 @@ static int set_nominal_level(struct echoaudio *chip, u16 index, char consumer)
536/* Set the gain for a single physical output channel (dB). */ 537/* Set the gain for a single physical output channel (dB). */
537static int set_output_gain(struct echoaudio *chip, u16 channel, s8 gain) 538static int set_output_gain(struct echoaudio *chip, u16 channel, s8 gain)
538{ 539{
539 snd_assert(channel < num_busses_out(chip), return -EINVAL); 540 if (snd_BUG_ON(channel >= num_busses_out(chip)))
541 return -EINVAL;
540 542
541 if (wait_handshake(chip)) 543 if (wait_handshake(chip))
542 return -EIO; 544 return -EIO;
@@ -554,8 +556,9 @@ static int set_output_gain(struct echoaudio *chip, u16 channel, s8 gain)
554static int set_monitor_gain(struct echoaudio *chip, u16 output, u16 input, 556static int set_monitor_gain(struct echoaudio *chip, u16 output, u16 input,
555 s8 gain) 557 s8 gain)
556{ 558{
557 snd_assert(output < num_busses_out(chip) && 559 if (snd_BUG_ON(output >= num_busses_out(chip) ||
558 input < num_busses_in(chip), return -EINVAL); 560 input >= num_busses_in(chip)))
561 return -EINVAL;
559 562
560 if (wait_handshake(chip)) 563 if (wait_handshake(chip))
561 return -EIO; 564 return -EIO;
@@ -1065,8 +1068,10 @@ static int free_pipes(struct echoaudio *chip, struct audiopipe *pipe)
1065 int i; 1068 int i;
1066 1069
1067 DE_ACT(("free_pipes: Pipe %d\n", pipe->index)); 1070 DE_ACT(("free_pipes: Pipe %d\n", pipe->index));
1068 snd_assert(is_pipe_allocated(chip, pipe->index), return -EINVAL); 1071 if (snd_BUG_ON(!is_pipe_allocated(chip, pipe->index)))
1069 snd_assert(pipe->state == PIPE_STATE_STOPPED, return -EINVAL); 1072 return -EINVAL;
1073 if (snd_BUG_ON(pipe->state != PIPE_STATE_STOPPED))
1074 return -EINVAL;
1070 1075
1071 for (channel_mask = i = 0; i < pipe->interleave; i++) 1076 for (channel_mask = i = 0; i < pipe->interleave; i++)
1072 channel_mask |= 1 << (pipe->index + i); 1077 channel_mask |= 1 << (pipe->index + i);
diff --git a/sound/pci/echoaudio/echoaudio_gml.c b/sound/pci/echoaudio/echoaudio_gml.c
index 3aa37e76ebab..afa273330e8a 100644
--- a/sound/pci/echoaudio/echoaudio_gml.c
+++ b/sound/pci/echoaudio/echoaudio_gml.c
@@ -112,9 +112,11 @@ static int set_digital_mode(struct echoaudio *chip, u8 mode)
112 return -EIO; 112 return -EIO;
113 113
114 /* All audio channels must be closed before changing the digital mode */ 114 /* All audio channels must be closed before changing the digital mode */
115 snd_assert(!chip->pipe_alloc_mask, return -EAGAIN); 115 if (snd_BUG_ON(chip->pipe_alloc_mask))
116 return -EAGAIN;
116 117
117 snd_assert(chip->digital_modes & (1 << mode), return -EINVAL); 118 if (snd_BUG_ON(!(chip->digital_modes & (1 << mode))))
119 return -EINVAL;
118 120
119 previous_mode = chip->digital_mode; 121 previous_mode = chip->digital_mode;
120 err = dsp_set_digital_mode(chip, mode); 122 err = dsp_set_digital_mode(chip, mode);
diff --git a/sound/pci/echoaudio/gina20_dsp.c b/sound/pci/echoaudio/gina20_dsp.c
index 2757c8960843..db6c952e9d7f 100644
--- a/sound/pci/echoaudio/gina20_dsp.c
+++ b/sound/pci/echoaudio/gina20_dsp.c
@@ -38,7 +38,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
38 int err; 38 int err;
39 39
40 DE_INIT(("init_hw() - Gina20\n")); 40 DE_INIT(("init_hw() - Gina20\n"));
41 snd_assert((subdevice_id & 0xfff0) == GINA20, return -ENODEV); 41 if (snd_BUG_ON((subdevice_id & 0xfff0) != GINA20))
42 return -ENODEV;
42 43
43 if ((err = init_dsp_comm_page(chip))) { 44 if ((err = init_dsp_comm_page(chip))) {
44 DE_INIT(("init_hw - could not initialize DSP comm page\n")); 45 DE_INIT(("init_hw - could not initialize DSP comm page\n"));
@@ -177,7 +178,8 @@ static int set_input_clock(struct echoaudio *chip, u16 clock)
177/* Set input bus gain (one unit is 0.5dB !) */ 178/* Set input bus gain (one unit is 0.5dB !) */
178static int set_input_gain(struct echoaudio *chip, u16 input, int gain) 179static int set_input_gain(struct echoaudio *chip, u16 input, int gain)
179{ 180{
180 snd_assert(input < num_busses_in(chip), return -EINVAL); 181 if (snd_BUG_ON(input >= num_busses_in(chip)))
182 return -EINVAL;
181 183
182 if (wait_handshake(chip)) 184 if (wait_handshake(chip))
183 return -EIO; 185 return -EIO;
diff --git a/sound/pci/echoaudio/gina24_dsp.c b/sound/pci/echoaudio/gina24_dsp.c
index 144fc567becf..2fef37a2a5b9 100644
--- a/sound/pci/echoaudio/gina24_dsp.c
+++ b/sound/pci/echoaudio/gina24_dsp.c
@@ -43,7 +43,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
43 int err; 43 int err;
44 44
45 DE_INIT(("init_hw() - Gina24\n")); 45 DE_INIT(("init_hw() - Gina24\n"));
46 snd_assert((subdevice_id & 0xfff0) == GINA24, return -ENODEV); 46 if (snd_BUG_ON((subdevice_id & 0xfff0) != GINA24))
47 return -ENODEV;
47 48
48 if ((err = init_dsp_comm_page(chip))) { 49 if ((err = init_dsp_comm_page(chip))) {
49 DE_INIT(("init_hw - could not initialize DSP comm page\n")); 50 DE_INIT(("init_hw - could not initialize DSP comm page\n"));
@@ -84,7 +85,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
84 if ((err = init_line_levels(chip)) < 0) 85 if ((err = init_line_levels(chip)) < 0)
85 return err; 86 return err;
86 err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA); 87 err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA);
87 snd_assert(err >= 0, return err); 88 if (err < 0)
89 return err;
88 err = set_professional_spdif(chip, TRUE); 90 err = set_professional_spdif(chip, TRUE);
89 91
90 DE_INIT(("init_hw done\n")); 92 DE_INIT(("init_hw done\n"));
@@ -163,8 +165,9 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate)
163{ 165{
164 u32 control_reg, clock; 166 u32 control_reg, clock;
165 167
166 snd_assert(rate < 50000 || chip->digital_mode != DIGITAL_MODE_ADAT, 168 if (snd_BUG_ON(rate >= 50000 &&
167 return -EINVAL); 169 chip->digital_mode == DIGITAL_MODE_ADAT))
170 return -EINVAL;
168 171
169 /* Only set the clock for internal mode. */ 172 /* Only set the clock for internal mode. */
170 if (chip->input_clock != ECHO_CLOCK_INTERNAL) { 173 if (chip->input_clock != ECHO_CLOCK_INTERNAL) {
diff --git a/sound/pci/echoaudio/indigo_dsp.c b/sound/pci/echoaudio/indigo_dsp.c
index d6ac7734609e..f05e39f7aad9 100644
--- a/sound/pci/echoaudio/indigo_dsp.c
+++ b/sound/pci/echoaudio/indigo_dsp.c
@@ -39,7 +39,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
39 int err; 39 int err;
40 40
41 DE_INIT(("init_hw() - Indigo\n")); 41 DE_INIT(("init_hw() - Indigo\n"));
42 snd_assert((subdevice_id & 0xfff0) == INDIGO, return -ENODEV); 42 if (snd_BUG_ON((subdevice_id & 0xfff0) != INDIGO))
43 return -ENODEV;
43 44
44 if ((err = init_dsp_comm_page(chip))) { 45 if ((err = init_dsp_comm_page(chip))) {
45 DE_INIT(("init_hw - could not initialize DSP comm page\n")); 46 DE_INIT(("init_hw - could not initialize DSP comm page\n"));
@@ -143,8 +144,9 @@ static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe,
143{ 144{
144 int index; 145 int index;
145 146
146 snd_assert(pipe < num_pipes_out(chip) && 147 if (snd_BUG_ON(pipe >= num_pipes_out(chip) ||
147 output < num_busses_out(chip), return -EINVAL); 148 output >= num_busses_out(chip)))
149 return -EINVAL;
148 150
149 if (wait_handshake(chip)) 151 if (wait_handshake(chip))
150 return -EIO; 152 return -EIO;
diff --git a/sound/pci/echoaudio/indigodj_dsp.c b/sound/pci/echoaudio/indigodj_dsp.c
index 500e150b49fc..90730a5ecb42 100644
--- a/sound/pci/echoaudio/indigodj_dsp.c
+++ b/sound/pci/echoaudio/indigodj_dsp.c
@@ -39,7 +39,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
39 int err; 39 int err;
40 40
41 DE_INIT(("init_hw() - Indigo DJ\n")); 41 DE_INIT(("init_hw() - Indigo DJ\n"));
42 snd_assert((subdevice_id & 0xfff0) == INDIGO_DJ, return -ENODEV); 42 if (snd_BUG_ON((subdevice_id & 0xfff0) != INDIGO_DJ))
43 return -ENODEV;
43 44
44 if ((err = init_dsp_comm_page(chip))) { 45 if ((err = init_dsp_comm_page(chip))) {
45 DE_INIT(("init_hw - could not initialize DSP comm page\n")); 46 DE_INIT(("init_hw - could not initialize DSP comm page\n"));
@@ -143,8 +144,9 @@ static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe,
143{ 144{
144 int index; 145 int index;
145 146
146 snd_assert(pipe < num_pipes_out(chip) && 147 if (snd_BUG_ON(pipe >= num_pipes_out(chip) ||
147 output < num_busses_out(chip), return -EINVAL); 148 output >= num_busses_out(chip)))
149 return -EINVAL;
148 150
149 if (wait_handshake(chip)) 151 if (wait_handshake(chip))
150 return -EIO; 152 return -EIO;
diff --git a/sound/pci/echoaudio/indigoio_dsp.c b/sound/pci/echoaudio/indigoio_dsp.c
index f3ad13d06be0..a7e09ec21079 100644
--- a/sound/pci/echoaudio/indigoio_dsp.c
+++ b/sound/pci/echoaudio/indigoio_dsp.c
@@ -39,7 +39,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
39 int err; 39 int err;
40 40
41 DE_INIT(("init_hw() - Indigo IO\n")); 41 DE_INIT(("init_hw() - Indigo IO\n"));
42 snd_assert((subdevice_id & 0xfff0) == INDIGO_IO, return -ENODEV); 42 if (snd_BUG_ON((subdevice_id & 0xfff0) != INDIGO_IO))
43 return -ENODEV;
43 44
44 if ((err = init_dsp_comm_page(chip))) { 45 if ((err = init_dsp_comm_page(chip))) {
45 DE_INIT(("init_hw - could not initialize DSP comm page\n")); 46 DE_INIT(("init_hw - could not initialize DSP comm page\n"));
@@ -114,8 +115,9 @@ static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe,
114{ 115{
115 int index; 116 int index;
116 117
117 snd_assert(pipe < num_pipes_out(chip) && 118 if (snd_BUG_ON(pipe >= num_pipes_out(chip) ||
118 output < num_busses_out(chip), return -EINVAL); 119 output >= num_busses_out(chip)))
120 return -EINVAL;
119 121
120 if (wait_handshake(chip)) 122 if (wait_handshake(chip))
121 return -EIO; 123 return -EIO;
diff --git a/sound/pci/echoaudio/layla20_dsp.c b/sound/pci/echoaudio/layla20_dsp.c
index 990c9a60a0a8..ede75c6ca0fb 100644
--- a/sound/pci/echoaudio/layla20_dsp.c
+++ b/sound/pci/echoaudio/layla20_dsp.c
@@ -42,7 +42,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
42 int err; 42 int err;
43 43
44 DE_INIT(("init_hw() - Layla20\n")); 44 DE_INIT(("init_hw() - Layla20\n"));
45 snd_assert((subdevice_id & 0xfff0) == LAYLA20, return -ENODEV); 45 if (snd_BUG_ON((subdevice_id & 0xfff0) != LAYLA20))
46 return -ENODEV;
46 47
47 if ((err = init_dsp_comm_page(chip))) { 48 if ((err = init_dsp_comm_page(chip))) {
48 DE_INIT(("init_hw - could not initialize DSP comm page\n")); 49 DE_INIT(("init_hw - could not initialize DSP comm page\n"));
@@ -155,7 +156,8 @@ static int load_asic(struct echoaudio *chip)
155 156
156static int set_sample_rate(struct echoaudio *chip, u32 rate) 157static int set_sample_rate(struct echoaudio *chip, u32 rate)
157{ 158{
158 snd_assert(rate >= 8000 && rate <= 50000, return -EINVAL); 159 if (snd_BUG_ON(rate < 8000 || rate > 50000))
160 return -EINVAL;
159 161
160 /* Only set the clock for internal mode. Do not return failure, 162 /* Only set the clock for internal mode. Do not return failure,
161 simply treat it as a non-event. */ 163 simply treat it as a non-event. */
@@ -252,7 +254,8 @@ static int set_output_clock(struct echoaudio *chip, u16 clock)
252/* Set input bus gain (one unit is 0.5dB !) */ 254/* Set input bus gain (one unit is 0.5dB !) */
253static int set_input_gain(struct echoaudio *chip, u16 input, int gain) 255static int set_input_gain(struct echoaudio *chip, u16 input, int gain)
254{ 256{
255 snd_assert(input < num_busses_in(chip), return -EINVAL); 257 if (snd_BUG_ON(input >= num_busses_in(chip)))
258 return -EINVAL;
256 259
257 if (wait_handshake(chip)) 260 if (wait_handshake(chip))
258 return -EIO; 261 return -EIO;
diff --git a/sound/pci/echoaudio/layla24_dsp.c b/sound/pci/echoaudio/layla24_dsp.c
index 97e42e115147..d61b5cbcccad 100644
--- a/sound/pci/echoaudio/layla24_dsp.c
+++ b/sound/pci/echoaudio/layla24_dsp.c
@@ -42,7 +42,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
42 int err; 42 int err;
43 43
44 DE_INIT(("init_hw() - Layla24\n")); 44 DE_INIT(("init_hw() - Layla24\n"));
45 snd_assert((subdevice_id & 0xfff0) == LAYLA24, return -ENODEV); 45 if (snd_BUG_ON((subdevice_id & 0xfff0) != LAYLA24))
46 return -ENODEV;
46 47
47 if ((err = init_dsp_comm_page(chip))) { 48 if ((err = init_dsp_comm_page(chip))) {
48 DE_INIT(("init_hw - could not initialize DSP comm page\n")); 49 DE_INIT(("init_hw - could not initialize DSP comm page\n"));
@@ -73,7 +74,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
73 return err; 74 return err;
74 75
75 err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA); 76 err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA);
76 snd_assert(err >= 0, return err); 77 if (err < 0)
78 return err;
77 err = set_professional_spdif(chip, TRUE); 79 err = set_professional_spdif(chip, TRUE);
78 80
79 DE_INIT(("init_hw done\n")); 81 DE_INIT(("init_hw done\n"));
@@ -158,8 +160,9 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate)
158{ 160{
159 u32 control_reg, clock, base_rate; 161 u32 control_reg, clock, base_rate;
160 162
161 snd_assert(rate < 50000 || chip->digital_mode != DIGITAL_MODE_ADAT, 163 if (snd_BUG_ON(rate >= 50000 &&
162 return -EINVAL); 164 chip->digital_mode == DIGITAL_MODE_ADAT))
165 return -EINVAL;
163 166
164 /* Only set the clock for internal mode. */ 167 /* Only set the clock for internal mode. */
165 if (chip->input_clock != ECHO_CLOCK_INTERNAL) { 168 if (chip->input_clock != ECHO_CLOCK_INTERNAL) {
diff --git a/sound/pci/echoaudio/mia_dsp.c b/sound/pci/echoaudio/mia_dsp.c
index 891c70519096..227386602f9b 100644
--- a/sound/pci/echoaudio/mia_dsp.c
+++ b/sound/pci/echoaudio/mia_dsp.c
@@ -42,7 +42,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
42 int err; 42 int err;
43 43
44 DE_INIT(("init_hw() - Mia\n")); 44 DE_INIT(("init_hw() - Mia\n"));
45 snd_assert((subdevice_id & 0xfff0) == MIA, return -ENODEV); 45 if (snd_BUG_ON((subdevice_id & 0xfff0) != MIA))
46 return -ENODEV;
46 47
47 if ((err = init_dsp_comm_page(chip))) { 48 if ((err = init_dsp_comm_page(chip))) {
48 DE_INIT(("init_hw - could not initialize DSP comm page\n")); 49 DE_INIT(("init_hw - could not initialize DSP comm page\n"));
@@ -161,8 +162,9 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate)
161static int set_input_clock(struct echoaudio *chip, u16 clock) 162static int set_input_clock(struct echoaudio *chip, u16 clock)
162{ 163{
163 DE_ACT(("set_input_clock(%d)\n", clock)); 164 DE_ACT(("set_input_clock(%d)\n", clock));
164 snd_assert(clock == ECHO_CLOCK_INTERNAL || clock == ECHO_CLOCK_SPDIF, 165 if (snd_BUG_ON(clock != ECHO_CLOCK_INTERNAL &&
165 return -EINVAL); 166 clock != ECHO_CLOCK_SPDIF))
167 return -EINVAL;
166 168
167 chip->input_clock = clock; 169 chip->input_clock = clock;
168 return set_sample_rate(chip, chip->sample_rate); 170 return set_sample_rate(chip, chip->sample_rate);
@@ -176,8 +178,9 @@ static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe,
176{ 178{
177 int index; 179 int index;
178 180
179 snd_assert(pipe < num_pipes_out(chip) && 181 if (snd_BUG_ON(pipe >= num_pipes_out(chip) ||
180 output < num_busses_out(chip), return -EINVAL); 182 output >= num_busses_out(chip)))
183 return -EINVAL;
181 184
182 if (wait_handshake(chip)) 185 if (wait_handshake(chip))
183 return -EIO; 186 return -EIO;
diff --git a/sound/pci/echoaudio/midi.c b/sound/pci/echoaudio/midi.c
index 91f5bff66d3f..77bf2a83d997 100644
--- a/sound/pci/echoaudio/midi.c
+++ b/sound/pci/echoaudio/midi.c
@@ -59,7 +59,8 @@ static int enable_midi_input(struct echoaudio *chip, char enable)
59Returns how many actually written or < 0 on error */ 59Returns how many actually written or < 0 on error */
60static int write_midi(struct echoaudio *chip, u8 *data, int bytes) 60static int write_midi(struct echoaudio *chip, u8 *data, int bytes)
61{ 61{
62 snd_assert(bytes > 0 && bytes < MIDI_OUT_BUFFER_SIZE, return -EINVAL); 62 if (snd_BUG_ON(bytes <= 0 || bytes >= MIDI_OUT_BUFFER_SIZE))
63 return -EINVAL;
63 64
64 if (wait_handshake(chip)) 65 if (wait_handshake(chip))
65 return -EIO; 66 return -EIO;
@@ -119,7 +120,8 @@ static int midi_service_irq(struct echoaudio *chip)
119 /* The count is at index 0, followed by actual data */ 120 /* The count is at index 0, followed by actual data */
120 count = le16_to_cpu(chip->comm_page->midi_input[0]); 121 count = le16_to_cpu(chip->comm_page->midi_input[0]);
121 122
122 snd_assert(count < MIDI_IN_BUFFER_SIZE, return 0); 123 if (snd_BUG_ON(count >= MIDI_IN_BUFFER_SIZE))
124 return 0;
123 125
124 /* Get the MIDI data from the comm page */ 126 /* Get the MIDI data from the comm page */
125 i = 1; 127 i = 1;
diff --git a/sound/pci/echoaudio/mona_dsp.c b/sound/pci/echoaudio/mona_dsp.c
index c0b4bf0be7d1..eaa619bd2a03 100644
--- a/sound/pci/echoaudio/mona_dsp.c
+++ b/sound/pci/echoaudio/mona_dsp.c
@@ -43,7 +43,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
43 int err; 43 int err;
44 44
45 DE_INIT(("init_hw() - Mona\n")); 45 DE_INIT(("init_hw() - Mona\n"));
46 snd_assert((subdevice_id & 0xfff0) == MONA, return -ENODEV); 46 if (snd_BUG_ON((subdevice_id & 0xfff0) != MONA))
47 return -ENODEV;
47 48
48 if ((err = init_dsp_comm_page(chip))) { 49 if ((err = init_dsp_comm_page(chip))) {
49 DE_INIT(("init_hw - could not initialize DSP comm page\n")); 50 DE_INIT(("init_hw - could not initialize DSP comm page\n"));
@@ -79,7 +80,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
79 return err; 80 return err;
80 81
81 err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA); 82 err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA);
82 snd_assert(err >= 0, return err); 83 if (err < 0)
84 return err;
83 err = set_professional_spdif(chip, TRUE); 85 err = set_professional_spdif(chip, TRUE);
84 86
85 DE_INIT(("init_hw done\n")); 87 DE_INIT(("init_hw done\n"));
diff --git a/sound/pci/emu10k1/emu10k1_callback.c b/sound/pci/emu10k1/emu10k1_callback.c
index 45088ebcce50..0e649dcdbf64 100644
--- a/sound/pci/emu10k1/emu10k1_callback.c
+++ b/sound/pci/emu10k1/emu10k1_callback.c
@@ -145,7 +145,8 @@ terminate_voice(struct snd_emux_voice *vp)
145{ 145{
146 struct snd_emu10k1 *hw; 146 struct snd_emu10k1 *hw;
147 147
148 snd_assert(vp, return); 148 if (snd_BUG_ON(!vp))
149 return;
149 hw = vp->hw; 150 hw = vp->hw;
150 snd_emu10k1_ptr_write(hw, DCYSUSV, vp->ch, 0x807f | DCYSUSV_CHANNELENABLE_MASK); 151 snd_emu10k1_ptr_write(hw, DCYSUSV, vp->ch, 0x807f | DCYSUSV_CHANNELENABLE_MASK);
151 if (vp->block) { 152 if (vp->block) {
@@ -325,7 +326,8 @@ start_voice(struct snd_emux_voice *vp)
325 326
326 hw = vp->hw; 327 hw = vp->hw;
327 ch = vp->ch; 328 ch = vp->ch;
328 snd_assert(ch >= 0, return -EINVAL); 329 if (snd_BUG_ON(ch < 0))
330 return -EINVAL;
329 chan = vp->chan; 331 chan = vp->chan;
330 332
331 emem = (struct snd_emu10k1_memblk *)vp->block; 333 emem = (struct snd_emu10k1_memblk *)vp->block;
diff --git a/sound/pci/emu10k1/emu10k1_patch.c b/sound/pci/emu10k1/emu10k1_patch.c
index 42bae6f7e9a4..e10f027bde03 100644
--- a/sound/pci/emu10k1/emu10k1_patch.c
+++ b/sound/pci/emu10k1/emu10k1_patch.c
@@ -46,8 +46,8 @@ snd_emu10k1_sample_new(struct snd_emux *rec, struct snd_sf_sample *sp,
46 struct snd_emu10k1 *emu; 46 struct snd_emu10k1 *emu;
47 47
48 emu = rec->hw; 48 emu = rec->hw;
49 snd_assert(sp != NULL, return -EINVAL); 49 if (snd_BUG_ON(!sp || !hdr))
50 snd_assert(hdr != NULL, return -EINVAL); 50 return -EINVAL;
51 51
52 if (sp->v.size == 0) { 52 if (sp->v.size == 0) {
53 snd_printd("emu: rom font for sample %d\n", sp->v.sample); 53 snd_printd("emu: rom font for sample %d\n", sp->v.sample);
@@ -104,7 +104,8 @@ snd_emu10k1_sample_new(struct snd_emux *rec, struct snd_sf_sample *sp,
104 size = BLANK_HEAD_SIZE; 104 size = BLANK_HEAD_SIZE;
105 if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS)) 105 if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS))
106 size *= 2; 106 size *= 2;
107 snd_assert(offset + size <= blocksize, return -EINVAL); 107 if (offset + size > blocksize)
108 return -EINVAL;
108 snd_emu10k1_synth_bzero(emu, sp->block, offset, size); 109 snd_emu10k1_synth_bzero(emu, sp->block, offset, size);
109 offset += size; 110 offset += size;
110 111
@@ -112,7 +113,8 @@ snd_emu10k1_sample_new(struct snd_emux *rec, struct snd_sf_sample *sp,
112 size = loopend; 113 size = loopend;
113 if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS)) 114 if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS))
114 size *= 2; 115 size *= 2;
115 snd_assert(offset + size <= blocksize, return -EINVAL); 116 if (offset + size > blocksize)
117 return -EINVAL;
116 if (snd_emu10k1_synth_copy_from_user(emu, sp->block, offset, data, size)) { 118 if (snd_emu10k1_synth_copy_from_user(emu, sp->block, offset, data, size)) {
117 snd_emu10k1_synth_free(emu, sp->block); 119 snd_emu10k1_synth_free(emu, sp->block);
118 sp->block = NULL; 120 sp->block = NULL;
@@ -129,12 +131,14 @@ snd_emu10k1_sample_new(struct snd_emux *rec, struct snd_sf_sample *sp,
129 int woffset; 131 int woffset;
130 unsigned short *wblock = (unsigned short*)block; 132 unsigned short *wblock = (unsigned short*)block;
131 woffset = offset / 2; 133 woffset = offset / 2;
132 snd_assert(offset + loopsize*2 <= blocksize, return -EINVAL); 134 if (offset + loopsize * 2 > blocksize)
135 return -EINVAL;
133 for (i = 0; i < loopsize; i++) 136 for (i = 0; i < loopsize; i++)
134 wblock[woffset + i] = wblock[woffset - i -1]; 137 wblock[woffset + i] = wblock[woffset - i -1];
135 offset += loopsize * 2; 138 offset += loopsize * 2;
136 } else { 139 } else {
137 snd_assert(offset + loopsize <= blocksize, return -EINVAL); 140 if (offset + loopsize > blocksize)
141 return -EINVAL;
138 for (i = 0; i < loopsize; i++) 142 for (i = 0; i < loopsize; i++)
139 block[offset + i] = block[offset - i -1]; 143 block[offset + i] = block[offset - i -1];
140 offset += loopsize; 144 offset += loopsize;
@@ -154,7 +158,8 @@ snd_emu10k1_sample_new(struct snd_emux *rec, struct snd_sf_sample *sp,
154 158
155 /* loopend -> sample end */ 159 /* loopend -> sample end */
156 size = sp->v.size - loopend; 160 size = sp->v.size - loopend;
157 snd_assert(size >= 0, return -EINVAL); 161 if (size < 0)
162 return -EINVAL;
158 if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS)) 163 if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS))
159 size *= 2; 164 size *= 2;
160 if (snd_emu10k1_synth_copy_from_user(emu, sp->block, offset, data, size)) { 165 if (snd_emu10k1_synth_copy_from_user(emu, sp->block, offset, data, size)) {
@@ -212,8 +217,8 @@ snd_emu10k1_sample_free(struct snd_emux *rec, struct snd_sf_sample *sp,
212 struct snd_emu10k1 *emu; 217 struct snd_emu10k1 *emu;
213 218
214 emu = rec->hw; 219 emu = rec->hw;
215 snd_assert(sp != NULL, return -EINVAL); 220 if (snd_BUG_ON(!sp || !hdr))
216 snd_assert(hdr != NULL, return -EINVAL); 221 return -EINVAL;
217 222
218 if (sp->block) { 223 if (sp->block) {
219 snd_emu10k1_synth_free(emu, sp->block); 224 snd_emu10k1_synth_free(emu, sp->block);
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c
index 491a4a50f869..5ff4dbb62dad 100644
--- a/sound/pci/emu10k1/emu10k1x.c
+++ b/sound/pci/emu10k1/emu10k1x.c
@@ -1319,7 +1319,8 @@ static int snd_emu10k1x_midi_input_open(struct snd_rawmidi_substream *substream)
1319 unsigned long flags; 1319 unsigned long flags;
1320 1320
1321 emu = midi->emu; 1321 emu = midi->emu;
1322 snd_assert(emu, return -ENXIO); 1322 if (snd_BUG_ON(!emu))
1323 return -ENXIO;
1323 spin_lock_irqsave(&midi->open_lock, flags); 1324 spin_lock_irqsave(&midi->open_lock, flags);
1324 midi->midi_mode |= EMU10K1X_MIDI_MODE_INPUT; 1325 midi->midi_mode |= EMU10K1X_MIDI_MODE_INPUT;
1325 midi->substream_input = substream; 1326 midi->substream_input = substream;
@@ -1345,7 +1346,8 @@ static int snd_emu10k1x_midi_output_open(struct snd_rawmidi_substream *substream
1345 unsigned long flags; 1346 unsigned long flags;
1346 1347
1347 emu = midi->emu; 1348 emu = midi->emu;
1348 snd_assert(emu, return -ENXIO); 1349 if (snd_BUG_ON(!emu))
1350 return -ENXIO;
1349 spin_lock_irqsave(&midi->open_lock, flags); 1351 spin_lock_irqsave(&midi->open_lock, flags);
1350 midi->midi_mode |= EMU10K1X_MIDI_MODE_OUTPUT; 1352 midi->midi_mode |= EMU10K1X_MIDI_MODE_OUTPUT;
1351 midi->substream_output = substream; 1353 midi->substream_output = substream;
@@ -1372,7 +1374,8 @@ static int snd_emu10k1x_midi_input_close(struct snd_rawmidi_substream *substream
1372 int err = 0; 1374 int err = 0;
1373 1375
1374 emu = midi->emu; 1376 emu = midi->emu;
1375 snd_assert(emu, return -ENXIO); 1377 if (snd_BUG_ON(!emu))
1378 return -ENXIO;
1376 spin_lock_irqsave(&midi->open_lock, flags); 1379 spin_lock_irqsave(&midi->open_lock, flags);
1377 snd_emu10k1x_intr_disable(emu, midi->rx_enable); 1380 snd_emu10k1x_intr_disable(emu, midi->rx_enable);
1378 midi->midi_mode &= ~EMU10K1X_MIDI_MODE_INPUT; 1381 midi->midi_mode &= ~EMU10K1X_MIDI_MODE_INPUT;
@@ -1394,7 +1397,8 @@ static int snd_emu10k1x_midi_output_close(struct snd_rawmidi_substream *substrea
1394 int err = 0; 1397 int err = 0;
1395 1398
1396 emu = midi->emu; 1399 emu = midi->emu;
1397 snd_assert(emu, return -ENXIO); 1400 if (snd_BUG_ON(!emu))
1401 return -ENXIO;
1398 spin_lock_irqsave(&midi->open_lock, flags); 1402 spin_lock_irqsave(&midi->open_lock, flags);
1399 snd_emu10k1x_intr_disable(emu, midi->tx_enable); 1403 snd_emu10k1x_intr_disable(emu, midi->tx_enable);
1400 midi->midi_mode &= ~EMU10K1X_MIDI_MODE_OUTPUT; 1404 midi->midi_mode &= ~EMU10K1X_MIDI_MODE_OUTPUT;
@@ -1413,7 +1417,8 @@ static void snd_emu10k1x_midi_input_trigger(struct snd_rawmidi_substream *substr
1413 struct emu10k1x *emu; 1417 struct emu10k1x *emu;
1414 struct emu10k1x_midi *midi = substream->rmidi->private_data; 1418 struct emu10k1x_midi *midi = substream->rmidi->private_data;
1415 emu = midi->emu; 1419 emu = midi->emu;
1416 snd_assert(emu, return); 1420 if (snd_BUG_ON(!emu))
1421 return;
1417 1422
1418 if (up) 1423 if (up)
1419 snd_emu10k1x_intr_enable(emu, midi->rx_enable); 1424 snd_emu10k1x_intr_enable(emu, midi->rx_enable);
@@ -1428,7 +1433,8 @@ static void snd_emu10k1x_midi_output_trigger(struct snd_rawmidi_substream *subst
1428 unsigned long flags; 1433 unsigned long flags;
1429 1434
1430 emu = midi->emu; 1435 emu = midi->emu;
1431 snd_assert(emu, return); 1436 if (snd_BUG_ON(!emu))
1437 return;
1432 1438
1433 if (up) { 1439 if (up) {
1434 int max = 4; 1440 int max = 4;
diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c
index 71dc4c8865b8..7dba08f0ab8e 100644
--- a/sound/pci/emu10k1/emufx.c
+++ b/sound/pci/emu10k1/emufx.c
@@ -487,7 +487,8 @@ static void snd_emu10k1_write_op(struct snd_emu10k1_fx8010_code *icode,
487 u32 op, u32 r, u32 a, u32 x, u32 y) 487 u32 op, u32 r, u32 a, u32 x, u32 y)
488{ 488{
489 u_int32_t *code; 489 u_int32_t *code;
490 snd_assert(*ptr < 512, return); 490 if (snd_BUG_ON(*ptr >= 512))
491 return;
491 code = (u_int32_t __force *)icode->code + (*ptr) * 2; 492 code = (u_int32_t __force *)icode->code + (*ptr) * 2;
492 set_bit(*ptr, icode->code_valid); 493 set_bit(*ptr, icode->code_valid);
493 code[0] = ((x & 0x3ff) << 10) | (y & 0x3ff); 494 code[0] = ((x & 0x3ff) << 10) | (y & 0x3ff);
@@ -503,7 +504,8 @@ static void snd_emu10k1_audigy_write_op(struct snd_emu10k1_fx8010_code *icode,
503 u32 op, u32 r, u32 a, u32 x, u32 y) 504 u32 op, u32 r, u32 a, u32 x, u32 y)
504{ 505{
505 u_int32_t *code; 506 u_int32_t *code;
506 snd_assert(*ptr < 1024, return); 507 if (snd_BUG_ON(*ptr >= 1024))
508 return;
507 code = (u_int32_t __force *)icode->code + (*ptr) * 2; 509 code = (u_int32_t __force *)icode->code + (*ptr) * 2;
508 set_bit(*ptr, icode->code_valid); 510 set_bit(*ptr, icode->code_valid);
509 code[0] = ((x & 0x7ff) << 12) | (y & 0x7ff); 511 code[0] = ((x & 0x7ff) << 12) | (y & 0x7ff);
diff --git a/sound/pci/emu10k1/emumpu401.c b/sound/pci/emu10k1/emumpu401.c
index c4d76d16661e..8578c70c61f2 100644
--- a/sound/pci/emu10k1/emumpu401.c
+++ b/sound/pci/emu10k1/emumpu401.c
@@ -157,7 +157,8 @@ static int snd_emu10k1_midi_input_open(struct snd_rawmidi_substream *substream)
157 unsigned long flags; 157 unsigned long flags;
158 158
159 emu = midi->emu; 159 emu = midi->emu;
160 snd_assert(emu, return -ENXIO); 160 if (snd_BUG_ON(!emu))
161 return -ENXIO;
161 spin_lock_irqsave(&midi->open_lock, flags); 162 spin_lock_irqsave(&midi->open_lock, flags);
162 midi->midi_mode |= EMU10K1_MIDI_MODE_INPUT; 163 midi->midi_mode |= EMU10K1_MIDI_MODE_INPUT;
163 midi->substream_input = substream; 164 midi->substream_input = substream;
@@ -183,7 +184,8 @@ static int snd_emu10k1_midi_output_open(struct snd_rawmidi_substream *substream)
183 unsigned long flags; 184 unsigned long flags;
184 185
185 emu = midi->emu; 186 emu = midi->emu;
186 snd_assert(emu, return -ENXIO); 187 if (snd_BUG_ON(!emu))
188 return -ENXIO;
187 spin_lock_irqsave(&midi->open_lock, flags); 189 spin_lock_irqsave(&midi->open_lock, flags);
188 midi->midi_mode |= EMU10K1_MIDI_MODE_OUTPUT; 190 midi->midi_mode |= EMU10K1_MIDI_MODE_OUTPUT;
189 midi->substream_output = substream; 191 midi->substream_output = substream;
@@ -210,7 +212,8 @@ static int snd_emu10k1_midi_input_close(struct snd_rawmidi_substream *substream)
210 int err = 0; 212 int err = 0;
211 213
212 emu = midi->emu; 214 emu = midi->emu;
213 snd_assert(emu, return -ENXIO); 215 if (snd_BUG_ON(!emu))
216 return -ENXIO;
214 spin_lock_irqsave(&midi->open_lock, flags); 217 spin_lock_irqsave(&midi->open_lock, flags);
215 snd_emu10k1_intr_disable(emu, midi->rx_enable); 218 snd_emu10k1_intr_disable(emu, midi->rx_enable);
216 midi->midi_mode &= ~EMU10K1_MIDI_MODE_INPUT; 219 midi->midi_mode &= ~EMU10K1_MIDI_MODE_INPUT;
@@ -232,7 +235,8 @@ static int snd_emu10k1_midi_output_close(struct snd_rawmidi_substream *substream
232 int err = 0; 235 int err = 0;
233 236
234 emu = midi->emu; 237 emu = midi->emu;
235 snd_assert(emu, return -ENXIO); 238 if (snd_BUG_ON(!emu))
239 return -ENXIO;
236 spin_lock_irqsave(&midi->open_lock, flags); 240 spin_lock_irqsave(&midi->open_lock, flags);
237 snd_emu10k1_intr_disable(emu, midi->tx_enable); 241 snd_emu10k1_intr_disable(emu, midi->tx_enable);
238 midi->midi_mode &= ~EMU10K1_MIDI_MODE_OUTPUT; 242 midi->midi_mode &= ~EMU10K1_MIDI_MODE_OUTPUT;
@@ -251,7 +255,8 @@ static void snd_emu10k1_midi_input_trigger(struct snd_rawmidi_substream *substre
251 struct snd_emu10k1 *emu; 255 struct snd_emu10k1 *emu;
252 struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data; 256 struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;
253 emu = midi->emu; 257 emu = midi->emu;
254 snd_assert(emu, return); 258 if (snd_BUG_ON(!emu))
259 return;
255 260
256 if (up) 261 if (up)
257 snd_emu10k1_intr_enable(emu, midi->rx_enable); 262 snd_emu10k1_intr_enable(emu, midi->rx_enable);
@@ -266,7 +271,8 @@ static void snd_emu10k1_midi_output_trigger(struct snd_rawmidi_substream *substr
266 unsigned long flags; 271 unsigned long flags;
267 272
268 emu = midi->emu; 273 emu = midi->emu;
269 snd_assert(emu, return); 274 if (snd_BUG_ON(!emu))
275 return;
270 276
271 if (up) { 277 if (up) {
272 int max = 4; 278 int max = 4;
diff --git a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c
index 7d379f5131fb..6a47672f930a 100644
--- a/sound/pci/emu10k1/memory.c
+++ b/sound/pci/emu10k1/memory.c
@@ -107,7 +107,8 @@ static int search_empty_map_area(struct snd_emu10k1 *emu, int npages, struct lis
107 107
108 list_for_each (pos, &emu->mapped_link_head) { 108 list_for_each (pos, &emu->mapped_link_head) {
109 struct snd_emu10k1_memblk *blk = get_emu10k1_memblk(pos, mapped_link); 109 struct snd_emu10k1_memblk *blk = get_emu10k1_memblk(pos, mapped_link);
110 snd_assert(blk->mapped_page >= 0, continue); 110 if (blk->mapped_page < 0)
111 continue;
111 size = blk->mapped_page - page; 112 size = blk->mapped_page - page;
112 if (size == npages) { 113 if (size == npages) {
113 *nextp = pos; 114 *nextp = pos;
@@ -295,15 +296,18 @@ struct snd_util_memblk *
295snd_emu10k1_alloc_pages(struct snd_emu10k1 *emu, struct snd_pcm_substream *substream) 296snd_emu10k1_alloc_pages(struct snd_emu10k1 *emu, struct snd_pcm_substream *substream)
296{ 297{
297 struct snd_pcm_runtime *runtime = substream->runtime; 298 struct snd_pcm_runtime *runtime = substream->runtime;
298 struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream);
299 struct snd_util_memhdr *hdr; 299 struct snd_util_memhdr *hdr;
300 struct snd_emu10k1_memblk *blk; 300 struct snd_emu10k1_memblk *blk;
301 int page, err, idx; 301 int page, err, idx;
302 302
303 snd_assert(emu, return NULL); 303 if (snd_BUG_ON(!emu))
304 snd_assert(runtime->dma_bytes > 0 && runtime->dma_bytes < MAXPAGES * EMUPAGESIZE, return NULL); 304 return NULL;
305 if (snd_BUG_ON(runtime->dma_bytes <= 0 ||
306 runtime->dma_bytes >= MAXPAGES * EMUPAGESIZE))
307 return NULL;
305 hdr = emu->memhdr; 308 hdr = emu->memhdr;
306 snd_assert(hdr, return NULL); 309 if (snd_BUG_ON(!hdr))
310 return NULL;
307 311
308 mutex_lock(&hdr->block_mutex); 312 mutex_lock(&hdr->block_mutex);
309 blk = search_empty(emu, runtime->dma_bytes); 313 blk = search_empty(emu, runtime->dma_bytes);
@@ -316,16 +320,9 @@ snd_emu10k1_alloc_pages(struct snd_emu10k1 *emu, struct snd_pcm_substream *subst
316 */ 320 */
317 idx = 0; 321 idx = 0;
318 for (page = blk->first_page; page <= blk->last_page; page++, idx++) { 322 for (page = blk->first_page; page <= blk->last_page; page++, idx++) {
323 unsigned long ofs = idx << PAGE_SHIFT;
319 dma_addr_t addr; 324 dma_addr_t addr;
320#ifdef CONFIG_SND_DEBUG 325 addr = snd_pcm_sgbuf_get_addr(substream, ofs);
321 if (idx >= sgbuf->pages) {
322 printk(KERN_ERR "emu: pages overflow! (%d-%d) for %d\n",
323 blk->first_page, blk->last_page, sgbuf->pages);
324 mutex_unlock(&hdr->block_mutex);
325 return NULL;
326 }
327#endif
328 addr = sgbuf->table[idx].addr;
329 if (! is_valid_page(emu, addr)) { 326 if (! is_valid_page(emu, addr)) {
330 printk(KERN_ERR "emu: failure page = %d\n", idx); 327 printk(KERN_ERR "emu: failure page = %d\n", idx);
331 mutex_unlock(&hdr->block_mutex); 328 mutex_unlock(&hdr->block_mutex);
@@ -353,7 +350,8 @@ snd_emu10k1_alloc_pages(struct snd_emu10k1 *emu, struct snd_pcm_substream *subst
353 */ 350 */
354int snd_emu10k1_free_pages(struct snd_emu10k1 *emu, struct snd_util_memblk *blk) 351int snd_emu10k1_free_pages(struct snd_emu10k1 *emu, struct snd_util_memblk *blk)
355{ 352{
356 snd_assert(emu && blk, return -EINVAL); 353 if (snd_BUG_ON(!emu || !blk))
354 return -EINVAL;
357 return snd_emu10k1_synth_free(emu, blk); 355 return snd_emu10k1_synth_free(emu, blk);
358} 356}
359 357
@@ -498,7 +496,8 @@ static int synth_free_pages(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *
498static inline void *offset_ptr(struct snd_emu10k1 *emu, int page, int offset) 496static inline void *offset_ptr(struct snd_emu10k1 *emu, int page, int offset)
499{ 497{
500 char *ptr; 498 char *ptr;
501 snd_assert(page >= 0 && page < emu->max_cache_pages, return NULL); 499 if (snd_BUG_ON(page < 0 || page >= emu->max_cache_pages))
500 return NULL;
502 ptr = emu->page_ptr_table[page]; 501 ptr = emu->page_ptr_table[page];
503 if (! ptr) { 502 if (! ptr) {
504 printk(KERN_ERR "emu10k1: access to NULL ptr: page = %d\n", page); 503 printk(KERN_ERR "emu10k1: access to NULL ptr: page = %d\n", page);
diff --git a/sound/pci/emu10k1/voice.c b/sound/pci/emu10k1/voice.c
index 958cb2a65a4e..d7300a1aa262 100644
--- a/sound/pci/emu10k1/voice.c
+++ b/sound/pci/emu10k1/voice.c
@@ -111,8 +111,10 @@ int snd_emu10k1_voice_alloc(struct snd_emu10k1 *emu, int type, int number,
111 unsigned long flags; 111 unsigned long flags;
112 int result; 112 int result;
113 113
114 snd_assert(rvoice != NULL, return -EINVAL); 114 if (snd_BUG_ON(!rvoice))
115 snd_assert(number, return -EINVAL); 115 return -EINVAL;
116 if (snd_BUG_ON(!number))
117 return -EINVAL;
116 118
117 spin_lock_irqsave(&emu->voice_lock, flags); 119 spin_lock_irqsave(&emu->voice_lock, flags);
118 for (;;) { 120 for (;;) {
@@ -145,7 +147,8 @@ int snd_emu10k1_voice_free(struct snd_emu10k1 *emu,
145{ 147{
146 unsigned long flags; 148 unsigned long flags;
147 149
148 snd_assert(pvoice != NULL, return -EINVAL); 150 if (snd_BUG_ON(!pvoice))
151 return -EINVAL;
149 spin_lock_irqsave(&emu->voice_lock, flags); 152 spin_lock_irqsave(&emu->voice_lock, flags);
150 pvoice->interrupt = NULL; 153 pvoice->interrupt = NULL;
151 pvoice->use = pvoice->pcm = pvoice->synth = pvoice->midi = pvoice->efx = 0; 154 pvoice->use = pvoice->pcm = pvoice->synth = pvoice->midi = pvoice->efx = 0;
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c
index 84fac1fbf103..4cd9a1faaecc 100644
--- a/sound/pci/es1938.c
+++ b/sound/pci/es1938.c
@@ -860,7 +860,8 @@ static int snd_es1938_capture_copy(struct snd_pcm_substream *substream,
860 struct es1938 *chip = snd_pcm_substream_chip(substream); 860 struct es1938 *chip = snd_pcm_substream_chip(substream);
861 pos <<= chip->dma1_shift; 861 pos <<= chip->dma1_shift;
862 count <<= chip->dma1_shift; 862 count <<= chip->dma1_shift;
863 snd_assert(pos + count <= chip->dma1_size, return -EINVAL); 863 if (snd_BUG_ON(pos + count > chip->dma1_size))
864 return -EINVAL;
864 if (pos + count < chip->dma1_size) { 865 if (pos + count < chip->dma1_size) {
865 if (copy_to_user(dst, runtime->dma_area + pos + 1, count)) 866 if (copy_to_user(dst, runtime->dma_area + pos + 1, count))
866 return -EFAULT; 867 return -EFAULT;
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index 1bf298d214b9..20ee7599600b 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -692,7 +692,8 @@ static void apu_data_set(struct es1968 *chip, u16 data)
692/* no spinlock */ 692/* no spinlock */
693static void __apu_set_register(struct es1968 *chip, u16 channel, u8 reg, u16 data) 693static void __apu_set_register(struct es1968 *chip, u16 channel, u8 reg, u16 data)
694{ 694{
695 snd_assert(channel < NR_APUS, return); 695 if (snd_BUG_ON(channel >= NR_APUS))
696 return;
696#ifdef CONFIG_PM 697#ifdef CONFIG_PM
697 chip->apu_map[channel][reg] = data; 698 chip->apu_map[channel][reg] = data;
698#endif 699#endif
@@ -711,7 +712,8 @@ static void apu_set_register(struct es1968 *chip, u16 channel, u8 reg, u16 data)
711 712
712static u16 __apu_get_register(struct es1968 *chip, u16 channel, u8 reg) 713static u16 __apu_get_register(struct es1968 *chip, u16 channel, u8 reg)
713{ 714{
714 snd_assert(channel < NR_APUS, return 0); 715 if (snd_BUG_ON(channel >= NR_APUS))
716 return 0;
715 reg |= (channel << 4); 717 reg |= (channel << 4);
716 apu_index_set(chip, reg); 718 apu_index_set(chip, reg);
717 return __maestro_read(chip, IDR0_DATA_PORT); 719 return __maestro_read(chip, IDR0_DATA_PORT);
diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile
index ab0c726d648e..1980c6d207e7 100644
--- a/sound/pci/hda/Makefile
+++ b/sound/pci/hda/Makefile
@@ -5,6 +5,7 @@ snd-hda-intel-y := hda_intel.o
5snd-hda-intel-y += hda_codec.o 5snd-hda-intel-y += hda_codec.o
6snd-hda-intel-$(CONFIG_PROC_FS) += hda_proc.o 6snd-hda-intel-$(CONFIG_PROC_FS) += hda_proc.o
7snd-hda-intel-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o 7snd-hda-intel-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o
8snd-hda-intel-$(CONFIG_SND_HDA_INPUT_BEEP) += hda_beep.o
8snd-hda-intel-$(CONFIG_SND_HDA_GENERIC) += hda_generic.o 9snd-hda-intel-$(CONFIG_SND_HDA_GENERIC) += hda_generic.o
9snd-hda-intel-$(CONFIG_SND_HDA_CODEC_REALTEK) += patch_realtek.o 10snd-hda-intel-$(CONFIG_SND_HDA_CODEC_REALTEK) += patch_realtek.o
10snd-hda-intel-$(CONFIG_SND_HDA_CODEC_CMEDIA) += patch_cmedia.o 11snd-hda-intel-$(CONFIG_SND_HDA_CODEC_CMEDIA) += patch_cmedia.o
@@ -14,5 +15,6 @@ snd-hda-intel-$(CONFIG_SND_HDA_CODEC_SI3054) += patch_si3054.o
14snd-hda-intel-$(CONFIG_SND_HDA_CODEC_ATIHDMI) += patch_atihdmi.o 15snd-hda-intel-$(CONFIG_SND_HDA_CODEC_ATIHDMI) += patch_atihdmi.o
15snd-hda-intel-$(CONFIG_SND_HDA_CODEC_CONEXANT) += patch_conexant.o 16snd-hda-intel-$(CONFIG_SND_HDA_CODEC_CONEXANT) += patch_conexant.o
16snd-hda-intel-$(CONFIG_SND_HDA_CODEC_VIA) += patch_via.o 17snd-hda-intel-$(CONFIG_SND_HDA_CODEC_VIA) += patch_via.o
18snd-hda-intel-$(CONFIG_SND_HDA_CODEC_NVHDMI) += patch_nvhdmi.o
17 19
18obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-intel.o 20obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-intel.o
diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c
new file mode 100644
index 000000000000..9b77b3e0fa98
--- /dev/null
+++ b/sound/pci/hda/hda_beep.c
@@ -0,0 +1,134 @@
1/*
2 * Digital Beep Input Interface for HD-audio codec
3 *
4 * Author: Matthew Ranostay <mranostay@embeddedalley.com>
5 * Copyright (c) 2008 Embedded Alley Solutions Inc
6 *
7 * This driver is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This driver is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#include <linux/input.h>
23#include <linux/pci.h>
24#include <linux/workqueue.h>
25#include <sound/core.h>
26#include "hda_beep.h"
27
28enum {
29 DIGBEEP_HZ_STEP = 46875, /* 46.875 Hz */
30 DIGBEEP_HZ_MIN = 93750, /* 93.750 Hz */
31 DIGBEEP_HZ_MAX = 12000000, /* 12 KHz */
32};
33
34static void snd_hda_generate_beep(struct work_struct *work)
35{
36 struct hda_beep *beep =
37 container_of(work, struct hda_beep, beep_work);
38 struct hda_codec *codec = beep->codec;
39
40 /* generate tone */
41 snd_hda_codec_write_cache(codec, beep->nid, 0,
42 AC_VERB_SET_BEEP_CONTROL, beep->tone);
43}
44
45static int snd_hda_beep_event(struct input_dev *dev, unsigned int type,
46 unsigned int code, int hz)
47{
48 struct hda_beep *beep = input_get_drvdata(dev);
49
50 switch (code) {
51 case SND_BELL:
52 if (hz)
53 hz = 1000;
54 case SND_TONE:
55 hz *= 1000; /* fixed point */
56 hz = hz - DIGBEEP_HZ_MIN;
57 if (hz < 0)
58 hz = 0; /* turn off PC beep*/
59 else if (hz >= (DIGBEEP_HZ_MAX - DIGBEEP_HZ_MIN))
60 hz = 0xff;
61 else {
62 hz /= DIGBEEP_HZ_STEP;
63 hz++;
64 }
65 break;
66 default:
67 return -1;
68 }
69 beep->tone = hz;
70
71 /* schedule beep event */
72 schedule_work(&beep->beep_work);
73 return 0;
74}
75
76int snd_hda_attach_beep_device(struct hda_codec *codec, int nid)
77{
78 struct input_dev *input_dev;
79 struct hda_beep *beep;
80 int err;
81
82 beep = kzalloc(sizeof(*beep), GFP_KERNEL);
83 if (beep == NULL)
84 return -ENOMEM;
85 snprintf(beep->phys, sizeof(beep->phys),
86 "card%d/codec#%d/beep0", codec->bus->card->number, codec->addr);
87 input_dev = input_allocate_device();
88
89 /* setup digital beep device */
90 input_dev->name = "HDA Digital PCBeep";
91 input_dev->phys = beep->phys;
92 input_dev->id.bustype = BUS_PCI;
93
94 input_dev->id.vendor = codec->vendor_id >> 16;
95 input_dev->id.product = codec->vendor_id & 0xffff;
96 input_dev->id.version = 0x01;
97
98 input_dev->evbit[0] = BIT_MASK(EV_SND);
99 input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
100 input_dev->event = snd_hda_beep_event;
101 input_dev->dev.parent = &codec->bus->pci->dev;
102 input_set_drvdata(input_dev, beep);
103
104 err = input_register_device(input_dev);
105 if (err < 0) {
106 input_free_device(input_dev);
107 kfree(beep);
108 return err;
109 }
110
111 /* enable linear scale */
112 snd_hda_codec_write(codec, nid, 0,
113 AC_VERB_SET_DIGI_CONVERT_2, 0x01);
114
115 beep->nid = nid;
116 beep->dev = input_dev;
117 beep->codec = codec;
118 codec->beep = beep;
119
120 INIT_WORK(&beep->beep_work, &snd_hda_generate_beep);
121 return 0;
122}
123
124void snd_hda_detach_beep_device(struct hda_codec *codec)
125{
126 struct hda_beep *beep = codec->beep;
127 if (beep) {
128 cancel_work_sync(&beep->beep_work);
129 flush_scheduled_work();
130
131 input_unregister_device(beep->dev);
132 kfree(beep);
133 }
134}
diff --git a/sound/pci/hda/hda_beep.h b/sound/pci/hda/hda_beep.h
new file mode 100644
index 000000000000..de4036e6e710
--- /dev/null
+++ b/sound/pci/hda/hda_beep.h
@@ -0,0 +1,44 @@
1/*
2 * Digital Beep Input Interface for HD-audio codec
3 *
4 * Author: Matthew Ranostay <mranostay@embeddedalley.com>
5 * Copyright (c) 2008 Embedded Alley Solutions Inc
6 *
7 * This driver is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This driver is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#ifndef __SOUND_HDA_BEEP_H
23#define __SOUND_HDA_BEEP_H
24
25#include "hda_codec.h"
26
27/* beep information */
28struct hda_beep {
29 struct input_dev *dev;
30 struct hda_codec *codec;
31 char phys[32];
32 int tone;
33 int nid;
34 struct work_struct beep_work; /* scheduled task for beep event */
35};
36
37#ifdef CONFIG_SND_HDA_INPUT_BEEP
38int snd_hda_attach_beep_device(struct hda_codec *codec, int nid);
39void snd_hda_detach_beep_device(struct hda_codec *codec);
40#else
41#define snd_hda_attach_beep_device(...)
42#define snd_hda_detach_beep_device(...)
43#endif
44#endif
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index d2e1093f8e97..6447754ae56e 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -94,6 +94,9 @@ static const struct hda_codec_preset *hda_preset_tables[] = {
94#ifdef CONFIG_SND_HDA_CODEC_VIA 94#ifdef CONFIG_SND_HDA_CODEC_VIA
95 snd_hda_preset_via, 95 snd_hda_preset_via,
96#endif 96#endif
97#ifdef CONFIG_SND_HDA_CODEC_NVHDMI
98 snd_hda_preset_nvhdmi,
99#endif
97 NULL 100 NULL
98}; 101};
99 102
@@ -211,7 +214,8 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
211 unsigned int shift, num_elems, mask; 214 unsigned int shift, num_elems, mask;
212 hda_nid_t prev_nid; 215 hda_nid_t prev_nid;
213 216
214 snd_assert(conn_list && max_conns > 0, return -EINVAL); 217 if (snd_BUG_ON(!conn_list || max_conns <= 0))
218 return -EINVAL;
215 219
216 parm = snd_hda_param_read(codec, nid, AC_PAR_CONNLIST_LEN); 220 parm = snd_hda_param_read(codec, nid, AC_PAR_CONNLIST_LEN);
217 if (parm & AC_CLIST_LONG) { 221 if (parm & AC_CLIST_LONG) {
@@ -313,7 +317,7 @@ int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex)
313} 317}
314 318
315/* 319/*
316 * process queueud unsolicited events 320 * process queued unsolicited events
317 */ 321 */
318static void process_unsol_events(struct work_struct *work) 322static void process_unsol_events(struct work_struct *work)
319{ 323{
@@ -407,8 +411,10 @@ int __devinit snd_hda_bus_new(struct snd_card *card,
407 .dev_free = snd_hda_bus_dev_free, 411 .dev_free = snd_hda_bus_dev_free,
408 }; 412 };
409 413
410 snd_assert(temp, return -EINVAL); 414 if (snd_BUG_ON(!temp))
411 snd_assert(temp->ops.command && temp->ops.get_response, return -EINVAL); 415 return -EINVAL;
416 if (snd_BUG_ON(!temp->ops.command || !temp->ops.get_response))
417 return -EINVAL;
412 418
413 if (busp) 419 if (busp)
414 *busp = NULL; 420 *busp = NULL;
@@ -585,11 +591,13 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
585 struct hda_codec **codecp) 591 struct hda_codec **codecp)
586{ 592{
587 struct hda_codec *codec; 593 struct hda_codec *codec;
588 char component[13]; 594 char component[31];
589 int err; 595 int err;
590 596
591 snd_assert(bus, return -EINVAL); 597 if (snd_BUG_ON(!bus))
592 snd_assert(codec_addr <= HDA_MAX_CODEC_ADDRESS, return -EINVAL); 598 return -EINVAL;
599 if (snd_BUG_ON(codec_addr > HDA_MAX_CODEC_ADDRESS))
600 return -EINVAL;
593 601
594 if (bus->caddr_tbl[codec_addr]) { 602 if (bus->caddr_tbl[codec_addr]) {
595 snd_printk(KERN_ERR "hda_codec: " 603 snd_printk(KERN_ERR "hda_codec: "
@@ -688,7 +696,7 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
688 snd_hda_create_hwdep(codec); 696 snd_hda_create_hwdep(codec);
689#endif 697#endif
690 698
691 sprintf(component, "HDA:%08x", codec->vendor_id); 699 sprintf(component, "HDA:%08x,%08x,%08x", codec->vendor_id, codec->subsystem_id, codec->revision_id);
692 snd_component_add(codec->bus->card, component); 700 snd_component_add(codec->bus->card, component);
693 701
694 if (codecp) 702 if (codecp)
@@ -956,15 +964,6 @@ void snd_hda_codec_resume_amp(struct hda_codec *codec)
956} 964}
957#endif /* SND_HDA_NEEDS_RESUME */ 965#endif /* SND_HDA_NEEDS_RESUME */
958 966
959/*
960 * AMP control callbacks
961 */
962/* retrieve parameters from private_value */
963#define get_amp_nid(kc) ((kc)->private_value & 0xffff)
964#define get_amp_channels(kc) (((kc)->private_value >> 16) & 0x3)
965#define get_amp_direction(kc) (((kc)->private_value >> 18) & 0x1)
966#define get_amp_index(kc) (((kc)->private_value >> 19) & 0xf)
967
968/* volume */ 967/* volume */
969int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, 968int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol,
970 struct snd_ctl_elem_info *uinfo) 969 struct snd_ctl_elem_info *uinfo)
@@ -1430,6 +1429,29 @@ static unsigned int convert_to_spdif_status(unsigned short val)
1430 return sbits; 1429 return sbits;
1431} 1430}
1432 1431
1432/* set digital convert verbs both for the given NID and its slaves */
1433static void set_dig_out(struct hda_codec *codec, hda_nid_t nid,
1434 int verb, int val)
1435{
1436 hda_nid_t *d;
1437
1438 snd_hda_codec_write(codec, nid, 0, verb, val);
1439 d = codec->slave_dig_outs;
1440 if (!d)
1441 return;
1442 for (; *d; d++)
1443 snd_hda_codec_write(codec, *d, 0, verb, val);
1444}
1445
1446static inline void set_dig_out_convert(struct hda_codec *codec, hda_nid_t nid,
1447 int dig1, int dig2)
1448{
1449 if (dig1 != -1)
1450 set_dig_out(codec, nid, AC_VERB_SET_DIGI_CONVERT_1, dig1);
1451 if (dig2 != -1)
1452 set_dig_out(codec, nid, AC_VERB_SET_DIGI_CONVERT_2, dig2);
1453}
1454
1433static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol, 1455static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol,
1434 struct snd_ctl_elem_value *ucontrol) 1456 struct snd_ctl_elem_value *ucontrol)
1435{ 1457{
@@ -1448,14 +1470,8 @@ static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol,
1448 change = codec->spdif_ctls != val; 1470 change = codec->spdif_ctls != val;
1449 codec->spdif_ctls = val; 1471 codec->spdif_ctls = val;
1450 1472
1451 if (change) { 1473 if (change)
1452 snd_hda_codec_write_cache(codec, nid, 0, 1474 set_dig_out_convert(codec, nid, val & 0xff, (val >> 8) & 0xff);
1453 AC_VERB_SET_DIGI_CONVERT_1,
1454 val & 0xff);
1455 snd_hda_codec_write_cache(codec, nid, 0,
1456 AC_VERB_SET_DIGI_CONVERT_2,
1457 val >> 8);
1458 }
1459 1475
1460 mutex_unlock(&codec->spdif_mutex); 1476 mutex_unlock(&codec->spdif_mutex);
1461 return change; 1477 return change;
@@ -1487,9 +1503,7 @@ static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol,
1487 change = codec->spdif_ctls != val; 1503 change = codec->spdif_ctls != val;
1488 if (change) { 1504 if (change) {
1489 codec->spdif_ctls = val; 1505 codec->spdif_ctls = val;
1490 snd_hda_codec_write_cache(codec, nid, 0, 1506 set_dig_out_convert(codec, nid, val & 0xff, -1);
1491 AC_VERB_SET_DIGI_CONVERT_1,
1492 val & 0xff);
1493 /* unmute amp switch (if any) */ 1507 /* unmute amp switch (if any) */
1494 if ((get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) && 1508 if ((get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) &&
1495 (val & AC_DIG1_ENABLE)) 1509 (val & AC_DIG1_ENABLE))
@@ -2236,11 +2250,13 @@ static int __devinit set_pcm_default_values(struct hda_codec *codec,
2236 if (info->ops.close == NULL) 2250 if (info->ops.close == NULL)
2237 info->ops.close = hda_pcm_default_open_close; 2251 info->ops.close = hda_pcm_default_open_close;
2238 if (info->ops.prepare == NULL) { 2252 if (info->ops.prepare == NULL) {
2239 snd_assert(info->nid, return -EINVAL); 2253 if (snd_BUG_ON(!info->nid))
2254 return -EINVAL;
2240 info->ops.prepare = hda_pcm_default_prepare; 2255 info->ops.prepare = hda_pcm_default_prepare;
2241 } 2256 }
2242 if (info->ops.cleanup == NULL) { 2257 if (info->ops.cleanup == NULL) {
2243 snd_assert(info->nid, return -EINVAL); 2258 if (snd_BUG_ON(!info->nid))
2259 return -EINVAL;
2244 info->ops.cleanup = hda_pcm_default_cleanup; 2260 info->ops.cleanup = hda_pcm_default_cleanup;
2245 } 2261 }
2246 return 0; 2262 return 0;
@@ -2583,14 +2599,31 @@ static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid,
2583 unsigned int stream_tag, unsigned int format) 2599 unsigned int stream_tag, unsigned int format)
2584{ 2600{
2585 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */ 2601 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
2586 if (codec->spdif_ctls & AC_DIG1_ENABLE) 2602 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE))
2587 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, 2603 set_dig_out_convert(codec, nid,
2588 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff); 2604 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff,
2605 -1);
2589 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format); 2606 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
2607 if (codec->slave_dig_outs) {
2608 hda_nid_t *d;
2609 for (d = codec->slave_dig_outs; *d; d++)
2610 snd_hda_codec_setup_stream(codec, *d, stream_tag, 0,
2611 format);
2612 }
2590 /* turn on again (if needed) */ 2613 /* turn on again (if needed) */
2591 if (codec->spdif_ctls & AC_DIG1_ENABLE) 2614 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE))
2592 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, 2615 set_dig_out_convert(codec, nid,
2593 codec->spdif_ctls & 0xff); 2616 codec->spdif_ctls & 0xff, -1);
2617}
2618
2619static void cleanup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid)
2620{
2621 snd_hda_codec_cleanup_stream(codec, nid);
2622 if (codec->slave_dig_outs) {
2623 hda_nid_t *d;
2624 for (d = codec->slave_dig_outs; *d; d++)
2625 snd_hda_codec_cleanup_stream(codec, *d);
2626 }
2594} 2627}
2595 2628
2596/* 2629/*
@@ -2602,7 +2635,7 @@ int snd_hda_multi_out_dig_open(struct hda_codec *codec,
2602 mutex_lock(&codec->spdif_mutex); 2635 mutex_lock(&codec->spdif_mutex);
2603 if (mout->dig_out_used == HDA_DIG_ANALOG_DUP) 2636 if (mout->dig_out_used == HDA_DIG_ANALOG_DUP)
2604 /* already opened as analog dup; reset it once */ 2637 /* already opened as analog dup; reset it once */
2605 snd_hda_codec_cleanup_stream(codec, mout->dig_out_nid); 2638 cleanup_dig_out_stream(codec, mout->dig_out_nid);
2606 mout->dig_out_used = HDA_DIG_EXCLUSIVE; 2639 mout->dig_out_used = HDA_DIG_EXCLUSIVE;
2607 mutex_unlock(&codec->spdif_mutex); 2640 mutex_unlock(&codec->spdif_mutex);
2608 return 0; 2641 return 0;
@@ -2697,7 +2730,7 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec,
2697 stream_tag, format); 2730 stream_tag, format);
2698 } else { 2731 } else {
2699 mout->dig_out_used = 0; 2732 mout->dig_out_used = 0;
2700 snd_hda_codec_cleanup_stream(codec, mout->dig_out_nid); 2733 cleanup_dig_out_stream(codec, mout->dig_out_nid);
2701 } 2734 }
2702 } 2735 }
2703 mutex_unlock(&codec->spdif_mutex); 2736 mutex_unlock(&codec->spdif_mutex);
@@ -2748,7 +2781,7 @@ int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec,
2748 mout->extra_out_nid[i]); 2781 mout->extra_out_nid[i]);
2749 mutex_lock(&codec->spdif_mutex); 2782 mutex_lock(&codec->spdif_mutex);
2750 if (mout->dig_out_nid && mout->dig_out_used == HDA_DIG_ANALOG_DUP) { 2783 if (mout->dig_out_nid && mout->dig_out_used == HDA_DIG_ANALOG_DUP) {
2751 snd_hda_codec_cleanup_stream(codec, mout->dig_out_nid); 2784 cleanup_dig_out_stream(codec, mout->dig_out_nid);
2752 mout->dig_out_used = 0; 2785 mout->dig_out_used = 0;
2753 } 2786 }
2754 mutex_unlock(&codec->spdif_mutex); 2787 mutex_unlock(&codec->spdif_mutex);
@@ -2756,7 +2789,7 @@ int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec,
2756} 2789}
2757 2790
2758/* 2791/*
2759 * Helper for automatic ping configuration 2792 * Helper for automatic pin configuration
2760 */ 2793 */
2761 2794
2762static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list) 2795static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list)
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index efc682888b31..60468f562400 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -90,6 +90,14 @@ enum {
90#define AC_VERB_GET_CONFIG_DEFAULT 0x0f1c 90#define AC_VERB_GET_CONFIG_DEFAULT 0x0f1c
91/* f20: AFG/MFG */ 91/* f20: AFG/MFG */
92#define AC_VERB_GET_SUBSYSTEM_ID 0x0f20 92#define AC_VERB_GET_SUBSYSTEM_ID 0x0f20
93#define AC_VERB_GET_CVT_CHAN_COUNT 0x0f2d
94#define AC_VERB_GET_HDMI_DIP_SIZE 0x0f2e
95#define AC_VERB_GET_HDMI_ELDD 0x0f2f
96#define AC_VERB_GET_HDMI_DIP_INDEX 0x0f30
97#define AC_VERB_GET_HDMI_DIP_DATA 0x0f31
98#define AC_VERB_GET_HDMI_DIP_XMIT 0x0f32
99#define AC_VERB_GET_HDMI_CP_CTRL 0x0f33
100#define AC_VERB_GET_HDMI_CHAN_SLOT 0x0f34
93 101
94/* 102/*
95 * SET verbs 103 * SET verbs
@@ -121,7 +129,14 @@ enum {
121#define AC_VERB_SET_CONFIG_DEFAULT_BYTES_1 0x71d 129#define AC_VERB_SET_CONFIG_DEFAULT_BYTES_1 0x71d
122#define AC_VERB_SET_CONFIG_DEFAULT_BYTES_2 0x71e 130#define AC_VERB_SET_CONFIG_DEFAULT_BYTES_2 0x71e
123#define AC_VERB_SET_CONFIG_DEFAULT_BYTES_3 0x71f 131#define AC_VERB_SET_CONFIG_DEFAULT_BYTES_3 0x71f
132#define AC_VERB_SET_EAPD 0x788
124#define AC_VERB_SET_CODEC_RESET 0x7ff 133#define AC_VERB_SET_CODEC_RESET 0x7ff
134#define AC_VERB_SET_CVT_CHAN_COUNT 0x72d
135#define AC_VERB_SET_HDMI_DIP_INDEX 0x730
136#define AC_VERB_SET_HDMI_DIP_DATA 0x731
137#define AC_VERB_SET_HDMI_DIP_XMIT 0x732
138#define AC_VERB_SET_HDMI_CP_CTRL 0x733
139#define AC_VERB_SET_HDMI_CHAN_SLOT 0x734
125 140
126/* 141/*
127 * Parameter IDs 142 * Parameter IDs
@@ -143,6 +158,7 @@ enum {
143#define AC_PAR_GPIO_CAP 0x11 158#define AC_PAR_GPIO_CAP 0x11
144#define AC_PAR_AMP_OUT_CAP 0x12 159#define AC_PAR_AMP_OUT_CAP 0x12
145#define AC_PAR_VOL_KNB_CAP 0x13 160#define AC_PAR_VOL_KNB_CAP 0x13
161#define AC_PAR_HDMI_LPCM_CAP 0x20
146 162
147/* 163/*
148 * AC_VERB_PARAMETERS results (32bit) 164 * AC_VERB_PARAMETERS results (32bit)
@@ -171,6 +187,8 @@ enum {
171#define AC_WCAP_DIGITAL (1<<9) /* digital I/O */ 187#define AC_WCAP_DIGITAL (1<<9) /* digital I/O */
172#define AC_WCAP_POWER (1<<10) /* power control */ 188#define AC_WCAP_POWER (1<<10) /* power control */
173#define AC_WCAP_LR_SWAP (1<<11) /* L/R swap */ 189#define AC_WCAP_LR_SWAP (1<<11) /* L/R swap */
190#define AC_WCAP_CP_CAPS (1<<12) /* content protection */
191#define AC_WCAP_CHAN_CNT_EXT (7<<13) /* channel count ext */
174#define AC_WCAP_DELAY (0xf<<16) 192#define AC_WCAP_DELAY (0xf<<16)
175#define AC_WCAP_DELAY_SHIFT 16 193#define AC_WCAP_DELAY_SHIFT 16
176#define AC_WCAP_TYPE (0xf<<20) 194#define AC_WCAP_TYPE (0xf<<20)
@@ -206,9 +224,20 @@ enum {
206/* Input converter SDI select */ 224/* Input converter SDI select */
207#define AC_SDI_SELECT (0xf<<0) 225#define AC_SDI_SELECT (0xf<<0)
208 226
209/* Unsolicited response */ 227/* Unsolicited response control */
210#define AC_UNSOL_TAG (0x3f<<0) 228#define AC_UNSOL_TAG (0x3f<<0)
211#define AC_UNSOL_ENABLED (1<<7) 229#define AC_UNSOL_ENABLED (1<<7)
230#define AC_USRSP_EN AC_UNSOL_ENABLED
231
232/* Unsolicited responses */
233#define AC_UNSOL_RES_TAG (0x3f<<26)
234#define AC_UNSOL_RES_TAG_SHIFT 26
235#define AC_UNSOL_RES_SUBTAG (0x1f<<21)
236#define AC_UNSOL_RES_SUBTAG_SHIFT 21
237#define AC_UNSOL_RES_ELDV (1<<1) /* ELD Data valid (for HDMI) */
238#define AC_UNSOL_RES_PD (1<<0) /* pinsense detect */
239#define AC_UNSOL_RES_CP_STATE (1<<1) /* content protection */
240#define AC_UNSOL_RES_CP_READY (1<<0) /* content protection */
212 241
213/* Pin widget capabilies */ 242/* Pin widget capabilies */
214#define AC_PINCAP_IMP_SENSE (1<<0) /* impedance sense capable */ 243#define AC_PINCAP_IMP_SENSE (1<<0) /* impedance sense capable */
@@ -222,6 +251,10 @@ enum {
222 * but is marked reserved in the Intel HDA specification. 251 * but is marked reserved in the Intel HDA specification.
223 */ 252 */
224#define AC_PINCAP_LR_SWAP (1<<7) /* L/R swap */ 253#define AC_PINCAP_LR_SWAP (1<<7) /* L/R swap */
254/* Note: The same bit as LR_SWAP is newly defined as HDMI capability
255 * in HD-audio specification
256 */
257#define AC_PINCAP_HDMI (1<<7) /* HDMI pin */
225#define AC_PINCAP_VREF (0x37<<8) 258#define AC_PINCAP_VREF (0x37<<8)
226#define AC_PINCAP_VREF_SHIFT 8 259#define AC_PINCAP_VREF_SHIFT 8
227#define AC_PINCAP_EAPD (1<<16) /* EAPD capable */ 260#define AC_PINCAP_EAPD (1<<16) /* EAPD capable */
@@ -272,6 +305,22 @@ enum {
272#define AC_KNBCAP_NUM_STEPS (0x7f<<0) 305#define AC_KNBCAP_NUM_STEPS (0x7f<<0)
273#define AC_KNBCAP_DELTA (1<<7) 306#define AC_KNBCAP_DELTA (1<<7)
274 307
308/* HDMI LPCM capabilities */
309#define AC_LPCMCAP_48K_CP_CHNS (0x0f<<0) /* max channels w/ CP-on */
310#define AC_LPCMCAP_48K_NO_CHNS (0x0f<<4) /* max channels w/o CP-on */
311#define AC_LPCMCAP_48K_20BIT (1<<8) /* 20b bitrate supported */
312#define AC_LPCMCAP_48K_24BIT (1<<9) /* 24b bitrate supported */
313#define AC_LPCMCAP_96K_CP_CHNS (0x0f<<10) /* max channels w/ CP-on */
314#define AC_LPCMCAP_96K_NO_CHNS (0x0f<<14) /* max channels w/o CP-on */
315#define AC_LPCMCAP_96K_20BIT (1<<18) /* 20b bitrate supported */
316#define AC_LPCMCAP_96K_24BIT (1<<19) /* 24b bitrate supported */
317#define AC_LPCMCAP_192K_CP_CHNS (0x0f<<20) /* max channels w/ CP-on */
318#define AC_LPCMCAP_192K_NO_CHNS (0x0f<<24) /* max channels w/o CP-on */
319#define AC_LPCMCAP_192K_20BIT (1<<28) /* 20b bitrate supported */
320#define AC_LPCMCAP_192K_24BIT (1<<29) /* 24b bitrate supported */
321#define AC_LPCMCAP_44K (1<<30) /* 44.1kHz support */
322#define AC_LPCMCAP_44K_MS (1<<31) /* 44.1kHz-multiplies support */
323
275/* 324/*
276 * Control Parameters 325 * Control Parameters
277 */ 326 */
@@ -317,18 +366,44 @@ enum {
317#define AC_PINCTL_OUT_EN (1<<6) 366#define AC_PINCTL_OUT_EN (1<<6)
318#define AC_PINCTL_HP_EN (1<<7) 367#define AC_PINCTL_HP_EN (1<<7)
319 368
320/* Unsolicited response - 8bit */
321#define AC_USRSP_EN (1<<7)
322
323/* Pin sense - 32bit */ 369/* Pin sense - 32bit */
324#define AC_PINSENSE_IMPEDANCE_MASK (0x7fffffff) 370#define AC_PINSENSE_IMPEDANCE_MASK (0x7fffffff)
325#define AC_PINSENSE_PRESENCE (1<<31) 371#define AC_PINSENSE_PRESENCE (1<<31)
372#define AC_PINSENSE_ELDV (1<<30) /* ELD valid (HDMI) */
326 373
327/* EAPD/BTL enable - 32bit */ 374/* EAPD/BTL enable - 32bit */
328#define AC_EAPDBTL_BALANCED (1<<0) 375#define AC_EAPDBTL_BALANCED (1<<0)
329#define AC_EAPDBTL_EAPD (1<<1) 376#define AC_EAPDBTL_EAPD (1<<1)
330#define AC_EAPDBTL_LR_SWAP (1<<2) 377#define AC_EAPDBTL_LR_SWAP (1<<2)
331 378
379/* HDMI ELD data */
380#define AC_ELDD_ELD_VALID (1<<31)
381#define AC_ELDD_ELD_DATA 0xff
382
383/* HDMI DIP size */
384#define AC_DIPSIZE_ELD_BUF (1<<3) /* ELD buf size of packet size */
385#define AC_DIPSIZE_PACK_IDX (0x07<<0) /* packet index */
386
387/* HDMI DIP index */
388#define AC_DIPIDX_PACK_IDX (0x07<<5) /* packet idnex */
389#define AC_DIPIDX_BYTE_IDX (0x1f<<0) /* byte index */
390
391/* HDMI DIP xmit (transmit) control */
392#define AC_DIPXMIT_MASK (0x3<<6)
393#define AC_DIPXMIT_DISABLE (0x0<<6) /* disable xmit */
394#define AC_DIPXMIT_ONCE (0x2<<6) /* xmit once then disable */
395#define AC_DIPXMIT_BEST (0x3<<6) /* best effort */
396
397/* HDMI content protection (CP) control */
398#define AC_CPCTRL_CES (1<<9) /* current encryption state */
399#define AC_CPCTRL_READY (1<<8) /* ready bit */
400#define AC_CPCTRL_SUBTAG (0x1f<<3) /* subtag for unsol-resp */
401#define AC_CPCTRL_STATE (3<<0) /* current CP request state */
402
403/* Converter channel <-> HDMI slot mapping */
404#define AC_CVTMAP_HDMI_SLOT (0xf<<0) /* HDMI slot number */
405#define AC_CVTMAP_CHAN (0xf<<4) /* converter channel number */
406
332/* configuration default - 32bit */ 407/* configuration default - 32bit */
333#define AC_DEFCFG_SEQUENCE (0xf<<0) 408#define AC_DEFCFG_SEQUENCE (0xf<<0)
334#define AC_DEFCFG_DEF_ASSOC (0xf<<4) 409#define AC_DEFCFG_DEF_ASSOC (0xf<<4)
@@ -449,6 +524,7 @@ enum {
449 */ 524 */
450 525
451struct hda_bus; 526struct hda_bus;
527struct hda_beep;
452struct hda_codec; 528struct hda_codec;
453struct hda_pcm; 529struct hda_pcm;
454struct hda_pcm_stream; 530struct hda_pcm_stream;
@@ -634,6 +710,9 @@ struct hda_codec {
634 /* codec specific info */ 710 /* codec specific info */
635 void *spec; 711 void *spec;
636 712
713 /* beep device */
714 struct hda_beep *beep;
715
637 /* widget capabilities cache */ 716 /* widget capabilities cache */
638 unsigned int num_nodes; 717 unsigned int num_nodes;
639 hda_nid_t start_nid; 718 hda_nid_t start_nid;
@@ -646,9 +725,15 @@ struct hda_codec {
646 unsigned int spdif_status; /* IEC958 status bits */ 725 unsigned int spdif_status; /* IEC958 status bits */
647 unsigned short spdif_ctls; /* SPDIF control bits */ 726 unsigned short spdif_ctls; /* SPDIF control bits */
648 unsigned int spdif_in_enable; /* SPDIF input enable? */ 727 unsigned int spdif_in_enable; /* SPDIF input enable? */
728 hda_nid_t *slave_dig_outs; /* optional digital out slave widgets */
649 729
650 struct snd_hwdep *hwdep; /* assigned hwdep device */ 730 struct snd_hwdep *hwdep; /* assigned hwdep device */
651 731
732 /* misc flags */
733 unsigned int spdif_status_reset :1; /* needs to toggle SPDIF for each
734 * status change
735 * (e.g. Realtek codecs)
736 */
652#ifdef CONFIG_SND_HDA_POWER_SAVE 737#ifdef CONFIG_SND_HDA_POWER_SAVE
653 unsigned int power_on :1; /* current (global) power-state */ 738 unsigned int power_on :1; /* current (global) power-state */
654 unsigned int power_transition :1; /* power-state in transition */ 739 unsigned int power_transition :1; /* power-state in transition */
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index 59e4389c94a4..0ca30894f7c6 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -174,7 +174,8 @@ static int build_afg_tree(struct hda_codec *codec)
174 int i, nodes, err; 174 int i, nodes, err;
175 hda_nid_t nid; 175 hda_nid_t nid;
176 176
177 snd_assert(spec, return -EINVAL); 177 if (snd_BUG_ON(!spec))
178 return -EINVAL;
178 179
179 spec->def_amp_out_caps = snd_hda_param_read(codec, codec->afg, AC_PAR_AMP_OUT_CAP); 180 spec->def_amp_out_caps = snd_hda_param_read(codec, codec->afg, AC_PAR_AMP_OUT_CAP);
180 spec->def_amp_in_caps = snd_hda_param_read(codec, codec->afg, AC_PAR_AMP_IN_CAP); 181 spec->def_amp_in_caps = snd_hda_param_read(codec, codec->afg, AC_PAR_AMP_IN_CAP);
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 1c53e337ecb2..9f316c1b2790 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -222,9 +222,9 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
222#define RIRB_INT_OVERRUN 0x04 222#define RIRB_INT_OVERRUN 0x04
223#define RIRB_INT_MASK 0x05 223#define RIRB_INT_MASK 0x05
224 224
225/* STATESTS int mask: SD2,SD1,SD0 */ 225/* STATESTS int mask: S3,SD2,SD1,SD0 */
226#define AZX_MAX_CODECS 3 226#define AZX_MAX_CODECS 4
227#define STATESTS_INT_MASK 0x07 227#define STATESTS_INT_MASK 0x0f
228 228
229/* SD_CTL bits */ 229/* SD_CTL bits */
230#define SD_CTL_STREAM_RESET 0x01 /* stream reset bit */ 230#define SD_CTL_STREAM_RESET 0x01 /* stream reset bit */
@@ -286,6 +286,11 @@ enum {
286#define INTEL_SCH_HDA_DEVC 0x78 286#define INTEL_SCH_HDA_DEVC 0x78
287#define INTEL_SCH_HDA_DEVC_NOSNOOP (0x1<<11) 287#define INTEL_SCH_HDA_DEVC_NOSNOOP (0x1<<11)
288 288
289/* Define IN stream 0 FIFO size offset in VIA controller */
290#define VIA_IN_STREAM0_FIFO_SIZE_OFFSET 0x90
291/* Define VIA HD Audio Device ID*/
292#define VIA_HDAC_DEVICE_ID 0x3288
293
289 294
290/* 295/*
291 */ 296 */
@@ -317,6 +322,12 @@ struct azx_dev {
317 unsigned int running :1; 322 unsigned int running :1;
318 unsigned int irq_pending :1; 323 unsigned int irq_pending :1;
319 unsigned int irq_ignore :1; 324 unsigned int irq_ignore :1;
325 /*
326 * For VIA:
327 * A flag to ensure DMA position is 0
328 * when link position is not greater than FIFO size
329 */
330 unsigned int insufficient :1;
320}; 331};
321 332
322/* CORB/RIRB */ 333/* CORB/RIRB */
@@ -379,6 +390,7 @@ struct azx {
379 unsigned int polling_mode :1; 390 unsigned int polling_mode :1;
380 unsigned int msi :1; 391 unsigned int msi :1;
381 unsigned int irq_pending_warned :1; 392 unsigned int irq_pending_warned :1;
393 unsigned int via_dmapos_patch :1; /* enable DMA-position fix for VIA */
382 394
383 /* for debugging */ 395 /* for debugging */
384 unsigned int last_cmd; /* last issued command (to sync) */ 396 unsigned int last_cmd; /* last issued command (to sync) */
@@ -398,6 +410,7 @@ enum {
398 AZX_DRIVER_ULI, 410 AZX_DRIVER_ULI,
399 AZX_DRIVER_NVIDIA, 411 AZX_DRIVER_NVIDIA,
400 AZX_DRIVER_TERA, 412 AZX_DRIVER_TERA,
413 AZX_NUM_DRIVERS, /* keep this as last entry */
401}; 414};
402 415
403static char *driver_short_names[] __devinitdata = { 416static char *driver_short_names[] __devinitdata = {
@@ -818,6 +831,11 @@ static void azx_int_clear(struct azx *chip)
818/* start a stream */ 831/* start a stream */
819static void azx_stream_start(struct azx *chip, struct azx_dev *azx_dev) 832static void azx_stream_start(struct azx *chip, struct azx_dev *azx_dev)
820{ 833{
834 /*
835 * Before stream start, initialize parameter
836 */
837 azx_dev->insufficient = 1;
838
821 /* enable SIE */ 839 /* enable SIE */
822 azx_writeb(chip, INTCTL, 840 azx_writeb(chip, INTCTL,
823 azx_readb(chip, INTCTL) | (1 << azx_dev->index)); 841 azx_readb(chip, INTCTL) | (1 << azx_dev->index));
@@ -998,7 +1016,6 @@ static int setup_bdle(struct snd_pcm_substream *substream,
998 struct azx_dev *azx_dev, u32 **bdlp, 1016 struct azx_dev *azx_dev, u32 **bdlp,
999 int ofs, int size, int with_ioc) 1017 int ofs, int size, int with_ioc)
1000{ 1018{
1001 struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream);
1002 u32 *bdl = *bdlp; 1019 u32 *bdl = *bdlp;
1003 1020
1004 while (size > 0) { 1021 while (size > 0) {
@@ -1008,14 +1025,12 @@ static int setup_bdle(struct snd_pcm_substream *substream,
1008 if (azx_dev->frags >= AZX_MAX_BDL_ENTRIES) 1025 if (azx_dev->frags >= AZX_MAX_BDL_ENTRIES)
1009 return -EINVAL; 1026 return -EINVAL;
1010 1027
1011 addr = snd_pcm_sgbuf_get_addr(sgbuf, ofs); 1028 addr = snd_pcm_sgbuf_get_addr(substream, ofs);
1012 /* program the address field of the BDL entry */ 1029 /* program the address field of the BDL entry */
1013 bdl[0] = cpu_to_le32((u32)addr); 1030 bdl[0] = cpu_to_le32((u32)addr);
1014 bdl[1] = cpu_to_le32(upper_32_bits(addr)); 1031 bdl[1] = cpu_to_le32(upper_32_bits(addr));
1015 /* program the size field of the BDL entry */ 1032 /* program the size field of the BDL entry */
1016 chunk = PAGE_SIZE - (ofs % PAGE_SIZE); 1033 chunk = snd_pcm_sgbuf_get_chunk_size(substream, ofs, size);
1017 if (size < chunk)
1018 chunk = size;
1019 bdl[2] = cpu_to_le32(chunk); 1034 bdl[2] = cpu_to_le32(chunk);
1020 /* program the IOC to enable interrupt 1035 /* program the IOC to enable interrupt
1021 * only when the whole fragment is processed 1036 * only when the whole fragment is processed
@@ -1151,7 +1166,8 @@ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev)
1151 1166
1152 /* enable the position buffer */ 1167 /* enable the position buffer */
1153 if (chip->position_fix == POS_FIX_POSBUF || 1168 if (chip->position_fix == POS_FIX_POSBUF ||
1154 chip->position_fix == POS_FIX_AUTO) { 1169 chip->position_fix == POS_FIX_AUTO ||
1170 chip->via_dmapos_patch) {
1155 if (!(azx_readl(chip, DPLBASE) & ICH6_DPLBASE_ENABLE)) 1171 if (!(azx_readl(chip, DPLBASE) & ICH6_DPLBASE_ENABLE))
1156 azx_writel(chip, DPLBASE, 1172 azx_writel(chip, DPLBASE,
1157 (u32)chip->posbuf.addr | ICH6_DPLBASE_ENABLE); 1173 (u32)chip->posbuf.addr | ICH6_DPLBASE_ENABLE);
@@ -1169,23 +1185,26 @@ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev)
1169 * Codec initialization 1185 * Codec initialization
1170 */ 1186 */
1171 1187
1172static unsigned int azx_max_codecs[] __devinitdata = { 1188/* number of codec slots for each chipset: 0 = default slots (i.e. 4) */
1173 [AZX_DRIVER_ICH] = 4, /* Some ICH9 boards use SD3 */ 1189static unsigned int azx_max_codecs[AZX_NUM_DRIVERS] __devinitdata = {
1174 [AZX_DRIVER_SCH] = 3,
1175 [AZX_DRIVER_ATI] = 4,
1176 [AZX_DRIVER_ATIHDMI] = 4,
1177 [AZX_DRIVER_VIA] = 3, /* FIXME: correct? */
1178 [AZX_DRIVER_SIS] = 3, /* FIXME: correct? */
1179 [AZX_DRIVER_ULI] = 3, /* FIXME: correct? */
1180 [AZX_DRIVER_NVIDIA] = 3, /* FIXME: correct? */
1181 [AZX_DRIVER_TERA] = 1, 1190 [AZX_DRIVER_TERA] = 1,
1182}; 1191};
1183 1192
1193/* number of slots to probe as default
1194 * this can be different from azx_max_codecs[] -- e.g. some boards
1195 * report wrongly the non-existing 4th slot availability
1196 */
1197static unsigned int azx_default_codecs[AZX_NUM_DRIVERS] __devinitdata = {
1198 [AZX_DRIVER_ICH] = 3,
1199 [AZX_DRIVER_ATI] = 3,
1200};
1201
1184static int __devinit azx_codec_create(struct azx *chip, const char *model, 1202static int __devinit azx_codec_create(struct azx *chip, const char *model,
1185 unsigned int codec_probe_mask) 1203 unsigned int codec_probe_mask)
1186{ 1204{
1187 struct hda_bus_template bus_temp; 1205 struct hda_bus_template bus_temp;
1188 int c, codecs, audio_codecs, err; 1206 int c, codecs, audio_codecs, err;
1207 int def_slots, max_slots;
1189 1208
1190 memset(&bus_temp, 0, sizeof(bus_temp)); 1209 memset(&bus_temp, 0, sizeof(bus_temp));
1191 bus_temp.private_data = chip; 1210 bus_temp.private_data = chip;
@@ -1201,8 +1220,17 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model,
1201 if (err < 0) 1220 if (err < 0)
1202 return err; 1221 return err;
1203 1222
1223 if (chip->driver_type == AZX_DRIVER_NVIDIA)
1224 chip->bus->needs_damn_long_delay = 1;
1225
1204 codecs = audio_codecs = 0; 1226 codecs = audio_codecs = 0;
1205 for (c = 0; c < AZX_MAX_CODECS; c++) { 1227 max_slots = azx_max_codecs[chip->driver_type];
1228 if (!max_slots)
1229 max_slots = AZX_MAX_CODECS;
1230 def_slots = azx_default_codecs[chip->driver_type];
1231 if (!def_slots)
1232 def_slots = max_slots;
1233 for (c = 0; c < def_slots; c++) {
1206 if ((chip->codec_mask & (1 << c)) & codec_probe_mask) { 1234 if ((chip->codec_mask & (1 << c)) & codec_probe_mask) {
1207 struct hda_codec *codec; 1235 struct hda_codec *codec;
1208 err = snd_hda_codec_new(chip->bus, c, &codec); 1236 err = snd_hda_codec_new(chip->bus, c, &codec);
@@ -1215,7 +1243,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model,
1215 } 1243 }
1216 if (!audio_codecs) { 1244 if (!audio_codecs) {
1217 /* probe additional slots if no codec is found */ 1245 /* probe additional slots if no codec is found */
1218 for (; c < azx_max_codecs[chip->driver_type]; c++) { 1246 for (; c < max_slots; c++) {
1219 if ((chip->codec_mask & (1 << c)) & codec_probe_mask) { 1247 if ((chip->codec_mask & (1 << c)) & codec_probe_mask) {
1220 err = snd_hda_codec_new(chip->bus, c, NULL); 1248 err = snd_hda_codec_new(chip->bus, c, NULL);
1221 if (err < 0) 1249 if (err < 0)
@@ -1507,13 +1535,71 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
1507 return 0; 1535 return 0;
1508} 1536}
1509 1537
1538/* get the current DMA position with correction on VIA chips */
1539static unsigned int azx_via_get_position(struct azx *chip,
1540 struct azx_dev *azx_dev)
1541{
1542 unsigned int link_pos, mini_pos, bound_pos;
1543 unsigned int mod_link_pos, mod_dma_pos, mod_mini_pos;
1544 unsigned int fifo_size;
1545
1546 link_pos = azx_sd_readl(azx_dev, SD_LPIB);
1547 if (azx_dev->index >= 4) {
1548 /* Playback, no problem using link position */
1549 return link_pos;
1550 }
1551
1552 /* Capture */
1553 /* For new chipset,
1554 * use mod to get the DMA position just like old chipset
1555 */
1556 mod_dma_pos = le32_to_cpu(*azx_dev->posbuf);
1557 mod_dma_pos %= azx_dev->period_bytes;
1558
1559 /* azx_dev->fifo_size can't get FIFO size of in stream.
1560 * Get from base address + offset.
1561 */
1562 fifo_size = readw(chip->remap_addr + VIA_IN_STREAM0_FIFO_SIZE_OFFSET);
1563
1564 if (azx_dev->insufficient) {
1565 /* Link position never gather than FIFO size */
1566 if (link_pos <= fifo_size)
1567 return 0;
1568
1569 azx_dev->insufficient = 0;
1570 }
1571
1572 if (link_pos <= fifo_size)
1573 mini_pos = azx_dev->bufsize + link_pos - fifo_size;
1574 else
1575 mini_pos = link_pos - fifo_size;
1576
1577 /* Find nearest previous boudary */
1578 mod_mini_pos = mini_pos % azx_dev->period_bytes;
1579 mod_link_pos = link_pos % azx_dev->period_bytes;
1580 if (mod_link_pos >= fifo_size)
1581 bound_pos = link_pos - mod_link_pos;
1582 else if (mod_dma_pos >= mod_mini_pos)
1583 bound_pos = mini_pos - mod_mini_pos;
1584 else {
1585 bound_pos = mini_pos - mod_mini_pos + azx_dev->period_bytes;
1586 if (bound_pos >= azx_dev->bufsize)
1587 bound_pos = 0;
1588 }
1589
1590 /* Calculate real DMA position we want */
1591 return bound_pos + mod_dma_pos;
1592}
1593
1510static unsigned int azx_get_position(struct azx *chip, 1594static unsigned int azx_get_position(struct azx *chip,
1511 struct azx_dev *azx_dev) 1595 struct azx_dev *azx_dev)
1512{ 1596{
1513 unsigned int pos; 1597 unsigned int pos;
1514 1598
1515 if (chip->position_fix == POS_FIX_POSBUF || 1599 if (chip->via_dmapos_patch)
1516 chip->position_fix == POS_FIX_AUTO) { 1600 pos = azx_via_get_position(chip, azx_dev);
1601 else if (chip->position_fix == POS_FIX_POSBUF ||
1602 chip->position_fix == POS_FIX_AUTO) {
1517 /* use the position buffer */ 1603 /* use the position buffer */
1518 pos = le32_to_cpu(*azx_dev->posbuf); 1604 pos = le32_to_cpu(*azx_dev->posbuf);
1519 } else { 1605 } else {
@@ -1559,6 +1645,8 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev)
1559 chip->position_fix = POS_FIX_POSBUF; 1645 chip->position_fix = POS_FIX_POSBUF;
1560 } 1646 }
1561 1647
1648 if (!bdl_pos_adj[chip->dev_index])
1649 return 1; /* no delayed ack */
1562 if (pos % azx_dev->period_bytes > azx_dev->period_bytes / 2) 1650 if (pos % azx_dev->period_bytes > azx_dev->period_bytes / 2)
1563 return 0; /* NG - it's below the period boundary */ 1651 return 0; /* NG - it's below the period boundary */
1564 return 1; /* OK, it's fine */ 1652 return 1; /* OK, it's fine */
@@ -1646,7 +1734,8 @@ static int __devinit create_codec_pcm(struct azx *chip, struct hda_codec *codec,
1646 if (!cpcm->stream[0].substreams && !cpcm->stream[1].substreams) 1734 if (!cpcm->stream[0].substreams && !cpcm->stream[1].substreams)
1647 return 0; 1735 return 0;
1648 1736
1649 snd_assert(cpcm->name, return -EINVAL); 1737 if (snd_BUG_ON(!cpcm->name))
1738 return -EINVAL;
1650 1739
1651 err = snd_pcm_new(chip->card, cpcm->name, cpcm->device, 1740 err = snd_pcm_new(chip->card, cpcm->name, cpcm->device,
1652 cpcm->stream[0].substreams, 1741 cpcm->stream[0].substreams,
@@ -1670,7 +1759,7 @@ static int __devinit create_codec_pcm(struct azx *chip, struct hda_codec *codec,
1670 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &azx_pcm_ops); 1759 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &azx_pcm_ops);
1671 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG, 1760 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
1672 snd_dma_pci_data(chip->pci), 1761 snd_dma_pci_data(chip->pci),
1673 1024 * 64, 1024 * 1024); 1762 1024 * 64, 32 * 1024 * 1024);
1674 chip->pcm[cpcm->device] = pcm; 1763 chip->pcm[cpcm->device] = pcm;
1675 return 0; 1764 return 0;
1676} 1765}
@@ -1946,6 +2035,15 @@ static int __devinit check_position_fix(struct azx *chip, int fix)
1946{ 2035{
1947 const struct snd_pci_quirk *q; 2036 const struct snd_pci_quirk *q;
1948 2037
2038 /* Check VIA HD Audio Controller exist */
2039 if (chip->pci->vendor == PCI_VENDOR_ID_VIA &&
2040 chip->pci->device == VIA_HDAC_DEVICE_ID) {
2041 chip->via_dmapos_patch = 1;
2042 /* Use link position directly, avoid any transfer problem. */
2043 return POS_FIX_LPIB;
2044 }
2045 chip->via_dmapos_patch = 0;
2046
1949 if (fix == POS_FIX_AUTO) { 2047 if (fix == POS_FIX_AUTO) {
1950 q = snd_pci_quirk_lookup(chip->pci, position_fix_list); 2048 q = snd_pci_quirk_lookup(chip->pci, position_fix_list);
1951 if (q) { 2049 if (q) {
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 5c9e578f7f2d..7957fefda730 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -368,12 +368,15 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
368#define AMP_OUT_UNMUTE 0xb000 368#define AMP_OUT_UNMUTE 0xb000
369#define AMP_OUT_ZERO 0xb000 369#define AMP_OUT_ZERO 0xb000
370/* pinctl values */ 370/* pinctl values */
371#define PIN_IN 0x20 371#define PIN_IN (AC_PINCTL_IN_EN)
372#define PIN_VREF80 0x24 372#define PIN_VREFHIZ (AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ)
373#define PIN_VREF50 0x21 373#define PIN_VREF50 (AC_PINCTL_IN_EN | AC_PINCTL_VREF_50)
374#define PIN_OUT 0x40 374#define PIN_VREFGRD (AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD)
375#define PIN_HP 0xc0 375#define PIN_VREF80 (AC_PINCTL_IN_EN | AC_PINCTL_VREF_80)
376#define PIN_HP_AMP 0x80 376#define PIN_VREF100 (AC_PINCTL_IN_EN | AC_PINCTL_VREF_100)
377#define PIN_OUT (AC_PINCTL_OUT_EN)
378#define PIN_HP (AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN)
379#define PIN_HP_AMP (AC_PINCTL_HP_EN)
377 380
378/* 381/*
379 * get widget capabilities 382 * get widget capabilities
@@ -418,4 +421,13 @@ int snd_hda_check_amp_list_power(struct hda_codec *codec,
418 hda_nid_t nid); 421 hda_nid_t nid);
419#endif /* CONFIG_SND_HDA_POWER_SAVE */ 422#endif /* CONFIG_SND_HDA_POWER_SAVE */
420 423
424/*
425 * AMP control callbacks
426 */
427/* retrieve parameters from private_value */
428#define get_amp_nid(kc) ((kc)->private_value & 0xffff)
429#define get_amp_channels(kc) (((kc)->private_value >> 16) & 0x3)
430#define get_amp_direction(kc) (((kc)->private_value >> 18) & 0x1)
431#define get_amp_index(kc) (((kc)->private_value >> 19) & 0xf)
432
421#endif /* __SOUND_HDA_LOCAL_H */ 433#endif /* __SOUND_HDA_LOCAL_H */
diff --git a/sound/pci/hda/hda_patch.h b/sound/pci/hda/hda_patch.h
index 2fdf2358dbc2..dfbcfa88da44 100644
--- a/sound/pci/hda/hda_patch.h
+++ b/sound/pci/hda/hda_patch.h
@@ -18,3 +18,5 @@ extern struct hda_codec_preset snd_hda_preset_atihdmi[];
18extern struct hda_codec_preset snd_hda_preset_conexant[]; 18extern struct hda_codec_preset snd_hda_preset_conexant[];
19/* VIA codecs */ 19/* VIA codecs */
20extern struct hda_codec_preset snd_hda_preset_via[]; 20extern struct hda_codec_preset snd_hda_preset_via[];
21/* NVIDIA HDMI codecs */
22extern struct hda_codec_preset snd_hda_preset_nvhdmi[];
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
index 1e5aff5c48d1..743d77922bce 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -216,7 +216,7 @@ static void print_pin_caps(struct snd_info_buffer *buffer,
216 unsigned int caps, val; 216 unsigned int caps, val;
217 217
218 caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP); 218 caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
219 snd_iprintf(buffer, " Pincap 0x08%x:", caps); 219 snd_iprintf(buffer, " Pincap 0x%08x:", caps);
220 if (caps & AC_PINCAP_IN) 220 if (caps & AC_PINCAP_IN)
221 snd_iprintf(buffer, " IN"); 221 snd_iprintf(buffer, " IN");
222 if (caps & AC_PINCAP_OUT) 222 if (caps & AC_PINCAP_OUT)
@@ -229,8 +229,13 @@ static void print_pin_caps(struct snd_info_buffer *buffer,
229 snd_iprintf(buffer, " Detect"); 229 snd_iprintf(buffer, " Detect");
230 if (caps & AC_PINCAP_BALANCE) 230 if (caps & AC_PINCAP_BALANCE)
231 snd_iprintf(buffer, " Balanced"); 231 snd_iprintf(buffer, " Balanced");
232 if (caps & AC_PINCAP_LR_SWAP) 232 if (caps & AC_PINCAP_HDMI) {
233 snd_iprintf(buffer, " R/L"); 233 /* Realtek uses this bit as a different meaning */
234 if ((codec->vendor_id >> 16) == 0x10ec)
235 snd_iprintf(buffer, " R/L");
236 else
237 snd_iprintf(buffer, " HDMI");
238 }
234 if (caps & AC_PINCAP_TRIG_REQ) 239 if (caps & AC_PINCAP_TRIG_REQ)
235 snd_iprintf(buffer, " Trigger"); 240 snd_iprintf(buffer, " Trigger");
236 if (caps & AC_PINCAP_IMP_SENSE) 241 if (caps & AC_PINCAP_IMP_SENSE)
@@ -552,9 +557,15 @@ static void print_codec_info(struct snd_info_entry *entry,
552 557
553 snd_iprintf(buffer, "Node 0x%02x [%s] wcaps 0x%x:", nid, 558 snd_iprintf(buffer, "Node 0x%02x [%s] wcaps 0x%x:", nid,
554 get_wid_type_name(wid_type), wid_caps); 559 get_wid_type_name(wid_type), wid_caps);
555 if (wid_caps & AC_WCAP_STEREO) 560 if (wid_caps & AC_WCAP_STEREO) {
556 snd_iprintf(buffer, " Stereo"); 561 unsigned int chans;
557 else 562 chans = (wid_caps & AC_WCAP_CHAN_CNT_EXT) >> 13;
563 chans = ((chans << 1) | 1) + 1;
564 if (chans == 2)
565 snd_iprintf(buffer, " Stereo");
566 else
567 snd_iprintf(buffer, " %d-Channels", chans);
568 } else
558 snd_iprintf(buffer, " Mono"); 569 snd_iprintf(buffer, " Mono");
559 if (wid_caps & AC_WCAP_DIGITAL) 570 if (wid_caps & AC_WCAP_DIGITAL)
560 snd_iprintf(buffer, " Digital"); 571 snd_iprintf(buffer, " Digital");
@@ -566,6 +577,8 @@ static void print_codec_info(struct snd_info_entry *entry,
566 snd_iprintf(buffer, " Stripe"); 577 snd_iprintf(buffer, " Stripe");
567 if (wid_caps & AC_WCAP_LR_SWAP) 578 if (wid_caps & AC_WCAP_LR_SWAP)
568 snd_iprintf(buffer, " R/L"); 579 snd_iprintf(buffer, " R/L");
580 if (wid_caps & AC_WCAP_CP_CAPS)
581 snd_iprintf(buffer, " CP");
569 snd_iprintf(buffer, "\n"); 582 snd_iprintf(buffer, "\n");
570 583
571 /* volume knob is a special widget that always have connection 584 /* volume knob is a special widget that always have connection
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index e8003d99f0bf..2b00c4afdf97 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -1826,9 +1826,14 @@ static hda_nid_t ad1988_capsrc_nids[3] = {
1826 0x0c, 0x0d, 0x0e 1826 0x0c, 0x0d, 0x0e
1827}; 1827};
1828 1828
1829#define AD1988_SPDIF_OUT 0x02 1829#define AD1988_SPDIF_OUT 0x02
1830#define AD1988_SPDIF_OUT_HDMI 0x0b
1830#define AD1988_SPDIF_IN 0x07 1831#define AD1988_SPDIF_IN 0x07
1831 1832
1833static hda_nid_t ad1989b_slave_dig_outs[2] = {
1834 AD1988_SPDIF_OUT, AD1988_SPDIF_OUT_HDMI
1835};
1836
1832static struct hda_input_mux ad1988_6stack_capture_source = { 1837static struct hda_input_mux ad1988_6stack_capture_source = {
1833 .num_items = 5, 1838 .num_items = 5,
1834 .items = { 1839 .items = {
@@ -2143,6 +2148,7 @@ static struct snd_kcontrol_new ad1988_spdif_in_mixers[] = {
2143 2148
2144static struct snd_kcontrol_new ad1989_spdif_out_mixers[] = { 2149static struct snd_kcontrol_new ad1989_spdif_out_mixers[] = {
2145 HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT), 2150 HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
2151 HDA_CODEC_VOLUME("HDMI Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
2146 { } /* end */ 2152 { } /* end */
2147}; 2153};
2148 2154
@@ -2207,6 +2213,8 @@ static struct hda_verb ad1988_6stack_init_verbs[] = {
2207 {0x34, AC_VERB_SET_CONNECT_SEL, 0x0}, 2213 {0x34, AC_VERB_SET_CONNECT_SEL, 0x0},
2208 /* Analog CD Input */ 2214 /* Analog CD Input */
2209 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2215 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2216 /* Analog Mix output amp */
2217 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
2210 2218
2211 { } 2219 { }
2212}; 2220};
@@ -2247,8 +2255,12 @@ static struct hda_verb ad1988_spdif_init_verbs[] = {
2247 2255
2248/* AD1989 has no ADC -> SPDIF route */ 2256/* AD1989 has no ADC -> SPDIF route */
2249static struct hda_verb ad1989_spdif_init_verbs[] = { 2257static struct hda_verb ad1989_spdif_init_verbs[] = {
2250 /* SPDIF out pin */ 2258 /* SPDIF-1 out pin */
2259 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2251 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */ 2260 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
2261 /* SPDIF-2/HDMI out pin */
2262 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2263 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
2252 { } 2264 { }
2253}; 2265};
2254 2266
@@ -2336,6 +2348,8 @@ static struct hda_verb ad1988_3stack_init_verbs[] = {
2336 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2348 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2337 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2349 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2338 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2350 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2351 /* Analog Mix output amp */
2352 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
2339 { } 2353 { }
2340}; 2354};
2341 2355
@@ -2409,6 +2423,8 @@ static struct hda_verb ad1988_laptop_init_verbs[] = {
2409 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2423 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2410 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2424 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2411 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2425 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2426 /* Analog Mix output amp */
2427 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
2412 { } 2428 { }
2413}; 2429};
2414 2430
@@ -2868,6 +2884,7 @@ static struct snd_pci_quirk ad1988_cfg_tbl[] = {
2868 SND_PCI_QUIRK(0x1043, 0x81ec, "Asus P5B-DLX", AD1988_6STACK_DIG), 2884 SND_PCI_QUIRK(0x1043, 0x81ec, "Asus P5B-DLX", AD1988_6STACK_DIG),
2869 SND_PCI_QUIRK(0x1043, 0x81f6, "Asus M2N-SLI", AD1988_6STACK_DIG), 2885 SND_PCI_QUIRK(0x1043, 0x81f6, "Asus M2N-SLI", AD1988_6STACK_DIG),
2870 SND_PCI_QUIRK(0x1043, 0x8277, "Asus P5K-E/WIFI-AP", AD1988_6STACK_DIG), 2886 SND_PCI_QUIRK(0x1043, 0x8277, "Asus P5K-E/WIFI-AP", AD1988_6STACK_DIG),
2887 SND_PCI_QUIRK(0x1043, 0x8311, "Asus P5Q-Premium/Pro", AD1988_6STACK_DIG),
2871 {} 2888 {}
2872}; 2889};
2873 2890
@@ -2975,6 +2992,7 @@ static int patch_ad1988(struct hda_codec *codec)
2975 ad1989_spdif_out_mixers; 2992 ad1989_spdif_out_mixers;
2976 spec->init_verbs[spec->num_init_verbs++] = 2993 spec->init_verbs[spec->num_init_verbs++] =
2977 ad1989_spdif_init_verbs; 2994 ad1989_spdif_init_verbs;
2995 codec->slave_dig_outs = ad1989b_slave_dig_outs;
2978 } else { 2996 } else {
2979 spec->mixers[spec->num_mixers++] = 2997 spec->mixers[spec->num_mixers++] =
2980 ad1988_spdif_out_mixers; 2998 ad1988_spdif_out_mixers;
@@ -3911,7 +3929,7 @@ static int patch_ad1884a(struct hda_codec *codec)
3911 3929
3912 3930
3913/* 3931/*
3914 * AD1882 3932 * AD1882 / AD1882A
3915 * 3933 *
3916 * port-A - front hp-out 3934 * port-A - front hp-out
3917 * port-B - front mic-in 3935 * port-B - front mic-in
@@ -3948,6 +3966,18 @@ static struct hda_input_mux ad1882_capture_source = {
3948 }, 3966 },
3949}; 3967};
3950 3968
3969/* list: 0x11, 0x39, 0x3a, 0x3c, 0x18, 0x1f, 0x12, 0x20 */
3970static struct hda_input_mux ad1882a_capture_source = {
3971 .num_items = 5,
3972 .items = {
3973 { "Front Mic", 0x1 },
3974 { "Mic", 0x4},
3975 { "Line", 0x2 },
3976 { "Digital Mic", 0x06 },
3977 { "Mix", 0x7 },
3978 },
3979};
3980
3951static struct snd_kcontrol_new ad1882_base_mixers[] = { 3981static struct snd_kcontrol_new ad1882_base_mixers[] = {
3952 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), 3982 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
3953 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), 3983 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
@@ -3957,16 +3987,7 @@ static struct snd_kcontrol_new ad1882_base_mixers[] = {
3957 HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT), 3987 HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3958 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT), 3988 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
3959 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT), 3989 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
3960 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT), 3990
3961 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3962 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
3963 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
3964 HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x04, HDA_INPUT),
3965 HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x04, HDA_INPUT),
3966 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT),
3967 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT),
3968 HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x07, HDA_INPUT),
3969 HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x07, HDA_INPUT),
3970 HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT), 3991 HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT),
3971 HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT), 3992 HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT),
3972 HDA_CODEC_VOLUME("Line-In Boost", 0x3a, 0x0, HDA_OUTPUT), 3993 HDA_CODEC_VOLUME("Line-In Boost", 0x3a, 0x0, HDA_OUTPUT),
@@ -3999,6 +4020,35 @@ static struct snd_kcontrol_new ad1882_base_mixers[] = {
3999 { } /* end */ 4020 { } /* end */
4000}; 4021};
4001 4022
4023static struct snd_kcontrol_new ad1882_loopback_mixers[] = {
4024 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
4025 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
4026 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
4027 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
4028 HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x04, HDA_INPUT),
4029 HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x04, HDA_INPUT),
4030 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT),
4031 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT),
4032 HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x07, HDA_INPUT),
4033 HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x07, HDA_INPUT),
4034 { } /* end */
4035};
4036
4037static struct snd_kcontrol_new ad1882a_loopback_mixers[] = {
4038 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
4039 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
4040 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
4041 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
4042 HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x01, HDA_INPUT),
4043 HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x01, HDA_INPUT),
4044 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT),
4045 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT),
4046 HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x07, HDA_INPUT),
4047 HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x07, HDA_INPUT),
4048 HDA_CODEC_VOLUME("Digital Mic Boost", 0x1f, 0x0, HDA_INPUT),
4049 { } /* end */
4050};
4051
4002static struct snd_kcontrol_new ad1882_3stack_mixers[] = { 4052static struct snd_kcontrol_new ad1882_3stack_mixers[] = {
4003 HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT), 4053 HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4004 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x17, 1, 0x0, HDA_OUTPUT), 4054 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x17, 1, 0x0, HDA_OUTPUT),
@@ -4168,9 +4218,16 @@ static int patch_ad1882(struct hda_codec *codec)
4168 spec->num_adc_nids = ARRAY_SIZE(ad1882_adc_nids); 4218 spec->num_adc_nids = ARRAY_SIZE(ad1882_adc_nids);
4169 spec->adc_nids = ad1882_adc_nids; 4219 spec->adc_nids = ad1882_adc_nids;
4170 spec->capsrc_nids = ad1882_capsrc_nids; 4220 spec->capsrc_nids = ad1882_capsrc_nids;
4171 spec->input_mux = &ad1882_capture_source; 4221 if (codec->vendor_id == 0x11d1882)
4172 spec->num_mixers = 1; 4222 spec->input_mux = &ad1882_capture_source;
4223 else
4224 spec->input_mux = &ad1882a_capture_source;
4225 spec->num_mixers = 2;
4173 spec->mixers[0] = ad1882_base_mixers; 4226 spec->mixers[0] = ad1882_base_mixers;
4227 if (codec->vendor_id == 0x11d1882)
4228 spec->mixers[1] = ad1882_loopback_mixers;
4229 else
4230 spec->mixers[1] = ad1882a_loopback_mixers;
4174 spec->num_init_verbs = 1; 4231 spec->num_init_verbs = 1;
4175 spec->init_verbs[0] = ad1882_init_verbs; 4232 spec->init_verbs[0] = ad1882_init_verbs;
4176 spec->spdif_route = 0; 4233 spec->spdif_route = 0;
@@ -4187,8 +4244,8 @@ static int patch_ad1882(struct hda_codec *codec)
4187 switch (board_config) { 4244 switch (board_config) {
4188 default: 4245 default:
4189 case AD1882_3STACK: 4246 case AD1882_3STACK:
4190 spec->num_mixers = 2; 4247 spec->num_mixers = 3;
4191 spec->mixers[1] = ad1882_3stack_mixers; 4248 spec->mixers[2] = ad1882_3stack_mixers;
4192 spec->channel_mode = ad1882_modes; 4249 spec->channel_mode = ad1882_modes;
4193 spec->num_channel_mode = ARRAY_SIZE(ad1882_modes); 4250 spec->num_channel_mode = ARRAY_SIZE(ad1882_modes);
4194 spec->need_dac_fix = 1; 4251 spec->need_dac_fix = 1;
@@ -4196,8 +4253,8 @@ static int patch_ad1882(struct hda_codec *codec)
4196 spec->multiout.num_dacs = 1; 4253 spec->multiout.num_dacs = 1;
4197 break; 4254 break;
4198 case AD1882_6STACK: 4255 case AD1882_6STACK:
4199 spec->num_mixers = 2; 4256 spec->num_mixers = 3;
4200 spec->mixers[1] = ad1882_6stack_mixers; 4257 spec->mixers[2] = ad1882_6stack_mixers;
4201 break; 4258 break;
4202 } 4259 }
4203 return 0; 4260 return 0;
@@ -4220,6 +4277,7 @@ struct hda_codec_preset snd_hda_preset_analog[] = {
4220 { .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a }, 4277 { .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a },
4221 { .id = 0x11d41988, .name = "AD1988", .patch = patch_ad1988 }, 4278 { .id = 0x11d41988, .name = "AD1988", .patch = patch_ad1988 },
4222 { .id = 0x11d4198b, .name = "AD1988B", .patch = patch_ad1988 }, 4279 { .id = 0x11d4198b, .name = "AD1988B", .patch = patch_ad1988 },
4280 { .id = 0x11d4882a, .name = "AD1882A", .patch = patch_ad1882 },
4223 { .id = 0x11d4989a, .name = "AD1989A", .patch = patch_ad1988 }, 4281 { .id = 0x11d4989a, .name = "AD1989A", .patch = patch_ad1988 },
4224 { .id = 0x11d4989b, .name = "AD1989B", .patch = patch_ad1988 }, 4282 { .id = 0x11d4989b, .name = "AD1989B", .patch = patch_ad1988 },
4225 {} /* terminator */ 4283 {} /* terminator */
diff --git a/sound/pci/hda/patch_atihdmi.c b/sound/pci/hda/patch_atihdmi.c
index 12272508b112..ba61575983fd 100644
--- a/sound/pci/hda/patch_atihdmi.c
+++ b/sound/pci/hda/patch_atihdmi.c
@@ -35,6 +35,9 @@ struct atihdmi_spec {
35 struct hda_pcm pcm_rec; 35 struct hda_pcm pcm_rec;
36}; 36};
37 37
38#define CVT_NID 0x02 /* audio converter */
39#define PIN_NID 0x03 /* HDMI output pin */
40
38static struct hda_verb atihdmi_basic_init[] = { 41static struct hda_verb atihdmi_basic_init[] = {
39 /* enable digital output on pin widget */ 42 /* enable digital output on pin widget */
40 { 0x03, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 43 { 0x03, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
@@ -60,8 +63,9 @@ static int atihdmi_init(struct hda_codec *codec)
60{ 63{
61 snd_hda_sequence_write(codec, atihdmi_basic_init); 64 snd_hda_sequence_write(codec, atihdmi_basic_init);
62 /* SI codec requires to unmute the pin */ 65 /* SI codec requires to unmute the pin */
63 if (get_wcaps(codec, 0x03) & AC_WCAP_OUT_AMP) 66 if (get_wcaps(codec, PIN_NID) & AC_WCAP_OUT_AMP)
64 snd_hda_codec_write(codec, 0x03, 0, AC_VERB_SET_AMP_GAIN_MUTE, 67 snd_hda_codec_write(codec, PIN_NID, 0,
68 AC_VERB_SET_AMP_GAIN_MUTE,
65 AMP_OUT_UNMUTE); 69 AMP_OUT_UNMUTE);
66 return 0; 70 return 0;
67} 71}
@@ -92,15 +96,29 @@ static int atihdmi_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
92 struct snd_pcm_substream *substream) 96 struct snd_pcm_substream *substream)
93{ 97{
94 struct atihdmi_spec *spec = codec->spec; 98 struct atihdmi_spec *spec = codec->spec;
95 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag, 99 int chans = substream->runtime->channels;
96 format, substream); 100 int i, err;
101
102 err = snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
103 format, substream);
104 if (err < 0)
105 return err;
106 snd_hda_codec_write(codec, CVT_NID, 0, AC_VERB_SET_CVT_CHAN_COUNT,
107 chans - 1);
108 /* FIXME: XXX */
109 for (i = 0; i < chans; i++) {
110 snd_hda_codec_write(codec, CVT_NID, 0,
111 AC_VERB_SET_HDMI_CHAN_SLOT,
112 (i << 4) | i);
113 }
114 return 0;
97} 115}
98 116
99static struct hda_pcm_stream atihdmi_pcm_digital_playback = { 117static struct hda_pcm_stream atihdmi_pcm_digital_playback = {
100 .substreams = 1, 118 .substreams = 1,
101 .channels_min = 2, 119 .channels_min = 2,
102 .channels_max = 2, 120 .channels_max = 2,
103 .nid = 0x2, /* NID to query formats and rates and setup streams */ 121 .nid = CVT_NID, /* NID to query formats and rates and setup streams */
104 .ops = { 122 .ops = {
105 .open = atihdmi_dig_playback_pcm_open, 123 .open = atihdmi_dig_playback_pcm_open,
106 .close = atihdmi_dig_playback_pcm_close, 124 .close = atihdmi_dig_playback_pcm_close,
@@ -112,6 +130,7 @@ static int atihdmi_build_pcms(struct hda_codec *codec)
112{ 130{
113 struct atihdmi_spec *spec = codec->spec; 131 struct atihdmi_spec *spec = codec->spec;
114 struct hda_pcm *info = &spec->pcm_rec; 132 struct hda_pcm *info = &spec->pcm_rec;
133 unsigned int chans;
115 134
116 codec->num_pcms = 1; 135 codec->num_pcms = 1;
117 codec->pcm_info = info; 136 codec->pcm_info = info;
@@ -120,6 +139,13 @@ static int atihdmi_build_pcms(struct hda_codec *codec)
120 info->pcm_type = HDA_PCM_TYPE_HDMI; 139 info->pcm_type = HDA_PCM_TYPE_HDMI;
121 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = atihdmi_pcm_digital_playback; 140 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = atihdmi_pcm_digital_playback;
122 141
142 /* FIXME: we must check ELD and change the PCM parameters dynamically
143 */
144 chans = get_wcaps(codec, CVT_NID);
145 chans = (chans & AC_WCAP_CHAN_CNT_EXT) >> 13;
146 chans = ((chans << 1) | 1) + 1;
147 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = chans;
148
123 return 0; 149 return 0;
124} 150}
125 151
@@ -147,9 +173,11 @@ static int patch_atihdmi(struct hda_codec *codec)
147 173
148 spec->multiout.num_dacs = 0; /* no analog */ 174 spec->multiout.num_dacs = 0; /* no analog */
149 spec->multiout.max_channels = 2; 175 spec->multiout.max_channels = 2;
150 spec->multiout.dig_out_nid = 0x2; /* NID for copying analog to digital, 176 /* NID for copying analog to digital,
151 * seems to be unused in pure-digital 177 * seems to be unused in pure-digital
152 * case. */ 178 * case.
179 */
180 spec->multiout.dig_out_nid = CVT_NID;
153 181
154 codec->patch_ops = atihdmi_patch_ops; 182 codec->patch_ops = atihdmi_patch_ops;
155 183
@@ -164,6 +192,7 @@ struct hda_codec_preset snd_hda_preset_atihdmi[] = {
164 { .id = 0x10027919, .name = "ATI RS600 HDMI", .patch = patch_atihdmi }, 192 { .id = 0x10027919, .name = "ATI RS600 HDMI", .patch = patch_atihdmi },
165 { .id = 0x1002791a, .name = "ATI RS690/780 HDMI", .patch = patch_atihdmi }, 193 { .id = 0x1002791a, .name = "ATI RS690/780 HDMI", .patch = patch_atihdmi },
166 { .id = 0x1002aa01, .name = "ATI R6xx HDMI", .patch = patch_atihdmi }, 194 { .id = 0x1002aa01, .name = "ATI R6xx HDMI", .patch = patch_atihdmi },
195 { .id = 0x10951390, .name = "SiI1390 HDMI", .patch = patch_atihdmi },
167 { .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_atihdmi }, 196 { .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_atihdmi },
168 { .id = 0x17e80047, .name = "Chrontel HDMI", .patch = patch_atihdmi }, 197 { .id = 0x17e80047, .name = "Chrontel HDMI", .patch = patch_atihdmi },
169 {} /* terminator */ 198 {} /* terminator */
diff --git a/sound/pci/hda/patch_nvhdmi.c b/sound/pci/hda/patch_nvhdmi.c
new file mode 100644
index 000000000000..1a65775d28e1
--- /dev/null
+++ b/sound/pci/hda/patch_nvhdmi.c
@@ -0,0 +1,164 @@
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for NVIDIA HDMI codecs
5 *
6 * Copyright (c) 2008 NVIDIA Corp. All rights reserved.
7 * Copyright (c) 2008 Wei Ni <wni@nvidia.com>
8 *
9 *
10 * This driver is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This driver is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24
25#include <linux/init.h>
26#include <linux/delay.h>
27#include <linux/slab.h>
28#include <sound/core.h>
29#include "hda_codec.h"
30#include "hda_local.h"
31
32struct nvhdmi_spec {
33 struct hda_multi_out multiout;
34
35 struct hda_pcm pcm_rec;
36};
37
38static struct hda_verb nvhdmi_basic_init[] = {
39 /* enable digital output on pin widget */
40 { 0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
41 {} /* terminator */
42};
43
44/*
45 * Controls
46 */
47static int nvhdmi_build_controls(struct hda_codec *codec)
48{
49 struct nvhdmi_spec *spec = codec->spec;
50 int err;
51
52 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
53 if (err < 0)
54 return err;
55
56 return 0;
57}
58
59static int nvhdmi_init(struct hda_codec *codec)
60{
61 snd_hda_sequence_write(codec, nvhdmi_basic_init);
62 return 0;
63}
64
65/*
66 * Digital out
67 */
68static int nvhdmi_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
69 struct hda_codec *codec,
70 struct snd_pcm_substream *substream)
71{
72 struct nvhdmi_spec *spec = codec->spec;
73 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
74}
75
76static int nvhdmi_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
77 struct hda_codec *codec,
78 struct snd_pcm_substream *substream)
79{
80 struct nvhdmi_spec *spec = codec->spec;
81 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
82}
83
84static int nvhdmi_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
85 struct hda_codec *codec,
86 unsigned int stream_tag,
87 unsigned int format,
88 struct snd_pcm_substream *substream)
89{
90 struct nvhdmi_spec *spec = codec->spec;
91 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
92 format, substream);
93}
94
95static struct hda_pcm_stream nvhdmi_pcm_digital_playback = {
96 .substreams = 1,
97 .channels_min = 2,
98 .channels_max = 2,
99 .nid = 0x4, /* NID to query formats and rates and setup streams */
100 .rates = SNDRV_PCM_RATE_48000,
101 .maxbps = 16,
102 .formats = SNDRV_PCM_FMTBIT_S16_LE,
103 .ops = {
104 .open = nvhdmi_dig_playback_pcm_open,
105 .close = nvhdmi_dig_playback_pcm_close,
106 .prepare = nvhdmi_dig_playback_pcm_prepare
107 },
108};
109
110static int nvhdmi_build_pcms(struct hda_codec *codec)
111{
112 struct nvhdmi_spec *spec = codec->spec;
113 struct hda_pcm *info = &spec->pcm_rec;
114
115 codec->num_pcms = 1;
116 codec->pcm_info = info;
117
118 info->name = "NVIDIA HDMI";
119 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = nvhdmi_pcm_digital_playback;
120
121 return 0;
122}
123
124static void nvhdmi_free(struct hda_codec *codec)
125{
126 kfree(codec->spec);
127}
128
129static struct hda_codec_ops nvhdmi_patch_ops = {
130 .build_controls = nvhdmi_build_controls,
131 .build_pcms = nvhdmi_build_pcms,
132 .init = nvhdmi_init,
133 .free = nvhdmi_free,
134};
135
136static int patch_nvhdmi(struct hda_codec *codec)
137{
138 struct nvhdmi_spec *spec;
139
140 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
141 if (spec == NULL)
142 return -ENOMEM;
143
144 codec->spec = spec;
145
146 spec->multiout.num_dacs = 0; /* no analog */
147 spec->multiout.max_channels = 2;
148 spec->multiout.dig_out_nid = 0x4; /* NID for copying analog to digital,
149 * seems to be unused in pure-digital
150 * case. */
151
152 codec->patch_ops = nvhdmi_patch_ops;
153
154 return 0;
155}
156
157/*
158 * patch entries
159 */
160struct hda_codec_preset snd_hda_preset_nvhdmi[] = {
161 { .id = 0x10de0002, .name = "NVIDIA MCP78 HDMI", .patch = patch_nvhdmi },
162 { .id = 0x10de0007, .name = "NVIDIA MCP7A HDMI", .patch = patch_nvhdmi },
163 {} /* terminator */
164};
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 66025161bd69..0b6e682c46d0 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -72,6 +72,7 @@ enum {
72enum { 72enum {
73 ALC260_BASIC, 73 ALC260_BASIC,
74 ALC260_HP, 74 ALC260_HP,
75 ALC260_HP_DC7600,
75 ALC260_HP_3013, 76 ALC260_HP_3013,
76 ALC260_FUJITSU_S702X, 77 ALC260_FUJITSU_S702X,
77 ALC260_ACER, 78 ALC260_ACER,
@@ -100,6 +101,9 @@ enum {
100 ALC262_BENQ_T31, 101 ALC262_BENQ_T31,
101 ALC262_ULTRA, 102 ALC262_ULTRA,
102 ALC262_LENOVO_3000, 103 ALC262_LENOVO_3000,
104 ALC262_NEC,
105 ALC262_TOSHIBA_S06,
106 ALC262_TOSHIBA_RX1,
103 ALC262_AUTO, 107 ALC262_AUTO,
104 ALC262_MODEL_LAST /* last tag */ 108 ALC262_MODEL_LAST /* last tag */
105}; 109};
@@ -110,6 +114,7 @@ enum {
110 ALC268_3ST, 114 ALC268_3ST,
111 ALC268_TOSHIBA, 115 ALC268_TOSHIBA,
112 ALC268_ACER, 116 ALC268_ACER,
117 ALC268_ACER_ASPIRE_ONE,
113 ALC268_DELL, 118 ALC268_DELL,
114 ALC268_ZEPTO, 119 ALC268_ZEPTO,
115#ifdef CONFIG_SND_DEBUG 120#ifdef CONFIG_SND_DEBUG
@@ -122,6 +127,7 @@ enum {
122/* ALC269 models */ 127/* ALC269 models */
123enum { 128enum {
124 ALC269_BASIC, 129 ALC269_BASIC,
130 ALC269_QUANTA_FL1,
125 ALC269_ASUS_EEEPC_P703, 131 ALC269_ASUS_EEEPC_P703,
126 ALC269_ASUS_EEEPC_P901, 132 ALC269_ASUS_EEEPC_P901,
127 ALC269_AUTO, 133 ALC269_AUTO,
@@ -169,6 +175,13 @@ enum {
169 ALC663_ASUS_G71V, 175 ALC663_ASUS_G71V,
170 ALC663_ASUS_H13, 176 ALC663_ASUS_H13,
171 ALC663_ASUS_G50V, 177 ALC663_ASUS_G50V,
178 ALC662_ECS,
179 ALC663_ASUS_MODE1,
180 ALC662_ASUS_MODE2,
181 ALC663_ASUS_MODE3,
182 ALC663_ASUS_MODE4,
183 ALC663_ASUS_MODE5,
184 ALC663_ASUS_MODE6,
172 ALC662_AUTO, 185 ALC662_AUTO,
173 ALC662_MODEL_LAST, 186 ALC662_MODEL_LAST,
174}; 187};
@@ -200,18 +213,21 @@ enum {
200 ALC883_ACER, 213 ALC883_ACER,
201 ALC883_ACER_ASPIRE, 214 ALC883_ACER_ASPIRE,
202 ALC883_MEDION, 215 ALC883_MEDION,
203 ALC883_MEDION_MD2, 216 ALC883_MEDION_MD2,
204 ALC883_LAPTOP_EAPD, 217 ALC883_LAPTOP_EAPD,
205 ALC883_LENOVO_101E_2ch, 218 ALC883_LENOVO_101E_2ch,
206 ALC883_LENOVO_NB0763, 219 ALC883_LENOVO_NB0763,
207 ALC888_LENOVO_MS7195_DIG, 220 ALC888_LENOVO_MS7195_DIG,
208 ALC883_HAIER_W66, 221 ALC888_LENOVO_SKY,
222 ALC883_HAIER_W66,
209 ALC888_3ST_HP, 223 ALC888_3ST_HP,
210 ALC888_6ST_DELL, 224 ALC888_6ST_DELL,
211 ALC883_MITAC, 225 ALC883_MITAC,
212 ALC883_CLEVO_M720, 226 ALC883_CLEVO_M720,
213 ALC883_FUJITSU_PI2515, 227 ALC883_FUJITSU_PI2515,
214 ALC883_3ST_6ch_INTEL, 228 ALC883_3ST_6ch_INTEL,
229 ALC888_ASUS_M90V,
230 ALC888_ASUS_EEE1601,
215 ALC883_AUTO, 231 ALC883_AUTO,
216 ALC883_MODEL_LAST, 232 ALC883_MODEL_LAST,
217}; 233};
@@ -398,7 +414,7 @@ static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
398 414
399/* 415/*
400 * Control the mode of pin widget settings via the mixer. "pc" is used 416 * Control the mode of pin widget settings via the mixer. "pc" is used
401 * instead of "%" to avoid consequences of accidently treating the % as 417 * instead of "%" to avoid consequences of accidently treating the % as
402 * being part of a format specifier. Maximum allowed length of a value is 418 * being part of a format specifier. Maximum allowed length of a value is
403 * 63 characters plus NULL terminator. 419 * 63 characters plus NULL terminator.
404 * 420 *
@@ -429,7 +445,7 @@ static unsigned char alc_pin_mode_values[] = {
429#define ALC_PIN_DIR_IN_NOMICBIAS 0x03 445#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
430#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04 446#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
431 447
432/* Info about the pin modes supported by the different pin direction modes. 448/* Info about the pin modes supported by the different pin direction modes.
433 * For each direction the minimum and maximum values are given. 449 * For each direction the minimum and maximum values are given.
434 */ 450 */
435static signed char alc_pin_mode_dir_info[5][2] = { 451static signed char alc_pin_mode_dir_info[5][2] = {
@@ -502,7 +518,7 @@ static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
502 AC_VERB_SET_PIN_WIDGET_CONTROL, 518 AC_VERB_SET_PIN_WIDGET_CONTROL,
503 alc_pin_mode_values[val]); 519 alc_pin_mode_values[val]);
504 520
505 /* Also enable the retasking pin's input/output as required 521 /* Also enable the retasking pin's input/output as required
506 * for the requested pin mode. Enum values of 2 or less are 522 * for the requested pin mode. Enum values of 2 or less are
507 * input modes. 523 * input modes.
508 * 524 *
@@ -707,7 +723,7 @@ static void setup_preset(struct alc_spec *spec,
707 i++) 723 i++)
708 spec->init_verbs[spec->num_init_verbs++] = 724 spec->init_verbs[spec->num_init_verbs++] =
709 preset->init_verbs[i]; 725 preset->init_verbs[i];
710 726
711 spec->channel_mode = preset->channel_mode; 727 spec->channel_mode = preset->channel_mode;
712 spec->num_channel_mode = preset->num_channel_mode; 728 spec->num_channel_mode = preset->num_channel_mode;
713 spec->need_dac_fix = preset->need_dac_fix; 729 spec->need_dac_fix = preset->need_dac_fix;
@@ -718,7 +734,7 @@ static void setup_preset(struct alc_spec *spec,
718 spec->multiout.dac_nids = preset->dac_nids; 734 spec->multiout.dac_nids = preset->dac_nids;
719 spec->multiout.dig_out_nid = preset->dig_out_nid; 735 spec->multiout.dig_out_nid = preset->dig_out_nid;
720 spec->multiout.hp_nid = preset->hp_nid; 736 spec->multiout.hp_nid = preset->hp_nid;
721 737
722 spec->num_mux_defs = preset->num_mux_defs; 738 spec->num_mux_defs = preset->num_mux_defs;
723 if (!spec->num_mux_defs) 739 if (!spec->num_mux_defs)
724 spec->num_mux_defs = 1; 740 spec->num_mux_defs = 1;
@@ -855,7 +871,7 @@ static void alc_subsystem_id(struct hda_codec *codec,
855 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1)) 871 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
856 goto do_sku; 872 goto do_sku;
857 873
858 /* 874 /*
859 * 31~30 : port conetcivity 875 * 31~30 : port conetcivity
860 * 29~21 : reserve 876 * 29~21 : reserve
861 * 20 : PCBEEP input 877 * 20 : PCBEEP input
@@ -946,7 +962,7 @@ do_sku:
946 tmp = snd_hda_codec_read(codec, 0x20, 0, 962 tmp = snd_hda_codec_read(codec, 0x20, 0,
947 AC_VERB_GET_PROC_COEF, 0); 963 AC_VERB_GET_PROC_COEF, 0);
948 snd_hda_codec_write(codec, 0x20, 0, 964 snd_hda_codec_write(codec, 0x20, 0,
949 AC_VERB_SET_COEF_INDEX, 7); 965 AC_VERB_SET_COEF_INDEX, 7);
950 snd_hda_codec_write(codec, 0x20, 0, 966 snd_hda_codec_write(codec, 0x20, 0,
951 AC_VERB_SET_PROC_COEF, 967 AC_VERB_SET_PROC_COEF,
952 tmp | 0x2010); 968 tmp | 0x2010);
@@ -961,7 +977,7 @@ do_sku:
961 tmp = snd_hda_codec_read(codec, 0x20, 0, 977 tmp = snd_hda_codec_read(codec, 0x20, 0,
962 AC_VERB_GET_PROC_COEF, 0); 978 AC_VERB_GET_PROC_COEF, 0);
963 snd_hda_codec_write(codec, 0x20, 0, 979 snd_hda_codec_write(codec, 0x20, 0,
964 AC_VERB_SET_COEF_INDEX, 7); 980 AC_VERB_SET_COEF_INDEX, 7);
965 snd_hda_codec_write(codec, 0x20, 0, 981 snd_hda_codec_write(codec, 0x20, 0,
966 AC_VERB_SET_PROC_COEF, 982 AC_VERB_SET_PROC_COEF,
967 tmp | 0x3000); 983 tmp | 0x3000);
@@ -970,7 +986,7 @@ do_sku:
970 default: 986 default:
971 break; 987 break;
972 } 988 }
973 989
974 /* is laptop or Desktop and enable the function "Mute internal speaker 990 /* is laptop or Desktop and enable the function "Mute internal speaker
975 * when the external headphone out jack is plugged" 991 * when the external headphone out jack is plugged"
976 */ 992 */
@@ -1006,6 +1022,7 @@ do_sku:
1006 snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0, 1022 snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
1007 AC_VERB_SET_UNSOLICITED_ENABLE, 1023 AC_VERB_SET_UNSOLICITED_ENABLE,
1008 AC_USRSP_EN | ALC880_HP_EVENT); 1024 AC_USRSP_EN | ALC880_HP_EVENT);
1025
1009 spec->unsol_event = alc_sku_unsol_event; 1026 spec->unsol_event = alc_sku_unsol_event;
1010} 1027}
1011 1028
@@ -1296,7 +1313,7 @@ static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
1296 * 1313 *
1297 * The system also has a pair of internal speakers, and a headphone jack. 1314 * The system also has a pair of internal speakers, and a headphone jack.
1298 * These are both connected to Line2 on the codec, hence to DAC 02. 1315 * These are both connected to Line2 on the codec, hence to DAC 02.
1299 * 1316 *
1300 * There is a variable resistor to control the speaker or headphone 1317 * There is a variable resistor to control the speaker or headphone
1301 * volume. This is a hardware-only device without a software API. 1318 * volume. This is a hardware-only device without a software API.
1302 * 1319 *
@@ -1824,7 +1841,7 @@ static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1824 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1841 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1825 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1842 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1826 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1843 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1827 1844
1828 { } 1845 { }
1829}; 1846};
1830 1847
@@ -1869,7 +1886,7 @@ static struct hda_verb alc880_uniwill_init_verbs[] = {
1869 1886
1870/* 1887/*
1871* Uniwill P53 1888* Uniwill P53
1872* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19, 1889* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
1873 */ 1890 */
1874static struct hda_verb alc880_uniwill_p53_init_verbs[] = { 1891static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1875 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 1892 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
@@ -1968,7 +1985,7 @@ static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
1968static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec) 1985static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
1969{ 1986{
1970 unsigned int present; 1987 unsigned int present;
1971 1988
1972 present = snd_hda_codec_read(codec, 0x21, 0, 1989 present = snd_hda_codec_read(codec, 0x21, 0,
1973 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0); 1990 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
1974 present &= HDA_AMP_VOLMASK; 1991 present &= HDA_AMP_VOLMASK;
@@ -2050,7 +2067,7 @@ static struct hda_verb alc880_pin_asus_init_verbs[] = {
2050 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2067 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2051 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2068 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2052 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2069 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2053 2070
2054 { } 2071 { }
2055}; 2072};
2056 2073
@@ -2632,12 +2649,14 @@ static int alc_build_pcms(struct hda_codec *codec)
2632 2649
2633 info->name = spec->stream_name_analog; 2650 info->name = spec->stream_name_analog;
2634 if (spec->stream_analog_playback) { 2651 if (spec->stream_analog_playback) {
2635 snd_assert(spec->multiout.dac_nids, return -EINVAL); 2652 if (snd_BUG_ON(!spec->multiout.dac_nids))
2653 return -EINVAL;
2636 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback); 2654 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2637 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0]; 2655 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2638 } 2656 }
2639 if (spec->stream_analog_capture) { 2657 if (spec->stream_analog_capture) {
2640 snd_assert(spec->adc_nids, return -EINVAL); 2658 if (snd_BUG_ON(!spec->adc_nids))
2659 return -EINVAL;
2641 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture); 2660 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2642 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; 2661 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2643 } 2662 }
@@ -2667,6 +2686,8 @@ static int alc_build_pcms(struct hda_codec *codec)
2667 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture); 2686 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2668 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid; 2687 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2669 } 2688 }
2689 /* FIXME: do we need this for all Realtek codec models? */
2690 codec->spdif_status_reset = 1;
2670 } 2691 }
2671 2692
2672 /* If the use of more than one ADC is requested for the current 2693 /* If the use of more than one ADC is requested for the current
@@ -3683,7 +3704,7 @@ static void alc880_auto_init_multi_out(struct hda_codec *codec)
3683{ 3704{
3684 struct alc_spec *spec = codec->spec; 3705 struct alc_spec *spec = codec->spec;
3685 int i; 3706 int i;
3686 3707
3687 alc_subsystem_id(codec, 0x15, 0x1b, 0x14); 3708 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
3688 for (i = 0; i < spec->autocfg.line_outs; i++) { 3709 for (i = 0; i < spec->autocfg.line_outs; i++) {
3689 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 3710 hda_nid_t nid = spec->autocfg.line_out_pins[i];
@@ -4124,6 +4145,33 @@ static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
4124 { } /* end */ 4145 { } /* end */
4125}; 4146};
4126 4147
4148static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
4149 .ops = &snd_hda_bind_vol,
4150 .values = {
4151 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
4152 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
4153 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
4154 0
4155 },
4156};
4157
4158static struct hda_bind_ctls alc260_dc7600_bind_switch = {
4159 .ops = &snd_hda_bind_sw,
4160 .values = {
4161 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
4162 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
4163 0
4164 },
4165};
4166
4167static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
4168 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
4169 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
4170 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
4171 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4172 { } /* end */
4173};
4174
4127static struct hda_verb alc260_hp_3013_unsol_verbs[] = { 4175static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
4128 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 4176 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4129 {}, 4177 {},
@@ -4147,7 +4195,30 @@ static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
4147 alc260_hp_3013_automute(codec); 4195 alc260_hp_3013_automute(codec);
4148} 4196}
4149 4197
4150/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12, 4198static void alc260_hp_3012_automute(struct hda_codec *codec)
4199{
4200 unsigned int present, bits;
4201
4202 present = snd_hda_codec_read(codec, 0x10, 0,
4203 AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
4204
4205 bits = present ? 0 : PIN_OUT;
4206 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4207 bits);
4208 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4209 bits);
4210 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4211 bits);
4212}
4213
4214static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
4215 unsigned int res)
4216{
4217 if ((res >> 26) == ALC880_HP_EVENT)
4218 alc260_hp_3012_automute(codec);
4219}
4220
4221/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
4151 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10. 4222 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
4152 */ 4223 */
4153static struct snd_kcontrol_new alc260_fujitsu_mixer[] = { 4224static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
@@ -4478,7 +4549,7 @@ static struct hda_verb alc260_fujitsu_init_verbs[] = {
4478 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 4549 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4479 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 4550 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4480 4551
4481 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus 4552 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
4482 * when acting as an output. 4553 * when acting as an output.
4483 */ 4554 */
4484 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 4555 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
@@ -4503,14 +4574,14 @@ static struct hda_verb alc260_fujitsu_init_verbs[] = {
4503 * stage. 4574 * stage.
4504 */ 4575 */
4505 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4576 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4506 /* Unmute input buffer of pin widget used for Line-in (no equiv 4577 /* Unmute input buffer of pin widget used for Line-in (no equiv
4507 * mixer ctrl) 4578 * mixer ctrl)
4508 */ 4579 */
4509 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4580 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4510 4581
4511 /* Mute capture amp left and right */ 4582 /* Mute capture amp left and right */
4512 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4583 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4513 /* Set ADC connection select to match default mixer setting - line 4584 /* Set ADC connection select to match default mixer setting - line
4514 * in (on mic1 pin) 4585 * in (on mic1 pin)
4515 */ 4586 */
4516 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 4587 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
@@ -4564,7 +4635,7 @@ static struct hda_verb alc260_acer_init_verbs[] = {
4564 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 4635 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4565 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 4636 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4566 4637
4567 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum 4638 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
4568 * bus when acting as outputs. 4639 * bus when acting as outputs.
4569 */ 4640 */
4570 {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, 4641 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
@@ -4675,6 +4746,20 @@ static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4675 alc260_replacer_672v_automute(codec); 4746 alc260_replacer_672v_automute(codec);
4676} 4747}
4677 4748
4749static struct hda_verb alc260_hp_dc7600_verbs[] = {
4750 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
4751 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
4752 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4753 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4754 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4755 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4756 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4757 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4758 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4759 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4760 {}
4761};
4762
4678/* Test configuration for debugging, modelled after the ALC880 test 4763/* Test configuration for debugging, modelled after the ALC880 test
4679 * configuration. 4764 * configuration.
4680 */ 4765 */
@@ -4686,7 +4771,7 @@ static hda_nid_t alc260_test_adc_nids[2] = {
4686 0x04, 0x05, 4771 0x04, 0x05,
4687}; 4772};
4688/* For testing the ALC260, each input MUX needs its own definition since 4773/* For testing the ALC260, each input MUX needs its own definition since
4689 * the signal assignments are different. This assumes that the first ADC 4774 * the signal assignments are different. This assumes that the first ADC
4690 * is NID 0x04. 4775 * is NID 0x04.
4691 */ 4776 */
4692static struct hda_input_mux alc260_test_capture_sources[2] = { 4777static struct hda_input_mux alc260_test_capture_sources[2] = {
@@ -4769,7 +4854,7 @@ static struct snd_kcontrol_new alc260_test_mixer[] = {
4769 4854
4770 /* Switches to allow the digital IO pins to be enabled. The datasheet 4855 /* Switches to allow the digital IO pins to be enabled. The datasheet
4771 * is ambigious as to which NID is which; testing on laptops which 4856 * is ambigious as to which NID is which; testing on laptops which
4772 * make this output available should provide clarification. 4857 * make this output available should provide clarification.
4773 */ 4858 */
4774 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01), 4859 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
4775 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01), 4860 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
@@ -4805,7 +4890,7 @@ static struct hda_verb alc260_test_init_verbs[] = {
4805 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 4890 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4806 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 4891 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4807 4892
4808 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the 4893 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
4809 * OUT1 sum bus when acting as an output. 4894 * OUT1 sum bus when acting as an output.
4810 */ 4895 */
4811 {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, 4896 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
@@ -4897,7 +4982,7 @@ static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
4897 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); 4982 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4898 } else 4983 } else
4899 return 0; /* N/A */ 4984 return 0; /* N/A */
4900 4985
4901 snprintf(name, sizeof(name), "%s Playback Volume", pfx); 4986 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
4902 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val); 4987 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
4903 if (err < 0) 4988 if (err < 0)
@@ -5003,7 +5088,7 @@ static void alc260_auto_init_multi_out(struct hda_codec *codec)
5003 int pin_type = get_pin_type(spec->autocfg.line_out_type); 5088 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5004 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0); 5089 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
5005 } 5090 }
5006 5091
5007 nid = spec->autocfg.speaker_pins[0]; 5092 nid = spec->autocfg.speaker_pins[0];
5008 if (nid) 5093 if (nid)
5009 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0); 5094 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
@@ -5045,7 +5130,7 @@ static struct hda_verb alc260_volume_init_verbs[] = {
5045 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5130 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5046 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 5131 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5047 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5132 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5048 5133
5049 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 5134 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5050 * mixer widget 5135 * mixer widget
5051 * Note: PASD motherboards uses the Line In 2 as the input for 5136 * Note: PASD motherboards uses the Line In 2 as the input for
@@ -5074,7 +5159,7 @@ static struct hda_verb alc260_volume_init_verbs[] = {
5074 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5159 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5075 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5160 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5076 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5161 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5077 5162
5078 { } 5163 { }
5079}; 5164};
5080 5165
@@ -5155,6 +5240,7 @@ static const char *alc260_models[ALC260_MODEL_LAST] = {
5155 [ALC260_BASIC] = "basic", 5240 [ALC260_BASIC] = "basic",
5156 [ALC260_HP] = "hp", 5241 [ALC260_HP] = "hp",
5157 [ALC260_HP_3013] = "hp-3013", 5242 [ALC260_HP_3013] = "hp-3013",
5243 [ALC260_HP_DC7600] = "hp-dc7600",
5158 [ALC260_FUJITSU_S702X] = "fujitsu", 5244 [ALC260_FUJITSU_S702X] = "fujitsu",
5159 [ALC260_ACER] = "acer", 5245 [ALC260_ACER] = "acer",
5160 [ALC260_WILL] = "will", 5246 [ALC260_WILL] = "will",
@@ -5172,7 +5258,7 @@ static struct snd_pci_quirk alc260_cfg_tbl[] = {
5172 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013), 5258 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
5173 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013), 5259 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
5174 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013), 5260 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
5175 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013), 5261 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
5176 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013), 5262 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
5177 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP), 5263 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
5178 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP), 5264 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
@@ -5218,6 +5304,22 @@ static struct alc_config_preset alc260_presets[] = {
5218 .unsol_event = alc260_hp_unsol_event, 5304 .unsol_event = alc260_hp_unsol_event,
5219 .init_hook = alc260_hp_automute, 5305 .init_hook = alc260_hp_automute,
5220 }, 5306 },
5307 [ALC260_HP_DC7600] = {
5308 .mixers = { alc260_hp_dc7600_mixer,
5309 alc260_input_mixer,
5310 alc260_capture_alt_mixer },
5311 .init_verbs = { alc260_init_verbs,
5312 alc260_hp_dc7600_verbs },
5313 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5314 .dac_nids = alc260_dac_nids,
5315 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5316 .adc_nids = alc260_hp_adc_nids,
5317 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5318 .channel_mode = alc260_modes,
5319 .input_mux = &alc260_capture_source,
5320 .unsol_event = alc260_hp_3012_unsol_event,
5321 .init_hook = alc260_hp_3012_automute,
5322 },
5221 [ALC260_HP_3013] = { 5323 [ALC260_HP_3013] = {
5222 .mixers = { alc260_hp_3013_mixer, 5324 .mixers = { alc260_hp_3013_mixer,
5223 alc260_input_mixer, 5325 alc260_input_mixer,
@@ -5933,7 +6035,7 @@ static struct hda_verb alc882_targa_verbs[] = {
5933 6035
5934 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6036 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5935 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6037 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5936 6038
5937 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 6039 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5938 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ 6040 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5939 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 6041 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
@@ -5949,7 +6051,7 @@ static struct hda_verb alc882_targa_verbs[] = {
5949static void alc882_targa_automute(struct hda_codec *codec) 6051static void alc882_targa_automute(struct hda_codec *codec)
5950{ 6052{
5951 unsigned int present; 6053 unsigned int present;
5952 6054
5953 present = snd_hda_codec_read(codec, 0x14, 0, 6055 present = snd_hda_codec_read(codec, 0x14, 0,
5954 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 6056 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5955 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0, 6057 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
@@ -5975,7 +6077,7 @@ static struct hda_verb alc882_asus_a7j_verbs[] = {
5975 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6077 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5976 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6078 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5977 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6079 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5978 6080
5979 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 6081 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5980 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 6082 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5981 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 6083 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
@@ -5993,7 +6095,7 @@ static struct hda_verb alc882_asus_a7m_verbs[] = {
5993 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6095 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5994 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6096 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5995 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6097 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5996 6098
5997 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 6099 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5998 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 6100 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5999 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 6101 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
@@ -6319,7 +6421,7 @@ static struct alc_config_preset alc882_presets[] = {
6319 .channel_mode = alc882_3ST_6ch_modes, 6421 .channel_mode = alc882_3ST_6ch_modes,
6320 .need_dac_fix = 1, 6422 .need_dac_fix = 1,
6321 .input_mux = &alc882_capture_source, 6423 .input_mux = &alc882_capture_source,
6322 }, 6424 },
6323 [ALC882_ASUS_A7M] = { 6425 [ALC882_ASUS_A7M] = {
6324 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer }, 6426 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
6325 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs, 6427 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
@@ -6332,14 +6434,14 @@ static struct alc_config_preset alc882_presets[] = {
6332 .channel_mode = alc880_threestack_modes, 6434 .channel_mode = alc880_threestack_modes,
6333 .need_dac_fix = 1, 6435 .need_dac_fix = 1,
6334 .input_mux = &alc882_capture_source, 6436 .input_mux = &alc882_capture_source,
6335 }, 6437 },
6336}; 6438};
6337 6439
6338 6440
6339/* 6441/*
6340 * Pin config fixes 6442 * Pin config fixes
6341 */ 6443 */
6342enum { 6444enum {
6343 PINFIX_ABIT_AW9D_MAX 6445 PINFIX_ABIT_AW9D_MAX
6344}; 6446};
6345 6447
@@ -6554,16 +6656,19 @@ static int patch_alc882(struct hda_codec *codec)
6554 board_config = ALC885_MACPRO; 6656 board_config = ALC885_MACPRO;
6555 break; 6657 break;
6556 case 0x106b1000: /* iMac 24 */ 6658 case 0x106b1000: /* iMac 24 */
6659 case 0x106b2800: /* AppleTV */
6557 board_config = ALC885_IMAC24; 6660 board_config = ALC885_IMAC24;
6558 break; 6661 break;
6559 case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */ 6662 case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
6663 case 0x106b00a4: /* MacbookPro4,1 */
6560 case 0x106b2c00: /* Macbook Pro rev3 */ 6664 case 0x106b2c00: /* Macbook Pro rev3 */
6561 case 0x106b3600: /* Macbook 3.1 */ 6665 case 0x106b3600: /* Macbook 3.1 */
6562 board_config = ALC885_MBP3; 6666 board_config = ALC885_MBP3;
6563 break; 6667 break;
6564 default: 6668 default:
6565 /* ALC889A is handled better as ALC888-compatible */ 6669 /* ALC889A is handled better as ALC888-compatible */
6566 if (codec->revision_id == 0x100103) { 6670 if (codec->revision_id == 0x100101 ||
6671 codec->revision_id == 0x100103) {
6567 alc_free(codec); 6672 alc_free(codec);
6568 return patch_alc883(codec); 6673 return patch_alc883(codec);
6569 } 6674 }
@@ -6718,6 +6823,23 @@ static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
6718 }, 6823 },
6719}; 6824};
6720 6825
6826static struct hda_input_mux alc883_lenovo_sky_capture_source = {
6827 .num_items = 3,
6828 .items = {
6829 { "Mic", 0x0 },
6830 { "Front Mic", 0x1 },
6831 { "Line", 0x4 },
6832 },
6833};
6834
6835static struct hda_input_mux alc883_asus_eee1601_capture_source = {
6836 .num_items = 2,
6837 .items = {
6838 { "Mic", 0x0 },
6839 { "Line", 0x2 },
6840 },
6841};
6842
6721#define alc883_mux_enum_info alc_mux_enum_info 6843#define alc883_mux_enum_info alc_mux_enum_info
6722#define alc883_mux_enum_get alc_mux_enum_get 6844#define alc883_mux_enum_get alc_mux_enum_get
6723/* ALC883 has the ALC882-type input selection */ 6845/* ALC883 has the ALC882-type input selection */
@@ -7032,13 +7154,11 @@ static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
7032 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 7154 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7033 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 7155 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7034 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 7156 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7035 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7036 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7037 { 7157 {
7038 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 7158 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7039 /* .name = "Capture Source", */ 7159 /* .name = "Capture Source", */
7040 .name = "Input Source", 7160 .name = "Input Source",
7041 .count = 2, 7161 .count = 1,
7042 .info = alc883_mux_enum_info, 7162 .info = alc883_mux_enum_info,
7043 .get = alc883_mux_enum_get, 7163 .get = alc883_mux_enum_get,
7044 .put = alc883_mux_enum_put, 7164 .put = alc883_mux_enum_put,
@@ -7256,7 +7376,7 @@ static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
7256 .put = alc883_mux_enum_put, 7376 .put = alc883_mux_enum_put,
7257 }, 7377 },
7258 { } /* end */ 7378 { } /* end */
7259}; 7379};
7260 7380
7261static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = { 7381static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
7262 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7382 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
@@ -7283,6 +7403,87 @@ static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
7283 { } /* end */ 7403 { } /* end */
7284}; 7404};
7285 7405
7406static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
7407 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7408 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7409 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
7410 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
7411 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
7412 0x0d, 1, 0x0, HDA_OUTPUT),
7413 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
7414 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
7415 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
7416 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7417 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7418 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7419 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
7420 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7421 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7422 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7423 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7424 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7425 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7426 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7427 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7428 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7429 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7430 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7431 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7432 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7433 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7434 {
7435 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7436 /* .name = "Capture Source", */
7437 .name = "Input Source",
7438 .count = 2,
7439 .info = alc883_mux_enum_info,
7440 .get = alc883_mux_enum_get,
7441 .put = alc883_mux_enum_put,
7442 },
7443 { } /* end */
7444};
7445
7446static struct hda_bind_ctls alc883_bind_cap_vol = {
7447 .ops = &snd_hda_bind_vol,
7448 .values = {
7449 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7450 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7451 0
7452 },
7453};
7454
7455static struct hda_bind_ctls alc883_bind_cap_switch = {
7456 .ops = &snd_hda_bind_sw,
7457 .values = {
7458 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7459 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7460 0
7461 },
7462};
7463
7464static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
7465 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7466 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7467 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7468 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7469 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7470 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7471 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7472 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7473 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
7474 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
7475 {
7476 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7477 /* .name = "Capture Source", */
7478 .name = "Input Source",
7479 .count = 1,
7480 .info = alc883_mux_enum_info,
7481 .get = alc883_mux_enum_get,
7482 .put = alc883_mux_enum_put,
7483 },
7484 { } /* end */
7485};
7486
7286static struct snd_kcontrol_new alc883_chmode_mixer[] = { 7487static struct snd_kcontrol_new alc883_chmode_mixer[] = {
7287 { 7488 {
7288 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 7489 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -7296,7 +7497,7 @@ static struct snd_kcontrol_new alc883_chmode_mixer[] = {
7296 7497
7297static struct hda_verb alc883_init_verbs[] = { 7498static struct hda_verb alc883_init_verbs[] = {
7298 /* ADC1: mute amp left and right */ 7499 /* ADC1: mute amp left and right */
7299 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7500 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7300 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 7501 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7301 /* ADC2: mute amp left and right */ 7502 /* ADC2: mute amp left and right */
7302 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7503 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
@@ -7361,14 +7562,14 @@ static struct hda_verb alc883_init_verbs[] = {
7361 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 7562 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7362 /* Input mixer2 */ 7563 /* Input mixer2 */
7363 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7564 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7364 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7565 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7365 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 7566 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7366 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 7567 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7367 /* Input mixer3 */ 7568 /* Input mixer3 */
7368 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7569 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7369 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7570 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7370 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 7571 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7371 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 7572 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7372 { } 7573 { }
7373}; 7574};
7374 7575
@@ -7468,7 +7669,7 @@ static struct hda_verb alc883_tagra_verbs[] = {
7468 7669
7469 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7670 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7470 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7671 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7471 7672
7472 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 7673 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7473 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ 7674 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7474 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 7675 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
@@ -7518,6 +7719,18 @@ static struct hda_verb alc883_haier_w66_verbs[] = {
7518 { } /* end */ 7719 { } /* end */
7519}; 7720};
7520 7721
7722static struct hda_verb alc888_lenovo_sky_verbs[] = {
7723 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7724 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7725 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7726 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7727 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7728 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7729 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
7730 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7731 { } /* end */
7732};
7733
7521static struct hda_verb alc888_3st_hp_verbs[] = { 7734static struct hda_verb alc888_3st_hp_verbs[] = {
7522 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */ 7735 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
7523 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */ 7736 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
@@ -7555,7 +7768,7 @@ static struct hda_channel_mode alc888_3st_hp_modes[2] = {
7555static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec) 7768static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
7556{ 7769{
7557 unsigned int present; 7770 unsigned int present;
7558 7771
7559 present = snd_hda_codec_read(codec, 0x1b, 0, 7772 present = snd_hda_codec_read(codec, 0x1b, 0,
7560 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 7773 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7561 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 7774 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
@@ -7568,7 +7781,7 @@ static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
7568static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec) 7781static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
7569{ 7782{
7570 unsigned int present; 7783 unsigned int present;
7571 7784
7572 present = snd_hda_codec_read(codec, 0x14, 0, 7785 present = snd_hda_codec_read(codec, 0x14, 0,
7573 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 7786 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7574 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 7787 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
@@ -7598,7 +7811,7 @@ static struct hda_verb alc883_medion_md2_verbs[] = {
7598static void alc883_medion_md2_automute(struct hda_codec *codec) 7811static void alc883_medion_md2_automute(struct hda_codec *codec)
7599{ 7812{
7600 unsigned int present; 7813 unsigned int present;
7601 7814
7602 present = snd_hda_codec_read(codec, 0x14, 0, 7815 present = snd_hda_codec_read(codec, 0x14, 0,
7603 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 7816 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7604 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 7817 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
@@ -7753,7 +7966,7 @@ static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
7753static void alc883_acer_aspire_automute(struct hda_codec *codec) 7966static void alc883_acer_aspire_automute(struct hda_codec *codec)
7754{ 7967{
7755 unsigned int present; 7968 unsigned int present;
7756 7969
7757 present = snd_hda_codec_read(codec, 0x14, 0, 7970 present = snd_hda_codec_read(codec, 0x14, 0,
7758 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 7971 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7759 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 7972 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
@@ -7790,7 +8003,7 @@ static struct hda_verb alc883_acer_eapd_verbs[] = {
7790static void alc888_6st_dell_front_automute(struct hda_codec *codec) 8003static void alc888_6st_dell_front_automute(struct hda_codec *codec)
7791{ 8004{
7792 unsigned int present; 8005 unsigned int present;
7793 8006
7794 present = snd_hda_codec_read(codec, 0x1b, 0, 8007 present = snd_hda_codec_read(codec, 0x1b, 0,
7795 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 8008 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7796 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 8009 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
@@ -7814,6 +8027,50 @@ static void alc888_6st_dell_unsol_event(struct hda_codec *codec,
7814 } 8027 }
7815} 8028}
7816 8029
8030static void alc888_lenovo_sky_front_automute(struct hda_codec *codec)
8031{
8032 unsigned int mute;
8033 unsigned int present;
8034
8035 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
8036 present = snd_hda_codec_read(codec, 0x1b, 0,
8037 AC_VERB_GET_PIN_SENSE, 0);
8038 present = (present & 0x80000000) != 0;
8039 if (present) {
8040 /* mute internal speaker */
8041 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8042 HDA_AMP_MUTE, HDA_AMP_MUTE);
8043 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8044 HDA_AMP_MUTE, HDA_AMP_MUTE);
8045 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8046 HDA_AMP_MUTE, HDA_AMP_MUTE);
8047 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8048 HDA_AMP_MUTE, HDA_AMP_MUTE);
8049 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
8050 HDA_AMP_MUTE, HDA_AMP_MUTE);
8051 } else {
8052 /* unmute internal speaker if necessary */
8053 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
8054 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8055 HDA_AMP_MUTE, mute);
8056 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8057 HDA_AMP_MUTE, mute);
8058 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8059 HDA_AMP_MUTE, mute);
8060 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8061 HDA_AMP_MUTE, mute);
8062 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
8063 HDA_AMP_MUTE, mute);
8064 }
8065}
8066
8067static void alc883_lenovo_sky_unsol_event(struct hda_codec *codec,
8068 unsigned int res)
8069{
8070 if ((res >> 26) == ALC880_HP_EVENT)
8071 alc888_lenovo_sky_front_automute(codec);
8072}
8073
7817/* 8074/*
7818 * generic initialization of ADC, input mixers and output mixers 8075 * generic initialization of ADC, input mixers and output mixers
7819 */ 8076 */
@@ -7898,6 +8155,105 @@ static struct snd_kcontrol_new alc883_capture_mixer[] = {
7898 { } /* end */ 8155 { } /* end */
7899}; 8156};
7900 8157
8158static struct hda_verb alc888_asus_m90v_verbs[] = {
8159 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8160 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8161 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8162 /* enable unsolicited event */
8163 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8164 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8165 { } /* end */
8166};
8167
8168static void alc883_nb_mic_automute(struct hda_codec *codec)
8169{
8170 unsigned int present;
8171
8172 present = snd_hda_codec_read(codec, 0x18, 0,
8173 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8174 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8175 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
8176 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8177 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
8178}
8179
8180static void alc883_M90V_speaker_automute(struct hda_codec *codec)
8181{
8182 unsigned int present;
8183 unsigned char bits;
8184
8185 present = snd_hda_codec_read(codec, 0x1b, 0,
8186 AC_VERB_GET_PIN_SENSE, 0)
8187 & AC_PINSENSE_PRESENCE;
8188 bits = present ? 0 : PIN_OUT;
8189 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8190 bits);
8191 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8192 bits);
8193 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8194 bits);
8195}
8196
8197static void alc883_mode2_unsol_event(struct hda_codec *codec,
8198 unsigned int res)
8199{
8200 switch (res >> 26) {
8201 case ALC880_HP_EVENT:
8202 alc883_M90V_speaker_automute(codec);
8203 break;
8204 case ALC880_MIC_EVENT:
8205 alc883_nb_mic_automute(codec);
8206 break;
8207 }
8208}
8209
8210static void alc883_mode2_inithook(struct hda_codec *codec)
8211{
8212 alc883_M90V_speaker_automute(codec);
8213 alc883_nb_mic_automute(codec);
8214}
8215
8216static struct hda_verb alc888_asus_eee1601_verbs[] = {
8217 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8218 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8219 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8220 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8221 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8222 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
8223 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
8224 /* enable unsolicited event */
8225 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8226 { } /* end */
8227};
8228
8229static void alc883_eee1601_speaker_automute(struct hda_codec *codec)
8230{
8231 unsigned int present;
8232 unsigned char bits;
8233
8234 present = snd_hda_codec_read(codec, 0x14, 0,
8235 AC_VERB_GET_PIN_SENSE, 0)
8236 & AC_PINSENSE_PRESENCE;
8237 bits = present ? 0 : PIN_OUT;
8238 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8239 bits);
8240}
8241
8242static void alc883_eee1601_unsol_event(struct hda_codec *codec,
8243 unsigned int res)
8244{
8245 switch (res >> 26) {
8246 case ALC880_HP_EVENT:
8247 alc883_eee1601_speaker_automute(codec);
8248 break;
8249 }
8250}
8251
8252static void alc883_eee1601_inithook(struct hda_codec *codec)
8253{
8254 alc883_eee1601_speaker_automute(codec);
8255}
8256
7901#ifdef CONFIG_SND_HDA_POWER_SAVE 8257#ifdef CONFIG_SND_HDA_POWER_SAVE
7902#define alc883_loopbacks alc880_loopbacks 8258#define alc883_loopbacks alc880_loopbacks
7903#endif 8259#endif
@@ -7927,6 +8283,7 @@ static const char *alc883_models[ALC883_MODEL_LAST] = {
7927 [ALC883_LENOVO_101E_2ch] = "lenovo-101e", 8283 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
7928 [ALC883_LENOVO_NB0763] = "lenovo-nb0763", 8284 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
7929 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig", 8285 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
8286 [ALC888_LENOVO_SKY] = "lenovo-sky",
7930 [ALC883_HAIER_W66] = "haier-w66", 8287 [ALC883_HAIER_W66] = "haier-w66",
7931 [ALC888_3ST_HP] = "3stack-hp", 8288 [ALC888_3ST_HP] = "3stack-hp",
7932 [ALC888_6ST_DELL] = "6stack-dell", 8289 [ALC888_6ST_DELL] = "6stack-dell",
@@ -7942,7 +8299,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
7942 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE), 8299 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
7943 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE), 8300 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
7944 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE), 8301 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
7945 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE), 8302 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
7946 SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */ 8303 SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
7947 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL), 8304 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
7948 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG), 8305 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
@@ -7950,10 +8307,13 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
7950 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP), 8307 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
7951 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG), 8308 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
7952 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG), 8309 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
8310 SND_PCI_QUIRK(0x1043, 0x8317, "Asus M90V", ALC888_ASUS_M90V),
8311 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
7953 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG), 8312 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
7954 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG), 8313 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
7955 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC), 8314 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
7956 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD), 8315 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
8316 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
7957 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch), 8317 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
7958 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG), 8318 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
7959 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG), 8319 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
@@ -7989,6 +8349,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
7989 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763), 8349 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7990 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763), 8350 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7991 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763), 8351 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8352 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
7992 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2), 8353 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
7993 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG), 8354 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
7994 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66), 8355 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
@@ -8128,7 +8489,7 @@ static struct alc_config_preset alc883_presets[] = {
8128 .input_mux = &alc883_capture_source, 8489 .input_mux = &alc883_capture_source,
8129 .unsol_event = alc883_medion_md2_unsol_event, 8490 .unsol_event = alc883_medion_md2_unsol_event,
8130 .init_hook = alc883_medion_md2_automute, 8491 .init_hook = alc883_medion_md2_automute,
8131 }, 8492 },
8132 [ALC883_LAPTOP_EAPD] = { 8493 [ALC883_LAPTOP_EAPD] = {
8133 .mixers = { alc883_base_mixer }, 8494 .mixers = { alc883_base_mixer },
8134 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs }, 8495 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
@@ -8245,6 +8606,49 @@ static struct alc_config_preset alc883_presets[] = {
8245 .unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event, 8606 .unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event,
8246 .init_hook = alc883_2ch_fujitsu_pi2515_automute, 8607 .init_hook = alc883_2ch_fujitsu_pi2515_automute,
8247 }, 8608 },
8609 [ALC888_LENOVO_SKY] = {
8610 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
8611 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
8612 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8613 .dac_nids = alc883_dac_nids,
8614 .dig_out_nid = ALC883_DIGOUT_NID,
8615 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
8616 .adc_nids = alc883_adc_nids,
8617 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8618 .channel_mode = alc883_sixstack_modes,
8619 .need_dac_fix = 1,
8620 .input_mux = &alc883_lenovo_sky_capture_source,
8621 .unsol_event = alc883_lenovo_sky_unsol_event,
8622 .init_hook = alc888_lenovo_sky_front_automute,
8623 },
8624 [ALC888_ASUS_M90V] = {
8625 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8626 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
8627 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8628 .dac_nids = alc883_dac_nids,
8629 .dig_out_nid = ALC883_DIGOUT_NID,
8630 .dig_in_nid = ALC883_DIGIN_NID,
8631 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8632 .channel_mode = alc883_3ST_6ch_modes,
8633 .need_dac_fix = 1,
8634 .input_mux = &alc883_fujitsu_pi2515_capture_source,
8635 .unsol_event = alc883_mode2_unsol_event,
8636 .init_hook = alc883_mode2_inithook,
8637 },
8638 [ALC888_ASUS_EEE1601] = {
8639 .mixers = { alc883_asus_eee1601_mixer },
8640 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
8641 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8642 .dac_nids = alc883_dac_nids,
8643 .dig_out_nid = ALC883_DIGOUT_NID,
8644 .dig_in_nid = ALC883_DIGIN_NID,
8645 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8646 .channel_mode = alc883_3ST_2ch_modes,
8647 .need_dac_fix = 1,
8648 .input_mux = &alc883_asus_eee1601_capture_source,
8649 .unsol_event = alc883_eee1601_unsol_event,
8650 .init_hook = alc883_eee1601_inithook,
8651 },
8248}; 8652};
8249 8653
8250 8654
@@ -8452,6 +8856,13 @@ static int patch_alc883(struct hda_codec *codec)
8452#define alc262_modes alc260_modes 8856#define alc262_modes alc260_modes
8453#define alc262_capture_source alc882_capture_source 8857#define alc262_capture_source alc882_capture_source
8454 8858
8859static hda_nid_t alc262_dmic_adc_nids[1] = {
8860 /* ADC0 */
8861 0x09
8862};
8863
8864static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
8865
8455static struct snd_kcontrol_new alc262_base_mixer[] = { 8866static struct snd_kcontrol_new alc262_base_mixer[] = {
8456 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8867 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8457 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 8868 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
@@ -8833,10 +9244,10 @@ static struct hda_verb alc262_init_verbs[] = {
8833 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 9244 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8834 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 9245 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8835 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 9246 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8836 9247
8837 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 9248 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8838 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 9249 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8839 9250
8840 /* FIXME: use matrix-type input source selection */ 9251 /* FIXME: use matrix-type input source selection */
8841 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 9252 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8842 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 9253 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
@@ -8858,6 +9269,12 @@ static struct hda_verb alc262_init_verbs[] = {
8858 { } 9269 { }
8859}; 9270};
8860 9271
9272static struct hda_verb alc262_eapd_verbs[] = {
9273 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9274 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9275 { }
9276};
9277
8861static struct hda_verb alc262_hippo_unsol_verbs[] = { 9278static struct hda_verb alc262_hippo_unsol_verbs[] = {
8862 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 9279 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8863 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9280 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
@@ -8884,6 +9301,91 @@ static struct hda_verb alc262_sony_unsol_verbs[] = {
8884 {} 9301 {}
8885}; 9302};
8886 9303
9304static struct hda_input_mux alc262_dmic_capture_source = {
9305 .num_items = 2,
9306 .items = {
9307 { "Int DMic", 0x9 },
9308 { "Mic", 0x0 },
9309 },
9310};
9311
9312static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
9313 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9314 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9315 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9316 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9317 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9318 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
9319 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
9320 {
9321 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9322 /* The multiple "Capture Source" controls confuse alsamixer
9323 * So call somewhat different..
9324 */
9325 /* .name = "Capture Source", */
9326 .name = "Input Source",
9327 .count = 1,
9328 .info = alc_mux_enum_info,
9329 .get = alc_mux_enum_get,
9330 .put = alc_mux_enum_put,
9331 },
9332 { } /* end */
9333};
9334
9335static struct hda_verb alc262_toshiba_s06_verbs[] = {
9336 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9337 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9338 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9339 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9340 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
9341 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9342 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
9343 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9344 {}
9345};
9346
9347static void alc262_dmic_automute(struct hda_codec *codec)
9348{
9349 unsigned int present;
9350
9351 present = snd_hda_codec_read(codec, 0x18, 0,
9352 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9353 snd_hda_codec_write(codec, 0x22, 0,
9354 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09);
9355}
9356
9357/* toggle speaker-output according to the hp-jack state */
9358static void alc262_toshiba_s06_speaker_automute(struct hda_codec *codec)
9359{
9360 unsigned int present;
9361 unsigned char bits;
9362
9363 present = snd_hda_codec_read(codec, 0x15, 0,
9364 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9365 bits = present ? 0 : PIN_OUT;
9366 snd_hda_codec_write(codec, 0x14, 0,
9367 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
9368}
9369
9370
9371
9372/* unsolicited event for HP jack sensing */
9373static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec,
9374 unsigned int res)
9375{
9376 if ((res >> 26) == ALC880_HP_EVENT)
9377 alc262_toshiba_s06_speaker_automute(codec);
9378 if ((res >> 26) == ALC880_MIC_EVENT)
9379 alc262_dmic_automute(codec);
9380
9381}
9382
9383static void alc262_toshiba_s06_init_hook(struct hda_codec *codec)
9384{
9385 alc262_toshiba_s06_speaker_automute(codec);
9386 alc262_dmic_automute(codec);
9387}
9388
8887/* mute/unmute internal speaker according to the hp jack and mute state */ 9389/* mute/unmute internal speaker according to the hp jack and mute state */
8888static void alc262_hippo_automute(struct hda_codec *codec) 9390static void alc262_hippo_automute(struct hda_codec *codec)
8889{ 9391{
@@ -8948,6 +9450,41 @@ static void alc262_hippo1_unsol_event(struct hda_codec *codec,
8948} 9450}
8949 9451
8950/* 9452/*
9453 * nec model
9454 * 0x15 = headphone
9455 * 0x16 = internal speaker
9456 * 0x18 = external mic
9457 */
9458
9459static struct snd_kcontrol_new alc262_nec_mixer[] = {
9460 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9461 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
9462
9463 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9464 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9465 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9466
9467 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9468 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9469 { } /* end */
9470};
9471
9472static struct hda_verb alc262_nec_verbs[] = {
9473 /* Unmute Speaker */
9474 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9475
9476 /* Headphone */
9477 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9478 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9479
9480 /* External mic to headphone */
9481 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9482 /* External mic to speaker */
9483 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9484 {}
9485};
9486
9487/*
8951 * fujitsu model 9488 * fujitsu model
8952 * 0x14 = headphone/spdif-out, 0x15 = internal speaker, 9489 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
8953 * 0x1b = port replicator headphone out 9490 * 0x1b = port replicator headphone out
@@ -9179,6 +9716,25 @@ static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
9179 { } /* end */ 9716 { } /* end */
9180}; 9717};
9181 9718
9719static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
9720 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9721 {
9722 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9723 .name = "Master Playback Switch",
9724 .info = snd_hda_mixer_amp_switch_info,
9725 .get = snd_hda_mixer_amp_switch_get,
9726 .put = alc262_sony_master_sw_put,
9727 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
9728 },
9729 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9730 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9731 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9732 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9733 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9734 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9735 { } /* end */
9736};
9737
9182/* additional init verbs for Benq laptops */ 9738/* additional init verbs for Benq laptops */
9183static struct hda_verb alc262_EAPD_verbs[] = { 9739static struct hda_verb alc262_EAPD_verbs[] = {
9184 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 9740 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
@@ -9427,7 +9983,7 @@ static struct hda_verb alc262_volume_init_verbs[] = {
9427 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 9983 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9428 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 9984 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9429 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 9985 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9430 9986
9431 /* set up input amps for analog loopback */ 9987 /* set up input amps for analog loopback */
9432 /* Amp Indices: DAC = 0, mixer = 1 */ 9988 /* Amp Indices: DAC = 0, mixer = 1 */
9433 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9989 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
@@ -9482,7 +10038,7 @@ static struct hda_verb alc262_HP_BPC_init_verbs[] = {
9482 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 10038 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9483 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 10039 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
9484 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 10040 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9485 10041
9486 /* 10042 /*
9487 * Set up output mixers (0x0c - 0x0e) 10043 * Set up output mixers (0x0c - 0x0e)
9488 */ 10044 */
@@ -9643,6 +10199,24 @@ static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
9643 { } 10199 { }
9644}; 10200};
9645 10201
10202static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
10203
10204 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
10205 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10206 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
10207
10208 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
10209 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10210 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10211 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10212
10213 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
10214 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10215 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10216 {}
10217};
10218
10219
9646#ifdef CONFIG_SND_HDA_POWER_SAVE 10220#ifdef CONFIG_SND_HDA_POWER_SAVE
9647#define alc262_loopbacks alc880_loopbacks 10221#define alc262_loopbacks alc880_loopbacks
9648#endif 10222#endif
@@ -9729,13 +10303,17 @@ static const char *alc262_models[ALC262_MODEL_LAST] = {
9729 [ALC262_BENQ_ED8] = "benq", 10303 [ALC262_BENQ_ED8] = "benq",
9730 [ALC262_BENQ_T31] = "benq-t31", 10304 [ALC262_BENQ_T31] = "benq-t31",
9731 [ALC262_SONY_ASSAMD] = "sony-assamd", 10305 [ALC262_SONY_ASSAMD] = "sony-assamd",
10306 [ALC262_TOSHIBA_S06] = "toshiba-s06",
10307 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
9732 [ALC262_ULTRA] = "ultra", 10308 [ALC262_ULTRA] = "ultra",
9733 [ALC262_LENOVO_3000] = "lenovo-3000", 10309 [ALC262_LENOVO_3000] = "lenovo-3000",
10310 [ALC262_NEC] = "nec",
9734 [ALC262_AUTO] = "auto", 10311 [ALC262_AUTO] = "auto",
9735}; 10312};
9736 10313
9737static struct snd_pci_quirk alc262_cfg_tbl[] = { 10314static struct snd_pci_quirk alc262_cfg_tbl[] = {
9738 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO), 10315 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
10316 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
9739 SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC), 10317 SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
9740 SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC), 10318 SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
9741 SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC), 10319 SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
@@ -9764,7 +10342,8 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = {
9764 SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD), 10342 SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
9765 SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD), 10343 SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
9766 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1", 10344 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
9767 ALC262_SONY_ASSAMD), 10345 ALC262_TOSHIBA_RX1),
10346 SND_PCI_QUIRK(0x1179, 0x0268, "Toshiba S06", ALC262_TOSHIBA_S06),
9768 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU), 10347 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
9769 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU), 10348 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
9770 SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA), 10349 SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
@@ -9918,7 +10497,7 @@ static struct alc_config_preset alc262_presets[] = {
9918 .input_mux = &alc262_capture_source, 10497 .input_mux = &alc262_capture_source,
9919 .unsol_event = alc262_hippo_unsol_event, 10498 .unsol_event = alc262_hippo_unsol_event,
9920 .init_hook = alc262_hippo_automute, 10499 .init_hook = alc262_hippo_automute,
9921 }, 10500 },
9922 [ALC262_ULTRA] = { 10501 [ALC262_ULTRA] = {
9923 .mixers = { alc262_ultra_mixer, alc262_ultra_capture_mixer }, 10502 .mixers = { alc262_ultra_mixer, alc262_ultra_capture_mixer },
9924 .init_verbs = { alc262_ultra_verbs }, 10503 .init_verbs = { alc262_ultra_verbs },
@@ -9946,6 +10525,43 @@ static struct alc_config_preset alc262_presets[] = {
9946 .input_mux = &alc262_fujitsu_capture_source, 10525 .input_mux = &alc262_fujitsu_capture_source,
9947 .unsol_event = alc262_lenovo_3000_unsol_event, 10526 .unsol_event = alc262_lenovo_3000_unsol_event,
9948 }, 10527 },
10528 [ALC262_NEC] = {
10529 .mixers = { alc262_nec_mixer },
10530 .init_verbs = { alc262_nec_verbs },
10531 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10532 .dac_nids = alc262_dac_nids,
10533 .hp_nid = 0x03,
10534 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10535 .channel_mode = alc262_modes,
10536 .input_mux = &alc262_capture_source,
10537 },
10538 [ALC262_TOSHIBA_S06] = {
10539 .mixers = { alc262_toshiba_s06_mixer },
10540 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
10541 alc262_eapd_verbs },
10542 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10543 .capsrc_nids = alc262_dmic_capsrc_nids,
10544 .dac_nids = alc262_dac_nids,
10545 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
10546 .dig_out_nid = ALC262_DIGOUT_NID,
10547 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10548 .channel_mode = alc262_modes,
10549 .input_mux = &alc262_dmic_capture_source,
10550 .unsol_event = alc262_toshiba_s06_unsol_event,
10551 .init_hook = alc262_toshiba_s06_init_hook,
10552 },
10553 [ALC262_TOSHIBA_RX1] = {
10554 .mixers = { alc262_toshiba_rx1_mixer },
10555 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
10556 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10557 .dac_nids = alc262_dac_nids,
10558 .hp_nid = 0x03,
10559 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10560 .channel_mode = alc262_modes,
10561 .input_mux = &alc262_capture_source,
10562 .unsol_event = alc262_hippo_unsol_event,
10563 .init_hook = alc262_hippo_automute,
10564 },
9949}; 10565};
9950 10566
9951static int patch_alc262(struct hda_codec *codec) 10567static int patch_alc262(struct hda_codec *codec)
@@ -10004,7 +10620,7 @@ static int patch_alc262(struct hda_codec *codec)
10004 spec->stream_name_analog = "ALC262 Analog"; 10620 spec->stream_name_analog = "ALC262 Analog";
10005 spec->stream_analog_playback = &alc262_pcm_analog_playback; 10621 spec->stream_analog_playback = &alc262_pcm_analog_playback;
10006 spec->stream_analog_capture = &alc262_pcm_analog_capture; 10622 spec->stream_analog_capture = &alc262_pcm_analog_capture;
10007 10623
10008 spec->stream_name_digital = "ALC262 Digital"; 10624 spec->stream_name_digital = "ALC262 Digital";
10009 spec->stream_digital_playback = &alc262_pcm_digital_playback; 10625 spec->stream_digital_playback = &alc262_pcm_digital_playback;
10010 spec->stream_digital_capture = &alc262_pcm_digital_capture; 10626 spec->stream_digital_capture = &alc262_pcm_digital_capture;
@@ -10040,7 +10656,7 @@ static int patch_alc262(struct hda_codec *codec)
10040 if (!spec->loopback.amplist) 10656 if (!spec->loopback.amplist)
10041 spec->loopback.amplist = alc262_loopbacks; 10657 spec->loopback.amplist = alc262_loopbacks;
10042#endif 10658#endif
10043 10659
10044 return 0; 10660 return 0;
10045} 10661}
10046 10662
@@ -10049,7 +10665,7 @@ static int patch_alc262(struct hda_codec *codec)
10049 */ 10665 */
10050#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID 10666#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
10051#define alc268_modes alc260_modes 10667#define alc268_modes alc260_modes
10052 10668
10053static hda_nid_t alc268_dac_nids[2] = { 10669static hda_nid_t alc268_dac_nids[2] = {
10054 /* front, hp */ 10670 /* front, hp */
10055 0x02, 0x03 10671 0x02, 0x03
@@ -10109,6 +10725,14 @@ static struct hda_verb alc268_toshiba_verbs[] = {
10109 { } /* end */ 10725 { } /* end */
10110}; 10726};
10111 10727
10728static struct hda_input_mux alc268_acer_lc_capture_source = {
10729 .num_items = 2,
10730 .items = {
10731 { "i-Mic", 0x6 },
10732 { "E-Mic", 0x0 },
10733 },
10734};
10735
10112/* Acer specific */ 10736/* Acer specific */
10113/* bind volumes of both NID 0x02 and 0x03 */ 10737/* bind volumes of both NID 0x02 and 0x03 */
10114static struct hda_bind_ctls alc268_acer_bind_master_vol = { 10738static struct hda_bind_ctls alc268_acer_bind_master_vol = {
@@ -10161,6 +10785,21 @@ static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
10161 return change; 10785 return change;
10162} 10786}
10163 10787
10788static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
10789 /* output mixer control */
10790 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
10791 {
10792 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10793 .name = "Master Playback Switch",
10794 .info = snd_hda_mixer_amp_switch_info,
10795 .get = snd_hda_mixer_amp_switch_get,
10796 .put = alc268_acer_master_sw_put,
10797 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10798 },
10799 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
10800 { }
10801};
10802
10164static struct snd_kcontrol_new alc268_acer_mixer[] = { 10803static struct snd_kcontrol_new alc268_acer_mixer[] = {
10165 /* output mixer control */ 10804 /* output mixer control */
10166 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 10805 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
@@ -10178,6 +10817,16 @@ static struct snd_kcontrol_new alc268_acer_mixer[] = {
10178 { } 10817 { }
10179}; 10818};
10180 10819
10820static struct hda_verb alc268_acer_aspire_one_verbs[] = {
10821 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10822 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10823 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10824 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
10825 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
10826 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
10827 { }
10828};
10829
10181static struct hda_verb alc268_acer_verbs[] = { 10830static struct hda_verb alc268_acer_verbs[] = {
10182 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */ 10831 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
10183 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 10832 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
@@ -10185,7 +10834,6 @@ static struct hda_verb alc268_acer_verbs[] = {
10185 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 10834 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10186 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 10835 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10187 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 10836 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10188
10189 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 10837 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10190 { } 10838 { }
10191}; 10839};
@@ -10212,6 +10860,47 @@ static void alc268_acer_init_hook(struct hda_codec *codec)
10212 alc268_acer_automute(codec, 1); 10860 alc268_acer_automute(codec, 1);
10213} 10861}
10214 10862
10863/* toggle speaker-output according to the hp-jack state */
10864static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
10865{
10866 unsigned int present;
10867 unsigned char bits;
10868
10869 present = snd_hda_codec_read(codec, 0x15, 0,
10870 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10871 bits = present ? AMP_IN_MUTE(0) : 0;
10872 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
10873 AMP_IN_MUTE(0), bits);
10874 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
10875 AMP_IN_MUTE(0), bits);
10876}
10877
10878
10879static void alc268_acer_mic_automute(struct hda_codec *codec)
10880{
10881 unsigned int present;
10882
10883 present = snd_hda_codec_read(codec, 0x18, 0,
10884 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10885 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL,
10886 present ? 0x0 : 0x6);
10887}
10888
10889static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
10890 unsigned int res)
10891{
10892 if ((res >> 26) == ALC880_HP_EVENT)
10893 alc268_aspire_one_speaker_automute(codec);
10894 if ((res >> 26) == ALC880_MIC_EVENT)
10895 alc268_acer_mic_automute(codec);
10896}
10897
10898static void alc268_acer_lc_init_hook(struct hda_codec *codec)
10899{
10900 alc268_aspire_one_speaker_automute(codec);
10901 alc268_acer_mic_automute(codec);
10902}
10903
10215static struct snd_kcontrol_new alc268_dell_mixer[] = { 10904static struct snd_kcontrol_new alc268_dell_mixer[] = {
10216 /* output mixer control */ 10905 /* output mixer control */
10217 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 10906 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
@@ -10360,7 +11049,7 @@ static struct hda_verb alc268_base_init_verbs[] = {
10360 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 11049 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10361 11050
10362 /* Unmute Selector 23h,24h and set the default input to mic-in */ 11051 /* Unmute Selector 23h,24h and set the default input to mic-in */
10363 11052
10364 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00}, 11053 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
10365 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11054 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10366 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00}, 11055 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
@@ -10559,7 +11248,7 @@ static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
10559 11248
10560 nid = cfg->line_out_pins[0]; 11249 nid = cfg->line_out_pins[0];
10561 if (nid) 11250 if (nid)
10562 alc268_new_analog_output(spec, nid, "Front", 0); 11251 alc268_new_analog_output(spec, nid, "Front", 0);
10563 11252
10564 nid = cfg->speaker_pins[0]; 11253 nid = cfg->speaker_pins[0];
10565 if (nid == 0x1d) { 11254 if (nid == 0x1d) {
@@ -10581,7 +11270,7 @@ static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
10581 if (err < 0) 11270 if (err < 0)
10582 return err; 11271 return err;
10583 } 11272 }
10584 return 0; 11273 return 0;
10585} 11274}
10586 11275
10587/* create playback/capture controls for input pins */ 11276/* create playback/capture controls for input pins */
@@ -10602,7 +11291,7 @@ static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
10602 case 0x1a: 11291 case 0x1a:
10603 idx1 = 2; /* Line In */ 11292 idx1 = 2; /* Line In */
10604 break; 11293 break;
10605 case 0x1c: 11294 case 0x1c:
10606 idx1 = 3; /* CD */ 11295 idx1 = 3; /* CD */
10607 break; 11296 break;
10608 case 0x12: 11297 case 0x12:
@@ -10614,7 +11303,7 @@ static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
10614 } 11303 }
10615 imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; 11304 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
10616 imux->items[imux->num_items].index = idx1; 11305 imux->items[imux->num_items].index = idx1;
10617 imux->num_items++; 11306 imux->num_items++;
10618 } 11307 }
10619 return 0; 11308 return 0;
10620} 11309}
@@ -10644,11 +11333,11 @@ static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
10644 } 11333 }
10645 11334
10646 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */ 11335 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
10647 if (line_nid == 0x14) 11336 if (line_nid == 0x14)
10648 dac_vol2 = AMP_OUT_ZERO; 11337 dac_vol2 = AMP_OUT_ZERO;
10649 else if (line_nid == 0x15) 11338 else if (line_nid == 0x15)
10650 dac_vol1 = AMP_OUT_ZERO; 11339 dac_vol1 = AMP_OUT_ZERO;
10651 if (hp_nid == 0x14) 11340 if (hp_nid == 0x14)
10652 dac_vol2 = AMP_OUT_ZERO; 11341 dac_vol2 = AMP_OUT_ZERO;
10653 else if (hp_nid == 0x15) 11342 else if (hp_nid == 0x15)
10654 dac_vol1 = AMP_OUT_ZERO; 11343 dac_vol1 = AMP_OUT_ZERO;
@@ -10739,6 +11428,7 @@ static const char *alc268_models[ALC268_MODEL_LAST] = {
10739 [ALC268_3ST] = "3stack", 11428 [ALC268_3ST] = "3stack",
10740 [ALC268_TOSHIBA] = "toshiba", 11429 [ALC268_TOSHIBA] = "toshiba",
10741 [ALC268_ACER] = "acer", 11430 [ALC268_ACER] = "acer",
11431 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
10742 [ALC268_DELL] = "dell", 11432 [ALC268_DELL] = "dell",
10743 [ALC268_ZEPTO] = "zepto", 11433 [ALC268_ZEPTO] = "zepto",
10744#ifdef CONFIG_SND_DEBUG 11434#ifdef CONFIG_SND_DEBUG
@@ -10753,11 +11443,14 @@ static struct snd_pci_quirk alc268_cfg_tbl[] = {
10753 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER), 11443 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
10754 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER), 11444 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
10755 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER), 11445 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
11446 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
11447 ALC268_ACER_ASPIRE_ONE),
10756 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL), 11448 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
10757 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA), 11449 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
10758 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST), 11450 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
10759 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA), 11451 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
10760 SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA), 11452 SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
11453 SND_PCI_QUIRK(0x1179, 0xff64, "TOSHIBA L305", ALC268_TOSHIBA),
10761 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA), 11454 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
10762 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER), 11455 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
10763 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1), 11456 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
@@ -10830,6 +11523,23 @@ static struct alc_config_preset alc268_presets[] = {
10830 .unsol_event = alc268_acer_unsol_event, 11523 .unsol_event = alc268_acer_unsol_event,
10831 .init_hook = alc268_acer_init_hook, 11524 .init_hook = alc268_acer_init_hook,
10832 }, 11525 },
11526 [ALC268_ACER_ASPIRE_ONE] = {
11527 .mixers = { alc268_acer_aspire_one_mixer,
11528 alc268_capture_alt_mixer },
11529 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11530 alc268_acer_aspire_one_verbs },
11531 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11532 .dac_nids = alc268_dac_nids,
11533 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11534 .adc_nids = alc268_adc_nids_alt,
11535 .capsrc_nids = alc268_capsrc_nids,
11536 .hp_nid = 0x03,
11537 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11538 .channel_mode = alc268_modes,
11539 .input_mux = &alc268_acer_lc_capture_source,
11540 .unsol_event = alc268_acer_lc_unsol_event,
11541 .init_hook = alc268_acer_lc_init_hook,
11542 },
10833 [ALC268_DELL] = { 11543 [ALC268_DELL] = {
10834 .mixers = { alc268_dell_mixer, alc268_beep_mixer }, 11544 .mixers = { alc268_dell_mixer, alc268_beep_mixer },
10835 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 11545 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
@@ -10974,7 +11684,7 @@ static int patch_alc268(struct hda_codec *codec)
10974 codec->patch_ops = alc_patch_ops; 11684 codec->patch_ops = alc_patch_ops;
10975 if (board_config == ALC268_AUTO) 11685 if (board_config == ALC268_AUTO)
10976 spec->init_hook = alc268_auto_init; 11686 spec->init_hook = alc268_auto_init;
10977 11687
10978 return 0; 11688 return 0;
10979} 11689}
10980 11690
@@ -10990,6 +11700,14 @@ static hda_nid_t alc269_adc_nids[1] = {
10990 0x08, 11700 0x08,
10991}; 11701};
10992 11702
11703static hda_nid_t alc269_capsrc_nids[1] = {
11704 0x23,
11705};
11706
11707/* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
11708 * not a mux!
11709 */
11710
10993static struct hda_input_mux alc269_eeepc_dmic_capture_source = { 11711static struct hda_input_mux alc269_eeepc_dmic_capture_source = {
10994 .num_items = 2, 11712 .num_items = 2,
10995 .items = { 11713 .items = {
@@ -11016,6 +11734,8 @@ static struct snd_kcontrol_new alc269_base_mixer[] = {
11016 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11734 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11017 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11735 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11018 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11736 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11737 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
11738 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
11019 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11739 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11020 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11740 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11021 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11741 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
@@ -11025,6 +11745,28 @@ static struct snd_kcontrol_new alc269_base_mixer[] = {
11025 { } /* end */ 11745 { } /* end */
11026}; 11746};
11027 11747
11748static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
11749 /* output mixer control */
11750 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11751 {
11752 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11753 .name = "Master Playback Switch",
11754 .info = snd_hda_mixer_amp_switch_info,
11755 .get = snd_hda_mixer_amp_switch_get,
11756 .put = alc268_acer_master_sw_put,
11757 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11758 },
11759 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11760 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11761 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11762 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11763 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11764 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11765 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x04, HDA_INPUT),
11766 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x04, HDA_INPUT),
11767 { }
11768};
11769
11028/* bind volumes of both NID 0x0c and 0x0d */ 11770/* bind volumes of both NID 0x0c and 0x0d */
11029static struct hda_bind_ctls alc269_epc_bind_vol = { 11771static struct hda_bind_ctls alc269_epc_bind_vol = {
11030 .ops = &snd_hda_bind_vol, 11772 .ops = &snd_hda_bind_vol,
@@ -11068,75 +11810,72 @@ static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
11068 { } /* end */ 11810 { } /* end */
11069}; 11811};
11070 11812
11071/* 11813/* beep control */
11072 * generic initialization of ADC, input mixers and output mixers 11814static struct snd_kcontrol_new alc269_beep_mixer[] = {
11073 */ 11815 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
11074static struct hda_verb alc269_init_verbs[] = { 11816 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
11075 /* 11817 { } /* end */
11076 * Unmute ADC0 and set the default input to mic-in 11818};
11077 */
11078 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11079 11819
11080 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the 11820static struct hda_verb alc269_quanta_fl1_verbs[] = {
11081 * analog-loopback mixer widget 11821 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11082 * Note: PASD motherboards uses the Line In 2 as the input for 11822 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11083 * front panel mic (mic 2) 11823 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11084 */ 11824 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11085 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 11825 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11086 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11826 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11087 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 11827 { }
11088 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 11828};
11089 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11090 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11091 11829
11092 /* 11830/* toggle speaker-output according to the hp-jack state */
11093 * Set up output mixers (0x0c - 0x0e) 11831static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
11094 */ 11832{
11095 /* set vol=0 to output mixers */ 11833 unsigned int present;
11096 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11834 unsigned char bits;
11097 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11098 11835
11099 /* set up input amps for analog loopback */ 11836 present = snd_hda_codec_read(codec, 0x15, 0,
11100 /* Amp Indices: DAC = 0, mixer = 1 */ 11837 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11101 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11838 bits = present ? AMP_IN_MUTE(0) : 0;
11102 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11839 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
11103 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11840 AMP_IN_MUTE(0), bits);
11104 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11841 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
11105 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11842 AMP_IN_MUTE(0), bits);
11106 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11107 11843
11108 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11844 snd_hda_codec_write(codec, 0x20, 0,
11109 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11845 AC_VERB_SET_COEF_INDEX, 0x0c);
11110 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11846 snd_hda_codec_write(codec, 0x20, 0,
11111 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 11847 AC_VERB_SET_PROC_COEF, 0x680);
11112 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11113 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11114 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11115 11848
11116 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11849 snd_hda_codec_write(codec, 0x20, 0,
11117 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11850 AC_VERB_SET_COEF_INDEX, 0x0c);
11118 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11851 snd_hda_codec_write(codec, 0x20, 0,
11119 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11852 AC_VERB_SET_PROC_COEF, 0x480);
11120 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11853}
11121 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11122 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11123 11854
11124 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 11855static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec)
11125 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 11856{
11857 unsigned int present;
11126 11858
11127 /* FIXME: use matrix-type input source selection */ 11859 present = snd_hda_codec_read(codec, 0x18, 0,
11128 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */ 11860 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11129 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 11861 snd_hda_codec_write(codec, 0x23, 0,
11130 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11862 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1);
11131 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 11863}
11132 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11133 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11134 11864
11135 /* set EAPD */ 11865static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
11136 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 11866 unsigned int res)
11137 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 11867{
11138 { } 11868 if ((res >> 26) == ALC880_HP_EVENT)
11139}; 11869 alc269_quanta_fl1_speaker_automute(codec);
11870 if ((res >> 26) == ALC880_MIC_EVENT)
11871 alc269_quanta_fl1_mic_automute(codec);
11872}
11873
11874static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
11875{
11876 alc269_quanta_fl1_speaker_automute(codec);
11877 alc269_quanta_fl1_mic_automute(codec);
11878}
11140 11879
11141static struct hda_verb alc269_eeepc_dmic_init_verbs[] = { 11880static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
11142 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 11881 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
@@ -11163,42 +11902,42 @@ static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
11163static void alc269_speaker_automute(struct hda_codec *codec) 11902static void alc269_speaker_automute(struct hda_codec *codec)
11164{ 11903{
11165 unsigned int present; 11904 unsigned int present;
11166 unsigned int bits; 11905 unsigned char bits;
11167 11906
11168 present = snd_hda_codec_read(codec, 0x15, 0, 11907 present = snd_hda_codec_read(codec, 0x15, 0,
11169 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 11908 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11170 bits = present ? AMP_IN_MUTE(0) : 0; 11909 bits = present ? AMP_IN_MUTE(0) : 0;
11171 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 11910 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
11172 AMP_IN_MUTE(0), bits); 11911 AMP_IN_MUTE(0), bits);
11173 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 11912 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
11174 AMP_IN_MUTE(0), bits); 11913 AMP_IN_MUTE(0), bits);
11175} 11914}
11176 11915
11177static void alc269_eeepc_dmic_automute(struct hda_codec *codec) 11916static void alc269_eeepc_dmic_automute(struct hda_codec *codec)
11178{ 11917{
11179 unsigned int present; 11918 unsigned int present;
11180 11919
11181 present = snd_hda_codec_read(codec, 0x18, 0, AC_VERB_GET_PIN_SENSE, 0) 11920 present = snd_hda_codec_read(codec, 0x18, 0,
11182 & AC_PINSENSE_PRESENCE; 11921 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11183 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL, 11922 snd_hda_codec_write(codec, 0x23, 0,
11184 present ? 0 : 5); 11923 AC_VERB_SET_CONNECT_SEL, (present ? 0 : 5));
11185} 11924}
11186 11925
11187static void alc269_eeepc_amic_automute(struct hda_codec *codec) 11926static void alc269_eeepc_amic_automute(struct hda_codec *codec)
11188{ 11927{
11189 unsigned int present; 11928 unsigned int present;
11190 11929
11191 present = snd_hda_codec_read(codec, 0x18, 0, AC_VERB_GET_PIN_SENSE, 0) 11930 present = snd_hda_codec_read(codec, 0x18, 0,
11192 & AC_PINSENSE_PRESENCE; 11931 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11193 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE, 11932 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
11194 present ? AMP_IN_UNMUTE(0) : AMP_IN_MUTE(0)); 11933 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
11195 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE, 11934 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
11196 present ? AMP_IN_MUTE(1) : AMP_IN_UNMUTE(1)); 11935 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
11197} 11936}
11198 11937
11199/* unsolicited event for HP jack sensing */ 11938/* unsolicited event for HP jack sensing */
11200static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec, 11939static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec,
11201 unsigned int res) 11940 unsigned int res)
11202{ 11941{
11203 if ((res >> 26) == ALC880_HP_EVENT) 11942 if ((res >> 26) == ALC880_HP_EVENT)
11204 alc269_speaker_automute(codec); 11943 alc269_speaker_automute(codec);
@@ -11215,7 +11954,7 @@ static void alc269_eeepc_dmic_inithook(struct hda_codec *codec)
11215 11954
11216/* unsolicited event for HP jack sensing */ 11955/* unsolicited event for HP jack sensing */
11217static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec, 11956static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec,
11218 unsigned int res) 11957 unsigned int res)
11219{ 11958{
11220 if ((res >> 26) == ALC880_HP_EVENT) 11959 if ((res >> 26) == ALC880_HP_EVENT)
11221 alc269_speaker_automute(codec); 11960 alc269_speaker_automute(codec);
@@ -11230,6 +11969,76 @@ static void alc269_eeepc_amic_inithook(struct hda_codec *codec)
11230 alc269_eeepc_amic_automute(codec); 11969 alc269_eeepc_amic_automute(codec);
11231} 11970}
11232 11971
11972/*
11973 * generic initialization of ADC, input mixers and output mixers
11974 */
11975static struct hda_verb alc269_init_verbs[] = {
11976 /*
11977 * Unmute ADC0 and set the default input to mic-in
11978 */
11979 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11980
11981 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
11982 * analog-loopback mixer widget
11983 * Note: PASD motherboards uses the Line In 2 as the input for
11984 * front panel mic (mic 2)
11985 */
11986 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11987 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11988 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11989 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11990 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11991 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11992
11993 /*
11994 * Set up output mixers (0x0c - 0x0e)
11995 */
11996 /* set vol=0 to output mixers */
11997 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11998 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11999
12000 /* set up input amps for analog loopback */
12001 /* Amp Indices: DAC = 0, mixer = 1 */
12002 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12003 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12004 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12005 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12006 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12007 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12008
12009 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12010 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12011 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12012 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12013 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12014 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12015 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12016
12017 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12018 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12019 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12020 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12021 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12022 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12023 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12024
12025 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12026 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12027
12028 /* FIXME: use matrix-type input source selection */
12029 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
12030 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12031 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12032 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12033 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12034 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12035
12036 /* set EAPD */
12037 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12038 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12039 { }
12040};
12041
11233/* add playback controls from the parsed DAC table */ 12042/* add playback controls from the parsed DAC table */
11234static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec, 12043static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
11235 const struct auto_pin_cfg *cfg) 12044 const struct auto_pin_cfg *cfg)
@@ -11330,7 +12139,7 @@ static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
11330static int alc269_parse_auto_config(struct hda_codec *codec) 12139static int alc269_parse_auto_config(struct hda_codec *codec)
11331{ 12140{
11332 struct alc_spec *spec = codec->spec; 12141 struct alc_spec *spec = codec->spec;
11333 int err; 12142 int i, err;
11334 static hda_nid_t alc269_ignore[] = { 0x1d, 0 }; 12143 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
11335 12144
11336 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 12145 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
@@ -11353,9 +12162,20 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
11353 if (spec->kctl_alloc) 12162 if (spec->kctl_alloc)
11354 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 12163 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
11355 12164
12165 /* create a beep mixer control if the pin 0x1d isn't assigned */
12166 for (i = 0; i < ARRAY_SIZE(spec->autocfg.input_pins); i++)
12167 if (spec->autocfg.input_pins[i] == 0x1d)
12168 break;
12169 if (i >= ARRAY_SIZE(spec->autocfg.input_pins))
12170 spec->mixers[spec->num_mixers++] = alc269_beep_mixer;
12171
11356 spec->init_verbs[spec->num_init_verbs++] = alc269_init_verbs; 12172 spec->init_verbs[spec->num_init_verbs++] = alc269_init_verbs;
11357 spec->num_mux_defs = 1; 12173 spec->num_mux_defs = 1;
11358 spec->input_mux = &spec->private_imux; 12174 spec->input_mux = &spec->private_imux;
12175 /* set default input source */
12176 snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
12177 0, AC_VERB_SET_CONNECT_SEL,
12178 spec->input_mux->items[0].index);
11359 12179
11360 err = alc_auto_add_mic_boost(codec); 12180 err = alc_auto_add_mic_boost(codec);
11361 if (err < 0) 12181 if (err < 0)
@@ -11387,14 +12207,20 @@ static void alc269_auto_init(struct hda_codec *codec)
11387 * configuration and preset 12207 * configuration and preset
11388 */ 12208 */
11389static const char *alc269_models[ALC269_MODEL_LAST] = { 12209static const char *alc269_models[ALC269_MODEL_LAST] = {
11390 [ALC269_BASIC] = "basic", 12210 [ALC269_BASIC] = "basic",
12211 [ALC269_QUANTA_FL1] = "quanta",
12212 [ALC269_ASUS_EEEPC_P703] = "eeepc-p703",
12213 [ALC269_ASUS_EEEPC_P901] = "eeepc-p901"
11391}; 12214};
11392 12215
11393static struct snd_pci_quirk alc269_cfg_tbl[] = { 12216static struct snd_pci_quirk alc269_cfg_tbl[] = {
12217 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
11394 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", 12218 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
11395 ALC269_ASUS_EEEPC_P703), 12219 ALC269_ASUS_EEEPC_P703),
11396 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901", 12220 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
11397 ALC269_ASUS_EEEPC_P901), 12221 ALC269_ASUS_EEEPC_P901),
12222 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
12223 ALC269_ASUS_EEEPC_P901),
11398 {} 12224 {}
11399}; 12225};
11400 12226
@@ -11409,6 +12235,18 @@ static struct alc_config_preset alc269_presets[] = {
11409 .channel_mode = alc269_modes, 12235 .channel_mode = alc269_modes,
11410 .input_mux = &alc269_capture_source, 12236 .input_mux = &alc269_capture_source,
11411 }, 12237 },
12238 [ALC269_QUANTA_FL1] = {
12239 .mixers = { alc269_quanta_fl1_mixer },
12240 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
12241 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12242 .dac_nids = alc269_dac_nids,
12243 .hp_nid = 0x03,
12244 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12245 .channel_mode = alc269_modes,
12246 .input_mux = &alc269_capture_source,
12247 .unsol_event = alc269_quanta_fl1_unsol_event,
12248 .init_hook = alc269_quanta_fl1_init_hook,
12249 },
11412 [ALC269_ASUS_EEEPC_P703] = { 12250 [ALC269_ASUS_EEEPC_P703] = {
11413 .mixers = { alc269_eeepc_mixer, alc269_epc_capture_mixer }, 12251 .mixers = { alc269_eeepc_mixer, alc269_epc_capture_mixer },
11414 .init_verbs = { alc269_init_verbs, 12252 .init_verbs = { alc269_init_verbs,
@@ -11488,6 +12326,7 @@ static int patch_alc269(struct hda_codec *codec)
11488 12326
11489 spec->adc_nids = alc269_adc_nids; 12327 spec->adc_nids = alc269_adc_nids;
11490 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids); 12328 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
12329 spec->capsrc_nids = alc269_capsrc_nids;
11491 12330
11492 codec->patch_ops = alc_patch_ops; 12331 codec->patch_ops = alc_patch_ops;
11493 if (board_config == ALC269_AUTO) 12332 if (board_config == ALC269_AUTO)
@@ -11689,7 +12528,7 @@ static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
11689 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT), 12528 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
11690 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 12529 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
11691 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 12530 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
11692 12531
11693 /*Capture mixer control */ 12532 /*Capture mixer control */
11694 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 12533 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11695 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 12534 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
@@ -11832,20 +12671,20 @@ static struct hda_verb alc861_base_init_verbs[] = {
11832 /* route front mic to ADC1*/ 12671 /* route front mic to ADC1*/
11833 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 12672 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11834 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12673 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11835 12674
11836 /* Unmute DAC0~3 & spdif out*/ 12675 /* Unmute DAC0~3 & spdif out*/
11837 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 12676 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11838 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 12677 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11839 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 12678 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11840 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 12679 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11841 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 12680 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11842 12681
11843 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 12682 /* Unmute Mixer 14 (mic) 1c (Line in)*/
11844 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12683 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11845 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12684 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11846 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12685 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11847 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12686 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11848 12687
11849 /* Unmute Stereo Mixer 15 */ 12688 /* Unmute Stereo Mixer 15 */
11850 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12689 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11851 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12690 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
@@ -11901,13 +12740,13 @@ static struct hda_verb alc861_threestack_init_verbs[] = {
11901 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 12740 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11902 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 12741 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11903 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 12742 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11904 12743
11905 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 12744 /* Unmute Mixer 14 (mic) 1c (Line in)*/
11906 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12745 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11907 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12746 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11908 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12747 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11909 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12748 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11910 12749
11911 /* Unmute Stereo Mixer 15 */ 12750 /* Unmute Stereo Mixer 15 */
11912 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12751 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11913 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12752 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
@@ -11963,13 +12802,13 @@ static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
11963 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 12802 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11964 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 12803 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11965 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 12804 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11966 12805
11967 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 12806 /* Unmute Mixer 14 (mic) 1c (Line in)*/
11968 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12807 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11969 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12808 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11970 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12809 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11971 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12810 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11972 12811
11973 /* Unmute Stereo Mixer 15 */ 12812 /* Unmute Stereo Mixer 15 */
11974 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12813 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11975 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12814 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
@@ -12034,7 +12873,7 @@ static struct hda_verb alc861_asus_init_verbs[] = {
12034 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12873 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12035 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12874 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12036 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12875 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12037 12876
12038 /* Unmute Stereo Mixer 15 */ 12877 /* Unmute Stereo Mixer 15 */
12039 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12878 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12040 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12879 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
@@ -12071,20 +12910,20 @@ static struct hda_verb alc861_auto_init_verbs[] = {
12071 */ 12910 */
12072 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */ 12911 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
12073 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12912 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12074 12913
12075 /* Unmute DAC0~3 & spdif out*/ 12914 /* Unmute DAC0~3 & spdif out*/
12076 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 12915 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12077 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 12916 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12078 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 12917 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12079 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 12918 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12080 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 12919 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12081 12920
12082 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 12921 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12083 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12922 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12084 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12923 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12085 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12924 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12086 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12925 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12087 12926
12088 /* Unmute Stereo Mixer 15 */ 12927 /* Unmute Stereo Mixer 15 */
12089 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12928 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12090 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12929 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
@@ -12659,7 +13498,7 @@ static int patch_alc861(struct hda_codec *codec)
12659 if (!spec->loopback.amplist) 13498 if (!spec->loopback.amplist)
12660 spec->loopback.amplist = alc861_loopbacks; 13499 spec->loopback.amplist = alc861_loopbacks;
12661#endif 13500#endif
12662 13501
12663 return 0; 13502 return 0;
12664} 13503}
12665 13504
@@ -12913,7 +13752,7 @@ static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
12913 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 13752 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12914 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 13753 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12915 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 13754 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12916 13755
12917 { } /* end */ 13756 { } /* end */
12918}; 13757};
12919 13758
@@ -13058,7 +13897,7 @@ static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
13058 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 13897 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13059 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 13898 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
13060 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 13899 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13061 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 13900 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13062 {} 13901 {}
13063}; 13902};
13064 13903
@@ -13120,7 +13959,7 @@ static struct hda_verb alc861vd_dallas_verbs[] = {
13120 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 13959 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13121 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 13960 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13122 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 13961 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13123 13962
13124 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 13963 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13125 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13964 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13126 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 13965 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
@@ -13145,7 +13984,7 @@ static struct hda_verb alc861vd_dallas_verbs[] = {
13145 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 13984 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13146 13985
13147 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 13986 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13148 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 13987 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13149 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 13988 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13150 13989
13151 { } /* end */ 13990 { } /* end */
@@ -13304,7 +14143,7 @@ static struct alc_config_preset alc861vd_presets[] = {
13304 .input_mux = &alc861vd_hp_capture_source, 14143 .input_mux = &alc861vd_hp_capture_source,
13305 .unsol_event = alc861vd_dallas_unsol_event, 14144 .unsol_event = alc861vd_dallas_unsol_event,
13306 .init_hook = alc861vd_dallas_automute, 14145 .init_hook = alc861vd_dallas_automute,
13307 }, 14146 },
13308}; 14147};
13309 14148
13310/* 14149/*
@@ -13883,13 +14722,120 @@ static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
13883 { } /* end */ 14722 { } /* end */
13884}; 14723};
13885 14724
14725static struct hda_bind_ctls alc663_asus_bind_master_vol = {
14726 .ops = &snd_hda_bind_vol,
14727 .values = {
14728 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
14729 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
14730 0
14731 },
14732};
14733
14734static struct hda_bind_ctls alc663_asus_one_bind_switch = {
14735 .ops = &snd_hda_bind_sw,
14736 .values = {
14737 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14738 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
14739 0
14740 },
14741};
14742
13886static struct snd_kcontrol_new alc663_m51va_mixer[] = { 14743static struct snd_kcontrol_new alc663_m51va_mixer[] = {
14744 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14745 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
14746 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14747 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14748 { } /* end */
14749};
14750
14751static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
14752 .ops = &snd_hda_bind_sw,
14753 .values = {
14754 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14755 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
14756 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
14757 0
14758 },
14759};
14760
14761static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
14762 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14763 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
14764 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14765 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14766 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14767 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14768
14769 { } /* end */
14770};
14771
14772static struct hda_bind_ctls alc663_asus_four_bind_switch = {
14773 .ops = &snd_hda_bind_sw,
14774 .values = {
14775 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14776 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
14777 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
14778 0
14779 },
14780};
14781
14782static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
14783 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14784 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
14785 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14786 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14787 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14788 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14789 { } /* end */
14790};
14791
14792static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
13887 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 14793 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13888 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 14794 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14795 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14796 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14797 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14798 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14799 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14800 { } /* end */
14801};
14802
14803static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
14804 .ops = &snd_hda_bind_vol,
14805 .values = {
14806 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
14807 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
14808 0
14809 },
14810};
14811
14812static struct hda_bind_ctls alc663_asus_two_bind_switch = {
14813 .ops = &snd_hda_bind_sw,
14814 .values = {
14815 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14816 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
14817 0
14818 },
14819};
14820
14821static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
14822 HDA_BIND_VOL("Master Playback Volume",
14823 &alc663_asus_two_bind_master_vol),
14824 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
14825 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13889 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 14826 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
13890 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 14827 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13891 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 14828 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13892 HDA_CODEC_MUTE("DMic Playback Switch", 0x23, 0x9, HDA_INPUT), 14829 { } /* end */
14830};
14831
14832static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
14833 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14834 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
14835 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14836 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14837 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14838 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13893 { } /* end */ 14839 { } /* end */
13894}; 14840};
13895 14841
@@ -14074,14 +15020,81 @@ static struct hda_verb alc663_auto_init_verbs[] = {
14074}; 15020};
14075 15021
14076static struct hda_verb alc663_m51va_init_verbs[] = { 15022static struct hda_verb alc663_m51va_init_verbs[] = {
15023 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15024 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14077 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 15025 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14078 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15026 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14079 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */ 15027 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15028 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15029 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15030 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15031 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15032 {}
15033};
14080 15034
14081 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, 15035static struct hda_verb alc663_21jd_amic_init_verbs[] = {
15036 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15037 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15038 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15039 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15040 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15041 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15042 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15043 {}
15044};
14082 15045
15046static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
15047 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15048 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15049 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15050 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15051 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15052 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15053 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15054 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15055 {}
15056};
15057
15058static struct hda_verb alc663_15jd_amic_init_verbs[] = {
15059 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15060 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15061 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15062 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15063 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15064 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15065 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15066 {}
15067};
15068
15069static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
15070 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15071 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15072 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15073 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15074 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15075 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15076 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15077 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15078 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14083 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 15079 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14084 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 15080 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15081 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15082 {}
15083};
15084
15085static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
15086 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15087 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15088 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15089 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15090 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15091 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15092 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15093 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15094 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15095 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15096 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15097 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14085 {} 15098 {}
14086}; 15099};
14087 15100
@@ -14110,6 +15123,14 @@ static struct hda_verb alc663_g50v_init_verbs[] = {
14110 {} 15123 {}
14111}; 15124};
14112 15125
15126static struct hda_verb alc662_ecs_init_verbs[] = {
15127 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
15128 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15129 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15130 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15131 {}
15132};
15133
14113/* capture mixer elements */ 15134/* capture mixer elements */
14114static struct snd_kcontrol_new alc662_capture_mixer[] = { 15135static struct snd_kcontrol_new alc662_capture_mixer[] = {
14115 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 15136 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
@@ -14129,6 +15150,12 @@ static struct snd_kcontrol_new alc662_capture_mixer[] = {
14129 { } /* end */ 15150 { } /* end */
14130}; 15151};
14131 15152
15153static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
15154 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15155 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
15156 { } /* end */
15157};
15158
14132static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec) 15159static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
14133{ 15160{
14134 unsigned int present; 15161 unsigned int present;
@@ -14209,12 +15236,12 @@ static void alc662_eeepc_ep20_automute(struct hda_codec *codec)
14209 if (present) { 15236 if (present) {
14210 /* mute internal speaker */ 15237 /* mute internal speaker */
14211 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0, 15238 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
14212 HDA_AMP_MUTE, HDA_AMP_MUTE); 15239 HDA_AMP_MUTE, HDA_AMP_MUTE);
14213 } else { 15240 } else {
14214 /* unmute internal speaker if necessary */ 15241 /* unmute internal speaker if necessary */
14215 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0); 15242 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
14216 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0, 15243 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
14217 HDA_AMP_MUTE, mute); 15244 HDA_AMP_MUTE, mute);
14218 } 15245 }
14219} 15246}
14220 15247
@@ -14237,11 +15264,108 @@ static void alc663_m51va_speaker_automute(struct hda_codec *codec)
14237 unsigned char bits; 15264 unsigned char bits;
14238 15265
14239 present = snd_hda_codec_read(codec, 0x21, 0, 15266 present = snd_hda_codec_read(codec, 0x21, 0,
14240 AC_VERB_GET_PIN_SENSE, 0) 15267 AC_VERB_GET_PIN_SENSE, 0)
14241 & AC_PINSENSE_PRESENCE; 15268 & AC_PINSENSE_PRESENCE;
14242 bits = present ? HDA_AMP_MUTE : 0; 15269 bits = present ? HDA_AMP_MUTE : 0;
14243 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 15270 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
14244 HDA_AMP_MUTE, bits); 15271 AMP_IN_MUTE(0), bits);
15272 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15273 AMP_IN_MUTE(0), bits);
15274}
15275
15276static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
15277{
15278 unsigned int present;
15279 unsigned char bits;
15280
15281 present = snd_hda_codec_read(codec, 0x21, 0,
15282 AC_VERB_GET_PIN_SENSE, 0)
15283 & AC_PINSENSE_PRESENCE;
15284 bits = present ? HDA_AMP_MUTE : 0;
15285 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15286 AMP_IN_MUTE(0), bits);
15287 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15288 AMP_IN_MUTE(0), bits);
15289 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15290 AMP_IN_MUTE(0), bits);
15291 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15292 AMP_IN_MUTE(0), bits);
15293}
15294
15295static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
15296{
15297 unsigned int present;
15298 unsigned char bits;
15299
15300 present = snd_hda_codec_read(codec, 0x15, 0,
15301 AC_VERB_GET_PIN_SENSE, 0)
15302 & AC_PINSENSE_PRESENCE;
15303 bits = present ? HDA_AMP_MUTE : 0;
15304 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15305 AMP_IN_MUTE(0), bits);
15306 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15307 AMP_IN_MUTE(0), bits);
15308 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15309 AMP_IN_MUTE(0), bits);
15310 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15311 AMP_IN_MUTE(0), bits);
15312}
15313
15314static void alc662_f5z_speaker_automute(struct hda_codec *codec)
15315{
15316 unsigned int present;
15317 unsigned char bits;
15318
15319 present = snd_hda_codec_read(codec, 0x1b, 0,
15320 AC_VERB_GET_PIN_SENSE, 0)
15321 & AC_PINSENSE_PRESENCE;
15322 bits = present ? 0 : PIN_OUT;
15323 snd_hda_codec_write(codec, 0x14, 0,
15324 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
15325}
15326
15327static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
15328{
15329 unsigned int present1, present2;
15330
15331 present1 = snd_hda_codec_read(codec, 0x21, 0,
15332 AC_VERB_GET_PIN_SENSE, 0)
15333 & AC_PINSENSE_PRESENCE;
15334 present2 = snd_hda_codec_read(codec, 0x15, 0,
15335 AC_VERB_GET_PIN_SENSE, 0)
15336 & AC_PINSENSE_PRESENCE;
15337
15338 if (present1 || present2) {
15339 snd_hda_codec_write_cache(codec, 0x14, 0,
15340 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
15341 } else {
15342 snd_hda_codec_write_cache(codec, 0x14, 0,
15343 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
15344 }
15345}
15346
15347static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
15348{
15349 unsigned int present1, present2;
15350
15351 present1 = snd_hda_codec_read(codec, 0x1b, 0,
15352 AC_VERB_GET_PIN_SENSE, 0)
15353 & AC_PINSENSE_PRESENCE;
15354 present2 = snd_hda_codec_read(codec, 0x15, 0,
15355 AC_VERB_GET_PIN_SENSE, 0)
15356 & AC_PINSENSE_PRESENCE;
15357
15358 if (present1 || present2) {
15359 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15360 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15361 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15362 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15363 } else {
15364 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15365 AMP_IN_MUTE(0), 0);
15366 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15367 AMP_IN_MUTE(0), 0);
15368 }
14245} 15369}
14246 15370
14247static void alc663_m51va_mic_automute(struct hda_codec *codec) 15371static void alc663_m51va_mic_automute(struct hda_codec *codec)
@@ -14249,16 +15373,16 @@ static void alc663_m51va_mic_automute(struct hda_codec *codec)
14249 unsigned int present; 15373 unsigned int present;
14250 15374
14251 present = snd_hda_codec_read(codec, 0x18, 0, 15375 present = snd_hda_codec_read(codec, 0x18, 0,
14252 AC_VERB_GET_PIN_SENSE, 0) 15376 AC_VERB_GET_PIN_SENSE, 0)
14253 & AC_PINSENSE_PRESENCE; 15377 & AC_PINSENSE_PRESENCE;
14254 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE, 15378 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14255 0x7000 | (0x00 << 8) | (present ? 0 : 0x80)); 15379 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
14256 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE, 15380 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14257 0x7000 | (0x00 << 8) | (present ? 0 : 0x80)); 15381 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
14258 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE, 15382 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14259 0x7000 | (0x09 << 8) | (present ? 0x80 : 0)); 15383 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
14260 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE, 15384 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14261 0x7000 | (0x09 << 8) | (present ? 0x80 : 0)); 15385 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
14262} 15386}
14263 15387
14264static void alc663_m51va_unsol_event(struct hda_codec *codec, 15388static void alc663_m51va_unsol_event(struct hda_codec *codec,
@@ -14280,6 +15404,121 @@ static void alc663_m51va_inithook(struct hda_codec *codec)
14280 alc663_m51va_mic_automute(codec); 15404 alc663_m51va_mic_automute(codec);
14281} 15405}
14282 15406
15407/* ***************** Mode1 ******************************/
15408static void alc663_mode1_unsol_event(struct hda_codec *codec,
15409 unsigned int res)
15410{
15411 switch (res >> 26) {
15412 case ALC880_HP_EVENT:
15413 alc663_m51va_speaker_automute(codec);
15414 break;
15415 case ALC880_MIC_EVENT:
15416 alc662_eeepc_mic_automute(codec);
15417 break;
15418 }
15419}
15420
15421static void alc663_mode1_inithook(struct hda_codec *codec)
15422{
15423 alc663_m51va_speaker_automute(codec);
15424 alc662_eeepc_mic_automute(codec);
15425}
15426/* ***************** Mode2 ******************************/
15427static void alc662_mode2_unsol_event(struct hda_codec *codec,
15428 unsigned int res)
15429{
15430 switch (res >> 26) {
15431 case ALC880_HP_EVENT:
15432 alc662_f5z_speaker_automute(codec);
15433 break;
15434 case ALC880_MIC_EVENT:
15435 alc662_eeepc_mic_automute(codec);
15436 break;
15437 }
15438}
15439
15440static void alc662_mode2_inithook(struct hda_codec *codec)
15441{
15442 alc662_f5z_speaker_automute(codec);
15443 alc662_eeepc_mic_automute(codec);
15444}
15445/* ***************** Mode3 ******************************/
15446static void alc663_mode3_unsol_event(struct hda_codec *codec,
15447 unsigned int res)
15448{
15449 switch (res >> 26) {
15450 case ALC880_HP_EVENT:
15451 alc663_two_hp_m1_speaker_automute(codec);
15452 break;
15453 case ALC880_MIC_EVENT:
15454 alc662_eeepc_mic_automute(codec);
15455 break;
15456 }
15457}
15458
15459static void alc663_mode3_inithook(struct hda_codec *codec)
15460{
15461 alc663_two_hp_m1_speaker_automute(codec);
15462 alc662_eeepc_mic_automute(codec);
15463}
15464/* ***************** Mode4 ******************************/
15465static void alc663_mode4_unsol_event(struct hda_codec *codec,
15466 unsigned int res)
15467{
15468 switch (res >> 26) {
15469 case ALC880_HP_EVENT:
15470 alc663_21jd_two_speaker_automute(codec);
15471 break;
15472 case ALC880_MIC_EVENT:
15473 alc662_eeepc_mic_automute(codec);
15474 break;
15475 }
15476}
15477
15478static void alc663_mode4_inithook(struct hda_codec *codec)
15479{
15480 alc663_21jd_two_speaker_automute(codec);
15481 alc662_eeepc_mic_automute(codec);
15482}
15483/* ***************** Mode5 ******************************/
15484static void alc663_mode5_unsol_event(struct hda_codec *codec,
15485 unsigned int res)
15486{
15487 switch (res >> 26) {
15488 case ALC880_HP_EVENT:
15489 alc663_15jd_two_speaker_automute(codec);
15490 break;
15491 case ALC880_MIC_EVENT:
15492 alc662_eeepc_mic_automute(codec);
15493 break;
15494 }
15495}
15496
15497static void alc663_mode5_inithook(struct hda_codec *codec)
15498{
15499 alc663_15jd_two_speaker_automute(codec);
15500 alc662_eeepc_mic_automute(codec);
15501}
15502/* ***************** Mode6 ******************************/
15503static void alc663_mode6_unsol_event(struct hda_codec *codec,
15504 unsigned int res)
15505{
15506 switch (res >> 26) {
15507 case ALC880_HP_EVENT:
15508 alc663_two_hp_m2_speaker_automute(codec);
15509 break;
15510 case ALC880_MIC_EVENT:
15511 alc662_eeepc_mic_automute(codec);
15512 break;
15513 }
15514}
15515
15516static void alc663_mode6_inithook(struct hda_codec *codec)
15517{
15518 alc663_two_hp_m2_speaker_automute(codec);
15519 alc662_eeepc_mic_automute(codec);
15520}
15521
14283static void alc663_g71v_hp_automute(struct hda_codec *codec) 15522static void alc663_g71v_hp_automute(struct hda_codec *codec)
14284{ 15523{
14285 unsigned int present; 15524 unsigned int present;
@@ -14350,6 +15589,46 @@ static void alc663_g50v_inithook(struct hda_codec *codec)
14350 alc662_eeepc_mic_automute(codec); 15589 alc662_eeepc_mic_automute(codec);
14351} 15590}
14352 15591
15592/* bind hp and internal speaker mute (with plug check) */
15593static int alc662_ecs_master_sw_put(struct snd_kcontrol *kcontrol,
15594 struct snd_ctl_elem_value *ucontrol)
15595{
15596 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
15597 long *valp = ucontrol->value.integer.value;
15598 int change;
15599
15600 change = snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
15601 HDA_AMP_MUTE,
15602 valp[0] ? 0 : HDA_AMP_MUTE);
15603 change |= snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
15604 HDA_AMP_MUTE,
15605 valp[1] ? 0 : HDA_AMP_MUTE);
15606 if (change)
15607 alc262_hippo1_automute(codec);
15608 return change;
15609}
15610
15611static struct snd_kcontrol_new alc662_ecs_mixer[] = {
15612 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15613 {
15614 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15615 .name = "Master Playback Switch",
15616 .info = snd_hda_mixer_amp_switch_info,
15617 .get = snd_hda_mixer_amp_switch_get,
15618 .put = alc662_ecs_master_sw_put,
15619 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
15620 },
15621
15622 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
15623 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
15624 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
15625
15626 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
15627 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15628 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15629 { } /* end */
15630};
15631
14353#ifdef CONFIG_SND_HDA_POWER_SAVE 15632#ifdef CONFIG_SND_HDA_POWER_SAVE
14354#define alc662_loopbacks alc880_loopbacks 15633#define alc662_loopbacks alc880_loopbacks
14355#endif 15634#endif
@@ -14372,21 +15651,67 @@ static const char *alc662_models[ALC662_MODEL_LAST] = {
14372 [ALC662_LENOVO_101E] = "lenovo-101e", 15651 [ALC662_LENOVO_101E] = "lenovo-101e",
14373 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701", 15652 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
14374 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20", 15653 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
15654 [ALC662_ECS] = "ecs",
14375 [ALC663_ASUS_M51VA] = "m51va", 15655 [ALC663_ASUS_M51VA] = "m51va",
14376 [ALC663_ASUS_G71V] = "g71v", 15656 [ALC663_ASUS_G71V] = "g71v",
14377 [ALC663_ASUS_H13] = "h13", 15657 [ALC663_ASUS_H13] = "h13",
14378 [ALC663_ASUS_G50V] = "g50v", 15658 [ALC663_ASUS_G50V] = "g50v",
15659 [ALC663_ASUS_MODE1] = "asus-mode1",
15660 [ALC662_ASUS_MODE2] = "asus-mode2",
15661 [ALC663_ASUS_MODE3] = "asus-mode3",
15662 [ALC663_ASUS_MODE4] = "asus-mode4",
15663 [ALC663_ASUS_MODE5] = "asus-mode5",
15664 [ALC663_ASUS_MODE6] = "asus-mode6",
14379 [ALC662_AUTO] = "auto", 15665 [ALC662_AUTO] = "auto",
14380}; 15666};
14381 15667
14382static struct snd_pci_quirk alc662_cfg_tbl[] = { 15668static struct snd_pci_quirk alc662_cfg_tbl[] = {
14383 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS G71V", ALC663_ASUS_G71V),
14384 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA), 15669 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
14385 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS M51VA", ALC663_ASUS_G50V), 15670 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS M51VA", ALC663_ASUS_G50V),
14386 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG), 15671 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
14387 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701), 15672 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
14388 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20), 15673 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
15674 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
15675 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),
15676 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
15677 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
15678 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
15679 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),
15680 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
15681 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
15682 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
15683 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
15684 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
15685 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
15686 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
15687 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
15688 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
15689 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
15690 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
15691 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
15692 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
15693 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
15694 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
15695 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
15696 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
15697 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
15698 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
15699 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
15700 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
15701 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
15702 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
15703 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
15704 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
15705 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
15706 ALC662_3ST_6ch_DIG),
14389 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E), 15707 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
15708 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
15709 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
15710 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
15711 ALC662_3ST_6ch_DIG),
15712 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
15713 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
15714 ALC662_3ST_6ch_DIG),
14390 SND_PCI_QUIRK(0x1854, 0x2000, "ASUS H13-2000", ALC663_ASUS_H13), 15715 SND_PCI_QUIRK(0x1854, 0x2000, "ASUS H13-2000", ALC663_ASUS_H13),
14391 SND_PCI_QUIRK(0x1854, 0x2001, "ASUS H13-2001", ALC663_ASUS_H13), 15716 SND_PCI_QUIRK(0x1854, 0x2001, "ASUS H13-2001", ALC663_ASUS_H13),
14392 SND_PCI_QUIRK(0x1854, 0x2002, "ASUS H13-2002", ALC663_ASUS_H13), 15717 SND_PCI_QUIRK(0x1854, 0x2002, "ASUS H13-2002", ALC663_ASUS_H13),
@@ -14477,6 +15802,18 @@ static struct alc_config_preset alc662_presets[] = {
14477 .unsol_event = alc662_eeepc_ep20_unsol_event, 15802 .unsol_event = alc662_eeepc_ep20_unsol_event,
14478 .init_hook = alc662_eeepc_ep20_inithook, 15803 .init_hook = alc662_eeepc_ep20_inithook,
14479 }, 15804 },
15805 [ALC662_ECS] = {
15806 .mixers = { alc662_ecs_mixer, alc662_capture_mixer },
15807 .init_verbs = { alc662_init_verbs,
15808 alc662_ecs_init_verbs },
15809 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15810 .dac_nids = alc662_dac_nids,
15811 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15812 .channel_mode = alc662_3ST_2ch_modes,
15813 .input_mux = &alc662_eeepc_capture_source,
15814 .unsol_event = alc662_eeepc_unsol_event,
15815 .init_hook = alc662_eeepc_inithook,
15816 },
14480 [ALC663_ASUS_M51VA] = { 15817 [ALC663_ASUS_M51VA] = {
14481 .mixers = { alc663_m51va_mixer, alc662_capture_mixer}, 15818 .mixers = { alc663_m51va_mixer, alc662_capture_mixer},
14482 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs }, 15819 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
@@ -14524,6 +15861,91 @@ static struct alc_config_preset alc662_presets[] = {
14524 .unsol_event = alc663_g50v_unsol_event, 15861 .unsol_event = alc663_g50v_unsol_event,
14525 .init_hook = alc663_g50v_inithook, 15862 .init_hook = alc663_g50v_inithook,
14526 }, 15863 },
15864 [ALC663_ASUS_MODE1] = {
15865 .mixers = { alc663_m51va_mixer, alc662_auto_capture_mixer },
15866 .init_verbs = { alc662_init_verbs,
15867 alc663_21jd_amic_init_verbs },
15868 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15869 .hp_nid = 0x03,
15870 .dac_nids = alc662_dac_nids,
15871 .dig_out_nid = ALC662_DIGOUT_NID,
15872 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15873 .channel_mode = alc662_3ST_2ch_modes,
15874 .input_mux = &alc662_eeepc_capture_source,
15875 .unsol_event = alc663_mode1_unsol_event,
15876 .init_hook = alc663_mode1_inithook,
15877 },
15878 [ALC662_ASUS_MODE2] = {
15879 .mixers = { alc662_1bjd_mixer, alc662_auto_capture_mixer },
15880 .init_verbs = { alc662_init_verbs,
15881 alc662_1bjd_amic_init_verbs },
15882 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15883 .dac_nids = alc662_dac_nids,
15884 .dig_out_nid = ALC662_DIGOUT_NID,
15885 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15886 .channel_mode = alc662_3ST_2ch_modes,
15887 .input_mux = &alc662_eeepc_capture_source,
15888 .unsol_event = alc662_mode2_unsol_event,
15889 .init_hook = alc662_mode2_inithook,
15890 },
15891 [ALC663_ASUS_MODE3] = {
15892 .mixers = { alc663_two_hp_m1_mixer, alc662_auto_capture_mixer },
15893 .init_verbs = { alc662_init_verbs,
15894 alc663_two_hp_amic_m1_init_verbs },
15895 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15896 .hp_nid = 0x03,
15897 .dac_nids = alc662_dac_nids,
15898 .dig_out_nid = ALC662_DIGOUT_NID,
15899 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15900 .channel_mode = alc662_3ST_2ch_modes,
15901 .input_mux = &alc662_eeepc_capture_source,
15902 .unsol_event = alc663_mode3_unsol_event,
15903 .init_hook = alc663_mode3_inithook,
15904 },
15905 [ALC663_ASUS_MODE4] = {
15906 .mixers = { alc663_asus_21jd_clfe_mixer,
15907 alc662_auto_capture_mixer},
15908 .init_verbs = { alc662_init_verbs,
15909 alc663_21jd_amic_init_verbs},
15910 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15911 .hp_nid = 0x03,
15912 .dac_nids = alc662_dac_nids,
15913 .dig_out_nid = ALC662_DIGOUT_NID,
15914 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15915 .channel_mode = alc662_3ST_2ch_modes,
15916 .input_mux = &alc662_eeepc_capture_source,
15917 .unsol_event = alc663_mode4_unsol_event,
15918 .init_hook = alc663_mode4_inithook,
15919 },
15920 [ALC663_ASUS_MODE5] = {
15921 .mixers = { alc663_asus_15jd_clfe_mixer,
15922 alc662_auto_capture_mixer },
15923 .init_verbs = { alc662_init_verbs,
15924 alc663_15jd_amic_init_verbs },
15925 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15926 .hp_nid = 0x03,
15927 .dac_nids = alc662_dac_nids,
15928 .dig_out_nid = ALC662_DIGOUT_NID,
15929 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15930 .channel_mode = alc662_3ST_2ch_modes,
15931 .input_mux = &alc662_eeepc_capture_source,
15932 .unsol_event = alc663_mode5_unsol_event,
15933 .init_hook = alc663_mode5_inithook,
15934 },
15935 [ALC663_ASUS_MODE6] = {
15936 .mixers = { alc663_two_hp_m2_mixer, alc662_auto_capture_mixer },
15937 .init_verbs = { alc662_init_verbs,
15938 alc663_two_hp_amic_m2_init_verbs },
15939 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15940 .hp_nid = 0x03,
15941 .dac_nids = alc662_dac_nids,
15942 .dig_out_nid = ALC662_DIGOUT_NID,
15943 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15944 .channel_mode = alc662_3ST_2ch_modes,
15945 .input_mux = &alc662_eeepc_capture_source,
15946 .unsol_event = alc663_mode6_unsol_event,
15947 .init_hook = alc663_mode6_inithook,
15948 },
14527}; 15949};
14528 15950
14529 15951
@@ -14560,15 +15982,15 @@ static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
14560 HDA_OUTPUT)); 15982 HDA_OUTPUT));
14561 if (err < 0) 15983 if (err < 0)
14562 return err; 15984 return err;
14563 err = add_control(spec, ALC_CTL_BIND_MUTE, 15985 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
14564 "Center Playback Switch", 15986 "Center Playback Switch",
14565 HDA_COMPOSE_AMP_VAL(nid, 1, 2, 15987 HDA_COMPOSE_AMP_VAL(0x0e, 1, 0,
14566 HDA_INPUT)); 15988 HDA_INPUT));
14567 if (err < 0) 15989 if (err < 0)
14568 return err; 15990 return err;
14569 err = add_control(spec, ALC_CTL_BIND_MUTE, 15991 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
14570 "LFE Playback Switch", 15992 "LFE Playback Switch",
14571 HDA_COMPOSE_AMP_VAL(nid, 2, 2, 15993 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
14572 HDA_INPUT)); 15994 HDA_INPUT));
14573 if (err < 0) 15995 if (err < 0)
14574 return err; 15996 return err;
@@ -14580,9 +16002,9 @@ static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
14580 if (err < 0) 16002 if (err < 0)
14581 return err; 16003 return err;
14582 sprintf(name, "%s Playback Switch", chname[i]); 16004 sprintf(name, "%s Playback Switch", chname[i]);
14583 err = add_control(spec, ALC_CTL_BIND_MUTE, name, 16005 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
14584 HDA_COMPOSE_AMP_VAL(nid, 3, 2, 16006 HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i),
14585 HDA_INPUT)); 16007 3, 0, HDA_INPUT));
14586 if (err < 0) 16008 if (err < 0)
14587 return err; 16009 return err;
14588 } 16010 }
@@ -14777,7 +16199,7 @@ static int alc662_parse_auto_config(struct hda_codec *codec)
14777 16199
14778 spec->num_mux_defs = 1; 16200 spec->num_mux_defs = 1;
14779 spec->input_mux = &spec->private_imux; 16201 spec->input_mux = &spec->private_imux;
14780 16202
14781 spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs; 16203 spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
14782 if (codec->vendor_id == 0x10ec0663) 16204 if (codec->vendor_id == 0x10ec0663)
14783 spec->init_verbs[spec->num_init_verbs++] = 16205 spec->init_verbs[spec->num_init_verbs++] =
@@ -14896,6 +16318,8 @@ struct hda_codec_preset snd_hda_preset_realtek[] = {
14896 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, 16318 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
14897 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, 16319 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
14898 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 }, 16320 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
16321 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
16322 .patch = patch_alc882 }, /* should be patch_alc883() in future */
14899 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A", 16323 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
14900 .patch = patch_alc882 }, /* should be patch_alc883() in future */ 16324 .patch = patch_alc882 }, /* should be patch_alc883() in future */
14901 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, 16325 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index ad994fcab725..c59065513118 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -33,10 +33,12 @@
33#include "hda_codec.h" 33#include "hda_codec.h"
34#include "hda_local.h" 34#include "hda_local.h"
35#include "hda_patch.h" 35#include "hda_patch.h"
36#include "hda_beep.h"
36 37
37#define NUM_CONTROL_ALLOC 32 38#define NUM_CONTROL_ALLOC 32
38#define STAC_PWR_EVENT 0x20 39#define STAC_PWR_EVENT 0x20
39#define STAC_HP_EVENT 0x30 40#define STAC_HP_EVENT 0x30
41#define STAC_VREF_EVENT 0x40
40 42
41enum { 43enum {
42 STAC_REF, 44 STAC_REF,
@@ -71,9 +73,15 @@ enum {
71}; 73};
72 74
73enum { 75enum {
76 STAC_92HD83XXX_REF,
77 STAC_92HD83XXX_MODELS
78};
79
80enum {
74 STAC_92HD71BXX_REF, 81 STAC_92HD71BXX_REF,
75 STAC_DELL_M4_1, 82 STAC_DELL_M4_1,
76 STAC_DELL_M4_2, 83 STAC_DELL_M4_2,
84 STAC_HP_M4,
77 STAC_92HD71BXX_MODELS 85 STAC_92HD71BXX_MODELS
78}; 86};
79 87
@@ -104,6 +112,7 @@ enum {
104 STAC_MACBOOK_PRO_V2, 112 STAC_MACBOOK_PRO_V2,
105 STAC_IMAC_INTEL, 113 STAC_IMAC_INTEL,
106 STAC_IMAC_INTEL_20, 114 STAC_IMAC_INTEL_20,
115 STAC_ECS_202,
107 STAC_922X_DELL_D81, 116 STAC_922X_DELL_D81,
108 STAC_922X_DELL_D82, 117 STAC_922X_DELL_D82,
109 STAC_922X_DELL_M81, 118 STAC_922X_DELL_M81,
@@ -130,6 +139,7 @@ struct sigmatel_spec {
130 unsigned int mic_switch: 1; 139 unsigned int mic_switch: 1;
131 unsigned int alt_switch: 1; 140 unsigned int alt_switch: 1;
132 unsigned int hp_detect: 1; 141 unsigned int hp_detect: 1;
142 unsigned int spdif_mute: 1;
133 143
134 /* gpio lines */ 144 /* gpio lines */
135 unsigned int eapd_mask; 145 unsigned int eapd_mask;
@@ -138,17 +148,22 @@ struct sigmatel_spec {
138 unsigned int gpio_data; 148 unsigned int gpio_data;
139 unsigned int gpio_mute; 149 unsigned int gpio_mute;
140 150
151 /* stream */
152 unsigned int stream_delay;
153
141 /* analog loopback */ 154 /* analog loopback */
142 unsigned char aloopback_mask; 155 unsigned char aloopback_mask;
143 unsigned char aloopback_shift; 156 unsigned char aloopback_shift;
144 157
145 /* power management */ 158 /* power management */
146 unsigned int num_pwrs; 159 unsigned int num_pwrs;
160 unsigned int *pwr_mapping;
147 hda_nid_t *pwr_nids; 161 hda_nid_t *pwr_nids;
148 hda_nid_t *dac_list; 162 hda_nid_t *dac_list;
149 163
150 /* playback */ 164 /* playback */
151 struct hda_input_mux *mono_mux; 165 struct hda_input_mux *mono_mux;
166 struct hda_input_mux *amp_mux;
152 unsigned int cur_mmux; 167 unsigned int cur_mmux;
153 struct hda_multi_out multiout; 168 struct hda_multi_out multiout;
154 hda_nid_t dac_nids[5]; 169 hda_nid_t dac_nids[5];
@@ -162,8 +177,14 @@ struct sigmatel_spec {
162 unsigned int num_dmics; 177 unsigned int num_dmics;
163 hda_nid_t *dmux_nids; 178 hda_nid_t *dmux_nids;
164 unsigned int num_dmuxes; 179 unsigned int num_dmuxes;
180 hda_nid_t *smux_nids;
181 unsigned int num_smuxes;
182 const char **spdif_labels;
183
165 hda_nid_t dig_in_nid; 184 hda_nid_t dig_in_nid;
166 hda_nid_t mono_nid; 185 hda_nid_t mono_nid;
186 hda_nid_t anabeep_nid;
187 hda_nid_t digbeep_nid;
167 188
168 /* pin widgets */ 189 /* pin widgets */
169 hda_nid_t *pin_nids; 190 hda_nid_t *pin_nids;
@@ -180,6 +201,12 @@ struct sigmatel_spec {
180 unsigned int cur_dmux[2]; 201 unsigned int cur_dmux[2];
181 struct hda_input_mux *input_mux; 202 struct hda_input_mux *input_mux;
182 unsigned int cur_mux[3]; 203 unsigned int cur_mux[3];
204 struct hda_input_mux *sinput_mux;
205 unsigned int cur_smux[2];
206 unsigned int cur_amux;
207 hda_nid_t *amp_nids;
208 unsigned int num_amps;
209 unsigned int powerdown_adcs;
183 210
184 /* i/o switches */ 211 /* i/o switches */
185 unsigned int io_switch[2]; 212 unsigned int io_switch[2];
@@ -195,6 +222,8 @@ struct sigmatel_spec {
195 struct snd_kcontrol_new *kctl_alloc; 222 struct snd_kcontrol_new *kctl_alloc;
196 struct hda_input_mux private_dimux; 223 struct hda_input_mux private_dimux;
197 struct hda_input_mux private_imux; 224 struct hda_input_mux private_imux;
225 struct hda_input_mux private_smux;
226 struct hda_input_mux private_amp_mux;
198 struct hda_input_mux private_mono_mux; 227 struct hda_input_mux private_mono_mux;
199}; 228};
200 229
@@ -215,10 +244,19 @@ static hda_nid_t stac92hd73xx_pwr_nids[8] = {
215 0x0f, 0x10, 0x11 244 0x0f, 0x10, 0x11
216}; 245};
217 246
247static hda_nid_t stac92hd73xx_slave_dig_outs[2] = {
248 0x26, 0,
249};
250
218static hda_nid_t stac92hd73xx_adc_nids[2] = { 251static hda_nid_t stac92hd73xx_adc_nids[2] = {
219 0x1a, 0x1b 252 0x1a, 0x1b
220}; 253};
221 254
255#define DELL_M6_AMP 2
256static hda_nid_t stac92hd73xx_amp_nids[3] = {
257 0x0b, 0x0c, 0x0e
258};
259
222#define STAC92HD73XX_NUM_DMICS 2 260#define STAC92HD73XX_NUM_DMICS 2
223static hda_nid_t stac92hd73xx_dmic_nids[STAC92HD73XX_NUM_DMICS + 1] = { 261static hda_nid_t stac92hd73xx_dmic_nids[STAC92HD73XX_NUM_DMICS + 1] = {
224 0x13, 0x14, 0 262 0x13, 0x14, 0
@@ -237,6 +275,41 @@ static hda_nid_t stac92hd73xx_dmux_nids[2] = {
237 0x20, 0x21, 275 0x20, 0x21,
238}; 276};
239 277
278static hda_nid_t stac92hd73xx_smux_nids[2] = {
279 0x22, 0x23,
280};
281
282#define STAC92HD83XXX_NUM_DMICS 2
283static hda_nid_t stac92hd83xxx_dmic_nids[STAC92HD83XXX_NUM_DMICS + 1] = {
284 0x11, 0x12, 0
285};
286
287#define STAC92HD81_DAC_COUNT 2
288#define STAC92HD83_DAC_COUNT 3
289static hda_nid_t stac92hd83xxx_dac_nids[STAC92HD73_DAC_COUNT] = {
290 0x13, 0x14, 0x22,
291};
292
293static hda_nid_t stac92hd83xxx_dmux_nids[2] = {
294 0x17, 0x18,
295};
296
297static hda_nid_t stac92hd83xxx_adc_nids[2] = {
298 0x15, 0x16,
299};
300
301static hda_nid_t stac92hd83xxx_pwr_nids[4] = {
302 0xa, 0xb, 0xd, 0xe,
303};
304
305static hda_nid_t stac92hd83xxx_slave_dig_outs[2] = {
306 0x1e, 0,
307};
308
309static unsigned int stac92hd83xxx_pwr_mapping[4] = {
310 0x03, 0x0c, 0x10, 0x40,
311};
312
240static hda_nid_t stac92hd71bxx_pwr_nids[3] = { 313static hda_nid_t stac92hd71bxx_pwr_nids[3] = {
241 0x0a, 0x0d, 0x0f 314 0x0a, 0x0d, 0x0f
242}; 315};
@@ -249,8 +322,12 @@ static hda_nid_t stac92hd71bxx_mux_nids[2] = {
249 0x1a, 0x1b 322 0x1a, 0x1b
250}; 323};
251 324
252static hda_nid_t stac92hd71bxx_dmux_nids[1] = { 325static hda_nid_t stac92hd71bxx_dmux_nids[2] = {
253 0x1c, 326 0x1c, 0x1d,
327};
328
329static hda_nid_t stac92hd71bxx_smux_nids[2] = {
330 0x24, 0x25,
254}; 331};
255 332
256static hda_nid_t stac92hd71bxx_dac_nids[1] = { 333static hda_nid_t stac92hd71bxx_dac_nids[1] = {
@@ -262,6 +339,10 @@ static hda_nid_t stac92hd71bxx_dmic_nids[STAC92HD71BXX_NUM_DMICS + 1] = {
262 0x18, 0x19, 0 339 0x18, 0x19, 0
263}; 340};
264 341
342static hda_nid_t stac92hd71bxx_slave_dig_outs[2] = {
343 0x22, 0
344};
345
265static hda_nid_t stac925x_adc_nids[1] = { 346static hda_nid_t stac925x_adc_nids[1] = {
266 0x03, 347 0x03,
267}; 348};
@@ -299,6 +380,10 @@ static hda_nid_t stac927x_mux_nids[3] = {
299 0x15, 0x16, 0x17 380 0x15, 0x16, 0x17
300}; 381};
301 382
383static hda_nid_t stac927x_smux_nids[1] = {
384 0x21,
385};
386
302static hda_nid_t stac927x_dac_nids[6] = { 387static hda_nid_t stac927x_dac_nids[6] = {
303 0x02, 0x03, 0x04, 0x05, 0x06, 0 388 0x02, 0x03, 0x04, 0x05, 0x06, 0
304}; 389};
@@ -312,6 +397,11 @@ static hda_nid_t stac927x_dmic_nids[STAC927X_NUM_DMICS + 1] = {
312 0x13, 0x14, 0 397 0x13, 0x14, 0
313}; 398};
314 399
400static const char *stac927x_spdif_labels[5] = {
401 "Digital Playback", "ADAT", "Analog Mux 1",
402 "Analog Mux 2", "Analog Mux 3"
403};
404
315static hda_nid_t stac9205_adc_nids[2] = { 405static hda_nid_t stac9205_adc_nids[2] = {
316 0x12, 0x13 406 0x12, 0x13
317}; 407};
@@ -324,6 +414,10 @@ static hda_nid_t stac9205_dmux_nids[1] = {
324 0x1d, 414 0x1d,
325}; 415};
326 416
417static hda_nid_t stac9205_smux_nids[1] = {
418 0x21,
419};
420
327#define STAC9205_NUM_DMICS 2 421#define STAC9205_NUM_DMICS 2
328static hda_nid_t stac9205_dmic_nids[STAC9205_NUM_DMICS + 1] = { 422static hda_nid_t stac9205_dmic_nids[STAC9205_NUM_DMICS + 1] = {
329 0x17, 0x18, 0 423 0x17, 0x18, 0
@@ -347,12 +441,18 @@ static hda_nid_t stac922x_pin_nids[10] = {
347static hda_nid_t stac92hd73xx_pin_nids[13] = { 441static hda_nid_t stac92hd73xx_pin_nids[13] = {
348 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 442 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
349 0x0f, 0x10, 0x11, 0x12, 0x13, 443 0x0f, 0x10, 0x11, 0x12, 0x13,
350 0x14, 0x1e, 0x22 444 0x14, 0x22, 0x23
351}; 445};
352 446
353static hda_nid_t stac92hd71bxx_pin_nids[10] = { 447static hda_nid_t stac92hd83xxx_pin_nids[14] = {
448 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
449 0x0f, 0x10, 0x11, 0x12, 0x13,
450 0x1d, 0x1e, 0x1f, 0x20
451};
452static hda_nid_t stac92hd71bxx_pin_nids[11] = {
354 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 453 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
355 0x0f, 0x14, 0x18, 0x19, 0x1e, 454 0x0f, 0x14, 0x18, 0x19, 0x1e,
455 0x1f,
356}; 456};
357 457
358static hda_nid_t stac927x_pin_nids[14] = { 458static hda_nid_t stac927x_pin_nids[14] = {
@@ -367,6 +467,34 @@ static hda_nid_t stac9205_pin_nids[12] = {
367 0x21, 0x22, 467 0x21, 0x22,
368}; 468};
369 469
470#define stac92xx_amp_volume_info snd_hda_mixer_amp_volume_info
471
472static int stac92xx_amp_volume_get(struct snd_kcontrol *kcontrol,
473 struct snd_ctl_elem_value *ucontrol)
474{
475 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
476 struct sigmatel_spec *spec = codec->spec;
477 hda_nid_t nid = spec->amp_nids[spec->cur_amux];
478
479 kcontrol->private_value ^= get_amp_nid(kcontrol);
480 kcontrol->private_value |= nid;
481
482 return snd_hda_mixer_amp_volume_get(kcontrol, ucontrol);
483}
484
485static int stac92xx_amp_volume_put(struct snd_kcontrol *kcontrol,
486 struct snd_ctl_elem_value *ucontrol)
487{
488 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
489 struct sigmatel_spec *spec = codec->spec;
490 hda_nid_t nid = spec->amp_nids[spec->cur_amux];
491
492 kcontrol->private_value ^= get_amp_nid(kcontrol);
493 kcontrol->private_value |= nid;
494
495 return snd_hda_mixer_amp_volume_put(kcontrol, ucontrol);
496}
497
370static int stac92xx_dmux_enum_info(struct snd_kcontrol *kcontrol, 498static int stac92xx_dmux_enum_info(struct snd_kcontrol *kcontrol,
371 struct snd_ctl_elem_info *uinfo) 499 struct snd_ctl_elem_info *uinfo)
372{ 500{
@@ -397,6 +525,58 @@ static int stac92xx_dmux_enum_put(struct snd_kcontrol *kcontrol,
397 spec->dmux_nids[dmux_idx], &spec->cur_dmux[dmux_idx]); 525 spec->dmux_nids[dmux_idx], &spec->cur_dmux[dmux_idx]);
398} 526}
399 527
528static int stac92xx_smux_enum_info(struct snd_kcontrol *kcontrol,
529 struct snd_ctl_elem_info *uinfo)
530{
531 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
532 struct sigmatel_spec *spec = codec->spec;
533 return snd_hda_input_mux_info(spec->sinput_mux, uinfo);
534}
535
536static int stac92xx_smux_enum_get(struct snd_kcontrol *kcontrol,
537 struct snd_ctl_elem_value *ucontrol)
538{
539 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
540 struct sigmatel_spec *spec = codec->spec;
541 unsigned int smux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
542
543 ucontrol->value.enumerated.item[0] = spec->cur_smux[smux_idx];
544 return 0;
545}
546
547static int stac92xx_smux_enum_put(struct snd_kcontrol *kcontrol,
548 struct snd_ctl_elem_value *ucontrol)
549{
550 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
551 struct sigmatel_spec *spec = codec->spec;
552 struct hda_input_mux *smux = &spec->private_smux;
553 unsigned int smux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
554 int err, val;
555 hda_nid_t nid;
556
557 err = snd_hda_input_mux_put(codec, spec->sinput_mux, ucontrol,
558 spec->smux_nids[smux_idx], &spec->cur_smux[smux_idx]);
559 if (err < 0)
560 return err;
561
562 if (spec->spdif_mute) {
563 if (smux_idx == 0)
564 nid = spec->multiout.dig_out_nid;
565 else
566 nid = codec->slave_dig_outs[smux_idx - 1];
567 if (spec->cur_smux[smux_idx] == smux->num_items - 1)
568 val = AMP_OUT_MUTE;
569 if (smux_idx == 0)
570 nid = spec->multiout.dig_out_nid;
571 else
572 nid = codec->slave_dig_outs[smux_idx - 1];
573 /* un/mute SPDIF out */
574 snd_hda_codec_write_cache(codec, nid, 0,
575 AC_VERB_SET_AMP_GAIN_MUTE, val);
576 }
577 return 0;
578}
579
400static int stac92xx_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 580static int stac92xx_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
401{ 581{
402 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 582 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
@@ -452,6 +632,41 @@ static int stac92xx_mono_mux_enum_put(struct snd_kcontrol *kcontrol,
452 spec->mono_nid, &spec->cur_mmux); 632 spec->mono_nid, &spec->cur_mmux);
453} 633}
454 634
635static int stac92xx_amp_mux_enum_info(struct snd_kcontrol *kcontrol,
636 struct snd_ctl_elem_info *uinfo)
637{
638 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
639 struct sigmatel_spec *spec = codec->spec;
640 return snd_hda_input_mux_info(spec->amp_mux, uinfo);
641}
642
643static int stac92xx_amp_mux_enum_get(struct snd_kcontrol *kcontrol,
644 struct snd_ctl_elem_value *ucontrol)
645{
646 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
647 struct sigmatel_spec *spec = codec->spec;
648
649 ucontrol->value.enumerated.item[0] = spec->cur_amux;
650 return 0;
651}
652
653static int stac92xx_amp_mux_enum_put(struct snd_kcontrol *kcontrol,
654 struct snd_ctl_elem_value *ucontrol)
655{
656 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
657 struct sigmatel_spec *spec = codec->spec;
658 struct snd_kcontrol *ctl =
659 snd_hda_find_mixer_ctl(codec, "Amp Capture Volume");
660 if (!ctl)
661 return -EINVAL;
662
663 snd_ctl_notify(codec->bus->card, SNDRV_CTL_EVENT_MASK_VALUE |
664 SNDRV_CTL_EVENT_MASK_INFO, &ctl->id);
665
666 return snd_hda_input_mux_put(codec, spec->amp_mux, ucontrol,
667 0, &spec->cur_amux);
668}
669
455#define stac92xx_aloopback_info snd_ctl_boolean_mono_info 670#define stac92xx_aloopback_info snd_ctl_boolean_mono_info
456 671
457static int stac92xx_aloopback_get(struct snd_kcontrol *kcontrol, 672static int stac92xx_aloopback_get(struct snd_kcontrol *kcontrol,
@@ -546,8 +761,8 @@ static struct hda_verb dell_eq_core_init[] = {
546 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec}, 761 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec},
547 /* setup audio connections */ 762 /* setup audio connections */
548 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00}, 763 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
549 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01}, 764 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x02},
550 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x02}, 765 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x01},
551 /* setup adcs to point to mixer */ 766 /* setup adcs to point to mixer */
552 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b}, 767 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
553 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b}, 768 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
@@ -628,25 +843,36 @@ static struct hda_verb stac92hd73xx_10ch_core_init[] = {
628 {} 843 {}
629}; 844};
630 845
846static struct hda_verb stac92hd83xxx_core_init[] = {
847 /* start of config #1 */
848 { 0xe, AC_VERB_SET_CONNECT_SEL, 0x3},
849
850 /* start of config #2 */
851 { 0xa, AC_VERB_SET_CONNECT_SEL, 0x0},
852 { 0xb, AC_VERB_SET_CONNECT_SEL, 0x0},
853 { 0xd, AC_VERB_SET_CONNECT_SEL, 0x1},
854
855 /* power state controls amps */
856 { 0x01, AC_VERB_SET_EAPD, 1 << 2},
857};
858
631static struct hda_verb stac92hd71bxx_core_init[] = { 859static struct hda_verb stac92hd71bxx_core_init[] = {
632 /* set master volume and direct control */ 860 /* set master volume and direct control */
633 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 861 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
634 /* connect headphone jack to dac1 */ 862 /* connect headphone jack to dac1 */
635 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01}, 863 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01},
636 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Speaker */
637 /* unmute right and left channels for nodes 0x0a, 0xd, 0x0f */ 864 /* unmute right and left channels for nodes 0x0a, 0xd, 0x0f */
638 { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 865 { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
639 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 866 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
640 { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 867 { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
641}; 868};
642 869
643#define HD_DISABLE_PORTF 3 870#define HD_DISABLE_PORTF 2
644static struct hda_verb stac92hd71bxx_analog_core_init[] = { 871static struct hda_verb stac92hd71bxx_analog_core_init[] = {
645 /* start of config #1 */ 872 /* start of config #1 */
646 873
647 /* connect port 0f to audio mixer */ 874 /* connect port 0f to audio mixer */
648 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x2}, 875 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x2},
649 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Speaker */
650 /* unmute right and left channels for node 0x0f */ 876 /* unmute right and left channels for node 0x0f */
651 { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 877 { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
652 /* start of config #2 */ 878 /* start of config #2 */
@@ -655,10 +881,6 @@ static struct hda_verb stac92hd71bxx_analog_core_init[] = {
655 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 881 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
656 /* connect headphone jack to dac1 */ 882 /* connect headphone jack to dac1 */
657 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01}, 883 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01},
658 /* connect port 0d to audio mixer */
659 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x2},
660 /* unmute dac0 input in audio mixer */
661 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
662 /* unmute right and left channels for nodes 0x0a, 0xd */ 884 /* unmute right and left channels for nodes 0x0a, 0xd */
663 { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 885 { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
664 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 886 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
@@ -690,12 +912,16 @@ static struct hda_verb d965_core_init[] = {
690static struct hda_verb stac927x_core_init[] = { 912static struct hda_verb stac927x_core_init[] = {
691 /* set master volume and direct control */ 913 /* set master volume and direct control */
692 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 914 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
915 /* enable analog pc beep path */
916 { 0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5},
693 {} 917 {}
694}; 918};
695 919
696static struct hda_verb stac9205_core_init[] = { 920static struct hda_verb stac9205_core_init[] = {
697 /* set master volume and direct control */ 921 /* set master volume and direct control */
698 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 922 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
923 /* enable analog pc beep path */
924 { 0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5},
699 {} 925 {}
700}; 926};
701 927
@@ -709,6 +935,31 @@ static struct hda_verb stac9205_core_init[] = {
709 .put = stac92xx_mono_mux_enum_put, \ 935 .put = stac92xx_mono_mux_enum_put, \
710 } 936 }
711 937
938#define STAC_AMP_MUX \
939 { \
940 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
941 .name = "Amp Selector Capture Switch", \
942 .count = 1, \
943 .info = stac92xx_amp_mux_enum_info, \
944 .get = stac92xx_amp_mux_enum_get, \
945 .put = stac92xx_amp_mux_enum_put, \
946 }
947
948#define STAC_AMP_VOL(xname, nid, chs, idx, dir) \
949 { \
950 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
951 .name = xname, \
952 .index = 0, \
953 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
954 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
955 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, \
956 .info = stac92xx_amp_volume_info, \
957 .get = stac92xx_amp_volume_get, \
958 .put = stac92xx_amp_volume_put, \
959 .tlv = { .c = snd_hda_mixer_amp_tlv }, \
960 .private_value = HDA_COMPOSE_AMP_VAL(nid, chs, idx, dir) \
961 }
962
712#define STAC_INPUT_SOURCE(cnt) \ 963#define STAC_INPUT_SOURCE(cnt) \
713 { \ 964 { \
714 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 965 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
@@ -736,33 +987,36 @@ static struct snd_kcontrol_new stac9200_mixer[] = {
736 STAC_INPUT_SOURCE(1), 987 STAC_INPUT_SOURCE(1),
737 HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT), 988 HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT),
738 HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT), 989 HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT),
739 HDA_CODEC_VOLUME("Capture Mux Volume", 0x0c, 0, HDA_OUTPUT),
740 { } /* end */ 990 { } /* end */
741}; 991};
742 992
993#define DELL_M6_MIXER 6
743static struct snd_kcontrol_new stac92hd73xx_6ch_mixer[] = { 994static struct snd_kcontrol_new stac92hd73xx_6ch_mixer[] = {
744 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 3), 995 /* start of config #1 */
745
746 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT),
747 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT),
748
749 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x21, 0x0, HDA_OUTPUT),
750 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x21, 0x0, HDA_OUTPUT),
751
752 HDA_CODEC_VOLUME("Front Mic Mixer Capture Volume", 0x1d, 0, HDA_INPUT), 996 HDA_CODEC_VOLUME("Front Mic Mixer Capture Volume", 0x1d, 0, HDA_INPUT),
753 HDA_CODEC_MUTE("Front Mic Mixer Capture Switch", 0x1d, 0, HDA_INPUT), 997 HDA_CODEC_MUTE("Front Mic Mixer Capture Switch", 0x1d, 0, HDA_INPUT),
754 998
755 HDA_CODEC_VOLUME("Mic Mixer Capture Volume", 0x1d, 0x1, HDA_INPUT),
756 HDA_CODEC_MUTE("Mic Mixer Capture Switch", 0x1d, 0x1, HDA_INPUT),
757
758 HDA_CODEC_VOLUME("Line In Mixer Capture Volume", 0x1d, 0x2, HDA_INPUT), 999 HDA_CODEC_VOLUME("Line In Mixer Capture Volume", 0x1d, 0x2, HDA_INPUT),
759 HDA_CODEC_MUTE("Line In Mixer Capture Switch", 0x1d, 0x2, HDA_INPUT), 1000 HDA_CODEC_MUTE("Line In Mixer Capture Switch", 0x1d, 0x2, HDA_INPUT),
760 1001
1002 HDA_CODEC_VOLUME("CD Mixer Capture Volume", 0x1d, 0x4, HDA_INPUT),
1003 HDA_CODEC_MUTE("CD Mixer Capture Switch", 0x1d, 0x4, HDA_INPUT),
1004
1005 /* start of config #2 */
1006 HDA_CODEC_VOLUME("Mic Mixer Capture Volume", 0x1d, 0x1, HDA_INPUT),
1007 HDA_CODEC_MUTE("Mic Mixer Capture Switch", 0x1d, 0x1, HDA_INPUT),
1008
761 HDA_CODEC_VOLUME("DAC Mixer Capture Volume", 0x1d, 0x3, HDA_INPUT), 1009 HDA_CODEC_VOLUME("DAC Mixer Capture Volume", 0x1d, 0x3, HDA_INPUT),
762 HDA_CODEC_MUTE("DAC Mixer Capture Switch", 0x1d, 0x3, HDA_INPUT), 1010 HDA_CODEC_MUTE("DAC Mixer Capture Switch", 0x1d, 0x3, HDA_INPUT),
763 1011
764 HDA_CODEC_VOLUME("CD Mixer Capture Volume", 0x1d, 0x4, HDA_INPUT), 1012 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 3),
765 HDA_CODEC_MUTE("CD Mixer Capture Switch", 0x1d, 0x4, HDA_INPUT), 1013
1014 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT),
1015 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT),
1016
1017 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x21, 0x0, HDA_OUTPUT),
1018 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x21, 0x0, HDA_OUTPUT),
1019
766 { } /* end */ 1020 { } /* end */
767}; 1021};
768 1022
@@ -818,22 +1072,59 @@ static struct snd_kcontrol_new stac92hd73xx_10ch_mixer[] = {
818 { } /* end */ 1072 { } /* end */
819}; 1073};
820 1074
1075
1076static struct snd_kcontrol_new stac92hd83xxx_mixer[] = {
1077 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x17, 0x0, HDA_OUTPUT),
1078 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x17, 0x0, HDA_OUTPUT),
1079
1080 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x18, 0x0, HDA_OUTPUT),
1081 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x18, 0x0, HDA_OUTPUT),
1082
1083 HDA_CODEC_VOLUME("DAC0 Capture Volume", 0x1b, 0, HDA_INPUT),
1084 HDA_CODEC_MUTE("DAC0 Capture Switch", 0x1b, 0, HDA_INPUT),
1085
1086 HDA_CODEC_VOLUME("DAC1 Capture Volume", 0x1b, 0x1, HDA_INPUT),
1087 HDA_CODEC_MUTE("DAC1 Capture Switch", 0x1b, 0x1, HDA_INPUT),
1088
1089 HDA_CODEC_VOLUME("Front Mic Capture Volume", 0x1b, 0x2, HDA_INPUT),
1090 HDA_CODEC_MUTE("Front Mic Capture Switch", 0x1b, 0x2, HDA_INPUT),
1091
1092 HDA_CODEC_VOLUME("Line In Capture Volume", 0x1b, 0x3, HDA_INPUT),
1093 HDA_CODEC_MUTE("Line In Capture Switch", 0x1b, 0x3, HDA_INPUT),
1094
1095 /*
1096 HDA_CODEC_VOLUME("Mic Capture Volume", 0x1b, 0x4, HDA_INPUT),
1097 HDA_CODEC_MUTE("Mic Capture Switch", 0x1b 0x4, HDA_INPUT),
1098 */
1099 { } /* end */
1100};
1101
821static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = { 1102static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = {
822 STAC_INPUT_SOURCE(2), 1103 STAC_INPUT_SOURCE(2),
1104 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2),
823 1105
824 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT), 1106 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT),
825 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT), 1107 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT),
826 HDA_CODEC_VOLUME_IDX("Capture Mux Volume", 0x0, 0x1a, 0x0, HDA_OUTPUT),
827 1108
828 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1d, 0x0, HDA_OUTPUT), 1109 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1d, 0x0, HDA_OUTPUT),
829 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1d, 0x0, HDA_OUTPUT), 1110 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1d, 0x0, HDA_OUTPUT),
830 HDA_CODEC_VOLUME_IDX("Capture Mux Volume", 0x1, 0x1b, 0x0, HDA_OUTPUT), 1111 /* analog pc-beep replaced with digital beep support */
831 1112 /*
832 HDA_CODEC_VOLUME("PC Beep Volume", 0x17, 0x2, HDA_INPUT), 1113 HDA_CODEC_VOLUME("PC Beep Volume", 0x17, 0x2, HDA_INPUT),
833 HDA_CODEC_MUTE("PC Beep Switch", 0x17, 0x2, HDA_INPUT), 1114 HDA_CODEC_MUTE("PC Beep Switch", 0x17, 0x2, HDA_INPUT),
1115 */
1116
1117 HDA_CODEC_MUTE("Import0 Mux Capture Switch", 0x17, 0x0, HDA_INPUT),
1118 HDA_CODEC_VOLUME("Import0 Mux Capture Volume", 0x17, 0x0, HDA_INPUT),
1119
1120 HDA_CODEC_MUTE("Import1 Mux Capture Switch", 0x17, 0x1, HDA_INPUT),
1121 HDA_CODEC_VOLUME("Import1 Mux Capture Volume", 0x17, 0x1, HDA_INPUT),
834 1122
835 HDA_CODEC_MUTE("Analog Loopback 1", 0x17, 0x3, HDA_INPUT), 1123 HDA_CODEC_MUTE("DAC0 Capture Switch", 0x17, 0x3, HDA_INPUT),
836 HDA_CODEC_MUTE("Analog Loopback 2", 0x17, 0x4, HDA_INPUT), 1124 HDA_CODEC_VOLUME("DAC0 Capture Volume", 0x17, 0x3, HDA_INPUT),
1125
1126 HDA_CODEC_MUTE("DAC1 Capture Switch", 0x17, 0x4, HDA_INPUT),
1127 HDA_CODEC_VOLUME("DAC1 Capture Volume", 0x17, 0x4, HDA_INPUT),
837 { } /* end */ 1128 { } /* end */
838}; 1129};
839 1130
@@ -843,11 +1134,9 @@ static struct snd_kcontrol_new stac92hd71bxx_mixer[] = {
843 1134
844 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT), 1135 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT),
845 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT), 1136 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT),
846 HDA_CODEC_VOLUME_IDX("Capture Mux Volume", 0x0, 0x1a, 0x0, HDA_OUTPUT),
847 1137
848 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1d, 0x0, HDA_OUTPUT), 1138 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1d, 0x0, HDA_OUTPUT),
849 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1d, 0x0, HDA_OUTPUT), 1139 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1d, 0x0, HDA_OUTPUT),
850 HDA_CODEC_VOLUME_IDX("Capture Mux Volume", 0x1, 0x1b, 0x0, HDA_OUTPUT),
851 { } /* end */ 1140 { } /* end */
852}; 1141};
853 1142
@@ -855,7 +1144,6 @@ static struct snd_kcontrol_new stac925x_mixer[] = {
855 STAC_INPUT_SOURCE(1), 1144 STAC_INPUT_SOURCE(1),
856 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_OUTPUT), 1145 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_OUTPUT),
857 HDA_CODEC_MUTE("Capture Switch", 0x14, 0, HDA_OUTPUT), 1146 HDA_CODEC_MUTE("Capture Switch", 0x14, 0, HDA_OUTPUT),
858 HDA_CODEC_VOLUME("Capture Mux Volume", 0x0f, 0, HDA_OUTPUT),
859 { } /* end */ 1147 { } /* end */
860}; 1148};
861 1149
@@ -865,12 +1153,9 @@ static struct snd_kcontrol_new stac9205_mixer[] = {
865 1153
866 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1b, 0x0, HDA_INPUT), 1154 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1b, 0x0, HDA_INPUT),
867 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1d, 0x0, HDA_OUTPUT), 1155 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1d, 0x0, HDA_OUTPUT),
868 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x0, 0x19, 0x0, HDA_OUTPUT),
869 1156
870 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1c, 0x0, HDA_INPUT), 1157 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1c, 0x0, HDA_INPUT),
871 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1e, 0x0, HDA_OUTPUT), 1158 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1e, 0x0, HDA_OUTPUT),
872 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x1, 0x1A, 0x0, HDA_OUTPUT),
873
874 { } /* end */ 1159 { } /* end */
875}; 1160};
876 1161
@@ -879,11 +1164,9 @@ static struct snd_kcontrol_new stac922x_mixer[] = {
879 STAC_INPUT_SOURCE(2), 1164 STAC_INPUT_SOURCE(2),
880 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x17, 0x0, HDA_INPUT), 1165 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x17, 0x0, HDA_INPUT),
881 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x17, 0x0, HDA_INPUT), 1166 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x17, 0x0, HDA_INPUT),
882 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x0, 0x12, 0x0, HDA_OUTPUT),
883 1167
884 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x18, 0x0, HDA_INPUT), 1168 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x18, 0x0, HDA_INPUT),
885 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x18, 0x0, HDA_INPUT), 1169 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x18, 0x0, HDA_INPUT),
886 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x1, 0x13, 0x0, HDA_OUTPUT),
887 { } /* end */ 1170 { } /* end */
888}; 1171};
889 1172
@@ -894,15 +1177,12 @@ static struct snd_kcontrol_new stac927x_mixer[] = {
894 1177
895 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x18, 0x0, HDA_INPUT), 1178 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x18, 0x0, HDA_INPUT),
896 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1b, 0x0, HDA_OUTPUT), 1179 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1b, 0x0, HDA_OUTPUT),
897 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x0, 0x15, 0x0, HDA_OUTPUT),
898 1180
899 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x19, 0x0, HDA_INPUT), 1181 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x19, 0x0, HDA_INPUT),
900 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1c, 0x0, HDA_OUTPUT), 1182 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1c, 0x0, HDA_OUTPUT),
901 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x1, 0x16, 0x0, HDA_OUTPUT),
902 1183
903 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x2, 0x1A, 0x0, HDA_INPUT), 1184 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x2, 0x1A, 0x0, HDA_INPUT),
904 HDA_CODEC_MUTE_IDX("Capture Switch", 0x2, 0x1d, 0x0, HDA_OUTPUT), 1185 HDA_CODEC_MUTE_IDX("Capture Switch", 0x2, 0x1d, 0x0, HDA_OUTPUT),
905 HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x2, 0x17, 0x0, HDA_OUTPUT),
906 { } /* end */ 1186 { } /* end */
907}; 1187};
908 1188
@@ -915,6 +1195,15 @@ static struct snd_kcontrol_new stac_dmux_mixer = {
915 .put = stac92xx_dmux_enum_put, 1195 .put = stac92xx_dmux_enum_put,
916}; 1196};
917 1197
1198static struct snd_kcontrol_new stac_smux_mixer = {
1199 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1200 .name = "IEC958 Playback Source",
1201 /* count set later */
1202 .info = stac92xx_smux_enum_info,
1203 .get = stac92xx_smux_enum_get,
1204 .put = stac92xx_smux_enum_put,
1205};
1206
918static const char *slave_vols[] = { 1207static const char *slave_vols[] = {
919 "Front Playback Volume", 1208 "Front Playback Volume",
920 "Surround Playback Volume", 1209 "Surround Playback Volume",
@@ -966,6 +1255,22 @@ static int stac92xx_build_controls(struct hda_codec *codec)
966 if (err < 0) 1255 if (err < 0)
967 return err; 1256 return err;
968 } 1257 }
1258 if (spec->num_smuxes > 0) {
1259 int wcaps = get_wcaps(codec, spec->multiout.dig_out_nid);
1260 struct hda_input_mux *smux = &spec->private_smux;
1261 /* check for mute support on SPDIF out */
1262 if (wcaps & AC_WCAP_OUT_AMP) {
1263 smux->items[smux->num_items].label = "Off";
1264 smux->items[smux->num_items].index = 0;
1265 smux->num_items++;
1266 spec->spdif_mute = 1;
1267 }
1268 stac_smux_mixer.count = spec->num_smuxes;
1269 err = snd_ctl_add(codec->bus->card,
1270 snd_ctl_new1(&stac_smux_mixer, codec));
1271 if (err < 0)
1272 return err;
1273 }
969 1274
970 if (spec->multiout.dig_out_nid) { 1275 if (spec->multiout.dig_out_nid) {
971 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid); 1276 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
@@ -977,7 +1282,7 @@ static int stac92xx_build_controls(struct hda_codec *codec)
977 return err; 1282 return err;
978 spec->multiout.share_spdif = 1; 1283 spec->multiout.share_spdif = 1;
979 } 1284 }
980 if (spec->dig_in_nid) { 1285 if (spec->dig_in_nid && (!spec->gpio_dir & 0x01)) {
981 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); 1286 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
982 if (err < 0) 1287 if (err < 0)
983 return err; 1288 return err;
@@ -1325,40 +1630,65 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = {
1325 {} /* terminator */ 1630 {} /* terminator */
1326}; 1631};
1327 1632
1328static unsigned int ref92hd71bxx_pin_configs[10] = { 1633static unsigned int ref92hd83xxx_pin_configs[14] = {
1634 0x02214030, 0x02211010, 0x02a19020, 0x02170130,
1635 0x01014050, 0x01819040, 0x01014020, 0x90a3014e,
1636 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x40f000f0,
1637 0x01451160, 0x98560170,
1638};
1639
1640static unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = {
1641 [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs,
1642};
1643
1644static const char *stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = {
1645 [STAC_92HD83XXX_REF] = "ref",
1646};
1647
1648static struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = {
1649 /* SigmaTel reference board */
1650 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1651 "DFI LanParty", STAC_92HD71BXX_REF),
1652};
1653
1654static unsigned int ref92hd71bxx_pin_configs[11] = {
1329 0x02214030, 0x02a19040, 0x01a19020, 0x01014010, 1655 0x02214030, 0x02a19040, 0x01a19020, 0x01014010,
1330 0x0181302e, 0x01114010, 0x01019020, 0x90a000f0, 1656 0x0181302e, 0x01014010, 0x01019020, 0x90a000f0,
1331 0x90a000f0, 0x01452050, 1657 0x90a000f0, 0x01452050, 0x01452050,
1332}; 1658};
1333 1659
1334static unsigned int dell_m4_1_pin_configs[10] = { 1660static unsigned int dell_m4_1_pin_configs[11] = {
1335 0x0421101f, 0x04a11221, 0x40f000f0, 0x90170110, 1661 0x0421101f, 0x04a11221, 0x40f000f0, 0x90170110,
1336 0x23a1902e, 0x23014250, 0x40f000f0, 0x90a000f0, 1662 0x23a1902e, 0x23014250, 0x40f000f0, 0x90a000f0,
1337 0x40f000f0, 0x4f0000f0, 1663 0x40f000f0, 0x4f0000f0, 0x4f0000f0,
1338}; 1664};
1339 1665
1340static unsigned int dell_m4_2_pin_configs[10] = { 1666static unsigned int dell_m4_2_pin_configs[11] = {
1341 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110, 1667 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110,
1342 0x23a1902e, 0x23014250, 0x40f000f0, 0x40f000f0, 1668 0x23a1902e, 0x23014250, 0x40f000f0, 0x40f000f0,
1343 0x40f000f0, 0x044413b0, 1669 0x40f000f0, 0x044413b0, 0x044413b0,
1344}; 1670};
1345 1671
1346static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = { 1672static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = {
1347 [STAC_92HD71BXX_REF] = ref92hd71bxx_pin_configs, 1673 [STAC_92HD71BXX_REF] = ref92hd71bxx_pin_configs,
1348 [STAC_DELL_M4_1] = dell_m4_1_pin_configs, 1674 [STAC_DELL_M4_1] = dell_m4_1_pin_configs,
1349 [STAC_DELL_M4_2] = dell_m4_2_pin_configs, 1675 [STAC_DELL_M4_2] = dell_m4_2_pin_configs,
1676 [STAC_HP_M4] = NULL,
1350}; 1677};
1351 1678
1352static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = { 1679static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = {
1353 [STAC_92HD71BXX_REF] = "ref", 1680 [STAC_92HD71BXX_REF] = "ref",
1354 [STAC_DELL_M4_1] = "dell-m4-1", 1681 [STAC_DELL_M4_1] = "dell-m4-1",
1355 [STAC_DELL_M4_2] = "dell-m4-2", 1682 [STAC_DELL_M4_2] = "dell-m4-2",
1683 [STAC_HP_M4] = "hp-m4",
1356}; 1684};
1357 1685
1358static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { 1686static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = {
1359 /* SigmaTel reference board */ 1687 /* SigmaTel reference board */
1360 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, 1688 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1361 "DFI LanParty", STAC_92HD71BXX_REF), 1689 "DFI LanParty", STAC_92HD71BXX_REF),
1690 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361a,
1691 "unknown HP", STAC_HP_M4),
1362 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233, 1692 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233,
1363 "unknown Dell", STAC_DELL_M4_1), 1693 "unknown Dell", STAC_DELL_M4_1),
1364 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0234, 1694 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0234,
@@ -1477,6 +1807,11 @@ static unsigned int intel_mac_v5_pin_configs[10] = {
1477 0x400000fc, 0x400000fb, 1807 0x400000fc, 0x400000fb,
1478}; 1808};
1479 1809
1810static unsigned int ecs202_pin_configs[10] = {
1811 0x0221401f, 0x02a19020, 0x01a19020, 0x01114010,
1812 0x408000f0, 0x01813022, 0x074510a0, 0x40c400f1,
1813 0x9037012e, 0x40e000f2,
1814};
1480 1815
1481static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = { 1816static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = {
1482 [STAC_D945_REF] = ref922x_pin_configs, 1817 [STAC_D945_REF] = ref922x_pin_configs,
@@ -1495,6 +1830,7 @@ static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = {
1495 [STAC_MACBOOK_PRO_V2] = intel_mac_v3_pin_configs, 1830 [STAC_MACBOOK_PRO_V2] = intel_mac_v3_pin_configs,
1496 [STAC_IMAC_INTEL] = intel_mac_v2_pin_configs, 1831 [STAC_IMAC_INTEL] = intel_mac_v2_pin_configs,
1497 [STAC_IMAC_INTEL_20] = intel_mac_v3_pin_configs, 1832 [STAC_IMAC_INTEL_20] = intel_mac_v3_pin_configs,
1833 [STAC_ECS_202] = ecs202_pin_configs,
1498 [STAC_922X_DELL_D81] = dell_922x_d81_pin_configs, 1834 [STAC_922X_DELL_D81] = dell_922x_d81_pin_configs,
1499 [STAC_922X_DELL_D82] = dell_922x_d82_pin_configs, 1835 [STAC_922X_DELL_D82] = dell_922x_d82_pin_configs,
1500 [STAC_922X_DELL_M81] = dell_922x_m81_pin_configs, 1836 [STAC_922X_DELL_M81] = dell_922x_m81_pin_configs,
@@ -1518,6 +1854,7 @@ static const char *stac922x_models[STAC_922X_MODELS] = {
1518 [STAC_MACBOOK_PRO_V2] = "macbook-pro", 1854 [STAC_MACBOOK_PRO_V2] = "macbook-pro",
1519 [STAC_IMAC_INTEL] = "imac-intel", 1855 [STAC_IMAC_INTEL] = "imac-intel",
1520 [STAC_IMAC_INTEL_20] = "imac-intel-20", 1856 [STAC_IMAC_INTEL_20] = "imac-intel-20",
1857 [STAC_ECS_202] = "ecs202",
1521 [STAC_922X_DELL_D81] = "dell-d81", 1858 [STAC_922X_DELL_D81] = "dell-d81",
1522 [STAC_922X_DELL_D82] = "dell-d82", 1859 [STAC_922X_DELL_D82] = "dell-d82",
1523 [STAC_922X_DELL_M81] = "dell-m81", 1860 [STAC_922X_DELL_M81] = "dell-m81",
@@ -1604,6 +1941,33 @@ static struct snd_pci_quirk stac922x_cfg_tbl[] = {
1604 "unknown Dell", STAC_922X_DELL_D81), 1941 "unknown Dell", STAC_922X_DELL_D81),
1605 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d7, 1942 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d7,
1606 "Dell XPS M1210", STAC_922X_DELL_M82), 1943 "Dell XPS M1210", STAC_922X_DELL_M82),
1944 /* ECS/PC Chips boards */
1945 SND_PCI_QUIRK(0x1019, 0x2144,
1946 "ECS/PC chips", STAC_ECS_202),
1947 SND_PCI_QUIRK(0x1019, 0x2608,
1948 "ECS/PC chips", STAC_ECS_202),
1949 SND_PCI_QUIRK(0x1019, 0x2633,
1950 "ECS/PC chips P17G/1333", STAC_ECS_202),
1951 SND_PCI_QUIRK(0x1019, 0x2811,
1952 "ECS/PC chips", STAC_ECS_202),
1953 SND_PCI_QUIRK(0x1019, 0x2812,
1954 "ECS/PC chips", STAC_ECS_202),
1955 SND_PCI_QUIRK(0x1019, 0x2813,
1956 "ECS/PC chips", STAC_ECS_202),
1957 SND_PCI_QUIRK(0x1019, 0x2814,
1958 "ECS/PC chips", STAC_ECS_202),
1959 SND_PCI_QUIRK(0x1019, 0x2815,
1960 "ECS/PC chips", STAC_ECS_202),
1961 SND_PCI_QUIRK(0x1019, 0x2816,
1962 "ECS/PC chips", STAC_ECS_202),
1963 SND_PCI_QUIRK(0x1019, 0x2817,
1964 "ECS/PC chips", STAC_ECS_202),
1965 SND_PCI_QUIRK(0x1019, 0x2818,
1966 "ECS/PC chips", STAC_ECS_202),
1967 SND_PCI_QUIRK(0x1019, 0x2819,
1968 "ECS/PC chips", STAC_ECS_202),
1969 SND_PCI_QUIRK(0x1019, 0x2820,
1970 "ECS/PC chips", STAC_ECS_202),
1607 {} /* terminator */ 1971 {} /* terminator */
1608}; 1972};
1609 1973
@@ -1683,8 +2047,8 @@ static struct snd_pci_quirk stac927x_cfg_tbl[] = {
1683 /* Dell 3 stack systems with verb table in BIOS */ 2047 /* Dell 3 stack systems with verb table in BIOS */
1684 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f3, "Dell Inspiron 1420", STAC_DELL_BIOS), 2048 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f3, "Dell Inspiron 1420", STAC_DELL_BIOS),
1685 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0227, "Dell Vostro 1400 ", STAC_DELL_BIOS), 2049 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0227, "Dell Vostro 1400 ", STAC_DELL_BIOS),
1686 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022f, "Dell ", STAC_DELL_BIOS),
1687 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022e, "Dell ", STAC_DELL_BIOS), 2050 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022e, "Dell ", STAC_DELL_BIOS),
2051 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022f, "Dell Inspiron 1525", STAC_DELL_3ST),
1688 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0242, "Dell ", STAC_DELL_BIOS), 2052 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0242, "Dell ", STAC_DELL_BIOS),
1689 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0243, "Dell ", STAC_DELL_BIOS), 2053 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0243, "Dell ", STAC_DELL_BIOS),
1690 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ff, "Dell ", STAC_DELL_BIOS), 2054 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ff, "Dell ", STAC_DELL_BIOS),
@@ -1867,6 +2231,8 @@ static int stac92xx_playback_pcm_open(struct hda_pcm_stream *hinfo,
1867 struct snd_pcm_substream *substream) 2231 struct snd_pcm_substream *substream)
1868{ 2232{
1869 struct sigmatel_spec *spec = codec->spec; 2233 struct sigmatel_spec *spec = codec->spec;
2234 if (spec->stream_delay)
2235 msleep(spec->stream_delay);
1870 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, 2236 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
1871 hinfo); 2237 hinfo);
1872} 2238}
@@ -1930,9 +2296,14 @@ static int stac92xx_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1930 struct snd_pcm_substream *substream) 2296 struct snd_pcm_substream *substream)
1931{ 2297{
1932 struct sigmatel_spec *spec = codec->spec; 2298 struct sigmatel_spec *spec = codec->spec;
2299 hda_nid_t nid = spec->adc_nids[substream->number];
1933 2300
1934 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 2301 if (spec->powerdown_adcs) {
1935 stream_tag, 0, format); 2302 msleep(40);
2303 snd_hda_codec_write_cache(codec, nid, 0,
2304 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
2305 }
2306 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
1936 return 0; 2307 return 0;
1937} 2308}
1938 2309
@@ -1941,8 +2312,12 @@ static int stac92xx_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1941 struct snd_pcm_substream *substream) 2312 struct snd_pcm_substream *substream)
1942{ 2313{
1943 struct sigmatel_spec *spec = codec->spec; 2314 struct sigmatel_spec *spec = codec->spec;
2315 hda_nid_t nid = spec->adc_nids[substream->number];
1944 2316
1945 snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]); 2317 snd_hda_codec_cleanup_stream(codec, nid);
2318 if (spec->powerdown_adcs)
2319 snd_hda_codec_write_cache(codec, nid, 0,
2320 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
1946 return 0; 2321 return 0;
1947} 2322}
1948 2323
@@ -2193,6 +2568,8 @@ enum {
2193 STAC_CTL_WIDGET_VOL, 2568 STAC_CTL_WIDGET_VOL,
2194 STAC_CTL_WIDGET_MUTE, 2569 STAC_CTL_WIDGET_MUTE,
2195 STAC_CTL_WIDGET_MONO_MUX, 2570 STAC_CTL_WIDGET_MONO_MUX,
2571 STAC_CTL_WIDGET_AMP_MUX,
2572 STAC_CTL_WIDGET_AMP_VOL,
2196 STAC_CTL_WIDGET_HP_SWITCH, 2573 STAC_CTL_WIDGET_HP_SWITCH,
2197 STAC_CTL_WIDGET_IO_SWITCH, 2574 STAC_CTL_WIDGET_IO_SWITCH,
2198 STAC_CTL_WIDGET_CLFE_SWITCH 2575 STAC_CTL_WIDGET_CLFE_SWITCH
@@ -2202,13 +2579,16 @@ static struct snd_kcontrol_new stac92xx_control_templates[] = {
2202 HDA_CODEC_VOLUME(NULL, 0, 0, 0), 2579 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
2203 HDA_CODEC_MUTE(NULL, 0, 0, 0), 2580 HDA_CODEC_MUTE(NULL, 0, 0, 0),
2204 STAC_MONO_MUX, 2581 STAC_MONO_MUX,
2582 STAC_AMP_MUX,
2583 STAC_AMP_VOL(NULL, 0, 0, 0, 0),
2205 STAC_CODEC_HP_SWITCH(NULL), 2584 STAC_CODEC_HP_SWITCH(NULL),
2206 STAC_CODEC_IO_SWITCH(NULL, 0), 2585 STAC_CODEC_IO_SWITCH(NULL, 0),
2207 STAC_CODEC_CLFE_SWITCH(NULL, 0), 2586 STAC_CODEC_CLFE_SWITCH(NULL, 0),
2208}; 2587};
2209 2588
2210/* add dynamic controls */ 2589/* add dynamic controls */
2211static int stac92xx_add_control(struct sigmatel_spec *spec, int type, const char *name, unsigned long val) 2590static int stac92xx_add_control_idx(struct sigmatel_spec *spec, int type,
2591 int idx, const char *name, unsigned long val)
2212{ 2592{
2213 struct snd_kcontrol_new *knew; 2593 struct snd_kcontrol_new *knew;
2214 2594
@@ -2228,6 +2608,7 @@ static int stac92xx_add_control(struct sigmatel_spec *spec, int type, const char
2228 2608
2229 knew = &spec->kctl_alloc[spec->num_kctl_used]; 2609 knew = &spec->kctl_alloc[spec->num_kctl_used];
2230 *knew = stac92xx_control_templates[type]; 2610 *knew = stac92xx_control_templates[type];
2611 knew->index = idx;
2231 knew->name = kstrdup(name, GFP_KERNEL); 2612 knew->name = kstrdup(name, GFP_KERNEL);
2232 if (! knew->name) 2613 if (! knew->name)
2233 return -ENOMEM; 2614 return -ENOMEM;
@@ -2236,6 +2617,14 @@ static int stac92xx_add_control(struct sigmatel_spec *spec, int type, const char
2236 return 0; 2617 return 0;
2237} 2618}
2238 2619
2620
2621/* add dynamic controls */
2622static int stac92xx_add_control(struct sigmatel_spec *spec, int type,
2623 const char *name, unsigned long val)
2624{
2625 return stac92xx_add_control_idx(spec, type, 0, name, val);
2626}
2627
2239/* flag inputs as additional dynamic lineouts */ 2628/* flag inputs as additional dynamic lineouts */
2240static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cfg *cfg) 2629static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cfg *cfg)
2241{ 2630{
@@ -2467,6 +2856,10 @@ static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec,
2467 } 2856 }
2468 } 2857 }
2469 2858
2859 if ((spec->multiout.num_dacs - cfg->line_outs) > 0 &&
2860 cfg->hp_outs && !spec->multiout.hp_nid)
2861 spec->multiout.hp_nid = nid;
2862
2470 if (cfg->hp_outs > 1) { 2863 if (cfg->hp_outs > 1) {
2471 err = stac92xx_add_control(spec, 2864 err = stac92xx_add_control(spec,
2472 STAC_CTL_WIDGET_HP_SWITCH, 2865 STAC_CTL_WIDGET_HP_SWITCH,
@@ -2579,8 +2972,8 @@ static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec,
2579} 2972}
2580 2973
2581/* labels for mono mux outputs */ 2974/* labels for mono mux outputs */
2582static const char *stac92xx_mono_labels[3] = { 2975static const char *stac92xx_mono_labels[4] = {
2583 "DAC0", "DAC1", "Mixer" 2976 "DAC0", "DAC1", "Mixer", "DAC2"
2584}; 2977};
2585 2978
2586/* create mono mux for mono out on capable codecs */ 2979/* create mono mux for mono out on capable codecs */
@@ -2609,6 +3002,116 @@ static int stac92xx_auto_create_mono_output_ctls(struct hda_codec *codec)
2609 "Mono Mux", spec->mono_nid); 3002 "Mono Mux", spec->mono_nid);
2610} 3003}
2611 3004
3005/* labels for amp mux outputs */
3006static const char *stac92xx_amp_labels[3] = {
3007 "Front Microphone", "Microphone", "Line In",
3008};
3009
3010/* create amp out controls mux on capable codecs */
3011static int stac92xx_auto_create_amp_output_ctls(struct hda_codec *codec)
3012{
3013 struct sigmatel_spec *spec = codec->spec;
3014 struct hda_input_mux *amp_mux = &spec->private_amp_mux;
3015 int i, err;
3016
3017 for (i = 0; i < spec->num_amps; i++) {
3018 amp_mux->items[amp_mux->num_items].label =
3019 stac92xx_amp_labels[i];
3020 amp_mux->items[amp_mux->num_items].index = i;
3021 amp_mux->num_items++;
3022 }
3023
3024 if (spec->num_amps > 1) {
3025 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_AMP_MUX,
3026 "Amp Selector Capture Switch", 0);
3027 if (err < 0)
3028 return err;
3029 }
3030 return stac92xx_add_control(spec, STAC_CTL_WIDGET_AMP_VOL,
3031 "Amp Capture Volume",
3032 HDA_COMPOSE_AMP_VAL(spec->amp_nids[0], 3, 0, HDA_INPUT));
3033}
3034
3035
3036/* create PC beep volume controls */
3037static int stac92xx_auto_create_beep_ctls(struct hda_codec *codec,
3038 hda_nid_t nid)
3039{
3040 struct sigmatel_spec *spec = codec->spec;
3041 u32 caps = query_amp_caps(codec, nid, HDA_OUTPUT);
3042 int err;
3043
3044 /* check for mute support for the the amp */
3045 if ((caps & AC_AMPCAP_MUTE) >> AC_AMPCAP_MUTE_SHIFT) {
3046 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE,
3047 "PC Beep Playback Switch",
3048 HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT));
3049 if (err < 0)
3050 return err;
3051 }
3052
3053 /* check to see if there is volume support for the amp */
3054 if ((caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT) {
3055 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL,
3056 "PC Beep Playback Volume",
3057 HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT));
3058 if (err < 0)
3059 return err;
3060 }
3061 return 0;
3062}
3063
3064static int stac92xx_auto_create_mux_input_ctls(struct hda_codec *codec)
3065{
3066 struct sigmatel_spec *spec = codec->spec;
3067 int wcaps, nid, i, err = 0;
3068
3069 for (i = 0; i < spec->num_muxes; i++) {
3070 nid = spec->mux_nids[i];
3071 wcaps = get_wcaps(codec, nid);
3072
3073 if (wcaps & AC_WCAP_OUT_AMP) {
3074 err = stac92xx_add_control_idx(spec,
3075 STAC_CTL_WIDGET_VOL, i, "Mux Capture Volume",
3076 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3077 if (err < 0)
3078 return err;
3079 }
3080 }
3081 return 0;
3082};
3083
3084static const char *stac92xx_spdif_labels[3] = {
3085 "Digital Playback", "Analog Mux 1", "Analog Mux 2",
3086};
3087
3088static int stac92xx_auto_create_spdif_mux_ctls(struct hda_codec *codec)
3089{
3090 struct sigmatel_spec *spec = codec->spec;
3091 struct hda_input_mux *spdif_mux = &spec->private_smux;
3092 const char **labels = spec->spdif_labels;
3093 int i, num_cons;
3094 hda_nid_t con_lst[HDA_MAX_NUM_INPUTS];
3095
3096 num_cons = snd_hda_get_connections(codec,
3097 spec->smux_nids[0],
3098 con_lst,
3099 HDA_MAX_NUM_INPUTS);
3100 if (!num_cons)
3101 return -EINVAL;
3102
3103 if (!labels)
3104 labels = stac92xx_spdif_labels;
3105
3106 for (i = 0; i < num_cons; i++) {
3107 spdif_mux->items[spdif_mux->num_items].label = labels[i];
3108 spdif_mux->items[spdif_mux->num_items].index = i;
3109 spdif_mux->num_items++;
3110 }
3111
3112 return 0;
3113}
3114
2612/* labels for dmic mux inputs */ 3115/* labels for dmic mux inputs */
2613static const char *stac92xx_dmic_labels[5] = { 3116static const char *stac92xx_dmic_labels[5] = {
2614 "Analog Inputs", "Digital Mic 1", "Digital Mic 2", 3117 "Analog Inputs", "Digital Mic 1", "Digital Mic 2",
@@ -2656,16 +3159,19 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
2656 } 3159 }
2657 continue; 3160 continue;
2658found: 3161found:
2659 wcaps = get_wcaps(codec, nid); 3162 wcaps = get_wcaps(codec, nid) &
3163 (AC_WCAP_OUT_AMP | AC_WCAP_IN_AMP);
2660 3164
2661 if (wcaps & AC_WCAP_OUT_AMP) { 3165 if (wcaps) {
2662 sprintf(name, "%s Capture Volume", 3166 sprintf(name, "%s Capture Volume",
2663 stac92xx_dmic_labels[dimux->num_items]); 3167 stac92xx_dmic_labels[dimux->num_items]);
2664 3168
2665 err = stac92xx_add_control(spec, 3169 err = stac92xx_add_control(spec,
2666 STAC_CTL_WIDGET_VOL, 3170 STAC_CTL_WIDGET_VOL,
2667 name, 3171 name,
2668 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); 3172 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3173 (wcaps & AC_WCAP_OUT_AMP) ?
3174 HDA_OUTPUT : HDA_INPUT));
2669 if (err < 0) 3175 if (err < 0)
2670 return err; 3176 return err;
2671 } 3177 }
@@ -2789,8 +3295,8 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
2789 hp_speaker_swap = 1; 3295 hp_speaker_swap = 1;
2790 } 3296 }
2791 if (spec->autocfg.mono_out_pin) { 3297 if (spec->autocfg.mono_out_pin) {
2792 int dir = (get_wcaps(codec, spec->autocfg.mono_out_pin) 3298 int dir = get_wcaps(codec, spec->autocfg.mono_out_pin) &
2793 & AC_WCAP_OUT_AMP) ? HDA_OUTPUT : HDA_INPUT; 3299 (AC_WCAP_OUT_AMP | AC_WCAP_IN_AMP);
2794 u32 caps = query_amp_caps(codec, 3300 u32 caps = query_amp_caps(codec,
2795 spec->autocfg.mono_out_pin, dir); 3301 spec->autocfg.mono_out_pin, dir);
2796 hda_nid_t conn_list[1]; 3302 hda_nid_t conn_list[1];
@@ -2812,21 +3318,26 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
2812 !(wcaps & AC_WCAP_LR_SWAP)) 3318 !(wcaps & AC_WCAP_LR_SWAP))
2813 spec->mono_nid = conn_list[0]; 3319 spec->mono_nid = conn_list[0];
2814 } 3320 }
2815 /* all mono outs have a least a mute/unmute switch */ 3321 if (dir) {
2816 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, 3322 hda_nid_t nid = spec->autocfg.mono_out_pin;
2817 "Mono Playback Switch", 3323
2818 HDA_COMPOSE_AMP_VAL(spec->autocfg.mono_out_pin, 3324 /* most mono outs have a least a mute/unmute switch */
2819 1, 0, dir)); 3325 dir = (dir & AC_WCAP_OUT_AMP) ? HDA_OUTPUT : HDA_INPUT;
2820 if (err < 0) 3326 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE,
2821 return err; 3327 "Mono Playback Switch",
2822 /* check to see if there is volume support for the amp */ 3328 HDA_COMPOSE_AMP_VAL(nid, 1, 0, dir));
2823 if ((caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT) {
2824 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL,
2825 "Mono Playback Volume",
2826 HDA_COMPOSE_AMP_VAL(spec->autocfg.mono_out_pin,
2827 1, 0, dir));
2828 if (err < 0) 3329 if (err < 0)
2829 return err; 3330 return err;
3331 /* check for volume support for the amp */
3332 if ((caps & AC_AMPCAP_NUM_STEPS)
3333 >> AC_AMPCAP_NUM_STEPS_SHIFT) {
3334 err = stac92xx_add_control(spec,
3335 STAC_CTL_WIDGET_VOL,
3336 "Mono Playback Volume",
3337 HDA_COMPOSE_AMP_VAL(nid, 1, 0, dir));
3338 if (err < 0)
3339 return err;
3340 }
2830 } 3341 }
2831 3342
2832 stac92xx_auto_set_pinctl(codec, spec->autocfg.mono_out_pin, 3343 stac92xx_auto_set_pinctl(codec, spec->autocfg.mono_out_pin,
@@ -2844,6 +3355,28 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
2844 if (err < 0) 3355 if (err < 0)
2845 return err; 3356 return err;
2846 3357
3358 /* setup analog beep controls */
3359 if (spec->anabeep_nid > 0) {
3360 err = stac92xx_auto_create_beep_ctls(codec,
3361 spec->anabeep_nid);
3362 if (err < 0)
3363 return err;
3364 }
3365
3366 /* setup digital beep controls and input device */
3367#ifdef CONFIG_SND_HDA_INPUT_BEEP
3368 if (spec->digbeep_nid > 0) {
3369 hda_nid_t nid = spec->digbeep_nid;
3370
3371 err = stac92xx_auto_create_beep_ctls(codec, nid);
3372 if (err < 0)
3373 return err;
3374 err = snd_hda_attach_beep_device(codec, nid);
3375 if (err < 0)
3376 return err;
3377 }
3378#endif
3379
2847 if (hp_speaker_swap == 1) { 3380 if (hp_speaker_swap == 1) {
2848 /* Restore the hp_outs and line_outs */ 3381 /* Restore the hp_outs and line_outs */
2849 memcpy(spec->autocfg.hp_pins, spec->autocfg.line_out_pins, 3382 memcpy(spec->autocfg.hp_pins, spec->autocfg.line_out_pins,
@@ -2872,11 +3405,25 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
2872 if (err < 0) 3405 if (err < 0)
2873 return err; 3406 return err;
2874 } 3407 }
2875 3408 if (spec->num_amps > 0) {
2876 if (spec->num_dmics > 0) 3409 err = stac92xx_auto_create_amp_output_ctls(codec);
3410 if (err < 0)
3411 return err;
3412 }
3413 if (spec->num_dmics > 0 && !spec->dinput_mux)
2877 if ((err = stac92xx_auto_create_dmic_input_ctls(codec, 3414 if ((err = stac92xx_auto_create_dmic_input_ctls(codec,
2878 &spec->autocfg)) < 0) 3415 &spec->autocfg)) < 0)
2879 return err; 3416 return err;
3417 if (spec->num_muxes > 0) {
3418 err = stac92xx_auto_create_mux_input_ctls(codec);
3419 if (err < 0)
3420 return err;
3421 }
3422 if (spec->num_smuxes > 0) {
3423 err = stac92xx_auto_create_spdif_mux_ctls(codec);
3424 if (err < 0)
3425 return err;
3426 }
2880 3427
2881 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 3428 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
2882 if (spec->multiout.max_channels > 2) 3429 if (spec->multiout.max_channels > 2)
@@ -2884,17 +3431,17 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
2884 3431
2885 if (spec->autocfg.dig_out_pin) 3432 if (spec->autocfg.dig_out_pin)
2886 spec->multiout.dig_out_nid = dig_out; 3433 spec->multiout.dig_out_nid = dig_out;
2887 if (spec->autocfg.dig_in_pin) 3434 if (dig_in && spec->autocfg.dig_in_pin)
2888 spec->dig_in_nid = dig_in; 3435 spec->dig_in_nid = dig_in;
2889 3436
2890 if (spec->kctl_alloc) 3437 if (spec->kctl_alloc)
2891 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 3438 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
2892 3439
2893 spec->input_mux = &spec->private_imux; 3440 spec->input_mux = &spec->private_imux;
2894 if (!spec->dinput_mux) 3441 spec->dinput_mux = &spec->private_dimux;
2895 spec->dinput_mux = &spec->private_dimux; 3442 spec->sinput_mux = &spec->private_smux;
2896 spec->mono_mux = &spec->private_mono_mux; 3443 spec->mono_mux = &spec->private_mono_mux;
2897 3444 spec->amp_mux = &spec->private_amp_mux;
2898 return 1; 3445 return 1;
2899} 3446}
2900 3447
@@ -3074,6 +3621,12 @@ static int stac92xx_init(struct hda_codec *codec)
3074 3621
3075 snd_hda_sequence_write(codec, spec->init); 3622 snd_hda_sequence_write(codec, spec->init);
3076 3623
3624 /* power down adcs initially */
3625 if (spec->powerdown_adcs)
3626 for (i = 0; i < spec->num_adcs; i++)
3627 snd_hda_codec_write_cache(codec,
3628 spec->adc_nids[i], 0,
3629 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
3077 /* set up pins */ 3630 /* set up pins */
3078 if (spec->hp_detect) { 3631 if (spec->hp_detect) {
3079 /* Enable unsolicited responses on the HP widget */ 3632 /* Enable unsolicited responses on the HP widget */
@@ -3095,7 +3648,12 @@ static int stac92xx_init(struct hda_codec *codec)
3095 for (i = 0; i < AUTO_PIN_LAST; i++) { 3648 for (i = 0; i < AUTO_PIN_LAST; i++) {
3096 hda_nid_t nid = cfg->input_pins[i]; 3649 hda_nid_t nid = cfg->input_pins[i];
3097 if (nid) { 3650 if (nid) {
3098 unsigned int pinctl = AC_PINCTL_IN_EN; 3651 unsigned int pinctl = snd_hda_codec_read(codec, nid,
3652 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3653 /* if PINCTL already set then skip */
3654 if (pinctl & AC_PINCAP_IN)
3655 continue;
3656 pinctl = AC_PINCTL_IN_EN;
3099 if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC) 3657 if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC)
3100 pinctl |= stac92xx_get_vref(codec, nid); 3658 pinctl |= stac92xx_get_vref(codec, nid);
3101 stac92xx_auto_set_pinctl(codec, nid, pinctl); 3659 stac92xx_auto_set_pinctl(codec, nid, pinctl);
@@ -3158,6 +3716,7 @@ static void stac92xx_free(struct hda_codec *codec)
3158 kfree(spec->bios_pin_configs); 3716 kfree(spec->bios_pin_configs);
3159 3717
3160 kfree(spec); 3718 kfree(spec);
3719 snd_hda_detach_beep_device(codec);
3161} 3720}
3162 3721
3163static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid, 3722static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid,
@@ -3279,7 +3838,12 @@ static void stac92xx_pin_sense(struct hda_codec *codec, int idx)
3279 val = snd_hda_codec_read(codec, codec->afg, 0, 0x0fec, 0x0) 3838 val = snd_hda_codec_read(codec, codec->afg, 0, 0x0fec, 0x0)
3280 & 0x000000ff; 3839 & 0x000000ff;
3281 presence = get_hp_pin_presence(codec, nid); 3840 presence = get_hp_pin_presence(codec, nid);
3282 idx = 1 << idx; 3841
3842 /* several codecs have two power down bits */
3843 if (spec->pwr_mapping)
3844 idx = spec->pwr_mapping[idx];
3845 else
3846 idx = 1 << idx;
3283 3847
3284 if (presence) 3848 if (presence)
3285 val &= ~idx; 3849 val &= ~idx;
@@ -3295,13 +3859,22 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
3295 struct sigmatel_spec *spec = codec->spec; 3859 struct sigmatel_spec *spec = codec->spec;
3296 int idx = res >> 26 & 0x0f; 3860 int idx = res >> 26 & 0x0f;
3297 3861
3298 switch ((res >> 26) & 0x30) { 3862 switch ((res >> 26) & 0x70) {
3299 case STAC_HP_EVENT: 3863 case STAC_HP_EVENT:
3300 stac92xx_hp_detect(codec, res); 3864 stac92xx_hp_detect(codec, res);
3301 /* fallthru */ 3865 /* fallthru */
3302 case STAC_PWR_EVENT: 3866 case STAC_PWR_EVENT:
3303 if (spec->num_pwrs > 0) 3867 if (spec->num_pwrs > 0)
3304 stac92xx_pin_sense(codec, idx); 3868 stac92xx_pin_sense(codec, idx);
3869 break;
3870 case STAC_VREF_EVENT: {
3871 int data = snd_hda_codec_read(codec, codec->afg, 0,
3872 AC_VERB_GET_GPIO_DATA, 0);
3873 /* toggle VREF state based on GPIOx status */
3874 snd_hda_codec_write(codec, codec->afg, 0, 0x7e0,
3875 !!(data & (1 << idx)));
3876 break;
3877 }
3305 } 3878 }
3306} 3879}
3307 3880
@@ -3478,9 +4051,9 @@ static struct hda_input_mux stac92hd73xx_dmux = {
3478 .num_items = 4, 4051 .num_items = 4,
3479 .items = { 4052 .items = {
3480 { "Analog Inputs", 0x0b }, 4053 { "Analog Inputs", 0x0b },
3481 { "CD", 0x08 },
3482 { "Digital Mic 1", 0x09 }, 4054 { "Digital Mic 1", 0x09 },
3483 { "Digital Mic 2", 0x0a }, 4055 { "Digital Mic 2", 0x0a },
4056 { "CD", 0x08 },
3484 } 4057 }
3485}; 4058};
3486 4059
@@ -3495,6 +4068,7 @@ static int patch_stac92hd73xx(struct hda_codec *codec)
3495 return -ENOMEM; 4068 return -ENOMEM;
3496 4069
3497 codec->spec = spec; 4070 codec->spec = spec;
4071 codec->slave_dig_outs = stac92hd73xx_slave_dig_outs;
3498 spec->num_pins = ARRAY_SIZE(stac92hd73xx_pin_nids); 4072 spec->num_pins = ARRAY_SIZE(stac92hd73xx_pin_nids);
3499 spec->pin_nids = stac92hd73xx_pin_nids; 4073 spec->pin_nids = stac92hd73xx_pin_nids;
3500 spec->board_config = snd_hda_check_board_config(codec, 4074 spec->board_config = snd_hda_check_board_config(codec,
@@ -3527,17 +4101,14 @@ again:
3527 4101
3528 switch (spec->multiout.num_dacs) { 4102 switch (spec->multiout.num_dacs) {
3529 case 0x3: /* 6 Channel */ 4103 case 0x3: /* 6 Channel */
3530 spec->multiout.hp_nid = 0x17;
3531 spec->mixer = stac92hd73xx_6ch_mixer; 4104 spec->mixer = stac92hd73xx_6ch_mixer;
3532 spec->init = stac92hd73xx_6ch_core_init; 4105 spec->init = stac92hd73xx_6ch_core_init;
3533 break; 4106 break;
3534 case 0x4: /* 8 Channel */ 4107 case 0x4: /* 8 Channel */
3535 spec->multiout.hp_nid = 0x18;
3536 spec->mixer = stac92hd73xx_8ch_mixer; 4108 spec->mixer = stac92hd73xx_8ch_mixer;
3537 spec->init = stac92hd73xx_8ch_core_init; 4109 spec->init = stac92hd73xx_8ch_core_init;
3538 break; 4110 break;
3539 case 0x5: /* 10 Channel */ 4111 case 0x5: /* 10 Channel */
3540 spec->multiout.hp_nid = 0x19;
3541 spec->mixer = stac92hd73xx_10ch_mixer; 4112 spec->mixer = stac92hd73xx_10ch_mixer;
3542 spec->init = stac92hd73xx_10ch_core_init; 4113 spec->init = stac92hd73xx_10ch_core_init;
3543 }; 4114 };
@@ -3546,27 +4117,34 @@ again:
3546 spec->aloopback_mask = 0x01; 4117 spec->aloopback_mask = 0x01;
3547 spec->aloopback_shift = 8; 4118 spec->aloopback_shift = 8;
3548 4119
4120 spec->digbeep_nid = 0x1c;
3549 spec->mux_nids = stac92hd73xx_mux_nids; 4121 spec->mux_nids = stac92hd73xx_mux_nids;
3550 spec->adc_nids = stac92hd73xx_adc_nids; 4122 spec->adc_nids = stac92hd73xx_adc_nids;
3551 spec->dmic_nids = stac92hd73xx_dmic_nids; 4123 spec->dmic_nids = stac92hd73xx_dmic_nids;
3552 spec->dmux_nids = stac92hd73xx_dmux_nids; 4124 spec->dmux_nids = stac92hd73xx_dmux_nids;
4125 spec->smux_nids = stac92hd73xx_smux_nids;
4126 spec->amp_nids = stac92hd73xx_amp_nids;
4127 spec->num_amps = ARRAY_SIZE(stac92hd73xx_amp_nids);
3553 4128
3554 spec->num_muxes = ARRAY_SIZE(stac92hd73xx_mux_nids); 4129 spec->num_muxes = ARRAY_SIZE(stac92hd73xx_mux_nids);
3555 spec->num_adcs = ARRAY_SIZE(stac92hd73xx_adc_nids); 4130 spec->num_adcs = ARRAY_SIZE(stac92hd73xx_adc_nids);
3556 spec->num_dmuxes = ARRAY_SIZE(stac92hd73xx_dmux_nids); 4131 spec->num_dmuxes = ARRAY_SIZE(stac92hd73xx_dmux_nids);
3557 spec->dinput_mux = &stac92hd73xx_dmux; 4132 memcpy(&spec->private_dimux, &stac92hd73xx_dmux,
3558 /* GPIO0 High = Enable EAPD */ 4133 sizeof(stac92hd73xx_dmux));
3559 spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1;
3560 spec->gpio_data = 0x01;
3561 4134
3562 switch (spec->board_config) { 4135 switch (spec->board_config) {
3563 case STAC_DELL_M6: 4136 case STAC_DELL_M6:
3564 spec->init = dell_eq_core_init; 4137 spec->init = dell_eq_core_init;
4138 spec->num_smuxes = 0;
4139 spec->mixer = &stac92hd73xx_6ch_mixer[DELL_M6_MIXER];
4140 spec->amp_nids = &stac92hd73xx_amp_nids[DELL_M6_AMP];
4141 spec->num_amps = 1;
3565 switch (codec->subsystem_id) { 4142 switch (codec->subsystem_id) {
3566 case 0x1028025e: /* Analog Mics */ 4143 case 0x1028025e: /* Analog Mics */
3567 case 0x1028025f: 4144 case 0x1028025f:
3568 stac92xx_set_config_reg(codec, 0x0b, 0x90A70170); 4145 stac92xx_set_config_reg(codec, 0x0b, 0x90A70170);
3569 spec->num_dmics = 0; 4146 spec->num_dmics = 0;
4147 spec->private_dimux.num_items = 1;
3570 break; 4148 break;
3571 case 0x10280271: /* Digital Mics */ 4149 case 0x10280271: /* Digital Mics */
3572 case 0x10280272: 4150 case 0x10280272:
@@ -3576,23 +4154,32 @@ again:
3576 case 0x10280255: 4154 case 0x10280255:
3577 stac92xx_set_config_reg(codec, 0x13, 0x90A60160); 4155 stac92xx_set_config_reg(codec, 0x13, 0x90A60160);
3578 spec->num_dmics = 1; 4156 spec->num_dmics = 1;
4157 spec->private_dimux.num_items = 2;
3579 break; 4158 break;
3580 case 0x10280256: /* Both */ 4159 case 0x10280256: /* Both */
3581 case 0x10280057: 4160 case 0x10280057:
3582 stac92xx_set_config_reg(codec, 0x0b, 0x90A70170); 4161 stac92xx_set_config_reg(codec, 0x0b, 0x90A70170);
3583 stac92xx_set_config_reg(codec, 0x13, 0x90A60160); 4162 stac92xx_set_config_reg(codec, 0x13, 0x90A60160);
3584 spec->num_dmics = 1; 4163 spec->num_dmics = 1;
4164 spec->private_dimux.num_items = 2;
3585 break; 4165 break;
3586 } 4166 }
3587 break; 4167 break;
3588 default: 4168 default:
3589 spec->num_dmics = STAC92HD73XX_NUM_DMICS; 4169 spec->num_dmics = STAC92HD73XX_NUM_DMICS;
4170 spec->num_smuxes = ARRAY_SIZE(stac92hd73xx_smux_nids);
3590 } 4171 }
4172 if (spec->board_config > STAC_92HD73XX_REF) {
4173 /* GPIO0 High = Enable EAPD */
4174 spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1;
4175 spec->gpio_data = 0x01;
4176 }
4177 spec->dinput_mux = &spec->private_dimux;
3591 4178
3592 spec->num_pwrs = ARRAY_SIZE(stac92hd73xx_pwr_nids); 4179 spec->num_pwrs = ARRAY_SIZE(stac92hd73xx_pwr_nids);
3593 spec->pwr_nids = stac92hd73xx_pwr_nids; 4180 spec->pwr_nids = stac92hd73xx_pwr_nids;
3594 4181
3595 err = stac92xx_parse_auto_config(codec, 0x22, 0x24); 4182 err = stac92xx_parse_auto_config(codec, 0x25, 0x27);
3596 4183
3597 if (!err) { 4184 if (!err) {
3598 if (spec->board_config < 0) { 4185 if (spec->board_config < 0) {
@@ -3614,6 +4201,146 @@ again:
3614 return 0; 4201 return 0;
3615} 4202}
3616 4203
4204static struct hda_input_mux stac92hd83xxx_dmux = {
4205 .num_items = 3,
4206 .items = {
4207 { "Analog Inputs", 0x03 },
4208 { "Digital Mic 1", 0x04 },
4209 { "Digital Mic 2", 0x05 },
4210 }
4211};
4212
4213static int patch_stac92hd83xxx(struct hda_codec *codec)
4214{
4215 struct sigmatel_spec *spec;
4216 int err;
4217
4218 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4219 if (spec == NULL)
4220 return -ENOMEM;
4221
4222 codec->spec = spec;
4223 codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs;
4224 spec->mono_nid = 0x19;
4225 spec->digbeep_nid = 0x21;
4226 spec->dmic_nids = stac92hd83xxx_dmic_nids;
4227 spec->dmux_nids = stac92hd83xxx_dmux_nids;
4228 spec->adc_nids = stac92hd83xxx_adc_nids;
4229 spec->pwr_nids = stac92hd83xxx_pwr_nids;
4230 spec->pwr_mapping = stac92hd83xxx_pwr_mapping;
4231 spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids);
4232 spec->multiout.dac_nids = stac92hd83xxx_dac_nids;
4233
4234 spec->init = stac92hd83xxx_core_init;
4235 switch (codec->vendor_id) {
4236 case 0x111d7605:
4237 spec->multiout.num_dacs = STAC92HD81_DAC_COUNT;
4238 break;
4239 default:
4240 spec->num_pwrs--;
4241 spec->init++; /* switch to config #2 */
4242 spec->multiout.num_dacs = STAC92HD83_DAC_COUNT;
4243 }
4244
4245 spec->mixer = stac92hd83xxx_mixer;
4246 spec->num_pins = ARRAY_SIZE(stac92hd83xxx_pin_nids);
4247 spec->num_dmuxes = ARRAY_SIZE(stac92hd83xxx_dmux_nids);
4248 spec->num_adcs = ARRAY_SIZE(stac92hd83xxx_adc_nids);
4249 spec->num_dmics = STAC92HD83XXX_NUM_DMICS;
4250 spec->dinput_mux = &stac92hd83xxx_dmux;
4251 spec->pin_nids = stac92hd83xxx_pin_nids;
4252 spec->board_config = snd_hda_check_board_config(codec,
4253 STAC_92HD83XXX_MODELS,
4254 stac92hd83xxx_models,
4255 stac92hd83xxx_cfg_tbl);
4256again:
4257 if (spec->board_config < 0) {
4258 snd_printdd(KERN_INFO "hda_codec: Unknown model for"
4259 " STAC92HD83XXX, using BIOS defaults\n");
4260 err = stac92xx_save_bios_config_regs(codec);
4261 if (err < 0) {
4262 stac92xx_free(codec);
4263 return err;
4264 }
4265 spec->pin_configs = spec->bios_pin_configs;
4266 } else {
4267 spec->pin_configs = stac92hd83xxx_brd_tbl[spec->board_config];
4268 stac92xx_set_config_regs(codec);
4269 }
4270
4271 err = stac92xx_parse_auto_config(codec, 0x1d, 0);
4272 if (!err) {
4273 if (spec->board_config < 0) {
4274 printk(KERN_WARNING "hda_codec: No auto-config is "
4275 "available, default to model=ref\n");
4276 spec->board_config = STAC_92HD83XXX_REF;
4277 goto again;
4278 }
4279 err = -EINVAL;
4280 }
4281
4282 if (err < 0) {
4283 stac92xx_free(codec);
4284 return err;
4285 }
4286
4287 codec->patch_ops = stac92xx_patch_ops;
4288
4289 return 0;
4290}
4291
4292#ifdef SND_HDA_NEEDS_RESUME
4293static void stac92hd71xx_set_power_state(struct hda_codec *codec, int pwr)
4294{
4295 struct sigmatel_spec *spec = codec->spec;
4296 int i;
4297 snd_hda_codec_write_cache(codec, codec->afg, 0,
4298 AC_VERB_SET_POWER_STATE, pwr);
4299
4300 msleep(1);
4301 for (i = 0; i < spec->num_adcs; i++) {
4302 snd_hda_codec_write_cache(codec,
4303 spec->adc_nids[i], 0,
4304 AC_VERB_SET_POWER_STATE, pwr);
4305 }
4306};
4307
4308static int stac92hd71xx_resume(struct hda_codec *codec)
4309{
4310 stac92hd71xx_set_power_state(codec, AC_PWRST_D0);
4311 return stac92xx_resume(codec);
4312}
4313
4314static int stac92hd71xx_suspend(struct hda_codec *codec, pm_message_t state)
4315{
4316 stac92hd71xx_set_power_state(codec, AC_PWRST_D3);
4317 return 0;
4318};
4319
4320#endif
4321
4322static struct hda_codec_ops stac92hd71bxx_patch_ops = {
4323 .build_controls = stac92xx_build_controls,
4324 .build_pcms = stac92xx_build_pcms,
4325 .init = stac92xx_init,
4326 .free = stac92xx_free,
4327 .unsol_event = stac92xx_unsol_event,
4328#ifdef SND_HDA_NEEDS_RESUME
4329 .resume = stac92hd71xx_resume,
4330 .suspend = stac92hd71xx_suspend,
4331#endif
4332};
4333
4334static struct hda_input_mux stac92hd71bxx_dmux = {
4335 .num_items = 4,
4336 .items = {
4337 { "Analog Inputs", 0x00 },
4338 { "Mixer", 0x01 },
4339 { "Digital Mic 1", 0x02 },
4340 { "Digital Mic 2", 0x03 },
4341 }
4342};
4343
3617static int patch_stac92hd71bxx(struct hda_codec *codec) 4344static int patch_stac92hd71bxx(struct hda_codec *codec)
3618{ 4345{
3619 struct sigmatel_spec *spec; 4346 struct sigmatel_spec *spec;
@@ -3624,9 +4351,12 @@ static int patch_stac92hd71bxx(struct hda_codec *codec)
3624 return -ENOMEM; 4351 return -ENOMEM;
3625 4352
3626 codec->spec = spec; 4353 codec->spec = spec;
4354 codec->patch_ops = stac92xx_patch_ops;
3627 spec->num_pins = ARRAY_SIZE(stac92hd71bxx_pin_nids); 4355 spec->num_pins = ARRAY_SIZE(stac92hd71bxx_pin_nids);
3628 spec->num_pwrs = ARRAY_SIZE(stac92hd71bxx_pwr_nids); 4356 spec->num_pwrs = ARRAY_SIZE(stac92hd71bxx_pwr_nids);
3629 spec->pin_nids = stac92hd71bxx_pin_nids; 4357 spec->pin_nids = stac92hd71bxx_pin_nids;
4358 memcpy(&spec->private_dimux, &stac92hd71bxx_dmux,
4359 sizeof(stac92hd71bxx_dmux));
3630 spec->board_config = snd_hda_check_board_config(codec, 4360 spec->board_config = snd_hda_check_board_config(codec,
3631 STAC_92HD71BXX_MODELS, 4361 STAC_92HD71BXX_MODELS,
3632 stac92hd71bxx_models, 4362 stac92hd71bxx_models,
@@ -3653,47 +4383,101 @@ again:
3653 case 0x111d76b5: 4383 case 0x111d76b5:
3654 spec->mixer = stac92hd71bxx_mixer; 4384 spec->mixer = stac92hd71bxx_mixer;
3655 spec->init = stac92hd71bxx_core_init; 4385 spec->init = stac92hd71bxx_core_init;
4386 codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs;
3656 break; 4387 break;
3657 case 0x111d7608: /* 5 Port with Analog Mixer */ 4388 case 0x111d7608: /* 5 Port with Analog Mixer */
4389 switch (codec->subsystem_id) {
4390 case 0x103c361a:
4391 /* Enable VREF power saving on GPIO1 detect */
4392 snd_hda_codec_write(codec, codec->afg, 0,
4393 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x02);
4394 snd_hda_codec_write_cache(codec, codec->afg, 0,
4395 AC_VERB_SET_UNSOLICITED_ENABLE,
4396 (AC_USRSP_EN | STAC_VREF_EVENT | 0x01));
4397 spec->gpio_mask |= 0x02;
4398 break;
4399 }
4400 if ((codec->revision_id & 0xf) == 0 ||
4401 (codec->revision_id & 0xf) == 1) {
4402#ifdef SND_HDA_NEEDS_RESUME
4403 codec->patch_ops = stac92hd71bxx_patch_ops;
4404#endif
4405 spec->stream_delay = 40; /* 40 milliseconds */
4406 }
4407
3658 /* no output amps */ 4408 /* no output amps */
3659 spec->num_pwrs = 0; 4409 spec->num_pwrs = 0;
3660 spec->mixer = stac92hd71bxx_analog_mixer; 4410 spec->mixer = stac92hd71bxx_analog_mixer;
4411 spec->dinput_mux = &spec->private_dimux;
3661 4412
3662 /* disable VSW */ 4413 /* disable VSW */
3663 spec->init = &stac92hd71bxx_analog_core_init[HD_DISABLE_PORTF]; 4414 spec->init = &stac92hd71bxx_analog_core_init[HD_DISABLE_PORTF];
3664 stac92xx_set_config_reg(codec, 0xf, 0x40f000f0); 4415 stac92xx_set_config_reg(codec, 0xf, 0x40f000f0);
3665 break; 4416 break;
3666 case 0x111d7603: /* 6 Port with Analog Mixer */ 4417 case 0x111d7603: /* 6 Port with Analog Mixer */
4418 if ((codec->revision_id & 0xf) == 1) {
4419#ifdef SND_HDA_NEEDS_RESUME
4420 codec->patch_ops = stac92hd71bxx_patch_ops;
4421#endif
4422 spec->stream_delay = 40; /* 40 milliseconds */
4423 }
4424
3667 /* no output amps */ 4425 /* no output amps */
3668 spec->num_pwrs = 0; 4426 spec->num_pwrs = 0;
3669 /* fallthru */ 4427 /* fallthru */
3670 default: 4428 default:
4429 spec->dinput_mux = &spec->private_dimux;
3671 spec->mixer = stac92hd71bxx_analog_mixer; 4430 spec->mixer = stac92hd71bxx_analog_mixer;
3672 spec->init = stac92hd71bxx_analog_core_init; 4431 spec->init = stac92hd71bxx_analog_core_init;
4432 codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs;
3673 } 4433 }
3674 4434
3675 spec->aloopback_mask = 0x20; 4435 spec->aloopback_mask = 0x50;
3676 spec->aloopback_shift = 0; 4436 spec->aloopback_shift = 0;
3677 4437
3678 /* GPIO0 High = EAPD */ 4438 if (spec->board_config > STAC_92HD71BXX_REF) {
3679 spec->gpio_mask = 0x01; 4439 /* GPIO0 = EAPD */
3680 spec->gpio_dir = 0x01; 4440 spec->gpio_mask = 0x01;
3681 spec->gpio_data = 0x01; 4441 spec->gpio_dir = 0x01;
4442 spec->gpio_data = 0x01;
4443 }
3682 4444
4445 spec->powerdown_adcs = 1;
4446 spec->digbeep_nid = 0x26;
3683 spec->mux_nids = stac92hd71bxx_mux_nids; 4447 spec->mux_nids = stac92hd71bxx_mux_nids;
3684 spec->adc_nids = stac92hd71bxx_adc_nids; 4448 spec->adc_nids = stac92hd71bxx_adc_nids;
3685 spec->dmic_nids = stac92hd71bxx_dmic_nids; 4449 spec->dmic_nids = stac92hd71bxx_dmic_nids;
3686 spec->dmux_nids = stac92hd71bxx_dmux_nids; 4450 spec->dmux_nids = stac92hd71bxx_dmux_nids;
4451 spec->smux_nids = stac92hd71bxx_smux_nids;
3687 spec->pwr_nids = stac92hd71bxx_pwr_nids; 4452 spec->pwr_nids = stac92hd71bxx_pwr_nids;
3688 4453
3689 spec->num_muxes = ARRAY_SIZE(stac92hd71bxx_mux_nids); 4454 spec->num_muxes = ARRAY_SIZE(stac92hd71bxx_mux_nids);
3690 spec->num_adcs = ARRAY_SIZE(stac92hd71bxx_adc_nids); 4455 spec->num_adcs = ARRAY_SIZE(stac92hd71bxx_adc_nids);
3691 spec->num_dmics = STAC92HD71BXX_NUM_DMICS; 4456
3692 spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); 4457 switch (spec->board_config) {
4458 case STAC_HP_M4:
4459 spec->num_dmics = 0;
4460 spec->num_smuxes = 0;
4461 spec->num_dmuxes = 0;
4462
4463 /* enable internal microphone */
4464 stac92xx_set_config_reg(codec, 0x0e, 0x01813040);
4465 stac92xx_auto_set_pinctl(codec, 0x0e,
4466 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80);
4467 break;
4468 default:
4469 spec->num_dmics = STAC92HD71BXX_NUM_DMICS;
4470 spec->num_smuxes = ARRAY_SIZE(stac92hd71bxx_smux_nids);
4471 spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids);
4472 };
3693 4473
3694 spec->multiout.num_dacs = 1; 4474 spec->multiout.num_dacs = 1;
3695 spec->multiout.hp_nid = 0x11; 4475 spec->multiout.hp_nid = 0x11;
3696 spec->multiout.dac_nids = stac92hd71bxx_dac_nids; 4476 spec->multiout.dac_nids = stac92hd71bxx_dac_nids;
4477 if (spec->dinput_mux)
4478 spec->private_dimux.num_items +=
4479 spec->num_dmics -
4480 (ARRAY_SIZE(stac92hd71bxx_dmic_nids) - 1);
3697 4481
3698 err = stac92xx_parse_auto_config(codec, 0x21, 0x23); 4482 err = stac92xx_parse_auto_config(codec, 0x21, 0x23);
3699 if (!err) { 4483 if (!err) {
@@ -3711,8 +4495,6 @@ again:
3711 return err; 4495 return err;
3712 } 4496 }
3713 4497
3714 codec->patch_ops = stac92xx_patch_ops;
3715
3716 return 0; 4498 return 0;
3717}; 4499};
3718 4500
@@ -3854,10 +4636,14 @@ static int patch_stac927x(struct hda_codec *codec)
3854 stac92xx_set_config_regs(codec); 4636 stac92xx_set_config_regs(codec);
3855 } 4637 }
3856 4638
4639 spec->digbeep_nid = 0x23;
3857 spec->adc_nids = stac927x_adc_nids; 4640 spec->adc_nids = stac927x_adc_nids;
3858 spec->num_adcs = ARRAY_SIZE(stac927x_adc_nids); 4641 spec->num_adcs = ARRAY_SIZE(stac927x_adc_nids);
3859 spec->mux_nids = stac927x_mux_nids; 4642 spec->mux_nids = stac927x_mux_nids;
3860 spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids); 4643 spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids);
4644 spec->smux_nids = stac927x_smux_nids;
4645 spec->num_smuxes = ARRAY_SIZE(stac927x_smux_nids);
4646 spec->spdif_labels = stac927x_spdif_labels;
3861 spec->dac_list = stac927x_dac_nids; 4647 spec->dac_list = stac927x_dac_nids;
3862 spec->multiout.dac_nids = spec->dac_nids; 4648 spec->multiout.dac_nids = spec->dac_nids;
3863 4649
@@ -3900,9 +4686,11 @@ static int patch_stac927x(struct hda_codec *codec)
3900 spec->num_dmuxes = ARRAY_SIZE(stac927x_dmux_nids); 4686 spec->num_dmuxes = ARRAY_SIZE(stac927x_dmux_nids);
3901 break; 4687 break;
3902 default: 4688 default:
3903 /* GPIO0 High = Enable EAPD */ 4689 if (spec->board_config > STAC_D965_REF) {
3904 spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1; 4690 /* GPIO0 High = Enable EAPD */
3905 spec->gpio_data = 0x01; 4691 spec->eapd_mask = spec->gpio_mask = 0x01;
4692 spec->gpio_dir = spec->gpio_data = 0x01;
4693 }
3906 spec->num_dmics = 0; 4694 spec->num_dmics = 0;
3907 4695
3908 spec->init = stac927x_core_init; 4696 spec->init = stac927x_core_init;
@@ -3974,10 +4762,13 @@ static int patch_stac9205(struct hda_codec *codec)
3974 stac92xx_set_config_regs(codec); 4762 stac92xx_set_config_regs(codec);
3975 } 4763 }
3976 4764
4765 spec->digbeep_nid = 0x23;
3977 spec->adc_nids = stac9205_adc_nids; 4766 spec->adc_nids = stac9205_adc_nids;
3978 spec->num_adcs = ARRAY_SIZE(stac9205_adc_nids); 4767 spec->num_adcs = ARRAY_SIZE(stac9205_adc_nids);
3979 spec->mux_nids = stac9205_mux_nids; 4768 spec->mux_nids = stac9205_mux_nids;
3980 spec->num_muxes = ARRAY_SIZE(stac9205_mux_nids); 4769 spec->num_muxes = ARRAY_SIZE(stac9205_mux_nids);
4770 spec->smux_nids = stac9205_smux_nids;
4771 spec->num_smuxes = ARRAY_SIZE(stac9205_smux_nids);
3981 spec->dmic_nids = stac9205_dmic_nids; 4772 spec->dmic_nids = stac9205_dmic_nids;
3982 spec->num_dmics = STAC9205_NUM_DMICS; 4773 spec->num_dmics = STAC9205_NUM_DMICS;
3983 spec->dmux_nids = stac9205_dmux_nids; 4774 spec->dmux_nids = stac9205_dmux_nids;
@@ -4013,6 +4804,9 @@ static int patch_stac9205(struct hda_codec *codec)
4013 */ 4804 */
4014 spec->gpio_data = 0x01; 4805 spec->gpio_data = 0x01;
4015 break; 4806 break;
4807 case STAC_9205_REF:
4808 /* SPDIF-In enabled */
4809 break;
4016 default: 4810 default:
4017 /* GPIO0 High = EAPD */ 4811 /* GPIO0 High = EAPD */
4018 spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1; 4812 spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1;
@@ -4332,6 +5126,8 @@ struct hda_codec_preset snd_hda_preset_sigmatel[] = {
4332 { .id = 0x838476a6, .name = "STAC9254", .patch = patch_stac9205 }, 5126 { .id = 0x838476a6, .name = "STAC9254", .patch = patch_stac9205 },
4333 { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 }, 5127 { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 },
4334 { .id = 0x111d7603, .name = "92HD75B3X5", .patch = patch_stac92hd71bxx}, 5128 { .id = 0x111d7603, .name = "92HD75B3X5", .patch = patch_stac92hd71bxx},
5129 { .id = 0x111d7604, .name = "92HD83C1X5", .patch = patch_stac92hd83xxx},
5130 { .id = 0x111d7605, .name = "92HD81B1X5", .patch = patch_stac92hd83xxx},
4335 { .id = 0x111d7608, .name = "92HD75B2X5", .patch = patch_stac92hd71bxx}, 5131 { .id = 0x111d7608, .name = "92HD75B2X5", .patch = patch_stac92hd71bxx},
4336 { .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx }, 5132 { .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx },
4337 { .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx }, 5133 { .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx },
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index e7e43524f8c7..63e4871e5d8f 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -1,10 +1,10 @@
1/* 1/*
2 * Universal Interface for Intel High Definition Audio Codec 2 * Universal Interface for Intel High Definition Audio Codec
3 * 3 *
4 * HD audio interface patch for VIA VT1708 codec 4 * HD audio interface patch for VIA VT1702/VT1708/VT1709 codec
5 * 5 *
6 * Copyright (c) 2006 Lydia Wang <lydiawang@viatech.com> 6 * Copyright (c) 2006-2008 Lydia Wang <lydiawang@viatech.com>
7 * Takashi Iwai <tiwai@suse.de> 7 * Takashi Iwai <tiwai@suse.de>
8 * 8 *
9 * This driver is free software; you can redistribute it and/or modify 9 * This driver is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by 10 * it under the terms of the GNU General Public License as published by
@@ -29,6 +29,13 @@
29/* 2006-09-08 Lydia Wang Fix internal loopback recording source select bug */ 29/* 2006-09-08 Lydia Wang Fix internal loopback recording source select bug */
30/* 2007-09-12 Lydia Wang Add EAPD enable during driver initialization */ 30/* 2007-09-12 Lydia Wang Add EAPD enable during driver initialization */
31/* 2007-09-17 Lydia Wang Add VT1708B codec support */ 31/* 2007-09-17 Lydia Wang Add VT1708B codec support */
32/* 2007-11-14 Lydia Wang Add VT1708A codec HP and CD pin connect config */
33/* 2008-02-03 Lydia Wang Fix Rear channels and Back channels inverse issue */
34/* 2008-03-06 Lydia Wang Add VT1702 codec and VT1708S codec support */
35/* 2008-04-09 Lydia Wang Add mute front speaker when HP plugin */
36/* 2008-04-09 Lydia Wang Add Independent HP feature */
37/* 2008-05-28 Lydia Wang Add second S/PDIF Out support for VT1702 */
38/* 2008-09-15 Logan Li Add VT1708S Mic Boost workaround/backdoor */
32/* */ 39/* */
33/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 40/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
34 41
@@ -37,6 +44,7 @@
37#include <linux/delay.h> 44#include <linux/delay.h>
38#include <linux/slab.h> 45#include <linux/slab.h>
39#include <sound/core.h> 46#include <sound/core.h>
47#include <sound/asoundef.h>
40#include "hda_codec.h" 48#include "hda_codec.h"
41#include "hda_local.h" 49#include "hda_local.h"
42#include "hda_patch.h" 50#include "hda_patch.h"
@@ -53,6 +61,8 @@
53#define VT1708_DIGOUT_NID 0x14 61#define VT1708_DIGOUT_NID 0x14
54#define VT1708_DIGIN_NID 0x16 62#define VT1708_DIGIN_NID 0x16
55#define VT1708_DIGIN_PIN 0x26 63#define VT1708_DIGIN_PIN 0x26
64#define VT1708_HP_PIN_NID 0x20
65#define VT1708_CD_PIN_NID 0x24
56 66
57#define VT1709_HP_DAC_NID 0x28 67#define VT1709_HP_DAC_NID 0x28
58#define VT1709_DIGOUT_NID 0x13 68#define VT1709_DIGOUT_NID 0x13
@@ -64,12 +74,64 @@
64#define VT1708B_DIGIN_NID 0x15 74#define VT1708B_DIGIN_NID 0x15
65#define VT1708B_DIGIN_PIN 0x21 75#define VT1708B_DIGIN_PIN 0x21
66 76
77#define VT1708S_HP_NID 0x25
78#define VT1708S_DIGOUT_NID 0x12
79
80#define VT1702_HP_NID 0x17
81#define VT1702_DIGOUT_NID 0x11
82
67#define IS_VT1708_VENDORID(x) ((x) >= 0x11061708 && (x) <= 0x1106170b) 83#define IS_VT1708_VENDORID(x) ((x) >= 0x11061708 && (x) <= 0x1106170b)
68#define IS_VT1709_10CH_VENDORID(x) ((x) >= 0x1106e710 && (x) <= 0x1106e713) 84#define IS_VT1709_10CH_VENDORID(x) ((x) >= 0x1106e710 && (x) <= 0x1106e713)
69#define IS_VT1709_6CH_VENDORID(x) ((x) >= 0x1106e714 && (x) <= 0x1106e717) 85#define IS_VT1709_6CH_VENDORID(x) ((x) >= 0x1106e714 && (x) <= 0x1106e717)
70#define IS_VT1708B_8CH_VENDORID(x) ((x) >= 0x1106e720 && (x) <= 0x1106e723) 86#define IS_VT1708B_8CH_VENDORID(x) ((x) >= 0x1106e720 && (x) <= 0x1106e723)
71#define IS_VT1708B_4CH_VENDORID(x) ((x) >= 0x1106e724 && (x) <= 0x1106e727) 87#define IS_VT1708B_4CH_VENDORID(x) ((x) >= 0x1106e724 && (x) <= 0x1106e727)
88#define IS_VT1708S_VENDORID(x) ((x) >= 0x11060397 && (x) <= 0x11067397)
89#define IS_VT1702_VENDORID(x) ((x) >= 0x11060398 && (x) <= 0x11067398)
90
91enum VIA_HDA_CODEC {
92 UNKNOWN = -1,
93 VT1708,
94 VT1709_10CH,
95 VT1709_6CH,
96 VT1708B_8CH,
97 VT1708B_4CH,
98 VT1708S,
99 VT1702,
100 CODEC_TYPES,
101};
102
103static enum VIA_HDA_CODEC get_codec_type(u32 vendor_id)
104{
105 u16 ven_id = vendor_id >> 16;
106 u16 dev_id = vendor_id & 0xffff;
107 enum VIA_HDA_CODEC codec_type;
108
109 /* get codec type */
110 if (ven_id != 0x1106)
111 codec_type = UNKNOWN;
112 else if (dev_id >= 0x1708 && dev_id <= 0x170b)
113 codec_type = VT1708;
114 else if (dev_id >= 0xe710 && dev_id <= 0xe713)
115 codec_type = VT1709_10CH;
116 else if (dev_id >= 0xe714 && dev_id <= 0xe717)
117 codec_type = VT1709_6CH;
118 else if (dev_id >= 0xe720 && dev_id <= 0xe723)
119 codec_type = VT1708B_8CH;
120 else if (dev_id >= 0xe724 && dev_id <= 0xe727)
121 codec_type = VT1708B_4CH;
122 else if ((dev_id & 0xfff) == 0x397
123 && (dev_id >> 12) < 8)
124 codec_type = VT1708S;
125 else if ((dev_id & 0xfff) == 0x398
126 && (dev_id >> 12) < 8)
127 codec_type = VT1702;
128 else
129 codec_type = UNKNOWN;
130 return codec_type;
131};
72 132
133#define VIA_HP_EVENT 0x01
134#define VIA_GPIO_EVENT 0x02
73 135
74enum { 136enum {
75 VIA_CTL_WIDGET_VOL, 137 VIA_CTL_WIDGET_VOL,
@@ -77,12 +139,54 @@ enum {
77}; 139};
78 140
79enum { 141enum {
80 AUTO_SEQ_FRONT, 142 AUTO_SEQ_FRONT = 0,
81 AUTO_SEQ_SURROUND, 143 AUTO_SEQ_SURROUND,
82 AUTO_SEQ_CENLFE, 144 AUTO_SEQ_CENLFE,
83 AUTO_SEQ_SIDE 145 AUTO_SEQ_SIDE
84}; 146};
85 147
148#define get_amp_nid(kc) ((kc)->private_value & 0xffff)
149
150/* Some VT1708S based boards gets the micboost setting wrong, so we have
151 * to apply some brute-force and re-write the TLV's by software. */
152static int mic_boost_tlv(struct snd_kcontrol *kcontrol, int op_flag,
153 unsigned int size, unsigned int __user *_tlv)
154{
155 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
156 hda_nid_t nid = get_amp_nid(kcontrol);
157
158 if (get_codec_type(codec->vendor_id) == VT1708S
159 && (nid == 0x1a || nid == 0x1e)) {
160 if (size < 4 * sizeof(unsigned int))
161 return -ENOMEM;
162 if (put_user(1, _tlv)) /* SNDRV_CTL_TLVT_DB_SCALE */
163 return -EFAULT;
164 if (put_user(2 * sizeof(unsigned int), _tlv + 1))
165 return -EFAULT;
166 if (put_user(0, _tlv + 2)) /* offset = 0 */
167 return -EFAULT;
168 if (put_user(1000, _tlv + 3)) /* step size = 10 dB */
169 return -EFAULT;
170 }
171 return 0;
172}
173
174static int mic_boost_volume_info(struct snd_kcontrol *kcontrol,
175 struct snd_ctl_elem_info *uinfo)
176{
177 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
178 hda_nid_t nid = get_amp_nid(kcontrol);
179
180 if (get_codec_type(codec->vendor_id) == VT1708S
181 && (nid == 0x1a || nid == 0x1e)) {
182 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
183 uinfo->count = 2;
184 uinfo->value.integer.min = 0;
185 uinfo->value.integer.max = 3;
186 }
187 return 0;
188}
189
86static struct snd_kcontrol_new vt1708_control_templates[] = { 190static struct snd_kcontrol_new vt1708_control_templates[] = {
87 HDA_CODEC_VOLUME(NULL, 0, 0, 0), 191 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
88 HDA_CODEC_MUTE(NULL, 0, 0, 0), 192 HDA_CODEC_MUTE(NULL, 0, 0, 0),
@@ -94,7 +198,8 @@ struct via_spec {
94 struct snd_kcontrol_new *mixers[3]; 198 struct snd_kcontrol_new *mixers[3];
95 unsigned int num_mixers; 199 unsigned int num_mixers;
96 200
97 struct hda_verb *init_verbs; 201 struct hda_verb *init_verbs[5];
202 unsigned int num_iverbs;
98 203
99 char *stream_name_analog; 204 char *stream_name_analog;
100 struct hda_pcm_stream *stream_analog_playback; 205 struct hda_pcm_stream *stream_analog_playback;
@@ -106,6 +211,7 @@ struct via_spec {
106 211
107 /* playback */ 212 /* playback */
108 struct hda_multi_out multiout; 213 struct hda_multi_out multiout;
214 hda_nid_t extra_dig_out_nid;
109 215
110 /* capture */ 216 /* capture */
111 unsigned int num_adc_nids; 217 unsigned int num_adc_nids;
@@ -117,15 +223,19 @@ struct via_spec {
117 unsigned int cur_mux[3]; 223 unsigned int cur_mux[3];
118 224
119 /* PCM information */ 225 /* PCM information */
120 struct hda_pcm pcm_rec[2]; 226 struct hda_pcm pcm_rec[3];
121 227
122 /* dynamic controls, init_verbs and input_mux */ 228 /* dynamic controls, init_verbs and input_mux */
123 struct auto_pin_cfg autocfg; 229 struct auto_pin_cfg autocfg;
124 unsigned int num_kctl_alloc, num_kctl_used; 230 unsigned int num_kctl_alloc, num_kctl_used;
125 struct snd_kcontrol_new *kctl_alloc; 231 struct snd_kcontrol_new *kctl_alloc;
126 struct hda_input_mux private_imux; 232 struct hda_input_mux private_imux[2];
127 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; 233 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
128 234
235 /* HP mode source */
236 const struct hda_input_mux *hp_mux;
237 unsigned int hp_independent_mode;
238
129#ifdef CONFIG_SND_HDA_POWER_SAVE 239#ifdef CONFIG_SND_HDA_POWER_SAVE
130 struct hda_loopback_check loopback; 240 struct hda_loopback_check loopback;
131#endif 241#endif
@@ -146,6 +256,16 @@ static hda_nid_t vt1708B_adc_nids[2] = {
146 0x13, 0x14 256 0x13, 0x14
147}; 257};
148 258
259static hda_nid_t vt1708S_adc_nids[2] = {
260 /* ADC1-2 */
261 0x13, 0x14
262};
263
264static hda_nid_t vt1702_adc_nids[3] = {
265 /* ADC1-2 */
266 0x12, 0x20, 0x1F
267};
268
149/* add dynamic controls */ 269/* add dynamic controls */
150static int via_add_control(struct via_spec *spec, int type, const char *name, 270static int via_add_control(struct via_spec *spec, int type, const char *name,
151 unsigned long val) 271 unsigned long val)
@@ -283,19 +403,108 @@ static int via_mux_enum_put(struct snd_kcontrol *kcontrol,
283 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, 403 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
284 0x18, &spec->cur_mux[adc_idx]); 404 0x18, &spec->cur_mux[adc_idx]);
285 else if ((IS_VT1709_10CH_VENDORID(vendor_id) || 405 else if ((IS_VT1709_10CH_VENDORID(vendor_id) ||
286 IS_VT1709_6CH_VENDORID(vendor_id)) && adc_idx == 0) 406 IS_VT1709_6CH_VENDORID(vendor_id)) && (adc_idx == 0))
287 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, 407 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
288 0x19, &spec->cur_mux[adc_idx]); 408 0x19, &spec->cur_mux[adc_idx]);
289 else if ((IS_VT1708B_8CH_VENDORID(vendor_id) || 409 else if ((IS_VT1708B_8CH_VENDORID(vendor_id) ||
290 IS_VT1708B_4CH_VENDORID(vendor_id)) && adc_idx == 0) 410 IS_VT1708B_4CH_VENDORID(vendor_id)) && (adc_idx == 0))
291 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, 411 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
292 0x17, &spec->cur_mux[adc_idx]); 412 0x17, &spec->cur_mux[adc_idx]);
413 else if (IS_VT1702_VENDORID(vendor_id) && (adc_idx == 0))
414 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
415 0x13, &spec->cur_mux[adc_idx]);
293 else 416 else
294 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, 417 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
295 spec->adc_nids[adc_idx], 418 spec->adc_nids[adc_idx],
296 &spec->cur_mux[adc_idx]); 419 &spec->cur_mux[adc_idx]);
297} 420}
298 421
422static int via_independent_hp_info(struct snd_kcontrol *kcontrol,
423 struct snd_ctl_elem_info *uinfo)
424{
425 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
426 struct via_spec *spec = codec->spec;
427 return snd_hda_input_mux_info(spec->hp_mux, uinfo);
428}
429
430static int via_independent_hp_get(struct snd_kcontrol *kcontrol,
431 struct snd_ctl_elem_value *ucontrol)
432{
433 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
434 struct via_spec *spec = codec->spec;
435 hda_nid_t nid = spec->autocfg.hp_pins[0];
436 unsigned int pinsel = snd_hda_codec_read(codec, nid, 0,
437 AC_VERB_GET_CONNECT_SEL,
438 0x00);
439
440 ucontrol->value.enumerated.item[0] = pinsel;
441
442 return 0;
443}
444
445static int via_independent_hp_put(struct snd_kcontrol *kcontrol,
446 struct snd_ctl_elem_value *ucontrol)
447{
448 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
449 struct via_spec *spec = codec->spec;
450 hda_nid_t nid = spec->autocfg.hp_pins[0];
451 unsigned int pinsel = ucontrol->value.enumerated.item[0];
452 unsigned int con_nid = snd_hda_codec_read(codec, nid, 0,
453 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
454
455 if (con_nid == spec->multiout.hp_nid) {
456 if (pinsel == 0) {
457 if (!spec->hp_independent_mode) {
458 if (spec->multiout.num_dacs > 1)
459 spec->multiout.num_dacs -= 1;
460 spec->hp_independent_mode = 1;
461 }
462 } else if (pinsel == 1) {
463 if (spec->hp_independent_mode) {
464 if (spec->multiout.num_dacs > 1)
465 spec->multiout.num_dacs += 1;
466 spec->hp_independent_mode = 0;
467 }
468 }
469 } else {
470 if (pinsel == 0) {
471 if (spec->hp_independent_mode) {
472 if (spec->multiout.num_dacs > 1)
473 spec->multiout.num_dacs += 1;
474 spec->hp_independent_mode = 0;
475 }
476 } else if (pinsel == 1) {
477 if (!spec->hp_independent_mode) {
478 if (spec->multiout.num_dacs > 1)
479 spec->multiout.num_dacs -= 1;
480 spec->hp_independent_mode = 1;
481 }
482 }
483 }
484 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL,
485 pinsel);
486
487 if (spec->multiout.hp_nid &&
488 spec->multiout.hp_nid != spec->multiout.dac_nids[HDA_FRONT])
489 snd_hda_codec_setup_stream(codec,
490 spec->multiout.hp_nid,
491 0, 0, 0);
492
493 return 0;
494}
495
496static struct snd_kcontrol_new via_hp_mixer[] = {
497 {
498 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
499 .name = "Independent HP",
500 .count = 1,
501 .info = via_independent_hp_info,
502 .get = via_independent_hp_get,
503 .put = via_independent_hp_put,
504 },
505 { } /* end */
506};
507
299/* capture mixer elements */ 508/* capture mixer elements */
300static struct snd_kcontrol_new vt1708_capture_mixer[] = { 509static struct snd_kcontrol_new vt1708_capture_mixer[] = {
301 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT), 510 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT),
@@ -380,6 +589,138 @@ static int via_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
380 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); 589 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
381} 590}
382 591
592
593static void playback_multi_pcm_prep_0(struct hda_codec *codec,
594 unsigned int stream_tag,
595 unsigned int format,
596 struct snd_pcm_substream *substream)
597{
598 struct via_spec *spec = codec->spec;
599 struct hda_multi_out *mout = &spec->multiout;
600 hda_nid_t *nids = mout->dac_nids;
601 int chs = substream->runtime->channels;
602 int i;
603
604 mutex_lock(&codec->spdif_mutex);
605 if (mout->dig_out_nid && mout->dig_out_used != HDA_DIG_EXCLUSIVE) {
606 if (chs == 2 &&
607 snd_hda_is_supported_format(codec, mout->dig_out_nid,
608 format) &&
609 !(codec->spdif_status & IEC958_AES0_NONAUDIO)) {
610 mout->dig_out_used = HDA_DIG_ANALOG_DUP;
611 /* turn off SPDIF once; otherwise the IEC958 bits won't
612 * be updated */
613 if (codec->spdif_ctls & AC_DIG1_ENABLE)
614 snd_hda_codec_write(codec, mout->dig_out_nid, 0,
615 AC_VERB_SET_DIGI_CONVERT_1,
616 codec->spdif_ctls &
617 ~AC_DIG1_ENABLE & 0xff);
618 snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
619 stream_tag, 0, format);
620 /* turn on again (if needed) */
621 if (codec->spdif_ctls & AC_DIG1_ENABLE)
622 snd_hda_codec_write(codec, mout->dig_out_nid, 0,
623 AC_VERB_SET_DIGI_CONVERT_1,
624 codec->spdif_ctls & 0xff);
625 } else {
626 mout->dig_out_used = 0;
627 snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
628 0, 0, 0);
629 }
630 }
631 mutex_unlock(&codec->spdif_mutex);
632
633 /* front */
634 snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag,
635 0, format);
636
637 if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT] &&
638 !spec->hp_independent_mode)
639 /* headphone out will just decode front left/right (stereo) */
640 snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag,
641 0, format);
642
643 /* extra outputs copied from front */
644 for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
645 if (mout->extra_out_nid[i])
646 snd_hda_codec_setup_stream(codec,
647 mout->extra_out_nid[i],
648 stream_tag, 0, format);
649
650 /* surrounds */
651 for (i = 1; i < mout->num_dacs; i++) {
652 if (chs >= (i + 1) * 2) /* independent out */
653 snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
654 i * 2, format);
655 else /* copy front */
656 snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
657 0, format);
658 }
659}
660
661static int via_playback_multi_pcm_prepare(struct hda_pcm_stream *hinfo,
662 struct hda_codec *codec,
663 unsigned int stream_tag,
664 unsigned int format,
665 struct snd_pcm_substream *substream)
666{
667 struct via_spec *spec = codec->spec;
668 struct hda_multi_out *mout = &spec->multiout;
669 hda_nid_t *nids = mout->dac_nids;
670
671 if (substream->number == 0)
672 playback_multi_pcm_prep_0(codec, stream_tag, format,
673 substream);
674 else {
675 if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT] &&
676 spec->hp_independent_mode)
677 snd_hda_codec_setup_stream(codec, mout->hp_nid,
678 stream_tag, 0, format);
679 }
680
681 return 0;
682}
683
684static int via_playback_multi_pcm_cleanup(struct hda_pcm_stream *hinfo,
685 struct hda_codec *codec,
686 struct snd_pcm_substream *substream)
687{
688 struct via_spec *spec = codec->spec;
689 struct hda_multi_out *mout = &spec->multiout;
690 hda_nid_t *nids = mout->dac_nids;
691 int i;
692
693 if (substream->number == 0) {
694 for (i = 0; i < mout->num_dacs; i++)
695 snd_hda_codec_setup_stream(codec, nids[i], 0, 0, 0);
696
697 if (mout->hp_nid && !spec->hp_independent_mode)
698 snd_hda_codec_setup_stream(codec, mout->hp_nid,
699 0, 0, 0);
700
701 for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
702 if (mout->extra_out_nid[i])
703 snd_hda_codec_setup_stream(codec,
704 mout->extra_out_nid[i],
705 0, 0, 0);
706 mutex_lock(&codec->spdif_mutex);
707 if (mout->dig_out_nid &&
708 mout->dig_out_used == HDA_DIG_ANALOG_DUP) {
709 snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
710 0, 0, 0);
711 mout->dig_out_used = 0;
712 }
713 mutex_unlock(&codec->spdif_mutex);
714 } else {
715 if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT] &&
716 spec->hp_independent_mode)
717 snd_hda_codec_setup_stream(codec, mout->hp_nid,
718 0, 0, 0);
719 }
720
721 return 0;
722}
723
383/* 724/*
384 * Digital out 725 * Digital out
385 */ 726 */
@@ -399,6 +740,21 @@ static int via_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
399 return snd_hda_multi_out_dig_close(codec, &spec->multiout); 740 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
400} 741}
401 742
743/* setup SPDIF output stream */
744static void setup_dig_playback_stream(struct hda_codec *codec, hda_nid_t nid,
745 unsigned int stream_tag, unsigned int format)
746{
747 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
748 if (codec->spdif_ctls & AC_DIG1_ENABLE)
749 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
750 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff);
751 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
752 /* turn on again (if needed) */
753 if (codec->spdif_ctls & AC_DIG1_ENABLE)
754 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
755 codec->spdif_ctls & 0xff);
756}
757
402static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 758static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
403 struct hda_codec *codec, 759 struct hda_codec *codec,
404 unsigned int stream_tag, 760 unsigned int stream_tag,
@@ -406,8 +762,20 @@ static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
406 struct snd_pcm_substream *substream) 762 struct snd_pcm_substream *substream)
407{ 763{
408 struct via_spec *spec = codec->spec; 764 struct via_spec *spec = codec->spec;
409 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, 765 hda_nid_t nid;
410 stream_tag, format, substream); 766
767 /* 1st or 2nd S/PDIF */
768 if (substream->number == 0)
769 nid = spec->multiout.dig_out_nid;
770 else if (substream->number == 1)
771 nid = spec->extra_dig_out_nid;
772 else
773 return -1;
774
775 mutex_lock(&codec->spdif_mutex);
776 setup_dig_playback_stream(codec, nid, stream_tag, format);
777 mutex_unlock(&codec->spdif_mutex);
778 return 0;
411} 779}
412 780
413/* 781/*
@@ -436,14 +804,14 @@ static int via_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
436} 804}
437 805
438static struct hda_pcm_stream vt1708_pcm_analog_playback = { 806static struct hda_pcm_stream vt1708_pcm_analog_playback = {
439 .substreams = 1, 807 .substreams = 2,
440 .channels_min = 2, 808 .channels_min = 2,
441 .channels_max = 8, 809 .channels_max = 8,
442 .nid = 0x10, /* NID to query formats and rates */ 810 .nid = 0x10, /* NID to query formats and rates */
443 .ops = { 811 .ops = {
444 .open = via_playback_pcm_open, 812 .open = via_playback_pcm_open,
445 .prepare = via_playback_pcm_prepare, 813 .prepare = via_playback_multi_pcm_prepare,
446 .cleanup = via_playback_pcm_cleanup 814 .cleanup = via_playback_multi_pcm_cleanup
447 }, 815 },
448}; 816};
449 817
@@ -515,6 +883,13 @@ static int via_build_controls(struct hda_codec *codec)
515 if (err < 0) 883 if (err < 0)
516 return err; 884 return err;
517 spec->multiout.share_spdif = 1; 885 spec->multiout.share_spdif = 1;
886
887 if (spec->extra_dig_out_nid) {
888 err = snd_hda_create_spdif_out_ctls(codec,
889 spec->extra_dig_out_nid);
890 if (err < 0)
891 return err;
892 }
518 } 893 }
519 if (spec->dig_in_nid) { 894 if (spec->dig_in_nid) {
520 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); 895 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
@@ -580,10 +955,89 @@ static void via_free(struct hda_codec *codec)
580 kfree(codec->spec); 955 kfree(codec->spec);
581} 956}
582 957
958/* mute internal speaker if HP is plugged */
959static void via_hp_automute(struct hda_codec *codec)
960{
961 unsigned int present;
962 struct via_spec *spec = codec->spec;
963
964 present = snd_hda_codec_read(codec, spec->autocfg.hp_pins[0], 0,
965 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
966 snd_hda_codec_amp_stereo(codec, spec->autocfg.line_out_pins[0],
967 HDA_OUTPUT, 0, HDA_AMP_MUTE,
968 present ? HDA_AMP_MUTE : 0);
969}
970
971static void via_gpio_control(struct hda_codec *codec)
972{
973 unsigned int gpio_data;
974 unsigned int vol_counter;
975 unsigned int vol;
976 unsigned int master_vol;
977
978 struct via_spec *spec = codec->spec;
979
980 gpio_data = snd_hda_codec_read(codec, codec->afg, 0,
981 AC_VERB_GET_GPIO_DATA, 0) & 0x03;
982
983 vol_counter = (snd_hda_codec_read(codec, codec->afg, 0,
984 0xF84, 0) & 0x3F0000) >> 16;
985
986 vol = vol_counter & 0x1F;
987 master_vol = snd_hda_codec_read(codec, 0x1A, 0,
988 AC_VERB_GET_AMP_GAIN_MUTE,
989 AC_AMP_GET_INPUT);
990
991 if (gpio_data == 0x02) {
992 /* unmute line out */
993 snd_hda_codec_amp_stereo(codec, spec->autocfg.line_out_pins[0],
994 HDA_OUTPUT, 0, HDA_AMP_MUTE, 0);
995
996 if (vol_counter & 0x20) {
997 /* decrease volume */
998 if (vol > master_vol)
999 vol = master_vol;
1000 snd_hda_codec_amp_stereo(codec, 0x1A, HDA_INPUT,
1001 0, HDA_AMP_VOLMASK,
1002 master_vol-vol);
1003 } else {
1004 /* increase volume */
1005 snd_hda_codec_amp_stereo(codec, 0x1A, HDA_INPUT, 0,
1006 HDA_AMP_VOLMASK,
1007 ((master_vol+vol) > 0x2A) ? 0x2A :
1008 (master_vol+vol));
1009 }
1010 } else if (!(gpio_data & 0x02)) {
1011 /* mute line out */
1012 snd_hda_codec_amp_stereo(codec,
1013 spec->autocfg.line_out_pins[0],
1014 HDA_OUTPUT, 0, HDA_AMP_MUTE,
1015 HDA_AMP_MUTE);
1016 }
1017}
1018
1019/* unsolicited event for jack sensing */
1020static void via_unsol_event(struct hda_codec *codec,
1021 unsigned int res)
1022{
1023 res >>= 26;
1024 if (res == VIA_HP_EVENT)
1025 via_hp_automute(codec);
1026 else if (res == VIA_GPIO_EVENT)
1027 via_gpio_control(codec);
1028}
1029
1030static hda_nid_t slave_dig_outs[] = {
1031 0,
1032};
1033
583static int via_init(struct hda_codec *codec) 1034static int via_init(struct hda_codec *codec)
584{ 1035{
585 struct via_spec *spec = codec->spec; 1036 struct via_spec *spec = codec->spec;
586 snd_hda_sequence_write(codec, spec->init_verbs); 1037 int i;
1038 for (i = 0; i < spec->num_iverbs; i++)
1039 snd_hda_sequence_write(codec, spec->init_verbs[i]);
1040
587 /* Lydia Add for EAPD enable */ 1041 /* Lydia Add for EAPD enable */
588 if (!spec->dig_in_nid) { /* No Digital In connection */ 1042 if (!spec->dig_in_nid) { /* No Digital In connection */
589 if (IS_VT1708_VENDORID(codec->vendor_id)) { 1043 if (IS_VT1708_VENDORID(codec->vendor_id)) {
@@ -611,6 +1065,9 @@ static int via_init(struct hda_codec *codec)
611 snd_hda_codec_write(codec, spec->autocfg.dig_in_pin, 0, 1065 snd_hda_codec_write(codec, spec->autocfg.dig_in_pin, 0,
612 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN); 1066 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN);
613 1067
1068 /* no slave outs */
1069 codec->slave_dig_outs = slave_dig_outs;
1070
614 return 0; 1071 return 0;
615} 1072}
616 1073
@@ -657,10 +1114,10 @@ static int vt1708_auto_fill_dac_nids(struct via_spec *spec,
657 spec->multiout.dac_nids[i] = 0x12; 1114 spec->multiout.dac_nids[i] = 0x12;
658 break; 1115 break;
659 case AUTO_SEQ_SURROUND: 1116 case AUTO_SEQ_SURROUND:
660 spec->multiout.dac_nids[i] = 0x13; 1117 spec->multiout.dac_nids[i] = 0x11;
661 break; 1118 break;
662 case AUTO_SEQ_SIDE: 1119 case AUTO_SEQ_SIDE:
663 spec->multiout.dac_nids[i] = 0x11; 1120 spec->multiout.dac_nids[i] = 0x13;
664 break; 1121 break;
665 } 1122 }
666 } 1123 }
@@ -685,7 +1142,7 @@ static int vt1708_auto_create_multi_out_ctls(struct via_spec *spec,
685 continue; 1142 continue;
686 1143
687 if (i != AUTO_SEQ_FRONT) 1144 if (i != AUTO_SEQ_FRONT)
688 nid_vol = 0x1b - i + 1; 1145 nid_vol = 0x18 + i;
689 1146
690 if (i == AUTO_SEQ_CENLFE) { 1147 if (i == AUTO_SEQ_CENLFE) {
691 /* Center/LFE */ 1148 /* Center/LFE */
@@ -760,6 +1217,24 @@ static int vt1708_auto_create_multi_out_ctls(struct via_spec *spec,
760 return 0; 1217 return 0;
761} 1218}
762 1219
1220static void create_hp_imux(struct via_spec *spec)
1221{
1222 int i;
1223 struct hda_input_mux *imux = &spec->private_imux[1];
1224 static const char *texts[] = { "OFF", "ON", NULL};
1225
1226 /* for hp mode select */
1227 i = 0;
1228 while (texts[i] != NULL) {
1229 imux->items[imux->num_items].label = texts[i];
1230 imux->items[imux->num_items].index = i;
1231 imux->num_items++;
1232 i++;
1233 }
1234
1235 spec->hp_mux = &spec->private_imux[1];
1236}
1237
763static int vt1708_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) 1238static int vt1708_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
764{ 1239{
765 int err; 1240 int err;
@@ -780,6 +1255,8 @@ static int vt1708_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
780 if (err < 0) 1255 if (err < 0)
781 return err; 1256 return err;
782 1257
1258 create_hp_imux(spec);
1259
783 return 0; 1260 return 0;
784} 1261}
785 1262
@@ -790,7 +1267,7 @@ static int vt1708_auto_create_analog_input_ctls(struct via_spec *spec,
790 static char *labels[] = { 1267 static char *labels[] = {
791 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL 1268 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
792 }; 1269 };
793 struct hda_input_mux *imux = &spec->private_imux; 1270 struct hda_input_mux *imux = &spec->private_imux[0];
794 int i, err, idx = 0; 1271 int i, err, idx = 0;
795 1272
796 /* for internal loopback recording select */ 1273 /* for internal loopback recording select */
@@ -840,11 +1317,36 @@ static struct hda_amp_list vt1708_loopbacks[] = {
840}; 1317};
841#endif 1318#endif
842 1319
1320static void vt1708_set_pinconfig_connect(struct hda_codec *codec, hda_nid_t nid)
1321{
1322 unsigned int def_conf;
1323 unsigned char seqassoc;
1324
1325 def_conf = snd_hda_codec_read(codec, nid, 0,
1326 AC_VERB_GET_CONFIG_DEFAULT, 0);
1327 seqassoc = (unsigned char) get_defcfg_association(def_conf);
1328 seqassoc = (seqassoc << 4) | get_defcfg_sequence(def_conf);
1329 if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) {
1330 if (seqassoc == 0xff) {
1331 def_conf = def_conf & (~(AC_JACK_PORT_BOTH << 30));
1332 snd_hda_codec_write(codec, nid, 0,
1333 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3,
1334 def_conf >> 24);
1335 }
1336 }
1337
1338 return;
1339}
1340
843static int vt1708_parse_auto_config(struct hda_codec *codec) 1341static int vt1708_parse_auto_config(struct hda_codec *codec)
844{ 1342{
845 struct via_spec *spec = codec->spec; 1343 struct via_spec *spec = codec->spec;
846 int err; 1344 int err;
847 1345
1346 /* Add HP and CD pin config connect bit re-config action */
1347 vt1708_set_pinconfig_connect(codec, VT1708_HP_PIN_NID);
1348 vt1708_set_pinconfig_connect(codec, VT1708_CD_PIN_NID);
1349
848 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL); 1350 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
849 if (err < 0) 1351 if (err < 0)
850 return err; 1352 return err;
@@ -874,9 +1376,12 @@ static int vt1708_parse_auto_config(struct hda_codec *codec)
874 if (spec->kctl_alloc) 1376 if (spec->kctl_alloc)
875 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 1377 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
876 1378
877 spec->init_verbs = vt1708_volume_init_verbs; 1379 spec->init_verbs[spec->num_iverbs++] = vt1708_volume_init_verbs;
1380
1381 spec->input_mux = &spec->private_imux[0];
878 1382
879 spec->input_mux = &spec->private_imux; 1383 if (spec->hp_mux)
1384 spec->mixers[spec->num_mixers++] = via_hp_mixer;
880 1385
881 return 1; 1386 return 1;
882} 1387}
@@ -897,7 +1402,7 @@ static int patch_vt1708(struct hda_codec *codec)
897 int err; 1402 int err;
898 1403
899 /* create a codec specific record */ 1404 /* create a codec specific record */
900 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); 1405 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
901 if (spec == NULL) 1406 if (spec == NULL)
902 return -ENOMEM; 1407 return -ENOMEM;
903 1408
@@ -966,6 +1471,11 @@ static struct snd_kcontrol_new vt1709_capture_mixer[] = {
966 { } /* end */ 1471 { } /* end */
967}; 1472};
968 1473
1474static struct hda_verb vt1709_uniwill_init_verbs[] = {
1475 {0x20, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_HP_EVENT},
1476 { }
1477};
1478
969/* 1479/*
970 * generic initialization of ADC, input mixers and output mixers 1480 * generic initialization of ADC, input mixers and output mixers
971 */ 1481 */
@@ -1090,11 +1600,11 @@ static int vt1709_auto_fill_dac_nids(struct via_spec *spec,
1090 break; 1600 break;
1091 case AUTO_SEQ_SURROUND: 1601 case AUTO_SEQ_SURROUND:
1092 /* AOW3 */ 1602 /* AOW3 */
1093 spec->multiout.dac_nids[i] = 0x27; 1603 spec->multiout.dac_nids[i] = 0x11;
1094 break; 1604 break;
1095 case AUTO_SEQ_SIDE: 1605 case AUTO_SEQ_SIDE:
1096 /* AOW1 */ 1606 /* AOW1 */
1097 spec->multiout.dac_nids[i] = 0x11; 1607 spec->multiout.dac_nids[i] = 0x27;
1098 break; 1608 break;
1099 default: 1609 default:
1100 break; 1610 break;
@@ -1203,26 +1713,26 @@ static int vt1709_auto_create_multi_out_ctls(struct via_spec *spec,
1203 } else if (i == AUTO_SEQ_SURROUND) { 1713 } else if (i == AUTO_SEQ_SURROUND) {
1204 sprintf(name, "%s Playback Volume", chname[i]); 1714 sprintf(name, "%s Playback Volume", chname[i]);
1205 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 1715 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
1206 HDA_COMPOSE_AMP_VAL(0x29, 3, 0, 1716 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0,
1207 HDA_OUTPUT)); 1717 HDA_OUTPUT));
1208 if (err < 0) 1718 if (err < 0)
1209 return err; 1719 return err;
1210 sprintf(name, "%s Playback Switch", chname[i]); 1720 sprintf(name, "%s Playback Switch", chname[i]);
1211 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name, 1721 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1212 HDA_COMPOSE_AMP_VAL(0x29, 3, 0, 1722 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0,
1213 HDA_OUTPUT)); 1723 HDA_OUTPUT));
1214 if (err < 0) 1724 if (err < 0)
1215 return err; 1725 return err;
1216 } else if (i == AUTO_SEQ_SIDE) { 1726 } else if (i == AUTO_SEQ_SIDE) {
1217 sprintf(name, "%s Playback Volume", chname[i]); 1727 sprintf(name, "%s Playback Volume", chname[i]);
1218 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 1728 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
1219 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, 1729 HDA_COMPOSE_AMP_VAL(0x29, 3, 0,
1220 HDA_OUTPUT)); 1730 HDA_OUTPUT));
1221 if (err < 0) 1731 if (err < 0)
1222 return err; 1732 return err;
1223 sprintf(name, "%s Playback Switch", chname[i]); 1733 sprintf(name, "%s Playback Switch", chname[i]);
1224 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name, 1734 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1225 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, 1735 HDA_COMPOSE_AMP_VAL(0x29, 3, 0,
1226 HDA_OUTPUT)); 1736 HDA_OUTPUT));
1227 if (err < 0) 1737 if (err < 0)
1228 return err; 1738 return err;
@@ -1265,7 +1775,7 @@ static int vt1709_auto_create_analog_input_ctls(struct via_spec *spec,
1265 static char *labels[] = { 1775 static char *labels[] = {
1266 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL 1776 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
1267 }; 1777 };
1268 struct hda_input_mux *imux = &spec->private_imux; 1778 struct hda_input_mux *imux = &spec->private_imux[0];
1269 int i, err, idx = 0; 1779 int i, err, idx = 0;
1270 1780
1271 /* for internal loopback recording select */ 1781 /* for internal loopback recording select */
@@ -1339,7 +1849,10 @@ static int vt1709_parse_auto_config(struct hda_codec *codec)
1339 if (spec->kctl_alloc) 1849 if (spec->kctl_alloc)
1340 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 1850 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
1341 1851
1342 spec->input_mux = &spec->private_imux; 1852 spec->input_mux = &spec->private_imux[0];
1853
1854 if (spec->hp_mux)
1855 spec->mixers[spec->num_mixers++] = via_hp_mixer;
1343 1856
1344 return 1; 1857 return 1;
1345} 1858}
@@ -1360,7 +1873,7 @@ static int patch_vt1709_10ch(struct hda_codec *codec)
1360 int err; 1873 int err;
1361 1874
1362 /* create a codec specific record */ 1875 /* create a codec specific record */
1363 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); 1876 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1364 if (spec == NULL) 1877 if (spec == NULL)
1365 return -ENOMEM; 1878 return -ENOMEM;
1366 1879
@@ -1375,7 +1888,8 @@ static int patch_vt1709_10ch(struct hda_codec *codec)
1375 "Using genenic mode...\n"); 1888 "Using genenic mode...\n");
1376 } 1889 }
1377 1890
1378 spec->init_verbs = vt1709_10ch_volume_init_verbs; 1891 spec->init_verbs[spec->num_iverbs++] = vt1709_10ch_volume_init_verbs;
1892 spec->init_verbs[spec->num_iverbs++] = vt1709_uniwill_init_verbs;
1379 1893
1380 spec->stream_name_analog = "VT1709 Analog"; 1894 spec->stream_name_analog = "VT1709 Analog";
1381 spec->stream_analog_playback = &vt1709_10ch_pcm_analog_playback; 1895 spec->stream_analog_playback = &vt1709_10ch_pcm_analog_playback;
@@ -1396,6 +1910,7 @@ static int patch_vt1709_10ch(struct hda_codec *codec)
1396 codec->patch_ops = via_patch_ops; 1910 codec->patch_ops = via_patch_ops;
1397 1911
1398 codec->patch_ops.init = via_auto_init; 1912 codec->patch_ops.init = via_auto_init;
1913 codec->patch_ops.unsol_event = via_unsol_event;
1399#ifdef CONFIG_SND_HDA_POWER_SAVE 1914#ifdef CONFIG_SND_HDA_POWER_SAVE
1400 spec->loopback.amplist = vt1709_loopbacks; 1915 spec->loopback.amplist = vt1709_loopbacks;
1401#endif 1916#endif
@@ -1451,7 +1966,7 @@ static int patch_vt1709_6ch(struct hda_codec *codec)
1451 int err; 1966 int err;
1452 1967
1453 /* create a codec specific record */ 1968 /* create a codec specific record */
1454 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); 1969 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1455 if (spec == NULL) 1970 if (spec == NULL)
1456 return -ENOMEM; 1971 return -ENOMEM;
1457 1972
@@ -1466,7 +1981,8 @@ static int patch_vt1709_6ch(struct hda_codec *codec)
1466 "Using genenic mode...\n"); 1981 "Using genenic mode...\n");
1467 } 1982 }
1468 1983
1469 spec->init_verbs = vt1709_6ch_volume_init_verbs; 1984 spec->init_verbs[spec->num_iverbs++] = vt1709_6ch_volume_init_verbs;
1985 spec->init_verbs[spec->num_iverbs++] = vt1709_uniwill_init_verbs;
1470 1986
1471 spec->stream_name_analog = "VT1709 Analog"; 1987 spec->stream_name_analog = "VT1709 Analog";
1472 spec->stream_analog_playback = &vt1709_6ch_pcm_analog_playback; 1988 spec->stream_analog_playback = &vt1709_6ch_pcm_analog_playback;
@@ -1487,6 +2003,7 @@ static int patch_vt1709_6ch(struct hda_codec *codec)
1487 codec->patch_ops = via_patch_ops; 2003 codec->patch_ops = via_patch_ops;
1488 2004
1489 codec->patch_ops.init = via_auto_init; 2005 codec->patch_ops.init = via_auto_init;
2006 codec->patch_ops.unsol_event = via_unsol_event;
1490#ifdef CONFIG_SND_HDA_POWER_SAVE 2007#ifdef CONFIG_SND_HDA_POWER_SAVE
1491 spec->loopback.amplist = vt1709_loopbacks; 2008 spec->loopback.amplist = vt1709_loopbacks;
1492#endif 2009#endif
@@ -1586,27 +2103,32 @@ static struct hda_verb vt1708B_4ch_volume_init_verbs[] = {
1586 { } 2103 { }
1587}; 2104};
1588 2105
2106static struct hda_verb vt1708B_uniwill_init_verbs[] = {
2107 {0x1D, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_HP_EVENT},
2108 { }
2109};
2110
1589static struct hda_pcm_stream vt1708B_8ch_pcm_analog_playback = { 2111static struct hda_pcm_stream vt1708B_8ch_pcm_analog_playback = {
1590 .substreams = 1, 2112 .substreams = 2,
1591 .channels_min = 2, 2113 .channels_min = 2,
1592 .channels_max = 8, 2114 .channels_max = 8,
1593 .nid = 0x10, /* NID to query formats and rates */ 2115 .nid = 0x10, /* NID to query formats and rates */
1594 .ops = { 2116 .ops = {
1595 .open = via_playback_pcm_open, 2117 .open = via_playback_pcm_open,
1596 .prepare = via_playback_pcm_prepare, 2118 .prepare = via_playback_multi_pcm_prepare,
1597 .cleanup = via_playback_pcm_cleanup 2119 .cleanup = via_playback_multi_pcm_cleanup
1598 }, 2120 },
1599}; 2121};
1600 2122
1601static struct hda_pcm_stream vt1708B_4ch_pcm_analog_playback = { 2123static struct hda_pcm_stream vt1708B_4ch_pcm_analog_playback = {
1602 .substreams = 1, 2124 .substreams = 2,
1603 .channels_min = 2, 2125 .channels_min = 2,
1604 .channels_max = 4, 2126 .channels_max = 4,
1605 .nid = 0x10, /* NID to query formats and rates */ 2127 .nid = 0x10, /* NID to query formats and rates */
1606 .ops = { 2128 .ops = {
1607 .open = via_playback_pcm_open, 2129 .open = via_playback_pcm_open,
1608 .prepare = via_playback_pcm_prepare, 2130 .prepare = via_playback_multi_pcm_prepare,
1609 .cleanup = via_playback_pcm_cleanup 2131 .cleanup = via_playback_multi_pcm_cleanup
1610 }, 2132 },
1611}; 2133};
1612 2134
@@ -1662,10 +2184,10 @@ static int vt1708B_auto_fill_dac_nids(struct via_spec *spec,
1662 spec->multiout.dac_nids[i] = 0x24; 2184 spec->multiout.dac_nids[i] = 0x24;
1663 break; 2185 break;
1664 case AUTO_SEQ_SURROUND: 2186 case AUTO_SEQ_SURROUND:
1665 spec->multiout.dac_nids[i] = 0x25; 2187 spec->multiout.dac_nids[i] = 0x11;
1666 break; 2188 break;
1667 case AUTO_SEQ_SIDE: 2189 case AUTO_SEQ_SIDE:
1668 spec->multiout.dac_nids[i] = 0x11; 2190 spec->multiout.dac_nids[i] = 0x25;
1669 break; 2191 break;
1670 } 2192 }
1671 } 2193 }
@@ -1680,7 +2202,7 @@ static int vt1708B_auto_create_multi_out_ctls(struct via_spec *spec,
1680{ 2202{
1681 char name[32]; 2203 char name[32];
1682 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" }; 2204 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
1683 hda_nid_t nid_vols[] = {0x16, 0x27, 0x26, 0x18}; 2205 hda_nid_t nid_vols[] = {0x16, 0x18, 0x26, 0x27};
1684 hda_nid_t nid, nid_vol = 0; 2206 hda_nid_t nid, nid_vol = 0;
1685 int i, err; 2207 int i, err;
1686 2208
@@ -1785,6 +2307,8 @@ static int vt1708B_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
1785 if (err < 0) 2307 if (err < 0)
1786 return err; 2308 return err;
1787 2309
2310 create_hp_imux(spec);
2311
1788 return 0; 2312 return 0;
1789} 2313}
1790 2314
@@ -1795,7 +2319,7 @@ static int vt1708B_auto_create_analog_input_ctls(struct via_spec *spec,
1795 static char *labels[] = { 2319 static char *labels[] = {
1796 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL 2320 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
1797 }; 2321 };
1798 struct hda_input_mux *imux = &spec->private_imux; 2322 struct hda_input_mux *imux = &spec->private_imux[0];
1799 int i, err, idx = 0; 2323 int i, err, idx = 0;
1800 2324
1801 /* for internal loopback recording select */ 2325 /* for internal loopback recording select */
@@ -1869,7 +2393,10 @@ static int vt1708B_parse_auto_config(struct hda_codec *codec)
1869 if (spec->kctl_alloc) 2393 if (spec->kctl_alloc)
1870 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 2394 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
1871 2395
1872 spec->input_mux = &spec->private_imux; 2396 spec->input_mux = &spec->private_imux[0];
2397
2398 if (spec->hp_mux)
2399 spec->mixers[spec->num_mixers++] = via_hp_mixer;
1873 2400
1874 return 1; 2401 return 1;
1875} 2402}
@@ -1890,7 +2417,7 @@ static int patch_vt1708B_8ch(struct hda_codec *codec)
1890 int err; 2417 int err;
1891 2418
1892 /* create a codec specific record */ 2419 /* create a codec specific record */
1893 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); 2420 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1894 if (spec == NULL) 2421 if (spec == NULL)
1895 return -ENOMEM; 2422 return -ENOMEM;
1896 2423
@@ -1906,7 +2433,8 @@ static int patch_vt1708B_8ch(struct hda_codec *codec)
1906 "from BIOS. Using genenic mode...\n"); 2433 "from BIOS. Using genenic mode...\n");
1907 } 2434 }
1908 2435
1909 spec->init_verbs = vt1708B_8ch_volume_init_verbs; 2436 spec->init_verbs[spec->num_iverbs++] = vt1708B_8ch_volume_init_verbs;
2437 spec->init_verbs[spec->num_iverbs++] = vt1708B_uniwill_init_verbs;
1910 2438
1911 spec->stream_name_analog = "VT1708B Analog"; 2439 spec->stream_name_analog = "VT1708B Analog";
1912 spec->stream_analog_playback = &vt1708B_8ch_pcm_analog_playback; 2440 spec->stream_analog_playback = &vt1708B_8ch_pcm_analog_playback;
@@ -1926,6 +2454,7 @@ static int patch_vt1708B_8ch(struct hda_codec *codec)
1926 codec->patch_ops = via_patch_ops; 2454 codec->patch_ops = via_patch_ops;
1927 2455
1928 codec->patch_ops.init = via_auto_init; 2456 codec->patch_ops.init = via_auto_init;
2457 codec->patch_ops.unsol_event = via_unsol_event;
1929#ifdef CONFIG_SND_HDA_POWER_SAVE 2458#ifdef CONFIG_SND_HDA_POWER_SAVE
1930 spec->loopback.amplist = vt1708B_loopbacks; 2459 spec->loopback.amplist = vt1708B_loopbacks;
1931#endif 2460#endif
@@ -1939,7 +2468,7 @@ static int patch_vt1708B_4ch(struct hda_codec *codec)
1939 int err; 2468 int err;
1940 2469
1941 /* create a codec specific record */ 2470 /* create a codec specific record */
1942 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); 2471 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1943 if (spec == NULL) 2472 if (spec == NULL)
1944 return -ENOMEM; 2473 return -ENOMEM;
1945 2474
@@ -1955,7 +2484,8 @@ static int patch_vt1708B_4ch(struct hda_codec *codec)
1955 "from BIOS. Using genenic mode...\n"); 2484 "from BIOS. Using genenic mode...\n");
1956 } 2485 }
1957 2486
1958 spec->init_verbs = vt1708B_4ch_volume_init_verbs; 2487 spec->init_verbs[spec->num_iverbs++] = vt1708B_4ch_volume_init_verbs;
2488 spec->init_verbs[spec->num_iverbs++] = vt1708B_uniwill_init_verbs;
1959 2489
1960 spec->stream_name_analog = "VT1708B Analog"; 2490 spec->stream_name_analog = "VT1708B Analog";
1961 spec->stream_analog_playback = &vt1708B_4ch_pcm_analog_playback; 2491 spec->stream_analog_playback = &vt1708B_4ch_pcm_analog_playback;
@@ -1975,6 +2505,7 @@ static int patch_vt1708B_4ch(struct hda_codec *codec)
1975 codec->patch_ops = via_patch_ops; 2505 codec->patch_ops = via_patch_ops;
1976 2506
1977 codec->patch_ops.init = via_auto_init; 2507 codec->patch_ops.init = via_auto_init;
2508 codec->patch_ops.unsol_event = via_unsol_event;
1978#ifdef CONFIG_SND_HDA_POWER_SAVE 2509#ifdef CONFIG_SND_HDA_POWER_SAVE
1979 spec->loopback.amplist = vt1708B_loopbacks; 2510 spec->loopback.amplist = vt1708B_loopbacks;
1980#endif 2511#endif
@@ -1982,6 +2513,752 @@ static int patch_vt1708B_4ch(struct hda_codec *codec)
1982 return 0; 2513 return 0;
1983} 2514}
1984 2515
2516/* Patch for VT1708S */
2517
2518/* VT1708S software backdoor based override for buggy hardware micboost
2519 * setting */
2520#define MIC_BOOST_VOLUME(xname, nid) { \
2521 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2522 .name = xname, \
2523 .index = 0, \
2524 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2525 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2526 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, \
2527 .info = mic_boost_volume_info, \
2528 .get = snd_hda_mixer_amp_volume_get, \
2529 .put = snd_hda_mixer_amp_volume_put, \
2530 .tlv = { .c = mic_boost_tlv }, \
2531 .private_value = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT) }
2532
2533/* capture mixer elements */
2534static struct snd_kcontrol_new vt1708S_capture_mixer[] = {
2535 HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT),
2536 HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT),
2537 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT),
2538 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x14, 0x0, HDA_INPUT),
2539 MIC_BOOST_VOLUME("Mic Boost Capture Volume", 0x1A),
2540 MIC_BOOST_VOLUME("Front Mic Boost Capture Volume", 0x1E),
2541 {
2542 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2543 /* The multiple "Capture Source" controls confuse alsamixer
2544 * So call somewhat different..
2545 */
2546 /* .name = "Capture Source", */
2547 .name = "Input Source",
2548 .count = 1,
2549 .info = via_mux_enum_info,
2550 .get = via_mux_enum_get,
2551 .put = via_mux_enum_put,
2552 },
2553 { } /* end */
2554};
2555
2556static struct hda_verb vt1708S_volume_init_verbs[] = {
2557 /* Unmute ADC0-1 and set the default input to mic-in */
2558 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2559 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2560
2561 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the
2562 * analog-loopback mixer widget */
2563 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
2564 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2565 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2566 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
2567 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
2568 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
2569
2570 /* Setup default input of PW4 to MW0 */
2571 {0x1d, AC_VERB_SET_CONNECT_SEL, 0x0},
2572 /* PW9, PW10 Output enable */
2573 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
2574 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
2575 /* Enable Mic Boost Volume backdoor */
2576 {0x1, 0xf98, 0x1},
2577 { }
2578};
2579
2580static struct hda_verb vt1708S_uniwill_init_verbs[] = {
2581 {0x1D, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_HP_EVENT},
2582 { }
2583};
2584
2585static struct hda_pcm_stream vt1708S_pcm_analog_playback = {
2586 .substreams = 2,
2587 .channels_min = 2,
2588 .channels_max = 8,
2589 .nid = 0x10, /* NID to query formats and rates */
2590 .ops = {
2591 .open = via_playback_pcm_open,
2592 .prepare = via_playback_pcm_prepare,
2593 .cleanup = via_playback_pcm_cleanup
2594 },
2595};
2596
2597static struct hda_pcm_stream vt1708S_pcm_analog_capture = {
2598 .substreams = 2,
2599 .channels_min = 2,
2600 .channels_max = 2,
2601 .nid = 0x13, /* NID to query formats and rates */
2602 .ops = {
2603 .prepare = via_capture_pcm_prepare,
2604 .cleanup = via_capture_pcm_cleanup
2605 },
2606};
2607
2608static struct hda_pcm_stream vt1708S_pcm_digital_playback = {
2609 .substreams = 2,
2610 .channels_min = 2,
2611 .channels_max = 2,
2612 /* NID is set in via_build_pcms */
2613 .ops = {
2614 .open = via_dig_playback_pcm_open,
2615 .close = via_dig_playback_pcm_close,
2616 .prepare = via_dig_playback_pcm_prepare
2617 },
2618};
2619
2620/* fill in the dac_nids table from the parsed pin configuration */
2621static int vt1708S_auto_fill_dac_nids(struct via_spec *spec,
2622 const struct auto_pin_cfg *cfg)
2623{
2624 int i;
2625 hda_nid_t nid;
2626
2627 spec->multiout.num_dacs = cfg->line_outs;
2628
2629 spec->multiout.dac_nids = spec->private_dac_nids;
2630
2631 for (i = 0; i < 4; i++) {
2632 nid = cfg->line_out_pins[i];
2633 if (nid) {
2634 /* config dac list */
2635 switch (i) {
2636 case AUTO_SEQ_FRONT:
2637 spec->multiout.dac_nids[i] = 0x10;
2638 break;
2639 case AUTO_SEQ_CENLFE:
2640 spec->multiout.dac_nids[i] = 0x24;
2641 break;
2642 case AUTO_SEQ_SURROUND:
2643 spec->multiout.dac_nids[i] = 0x11;
2644 break;
2645 case AUTO_SEQ_SIDE:
2646 spec->multiout.dac_nids[i] = 0x25;
2647 break;
2648 }
2649 }
2650 }
2651
2652 return 0;
2653}
2654
2655/* add playback controls from the parsed DAC table */
2656static int vt1708S_auto_create_multi_out_ctls(struct via_spec *spec,
2657 const struct auto_pin_cfg *cfg)
2658{
2659 char name[32];
2660 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
2661 hda_nid_t nid_vols[] = {0x10, 0x11, 0x24, 0x25};
2662 hda_nid_t nid_mutes[] = {0x1C, 0x18, 0x26, 0x27};
2663 hda_nid_t nid, nid_vol, nid_mute;
2664 int i, err;
2665
2666 for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
2667 nid = cfg->line_out_pins[i];
2668
2669 if (!nid)
2670 continue;
2671
2672 nid_vol = nid_vols[i];
2673 nid_mute = nid_mutes[i];
2674
2675 if (i == AUTO_SEQ_CENLFE) {
2676 /* Center/LFE */
2677 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2678 "Center Playback Volume",
2679 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
2680 HDA_OUTPUT));
2681 if (err < 0)
2682 return err;
2683 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2684 "LFE Playback Volume",
2685 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
2686 HDA_OUTPUT));
2687 if (err < 0)
2688 return err;
2689 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2690 "Center Playback Switch",
2691 HDA_COMPOSE_AMP_VAL(nid_mute,
2692 1, 0,
2693 HDA_OUTPUT));
2694 if (err < 0)
2695 return err;
2696 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2697 "LFE Playback Switch",
2698 HDA_COMPOSE_AMP_VAL(nid_mute,
2699 2, 0,
2700 HDA_OUTPUT));
2701 if (err < 0)
2702 return err;
2703 } else if (i == AUTO_SEQ_FRONT) {
2704 /* add control to mixer index 0 */
2705 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2706 "Master Front Playback Volume",
2707 HDA_COMPOSE_AMP_VAL(0x16, 3, 0,
2708 HDA_INPUT));
2709 if (err < 0)
2710 return err;
2711 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2712 "Master Front Playback Switch",
2713 HDA_COMPOSE_AMP_VAL(0x16, 3, 0,
2714 HDA_INPUT));
2715 if (err < 0)
2716 return err;
2717
2718 /* Front */
2719 sprintf(name, "%s Playback Volume", chname[i]);
2720 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2721 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2722 HDA_OUTPUT));
2723 if (err < 0)
2724 return err;
2725 sprintf(name, "%s Playback Switch", chname[i]);
2726 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2727 HDA_COMPOSE_AMP_VAL(nid_mute,
2728 3, 0,
2729 HDA_OUTPUT));
2730 if (err < 0)
2731 return err;
2732 } else {
2733 sprintf(name, "%s Playback Volume", chname[i]);
2734 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2735 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2736 HDA_OUTPUT));
2737 if (err < 0)
2738 return err;
2739 sprintf(name, "%s Playback Switch", chname[i]);
2740 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2741 HDA_COMPOSE_AMP_VAL(nid_mute,
2742 3, 0,
2743 HDA_OUTPUT));
2744 if (err < 0)
2745 return err;
2746 }
2747 }
2748
2749 return 0;
2750}
2751
2752static int vt1708S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
2753{
2754 int err;
2755
2756 if (!pin)
2757 return 0;
2758
2759 spec->multiout.hp_nid = VT1708S_HP_NID; /* AOW3 */
2760
2761 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2762 "Headphone Playback Volume",
2763 HDA_COMPOSE_AMP_VAL(0x25, 3, 0, HDA_OUTPUT));
2764 if (err < 0)
2765 return err;
2766
2767 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2768 "Headphone Playback Switch",
2769 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
2770 if (err < 0)
2771 return err;
2772
2773 create_hp_imux(spec);
2774
2775 return 0;
2776}
2777
2778/* create playback/capture controls for input pins */
2779static int vt1708S_auto_create_analog_input_ctls(struct via_spec *spec,
2780 const struct auto_pin_cfg *cfg)
2781{
2782 static char *labels[] = {
2783 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
2784 };
2785 struct hda_input_mux *imux = &spec->private_imux[0];
2786 int i, err, idx = 0;
2787
2788 /* for internal loopback recording select */
2789 imux->items[imux->num_items].label = "Stereo Mixer";
2790 imux->items[imux->num_items].index = 5;
2791 imux->num_items++;
2792
2793 for (i = 0; i < AUTO_PIN_LAST; i++) {
2794 if (!cfg->input_pins[i])
2795 continue;
2796
2797 switch (cfg->input_pins[i]) {
2798 case 0x1a: /* Mic */
2799 idx = 2;
2800 break;
2801
2802 case 0x1b: /* Line In */
2803 idx = 3;
2804 break;
2805
2806 case 0x1e: /* Front Mic */
2807 idx = 4;
2808 break;
2809
2810 case 0x1f: /* CD */
2811 idx = 1;
2812 break;
2813 }
2814 err = via_new_analog_input(spec, cfg->input_pins[i], labels[i],
2815 idx, 0x16);
2816 if (err < 0)
2817 return err;
2818 imux->items[imux->num_items].label = labels[i];
2819 imux->items[imux->num_items].index = idx-1;
2820 imux->num_items++;
2821 }
2822 return 0;
2823}
2824
2825static int vt1708S_parse_auto_config(struct hda_codec *codec)
2826{
2827 struct via_spec *spec = codec->spec;
2828 int err;
2829 static hda_nid_t vt1708s_ignore[] = {0x21, 0};
2830
2831 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
2832 vt1708s_ignore);
2833 if (err < 0)
2834 return err;
2835 err = vt1708S_auto_fill_dac_nids(spec, &spec->autocfg);
2836 if (err < 0)
2837 return err;
2838 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
2839 return 0; /* can't find valid BIOS pin config */
2840
2841 err = vt1708S_auto_create_multi_out_ctls(spec, &spec->autocfg);
2842 if (err < 0)
2843 return err;
2844 err = vt1708S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
2845 if (err < 0)
2846 return err;
2847 err = vt1708S_auto_create_analog_input_ctls(spec, &spec->autocfg);
2848 if (err < 0)
2849 return err;
2850
2851 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
2852
2853 if (spec->autocfg.dig_out_pin)
2854 spec->multiout.dig_out_nid = VT1708S_DIGOUT_NID;
2855
2856 spec->extra_dig_out_nid = 0x15;
2857
2858 if (spec->kctl_alloc)
2859 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
2860
2861 spec->input_mux = &spec->private_imux[0];
2862
2863 if (spec->hp_mux)
2864 spec->mixers[spec->num_mixers++] = via_hp_mixer;
2865
2866 return 1;
2867}
2868
2869#ifdef CONFIG_SND_HDA_POWER_SAVE
2870static struct hda_amp_list vt1708S_loopbacks[] = {
2871 { 0x16, HDA_INPUT, 1 },
2872 { 0x16, HDA_INPUT, 2 },
2873 { 0x16, HDA_INPUT, 3 },
2874 { 0x16, HDA_INPUT, 4 },
2875 { } /* end */
2876};
2877#endif
2878
2879static int patch_vt1708S(struct hda_codec *codec)
2880{
2881 struct via_spec *spec;
2882 int err;
2883
2884 /* create a codec specific record */
2885 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2886 if (spec == NULL)
2887 return -ENOMEM;
2888
2889 codec->spec = spec;
2890
2891 /* automatic parse from the BIOS config */
2892 err = vt1708S_parse_auto_config(codec);
2893 if (err < 0) {
2894 via_free(codec);
2895 return err;
2896 } else if (!err) {
2897 printk(KERN_INFO "hda_codec: Cannot set up configuration "
2898 "from BIOS. Using genenic mode...\n");
2899 }
2900
2901 spec->init_verbs[spec->num_iverbs++] = vt1708S_volume_init_verbs;
2902 spec->init_verbs[spec->num_iverbs++] = vt1708S_uniwill_init_verbs;
2903
2904 spec->stream_name_analog = "VT1708S Analog";
2905 spec->stream_analog_playback = &vt1708S_pcm_analog_playback;
2906 spec->stream_analog_capture = &vt1708S_pcm_analog_capture;
2907
2908 spec->stream_name_digital = "VT1708S Digital";
2909 spec->stream_digital_playback = &vt1708S_pcm_digital_playback;
2910
2911 if (!spec->adc_nids && spec->input_mux) {
2912 spec->adc_nids = vt1708S_adc_nids;
2913 spec->num_adc_nids = ARRAY_SIZE(vt1708S_adc_nids);
2914 spec->mixers[spec->num_mixers] = vt1708S_capture_mixer;
2915 spec->num_mixers++;
2916 }
2917
2918 codec->patch_ops = via_patch_ops;
2919
2920 codec->patch_ops.init = via_auto_init;
2921 codec->patch_ops.unsol_event = via_unsol_event;
2922#ifdef CONFIG_SND_HDA_POWER_SAVE
2923 spec->loopback.amplist = vt1708S_loopbacks;
2924#endif
2925
2926 return 0;
2927}
2928
2929/* Patch for VT1702 */
2930
2931/* capture mixer elements */
2932static struct snd_kcontrol_new vt1702_capture_mixer[] = {
2933 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_INPUT),
2934 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_INPUT),
2935 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x20, 0x0, HDA_INPUT),
2936 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x20, 0x0, HDA_INPUT),
2937 HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x1F, 0x0, HDA_INPUT),
2938 HDA_CODEC_MUTE("Digital Mic Capture Switch", 0x1F, 0x0, HDA_INPUT),
2939 HDA_CODEC_VOLUME("Digital Mic Boost Capture Volume", 0x1E, 0x0,
2940 HDA_INPUT),
2941 {
2942 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2943 /* The multiple "Capture Source" controls confuse alsamixer
2944 * So call somewhat different..
2945 */
2946 /* .name = "Capture Source", */
2947 .name = "Input Source",
2948 .count = 1,
2949 .info = via_mux_enum_info,
2950 .get = via_mux_enum_get,
2951 .put = via_mux_enum_put,
2952 },
2953 { } /* end */
2954};
2955
2956static struct hda_verb vt1702_volume_init_verbs[] = {
2957 /*
2958 * Unmute ADC0-1 and set the default input to mic-in
2959 */
2960 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2961 {0x1F, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2962 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2963
2964
2965 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2966 * mixer widget
2967 */
2968 /* Amp Indices: Mic1 = 1, Line = 1, Mic2 = 3 */
2969 {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2970 {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2971 {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
2972 {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
2973 {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2974
2975 /* Setup default input of PW4 to MW0 */
2976 {0x17, AC_VERB_SET_CONNECT_SEL, 0x1},
2977 /* PW6 PW7 Output enable */
2978 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
2979 {0x1C, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
2980 { }
2981};
2982
2983static struct hda_verb vt1702_uniwill_init_verbs[] = {
2984 {0x01, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_GPIO_EVENT},
2985 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_HP_EVENT},
2986 { }
2987};
2988
2989static struct hda_pcm_stream vt1702_pcm_analog_playback = {
2990 .substreams = 2,
2991 .channels_min = 2,
2992 .channels_max = 2,
2993 .nid = 0x10, /* NID to query formats and rates */
2994 .ops = {
2995 .open = via_playback_pcm_open,
2996 .prepare = via_playback_multi_pcm_prepare,
2997 .cleanup = via_playback_multi_pcm_cleanup
2998 },
2999};
3000
3001static struct hda_pcm_stream vt1702_pcm_analog_capture = {
3002 .substreams = 3,
3003 .channels_min = 2,
3004 .channels_max = 2,
3005 .nid = 0x12, /* NID to query formats and rates */
3006 .ops = {
3007 .prepare = via_capture_pcm_prepare,
3008 .cleanup = via_capture_pcm_cleanup
3009 },
3010};
3011
3012static struct hda_pcm_stream vt1702_pcm_digital_playback = {
3013 .substreams = 2,
3014 .channels_min = 2,
3015 .channels_max = 2,
3016 /* NID is set in via_build_pcms */
3017 .ops = {
3018 .open = via_dig_playback_pcm_open,
3019 .close = via_dig_playback_pcm_close,
3020 .prepare = via_dig_playback_pcm_prepare
3021 },
3022};
3023
3024/* fill in the dac_nids table from the parsed pin configuration */
3025static int vt1702_auto_fill_dac_nids(struct via_spec *spec,
3026 const struct auto_pin_cfg *cfg)
3027{
3028 spec->multiout.num_dacs = 1;
3029 spec->multiout.dac_nids = spec->private_dac_nids;
3030
3031 if (cfg->line_out_pins[0]) {
3032 /* config dac list */
3033 spec->multiout.dac_nids[0] = 0x10;
3034 }
3035
3036 return 0;
3037}
3038
3039/* add playback controls from the parsed DAC table */
3040static int vt1702_auto_create_line_out_ctls(struct via_spec *spec,
3041 const struct auto_pin_cfg *cfg)
3042{
3043 int err;
3044
3045 if (!cfg->line_out_pins[0])
3046 return -1;
3047
3048 /* add control to mixer index 0 */
3049 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3050 "Master Front Playback Volume",
3051 HDA_COMPOSE_AMP_VAL(0x1A, 3, 0, HDA_INPUT));
3052 if (err < 0)
3053 return err;
3054 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3055 "Master Front Playback Switch",
3056 HDA_COMPOSE_AMP_VAL(0x1A, 3, 0, HDA_INPUT));
3057 if (err < 0)
3058 return err;
3059
3060 /* Front */
3061 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3062 "Front Playback Volume",
3063 HDA_COMPOSE_AMP_VAL(0x10, 3, 0, HDA_OUTPUT));
3064 if (err < 0)
3065 return err;
3066 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3067 "Front Playback Switch",
3068 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT));
3069 if (err < 0)
3070 return err;
3071
3072 return 0;
3073}
3074
3075static int vt1702_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
3076{
3077 int err;
3078
3079 if (!pin)
3080 return 0;
3081
3082 spec->multiout.hp_nid = 0x1D;
3083
3084 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3085 "Headphone Playback Volume",
3086 HDA_COMPOSE_AMP_VAL(0x1D, 3, 0, HDA_OUTPUT));
3087 if (err < 0)
3088 return err;
3089
3090 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3091 "Headphone Playback Switch",
3092 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3093 if (err < 0)
3094 return err;
3095
3096 create_hp_imux(spec);
3097
3098 return 0;
3099}
3100
3101/* create playback/capture controls for input pins */
3102static int vt1702_auto_create_analog_input_ctls(struct via_spec *spec,
3103 const struct auto_pin_cfg *cfg)
3104{
3105 static char *labels[] = {
3106 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
3107 };
3108 struct hda_input_mux *imux = &spec->private_imux[0];
3109 int i, err, idx = 0;
3110
3111 /* for internal loopback recording select */
3112 imux->items[imux->num_items].label = "Stereo Mixer";
3113 imux->items[imux->num_items].index = 3;
3114 imux->num_items++;
3115
3116 for (i = 0; i < AUTO_PIN_LAST; i++) {
3117 if (!cfg->input_pins[i])
3118 continue;
3119
3120 switch (cfg->input_pins[i]) {
3121 case 0x14: /* Mic */
3122 idx = 1;
3123 break;
3124
3125 case 0x15: /* Line In */
3126 idx = 2;
3127 break;
3128
3129 case 0x18: /* Front Mic */
3130 idx = 3;
3131 break;
3132 }
3133 err = via_new_analog_input(spec, cfg->input_pins[i],
3134 labels[i], idx, 0x1A);
3135 if (err < 0)
3136 return err;
3137 imux->items[imux->num_items].label = labels[i];
3138 imux->items[imux->num_items].index = idx-1;
3139 imux->num_items++;
3140 }
3141 return 0;
3142}
3143
3144static int vt1702_parse_auto_config(struct hda_codec *codec)
3145{
3146 struct via_spec *spec = codec->spec;
3147 int err;
3148 static hda_nid_t vt1702_ignore[] = {0x1C, 0};
3149
3150 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3151 vt1702_ignore);
3152 if (err < 0)
3153 return err;
3154 err = vt1702_auto_fill_dac_nids(spec, &spec->autocfg);
3155 if (err < 0)
3156 return err;
3157 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
3158 return 0; /* can't find valid BIOS pin config */
3159
3160 err = vt1702_auto_create_line_out_ctls(spec, &spec->autocfg);
3161 if (err < 0)
3162 return err;
3163 err = vt1702_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
3164 if (err < 0)
3165 return err;
3166 err = vt1702_auto_create_analog_input_ctls(spec, &spec->autocfg);
3167 if (err < 0)
3168 return err;
3169
3170 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3171
3172 if (spec->autocfg.dig_out_pin)
3173 spec->multiout.dig_out_nid = VT1702_DIGOUT_NID;
3174
3175 spec->extra_dig_out_nid = 0x1B;
3176
3177 if (spec->kctl_alloc)
3178 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
3179
3180 spec->input_mux = &spec->private_imux[0];
3181
3182 if (spec->hp_mux)
3183 spec->mixers[spec->num_mixers++] = via_hp_mixer;
3184
3185 return 1;
3186}
3187
3188#ifdef CONFIG_SND_HDA_POWER_SAVE
3189static struct hda_amp_list vt1702_loopbacks[] = {
3190 { 0x1A, HDA_INPUT, 1 },
3191 { 0x1A, HDA_INPUT, 2 },
3192 { 0x1A, HDA_INPUT, 3 },
3193 { 0x1A, HDA_INPUT, 4 },
3194 { } /* end */
3195};
3196#endif
3197
3198static int patch_vt1702(struct hda_codec *codec)
3199{
3200 struct via_spec *spec;
3201 int err;
3202 unsigned int response;
3203 unsigned char control;
3204
3205 /* create a codec specific record */
3206 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3207 if (spec == NULL)
3208 return -ENOMEM;
3209
3210 codec->spec = spec;
3211
3212 /* automatic parse from the BIOS config */
3213 err = vt1702_parse_auto_config(codec);
3214 if (err < 0) {
3215 via_free(codec);
3216 return err;
3217 } else if (!err) {
3218 printk(KERN_INFO "hda_codec: Cannot set up configuration "
3219 "from BIOS. Using genenic mode...\n");
3220 }
3221
3222 spec->init_verbs[spec->num_iverbs++] = vt1702_volume_init_verbs;
3223 spec->init_verbs[spec->num_iverbs++] = vt1702_uniwill_init_verbs;
3224
3225 spec->stream_name_analog = "VT1702 Analog";
3226 spec->stream_analog_playback = &vt1702_pcm_analog_playback;
3227 spec->stream_analog_capture = &vt1702_pcm_analog_capture;
3228
3229 spec->stream_name_digital = "VT1702 Digital";
3230 spec->stream_digital_playback = &vt1702_pcm_digital_playback;
3231
3232 if (!spec->adc_nids && spec->input_mux) {
3233 spec->adc_nids = vt1702_adc_nids;
3234 spec->num_adc_nids = ARRAY_SIZE(vt1702_adc_nids);
3235 spec->mixers[spec->num_mixers] = vt1702_capture_mixer;
3236 spec->num_mixers++;
3237 }
3238
3239 codec->patch_ops = via_patch_ops;
3240
3241 codec->patch_ops.init = via_auto_init;
3242 codec->patch_ops.unsol_event = via_unsol_event;
3243#ifdef CONFIG_SND_HDA_POWER_SAVE
3244 spec->loopback.amplist = vt1702_loopbacks;
3245#endif
3246
3247 /* Open backdoor */
3248 response = snd_hda_codec_read(codec, codec->afg, 0, 0xF8C, 0);
3249 control = (unsigned char)(response & 0xff);
3250 control |= 0x3;
3251 snd_hda_codec_write(codec, codec->afg, 0, 0xF88, control);
3252
3253 /* Enable GPIO 0&1 for volume&mute control */
3254 /* Enable GPIO 2 for DMIC-DATA */
3255 response = snd_hda_codec_read(codec, codec->afg, 0, 0xF84, 0);
3256 control = (unsigned char)((response >> 16) & 0x3f);
3257 snd_hda_codec_write(codec, codec->afg, 0, 0xF82, control);
3258
3259 return 0;
3260}
3261
1985/* 3262/*
1986 * patch entries 3263 * patch entries
1987 */ 3264 */
@@ -2022,5 +3299,37 @@ struct hda_codec_preset snd_hda_preset_via[] = {
2022 .patch = patch_vt1708B_4ch}, 3299 .patch = patch_vt1708B_4ch},
2023 { .id = 0x1106E727, .name = "VIA VT1708B 4-Ch", 3300 { .id = 0x1106E727, .name = "VIA VT1708B 4-Ch",
2024 .patch = patch_vt1708B_4ch}, 3301 .patch = patch_vt1708B_4ch},
3302 { .id = 0x11060397, .name = "VIA VT1708S",
3303 .patch = patch_vt1708S},
3304 { .id = 0x11061397, .name = "VIA VT1708S",
3305 .patch = patch_vt1708S},
3306 { .id = 0x11062397, .name = "VIA VT1708S",
3307 .patch = patch_vt1708S},
3308 { .id = 0x11063397, .name = "VIA VT1708S",
3309 .patch = patch_vt1708S},
3310 { .id = 0x11064397, .name = "VIA VT1708S",
3311 .patch = patch_vt1708S},
3312 { .id = 0x11065397, .name = "VIA VT1708S",
3313 .patch = patch_vt1708S},
3314 { .id = 0x11066397, .name = "VIA VT1708S",
3315 .patch = patch_vt1708S},
3316 { .id = 0x11067397, .name = "VIA VT1708S",
3317 .patch = patch_vt1708S},
3318 { .id = 0x11060398, .name = "VIA VT1702",
3319 .patch = patch_vt1702},
3320 { .id = 0x11061398, .name = "VIA VT1702",
3321 .patch = patch_vt1702},
3322 { .id = 0x11062398, .name = "VIA VT1702",
3323 .patch = patch_vt1702},
3324 { .id = 0x11063398, .name = "VIA VT1702",
3325 .patch = patch_vt1702},
3326 { .id = 0x11064398, .name = "VIA VT1702",
3327 .patch = patch_vt1702},
3328 { .id = 0x11065398, .name = "VIA VT1702",
3329 .patch = patch_vt1702},
3330 { .id = 0x11066398, .name = "VIA VT1702",
3331 .patch = patch_vt1702},
3332 { .id = 0x11067398, .name = "VIA VT1702",
3333 .patch = patch_vt1702},
2025 {} /* terminator */ 3334 {} /* terminator */
2026}; 3335};
diff --git a/sound/pci/ice1712/ak4xxx.c b/sound/pci/ice1712/ak4xxx.c
index dab31b2756a6..03391da8c8c7 100644
--- a/sound/pci/ice1712/ak4xxx.c
+++ b/sound/pci/ice1712/ak4xxx.c
@@ -59,7 +59,8 @@ static void snd_ice1712_akm4xxx_write(struct snd_akm4xxx *ak, int chip,
59 struct snd_ak4xxx_private *priv = (void *)ak->private_value[0]; 59 struct snd_ak4xxx_private *priv = (void *)ak->private_value[0];
60 struct snd_ice1712 *ice = ak->private_data[0]; 60 struct snd_ice1712 *ice = ak->private_data[0];
61 61
62 snd_assert(chip >= 0 && chip < 4, return); 62 if (snd_BUG_ON(chip < 0 || chip >= 4))
63 return;
63 64
64 tmp = snd_ice1712_gpio_read(ice); 65 tmp = snd_ice1712_gpio_read(ice);
65 tmp |= priv->add_flags; 66 tmp |= priv->add_flags;
diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c
index 868ae291b960..110d16e52733 100644
--- a/sound/pci/ice1712/aureon.c
+++ b/sound/pci/ice1712/aureon.c
@@ -44,10 +44,9 @@
44 * not working: prety much everything else, at least i could verify that 44 * not working: prety much everything else, at least i could verify that
45 * we have no digital output, no capture, pretty bad clicks and poops 45 * we have no digital output, no capture, pretty bad clicks and poops
46 * on mixer switch and other coll stuff. 46 * on mixer switch and other coll stuff.
47 * 47 */
48 */
49 48
50#include <asm/io.h> 49#include <linux/io.h>
51#include <linux/delay.h> 50#include <linux/delay.h>
52#include <linux/interrupt.h> 51#include <linux/interrupt.h>
53#include <linux/init.h> 52#include <linux/init.h>
@@ -131,7 +130,7 @@ static void aureon_pca9554_write(struct snd_ice1712 *ice, unsigned char reg,
131 snd_ice1712_gpio_write(ice, tmp); 130 snd_ice1712_gpio_write(ice, tmp);
132 udelay(50); 131 udelay(50);
133 132
134 /* 133 /*
135 * send i2c stop condition and start condition 134 * send i2c stop condition and start condition
136 * to obtain sane state 135 * to obtain sane state
137 */ 136 */
@@ -152,10 +151,16 @@ static void aureon_pca9554_write(struct snd_ice1712 *ice, unsigned char reg,
152 * skipping ack cycles inbetween 151 * skipping ack cycles inbetween
153 */ 152 */
154 for (j = 0; j < 3; j++) { 153 for (j = 0; j < 3; j++) {
155 switch(j) { 154 switch (j) {
156 case 0: val = dev; break; 155 case 0:
157 case 1: val = reg; break; 156 val = dev;
158 case 2: val = data; break; 157 break;
158 case 1:
159 val = reg;
160 break;
161 case 2:
162 val = data;
163 break;
159 } 164 }
160 for (i = 7; i >= 0; i--) { 165 for (i = 7; i >= 0; i--) {
161 tmp &= ~AUREON_SPI_CLK; 166 tmp &= ~AUREON_SPI_CLK;
@@ -171,7 +176,7 @@ static void aureon_pca9554_write(struct snd_ice1712 *ice, unsigned char reg,
171 snd_ice1712_gpio_write(ice, tmp); 176 snd_ice1712_gpio_write(ice, tmp);
172 udelay(40); 177 udelay(40);
173 } 178 }
174 tmp &= ~AUREON_SPI_CLK; 179 tmp &= ~AUREON_SPI_CLK;
175 snd_ice1712_gpio_write(ice, tmp); 180 snd_ice1712_gpio_write(ice, tmp);
176 udelay(40); 181 udelay(40);
177 tmp |= AUREON_SPI_CLK; 182 tmp |= AUREON_SPI_CLK;
@@ -203,7 +208,7 @@ static int aureon_universe_inmux_info(struct snd_kcontrol *kcontrol,
203 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 208 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
204 uinfo->count = 1; 209 uinfo->count = 1;
205 uinfo->value.enumerated.items = 3; 210 uinfo->value.enumerated.items = 3;
206 if(uinfo->value.enumerated.item >= uinfo->value.enumerated.items) 211 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
207 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; 212 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
208 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 213 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
209 return 0; 214 return 0;
@@ -231,12 +236,12 @@ static int aureon_universe_inmux_put(struct snd_kcontrol *kcontrol,
231 return -EINVAL; 236 return -EINVAL;
232 snd_ice1712_save_gpio_status(ice); 237 snd_ice1712_save_gpio_status(ice);
233 oval = spec->pca9554_out; 238 oval = spec->pca9554_out;
234 if ((change = (oval != nval))) { 239 change = (oval != nval);
240 if (change) {
235 aureon_pca9554_write(ice, PCA9554_OUT, nval); 241 aureon_pca9554_write(ice, PCA9554_OUT, nval);
236 spec->pca9554_out = nval; 242 spec->pca9554_out = nval;
237 } 243 }
238 snd_ice1712_restore_gpio_status(ice); 244 snd_ice1712_restore_gpio_status(ice);
239
240 return change; 245 return change;
241} 246}
242 247
@@ -256,7 +261,7 @@ static void aureon_ac97_write(struct snd_ice1712 *ice, unsigned short reg,
256 udelay(10); 261 udelay(10);
257 tmp &= ~AUREON_AC97_ADDR; 262 tmp &= ~AUREON_AC97_ADDR;
258 snd_ice1712_gpio_write(ice, tmp); 263 snd_ice1712_gpio_write(ice, tmp);
259 udelay(10); 264 udelay(10);
260 265
261 /* Send low-order byte to XILINX chip */ 266 /* Send low-order byte to XILINX chip */
262 tmp &= ~AUREON_AC97_DATA_MASK; 267 tmp &= ~AUREON_AC97_DATA_MASK;
@@ -269,7 +274,7 @@ static void aureon_ac97_write(struct snd_ice1712 *ice, unsigned short reg,
269 tmp &= ~AUREON_AC97_DATA_LOW; 274 tmp &= ~AUREON_AC97_DATA_LOW;
270 snd_ice1712_gpio_write(ice, tmp); 275 snd_ice1712_gpio_write(ice, tmp);
271 udelay(10); 276 udelay(10);
272 277
273 /* Send high-order byte to XILINX chip */ 278 /* Send high-order byte to XILINX chip */
274 tmp &= ~AUREON_AC97_DATA_MASK; 279 tmp &= ~AUREON_AC97_DATA_MASK;
275 tmp |= (val >> 8) & AUREON_AC97_DATA_MASK; 280 tmp |= (val >> 8) & AUREON_AC97_DATA_MASK;
@@ -282,7 +287,7 @@ static void aureon_ac97_write(struct snd_ice1712 *ice, unsigned short reg,
282 tmp &= ~AUREON_AC97_DATA_HIGH; 287 tmp &= ~AUREON_AC97_DATA_HIGH;
283 snd_ice1712_gpio_write(ice, tmp); 288 snd_ice1712_gpio_write(ice, tmp);
284 udelay(10); 289 udelay(10);
285 290
286 /* Instruct XILINX chip to parse the data to the STAC9744 chip */ 291 /* Instruct XILINX chip to parse the data to the STAC9744 chip */
287 tmp |= AUREON_AC97_COMMIT; 292 tmp |= AUREON_AC97_COMMIT;
288 snd_ice1712_gpio_write(ice, tmp); 293 snd_ice1712_gpio_write(ice, tmp);
@@ -290,7 +295,7 @@ static void aureon_ac97_write(struct snd_ice1712 *ice, unsigned short reg,
290 tmp &= ~AUREON_AC97_COMMIT; 295 tmp &= ~AUREON_AC97_COMMIT;
291 snd_ice1712_gpio_write(ice, tmp); 296 snd_ice1712_gpio_write(ice, tmp);
292 udelay(10); 297 udelay(10);
293 298
294 /* Store the data in out private buffer */ 299 /* Store the data in out private buffer */
295 spec->stac9744[(reg & 0x7F) >> 1] = val; 300 spec->stac9744[(reg & 0x7F) >> 1] = val;
296} 301}
@@ -304,7 +309,7 @@ static unsigned short aureon_ac97_read(struct snd_ice1712 *ice, unsigned short r
304/* 309/*
305 * Initialize STAC9744 chip 310 * Initialize STAC9744 chip
306 */ 311 */
307static int aureon_ac97_init (struct snd_ice1712 *ice) 312static int aureon_ac97_init(struct snd_ice1712 *ice)
308{ 313{
309 struct aureon_spec *spec = ice->spec; 314 struct aureon_spec *spec = ice->spec;
310 int i; 315 int i;
@@ -335,20 +340,21 @@ static int aureon_ac97_init (struct snd_ice1712 *ice)
335 tmp = (snd_ice1712_gpio_read(ice) | AUREON_AC97_RESET) & ~AUREON_AC97_DATA_MASK; 340 tmp = (snd_ice1712_gpio_read(ice) | AUREON_AC97_RESET) & ~AUREON_AC97_DATA_MASK;
336 snd_ice1712_gpio_write(ice, tmp); 341 snd_ice1712_gpio_write(ice, tmp);
337 udelay(3); 342 udelay(3);
338 343
339 tmp &= ~AUREON_AC97_RESET; 344 tmp &= ~AUREON_AC97_RESET;
340 snd_ice1712_gpio_write(ice, tmp); 345 snd_ice1712_gpio_write(ice, tmp);
341 udelay(3); 346 udelay(3);
342 347
343 tmp |= AUREON_AC97_RESET; 348 tmp |= AUREON_AC97_RESET;
344 snd_ice1712_gpio_write(ice, tmp); 349 snd_ice1712_gpio_write(ice, tmp);
345 udelay(3); 350 udelay(3);
346 351
347 memset(&spec->stac9744, 0, sizeof(spec->stac9744)); 352 memset(&spec->stac9744, 0, sizeof(spec->stac9744));
348 for (i=0; ac97_defaults[i] != (unsigned short)-1; i+=2) 353 for (i = 0; ac97_defaults[i] != (unsigned short)-1; i += 2)
349 spec->stac9744[(ac97_defaults[i]) >> 1] = ac97_defaults[i+1]; 354 spec->stac9744[(ac97_defaults[i]) >> 1] = ac97_defaults[i+1];
350 355
351 aureon_ac97_write(ice, AC97_MASTER, 0x0000); // Unmute AC'97 master volume permanently - muting is done by WM8770 356 /* Unmute AC'97 master volume permanently - muting is done by WM8770 */
357 aureon_ac97_write(ice, AC97_MASTER, 0x0000);
352 358
353 return 0; 359 return 0;
354} 360}
@@ -388,7 +394,7 @@ static int aureon_ac97_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ele
388 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 394 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
389 unsigned short ovol, nvol; 395 unsigned short ovol, nvol;
390 int change; 396 int change;
391 397
392 snd_ice1712_save_gpio_status(ice); 398 snd_ice1712_save_gpio_status(ice);
393 399
394 ovol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F); 400 ovol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F);
@@ -396,13 +402,14 @@ static int aureon_ac97_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ele
396 if (kcontrol->private_value & AUREON_AC97_STEREO) 402 if (kcontrol->private_value & AUREON_AC97_STEREO)
397 nvol |= ((0x1F - ucontrol->value.integer.value[1]) << 8) & 0x1F00; 403 nvol |= ((0x1F - ucontrol->value.integer.value[1]) << 8) & 0x1F00;
398 nvol |= ovol & ~0x1F1F; 404 nvol |= ovol & ~0x1F1F;
399 405
400 if ((change = (ovol != nvol))) 406 change = (ovol != nvol);
407 if (change)
401 aureon_ac97_write(ice, kcontrol->private_value & 0x7F, nvol); 408 aureon_ac97_write(ice, kcontrol->private_value & 0x7F, nvol);
402 409
403 snd_ice1712_restore_gpio_status(ice); 410 snd_ice1712_restore_gpio_status(ice);
404 411
405 return change; 412 return change;
406} 413}
407 414
408/* 415/*
@@ -416,7 +423,8 @@ static int aureon_ac97_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_el
416 423
417 mutex_lock(&ice->gpio_mutex); 424 mutex_lock(&ice->gpio_mutex);
418 425
419 ucontrol->value.integer.value[0] = aureon_ac97_read(ice, kcontrol->private_value & 0x7F) & 0x8000 ? 0 : 1; 426 ucontrol->value.integer.value[0] = aureon_ac97_read(ice,
427 kcontrol->private_value & 0x7F) & 0x8000 ? 0 : 1;
420 428
421 mutex_unlock(&ice->gpio_mutex); 429 mutex_unlock(&ice->gpio_mutex);
422 return 0; 430 return 0;
@@ -429,13 +437,14 @@ static int aureon_ac97_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_el
429 int change; 437 int change;
430 438
431 snd_ice1712_save_gpio_status(ice); 439 snd_ice1712_save_gpio_status(ice);
432 440
433 ovol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F); 441 ovol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F);
434 nvol = (ucontrol->value.integer.value[0] ? 0x0000 : 0x8000) | (ovol & ~ 0x8000); 442 nvol = (ucontrol->value.integer.value[0] ? 0x0000 : 0x8000) | (ovol & ~0x8000);
435 443
436 if ((change = (ovol != nvol))) 444 change = (ovol != nvol);
445 if (change)
437 aureon_ac97_write(ice, kcontrol->private_value & 0x7F, nvol); 446 aureon_ac97_write(ice, kcontrol->private_value & 0x7F, nvol);
438 447
439 snd_ice1712_restore_gpio_status(ice); 448 snd_ice1712_restore_gpio_status(ice);
440 449
441 return change; 450 return change;
@@ -465,13 +474,14 @@ static int aureon_ac97_micboost_put(struct snd_kcontrol *kcontrol, struct snd_ct
465 int change; 474 int change;
466 475
467 snd_ice1712_save_gpio_status(ice); 476 snd_ice1712_save_gpio_status(ice);
468 477
469 ovol = aureon_ac97_read(ice, AC97_MIC); 478 ovol = aureon_ac97_read(ice, AC97_MIC);
470 nvol = (ucontrol->value.integer.value[0] ? 0x0000 : 0x0020) | (ovol & ~0x0020); 479 nvol = (ucontrol->value.integer.value[0] ? 0x0000 : 0x0020) | (ovol & ~0x0020);
471 480
472 if ((change = (ovol != nvol))) 481 change = (ovol != nvol);
482 if (change)
473 aureon_ac97_write(ice, AC97_MIC, nvol); 483 aureon_ac97_write(ice, AC97_MIC, nvol);
474 484
475 snd_ice1712_restore_gpio_status(ice); 485 snd_ice1712_restore_gpio_status(ice);
476 486
477 return change; 487 return change;
@@ -493,16 +503,15 @@ static void aureon_spi_write(struct snd_ice1712 *ice, unsigned int cs, unsigned
493 snd_ice1712_gpio_set_mask(ice, ~(PRODIGY_SPI_MOSI|PRODIGY_SPI_CLK|PRODIGY_WM_CS)); 503 snd_ice1712_gpio_set_mask(ice, ~(PRODIGY_SPI_MOSI|PRODIGY_SPI_CLK|PRODIGY_WM_CS));
494 mosi = PRODIGY_SPI_MOSI; 504 mosi = PRODIGY_SPI_MOSI;
495 clk = PRODIGY_SPI_CLK; 505 clk = PRODIGY_SPI_CLK;
496 } 506 } else {
497 else {
498 snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RW|AUREON_SPI_MOSI|AUREON_SPI_CLK| 507 snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RW|AUREON_SPI_MOSI|AUREON_SPI_CLK|
499 AUREON_WM_CS|AUREON_CS8415_CS)); 508 AUREON_WM_CS|AUREON_CS8415_CS));
500 mosi = AUREON_SPI_MOSI; 509 mosi = AUREON_SPI_MOSI;
501 clk = AUREON_SPI_CLK; 510 clk = AUREON_SPI_CLK;
502 511
503 tmp |= AUREON_WM_RW; 512 tmp |= AUREON_WM_RW;
504 } 513 }
505 514
506 tmp &= ~cs; 515 tmp &= ~cs;
507 snd_ice1712_gpio_write(ice, tmp); 516 snd_ice1712_gpio_write(ice, tmp);
508 udelay(1); 517 udelay(1);
@@ -534,7 +543,9 @@ static void aureon_spi_write(struct snd_ice1712 *ice, unsigned int cs, unsigned
534/* 543/*
535 * Read data in SPI mode 544 * Read data in SPI mode
536 */ 545 */
537static void aureon_spi_read(struct snd_ice1712 *ice, unsigned int cs, unsigned int data, int bits, unsigned char *buffer, int size) { 546static void aureon_spi_read(struct snd_ice1712 *ice, unsigned int cs,
547 unsigned int data, int bits, unsigned char *buffer, int size)
548{
538 int i, j; 549 int i, j;
539 unsigned int tmp; 550 unsigned int tmp;
540 551
@@ -544,7 +555,7 @@ static void aureon_spi_read(struct snd_ice1712 *ice, unsigned int cs, unsigned i
544 snd_ice1712_gpio_write(ice, tmp); 555 snd_ice1712_gpio_write(ice, tmp);
545 udelay(1); 556 udelay(1);
546 557
547 for (i=bits-1; i>=0; i--) { 558 for (i = bits-1; i >= 0; i--) {
548 if (data & (1 << i)) 559 if (data & (1 << i))
549 tmp |= AUREON_SPI_MOSI; 560 tmp |= AUREON_SPI_MOSI;
550 else 561 else
@@ -561,9 +572,9 @@ static void aureon_spi_read(struct snd_ice1712 *ice, unsigned int cs, unsigned i
561 udelay(1); 572 udelay(1);
562 } 573 }
563 574
564 for (j=0; j<size; j++) { 575 for (j = 0; j < size; j++) {
565 unsigned char outdata = 0; 576 unsigned char outdata = 0;
566 for (i=7; i>=0; i--) { 577 for (i = 7; i >= 0; i--) {
567 tmp = snd_ice1712_gpio_read(ice); 578 tmp = snd_ice1712_gpio_read(ice);
568 outdata <<= 1; 579 outdata <<= 1;
569 outdata |= (tmp & AUREON_SPI_MISO) ? 1 : 0; 580 outdata |= (tmp & AUREON_SPI_MISO) ? 1 : 0;
@@ -584,19 +595,24 @@ static void aureon_spi_read(struct snd_ice1712 *ice, unsigned int cs, unsigned i
584 snd_ice1712_gpio_write(ice, tmp); 595 snd_ice1712_gpio_write(ice, tmp);
585} 596}
586 597
587static unsigned char aureon_cs8415_get(struct snd_ice1712 *ice, int reg) { 598static unsigned char aureon_cs8415_get(struct snd_ice1712 *ice, int reg)
599{
588 unsigned char val; 600 unsigned char val;
589 aureon_spi_write(ice, AUREON_CS8415_CS, 0x2000 | reg, 16); 601 aureon_spi_write(ice, AUREON_CS8415_CS, 0x2000 | reg, 16);
590 aureon_spi_read(ice, AUREON_CS8415_CS, 0x21, 8, &val, 1); 602 aureon_spi_read(ice, AUREON_CS8415_CS, 0x21, 8, &val, 1);
591 return val; 603 return val;
592} 604}
593 605
594static void aureon_cs8415_read(struct snd_ice1712 *ice, int reg, unsigned char *buffer, int size) { 606static void aureon_cs8415_read(struct snd_ice1712 *ice, int reg,
607 unsigned char *buffer, int size)
608{
595 aureon_spi_write(ice, AUREON_CS8415_CS, 0x2000 | reg, 16); 609 aureon_spi_write(ice, AUREON_CS8415_CS, 0x2000 | reg, 16);
596 aureon_spi_read(ice, AUREON_CS8415_CS, 0x21, 8, buffer, size); 610 aureon_spi_read(ice, AUREON_CS8415_CS, 0x21, 8, buffer, size);
597} 611}
598 612
599static void aureon_cs8415_put(struct snd_ice1712 *ice, int reg, unsigned char val) { 613static void aureon_cs8415_put(struct snd_ice1712 *ice, int reg,
614 unsigned char val)
615{
600 aureon_spi_write(ice, AUREON_CS8415_CS, 0x200000 | (reg << 8) | val, 24); 616 aureon_spi_write(ice, AUREON_CS8415_CS, 0x200000 | (reg << 8) | val, 24);
601} 617}
602 618
@@ -654,18 +670,20 @@ static int aureon_ac97_mmute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e
654 return 0; 670 return 0;
655} 671}
656 672
657static int aureon_ac97_mmute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { 673static int aureon_ac97_mmute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
674{
658 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 675 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
659 unsigned short ovol, nvol; 676 unsigned short ovol, nvol;
660 int change; 677 int change;
661 678
662 snd_ice1712_save_gpio_status(ice); 679 snd_ice1712_save_gpio_status(ice);
663 680
664 ovol = wm_get(ice, WM_OUT_MUX1); 681 ovol = wm_get(ice, WM_OUT_MUX1);
665 nvol = (ovol & ~0x02) | (ucontrol->value.integer.value[0] ? 0x02 : 0x00); 682 nvol = (ovol & ~0x02) | (ucontrol->value.integer.value[0] ? 0x02 : 0x00);
666 if ((change = (ovol != nvol))) 683 change = (ovol != nvol);
684 if (change)
667 wm_put(ice, WM_OUT_MUX1, nvol); 685 wm_put(ice, WM_OUT_MUX1, nvol);
668 686
669 snd_ice1712_restore_gpio_status(ice); 687 snd_ice1712_restore_gpio_status(ice);
670 688
671 return change; 689 return change;
@@ -702,12 +720,12 @@ static const unsigned char wm_vol[256] = {
702static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned short vol, unsigned short master) 720static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned short vol, unsigned short master)
703{ 721{
704 unsigned char nvol; 722 unsigned char nvol;
705 723
706 if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE)) 724 if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE))
707 nvol = 0; 725 nvol = 0;
708 else 726 else
709 nvol = 127 - wm_vol[(((vol & ~WM_VOL_MUTE) * (master & ~WM_VOL_MUTE)) / 127) & WM_VOL_MAX]; 727 nvol = 127 - wm_vol[(((vol & ~WM_VOL_MUTE) * (master & ~WM_VOL_MUTE)) / 127) & WM_VOL_MAX];
710 728
711 wm_put(ice, index, nvol); 729 wm_put(ice, index, nvol);
712 wm_put_nocache(ice, index, 0x180 | nvol); 730 wm_put_nocache(ice, index, 0x180 | nvol);
713} 731}
@@ -736,7 +754,8 @@ static int wm_pcm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_va
736 snd_ice1712_save_gpio_status(ice); 754 snd_ice1712_save_gpio_status(ice);
737 oval = wm_get(ice, WM_MUTE); 755 oval = wm_get(ice, WM_MUTE);
738 nval = (oval & ~0x10) | (ucontrol->value.integer.value[0] ? 0 : 0x10); 756 nval = (oval & ~0x10) | (ucontrol->value.integer.value[0] ? 0 : 0x10);
739 if ((change = (nval != oval))) 757 change = (oval != nval);
758 if (change)
740 wm_put(ice, WM_MUTE, nval); 759 wm_put(ice, WM_MUTE, nval);
741 snd_ice1712_restore_gpio_status(ice); 760 snd_ice1712_restore_gpio_status(ice);
742 761
@@ -760,7 +779,7 @@ static int wm_master_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_
760 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 779 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
761 struct aureon_spec *spec = ice->spec; 780 struct aureon_spec *spec = ice->spec;
762 int i; 781 int i;
763 for (i=0; i<2; i++) 782 for (i = 0; i < 2; i++)
764 ucontrol->value.integer.value[i] = 783 ucontrol->value.integer.value[i] =
765 spec->master[i] & ~WM_VOL_MUTE; 784 spec->master[i] & ~WM_VOL_MUTE;
766 return 0; 785 return 0;
@@ -849,7 +868,8 @@ static int wm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *
849/* 868/*
850 * WM8770 mute control 869 * WM8770 mute control
851 */ 870 */
852static int wm_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { 871static int wm_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
872{
853 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 873 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
854 uinfo->count = kcontrol->private_value >> 8; 874 uinfo->count = kcontrol->private_value >> 8;
855 uinfo->value.integer.min = 0; 875 uinfo->value.integer.min = 0;
@@ -862,7 +882,7 @@ static int wm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value
862 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 882 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
863 struct aureon_spec *spec = ice->spec; 883 struct aureon_spec *spec = ice->spec;
864 int voices, ofs, i; 884 int voices, ofs, i;
865 885
866 voices = kcontrol->private_value >> 8; 886 voices = kcontrol->private_value >> 8;
867 ofs = kcontrol->private_value & 0xFF; 887 ofs = kcontrol->private_value & 0xFF;
868 888
@@ -907,7 +927,7 @@ static int wm_master_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem
907{ 927{
908 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 928 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
909 struct aureon_spec *spec = ice->spec; 929 struct aureon_spec *spec = ice->spec;
910 930
911 ucontrol->value.integer.value[0] = 931 ucontrol->value.integer.value[0] =
912 (spec->master[0] & WM_VOL_MUTE) ? 0 : 1; 932 (spec->master[0] & WM_VOL_MUTE) ? 0 : 1;
913 ucontrol->value.integer.value[1] = 933 ucontrol->value.integer.value[1] =
@@ -1083,21 +1103,21 @@ static int wm_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val
1083static int wm_adc_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 1103static int wm_adc_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1084{ 1104{
1085 static const char * const texts[] = { 1105 static const char * const texts[] = {
1086 "CD", //AIN1 1106 "CD", /* AIN1 */
1087 "Aux", //AIN2 1107 "Aux", /* AIN2 */
1088 "Line", //AIN3 1108 "Line", /* AIN3 */
1089 "Mic", //AIN4 1109 "Mic", /* AIN4 */
1090 "AC97" //AIN5 1110 "AC97" /* AIN5 */
1091 }; 1111 };
1092 static const char * const universe_texts[] = { 1112 static const char * const universe_texts[] = {
1093 "Aux1", //AIN1 1113 "Aux1", /* AIN1 */
1094 "CD", //AIN2 1114 "CD", /* AIN2 */
1095 "Phono", //AIN3 1115 "Phono", /* AIN3 */
1096 "Line", //AIN4 1116 "Line", /* AIN4 */
1097 "Aux2", //AIN5 1117 "Aux2", /* AIN5 */
1098 "Mic", //AIN6 1118 "Mic", /* AIN6 */
1099 "Aux3", //AIN7 1119 "Aux3", /* AIN7 */
1100 "AC97" //AIN8 1120 "AC97" /* AIN8 */
1101 }; 1121 };
1102 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 1122 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1103 1123
@@ -1108,8 +1128,7 @@ static int wm_adc_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_in
1108 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) 1128 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1109 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; 1129 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1110 strcpy(uinfo->value.enumerated.name, universe_texts[uinfo->value.enumerated.item]); 1130 strcpy(uinfo->value.enumerated.name, universe_texts[uinfo->value.enumerated.item]);
1111 } 1131 } else {
1112 else {
1113 uinfo->value.enumerated.items = 5; 1132 uinfo->value.enumerated.items = 5;
1114 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) 1133 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1115 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; 1134 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
@@ -1156,8 +1175,8 @@ static int aureon_cs8415_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_
1156{ 1175{
1157 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 1176 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1158 static const char * const aureon_texts[] = { 1177 static const char * const aureon_texts[] = {
1159 "CD", //RXP0 1178 "CD", /* RXP0 */
1160 "Optical" //RXP1 1179 "Optical" /* RXP1 */
1161 }; 1180 };
1162 static const char * const prodigy_texts[] = { 1181 static const char * const prodigy_texts[] = {
1163 "CD", 1182 "CD",
@@ -1180,10 +1199,10 @@ static int aureon_cs8415_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e
1180 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 1199 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1181 struct aureon_spec *spec = ice->spec; 1200 struct aureon_spec *spec = ice->spec;
1182 1201
1183 //snd_ice1712_save_gpio_status(ice); 1202 /* snd_ice1712_save_gpio_status(ice); */
1184 //val = aureon_cs8415_get(ice, CS8415_CTRL2); 1203 /* val = aureon_cs8415_get(ice, CS8415_CTRL2); */
1185 ucontrol->value.enumerated.item[0] = spec->cs8415_mux; 1204 ucontrol->value.enumerated.item[0] = spec->cs8415_mux;
1186 //snd_ice1712_restore_gpio_status(ice); 1205 /* snd_ice1712_restore_gpio_status(ice); */
1187 return 0; 1206 return 0;
1188} 1207}
1189 1208
@@ -1206,7 +1225,7 @@ static int aureon_cs8415_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
1206 return change; 1225 return change;
1207} 1226}
1208 1227
1209static int aureon_cs8415_rate_info (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 1228static int aureon_cs8415_rate_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1210{ 1229{
1211 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 1230 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1212 uinfo->count = 1; 1231 uinfo->count = 1;
@@ -1215,7 +1234,7 @@ static int aureon_cs8415_rate_info (struct snd_kcontrol *kcontrol, struct snd_ct
1215 return 0; 1234 return 0;
1216} 1235}
1217 1236
1218static int aureon_cs8415_rate_get (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 1237static int aureon_cs8415_rate_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1219{ 1238{
1220 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 1239 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1221 unsigned char ratio; 1240 unsigned char ratio;
@@ -1229,7 +1248,7 @@ static int aureon_cs8415_rate_get (struct snd_kcontrol *kcontrol, struct snd_ctl
1229 */ 1248 */
1230#define aureon_cs8415_mute_info snd_ctl_boolean_mono_info 1249#define aureon_cs8415_mute_info snd_ctl_boolean_mono_info
1231 1250
1232static int aureon_cs8415_mute_get (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 1251static int aureon_cs8415_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1233{ 1252{
1234 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 1253 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1235 snd_ice1712_save_gpio_status(ice); 1254 snd_ice1712_save_gpio_status(ice);
@@ -1238,7 +1257,7 @@ static int aureon_cs8415_mute_get (struct snd_kcontrol *kcontrol, struct snd_ctl
1238 return 0; 1257 return 0;
1239} 1258}
1240 1259
1241static int aureon_cs8415_mute_put (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 1260static int aureon_cs8415_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1242{ 1261{
1243 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 1262 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1244 unsigned char oval, nval; 1263 unsigned char oval, nval;
@@ -1249,7 +1268,8 @@ static int aureon_cs8415_mute_put (struct snd_kcontrol *kcontrol, struct snd_ctl
1249 nval = oval & ~0x20; 1268 nval = oval & ~0x20;
1250 else 1269 else
1251 nval = oval | 0x20; 1270 nval = oval | 0x20;
1252 if ((change = (oval != nval))) 1271 change = (oval != nval);
1272 if (change)
1253 aureon_cs8415_put(ice, CS8415_CTRL1, nval); 1273 aureon_cs8415_put(ice, CS8415_CTRL1, nval);
1254 snd_ice1712_restore_gpio_status(ice); 1274 snd_ice1712_restore_gpio_status(ice);
1255 return change; 1275 return change;
@@ -1258,15 +1278,17 @@ static int aureon_cs8415_mute_put (struct snd_kcontrol *kcontrol, struct snd_ctl
1258/* 1278/*
1259 * CS8415A Q-Sub info 1279 * CS8415A Q-Sub info
1260 */ 1280 */
1261static int aureon_cs8415_qsub_info (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { 1281static int aureon_cs8415_qsub_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1282{
1262 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; 1283 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
1263 uinfo->count = 10; 1284 uinfo->count = 10;
1264 return 0; 1285 return 0;
1265} 1286}
1266 1287
1267static int aureon_cs8415_qsub_get (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { 1288static int aureon_cs8415_qsub_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1289{
1268 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 1290 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1269 1291
1270 snd_ice1712_save_gpio_status(ice); 1292 snd_ice1712_save_gpio_status(ice);
1271 aureon_cs8415_read(ice, CS8415_QSUB, ucontrol->value.bytes.data, 10); 1293 aureon_cs8415_read(ice, CS8415_QSUB, ucontrol->value.bytes.data, 10);
1272 snd_ice1712_restore_gpio_status(ice); 1294 snd_ice1712_restore_gpio_status(ice);
@@ -1274,18 +1296,21 @@ static int aureon_cs8415_qsub_get (struct snd_kcontrol *kcontrol, struct snd_ctl
1274 return 0; 1296 return 0;
1275} 1297}
1276 1298
1277static int aureon_cs8415_spdif_info (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { 1299static int aureon_cs8415_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1300{
1278 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; 1301 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
1279 uinfo->count = 1; 1302 uinfo->count = 1;
1280 return 0; 1303 return 0;
1281} 1304}
1282 1305
1283static int aureon_cs8415_mask_get (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { 1306static int aureon_cs8415_mask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1307{
1284 memset(ucontrol->value.iec958.status, 0xFF, 24); 1308 memset(ucontrol->value.iec958.status, 0xFF, 24);
1285 return 0; 1309 return 0;
1286} 1310}
1287 1311
1288static int aureon_cs8415_spdif_get (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { 1312static int aureon_cs8415_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1313{
1289 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 1314 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1290 1315
1291 snd_ice1712_save_gpio_status(ice); 1316 snd_ice1712_save_gpio_status(ice);
@@ -1311,9 +1336,9 @@ static int aureon_set_headphone_amp(struct snd_ice1712 *ice, int enable)
1311 else 1336 else
1312 if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT && 1337 if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
1313 ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) 1338 ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT)
1314 tmp &= ~ AUREON_HP_SEL; 1339 tmp &= ~AUREON_HP_SEL;
1315 else 1340 else
1316 tmp &= ~ PRODIGY_HP_SEL; 1341 tmp &= ~PRODIGY_HP_SEL;
1317 if (tmp != tmp2) { 1342 if (tmp != tmp2) {
1318 snd_ice1712_gpio_write(ice, tmp); 1343 snd_ice1712_gpio_write(ice, tmp);
1319 return 1; 1344 return 1;
@@ -1325,7 +1350,7 @@ static int aureon_get_headphone_amp(struct snd_ice1712 *ice)
1325{ 1350{
1326 unsigned int tmp = snd_ice1712_gpio_read(ice); 1351 unsigned int tmp = snd_ice1712_gpio_read(ice);
1327 1352
1328 return ( tmp & AUREON_HP_SEL )!= 0; 1353 return (tmp & AUREON_HP_SEL) != 0;
1329} 1354}
1330 1355
1331#define aureon_hpamp_info snd_ctl_boolean_mono_info 1356#define aureon_hpamp_info snd_ctl_boolean_mono_info
@@ -1343,7 +1368,7 @@ static int aureon_hpamp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v
1343{ 1368{
1344 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 1369 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1345 1370
1346 return aureon_set_headphone_amp(ice,ucontrol->value.integer.value[0]); 1371 return aureon_set_headphone_amp(ice, ucontrol->value.integer.value[0]);
1347} 1372}
1348 1373
1349/* 1374/*
@@ -1390,7 +1415,7 @@ static int aureon_oversampling_info(struct snd_kcontrol *k, struct snd_ctl_elem_
1390 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; 1415 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1391 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 1416 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1392 1417
1393 return 0; 1418 return 0;
1394} 1419}
1395 1420
1396static int aureon_oversampling_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 1421static int aureon_oversampling_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
@@ -1434,7 +1459,7 @@ static struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = {
1434 { 1459 {
1435 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1460 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1436 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 1461 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1437 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 1462 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1438 .name = "Master Playback Volume", 1463 .name = "Master Playback Volume",
1439 .info = wm_master_vol_info, 1464 .info = wm_master_vol_info,
1440 .get = wm_master_vol_get, 1465 .get = wm_master_vol_get,
@@ -1452,7 +1477,7 @@ static struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = {
1452 { 1477 {
1453 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1478 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1454 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 1479 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1455 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 1480 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1456 .name = "Front Playback Volume", 1481 .name = "Front Playback Volume",
1457 .info = wm_vol_info, 1482 .info = wm_vol_info,
1458 .get = wm_vol_get, 1483 .get = wm_vol_get,
@@ -1471,7 +1496,7 @@ static struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = {
1471 { 1496 {
1472 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1497 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1473 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 1498 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1474 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 1499 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1475 .name = "Rear Playback Volume", 1500 .name = "Rear Playback Volume",
1476 .info = wm_vol_info, 1501 .info = wm_vol_info,
1477 .get = wm_vol_get, 1502 .get = wm_vol_get,
@@ -1490,7 +1515,7 @@ static struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = {
1490 { 1515 {
1491 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1516 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1492 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 1517 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1493 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 1518 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1494 .name = "Center Playback Volume", 1519 .name = "Center Playback Volume",
1495 .info = wm_vol_info, 1520 .info = wm_vol_info,
1496 .get = wm_vol_get, 1521 .get = wm_vol_get,
@@ -1509,7 +1534,7 @@ static struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = {
1509 { 1534 {
1510 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1535 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1511 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 1536 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1512 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 1537 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1513 .name = "LFE Playback Volume", 1538 .name = "LFE Playback Volume",
1514 .info = wm_vol_info, 1539 .info = wm_vol_info,
1515 .get = wm_vol_get, 1540 .get = wm_vol_get,
@@ -1528,7 +1553,7 @@ static struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = {
1528 { 1553 {
1529 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1554 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1530 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 1555 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1531 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 1556 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1532 .name = "Side Playback Volume", 1557 .name = "Side Playback Volume",
1533 .info = wm_vol_info, 1558 .info = wm_vol_info,
1534 .get = wm_vol_get, 1559 .get = wm_vol_get,
@@ -1539,23 +1564,23 @@ static struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = {
1539}; 1564};
1540 1565
1541static struct snd_kcontrol_new wm_controls[] __devinitdata = { 1566static struct snd_kcontrol_new wm_controls[] __devinitdata = {
1542 { 1567 {
1543 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1568 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1544 .name = "PCM Playback Switch", 1569 .name = "PCM Playback Switch",
1545 .info = wm_pcm_mute_info, 1570 .info = wm_pcm_mute_info,
1546 .get = wm_pcm_mute_get, 1571 .get = wm_pcm_mute_get,
1547 .put = wm_pcm_mute_put 1572 .put = wm_pcm_mute_put
1548 }, 1573 },
1549 { 1574 {
1550 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1575 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1551 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 1576 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1552 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 1577 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1553 .name = "PCM Playback Volume", 1578 .name = "PCM Playback Volume",
1554 .info = wm_pcm_vol_info, 1579 .info = wm_pcm_vol_info,
1555 .get = wm_pcm_vol_get, 1580 .get = wm_pcm_vol_get,
1556 .put = wm_pcm_vol_put, 1581 .put = wm_pcm_vol_put,
1557 .tlv = { .p = db_scale_wm_pcm } 1582 .tlv = { .p = db_scale_wm_pcm }
1558 }, 1583 },
1559 { 1584 {
1560 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1585 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1561 .name = "Capture Switch", 1586 .name = "Capture Switch",
@@ -1566,7 +1591,7 @@ static struct snd_kcontrol_new wm_controls[] __devinitdata = {
1566 { 1591 {
1567 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1592 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1568 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 1593 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1569 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 1594 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1570 .name = "Capture Volume", 1595 .name = "Capture Volume",
1571 .info = wm_adc_vol_info, 1596 .info = wm_adc_vol_info,
1572 .get = wm_adc_vol_get, 1597 .get = wm_adc_vol_get,
@@ -1605,232 +1630,232 @@ static struct snd_kcontrol_new wm_controls[] __devinitdata = {
1605}; 1630};
1606 1631
1607static struct snd_kcontrol_new ac97_controls[] __devinitdata = { 1632static struct snd_kcontrol_new ac97_controls[] __devinitdata = {
1608 { 1633 {
1609 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1634 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1610 .name = "AC97 Playback Switch", 1635 .name = "AC97 Playback Switch",
1611 .info = aureon_ac97_mmute_info, 1636 .info = aureon_ac97_mmute_info,
1612 .get = aureon_ac97_mmute_get, 1637 .get = aureon_ac97_mmute_get,
1613 .put = aureon_ac97_mmute_put, 1638 .put = aureon_ac97_mmute_put,
1614 .private_value = AC97_MASTER 1639 .private_value = AC97_MASTER
1615 }, 1640 },
1616 { 1641 {
1617 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1642 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1618 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 1643 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1619 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 1644 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1620 .name = "AC97 Playback Volume", 1645 .name = "AC97 Playback Volume",
1621 .info = aureon_ac97_vol_info, 1646 .info = aureon_ac97_vol_info,
1622 .get = aureon_ac97_vol_get, 1647 .get = aureon_ac97_vol_get,
1623 .put = aureon_ac97_vol_put, 1648 .put = aureon_ac97_vol_put,
1624 .private_value = AC97_MASTER|AUREON_AC97_STEREO, 1649 .private_value = AC97_MASTER|AUREON_AC97_STEREO,
1625 .tlv = { .p = db_scale_ac97_master } 1650 .tlv = { .p = db_scale_ac97_master }
1626 }, 1651 },
1627 { 1652 {
1628 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1653 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1629 .name = "CD Playback Switch", 1654 .name = "CD Playback Switch",
1630 .info = aureon_ac97_mute_info, 1655 .info = aureon_ac97_mute_info,
1631 .get = aureon_ac97_mute_get, 1656 .get = aureon_ac97_mute_get,
1632 .put = aureon_ac97_mute_put, 1657 .put = aureon_ac97_mute_put,
1633 .private_value = AC97_CD 1658 .private_value = AC97_CD
1634 }, 1659 },
1635 { 1660 {
1636 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1661 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1637 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 1662 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1638 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 1663 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1639 .name = "CD Playback Volume", 1664 .name = "CD Playback Volume",
1640 .info = aureon_ac97_vol_info, 1665 .info = aureon_ac97_vol_info,
1641 .get = aureon_ac97_vol_get, 1666 .get = aureon_ac97_vol_get,
1642 .put = aureon_ac97_vol_put, 1667 .put = aureon_ac97_vol_put,
1643 .private_value = AC97_CD|AUREON_AC97_STEREO, 1668 .private_value = AC97_CD|AUREON_AC97_STEREO,
1644 .tlv = { .p = db_scale_ac97_gain } 1669 .tlv = { .p = db_scale_ac97_gain }
1645 }, 1670 },
1646 { 1671 {
1647 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1672 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1648 .name = "Aux Playback Switch", 1673 .name = "Aux Playback Switch",
1649 .info = aureon_ac97_mute_info, 1674 .info = aureon_ac97_mute_info,
1650 .get = aureon_ac97_mute_get, 1675 .get = aureon_ac97_mute_get,
1651 .put = aureon_ac97_mute_put, 1676 .put = aureon_ac97_mute_put,
1652 .private_value = AC97_AUX, 1677 .private_value = AC97_AUX,
1653 }, 1678 },
1654 { 1679 {
1655 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1680 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1656 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 1681 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1657 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 1682 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1658 .name = "Aux Playback Volume", 1683 .name = "Aux Playback Volume",
1659 .info = aureon_ac97_vol_info, 1684 .info = aureon_ac97_vol_info,
1660 .get = aureon_ac97_vol_get, 1685 .get = aureon_ac97_vol_get,
1661 .put = aureon_ac97_vol_put, 1686 .put = aureon_ac97_vol_put,
1662 .private_value = AC97_AUX|AUREON_AC97_STEREO, 1687 .private_value = AC97_AUX|AUREON_AC97_STEREO,
1663 .tlv = { .p = db_scale_ac97_gain } 1688 .tlv = { .p = db_scale_ac97_gain }
1664 }, 1689 },
1665 { 1690 {
1666 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1691 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1667 .name = "Line Playback Switch", 1692 .name = "Line Playback Switch",
1668 .info = aureon_ac97_mute_info, 1693 .info = aureon_ac97_mute_info,
1669 .get = aureon_ac97_mute_get, 1694 .get = aureon_ac97_mute_get,
1670 .put = aureon_ac97_mute_put, 1695 .put = aureon_ac97_mute_put,
1671 .private_value = AC97_LINE 1696 .private_value = AC97_LINE
1672 }, 1697 },
1673 { 1698 {
1674 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1699 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1675 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 1700 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1676 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 1701 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1677 .name = "Line Playback Volume", 1702 .name = "Line Playback Volume",
1678 .info = aureon_ac97_vol_info, 1703 .info = aureon_ac97_vol_info,
1679 .get = aureon_ac97_vol_get, 1704 .get = aureon_ac97_vol_get,
1680 .put = aureon_ac97_vol_put, 1705 .put = aureon_ac97_vol_put,
1681 .private_value = AC97_LINE|AUREON_AC97_STEREO, 1706 .private_value = AC97_LINE|AUREON_AC97_STEREO,
1682 .tlv = { .p = db_scale_ac97_gain } 1707 .tlv = { .p = db_scale_ac97_gain }
1683 }, 1708 },
1684 { 1709 {
1685 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1710 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1686 .name = "Mic Playback Switch", 1711 .name = "Mic Playback Switch",
1687 .info = aureon_ac97_mute_info, 1712 .info = aureon_ac97_mute_info,
1688 .get = aureon_ac97_mute_get, 1713 .get = aureon_ac97_mute_get,
1689 .put = aureon_ac97_mute_put, 1714 .put = aureon_ac97_mute_put,
1690 .private_value = AC97_MIC 1715 .private_value = AC97_MIC
1691 }, 1716 },
1692 { 1717 {
1693 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1718 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1694 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 1719 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1695 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 1720 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1696 .name = "Mic Playback Volume", 1721 .name = "Mic Playback Volume",
1697 .info = aureon_ac97_vol_info, 1722 .info = aureon_ac97_vol_info,
1698 .get = aureon_ac97_vol_get, 1723 .get = aureon_ac97_vol_get,
1699 .put = aureon_ac97_vol_put, 1724 .put = aureon_ac97_vol_put,
1700 .private_value = AC97_MIC, 1725 .private_value = AC97_MIC,
1701 .tlv = { .p = db_scale_ac97_gain } 1726 .tlv = { .p = db_scale_ac97_gain }
1702 }, 1727 },
1703 { 1728 {
1704 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1729 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1705 .name = "Mic Boost (+20dB)", 1730 .name = "Mic Boost (+20dB)",
1706 .info = aureon_ac97_micboost_info, 1731 .info = aureon_ac97_micboost_info,
1707 .get = aureon_ac97_micboost_get, 1732 .get = aureon_ac97_micboost_get,
1708 .put = aureon_ac97_micboost_put 1733 .put = aureon_ac97_micboost_put
1709 } 1734 }
1710}; 1735};
1711 1736
1712static struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = { 1737static struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = {
1713 { 1738 {
1714 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1739 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1715 .name = "AC97 Playback Switch", 1740 .name = "AC97 Playback Switch",
1716 .info = aureon_ac97_mmute_info, 1741 .info = aureon_ac97_mmute_info,
1717 .get = aureon_ac97_mmute_get, 1742 .get = aureon_ac97_mmute_get,
1718 .put = aureon_ac97_mmute_put, 1743 .put = aureon_ac97_mmute_put,
1719 .private_value = AC97_MASTER 1744 .private_value = AC97_MASTER
1720 }, 1745 },
1721 { 1746 {
1722 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1747 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1723 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 1748 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1724 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 1749 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1725 .name = "AC97 Playback Volume", 1750 .name = "AC97 Playback Volume",
1726 .info = aureon_ac97_vol_info, 1751 .info = aureon_ac97_vol_info,
1727 .get = aureon_ac97_vol_get, 1752 .get = aureon_ac97_vol_get,
1728 .put = aureon_ac97_vol_put, 1753 .put = aureon_ac97_vol_put,
1729 .private_value = AC97_MASTER|AUREON_AC97_STEREO, 1754 .private_value = AC97_MASTER|AUREON_AC97_STEREO,
1730 .tlv = { .p = db_scale_ac97_master } 1755 .tlv = { .p = db_scale_ac97_master }
1731 }, 1756 },
1732 { 1757 {
1733 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1758 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1734 .name = "CD Playback Switch", 1759 .name = "CD Playback Switch",
1735 .info = aureon_ac97_mute_info, 1760 .info = aureon_ac97_mute_info,
1736 .get = aureon_ac97_mute_get, 1761 .get = aureon_ac97_mute_get,
1737 .put = aureon_ac97_mute_put, 1762 .put = aureon_ac97_mute_put,
1738 .private_value = AC97_AUX 1763 .private_value = AC97_AUX
1739 }, 1764 },
1740 { 1765 {
1741 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1766 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1742 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 1767 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1743 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 1768 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1744 .name = "CD Playback Volume", 1769 .name = "CD Playback Volume",
1745 .info = aureon_ac97_vol_info, 1770 .info = aureon_ac97_vol_info,
1746 .get = aureon_ac97_vol_get, 1771 .get = aureon_ac97_vol_get,
1747 .put = aureon_ac97_vol_put, 1772 .put = aureon_ac97_vol_put,
1748 .private_value = AC97_AUX|AUREON_AC97_STEREO, 1773 .private_value = AC97_AUX|AUREON_AC97_STEREO,
1749 .tlv = { .p = db_scale_ac97_gain } 1774 .tlv = { .p = db_scale_ac97_gain }
1750 }, 1775 },
1751 { 1776 {
1752 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1777 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1753 .name = "Phono Playback Switch", 1778 .name = "Phono Playback Switch",
1754 .info = aureon_ac97_mute_info, 1779 .info = aureon_ac97_mute_info,
1755 .get = aureon_ac97_mute_get, 1780 .get = aureon_ac97_mute_get,
1756 .put = aureon_ac97_mute_put, 1781 .put = aureon_ac97_mute_put,
1757 .private_value = AC97_CD 1782 .private_value = AC97_CD
1758 }, 1783 },
1759 { 1784 {
1760 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1785 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1761 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 1786 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1762 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 1787 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1763 .name = "Phono Playback Volume", 1788 .name = "Phono Playback Volume",
1764 .info = aureon_ac97_vol_info, 1789 .info = aureon_ac97_vol_info,
1765 .get = aureon_ac97_vol_get, 1790 .get = aureon_ac97_vol_get,
1766 .put = aureon_ac97_vol_put, 1791 .put = aureon_ac97_vol_put,
1767 .private_value = AC97_CD|AUREON_AC97_STEREO, 1792 .private_value = AC97_CD|AUREON_AC97_STEREO,
1768 .tlv = { .p = db_scale_ac97_gain } 1793 .tlv = { .p = db_scale_ac97_gain }
1769 }, 1794 },
1770 { 1795 {
1771 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1796 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1772 .name = "Line Playback Switch", 1797 .name = "Line Playback Switch",
1773 .info = aureon_ac97_mute_info, 1798 .info = aureon_ac97_mute_info,
1774 .get = aureon_ac97_mute_get, 1799 .get = aureon_ac97_mute_get,
1775 .put = aureon_ac97_mute_put, 1800 .put = aureon_ac97_mute_put,
1776 .private_value = AC97_LINE 1801 .private_value = AC97_LINE
1777 }, 1802 },
1778 { 1803 {
1779 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1804 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1780 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 1805 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1781 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 1806 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1782 .name = "Line Playback Volume", 1807 .name = "Line Playback Volume",
1783 .info = aureon_ac97_vol_info, 1808 .info = aureon_ac97_vol_info,
1784 .get = aureon_ac97_vol_get, 1809 .get = aureon_ac97_vol_get,
1785 .put = aureon_ac97_vol_put, 1810 .put = aureon_ac97_vol_put,
1786 .private_value = AC97_LINE|AUREON_AC97_STEREO, 1811 .private_value = AC97_LINE|AUREON_AC97_STEREO,
1787 .tlv = { .p = db_scale_ac97_gain } 1812 .tlv = { .p = db_scale_ac97_gain }
1788 }, 1813 },
1789 { 1814 {
1790 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1815 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1791 .name = "Mic Playback Switch", 1816 .name = "Mic Playback Switch",
1792 .info = aureon_ac97_mute_info, 1817 .info = aureon_ac97_mute_info,
1793 .get = aureon_ac97_mute_get, 1818 .get = aureon_ac97_mute_get,
1794 .put = aureon_ac97_mute_put, 1819 .put = aureon_ac97_mute_put,
1795 .private_value = AC97_MIC 1820 .private_value = AC97_MIC
1796 }, 1821 },
1797 { 1822 {
1798 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1823 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1799 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 1824 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1800 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 1825 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1801 .name = "Mic Playback Volume", 1826 .name = "Mic Playback Volume",
1802 .info = aureon_ac97_vol_info, 1827 .info = aureon_ac97_vol_info,
1803 .get = aureon_ac97_vol_get, 1828 .get = aureon_ac97_vol_get,
1804 .put = aureon_ac97_vol_put, 1829 .put = aureon_ac97_vol_put,
1805 .private_value = AC97_MIC, 1830 .private_value = AC97_MIC,
1806 .tlv = { .p = db_scale_ac97_gain } 1831 .tlv = { .p = db_scale_ac97_gain }
1807 }, 1832 },
1808 { 1833 {
1809 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1834 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1810 .name = "Mic Boost (+20dB)", 1835 .name = "Mic Boost (+20dB)",
1811 .info = aureon_ac97_micboost_info, 1836 .info = aureon_ac97_micboost_info,
1812 .get = aureon_ac97_micboost_get, 1837 .get = aureon_ac97_micboost_get,
1813 .put = aureon_ac97_micboost_put 1838 .put = aureon_ac97_micboost_put
1814 }, 1839 },
1815 { 1840 {
1816 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1841 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1817 .name = "Aux Playback Switch", 1842 .name = "Aux Playback Switch",
1818 .info = aureon_ac97_mute_info, 1843 .info = aureon_ac97_mute_info,
1819 .get = aureon_ac97_mute_get, 1844 .get = aureon_ac97_mute_get,
1820 .put = aureon_ac97_mute_put, 1845 .put = aureon_ac97_mute_put,
1821 .private_value = AC97_VIDEO, 1846 .private_value = AC97_VIDEO,
1822 }, 1847 },
1823 { 1848 {
1824 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1849 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1825 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 1850 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1826 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 1851 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1827 .name = "Aux Playback Volume", 1852 .name = "Aux Playback Volume",
1828 .info = aureon_ac97_vol_info, 1853 .info = aureon_ac97_vol_info,
1829 .get = aureon_ac97_vol_get, 1854 .get = aureon_ac97_vol_get,
1830 .put = aureon_ac97_vol_put, 1855 .put = aureon_ac97_vol_put,
1831 .private_value = AC97_VIDEO|AUREON_AC97_STEREO, 1856 .private_value = AC97_VIDEO|AUREON_AC97_STEREO,
1832 .tlv = { .p = db_scale_ac97_gain } 1857 .tlv = { .p = db_scale_ac97_gain }
1833 }, 1858 },
1834 { 1859 {
1835 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1860 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1836 .name = "Aux Source", 1861 .name = "Aux Source",
@@ -1844,43 +1869,43 @@ static struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = {
1844static struct snd_kcontrol_new cs8415_controls[] __devinitdata = { 1869static struct snd_kcontrol_new cs8415_controls[] __devinitdata = {
1845 { 1870 {
1846 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1871 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1847 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 1872 .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, SWITCH),
1848 .info = aureon_cs8415_mute_info, 1873 .info = aureon_cs8415_mute_info,
1849 .get = aureon_cs8415_mute_get, 1874 .get = aureon_cs8415_mute_get,
1850 .put = aureon_cs8415_mute_put 1875 .put = aureon_cs8415_mute_put
1851 }, 1876 },
1852 { 1877 {
1853 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1878 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1854 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,NONE) "Source", 1879 .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, NONE) "Source",
1855 .info = aureon_cs8415_mux_info, 1880 .info = aureon_cs8415_mux_info,
1856 .get = aureon_cs8415_mux_get, 1881 .get = aureon_cs8415_mux_get,
1857 .put = aureon_cs8415_mux_put, 1882 .put = aureon_cs8415_mux_put,
1858 }, 1883 },
1859 { 1884 {
1860 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1885 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1861 .name = SNDRV_CTL_NAME_IEC958("Q-subcode ",CAPTURE,DEFAULT), 1886 .name = SNDRV_CTL_NAME_IEC958("Q-subcode ", CAPTURE, DEFAULT),
1862 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 1887 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
1863 .info = aureon_cs8415_qsub_info, 1888 .info = aureon_cs8415_qsub_info,
1864 .get = aureon_cs8415_qsub_get, 1889 .get = aureon_cs8415_qsub_get,
1865 }, 1890 },
1866 { 1891 {
1867 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1892 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1868 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,MASK), 1893 .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, MASK),
1869 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1894 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1870 .info = aureon_cs8415_spdif_info, 1895 .info = aureon_cs8415_spdif_info,
1871 .get = aureon_cs8415_mask_get 1896 .get = aureon_cs8415_mask_get
1872 }, 1897 },
1873 { 1898 {
1874 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1899 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1875 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,DEFAULT), 1900 .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, DEFAULT),
1876 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 1901 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
1877 .info = aureon_cs8415_spdif_info, 1902 .info = aureon_cs8415_spdif_info,
1878 .get = aureon_cs8415_spdif_get 1903 .get = aureon_cs8415_spdif_get
1879 }, 1904 },
1880 { 1905 {
1881 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1906 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1882 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,NONE) "Rate", 1907 .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, NONE) "Rate",
1883 .access =SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 1908 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
1884 .info = aureon_cs8415_rate_info, 1909 .info = aureon_cs8415_rate_info,
1885 .get = aureon_cs8415_rate_get 1910 .get = aureon_cs8415_rate_get
1886 } 1911 }
@@ -1905,15 +1930,14 @@ static int __devinit aureon_add_controls(struct snd_ice1712 *ice)
1905 if (err < 0) 1930 if (err < 0)
1906 return err; 1931 return err;
1907 } 1932 }
1908 1933
1909 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON71_UNIVERSE) { 1934 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON71_UNIVERSE) {
1910 for (i = 0; i < ARRAY_SIZE(universe_ac97_controls); i++) { 1935 for (i = 0; i < ARRAY_SIZE(universe_ac97_controls); i++) {
1911 err = snd_ctl_add(ice->card, snd_ctl_new1(&universe_ac97_controls[i], ice)); 1936 err = snd_ctl_add(ice->card, snd_ctl_new1(&universe_ac97_controls[i], ice));
1912 if (err < 0) 1937 if (err < 0)
1913 return err; 1938 return err;
1914 } 1939 }
1915 } 1940 } else if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
1916 else if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
1917 ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) { 1941 ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) {
1918 for (i = 0; i < ARRAY_SIZE(ac97_controls); i++) { 1942 for (i = 0; i < ARRAY_SIZE(ac97_controls); i++) {
1919 err = snd_ctl_add(ice->card, snd_ctl_new1(&ac97_controls[i], ice)); 1943 err = snd_ctl_add(ice->card, snd_ctl_new1(&ac97_controls[i], ice));
@@ -1932,7 +1956,7 @@ static int __devinit aureon_add_controls(struct snd_ice1712 *ice)
1932 else if ((id & 0x0F) != 0x01) 1956 else if ((id & 0x0F) != 0x01)
1933 snd_printk(KERN_INFO "Detected unsupported CS8415 rev. (%c)\n", (char)((id & 0x0F) + 'A' - 1)); 1957 snd_printk(KERN_INFO "Detected unsupported CS8415 rev. (%c)\n", (char)((id & 0x0F) + 'A' - 1));
1934 else { 1958 else {
1935 for (i = 0; i< ARRAY_SIZE(cs8415_controls); i++) { 1959 for (i = 0; i < ARRAY_SIZE(cs8415_controls); i++) {
1936 struct snd_kcontrol *kctl; 1960 struct snd_kcontrol *kctl;
1937 err = snd_ctl_add(ice->card, (kctl = snd_ctl_new1(&cs8415_controls[i], ice))); 1961 err = snd_ctl_add(ice->card, (kctl = snd_ctl_new1(&cs8415_controls[i], ice)));
1938 if (err < 0) 1962 if (err < 0)
@@ -1943,7 +1967,7 @@ static int __devinit aureon_add_controls(struct snd_ice1712 *ice)
1943 } 1967 }
1944 snd_ice1712_restore_gpio_status(ice); 1968 snd_ice1712_restore_gpio_status(ice);
1945 } 1969 }
1946 1970
1947 return 0; 1971 return 0;
1948} 1972}
1949 1973
@@ -2059,11 +2083,12 @@ static int __devinit aureon_init(struct snd_ice1712 *ice)
2059 2083
2060 /* to remeber the register values of CS8415 */ 2084 /* to remeber the register values of CS8415 */
2061 ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); 2085 ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
2062 if (! ice->akm) 2086 if (!ice->akm)
2063 return -ENOMEM; 2087 return -ENOMEM;
2064 ice->akm_codecs = 1; 2088 ice->akm_codecs = 1;
2065 2089
2066 if ((err = aureon_ac97_init(ice)) != 0) 2090 err = aureon_ac97_init(ice);
2091 if (err != 0)
2067 return err; 2092 return err;
2068 2093
2069 snd_ice1712_gpio_set_dir(ice, 0x5fffff); /* fix this for the time being */ 2094 snd_ice1712_gpio_set_dir(ice, 0x5fffff); /* fix this for the time being */
@@ -2086,7 +2111,7 @@ static int __devinit aureon_init(struct snd_ice1712 *ice)
2086 /* initialize WM8770 codec */ 2111 /* initialize WM8770 codec */
2087 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71 || 2112 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71 ||
2088 ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT || 2113 ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT ||
2089 ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71XT) 2114 ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71XT)
2090 p = wm_inits_prodigy; 2115 p = wm_inits_prodigy;
2091 else 2116 else
2092 p = wm_inits_aureon; 2117 p = wm_inits_aureon;
@@ -2105,10 +2130,10 @@ static int __devinit aureon_init(struct snd_ice1712 *ice)
2105 2130
2106 snd_ice1712_restore_gpio_status(ice); 2131 snd_ice1712_restore_gpio_status(ice);
2107 2132
2108 /* initialize PCA9554 pin directions & set default input*/ 2133 /* initialize PCA9554 pin directions & set default input */
2109 aureon_pca9554_write(ice, PCA9554_DIR, 0x00); 2134 aureon_pca9554_write(ice, PCA9554_DIR, 0x00);
2110 aureon_pca9554_write(ice, PCA9554_OUT, 0x00); /* internal AUX */ 2135 aureon_pca9554_write(ice, PCA9554_OUT, 0x00); /* internal AUX */
2111 2136
2112 spec->master[0] = WM_VOL_MUTE; 2137 spec->master[0] = WM_VOL_MUTE;
2113 spec->master[1] = WM_VOL_MUTE; 2138 spec->master[1] = WM_VOL_MUTE;
2114 for (i = 0; i < ice->num_total_dacs; i++) { 2139 for (i = 0; i < ice->num_total_dacs; i++) {
@@ -2158,6 +2183,24 @@ static unsigned char aureon71_eeprom[] __devinitdata = {
2158}; 2183};
2159#define prodigy71_eeprom aureon71_eeprom 2184#define prodigy71_eeprom aureon71_eeprom
2160 2185
2186static unsigned char aureon71_universe_eeprom[] __devinitdata = {
2187 [ICE_EEP2_SYSCONF] = 0x2b, /* clock 512, mpu401, spdif-in/ADC,
2188 * 4DACs
2189 */
2190 [ICE_EEP2_ACLINK] = 0x80, /* I2S */
2191 [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */
2192 [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
2193 [ICE_EEP2_GPIO_DIR] = 0xff,
2194 [ICE_EEP2_GPIO_DIR1] = 0xff,
2195 [ICE_EEP2_GPIO_DIR2] = 0x5f,
2196 [ICE_EEP2_GPIO_MASK] = 0x00,
2197 [ICE_EEP2_GPIO_MASK1] = 0x00,
2198 [ICE_EEP2_GPIO_MASK2] = 0x00,
2199 [ICE_EEP2_GPIO_STATE] = 0x00,
2200 [ICE_EEP2_GPIO_STATE1] = 0x00,
2201 [ICE_EEP2_GPIO_STATE2] = 0x00,
2202};
2203
2161static unsigned char prodigy71lt_eeprom[] __devinitdata = { 2204static unsigned char prodigy71lt_eeprom[] __devinitdata = {
2162 [ICE_EEP2_SYSCONF] = 0x4b, /* clock 384, spdif-in/ADC, 4DACs */ 2205 [ICE_EEP2_SYSCONF] = 0x4b, /* clock 384, spdif-in/ADC, 4DACs */
2163 [ICE_EEP2_ACLINK] = 0x80, /* I2S */ 2206 [ICE_EEP2_ACLINK] = 0x80, /* I2S */
@@ -2197,14 +2240,14 @@ struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = {
2197 .eeprom_data = aureon71_eeprom, 2240 .eeprom_data = aureon71_eeprom,
2198 .driver = "Aureon71", 2241 .driver = "Aureon71",
2199 }, 2242 },
2200 { 2243 {
2201 .subvendor = VT1724_SUBDEVICE_AUREON71_UNIVERSE, 2244 .subvendor = VT1724_SUBDEVICE_AUREON71_UNIVERSE,
2202 .name = "Terratec Aureon 7.1-Universe", 2245 .name = "Terratec Aureon 7.1-Universe",
2203 .model = "universe", 2246 .model = "universe",
2204 .chip_init = aureon_init, 2247 .chip_init = aureon_init,
2205 .build_controls = aureon_add_controls, 2248 .build_controls = aureon_add_controls,
2206 .eeprom_size = sizeof(aureon71_eeprom), 2249 .eeprom_size = sizeof(aureon71_universe_eeprom),
2207 .eeprom_data = aureon71_eeprom, 2250 .eeprom_data = aureon71_universe_eeprom,
2208 .driver = "Aureon71Univ", /* keep in 15 letters */ 2251 .driver = "Aureon71Univ", /* keep in 15 letters */
2209 }, 2252 },
2210 { 2253 {
diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c
index 0ed96c178059..d216362626d0 100644
--- a/sound/pci/ice1712/delta.c
+++ b/sound/pci/ice1712/delta.c
@@ -400,7 +400,7 @@ static void delta_setup_spdif(struct snd_ice1712 *ice, int rate)
400static int snd_ice1712_delta1010lt_wordclock_status_get(struct snd_kcontrol *kcontrol, 400static int snd_ice1712_delta1010lt_wordclock_status_get(struct snd_kcontrol *kcontrol,
401 struct snd_ctl_elem_value *ucontrol) 401 struct snd_ctl_elem_value *ucontrol)
402{ 402{
403 char reg = 0x10; // cs8427 receiver error register 403 char reg = 0x10; /* CS8427 receiver error register */
404 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 404 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
405 405
406 if (snd_i2c_sendbytes(ice->cs8427, &reg, 1) != 1) 406 if (snd_i2c_sendbytes(ice->cs8427, &reg, 1) != 1)
diff --git a/sound/pci/ice1712/delta.h b/sound/pci/ice1712/delta.h
index ea7116c304c0..f7f14df81f26 100644
--- a/sound/pci/ice1712/delta.h
+++ b/sound/pci/ice1712/delta.h
@@ -31,6 +31,7 @@
31 "{MidiMan M Audio,Delta DiO 2496},"\ 31 "{MidiMan M Audio,Delta DiO 2496},"\
32 "{MidiMan M Audio,Delta 66},"\ 32 "{MidiMan M Audio,Delta 66},"\
33 "{MidiMan M Audio,Delta 44},"\ 33 "{MidiMan M Audio,Delta 44},"\
34 "{MidiMan M Audio,Delta 410},"\
34 "{MidiMan M Audio,Audiophile 24/96},"\ 35 "{MidiMan M Audio,Audiophile 24/96},"\
35 "{Digigram,VX442},"\ 36 "{Digigram,VX442},"\
36 "{Lionstracs,Mediastation}," 37 "{Lionstracs,Mediastation},"
diff --git a/sound/pci/ice1712/ews.c b/sound/pci/ice1712/ews.c
index 013fc4f04822..6fe35b812040 100644
--- a/sound/pci/ice1712/ews.c
+++ b/sound/pci/ice1712/ews.c
@@ -149,7 +149,8 @@ static int snd_ice1712_ews88mt_chip_select(struct snd_ice1712 *ice, int chip_mas
149 struct ews_spec *spec = ice->spec; 149 struct ews_spec *spec = ice->spec;
150 unsigned char data, ndata; 150 unsigned char data, ndata;
151 151
152 snd_assert(chip_mask >= 0 && chip_mask <= 0x0f, return -EINVAL); 152 if (snd_BUG_ON(chip_mask < 0 || chip_mask > 0x0f))
153 return -EINVAL;
153 snd_i2c_lock(ice->i2c); 154 snd_i2c_lock(ice->i2c);
154 if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_PCF2], &data, 1) != 1) 155 if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_PCF2], &data, 1) != 1)
155 goto __error; 156 goto __error;
@@ -685,7 +686,8 @@ static int snd_ice1712_ews88mt_input_sense_get(struct snd_kcontrol *kcontrol, st
685 int channel = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 686 int channel = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
686 unsigned char data; 687 unsigned char data;
687 688
688 snd_assert(channel >= 0 && channel <= 7, return 0); 689 if (snd_BUG_ON(channel < 0 || channel > 7))
690 return 0;
689 snd_i2c_lock(ice->i2c); 691 snd_i2c_lock(ice->i2c);
690 if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_PCF1], &data, 1) != 1) { 692 if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_PCF1], &data, 1) != 1) {
691 snd_i2c_unlock(ice->i2c); 693 snd_i2c_unlock(ice->i2c);
@@ -705,7 +707,8 @@ static int snd_ice1712_ews88mt_input_sense_put(struct snd_kcontrol *kcontrol, st
705 int channel = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 707 int channel = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
706 unsigned char data, ndata; 708 unsigned char data, ndata;
707 709
708 snd_assert(channel >= 0 && channel <= 7, return 0); 710 if (snd_BUG_ON(channel < 0 || channel > 7))
711 return 0;
709 snd_i2c_lock(ice->i2c); 712 snd_i2c_lock(ice->i2c);
710 if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_PCF1], &data, 1) != 1) { 713 if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_PCF1], &data, 1) != 1) {
711 snd_i2c_unlock(ice->i2c); 714 snd_i2c_unlock(ice->i2c);
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
index 29d449d73c98..5b442383fcda 100644
--- a/sound/pci/ice1712/ice1712.c
+++ b/sound/pci/ice1712/ice1712.c
@@ -17,7 +17,7 @@
17 * along with this program; if not, write to the Free Software 17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 * 19 *
20 */ 20 */
21 21
22/* 22/*
23 NOTES: 23 NOTES:
@@ -35,7 +35,7 @@
35 * 35 *
36 * 2002.11.26 James Stafford <jstafford@ampltd.com> 36 * 2002.11.26 James Stafford <jstafford@ampltd.com>
37 * Added support for VT1724 (Envy24HT) 37 * Added support for VT1724 (Envy24HT)
38 * I have left out support for 176.4 and 192 KHz for the moment. 38 * I have left out support for 176.4 and 192 KHz for the moment.
39 * I also haven't done anything with the internal S/PDIF transmitter or the MPU-401 39 * I also haven't done anything with the internal S/PDIF transmitter or the MPU-401
40 * 40 *
41 * 2003.02.20 Taksahi Iwai <tiwai@suse.de> 41 * 2003.02.20 Taksahi Iwai <tiwai@suse.de>
@@ -47,7 +47,7 @@
47 */ 47 */
48 48
49 49
50#include <asm/io.h> 50#include <linux/io.h>
51#include <linux/delay.h> 51#include <linux/delay.h>
52#include <linux/interrupt.h> 52#include <linux/interrupt.h>
53#include <linux/init.h> 53#include <linux/init.h>
@@ -123,7 +123,7 @@ static unsigned int PRO_RATE_DEFAULT = 44100;
123/* 123/*
124 * Basic I/O 124 * Basic I/O
125 */ 125 */
126 126
127/* check whether the clock mode is spdif-in */ 127/* check whether the clock mode is spdif-in */
128static inline int is_spdif_master(struct snd_ice1712 *ice) 128static inline int is_spdif_master(struct snd_ice1712 *ice)
129{ 129{
@@ -135,13 +135,13 @@ static inline int is_pro_rate_locked(struct snd_ice1712 *ice)
135 return is_spdif_master(ice) || PRO_RATE_LOCKED; 135 return is_spdif_master(ice) || PRO_RATE_LOCKED;
136} 136}
137 137
138static inline void snd_ice1712_ds_write(struct snd_ice1712 * ice, u8 channel, u8 addr, u32 data) 138static inline void snd_ice1712_ds_write(struct snd_ice1712 *ice, u8 channel, u8 addr, u32 data)
139{ 139{
140 outb((channel << 4) | addr, ICEDS(ice, INDEX)); 140 outb((channel << 4) | addr, ICEDS(ice, INDEX));
141 outl(data, ICEDS(ice, DATA)); 141 outl(data, ICEDS(ice, DATA));
142} 142}
143 143
144static inline u32 snd_ice1712_ds_read(struct snd_ice1712 * ice, u8 channel, u8 addr) 144static inline u32 snd_ice1712_ds_read(struct snd_ice1712 *ice, u8 channel, u8 addr)
145{ 145{
146 outb((channel << 4) | addr, ICEDS(ice, INDEX)); 146 outb((channel << 4) | addr, ICEDS(ice, INDEX));
147 return inl(ICEDS(ice, DATA)); 147 return inl(ICEDS(ice, DATA));
@@ -260,7 +260,7 @@ static unsigned short snd_ice1712_pro_ac97_read(struct snd_ac97 *ac97,
260static int snd_ice1712_digmix_route_ac97_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 260static int snd_ice1712_digmix_route_ac97_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
261{ 261{
262 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 262 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
263 263
264 ucontrol->value.integer.value[0] = inb(ICEMT(ice, MONITOR_ROUTECTRL)) & ICE1712_ROUTE_AC97 ? 1 : 0; 264 ucontrol->value.integer.value[0] = inb(ICEMT(ice, MONITOR_ROUTECTRL)) & ICE1712_ROUTE_AC97 ? 1 : 0;
265 return 0; 265 return 0;
266} 266}
@@ -269,11 +269,12 @@ static int snd_ice1712_digmix_route_ac97_put(struct snd_kcontrol *kcontrol, stru
269{ 269{
270 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 270 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
271 unsigned char val, nval; 271 unsigned char val, nval;
272 272
273 spin_lock_irq(&ice->reg_lock); 273 spin_lock_irq(&ice->reg_lock);
274 val = inb(ICEMT(ice, MONITOR_ROUTECTRL)); 274 val = inb(ICEMT(ice, MONITOR_ROUTECTRL));
275 nval = val & ~ICE1712_ROUTE_AC97; 275 nval = val & ~ICE1712_ROUTE_AC97;
276 if (ucontrol->value.integer.value[0]) nval |= ICE1712_ROUTE_AC97; 276 if (ucontrol->value.integer.value[0])
277 nval |= ICE1712_ROUTE_AC97;
277 outb(nval, ICEMT(ice, MONITOR_ROUTECTRL)); 278 outb(nval, ICEMT(ice, MONITOR_ROUTECTRL));
278 spin_unlock_irq(&ice->reg_lock); 279 spin_unlock_irq(&ice->reg_lock);
279 return val != nval; 280 return val != nval;
@@ -329,7 +330,7 @@ static int snd_ice1712_cs8427_set_input_clock(struct snd_ice1712 *ice, int spdif
329 unsigned char reg[2] = { 0x80 | 4, 0 }; /* CS8427 auto increment | register number 4 + data */ 330 unsigned char reg[2] = { 0x80 | 4, 0 }; /* CS8427 auto increment | register number 4 + data */
330 unsigned char val, nval; 331 unsigned char val, nval;
331 int res = 0; 332 int res = 0;
332 333
333 snd_i2c_lock(ice->i2c); 334 snd_i2c_lock(ice->i2c);
334 if (snd_i2c_sendbytes(ice->cs8427, reg, 1) != 1) { 335 if (snd_i2c_sendbytes(ice->cs8427, reg, 1) != 1) {
335 snd_i2c_unlock(ice->i2c); 336 snd_i2c_unlock(ice->i2c);
@@ -381,9 +382,9 @@ int __devinit snd_ice1712_init_cs8427(struct snd_ice1712 *ice, int addr)
381{ 382{
382 int err; 383 int err;
383 384
384 if ((err = snd_cs8427_create(ice->i2c, addr, 385 err = snd_cs8427_create(ice->i2c, addr,
385 (ice->cs8427_timeout * HZ) / 1000, 386 (ice->cs8427_timeout * HZ) / 1000, &ice->cs8427);
386 &ice->cs8427)) < 0) { 387 if (err < 0) {
387 snd_printk(KERN_ERR "CS8427 initialization failed\n"); 388 snd_printk(KERN_ERR "CS8427 initialization failed\n");
388 return err; 389 return err;
389 } 390 }
@@ -395,9 +396,9 @@ int __devinit snd_ice1712_init_cs8427(struct snd_ice1712 *ice, int addr)
395 396
396static void snd_ice1712_set_input_clock_source(struct snd_ice1712 *ice, int spdif_is_master) 397static void snd_ice1712_set_input_clock_source(struct snd_ice1712 *ice, int spdif_is_master)
397{ 398{
398 /* change CS8427 clock source too */ 399 /* change CS8427 clock source too */
399 if (ice->cs8427) 400 if (ice->cs8427)
400 snd_ice1712_cs8427_set_input_clock(ice, spdif_is_master); 401 snd_ice1712_cs8427_set_input_clock(ice, spdif_is_master);
401 /* notify ak4524 chip as well */ 402 /* notify ak4524 chip as well */
402 if (spdif_is_master) { 403 if (spdif_is_master) {
403 unsigned int i; 404 unsigned int i;
@@ -457,11 +458,12 @@ static irqreturn_t snd_ice1712_interrupt(int irq, void *dev_id)
457 u16 pbkstatus; 458 u16 pbkstatus;
458 struct snd_pcm_substream *substream; 459 struct snd_pcm_substream *substream;
459 pbkstatus = inw(ICEDS(ice, INTSTAT)); 460 pbkstatus = inw(ICEDS(ice, INTSTAT));
460 //printk("pbkstatus = 0x%x\n", pbkstatus); 461 /* printk("pbkstatus = 0x%x\n", pbkstatus); */
461 for (idx = 0; idx < 6; idx++) { 462 for (idx = 0; idx < 6; idx++) {
462 if ((pbkstatus & (3 << (idx * 2))) == 0) 463 if ((pbkstatus & (3 << (idx * 2))) == 0)
463 continue; 464 continue;
464 if ((substream = ice->playback_con_substream_ds[idx]) != NULL) 465 substream = ice->playback_con_substream_ds[idx];
466 if (substream != NULL)
465 snd_pcm_period_elapsed(substream); 467 snd_pcm_period_elapsed(substream);
466 outw(3 << (idx * 2), ICEDS(ice, INTSTAT)); 468 outw(3 << (idx * 2), ICEDS(ice, INTSTAT));
467 } 469 }
@@ -507,7 +509,7 @@ static int snd_ice1712_playback_trigger(struct snd_pcm_substream *substream,
507 struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); 509 struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
508 int result = 0; 510 int result = 0;
509 u32 tmp; 511 u32 tmp;
510 512
511 spin_lock(&ice->reg_lock); 513 spin_lock(&ice->reg_lock);
512 tmp = snd_ice1712_read(ice, ICE1712_IREG_PBK_CTRL); 514 tmp = snd_ice1712_read(ice, ICE1712_IREG_PBK_CTRL);
513 if (cmd == SNDRV_PCM_TRIGGER_START) { 515 if (cmd == SNDRV_PCM_TRIGGER_START) {
@@ -532,7 +534,7 @@ static int snd_ice1712_playback_ds_trigger(struct snd_pcm_substream *substream,
532 struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); 534 struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
533 int result = 0; 535 int result = 0;
534 u32 tmp; 536 u32 tmp;
535 537
536 spin_lock(&ice->reg_lock); 538 spin_lock(&ice->reg_lock);
537 tmp = snd_ice1712_ds_read(ice, substream->number * 2, ICE1712_DSC_CONTROL); 539 tmp = snd_ice1712_ds_read(ice, substream->number * 2, ICE1712_DSC_CONTROL);
538 if (cmd == SNDRV_PCM_TRIGGER_START) { 540 if (cmd == SNDRV_PCM_TRIGGER_START) {
@@ -557,7 +559,7 @@ static int snd_ice1712_capture_trigger(struct snd_pcm_substream *substream,
557 struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); 559 struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
558 int result = 0; 560 int result = 0;
559 u8 tmp; 561 u8 tmp;
560 562
561 spin_lock(&ice->reg_lock); 563 spin_lock(&ice->reg_lock);
562 tmp = snd_ice1712_read(ice, ICE1712_IREG_CAP_CTRL); 564 tmp = snd_ice1712_read(ice, ICE1712_IREG_CAP_CTRL);
563 if (cmd == SNDRV_PCM_TRIGGER_START) { 565 if (cmd == SNDRV_PCM_TRIGGER_START) {
@@ -711,8 +713,7 @@ static snd_pcm_uframes_t snd_ice1712_capture_pointer(struct snd_pcm_substream *s
711 return bytes_to_frames(substream->runtime, ptr); 713 return bytes_to_frames(substream->runtime, ptr);
712} 714}
713 715
714static const struct snd_pcm_hardware snd_ice1712_playback = 716static const struct snd_pcm_hardware snd_ice1712_playback = {
715{
716 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 717 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
717 SNDRV_PCM_INFO_BLOCK_TRANSFER | 718 SNDRV_PCM_INFO_BLOCK_TRANSFER |
718 SNDRV_PCM_INFO_MMAP_VALID | 719 SNDRV_PCM_INFO_MMAP_VALID |
@@ -731,8 +732,7 @@ static const struct snd_pcm_hardware snd_ice1712_playback =
731 .fifo_size = 0, 732 .fifo_size = 0,
732}; 733};
733 734
734static const struct snd_pcm_hardware snd_ice1712_playback_ds = 735static const struct snd_pcm_hardware snd_ice1712_playback_ds = {
735{
736 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 736 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
737 SNDRV_PCM_INFO_BLOCK_TRANSFER | 737 SNDRV_PCM_INFO_BLOCK_TRANSFER |
738 SNDRV_PCM_INFO_MMAP_VALID | 738 SNDRV_PCM_INFO_MMAP_VALID |
@@ -751,8 +751,7 @@ static const struct snd_pcm_hardware snd_ice1712_playback_ds =
751 .fifo_size = 0, 751 .fifo_size = 0,
752}; 752};
753 753
754static const struct snd_pcm_hardware snd_ice1712_capture = 754static const struct snd_pcm_hardware snd_ice1712_capture = {
755{
756 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 755 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
757 SNDRV_PCM_INFO_BLOCK_TRANSFER | 756 SNDRV_PCM_INFO_BLOCK_TRANSFER |
758 SNDRV_PCM_INFO_MMAP_VALID), 757 SNDRV_PCM_INFO_MMAP_VALID),
@@ -788,7 +787,7 @@ static int snd_ice1712_playback_ds_open(struct snd_pcm_substream *substream)
788 787
789 ice->playback_con_substream_ds[substream->number] = substream; 788 ice->playback_con_substream_ds[substream->number] = substream;
790 runtime->hw = snd_ice1712_playback_ds; 789 runtime->hw = snd_ice1712_playback_ds;
791 spin_lock_irq(&ice->reg_lock); 790 spin_lock_irq(&ice->reg_lock);
792 tmp = inw(ICEDS(ice, INTMASK)) & ~(1 << (substream->number * 2)); 791 tmp = inw(ICEDS(ice, INTMASK)) & ~(1 << (substream->number * 2));
793 outw(tmp, ICEDS(ice, INTMASK)); 792 outw(tmp, ICEDS(ice, INTMASK));
794 spin_unlock_irq(&ice->reg_lock); 793 spin_unlock_irq(&ice->reg_lock);
@@ -821,7 +820,7 @@ static int snd_ice1712_playback_ds_close(struct snd_pcm_substream *substream)
821 struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); 820 struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
822 u32 tmp; 821 u32 tmp;
823 822
824 spin_lock_irq(&ice->reg_lock); 823 spin_lock_irq(&ice->reg_lock);
825 tmp = inw(ICEDS(ice, INTMASK)) | (3 << (substream->number * 2)); 824 tmp = inw(ICEDS(ice, INTMASK)) | (3 << (substream->number * 2));
826 outw(tmp, ICEDS(ice, INTMASK)); 825 outw(tmp, ICEDS(ice, INTMASK));
827 spin_unlock_irq(&ice->reg_lock); 826 spin_unlock_irq(&ice->reg_lock);
@@ -870,7 +869,7 @@ static struct snd_pcm_ops snd_ice1712_capture_ops = {
870 .pointer = snd_ice1712_capture_pointer, 869 .pointer = snd_ice1712_capture_pointer,
871}; 870};
872 871
873static int __devinit snd_ice1712_pcm(struct snd_ice1712 * ice, int device, struct snd_pcm ** rpcm) 872static int __devinit snd_ice1712_pcm(struct snd_ice1712 *ice, int device, struct snd_pcm **rpcm)
874{ 873{
875 struct snd_pcm *pcm; 874 struct snd_pcm *pcm;
876 int err; 875 int err;
@@ -900,7 +899,7 @@ static int __devinit snd_ice1712_pcm(struct snd_ice1712 * ice, int device, struc
900 return 0; 899 return 0;
901} 900}
902 901
903static int __devinit snd_ice1712_pcm_ds(struct snd_ice1712 * ice, int device, struct snd_pcm ** rpcm) 902static int __devinit snd_ice1712_pcm_ds(struct snd_ice1712 *ice, int device, struct snd_pcm **rpcm)
904{ 903{
905 struct snd_pcm *pcm; 904 struct snd_pcm *pcm;
906 int err; 905 int err;
@@ -1029,14 +1028,14 @@ static void snd_ice1712_set_pro_rate(struct snd_ice1712 *ice, unsigned int rate,
1029 if (inb(ICEMT(ice, PLAYBACK_CONTROL)) & (ICE1712_CAPTURE_START_SHADOW| 1028 if (inb(ICEMT(ice, PLAYBACK_CONTROL)) & (ICE1712_CAPTURE_START_SHADOW|
1030 ICE1712_PLAYBACK_PAUSE| 1029 ICE1712_PLAYBACK_PAUSE|
1031 ICE1712_PLAYBACK_START)) { 1030 ICE1712_PLAYBACK_START)) {
1032 __out: 1031__out:
1033 spin_unlock_irqrestore(&ice->reg_lock, flags); 1032 spin_unlock_irqrestore(&ice->reg_lock, flags);
1034 return; 1033 return;
1035 } 1034 }
1036 if (!force && is_pro_rate_locked(ice)) 1035 if (!force && is_pro_rate_locked(ice))
1037 goto __out; 1036 goto __out;
1038 1037
1039 old = inb(ICEMT(ice, RATE)); 1038 old = inb(ICEMT(ice, RATE));
1040 if (!force && old == val) 1039 if (!force && old == val)
1041 goto __out; 1040 goto __out;
1042 outb(val, ICEMT(ice, RATE)); 1041 outb(val, ICEMT(ice, RATE));
@@ -1123,8 +1122,7 @@ static snd_pcm_uframes_t snd_ice1712_capture_pro_pointer(struct snd_pcm_substrea
1123 return bytes_to_frames(substream->runtime, ptr); 1122 return bytes_to_frames(substream->runtime, ptr);
1124} 1123}
1125 1124
1126static const struct snd_pcm_hardware snd_ice1712_playback_pro = 1125static const struct snd_pcm_hardware snd_ice1712_playback_pro = {
1127{
1128 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 1126 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1129 SNDRV_PCM_INFO_BLOCK_TRANSFER | 1127 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1130 SNDRV_PCM_INFO_MMAP_VALID | 1128 SNDRV_PCM_INFO_MMAP_VALID |
@@ -1143,8 +1141,7 @@ static const struct snd_pcm_hardware snd_ice1712_playback_pro =
1143 .fifo_size = 0, 1141 .fifo_size = 0,
1144}; 1142};
1145 1143
1146static const struct snd_pcm_hardware snd_ice1712_capture_pro = 1144static const struct snd_pcm_hardware snd_ice1712_capture_pro = {
1147{
1148 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 1145 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1149 SNDRV_PCM_INFO_BLOCK_TRANSFER | 1146 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1150 SNDRV_PCM_INFO_MMAP_VALID | 1147 SNDRV_PCM_INFO_MMAP_VALID |
@@ -1238,7 +1235,7 @@ static struct snd_pcm_ops snd_ice1712_capture_pro_ops = {
1238 .pointer = snd_ice1712_capture_pro_pointer, 1235 .pointer = snd_ice1712_capture_pro_pointer,
1239}; 1236};
1240 1237
1241static int __devinit snd_ice1712_pcm_profi(struct snd_ice1712 * ice, int device, struct snd_pcm ** rpcm) 1238static int __devinit snd_ice1712_pcm_profi(struct snd_ice1712 *ice, int device, struct snd_pcm **rpcm)
1242{ 1239{
1243 struct snd_pcm *pcm; 1240 struct snd_pcm *pcm;
1244 int err; 1241 int err;
@@ -1262,7 +1259,7 @@ static int __devinit snd_ice1712_pcm_profi(struct snd_ice1712 * ice, int device,
1262 ice->pcm_pro = pcm; 1259 ice->pcm_pro = pcm;
1263 if (rpcm) 1260 if (rpcm)
1264 *rpcm = pcm; 1261 *rpcm = pcm;
1265 1262
1266 if (ice->cs8427) { 1263 if (ice->cs8427) {
1267 /* assign channels to iec958 */ 1264 /* assign channels to iec958 */
1268 err = snd_cs8427_iec958_build(ice->cs8427, 1265 err = snd_cs8427_iec958_build(ice->cs8427,
@@ -1272,7 +1269,8 @@ static int __devinit snd_ice1712_pcm_profi(struct snd_ice1712 * ice, int device,
1272 return err; 1269 return err;
1273 } 1270 }
1274 1271
1275 if ((err = snd_ice1712_build_pro_mixer(ice)) < 0) 1272 err = snd_ice1712_build_pro_mixer(ice);
1273 if (err < 0)
1276 return err; 1274 return err;
1277 return 0; 1275 return 0;
1278} 1276}
@@ -1299,7 +1297,7 @@ static int snd_ice1712_pro_mixer_switch_get(struct snd_kcontrol *kcontrol, struc
1299 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 1297 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1300 int priv_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + 1298 int priv_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) +
1301 kcontrol->private_value; 1299 kcontrol->private_value;
1302 1300
1303 spin_lock_irq(&ice->reg_lock); 1301 spin_lock_irq(&ice->reg_lock);
1304 ucontrol->value.integer.value[0] = 1302 ucontrol->value.integer.value[0] =
1305 !((ice->pro_volumes[priv_idx] >> 15) & 1); 1303 !((ice->pro_volumes[priv_idx] >> 15) & 1);
@@ -1341,7 +1339,7 @@ static int snd_ice1712_pro_mixer_volume_get(struct snd_kcontrol *kcontrol, struc
1341 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 1339 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1342 int priv_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + 1340 int priv_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) +
1343 kcontrol->private_value; 1341 kcontrol->private_value;
1344 1342
1345 spin_lock_irq(&ice->reg_lock); 1343 spin_lock_irq(&ice->reg_lock);
1346 ucontrol->value.integer.value[0] = 1344 ucontrol->value.integer.value[0] =
1347 (ice->pro_volumes[priv_idx] >> 0) & 127; 1345 (ice->pro_volumes[priv_idx] >> 0) & 127;
@@ -1406,7 +1404,7 @@ static struct snd_kcontrol_new snd_ice1712_multi_capture_analog_switch __devinit
1406 1404
1407static struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_switch __devinitdata = { 1405static struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_switch __devinitdata = {
1408 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1406 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1409 .name = SNDRV_CTL_NAME_IEC958("Multi ",CAPTURE,SWITCH), 1407 .name = SNDRV_CTL_NAME_IEC958("Multi ", CAPTURE, SWITCH),
1410 .info = snd_ice1712_pro_mixer_switch_info, 1408 .info = snd_ice1712_pro_mixer_switch_info,
1411 .get = snd_ice1712_pro_mixer_switch_get, 1409 .get = snd_ice1712_pro_mixer_switch_get,
1412 .put = snd_ice1712_pro_mixer_switch_put, 1410 .put = snd_ice1712_pro_mixer_switch_put,
@@ -1428,7 +1426,7 @@ static struct snd_kcontrol_new snd_ice1712_multi_capture_analog_volume __devinit
1428 1426
1429static struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_volume __devinitdata = { 1427static struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_volume __devinitdata = {
1430 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1428 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1431 .name = SNDRV_CTL_NAME_IEC958("Multi ",CAPTURE,VOLUME), 1429 .name = SNDRV_CTL_NAME_IEC958("Multi ", CAPTURE, VOLUME),
1432 .info = snd_ice1712_pro_mixer_volume_info, 1430 .info = snd_ice1712_pro_mixer_volume_info,
1433 .get = snd_ice1712_pro_mixer_volume_get, 1431 .get = snd_ice1712_pro_mixer_volume_get,
1434 .put = snd_ice1712_pro_mixer_volume_put, 1432 .put = snd_ice1712_pro_mixer_volume_put,
@@ -1448,7 +1446,7 @@ static int __devinit snd_ice1712_build_pro_mixer(struct snd_ice1712 *ice)
1448 if (err < 0) 1446 if (err < 0)
1449 return err; 1447 return err;
1450 } 1448 }
1451 1449
1452 if (ice->num_total_adcs > 0) { 1450 if (ice->num_total_adcs > 0) {
1453 struct snd_kcontrol_new tmp = snd_ice1712_multi_capture_analog_switch; 1451 struct snd_kcontrol_new tmp = snd_ice1712_multi_capture_analog_switch;
1454 tmp.count = ice->num_total_adcs; 1452 tmp.count = ice->num_total_adcs;
@@ -1495,7 +1493,7 @@ static void snd_ice1712_mixer_free_ac97(struct snd_ac97 *ac97)
1495 ice->ac97 = NULL; 1493 ice->ac97 = NULL;
1496} 1494}
1497 1495
1498static int __devinit snd_ice1712_ac97_mixer(struct snd_ice1712 * ice) 1496static int __devinit snd_ice1712_ac97_mixer(struct snd_ice1712 *ice)
1499{ 1497{
1500 int err, bus_num = 0; 1498 int err, bus_num = 0;
1501 struct snd_ac97_template ac97; 1499 struct snd_ac97_template ac97;
@@ -1510,27 +1508,32 @@ static int __devinit snd_ice1712_ac97_mixer(struct snd_ice1712 * ice)
1510 }; 1508 };
1511 1509
1512 if (ice_has_con_ac97(ice)) { 1510 if (ice_has_con_ac97(ice)) {
1513 if ((err = snd_ac97_bus(ice->card, bus_num++, &con_ops, NULL, &pbus)) < 0) 1511 err = snd_ac97_bus(ice->card, bus_num++, &con_ops, NULL, &pbus);
1512 if (err < 0)
1514 return err; 1513 return err;
1515 memset(&ac97, 0, sizeof(ac97)); 1514 memset(&ac97, 0, sizeof(ac97));
1516 ac97.private_data = ice; 1515 ac97.private_data = ice;
1517 ac97.private_free = snd_ice1712_mixer_free_ac97; 1516 ac97.private_free = snd_ice1712_mixer_free_ac97;
1518 if ((err = snd_ac97_mixer(pbus, &ac97, &ice->ac97)) < 0) 1517 err = snd_ac97_mixer(pbus, &ac97, &ice->ac97);
1518 if (err < 0)
1519 printk(KERN_WARNING "ice1712: cannot initialize ac97 for consumer, skipped\n"); 1519 printk(KERN_WARNING "ice1712: cannot initialize ac97 for consumer, skipped\n");
1520 else { 1520 else {
1521 if ((err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_mixer_digmix_route_ac97, ice))) < 0) 1521 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_mixer_digmix_route_ac97, ice));
1522 if (err < 0)
1522 return err; 1523 return err;
1523 return 0; 1524 return 0;
1524 } 1525 }
1525 } 1526 }
1526 1527
1527 if (! (ice->eeprom.data[ICE_EEP1_ACLINK] & ICE1712_CFG_PRO_I2S)) { 1528 if (!(ice->eeprom.data[ICE_EEP1_ACLINK] & ICE1712_CFG_PRO_I2S)) {
1528 if ((err = snd_ac97_bus(ice->card, bus_num, &pro_ops, NULL, &pbus)) < 0) 1529 err = snd_ac97_bus(ice->card, bus_num, &pro_ops, NULL, &pbus);
1530 if (err < 0)
1529 return err; 1531 return err;
1530 memset(&ac97, 0, sizeof(ac97)); 1532 memset(&ac97, 0, sizeof(ac97));
1531 ac97.private_data = ice; 1533 ac97.private_data = ice;
1532 ac97.private_free = snd_ice1712_mixer_free_ac97; 1534 ac97.private_free = snd_ice1712_mixer_free_ac97;
1533 if ((err = snd_ac97_mixer(pbus, &ac97, &ice->ac97)) < 0) 1535 err = snd_ac97_mixer(pbus, &ac97, &ice->ac97);
1536 if (err < 0)
1534 printk(KERN_WARNING "ice1712: cannot initialize pro ac97, skipped\n"); 1537 printk(KERN_WARNING "ice1712: cannot initialize pro ac97, skipped\n");
1535 else 1538 else
1536 return 0; 1539 return 0;
@@ -1549,7 +1552,7 @@ static inline unsigned int eeprom_double(struct snd_ice1712 *ice, int idx)
1549 return (unsigned int)ice->eeprom.data[idx] | ((unsigned int)ice->eeprom.data[idx + 1] << 8); 1552 return (unsigned int)ice->eeprom.data[idx] | ((unsigned int)ice->eeprom.data[idx + 1] << 8);
1550} 1553}
1551 1554
1552static void snd_ice1712_proc_read(struct snd_info_entry *entry, 1555static void snd_ice1712_proc_read(struct snd_info_entry *entry,
1553 struct snd_info_buffer *buffer) 1556 struct snd_info_buffer *buffer)
1554{ 1557{
1555 struct snd_ice1712 *ice = entry->private_data; 1558 struct snd_ice1712 *ice = entry->private_data;
@@ -1585,15 +1588,15 @@ static void snd_ice1712_proc_read(struct snd_info_entry *entry,
1585 snd_iprintf(buffer, " SPDOUT : 0x%04x\n", (unsigned)inw(ICEMT(ice, ROUTE_SPDOUT))); 1588 snd_iprintf(buffer, " SPDOUT : 0x%04x\n", (unsigned)inw(ICEMT(ice, ROUTE_SPDOUT)));
1586 snd_iprintf(buffer, " RATE : 0x%02x\n", (unsigned)inb(ICEMT(ice, RATE))); 1589 snd_iprintf(buffer, " RATE : 0x%02x\n", (unsigned)inb(ICEMT(ice, RATE)));
1587 snd_iprintf(buffer, " GPIO_DATA : 0x%02x\n", (unsigned)snd_ice1712_get_gpio_data(ice)); 1590 snd_iprintf(buffer, " GPIO_DATA : 0x%02x\n", (unsigned)snd_ice1712_get_gpio_data(ice));
1588 snd_iprintf(buffer, " GPIO_WRITE_MASK : 0x%02x\n", (unsigned)snd_ice1712_read(ice, ICE1712_IREG_GPIO_WRITE_MASK)); 1591 snd_iprintf(buffer, " GPIO_WRITE_MASK : 0x%02x\n", (unsigned)snd_ice1712_read(ice, ICE1712_IREG_GPIO_WRITE_MASK));
1589 snd_iprintf(buffer, " GPIO_DIRECTION : 0x%02x\n", (unsigned)snd_ice1712_read(ice, ICE1712_IREG_GPIO_DIRECTION)); 1592 snd_iprintf(buffer, " GPIO_DIRECTION : 0x%02x\n", (unsigned)snd_ice1712_read(ice, ICE1712_IREG_GPIO_DIRECTION));
1590} 1593}
1591 1594
1592static void __devinit snd_ice1712_proc_init(struct snd_ice1712 * ice) 1595static void __devinit snd_ice1712_proc_init(struct snd_ice1712 *ice)
1593{ 1596{
1594 struct snd_info_entry *entry; 1597 struct snd_info_entry *entry;
1595 1598
1596 if (! snd_card_proc_new(ice->card, "ice1712", &entry)) 1599 if (!snd_card_proc_new(ice->card, "ice1712", &entry))
1597 snd_info_set_text_ops(entry, ice, snd_ice1712_proc_read); 1600 snd_info_set_text_ops(entry, ice, snd_ice1712_proc_read);
1598} 1601}
1599 1602
@@ -1613,7 +1616,7 @@ static int snd_ice1712_eeprom_get(struct snd_kcontrol *kcontrol,
1613 struct snd_ctl_elem_value *ucontrol) 1616 struct snd_ctl_elem_value *ucontrol)
1614{ 1617{
1615 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 1618 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1616 1619
1617 memcpy(ucontrol->value.bytes.data, &ice->eeprom, sizeof(ice->eeprom)); 1620 memcpy(ucontrol->value.bytes.data, &ice->eeprom, sizeof(ice->eeprom));
1618 return 0; 1621 return 0;
1619} 1622}
@@ -1641,7 +1644,7 @@ static int snd_ice1712_spdif_default_get(struct snd_kcontrol *kcontrol,
1641{ 1644{
1642 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 1645 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1643 if (ice->spdif.ops.default_get) 1646 if (ice->spdif.ops.default_get)
1644 ice->spdif.ops.default_get(ice, ucontrol); 1647 ice->spdif.ops.default_get(ice, ucontrol);
1645 return 0; 1648 return 0;
1646} 1649}
1647 1650
@@ -1657,7 +1660,7 @@ static int snd_ice1712_spdif_default_put(struct snd_kcontrol *kcontrol,
1657static struct snd_kcontrol_new snd_ice1712_spdif_default __devinitdata = 1660static struct snd_kcontrol_new snd_ice1712_spdif_default __devinitdata =
1658{ 1661{
1659 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1662 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1660 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), 1663 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
1661 .info = snd_ice1712_spdif_info, 1664 .info = snd_ice1712_spdif_info,
1662 .get = snd_ice1712_spdif_default_get, 1665 .get = snd_ice1712_spdif_default_get,
1663 .put = snd_ice1712_spdif_default_put 1666 .put = snd_ice1712_spdif_default_put
@@ -1709,7 +1712,7 @@ static struct snd_kcontrol_new snd_ice1712_spdif_maskc __devinitdata =
1709{ 1712{
1710 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1713 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1711 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1714 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1712 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK), 1715 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, CON_MASK),
1713 .info = snd_ice1712_spdif_info, 1716 .info = snd_ice1712_spdif_info,
1714 .get = snd_ice1712_spdif_maskc_get, 1717 .get = snd_ice1712_spdif_maskc_get,
1715}; 1718};
@@ -1718,7 +1721,7 @@ static struct snd_kcontrol_new snd_ice1712_spdif_maskp __devinitdata =
1718{ 1721{
1719 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1722 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1720 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1723 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1721 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK), 1724 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PRO_MASK),
1722 .info = snd_ice1712_spdif_info, 1725 .info = snd_ice1712_spdif_info,
1723 .get = snd_ice1712_spdif_maskp_get, 1726 .get = snd_ice1712_spdif_maskp_get,
1724}; 1727};
@@ -1746,7 +1749,7 @@ static struct snd_kcontrol_new snd_ice1712_spdif_stream __devinitdata =
1746 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 1749 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1747 SNDRV_CTL_ELEM_ACCESS_INACTIVE), 1750 SNDRV_CTL_ELEM_ACCESS_INACTIVE),
1748 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1751 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1749 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM), 1752 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PCM_STREAM),
1750 .info = snd_ice1712_spdif_info, 1753 .info = snd_ice1712_spdif_info,
1751 .get = snd_ice1712_spdif_stream_get, 1754 .get = snd_ice1712_spdif_stream_get,
1752 .put = snd_ice1712_spdif_stream_put 1755 .put = snd_ice1712_spdif_stream_put
@@ -1758,7 +1761,7 @@ int snd_ice1712_gpio_get(struct snd_kcontrol *kcontrol,
1758 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 1761 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1759 unsigned char mask = kcontrol->private_value & 0xff; 1762 unsigned char mask = kcontrol->private_value & 0xff;
1760 int invert = (kcontrol->private_value & (1<<24)) ? 1 : 0; 1763 int invert = (kcontrol->private_value & (1<<24)) ? 1 : 0;
1761 1764
1762 snd_ice1712_save_gpio_status(ice); 1765 snd_ice1712_save_gpio_status(ice);
1763 ucontrol->value.integer.value[0] = 1766 ucontrol->value.integer.value[0] =
1764 (snd_ice1712_gpio_read(ice) & mask ? 1 : 0) ^ invert; 1767 (snd_ice1712_gpio_read(ice) & mask ? 1 : 0) ^ invert;
@@ -1825,7 +1828,7 @@ static int snd_ice1712_pro_internal_clock_get(struct snd_kcontrol *kcontrol,
1825 9, 6, 3, 1, 7, 4, 0, 12, 8, 5, 2, 11, 255, 255, 255, 10 1828 9, 6, 3, 1, 7, 4, 0, 12, 8, 5, 2, 11, 255, 255, 255, 10
1826 }; 1829 };
1827 unsigned char val; 1830 unsigned char val;
1828 1831
1829 spin_lock_irq(&ice->reg_lock); 1832 spin_lock_irq(&ice->reg_lock);
1830 if (is_spdif_master(ice)) { 1833 if (is_spdif_master(ice)) {
1831 ucontrol->value.enumerated.item[0] = 13; 1834 ucontrol->value.enumerated.item[0] = 13;
@@ -1867,7 +1870,7 @@ static int snd_ice1712_pro_internal_clock_put(struct snd_kcontrol *kcontrol,
1867 1870
1868 if ((oval & ICE1712_SPDIF_MASTER) != 1871 if ((oval & ICE1712_SPDIF_MASTER) !=
1869 (inb(ICEMT(ice, RATE)) & ICE1712_SPDIF_MASTER)) 1872 (inb(ICEMT(ice, RATE)) & ICE1712_SPDIF_MASTER))
1870 snd_ice1712_set_input_clock_source(ice, is_spdif_master(ice)); 1873 snd_ice1712_set_input_clock_source(ice, is_spdif_master(ice));
1871 1874
1872 return change; 1875 return change;
1873} 1876}
@@ -1897,7 +1900,7 @@ static int snd_ice1712_pro_internal_clock_default_info(struct snd_kcontrol *kcon
1897 "64000", /* 10: 15 */ 1900 "64000", /* 10: 15 */
1898 "88200", /* 11: 11 */ 1901 "88200", /* 11: 11 */
1899 "96000", /* 12: 7 */ 1902 "96000", /* 12: 7 */
1900 // "IEC958 Input", /* 13: -- */ 1903 /* "IEC958 Input", 13: -- */
1901 }; 1904 };
1902 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 1905 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1903 uinfo->count = 1; 1906 uinfo->count = 1;
@@ -2026,7 +2029,7 @@ static int snd_ice1712_pro_route_info(struct snd_kcontrol *kcontrol,
2026 "IEC958 In L", "IEC958 In R", /* 9-10 */ 2029 "IEC958 In L", "IEC958 In R", /* 9-10 */
2027 "Digital Mixer", /* 11 - optional */ 2030 "Digital Mixer", /* 11 - optional */
2028 }; 2031 };
2029 2032
2030 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 2033 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2031 uinfo->count = 1; 2034 uinfo->count = 1;
2032 uinfo->value.enumerated.items = 2035 uinfo->value.enumerated.items =
@@ -2070,7 +2073,7 @@ static int snd_ice1712_pro_route_analog_put(struct snd_kcontrol *kcontrol,
2070 int change, shift; 2073 int change, shift;
2071 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 2074 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2072 unsigned int val, old_val, nval; 2075 unsigned int val, old_val, nval;
2073 2076
2074 /* update PSDOUT */ 2077 /* update PSDOUT */
2075 if (ucontrol->value.enumerated.item[0] >= 11) 2078 if (ucontrol->value.enumerated.item[0] >= 11)
2076 nval = idx < 2 ? 1 : 0; /* dig mixer (or pcm) */ 2079 nval = idx < 2 ? 1 : 0; /* dig mixer (or pcm) */
@@ -2140,7 +2143,7 @@ static int snd_ice1712_pro_route_spdif_put(struct snd_kcontrol *kcontrol,
2140 int change, shift; 2143 int change, shift;
2141 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 2144 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2142 unsigned int val, old_val, nval; 2145 unsigned int val, old_val, nval;
2143 2146
2144 /* update SPDOUT */ 2147 /* update SPDOUT */
2145 spin_lock_irq(&ice->reg_lock); 2148 spin_lock_irq(&ice->reg_lock);
2146 val = old_val = inw(ICEMT(ice, ROUTE_SPDOUT)); 2149 val = old_val = inw(ICEMT(ice, ROUTE_SPDOUT));
@@ -2182,7 +2185,7 @@ static struct snd_kcontrol_new snd_ice1712_mixer_pro_analog_route __devinitdata
2182 2185
2183static struct snd_kcontrol_new snd_ice1712_mixer_pro_spdif_route __devinitdata = { 2186static struct snd_kcontrol_new snd_ice1712_mixer_pro_spdif_route __devinitdata = {
2184 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2187 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2185 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route", 2188 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, NONE) "Route",
2186 .info = snd_ice1712_pro_route_info, 2189 .info = snd_ice1712_pro_route_info,
2187 .get = snd_ice1712_pro_route_spdif_get, 2190 .get = snd_ice1712_pro_route_spdif_get,
2188 .put = snd_ice1712_pro_route_spdif_put, 2191 .put = snd_ice1712_pro_route_spdif_put,
@@ -2204,7 +2207,7 @@ static int snd_ice1712_pro_volume_rate_get(struct snd_kcontrol *kcontrol,
2204 struct snd_ctl_elem_value *ucontrol) 2207 struct snd_ctl_elem_value *ucontrol)
2205{ 2208{
2206 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 2209 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
2207 2210
2208 ucontrol->value.integer.value[0] = inb(ICEMT(ice, MONITOR_RATE)); 2211 ucontrol->value.integer.value[0] = inb(ICEMT(ice, MONITOR_RATE));
2209 return 0; 2212 return 0;
2210} 2213}
@@ -2245,7 +2248,7 @@ static int snd_ice1712_pro_peak_get(struct snd_kcontrol *kcontrol,
2245{ 2248{
2246 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 2249 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
2247 int idx; 2250 int idx;
2248 2251
2249 spin_lock_irq(&ice->reg_lock); 2252 spin_lock_irq(&ice->reg_lock);
2250 for (idx = 0; idx < 22; idx++) { 2253 for (idx = 0; idx < 22; idx++) {
2251 outb(idx, ICEMT(ice, MONITOR_PEAKINDEX)); 2254 outb(idx, ICEMT(ice, MONITOR_PEAKINDEX));
@@ -2296,12 +2299,12 @@ static int __devinit snd_ice1712_read_eeprom(struct snd_ice1712 *ice,
2296 unsigned int i, size; 2299 unsigned int i, size;
2297 struct snd_ice1712_card_info * const *tbl, *c; 2300 struct snd_ice1712_card_info * const *tbl, *c;
2298 2301
2299 if (! modelname || ! *modelname) { 2302 if (!modelname || !*modelname) {
2300 ice->eeprom.subvendor = 0; 2303 ice->eeprom.subvendor = 0;
2301 if ((inb(ICEREG(ice, I2C_CTRL)) & ICE1712_I2C_EEPROM) != 0) 2304 if ((inb(ICEREG(ice, I2C_CTRL)) & ICE1712_I2C_EEPROM) != 0)
2302 ice->eeprom.subvendor = (snd_ice1712_read_i2c(ice, dev, 0x00) << 0) | 2305 ice->eeprom.subvendor = (snd_ice1712_read_i2c(ice, dev, 0x00) << 0) |
2303 (snd_ice1712_read_i2c(ice, dev, 0x01) << 8) | 2306 (snd_ice1712_read_i2c(ice, dev, 0x01) << 8) |
2304 (snd_ice1712_read_i2c(ice, dev, 0x02) << 16) | 2307 (snd_ice1712_read_i2c(ice, dev, 0x02) << 16) |
2305 (snd_ice1712_read_i2c(ice, dev, 0x03) << 24); 2308 (snd_ice1712_read_i2c(ice, dev, 0x03) << 24);
2306 if (ice->eeprom.subvendor == 0 || 2309 if (ice->eeprom.subvendor == 0 ||
2307 ice->eeprom.subvendor == (unsigned int)-1) { 2310 ice->eeprom.subvendor == (unsigned int)-1) {
@@ -2318,12 +2321,12 @@ static int __devinit snd_ice1712_read_eeprom(struct snd_ice1712 *ice,
2318 } 2321 }
2319 for (tbl = card_tables; *tbl; tbl++) { 2322 for (tbl = card_tables; *tbl; tbl++) {
2320 for (c = *tbl; c->subvendor; c++) { 2323 for (c = *tbl; c->subvendor; c++) {
2321 if (modelname && c->model && ! strcmp(modelname, c->model)) { 2324 if (modelname && c->model && !strcmp(modelname, c->model)) {
2322 printk(KERN_INFO "ice1712: Using board model %s\n", c->name); 2325 printk(KERN_INFO "ice1712: Using board model %s\n", c->name);
2323 ice->eeprom.subvendor = c->subvendor; 2326 ice->eeprom.subvendor = c->subvendor;
2324 } else if (c->subvendor != ice->eeprom.subvendor) 2327 } else if (c->subvendor != ice->eeprom.subvendor)
2325 continue; 2328 continue;
2326 if (! c->eeprom_size || ! c->eeprom_data) 2329 if (!c->eeprom_size || !c->eeprom_data)
2327 goto found; 2330 goto found;
2328 /* if the EEPROM is given by the driver, use it */ 2331 /* if the EEPROM is given by the driver, use it */
2329 snd_printdd("using the defined eeprom..\n"); 2332 snd_printdd("using the defined eeprom..\n");
@@ -2416,7 +2419,8 @@ int __devinit snd_ice1712_spdif_build_controls(struct snd_ice1712 *ice)
2416 int err; 2419 int err;
2417 struct snd_kcontrol *kctl; 2420 struct snd_kcontrol *kctl;
2418 2421
2419 snd_assert(ice->pcm_pro != NULL, return -EIO); 2422 if (snd_BUG_ON(!ice->pcm_pro))
2423 return -EIO;
2420 err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_ice1712_spdif_default, ice)); 2424 err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_ice1712_spdif_default, ice));
2421 if (err < 0) 2425 if (err < 0)
2422 return err; 2426 return err;
@@ -2483,13 +2487,13 @@ static int __devinit snd_ice1712_build_controls(struct snd_ice1712 *ice)
2483 2487
2484static int snd_ice1712_free(struct snd_ice1712 *ice) 2488static int snd_ice1712_free(struct snd_ice1712 *ice)
2485{ 2489{
2486 if (! ice->port) 2490 if (!ice->port)
2487 goto __hw_end; 2491 goto __hw_end;
2488 /* mask all interrupts */ 2492 /* mask all interrupts */
2489 outb(0xc0, ICEMT(ice, IRQ)); 2493 outb(0xc0, ICEMT(ice, IRQ));
2490 outb(0xff, ICEREG(ice, IRQMASK)); 2494 outb(0xff, ICEREG(ice, IRQMASK));
2491 /* --- */ 2495 /* --- */
2492 __hw_end: 2496__hw_end:
2493 if (ice->irq >= 0) 2497 if (ice->irq >= 0)
2494 free_irq(ice->irq, ice); 2498 free_irq(ice->irq, ice);
2495 2499
@@ -2514,7 +2518,7 @@ static int __devinit snd_ice1712_create(struct snd_card *card,
2514 int omni, 2518 int omni,
2515 int cs8427_timeout, 2519 int cs8427_timeout,
2516 int dxr_enable, 2520 int dxr_enable,
2517 struct snd_ice1712 ** r_ice1712) 2521 struct snd_ice1712 **r_ice1712)
2518{ 2522{
2519 struct snd_ice1712 *ice; 2523 struct snd_ice1712 *ice;
2520 int err; 2524 int err;
@@ -2524,8 +2528,9 @@ static int __devinit snd_ice1712_create(struct snd_card *card,
2524 2528
2525 *r_ice1712 = NULL; 2529 *r_ice1712 = NULL;
2526 2530
2527 /* enable PCI device */ 2531 /* enable PCI device */
2528 if ((err = pci_enable_device(pci)) < 0) 2532 err = pci_enable_device(pci);
2533 if (err < 0)
2529 return err; 2534 return err;
2530 /* check, if we can restrict PCI DMA transfers to 28 bits */ 2535 /* check, if we can restrict PCI DMA transfers to 28 bits */
2531 if (pci_set_dma_mask(pci, DMA_28BIT_MASK) < 0 || 2536 if (pci_set_dma_mask(pci, DMA_28BIT_MASK) < 0 ||
@@ -2569,7 +2574,8 @@ static int __devinit snd_ice1712_create(struct snd_card *card,
2569 snd_ice1712_proc_init(ice); 2574 snd_ice1712_proc_init(ice);
2570 synchronize_irq(pci->irq); 2575 synchronize_irq(pci->irq);
2571 2576
2572 if ((err = pci_request_regions(pci, "ICE1712")) < 0) { 2577 err = pci_request_regions(pci, "ICE1712");
2578 if (err < 0) {
2573 kfree(ice); 2579 kfree(ice);
2574 pci_disable_device(pci); 2580 pci_disable_device(pci);
2575 return err; 2581 return err;
@@ -2585,7 +2591,7 @@ static int __devinit snd_ice1712_create(struct snd_card *card,
2585 snd_ice1712_free(ice); 2591 snd_ice1712_free(ice);
2586 return -EIO; 2592 return -EIO;
2587 } 2593 }
2588 2594
2589 ice->irq = pci->irq; 2595 ice->irq = pci->irq;
2590 2596
2591 if (snd_ice1712_read_eeprom(ice, modelname) < 0) { 2597 if (snd_ice1712_read_eeprom(ice, modelname) < 0) {
@@ -2605,9 +2611,10 @@ static int __devinit snd_ice1712_create(struct snd_card *card,
2605 ICEREG(ice, IRQMASK)); 2611 ICEREG(ice, IRQMASK));
2606 outb(0x00, ICEMT(ice, IRQ)); 2612 outb(0x00, ICEMT(ice, IRQ));
2607 2613
2608 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ice, &ops)) < 0) { 2614 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ice, &ops);
2615 if (err < 0) {
2609 snd_ice1712_free(ice); 2616 snd_ice1712_free(ice);
2610 return err; 2617 return err;
2611 } 2618 }
2612 2619
2613 snd_card_set_dev(card, &pci->dev); 2620 snd_card_set_dev(card, &pci->dev);
@@ -2647,10 +2654,10 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci,
2647 2654
2648 strcpy(card->driver, "ICE1712"); 2655 strcpy(card->driver, "ICE1712");
2649 strcpy(card->shortname, "ICEnsemble ICE1712"); 2656 strcpy(card->shortname, "ICEnsemble ICE1712");
2650 2657
2651 if ((err = snd_ice1712_create(card, pci, model[dev], omni[dev], 2658 err = snd_ice1712_create(card, pci, model[dev], omni[dev],
2652 cs8427_timeout[dev], dxr_enable[dev], 2659 cs8427_timeout[dev], dxr_enable[dev], &ice);
2653 &ice)) < 0) { 2660 if (err < 0) {
2654 snd_card_free(card); 2661 snd_card_free(card);
2655 return err; 2662 return err;
2656 } 2663 }
@@ -2662,7 +2669,8 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci,
2662 if (c->driver) /* specific driver? */ 2669 if (c->driver) /* specific driver? */
2663 strcpy(card->driver, c->driver); 2670 strcpy(card->driver, c->driver);
2664 if (c->chip_init) { 2671 if (c->chip_init) {
2665 if ((err = c->chip_init(ice)) < 0) { 2672 err = c->chip_init(ice);
2673 if (err < 0) {
2666 snd_card_free(card); 2674 snd_card_free(card);
2667 return err; 2675 return err;
2668 } 2676 }
@@ -2674,47 +2682,52 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci,
2674 c = &no_matched; 2682 c = &no_matched;
2675 __found: 2683 __found:
2676 2684
2677 if ((err = snd_ice1712_pcm_profi(ice, pcm_dev++, NULL)) < 0) { 2685 err = snd_ice1712_pcm_profi(ice, pcm_dev++, NULL);
2686 if (err < 0) {
2678 snd_card_free(card); 2687 snd_card_free(card);
2679 return err; 2688 return err;
2680 } 2689 }
2681 2690
2682 if (ice_has_con_ac97(ice)) 2691 if (ice_has_con_ac97(ice))
2683 if ((err = snd_ice1712_pcm(ice, pcm_dev++, NULL)) < 0) { 2692 err = snd_ice1712_pcm(ice, pcm_dev++, NULL);
2693 if (err < 0) {
2684 snd_card_free(card); 2694 snd_card_free(card);
2685 return err; 2695 return err;
2686 } 2696 }
2687 2697
2688 if ((err = snd_ice1712_ac97_mixer(ice)) < 0) { 2698 err = snd_ice1712_ac97_mixer(ice);
2699 if (err < 0) {
2689 snd_card_free(card); 2700 snd_card_free(card);
2690 return err; 2701 return err;
2691 } 2702 }
2692 2703
2693 if ((err = snd_ice1712_build_controls(ice)) < 0) { 2704 err = snd_ice1712_build_controls(ice);
2705 if (err < 0) {
2694 snd_card_free(card); 2706 snd_card_free(card);
2695 return err; 2707 return err;
2696 } 2708 }
2697 2709
2698 if (c->build_controls) { 2710 if (c->build_controls) {
2699 if ((err = c->build_controls(ice)) < 0) { 2711 err = c->build_controls(ice);
2712 if (err < 0) {
2700 snd_card_free(card); 2713 snd_card_free(card);
2701 return err; 2714 return err;
2702 } 2715 }
2703 } 2716 }
2704 2717
2705 if (ice_has_con_ac97(ice)) 2718 if (ice_has_con_ac97(ice))
2706 if ((err = snd_ice1712_pcm_ds(ice, pcm_dev++, NULL)) < 0) { 2719 err = snd_ice1712_pcm_ds(ice, pcm_dev++, NULL);
2720 if (err < 0) {
2707 snd_card_free(card); 2721 snd_card_free(card);
2708 return err; 2722 return err;
2709 } 2723 }
2710 2724
2711 if (! c->no_mpu401) { 2725 if (!c->no_mpu401) {
2712 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_ICE1712, 2726 err = snd_mpu401_uart_new(card, 0, MPU401_HW_ICE1712,
2713 ICEREG(ice, MPU1_CTRL), 2727 ICEREG(ice, MPU1_CTRL),
2714 (c->mpu401_1_info_flags | 2728 (c->mpu401_1_info_flags | MPU401_INFO_INTEGRATED),
2715 MPU401_INFO_INTEGRATED), 2729 ice->irq, 0, &ice->rmidi[0]);
2716 ice->irq, 0, 2730 if (err < 0) {
2717 &ice->rmidi[0])) < 0) {
2718 snd_card_free(card); 2731 snd_card_free(card);
2719 return err; 2732 return err;
2720 } 2733 }
@@ -2726,12 +2739,12 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci,
2726 2739
2727 if (ice->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_2xMPU401) { 2740 if (ice->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_2xMPU401) {
2728 /* 2nd port used */ 2741 /* 2nd port used */
2729 if ((err = snd_mpu401_uart_new(card, 1, MPU401_HW_ICE1712, 2742 err = snd_mpu401_uart_new(card, 1, MPU401_HW_ICE1712,
2730 ICEREG(ice, MPU2_CTRL), 2743 ICEREG(ice, MPU2_CTRL),
2731 (c->mpu401_2_info_flags | 2744 (c->mpu401_2_info_flags | MPU401_INFO_INTEGRATED),
2732 MPU401_INFO_INTEGRATED), 2745 ice->irq, 0, &ice->rmidi[1]);
2733 ice->irq, 0, 2746
2734 &ice->rmidi[1])) < 0) { 2747 if (err < 0) {
2735 snd_card_free(card); 2748 snd_card_free(card);
2736 return err; 2749 return err;
2737 } 2750 }
@@ -2749,7 +2762,8 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci,
2749 sprintf(card->longname, "%s at 0x%lx, irq %i", 2762 sprintf(card->longname, "%s at 0x%lx, irq %i",
2750 card->shortname, ice->port, ice->irq); 2763 card->shortname, ice->port, ice->irq);
2751 2764
2752 if ((err = snd_card_register(card)) < 0) { 2765 err = snd_card_register(card);
2766 if (err < 0) {
2753 snd_card_free(card); 2767 snd_card_free(card);
2754 return err; 2768 return err;
2755 } 2769 }
diff --git a/sound/pci/ice1712/ice1712.h b/sound/pci/ice1712/ice1712.h
index 762fbd7a7507..fdae6deba16b 100644
--- a/sound/pci/ice1712/ice1712.h
+++ b/sound/pci/ice1712/ice1712.h
@@ -20,7 +20,7 @@
20 * along with this program; if not, write to the Free Software 20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * 22 *
23 */ 23 */
24 24
25#include <sound/control.h> 25#include <sound/control.h>
26#include <sound/ac97_codec.h> 26#include <sound/ac97_codec.h>
@@ -112,7 +112,7 @@
112 */ 112 */
113 113
114#define ICEDS(ice, x) ((ice)->dmapath_port + ICE1712_DS_##x) 114#define ICEDS(ice, x) ((ice)->dmapath_port + ICE1712_DS_##x)
115 115
116#define ICE1712_DS_INTMASK 0x00 /* word - interrupt mask */ 116#define ICE1712_DS_INTMASK 0x00 /* word - interrupt mask */
117#define ICE1712_DS_INTSTAT 0x02 /* word - interrupt status */ 117#define ICE1712_DS_INTSTAT 0x02 /* word - interrupt status */
118#define ICE1712_DS_DATA 0x04 /* dword - channel data */ 118#define ICE1712_DS_DATA 0x04 /* dword - channel data */
@@ -121,7 +121,7 @@
121/* 121/*
122 * Consumer section channel registers 122 * Consumer section channel registers
123 */ 123 */
124 124
125#define ICE1712_DSC_ADDR0 0x00 /* dword - base address 0 */ 125#define ICE1712_DSC_ADDR0 0x00 /* dword - base address 0 */
126#define ICE1712_DSC_COUNT0 0x01 /* word - count 0 */ 126#define ICE1712_DSC_COUNT0 0x01 /* word - count 0 */
127#define ICE1712_DSC_ADDR1 0x02 /* dword - base address 1 */ 127#define ICE1712_DSC_ADDR1 0x02 /* dword - base address 1 */
@@ -138,7 +138,7 @@
138#define ICE1712_DSC_RATE 0x05 /* dword - rate */ 138#define ICE1712_DSC_RATE 0x05 /* dword - rate */
139#define ICE1712_DSC_VOLUME 0x06 /* word - volume control */ 139#define ICE1712_DSC_VOLUME 0x06 /* word - volume control */
140 140
141/* 141/*
142 * Professional multi-track direct control registers 142 * Professional multi-track direct control registers
143 */ 143 */
144 144
@@ -214,7 +214,7 @@
214 214
215 215
216/* 216/*
217 * 217 *
218 */ 218 */
219 219
220struct snd_ice1712; 220struct snd_ice1712;
@@ -253,12 +253,12 @@ enum {
253 ICE_EEP1_ADC_ID2, 253 ICE_EEP1_ADC_ID2,
254 ICE_EEP1_ADC_ID3 254 ICE_EEP1_ADC_ID3
255}; 255};
256 256
257#define ice_has_con_ac97(ice) (!((ice)->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_NO_CON_AC97)) 257#define ice_has_con_ac97(ice) (!((ice)->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_NO_CON_AC97))
258 258
259 259
260struct snd_ak4xxx_private { 260struct snd_ak4xxx_private {
261 unsigned int cif: 1; /* CIF mode */ 261 unsigned int cif:1; /* CIF mode */
262 unsigned char caddr; /* C0 and C1 bits */ 262 unsigned char caddr; /* C0 and C1 bits */
263 unsigned int data_mask; /* DATA gpio bit */ 263 unsigned int data_mask; /* DATA gpio bit */
264 unsigned int clk_mask; /* CLK gpio bit */ 264 unsigned int clk_mask; /* CLK gpio bit */
@@ -306,11 +306,11 @@ struct snd_ice1712 {
306 struct snd_pcm *pcm; 306 struct snd_pcm *pcm;
307 struct snd_pcm *pcm_ds; 307 struct snd_pcm *pcm_ds;
308 struct snd_pcm *pcm_pro; 308 struct snd_pcm *pcm_pro;
309 struct snd_pcm_substream *playback_con_substream; 309 struct snd_pcm_substream *playback_con_substream;
310 struct snd_pcm_substream *playback_con_substream_ds[6]; 310 struct snd_pcm_substream *playback_con_substream_ds[6];
311 struct snd_pcm_substream *capture_con_substream; 311 struct snd_pcm_substream *capture_con_substream;
312 struct snd_pcm_substream *playback_pro_substream; 312 struct snd_pcm_substream *playback_pro_substream;
313 struct snd_pcm_substream *capture_pro_substream; 313 struct snd_pcm_substream *capture_pro_substream;
314 unsigned int playback_pro_size; 314 unsigned int playback_pro_size;
315 unsigned int capture_pro_size; 315 unsigned int capture_pro_size;
316 unsigned int playback_con_virt_addr[6]; 316 unsigned int playback_con_virt_addr[6];
@@ -326,15 +326,15 @@ struct snd_ice1712 {
326 struct snd_ice1712_eeprom eeprom; 326 struct snd_ice1712_eeprom eeprom;
327 327
328 unsigned int pro_volumes[20]; 328 unsigned int pro_volumes[20];
329 unsigned int omni: 1; /* Delta Omni I/O */ 329 unsigned int omni:1; /* Delta Omni I/O */
330 unsigned int dxr_enable: 1; /* Terratec DXR enable for DMX6FIRE */ 330 unsigned int dxr_enable:1; /* Terratec DXR enable for DMX6FIRE */
331 unsigned int vt1724: 1; 331 unsigned int vt1724:1;
332 unsigned int vt1720: 1; 332 unsigned int vt1720:1;
333 unsigned int has_spdif: 1; /* VT1720/4 - has SPDIF I/O */ 333 unsigned int has_spdif:1; /* VT1720/4 - has SPDIF I/O */
334 unsigned int force_pdma4: 1; /* VT1720/4 - PDMA4 as non-spdif */ 334 unsigned int force_pdma4:1; /* VT1720/4 - PDMA4 as non-spdif */
335 unsigned int force_rdma1: 1; /* VT1720/4 - RDMA1 as non-spdif */ 335 unsigned int force_rdma1:1; /* VT1720/4 - RDMA1 as non-spdif */
336 unsigned int midi_output: 1; /* VT1720/4: MIDI output triggered */ 336 unsigned int midi_output:1; /* VT1720/4: MIDI output triggered */
337 unsigned int midi_input: 1; /* VT1720/4: MIDI input triggered */ 337 unsigned int midi_input:1; /* VT1720/4: MIDI input triggered */
338 unsigned int num_total_dacs; /* total DACs */ 338 unsigned int num_total_dacs; /* total DACs */
339 unsigned int num_total_adcs; /* total ADCs */ 339 unsigned int num_total_adcs; /* total ADCs */
340 unsigned int cur_rate; /* current rate */ 340 unsigned int cur_rate; /* current rate */
@@ -351,7 +351,7 @@ struct snd_ice1712 {
351 struct snd_i2c_bus *i2c; /* I2C bus */ 351 struct snd_i2c_bus *i2c; /* I2C bus */
352 struct snd_i2c_device *cs8427; /* CS8427 I2C device */ 352 struct snd_i2c_device *cs8427; /* CS8427 I2C device */
353 unsigned int cs8427_timeout; /* CS8427 reset timeout in HZ/100 */ 353 unsigned int cs8427_timeout; /* CS8427 reset timeout in HZ/100 */
354 354
355 struct ice1712_gpio { 355 struct ice1712_gpio {
356 unsigned int direction; /* current direction bits */ 356 unsigned int direction; /* current direction bits */
357 unsigned int write_mask; /* current mask bits */ 357 unsigned int write_mask; /* current mask bits */
@@ -455,7 +455,7 @@ static inline int snd_ice1712_gpio_read_bits(struct snd_ice1712 *ice,
455{ 455{
456 ice->gpio.direction &= ~mask; 456 ice->gpio.direction &= ~mask;
457 snd_ice1712_gpio_set_dir(ice, ice->gpio.direction); 457 snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
458 return (snd_ice1712_gpio_read(ice) & mask); 458 return snd_ice1712_gpio_read(ice) & mask;
459} 459}
460 460
461int snd_ice1712_spdif_build_controls(struct snd_ice1712 *ice); 461int snd_ice1712_spdif_build_controls(struct snd_ice1712 *ice);
@@ -467,13 +467,13 @@ int snd_ice1712_akm4xxx_build_controls(struct snd_ice1712 *ice);
467 467
468int snd_ice1712_init_cs8427(struct snd_ice1712 *ice, int addr); 468int snd_ice1712_init_cs8427(struct snd_ice1712 *ice, int addr);
469 469
470static inline void snd_ice1712_write(struct snd_ice1712 * ice, u8 addr, u8 data) 470static inline void snd_ice1712_write(struct snd_ice1712 *ice, u8 addr, u8 data)
471{ 471{
472 outb(addr, ICEREG(ice, INDEX)); 472 outb(addr, ICEREG(ice, INDEX));
473 outb(data, ICEREG(ice, DATA)); 473 outb(data, ICEREG(ice, DATA));
474} 474}
475 475
476static inline u8 snd_ice1712_read(struct snd_ice1712 * ice, u8 addr) 476static inline u8 snd_ice1712_read(struct snd_ice1712 *ice, u8 addr)
477{ 477{
478 outb(addr, ICEREG(ice, INDEX)); 478 outb(addr, ICEREG(ice, INDEX));
479 return inb(ICEREG(ice, DATA)); 479 return inb(ICEREG(ice, DATA));
@@ -491,7 +491,7 @@ struct snd_ice1712_card_info {
491 char *driver; 491 char *driver;
492 int (*chip_init)(struct snd_ice1712 *); 492 int (*chip_init)(struct snd_ice1712 *);
493 int (*build_controls)(struct snd_ice1712 *); 493 int (*build_controls)(struct snd_ice1712 *);
494 unsigned int no_mpu401: 1; 494 unsigned int no_mpu401:1;
495 unsigned int mpu401_1_info_flags; 495 unsigned int mpu401_1_info_flags;
496 unsigned int mpu401_2_info_flags; 496 unsigned int mpu401_2_info_flags;
497 const char *mpu401_1_name; 497 const char *mpu401_1_name;
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index e596d777d9dd..1b3f11702713 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -20,9 +20,9 @@
20 * along with this program; if not, write to the Free Software 20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * 22 *
23 */ 23 */
24 24
25#include <asm/io.h> 25#include <linux/io.h>
26#include <linux/delay.h> 26#include <linux/delay.h>
27#include <linux/interrupt.h> 27#include <linux/interrupt.h>
28#include <linux/init.h> 28#include <linux/init.h>
@@ -105,7 +105,7 @@ static unsigned int PRO_RATE_DEFAULT = 44100;
105/* 105/*
106 * Basic I/O 106 * Basic I/O
107 */ 107 */
108 108
109/* 109/*
110 * default rates, default clock routines 110 * default rates, default clock routines
111 */ 111 */
@@ -198,7 +198,7 @@ static void snd_vt1724_set_gpio_dir(struct snd_ice1712 *ice, unsigned int data)
198static void snd_vt1724_set_gpio_mask(struct snd_ice1712 *ice, unsigned int data) 198static void snd_vt1724_set_gpio_mask(struct snd_ice1712 *ice, unsigned int data)
199{ 199{
200 outw(data, ICEREG1724(ice, GPIO_WRITE_MASK)); 200 outw(data, ICEREG1724(ice, GPIO_WRITE_MASK));
201 if (! ice->vt1720) /* VT1720 supports only 16 GPIO bits */ 201 if (!ice->vt1720) /* VT1720 supports only 16 GPIO bits */
202 outb((data >> 16) & 0xff, ICEREG1724(ice, GPIO_WRITE_MASK_22)); 202 outb((data >> 16) & 0xff, ICEREG1724(ice, GPIO_WRITE_MASK_22));
203 inw(ICEREG1724(ice, GPIO_WRITE_MASK)); /* dummy read for pci-posting */ 203 inw(ICEREG1724(ice, GPIO_WRITE_MASK)); /* dummy read for pci-posting */
204} 204}
@@ -206,7 +206,7 @@ static void snd_vt1724_set_gpio_mask(struct snd_ice1712 *ice, unsigned int data)
206static void snd_vt1724_set_gpio_data(struct snd_ice1712 *ice, unsigned int data) 206static void snd_vt1724_set_gpio_data(struct snd_ice1712 *ice, unsigned int data)
207{ 207{
208 outw(data, ICEREG1724(ice, GPIO_DATA)); 208 outw(data, ICEREG1724(ice, GPIO_DATA));
209 if (! ice->vt1720) 209 if (!ice->vt1720)
210 outb(data >> 16, ICEREG1724(ice, GPIO_DATA_22)); 210 outb(data >> 16, ICEREG1724(ice, GPIO_DATA_22));
211 inw(ICEREG1724(ice, GPIO_DATA)); /* dummy read for pci-posting */ 211 inw(ICEREG1724(ice, GPIO_DATA)); /* dummy read for pci-posting */
212} 212}
@@ -214,7 +214,7 @@ static void snd_vt1724_set_gpio_data(struct snd_ice1712 *ice, unsigned int data)
214static unsigned int snd_vt1724_get_gpio_data(struct snd_ice1712 *ice) 214static unsigned int snd_vt1724_get_gpio_data(struct snd_ice1712 *ice)
215{ 215{
216 unsigned int data; 216 unsigned int data;
217 if (! ice->vt1720) 217 if (!ice->vt1720)
218 data = (unsigned int)inb(ICEREG1724(ice, GPIO_DATA_22)); 218 data = (unsigned int)inb(ICEREG1724(ice, GPIO_DATA_22));
219 else 219 else
220 data = 0; 220 data = 0;
@@ -399,7 +399,7 @@ static irqreturn_t snd_vt1724_interrupt(int irq, void *dev_id)
399 break; 399 break;
400 } 400 }
401#endif 401#endif
402 handled = 1; 402 handled = 1;
403 if (status & VT1724_IRQ_MPU_TX) { 403 if (status & VT1724_IRQ_MPU_TX) {
404 spin_lock(&ice->reg_lock); 404 spin_lock(&ice->reg_lock);
405 if (ice->midi_output) 405 if (ice->midi_output)
@@ -468,8 +468,8 @@ static irqreturn_t snd_vt1724_interrupt(int irq, void *dev_id)
468 /* ought to really handle this properly */ 468 /* ought to really handle this properly */
469 if (mtstat & VT1724_MULTI_FIFO_ERR) { 469 if (mtstat & VT1724_MULTI_FIFO_ERR) {
470 unsigned char fstat = inb(ICEMT1724(ice, DMA_FIFO_ERR)); 470 unsigned char fstat = inb(ICEMT1724(ice, DMA_FIFO_ERR));
471 outb(fstat, ICEMT1724(ice, DMA_FIFO_ERR)); 471 outb(fstat, ICEMT1724(ice, DMA_FIFO_ERR));
472 outb(VT1724_MULTI_FIFO_ERR | inb(ICEMT1724(ice, DMA_INT_MASK)), ICEMT1724(ice, DMA_INT_MASK)); 472 outb(VT1724_MULTI_FIFO_ERR | inb(ICEMT1724(ice, DMA_INT_MASK)), ICEMT1724(ice, DMA_INT_MASK));
473 /* If I don't do this, I get machine lockup due to continual interrupts */ 473 /* If I don't do this, I get machine lockup due to continual interrupts */
474 } 474 }
475 475
@@ -733,17 +733,17 @@ static int snd_vt1724_playback_pro_prepare(struct snd_pcm_substream *substream)
733 outl(substream->runtime->dma_addr, ICEMT1724(ice, PLAYBACK_ADDR)); 733 outl(substream->runtime->dma_addr, ICEMT1724(ice, PLAYBACK_ADDR));
734 734
735 size = (snd_pcm_lib_buffer_bytes(substream) >> 2) - 1; 735 size = (snd_pcm_lib_buffer_bytes(substream) >> 2) - 1;
736 // outl(size, ICEMT1724(ice, PLAYBACK_SIZE)); 736 /* outl(size, ICEMT1724(ice, PLAYBACK_SIZE)); */
737 outw(size, ICEMT1724(ice, PLAYBACK_SIZE)); 737 outw(size, ICEMT1724(ice, PLAYBACK_SIZE));
738 outb(size >> 16, ICEMT1724(ice, PLAYBACK_SIZE) + 2); 738 outb(size >> 16, ICEMT1724(ice, PLAYBACK_SIZE) + 2);
739 size = (snd_pcm_lib_period_bytes(substream) >> 2) - 1; 739 size = (snd_pcm_lib_period_bytes(substream) >> 2) - 1;
740 // outl(size, ICEMT1724(ice, PLAYBACK_COUNT)); 740 /* outl(size, ICEMT1724(ice, PLAYBACK_COUNT)); */
741 outw(size, ICEMT1724(ice, PLAYBACK_COUNT)); 741 outw(size, ICEMT1724(ice, PLAYBACK_COUNT));
742 outb(size >> 16, ICEMT1724(ice, PLAYBACK_COUNT) + 2); 742 outb(size >> 16, ICEMT1724(ice, PLAYBACK_COUNT) + 2);
743 743
744 spin_unlock_irq(&ice->reg_lock); 744 spin_unlock_irq(&ice->reg_lock);
745 745
746 // printk("pro prepare: ch = %d, addr = 0x%x, buffer = 0x%x, period = 0x%x\n", substream->runtime->channels, (unsigned int)substream->runtime->dma_addr, snd_pcm_lib_buffer_bytes(substream), snd_pcm_lib_period_bytes(substream)); 746 /* printk("pro prepare: ch = %d, addr = 0x%x, buffer = 0x%x, period = 0x%x\n", substream->runtime->channels, (unsigned int)substream->runtime->dma_addr, snd_pcm_lib_buffer_bytes(substream), snd_pcm_lib_period_bytes(substream)); */
747 return 0; 747 return 0;
748} 748}
749 749
@@ -771,7 +771,7 @@ static snd_pcm_uframes_t snd_vt1724_playback_pro_pointer(struct snd_pcm_substrea
771 ptr = inl(ICEMT1724(ice, PLAYBACK_SIZE)) & 0xffffff; 771 ptr = inl(ICEMT1724(ice, PLAYBACK_SIZE)) & 0xffffff;
772 ptr = (ptr + 1) << 2; 772 ptr = (ptr + 1) << 2;
773 ptr = bytes_to_frames(substream->runtime, ptr); 773 ptr = bytes_to_frames(substream->runtime, ptr);
774 if (! ptr) 774 if (!ptr)
775 ; 775 ;
776 else if (ptr <= substream->runtime->buffer_size) 776 else if (ptr <= substream->runtime->buffer_size)
777 ptr = substream->runtime->buffer_size - ptr; 777 ptr = substream->runtime->buffer_size - ptr;
@@ -815,7 +815,7 @@ static snd_pcm_uframes_t snd_vt1724_pcm_pointer(struct snd_pcm_substream *substr
815 ptr = inw(ice->profi_port + reg->size); 815 ptr = inw(ice->profi_port + reg->size);
816 ptr = (ptr + 1) << 2; 816 ptr = (ptr + 1) << 2;
817 ptr = bytes_to_frames(substream->runtime, ptr); 817 ptr = bytes_to_frames(substream->runtime, ptr);
818 if (! ptr) 818 if (!ptr)
819 ; 819 ;
820 else if (ptr <= substream->runtime->buffer_size) 820 else if (ptr <= substream->runtime->buffer_size)
821 ptr = substream->runtime->buffer_size - ptr; 821 ptr = substream->runtime->buffer_size - ptr;
@@ -842,8 +842,7 @@ static const struct vt1724_pcm_reg vt1724_capture_pro_reg = {
842 .start = VT1724_RDMA0_START, 842 .start = VT1724_RDMA0_START,
843}; 843};
844 844
845static const struct snd_pcm_hardware snd_vt1724_playback_pro = 845static const struct snd_pcm_hardware snd_vt1724_playback_pro = {
846{
847 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 846 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
848 SNDRV_PCM_INFO_BLOCK_TRANSFER | 847 SNDRV_PCM_INFO_BLOCK_TRANSFER |
849 SNDRV_PCM_INFO_MMAP_VALID | 848 SNDRV_PCM_INFO_MMAP_VALID |
@@ -861,8 +860,7 @@ static const struct snd_pcm_hardware snd_vt1724_playback_pro =
861 .periods_max = 1024, 860 .periods_max = 1024,
862}; 861};
863 862
864static const struct snd_pcm_hardware snd_vt1724_spdif = 863static const struct snd_pcm_hardware snd_vt1724_spdif = {
865{
866 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 864 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
867 SNDRV_PCM_INFO_BLOCK_TRANSFER | 865 SNDRV_PCM_INFO_BLOCK_TRANSFER |
868 SNDRV_PCM_INFO_MMAP_VALID | 866 SNDRV_PCM_INFO_MMAP_VALID |
@@ -883,8 +881,7 @@ static const struct snd_pcm_hardware snd_vt1724_spdif =
883 .periods_max = 1024, 881 .periods_max = 1024,
884}; 882};
885 883
886static const struct snd_pcm_hardware snd_vt1724_2ch_stereo = 884static const struct snd_pcm_hardware snd_vt1724_2ch_stereo = {
887{
888 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 885 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
889 SNDRV_PCM_INFO_BLOCK_TRANSFER | 886 SNDRV_PCM_INFO_BLOCK_TRANSFER |
890 SNDRV_PCM_INFO_MMAP_VALID | 887 SNDRV_PCM_INFO_MMAP_VALID |
@@ -942,7 +939,7 @@ static int snd_vt1724_playback_pro_open(struct snd_pcm_substream *substream)
942{ 939{
943 struct snd_pcm_runtime *runtime = substream->runtime; 940 struct snd_pcm_runtime *runtime = substream->runtime;
944 struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); 941 struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
945 int chs; 942 int chs, num_indeps;
946 943
947 runtime->private_data = (void *)&vt1724_playback_pro_reg; 944 runtime->private_data = (void *)&vt1724_playback_pro_reg;
948 ice->playback_pro_substream = substream; 945 ice->playback_pro_substream = substream;
@@ -952,7 +949,8 @@ static int snd_vt1724_playback_pro_open(struct snd_pcm_substream *substream)
952 set_rate_constraints(ice, substream); 949 set_rate_constraints(ice, substream);
953 mutex_lock(&ice->open_mutex); 950 mutex_lock(&ice->open_mutex);
954 /* calculate the currently available channels */ 951 /* calculate the currently available channels */
955 for (chs = 0; chs < 3; chs++) { 952 num_indeps = ice->num_total_dacs / 2 - 1;
953 for (chs = 0; chs < num_indeps; chs++) {
956 if (ice->pcm_reserved[chs]) 954 if (ice->pcm_reserved[chs])
957 break; 955 break;
958 } 956 }
@@ -1029,7 +1027,7 @@ static struct snd_pcm_ops snd_vt1724_capture_pro_ops = {
1029 .pointer = snd_vt1724_pcm_pointer, 1027 .pointer = snd_vt1724_pcm_pointer,
1030}; 1028};
1031 1029
1032static int __devinit snd_vt1724_pcm_profi(struct snd_ice1712 * ice, int device) 1030static int __devinit snd_vt1724_pcm_profi(struct snd_ice1712 *ice, int device)
1033{ 1031{
1034 struct snd_pcm *pcm; 1032 struct snd_pcm *pcm;
1035 int err; 1033 int err;
@@ -1114,7 +1112,7 @@ static void update_spdif_rate(struct snd_ice1712 *ice, unsigned int rate)
1114static int snd_vt1724_playback_spdif_prepare(struct snd_pcm_substream *substream) 1112static int snd_vt1724_playback_spdif_prepare(struct snd_pcm_substream *substream)
1115{ 1113{
1116 struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); 1114 struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
1117 if (! ice->force_pdma4) 1115 if (!ice->force_pdma4)
1118 update_spdif_rate(ice, substream->runtime->rate); 1116 update_spdif_rate(ice, substream->runtime->rate);
1119 return snd_vt1724_pcm_prepare(substream); 1117 return snd_vt1724_pcm_prepare(substream);
1120} 1118}
@@ -1214,7 +1212,7 @@ static struct snd_pcm_ops snd_vt1724_capture_spdif_ops = {
1214}; 1212};
1215 1213
1216 1214
1217static int __devinit snd_vt1724_pcm_spdif(struct snd_ice1712 * ice, int device) 1215static int __devinit snd_vt1724_pcm_spdif(struct snd_ice1712 *ice, int device)
1218{ 1216{
1219 char *name; 1217 char *name;
1220 struct snd_pcm *pcm; 1218 struct snd_pcm *pcm;
@@ -1233,7 +1231,7 @@ static int __devinit snd_vt1724_pcm_spdif(struct snd_ice1712 * ice, int device)
1233 ice->has_spdif = 1; 1231 ice->has_spdif = 1;
1234 } else 1232 } else
1235 capt = 0; 1233 capt = 0;
1236 if (! play && ! capt) 1234 if (!play && !capt)
1237 return 0; /* no spdif device */ 1235 return 0; /* no spdif device */
1238 1236
1239 if (ice->force_pdma4 || ice->force_rdma1) 1237 if (ice->force_pdma4 || ice->force_rdma1)
@@ -1348,7 +1346,7 @@ static struct snd_pcm_ops snd_vt1724_playback_indep_ops = {
1348}; 1346};
1349 1347
1350 1348
1351static int __devinit snd_vt1724_pcm_indep(struct snd_ice1712 * ice, int device) 1349static int __devinit snd_vt1724_pcm_indep(struct snd_ice1712 *ice, int device)
1352{ 1350{
1353 struct snd_pcm *pcm; 1351 struct snd_pcm *pcm;
1354 int play; 1352 int play;
@@ -1383,11 +1381,11 @@ static int __devinit snd_vt1724_pcm_indep(struct snd_ice1712 * ice, int device)
1383 * Mixer section 1381 * Mixer section
1384 */ 1382 */
1385 1383
1386static int __devinit snd_vt1724_ac97_mixer(struct snd_ice1712 * ice) 1384static int __devinit snd_vt1724_ac97_mixer(struct snd_ice1712 *ice)
1387{ 1385{
1388 int err; 1386 int err;
1389 1387
1390 if (! (ice->eeprom.data[ICE_EEP2_ACLINK] & VT1724_CFG_PRO_I2S)) { 1388 if (!(ice->eeprom.data[ICE_EEP2_ACLINK] & VT1724_CFG_PRO_I2S)) {
1391 struct snd_ac97_bus *pbus; 1389 struct snd_ac97_bus *pbus;
1392 struct snd_ac97_template ac97; 1390 struct snd_ac97_template ac97;
1393 static struct snd_ac97_bus_ops ops = { 1391 static struct snd_ac97_bus_ops ops = {
@@ -1400,11 +1398,13 @@ static int __devinit snd_vt1724_ac97_mixer(struct snd_ice1712 * ice)
1400 mdelay(5); /* FIXME */ 1398 mdelay(5); /* FIXME */
1401 outb(inb(ICEMT1724(ice, AC97_CMD)) & ~0x80, ICEMT1724(ice, AC97_CMD)); 1399 outb(inb(ICEMT1724(ice, AC97_CMD)) & ~0x80, ICEMT1724(ice, AC97_CMD));
1402 1400
1403 if ((err = snd_ac97_bus(ice->card, 0, &ops, NULL, &pbus)) < 0) 1401 err = snd_ac97_bus(ice->card, 0, &ops, NULL, &pbus);
1402 if (err < 0)
1404 return err; 1403 return err;
1405 memset(&ac97, 0, sizeof(ac97)); 1404 memset(&ac97, 0, sizeof(ac97));
1406 ac97.private_data = ice; 1405 ac97.private_data = ice;
1407 if ((err = snd_ac97_mixer(pbus, &ac97, &ice->ac97)) < 0) 1406 err = snd_ac97_mixer(pbus, &ac97, &ice->ac97);
1407 if (err < 0)
1408 printk(KERN_WARNING "ice1712: cannot initialize pro ac97, skipped\n"); 1408 printk(KERN_WARNING "ice1712: cannot initialize pro ac97, skipped\n");
1409 else 1409 else
1410 return 0; 1410 return 0;
@@ -1425,7 +1425,7 @@ static inline unsigned int eeprom_triple(struct snd_ice1712 *ice, int idx)
1425 ((unsigned int)ice->eeprom.data[idx + 2] << 16); 1425 ((unsigned int)ice->eeprom.data[idx + 2] << 16);
1426} 1426}
1427 1427
1428static void snd_vt1724_proc_read(struct snd_info_entry *entry, 1428static void snd_vt1724_proc_read(struct snd_info_entry *entry,
1429 struct snd_info_buffer *buffer) 1429 struct snd_info_buffer *buffer)
1430{ 1430{
1431 struct snd_ice1712 *ice = entry->private_data; 1431 struct snd_ice1712 *ice = entry->private_data;
@@ -1467,11 +1467,11 @@ static void snd_vt1724_proc_read(struct snd_info_entry *entry,
1467 idx, inb(ice->profi_port+idx)); 1467 idx, inb(ice->profi_port+idx));
1468} 1468}
1469 1469
1470static void __devinit snd_vt1724_proc_init(struct snd_ice1712 * ice) 1470static void __devinit snd_vt1724_proc_init(struct snd_ice1712 *ice)
1471{ 1471{
1472 struct snd_info_entry *entry; 1472 struct snd_info_entry *entry;
1473 1473
1474 if (! snd_card_proc_new(ice->card, "ice1724", &entry)) 1474 if (!snd_card_proc_new(ice->card, "ice1724", &entry))
1475 snd_info_set_text_ops(entry, ice, snd_vt1724_proc_read); 1475 snd_info_set_text_ops(entry, ice, snd_vt1724_proc_read);
1476} 1476}
1477 1477
@@ -1491,7 +1491,7 @@ static int snd_vt1724_eeprom_get(struct snd_kcontrol *kcontrol,
1491 struct snd_ctl_elem_value *ucontrol) 1491 struct snd_ctl_elem_value *ucontrol)
1492{ 1492{
1493 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 1493 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1494 1494
1495 memcpy(ucontrol->value.bytes.data, &ice->eeprom, sizeof(ice->eeprom)); 1495 memcpy(ucontrol->value.bytes.data, &ice->eeprom, sizeof(ice->eeprom));
1496 return 0; 1496 return 0;
1497} 1497}
@@ -1606,13 +1606,13 @@ static int snd_vt1724_spdif_default_put(struct snd_kcontrol *kcontrol,
1606 if (val != old) 1606 if (val != old)
1607 update_spdif_bits(ice, val); 1607 update_spdif_bits(ice, val);
1608 spin_unlock_irq(&ice->reg_lock); 1608 spin_unlock_irq(&ice->reg_lock);
1609 return (val != old); 1609 return val != old;
1610} 1610}
1611 1611
1612static struct snd_kcontrol_new snd_vt1724_spdif_default __devinitdata = 1612static struct snd_kcontrol_new snd_vt1724_spdif_default __devinitdata =
1613{ 1613{
1614 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1614 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1615 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), 1615 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
1616 .info = snd_vt1724_spdif_info, 1616 .info = snd_vt1724_spdif_info,
1617 .get = snd_vt1724_spdif_default_get, 1617 .get = snd_vt1724_spdif_default_get,
1618 .put = snd_vt1724_spdif_default_put 1618 .put = snd_vt1724_spdif_default_put
@@ -1645,7 +1645,7 @@ static struct snd_kcontrol_new snd_vt1724_spdif_maskc __devinitdata =
1645{ 1645{
1646 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1646 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1647 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1647 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1648 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK), 1648 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, CON_MASK),
1649 .info = snd_vt1724_spdif_info, 1649 .info = snd_vt1724_spdif_info,
1650 .get = snd_vt1724_spdif_maskc_get, 1650 .get = snd_vt1724_spdif_maskc_get,
1651}; 1651};
@@ -1654,7 +1654,7 @@ static struct snd_kcontrol_new snd_vt1724_spdif_maskp __devinitdata =
1654{ 1654{
1655 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1655 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1656 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1656 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1657 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK), 1657 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PRO_MASK),
1658 .info = snd_vt1724_spdif_info, 1658 .info = snd_vt1724_spdif_info,
1659 .get = snd_vt1724_spdif_maskp_get, 1659 .get = snd_vt1724_spdif_maskp_get,
1660}; 1660};
@@ -1691,8 +1691,8 @@ static struct snd_kcontrol_new snd_vt1724_spdif_switch __devinitdata =
1691{ 1691{
1692 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1692 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1693 /* FIXME: the following conflict with IEC958 Playback Route */ 1693 /* FIXME: the following conflict with IEC958 Playback Route */
1694 // .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), 1694 /* .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, SWITCH), */
1695 .name = SNDRV_CTL_NAME_IEC958("Output ",NONE,SWITCH), 1695 .name = SNDRV_CTL_NAME_IEC958("Output ", NONE, SWITCH),
1696 .info = snd_vt1724_spdif_sw_info, 1696 .info = snd_vt1724_spdif_sw_info,
1697 .get = snd_vt1724_spdif_sw_get, 1697 .get = snd_vt1724_spdif_sw_get,
1698 .put = snd_vt1724_spdif_sw_put 1698 .put = snd_vt1724_spdif_sw_put
@@ -1712,7 +1712,7 @@ int snd_vt1724_gpio_get(struct snd_kcontrol *kcontrol,
1712 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 1712 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1713 int shift = kcontrol->private_value & 0xff; 1713 int shift = kcontrol->private_value & 0xff;
1714 int invert = (kcontrol->private_value & (1<<24)) ? 1 : 0; 1714 int invert = (kcontrol->private_value & (1<<24)) ? 1 : 0;
1715 1715
1716 snd_ice1712_save_gpio_status(ice); 1716 snd_ice1712_save_gpio_status(ice);
1717 ucontrol->value.integer.value[0] = 1717 ucontrol->value.integer.value[0] =
1718 (snd_ice1712_gpio_read(ice) & (1 << shift) ? 1 : 0) ^ invert; 1718 (snd_ice1712_gpio_read(ice) & (1 << shift) ? 1 : 0) ^ invert;
@@ -1767,7 +1767,7 @@ static int snd_vt1724_pro_internal_clock_get(struct snd_kcontrol *kcontrol,
1767{ 1767{
1768 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 1768 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1769 unsigned int i, rate; 1769 unsigned int i, rate;
1770 1770
1771 spin_lock_irq(&ice->reg_lock); 1771 spin_lock_irq(&ice->reg_lock);
1772 if (ice->is_spdif_master(ice)) { 1772 if (ice->is_spdif_master(ice)) {
1773 ucontrol->value.enumerated.item[0] = ice->hw_rates->count; 1773 ucontrol->value.enumerated.item[0] = ice->hw_rates->count;
@@ -1923,7 +1923,7 @@ static int snd_vt1724_pro_route_info(struct snd_kcontrol *kcontrol,
1923 "H/W In 0", "H/W In 1", /* 1-2 */ 1923 "H/W In 0", "H/W In 1", /* 1-2 */
1924 "IEC958 In L", "IEC958 In R", /* 3-4 */ 1924 "IEC958 In L", "IEC958 In R", /* 3-4 */
1925 }; 1925 };
1926 1926
1927 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 1927 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1928 uinfo->count = 1; 1928 uinfo->count = 1;
1929 uinfo->value.enumerated.items = 5; 1929 uinfo->value.enumerated.items = 5;
@@ -1953,7 +1953,7 @@ static int get_route_val(struct snd_ice1712 *ice, int shift)
1953 1953
1954 val = inl(ICEMT1724(ice, ROUTE_PLAYBACK)); 1954 val = inl(ICEMT1724(ice, ROUTE_PLAYBACK));
1955 val >>= shift; 1955 val >>= shift;
1956 val &= 7; //we now have 3 bits per output 1956 val &= 7; /* we now have 3 bits per output */
1957 eitem = xlate[val]; 1957 eitem = xlate[val];
1958 if (eitem == 255) { 1958 if (eitem == 255) {
1959 snd_BUG(); 1959 snd_BUG();
@@ -2032,7 +2032,7 @@ static struct snd_kcontrol_new snd_vt1724_mixer_pro_analog_route __devinitdata =
2032 2032
2033static struct snd_kcontrol_new snd_vt1724_mixer_pro_spdif_route __devinitdata = { 2033static struct snd_kcontrol_new snd_vt1724_mixer_pro_spdif_route __devinitdata = {
2034 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2034 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2035 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route", 2035 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, NONE) "Route",
2036 .info = snd_vt1724_pro_route_info, 2036 .info = snd_vt1724_pro_route_info,
2037 .get = snd_vt1724_pro_route_spdif_get, 2037 .get = snd_vt1724_pro_route_spdif_get,
2038 .put = snd_vt1724_pro_route_spdif_put, 2038 .put = snd_vt1724_pro_route_spdif_put,
@@ -2055,7 +2055,7 @@ static int snd_vt1724_pro_peak_get(struct snd_kcontrol *kcontrol,
2055{ 2055{
2056 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 2056 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
2057 int idx; 2057 int idx;
2058 2058
2059 spin_lock_irq(&ice->reg_lock); 2059 spin_lock_irq(&ice->reg_lock);
2060 for (idx = 0; idx < 22; idx++) { 2060 for (idx = 0; idx < 22; idx++) {
2061 outb(idx, ICEMT1724(ice, MONITOR_PEAKINDEX)); 2061 outb(idx, ICEMT1724(ice, MONITOR_PEAKINDEX));
@@ -2082,7 +2082,7 @@ static struct snd_ice1712_card_info no_matched __devinitdata;
2082 2082
2083static struct snd_ice1712_card_info *card_tables[] __devinitdata = { 2083static struct snd_ice1712_card_info *card_tables[] __devinitdata = {
2084 snd_vt1724_revo_cards, 2084 snd_vt1724_revo_cards,
2085 snd_vt1724_amp_cards, 2085 snd_vt1724_amp_cards,
2086 snd_vt1724_aureon_cards, 2086 snd_vt1724_aureon_cards,
2087 snd_vt1720_mobo_cards, 2087 snd_vt1720_mobo_cards,
2088 snd_vt1720_pontis_cards, 2088 snd_vt1720_pontis_cards,
@@ -2120,7 +2120,7 @@ unsigned char snd_vt1724_read_i2c(struct snd_ice1712 *ice,
2120 wait_i2c_busy(ice); 2120 wait_i2c_busy(ice);
2121 val = inb(ICEREG1724(ice, I2C_DATA)); 2121 val = inb(ICEREG1724(ice, I2C_DATA));
2122 mutex_unlock(&ice->i2c_mutex); 2122 mutex_unlock(&ice->i2c_mutex);
2123 //printk("i2c_read: [0x%x,0x%x] = 0x%x\n", dev, addr, val); 2123 /* printk("i2c_read: [0x%x,0x%x] = 0x%x\n", dev, addr, val); */
2124 return val; 2124 return val;
2125} 2125}
2126 2126
@@ -2129,7 +2129,7 @@ void snd_vt1724_write_i2c(struct snd_ice1712 *ice,
2129{ 2129{
2130 mutex_lock(&ice->i2c_mutex); 2130 mutex_lock(&ice->i2c_mutex);
2131 wait_i2c_busy(ice); 2131 wait_i2c_busy(ice);
2132 //printk("i2c_write: [0x%x,0x%x] = 0x%x\n", dev, addr, data); 2132 /* printk("i2c_write: [0x%x,0x%x] = 0x%x\n", dev, addr, data); */
2133 outb(addr, ICEREG1724(ice, I2C_BYTE_ADDR)); 2133 outb(addr, ICEREG1724(ice, I2C_BYTE_ADDR));
2134 outb(data, ICEREG1724(ice, I2C_DATA)); 2134 outb(data, ICEREG1724(ice, I2C_DATA));
2135 outb(dev | VT1724_I2C_WRITE, ICEREG1724(ice, I2C_DEV_ADDR)); 2135 outb(dev | VT1724_I2C_WRITE, ICEREG1724(ice, I2C_DEV_ADDR));
@@ -2144,13 +2144,13 @@ static int __devinit snd_vt1724_read_eeprom(struct snd_ice1712 *ice,
2144 unsigned int i, size; 2144 unsigned int i, size;
2145 struct snd_ice1712_card_info * const *tbl, *c; 2145 struct snd_ice1712_card_info * const *tbl, *c;
2146 2146
2147 if (! modelname || ! *modelname) { 2147 if (!modelname || !*modelname) {
2148 ice->eeprom.subvendor = 0; 2148 ice->eeprom.subvendor = 0;
2149 if ((inb(ICEREG1724(ice, I2C_CTRL)) & VT1724_I2C_EEPROM) != 0) 2149 if ((inb(ICEREG1724(ice, I2C_CTRL)) & VT1724_I2C_EEPROM) != 0)
2150 ice->eeprom.subvendor = 2150 ice->eeprom.subvendor =
2151 (snd_vt1724_read_i2c(ice, dev, 0x00) << 0) | 2151 (snd_vt1724_read_i2c(ice, dev, 0x00) << 0) |
2152 (snd_vt1724_read_i2c(ice, dev, 0x01) << 8) | 2152 (snd_vt1724_read_i2c(ice, dev, 0x01) << 8) |
2153 (snd_vt1724_read_i2c(ice, dev, 0x02) << 16) | 2153 (snd_vt1724_read_i2c(ice, dev, 0x02) << 16) |
2154 (snd_vt1724_read_i2c(ice, dev, 0x03) << 24); 2154 (snd_vt1724_read_i2c(ice, dev, 0x03) << 24);
2155 if (ice->eeprom.subvendor == 0 || 2155 if (ice->eeprom.subvendor == 0 ||
2156 ice->eeprom.subvendor == (unsigned int)-1) { 2156 ice->eeprom.subvendor == (unsigned int)-1) {
@@ -2173,13 +2173,13 @@ static int __devinit snd_vt1724_read_eeprom(struct snd_ice1712 *ice,
2173 for (tbl = card_tables; *tbl; tbl++) { 2173 for (tbl = card_tables; *tbl; tbl++) {
2174 for (c = *tbl; c->subvendor; c++) { 2174 for (c = *tbl; c->subvendor; c++) {
2175 if (modelname && c->model && 2175 if (modelname && c->model &&
2176 ! strcmp(modelname, c->model)) { 2176 !strcmp(modelname, c->model)) {
2177 printk(KERN_INFO "ice1724: Using board model %s\n", 2177 printk(KERN_INFO "ice1724: Using board model %s\n",
2178 c->name); 2178 c->name);
2179 ice->eeprom.subvendor = c->subvendor; 2179 ice->eeprom.subvendor = c->subvendor;
2180 } else if (c->subvendor != ice->eeprom.subvendor) 2180 } else if (c->subvendor != ice->eeprom.subvendor)
2181 continue; 2181 continue;
2182 if (! c->eeprom_size || ! c->eeprom_data) 2182 if (!c->eeprom_size || !c->eeprom_data)
2183 goto found; 2183 goto found;
2184 /* if the EEPROM is given by the driver, use it */ 2184 /* if the EEPROM is given by the driver, use it */
2185 snd_printdd("using the defined eeprom..\n"); 2185 snd_printdd("using the defined eeprom..\n");
@@ -2250,7 +2250,8 @@ static int __devinit snd_vt1724_spdif_build_controls(struct snd_ice1712 *ice)
2250 int err; 2250 int err;
2251 struct snd_kcontrol *kctl; 2251 struct snd_kcontrol *kctl;
2252 2252
2253 snd_assert(ice->pcm != NULL, return -EIO); 2253 if (snd_BUG_ON(!ice->pcm))
2254 return -EIO;
2254 2255
2255 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_vt1724_mixer_pro_spdif_route, ice)); 2256 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_vt1724_mixer_pro_spdif_route, ice));
2256 if (err < 0) 2257 if (err < 0)
@@ -2320,13 +2321,13 @@ static int __devinit snd_vt1724_build_controls(struct snd_ice1712 *ice)
2320 2321
2321static int snd_vt1724_free(struct snd_ice1712 *ice) 2322static int snd_vt1724_free(struct snd_ice1712 *ice)
2322{ 2323{
2323 if (! ice->port) 2324 if (!ice->port)
2324 goto __hw_end; 2325 goto __hw_end;
2325 /* mask all interrupts */ 2326 /* mask all interrupts */
2326 outb(0xff, ICEMT1724(ice, DMA_INT_MASK)); 2327 outb(0xff, ICEMT1724(ice, DMA_INT_MASK));
2327 outb(0xff, ICEREG1724(ice, IRQMASK)); 2328 outb(0xff, ICEREG1724(ice, IRQMASK));
2328 /* --- */ 2329 /* --- */
2329 __hw_end: 2330__hw_end:
2330 if (ice->irq >= 0) 2331 if (ice->irq >= 0)
2331 free_irq(ice->irq, ice); 2332 free_irq(ice->irq, ice);
2332 pci_release_regions(ice->pci); 2333 pci_release_regions(ice->pci);
@@ -2346,7 +2347,7 @@ static int snd_vt1724_dev_free(struct snd_device *device)
2346static int __devinit snd_vt1724_create(struct snd_card *card, 2347static int __devinit snd_vt1724_create(struct snd_card *card,
2347 struct pci_dev *pci, 2348 struct pci_dev *pci,
2348 const char *modelname, 2349 const char *modelname,
2349 struct snd_ice1712 ** r_ice1712) 2350 struct snd_ice1712 **r_ice1712)
2350{ 2351{
2351 struct snd_ice1712 *ice; 2352 struct snd_ice1712 *ice;
2352 int err; 2353 int err;
@@ -2357,8 +2358,9 @@ static int __devinit snd_vt1724_create(struct snd_card *card,
2357 2358
2358 *r_ice1712 = NULL; 2359 *r_ice1712 = NULL;
2359 2360
2360 /* enable PCI device */ 2361 /* enable PCI device */
2361 if ((err = pci_enable_device(pci)) < 0) 2362 err = pci_enable_device(pci);
2363 if (err < 0)
2362 return err; 2364 return err;
2363 2365
2364 ice = kzalloc(sizeof(*ice), GFP_KERNEL); 2366 ice = kzalloc(sizeof(*ice), GFP_KERNEL);
@@ -2382,7 +2384,8 @@ static int __devinit snd_vt1724_create(struct snd_card *card,
2382 snd_vt1724_proc_init(ice); 2384 snd_vt1724_proc_init(ice);
2383 synchronize_irq(pci->irq); 2385 synchronize_irq(pci->irq);
2384 2386
2385 if ((err = pci_request_regions(pci, "ICE1724")) < 0) { 2387 err = pci_request_regions(pci, "ICE1724");
2388 if (err < 0) {
2386 kfree(ice); 2389 kfree(ice);
2387 pci_disable_device(pci); 2390 pci_disable_device(pci);
2388 return err; 2391 return err;
@@ -2417,9 +2420,10 @@ static int __devinit snd_vt1724_create(struct snd_card *card,
2417 */ 2420 */
2418 outb(VT1724_MULTI_FIFO_ERR, ICEMT1724(ice, DMA_INT_MASK)); 2421 outb(VT1724_MULTI_FIFO_ERR, ICEMT1724(ice, DMA_INT_MASK));
2419 2422
2420 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ice, &ops)) < 0) { 2423 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ice, &ops);
2424 if (err < 0) {
2421 snd_vt1724_free(ice); 2425 snd_vt1724_free(ice);
2422 return err; 2426 return err;
2423 } 2427 }
2424 2428
2425 snd_card_set_dev(card, &pci->dev); 2429 snd_card_set_dev(card, &pci->dev);
@@ -2457,8 +2461,9 @@ static int __devinit snd_vt1724_probe(struct pci_dev *pci,
2457 2461
2458 strcpy(card->driver, "ICE1724"); 2462 strcpy(card->driver, "ICE1724");
2459 strcpy(card->shortname, "ICEnsemble ICE1724"); 2463 strcpy(card->shortname, "ICEnsemble ICE1724");
2460 2464
2461 if ((err = snd_vt1724_create(card, pci, model[dev], &ice)) < 0) { 2465 err = snd_vt1724_create(card, pci, model[dev], &ice);
2466 if (err < 0) {
2462 snd_card_free(card); 2467 snd_card_free(card);
2463 return err; 2468 return err;
2464 } 2469 }
@@ -2470,7 +2475,8 @@ static int __devinit snd_vt1724_probe(struct pci_dev *pci,
2470 if (c->driver) /* specific driver? */ 2475 if (c->driver) /* specific driver? */
2471 strcpy(card->driver, c->driver); 2476 strcpy(card->driver, c->driver);
2472 if (c->chip_init) { 2477 if (c->chip_init) {
2473 if ((err = c->chip_init(ice)) < 0) { 2478 err = c->chip_init(ice);
2479 if (err < 0) {
2474 snd_card_free(card); 2480 snd_card_free(card);
2475 return err; 2481 return err;
2476 } 2482 }
@@ -2480,15 +2486,15 @@ static int __devinit snd_vt1724_probe(struct pci_dev *pci,
2480 } 2486 }
2481 } 2487 }
2482 c = &no_matched; 2488 c = &no_matched;
2483 __found: 2489__found:
2484 /* 2490 /*
2485 * VT1724 has separate DMAs for the analog and the SPDIF streams while 2491 * VT1724 has separate DMAs for the analog and the SPDIF streams while
2486 * ICE1712 has only one for both (mixed up). 2492 * ICE1712 has only one for both (mixed up).
2487 * 2493 *
2488 * Confusingly the analog PCM is named "professional" here because it 2494 * Confusingly the analog PCM is named "professional" here because it
2489 * was called so in ice1712 driver, and vt1724 driver is derived from 2495 * was called so in ice1712 driver, and vt1724 driver is derived from
2490 * ice1712 driver. 2496 * ice1712 driver.
2491 */ 2497 */
2492 ice->pro_rate_default = PRO_RATE_DEFAULT; 2498 ice->pro_rate_default = PRO_RATE_DEFAULT;
2493 if (!ice->is_spdif_master) 2499 if (!ice->is_spdif_master)
2494 ice->is_spdif_master = stdclock_is_spdif_master; 2500 ice->is_spdif_master = stdclock_is_spdif_master;
@@ -2503,46 +2509,53 @@ static int __devinit snd_vt1724_probe(struct pci_dev *pci,
2503 if (!ice->hw_rates) 2509 if (!ice->hw_rates)
2504 set_std_hw_rates(ice); 2510 set_std_hw_rates(ice);
2505 2511
2506 if ((err = snd_vt1724_pcm_profi(ice, pcm_dev++)) < 0) { 2512 err = snd_vt1724_pcm_profi(ice, pcm_dev++);
2513 if (err < 0) {
2507 snd_card_free(card); 2514 snd_card_free(card);
2508 return err; 2515 return err;
2509 } 2516 }
2510 2517
2511 if ((err = snd_vt1724_pcm_spdif(ice, pcm_dev++)) < 0) { 2518 err = snd_vt1724_pcm_spdif(ice, pcm_dev++);
2519 if (err < 0) {
2512 snd_card_free(card); 2520 snd_card_free(card);
2513 return err; 2521 return err;
2514 } 2522 }
2515 2523
2516 if ((err = snd_vt1724_pcm_indep(ice, pcm_dev++)) < 0) { 2524 err = snd_vt1724_pcm_indep(ice, pcm_dev++);
2525 if (err < 0) {
2517 snd_card_free(card); 2526 snd_card_free(card);
2518 return err; 2527 return err;
2519 } 2528 }
2520 2529
2521 if ((err = snd_vt1724_ac97_mixer(ice)) < 0) { 2530 err = snd_vt1724_ac97_mixer(ice);
2531 if (err < 0) {
2522 snd_card_free(card); 2532 snd_card_free(card);
2523 return err; 2533 return err;
2524 } 2534 }
2525 2535
2526 if ((err = snd_vt1724_build_controls(ice)) < 0) { 2536 err = snd_vt1724_build_controls(ice);
2537 if (err < 0) {
2527 snd_card_free(card); 2538 snd_card_free(card);
2528 return err; 2539 return err;
2529 } 2540 }
2530 2541
2531 if (ice->pcm && ice->has_spdif) { /* has SPDIF I/O */ 2542 if (ice->pcm && ice->has_spdif) { /* has SPDIF I/O */
2532 if ((err = snd_vt1724_spdif_build_controls(ice)) < 0) { 2543 err = snd_vt1724_spdif_build_controls(ice);
2544 if (err < 0) {
2533 snd_card_free(card); 2545 snd_card_free(card);
2534 return err; 2546 return err;
2535 } 2547 }
2536 } 2548 }
2537 2549
2538 if (c->build_controls) { 2550 if (c->build_controls) {
2539 if ((err = c->build_controls(ice)) < 0) { 2551 err = c->build_controls(ice);
2552 if (err < 0) {
2540 snd_card_free(card); 2553 snd_card_free(card);
2541 return err; 2554 return err;
2542 } 2555 }
2543 } 2556 }
2544 2557
2545 if (! c->no_mpu401) { 2558 if (!c->no_mpu401) {
2546 if (ice->eeprom.data[ICE_EEP2_SYSCONF] & VT1724_CFG_MPU401) { 2559 if (ice->eeprom.data[ICE_EEP2_SYSCONF] & VT1724_CFG_MPU401) {
2547 struct snd_rawmidi *rmidi; 2560 struct snd_rawmidi *rmidi;
2548 2561
@@ -2574,7 +2587,8 @@ static int __devinit snd_vt1724_probe(struct pci_dev *pci,
2574 sprintf(card->longname, "%s at 0x%lx, irq %i", 2587 sprintf(card->longname, "%s at 0x%lx, irq %i",
2575 card->shortname, ice->port, ice->irq); 2588 card->shortname, ice->port, ice->irq);
2576 2589
2577 if ((err = snd_card_register(card)) < 0) { 2590 err = snd_card_register(card);
2591 if (err < 0) {
2578 snd_card_free(card); 2592 snd_card_free(card);
2579 return err; 2593 return err;
2580 } 2594 }
diff --git a/sound/pci/ice1712/juli.c b/sound/pci/ice1712/juli.c
index b4e0c16852a6..c51659b9caf6 100644
--- a/sound/pci/ice1712/juli.c
+++ b/sound/pci/ice1712/juli.c
@@ -21,7 +21,7 @@
21 * along with this program; if not, write to the Free Software 21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 * 23 *
24 */ 24 */
25 25
26#include <asm/io.h> 26#include <asm/io.h>
27#include <linux/delay.h> 27#include <linux/delay.h>
@@ -34,9 +34,10 @@
34#include "ice1712.h" 34#include "ice1712.h"
35#include "envy24ht.h" 35#include "envy24ht.h"
36#include "juli.h" 36#include "juli.h"
37
37struct juli_spec { 38struct juli_spec {
38 struct ak4114 *ak4114; 39 struct ak4114 *ak4114;
39 unsigned int analog: 1; 40 unsigned int analog:1;
40}; 41};
41 42
42/* 43/*
@@ -160,14 +161,17 @@ static int get_gpio_val(int rate)
160 return 0; 161 return 0;
161} 162}
162 163
163static void juli_ak4114_write(void *private_data, unsigned char reg, unsigned char val) 164static void juli_ak4114_write(void *private_data, unsigned char reg,
165 unsigned char val)
164{ 166{
165 snd_vt1724_write_i2c((struct snd_ice1712 *)private_data, AK4114_ADDR, reg, val); 167 snd_vt1724_write_i2c((struct snd_ice1712 *)private_data, AK4114_ADDR,
168 reg, val);
166} 169}
167 170
168static unsigned char juli_ak4114_read(void *private_data, unsigned char reg) 171static unsigned char juli_ak4114_read(void *private_data, unsigned char reg)
169{ 172{
170 return snd_vt1724_read_i2c((struct snd_ice1712 *)private_data, AK4114_ADDR, reg); 173 return snd_vt1724_read_i2c((struct snd_ice1712 *)private_data,
174 AK4114_ADDR, reg);
171} 175}
172 176
173/* 177/*
@@ -175,7 +179,7 @@ static unsigned char juli_ak4114_read(void *private_data, unsigned char reg)
175 * to the external rate 179 * to the external rate
176 */ 180 */
177static void juli_spdif_in_open(struct snd_ice1712 *ice, 181static void juli_spdif_in_open(struct snd_ice1712 *ice,
178 struct snd_pcm_substream *substream) 182 struct snd_pcm_substream *substream)
179{ 183{
180 struct juli_spec *spec = ice->spec; 184 struct juli_spec *spec = ice->spec;
181 struct snd_pcm_runtime *runtime = substream->runtime; 185 struct snd_pcm_runtime *runtime = substream->runtime;
@@ -208,7 +212,8 @@ static void juli_akm_write(struct snd_akm4xxx *ak, int chip,
208{ 212{
209 struct snd_ice1712 *ice = ak->private_data[0]; 213 struct snd_ice1712 *ice = ak->private_data[0];
210 214
211 snd_assert(chip == 0, return); 215 if (snd_BUG_ON(chip))
216 return;
212 snd_vt1724_write_i2c(ice, AK4358_ADDR, addr, data); 217 snd_vt1724_write_i2c(ice, AK4358_ADDR, addr, data);
213} 218}
214 219
@@ -571,10 +576,12 @@ static void juli_ak4114_change(struct ak4114 *ak4114, unsigned char c0,
571static int __devinit juli_init(struct snd_ice1712 *ice) 576static int __devinit juli_init(struct snd_ice1712 *ice)
572{ 577{
573 static const unsigned char ak4114_init_vals[] = { 578 static const unsigned char ak4114_init_vals[] = {
574 /* AK4117_REG_PWRDN */ AK4114_RST | AK4114_PWN | AK4114_OCKS0 | AK4114_OCKS1, 579 /* AK4117_REG_PWRDN */ AK4114_RST | AK4114_PWN |
580 AK4114_OCKS0 | AK4114_OCKS1,
575 /* AK4114_REQ_FORMAT */ AK4114_DIF_I24I2S, 581 /* AK4114_REQ_FORMAT */ AK4114_DIF_I24I2S,
576 /* AK4114_REG_IO0 */ AK4114_TX1E, 582 /* AK4114_REG_IO0 */ AK4114_TX1E,
577 /* AK4114_REG_IO1 */ AK4114_EFH_1024 | AK4114_DIT | AK4114_IPS(1), 583 /* AK4114_REG_IO1 */ AK4114_EFH_1024 | AK4114_DIT |
584 AK4114_IPS(1),
578 /* AK4114_REG_INT0_MASK */ 0, 585 /* AK4114_REG_INT0_MASK */ 0,
579 /* AK4114_REG_INT1_MASK */ 0 586 /* AK4114_REG_INT1_MASK */ 0
580 }; 587 };
@@ -604,12 +611,14 @@ static int __devinit juli_init(struct snd_ice1712 *ice)
604 spec->ak4114->check_flags = 0; 611 spec->ak4114->check_flags = 0;
605 612
606#if 0 613#if 0
607 /* it seems that the analog doughter board detection does not work 614/*
608 reliably, so force the analog flag; it should be very rare 615 * it seems that the analog doughter board detection does not work reliably, so
609 to use Juli@ without the analog doughter board */ 616 * force the analog flag; it should be very rare (if ever) to come at Juli@
617 * used without the analog daughter board
618 */
610 spec->analog = (ice->gpio.get_data(ice) & GPIO_ANALOG_PRESENT) ? 0 : 1; 619 spec->analog = (ice->gpio.get_data(ice) & GPIO_ANALOG_PRESENT) ? 0 : 1;
611#else 620#else
612 spec->analog = 1; 621 spec->analog = 1;
613#endif 622#endif
614 623
615 if (spec->analog) { 624 if (spec->analog) {
@@ -617,14 +626,16 @@ static int __devinit juli_init(struct snd_ice1712 *ice)
617 ice->num_total_dacs = 2; 626 ice->num_total_dacs = 2;
618 ice->num_total_adcs = 2; 627 ice->num_total_adcs = 2;
619 628
620 ak = ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); 629 ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
621 if (! ak) 630 ak = ice->akm;
631 if (!ak)
622 return -ENOMEM; 632 return -ENOMEM;
623 ice->akm_codecs = 1; 633 ice->akm_codecs = 1;
624 if ((err = snd_ice1712_akm4xxx_init(ak, &akm_juli_dac, NULL, ice)) < 0) 634 err = snd_ice1712_akm4xxx_init(ak, &akm_juli_dac, NULL, ice);
635 if (err < 0)
625 return err; 636 return err;
626 } 637 }
627 638
628 /* juli is clocked by Xilinx array */ 639 /* juli is clocked by Xilinx array */
629 ice->hw_rates = &juli_rates_info; 640 ice->hw_rates = &juli_rates_info;
630 ice->is_spdif_master = juli_is_spdif_master; 641 ice->is_spdif_master = juli_is_spdif_master;
diff --git a/sound/pci/ice1712/phase.c b/sound/pci/ice1712/phase.c
index 5a158b73dcaa..de29be8c9657 100644
--- a/sound/pci/ice1712/phase.c
+++ b/sound/pci/ice1712/phase.c
@@ -22,15 +22,24 @@
22 */ 22 */
23 23
24/* PHASE 22 overview: 24/* PHASE 22 overview:
25 * Audio controller: VIA Envy24HT-S (slightly trimmed down version of Envy24HT) 25 * Audio controller: VIA Envy24HT-S (slightly trimmed down Envy24HT, 4in/4out)
26 * Analog chip: AK4524 (partially via Philip's 74HCT125) 26 * Analog chip: AK4524 (partially via Philip's 74HCT125)
27 * Digital receiver: CS8414-CS (not supported in this release) 27 * Digital receiver: CS8414-CS (supported in this release)
28 * PHASE 22 revision 2.0 and Terrasoniq/Musonik TS22PCI have CS8416
29 * (support status unknown, please test and report)
28 * 30 *
29 * Envy connects to AK4524 31 * Envy connects to AK4524
30 * - CS directly from GPIO 10 32 * - CS directly from GPIO 10
31 * - CCLK via 74HCT125's gate #4 from GPIO 4 33 * - CCLK via 74HCT125's gate #4 from GPIO 4
32 * - CDTI via 74HCT125's gate #2 from GPIO 5 34 * - CDTI via 74HCT125's gate #2 from GPIO 5
33 * CDTI may be completely blocked by 74HCT125's gate #1 controlled by GPIO 3 35 * CDTI may be completely blocked by 74HCT125's gate #1
36 * controlled by GPIO 3
37 */
38
39/* PHASE 28 overview:
40 * Audio controller: VIA Envy24HT (full untrimmed version, 4in/8out)
41 * Analog chip: WM8770 (8 channel 192k DAC, 2 channel 96k ADC)
42 * Digital receiver: CS8414-CS (supported in this release)
34 */ 43 */
35 44
36#include <asm/io.h> 45#include <asm/io.h>
@@ -77,18 +86,18 @@ struct phase28_spec {
77 * Computed as 20 * Log10(255 / x) 86 * Computed as 20 * Log10(255 / x)
78 */ 87 */
79static const unsigned char wm_vol[256] = { 88static const unsigned char wm_vol[256] = {
80 127, 48, 42, 39, 36, 34, 33, 31, 30, 29, 28, 27, 27, 26, 25, 25, 24, 24, 23, 89 127, 48, 42, 39, 36, 34, 33, 31, 30, 29, 28, 27, 27, 26, 25, 25, 24,
81 23, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 18, 17, 17, 17, 90 24, 23, 23, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 18,
82 17, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, 13, 91 17, 17, 17, 17, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14,
83 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11, 92 14, 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11,
84 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 93 11, 11, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9,
85 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 94 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7,
86 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 95 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5,
87 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 96 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
88 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 97 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
89 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 98 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
90 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
91 0, 0 100 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
92}; 101};
93 102
94#define WM_VOL_MAX (sizeof(wm_vol) - 1) 103#define WM_VOL_MAX (sizeof(wm_vol) - 1)
@@ -117,26 +126,31 @@ static int __devinit phase22_init(struct snd_ice1712 *ice)
117 struct snd_akm4xxx *ak; 126 struct snd_akm4xxx *ak;
118 int err; 127 int err;
119 128
120 // Configure DAC/ADC description for generic part of ice1724 129 /* Configure DAC/ADC description for generic part of ice1724 */
121 switch (ice->eeprom.subvendor) { 130 switch (ice->eeprom.subvendor) {
122 case VT1724_SUBDEVICE_PHASE22: 131 case VT1724_SUBDEVICE_PHASE22:
132 case VT1724_SUBDEVICE_TS22:
123 ice->num_total_dacs = 2; 133 ice->num_total_dacs = 2;
124 ice->num_total_adcs = 2; 134 ice->num_total_adcs = 2;
125 ice->vt1720 = 1; // Envy24HT-S have 16 bit wide GPIO 135 ice->vt1720 = 1; /* Envy24HT-S have 16 bit wide GPIO */
126 break; 136 break;
127 default: 137 default:
128 snd_BUG(); 138 snd_BUG();
129 return -EINVAL; 139 return -EINVAL;
130 } 140 }
131 141
132 // Initialize analog chips 142 /* Initialize analog chips */
133 ak = ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); 143 ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
134 if (! ak) 144 ak = ice->akm;
145 if (!ak)
135 return -ENOMEM; 146 return -ENOMEM;
136 ice->akm_codecs = 1; 147 ice->akm_codecs = 1;
137 switch (ice->eeprom.subvendor) { 148 switch (ice->eeprom.subvendor) {
138 case VT1724_SUBDEVICE_PHASE22: 149 case VT1724_SUBDEVICE_PHASE22:
139 if ((err = snd_ice1712_akm4xxx_init(ak, &akm_phase22, &akm_phase22_priv, ice)) < 0) 150 case VT1724_SUBDEVICE_TS22:
151 err = snd_ice1712_akm4xxx_init(ak, &akm_phase22,
152 &akm_phase22_priv, ice);
153 if (err < 0)
140 return err; 154 return err;
141 break; 155 break;
142 } 156 }
@@ -150,6 +164,7 @@ static int __devinit phase22_add_controls(struct snd_ice1712 *ice)
150 164
151 switch (ice->eeprom.subvendor) { 165 switch (ice->eeprom.subvendor) {
152 case VT1724_SUBDEVICE_PHASE22: 166 case VT1724_SUBDEVICE_PHASE22:
167 case VT1724_SUBDEVICE_TS22:
153 err = snd_ice1712_akm4xxx_build_controls(ice); 168 err = snd_ice1712_akm4xxx_build_controls(ice);
154 if (err < 0) 169 if (err < 0)
155 return err; 170 return err;
@@ -158,9 +173,10 @@ static int __devinit phase22_add_controls(struct snd_ice1712 *ice)
158} 173}
159 174
160static unsigned char phase22_eeprom[] __devinitdata = { 175static unsigned char phase22_eeprom[] __devinitdata = {
161 [ICE_EEP2_SYSCONF] = 0x00, /* 1xADC, 1xDACs */ 176 [ICE_EEP2_SYSCONF] = 0x28, /* clock 512, mpu 401,
177 spdif-in/1xADC, 1xDACs */
162 [ICE_EEP2_ACLINK] = 0x80, /* I2S */ 178 [ICE_EEP2_ACLINK] = 0x80, /* I2S */
163 [ICE_EEP2_I2S] = 0xf8, /* vol, 96k, 24bit */ 179 [ICE_EEP2_I2S] = 0xf0, /* vol, 96k, 24bit */
164 [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */ 180 [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
165 [ICE_EEP2_GPIO_DIR] = 0xff, 181 [ICE_EEP2_GPIO_DIR] = 0xff,
166 [ICE_EEP2_GPIO_DIR1] = 0xff, 182 [ICE_EEP2_GPIO_DIR1] = 0xff,
@@ -174,7 +190,8 @@ static unsigned char phase22_eeprom[] __devinitdata = {
174}; 190};
175 191
176static unsigned char phase28_eeprom[] __devinitdata = { 192static unsigned char phase28_eeprom[] __devinitdata = {
177 [ICE_EEP2_SYSCONF] = 0x0b, /* clock 512, spdif-in/ADC, 4DACs */ 193 [ICE_EEP2_SYSCONF] = 0x2b, /* clock 512, mpu401,
194 spdif-in/1xADC, 4xDACs */
178 [ICE_EEP2_ACLINK] = 0x80, /* I2S */ 195 [ICE_EEP2_ACLINK] = 0x80, /* I2S */
179 [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */ 196 [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */
180 [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */ 197 [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
@@ -192,15 +209,16 @@ static unsigned char phase28_eeprom[] __devinitdata = {
192/* 209/*
193 * write data in the SPI mode 210 * write data in the SPI mode
194 */ 211 */
195static void phase28_spi_write(struct snd_ice1712 *ice, unsigned int cs, unsigned int data, int bits) 212static void phase28_spi_write(struct snd_ice1712 *ice, unsigned int cs,
213 unsigned int data, int bits)
196{ 214{
197 unsigned int tmp; 215 unsigned int tmp;
198 int i; 216 int i;
199 217
200 tmp = snd_ice1712_gpio_read(ice); 218 tmp = snd_ice1712_gpio_read(ice);
201 219
202 snd_ice1712_gpio_set_mask(ice, ~(PHASE28_WM_RW|PHASE28_SPI_MOSI|PHASE28_SPI_CLK| 220 snd_ice1712_gpio_set_mask(ice, ~(PHASE28_WM_RW|PHASE28_SPI_MOSI|
203 PHASE28_WM_CS)); 221 PHASE28_SPI_CLK|PHASE28_WM_CS));
204 tmp |= PHASE28_WM_RW; 222 tmp |= PHASE28_WM_RW;
205 tmp &= ~cs; 223 tmp &= ~cs;
206 snd_ice1712_gpio_write(ice, tmp); 224 snd_ice1712_gpio_write(ice, tmp);
@@ -259,14 +277,16 @@ static void wm_put(struct snd_ice1712 *ice, int reg, unsigned short val)
259 ice->akm[0].images[reg + 1] = val; 277 ice->akm[0].images[reg + 1] = val;
260} 278}
261 279
262static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned short vol, unsigned short master) 280static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index,
281 unsigned short vol, unsigned short master)
263{ 282{
264 unsigned char nvol; 283 unsigned char nvol;
265 284
266 if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE)) 285 if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE))
267 nvol = 0; 286 nvol = 0;
268 else 287 else
269 nvol = 127 - wm_vol[(((vol & ~WM_VOL_MUTE) * (master & ~WM_VOL_MUTE)) / 127) & WM_VOL_MAX]; 288 nvol = 127 - wm_vol[(((vol & ~WM_VOL_MUTE) *
289 (master & ~WM_VOL_MUTE)) / 127) & WM_VOL_MAX];
270 290
271 wm_put(ice, index, nvol); 291 wm_put(ice, index, nvol);
272 wm_put_nocache(ice, index, 0x180 | nvol); 292 wm_put_nocache(ice, index, 0x180 | nvol);
@@ -277,17 +297,20 @@ static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned sho
277 */ 297 */
278#define wm_pcm_mute_info snd_ctl_boolean_mono_info 298#define wm_pcm_mute_info snd_ctl_boolean_mono_info
279 299
280static int wm_pcm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 300static int wm_pcm_mute_get(struct snd_kcontrol *kcontrol,
301 struct snd_ctl_elem_value *ucontrol)
281{ 302{
282 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 303 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
283 304
284 mutex_lock(&ice->gpio_mutex); 305 mutex_lock(&ice->gpio_mutex);
285 ucontrol->value.integer.value[0] = (wm_get(ice, WM_MUTE) & 0x10) ? 0 : 1; 306 ucontrol->value.integer.value[0] = (wm_get(ice, WM_MUTE) & 0x10) ?
307 0 : 1;
286 mutex_unlock(&ice->gpio_mutex); 308 mutex_unlock(&ice->gpio_mutex);
287 return 0; 309 return 0;
288} 310}
289 311
290static int wm_pcm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 312static int wm_pcm_mute_put(struct snd_kcontrol *kcontrol,
313 struct snd_ctl_elem_value *ucontrol)
291{ 314{
292 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 315 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
293 unsigned short nval, oval; 316 unsigned short nval, oval;
@@ -296,7 +319,8 @@ static int wm_pcm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_va
296 snd_ice1712_save_gpio_status(ice); 319 snd_ice1712_save_gpio_status(ice);
297 oval = wm_get(ice, WM_MUTE); 320 oval = wm_get(ice, WM_MUTE);
298 nval = (oval & ~0x10) | (ucontrol->value.integer.value[0] ? 0 : 0x10); 321 nval = (oval & ~0x10) | (ucontrol->value.integer.value[0] ? 0 : 0x10);
299 if ((change = (nval != oval))) 322 change = (nval != oval);
323 if (change)
300 wm_put(ice, WM_MUTE, nval); 324 wm_put(ice, WM_MUTE, nval);
301 snd_ice1712_restore_gpio_status(ice); 325 snd_ice1712_restore_gpio_status(ice);
302 326
@@ -306,7 +330,8 @@ static int wm_pcm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_va
306/* 330/*
307 * Master volume attenuation mixer control 331 * Master volume attenuation mixer control
308 */ 332 */
309static int wm_master_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 333static int wm_master_vol_info(struct snd_kcontrol *kcontrol,
334 struct snd_ctl_elem_info *uinfo)
310{ 335{
311 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 336 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
312 uinfo->count = 2; 337 uinfo->count = 2;
@@ -315,17 +340,20 @@ static int wm_master_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem
315 return 0; 340 return 0;
316} 341}
317 342
318static int wm_master_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 343static int wm_master_vol_get(struct snd_kcontrol *kcontrol,
344 struct snd_ctl_elem_value *ucontrol)
319{ 345{
320 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 346 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
321 struct phase28_spec *spec = ice->spec; 347 struct phase28_spec *spec = ice->spec;
322 int i; 348 int i;
323 for (i=0; i<2; i++) 349 for (i = 0; i < 2; i++)
324 ucontrol->value.integer.value[i] = spec->master[i] & ~WM_VOL_MUTE; 350 ucontrol->value.integer.value[i] = spec->master[i] &
351 ~WM_VOL_MUTE;
325 return 0; 352 return 0;
326} 353}
327 354
328static int wm_master_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 355static int wm_master_vol_put(struct snd_kcontrol *kcontrol,
356 struct snd_ctl_elem_value *ucontrol)
329{ 357{
330 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 358 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
331 struct phase28_spec *spec = ice->spec; 359 struct phase28_spec *spec = ice->spec;
@@ -355,38 +383,38 @@ static int __devinit phase28_init(struct snd_ice1712 *ice)
355{ 383{
356 static const unsigned short wm_inits_phase28[] = { 384 static const unsigned short wm_inits_phase28[] = {
357 /* These come first to reduce init pop noise */ 385 /* These come first to reduce init pop noise */
358 0x1b, 0x044, /* ADC Mux (AC'97 source) */ 386 0x1b, 0x044, /* ADC Mux (AC'97 source) */
359 0x1c, 0x00B, /* Out Mux1 (VOUT1 = DAC+AUX, VOUT2 = DAC) */ 387 0x1c, 0x00B, /* Out Mux1 (VOUT1 = DAC+AUX, VOUT2 = DAC) */
360 0x1d, 0x009, /* Out Mux2 (VOUT2 = DAC, VOUT3 = DAC) */ 388 0x1d, 0x009, /* Out Mux2 (VOUT2 = DAC, VOUT3 = DAC) */
361 389
362 0x18, 0x000, /* All power-up */ 390 0x18, 0x000, /* All power-up */
363 391
364 0x16, 0x122, /* I2S, normal polarity, 24bit */ 392 0x16, 0x122, /* I2S, normal polarity, 24bit */
365 0x17, 0x022, /* 256fs, slave mode */ 393 0x17, 0x022, /* 256fs, slave mode */
366 0x00, 0, /* DAC1 analog mute */ 394 0x00, 0, /* DAC1 analog mute */
367 0x01, 0, /* DAC2 analog mute */ 395 0x01, 0, /* DAC2 analog mute */
368 0x02, 0, /* DAC3 analog mute */ 396 0x02, 0, /* DAC3 analog mute */
369 0x03, 0, /* DAC4 analog mute */ 397 0x03, 0, /* DAC4 analog mute */
370 0x04, 0, /* DAC5 analog mute */ 398 0x04, 0, /* DAC5 analog mute */
371 0x05, 0, /* DAC6 analog mute */ 399 0x05, 0, /* DAC6 analog mute */
372 0x06, 0, /* DAC7 analog mute */ 400 0x06, 0, /* DAC7 analog mute */
373 0x07, 0, /* DAC8 analog mute */ 401 0x07, 0, /* DAC8 analog mute */
374 0x08, 0x100, /* master analog mute */ 402 0x08, 0x100, /* master analog mute */
375 0x09, 0xff, /* DAC1 digital full */ 403 0x09, 0xff, /* DAC1 digital full */
376 0x0a, 0xff, /* DAC2 digital full */ 404 0x0a, 0xff, /* DAC2 digital full */
377 0x0b, 0xff, /* DAC3 digital full */ 405 0x0b, 0xff, /* DAC3 digital full */
378 0x0c, 0xff, /* DAC4 digital full */ 406 0x0c, 0xff, /* DAC4 digital full */
379 0x0d, 0xff, /* DAC5 digital full */ 407 0x0d, 0xff, /* DAC5 digital full */
380 0x0e, 0xff, /* DAC6 digital full */ 408 0x0e, 0xff, /* DAC6 digital full */
381 0x0f, 0xff, /* DAC7 digital full */ 409 0x0f, 0xff, /* DAC7 digital full */
382 0x10, 0xff, /* DAC8 digital full */ 410 0x10, 0xff, /* DAC8 digital full */
383 0x11, 0x1ff, /* master digital full */ 411 0x11, 0x1ff, /* master digital full */
384 0x12, 0x000, /* phase normal */ 412 0x12, 0x000, /* phase normal */
385 0x13, 0x090, /* unmute DAC L/R */ 413 0x13, 0x090, /* unmute DAC L/R */
386 0x14, 0x000, /* all unmute */ 414 0x14, 0x000, /* all unmute */
387 0x15, 0x000, /* no deemphasis, no ZFLG */ 415 0x15, 0x000, /* no deemphasis, no ZFLG */
388 0x19, 0x000, /* -12dB ADC/L */ 416 0x19, 0x000, /* -12dB ADC/L */
389 0x1a, 0x000, /* -12dB ADC/R */ 417 0x1a, 0x000, /* -12dB ADC/R */
390 (unsigned short)-1 418 (unsigned short)-1
391 }; 419 };
392 420
@@ -404,17 +432,19 @@ static int __devinit phase28_init(struct snd_ice1712 *ice)
404 return -ENOMEM; 432 return -ENOMEM;
405 ice->spec = spec; 433 ice->spec = spec;
406 434
407 // Initialize analog chips 435 /* Initialize analog chips */
408 ak = ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); 436 ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
437 ak = ice->akm;
409 if (!ak) 438 if (!ak)
410 return -ENOMEM; 439 return -ENOMEM;
411 ice->akm_codecs = 1; 440 ice->akm_codecs = 1;
412 441
413 snd_ice1712_gpio_set_dir(ice, 0x5fffff); /* fix this for the time being */ 442 snd_ice1712_gpio_set_dir(ice, 0x5fffff); /* fix this for time being */
414 443
415 /* reset the wm codec as the SPI mode */ 444 /* reset the wm codec as the SPI mode */
416 snd_ice1712_save_gpio_status(ice); 445 snd_ice1712_save_gpio_status(ice);
417 snd_ice1712_gpio_set_mask(ice, ~(PHASE28_WM_RESET|PHASE28_WM_CS|PHASE28_HP_SEL)); 446 snd_ice1712_gpio_set_mask(ice, ~(PHASE28_WM_RESET|PHASE28_WM_CS|
447 PHASE28_HP_SEL));
418 448
419 tmp = snd_ice1712_gpio_read(ice); 449 tmp = snd_ice1712_gpio_read(ice);
420 tmp &= ~PHASE28_WM_RESET; 450 tmp &= ~PHASE28_WM_RESET;
@@ -446,7 +476,8 @@ static int __devinit phase28_init(struct snd_ice1712 *ice)
446/* 476/*
447 * DAC volume attenuation mixer control 477 * DAC volume attenuation mixer control
448 */ 478 */
449static int wm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 479static int wm_vol_info(struct snd_kcontrol *kcontrol,
480 struct snd_ctl_elem_info *uinfo)
450{ 481{
451 int voices = kcontrol->private_value >> 8; 482 int voices = kcontrol->private_value >> 8;
452 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 483 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
@@ -456,7 +487,8 @@ static int wm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *
456 return 0; 487 return 0;
457} 488}
458 489
459static int wm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 490static int wm_vol_get(struct snd_kcontrol *kcontrol,
491 struct snd_ctl_elem_value *ucontrol)
460{ 492{
461 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 493 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
462 struct phase28_spec *spec = ice->spec; 494 struct phase28_spec *spec = ice->spec;
@@ -470,7 +502,8 @@ static int wm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *
470 return 0; 502 return 0;
471} 503}
472 504
473static int wm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 505static int wm_vol_put(struct snd_kcontrol *kcontrol,
506 struct snd_ctl_elem_value *ucontrol)
474{ 507{
475 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 508 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
476 struct phase28_spec *spec = ice->spec; 509 struct phase28_spec *spec = ice->spec;
@@ -501,7 +534,8 @@ static int wm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *
501/* 534/*
502 * WM8770 mute control 535 * WM8770 mute control
503 */ 536 */
504static int wm_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { 537static int wm_mute_info(struct snd_kcontrol *kcontrol,
538 struct snd_ctl_elem_info *uinfo) {
505 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 539 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
506 uinfo->count = kcontrol->private_value >> 8; 540 uinfo->count = kcontrol->private_value >> 8;
507 uinfo->value.integer.min = 0; 541 uinfo->value.integer.min = 0;
@@ -509,7 +543,8 @@ static int wm_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info
509 return 0; 543 return 0;
510} 544}
511 545
512static int wm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 546static int wm_mute_get(struct snd_kcontrol *kcontrol,
547 struct snd_ctl_elem_value *ucontrol)
513{ 548{
514 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 549 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
515 struct phase28_spec *spec = ice->spec; 550 struct phase28_spec *spec = ice->spec;
@@ -524,7 +559,8 @@ static int wm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value
524 return 0; 559 return 0;
525} 560}
526 561
527static int wm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 562static int wm_mute_put(struct snd_kcontrol *kcontrol,
563 struct snd_ctl_elem_value *ucontrol)
528{ 564{
529 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 565 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
530 struct phase28_spec *spec = ice->spec; 566 struct phase28_spec *spec = ice->spec;
@@ -539,9 +575,10 @@ static int wm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value
539 if (ucontrol->value.integer.value[i] != val) { 575 if (ucontrol->value.integer.value[i] != val) {
540 spec->vol[ofs + i] &= ~WM_VOL_MUTE; 576 spec->vol[ofs + i] &= ~WM_VOL_MUTE;
541 spec->vol[ofs + i] |= 577 spec->vol[ofs + i] |=
542 ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE; 578 ucontrol->value.integer.value[i] ? 0 :
579 WM_VOL_MUTE;
543 wm_set_vol(ice, ofs + i, spec->vol[ofs + i], 580 wm_set_vol(ice, ofs + i, spec->vol[ofs + i],
544 spec->master[i]); 581 spec->master[i]);
545 change = 1; 582 change = 1;
546 } 583 }
547 } 584 }
@@ -555,7 +592,8 @@ static int wm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value
555 */ 592 */
556#define wm_master_mute_info snd_ctl_boolean_stereo_info 593#define wm_master_mute_info snd_ctl_boolean_stereo_info
557 594
558static int wm_master_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 595static int wm_master_mute_get(struct snd_kcontrol *kcontrol,
596 struct snd_ctl_elem_value *ucontrol)
559{ 597{
560 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 598 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
561 struct phase28_spec *spec = ice->spec; 599 struct phase28_spec *spec = ice->spec;
@@ -567,7 +605,8 @@ static int wm_master_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem
567 return 0; 605 return 0;
568} 606}
569 607
570static int wm_master_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 608static int wm_master_mute_put(struct snd_kcontrol *kcontrol,
609 struct snd_ctl_elem_value *ucontrol)
571{ 610{
572 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 611 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
573 struct phase28_spec *spec = ice->spec; 612 struct phase28_spec *spec = ice->spec;
@@ -580,11 +619,12 @@ static int wm_master_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem
580 int dac; 619 int dac;
581 spec->master[i] &= ~WM_VOL_MUTE; 620 spec->master[i] &= ~WM_VOL_MUTE;
582 spec->master[i] |= 621 spec->master[i] |=
583 ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE; 622 ucontrol->value.integer.value[i] ? 0 :
623 WM_VOL_MUTE;
584 for (dac = 0; dac < ice->num_total_dacs; dac += 2) 624 for (dac = 0; dac < ice->num_total_dacs; dac += 2)
585 wm_set_vol(ice, WM_DAC_ATTEN + dac + i, 625 wm_set_vol(ice, WM_DAC_ATTEN + dac + i,
586 spec->vol[dac + i], 626 spec->vol[dac + i],
587 spec->master[i]); 627 spec->master[i]);
588 change = 1; 628 change = 1;
589 } 629 }
590 } 630 }
@@ -597,7 +637,8 @@ static int wm_master_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem
597#define PCM_0dB 0xff 637#define PCM_0dB 0xff
598#define PCM_RES 128 /* -64dB */ 638#define PCM_RES 128 /* -64dB */
599#define PCM_MIN (PCM_0dB - PCM_RES) 639#define PCM_MIN (PCM_0dB - PCM_RES)
600static int wm_pcm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 640static int wm_pcm_vol_info(struct snd_kcontrol *kcontrol,
641 struct snd_ctl_elem_info *uinfo)
601{ 642{
602 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 643 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
603 uinfo->count = 1; 644 uinfo->count = 1;
@@ -606,7 +647,8 @@ static int wm_pcm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_in
606 return 0; 647 return 0;
607} 648}
608 649
609static int wm_pcm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 650static int wm_pcm_vol_get(struct snd_kcontrol *kcontrol,
651 struct snd_ctl_elem_value *ucontrol)
610{ 652{
611 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 653 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
612 unsigned short val; 654 unsigned short val;
@@ -619,7 +661,8 @@ static int wm_pcm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val
619 return 0; 661 return 0;
620} 662}
621 663
622static int wm_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 664static int wm_pcm_vol_put(struct snd_kcontrol *kcontrol,
665 struct snd_ctl_elem_value *ucontrol)
623{ 666{
624 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 667 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
625 unsigned short ovol, nvol; 668 unsigned short ovol, nvol;
@@ -633,7 +676,8 @@ static int wm_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val
633 ovol = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff; 676 ovol = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
634 if (ovol != nvol) { 677 if (ovol != nvol) {
635 wm_put(ice, WM_DAC_DIG_MASTER_ATTEN, nvol); /* prelatch */ 678 wm_put(ice, WM_DAC_DIG_MASTER_ATTEN, nvol); /* prelatch */
636 wm_put_nocache(ice, WM_DAC_DIG_MASTER_ATTEN, nvol | 0x100); /* update */ 679 /* update */
680 wm_put_nocache(ice, WM_DAC_DIG_MASTER_ATTEN, nvol | 0x100);
637 change = 1; 681 change = 1;
638 } 682 }
639 snd_ice1712_restore_gpio_status(ice); 683 snd_ice1712_restore_gpio_status(ice);
@@ -645,18 +689,22 @@ static int wm_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val
645 */ 689 */
646#define phase28_deemp_info snd_ctl_boolean_mono_info 690#define phase28_deemp_info snd_ctl_boolean_mono_info
647 691
648static int phase28_deemp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 692static int phase28_deemp_get(struct snd_kcontrol *kcontrol,
693 struct snd_ctl_elem_value *ucontrol)
649{ 694{
650 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 695 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
651 ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL2) & 0xf) == 0xf; 696 ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL2) & 0xf) ==
697 0xf;
652 return 0; 698 return 0;
653} 699}
654 700
655static int phase28_deemp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 701static int phase28_deemp_put(struct snd_kcontrol *kcontrol,
702 struct snd_ctl_elem_value *ucontrol)
656{ 703{
657 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 704 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
658 int temp, temp2; 705 int temp, temp2;
659 temp2 = temp = wm_get(ice, WM_DAC_CTRL2); 706 temp = wm_get(ice, WM_DAC_CTRL2);
707 temp2 = temp;
660 if (ucontrol->value.integer.value[0]) 708 if (ucontrol->value.integer.value[0])
661 temp |= 0xf; 709 temp |= 0xf;
662 else 710 else
@@ -671,7 +719,8 @@ static int phase28_deemp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_
671/* 719/*
672 * ADC Oversampling 720 * ADC Oversampling
673 */ 721 */
674static int phase28_oversampling_info(struct snd_kcontrol *k, struct snd_ctl_elem_info *uinfo) 722static int phase28_oversampling_info(struct snd_kcontrol *k,
723 struct snd_ctl_elem_info *uinfo)
675{ 724{
676 static char *texts[2] = { "128x", "64x" }; 725 static char *texts[2] = { "128x", "64x" };
677 726
@@ -680,25 +729,31 @@ static int phase28_oversampling_info(struct snd_kcontrol *k, struct snd_ctl_elem
680 uinfo->value.enumerated.items = 2; 729 uinfo->value.enumerated.items = 2;
681 730
682 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) 731 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
683 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; 732 uinfo->value.enumerated.item = uinfo->value.enumerated.items -
684 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 733 1;
734 strcpy(uinfo->value.enumerated.name,
735 texts[uinfo->value.enumerated.item]);
685 736
686 return 0; 737 return 0;
687} 738}
688 739
689static int phase28_oversampling_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 740static int phase28_oversampling_get(struct snd_kcontrol *kcontrol,
741 struct snd_ctl_elem_value *ucontrol)
690{ 742{
691 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 743 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
692 ucontrol->value.enumerated.item[0] = (wm_get(ice, WM_MASTER) & 0x8) == 0x8; 744 ucontrol->value.enumerated.item[0] = (wm_get(ice, WM_MASTER) & 0x8) ==
745 0x8;
693 return 0; 746 return 0;
694} 747}
695 748
696static int phase28_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 749static int phase28_oversampling_put(struct snd_kcontrol *kcontrol,
750 struct snd_ctl_elem_value *ucontrol)
697{ 751{
698 int temp, temp2; 752 int temp, temp2;
699 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 753 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
700 754
701 temp2 = temp = wm_get(ice, WM_MASTER); 755 temp = wm_get(ice, WM_MASTER);
756 temp2 = temp;
702 757
703 if (ucontrol->value.enumerated.item[0]) 758 if (ucontrol->value.enumerated.item[0])
704 temp |= 0x8; 759 temp |= 0x8;
@@ -871,13 +926,16 @@ static int __devinit phase28_add_controls(struct snd_ice1712 *ice)
871 926
872 counts = ARRAY_SIZE(phase28_dac_controls); 927 counts = ARRAY_SIZE(phase28_dac_controls);
873 for (i = 0; i < counts; i++) { 928 for (i = 0; i < counts; i++) {
874 err = snd_ctl_add(ice->card, snd_ctl_new1(&phase28_dac_controls[i], ice)); 929 err = snd_ctl_add(ice->card,
930 snd_ctl_new1(&phase28_dac_controls[i],
931 ice));
875 if (err < 0) 932 if (err < 0)
876 return err; 933 return err;
877 } 934 }
878 935
879 for (i = 0; i < ARRAY_SIZE(wm_controls); i++) { 936 for (i = 0; i < ARRAY_SIZE(wm_controls); i++) {
880 err = snd_ctl_add(ice->card, snd_ctl_new1(&wm_controls[i], ice)); 937 err = snd_ctl_add(ice->card,
938 snd_ctl_new1(&wm_controls[i], ice));
881 if (err < 0) 939 if (err < 0)
882 return err; 940 return err;
883 } 941 }
@@ -904,5 +962,14 @@ struct snd_ice1712_card_info snd_vt1724_phase_cards[] __devinitdata = {
904 .eeprom_size = sizeof(phase28_eeprom), 962 .eeprom_size = sizeof(phase28_eeprom),
905 .eeprom_data = phase28_eeprom, 963 .eeprom_data = phase28_eeprom,
906 }, 964 },
965 {
966 .subvendor = VT1724_SUBDEVICE_TS22,
967 .name = "Terrasoniq TS22 PCI",
968 .model = "TS22",
969 .chip_init = phase22_init,
970 .build_controls = phase22_add_controls,
971 .eeprom_size = sizeof(phase22_eeprom),
972 .eeprom_data = phase22_eeprom,
973 },
907 { } /* terminator */ 974 { } /* terminator */
908}; 975};
diff --git a/sound/pci/ice1712/phase.h b/sound/pci/ice1712/phase.h
index 13e841b55488..7fc22d9d442f 100644
--- a/sound/pci/ice1712/phase.h
+++ b/sound/pci/ice1712/phase.h
@@ -22,13 +22,15 @@
22 * along with this program; if not, write to the Free Software 22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 * 24 *
25 */ 25 */
26 26
27#define PHASE_DEVICE_DESC "{Terratec,Phase 22},"\ 27#define PHASE_DEVICE_DESC "{Terratec,Phase 22},"\
28 "{Terratec,Phase 28}," 28 "{Terratec,Phase 28},"\
29 "{Terrasoniq,TS22},"
29 30
30#define VT1724_SUBDEVICE_PHASE22 0x3b155011 31#define VT1724_SUBDEVICE_PHASE22 0x3b155011
31#define VT1724_SUBDEVICE_PHASE28 0x3b154911 32#define VT1724_SUBDEVICE_PHASE28 0x3b154911
33#define VT1724_SUBDEVICE_TS22 0x3b157b11
32 34
33/* entry point */ 35/* entry point */
34extern struct snd_ice1712_card_info snd_vt1724_phase_cards[]; 36extern struct snd_ice1712_card_info snd_vt1724_phase_cards[];
diff --git a/sound/pci/ice1712/pontis.c b/sound/pci/ice1712/pontis.c
index 203cdc1bf8da..6bc3f91b7281 100644
--- a/sound/pci/ice1712/pontis.c
+++ b/sound/pci/ice1712/pontis.c
@@ -43,7 +43,8 @@
43/* WM8776 registers */ 43/* WM8776 registers */
44#define WM_HP_ATTEN_L 0x00 /* headphone left attenuation */ 44#define WM_HP_ATTEN_L 0x00 /* headphone left attenuation */
45#define WM_HP_ATTEN_R 0x01 /* headphone left attenuation */ 45#define WM_HP_ATTEN_R 0x01 /* headphone left attenuation */
46#define WM_HP_MASTER 0x02 /* headphone master (both channels), override LLR */ 46#define WM_HP_MASTER 0x02 /* headphone master (both channels) */
47 /* override LLR */
47#define WM_DAC_ATTEN_L 0x03 /* digital left attenuation */ 48#define WM_DAC_ATTEN_L 0x03 /* digital left attenuation */
48#define WM_DAC_ATTEN_R 0x04 49#define WM_DAC_ATTEN_R 0x04
49#define WM_DAC_MASTER 0x05 50#define WM_DAC_MASTER 0x05
@@ -740,7 +741,7 @@ static int __devinit pontis_init(struct snd_ice1712 *ice)
740 WM_DAC_ATTEN_L, 0x0100, /* DAC 0dB */ 741 WM_DAC_ATTEN_L, 0x0100, /* DAC 0dB */
741 WM_DAC_ATTEN_R, 0x0000, /* DAC 0dB */ 742 WM_DAC_ATTEN_R, 0x0000, /* DAC 0dB */
742 WM_DAC_ATTEN_R, 0x0100, /* DAC 0dB */ 743 WM_DAC_ATTEN_R, 0x0100, /* DAC 0dB */
743 // WM_DAC_MASTER, 0x0100, /* DAC master muted */ 744 /* WM_DAC_MASTER, 0x0100, */ /* DAC master muted */
744 WM_PHASE_SWAP, 0x0000, /* phase normal */ 745 WM_PHASE_SWAP, 0x0000, /* phase normal */
745 WM_DAC_CTRL2, 0x0000, /* no deemphasis, no ZFLG */ 746 WM_DAC_CTRL2, 0x0000, /* no deemphasis, no ZFLG */
746 WM_ADC_ATTEN_L, 0x0000, /* ADC muted */ 747 WM_ADC_ATTEN_L, 0x0000, /* ADC muted */
diff --git a/sound/pci/ice1712/revo.c b/sound/pci/ice1712/revo.c
index 4d2631434dc8..b508bb360b97 100644
--- a/sound/pci/ice1712/revo.c
+++ b/sound/pci/ice1712/revo.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * ALSA driver for ICEnsemble ICE1712 (Envy24) 2 * ALSA driver for ICEnsemble ICE1712 (Envy24)
3 * 3 *
4 * Lowlevel functions for M-Audio Revolution 7.1 4 * Lowlevel functions for M-Audio Audiophile 192, Revolution 7.1 and 5.1
5 * 5 *
6 * Copyright (c) 2003 Takashi Iwai <tiwai@suse.de> 6 * Copyright (c) 2003 Takashi Iwai <tiwai@suse.de>
7 * 7 *
@@ -48,7 +48,7 @@ static void revo_i2s_mclk_changed(struct snd_ice1712 *ice)
48} 48}
49 49
50/* 50/*
51 * change the rate of envy24HT, AK4355 and AK4381 51 * change the rate of Envy24HT, AK4355 and AK4381
52 */ 52 */
53static void revo_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate) 53static void revo_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate)
54{ 54{
@@ -83,8 +83,8 @@ static void revo_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate)
83 tmp = snd_akm4xxx_get(ak, 0, reg); 83 tmp = snd_akm4xxx_get(ak, 0, reg);
84 tmp &= ~(0x03 << shift); 84 tmp &= ~(0x03 << shift);
85 tmp |= dfs << shift; 85 tmp |= dfs << shift;
86 // snd_akm4xxx_write(ak, 0, reg, tmp); 86 /* snd_akm4xxx_write(ak, 0, reg, tmp); */
87 snd_akm4xxx_set(ak, 0, reg, tmp); /* the value is written in reset(0) */ 87 snd_akm4xxx_set(ak, 0, reg, tmp); /* value is written in reset(0) */
88 snd_akm4xxx_reset(ak, 0); 88 snd_akm4xxx_reset(ak, 0);
89} 89}
90 90
@@ -216,6 +216,7 @@ static const struct snd_akm4xxx_dac_channel revo51_dac[] = {
216 AK_DAC("PCM Center Playback Volume", 1), 216 AK_DAC("PCM Center Playback Volume", 1),
217 AK_DAC("PCM LFE Playback Volume", 1), 217 AK_DAC("PCM LFE Playback Volume", 1),
218 AK_DAC("PCM Rear Playback Volume", 2), 218 AK_DAC("PCM Rear Playback Volume", 2),
219 AK_DAC("PCM Headphone Volume", 2),
219}; 220};
220 221
221static const char *revo51_adc_input_names[] = { 222static const char *revo51_adc_input_names[] = {
@@ -279,7 +280,7 @@ static struct snd_ak4xxx_private akm_revo_surround_priv __devinitdata = {
279 280
280static struct snd_akm4xxx akm_revo51 __devinitdata = { 281static struct snd_akm4xxx akm_revo51 __devinitdata = {
281 .type = SND_AK4358, 282 .type = SND_AK4358,
282 .num_dacs = 6, 283 .num_dacs = 8,
283 .ops = { 284 .ops = {
284 .set_rate_val = revo_set_rate_val 285 .set_rate_val = revo_set_rate_val
285 }, 286 },
@@ -508,7 +509,7 @@ static int __devinit revo_init(struct snd_ice1712 *ice)
508 ice->gpio.i2s_mclk_changed = revo_i2s_mclk_changed; 509 ice->gpio.i2s_mclk_changed = revo_i2s_mclk_changed;
509 break; 510 break;
510 case VT1724_SUBDEVICE_REVOLUTION51: 511 case VT1724_SUBDEVICE_REVOLUTION51:
511 ice->num_total_dacs = 6; 512 ice->num_total_dacs = 8;
512 ice->num_total_adcs = 2; 513 ice->num_total_adcs = 2;
513 break; 514 break;
514 case VT1724_SUBDEVICE_AUDIOPHILE192: 515 case VT1724_SUBDEVICE_AUDIOPHILE192:
@@ -524,16 +525,20 @@ static int __devinit revo_init(struct snd_ice1712 *ice)
524 ak = ice->akm = kcalloc(2, sizeof(struct snd_akm4xxx), GFP_KERNEL); 525 ak = ice->akm = kcalloc(2, sizeof(struct snd_akm4xxx), GFP_KERNEL);
525 if (! ak) 526 if (! ak)
526 return -ENOMEM; 527 return -ENOMEM;
527 ice->akm_codecs = 2;
528 switch (ice->eeprom.subvendor) { 528 switch (ice->eeprom.subvendor) {
529 case VT1724_SUBDEVICE_REVOLUTION71: 529 case VT1724_SUBDEVICE_REVOLUTION71:
530 ice->akm_codecs = 2; 530 ice->akm_codecs = 2;
531 if ((err = snd_ice1712_akm4xxx_init(ak, &akm_revo_front, &akm_revo_front_priv, ice)) < 0) 531 err = snd_ice1712_akm4xxx_init(ak, &akm_revo_front,
532 &akm_revo_front_priv, ice);
533 if (err < 0)
532 return err; 534 return err;
533 if ((err = snd_ice1712_akm4xxx_init(ak + 1, &akm_revo_surround, &akm_revo_surround_priv, ice)) < 0) 535 err = snd_ice1712_akm4xxx_init(ak+1, &akm_revo_surround,
536 &akm_revo_surround_priv, ice);
537 if (err < 0)
534 return err; 538 return err;
535 /* unmute all codecs */ 539 /* unmute all codecs */
536 snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE, VT1724_REVO_MUTE); 540 snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE,
541 VT1724_REVO_MUTE);
537 break; 542 break;
538 case VT1724_SUBDEVICE_REVOLUTION51: 543 case VT1724_SUBDEVICE_REVOLUTION51:
539 ice->akm_codecs = 2; 544 ice->akm_codecs = 2;
diff --git a/sound/pci/ice1712/wtm.c b/sound/pci/ice1712/wtm.c
index a08d17c7e651..5af9e84456d1 100644
--- a/sound/pci/ice1712/wtm.c
+++ b/sound/pci/ice1712/wtm.c
@@ -1,12 +1,12 @@
1/* 1/*
2 * ALSA driver for ICEnsemble VT1724 (Envy24HT) 2 * ALSA driver for ICEnsemble VT1724 (Envy24HT)
3 * 3 *
4 * Lowlevel functions for Ego Sys Waveterminal 192M 4 * Lowlevel functions for Ego Sys Waveterminal 192M
5 * 5 *
6 * Copyright (c) 2006 Guedez Clement <klem.dev@gmail.com> 6 * Copyright (c) 2006 Guedez Clement <klem.dev@gmail.com>
7 * Some functions are taken from the Prodigy192 driver 7 * Some functions are taken from the Prodigy192 driver
8 * source 8 * source
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by 11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or 12 * the Free Software Foundation; either version 2 of the License, or
@@ -20,12 +20,12 @@
20 * You should have received a copy of the GNU General Public License 20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software 21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 * 23 *
24 */ 24 */
25 25
26 26
27 27
28#include <asm/io.h> 28#include <linux/io.h>
29#include <linux/delay.h> 29#include <linux/delay.h>
30#include <linux/interrupt.h> 30#include <linux/interrupt.h>
31#include <linux/init.h> 31#include <linux/init.h>
@@ -39,9 +39,9 @@
39 39
40 40
41/* 41/*
42 * 2*ADC 6*DAC no1 ringbuffer r/w on i2c bus 42 * 2*ADC 6*DAC no1 ringbuffer r/w on i2c bus
43 */ 43 */
44static inline void stac9460_put(struct snd_ice1712 *ice, int reg, 44static inline void stac9460_put(struct snd_ice1712 *ice, int reg,
45 unsigned char val) 45 unsigned char val)
46{ 46{
47 snd_vt1724_write_i2c(ice, STAC9460_I2C_ADDR, reg, val); 47 snd_vt1724_write_i2c(ice, STAC9460_I2C_ADDR, reg, val);
@@ -73,7 +73,7 @@ static inline unsigned char stac9460_2_get(struct snd_ice1712 *ice, int reg)
73#define stac9460_dac_mute_info snd_ctl_boolean_mono_info 73#define stac9460_dac_mute_info snd_ctl_boolean_mono_info
74 74
75static int stac9460_dac_mute_get(struct snd_kcontrol *kcontrol, 75static int stac9460_dac_mute_get(struct snd_kcontrol *kcontrol,
76 struct snd_ctl_elem_value *ucontrol) 76 struct snd_ctl_elem_value *ucontrol)
77{ 77{
78 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 78 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
79 unsigned char val; 79 unsigned char val;
@@ -88,14 +88,14 @@ static int stac9460_dac_mute_get(struct snd_kcontrol *kcontrol,
88 } 88 }
89 if (id < 6) 89 if (id < 6)
90 val = stac9460_get(ice, idx); 90 val = stac9460_get(ice, idx);
91 else 91 else
92 val = stac9460_2_get(ice,idx - 6); 92 val = stac9460_2_get(ice, idx - 6);
93 ucontrol->value.integer.value[0] = (~val >> 7) & 0x1; 93 ucontrol->value.integer.value[0] = (~val >> 7) & 0x1;
94 return 0; 94 return 0;
95} 95}
96 96
97static int stac9460_dac_mute_put(struct snd_kcontrol *kcontrol, 97static int stac9460_dac_mute_put(struct snd_kcontrol *kcontrol,
98 struct snd_ctl_elem_value *ucontrol) 98 struct snd_ctl_elem_value *ucontrol)
99{ 99{
100 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 100 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
101 unsigned char new, old; 101 unsigned char new, old;
@@ -105,8 +105,8 @@ static int stac9460_dac_mute_put(struct snd_kcontrol *kcontrol,
105 if (kcontrol->private_value) { 105 if (kcontrol->private_value) {
106 idx = STAC946X_MASTER_VOLUME; 106 idx = STAC946X_MASTER_VOLUME;
107 old = stac9460_get(ice, idx); 107 old = stac9460_get(ice, idx);
108 new = (~ucontrol->value.integer.value[0]<< 7 & 0x80) | 108 new = (~ucontrol->value.integer.value[0] << 7 & 0x80) |
109 (old & ~0x80); 109 (old & ~0x80);
110 change = (new != old); 110 change = (new != old);
111 if (change) { 111 if (change) {
112 stac9460_put(ice, idx, new); 112 stac9460_put(ice, idx, new);
@@ -117,16 +117,16 @@ static int stac9460_dac_mute_put(struct snd_kcontrol *kcontrol,
117 idx = id + STAC946X_LF_VOLUME; 117 idx = id + STAC946X_LF_VOLUME;
118 if (id < 6) 118 if (id < 6)
119 old = stac9460_get(ice, idx); 119 old = stac9460_get(ice, idx);
120 else 120 else
121 old = stac9460_2_get(ice, idx - 6); 121 old = stac9460_2_get(ice, idx - 6);
122 new = (~ucontrol->value.integer.value[0]<< 7 & 0x80) | 122 new = (~ucontrol->value.integer.value[0] << 7 & 0x80) |
123 (old & ~0x80); 123 (old & ~0x80);
124 change = (new != old); 124 change = (new != old);
125 if (change) { 125 if (change) {
126 if (id < 6) 126 if (id < 6)
127 stac9460_put(ice, idx, new); 127 stac9460_put(ice, idx, new);
128 else 128 else
129 stac9460_2_put(ice, idx - 6, new); 129 stac9460_2_put(ice, idx - 6, new);
130 } 130 }
131 } 131 }
132 return change; 132 return change;
@@ -136,7 +136,7 @@ static int stac9460_dac_mute_put(struct snd_kcontrol *kcontrol,
136 * DAC volume attenuation mixer control 136 * DAC volume attenuation mixer control
137 */ 137 */
138static int stac9460_dac_vol_info(struct snd_kcontrol *kcontrol, 138static int stac9460_dac_vol_info(struct snd_kcontrol *kcontrol,
139 struct snd_ctl_elem_info *uinfo) 139 struct snd_ctl_elem_info *uinfo)
140{ 140{
141 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 141 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
142 uinfo->count = 1; 142 uinfo->count = 1;
@@ -146,7 +146,7 @@ static int stac9460_dac_vol_info(struct snd_kcontrol *kcontrol,
146} 146}
147 147
148static int stac9460_dac_vol_get(struct snd_kcontrol *kcontrol, 148static int stac9460_dac_vol_get(struct snd_kcontrol *kcontrol,
149 struct snd_ctl_elem_value *ucontrol) 149 struct snd_ctl_elem_value *ucontrol)
150{ 150{
151 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 151 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
152 int idx, id; 152 int idx, id;
@@ -161,14 +161,14 @@ static int stac9460_dac_vol_get(struct snd_kcontrol *kcontrol,
161 } 161 }
162 if (id < 6) 162 if (id < 6)
163 vol = stac9460_get(ice, idx) & 0x7f; 163 vol = stac9460_get(ice, idx) & 0x7f;
164 else 164 else
165 vol = stac9460_2_get(ice, idx - 6) & 0x7f; 165 vol = stac9460_2_get(ice, idx - 6) & 0x7f;
166 ucontrol->value.integer.value[0] = 0x7f - vol; 166 ucontrol->value.integer.value[0] = 0x7f - vol;
167 return 0; 167 return 0;
168} 168}
169 169
170static int stac9460_dac_vol_put(struct snd_kcontrol *kcontrol, 170static int stac9460_dac_vol_put(struct snd_kcontrol *kcontrol,
171 struct snd_ctl_elem_value *ucontrol) 171 struct snd_ctl_elem_value *ucontrol)
172{ 172{
173 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 173 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
174 int idx, id; 174 int idx, id;
@@ -182,8 +182,8 @@ static int stac9460_dac_vol_put(struct snd_kcontrol *kcontrol,
182 ovol = 0x7f - (tmp & 0x7f); 182 ovol = 0x7f - (tmp & 0x7f);
183 change = (ovol != nvol); 183 change = (ovol != nvol);
184 if (change) { 184 if (change) {
185 stac9460_put(ice, idx, (0x7f - nvol) | (tmp & 0x80)); 185 stac9460_put(ice, idx, (0x7f - nvol) | (tmp & 0x80));
186 stac9460_2_put(ice, idx, (0x7f - nvol) | (tmp & 0x80)); 186 stac9460_2_put(ice, idx, (0x7f - nvol) | (tmp & 0x80));
187 } 187 }
188 } else { 188 } else {
189 id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 189 id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
@@ -191,17 +191,17 @@ static int stac9460_dac_vol_put(struct snd_kcontrol *kcontrol,
191 nvol = ucontrol->value.integer.value[0] & 0x7f; 191 nvol = ucontrol->value.integer.value[0] & 0x7f;
192 if (id < 6) 192 if (id < 6)
193 tmp = stac9460_get(ice, idx); 193 tmp = stac9460_get(ice, idx);
194 else 194 else
195 tmp = stac9460_2_get(ice, idx - 6); 195 tmp = stac9460_2_get(ice, idx - 6);
196 ovol = 0x7f - (tmp & 0x7f); 196 ovol = 0x7f - (tmp & 0x7f);
197 change = (ovol != nvol); 197 change = (ovol != nvol);
198 if (change) { 198 if (change) {
199 if (id < 6) 199 if (id < 6)
200 stac9460_put(ice, idx, (0x7f - nvol) | 200 stac9460_put(ice, idx, (0x7f - nvol) |
201 (tmp & 0x80)); 201 (tmp & 0x80));
202 else 202 else
203 stac9460_2_put(ice, idx-6, (0x7f - nvol) | 203 stac9460_2_put(ice, idx-6, (0x7f - nvol) |
204 (tmp & 0x80)); 204 (tmp & 0x80));
205 } 205 }
206 } 206 }
207 return change; 207 return change;
@@ -213,12 +213,12 @@ static int stac9460_dac_vol_put(struct snd_kcontrol *kcontrol,
213#define stac9460_adc_mute_info snd_ctl_boolean_stereo_info 213#define stac9460_adc_mute_info snd_ctl_boolean_stereo_info
214 214
215static int stac9460_adc_mute_get(struct snd_kcontrol *kcontrol, 215static int stac9460_adc_mute_get(struct snd_kcontrol *kcontrol,
216 struct snd_ctl_elem_value *ucontrol) 216 struct snd_ctl_elem_value *ucontrol)
217{ 217{
218 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 218 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
219 unsigned char val; 219 unsigned char val;
220 int i, id; 220 int i, id;
221 221
222 id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 222 id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
223 if (id == 0) { 223 if (id == 0) {
224 for (i = 0; i < 2; ++i) { 224 for (i = 0; i < 2; ++i) {
@@ -235,20 +235,20 @@ static int stac9460_adc_mute_get(struct snd_kcontrol *kcontrol,
235} 235}
236 236
237static int stac9460_adc_mute_put(struct snd_kcontrol *kcontrol, 237static int stac9460_adc_mute_put(struct snd_kcontrol *kcontrol,
238 struct snd_ctl_elem_value *ucontrol) 238 struct snd_ctl_elem_value *ucontrol)
239{ 239{
240 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 240 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
241 unsigned char new, old; 241 unsigned char new, old;
242 int i, reg, id; 242 int i, reg, id;
243 int change; 243 int change;
244 244
245 id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 245 id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
246 if (id == 0) { 246 if (id == 0) {
247 for (i = 0; i < 2; ++i) { 247 for (i = 0; i < 2; ++i) {
248 reg = STAC946X_MIC_L_VOLUME + i; 248 reg = STAC946X_MIC_L_VOLUME + i;
249 old = stac9460_get(ice, reg); 249 old = stac9460_get(ice, reg);
250 new = (~ucontrol->value.integer.value[i]<<7&0x80) | 250 new = (~ucontrol->value.integer.value[i]<<7&0x80) |
251 (old&~0x80); 251 (old&~0x80);
252 change = (new != old); 252 change = (new != old);
253 if (change) 253 if (change)
254 stac9460_put(ice, reg, new); 254 stac9460_put(ice, reg, new);
@@ -258,7 +258,7 @@ static int stac9460_adc_mute_put(struct snd_kcontrol *kcontrol,
258 reg = STAC946X_MIC_L_VOLUME + i; 258 reg = STAC946X_MIC_L_VOLUME + i;
259 old = stac9460_2_get(ice, reg); 259 old = stac9460_2_get(ice, reg);
260 new = (~ucontrol->value.integer.value[i]<<7&0x80) | 260 new = (~ucontrol->value.integer.value[i]<<7&0x80) |
261 (old&~0x80); 261 (old&~0x80);
262 change = (new != old); 262 change = (new != old);
263 if (change) 263 if (change)
264 stac9460_2_put(ice, reg, new); 264 stac9460_2_put(ice, reg, new);
@@ -271,7 +271,7 @@ static int stac9460_adc_mute_put(struct snd_kcontrol *kcontrol,
271 *ADC gain mixer control 271 *ADC gain mixer control
272 */ 272 */
273static int stac9460_adc_vol_info(struct snd_kcontrol *kcontrol, 273static int stac9460_adc_vol_info(struct snd_kcontrol *kcontrol,
274 struct snd_ctl_elem_info *uinfo) 274 struct snd_ctl_elem_info *uinfo)
275{ 275{
276 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 276 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
277 uinfo->count = 2; 277 uinfo->count = 2;
@@ -281,12 +281,12 @@ static int stac9460_adc_vol_info(struct snd_kcontrol *kcontrol,
281} 281}
282 282
283static int stac9460_adc_vol_get(struct snd_kcontrol *kcontrol, 283static int stac9460_adc_vol_get(struct snd_kcontrol *kcontrol,
284 struct snd_ctl_elem_value *ucontrol) 284 struct snd_ctl_elem_value *ucontrol)
285{ 285{
286 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 286 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
287 int i, reg, id; 287 int i, reg, id;
288 unsigned char vol; 288 unsigned char vol;
289 289
290 id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 290 id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
291 if (id == 0) { 291 if (id == 0) {
292 for (i = 0; i < 2; ++i) { 292 for (i = 0; i < 2; ++i) {
@@ -305,13 +305,13 @@ static int stac9460_adc_vol_get(struct snd_kcontrol *kcontrol,
305} 305}
306 306
307static int stac9460_adc_vol_put(struct snd_kcontrol *kcontrol, 307static int stac9460_adc_vol_put(struct snd_kcontrol *kcontrol,
308 struct snd_ctl_elem_value *ucontrol) 308 struct snd_ctl_elem_value *ucontrol)
309{ 309{
310 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 310 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
311 int i, reg, id; 311 int i, reg, id;
312 unsigned char ovol, nvol; 312 unsigned char ovol, nvol;
313 int change; 313 int change;
314 314
315 id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 315 id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
316 if (id == 0) { 316 if (id == 0) {
317 for (i = 0; i < 2; ++i) { 317 for (i = 0; i < 2; ++i) {
@@ -321,7 +321,7 @@ static int stac9460_adc_vol_put(struct snd_kcontrol *kcontrol,
321 change = ((ovol & 0x0f) != nvol); 321 change = ((ovol & 0x0f) != nvol);
322 if (change) 322 if (change)
323 stac9460_put(ice, reg, (0x0f - nvol) | 323 stac9460_put(ice, reg, (0x0f - nvol) |
324 (ovol & ~0x0f)); 324 (ovol & ~0x0f));
325 } 325 }
326 } else { 326 } else {
327 for (i = 0; i < 2; ++i) { 327 for (i = 0; i < 2; ++i) {
@@ -331,7 +331,7 @@ static int stac9460_adc_vol_put(struct snd_kcontrol *kcontrol,
331 change = ((ovol & 0x0f) != nvol); 331 change = ((ovol & 0x0f) != nvol);
332 if (change) 332 if (change)
333 stac9460_2_put(ice, reg, (0x0f - nvol) | 333 stac9460_2_put(ice, reg, (0x0f - nvol) |
334 (ovol & ~0x0f)); 334 (ovol & ~0x0f));
335 } 335 }
336 } 336 }
337 return change; 337 return change;
@@ -344,23 +344,23 @@ static int stac9460_adc_vol_put(struct snd_kcontrol *kcontrol,
344#define stac9460_mic_sw_info snd_ctl_boolean_mono_info 344#define stac9460_mic_sw_info snd_ctl_boolean_mono_info
345 345
346static int stac9460_mic_sw_get(struct snd_kcontrol *kcontrol, 346static int stac9460_mic_sw_get(struct snd_kcontrol *kcontrol,
347 struct snd_ctl_elem_value *ucontrol) 347 struct snd_ctl_elem_value *ucontrol)
348{ 348{
349 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 349 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
350 unsigned char val; 350 unsigned char val;
351 int id; 351 int id;
352 352
353 id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 353 id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
354 if (id == 0) 354 if (id == 0)
355 val = stac9460_get(ice, STAC946X_GENERAL_PURPOSE); 355 val = stac9460_get(ice, STAC946X_GENERAL_PURPOSE);
356 else 356 else
357 val = stac9460_2_get(ice, STAC946X_GENERAL_PURPOSE); 357 val = stac9460_2_get(ice, STAC946X_GENERAL_PURPOSE);
358 ucontrol->value.integer.value[0] = ~val>>7 & 0x1; 358 ucontrol->value.integer.value[0] = ~val>>7 & 0x1;
359 return 0; 359 return 0;
360} 360}
361 361
362static int stac9460_mic_sw_put(struct snd_kcontrol *kcontrol, 362static int stac9460_mic_sw_put(struct snd_kcontrol *kcontrol,
363 struct snd_ctl_elem_value *ucontrol) 363 struct snd_ctl_elem_value *ucontrol)
364{ 364{
365 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 365 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
366 unsigned char new, old; 366 unsigned char new, old;
@@ -368,16 +368,16 @@ static int stac9460_mic_sw_put(struct snd_kcontrol *kcontrol,
368 368
369 id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 369 id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
370 if (id == 0) 370 if (id == 0)
371 old = stac9460_get(ice, STAC946X_GENERAL_PURPOSE); 371 old = stac9460_get(ice, STAC946X_GENERAL_PURPOSE);
372 else 372 else
373 old = stac9460_2_get(ice, STAC946X_GENERAL_PURPOSE); 373 old = stac9460_2_get(ice, STAC946X_GENERAL_PURPOSE);
374 new = (~ucontrol->value.integer.value[0]<< 7 & 0x80) | (old & ~0x80); 374 new = (~ucontrol->value.integer.value[0] << 7 & 0x80) | (old & ~0x80);
375 change = (new != old); 375 change = (new != old);
376 if (change) { 376 if (change) {
377 if (id == 0) 377 if (id == 0)
378 stac9460_put(ice, STAC946X_GENERAL_PURPOSE, new); 378 stac9460_put(ice, STAC946X_GENERAL_PURPOSE, new);
379 else 379 else
380 stac9460_2_put(ice, STAC946X_GENERAL_PURPOSE, new); 380 stac9460_2_put(ice, STAC946X_GENERAL_PURPOSE, new);
381 } 381 }
382 return change; 382 return change;
383} 383}
@@ -443,7 +443,7 @@ static struct snd_kcontrol_new stac9640_controls[] __devinitdata = {
443 .get = stac9460_adc_vol_get, 443 .get = stac9460_adc_vol_get,
444 .put = stac9460_adc_vol_put, 444 .put = stac9460_adc_vol_put,
445 445
446 } 446 }
447}; 447};
448 448
449 449
@@ -470,7 +470,7 @@ static int __devinit wtm_init(struct snd_ice1712 *ice)
470 (unsigned short)-1 470 (unsigned short)-1
471 }; 471 };
472 unsigned short *p; 472 unsigned short *p;
473 473
474 /*WTM 192M*/ 474 /*WTM 192M*/
475 ice->num_total_dacs = 8; 475 ice->num_total_dacs = 8;
476 ice->num_total_adcs = 4; 476 ice->num_total_adcs = 4;
diff --git a/sound/pci/ice1712/wtm.h b/sound/pci/ice1712/wtm.h
index 03a394e442f1..423c1a204c0b 100644
--- a/sound/pci/ice1712/wtm.h
+++ b/sound/pci/ice1712/wtm.h
@@ -10,8 +10,8 @@
10 */ 10 */
11 11
12#define AK4114_ADDR 0x20 /*S/PDIF receiver*/ 12#define AK4114_ADDR 0x20 /*S/PDIF receiver*/
13#define STAC9460_I2C_ADDR 0x54 /* ADC*2 | DAC*6 */ 13#define STAC9460_I2C_ADDR 0x54 /* ADC*2 | DAC*6 */
14#define STAC9460_2_I2C_ADDR 0x56 /* ADC|DAC *2 */ 14#define STAC9460_2_I2C_ADDR 0x56 /* ADC|DAC *2 */
15 15
16 16
17extern struct snd_ice1712_card_info snd_vt1724_wtm_cards[]; 17extern struct snd_ice1712_card_info snd_vt1724_wtm_cards[];
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index 048d99e25ab0..c88d1eace1c4 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -59,6 +59,12 @@ MODULE_SUPPORTED_DEVICE("{{Intel,82801AA-ICH},"
59 "{SiS,SI7012}," 59 "{SiS,SI7012},"
60 "{NVidia,nForce Audio}," 60 "{NVidia,nForce Audio},"
61 "{NVidia,nForce2 Audio}," 61 "{NVidia,nForce2 Audio},"
62 "{NVidia,nForce3 Audio},"
63 "{NVidia,MCP04},"
64 "{NVidia,MCP501},"
65 "{NVidia,CK804},"
66 "{NVidia,CK8},"
67 "{NVidia,CK8S},"
62 "{AMD,AMD768}," 68 "{AMD,AMD768},"
63 "{AMD,AMD8111}," 69 "{AMD,AMD8111},"
64 "{ALI,M5455}}"); 70 "{ALI,M5455}}");
@@ -77,7 +83,7 @@ MODULE_PARM_DESC(index, "Index value for Intel i8x0 soundcard.");
77module_param(id, charp, 0444); 83module_param(id, charp, 0444);
78MODULE_PARM_DESC(id, "ID string for Intel i8x0 soundcard."); 84MODULE_PARM_DESC(id, "ID string for Intel i8x0 soundcard.");
79module_param(ac97_clock, int, 0444); 85module_param(ac97_clock, int, 0444);
80MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (0 = auto-detect)."); 86MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (0 = whitelist + auto-detect, 1 = force autodetect).");
81module_param(ac97_quirk, charp, 0444); 87module_param(ac97_quirk, charp, 0444);
82MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware."); 88MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware.");
83module_param(buggy_semaphore, bool, 0444); 89module_param(buggy_semaphore, bool, 0444);
@@ -1957,6 +1963,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
1957 }, 1963 },
1958 { 1964 {
1959 .subvendor = 0x10cf, 1965 .subvendor = 0x10cf,
1966 .subdevice = 0x127d,
1967 .name = "Fujitsu Lifebook P7010",
1968 .type = AC97_TUNE_HP_ONLY
1969 },
1970 {
1971 .subvendor = 0x10cf,
1960 .subdevice = 0x127e, 1972 .subdevice = 0x127e,
1961 .name = "Fujitsu Lifebook C1211D", 1973 .name = "Fujitsu Lifebook C1211D",
1962 .type = AC97_TUNE_HP_ONLY 1974 .type = AC97_TUNE_HP_ONLY
@@ -2132,8 +2144,8 @@ static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock,
2132 snd_intel8x0_codec_read_test(chip, codecs); 2144 snd_intel8x0_codec_read_test(chip, codecs);
2133 chip->ac97_sdin[codecs] = 2145 chip->ac97_sdin[codecs] =
2134 igetbyte(chip, ICHREG(SDM)) & ICH_LDI_MASK; 2146 igetbyte(chip, ICHREG(SDM)) & ICH_LDI_MASK;
2135 snd_assert(chip->ac97_sdin[codecs] < 3, 2147 if (snd_BUG_ON(chip->ac97_sdin[codecs] >= 3))
2136 chip->ac97_sdin[codecs] = 0); 2148 chip->ac97_sdin[codecs] = 0;
2137 } else 2149 } else
2138 chip->ac97_sdin[codecs] = i; 2150 chip->ac97_sdin[codecs] = i;
2139 codecs++; 2151 codecs++;
@@ -2686,6 +2698,28 @@ static void __devinit intel8x0_measure_ac97_clock(struct intel8x0 *chip)
2686 snd_ac97_update_power(chip->ac97[0], AC97_PCM_FRONT_DAC_RATE, 0); 2698 snd_ac97_update_power(chip->ac97[0], AC97_PCM_FRONT_DAC_RATE, 0);
2687} 2699}
2688 2700
2701static struct snd_pci_quirk intel8x0_clock_list[] __devinitdata = {
2702 SND_PCI_QUIRK(0x0e11, 0x008a, "AD1885", 41000),
2703 SND_PCI_QUIRK(0x1028, 0x00be, "AD1885", 44100),
2704 SND_PCI_QUIRK(0x1028, 0x0177, "AD1980", 48000),
2705 SND_PCI_QUIRK(0x1043, 0x80f3, "AD1985", 48000),
2706 { } /* terminator */
2707};
2708
2709static int __devinit intel8x0_in_clock_list(struct intel8x0 *chip)
2710{
2711 struct pci_dev *pci = chip->pci;
2712 const struct snd_pci_quirk *wl;
2713
2714 wl = snd_pci_quirk_lookup(pci, intel8x0_clock_list);
2715 if (!wl)
2716 return 0;
2717 printk(KERN_INFO "intel8x0: white list rate for %04x:%04x is %i\n",
2718 pci->subsystem_vendor, pci->subsystem_device, wl->value);
2719 chip->ac97_bus->clock = wl->value;
2720 return 1;
2721}
2722
2689#ifdef CONFIG_PROC_FS 2723#ifdef CONFIG_PROC_FS
2690static void snd_intel8x0_proc_read(struct snd_info_entry * entry, 2724static void snd_intel8x0_proc_read(struct snd_info_entry * entry,
2691 struct snd_info_buffer *buffer) 2725 struct snd_info_buffer *buffer)
@@ -3081,8 +3115,14 @@ static int __devinit snd_intel8x0_probe(struct pci_dev *pci,
3081 "%s with %s at irq %i", card->shortname, 3115 "%s with %s at irq %i", card->shortname,
3082 snd_ac97_get_short_name(chip->ac97[0]), chip->irq); 3116 snd_ac97_get_short_name(chip->ac97[0]), chip->irq);
3083 3117
3084 if (! ac97_clock) 3118 if (ac97_clock == 0 || ac97_clock == 1) {
3085 intel8x0_measure_ac97_clock(chip); 3119 if (ac97_clock == 0) {
3120 if (intel8x0_in_clock_list(chip) == 0)
3121 intel8x0_measure_ac97_clock(chip);
3122 } else {
3123 intel8x0_measure_ac97_clock(chip);
3124 }
3125 }
3086 3126
3087 if ((err = snd_card_register(card)) < 0) { 3127 if ((err = snd_card_register(card)) < 0) {
3088 snd_card_free(card); 3128 snd_card_free(card);
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c
index faf674e671ac..93449e464566 100644
--- a/sound/pci/intel8x0m.c
+++ b/sound/pci/intel8x0m.c
@@ -306,7 +306,8 @@ static unsigned int get_ich_codec_bit(struct intel8x0m *chip, unsigned int codec
306 static unsigned int codec_bit[3] = { 306 static unsigned int codec_bit[3] = {
307 ICH_PCR, ICH_SCR, ICH_TCR 307 ICH_PCR, ICH_SCR, ICH_TCR
308 }; 308 };
309 snd_assert(codec < 3, return ICH_PCR); 309 if (snd_BUG_ON(codec >= 3))
310 return ICH_PCR;
310 return codec_bit[codec]; 311 return codec_bit[codec];
311} 312}
312 313
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c
index 4a44c0f20f76..5f8006b42750 100644
--- a/sound/pci/korg1212/korg1212.c
+++ b/sound/pci/korg1212/korg1212.c
@@ -1281,7 +1281,8 @@ static int snd_korg1212_silence(struct snd_korg1212 *korg1212, int pos, int coun
1281 1281
1282 K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_silence pos=%d offset=%d size=%d count=%d\n", 1282 K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_silence pos=%d offset=%d size=%d count=%d\n",
1283 pos, offset, size, count); 1283 pos, offset, size, count);
1284 snd_assert(pos + count <= K1212_MAX_SAMPLES, return -EINVAL); 1284 if (snd_BUG_ON(pos + count > K1212_MAX_SAMPLES))
1285 return -EINVAL;
1285 1286
1286 for (i=0; i < count; i++) { 1287 for (i=0; i < count; i++) {
1287#if K1212_DEBUG_LEVEL > 0 1288#if K1212_DEBUG_LEVEL > 0
@@ -1306,7 +1307,8 @@ static int snd_korg1212_copy_to(struct snd_korg1212 *korg1212, void __user *dst,
1306 1307
1307 K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_copy_to pos=%d offset=%d size=%d\n", 1308 K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_copy_to pos=%d offset=%d size=%d\n",
1308 pos, offset, size); 1309 pos, offset, size);
1309 snd_assert(pos + count <= K1212_MAX_SAMPLES, return -EINVAL); 1310 if (snd_BUG_ON(pos + count > K1212_MAX_SAMPLES))
1311 return -EINVAL;
1310 1312
1311 for (i=0; i < count; i++) { 1313 for (i=0; i < count; i++) {
1312#if K1212_DEBUG_LEVEL > 0 1314#if K1212_DEBUG_LEVEL > 0
@@ -1336,7 +1338,8 @@ static int snd_korg1212_copy_from(struct snd_korg1212 *korg1212, void __user *sr
1336 K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_copy_from pos=%d offset=%d size=%d count=%d\n", 1338 K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_copy_from pos=%d offset=%d size=%d count=%d\n",
1337 pos, offset, size, count); 1339 pos, offset, size, count);
1338 1340
1339 snd_assert(pos + count <= K1212_MAX_SAMPLES, return -EINVAL); 1341 if (snd_BUG_ON(pos + count > K1212_MAX_SAMPLES))
1342 return -EINVAL;
1340 1343
1341 for (i=0; i < count; i++) { 1344 for (i=0; i < count; i++) {
1342#if K1212_DEBUG_LEVEL > 0 1345#if K1212_DEBUG_LEVEL > 0
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index 0037be74fdea..9ff3f9e34404 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -1175,7 +1175,8 @@ snd_m3_pcm_trigger(struct snd_pcm_substream *subs, int cmd)
1175 struct m3_dma *s = subs->runtime->private_data; 1175 struct m3_dma *s = subs->runtime->private_data;
1176 int err = -EINVAL; 1176 int err = -EINVAL;
1177 1177
1178 snd_assert(s != NULL, return -ENXIO); 1178 if (snd_BUG_ON(!s))
1179 return -ENXIO;
1179 1180
1180 spin_lock(&chip->reg_lock); 1181 spin_lock(&chip->reg_lock);
1181 switch (cmd) { 1182 switch (cmd) {
@@ -1487,7 +1488,8 @@ snd_m3_pcm_prepare(struct snd_pcm_substream *subs)
1487 struct snd_pcm_runtime *runtime = subs->runtime; 1488 struct snd_pcm_runtime *runtime = subs->runtime;
1488 struct m3_dma *s = runtime->private_data; 1489 struct m3_dma *s = runtime->private_data;
1489 1490
1490 snd_assert(s != NULL, return -ENXIO); 1491 if (snd_BUG_ON(!s))
1492 return -ENXIO;
1491 1493
1492 if (runtime->format != SNDRV_PCM_FORMAT_U8 && 1494 if (runtime->format != SNDRV_PCM_FORMAT_U8 &&
1493 runtime->format != SNDRV_PCM_FORMAT_S16_LE) 1495 runtime->format != SNDRV_PCM_FORMAT_S16_LE)
@@ -1546,7 +1548,9 @@ snd_m3_pcm_pointer(struct snd_pcm_substream *subs)
1546 struct snd_m3 *chip = snd_pcm_substream_chip(subs); 1548 struct snd_m3 *chip = snd_pcm_substream_chip(subs);
1547 unsigned int ptr; 1549 unsigned int ptr;
1548 struct m3_dma *s = subs->runtime->private_data; 1550 struct m3_dma *s = subs->runtime->private_data;
1549 snd_assert(s != NULL, return 0); 1551
1552 if (snd_BUG_ON(!s))
1553 return 0;
1550 1554
1551 spin_lock(&chip->reg_lock); 1555 spin_lock(&chip->reg_lock);
1552 ptr = snd_m3_get_pointer(chip, s, subs); 1556 ptr = snd_m3_get_pointer(chip, s, subs);
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c
index 3dd0c7963273..2d0dce649a64 100644
--- a/sound/pci/mixart/mixart.c
+++ b/sound/pci/mixart/mixart.c
@@ -708,7 +708,7 @@ static int snd_mixart_playback_open(struct snd_pcm_substream *subs)
708 pcm_number = MIXART_PCM_ANALOG; 708 pcm_number = MIXART_PCM_ANALOG;
709 runtime->hw = snd_mixart_analog_caps; 709 runtime->hw = snd_mixart_analog_caps;
710 } else { 710 } else {
711 snd_assert ( pcm == chip->pcm_dig ); 711 snd_BUG_ON(pcm != chip->pcm_dig);
712 pcm_number = MIXART_PCM_DIGITAL; 712 pcm_number = MIXART_PCM_DIGITAL;
713 runtime->hw = snd_mixart_digital_caps; 713 runtime->hw = snd_mixart_digital_caps;
714 } 714 }
@@ -783,7 +783,7 @@ static int snd_mixart_capture_open(struct snd_pcm_substream *subs)
783 pcm_number = MIXART_PCM_ANALOG; 783 pcm_number = MIXART_PCM_ANALOG;
784 runtime->hw = snd_mixart_analog_caps; 784 runtime->hw = snd_mixart_analog_caps;
785 } else { 785 } else {
786 snd_assert ( pcm == chip->pcm_dig ); 786 snd_BUG_ON(pcm != chip->pcm_dig);
787 pcm_number = MIXART_PCM_DIGITAL; 787 pcm_number = MIXART_PCM_DIGITAL;
788 runtime->hw = snd_mixart_digital_caps; 788 runtime->hw = snd_mixart_digital_caps;
789 } 789 }
diff --git a/sound/pci/mixart/mixart_core.c b/sound/pci/mixart/mixart_core.c
index 785085e48353..b9a06c279397 100644
--- a/sound/pci/mixart/mixart_core.c
+++ b/sound/pci/mixart/mixart_core.c
@@ -56,8 +56,10 @@ static int retrieve_msg_frame(struct mixart_mgr *mgr, u32 *msg_frame)
56 if (tailptr == headptr) 56 if (tailptr == headptr)
57 return 0; /* no message posted */ 57 return 0; /* no message posted */
58 58
59 snd_assert( tailptr >= MSG_OUTBOUND_POST_STACK, return 0); /* error */ 59 if (tailptr < MSG_OUTBOUND_POST_STACK)
60 snd_assert( tailptr < (MSG_OUTBOUND_POST_STACK+MSG_BOUND_STACK_SIZE), return 0); /* error */ 60 return 0; /* error */
61 if (tailptr >= MSG_OUTBOUND_POST_STACK + MSG_BOUND_STACK_SIZE)
62 return 0; /* error */
61 63
62 *msg_frame = readl_be(MIXART_MEM(mgr, tailptr)); 64 *msg_frame = readl_be(MIXART_MEM(mgr, tailptr));
63 65
@@ -149,7 +151,8 @@ static int send_msg( struct mixart_mgr *mgr,
149 u32 msg_frame_address; 151 u32 msg_frame_address;
150 int err, i; 152 int err, i;
151 153
152 snd_assert(msg->size % 4 == 0, return -EINVAL); 154 if (snd_BUG_ON(msg->size % 4))
155 return -EINVAL;
153 156
154 err = 0; 157 err = 0;
155 158
@@ -289,9 +292,12 @@ int snd_mixart_send_msg_wait_notif(struct mixart_mgr *mgr,
289 wait_queue_t wait; 292 wait_queue_t wait;
290 long timeout; 293 long timeout;
291 294
292 snd_assert(notif_event != 0, return -EINVAL); 295 if (snd_BUG_ON(!notif_event))
293 snd_assert((notif_event & MSG_TYPE_MASK) == MSG_TYPE_NOTIFY, return -EINVAL); 296 return -EINVAL;
294 snd_assert((notif_event & MSG_CANCEL_NOTIFY_MASK) == 0, return -EINVAL); 297 if (snd_BUG_ON((notif_event & MSG_TYPE_MASK) != MSG_TYPE_NOTIFY))
298 return -EINVAL;
299 if (snd_BUG_ON(notif_event & MSG_CANCEL_NOTIFY_MASK))
300 return -EINVAL;
295 301
296 mutex_lock(&mgr->msg_mutex); 302 mutex_lock(&mgr->msg_mutex);
297 303
diff --git a/sound/pci/mixart/mixart_hwdep.c b/sound/pci/mixart/mixart_hwdep.c
index f98603146132..3782b52bc0e8 100644
--- a/sound/pci/mixart/mixart_hwdep.c
+++ b/sound/pci/mixart/mixart_hwdep.c
@@ -288,7 +288,9 @@ static int mixart_enum_physio(struct mixart_mgr *mgr)
288 return -EINVAL; 288 return -EINVAL;
289 } 289 }
290 290
291 snd_assert(phys_io.nb_uid >= (MIXART_MAX_CARDS * 2), return -EINVAL); /* min 2 phys io per card (analog in + analog out) */ 291 /* min 2 phys io per card (analog in + analog out) */
292 if (phys_io.nb_uid < MIXART_MAX_CARDS * 2)
293 return -EINVAL;
292 294
293 for(k=0; k<mgr->num_cards; k++) { 295 for(k=0; k<mgr->num_cards; k++) {
294 mgr->chip[k]->uid_in_analog_physio = phys_io.uid[k]; 296 mgr->chip[k]->uid_in_analog_physio = phys_io.uid[k];
@@ -363,8 +365,10 @@ static int mixart_dsp_load(struct mixart_mgr* mgr, int index, const struct firmw
363 } 365 }
364 366
365 /* check xilinx validity */ 367 /* check xilinx validity */
366 snd_assert(((u32*)(dsp->data))[0]==0xFFFFFFFF, return -EINVAL); 368 if (((u32*)(dsp->data))[0] == 0xffffffff)
367 snd_assert(dsp->size % 4 == 0, return -EINVAL); 369 return -EINVAL;
370 if (dsp->size % 4)
371 return -EINVAL;
368 372
369 /* set xilinx status to copying */ 373 /* set xilinx status to copying */
370 writel_be( 1, MIXART_MEM( mgr, MIXART_PSEUDOREG_MXLX_STATUS_OFFSET )); 374 writel_be( 1, MIXART_MEM( mgr, MIXART_PSEUDOREG_MXLX_STATUS_OFFSET ));
@@ -462,8 +466,10 @@ static int mixart_dsp_load(struct mixart_mgr* mgr, int index, const struct firmw
462 } 466 }
463 467
464 /* check daughterboard xilinx validity */ 468 /* check daughterboard xilinx validity */
465 snd_assert(((u32*)(dsp->data))[0]==0xFFFFFFFF, return -EINVAL); 469 if (((u32*)(dsp->data))[0] == 0xffffffff)
466 snd_assert(dsp->size % 4 == 0, return -EINVAL); 470 return -EINVAL;
471 if (dsp->size % 4)
472 return -EINVAL;
467 473
468 /* inform mixart about the size of the file */ 474 /* inform mixart about the size of the file */
469 writel_be( dsp->size, MIXART_MEM( mgr, MIXART_PSEUDOREG_DXLX_SIZE_OFFSET )); 475 writel_be( dsp->size, MIXART_MEM( mgr, MIXART_PSEUDOREG_DXLX_SIZE_OFFSET ));
@@ -480,7 +486,8 @@ static int mixart_dsp_load(struct mixart_mgr* mgr, int index, const struct firmw
480 486
481 /* get the address where to write the file */ 487 /* get the address where to write the file */
482 val = readl_be( MIXART_MEM( mgr, MIXART_PSEUDOREG_DXLX_BASE_ADDR_OFFSET )); 488 val = readl_be( MIXART_MEM( mgr, MIXART_PSEUDOREG_DXLX_BASE_ADDR_OFFSET ));
483 snd_assert(val != 0, return -EINVAL); 489 if (!val)
490 return -EINVAL;
484 491
485 /* copy daughterboard xilinx code */ 492 /* copy daughterboard xilinx code */
486 memcpy_toio( MIXART_MEM( mgr, val), dsp->data, dsp->size); 493 memcpy_toio( MIXART_MEM( mgr, val), dsp->data, dsp->size);
diff --git a/sound/pci/mixart/mixart_mixer.c b/sound/pci/mixart/mixart_mixer.c
index 6fdda1f70b25..3ba6174c3df1 100644
--- a/sound/pci/mixart/mixart_mixer.c
+++ b/sound/pci/mixart/mixart_mixer.c
@@ -837,7 +837,7 @@ static int mixart_pcm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem
837 if(is_aes) stored_volume = chip->digital_capture_volume[1]; /* AES capture */ 837 if(is_aes) stored_volume = chip->digital_capture_volume[1]; /* AES capture */
838 else stored_volume = chip->digital_capture_volume[0]; /* analog capture */ 838 else stored_volume = chip->digital_capture_volume[0]; /* analog capture */
839 } else { 839 } else {
840 snd_assert ( idx < MIXART_PLAYBACK_STREAMS ); 840 snd_BUG_ON(idx >= MIXART_PLAYBACK_STREAMS);
841 if(is_aes) stored_volume = chip->digital_playback_volume[MIXART_PLAYBACK_STREAMS + idx]; /* AES playback */ 841 if(is_aes) stored_volume = chip->digital_playback_volume[MIXART_PLAYBACK_STREAMS + idx]; /* AES playback */
842 else stored_volume = chip->digital_playback_volume[idx]; /* analog playback */ 842 else stored_volume = chip->digital_playback_volume[idx]; /* analog playback */
843 } 843 }
@@ -863,7 +863,7 @@ static int mixart_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem
863 else /* analog capture */ 863 else /* analog capture */
864 stored_volume = chip->digital_capture_volume[0]; 864 stored_volume = chip->digital_capture_volume[0];
865 } else { 865 } else {
866 snd_assert ( idx < MIXART_PLAYBACK_STREAMS ); 866 snd_BUG_ON(idx >= MIXART_PLAYBACK_STREAMS);
867 if (is_aes) /* AES playback */ 867 if (is_aes) /* AES playback */
868 stored_volume = chip->digital_playback_volume[MIXART_PLAYBACK_STREAMS + idx]; 868 stored_volume = chip->digital_playback_volume[MIXART_PLAYBACK_STREAMS + idx];
869 else /* analog playback */ 869 else /* analog playback */
@@ -909,7 +909,7 @@ static int mixart_pcm_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_
909{ 909{
910 struct snd_mixart *chip = snd_kcontrol_chip(kcontrol); 910 struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
911 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */ 911 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */
912 snd_assert ( idx < MIXART_PLAYBACK_STREAMS ); 912 snd_BUG_ON(idx >= MIXART_PLAYBACK_STREAMS);
913 mutex_lock(&chip->mgr->mixer_mutex); 913 mutex_lock(&chip->mgr->mixer_mutex);
914 if(kcontrol->private_value & MIXART_VOL_AES_MASK) /* AES playback */ 914 if(kcontrol->private_value & MIXART_VOL_AES_MASK) /* AES playback */
915 idx += MIXART_PLAYBACK_STREAMS; 915 idx += MIXART_PLAYBACK_STREAMS;
@@ -926,7 +926,7 @@ static int mixart_pcm_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_
926 int is_aes = kcontrol->private_value & MIXART_VOL_AES_MASK; 926 int is_aes = kcontrol->private_value & MIXART_VOL_AES_MASK;
927 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */ 927 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */
928 int i, j; 928 int i, j;
929 snd_assert ( idx < MIXART_PLAYBACK_STREAMS ); 929 snd_BUG_ON(idx >= MIXART_PLAYBACK_STREAMS);
930 mutex_lock(&chip->mgr->mixer_mutex); 930 mutex_lock(&chip->mgr->mixer_mutex);
931 j = idx; 931 j = idx;
932 if (is_aes) 932 if (is_aes)
diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c
index 06d13e717114..50c9f8a05082 100644
--- a/sound/pci/nm256/nm256.c
+++ b/sound/pci/nm256/nm256.c
@@ -562,7 +562,8 @@ snd_nm256_playback_trigger(struct snd_pcm_substream *substream, int cmd)
562 struct nm256_stream *s = substream->runtime->private_data; 562 struct nm256_stream *s = substream->runtime->private_data;
563 int err = 0; 563 int err = 0;
564 564
565 snd_assert(s != NULL, return -ENXIO); 565 if (snd_BUG_ON(!s))
566 return -ENXIO;
566 567
567 spin_lock(&chip->reg_lock); 568 spin_lock(&chip->reg_lock);
568 switch (cmd) { 569 switch (cmd) {
@@ -599,7 +600,8 @@ snd_nm256_capture_trigger(struct snd_pcm_substream *substream, int cmd)
599 struct nm256_stream *s = substream->runtime->private_data; 600 struct nm256_stream *s = substream->runtime->private_data;
600 int err = 0; 601 int err = 0;
601 602
602 snd_assert(s != NULL, return -ENXIO); 603 if (snd_BUG_ON(!s))
604 return -ENXIO;
603 605
604 spin_lock(&chip->reg_lock); 606 spin_lock(&chip->reg_lock);
605 switch (cmd) { 607 switch (cmd) {
@@ -635,7 +637,8 @@ static int snd_nm256_pcm_prepare(struct snd_pcm_substream *substream)
635 struct snd_pcm_runtime *runtime = substream->runtime; 637 struct snd_pcm_runtime *runtime = substream->runtime;
636 struct nm256_stream *s = runtime->private_data; 638 struct nm256_stream *s = runtime->private_data;
637 639
638 snd_assert(s, return -ENXIO); 640 if (snd_BUG_ON(!s))
641 return -ENXIO;
639 s->dma_size = frames_to_bytes(runtime, substream->runtime->buffer_size); 642 s->dma_size = frames_to_bytes(runtime, substream->runtime->buffer_size);
640 s->period_size = frames_to_bytes(runtime, substream->runtime->period_size); 643 s->period_size = frames_to_bytes(runtime, substream->runtime->period_size);
641 s->periods = substream->runtime->periods; 644 s->periods = substream->runtime->periods;
@@ -660,7 +663,8 @@ snd_nm256_playback_pointer(struct snd_pcm_substream *substream)
660 struct nm256_stream *s = substream->runtime->private_data; 663 struct nm256_stream *s = substream->runtime->private_data;
661 unsigned long curp; 664 unsigned long curp;
662 665
663 snd_assert(s, return 0); 666 if (snd_BUG_ON(!s))
667 return 0;
664 curp = snd_nm256_readl(chip, NM_PBUFFER_CURRP) - (unsigned long)s->buf; 668 curp = snd_nm256_readl(chip, NM_PBUFFER_CURRP) - (unsigned long)s->buf;
665 curp %= s->dma_size; 669 curp %= s->dma_size;
666 return bytes_to_frames(substream->runtime, curp); 670 return bytes_to_frames(substream->runtime, curp);
@@ -673,7 +677,8 @@ snd_nm256_capture_pointer(struct snd_pcm_substream *substream)
673 struct nm256_stream *s = substream->runtime->private_data; 677 struct nm256_stream *s = substream->runtime->private_data;
674 unsigned long curp; 678 unsigned long curp;
675 679
676 snd_assert(s != NULL, return 0); 680 if (snd_BUG_ON(!s))
681 return 0;
677 curp = snd_nm256_readl(chip, NM_RBUFFER_CURRP) - (unsigned long)s->buf; 682 curp = snd_nm256_readl(chip, NM_RBUFFER_CURRP) - (unsigned long)s->buf;
678 curp %= s->dma_size; 683 curp %= s->dma_size;
679 return bytes_to_frames(substream->runtime, curp); 684 return bytes_to_frames(substream->runtime, curp);
diff --git a/sound/pci/oxygen/hifier.c b/sound/pci/oxygen/hifier.c
index dad393ae040a..1ab833f843eb 100644
--- a/sound/pci/oxygen/hifier.c
+++ b/sound/pci/oxygen/hifier.c
@@ -94,6 +94,11 @@ static void hifier_cleanup(struct oxygen *chip)
94{ 94{
95} 95}
96 96
97static void hifier_resume(struct oxygen *chip)
98{
99 hifier_registers_init(chip);
100}
101
97static void set_ak4396_params(struct oxygen *chip, 102static void set_ak4396_params(struct oxygen *chip,
98 struct snd_pcm_hw_params *params) 103 struct snd_pcm_hw_params *params)
99{ 104{
@@ -150,16 +155,16 @@ static const struct oxygen_model model_hifier = {
150 .init = hifier_init, 155 .init = hifier_init,
151 .control_filter = hifier_control_filter, 156 .control_filter = hifier_control_filter,
152 .cleanup = hifier_cleanup, 157 .cleanup = hifier_cleanup,
153 .resume = hifier_registers_init, 158 .resume = hifier_resume,
154 .set_dac_params = set_ak4396_params, 159 .set_dac_params = set_ak4396_params,
155 .set_adc_params = set_cs5340_params, 160 .set_adc_params = set_cs5340_params,
156 .update_dac_volume = update_ak4396_volume, 161 .update_dac_volume = update_ak4396_volume,
157 .update_dac_mute = update_ak4396_mute, 162 .update_dac_mute = update_ak4396_mute,
158 .dac_tlv = ak4396_db_scale, 163 .dac_tlv = ak4396_db_scale,
159 .model_data_size = sizeof(struct hifier_data), 164 .model_data_size = sizeof(struct hifier_data),
160 .pcm_dev_cfg = PLAYBACK_0_TO_I2S | 165 .device_config = PLAYBACK_0_TO_I2S |
161 PLAYBACK_1_TO_SPDIF | 166 PLAYBACK_1_TO_SPDIF |
162 CAPTURE_0_FROM_I2S_1, 167 CAPTURE_0_FROM_I2S_1,
163 .dac_channels = 2, 168 .dac_channels = 2,
164 .dac_volume_min = 0, 169 .dac_volume_min = 0,
165 .dac_volume_max = 255, 170 .dac_volume_max = 255,
@@ -180,7 +185,7 @@ static int __devinit hifier_probe(struct pci_dev *pci,
180 ++dev; 185 ++dev;
181 return -ENOENT; 186 return -ENOENT;
182 } 187 }
183 err = oxygen_pci_probe(pci, index[dev], id[dev], &model_hifier); 188 err = oxygen_pci_probe(pci, index[dev], id[dev], &model_hifier, 0);
184 if (err >= 0) 189 if (err >= 0)
185 ++dev; 190 ++dev;
186 return err; 191 return err;
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c
index c5829d30ef86..b60f6212745a 100644
--- a/sound/pci/oxygen/oxygen.c
+++ b/sound/pci/oxygen/oxygen.c
@@ -58,17 +58,22 @@ MODULE_PARM_DESC(id, "ID string");
58module_param_array(enable, bool, NULL, 0444); 58module_param_array(enable, bool, NULL, 0444);
59MODULE_PARM_DESC(enable, "enable card"); 59MODULE_PARM_DESC(enable, "enable card");
60 60
61enum {
62 MODEL_CMEDIA_REF, /* C-Media's reference design */
63 MODEL_MERIDIAN, /* AuzenTech X-Meridian */
64};
65
61static struct pci_device_id oxygen_ids[] __devinitdata = { 66static struct pci_device_id oxygen_ids[] __devinitdata = {
62 { OXYGEN_PCI_SUBID(0x10b0, 0x0216) }, 67 { OXYGEN_PCI_SUBID(0x10b0, 0x0216), .driver_data = MODEL_CMEDIA_REF },
63 { OXYGEN_PCI_SUBID(0x10b0, 0x0218) }, 68 { OXYGEN_PCI_SUBID(0x10b0, 0x0218), .driver_data = MODEL_CMEDIA_REF },
64 { OXYGEN_PCI_SUBID(0x10b0, 0x0219) }, 69 { OXYGEN_PCI_SUBID(0x10b0, 0x0219), .driver_data = MODEL_CMEDIA_REF },
65 { OXYGEN_PCI_SUBID(0x13f6, 0x0001) }, 70 { OXYGEN_PCI_SUBID(0x13f6, 0x0001), .driver_data = MODEL_CMEDIA_REF },
66 { OXYGEN_PCI_SUBID(0x13f6, 0x0010) }, 71 { OXYGEN_PCI_SUBID(0x13f6, 0x0010), .driver_data = MODEL_CMEDIA_REF },
67 { OXYGEN_PCI_SUBID(0x13f6, 0x8788) }, 72 { OXYGEN_PCI_SUBID(0x13f6, 0x8788), .driver_data = MODEL_CMEDIA_REF },
68 { OXYGEN_PCI_SUBID(0x147a, 0xa017) }, 73 { OXYGEN_PCI_SUBID(0x147a, 0xa017), .driver_data = MODEL_CMEDIA_REF },
69 { OXYGEN_PCI_SUBID(0x1a58, 0x0910) }, 74 { OXYGEN_PCI_SUBID(0x1a58, 0x0910), .driver_data = MODEL_CMEDIA_REF },
70 { OXYGEN_PCI_SUBID(0x415a, 0x5431), .driver_data = 1 }, 75 { OXYGEN_PCI_SUBID(0x415a, 0x5431), .driver_data = MODEL_MERIDIAN },
71 { OXYGEN_PCI_SUBID(0x7284, 0x9761) }, 76 { OXYGEN_PCI_SUBID(0x7284, 0x9761), .driver_data = MODEL_CMEDIA_REF },
72 { } 77 { }
73}; 78};
74MODULE_DEVICE_TABLE(pci, oxygen_ids); 79MODULE_DEVICE_TABLE(pci, oxygen_ids);
@@ -199,6 +204,11 @@ static void generic_resume(struct oxygen *chip)
199 wm8785_registers_init(chip); 204 wm8785_registers_init(chip);
200} 205}
201 206
207static void meridian_resume(struct oxygen *chip)
208{
209 ak4396_registers_init(chip);
210}
211
202static void set_ak4396_params(struct oxygen *chip, 212static void set_ak4396_params(struct oxygen *chip,
203 struct snd_pcm_hw_params *params) 213 struct snd_pcm_hw_params *params)
204{ 214{
@@ -281,11 +291,28 @@ static void set_ak5385_params(struct oxygen *chip,
281 291
282static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0); 292static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0);
283 293
294static int generic_probe(struct oxygen *chip, unsigned long driver_data)
295{
296 if (driver_data == MODEL_MERIDIAN) {
297 chip->model.init = meridian_init;
298 chip->model.resume = meridian_resume;
299 chip->model.set_adc_params = set_ak5385_params;
300 chip->model.device_config = PLAYBACK_0_TO_I2S |
301 PLAYBACK_1_TO_SPDIF |
302 CAPTURE_0_FROM_I2S_2 |
303 CAPTURE_1_FROM_SPDIF;
304 chip->model.misc_flags = OXYGEN_MISC_MIDI;
305 chip->model.device_config |= MIDI_OUTPUT | MIDI_INPUT;
306 }
307 return 0;
308}
309
284static const struct oxygen_model model_generic = { 310static const struct oxygen_model model_generic = {
285 .shortname = "C-Media CMI8788", 311 .shortname = "C-Media CMI8788",
286 .longname = "C-Media Oxygen HD Audio", 312 .longname = "C-Media Oxygen HD Audio",
287 .chip = "CMI8788", 313 .chip = "CMI8788",
288 .owner = THIS_MODULE, 314 .owner = THIS_MODULE,
315 .probe = generic_probe,
289 .init = generic_init, 316 .init = generic_init,
290 .cleanup = generic_cleanup, 317 .cleanup = generic_cleanup,
291 .resume = generic_resume, 318 .resume = generic_resume,
@@ -295,44 +322,15 @@ static const struct oxygen_model model_generic = {
295 .update_dac_mute = update_ak4396_mute, 322 .update_dac_mute = update_ak4396_mute,
296 .dac_tlv = ak4396_db_scale, 323 .dac_tlv = ak4396_db_scale,
297 .model_data_size = sizeof(struct generic_data), 324 .model_data_size = sizeof(struct generic_data),
298 .pcm_dev_cfg = PLAYBACK_0_TO_I2S | 325 .device_config = PLAYBACK_0_TO_I2S |
299 PLAYBACK_1_TO_SPDIF | 326 PLAYBACK_1_TO_SPDIF |
300 PLAYBACK_2_TO_AC97_1 | 327 PLAYBACK_2_TO_AC97_1 |
301 CAPTURE_0_FROM_I2S_1 | 328 CAPTURE_0_FROM_I2S_1 |
302 CAPTURE_1_FROM_SPDIF | 329 CAPTURE_1_FROM_SPDIF |
303 CAPTURE_2_FROM_AC97_1, 330 CAPTURE_2_FROM_AC97_1,
304 .dac_channels = 8,
305 .dac_volume_min = 0,
306 .dac_volume_max = 255,
307 .function_flags = OXYGEN_FUNCTION_SPI |
308 OXYGEN_FUNCTION_ENABLE_SPI_4_5,
309 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
310 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
311};
312static const struct oxygen_model model_meridian = {
313 .shortname = "C-Media CMI8788",
314 .longname = "C-Media Oxygen HD Audio",
315 .chip = "CMI8788",
316 .owner = THIS_MODULE,
317 .init = meridian_init,
318 .cleanup = generic_cleanup,
319 .resume = ak4396_registers_init,
320 .set_dac_params = set_ak4396_params,
321 .set_adc_params = set_ak5385_params,
322 .update_dac_volume = update_ak4396_volume,
323 .update_dac_mute = update_ak4396_mute,
324 .dac_tlv = ak4396_db_scale,
325 .model_data_size = sizeof(struct generic_data),
326 .pcm_dev_cfg = PLAYBACK_0_TO_I2S |
327 PLAYBACK_1_TO_SPDIF |
328 PLAYBACK_2_TO_AC97_1 |
329 CAPTURE_0_FROM_I2S_2 |
330 CAPTURE_1_FROM_SPDIF |
331 CAPTURE_2_FROM_AC97_1,
332 .dac_channels = 8, 331 .dac_channels = 8,
333 .dac_volume_min = 0, 332 .dac_volume_min = 0,
334 .dac_volume_max = 255, 333 .dac_volume_max = 255,
335 .misc_flags = OXYGEN_MISC_MIDI,
336 .function_flags = OXYGEN_FUNCTION_SPI | 334 .function_flags = OXYGEN_FUNCTION_SPI |
337 OXYGEN_FUNCTION_ENABLE_SPI_4_5, 335 OXYGEN_FUNCTION_ENABLE_SPI_4_5,
338 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 336 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
@@ -343,7 +341,6 @@ static int __devinit generic_oxygen_probe(struct pci_dev *pci,
343 const struct pci_device_id *pci_id) 341 const struct pci_device_id *pci_id)
344{ 342{
345 static int dev; 343 static int dev;
346 int is_meridian;
347 int err; 344 int err;
348 345
349 if (dev >= SNDRV_CARDS) 346 if (dev >= SNDRV_CARDS)
@@ -352,9 +349,8 @@ static int __devinit generic_oxygen_probe(struct pci_dev *pci,
352 ++dev; 349 ++dev;
353 return -ENOENT; 350 return -ENOENT;
354 } 351 }
355 is_meridian = pci_id->driver_data;
356 err = oxygen_pci_probe(pci, index[dev], id[dev], 352 err = oxygen_pci_probe(pci, index[dev], id[dev],
357 is_meridian ? &model_meridian : &model_generic); 353 &model_generic, pci_id->driver_data);
358 if (err >= 0) 354 if (err >= 0)
359 ++dev; 355 ++dev;
360 return err; 356 return err;
diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h
index 74a644880074..19107c6307e5 100644
--- a/sound/pci/oxygen/oxygen.h
+++ b/sound/pci/oxygen/oxygen.h
@@ -19,14 +19,19 @@
19#define OXYGEN_IO_SIZE 0x100 19#define OXYGEN_IO_SIZE 0x100
20 20
21/* model-specific configuration of outputs/inputs */ 21/* model-specific configuration of outputs/inputs */
22#define PLAYBACK_0_TO_I2S 0x001 22#define PLAYBACK_0_TO_I2S 0x0001
23#define PLAYBACK_1_TO_SPDIF 0x004 23 /* PLAYBACK_0_TO_AC97_0 not implemented */
24#define PLAYBACK_2_TO_AC97_1 0x008 24#define PLAYBACK_1_TO_SPDIF 0x0004
25#define CAPTURE_0_FROM_I2S_1 0x010 25#define PLAYBACK_2_TO_AC97_1 0x0008
26#define CAPTURE_0_FROM_I2S_2 0x020 26#define CAPTURE_0_FROM_I2S_1 0x0010
27#define CAPTURE_1_FROM_SPDIF 0x080 27#define CAPTURE_0_FROM_I2S_2 0x0020
28#define CAPTURE_2_FROM_I2S_2 0x100 28 /* CAPTURE_0_FROM_AC97_0 not implemented */
29#define CAPTURE_2_FROM_AC97_1 0x200 29#define CAPTURE_1_FROM_SPDIF 0x0080
30#define CAPTURE_2_FROM_I2S_2 0x0100
31#define CAPTURE_2_FROM_AC97_1 0x0200
32 /* CAPTURE_3_FROM_I2S_3 not implemented */
33#define MIDI_OUTPUT 0x0800
34#define MIDI_INPUT 0x1000
30 35
31enum { 36enum {
32 CONTROL_SPDIF_PCM, 37 CONTROL_SPDIF_PCM,
@@ -51,7 +56,43 @@ struct snd_pcm_hardware;
51struct snd_pcm_hw_params; 56struct snd_pcm_hw_params;
52struct snd_kcontrol_new; 57struct snd_kcontrol_new;
53struct snd_rawmidi; 58struct snd_rawmidi;
54struct oxygen_model; 59struct oxygen;
60
61struct oxygen_model {
62 const char *shortname;
63 const char *longname;
64 const char *chip;
65 struct module *owner;
66 int (*probe)(struct oxygen *chip, unsigned long driver_data);
67 void (*init)(struct oxygen *chip);
68 int (*control_filter)(struct snd_kcontrol_new *template);
69 int (*mixer_init)(struct oxygen *chip);
70 void (*cleanup)(struct oxygen *chip);
71 void (*suspend)(struct oxygen *chip);
72 void (*resume)(struct oxygen *chip);
73 void (*pcm_hardware_filter)(unsigned int channel,
74 struct snd_pcm_hardware *hardware);
75 void (*set_dac_params)(struct oxygen *chip,
76 struct snd_pcm_hw_params *params);
77 void (*set_adc_params)(struct oxygen *chip,
78 struct snd_pcm_hw_params *params);
79 void (*update_dac_volume)(struct oxygen *chip);
80 void (*update_dac_mute)(struct oxygen *chip);
81 void (*gpio_changed)(struct oxygen *chip);
82 void (*uart_input)(struct oxygen *chip);
83 void (*ac97_switch)(struct oxygen *chip,
84 unsigned int reg, unsigned int mute);
85 const unsigned int *dac_tlv;
86 size_t model_data_size;
87 unsigned int device_config;
88 u8 dac_channels;
89 u8 dac_volume_min;
90 u8 dac_volume_max;
91 u8 misc_flags;
92 u8 function_flags;
93 u16 dac_i2s_format;
94 u16 adc_i2s_format;
95};
55 96
56struct oxygen { 97struct oxygen {
57 unsigned long addr; 98 unsigned long addr;
@@ -61,7 +102,6 @@ struct oxygen {
61 struct pci_dev *pci; 102 struct pci_dev *pci;
62 struct snd_rawmidi *midi; 103 struct snd_rawmidi *midi;
63 int irq; 104 int irq;
64 const struct oxygen_model *model;
65 void *model_data; 105 void *model_data;
66 unsigned int interrupt_mask; 106 unsigned int interrupt_mask;
67 u8 dac_volume[8]; 107 u8 dac_volume[8];
@@ -86,46 +126,16 @@ struct oxygen {
86 __le32 _32[OXYGEN_IO_SIZE / 4]; 126 __le32 _32[OXYGEN_IO_SIZE / 4];
87 } saved_registers; 127 } saved_registers;
88 u16 saved_ac97_registers[2][0x40]; 128 u16 saved_ac97_registers[2][0x40];
89}; 129 unsigned int uart_input_count;
90 130 u8 uart_input[32];
91struct oxygen_model { 131 struct oxygen_model model;
92 const char *shortname;
93 const char *longname;
94 const char *chip;
95 struct module *owner;
96 void (*init)(struct oxygen *chip);
97 int (*control_filter)(struct snd_kcontrol_new *template);
98 int (*mixer_init)(struct oxygen *chip);
99 void (*cleanup)(struct oxygen *chip);
100 void (*suspend)(struct oxygen *chip);
101 void (*resume)(struct oxygen *chip);
102 void (*pcm_hardware_filter)(unsigned int channel,
103 struct snd_pcm_hardware *hardware);
104 void (*set_dac_params)(struct oxygen *chip,
105 struct snd_pcm_hw_params *params);
106 void (*set_adc_params)(struct oxygen *chip,
107 struct snd_pcm_hw_params *params);
108 void (*update_dac_volume)(struct oxygen *chip);
109 void (*update_dac_mute)(struct oxygen *chip);
110 void (*gpio_changed)(struct oxygen *chip);
111 void (*ac97_switch)(struct oxygen *chip,
112 unsigned int reg, unsigned int mute);
113 const unsigned int *dac_tlv;
114 size_t model_data_size;
115 unsigned int pcm_dev_cfg;
116 u8 dac_channels;
117 u8 dac_volume_min;
118 u8 dac_volume_max;
119 u8 misc_flags;
120 u8 function_flags;
121 u16 dac_i2s_format;
122 u16 adc_i2s_format;
123}; 132};
124 133
125/* oxygen_lib.c */ 134/* oxygen_lib.c */
126 135
127int oxygen_pci_probe(struct pci_dev *pci, int index, char *id, 136int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
128 const struct oxygen_model *model); 137 const struct oxygen_model *model,
138 unsigned long driver_data);
129void oxygen_pci_remove(struct pci_dev *pci); 139void oxygen_pci_remove(struct pci_dev *pci);
130#ifdef CONFIG_PM 140#ifdef CONFIG_PM
131int oxygen_pci_suspend(struct pci_dev *pci, pm_message_t state); 141int oxygen_pci_suspend(struct pci_dev *pci, pm_message_t state);
@@ -167,6 +177,9 @@ void oxygen_write_ac97_masked(struct oxygen *chip, unsigned int codec,
167void oxygen_write_spi(struct oxygen *chip, u8 control, unsigned int data); 177void oxygen_write_spi(struct oxygen *chip, u8 control, unsigned int data);
168void oxygen_write_i2c(struct oxygen *chip, u8 device, u8 map, u8 data); 178void oxygen_write_i2c(struct oxygen *chip, u8 device, u8 map, u8 data);
169 179
180void oxygen_reset_uart(struct oxygen *chip);
181void oxygen_write_uart(struct oxygen *chip, u8 data);
182
170static inline void oxygen_set_bits8(struct oxygen *chip, 183static inline void oxygen_set_bits8(struct oxygen *chip,
171 unsigned int reg, u8 value) 184 unsigned int reg, u8 value)
172{ 185{
diff --git a/sound/pci/oxygen/oxygen_io.c b/sound/pci/oxygen/oxygen_io.c
index 83f135f80df4..3126c4b403dd 100644
--- a/sound/pci/oxygen/oxygen_io.c
+++ b/sound/pci/oxygen/oxygen_io.c
@@ -20,6 +20,7 @@
20#include <linux/delay.h> 20#include <linux/delay.h>
21#include <linux/sched.h> 21#include <linux/sched.h>
22#include <sound/core.h> 22#include <sound/core.h>
23#include <sound/mpu401.h>
23#include <asm/io.h> 24#include <asm/io.h>
24#include "oxygen.h" 25#include "oxygen.h"
25 26
@@ -232,3 +233,24 @@ void oxygen_write_i2c(struct oxygen *chip, u8 device, u8 map, u8 data)
232 device | OXYGEN_2WIRE_DIR_WRITE); 233 device | OXYGEN_2WIRE_DIR_WRITE);
233} 234}
234EXPORT_SYMBOL(oxygen_write_i2c); 235EXPORT_SYMBOL(oxygen_write_i2c);
236
237static void _write_uart(struct oxygen *chip, unsigned int port, u8 data)
238{
239 if (oxygen_read8(chip, OXYGEN_MPU401 + 1) & MPU401_TX_FULL)
240 msleep(1);
241 oxygen_write8(chip, OXYGEN_MPU401 + port, data);
242}
243
244void oxygen_reset_uart(struct oxygen *chip)
245{
246 _write_uart(chip, 1, MPU401_RESET);
247 msleep(1); /* wait for ACK */
248 _write_uart(chip, 1, MPU401_ENTER_UART);
249}
250EXPORT_SYMBOL(oxygen_reset_uart);
251
252void oxygen_write_uart(struct oxygen *chip, u8 data)
253{
254 _write_uart(chip, 0, data);
255}
256EXPORT_SYMBOL(oxygen_write_uart);
diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c
index 22f37851045e..84f481d41efa 100644
--- a/sound/pci/oxygen/oxygen_lib.c
+++ b/sound/pci/oxygen/oxygen_lib.c
@@ -35,6 +35,30 @@ MODULE_DESCRIPTION("C-Media CMI8788 helper library");
35MODULE_LICENSE("GPL v2"); 35MODULE_LICENSE("GPL v2");
36 36
37 37
38static inline int oxygen_uart_input_ready(struct oxygen *chip)
39{
40 return !(oxygen_read8(chip, OXYGEN_MPU401 + 1) & MPU401_RX_EMPTY);
41}
42
43static void oxygen_read_uart(struct oxygen *chip)
44{
45 if (unlikely(!oxygen_uart_input_ready(chip))) {
46 /* no data, but read it anyway to clear the interrupt */
47 oxygen_read8(chip, OXYGEN_MPU401);
48 return;
49 }
50 do {
51 u8 data = oxygen_read8(chip, OXYGEN_MPU401);
52 if (data == MPU401_ACK)
53 continue;
54 if (chip->uart_input_count >= ARRAY_SIZE(chip->uart_input))
55 chip->uart_input_count = 0;
56 chip->uart_input[chip->uart_input_count++] = data;
57 } while (oxygen_uart_input_ready(chip));
58 if (chip->model.uart_input)
59 chip->model.uart_input(chip);
60}
61
38static irqreturn_t oxygen_interrupt(int dummy, void *dev_id) 62static irqreturn_t oxygen_interrupt(int dummy, void *dev_id)
39{ 63{
40 struct oxygen *chip = dev_id; 64 struct oxygen *chip = dev_id;
@@ -87,8 +111,12 @@ static irqreturn_t oxygen_interrupt(int dummy, void *dev_id)
87 if (status & OXYGEN_INT_GPIO) 111 if (status & OXYGEN_INT_GPIO)
88 schedule_work(&chip->gpio_work); 112 schedule_work(&chip->gpio_work);
89 113
90 if ((status & OXYGEN_INT_MIDI) && chip->midi) 114 if (status & OXYGEN_INT_MIDI) {
91 snd_mpu401_uart_interrupt(0, chip->midi->private_data); 115 if (chip->midi)
116 snd_mpu401_uart_interrupt(0, chip->midi->private_data);
117 else
118 oxygen_read_uart(chip);
119 }
92 120
93 if (status & OXYGEN_INT_AC97) 121 if (status & OXYGEN_INT_AC97)
94 wake_up(&chip->ac97_waitqueue); 122 wake_up(&chip->ac97_waitqueue);
@@ -161,8 +189,8 @@ static void oxygen_gpio_changed(struct work_struct *work)
161{ 189{
162 struct oxygen *chip = container_of(work, struct oxygen, gpio_work); 190 struct oxygen *chip = container_of(work, struct oxygen, gpio_work);
163 191
164 if (chip->model->gpio_changed) 192 if (chip->model.gpio_changed)
165 chip->model->gpio_changed(chip); 193 chip->model.gpio_changed(chip);
166} 194}
167 195
168#ifdef CONFIG_PROC_FS 196#ifdef CONFIG_PROC_FS
@@ -221,7 +249,7 @@ static void oxygen_init(struct oxygen *chip)
221 249
222 chip->dac_routing = 1; 250 chip->dac_routing = 1;
223 for (i = 0; i < 8; ++i) 251 for (i = 0; i < 8; ++i)
224 chip->dac_volume[i] = chip->model->dac_volume_min; 252 chip->dac_volume[i] = chip->model.dac_volume_min;
225 chip->dac_mute = 1; 253 chip->dac_mute = 1;
226 chip->spdif_playback_enable = 1; 254 chip->spdif_playback_enable = 1;
227 chip->spdif_bits = OXYGEN_SPDIF_C | OXYGEN_SPDIF_ORIGINAL | 255 chip->spdif_bits = OXYGEN_SPDIF_C | OXYGEN_SPDIF_ORIGINAL |
@@ -243,7 +271,7 @@ static void oxygen_init(struct oxygen *chip)
243 271
244 oxygen_write8_masked(chip, OXYGEN_FUNCTION, 272 oxygen_write8_masked(chip, OXYGEN_FUNCTION,
245 OXYGEN_FUNCTION_RESET_CODEC | 273 OXYGEN_FUNCTION_RESET_CODEC |
246 chip->model->function_flags, 274 chip->model.function_flags,
247 OXYGEN_FUNCTION_RESET_CODEC | 275 OXYGEN_FUNCTION_RESET_CODEC |
248 OXYGEN_FUNCTION_2WIRE_SPI_MASK | 276 OXYGEN_FUNCTION_2WIRE_SPI_MASK |
249 OXYGEN_FUNCTION_ENABLE_SPI_4_5); 277 OXYGEN_FUNCTION_ENABLE_SPI_4_5);
@@ -255,7 +283,7 @@ static void oxygen_init(struct oxygen *chip)
255 OXYGEN_DMA_MULTICH_BURST_8); 283 OXYGEN_DMA_MULTICH_BURST_8);
256 oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, 0); 284 oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, 0);
257 oxygen_write8_masked(chip, OXYGEN_MISC, 285 oxygen_write8_masked(chip, OXYGEN_MISC,
258 chip->model->misc_flags, 286 chip->model.misc_flags,
259 OXYGEN_MISC_WRITE_PCI_SUBID | 287 OXYGEN_MISC_WRITE_PCI_SUBID |
260 OXYGEN_MISC_REC_C_FROM_SPDIF | 288 OXYGEN_MISC_REC_C_FROM_SPDIF |
261 OXYGEN_MISC_REC_B_FROM_AC97 | 289 OXYGEN_MISC_REC_B_FROM_AC97 |
@@ -270,21 +298,21 @@ static void oxygen_init(struct oxygen *chip)
270 (OXYGEN_FORMAT_16 << OXYGEN_MULTICH_FORMAT_SHIFT)); 298 (OXYGEN_FORMAT_16 << OXYGEN_MULTICH_FORMAT_SHIFT));
271 oxygen_write8(chip, OXYGEN_REC_CHANNELS, OXYGEN_REC_CHANNELS_2_2_2); 299 oxygen_write8(chip, OXYGEN_REC_CHANNELS, OXYGEN_REC_CHANNELS_2_2_2);
272 oxygen_write16(chip, OXYGEN_I2S_MULTICH_FORMAT, 300 oxygen_write16(chip, OXYGEN_I2S_MULTICH_FORMAT,
273 OXYGEN_RATE_48000 | chip->model->dac_i2s_format | 301 OXYGEN_RATE_48000 | chip->model.dac_i2s_format |
274 OXYGEN_I2S_MCLK_256 | OXYGEN_I2S_BITS_16 | 302 OXYGEN_I2S_MCLK_256 | OXYGEN_I2S_BITS_16 |
275 OXYGEN_I2S_MASTER | OXYGEN_I2S_BCLK_64); 303 OXYGEN_I2S_MASTER | OXYGEN_I2S_BCLK_64);
276 if (chip->model->pcm_dev_cfg & CAPTURE_0_FROM_I2S_1) 304 if (chip->model.device_config & CAPTURE_0_FROM_I2S_1)
277 oxygen_write16(chip, OXYGEN_I2S_A_FORMAT, 305 oxygen_write16(chip, OXYGEN_I2S_A_FORMAT,
278 OXYGEN_RATE_48000 | chip->model->adc_i2s_format | 306 OXYGEN_RATE_48000 | chip->model.adc_i2s_format |
279 OXYGEN_I2S_MCLK_256 | OXYGEN_I2S_BITS_16 | 307 OXYGEN_I2S_MCLK_256 | OXYGEN_I2S_BITS_16 |
280 OXYGEN_I2S_MASTER | OXYGEN_I2S_BCLK_64); 308 OXYGEN_I2S_MASTER | OXYGEN_I2S_BCLK_64);
281 else 309 else
282 oxygen_write16(chip, OXYGEN_I2S_A_FORMAT, 310 oxygen_write16(chip, OXYGEN_I2S_A_FORMAT,
283 OXYGEN_I2S_MASTER | OXYGEN_I2S_MUTE_MCLK); 311 OXYGEN_I2S_MASTER | OXYGEN_I2S_MUTE_MCLK);
284 if (chip->model->pcm_dev_cfg & (CAPTURE_0_FROM_I2S_2 | 312 if (chip->model.device_config & (CAPTURE_0_FROM_I2S_2 |
285 CAPTURE_2_FROM_I2S_2)) 313 CAPTURE_2_FROM_I2S_2))
286 oxygen_write16(chip, OXYGEN_I2S_B_FORMAT, 314 oxygen_write16(chip, OXYGEN_I2S_B_FORMAT,
287 OXYGEN_RATE_48000 | chip->model->adc_i2s_format | 315 OXYGEN_RATE_48000 | chip->model.adc_i2s_format |
288 OXYGEN_I2S_MCLK_256 | OXYGEN_I2S_BITS_16 | 316 OXYGEN_I2S_MCLK_256 | OXYGEN_I2S_BITS_16 |
289 OXYGEN_I2S_MASTER | OXYGEN_I2S_BCLK_64); 317 OXYGEN_I2S_MASTER | OXYGEN_I2S_BCLK_64);
290 else 318 else
@@ -295,7 +323,7 @@ static void oxygen_init(struct oxygen *chip)
295 oxygen_clear_bits32(chip, OXYGEN_SPDIF_CONTROL, 323 oxygen_clear_bits32(chip, OXYGEN_SPDIF_CONTROL,
296 OXYGEN_SPDIF_OUT_ENABLE | 324 OXYGEN_SPDIF_OUT_ENABLE |
297 OXYGEN_SPDIF_LOOPBACK); 325 OXYGEN_SPDIF_LOOPBACK);
298 if (chip->model->pcm_dev_cfg & CAPTURE_1_FROM_SPDIF) 326 if (chip->model.device_config & CAPTURE_1_FROM_SPDIF)
299 oxygen_write32_masked(chip, OXYGEN_SPDIF_CONTROL, 327 oxygen_write32_masked(chip, OXYGEN_SPDIF_CONTROL,
300 OXYGEN_SPDIF_SENSE_MASK | 328 OXYGEN_SPDIF_SENSE_MASK |
301 OXYGEN_SPDIF_LOCK_MASK | 329 OXYGEN_SPDIF_LOCK_MASK |
@@ -417,14 +445,15 @@ static void oxygen_card_free(struct snd_card *card)
417 if (chip->irq >= 0) 445 if (chip->irq >= 0)
418 free_irq(chip->irq, chip); 446 free_irq(chip->irq, chip);
419 flush_scheduled_work(); 447 flush_scheduled_work();
420 chip->model->cleanup(chip); 448 chip->model.cleanup(chip);
421 mutex_destroy(&chip->mutex); 449 mutex_destroy(&chip->mutex);
422 pci_release_regions(chip->pci); 450 pci_release_regions(chip->pci);
423 pci_disable_device(chip->pci); 451 pci_disable_device(chip->pci);
424} 452}
425 453
426int oxygen_pci_probe(struct pci_dev *pci, int index, char *id, 454int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
427 const struct oxygen_model *model) 455 const struct oxygen_model *model,
456 unsigned long driver_data)
428{ 457{
429 struct snd_card *card; 458 struct snd_card *card;
430 struct oxygen *chip; 459 struct oxygen *chip;
@@ -439,7 +468,7 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
439 chip->card = card; 468 chip->card = card;
440 chip->pci = pci; 469 chip->pci = pci;
441 chip->irq = -1; 470 chip->irq = -1;
442 chip->model = model; 471 chip->model = *model;
443 chip->model_data = chip + 1; 472 chip->model_data = chip + 1;
444 spin_lock_init(&chip->reg_lock); 473 spin_lock_init(&chip->reg_lock);
445 mutex_init(&chip->mutex); 474 mutex_init(&chip->mutex);
@@ -470,23 +499,28 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
470 snd_card_set_dev(card, &pci->dev); 499 snd_card_set_dev(card, &pci->dev);
471 card->private_free = oxygen_card_free; 500 card->private_free = oxygen_card_free;
472 501
502 if (chip->model.probe) {
503 err = chip->model.probe(chip, driver_data);
504 if (err < 0)
505 goto err_card;
506 }
473 oxygen_init(chip); 507 oxygen_init(chip);
474 model->init(chip); 508 chip->model.init(chip);
475 509
476 err = request_irq(pci->irq, oxygen_interrupt, IRQF_SHARED, 510 err = request_irq(pci->irq, oxygen_interrupt, IRQF_SHARED,
477 model->chip, chip); 511 chip->model.chip, chip);
478 if (err < 0) { 512 if (err < 0) {
479 snd_printk(KERN_ERR "cannot grab interrupt %d\n", pci->irq); 513 snd_printk(KERN_ERR "cannot grab interrupt %d\n", pci->irq);
480 goto err_card; 514 goto err_card;
481 } 515 }
482 chip->irq = pci->irq; 516 chip->irq = pci->irq;
483 517
484 strcpy(card->driver, model->chip); 518 strcpy(card->driver, chip->model.chip);
485 strcpy(card->shortname, model->shortname); 519 strcpy(card->shortname, chip->model.shortname);
486 sprintf(card->longname, "%s (rev %u) at %#lx, irq %i", 520 sprintf(card->longname, "%s (rev %u) at %#lx, irq %i",
487 model->longname, chip->revision, chip->addr, chip->irq); 521 chip->model.longname, chip->revision, chip->addr, chip->irq);
488 strcpy(card->mixername, model->chip); 522 strcpy(card->mixername, chip->model.chip);
489 snd_component_add(card, model->chip); 523 snd_component_add(card, chip->model.chip);
490 524
491 err = oxygen_pcm_init(chip); 525 err = oxygen_pcm_init(chip);
492 if (err < 0) 526 if (err < 0)
@@ -496,10 +530,15 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
496 if (err < 0) 530 if (err < 0)
497 goto err_card; 531 goto err_card;
498 532
499 if (model->misc_flags & OXYGEN_MISC_MIDI) { 533 if (chip->model.device_config & (MIDI_OUTPUT | MIDI_INPUT)) {
534 unsigned int info_flags = MPU401_INFO_INTEGRATED;
535 if (chip->model.device_config & MIDI_OUTPUT)
536 info_flags |= MPU401_INFO_OUTPUT;
537 if (chip->model.device_config & MIDI_INPUT)
538 info_flags |= MPU401_INFO_INPUT;
500 err = snd_mpu401_uart_new(card, 0, MPU401_HW_CMIPCI, 539 err = snd_mpu401_uart_new(card, 0, MPU401_HW_CMIPCI,
501 chip->addr + OXYGEN_MPU401, 540 chip->addr + OXYGEN_MPU401,
502 MPU401_INFO_INTEGRATED, 0, 0, 541 info_flags, 0, 0,
503 &chip->midi); 542 &chip->midi);
504 if (err < 0) 543 if (err < 0)
505 goto err_card; 544 goto err_card;
@@ -508,7 +547,7 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
508 oxygen_proc_init(chip); 547 oxygen_proc_init(chip);
509 548
510 spin_lock_irq(&chip->reg_lock); 549 spin_lock_irq(&chip->reg_lock);
511 if (chip->model->pcm_dev_cfg & CAPTURE_1_FROM_SPDIF) 550 if (chip->model.device_config & CAPTURE_1_FROM_SPDIF)
512 chip->interrupt_mask |= OXYGEN_INT_SPDIF_IN_DETECT; 551 chip->interrupt_mask |= OXYGEN_INT_SPDIF_IN_DETECT;
513 if (chip->has_ac97_0 | chip->has_ac97_1) 552 if (chip->has_ac97_0 | chip->has_ac97_1)
514 chip->interrupt_mask |= OXYGEN_INT_AC97; 553 chip->interrupt_mask |= OXYGEN_INT_AC97;
@@ -552,8 +591,8 @@ int oxygen_pci_suspend(struct pci_dev *pci, pm_message_t state)
552 if (chip->streams[i]) 591 if (chip->streams[i])
553 snd_pcm_suspend(chip->streams[i]); 592 snd_pcm_suspend(chip->streams[i]);
554 593
555 if (chip->model->suspend) 594 if (chip->model.suspend)
556 chip->model->suspend(chip); 595 chip->model.suspend(chip);
557 596
558 spin_lock_irq(&chip->reg_lock); 597 spin_lock_irq(&chip->reg_lock);
559 saved_interrupt_mask = chip->interrupt_mask; 598 saved_interrupt_mask = chip->interrupt_mask;
@@ -624,8 +663,8 @@ int oxygen_pci_resume(struct pci_dev *pci)
624 if (chip->has_ac97_1) 663 if (chip->has_ac97_1)
625 oxygen_restore_ac97(chip, 1); 664 oxygen_restore_ac97(chip, 1);
626 665
627 if (chip->model->resume) 666 if (chip->model.resume)
628 chip->model->resume(chip); 667 chip->model.resume(chip);
629 668
630 oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, chip->interrupt_mask); 669 oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, chip->interrupt_mask);
631 670
diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c
index 05eb8994c141..304da169bfdc 100644
--- a/sound/pci/oxygen/oxygen_mixer.c
+++ b/sound/pci/oxygen/oxygen_mixer.c
@@ -31,9 +31,9 @@ static int dac_volume_info(struct snd_kcontrol *ctl,
31 struct oxygen *chip = ctl->private_data; 31 struct oxygen *chip = ctl->private_data;
32 32
33 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 33 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
34 info->count = chip->model->dac_channels; 34 info->count = chip->model.dac_channels;
35 info->value.integer.min = chip->model->dac_volume_min; 35 info->value.integer.min = chip->model.dac_volume_min;
36 info->value.integer.max = chip->model->dac_volume_max; 36 info->value.integer.max = chip->model.dac_volume_max;
37 return 0; 37 return 0;
38} 38}
39 39
@@ -44,7 +44,7 @@ static int dac_volume_get(struct snd_kcontrol *ctl,
44 unsigned int i; 44 unsigned int i;
45 45
46 mutex_lock(&chip->mutex); 46 mutex_lock(&chip->mutex);
47 for (i = 0; i < chip->model->dac_channels; ++i) 47 for (i = 0; i < chip->model.dac_channels; ++i)
48 value->value.integer.value[i] = chip->dac_volume[i]; 48 value->value.integer.value[i] = chip->dac_volume[i];
49 mutex_unlock(&chip->mutex); 49 mutex_unlock(&chip->mutex);
50 return 0; 50 return 0;
@@ -59,13 +59,13 @@ static int dac_volume_put(struct snd_kcontrol *ctl,
59 59
60 changed = 0; 60 changed = 0;
61 mutex_lock(&chip->mutex); 61 mutex_lock(&chip->mutex);
62 for (i = 0; i < chip->model->dac_channels; ++i) 62 for (i = 0; i < chip->model.dac_channels; ++i)
63 if (value->value.integer.value[i] != chip->dac_volume[i]) { 63 if (value->value.integer.value[i] != chip->dac_volume[i]) {
64 chip->dac_volume[i] = value->value.integer.value[i]; 64 chip->dac_volume[i] = value->value.integer.value[i];
65 changed = 1; 65 changed = 1;
66 } 66 }
67 if (changed) 67 if (changed)
68 chip->model->update_dac_volume(chip); 68 chip->model.update_dac_volume(chip);
69 mutex_unlock(&chip->mutex); 69 mutex_unlock(&chip->mutex);
70 return changed; 70 return changed;
71} 71}
@@ -91,7 +91,7 @@ static int dac_mute_put(struct snd_kcontrol *ctl,
91 changed = !value->value.integer.value[0] != chip->dac_mute; 91 changed = !value->value.integer.value[0] != chip->dac_mute;
92 if (changed) { 92 if (changed) {
93 chip->dac_mute = !value->value.integer.value[0]; 93 chip->dac_mute = !value->value.integer.value[0];
94 chip->model->update_dac_mute(chip); 94 chip->model.update_dac_mute(chip);
95 } 95 }
96 mutex_unlock(&chip->mutex); 96 mutex_unlock(&chip->mutex);
97 return changed; 97 return changed;
@@ -103,7 +103,7 @@ static int upmix_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info)
103 "Front", "Front+Surround", "Front+Surround+Back" 103 "Front", "Front+Surround", "Front+Surround+Back"
104 }; 104 };
105 struct oxygen *chip = ctl->private_data; 105 struct oxygen *chip = ctl->private_data;
106 unsigned int count = 2 + (chip->model->dac_channels == 8); 106 unsigned int count = 2 + (chip->model.dac_channels == 8);
107 107
108 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 108 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
109 info->count = 1; 109 info->count = 1;
@@ -172,7 +172,7 @@ void oxygen_update_dac_routing(struct oxygen *chip)
172static int upmix_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) 172static int upmix_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
173{ 173{
174 struct oxygen *chip = ctl->private_data; 174 struct oxygen *chip = ctl->private_data;
175 unsigned int count = 2 + (chip->model->dac_channels == 8); 175 unsigned int count = 2 + (chip->model.dac_channels == 8);
176 int changed; 176 int changed;
177 177
178 mutex_lock(&chip->mutex); 178 mutex_lock(&chip->mutex);
@@ -211,13 +211,13 @@ static unsigned int oxygen_spdif_rate(unsigned int oxygen_rate)
211 case OXYGEN_RATE_64000: 211 case OXYGEN_RATE_64000:
212 return 0xb << OXYGEN_SPDIF_CS_RATE_SHIFT; 212 return 0xb << OXYGEN_SPDIF_CS_RATE_SHIFT;
213 case OXYGEN_RATE_88200: 213 case OXYGEN_RATE_88200:
214 return 0x8 << OXYGEN_SPDIF_CS_RATE_SHIFT; 214 return IEC958_AES3_CON_FS_88200 << OXYGEN_SPDIF_CS_RATE_SHIFT;
215 case OXYGEN_RATE_96000: 215 case OXYGEN_RATE_96000:
216 return 0xa << OXYGEN_SPDIF_CS_RATE_SHIFT; 216 return IEC958_AES3_CON_FS_96000 << OXYGEN_SPDIF_CS_RATE_SHIFT;
217 case OXYGEN_RATE_176400: 217 case OXYGEN_RATE_176400:
218 return 0xc << OXYGEN_SPDIF_CS_RATE_SHIFT; 218 return IEC958_AES3_CON_FS_176400 << OXYGEN_SPDIF_CS_RATE_SHIFT;
219 case OXYGEN_RATE_192000: 219 case OXYGEN_RATE_192000:
220 return 0xe << OXYGEN_SPDIF_CS_RATE_SHIFT; 220 return IEC958_AES3_CON_FS_192000 << OXYGEN_SPDIF_CS_RATE_SHIFT;
221 } 221 }
222} 222}
223 223
@@ -521,8 +521,8 @@ static void mute_ac97_ctl(struct oxygen *chip, unsigned int control)
521 value = oxygen_read_ac97(chip, 0, priv_idx); 521 value = oxygen_read_ac97(chip, 0, priv_idx);
522 if (!(value & 0x8000)) { 522 if (!(value & 0x8000)) {
523 oxygen_write_ac97(chip, 0, priv_idx, value | 0x8000); 523 oxygen_write_ac97(chip, 0, priv_idx, value | 0x8000);
524 if (chip->model->ac97_switch) 524 if (chip->model.ac97_switch)
525 chip->model->ac97_switch(chip, priv_idx, 0x8000); 525 chip->model.ac97_switch(chip, priv_idx, 0x8000);
526 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, 526 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
527 &chip->controls[control]->id); 527 &chip->controls[control]->id);
528 } 528 }
@@ -549,8 +549,8 @@ static int ac97_switch_put(struct snd_kcontrol *ctl,
549 change = newreg != oldreg; 549 change = newreg != oldreg;
550 if (change) { 550 if (change) {
551 oxygen_write_ac97(chip, codec, index, newreg); 551 oxygen_write_ac97(chip, codec, index, newreg);
552 if (codec == 0 && chip->model->ac97_switch) 552 if (codec == 0 && chip->model.ac97_switch)
553 chip->model->ac97_switch(chip, index, newreg & 0x8000); 553 chip->model.ac97_switch(chip, index, newreg & 0x8000);
554 if (index == AC97_LINE) { 554 if (index == AC97_LINE) {
555 oxygen_write_ac97_masked(chip, 0, CM9780_GPIO_STATUS, 555 oxygen_write_ac97_masked(chip, 0, CM9780_GPIO_STATUS,
556 newreg & 0x8000 ? 556 newreg & 0x8000 ?
@@ -939,16 +939,16 @@ static int add_controls(struct oxygen *chip,
939 939
940 for (i = 0; i < count; ++i) { 940 for (i = 0; i < count; ++i) {
941 template = controls[i]; 941 template = controls[i];
942 if (chip->model->control_filter) { 942 if (chip->model.control_filter) {
943 err = chip->model->control_filter(&template); 943 err = chip->model.control_filter(&template);
944 if (err < 0) 944 if (err < 0)
945 return err; 945 return err;
946 if (err == 1) 946 if (err == 1)
947 continue; 947 continue;
948 } 948 }
949 if (!strcmp(template.name, "Master Playback Volume") && 949 if (!strcmp(template.name, "Master Playback Volume") &&
950 chip->model->dac_tlv) { 950 chip->model.dac_tlv) {
951 template.tlv.p = chip->model->dac_tlv; 951 template.tlv.p = chip->model.dac_tlv;
952 template.access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ; 952 template.access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
953 } 953 }
954 ctl = snd_ctl_new1(&template, chip); 954 ctl = snd_ctl_new1(&template, chip);
@@ -974,14 +974,14 @@ int oxygen_mixer_init(struct oxygen *chip)
974 err = add_controls(chip, controls, ARRAY_SIZE(controls)); 974 err = add_controls(chip, controls, ARRAY_SIZE(controls));
975 if (err < 0) 975 if (err < 0)
976 return err; 976 return err;
977 if (chip->model->pcm_dev_cfg & CAPTURE_1_FROM_SPDIF) { 977 if (chip->model.device_config & CAPTURE_1_FROM_SPDIF) {
978 err = add_controls(chip, spdif_input_controls, 978 err = add_controls(chip, spdif_input_controls,
979 ARRAY_SIZE(spdif_input_controls)); 979 ARRAY_SIZE(spdif_input_controls));
980 if (err < 0) 980 if (err < 0)
981 return err; 981 return err;
982 } 982 }
983 for (i = 0; i < ARRAY_SIZE(monitor_controls); ++i) { 983 for (i = 0; i < ARRAY_SIZE(monitor_controls); ++i) {
984 if (!(chip->model->pcm_dev_cfg & monitor_controls[i].pcm_dev)) 984 if (!(chip->model.device_config & monitor_controls[i].pcm_dev))
985 continue; 985 continue;
986 err = add_controls(chip, monitor_controls[i].controls, 986 err = add_controls(chip, monitor_controls[i].controls,
987 ARRAY_SIZE(monitor_controls[i].controls)); 987 ARRAY_SIZE(monitor_controls[i].controls));
@@ -1000,5 +1000,5 @@ int oxygen_mixer_init(struct oxygen *chip)
1000 if (err < 0) 1000 if (err < 0)
1001 return err; 1001 return err;
1002 } 1002 }
1003 return chip->model->mixer_init ? chip->model->mixer_init(chip) : 0; 1003 return chip->model.mixer_init ? chip->model.mixer_init(chip) : 0;
1004} 1004}
diff --git a/sound/pci/oxygen/oxygen_pcm.c b/sound/pci/oxygen/oxygen_pcm.c
index c4ad65a3406f..c262049961e1 100644
--- a/sound/pci/oxygen/oxygen_pcm.c
+++ b/sound/pci/oxygen/oxygen_pcm.c
@@ -129,7 +129,7 @@ static int oxygen_open(struct snd_pcm_substream *substream,
129 129
130 runtime->private_data = (void *)(uintptr_t)channel; 130 runtime->private_data = (void *)(uintptr_t)channel;
131 if (channel == PCM_B && chip->has_ac97_1 && 131 if (channel == PCM_B && chip->has_ac97_1 &&
132 (chip->model->pcm_dev_cfg & CAPTURE_2_FROM_AC97_1)) 132 (chip->model.device_config & CAPTURE_2_FROM_AC97_1))
133 runtime->hw = oxygen_ac97_hardware; 133 runtime->hw = oxygen_ac97_hardware;
134 else 134 else
135 runtime->hw = *oxygen_hardware[channel]; 135 runtime->hw = *oxygen_hardware[channel];
@@ -140,11 +140,11 @@ static int oxygen_open(struct snd_pcm_substream *substream,
140 runtime->hw.rate_min = 44100; 140 runtime->hw.rate_min = 44100;
141 break; 141 break;
142 case PCM_MULTICH: 142 case PCM_MULTICH:
143 runtime->hw.channels_max = chip->model->dac_channels; 143 runtime->hw.channels_max = chip->model.dac_channels;
144 break; 144 break;
145 } 145 }
146 if (chip->model->pcm_hardware_filter) 146 if (chip->model.pcm_hardware_filter)
147 chip->model->pcm_hardware_filter(channel, &runtime->hw); 147 chip->model.pcm_hardware_filter(channel, &runtime->hw);
148 err = snd_pcm_hw_constraint_step(runtime, 0, 148 err = snd_pcm_hw_constraint_step(runtime, 0,
149 SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32); 149 SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32);
150 if (err < 0) 150 if (err < 0)
@@ -355,7 +355,7 @@ static int oxygen_rec_a_hw_params(struct snd_pcm_substream *substream,
355 oxygen_write16_masked(chip, OXYGEN_I2S_A_FORMAT, 355 oxygen_write16_masked(chip, OXYGEN_I2S_A_FORMAT,
356 oxygen_rate(hw_params) | 356 oxygen_rate(hw_params) |
357 oxygen_i2s_mclk(hw_params) | 357 oxygen_i2s_mclk(hw_params) |
358 chip->model->adc_i2s_format | 358 chip->model.adc_i2s_format |
359 oxygen_i2s_bits(hw_params), 359 oxygen_i2s_bits(hw_params),
360 OXYGEN_I2S_RATE_MASK | 360 OXYGEN_I2S_RATE_MASK |
361 OXYGEN_I2S_FORMAT_MASK | 361 OXYGEN_I2S_FORMAT_MASK |
@@ -364,7 +364,7 @@ static int oxygen_rec_a_hw_params(struct snd_pcm_substream *substream,
364 spin_unlock_irq(&chip->reg_lock); 364 spin_unlock_irq(&chip->reg_lock);
365 365
366 mutex_lock(&chip->mutex); 366 mutex_lock(&chip->mutex);
367 chip->model->set_adc_params(chip, hw_params); 367 chip->model.set_adc_params(chip, hw_params);
368 mutex_unlock(&chip->mutex); 368 mutex_unlock(&chip->mutex);
369 return 0; 369 return 0;
370} 370}
@@ -381,7 +381,7 @@ static int oxygen_rec_b_hw_params(struct snd_pcm_substream *substream,
381 return err; 381 return err;
382 382
383 is_ac97 = chip->has_ac97_1 && 383 is_ac97 = chip->has_ac97_1 &&
384 (chip->model->pcm_dev_cfg & CAPTURE_2_FROM_AC97_1); 384 (chip->model.device_config & CAPTURE_2_FROM_AC97_1);
385 385
386 spin_lock_irq(&chip->reg_lock); 386 spin_lock_irq(&chip->reg_lock);
387 oxygen_write8_masked(chip, OXYGEN_REC_FORMAT, 387 oxygen_write8_masked(chip, OXYGEN_REC_FORMAT,
@@ -391,7 +391,7 @@ static int oxygen_rec_b_hw_params(struct snd_pcm_substream *substream,
391 oxygen_write16_masked(chip, OXYGEN_I2S_B_FORMAT, 391 oxygen_write16_masked(chip, OXYGEN_I2S_B_FORMAT,
392 oxygen_rate(hw_params) | 392 oxygen_rate(hw_params) |
393 oxygen_i2s_mclk(hw_params) | 393 oxygen_i2s_mclk(hw_params) |
394 chip->model->adc_i2s_format | 394 chip->model.adc_i2s_format |
395 oxygen_i2s_bits(hw_params), 395 oxygen_i2s_bits(hw_params),
396 OXYGEN_I2S_RATE_MASK | 396 OXYGEN_I2S_RATE_MASK |
397 OXYGEN_I2S_FORMAT_MASK | 397 OXYGEN_I2S_FORMAT_MASK |
@@ -401,7 +401,7 @@ static int oxygen_rec_b_hw_params(struct snd_pcm_substream *substream,
401 401
402 if (!is_ac97) { 402 if (!is_ac97) {
403 mutex_lock(&chip->mutex); 403 mutex_lock(&chip->mutex);
404 chip->model->set_adc_params(chip, hw_params); 404 chip->model.set_adc_params(chip, hw_params);
405 mutex_unlock(&chip->mutex); 405 mutex_unlock(&chip->mutex);
406 } 406 }
407 return 0; 407 return 0;
@@ -468,7 +468,7 @@ static int oxygen_multich_hw_params(struct snd_pcm_substream *substream,
468 OXYGEN_MULTICH_FORMAT_MASK); 468 OXYGEN_MULTICH_FORMAT_MASK);
469 oxygen_write16_masked(chip, OXYGEN_I2S_MULTICH_FORMAT, 469 oxygen_write16_masked(chip, OXYGEN_I2S_MULTICH_FORMAT,
470 oxygen_rate(hw_params) | 470 oxygen_rate(hw_params) |
471 chip->model->dac_i2s_format | 471 chip->model.dac_i2s_format |
472 oxygen_i2s_bits(hw_params), 472 oxygen_i2s_bits(hw_params),
473 OXYGEN_I2S_RATE_MASK | 473 OXYGEN_I2S_RATE_MASK |
474 OXYGEN_I2S_FORMAT_MASK | 474 OXYGEN_I2S_FORMAT_MASK |
@@ -478,7 +478,7 @@ static int oxygen_multich_hw_params(struct snd_pcm_substream *substream,
478 spin_unlock_irq(&chip->reg_lock); 478 spin_unlock_irq(&chip->reg_lock);
479 479
480 mutex_lock(&chip->mutex); 480 mutex_lock(&chip->mutex);
481 chip->model->set_dac_params(chip, hw_params); 481 chip->model.set_dac_params(chip, hw_params);
482 mutex_unlock(&chip->mutex); 482 mutex_unlock(&chip->mutex);
483 return 0; 483 return 0;
484} 484}
@@ -657,25 +657,26 @@ int oxygen_pcm_init(struct oxygen *chip)
657 int outs, ins; 657 int outs, ins;
658 int err; 658 int err;
659 659
660 outs = !!(chip->model->pcm_dev_cfg & PLAYBACK_0_TO_I2S); 660 outs = !!(chip->model.device_config & PLAYBACK_0_TO_I2S);
661 ins = !!(chip->model->pcm_dev_cfg & (CAPTURE_0_FROM_I2S_1 | 661 ins = !!(chip->model.device_config & (CAPTURE_0_FROM_I2S_1 |
662 CAPTURE_0_FROM_I2S_2)); 662 CAPTURE_0_FROM_I2S_2));
663 if (outs | ins) { 663 if (outs | ins) {
664 err = snd_pcm_new(chip->card, "Analog", 0, outs, ins, &pcm); 664 err = snd_pcm_new(chip->card, "Multichannel",
665 0, outs, ins, &pcm);
665 if (err < 0) 666 if (err < 0)
666 return err; 667 return err;
667 if (outs) 668 if (outs)
668 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, 669 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
669 &oxygen_multich_ops); 670 &oxygen_multich_ops);
670 if (chip->model->pcm_dev_cfg & CAPTURE_0_FROM_I2S_1) 671 if (chip->model.device_config & CAPTURE_0_FROM_I2S_1)
671 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, 672 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
672 &oxygen_rec_a_ops); 673 &oxygen_rec_a_ops);
673 else if (chip->model->pcm_dev_cfg & CAPTURE_0_FROM_I2S_2) 674 else if (chip->model.device_config & CAPTURE_0_FROM_I2S_2)
674 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, 675 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
675 &oxygen_rec_b_ops); 676 &oxygen_rec_b_ops);
676 pcm->private_data = chip; 677 pcm->private_data = chip;
677 pcm->private_free = oxygen_pcm_free; 678 pcm->private_free = oxygen_pcm_free;
678 strcpy(pcm->name, "Analog"); 679 strcpy(pcm->name, "Multichannel");
679 if (outs) 680 if (outs)
680 snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream, 681 snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream,
681 SNDRV_DMA_TYPE_DEV, 682 SNDRV_DMA_TYPE_DEV,
@@ -690,8 +691,8 @@ int oxygen_pcm_init(struct oxygen *chip)
690 BUFFER_BYTES_MAX); 691 BUFFER_BYTES_MAX);
691 } 692 }
692 693
693 outs = !!(chip->model->pcm_dev_cfg & PLAYBACK_1_TO_SPDIF); 694 outs = !!(chip->model.device_config & PLAYBACK_1_TO_SPDIF);
694 ins = !!(chip->model->pcm_dev_cfg & CAPTURE_1_FROM_SPDIF); 695 ins = !!(chip->model.device_config & CAPTURE_1_FROM_SPDIF);
695 if (outs | ins) { 696 if (outs | ins) {
696 err = snd_pcm_new(chip->card, "Digital", 1, outs, ins, &pcm); 697 err = snd_pcm_new(chip->card, "Digital", 1, outs, ins, &pcm);
697 if (err < 0) 698 if (err < 0)
@@ -712,11 +713,11 @@ int oxygen_pcm_init(struct oxygen *chip)
712 } 713 }
713 714
714 if (chip->has_ac97_1) { 715 if (chip->has_ac97_1) {
715 outs = !!(chip->model->pcm_dev_cfg & PLAYBACK_2_TO_AC97_1); 716 outs = !!(chip->model.device_config & PLAYBACK_2_TO_AC97_1);
716 ins = !!(chip->model->pcm_dev_cfg & CAPTURE_2_FROM_AC97_1); 717 ins = !!(chip->model.device_config & CAPTURE_2_FROM_AC97_1);
717 } else { 718 } else {
718 outs = 0; 719 outs = 0;
719 ins = !!(chip->model->pcm_dev_cfg & CAPTURE_2_FROM_I2S_2); 720 ins = !!(chip->model.device_config & CAPTURE_2_FROM_I2S_2);
720 } 721 }
721 if (outs | ins) { 722 if (outs | ins) {
722 err = snd_pcm_new(chip->card, outs ? "AC97" : "Analog2", 723 err = snd_pcm_new(chip->card, outs ? "AC97" : "Analog2",
diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c
index 01d7b75f9182..98c6a8c65d81 100644
--- a/sound/pci/oxygen/virtuoso.c
+++ b/sound/pci/oxygen/virtuoso.c
@@ -62,14 +62,66 @@
62 * AD0 <- 0 62 * AD0 <- 0
63 */ 63 */
64 64
65/*
66 * Xonar HDAV1.3 (Deluxe)
67 * ----------------------
68 *
69 * CMI8788:
70 *
71 * I²C <-> PCM1796 (front)
72 *
73 * GPI 0 <- external power present
74 *
75 * GPIO 0 -> enable output to speakers
76 * GPIO 2 -> M0 of CS5381
77 * GPIO 3 -> M1 of CS5381
78 * GPIO 8 -> route input jack to line-in (0) or mic-in (1)
79 *
80 * TXD -> HDMI controller
81 * RXD <- HDMI controller
82 *
83 * PCM1796 front: AD1,0 <- 0,0
84 *
85 * no daughterboard
86 * ----------------
87 *
88 * GPIO 4 <- 1
89 *
90 * H6 daughterboard
91 * ----------------
92 *
93 * GPIO 4 <- 0
94 * GPIO 5 <- 0
95 *
96 * I²C <-> PCM1796 (surround)
97 * <-> PCM1796 (center/LFE)
98 * <-> PCM1796 (back)
99 *
100 * PCM1796 surround: AD1,0 <- 0,1
101 * PCM1796 center/LFE: AD1,0 <- 1,0
102 * PCM1796 back: AD1,0 <- 1,1
103 *
104 * unknown daughterboard
105 * ---------------------
106 *
107 * GPIO 4 <- 0
108 * GPIO 5 <- 1
109 *
110 * I²C <-> CS4362A (surround, center/LFE, back)
111 *
112 * CS4362A: AD0 <- 0
113 */
114
65#include <linux/pci.h> 115#include <linux/pci.h>
66#include <linux/delay.h> 116#include <linux/delay.h>
67#include <linux/mutex.h> 117#include <linux/mutex.h>
68#include <sound/ac97_codec.h> 118#include <sound/ac97_codec.h>
119#include <sound/asoundef.h>
69#include <sound/control.h> 120#include <sound/control.h>
70#include <sound/core.h> 121#include <sound/core.h>
71#include <sound/initval.h> 122#include <sound/initval.h>
72#include <sound/pcm.h> 123#include <sound/pcm.h>
124#include <sound/pcm_params.h>
73#include <sound/tlv.h> 125#include <sound/tlv.h>
74#include "oxygen.h" 126#include "oxygen.h"
75#include "cm9780.h" 127#include "cm9780.h"
@@ -98,12 +150,15 @@ enum {
98 MODEL_D2X, 150 MODEL_D2X,
99 MODEL_D1, 151 MODEL_D1,
100 MODEL_DX, 152 MODEL_DX,
153 MODEL_HDAV, /* without daughterboard */
154 MODEL_HDAV_H6, /* with H6 daughterboard */
101}; 155};
102 156
103static struct pci_device_id xonar_ids[] __devinitdata = { 157static struct pci_device_id xonar_ids[] __devinitdata = {
104 { OXYGEN_PCI_SUBID(0x1043, 0x8269), .driver_data = MODEL_D2 }, 158 { OXYGEN_PCI_SUBID(0x1043, 0x8269), .driver_data = MODEL_D2 },
105 { OXYGEN_PCI_SUBID(0x1043, 0x8275), .driver_data = MODEL_DX }, 159 { OXYGEN_PCI_SUBID(0x1043, 0x8275), .driver_data = MODEL_DX },
106 { OXYGEN_PCI_SUBID(0x1043, 0x82b7), .driver_data = MODEL_D2X }, 160 { OXYGEN_PCI_SUBID(0x1043, 0x82b7), .driver_data = MODEL_D2X },
161 { OXYGEN_PCI_SUBID(0x1043, 0x8314), .driver_data = MODEL_HDAV },
107 { OXYGEN_PCI_SUBID(0x1043, 0x834f), .driver_data = MODEL_D1 }, 162 { OXYGEN_PCI_SUBID(0x1043, 0x834f), .driver_data = MODEL_D1 },
108 { } 163 { }
109}; 164};
@@ -124,11 +179,18 @@ MODULE_DEVICE_TABLE(pci, xonar_ids);
124#define GPIO_DX_FRONT_PANEL 0x0002 179#define GPIO_DX_FRONT_PANEL 0x0002
125#define GPIO_DX_INPUT_ROUTE 0x0100 180#define GPIO_DX_INPUT_ROUTE 0x0100
126 181
182#define GPIO_HDAV_DB_MASK 0x0030
183#define GPIO_HDAV_DB_H6 0x0000
184#define GPIO_HDAV_DB_XX 0x0020
185
186#define I2C_DEVICE_PCM1796(i) (0x98 + ((i) << 1)) /* 10011, ADx=i, /W=0 */
127#define I2C_DEVICE_CS4398 0x9e /* 10011, AD1=1, AD0=1, /W=0 */ 187#define I2C_DEVICE_CS4398 0x9e /* 10011, AD1=1, AD0=1, /W=0 */
128#define I2C_DEVICE_CS4362A 0x30 /* 001100, AD0=0, /W=0 */ 188#define I2C_DEVICE_CS4362A 0x30 /* 001100, AD0=0, /W=0 */
129 189
130struct xonar_data { 190struct xonar_data {
191 unsigned int model;
131 unsigned int anti_pop_delay; 192 unsigned int anti_pop_delay;
193 unsigned int dacs;
132 u16 output_enable_bit; 194 u16 output_enable_bit;
133 u8 ext_power_reg; 195 u8 ext_power_reg;
134 u8 ext_power_int_reg; 196 u8 ext_power_int_reg;
@@ -137,10 +199,13 @@ struct xonar_data {
137 u8 pcm1796_oversampling; 199 u8 pcm1796_oversampling;
138 u8 cs4398_fm; 200 u8 cs4398_fm;
139 u8 cs4362a_fm; 201 u8 cs4362a_fm;
202 u8 hdmi_params[5];
140}; 203};
141 204
142static void pcm1796_write(struct oxygen *chip, unsigned int codec, 205static void xonar_gpio_changed(struct oxygen *chip);
143 u8 reg, u8 value) 206
207static inline void pcm1796_write_spi(struct oxygen *chip, unsigned int codec,
208 u8 reg, u8 value)
144{ 209{
145 /* maps ALSA channel pair number to SPI output */ 210 /* maps ALSA channel pair number to SPI output */
146 static const u8 codec_map[4] = { 211 static const u8 codec_map[4] = {
@@ -154,6 +219,22 @@ static void pcm1796_write(struct oxygen *chip, unsigned int codec,
154 (reg << 8) | value); 219 (reg << 8) | value);
155} 220}
156 221
222static inline void pcm1796_write_i2c(struct oxygen *chip, unsigned int codec,
223 u8 reg, u8 value)
224{
225 oxygen_write_i2c(chip, I2C_DEVICE_PCM1796(codec), reg, value);
226}
227
228static void pcm1796_write(struct oxygen *chip, unsigned int codec,
229 u8 reg, u8 value)
230{
231 if ((chip->model.function_flags & OXYGEN_FUNCTION_2WIRE_SPI_MASK) ==
232 OXYGEN_FUNCTION_SPI)
233 pcm1796_write_spi(chip, codec, reg, value);
234 else
235 pcm1796_write_i2c(chip, codec, reg, value);
236}
237
157static void cs4398_write(struct oxygen *chip, u8 reg, u8 value) 238static void cs4398_write(struct oxygen *chip, u8 reg, u8 value)
158{ 239{
159 oxygen_write_i2c(chip, I2C_DEVICE_CS4398, reg, value); 240 oxygen_write_i2c(chip, I2C_DEVICE_CS4398, reg, value);
@@ -164,6 +245,24 @@ static void cs4362a_write(struct oxygen *chip, u8 reg, u8 value)
164 oxygen_write_i2c(chip, I2C_DEVICE_CS4362A, reg, value); 245 oxygen_write_i2c(chip, I2C_DEVICE_CS4362A, reg, value);
165} 246}
166 247
248static void hdmi_write_command(struct oxygen *chip, u8 command,
249 unsigned int count, const u8 *params)
250{
251 unsigned int i;
252 u8 checksum;
253
254 oxygen_write_uart(chip, 0xfb);
255 oxygen_write_uart(chip, 0xef);
256 oxygen_write_uart(chip, command);
257 oxygen_write_uart(chip, count);
258 for (i = 0; i < count; ++i)
259 oxygen_write_uart(chip, params[i]);
260 checksum = 0xfb + 0xef + command + count;
261 for (i = 0; i < count; ++i)
262 checksum += params[i];
263 oxygen_write_uart(chip, checksum);
264}
265
167static void xonar_enable_output(struct oxygen *chip) 266static void xonar_enable_output(struct oxygen *chip)
168{ 267{
169 struct xonar_data *data = chip->model_data; 268 struct xonar_data *data = chip->model_data;
@@ -180,6 +279,7 @@ static void xonar_common_init(struct oxygen *chip)
180 oxygen_set_bits8(chip, data->ext_power_int_reg, 279 oxygen_set_bits8(chip, data->ext_power_int_reg,
181 data->ext_power_bit); 280 data->ext_power_bit);
182 chip->interrupt_mask |= OXYGEN_INT_GPIO; 281 chip->interrupt_mask |= OXYGEN_INT_GPIO;
282 chip->model.gpio_changed = xonar_gpio_changed;
183 data->has_power = !!(oxygen_read8(chip, data->ext_power_reg) 283 data->has_power = !!(oxygen_read8(chip, data->ext_power_reg)
184 & data->ext_power_bit); 284 & data->ext_power_bit);
185 } 285 }
@@ -193,9 +293,10 @@ static void xonar_common_init(struct oxygen *chip)
193 293
194static void update_pcm1796_volume(struct oxygen *chip) 294static void update_pcm1796_volume(struct oxygen *chip)
195{ 295{
296 struct xonar_data *data = chip->model_data;
196 unsigned int i; 297 unsigned int i;
197 298
198 for (i = 0; i < 4; ++i) { 299 for (i = 0; i < data->dacs; ++i) {
199 pcm1796_write(chip, i, 16, chip->dac_volume[i * 2]); 300 pcm1796_write(chip, i, 16, chip->dac_volume[i * 2]);
200 pcm1796_write(chip, i, 17, chip->dac_volume[i * 2 + 1]); 301 pcm1796_write(chip, i, 17, chip->dac_volume[i * 2 + 1]);
201 } 302 }
@@ -203,13 +304,14 @@ static void update_pcm1796_volume(struct oxygen *chip)
203 304
204static void update_pcm1796_mute(struct oxygen *chip) 305static void update_pcm1796_mute(struct oxygen *chip)
205{ 306{
307 struct xonar_data *data = chip->model_data;
206 unsigned int i; 308 unsigned int i;
207 u8 value; 309 u8 value;
208 310
209 value = PCM1796_DMF_DISABLED | PCM1796_FMT_24_LJUST | PCM1796_ATLD; 311 value = PCM1796_DMF_DISABLED | PCM1796_FMT_24_LJUST | PCM1796_ATLD;
210 if (chip->dac_mute) 312 if (chip->dac_mute)
211 value |= PCM1796_MUTE; 313 value |= PCM1796_MUTE;
212 for (i = 0; i < 4; ++i) 314 for (i = 0; i < data->dacs; ++i)
213 pcm1796_write(chip, i, 18, value); 315 pcm1796_write(chip, i, 18, value);
214} 316}
215 317
@@ -218,7 +320,7 @@ static void pcm1796_init(struct oxygen *chip)
218 struct xonar_data *data = chip->model_data; 320 struct xonar_data *data = chip->model_data;
219 unsigned int i; 321 unsigned int i;
220 322
221 for (i = 0; i < 4; ++i) { 323 for (i = 0; i < data->dacs; ++i) {
222 pcm1796_write(chip, i, 19, PCM1796_FLT_SHARP | PCM1796_ATS_1); 324 pcm1796_write(chip, i, 19, PCM1796_FLT_SHARP | PCM1796_ATS_1);
223 pcm1796_write(chip, i, 20, data->pcm1796_oversampling); 325 pcm1796_write(chip, i, 20, data->pcm1796_oversampling);
224 pcm1796_write(chip, i, 21, 0); 326 pcm1796_write(chip, i, 21, 0);
@@ -234,6 +336,13 @@ static void xonar_d2_init(struct oxygen *chip)
234 data->anti_pop_delay = 300; 336 data->anti_pop_delay = 300;
235 data->output_enable_bit = GPIO_D2_OUTPUT_ENABLE; 337 data->output_enable_bit = GPIO_D2_OUTPUT_ENABLE;
236 data->pcm1796_oversampling = PCM1796_OS_64; 338 data->pcm1796_oversampling = PCM1796_OS_64;
339 if (data->model == MODEL_D2X) {
340 data->ext_power_reg = OXYGEN_GPIO_DATA;
341 data->ext_power_int_reg = OXYGEN_GPIO_INTERRUPT_MASK;
342 data->ext_power_bit = GPIO_D2X_EXT_POWER;
343 oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL,
344 GPIO_D2X_EXT_POWER);
345 }
237 346
238 pcm1796_init(chip); 347 pcm1796_init(chip);
239 348
@@ -246,17 +355,6 @@ static void xonar_d2_init(struct oxygen *chip)
246 snd_component_add(chip->card, "CS5381"); 355 snd_component_add(chip->card, "CS5381");
247} 356}
248 357
249static void xonar_d2x_init(struct oxygen *chip)
250{
251 struct xonar_data *data = chip->model_data;
252
253 data->ext_power_reg = OXYGEN_GPIO_DATA;
254 data->ext_power_int_reg = OXYGEN_GPIO_INTERRUPT_MASK;
255 data->ext_power_bit = GPIO_D2X_EXT_POWER;
256 oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_D2X_EXT_POWER);
257 xonar_d2_init(chip);
258}
259
260static void update_cs4362a_volumes(struct oxygen *chip) 358static void update_cs4362a_volumes(struct oxygen *chip)
261{ 359{
262 u8 mute; 360 u8 mute;
@@ -324,6 +422,11 @@ static void xonar_d1_init(struct oxygen *chip)
324 data->cs4398_fm = CS4398_FM_SINGLE | CS4398_DEM_NONE | CS4398_DIF_LJUST; 422 data->cs4398_fm = CS4398_FM_SINGLE | CS4398_DEM_NONE | CS4398_DIF_LJUST;
325 data->cs4362a_fm = CS4362A_FM_SINGLE | 423 data->cs4362a_fm = CS4362A_FM_SINGLE |
326 CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L; 424 CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L;
425 if (data->model == MODEL_DX) {
426 data->ext_power_reg = OXYGEN_GPI_DATA;
427 data->ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK;
428 data->ext_power_bit = GPI_DX_EXT_POWER;
429 }
327 430
328 oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS, 431 oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS,
329 OXYGEN_2WIRE_LENGTH_8 | 432 OXYGEN_2WIRE_LENGTH_8 |
@@ -344,30 +447,86 @@ static void xonar_d1_init(struct oxygen *chip)
344 snd_component_add(chip->card, "CS5361"); 447 snd_component_add(chip->card, "CS5361");
345} 448}
346 449
347static void xonar_dx_init(struct oxygen *chip) 450static void xonar_hdav_init(struct oxygen *chip)
348{ 451{
349 struct xonar_data *data = chip->model_data; 452 struct xonar_data *data = chip->model_data;
453 u8 param;
350 454
455 oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS,
456 OXYGEN_2WIRE_LENGTH_8 |
457 OXYGEN_2WIRE_INTERRUPT_MASK |
458 OXYGEN_2WIRE_SPEED_FAST);
459
460 data->anti_pop_delay = 100;
461 data->output_enable_bit = GPIO_DX_OUTPUT_ENABLE;
351 data->ext_power_reg = OXYGEN_GPI_DATA; 462 data->ext_power_reg = OXYGEN_GPI_DATA;
352 data->ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK; 463 data->ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK;
353 data->ext_power_bit = GPI_DX_EXT_POWER; 464 data->ext_power_bit = GPI_DX_EXT_POWER;
354 xonar_d1_init(chip); 465 data->pcm1796_oversampling = PCM1796_OS_64;
466
467 pcm1796_init(chip);
468
469 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_DX_INPUT_ROUTE);
470 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_DX_INPUT_ROUTE);
471
472 oxygen_reset_uart(chip);
473 param = 0;
474 hdmi_write_command(chip, 0x61, 1, &param);
475 param = 1;
476 hdmi_write_command(chip, 0x74, 1, &param);
477 data->hdmi_params[1] = IEC958_AES3_CON_FS_48000;
478 data->hdmi_params[4] = 1;
479 hdmi_write_command(chip, 0x54, 5, data->hdmi_params);
480
481 xonar_common_init(chip);
482
483 snd_component_add(chip->card, "PCM1796");
484 snd_component_add(chip->card, "CS5381");
355} 485}
356 486
357static void xonar_cleanup(struct oxygen *chip) 487static void xonar_disable_output(struct oxygen *chip)
358{ 488{
359 struct xonar_data *data = chip->model_data; 489 struct xonar_data *data = chip->model_data;
360 490
361 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, data->output_enable_bit); 491 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, data->output_enable_bit);
362} 492}
363 493
494static void xonar_d2_cleanup(struct oxygen *chip)
495{
496 xonar_disable_output(chip);
497}
498
364static void xonar_d1_cleanup(struct oxygen *chip) 499static void xonar_d1_cleanup(struct oxygen *chip)
365{ 500{
366 xonar_cleanup(chip); 501 xonar_disable_output(chip);
367 cs4362a_write(chip, 0x01, CS4362A_PDN | CS4362A_CPEN); 502 cs4362a_write(chip, 0x01, CS4362A_PDN | CS4362A_CPEN);
368 oxygen_clear_bits8(chip, OXYGEN_FUNCTION, OXYGEN_FUNCTION_RESET_CODEC); 503 oxygen_clear_bits8(chip, OXYGEN_FUNCTION, OXYGEN_FUNCTION_RESET_CODEC);
369} 504}
370 505
506static void xonar_hdav_cleanup(struct oxygen *chip)
507{
508 u8 param = 0;
509
510 hdmi_write_command(chip, 0x74, 1, &param);
511 xonar_disable_output(chip);
512}
513
514static void xonar_d2_suspend(struct oxygen *chip)
515{
516 xonar_d2_cleanup(chip);
517}
518
519static void xonar_d1_suspend(struct oxygen *chip)
520{
521 xonar_d1_cleanup(chip);
522}
523
524static void xonar_hdav_suspend(struct oxygen *chip)
525{
526 xonar_hdav_cleanup(chip);
527 msleep(2);
528}
529
371static void xonar_d2_resume(struct oxygen *chip) 530static void xonar_d2_resume(struct oxygen *chip)
372{ 531{
373 pcm1796_init(chip); 532 pcm1796_init(chip);
@@ -380,6 +539,33 @@ static void xonar_d1_resume(struct oxygen *chip)
380 xonar_enable_output(chip); 539 xonar_enable_output(chip);
381} 540}
382 541
542static void xonar_hdav_resume(struct oxygen *chip)
543{
544 struct xonar_data *data = chip->model_data;
545 u8 param;
546
547 oxygen_reset_uart(chip);
548 param = 0;
549 hdmi_write_command(chip, 0x61, 1, &param);
550 param = 1;
551 hdmi_write_command(chip, 0x74, 1, &param);
552 hdmi_write_command(chip, 0x54, 5, data->hdmi_params);
553 pcm1796_init(chip);
554 xonar_enable_output(chip);
555}
556
557static void xonar_hdav_pcm_hardware_filter(unsigned int channel,
558 struct snd_pcm_hardware *hardware)
559{
560 if (channel == PCM_MULTICH) {
561 hardware->rates = SNDRV_PCM_RATE_44100 |
562 SNDRV_PCM_RATE_48000 |
563 SNDRV_PCM_RATE_96000 |
564 SNDRV_PCM_RATE_192000;
565 hardware->rate_min = 44100;
566 }
567}
568
383static void set_pcm1796_params(struct oxygen *chip, 569static void set_pcm1796_params(struct oxygen *chip,
384 struct snd_pcm_hw_params *params) 570 struct snd_pcm_hw_params *params)
385{ 571{
@@ -388,7 +574,7 @@ static void set_pcm1796_params(struct oxygen *chip,
388 574
389 data->pcm1796_oversampling = 575 data->pcm1796_oversampling =
390 params_rate(params) >= 96000 ? PCM1796_OS_32 : PCM1796_OS_64; 576 params_rate(params) >= 96000 ? PCM1796_OS_32 : PCM1796_OS_64;
391 for (i = 0; i < 4; ++i) 577 for (i = 0; i < data->dacs; ++i)
392 pcm1796_write(chip, i, 20, data->pcm1796_oversampling); 578 pcm1796_write(chip, i, 20, data->pcm1796_oversampling);
393} 579}
394 580
@@ -430,6 +616,42 @@ static void set_cs43xx_params(struct oxygen *chip,
430 cs4362a_write(chip, 0x0c, data->cs4362a_fm); 616 cs4362a_write(chip, 0x0c, data->cs4362a_fm);
431} 617}
432 618
619static void set_hdmi_params(struct oxygen *chip,
620 struct snd_pcm_hw_params *params)
621{
622 struct xonar_data *data = chip->model_data;
623
624 data->hdmi_params[0] = 0; /* 1 = non-audio */
625 switch (params_rate(params)) {
626 case 44100:
627 data->hdmi_params[1] = IEC958_AES3_CON_FS_44100;
628 break;
629 case 48000:
630 data->hdmi_params[1] = IEC958_AES3_CON_FS_48000;
631 break;
632 default: /* 96000 */
633 data->hdmi_params[1] = IEC958_AES3_CON_FS_96000;
634 break;
635 case 192000:
636 data->hdmi_params[1] = IEC958_AES3_CON_FS_192000;
637 break;
638 }
639 data->hdmi_params[2] = params_channels(params) / 2 - 1;
640 if (params_format(params) == SNDRV_PCM_FORMAT_S16_LE)
641 data->hdmi_params[3] = 0;
642 else
643 data->hdmi_params[3] = 0xc0;
644 data->hdmi_params[4] = 1; /* ? */
645 hdmi_write_command(chip, 0x54, 5, data->hdmi_params);
646}
647
648static void set_hdav_params(struct oxygen *chip,
649 struct snd_pcm_hw_params *params)
650{
651 set_pcm1796_params(chip, params);
652 set_hdmi_params(chip, params);
653}
654
433static void xonar_gpio_changed(struct oxygen *chip) 655static void xonar_gpio_changed(struct oxygen *chip)
434{ 656{
435 struct xonar_data *data = chip->model_data; 657 struct xonar_data *data = chip->model_data;
@@ -449,29 +671,43 @@ static void xonar_gpio_changed(struct oxygen *chip)
449 } 671 }
450} 672}
451 673
452static int alt_switch_get(struct snd_kcontrol *ctl, 674static void xonar_hdav_uart_input(struct oxygen *chip)
453 struct snd_ctl_elem_value *value) 675{
676 if (chip->uart_input_count >= 2 &&
677 chip->uart_input[chip->uart_input_count - 2] == 'O' &&
678 chip->uart_input[chip->uart_input_count - 1] == 'K') {
679 printk(KERN_DEBUG "message from Xonar HDAV HDMI chip received:");
680 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
681 chip->uart_input, chip->uart_input_count);
682 chip->uart_input_count = 0;
683 }
684}
685
686static int gpio_bit_switch_get(struct snd_kcontrol *ctl,
687 struct snd_ctl_elem_value *value)
454{ 688{
455 struct oxygen *chip = ctl->private_data; 689 struct oxygen *chip = ctl->private_data;
690 u16 bit = ctl->private_value;
456 691
457 value->value.integer.value[0] = 692 value->value.integer.value[0] =
458 !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) & GPIO_D2_ALT); 693 !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) & bit);
459 return 0; 694 return 0;
460} 695}
461 696
462static int alt_switch_put(struct snd_kcontrol *ctl, 697static int gpio_bit_switch_put(struct snd_kcontrol *ctl,
463 struct snd_ctl_elem_value *value) 698 struct snd_ctl_elem_value *value)
464{ 699{
465 struct oxygen *chip = ctl->private_data; 700 struct oxygen *chip = ctl->private_data;
701 u16 bit = ctl->private_value;
466 u16 old_bits, new_bits; 702 u16 old_bits, new_bits;
467 int changed; 703 int changed;
468 704
469 spin_lock_irq(&chip->reg_lock); 705 spin_lock_irq(&chip->reg_lock);
470 old_bits = oxygen_read16(chip, OXYGEN_GPIO_DATA); 706 old_bits = oxygen_read16(chip, OXYGEN_GPIO_DATA);
471 if (value->value.integer.value[0]) 707 if (value->value.integer.value[0])
472 new_bits = old_bits | GPIO_D2_ALT; 708 new_bits = old_bits | bit;
473 else 709 else
474 new_bits = old_bits & ~GPIO_D2_ALT; 710 new_bits = old_bits & ~bit;
475 changed = new_bits != old_bits; 711 changed = new_bits != old_bits;
476 if (changed) 712 if (changed)
477 oxygen_write16(chip, OXYGEN_GPIO_DATA, new_bits); 713 oxygen_write16(chip, OXYGEN_GPIO_DATA, new_bits);
@@ -483,47 +719,22 @@ static const struct snd_kcontrol_new alt_switch = {
483 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 719 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
484 .name = "Analog Loopback Switch", 720 .name = "Analog Loopback Switch",
485 .info = snd_ctl_boolean_mono_info, 721 .info = snd_ctl_boolean_mono_info,
486 .get = alt_switch_get, 722 .get = gpio_bit_switch_get,
487 .put = alt_switch_put, 723 .put = gpio_bit_switch_put,
724 .private_value = GPIO_D2_ALT,
488}; 725};
489 726
490static int front_panel_get(struct snd_kcontrol *ctl,
491 struct snd_ctl_elem_value *value)
492{
493 struct oxygen *chip = ctl->private_data;
494
495 value->value.integer.value[0] =
496 !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) & GPIO_DX_FRONT_PANEL);
497 return 0;
498}
499
500static int front_panel_put(struct snd_kcontrol *ctl,
501 struct snd_ctl_elem_value *value)
502{
503 struct oxygen *chip = ctl->private_data;
504 u16 old_reg, new_reg;
505
506 spin_lock_irq(&chip->reg_lock);
507 old_reg = oxygen_read16(chip, OXYGEN_GPIO_DATA);
508 if (value->value.integer.value[0])
509 new_reg = old_reg | GPIO_DX_FRONT_PANEL;
510 else
511 new_reg = old_reg & ~GPIO_DX_FRONT_PANEL;
512 oxygen_write16(chip, OXYGEN_GPIO_DATA, new_reg);
513 spin_unlock_irq(&chip->reg_lock);
514 return old_reg != new_reg;
515}
516
517static const struct snd_kcontrol_new front_panel_switch = { 727static const struct snd_kcontrol_new front_panel_switch = {
518 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 728 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
519 .name = "Front Panel Switch", 729 .name = "Front Panel Switch",
520 .info = snd_ctl_boolean_mono_info, 730 .info = snd_ctl_boolean_mono_info,
521 .get = front_panel_get, 731 .get = gpio_bit_switch_get,
522 .put = front_panel_put, 732 .put = gpio_bit_switch_put,
733 .private_value = GPIO_DX_FRONT_PANEL,
523}; 734};
524 735
525static void xonar_d1_ac97_switch(struct oxygen *chip, 736static void xonar_line_mic_ac97_switch(struct oxygen *chip,
526 unsigned int reg, unsigned int mute) 737 unsigned int reg, unsigned int mute)
527{ 738{
528 if (reg == AC97_LINE) { 739 if (reg == AC97_LINE) {
529 spin_lock_irq(&chip->reg_lock); 740 spin_lock_irq(&chip->reg_lock);
@@ -552,7 +763,7 @@ static int xonar_d1_control_filter(struct snd_kcontrol_new *template)
552 return 0; 763 return 0;
553} 764}
554 765
555static int xonar_mixer_init(struct oxygen *chip) 766static int xonar_d2_mixer_init(struct oxygen *chip)
556{ 767{
557 return snd_ctl_add(chip->card, snd_ctl_new1(&alt_switch, chip)); 768 return snd_ctl_add(chip->card, snd_ctl_new1(&alt_switch, chip));
558} 769}
@@ -562,130 +773,147 @@ static int xonar_d1_mixer_init(struct oxygen *chip)
562 return snd_ctl_add(chip->card, snd_ctl_new1(&front_panel_switch, chip)); 773 return snd_ctl_add(chip->card, snd_ctl_new1(&front_panel_switch, chip));
563} 774}
564 775
565static const struct oxygen_model xonar_models[] = { 776static int xonar_model_probe(struct oxygen *chip, unsigned long driver_data)
566 [MODEL_D2] = { 777{
567 .shortname = "Xonar D2", 778 static const char *const names[] = {
568 .longname = "Asus Virtuoso 200", 779 [MODEL_D1] = "Xonar D1",
569 .chip = "AV200", 780 [MODEL_DX] = "Xonar DX",
570 .owner = THIS_MODULE, 781 [MODEL_D2] = "Xonar D2",
571 .init = xonar_d2_init, 782 [MODEL_D2X] = "Xonar D2X",
572 .control_filter = xonar_d2_control_filter, 783 [MODEL_HDAV] = "Xonar HDAV1.3",
573 .mixer_init = xonar_mixer_init, 784 [MODEL_HDAV_H6] = "Xonar HDAV1.3+H6",
574 .cleanup = xonar_cleanup, 785 };
575 .suspend = xonar_cleanup, 786 static const u8 dacs[] = {
576 .resume = xonar_d2_resume, 787 [MODEL_D1] = 2,
577 .set_dac_params = set_pcm1796_params, 788 [MODEL_DX] = 2,
578 .set_adc_params = set_cs53x1_params, 789 [MODEL_D2] = 4,
579 .update_dac_volume = update_pcm1796_volume, 790 [MODEL_D2X] = 4,
580 .update_dac_mute = update_pcm1796_mute, 791 [MODEL_HDAV] = 1,
581 .dac_tlv = pcm1796_db_scale, 792 [MODEL_HDAV_H6] = 4,
582 .model_data_size = sizeof(struct xonar_data), 793 };
583 .pcm_dev_cfg = PLAYBACK_0_TO_I2S | 794 struct xonar_data *data = chip->model_data;
584 PLAYBACK_1_TO_SPDIF | 795
585 CAPTURE_0_FROM_I2S_2 | 796 data->model = driver_data;
586 CAPTURE_1_FROM_SPDIF, 797 if (data->model == MODEL_HDAV) {
587 .dac_channels = 8, 798 oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL,
588 .dac_volume_min = 0x0f, 799 GPIO_HDAV_DB_MASK);
589 .dac_volume_max = 0xff, 800 switch (oxygen_read16(chip, OXYGEN_GPIO_DATA) &
590 .misc_flags = OXYGEN_MISC_MIDI, 801 GPIO_HDAV_DB_MASK) {
591 .function_flags = OXYGEN_FUNCTION_SPI | 802 case GPIO_HDAV_DB_H6:
592 OXYGEN_FUNCTION_ENABLE_SPI_4_5, 803 data->model = MODEL_HDAV_H6;
593 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 804 break;
594 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 805 case GPIO_HDAV_DB_XX:
595 }, 806 snd_printk(KERN_ERR "unknown daughterboard\n");
596 [MODEL_D2X] = { 807 return -ENODEV;
597 .shortname = "Xonar D2X", 808 }
598 .longname = "Asus Virtuoso 200", 809 }
599 .chip = "AV200", 810
600 .owner = THIS_MODULE, 811 data->dacs = dacs[data->model];
601 .init = xonar_d2x_init, 812 chip->model.shortname = names[data->model];
602 .control_filter = xonar_d2_control_filter, 813 return 0;
603 .mixer_init = xonar_mixer_init, 814}
604 .cleanup = xonar_cleanup, 815
605 .suspend = xonar_cleanup, 816static const struct oxygen_model model_xonar_d2 = {
606 .resume = xonar_d2_resume, 817 .longname = "Asus Virtuoso 200",
607 .set_dac_params = set_pcm1796_params, 818 .chip = "AV200",
608 .set_adc_params = set_cs53x1_params, 819 .owner = THIS_MODULE,
609 .update_dac_volume = update_pcm1796_volume, 820 .probe = xonar_model_probe,
610 .update_dac_mute = update_pcm1796_mute, 821 .init = xonar_d2_init,
611 .gpio_changed = xonar_gpio_changed, 822 .control_filter = xonar_d2_control_filter,
612 .dac_tlv = pcm1796_db_scale, 823 .mixer_init = xonar_d2_mixer_init,
613 .model_data_size = sizeof(struct xonar_data), 824 .cleanup = xonar_d2_cleanup,
614 .pcm_dev_cfg = PLAYBACK_0_TO_I2S | 825 .suspend = xonar_d2_suspend,
615 PLAYBACK_1_TO_SPDIF | 826 .resume = xonar_d2_resume,
616 CAPTURE_0_FROM_I2S_2 | 827 .set_dac_params = set_pcm1796_params,
617 CAPTURE_1_FROM_SPDIF, 828 .set_adc_params = set_cs53x1_params,
618 .dac_channels = 8, 829 .update_dac_volume = update_pcm1796_volume,
619 .dac_volume_min = 0x0f, 830 .update_dac_mute = update_pcm1796_mute,
620 .dac_volume_max = 0xff, 831 .dac_tlv = pcm1796_db_scale,
621 .misc_flags = OXYGEN_MISC_MIDI, 832 .model_data_size = sizeof(struct xonar_data),
622 .function_flags = OXYGEN_FUNCTION_SPI | 833 .device_config = PLAYBACK_0_TO_I2S |
623 OXYGEN_FUNCTION_ENABLE_SPI_4_5, 834 PLAYBACK_1_TO_SPDIF |
624 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 835 CAPTURE_0_FROM_I2S_2 |
625 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 836 CAPTURE_1_FROM_SPDIF |
626 }, 837 MIDI_OUTPUT |
627 [MODEL_D1] = { 838 MIDI_INPUT,
628 .shortname = "Xonar D1", 839 .dac_channels = 8,
629 .longname = "Asus Virtuoso 100", 840 .dac_volume_min = 0x0f,
630 .chip = "AV200", 841 .dac_volume_max = 0xff,
631 .owner = THIS_MODULE, 842 .misc_flags = OXYGEN_MISC_MIDI,
632 .init = xonar_d1_init, 843 .function_flags = OXYGEN_FUNCTION_SPI |
633 .control_filter = xonar_d1_control_filter, 844 OXYGEN_FUNCTION_ENABLE_SPI_4_5,
634 .mixer_init = xonar_d1_mixer_init, 845 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
635 .cleanup = xonar_d1_cleanup, 846 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
636 .suspend = xonar_d1_cleanup, 847};
637 .resume = xonar_d1_resume, 848
638 .set_dac_params = set_cs43xx_params, 849static const struct oxygen_model model_xonar_d1 = {
639 .set_adc_params = set_cs53x1_params, 850 .longname = "Asus Virtuoso 100",
640 .update_dac_volume = update_cs43xx_volume, 851 .chip = "AV200",
641 .update_dac_mute = update_cs43xx_mute, 852 .owner = THIS_MODULE,
642 .ac97_switch = xonar_d1_ac97_switch, 853 .probe = xonar_model_probe,
643 .dac_tlv = cs4362a_db_scale, 854 .init = xonar_d1_init,
644 .model_data_size = sizeof(struct xonar_data), 855 .control_filter = xonar_d1_control_filter,
645 .pcm_dev_cfg = PLAYBACK_0_TO_I2S | 856 .mixer_init = xonar_d1_mixer_init,
646 PLAYBACK_1_TO_SPDIF | 857 .cleanup = xonar_d1_cleanup,
647 CAPTURE_0_FROM_I2S_2, 858 .suspend = xonar_d1_suspend,
648 .dac_channels = 8, 859 .resume = xonar_d1_resume,
649 .dac_volume_min = 0, 860 .set_dac_params = set_cs43xx_params,
650 .dac_volume_max = 127, 861 .set_adc_params = set_cs53x1_params,
651 .function_flags = OXYGEN_FUNCTION_2WIRE, 862 .update_dac_volume = update_cs43xx_volume,
652 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 863 .update_dac_mute = update_cs43xx_mute,
653 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 864 .ac97_switch = xonar_line_mic_ac97_switch,
654 }, 865 .dac_tlv = cs4362a_db_scale,
655 [MODEL_DX] = { 866 .model_data_size = sizeof(struct xonar_data),
656 .shortname = "Xonar DX", 867 .device_config = PLAYBACK_0_TO_I2S |
657 .longname = "Asus Virtuoso 100", 868 PLAYBACK_1_TO_SPDIF |
658 .chip = "AV200", 869 CAPTURE_0_FROM_I2S_2,
659 .owner = THIS_MODULE, 870 .dac_channels = 8,
660 .init = xonar_dx_init, 871 .dac_volume_min = 0,
661 .control_filter = xonar_d1_control_filter, 872 .dac_volume_max = 127,
662 .mixer_init = xonar_d1_mixer_init, 873 .function_flags = OXYGEN_FUNCTION_2WIRE,
663 .cleanup = xonar_d1_cleanup, 874 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
664 .suspend = xonar_d1_cleanup, 875 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
665 .resume = xonar_d1_resume, 876};
666 .set_dac_params = set_cs43xx_params, 877
667 .set_adc_params = set_cs53x1_params, 878static const struct oxygen_model model_xonar_hdav = {
668 .update_dac_volume = update_cs43xx_volume, 879 .longname = "Asus Virtuoso 200",
669 .update_dac_mute = update_cs43xx_mute, 880 .chip = "AV200",
670 .gpio_changed = xonar_gpio_changed, 881 .owner = THIS_MODULE,
671 .ac97_switch = xonar_d1_ac97_switch, 882 .probe = xonar_model_probe,
672 .dac_tlv = cs4362a_db_scale, 883 .init = xonar_hdav_init,
673 .model_data_size = sizeof(struct xonar_data), 884 .cleanup = xonar_hdav_cleanup,
674 .pcm_dev_cfg = PLAYBACK_0_TO_I2S | 885 .suspend = xonar_hdav_suspend,
675 PLAYBACK_1_TO_SPDIF | 886 .resume = xonar_hdav_resume,
676 CAPTURE_0_FROM_I2S_2, 887 .pcm_hardware_filter = xonar_hdav_pcm_hardware_filter,
677 .dac_channels = 8, 888 .set_dac_params = set_hdav_params,
678 .dac_volume_min = 0, 889 .set_adc_params = set_cs53x1_params,
679 .dac_volume_max = 127, 890 .update_dac_volume = update_pcm1796_volume,
680 .function_flags = OXYGEN_FUNCTION_2WIRE, 891 .update_dac_mute = update_pcm1796_mute,
681 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 892 .uart_input = xonar_hdav_uart_input,
682 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 893 .ac97_switch = xonar_line_mic_ac97_switch,
683 }, 894 .dac_tlv = pcm1796_db_scale,
895 .model_data_size = sizeof(struct xonar_data),
896 .device_config = PLAYBACK_0_TO_I2S |
897 PLAYBACK_1_TO_SPDIF |
898 CAPTURE_0_FROM_I2S_2,
899 .dac_channels = 8,
900 .dac_volume_min = 0x0f,
901 .dac_volume_max = 0xff,
902 .function_flags = OXYGEN_FUNCTION_2WIRE,
903 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
904 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
684}; 905};
685 906
686static int __devinit xonar_probe(struct pci_dev *pci, 907static int __devinit xonar_probe(struct pci_dev *pci,
687 const struct pci_device_id *pci_id) 908 const struct pci_device_id *pci_id)
688{ 909{
910 static const struct oxygen_model *const models[] = {
911 [MODEL_D1] = &model_xonar_d1,
912 [MODEL_DX] = &model_xonar_d1,
913 [MODEL_D2] = &model_xonar_d2,
914 [MODEL_D2X] = &model_xonar_d2,
915 [MODEL_HDAV] = &model_xonar_hdav,
916 };
689 static int dev; 917 static int dev;
690 int err; 918 int err;
691 919
@@ -695,8 +923,10 @@ static int __devinit xonar_probe(struct pci_dev *pci,
695 ++dev; 923 ++dev;
696 return -ENOENT; 924 return -ENOENT;
697 } 925 }
926 BUG_ON(pci_id->driver_data >= ARRAY_SIZE(models));
698 err = oxygen_pci_probe(pci, index[dev], id[dev], 927 err = oxygen_pci_probe(pci, index[dev], id[dev],
699 &xonar_models[pci_id->driver_data]); 928 models[pci_id->driver_data],
929 pci_id->driver_data);
700 if (err >= 0) 930 if (err >= 0)
701 ++dev; 931 ++dev;
702 return err; 932 return err;
diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c
index 2c7e25336795..0e06c6c9fcc0 100644
--- a/sound/pci/pcxhr/pcxhr.c
+++ b/sound/pci/pcxhr/pcxhr.c
@@ -464,7 +464,8 @@ static int pcxhr_update_r_buffer(struct pcxhr_stream *stream)
464 pcxhr_init_rmh(&rmh, CMD_UPDATE_R_BUFFERS); 464 pcxhr_init_rmh(&rmh, CMD_UPDATE_R_BUFFERS);
465 pcxhr_set_pipe_cmd_params(&rmh, is_capture, stream->pipe->first_audio, stream_num, 0); 465 pcxhr_set_pipe_cmd_params(&rmh, is_capture, stream->pipe->first_audio, stream_num, 0);
466 466
467 snd_assert(subs->runtime->dma_bytes < 0x200000); /* max buffer size is 2 MByte */ 467 /* max buffer size is 2 MByte */
468 snd_BUG_ON(subs->runtime->dma_bytes >= 0x200000);
468 rmh.cmd[1] = subs->runtime->dma_bytes * 8; /* size in bits */ 469 rmh.cmd[1] = subs->runtime->dma_bytes * 8; /* size in bits */
469 rmh.cmd[2] = subs->runtime->dma_addr >> 24; /* most significant byte */ 470 rmh.cmd[2] = subs->runtime->dma_addr >> 24; /* most significant byte */
470 rmh.cmd[2] |= 1<<19; /* this is a circular buffer */ 471 rmh.cmd[2] |= 1<<19; /* this is a circular buffer */
@@ -1228,7 +1229,8 @@ static int __devinit pcxhr_probe(struct pci_dev *pci, const struct pci_device_id
1228 return -ENOMEM; 1229 return -ENOMEM;
1229 } 1230 }
1230 1231
1231 snd_assert(pci_id->driver_data < PCI_ID_LAST, return -ENODEV); 1232 if (snd_BUG_ON(pci_id->driver_data >= PCI_ID_LAST))
1233 return -ENODEV;
1232 card_name = pcxhr_board_params[pci_id->driver_data].board_name; 1234 card_name = pcxhr_board_params[pci_id->driver_data].board_name;
1233 mgr->playback_chips = pcxhr_board_params[pci_id->driver_data].playback_chips; 1235 mgr->playback_chips = pcxhr_board_params[pci_id->driver_data].playback_chips;
1234 mgr->capture_chips = pcxhr_board_params[pci_id->driver_data].capture_chips; 1236 mgr->capture_chips = pcxhr_board_params[pci_id->driver_data].capture_chips;
diff --git a/sound/pci/pcxhr/pcxhr_core.c b/sound/pci/pcxhr/pcxhr_core.c
index 000e6fed6e39..7143259cfe34 100644
--- a/sound/pci/pcxhr/pcxhr_core.c
+++ b/sound/pci/pcxhr/pcxhr_core.c
@@ -319,16 +319,20 @@ static int pcxhr_download_dsp(struct pcxhr_mgr *mgr, const struct firmware *dsp)
319 const unsigned char *data; 319 const unsigned char *data;
320 unsigned char dummy; 320 unsigned char dummy;
321 /* check the length of boot image */ 321 /* check the length of boot image */
322 snd_assert(dsp->size > 0, return -EINVAL); 322 if (dsp->size <= 0)
323 snd_assert(dsp->size % 3 == 0, return -EINVAL); 323 return -EINVAL;
324 snd_assert(dsp->data, return -EINVAL); 324 if (dsp->size % 3)
325 return -EINVAL;
326 if (snd_BUG_ON(!dsp->data))
327 return -EINVAL;
325 /* transfert data buffer from PC to DSP */ 328 /* transfert data buffer from PC to DSP */
326 for (i = 0; i < dsp->size; i += 3) { 329 for (i = 0; i < dsp->size; i += 3) {
327 data = dsp->data + i; 330 data = dsp->data + i;
328 if (i == 0) { 331 if (i == 0) {
329 /* test data header consistency */ 332 /* test data header consistency */
330 len = (unsigned int)((data[0]<<16) + (data[1]<<8) + data[2]); 333 len = (unsigned int)((data[0]<<16) + (data[1]<<8) + data[2]);
331 snd_assert((len==0) || (dsp->size == (len+2)*3), return -EINVAL); 334 if (len && dsp->size != (len + 2) * 3)
335 return -EINVAL;
332 } 336 }
333 /* wait DSP ready for new transfer */ 337 /* wait DSP ready for new transfer */
334 err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR, PCXHR_ISR_HI08_TRDY, 338 err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR, PCXHR_ISR_HI08_TRDY,
@@ -389,7 +393,8 @@ int pcxhr_load_boot_binary(struct pcxhr_mgr *mgr, const struct firmware *boot)
389 unsigned char dummy; 393 unsigned char dummy;
390 394
391 /* send the hostport address to the DSP (only the upper 24 bit !) */ 395 /* send the hostport address to the DSP (only the upper 24 bit !) */
392 snd_assert((physaddr & 0xff) == 0, return -EINVAL); 396 if (snd_BUG_ON(physaddr & 0xff))
397 return -EINVAL;
393 PCXHR_OUTPL(mgr, PCXHR_PLX_MBOX1, (physaddr >> 8)); 398 PCXHR_OUTPL(mgr, PCXHR_PLX_MBOX1, (physaddr >> 8));
394 399
395 err = pcxhr_send_it_dsp(mgr, PCXHR_IT_DOWNLOAD_BOOT, 0); 400 err = pcxhr_send_it_dsp(mgr, PCXHR_IT_DOWNLOAD_BOOT, 0);
@@ -570,7 +575,8 @@ static int pcxhr_send_msg_nolock(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
570 u32 data; 575 u32 data;
571 unsigned char reg; 576 unsigned char reg;
572 577
573 snd_assert(rmh->cmd_len<PCXHR_SIZE_MAX_CMD, return -EINVAL); 578 if (snd_BUG_ON(rmh->cmd_len >= PCXHR_SIZE_MAX_CMD))
579 return -EINVAL;
574 err = pcxhr_send_it_dsp(mgr, PCXHR_IT_MESSAGE, 1); 580 err = pcxhr_send_it_dsp(mgr, PCXHR_IT_MESSAGE, 1);
575 if (err) { 581 if (err) {
576 snd_printk(KERN_ERR "pcxhr_send_message : ED_DSP_CRASHED\n"); 582 snd_printk(KERN_ERR "pcxhr_send_message : ED_DSP_CRASHED\n");
@@ -677,7 +683,8 @@ static int pcxhr_send_msg_nolock(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
677 */ 683 */
678void pcxhr_init_rmh(struct pcxhr_rmh *rmh, int cmd) 684void pcxhr_init_rmh(struct pcxhr_rmh *rmh, int cmd)
679{ 685{
680 snd_assert(cmd < CMD_LAST_INDEX, return); 686 if (snd_BUG_ON(cmd >= CMD_LAST_INDEX))
687 return;
681 rmh->cmd[0] = pcxhr_dsp_cmds[cmd].opcode; 688 rmh->cmd[0] = pcxhr_dsp_cmds[cmd].opcode;
682 rmh->cmd_len = 1; 689 rmh->cmd_len = 1;
683 rmh->stat_len = pcxhr_dsp_cmds[cmd].st_length; 690 rmh->stat_len = pcxhr_dsp_cmds[cmd].st_length;
@@ -690,17 +697,17 @@ void pcxhr_set_pipe_cmd_params(struct pcxhr_rmh *rmh, int capture,
690 unsigned int param1, unsigned int param2, 697 unsigned int param1, unsigned int param2,
691 unsigned int param3) 698 unsigned int param3)
692{ 699{
693 snd_assert(param1 <= MASK_FIRST_FIELD); 700 snd_BUG_ON(param1 > MASK_FIRST_FIELD);
694 if (capture) 701 if (capture)
695 rmh->cmd[0] |= 0x800; /* COMMAND_RECORD_MASK */ 702 rmh->cmd[0] |= 0x800; /* COMMAND_RECORD_MASK */
696 if (param1) 703 if (param1)
697 rmh->cmd[0] |= (param1 << FIELD_SIZE); 704 rmh->cmd[0] |= (param1 << FIELD_SIZE);
698 if (param2) { 705 if (param2) {
699 snd_assert(param2 <= MASK_FIRST_FIELD); 706 snd_BUG_ON(param2 > MASK_FIRST_FIELD);
700 rmh->cmd[0] |= param2; 707 rmh->cmd[0] |= param2;
701 } 708 }
702 if(param3) { 709 if(param3) {
703 snd_assert(param3 <= MASK_DSP_WORD); 710 snd_BUG_ON(param3 > MASK_DSP_WORD);
704 rmh->cmd[1] = param3; 711 rmh->cmd[1] = param3;
705 rmh->cmd_len = 2; 712 rmh->cmd_len = 2;
706 } 713 }
diff --git a/sound/pci/pcxhr/pcxhr_hwdep.c b/sound/pci/pcxhr/pcxhr_hwdep.c
index d2f043278cf4..96640d9c227d 100644
--- a/sound/pci/pcxhr/pcxhr_hwdep.c
+++ b/sound/pci/pcxhr/pcxhr_hwdep.c
@@ -65,15 +65,18 @@ static int pcxhr_init_board(struct pcxhr_mgr *mgr)
65 if (err) 65 if (err)
66 return err; 66 return err;
67 /* test 8 or 12 phys out */ 67 /* test 8 or 12 phys out */
68 snd_assert((rmh.stat[0] & MASK_FIRST_FIELD) == mgr->playback_chips*2, 68 if ((rmh.stat[0] & MASK_FIRST_FIELD) != mgr->playback_chips * 2)
69 return -EINVAL); 69 return -EINVAL;
70 /* test 8 or 2 phys in */ 70 /* test 8 or 2 phys in */
71 snd_assert(((rmh.stat[0] >> (2*FIELD_SIZE)) & MASK_FIRST_FIELD) == 71 if (((rmh.stat[0] >> (2 * FIELD_SIZE)) & MASK_FIRST_FIELD) !=
72 mgr->capture_chips * 2, return -EINVAL); 72 mgr->capture_chips * 2)
73 return -EINVAL;
73 /* test max nb substream per board */ 74 /* test max nb substream per board */
74 snd_assert((rmh.stat[1] & 0x5F) >= card_streams, return -EINVAL); 75 if ((rmh.stat[1] & 0x5F) < card_streams)
76 return -EINVAL;
75 /* test max nb substream per pipe */ 77 /* test max nb substream per pipe */
76 snd_assert(((rmh.stat[1]>>7)&0x5F) >= PCXHR_PLAYBACK_STREAMS, return -EINVAL); 78 if (((rmh.stat[1] >> 7) & 0x5F) < PCXHR_PLAYBACK_STREAMS)
79 return -EINVAL;
77 80
78 pcxhr_init_rmh(&rmh, CMD_VERSION); 81 pcxhr_init_rmh(&rmh, CMD_VERSION);
79 /* firmware num for DSP */ 82 /* firmware num for DSP */
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c
index 6a3596247348..e9f0706ed3e4 100644
--- a/sound/pci/riptide/riptide.c
+++ b/sound/pci/riptide/riptide.c
@@ -865,7 +865,8 @@ static int sendcmd(struct cmdif *cif, u32 flags, u32 cmd, u32 parm,
865 struct riptideport *hwport; 865 struct riptideport *hwport;
866 struct cmdport *cmdport = NULL; 866 struct cmdport *cmdport = NULL;
867 867
868 snd_assert(cif, return -EINVAL); 868 if (snd_BUG_ON(!cif))
869 return -EINVAL;
869 870
870 hwport = cif->hwport; 871 hwport = cif->hwport;
871 if (cif->errcnt > MAX_ERROR_COUNT) { 872 if (cif->errcnt > MAX_ERROR_COUNT) {
@@ -1482,7 +1483,6 @@ static int snd_riptide_prepare(struct snd_pcm_substream *substream)
1482{ 1483{
1483 struct snd_riptide *chip = snd_pcm_substream_chip(substream); 1484 struct snd_riptide *chip = snd_pcm_substream_chip(substream);
1484 struct snd_pcm_runtime *runtime = substream->runtime; 1485 struct snd_pcm_runtime *runtime = substream->runtime;
1485 struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream);
1486 struct pcmhw *data = get_pcmhwdev(substream); 1486 struct pcmhw *data = get_pcmhwdev(substream);
1487 struct cmdif *cif = chip->cif; 1487 struct cmdif *cif = chip->cif;
1488 unsigned char *lbuspath = NULL; 1488 unsigned char *lbuspath = NULL;
@@ -1490,7 +1490,8 @@ static int snd_riptide_prepare(struct snd_pcm_substream *substream)
1490 int err = 0; 1490 int err = 0;
1491 snd_pcm_format_t format; 1491 snd_pcm_format_t format;
1492 1492
1493 snd_assert(cif && data, return -EINVAL); 1493 if (snd_BUG_ON(!cif || !data))
1494 return -EINVAL;
1494 1495
1495 snd_printdd("prepare id %d ch: %d f:0x%x r:%d\n", data->id, 1496 snd_printdd("prepare id %d ch: %d f:0x%x r:%d\n", data->id,
1496 runtime->channels, runtime->format, runtime->rate); 1497 runtime->channels, runtime->format, runtime->rate);
@@ -1513,9 +1514,9 @@ static int snd_riptide_prepare(struct snd_pcm_substream *substream)
1513 lbuspath = data->paths.stereo; 1514 lbuspath = data->paths.stereo;
1514 break; 1515 break;
1515 } 1516 }
1516 snd_printdd("use sgdlist at 0x%p and buffer at 0x%p\n", 1517 snd_printdd("use sgdlist at 0x%p\n",
1517 data->sgdlist.area, sgbuf); 1518 data->sgdlist.area);
1518 if (data->sgdlist.area && sgbuf) { 1519 if (data->sgdlist.area) {
1519 unsigned int i, j, size, pages, f, pt, period; 1520 unsigned int i, j, size, pages, f, pt, period;
1520 struct sgd *c, *p = NULL; 1521 struct sgd *c, *p = NULL;
1521 1522
@@ -1533,6 +1534,7 @@ static int snd_riptide_prepare(struct snd_pcm_substream *substream)
1533 pt = 0; 1534 pt = 0;
1534 j = 0; 1535 j = 0;
1535 for (i = 0; i < pages; i++) { 1536 for (i = 0; i < pages; i++) {
1537 unsigned int ofs, addr;
1536 c = &data->sgdbuf[i]; 1538 c = &data->sgdbuf[i];
1537 if (p) 1539 if (p)
1538 p->dwNextLink = cpu_to_le32(data->sgdlist.addr + 1540 p->dwNextLink = cpu_to_le32(data->sgdlist.addr +
@@ -1540,8 +1542,9 @@ static int snd_riptide_prepare(struct snd_pcm_substream *substream)
1540 sizeof(struct 1542 sizeof(struct
1541 sgd))); 1543 sgd)));
1542 c->dwNextLink = cpu_to_le32(data->sgdlist.addr); 1544 c->dwNextLink = cpu_to_le32(data->sgdlist.addr);
1543 c->dwSegPtrPhys = 1545 ofs = j << PAGE_SHIFT;
1544 cpu_to_le32(sgbuf->table[j].addr + pt); 1546 addr = snd_pcm_sgbuf_get_addr(substream, ofs) + pt;
1547 c->dwSegPtrPhys = cpu_to_le32(addr);
1545 pt = (pt + f) % PAGE_SIZE; 1548 pt = (pt + f) % PAGE_SIZE;
1546 if (pt == 0) 1549 if (pt == 0)
1547 j++; 1550 j++;
@@ -1772,7 +1775,8 @@ snd_riptide_codec_write(struct snd_ac97 *ac97, unsigned short reg,
1772 union cmdret rptr = CMDRET_ZERO; 1775 union cmdret rptr = CMDRET_ZERO;
1773 int i = 0; 1776 int i = 0;
1774 1777
1775 snd_assert(cif, return); 1778 if (snd_BUG_ON(!cif))
1779 return;
1776 1780
1777 snd_printdd("Write AC97 reg 0x%x 0x%x\n", reg, val); 1781 snd_printdd("Write AC97 reg 0x%x 0x%x\n", reg, val);
1778 do { 1782 do {
@@ -1790,7 +1794,8 @@ static unsigned short snd_riptide_codec_read(struct snd_ac97 *ac97,
1790 struct cmdif *cif = chip->cif; 1794 struct cmdif *cif = chip->cif;
1791 union cmdret rptr = CMDRET_ZERO; 1795 union cmdret rptr = CMDRET_ZERO;
1792 1796
1793 snd_assert(cif, return 0); 1797 if (snd_BUG_ON(!cif))
1798 return 0;
1794 1799
1795 if (SEND_RACR(cif, reg, &rptr) != 0) 1800 if (SEND_RACR(cif, reg, &rptr) != 0)
1796 SEND_RACR(cif, reg, &rptr); 1801 SEND_RACR(cif, reg, &rptr);
@@ -1804,7 +1809,8 @@ static int snd_riptide_initialize(struct snd_riptide *chip)
1804 unsigned int device_id; 1809 unsigned int device_id;
1805 int err; 1810 int err;
1806 1811
1807 snd_assert(chip, return -EINVAL); 1812 if (snd_BUG_ON(!chip))
1813 return -EINVAL;
1808 1814
1809 cif = chip->cif; 1815 cif = chip->cif;
1810 if (!cif) { 1816 if (!cif) {
@@ -1836,7 +1842,8 @@ static int snd_riptide_free(struct snd_riptide *chip)
1836{ 1842{
1837 struct cmdif *cif; 1843 struct cmdif *cif;
1838 1844
1839 snd_assert(chip, return 0); 1845 if (!chip)
1846 return 0;
1840 1847
1841 if ((cif = chip->cif)) { 1848 if ((cif = chip->cif)) {
1842 SET_GRESET(cif->hwport); 1849 SET_GRESET(cif->hwport);
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 4d6fbb36ab8a..d723543beadd 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -1036,7 +1036,7 @@ static void hdsp_set_dds_value(struct hdsp *hdsp, int rate)
1036 n = DDS_NUMERATOR; 1036 n = DDS_NUMERATOR;
1037 div64_32(&n, rate, &r); 1037 div64_32(&n, rate, &r);
1038 /* n should be less than 2^32 for being written to FREQ register */ 1038 /* n should be less than 2^32 for being written to FREQ register */
1039 snd_assert((n >> 32) == 0); 1039 snd_BUG_ON(n >> 32);
1040 /* HDSP_freqReg and HDSP_resetPointer are the same, so keep the DDS 1040 /* HDSP_freqReg and HDSP_resetPointer are the same, so keep the DDS
1041 value to write it after a reset */ 1041 value to write it after a reset */
1042 hdsp->dds_value = n; 1042 hdsp->dds_value = n;
@@ -3043,7 +3043,7 @@ static int snd_hdsp_get_adat_sync_check(struct snd_kcontrol *kcontrol, struct sn
3043 struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); 3043 struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
3044 3044
3045 offset = ucontrol->id.index - 1; 3045 offset = ucontrol->id.index - 1;
3046 snd_assert(offset >= 0); 3046 snd_BUG_ON(offset < 0);
3047 3047
3048 switch (hdsp->io_type) { 3048 switch (hdsp->io_type) {
3049 case Digiface: 3049 case Digiface:
@@ -3767,7 +3767,8 @@ static char *hdsp_channel_buffer_location(struct hdsp *hdsp,
3767{ 3767{
3768 int mapped_channel; 3768 int mapped_channel;
3769 3769
3770 snd_assert(channel >= 0 && channel < hdsp->max_channels, return NULL); 3770 if (snd_BUG_ON(channel < 0 || channel >= hdsp->max_channels))
3771 return NULL;
3771 3772
3772 if ((mapped_channel = hdsp->channel_map[channel]) < 0) 3773 if ((mapped_channel = hdsp->channel_map[channel]) < 0)
3773 return NULL; 3774 return NULL;
@@ -3784,10 +3785,12 @@ static int snd_hdsp_playback_copy(struct snd_pcm_substream *substream, int chann
3784 struct hdsp *hdsp = snd_pcm_substream_chip(substream); 3785 struct hdsp *hdsp = snd_pcm_substream_chip(substream);
3785 char *channel_buf; 3786 char *channel_buf;
3786 3787
3787 snd_assert(pos + count <= HDSP_CHANNEL_BUFFER_BYTES / 4, return -EINVAL); 3788 if (snd_BUG_ON(pos + count > HDSP_CHANNEL_BUFFER_BYTES / 4))
3789 return -EINVAL;
3788 3790
3789 channel_buf = hdsp_channel_buffer_location (hdsp, substream->pstr->stream, channel); 3791 channel_buf = hdsp_channel_buffer_location (hdsp, substream->pstr->stream, channel);
3790 snd_assert(channel_buf != NULL, return -EIO); 3792 if (snd_BUG_ON(!channel_buf))
3793 return -EIO;
3791 if (copy_from_user(channel_buf + pos * 4, src, count * 4)) 3794 if (copy_from_user(channel_buf + pos * 4, src, count * 4))
3792 return -EFAULT; 3795 return -EFAULT;
3793 return count; 3796 return count;
@@ -3799,10 +3802,12 @@ static int snd_hdsp_capture_copy(struct snd_pcm_substream *substream, int channe
3799 struct hdsp *hdsp = snd_pcm_substream_chip(substream); 3802 struct hdsp *hdsp = snd_pcm_substream_chip(substream);
3800 char *channel_buf; 3803 char *channel_buf;
3801 3804
3802 snd_assert(pos + count <= HDSP_CHANNEL_BUFFER_BYTES / 4, return -EINVAL); 3805 if (snd_BUG_ON(pos + count > HDSP_CHANNEL_BUFFER_BYTES / 4))
3806 return -EINVAL;
3803 3807
3804 channel_buf = hdsp_channel_buffer_location (hdsp, substream->pstr->stream, channel); 3808 channel_buf = hdsp_channel_buffer_location (hdsp, substream->pstr->stream, channel);
3805 snd_assert(channel_buf != NULL, return -EIO); 3809 if (snd_BUG_ON(!channel_buf))
3810 return -EIO;
3806 if (copy_to_user(dst, channel_buf + pos * 4, count * 4)) 3811 if (copy_to_user(dst, channel_buf + pos * 4, count * 4))
3807 return -EFAULT; 3812 return -EFAULT;
3808 return count; 3813 return count;
@@ -3815,7 +3820,8 @@ static int snd_hdsp_hw_silence(struct snd_pcm_substream *substream, int channel,
3815 char *channel_buf; 3820 char *channel_buf;
3816 3821
3817 channel_buf = hdsp_channel_buffer_location (hdsp, substream->pstr->stream, channel); 3822 channel_buf = hdsp_channel_buffer_location (hdsp, substream->pstr->stream, channel);
3818 snd_assert(channel_buf != NULL, return -EIO); 3823 if (snd_BUG_ON(!channel_buf))
3824 return -EIO;
3819 memset(channel_buf + pos * 4, 0, count * 4); 3825 memset(channel_buf + pos * 4, 0, count * 4);
3820 return count; 3826 return count;
3821} 3827}
@@ -3927,7 +3933,8 @@ static int snd_hdsp_channel_info(struct snd_pcm_substream *substream,
3927 struct hdsp *hdsp = snd_pcm_substream_chip(substream); 3933 struct hdsp *hdsp = snd_pcm_substream_chip(substream);
3928 int mapped_channel; 3934 int mapped_channel;
3929 3935
3930 snd_assert(info->channel < hdsp->max_channels, return -EINVAL); 3936 if (snd_BUG_ON(info->channel >= hdsp->max_channels))
3937 return -EINVAL;
3931 3938
3932 if ((mapped_channel = hdsp->channel_map[info->channel]) < 0) 3939 if ((mapped_channel = hdsp->channel_map[info->channel]) < 0)
3933 return -EINVAL; 3940 return -EINVAL;
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index ab423bc82342..98762f909d64 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -535,7 +535,8 @@ static inline void snd_hdspm_initialize_midi_flush(struct hdspm * hdspm);
535static int hdspm_update_simple_mixer_controls(struct hdspm * hdspm); 535static int hdspm_update_simple_mixer_controls(struct hdspm * hdspm);
536static int hdspm_autosync_ref(struct hdspm * hdspm); 536static int hdspm_autosync_ref(struct hdspm * hdspm);
537static int snd_hdspm_set_defaults(struct hdspm * hdspm); 537static int snd_hdspm_set_defaults(struct hdspm * hdspm);
538static void hdspm_set_sgbuf(struct hdspm * hdspm, struct snd_sg_buf *sgbuf, 538static void hdspm_set_sgbuf(struct hdspm * hdspm,
539 struct snd_pcm_substream *substream,
539 unsigned int reg, int channels); 540 unsigned int reg, int channels);
540 541
541static inline int HDSPM_bit2freq(int n) 542static inline int HDSPM_bit2freq(int n)
@@ -845,7 +846,7 @@ static void hdspm_set_dds_value(struct hdspm *hdspm, int rate)
845 n = 110100480000000ULL; /* Value checked for AES32 and MADI */ 846 n = 110100480000000ULL; /* Value checked for AES32 and MADI */
846 div64_32(&n, rate, &r); 847 div64_32(&n, rate, &r);
847 /* n should be less than 2^32 for being written to FREQ register */ 848 /* n should be less than 2^32 for being written to FREQ register */
848 snd_assert((n >> 32) == 0); 849 snd_BUG_ON(n >> 32);
849 hdspm_write(hdspm, HDSPM_freqReg, (u32)n); 850 hdspm_write(hdspm, HDSPM_freqReg, (u32)n);
850} 851}
851 852
@@ -2617,8 +2618,8 @@ static int snd_hdspm_get_playback_mixer(struct snd_kcontrol *kcontrol,
2617 2618
2618 channel = ucontrol->id.index - 1; 2619 channel = ucontrol->id.index - 1;
2619 2620
2620 snd_assert(channel >= 0 2621 if (snd_BUG_ON(channel < 0 || channel >= HDSPM_MAX_CHANNELS))
2621 || channel < HDSPM_MAX_CHANNELS, return -EINVAL); 2622 return -EINVAL;
2622 2623
2623 mapped_channel = hdspm->channel_map[channel]; 2624 mapped_channel = hdspm->channel_map[channel];
2624 if (mapped_channel < 0) 2625 if (mapped_channel < 0)
@@ -2652,8 +2653,8 @@ static int snd_hdspm_put_playback_mixer(struct snd_kcontrol *kcontrol,
2652 2653
2653 channel = ucontrol->id.index - 1; 2654 channel = ucontrol->id.index - 1;
2654 2655
2655 snd_assert(channel >= 0 2656 if (snd_BUG_ON(channel < 0 || channel >= HDSPM_MAX_CHANNELS))
2656 || channel < HDSPM_MAX_CHANNELS, return -EINVAL); 2657 return -EINVAL;
2657 2658
2658 mapped_channel = hdspm->channel_map[channel]; 2659 mapped_channel = hdspm->channel_map[channel];
2659 if (mapped_channel < 0) 2660 if (mapped_channel < 0)
@@ -3496,8 +3497,8 @@ static char *hdspm_channel_buffer_location(struct hdspm * hdspm,
3496{ 3497{
3497 int mapped_channel; 3498 int mapped_channel;
3498 3499
3499 snd_assert(channel >= 0 3500 if (snd_BUG_ON(channel < 0 || channel >= HDSPM_MAX_CHANNELS))
3500 || channel < HDSPM_MAX_CHANNELS, return NULL); 3501 return NULL;
3501 3502
3502 mapped_channel = hdspm->channel_map[channel]; 3503 mapped_channel = hdspm->channel_map[channel];
3503 if (mapped_channel < 0) 3504 if (mapped_channel < 0)
@@ -3520,14 +3521,15 @@ static int snd_hdspm_playback_copy(struct snd_pcm_substream *substream,
3520 struct hdspm *hdspm = snd_pcm_substream_chip(substream); 3521 struct hdspm *hdspm = snd_pcm_substream_chip(substream);
3521 char *channel_buf; 3522 char *channel_buf;
3522 3523
3523 snd_assert(pos + count <= HDSPM_CHANNEL_BUFFER_BYTES / 4, 3524 if (snd_BUG_ON(pos + count > HDSPM_CHANNEL_BUFFER_BYTES / 4))
3524 return -EINVAL); 3525 return -EINVAL;
3525 3526
3526 channel_buf = 3527 channel_buf =
3527 hdspm_channel_buffer_location(hdspm, substream->pstr->stream, 3528 hdspm_channel_buffer_location(hdspm, substream->pstr->stream,
3528 channel); 3529 channel);
3529 3530
3530 snd_assert(channel_buf != NULL, return -EIO); 3531 if (snd_BUG_ON(!channel_buf))
3532 return -EIO;
3531 3533
3532 return copy_from_user(channel_buf + pos * 4, src, count * 4); 3534 return copy_from_user(channel_buf + pos * 4, src, count * 4);
3533} 3535}
@@ -3539,13 +3541,14 @@ static int snd_hdspm_capture_copy(struct snd_pcm_substream *substream,
3539 struct hdspm *hdspm = snd_pcm_substream_chip(substream); 3541 struct hdspm *hdspm = snd_pcm_substream_chip(substream);
3540 char *channel_buf; 3542 char *channel_buf;
3541 3543
3542 snd_assert(pos + count <= HDSPM_CHANNEL_BUFFER_BYTES / 4, 3544 if (snd_BUG_ON(pos + count > HDSPM_CHANNEL_BUFFER_BYTES / 4))
3543 return -EINVAL); 3545 return -EINVAL;
3544 3546
3545 channel_buf = 3547 channel_buf =
3546 hdspm_channel_buffer_location(hdspm, substream->pstr->stream, 3548 hdspm_channel_buffer_location(hdspm, substream->pstr->stream,
3547 channel); 3549 channel);
3548 snd_assert(channel_buf != NULL, return -EIO); 3550 if (snd_BUG_ON(!channel_buf))
3551 return -EIO;
3549 return copy_to_user(dst, channel_buf + pos * 4, count * 4); 3552 return copy_to_user(dst, channel_buf + pos * 4, count * 4);
3550} 3553}
3551 3554
@@ -3559,7 +3562,8 @@ static int snd_hdspm_hw_silence(struct snd_pcm_substream *substream,
3559 channel_buf = 3562 channel_buf =
3560 hdspm_channel_buffer_location(hdspm, substream->pstr->stream, 3563 hdspm_channel_buffer_location(hdspm, substream->pstr->stream,
3561 channel); 3564 channel);
3562 snd_assert(channel_buf != NULL, return -EIO); 3565 if (snd_BUG_ON(!channel_buf))
3566 return -EIO;
3563 memset(channel_buf + pos * 4, 0, count * 4); 3567 memset(channel_buf + pos * 4, 0, count * 4);
3564 return 0; 3568 return 0;
3565} 3569}
@@ -3601,8 +3605,6 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream,
3601 int i; 3605 int i;
3602 pid_t this_pid; 3606 pid_t this_pid;
3603 pid_t other_pid; 3607 pid_t other_pid;
3604 struct snd_sg_buf *sgbuf;
3605
3606 3608
3607 spin_lock_irq(&hdspm->lock); 3609 spin_lock_irq(&hdspm->lock);
3608 3610
@@ -3670,11 +3672,9 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream,
3670 if (err < 0) 3672 if (err < 0)
3671 return err; 3673 return err;
3672 3674
3673 sgbuf = snd_pcm_substream_sgbuf(substream);
3674
3675 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 3675 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
3676 3676
3677 hdspm_set_sgbuf(hdspm, sgbuf, HDSPM_pageAddressBufferOut, 3677 hdspm_set_sgbuf(hdspm, substream, HDSPM_pageAddressBufferOut,
3678 params_channels(params)); 3678 params_channels(params));
3679 3679
3680 for (i = 0; i < params_channels(params); ++i) 3680 for (i = 0; i < params_channels(params); ++i)
@@ -3685,7 +3685,7 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream,
3685 snd_printdd("Allocated sample buffer for playback at %p\n", 3685 snd_printdd("Allocated sample buffer for playback at %p\n",
3686 hdspm->playback_buffer); 3686 hdspm->playback_buffer);
3687 } else { 3687 } else {
3688 hdspm_set_sgbuf(hdspm, sgbuf, HDSPM_pageAddressBufferIn, 3688 hdspm_set_sgbuf(hdspm, substream, HDSPM_pageAddressBufferIn,
3689 params_channels(params)); 3689 params_channels(params));
3690 3690
3691 for (i = 0; i < params_channels(params); ++i) 3691 for (i = 0; i < params_channels(params); ++i)
@@ -3700,7 +3700,7 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream,
3700 snd_printdd("Allocated sample buffer for %s at 0x%08X\n", 3700 snd_printdd("Allocated sample buffer for %s at 0x%08X\n",
3701 substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 3701 substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
3702 "playback" : "capture", 3702 "playback" : "capture",
3703 snd_pcm_sgbuf_get_addr(sgbuf, 0)); 3703 snd_pcm_sgbuf_get_addr(substream, 0));
3704 */ 3704 */
3705 /* 3705 /*
3706 snd_printdd("set_hwparams: %s %d Hz, %d channels, bs = %d\n", 3706 snd_printdd("set_hwparams: %s %d Hz, %d channels, bs = %d\n",
@@ -3744,7 +3744,8 @@ static int snd_hdspm_channel_info(struct snd_pcm_substream *substream,
3744 struct hdspm *hdspm = snd_pcm_substream_chip(substream); 3744 struct hdspm *hdspm = snd_pcm_substream_chip(substream);
3745 int mapped_channel; 3745 int mapped_channel;
3746 3746
3747 snd_assert(info->channel < HDSPM_MAX_CHANNELS, return -EINVAL); 3747 if (snd_BUG_ON(info->channel >= HDSPM_MAX_CHANNELS))
3748 return -EINVAL;
3748 3749
3749 mapped_channel = hdspm->channel_map[info->channel]; 3750 mapped_channel = hdspm->channel_map[info->channel];
3750 if (mapped_channel < 0) 3751 if (mapped_channel < 0)
@@ -4249,13 +4250,14 @@ static int __devinit snd_hdspm_preallocate_memory(struct hdspm * hdspm)
4249 return 0; 4250 return 0;
4250} 4251}
4251 4252
4252static void hdspm_set_sgbuf(struct hdspm * hdspm, struct snd_sg_buf *sgbuf, 4253static void hdspm_set_sgbuf(struct hdspm * hdspm,
4254 struct snd_pcm_substream *substream,
4253 unsigned int reg, int channels) 4255 unsigned int reg, int channels)
4254{ 4256{
4255 int i; 4257 int i;
4256 for (i = 0; i < (channels * 16); i++) 4258 for (i = 0; i < (channels * 16); i++)
4257 hdspm_write(hdspm, reg + 4 * i, 4259 hdspm_write(hdspm, reg + 4 * i,
4258 snd_pcm_sgbuf_get_addr(sgbuf, (size_t) 4096 * i)); 4260 snd_pcm_sgbuf_get_addr(substream, 4096 * i));
4259} 4261}
4260 4262
4261/* ------------- ALSA Devices ---------------------------- */ 4263/* ------------- ALSA Devices ---------------------------- */
diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c
index a123f0e6ba23..2570907134d7 100644
--- a/sound/pci/rme9652/rme9652.c
+++ b/sound/pci/rme9652/rme9652.c
@@ -595,8 +595,6 @@ static void rme9652_set_thru(struct snd_rme9652 *rme9652, int channel, int enabl
595 } else { 595 } else {
596 int mapped_channel; 596 int mapped_channel;
597 597
598 snd_assert(channel == RME9652_NCHANNELS, return);
599
600 mapped_channel = rme9652->channel_map[channel]; 598 mapped_channel = rme9652->channel_map[channel];
601 599
602 if (enable) { 600 if (enable) {
@@ -1893,7 +1891,8 @@ static char *rme9652_channel_buffer_location(struct snd_rme9652 *rme9652,
1893{ 1891{
1894 int mapped_channel; 1892 int mapped_channel;
1895 1893
1896 snd_assert(channel >= 0 || channel < RME9652_NCHANNELS, return NULL); 1894 if (snd_BUG_ON(channel < 0 || channel >= RME9652_NCHANNELS))
1895 return NULL;
1897 1896
1898 if ((mapped_channel = rme9652->channel_map[channel]) < 0) { 1897 if ((mapped_channel = rme9652->channel_map[channel]) < 0) {
1899 return NULL; 1898 return NULL;
@@ -1914,12 +1913,14 @@ static int snd_rme9652_playback_copy(struct snd_pcm_substream *substream, int ch
1914 struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream); 1913 struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
1915 char *channel_buf; 1914 char *channel_buf;
1916 1915
1917 snd_assert(pos + count <= RME9652_CHANNEL_BUFFER_BYTES / 4, return -EINVAL); 1916 if (snd_BUG_ON(pos + count > RME9652_CHANNEL_BUFFER_BYTES / 4))
1917 return -EINVAL;
1918 1918
1919 channel_buf = rme9652_channel_buffer_location (rme9652, 1919 channel_buf = rme9652_channel_buffer_location (rme9652,
1920 substream->pstr->stream, 1920 substream->pstr->stream,
1921 channel); 1921 channel);
1922 snd_assert(channel_buf != NULL, return -EIO); 1922 if (snd_BUG_ON(!channel_buf))
1923 return -EIO;
1923 if (copy_from_user(channel_buf + pos * 4, src, count * 4)) 1924 if (copy_from_user(channel_buf + pos * 4, src, count * 4))
1924 return -EFAULT; 1925 return -EFAULT;
1925 return count; 1926 return count;
@@ -1931,12 +1932,14 @@ static int snd_rme9652_capture_copy(struct snd_pcm_substream *substream, int cha
1931 struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream); 1932 struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
1932 char *channel_buf; 1933 char *channel_buf;
1933 1934
1934 snd_assert(pos + count <= RME9652_CHANNEL_BUFFER_BYTES / 4, return -EINVAL); 1935 if (snd_BUG_ON(pos + count > RME9652_CHANNEL_BUFFER_BYTES / 4))
1936 return -EINVAL;
1935 1937
1936 channel_buf = rme9652_channel_buffer_location (rme9652, 1938 channel_buf = rme9652_channel_buffer_location (rme9652,
1937 substream->pstr->stream, 1939 substream->pstr->stream,
1938 channel); 1940 channel);
1939 snd_assert(channel_buf != NULL, return -EIO); 1941 if (snd_BUG_ON(!channel_buf))
1942 return -EIO;
1940 if (copy_to_user(dst, channel_buf + pos * 4, count * 4)) 1943 if (copy_to_user(dst, channel_buf + pos * 4, count * 4))
1941 return -EFAULT; 1944 return -EFAULT;
1942 return count; 1945 return count;
@@ -1951,7 +1954,8 @@ static int snd_rme9652_hw_silence(struct snd_pcm_substream *substream, int chann
1951 channel_buf = rme9652_channel_buffer_location (rme9652, 1954 channel_buf = rme9652_channel_buffer_location (rme9652,
1952 substream->pstr->stream, 1955 substream->pstr->stream,
1953 channel); 1956 channel);
1954 snd_assert(channel_buf != NULL, return -EIO); 1957 if (snd_BUG_ON(!channel_buf))
1958 return -EIO;
1955 memset(channel_buf + pos * 4, 0, count * 4); 1959 memset(channel_buf + pos * 4, 0, count * 4);
1956 return count; 1960 return count;
1957} 1961}
@@ -2053,7 +2057,8 @@ static int snd_rme9652_channel_info(struct snd_pcm_substream *substream,
2053 struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream); 2057 struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
2054 int chn; 2058 int chn;
2055 2059
2056 snd_assert(info->channel < RME9652_NCHANNELS, return -EINVAL); 2060 if (snd_BUG_ON(info->channel >= RME9652_NCHANNELS))
2061 return -EINVAL;
2057 2062
2058 if ((chn = rme9652->channel_map[info->channel]) < 0) { 2063 if ((chn = rme9652->channel_map[info->channel]) < 0) {
2059 return -EINVAL; 2064 return -EINVAL;
diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c
index 0d3d305b0a0b..cd408b86c839 100644
--- a/sound/pci/sonicvibes.c
+++ b/sound/pci/sonicvibes.c
@@ -534,8 +534,8 @@ static int snd_sonicvibes_hw_constraint_dac_rate(struct snd_pcm_hw_params *param
534 params->rate_den = 1; 534 params->rate_den = 1;
535 } else { 535 } else {
536 snd_sonicvibes_pll(rate, &r, &m, &n); 536 snd_sonicvibes_pll(rate, &r, &m, &n);
537 snd_assert((SV_REFFREQUENCY % 16) == 0, return -EINVAL); 537 snd_BUG_ON(SV_REFFREQUENCY % 16);
538 snd_assert((SV_ADCMULT % 512) == 0, return -EINVAL); 538 snd_BUG_ON(SV_ADCMULT % 512);
539 params->rate_num = (SV_REFFREQUENCY/16) * (n+2) * r; 539 params->rate_num = (SV_REFFREQUENCY/16) * (n+2) * r;
540 params->rate_den = (SV_ADCMULT/512) * (m+2); 540 params->rate_den = (SV_ADCMULT/512) * (m+2);
541 } 541 }
@@ -849,7 +849,8 @@ static int __devinit snd_sonicvibes_pcm(struct sonicvibes * sonic, int device, s
849 849
850 if ((err = snd_pcm_new(sonic->card, "s3_86c617", device, 1, 1, &pcm)) < 0) 850 if ((err = snd_pcm_new(sonic->card, "s3_86c617", device, 1, 1, &pcm)) < 0)
851 return err; 851 return err;
852 snd_assert(pcm != NULL, return -EINVAL); 852 if (snd_BUG_ON(!pcm))
853 return -EINVAL;
853 854
854 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_sonicvibes_playback_ops); 855 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_sonicvibes_playback_ops);
855 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_sonicvibes_capture_ops); 856 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_sonicvibes_capture_ops);
@@ -1089,7 +1090,8 @@ static int __devinit snd_sonicvibes_mixer(struct sonicvibes * sonic)
1089 unsigned int idx; 1090 unsigned int idx;
1090 int err; 1091 int err;
1091 1092
1092 snd_assert(sonic != NULL && sonic->card != NULL, return -EINVAL); 1093 if (snd_BUG_ON(!sonic || !sonic->card))
1094 return -EINVAL;
1093 card = sonic->card; 1095 card = sonic->card;
1094 strcpy(card->mixername, "S3 SonicVibes"); 1096 strcpy(card->mixername, "S3 SonicVibes");
1095 1097
diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c
index a69b4206c69e..c612b435ca2b 100644
--- a/sound/pci/trident/trident_main.c
+++ b/sound/pci/trident/trident_main.c
@@ -2931,7 +2931,8 @@ static int snd_trident_pcm_mixer_build(struct snd_trident *trident,
2931{ 2931{
2932 struct snd_trident_pcm_mixer *tmix; 2932 struct snd_trident_pcm_mixer *tmix;
2933 2933
2934 snd_assert(trident != NULL && voice != NULL && substream != NULL, return -EINVAL); 2934 if (snd_BUG_ON(!trident || !voice || !substream))
2935 return -EINVAL;
2935 tmix = &trident->pcm_mixer[substream->number]; 2936 tmix = &trident->pcm_mixer[substream->number];
2936 tmix->voice = voice; 2937 tmix->voice = voice;
2937 tmix->vol = T4D_DEFAULT_PCM_VOL; 2938 tmix->vol = T4D_DEFAULT_PCM_VOL;
@@ -2946,7 +2947,8 @@ static int snd_trident_pcm_mixer_free(struct snd_trident *trident, struct snd_tr
2946{ 2947{
2947 struct snd_trident_pcm_mixer *tmix; 2948 struct snd_trident_pcm_mixer *tmix;
2948 2949
2949 snd_assert(trident != NULL && substream != NULL, return -EINVAL); 2950 if (snd_BUG_ON(!trident || !substream))
2951 return -EINVAL;
2950 tmix = &trident->pcm_mixer[substream->number]; 2952 tmix = &trident->pcm_mixer[substream->number];
2951 tmix->voice = NULL; 2953 tmix->voice = NULL;
2952 snd_trident_notify_pcm_change(trident, tmix, substream->number, 0); 2954 snd_trident_notify_pcm_change(trident, tmix, substream->number, 0);
@@ -3131,7 +3133,8 @@ static unsigned char snd_trident_gameport_read(struct gameport *gameport)
3131{ 3133{
3132 struct snd_trident *chip = gameport_get_port_data(gameport); 3134 struct snd_trident *chip = gameport_get_port_data(gameport);
3133 3135
3134 snd_assert(chip, return 0); 3136 if (snd_BUG_ON(!chip))
3137 return 0;
3135 return inb(TRID_REG(chip, GAMEPORT_LEGACY)); 3138 return inb(TRID_REG(chip, GAMEPORT_LEGACY));
3136} 3139}
3137 3140
@@ -3139,7 +3142,8 @@ static void snd_trident_gameport_trigger(struct gameport *gameport)
3139{ 3142{
3140 struct snd_trident *chip = gameport_get_port_data(gameport); 3143 struct snd_trident *chip = gameport_get_port_data(gameport);
3141 3144
3142 snd_assert(chip, return); 3145 if (snd_BUG_ON(!chip))
3146 return;
3143 outb(0xff, TRID_REG(chip, GAMEPORT_LEGACY)); 3147 outb(0xff, TRID_REG(chip, GAMEPORT_LEGACY));
3144} 3148}
3145 3149
@@ -3148,7 +3152,8 @@ static int snd_trident_gameport_cooked_read(struct gameport *gameport, int *axes
3148 struct snd_trident *chip = gameport_get_port_data(gameport); 3152 struct snd_trident *chip = gameport_get_port_data(gameport);
3149 int i; 3153 int i;
3150 3154
3151 snd_assert(chip, return 0); 3155 if (snd_BUG_ON(!chip))
3156 return 0;
3152 3157
3153 *buttons = (~inb(TRID_REG(chip, GAMEPORT_LEGACY)) >> 4) & 0xf; 3158 *buttons = (~inb(TRID_REG(chip, GAMEPORT_LEGACY)) >> 4) & 0xf;
3154 3159
@@ -3164,7 +3169,8 @@ static int snd_trident_gameport_open(struct gameport *gameport, int mode)
3164{ 3169{
3165 struct snd_trident *chip = gameport_get_port_data(gameport); 3170 struct snd_trident *chip = gameport_get_port_data(gameport);
3166 3171
3167 snd_assert(chip, return 0); 3172 if (snd_BUG_ON(!chip))
3173 return 0;
3168 3174
3169 switch (mode) { 3175 switch (mode) {
3170 case GAMEPORT_MODE_COOKED: 3176 case GAMEPORT_MODE_COOKED:
@@ -3891,8 +3897,8 @@ static void snd_trident_clear_voices(struct snd_trident * trident, unsigned shor
3891{ 3897{
3892 unsigned int i, val, mask[2] = { 0, 0 }; 3898 unsigned int i, val, mask[2] = { 0, 0 };
3893 3899
3894 snd_assert(v_min <= 63, return); 3900 if (snd_BUG_ON(v_min > 63 || v_max > 63))
3895 snd_assert(v_max <= 63, return); 3901 return;
3896 for (i = v_min; i <= v_max; i++) 3902 for (i = v_min; i <= v_max; i++)
3897 mask[i >> 5] |= 1 << (i & 0x1f); 3903 mask[i >> 5] |= 1 << (i & 0x1f);
3898 if (mask[0]) { 3904 if (mask[0]) {
diff --git a/sound/pci/trident/trident_memory.c b/sound/pci/trident/trident_memory.c
index 3fd7f1b29b0f..f9779e23fe57 100644
--- a/sound/pci/trident/trident_memory.c
+++ b/sound/pci/trident/trident_memory.c
@@ -194,11 +194,14 @@ snd_trident_alloc_sg_pages(struct snd_trident *trident,
194 struct snd_util_memblk *blk; 194 struct snd_util_memblk *blk;
195 struct snd_pcm_runtime *runtime = substream->runtime; 195 struct snd_pcm_runtime *runtime = substream->runtime;
196 int idx, page; 196 int idx, page;
197 struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream);
198 197
199 snd_assert(runtime->dma_bytes > 0 && runtime->dma_bytes <= SNDRV_TRIDENT_MAX_PAGES * SNDRV_TRIDENT_PAGE_SIZE, return NULL); 198 if (snd_BUG_ON(runtime->dma_bytes <= 0 ||
199 runtime->dma_bytes > SNDRV_TRIDENT_MAX_PAGES *
200 SNDRV_TRIDENT_PAGE_SIZE))
201 return NULL;
200 hdr = trident->tlb.memhdr; 202 hdr = trident->tlb.memhdr;
201 snd_assert(hdr != NULL, return NULL); 203 if (snd_BUG_ON(!hdr))
204 return NULL;
202 205
203 206
204 207
@@ -208,18 +211,14 @@ snd_trident_alloc_sg_pages(struct snd_trident *trident,
208 mutex_unlock(&hdr->block_mutex); 211 mutex_unlock(&hdr->block_mutex);
209 return NULL; 212 return NULL;
210 } 213 }
211 if (lastpg(blk) - firstpg(blk) >= sgbuf->pages) {
212 snd_printk(KERN_ERR "page calculation doesn't match: allocated pages = %d, trident = %d/%d\n", sgbuf->pages, firstpg(blk), lastpg(blk));
213 __snd_util_mem_free(hdr, blk);
214 mutex_unlock(&hdr->block_mutex);
215 return NULL;
216 }
217 214
218 /* set TLB entries */ 215 /* set TLB entries */
219 idx = 0; 216 idx = 0;
220 for (page = firstpg(blk); page <= lastpg(blk); page++, idx++) { 217 for (page = firstpg(blk); page <= lastpg(blk); page++, idx++) {
221 dma_addr_t addr = sgbuf->table[idx].addr; 218 unsigned long ofs = idx << PAGE_SHIFT;
222 unsigned long ptr = (unsigned long)sgbuf->table[idx].buf; 219 dma_addr_t addr = snd_pcm_sgbuf_get_addr(substream, ofs);
220 unsigned long ptr = (unsigned long)
221 snd_pcm_sgbuf_get_ptr(substream, ofs);
223 if (! is_valid_page(addr)) { 222 if (! is_valid_page(addr)) {
224 __snd_util_mem_free(hdr, blk); 223 __snd_util_mem_free(hdr, blk);
225 mutex_unlock(&hdr->block_mutex); 224 mutex_unlock(&hdr->block_mutex);
@@ -245,9 +244,13 @@ snd_trident_alloc_cont_pages(struct snd_trident *trident,
245 dma_addr_t addr; 244 dma_addr_t addr;
246 unsigned long ptr; 245 unsigned long ptr;
247 246
248 snd_assert(runtime->dma_bytes> 0 && runtime->dma_bytes <= SNDRV_TRIDENT_MAX_PAGES * SNDRV_TRIDENT_PAGE_SIZE, return NULL); 247 if (snd_BUG_ON(runtime->dma_bytes <= 0 ||
248 runtime->dma_bytes > SNDRV_TRIDENT_MAX_PAGES *
249 SNDRV_TRIDENT_PAGE_SIZE))
250 return NULL;
249 hdr = trident->tlb.memhdr; 251 hdr = trident->tlb.memhdr;
250 snd_assert(hdr != NULL, return NULL); 252 if (snd_BUG_ON(!hdr))
253 return NULL;
251 254
252 mutex_lock(&hdr->block_mutex); 255 mutex_lock(&hdr->block_mutex);
253 blk = search_empty(hdr, runtime->dma_bytes); 256 blk = search_empty(hdr, runtime->dma_bytes);
@@ -279,8 +282,8 @@ struct snd_util_memblk *
279snd_trident_alloc_pages(struct snd_trident *trident, 282snd_trident_alloc_pages(struct snd_trident *trident,
280 struct snd_pcm_substream *substream) 283 struct snd_pcm_substream *substream)
281{ 284{
282 snd_assert(trident != NULL, return NULL); 285 if (snd_BUG_ON(!trident || !substream))
283 snd_assert(substream != NULL, return NULL); 286 return NULL;
284 if (substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV_SG) 287 if (substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV_SG)
285 return snd_trident_alloc_sg_pages(trident, substream); 288 return snd_trident_alloc_sg_pages(trident, substream);
286 else 289 else
@@ -297,8 +300,8 @@ int snd_trident_free_pages(struct snd_trident *trident,
297 struct snd_util_memhdr *hdr; 300 struct snd_util_memhdr *hdr;
298 int page; 301 int page;
299 302
300 snd_assert(trident != NULL, return -EINVAL); 303 if (snd_BUG_ON(!trident || !blk))
301 snd_assert(blk != NULL, return -EINVAL); 304 return -EINVAL;
302 305
303 hdr = trident->tlb.memhdr; 306 hdr = trident->tlb.memhdr;
304 mutex_lock(&hdr->block_mutex); 307 mutex_lock(&hdr->block_mutex);
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index 6781be9e3078..1aafe956ee2b 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -313,6 +313,7 @@ struct snd_via_sg_table {
313} ; 313} ;
314 314
315#define VIA_TABLE_SIZE 255 315#define VIA_TABLE_SIZE 255
316#define VIA_MAX_BUFSIZE (1<<24)
316 317
317struct viadev { 318struct viadev {
318 unsigned int reg_offset; 319 unsigned int reg_offset;
@@ -420,7 +421,6 @@ static int build_via_table(struct viadev *dev, struct snd_pcm_substream *substre
420{ 421{
421 unsigned int i, idx, ofs, rest; 422 unsigned int i, idx, ofs, rest;
422 struct via82xx *chip = snd_pcm_substream_chip(substream); 423 struct via82xx *chip = snd_pcm_substream_chip(substream);
423 struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream);
424 424
425 if (dev->table.area == NULL) { 425 if (dev->table.area == NULL) {
426 /* the start of each lists must be aligned to 8 bytes, 426 /* the start of each lists must be aligned to 8 bytes,
@@ -449,15 +449,15 @@ static int build_via_table(struct viadev *dev, struct snd_pcm_substream *substre
449 do { 449 do {
450 unsigned int r; 450 unsigned int r;
451 unsigned int flag; 451 unsigned int flag;
452 unsigned int addr;
452 453
453 if (idx >= VIA_TABLE_SIZE) { 454 if (idx >= VIA_TABLE_SIZE) {
454 snd_printk(KERN_ERR "via82xx: too much table size!\n"); 455 snd_printk(KERN_ERR "via82xx: too much table size!\n");
455 return -EINVAL; 456 return -EINVAL;
456 } 457 }
457 ((u32 *)dev->table.area)[idx << 1] = cpu_to_le32((u32)snd_pcm_sgbuf_get_addr(sgbuf, ofs)); 458 addr = snd_pcm_sgbuf_get_addr(substream, ofs);
458 r = PAGE_SIZE - (ofs % PAGE_SIZE); 459 ((u32 *)dev->table.area)[idx << 1] = cpu_to_le32(addr);
459 if (rest < r) 460 r = snd_pcm_sgbuf_get_chunk_size(substream, ofs, rest);
460 r = rest;
461 rest -= r; 461 rest -= r;
462 if (! rest) { 462 if (! rest) {
463 if (i == periods - 1) 463 if (i == periods - 1)
@@ -824,7 +824,8 @@ static snd_pcm_uframes_t snd_via686_pcm_pointer(struct snd_pcm_substream *substr
824 struct viadev *viadev = substream->runtime->private_data; 824 struct viadev *viadev = substream->runtime->private_data;
825 unsigned int idx, ptr, count, res; 825 unsigned int idx, ptr, count, res;
826 826
827 snd_assert(viadev->tbl_entries, return 0); 827 if (snd_BUG_ON(!viadev->tbl_entries))
828 return 0;
828 if (!(inb(VIADEV_REG(viadev, OFFSET_STATUS)) & VIA_REG_STAT_ACTIVE)) 829 if (!(inb(VIADEV_REG(viadev, OFFSET_STATUS)) & VIA_REG_STAT_ACTIVE))
829 return 0; 830 return 0;
830 831
@@ -855,7 +856,8 @@ static snd_pcm_uframes_t snd_via8233_pcm_pointer(struct snd_pcm_substream *subst
855 unsigned int idx, count, res; 856 unsigned int idx, count, res;
856 int status; 857 int status;
857 858
858 snd_assert(viadev->tbl_entries, return 0); 859 if (snd_BUG_ON(!viadev->tbl_entries))
860 return 0;
859 861
860 spin_lock(&chip->reg_lock); 862 spin_lock(&chip->reg_lock);
861 count = inl(VIADEV_REG(viadev, OFFSET_CURR_COUNT)); 863 count = inl(VIADEV_REG(viadev, OFFSET_CURR_COUNT));
@@ -1037,7 +1039,7 @@ static int snd_via8233_playback_prepare(struct snd_pcm_substream *substream)
1037 else 1039 else
1038 rbits = (0x100000 / 48000) * runtime->rate + 1040 rbits = (0x100000 / 48000) * runtime->rate +
1039 ((0x100000 % 48000) * runtime->rate) / 48000; 1041 ((0x100000 % 48000) * runtime->rate) / 48000;
1040 snd_assert((rbits & ~0xfffff) == 0, return -EINVAL); 1042 snd_BUG_ON(rbits & ~0xfffff);
1041 snd_via82xx_channel_reset(chip, viadev); 1043 snd_via82xx_channel_reset(chip, viadev);
1042 snd_via82xx_set_table_ptr(chip, viadev); 1044 snd_via82xx_set_table_ptr(chip, viadev);
1043 outb(chip->playback_volume[viadev->reg_offset / 0x10][0], 1045 outb(chip->playback_volume[viadev->reg_offset / 0x10][0],
@@ -1144,9 +1146,9 @@ static struct snd_pcm_hardware snd_via82xx_hw =
1144 .rate_max = 48000, 1146 .rate_max = 48000,
1145 .channels_min = 1, 1147 .channels_min = 1,
1146 .channels_max = 2, 1148 .channels_max = 2,
1147 .buffer_bytes_max = 128 * 1024, 1149 .buffer_bytes_max = VIA_MAX_BUFSIZE,
1148 .period_bytes_min = 32, 1150 .period_bytes_min = 32,
1149 .period_bytes_max = 128 * 1024, 1151 .period_bytes_max = VIA_MAX_BUFSIZE / 2,
1150 .periods_min = 2, 1152 .periods_min = 2,
1151 .periods_max = VIA_TABLE_SIZE / 2, 1153 .periods_max = VIA_TABLE_SIZE / 2,
1152 .fifo_size = 0, 1154 .fifo_size = 0,
@@ -1398,10 +1400,9 @@ static int __devinit snd_via8233_pcm_new(struct via82xx *chip)
1398 /* capture */ 1400 /* capture */
1399 init_viadev(chip, chip->capture_devno, VIA_REG_CAPTURE_8233_STATUS, 6, 1); 1401 init_viadev(chip, chip->capture_devno, VIA_REG_CAPTURE_8233_STATUS, 6, 1);
1400 1402
1401 if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG, 1403 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
1402 snd_dma_pci_data(chip->pci), 1404 snd_dma_pci_data(chip->pci),
1403 64*1024, 128*1024)) < 0) 1405 64*1024, VIA_MAX_BUFSIZE);
1404 return err;
1405 1406
1406 /* PCM #1: multi-channel playback and 2nd capture */ 1407 /* PCM #1: multi-channel playback and 2nd capture */
1407 err = snd_pcm_new(chip->card, chip->card->shortname, 1, 1, 1, &pcm); 1408 err = snd_pcm_new(chip->card, chip->card->shortname, 1, 1, 1, &pcm);
@@ -1417,11 +1418,9 @@ static int __devinit snd_via8233_pcm_new(struct via82xx *chip)
1417 /* set up capture */ 1418 /* set up capture */
1418 init_viadev(chip, chip->capture_devno + 1, VIA_REG_CAPTURE_8233_STATUS + 0x10, 7, 1); 1419 init_viadev(chip, chip->capture_devno + 1, VIA_REG_CAPTURE_8233_STATUS + 0x10, 7, 1);
1419 1420
1420 if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG, 1421 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
1421 snd_dma_pci_data(chip->pci), 1422 snd_dma_pci_data(chip->pci),
1422 64*1024, 128*1024)) < 0) 1423 64*1024, VIA_MAX_BUFSIZE);
1423 return err;
1424
1425 return 0; 1424 return 0;
1426} 1425}
1427 1426
@@ -1453,10 +1452,9 @@ static int __devinit snd_via8233a_pcm_new(struct via82xx *chip)
1453 /* capture */ 1452 /* capture */
1454 init_viadev(chip, chip->capture_devno, VIA_REG_CAPTURE_8233_STATUS, 6, 1); 1453 init_viadev(chip, chip->capture_devno, VIA_REG_CAPTURE_8233_STATUS, 6, 1);
1455 1454
1456 if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG, 1455 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
1457 snd_dma_pci_data(chip->pci), 1456 snd_dma_pci_data(chip->pci),
1458 64*1024, 128*1024)) < 0) 1457 64*1024, VIA_MAX_BUFSIZE);
1459 return err;
1460 1458
1461 /* SPDIF supported? */ 1459 /* SPDIF supported? */
1462 if (! ac97_can_spdif(chip->ac97)) 1460 if (! ac97_can_spdif(chip->ac97))
@@ -1473,11 +1471,9 @@ static int __devinit snd_via8233a_pcm_new(struct via82xx *chip)
1473 /* set up playback */ 1471 /* set up playback */
1474 init_viadev(chip, chip->playback_devno, 0x30, 3, 0); 1472 init_viadev(chip, chip->playback_devno, 0x30, 3, 0);
1475 1473
1476 if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG, 1474 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
1477 snd_dma_pci_data(chip->pci), 1475 snd_dma_pci_data(chip->pci),
1478 64*1024, 128*1024)) < 0) 1476 64*1024, VIA_MAX_BUFSIZE);
1479 return err;
1480
1481 return 0; 1477 return 0;
1482} 1478}
1483 1479
@@ -1505,11 +1501,9 @@ static int __devinit snd_via686_pcm_new(struct via82xx *chip)
1505 init_viadev(chip, 0, VIA_REG_PLAYBACK_STATUS, 0, 0); 1501 init_viadev(chip, 0, VIA_REG_PLAYBACK_STATUS, 0, 0);
1506 init_viadev(chip, 1, VIA_REG_CAPTURE_STATUS, 0, 1); 1502 init_viadev(chip, 1, VIA_REG_CAPTURE_STATUS, 0, 1);
1507 1503
1508 if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG, 1504 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
1509 snd_dma_pci_data(chip->pci), 1505 snd_dma_pci_data(chip->pci),
1510 64*1024, 128*1024)) < 0) 1506 64*1024, VIA_MAX_BUFSIZE);
1511 return err;
1512
1513 return 0; 1507 return 0;
1514} 1508}
1515 1509
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c
index 31f64ee39882..5bd79d2a5a15 100644
--- a/sound/pci/via82xx_modem.c
+++ b/sound/pci/via82xx_modem.c
@@ -281,7 +281,6 @@ static int build_via_table(struct viadev *dev, struct snd_pcm_substream *substre
281{ 281{
282 unsigned int i, idx, ofs, rest; 282 unsigned int i, idx, ofs, rest;
283 struct via82xx_modem *chip = snd_pcm_substream_chip(substream); 283 struct via82xx_modem *chip = snd_pcm_substream_chip(substream);
284 struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream);
285 284
286 if (dev->table.area == NULL) { 285 if (dev->table.area == NULL) {
287 /* the start of each lists must be aligned to 8 bytes, 286 /* the start of each lists must be aligned to 8 bytes,
@@ -310,12 +309,14 @@ static int build_via_table(struct viadev *dev, struct snd_pcm_substream *substre
310 do { 309 do {
311 unsigned int r; 310 unsigned int r;
312 unsigned int flag; 311 unsigned int flag;
312 unsigned int addr;
313 313
314 if (idx >= VIA_TABLE_SIZE) { 314 if (idx >= VIA_TABLE_SIZE) {
315 snd_printk(KERN_ERR "via82xx: too much table size!\n"); 315 snd_printk(KERN_ERR "via82xx: too much table size!\n");
316 return -EINVAL; 316 return -EINVAL;
317 } 317 }
318 ((u32 *)dev->table.area)[idx << 1] = cpu_to_le32((u32)snd_pcm_sgbuf_get_addr(sgbuf, ofs)); 318 addr = snd_pcm_sgbuf_get_addr(substream, ofs);
319 ((u32 *)dev->table.area)[idx << 1] = cpu_to_le32(addr);
319 r = PAGE_SIZE - (ofs % PAGE_SIZE); 320 r = PAGE_SIZE - (ofs % PAGE_SIZE);
320 if (rest < r) 321 if (rest < r)
321 r = rest; 322 r = rest;
@@ -612,7 +613,8 @@ static snd_pcm_uframes_t snd_via686_pcm_pointer(struct snd_pcm_substream *substr
612 struct viadev *viadev = substream->runtime->private_data; 613 struct viadev *viadev = substream->runtime->private_data;
613 unsigned int idx, ptr, count, res; 614 unsigned int idx, ptr, count, res;
614 615
615 snd_assert(viadev->tbl_entries, return 0); 616 if (snd_BUG_ON(!viadev->tbl_entries))
617 return 0;
616 if (!(inb(VIADEV_REG(viadev, OFFSET_STATUS)) & VIA_REG_STAT_ACTIVE)) 618 if (!(inb(VIADEV_REG(viadev, OFFSET_STATUS)) & VIA_REG_STAT_ACTIVE))
617 return 0; 619 return 0;
618 620
diff --git a/sound/pci/vx222/vx222_ops.c b/sound/pci/vx222/vx222_ops.c
index 631f3a639993..7e87f398ff0b 100644
--- a/sound/pci/vx222/vx222_ops.c
+++ b/sound/pci/vx222/vx222_ops.c
@@ -253,7 +253,8 @@ static void vx2_dma_write(struct vx_core *chip, struct snd_pcm_runtime *runtime,
253 int offset = pipe->hw_ptr; 253 int offset = pipe->hw_ptr;
254 u32 *addr = (u32 *)(runtime->dma_area + offset); 254 u32 *addr = (u32 *)(runtime->dma_area + offset);
255 255
256 snd_assert(count % 4 == 0, return); 256 if (snd_BUG_ON(count % 4))
257 return;
257 258
258 vx2_setup_pseudo_dma(chip, 1); 259 vx2_setup_pseudo_dma(chip, 1);
259 260
@@ -291,7 +292,8 @@ static void vx2_dma_read(struct vx_core *chip, struct snd_pcm_runtime *runtime,
291 u32 *addr = (u32 *)(runtime->dma_area + offset); 292 u32 *addr = (u32 *)(runtime->dma_area + offset);
292 unsigned long port = vx2_reg_addr(chip, VX_DMA); 293 unsigned long port = vx2_reg_addr(chip, VX_DMA);
293 294
294 snd_assert(count % 4 == 0, return); 295 if (snd_BUG_ON(count % 4))
296 return;
295 297
296 vx2_setup_pseudo_dma(chip, 0); 298 vx2_setup_pseudo_dma(chip, 0);
297 /* Transfer using pseudo-dma. 299 /* Transfer using pseudo-dma.
@@ -675,7 +677,8 @@ static void vx2_write_akm(struct vx_core *chip, int reg, unsigned int data)
675 a look up table, as there is no linear matching between the driver codec values 677 a look up table, as there is no linear matching between the driver codec values
676 and the real dBu value 678 and the real dBu value
677 */ 679 */
678 snd_assert(data < sizeof(vx2_akm_gains_lut), return); 680 if (snd_BUG_ON(data >= sizeof(vx2_akm_gains_lut)))
681 return;
679 682
680 switch (reg) { 683 switch (reg) {
681 case XX_CODEC_LEVEL_LEFT_REGISTER: 684 case XX_CODEC_LEVEL_LEFT_REGISTER:
@@ -823,7 +826,8 @@ static void vx2_set_input_level(struct snd_vx222 *chip)
823 preamp++; /* raise pre ampli + 18dB */ 826 preamp++; /* raise pre ampli + 18dB */
824 miclevel -= (18 * 2); /* lower level 18 dB (*2 because of 0.5 dB steps !) */ 827 miclevel -= (18 * 2); /* lower level 18 dB (*2 because of 0.5 dB steps !) */
825 } 828 }
826 snd_assert(preamp < 4, return); 829 if (snd_BUG_ON(preamp >= 4))
830 return;
827 831
828 /* set pre-amp level */ 832 /* set pre-amp level */
829 chip->regSELMIC &= ~MICRO_SELECT_PREAMPLI_MASK; 833 chip->regSELMIC &= ~MICRO_SELECT_PREAMPLI_MASK;
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
index 92d49aadf579..90d0d62bd0b4 100644
--- a/sound/pci/ymfpci/ymfpci_main.c
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -259,8 +259,10 @@ static int snd_ymfpci_voice_alloc(struct snd_ymfpci *chip,
259 unsigned long flags; 259 unsigned long flags;
260 int result; 260 int result;
261 261
262 snd_assert(rvoice != NULL, return -EINVAL); 262 if (snd_BUG_ON(!rvoice))
263 snd_assert(!pair || type == YMFPCI_PCM, return -EINVAL); 263 return -EINVAL;
264 if (snd_BUG_ON(pair && type != YMFPCI_PCM))
265 return -EINVAL;
264 266
265 spin_lock_irqsave(&chip->voice_lock, flags); 267 spin_lock_irqsave(&chip->voice_lock, flags);
266 for (;;) { 268 for (;;) {
@@ -278,7 +280,8 @@ static int snd_ymfpci_voice_free(struct snd_ymfpci *chip, struct snd_ymfpci_voic
278{ 280{
279 unsigned long flags; 281 unsigned long flags;
280 282
281 snd_assert(pvoice != NULL, return -EINVAL); 283 if (snd_BUG_ON(!pvoice))
284 return -EINVAL;
282 snd_ymfpci_hw_stop(chip); 285 snd_ymfpci_hw_stop(chip);
283 spin_lock_irqsave(&chip->voice_lock, flags); 286 spin_lock_irqsave(&chip->voice_lock, flags);
284 if (pvoice->number == chip->src441_used) { 287 if (pvoice->number == chip->src441_used) {
@@ -494,7 +497,8 @@ static void snd_ymfpci_pcm_init_voice(struct snd_ymfpci_pcm *ypcm, unsigned int
494 u8 use_left, use_right; 497 u8 use_left, use_right;
495 unsigned long flags; 498 unsigned long flags;
496 499
497 snd_assert(voice != NULL, return); 500 if (snd_BUG_ON(!voice))
501 return;
498 if (runtime->channels == 1) { 502 if (runtime->channels == 1) {
499 use_left = 1; 503 use_left = 1;
500 use_right = 1; 504 use_right = 1;
@@ -1813,7 +1817,8 @@ int __devinit snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch)
1813 } 1817 }
1814 1818
1815 /* add S/PDIF control */ 1819 /* add S/PDIF control */
1816 snd_assert(chip->pcm_spdif != NULL, return -EIO); 1820 if (snd_BUG_ON(!chip->pcm_spdif))
1821 return -ENXIO;
1817 if ((err = snd_ctl_add(chip->card, kctl = snd_ctl_new1(&snd_ymfpci_spdif_default, chip))) < 0) 1822 if ((err = snd_ctl_add(chip->card, kctl = snd_ctl_new1(&snd_ymfpci_spdif_default, chip))) < 0)
1818 return err; 1823 return err;
1819 kctl->id.device = chip->pcm_spdif->device; 1824 kctl->id.device = chip->pcm_spdif->device;
@@ -2133,7 +2138,8 @@ static int __devinit snd_ymfpci_memalloc(struct snd_ymfpci *chip)
2133 chip->work_base = ptr; 2138 chip->work_base = ptr;
2134 chip->work_base_addr = ptr_addr; 2139 chip->work_base_addr = ptr_addr;
2135 2140
2136 snd_assert(ptr + chip->work_size == chip->work_ptr.area + chip->work_ptr.bytes, ); 2141 snd_BUG_ON(ptr + chip->work_size !=
2142 chip->work_ptr.area + chip->work_ptr.bytes);
2137 2143
2138 snd_ymfpci_writel(chip, YDSXGR_PLAYCTRLBASE, chip->bank_base_playback_addr); 2144 snd_ymfpci_writel(chip, YDSXGR_PLAYCTRLBASE, chip->bank_base_playback_addr);
2139 snd_ymfpci_writel(chip, YDSXGR_RECCTRLBASE, chip->bank_base_capture_addr); 2145 snd_ymfpci_writel(chip, YDSXGR_RECCTRLBASE, chip->bank_base_capture_addr);
@@ -2168,7 +2174,8 @@ static int snd_ymfpci_free(struct snd_ymfpci *chip)
2168{ 2174{
2169 u16 ctrl; 2175 u16 ctrl;
2170 2176
2171 snd_assert(chip != NULL, return -EINVAL); 2177 if (snd_BUG_ON(!chip))
2178 return -EINVAL;
2172 2179
2173 if (chip->res_reg_area) { /* don't touch busy hardware */ 2180 if (chip->res_reg_area) { /* don't touch busy hardware */
2174 snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0); 2181 snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0);
diff --git a/sound/pcmcia/vx/vxp_ops.c b/sound/pcmcia/vx/vxp_ops.c
index 99bf2a65a6f5..989e04abb520 100644
--- a/sound/pcmcia/vx/vxp_ops.c
+++ b/sound/pcmcia/vx/vxp_ops.c
@@ -408,7 +408,8 @@ static void vxp_dma_read(struct vx_core *chip, struct snd_pcm_runtime *runtime,
408 int offset = pipe->hw_ptr; 408 int offset = pipe->hw_ptr;
409 unsigned short *addr = (unsigned short *)(runtime->dma_area + offset); 409 unsigned short *addr = (unsigned short *)(runtime->dma_area + offset);
410 410
411 snd_assert(count % 2 == 0, return); 411 if (snd_BUG_ON(count % 2))
412 return;
412 vx_setup_pseudo_dma(chip, 0); 413 vx_setup_pseudo_dma(chip, 0);
413 if (offset + count > pipe->buffer_bytes) { 414 if (offset + count > pipe->buffer_bytes) {
414 int length = pipe->buffer_bytes - offset; 415 int length = pipe->buffer_bytes - offset;
diff --git a/sound/ppc/awacs.c b/sound/ppc/awacs.c
index 566a6d0daf4a..7bd33e6552ab 100644
--- a/sound/ppc/awacs.c
+++ b/sound/ppc/awacs.c
@@ -319,7 +319,8 @@ static void awacs_amp_set_master(struct awacs_amp *amp, int vol)
319static void awacs_amp_free(struct snd_pmac *chip) 319static void awacs_amp_free(struct snd_pmac *chip)
320{ 320{
321 struct awacs_amp *amp = chip->mixer_data; 321 struct awacs_amp *amp = chip->mixer_data;
322 snd_assert(amp, return); 322 if (!amp)
323 return;
323 kfree(amp); 324 kfree(amp);
324 chip->mixer_data = NULL; 325 chip->mixer_data = NULL;
325 chip->mixer_free = NULL; 326 chip->mixer_free = NULL;
@@ -345,8 +346,7 @@ static int snd_pmac_awacs_get_volume_amp(struct snd_kcontrol *kcontrol,
345 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); 346 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
346 int index = kcontrol->private_value; 347 int index = kcontrol->private_value;
347 struct awacs_amp *amp = chip->mixer_data; 348 struct awacs_amp *amp = chip->mixer_data;
348 snd_assert(amp, return -EINVAL); 349
349 snd_assert(index >= 0 && index <= 1, return -EINVAL);
350 ucontrol->value.integer.value[0] = 31 - (amp->amp_vol[index][0] & 31); 350 ucontrol->value.integer.value[0] = 31 - (amp->amp_vol[index][0] & 31);
351 ucontrol->value.integer.value[1] = 31 - (amp->amp_vol[index][1] & 31); 351 ucontrol->value.integer.value[1] = 31 - (amp->amp_vol[index][1] & 31);
352 return 0; 352 return 0;
@@ -359,8 +359,6 @@ static int snd_pmac_awacs_put_volume_amp(struct snd_kcontrol *kcontrol,
359 int index = kcontrol->private_value; 359 int index = kcontrol->private_value;
360 int vol[2]; 360 int vol[2];
361 struct awacs_amp *amp = chip->mixer_data; 361 struct awacs_amp *amp = chip->mixer_data;
362 snd_assert(amp, return -EINVAL);
363 snd_assert(index >= 0 && index <= 1, return -EINVAL);
364 362
365 vol[0] = (31 - (ucontrol->value.integer.value[0] & 31)) 363 vol[0] = (31 - (ucontrol->value.integer.value[0] & 31))
366 | (amp->amp_vol[index][0] & 32); 364 | (amp->amp_vol[index][0] & 32);
@@ -375,8 +373,7 @@ static int snd_pmac_awacs_get_switch_amp(struct snd_kcontrol *kcontrol,
375 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); 373 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
376 int index = kcontrol->private_value; 374 int index = kcontrol->private_value;
377 struct awacs_amp *amp = chip->mixer_data; 375 struct awacs_amp *amp = chip->mixer_data;
378 snd_assert(amp, return -EINVAL); 376
379 snd_assert(index >= 0 && index <= 1, return -EINVAL);
380 ucontrol->value.integer.value[0] = (amp->amp_vol[index][0] & 32) 377 ucontrol->value.integer.value[0] = (amp->amp_vol[index][0] & 32)
381 ? 0 : 1; 378 ? 0 : 1;
382 ucontrol->value.integer.value[1] = (amp->amp_vol[index][1] & 32) 379 ucontrol->value.integer.value[1] = (amp->amp_vol[index][1] & 32)
@@ -391,8 +388,6 @@ static int snd_pmac_awacs_put_switch_amp(struct snd_kcontrol *kcontrol,
391 int index = kcontrol->private_value; 388 int index = kcontrol->private_value;
392 int vol[2]; 389 int vol[2];
393 struct awacs_amp *amp = chip->mixer_data; 390 struct awacs_amp *amp = chip->mixer_data;
394 snd_assert(amp, return -EINVAL);
395 snd_assert(index >= 0 && index <= 1, return -EINVAL);
396 391
397 vol[0] = (ucontrol->value.integer.value[0] ? 0 : 32) 392 vol[0] = (ucontrol->value.integer.value[0] ? 0 : 32)
398 | (amp->amp_vol[index][0] & 31); 393 | (amp->amp_vol[index][0] & 31);
@@ -417,8 +412,7 @@ static int snd_pmac_awacs_get_tone_amp(struct snd_kcontrol *kcontrol,
417 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); 412 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
418 int index = kcontrol->private_value; 413 int index = kcontrol->private_value;
419 struct awacs_amp *amp = chip->mixer_data; 414 struct awacs_amp *amp = chip->mixer_data;
420 snd_assert(amp, return -EINVAL); 415
421 snd_assert(index >= 0 && index <= 1, return -EINVAL);
422 ucontrol->value.integer.value[0] = amp->amp_tone[index]; 416 ucontrol->value.integer.value[0] = amp->amp_tone[index];
423 return 0; 417 return 0;
424} 418}
@@ -430,8 +424,7 @@ static int snd_pmac_awacs_put_tone_amp(struct snd_kcontrol *kcontrol,
430 int index = kcontrol->private_value; 424 int index = kcontrol->private_value;
431 struct awacs_amp *amp = chip->mixer_data; 425 struct awacs_amp *amp = chip->mixer_data;
432 unsigned int val; 426 unsigned int val;
433 snd_assert(amp, return -EINVAL); 427
434 snd_assert(index >= 0 && index <= 1, return -EINVAL);
435 val = ucontrol->value.integer.value[0]; 428 val = ucontrol->value.integer.value[0];
436 if (val > 14) 429 if (val > 14)
437 return -EINVAL; 430 return -EINVAL;
@@ -458,7 +451,7 @@ static int snd_pmac_awacs_get_master_amp(struct snd_kcontrol *kcontrol,
458{ 451{
459 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); 452 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
460 struct awacs_amp *amp = chip->mixer_data; 453 struct awacs_amp *amp = chip->mixer_data;
461 snd_assert(amp, return -EINVAL); 454
462 ucontrol->value.integer.value[0] = amp->amp_master; 455 ucontrol->value.integer.value[0] = amp->amp_master;
463 return 0; 456 return 0;
464} 457}
@@ -469,7 +462,7 @@ static int snd_pmac_awacs_put_master_amp(struct snd_kcontrol *kcontrol,
469 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); 462 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
470 struct awacs_amp *amp = chip->mixer_data; 463 struct awacs_amp *amp = chip->mixer_data;
471 unsigned int val; 464 unsigned int val;
472 snd_assert(amp, return -EINVAL); 465
473 val = ucontrol->value.integer.value[0]; 466 val = ucontrol->value.integer.value[0];
474 if (val > 99) 467 if (val > 99)
475 return -EINVAL; 468 return -EINVAL;
@@ -621,6 +614,13 @@ static struct snd_kcontrol_new snd_pmac_screamer_mixers_imac[] __initdata = {
621 AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0), 614 AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0),
622}; 615};
623 616
617static struct snd_kcontrol_new snd_pmac_screamer_mixers_g4agp[] __initdata = {
618 AWACS_VOLUME("Line out Playback Volume", 2, 6, 1),
619 AWACS_VOLUME("Master Playback Volume", 5, 6, 1),
620 AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0),
621 AWACS_SWITCH("Line Capture Switch", 0, SHIFT_MUX_MIC, 0),
622};
623
624static struct snd_kcontrol_new snd_pmac_awacs_mixers_pmac7500[] __initdata = { 624static struct snd_kcontrol_new snd_pmac_awacs_mixers_pmac7500[] __initdata = {
625 AWACS_VOLUME("Line out Playback Volume", 2, 6, 1), 625 AWACS_VOLUME("Line out Playback Volume", 2, 6, 1),
626 AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0), 626 AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0),
@@ -688,7 +688,10 @@ static struct snd_kcontrol_new snd_pmac_awacs_speaker_vol[] __initdata = {
688static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw __initdata = 688static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw __initdata =
689AWACS_SWITCH("PC Speaker Playback Switch", 1, SHIFT_SPKMUTE, 1); 689AWACS_SWITCH("PC Speaker Playback Switch", 1, SHIFT_SPKMUTE, 1);
690 690
691static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw_imac __initdata = 691static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw_imac1 __initdata =
692AWACS_SWITCH("PC Speaker Playback Switch", 1, SHIFT_PAROUT1, 1);
693
694static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw_imac2 __initdata =
692AWACS_SWITCH("PC Speaker Playback Switch", 1, SHIFT_PAROUT1, 0); 695AWACS_SWITCH("PC Speaker Playback Switch", 1, SHIFT_PAROUT1, 0);
693 696
694 697
@@ -765,11 +768,12 @@ static void snd_pmac_awacs_resume(struct snd_pmac *chip)
765 768
766#define IS_PM7500 (machine_is_compatible("AAPL,7500")) 769#define IS_PM7500 (machine_is_compatible("AAPL,7500"))
767#define IS_BEIGE (machine_is_compatible("AAPL,Gossamer")) 770#define IS_BEIGE (machine_is_compatible("AAPL,Gossamer"))
768#define IS_IMAC (machine_is_compatible("PowerMac2,1") \ 771#define IS_IMAC1 (machine_is_compatible("PowerMac2,1"))
769 || machine_is_compatible("PowerMac2,2") \ 772#define IS_IMAC2 (machine_is_compatible("PowerMac2,2") \
770 || machine_is_compatible("PowerMac4,1")) 773 || machine_is_compatible("PowerMac4,1"))
774#define IS_G4AGP (machine_is_compatible("PowerMac3,1"))
771 775
772static int imac; 776static int imac1, imac2;
773 777
774#ifdef PMAC_SUPPORT_AUTOMUTE 778#ifdef PMAC_SUPPORT_AUTOMUTE
775/* 779/*
@@ -815,13 +819,18 @@ static void snd_pmac_awacs_update_automute(struct snd_pmac *chip, int do_notify)
815 { 819 {
816 int reg = chip->awacs_reg[1] 820 int reg = chip->awacs_reg[1]
817 | (MASK_HDMUTE | MASK_SPKMUTE); 821 | (MASK_HDMUTE | MASK_SPKMUTE);
818 if (imac) { 822 if (imac1) {
823 reg &= ~MASK_SPKMUTE;
824 reg |= MASK_PAROUT1;
825 } else if (imac2) {
819 reg &= ~MASK_SPKMUTE; 826 reg &= ~MASK_SPKMUTE;
820 reg &= ~MASK_PAROUT1; 827 reg &= ~MASK_PAROUT1;
821 } 828 }
822 if (snd_pmac_awacs_detect_headphone(chip)) 829 if (snd_pmac_awacs_detect_headphone(chip))
823 reg &= ~MASK_HDMUTE; 830 reg &= ~MASK_HDMUTE;
824 else if (imac) 831 else if (imac1)
832 reg &= ~MASK_PAROUT1;
833 else if (imac2)
825 reg |= MASK_PAROUT1; 834 reg |= MASK_PAROUT1;
826 else 835 else
827 reg &= ~MASK_SPKMUTE; 836 reg &= ~MASK_SPKMUTE;
@@ -850,9 +859,13 @@ snd_pmac_awacs_init(struct snd_pmac *chip)
850{ 859{
851 int pm7500 = IS_PM7500; 860 int pm7500 = IS_PM7500;
852 int beige = IS_BEIGE; 861 int beige = IS_BEIGE;
862 int g4agp = IS_G4AGP;
863 int imac;
853 int err, vol; 864 int err, vol;
854 865
855 imac = IS_IMAC; 866 imac1 = IS_IMAC1;
867 imac2 = IS_IMAC2;
868 imac = imac1 || imac2;
856 /* looks like MASK_GAINLINE triggers something, so we set here 869 /* looks like MASK_GAINLINE triggers something, so we set here
857 * as start-up 870 * as start-up
858 */ 871 */
@@ -939,7 +952,7 @@ snd_pmac_awacs_init(struct snd_pmac *chip)
939 snd_pmac_awacs_mixers); 952 snd_pmac_awacs_mixers);
940 if (err < 0) 953 if (err < 0)
941 return err; 954 return err;
942 if (beige) 955 if (beige || g4agp)
943 ; 956 ;
944 else if (chip->model == PMAC_SCREAMER) 957 else if (chip->model == PMAC_SCREAMER)
945 err = build_mixers(chip, ARRAY_SIZE(snd_pmac_screamer_mixers2), 958 err = build_mixers(chip, ARRAY_SIZE(snd_pmac_screamer_mixers2),
@@ -961,13 +974,17 @@ snd_pmac_awacs_init(struct snd_pmac *chip)
961 err = build_mixers(chip, 974 err = build_mixers(chip,
962 ARRAY_SIZE(snd_pmac_screamer_mixers_imac), 975 ARRAY_SIZE(snd_pmac_screamer_mixers_imac),
963 snd_pmac_screamer_mixers_imac); 976 snd_pmac_screamer_mixers_imac);
977 else if (g4agp)
978 err = build_mixers(chip,
979 ARRAY_SIZE(snd_pmac_screamer_mixers_g4agp),
980 snd_pmac_screamer_mixers_g4agp);
964 else 981 else
965 err = build_mixers(chip, 982 err = build_mixers(chip,
966 ARRAY_SIZE(snd_pmac_awacs_mixers_pmac), 983 ARRAY_SIZE(snd_pmac_awacs_mixers_pmac),
967 snd_pmac_awacs_mixers_pmac); 984 snd_pmac_awacs_mixers_pmac);
968 if (err < 0) 985 if (err < 0)
969 return err; 986 return err;
970 chip->master_sw_ctl = snd_ctl_new1((pm7500 || imac) 987 chip->master_sw_ctl = snd_ctl_new1((pm7500 || imac || g4agp)
971 ? &snd_pmac_awacs_master_sw_imac 988 ? &snd_pmac_awacs_master_sw_imac
972 : &snd_pmac_awacs_master_sw, chip); 989 : &snd_pmac_awacs_master_sw, chip);
973 err = snd_ctl_add(chip->card, chip->master_sw_ctl); 990 err = snd_ctl_add(chip->card, chip->master_sw_ctl);
@@ -1004,15 +1021,17 @@ snd_pmac_awacs_init(struct snd_pmac *chip)
1004 snd_pmac_awacs_speaker_vol); 1021 snd_pmac_awacs_speaker_vol);
1005 if (err < 0) 1022 if (err < 0)
1006 return err; 1023 return err;
1007 chip->speaker_sw_ctl = snd_ctl_new1(imac 1024 chip->speaker_sw_ctl = snd_ctl_new1(imac1
1008 ? &snd_pmac_awacs_speaker_sw_imac 1025 ? &snd_pmac_awacs_speaker_sw_imac1
1026 : imac2
1027 ? &snd_pmac_awacs_speaker_sw_imac2
1009 : &snd_pmac_awacs_speaker_sw, chip); 1028 : &snd_pmac_awacs_speaker_sw, chip);
1010 err = snd_ctl_add(chip->card, chip->speaker_sw_ctl); 1029 err = snd_ctl_add(chip->card, chip->speaker_sw_ctl);
1011 if (err < 0) 1030 if (err < 0)
1012 return err; 1031 return err;
1013 } 1032 }
1014 1033
1015 if (beige) 1034 if (beige || g4agp)
1016 err = build_mixers(chip, 1035 err = build_mixers(chip,
1017 ARRAY_SIZE(snd_pmac_screamer_mic_boost_beige), 1036 ARRAY_SIZE(snd_pmac_screamer_mic_boost_beige),
1018 snd_pmac_screamer_mic_boost_beige); 1037 snd_pmac_screamer_mic_boost_beige);
diff --git a/sound/ppc/beep.c b/sound/ppc/beep.c
index baa2a7237370..89f5c328acfe 100644
--- a/sound/ppc/beep.c
+++ b/sound/ppc/beep.c
@@ -185,7 +185,8 @@ static int snd_pmac_get_beep(struct snd_kcontrol *kcontrol,
185 struct snd_ctl_elem_value *ucontrol) 185 struct snd_ctl_elem_value *ucontrol)
186{ 186{
187 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); 187 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
188 snd_assert(chip->beep, return -ENXIO); 188 if (snd_BUG_ON(!chip->beep))
189 return -ENXIO;
189 ucontrol->value.integer.value[0] = chip->beep->volume; 190 ucontrol->value.integer.value[0] = chip->beep->volume;
190 return 0; 191 return 0;
191} 192}
@@ -195,7 +196,8 @@ static int snd_pmac_put_beep(struct snd_kcontrol *kcontrol,
195{ 196{
196 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); 197 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
197 unsigned int oval, nval; 198 unsigned int oval, nval;
198 snd_assert(chip->beep, return -ENXIO); 199 if (snd_BUG_ON(!chip->beep))
200 return -ENXIO;
199 oval = chip->beep->volume; 201 oval = chip->beep->volume;
200 nval = ucontrol->value.integer.value[0]; 202 nval = ucontrol->value.integer.value[0];
201 if (nval > 100) 203 if (nval > 100)
diff --git a/sound/ppc/tumbler.c b/sound/ppc/tumbler.c
index 009df8dd37a8..f746e15b8481 100644
--- a/sound/ppc/tumbler.c
+++ b/sound/ppc/tumbler.c
@@ -263,7 +263,7 @@ static int tumbler_get_master_volume(struct snd_kcontrol *kcontrol,
263{ 263{
264 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); 264 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
265 struct pmac_tumbler *mix = chip->mixer_data; 265 struct pmac_tumbler *mix = chip->mixer_data;
266 snd_assert(mix, return -ENODEV); 266
267 ucontrol->value.integer.value[0] = mix->master_vol[0]; 267 ucontrol->value.integer.value[0] = mix->master_vol[0];
268 ucontrol->value.integer.value[1] = mix->master_vol[1]; 268 ucontrol->value.integer.value[1] = mix->master_vol[1];
269 return 0; 269 return 0;
@@ -277,7 +277,6 @@ static int tumbler_put_master_volume(struct snd_kcontrol *kcontrol,
277 unsigned int vol[2]; 277 unsigned int vol[2];
278 int change; 278 int change;
279 279
280 snd_assert(mix, return -ENODEV);
281 vol[0] = ucontrol->value.integer.value[0]; 280 vol[0] = ucontrol->value.integer.value[0];
282 vol[1] = ucontrol->value.integer.value[1]; 281 vol[1] = ucontrol->value.integer.value[1];
283 if (vol[0] >= ARRAY_SIZE(master_volume_table) || 282 if (vol[0] >= ARRAY_SIZE(master_volume_table) ||
@@ -299,7 +298,7 @@ static int tumbler_get_master_switch(struct snd_kcontrol *kcontrol,
299{ 298{
300 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); 299 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
301 struct pmac_tumbler *mix = chip->mixer_data; 300 struct pmac_tumbler *mix = chip->mixer_data;
302 snd_assert(mix, return -ENODEV); 301
303 ucontrol->value.integer.value[0] = mix->master_switch[0]; 302 ucontrol->value.integer.value[0] = mix->master_switch[0];
304 ucontrol->value.integer.value[1] = mix->master_switch[1]; 303 ucontrol->value.integer.value[1] = mix->master_switch[1];
305 return 0; 304 return 0;
@@ -312,7 +311,6 @@ static int tumbler_put_master_switch(struct snd_kcontrol *kcontrol,
312 struct pmac_tumbler *mix = chip->mixer_data; 311 struct pmac_tumbler *mix = chip->mixer_data;
313 int change; 312 int change;
314 313
315 snd_assert(mix, return -ENODEV);
316 change = mix->master_switch[0] != ucontrol->value.integer.value[0] || 314 change = mix->master_switch[0] != ucontrol->value.integer.value[0] ||
317 mix->master_switch[1] != ucontrol->value.integer.value[1]; 315 mix->master_switch[1] != ucontrol->value.integer.value[1];
318 if (change) { 316 if (change) {
@@ -807,7 +805,6 @@ static int snapper_get_capture_source(struct snd_kcontrol *kcontrol,
807 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); 805 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
808 struct pmac_tumbler *mix = chip->mixer_data; 806 struct pmac_tumbler *mix = chip->mixer_data;
809 807
810 snd_assert(mix, return -ENODEV);
811 ucontrol->value.enumerated.item[0] = mix->capture_source; 808 ucontrol->value.enumerated.item[0] = mix->capture_source;
812 return 0; 809 return 0;
813} 810}
@@ -819,7 +816,6 @@ static int snapper_put_capture_source(struct snd_kcontrol *kcontrol,
819 struct pmac_tumbler *mix = chip->mixer_data; 816 struct pmac_tumbler *mix = chip->mixer_data;
820 int change; 817 int change;
821 818
822 snd_assert(mix, return -ENODEV);
823 change = ucontrol->value.enumerated.item[0] != mix->capture_source; 819 change = ucontrol->value.enumerated.item[0] != mix->capture_source;
824 if (change) { 820 if (change) {
825 mix->capture_source = !!ucontrol->value.enumerated.item[0]; 821 mix->capture_source = !!ucontrol->value.enumerated.item[0];
@@ -978,7 +974,8 @@ static void device_change_handler(struct work_struct *work)
978 return; 974 return;
979 975
980 mix = chip->mixer_data; 976 mix = chip->mixer_data;
981 snd_assert(mix, return); 977 if (snd_BUG_ON(!mix))
978 return;
982 979
983 headphone = tumbler_detect_headphone(chip); 980 headphone = tumbler_detect_headphone(chip);
984 lineout = tumbler_detect_lineout(chip); 981 lineout = tumbler_detect_lineout(chip);
@@ -1033,7 +1030,8 @@ static void tumbler_update_automute(struct snd_pmac *chip, int do_notify)
1033 if (chip->auto_mute) { 1030 if (chip->auto_mute) {
1034 struct pmac_tumbler *mix; 1031 struct pmac_tumbler *mix;
1035 mix = chip->mixer_data; 1032 mix = chip->mixer_data;
1036 snd_assert(mix, return); 1033 if (snd_BUG_ON(!mix))
1034 return;
1037 mix->auto_mute_notify = do_notify; 1035 mix->auto_mute_notify = do_notify;
1038 schedule_work(&device_change); 1036 schedule_work(&device_change);
1039 } 1037 }
@@ -1227,8 +1225,6 @@ static void tumbler_resume(struct snd_pmac *chip)
1227{ 1225{
1228 struct pmac_tumbler *mix = chip->mixer_data; 1226 struct pmac_tumbler *mix = chip->mixer_data;
1229 1227
1230 snd_assert(mix, return);
1231
1232 mix->acs &= ~1; 1228 mix->acs &= ~1;
1233 mix->master_switch[0] = mix->save_master_switch[0]; 1229 mix->master_switch[0] = mix->save_master_switch[0];
1234 mix->master_switch[1] = mix->save_master_switch[1]; 1230 mix->master_switch[1] = mix->save_master_switch[1];
@@ -1275,7 +1271,6 @@ static int __init tumbler_init(struct snd_pmac *chip)
1275{ 1271{
1276 int irq; 1272 int irq;
1277 struct pmac_tumbler *mix = chip->mixer_data; 1273 struct pmac_tumbler *mix = chip->mixer_data;
1278 snd_assert(mix, return -EINVAL);
1279 1274
1280 if (tumbler_find_device("audio-hw-reset", 1275 if (tumbler_find_device("audio-hw-reset",
1281 "platform-do-hw-reset", 1276 "platform-do-hw-reset",
diff --git a/sound/sh/aica.c b/sound/sh/aica.c
index 54df8baf916f..7c920f3e7fe3 100644
--- a/sound/sh/aica.c
+++ b/sound/sh/aica.c
@@ -106,7 +106,8 @@ static void spu_memset(u32 toi, u32 what, int length)
106{ 106{
107 int i; 107 int i;
108 unsigned long flags; 108 unsigned long flags;
109 snd_assert(length % 4 == 0, return); 109 if (snd_BUG_ON(length % 4))
110 return;
110 for (i = 0; i < length; i++) { 111 for (i = 0; i < length; i++) {
111 if (!(i % 8)) 112 if (!(i % 8))
112 spu_write_wait(); 113 spu_write_wait();
@@ -589,7 +590,7 @@ static int __devinit add_aicamixer_controls(struct snd_card_aica
589 return 0; 590 return 0;
590} 591}
591 592
592static int snd_aica_remove(struct platform_device *devptr) 593static int __devexit snd_aica_remove(struct platform_device *devptr)
593{ 594{
594 struct snd_card_aica *dreamcastcard; 595 struct snd_card_aica *dreamcastcard;
595 dreamcastcard = platform_get_drvdata(devptr); 596 dreamcastcard = platform_get_drvdata(devptr);
@@ -601,7 +602,7 @@ static int snd_aica_remove(struct platform_device *devptr)
601 return 0; 602 return 0;
602} 603}
603 604
604static int __init snd_aica_probe(struct platform_device *devptr) 605static int __devinit snd_aica_probe(struct platform_device *devptr)
605{ 606{
606 int err; 607 int err;
607 struct snd_card_aica *dreamcastcard; 608 struct snd_card_aica *dreamcastcard;
@@ -650,7 +651,7 @@ static int __init snd_aica_probe(struct platform_device *devptr)
650 651
651static struct platform_driver snd_aica_driver = { 652static struct platform_driver snd_aica_driver = {
652 .probe = snd_aica_probe, 653 .probe = snd_aica_probe,
653 .remove = snd_aica_remove, 654 .remove = __devexit_p(snd_aica_remove),
654 .driver = { 655 .driver = {
655 .name = SND_AICA_DRIVER}, 656 .name = SND_AICA_DRIVER},
656}; 657};
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index f743530add8f..4dfda6674bec 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -5,6 +5,7 @@
5menuconfig SND_SOC 5menuconfig SND_SOC
6 tristate "ALSA for SoC audio support" 6 tristate "ALSA for SoC audio support"
7 select SND_PCM 7 select SND_PCM
8 select AC97_BUS if SND_SOC_AC97_BUS
8 ---help--- 9 ---help---
9 10
10 If you want ASoC support, you should say Y here and also to the 11 If you want ASoC support, you should say Y here and also to the
@@ -31,6 +32,7 @@ source "sound/soc/sh/Kconfig"
31source "sound/soc/fsl/Kconfig" 32source "sound/soc/fsl/Kconfig"
32source "sound/soc/davinci/Kconfig" 33source "sound/soc/davinci/Kconfig"
33source "sound/soc/omap/Kconfig" 34source "sound/soc/omap/Kconfig"
35source "sound/soc/blackfin/Kconfig"
34 36
35# Supported codecs 37# Supported codecs
36source "sound/soc/codecs/Kconfig" 38source "sound/soc/codecs/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 933a66d30804..d849349f2c66 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -2,4 +2,4 @@ snd-soc-core-objs := soc-core.o soc-dapm.o
2 2
3obj-$(CONFIG_SND_SOC) += snd-soc-core.o 3obj-$(CONFIG_SND_SOC) += snd-soc-core.o
4obj-$(CONFIG_SND_SOC) += codecs/ at32/ at91/ pxa/ s3c24xx/ sh/ fsl/ davinci/ 4obj-$(CONFIG_SND_SOC) += codecs/ at32/ at91/ pxa/ s3c24xx/ sh/ fsl/ davinci/
5obj-$(CONFIG_SND_SOC) += omap/ au1x/ 5obj-$(CONFIG_SND_SOC) += omap/ au1x/ blackfin/
diff --git a/sound/soc/at32/at32-pcm.c b/sound/soc/at32/at32-pcm.c
index 435f1daf177c..c83584f989a9 100644
--- a/sound/soc/at32/at32-pcm.c
+++ b/sound/soc/at32/at32-pcm.c
@@ -434,7 +434,8 @@ static int at32_pcm_suspend(struct platform_device *pdev,
434 params = prtd->params; 434 params = prtd->params;
435 435
436 /* Disable the PDC and save the PDC registers */ 436 /* Disable the PDC and save the PDC registers */
437 ssc_writex(params->ssc->regs, PDC_PTCR, params->mask->pdc_disable); 437 ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
438 params->mask->pdc_disable);
438 439
439 prtd->pdc_xpr_save = ssc_readx(params->ssc->regs, params->pdc->xpr); 440 prtd->pdc_xpr_save = ssc_readx(params->ssc->regs, params->pdc->xpr);
440 prtd->pdc_xcr_save = ssc_readx(params->ssc->regs, params->pdc->xcr); 441 prtd->pdc_xcr_save = ssc_readx(params->ssc->regs, params->pdc->xcr);
@@ -464,7 +465,7 @@ static int at32_pcm_resume(struct platform_device *pdev,
464 ssc_writex(params->ssc->regs, params->pdc->xnpr, prtd->pdc_xnpr_save); 465 ssc_writex(params->ssc->regs, params->pdc->xnpr, prtd->pdc_xnpr_save);
465 ssc_writex(params->ssc->regs, params->pdc->xncr, prtd->pdc_xncr_save); 466 ssc_writex(params->ssc->regs, params->pdc->xncr, prtd->pdc_xncr_save);
466 467
467 ssc_writex(params->ssc->regs, PDC_PTCR, params->mask->pdc_enable); 468 ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR, params->mask->pdc_enable);
468 return 0; 469 return 0;
469} 470}
470#else /* CONFIG_PM */ 471#else /* CONFIG_PM */
diff --git a/sound/soc/at32/playpaq_wm8510.c b/sound/soc/at32/playpaq_wm8510.c
index 3f326219f1ec..98a2d5826a85 100644
--- a/sound/soc/at32/playpaq_wm8510.c
+++ b/sound/soc/at32/playpaq_wm8510.c
@@ -377,6 +377,7 @@ static struct snd_soc_machine snd_soc_machine_playpaq = {
377 377
378 378
379static struct wm8510_setup_data playpaq_wm8510_setup = { 379static struct wm8510_setup_data playpaq_wm8510_setup = {
380 .i2c_bus = 0,
380 .i2c_address = 0x1a, 381 .i2c_address = 0x1a,
381}; 382};
382 383
@@ -405,7 +406,6 @@ static int __init playpaq_asoc_init(void)
405 ssc = ssc_request(0); 406 ssc = ssc_request(0);
406 if (IS_ERR(ssc)) { 407 if (IS_ERR(ssc)) {
407 ret = PTR_ERR(ssc); 408 ret = PTR_ERR(ssc);
408 ssc = NULL;
409 goto err_ssc; 409 goto err_ssc;
410 } 410 }
411 ssc_p->ssc = ssc; 411 ssc_p->ssc = ssc;
@@ -476,10 +476,7 @@ err_pll0:
476 _gclk0 = NULL; 476 _gclk0 = NULL;
477 } 477 }
478err_gclk0: 478err_gclk0:
479 if (ssc != NULL) { 479 ssc_free(ssc);
480 ssc_free(ssc);
481 ssc = NULL;
482 }
483err_ssc: 480err_ssc:
484 return ret; 481 return ret;
485} 482}
diff --git a/sound/soc/at91/Kconfig b/sound/soc/at91/Kconfig
index 905186502e00..85a883299c2e 100644
--- a/sound/soc/at91/Kconfig
+++ b/sound/soc/at91/Kconfig
@@ -8,20 +8,3 @@ config SND_AT91_SOC
8 8
9config SND_AT91_SOC_SSC 9config SND_AT91_SOC_SSC
10 tristate 10 tristate
11
12config SND_AT91_SOC_ETI_B1_WM8731
13 tristate "SoC Audio support for WM8731-based Endrelia ETI-B1 boards"
14 depends on SND_AT91_SOC && (MACH_ETI_B1 || MACH_ETI_C1)
15 select SND_AT91_SOC_SSC
16 select SND_SOC_WM8731
17 help
18 Say Y if you want to add support for SoC audio on WM8731-based
19 Endrelia Technologies Inc ETI-B1 or ETI-C1 boards.
20
21config SND_AT91_SOC_ETI_SLAVE
22 bool "Run codec in slave Mode on Endrelia boards"
23 depends on SND_AT91_SOC_ETI_B1_WM8731
24 default n
25 help
26 Say Y if you want to run with the AT91 SSC generating the BCLK
27 and LRC signals on Endrelia boards.
diff --git a/sound/soc/at91/Makefile b/sound/soc/at91/Makefile
index f23da17cc328..b817f11df286 100644
--- a/sound/soc/at91/Makefile
+++ b/sound/soc/at91/Makefile
@@ -4,8 +4,3 @@ snd-soc-at91-ssc-objs := at91-ssc.o
4 4
5obj-$(CONFIG_SND_AT91_SOC) += snd-soc-at91.o 5obj-$(CONFIG_SND_AT91_SOC) += snd-soc-at91.o
6obj-$(CONFIG_SND_AT91_SOC_SSC) += snd-soc-at91-ssc.o 6obj-$(CONFIG_SND_AT91_SOC_SSC) += snd-soc-at91-ssc.o
7
8# AT91 Machine Support
9snd-soc-eti-b1-wm8731-objs := eti_b1_wm8731.o
10
11obj-$(CONFIG_SND_AT91_SOC_ETI_B1_WM8731) += snd-soc-eti-b1-wm8731.o
diff --git a/sound/soc/at91/at91-ssc.c b/sound/soc/at91/at91-ssc.c
index 5d44515e62e0..1b61cc461261 100644
--- a/sound/soc/at91/at91-ssc.c
+++ b/sound/soc/at91/at91-ssc.c
@@ -5,7 +5,7 @@
5 * Endrelia Technologies Inc. 5 * Endrelia Technologies Inc.
6 * 6 *
7 * Based on pxa2xx Platform drivers by 7 * Based on pxa2xx Platform drivers by
8 * Liam Girdwood <liam.girdwood@wolfsonmicro.com> 8 * Liam Girdwood <lrg@slimlogic.co.uk>
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify it 10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the 11 * under the terms of the GNU General Public License as published by the
@@ -408,7 +408,7 @@ static int at91_ssc_hw_params(struct snd_pcm_substream *substream,
408 dma_params->pdc_xfer_size = 4; 408 dma_params->pdc_xfer_size = 4;
409 break; 409 break;
410 default: 410 default:
411 printk(KERN_WARNING "at91-ssc: unsupported PCM format"); 411 printk(KERN_WARNING "at91-ssc: unsupported PCM format\n");
412 return -EINVAL; 412 return -EINVAL;
413 } 413 }
414 414
diff --git a/sound/soc/at91/eti_b1_wm8731.c b/sound/soc/at91/eti_b1_wm8731.c
deleted file mode 100644
index b81d6b2cfa1d..000000000000
--- a/sound/soc/at91/eti_b1_wm8731.c
+++ /dev/null
@@ -1,348 +0,0 @@
1/*
2 * eti_b1_wm8731 -- SoC audio for AT91RM9200-based Endrelia ETI_B1 board.
3 *
4 * Author: Frank Mandarino <fmandarino@endrelia.com>
5 * Endrelia Technologies Inc.
6 * Created: Mar 29, 2006
7 *
8 * Based on corgi.c by:
9 *
10 * Copyright 2005 Wolfson Microelectronics PLC.
11 * Copyright 2005 Openedhand Ltd.
12 *
13 * Authors: Liam Girdwood <liam.girdwood@wolfsonmicro.com>
14 * Richard Purdie <richard@openedhand.com>
15 *
16 * This program is free software; you can redistribute it and/or modify it
17 * under the terms of the GNU General Public License as published by the
18 * Free Software Foundation; either version 2 of the License, or (at your
19 * option) any later version.
20 *
21 */
22
23#include <linux/module.h>
24#include <linux/moduleparam.h>
25#include <linux/kernel.h>
26#include <linux/clk.h>
27#include <linux/timer.h>
28#include <linux/interrupt.h>
29#include <linux/platform_device.h>
30#include <sound/core.h>
31#include <sound/pcm.h>
32#include <sound/soc.h>
33#include <sound/soc-dapm.h>
34
35#include <mach/hardware.h>
36#include <mach/gpio.h>
37
38#include "../codecs/wm8731.h"
39#include "at91-pcm.h"
40#include "at91-ssc.h"
41
42#if 0
43#define DBG(x...) printk(KERN_INFO "eti_b1_wm8731: " x)
44#else
45#define DBG(x...)
46#endif
47
48static struct clk *pck1_clk;
49static struct clk *pllb_clk;
50
51
52static int eti_b1_startup(struct snd_pcm_substream *substream)
53{
54 struct snd_soc_pcm_runtime *rtd = substream->private_data;
55 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
56 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
57 int ret;
58
59 /* cpu clock is the AT91 master clock sent to the SSC */
60 ret = snd_soc_dai_set_sysclk(cpu_dai, AT91_SYSCLK_MCK,
61 60000000, SND_SOC_CLOCK_IN);
62 if (ret < 0)
63 return ret;
64
65 /* codec system clock is supplied by PCK1, set to 12MHz */
66 ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK,
67 12000000, SND_SOC_CLOCK_IN);
68 if (ret < 0)
69 return ret;
70
71 /* Start PCK1 clock. */
72 clk_enable(pck1_clk);
73 DBG("pck1 started\n");
74
75 return 0;
76}
77
78static void eti_b1_shutdown(struct snd_pcm_substream *substream)
79{
80 /* Stop PCK1 clock. */
81 clk_disable(pck1_clk);
82 DBG("pck1 stopped\n");
83}
84
85static int eti_b1_hw_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->dai->codec_dai;
90 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
91 int ret;
92
93#ifdef CONFIG_SND_AT91_SOC_ETI_SLAVE
94 unsigned int rate;
95 int cmr_div, period;
96
97 /* set codec DAI configuration */
98 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
99 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
100 if (ret < 0)
101 return ret;
102
103 /* set cpu DAI configuration */
104 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
105 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
106 if (ret < 0)
107 return ret;
108
109 /*
110 * The SSC clock dividers depend on the sample rate. The CMR.DIV
111 * field divides the system master clock MCK to drive the SSC TK
112 * signal which provides the codec BCLK. The TCMR.PERIOD and
113 * RCMR.PERIOD fields further divide the BCLK signal to drive
114 * the SSC TF and RF signals which provide the codec DACLRC and
115 * ADCLRC clocks.
116 *
117 * The dividers were determined through trial and error, where a
118 * CMR.DIV value is chosen such that the resulting BCLK value is
119 * divisible, or almost divisible, by (2 * sample rate), and then
120 * the TCMR.PERIOD or RCMR.PERIOD is BCLK / (2 * sample rate) - 1.
121 */
122 rate = params_rate(params);
123
124 switch (rate) {
125 case 8000:
126 cmr_div = 25; /* BCLK = 60MHz/(2*25) = 1.2MHz */
127 period = 74; /* LRC = BCLK/(2*(74+1)) = 8000Hz */
128 break;
129 case 32000:
130 cmr_div = 7; /* BCLK = 60MHz/(2*7) ~= 4.28571428MHz */
131 period = 66; /* LRC = BCLK/(2*(66+1)) = 31982.942Hz */
132 break;
133 case 48000:
134 cmr_div = 13; /* BCLK = 60MHz/(2*13) ~= 2.3076923MHz */
135 period = 23; /* LRC = BCLK/(2*(23+1)) = 48076.923Hz */
136 break;
137 default:
138 printk(KERN_WARNING "unsupported rate %d on ETI-B1 board\n", rate);
139 return -EINVAL;
140 }
141
142 /* set the MCK divider for BCLK */
143 ret = snd_soc_dai_set_clkdiv(cpu_dai, AT91SSC_CMR_DIV, cmr_div);
144 if (ret < 0)
145 return ret;
146
147 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
148 /* set the BCLK divider for DACLRC */
149 ret = snd_soc_dai_set_clkdiv(cpu_dai,
150 AT91SSC_TCMR_PERIOD, period);
151 } else {
152 /* set the BCLK divider for ADCLRC */
153 ret = snd_soc_dai_set_clkdiv(cpu_dai,
154 AT91SSC_RCMR_PERIOD, period);
155 }
156 if (ret < 0)
157 return ret;
158
159#else /* CONFIG_SND_AT91_SOC_ETI_SLAVE */
160 /*
161 * Codec in Master Mode.
162 */
163
164 /* set codec DAI configuration */
165 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
166 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
167 if (ret < 0)
168 return ret;
169
170 /* set cpu DAI configuration */
171 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
172 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
173 if (ret < 0)
174 return ret;
175
176#endif /* CONFIG_SND_AT91_SOC_ETI_SLAVE */
177
178 return 0;
179}
180
181static struct snd_soc_ops eti_b1_ops = {
182 .startup = eti_b1_startup,
183 .hw_params = eti_b1_hw_params,
184 .shutdown = eti_b1_shutdown,
185};
186
187
188static const struct snd_soc_dapm_widget eti_b1_dapm_widgets[] = {
189 SND_SOC_DAPM_MIC("Int Mic", NULL),
190 SND_SOC_DAPM_SPK("Ext Spk", NULL),
191};
192
193static const struct snd_soc_dapm_route intercon[] = {
194
195 /* speaker connected to LHPOUT */
196 {"Ext Spk", NULL, "LHPOUT"},
197
198 /* mic is connected to Mic Jack, with WM8731 Mic Bias */
199 {"MICIN", NULL, "Mic Bias"},
200 {"Mic Bias", NULL, "Int Mic"},
201};
202
203/*
204 * Logic for a wm8731 as connected on a Endrelia ETI-B1 board.
205 */
206static int eti_b1_wm8731_init(struct snd_soc_codec *codec)
207{
208 DBG("eti_b1_wm8731_init() called\n");
209
210 /* Add specific widgets */
211 snd_soc_dapm_new_controls(codec, eti_b1_dapm_widgets,
212 ARRAY_SIZE(eti_b1_dapm_widgets));
213
214 /* Set up specific audio path interconnects */
215 snd_soc_dapm_add_route(codec, intercon, ARRAY_SIZE(intercon));
216
217 /* not connected */
218 snd_soc_dapm_disable_pin(codec, "RLINEIN");
219 snd_soc_dapm_disable_pin(codec, "LLINEIN");
220
221 /* always connected */
222 snd_soc_dapm_enable_pin(codec, "Int Mic");
223 snd_soc_dapm_enable_pin(codec, "Ext Spk");
224
225 snd_soc_dapm_sync(codec);
226
227 return 0;
228}
229
230static struct snd_soc_dai_link eti_b1_dai = {
231 .name = "WM8731",
232 .stream_name = "WM8731 PCM",
233 .cpu_dai = &at91_ssc_dai[1],
234 .codec_dai = &wm8731_dai,
235 .init = eti_b1_wm8731_init,
236 .ops = &eti_b1_ops,
237};
238
239static struct snd_soc_machine snd_soc_machine_eti_b1 = {
240 .name = "ETI_B1_WM8731",
241 .dai_link = &eti_b1_dai,
242 .num_links = 1,
243};
244
245static struct wm8731_setup_data eti_b1_wm8731_setup = {
246 .i2c_address = 0x1a,
247};
248
249static struct snd_soc_device eti_b1_snd_devdata = {
250 .machine = &snd_soc_machine_eti_b1,
251 .platform = &at91_soc_platform,
252 .codec_dev = &soc_codec_dev_wm8731,
253 .codec_data = &eti_b1_wm8731_setup,
254};
255
256static struct platform_device *eti_b1_snd_device;
257
258static int __init eti_b1_init(void)
259{
260 int ret;
261 struct at91_ssc_periph *ssc = eti_b1_dai.cpu_dai->private_data;
262
263 if (!request_mem_region(AT91RM9200_BASE_SSC1, SZ_16K, "soc-audio")) {
264 DBG("SSC1 memory region is busy\n");
265 return -EBUSY;
266 }
267
268 ssc->base = ioremap(AT91RM9200_BASE_SSC1, SZ_16K);
269 if (!ssc->base) {
270 DBG("SSC1 memory ioremap failed\n");
271 ret = -ENOMEM;
272 goto fail_release_mem;
273 }
274
275 ssc->pid = AT91RM9200_ID_SSC1;
276
277 eti_b1_snd_device = platform_device_alloc("soc-audio", -1);
278 if (!eti_b1_snd_device) {
279 DBG("platform device allocation failed\n");
280 ret = -ENOMEM;
281 goto fail_io_unmap;
282 }
283
284 platform_set_drvdata(eti_b1_snd_device, &eti_b1_snd_devdata);
285 eti_b1_snd_devdata.dev = &eti_b1_snd_device->dev;
286
287 ret = platform_device_add(eti_b1_snd_device);
288 if (ret) {
289 DBG("platform device add failed\n");
290 platform_device_put(eti_b1_snd_device);
291 goto fail_io_unmap;
292 }
293
294 at91_set_A_periph(AT91_PIN_PB6, 0); /* TF1 */
295 at91_set_A_periph(AT91_PIN_PB7, 0); /* TK1 */
296 at91_set_A_periph(AT91_PIN_PB8, 0); /* TD1 */
297 at91_set_A_periph(AT91_PIN_PB9, 0); /* RD1 */
298/* at91_set_A_periph(AT91_PIN_PB10, 0);*/ /* RK1 */
299 at91_set_A_periph(AT91_PIN_PB11, 0); /* RF1 */
300
301 /*
302 * Set PCK1 parent to PLLB and its rate to 12 Mhz.
303 */
304 pllb_clk = clk_get(NULL, "pllb");
305 pck1_clk = clk_get(NULL, "pck1");
306
307 clk_set_parent(pck1_clk, pllb_clk);
308 clk_set_rate(pck1_clk, 12000000);
309
310 DBG("MCLK rate %luHz\n", clk_get_rate(pck1_clk));
311
312 /* assign the GPIO pin to PCK1 */
313 at91_set_B_periph(AT91_PIN_PA24, 0);
314
315#ifdef CONFIG_SND_AT91_SOC_ETI_SLAVE
316 printk(KERN_INFO "eti_b1_wm8731: Codec in Slave Mode\n");
317#else
318 printk(KERN_INFO "eti_b1_wm8731: Codec in Master Mode\n");
319#endif
320 return ret;
321
322fail_io_unmap:
323 iounmap(ssc->base);
324fail_release_mem:
325 release_mem_region(AT91RM9200_BASE_SSC1, SZ_16K);
326 return ret;
327}
328
329static void __exit eti_b1_exit(void)
330{
331 struct at91_ssc_periph *ssc = eti_b1_dai.cpu_dai->private_data;
332
333 clk_put(pck1_clk);
334 clk_put(pllb_clk);
335
336 platform_device_unregister(eti_b1_snd_device);
337
338 iounmap(ssc->base);
339 release_mem_region(AT91RM9200_BASE_SSC1, SZ_16K);
340}
341
342module_init(eti_b1_init);
343module_exit(eti_b1_exit);
344
345/* Module information */
346MODULE_AUTHOR("Frank Mandarino <fmandarino@endrelia.com>");
347MODULE_DESCRIPTION("ALSA SoC ETI-B1-WM8731");
348MODULE_LICENSE("GPL");
diff --git a/sound/soc/blackfin/Kconfig b/sound/soc/blackfin/Kconfig
new file mode 100644
index 000000000000..dc006206f622
--- /dev/null
+++ b/sound/soc/blackfin/Kconfig
@@ -0,0 +1,101 @@
1config SND_BF5XX_I2S
2 tristate "SoC I2S Audio for the ADI BF5xx chip"
3 depends on BLACKFIN && SND_SOC
4 help
5 Say Y or M if you want to add support for codecs attached to
6 the Blackfin SPORT (synchronous serial ports) interface in I2S
7 mode (supports single stereo In/Out).
8 You will also need to select the audio interfaces to support below.
9
10config SND_BF5XX_SOC_SSM2602
11 tristate "SoC SSM2602 Audio support for BF52x ezkit"
12 depends on SND_BF5XX_I2S
13 select SND_BF5XX_SOC_I2S
14 select SND_SOC_SSM2602
15 select I2C
16 select I2C_BLACKFIN_TWI
17 help
18 Say Y if you want to add support for SoC audio on BF527-EZKIT.
19
20config SND_BF5XX_SOC_AD73311
21 tristate "SoC AD73311 Audio support for Blackfin"
22 depends on SND_BF5XX_I2S
23 select SND_BF5XX_SOC_I2S
24 select SND_SOC_AD73311
25 help
26 Say Y if you want to add support for AD73311 codec on Blackfin.
27
28config SND_BFIN_AD73311_SE
29 int "PF pin for AD73311L Chip Select"
30 depends on SND_BF5XX_SOC_AD73311
31 default 4
32 help
33 Enter the GPIO used to control AD73311's SE pin. Acceptable
34 values are 0 to 7
35
36config SND_BF5XX_AC97
37 tristate "SoC AC97 Audio for the ADI BF5xx chip"
38 depends on BLACKFIN && SND_SOC
39 help
40 Say Y or M if you want to add support for codecs attached to
41 the Blackfin SPORT (synchronous serial ports) interface in slot 16
42 mode (pseudo AC97 interface).
43 You will also need to select the audio interfaces to support below.
44
45 Note:
46 AC97 codecs which do not implment the slot-16 mode will not function
47 properly with this driver. This driver is known to work with the
48 Analog Devices line of AC97 codecs.
49
50config SND_MMAP_SUPPORT
51 bool "Enable MMAP Support"
52 depends on SND_BF5XX_AC97
53 default y
54 help
55 Say y if you want AC97 driver to support mmap mode.
56 We introduce an intermediate buffer to simulate mmap.
57
58config SND_BF5XX_SOC_SPORT
59 tristate
60
61config SND_BF5XX_SOC_I2S
62 tristate
63 select SND_BF5XX_SOC_SPORT
64
65config SND_BF5XX_SOC_AC97
66 tristate
67 select AC97_BUS
68 select SND_SOC_AC97_BUS
69 select SND_BF5XX_SOC_SPORT
70
71config SND_BF5XX_SOC_AD1980
72 tristate "SoC AD1980/1 Audio support for BF5xx"
73 depends on SND_BF5XX_AC97
74 select SND_BF5XX_SOC_AC97
75 select SND_SOC_AD1980
76 help
77 Say Y if you want to add support for SoC audio on BF5xx STAMP/EZKIT.
78
79config SND_BF5XX_SPORT_NUM
80 int "Set a SPORT for Sound chip"
81 depends on (SND_BF5XX_I2S || SND_BF5XX_AC97)
82 range 0 3 if BF54x
83 range 0 1 if (BF53x || BF561)
84 default 0
85 help
86 Set the correct SPORT for sound chip.
87
88config SND_BF5XX_HAVE_COLD_RESET
89 bool "BOARD has COLD Reset GPIO"
90 depends on SND_BF5XX_AC97
91 default y if BFIN548_EZKIT
92 default n if !BFIN548_EZKIT
93
94config SND_BF5XX_RESET_GPIO_NUM
95 int "Set a GPIO for cold reset"
96 depends on SND_BF5XX_HAVE_COLD_RESET
97 range 0 159
98 default 19 if BFIN548_EZKIT
99 default 5 if BFIN537_STAMP
100 help
101 Set the correct GPIO for RESET the sound chip.
diff --git a/sound/soc/blackfin/Makefile b/sound/soc/blackfin/Makefile
new file mode 100644
index 000000000000..97bb37a6359c
--- /dev/null
+++ b/sound/soc/blackfin/Makefile
@@ -0,0 +1,21 @@
1# Blackfin Platform Support
2snd-bf5xx-ac97-objs := bf5xx-ac97-pcm.o
3snd-bf5xx-i2s-objs := bf5xx-i2s-pcm.o
4snd-soc-bf5xx-sport-objs := bf5xx-sport.o
5snd-soc-bf5xx-ac97-objs := bf5xx-ac97.o
6snd-soc-bf5xx-i2s-objs := bf5xx-i2s.o
7
8obj-$(CONFIG_SND_BF5XX_AC97) += snd-bf5xx-ac97.o
9obj-$(CONFIG_SND_BF5XX_I2S) += snd-bf5xx-i2s.o
10obj-$(CONFIG_SND_BF5XX_SOC_SPORT) += snd-soc-bf5xx-sport.o
11obj-$(CONFIG_SND_BF5XX_SOC_AC97) += snd-soc-bf5xx-ac97.o
12obj-$(CONFIG_SND_BF5XX_SOC_I2S) += snd-soc-bf5xx-i2s.o
13
14# Blackfin Machine Support
15snd-ad1980-objs := bf5xx-ad1980.o
16snd-ssm2602-objs := bf5xx-ssm2602.o
17snd-ad73311-objs := bf5xx-ad73311.o
18
19obj-$(CONFIG_SND_BF5XX_SOC_AD1980) += snd-ad1980.o
20obj-$(CONFIG_SND_BF5XX_SOC_SSM2602) += snd-ssm2602.o
21obj-$(CONFIG_SND_BF5XX_SOC_AD73311) += snd-ad73311.o
diff --git a/sound/soc/blackfin/bf5xx-ac97-pcm.c b/sound/soc/blackfin/bf5xx-ac97-pcm.c
new file mode 100644
index 000000000000..25e50d2ea1ec
--- /dev/null
+++ b/sound/soc/blackfin/bf5xx-ac97-pcm.c
@@ -0,0 +1,457 @@
1/*
2 * File: sound/soc/blackfin/bf5xx-ac97-pcm.c
3 * Author: Cliff Cai <Cliff.Cai@analog.com>
4 *
5 * Created: Tue June 06 2008
6 * Description: DMA Driver for AC97 sound chip
7 *
8 * Modified:
9 * Copyright 2008 Analog Devices Inc.
10 *
11 * Bugs: Enter bugs at http://blackfin.uclinux.org/
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, see the file COPYING, or write
25 * to the Free Software Foundation, Inc.,
26 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27 */
28
29#include <linux/module.h>
30#include <linux/init.h>
31#include <linux/platform_device.h>
32#include <linux/slab.h>
33#include <linux/dma-mapping.h>
34
35#include <sound/core.h>
36#include <sound/pcm.h>
37#include <sound/pcm_params.h>
38#include <sound/soc.h>
39
40#include <asm/dma.h>
41
42#include "bf5xx-ac97-pcm.h"
43#include "bf5xx-ac97.h"
44#include "bf5xx-sport.h"
45
46#if defined(CONFIG_SND_MMAP_SUPPORT)
47static void bf5xx_mmap_copy(struct snd_pcm_substream *substream,
48 snd_pcm_uframes_t count)
49{
50 struct snd_pcm_runtime *runtime = substream->runtime;
51 struct sport_device *sport = runtime->private_data;
52 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
53 bf5xx_pcm_to_ac97(
54 (struct ac97_frame *)sport->tx_dma_buf + sport->tx_pos,
55 (__u32 *)runtime->dma_area + sport->tx_pos, count);
56 sport->tx_pos += runtime->period_size;
57 if (sport->tx_pos >= runtime->buffer_size)
58 sport->tx_pos %= runtime->buffer_size;
59 sport->tx_delay_pos = sport->tx_pos;
60 } else {
61 bf5xx_ac97_to_pcm(
62 (struct ac97_frame *)sport->rx_dma_buf + sport->rx_pos,
63 (__u32 *)runtime->dma_area + sport->rx_pos, count);
64 sport->rx_pos += runtime->period_size;
65 if (sport->rx_pos >= runtime->buffer_size)
66 sport->rx_pos %= runtime->buffer_size;
67 }
68}
69#endif
70
71static void bf5xx_dma_irq(void *data)
72{
73 struct snd_pcm_substream *pcm = data;
74#if defined(CONFIG_SND_MMAP_SUPPORT)
75 struct snd_pcm_runtime *runtime = pcm->runtime;
76 struct sport_device *sport = runtime->private_data;
77 bf5xx_mmap_copy(pcm, runtime->period_size);
78 if (pcm->stream == SNDRV_PCM_STREAM_PLAYBACK) {
79 if (sport->once == 0) {
80 snd_pcm_period_elapsed(pcm);
81 bf5xx_mmap_copy(pcm, runtime->period_size);
82 sport->once = 1;
83 }
84 }
85#endif
86 snd_pcm_period_elapsed(pcm);
87}
88
89/* The memory size for pure pcm data is 128*1024 = 0x20000 bytes.
90 * The total rx/tx buffer is for ac97 frame to hold all pcm data
91 * is 0x20000 * sizeof(struct ac97_frame) / 4.
92 */
93#ifdef CONFIG_SND_MMAP_SUPPORT
94static const struct snd_pcm_hardware bf5xx_pcm_hardware = {
95 .info = SNDRV_PCM_INFO_INTERLEAVED |
96 SNDRV_PCM_INFO_MMAP |
97 SNDRV_PCM_INFO_MMAP_VALID |
98 SNDRV_PCM_INFO_BLOCK_TRANSFER,
99#else
100static const struct snd_pcm_hardware bf5xx_pcm_hardware = {
101 .info = SNDRV_PCM_INFO_INTERLEAVED |
102 SNDRV_PCM_INFO_BLOCK_TRANSFER,
103#endif
104 .formats = SNDRV_PCM_FMTBIT_S16_LE,
105 .period_bytes_min = 32,
106 .period_bytes_max = 0x10000,
107 .periods_min = 1,
108 .periods_max = PAGE_SIZE/32,
109 .buffer_bytes_max = 0x20000, /* 128 kbytes */
110 .fifo_size = 16,
111};
112
113static int bf5xx_pcm_hw_params(struct snd_pcm_substream *substream,
114 struct snd_pcm_hw_params *params)
115{
116 size_t size = bf5xx_pcm_hardware.buffer_bytes_max
117 * sizeof(struct ac97_frame) / 4;
118
119 snd_pcm_lib_malloc_pages(substream, size);
120
121 return 0;
122}
123
124static int bf5xx_pcm_hw_free(struct snd_pcm_substream *substream)
125{
126 struct snd_pcm_runtime *runtime = substream->runtime;
127
128 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
129 memset(runtime->dma_area, 0, runtime->buffer_size);
130 snd_pcm_lib_free_pages(substream);
131 return 0;
132}
133
134static int bf5xx_pcm_prepare(struct snd_pcm_substream *substream)
135{
136 struct snd_pcm_runtime *runtime = substream->runtime;
137 struct sport_device *sport = runtime->private_data;
138
139 /* An intermediate buffer is introduced for implementing mmap for
140 * SPORT working in TMD mode(include AC97).
141 */
142#if defined(CONFIG_SND_MMAP_SUPPORT)
143 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
144 sport_set_tx_callback(sport, bf5xx_dma_irq, substream);
145 sport_config_tx_dma(sport, sport->tx_dma_buf, runtime->periods,
146 runtime->period_size * sizeof(struct ac97_frame));
147 } else {
148 sport_set_rx_callback(sport, bf5xx_dma_irq, substream);
149 sport_config_rx_dma(sport, sport->rx_dma_buf, runtime->periods,
150 runtime->period_size * sizeof(struct ac97_frame));
151 }
152#else
153 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
154 sport_set_tx_callback(sport, bf5xx_dma_irq, substream);
155 sport_config_tx_dma(sport, runtime->dma_area, runtime->periods,
156 runtime->period_size * sizeof(struct ac97_frame));
157 } else {
158 sport_set_rx_callback(sport, bf5xx_dma_irq, substream);
159 sport_config_rx_dma(sport, runtime->dma_area, runtime->periods,
160 runtime->period_size * sizeof(struct ac97_frame));
161 }
162#endif
163 return 0;
164}
165
166static int bf5xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
167{
168 struct snd_pcm_runtime *runtime = substream->runtime;
169 struct sport_device *sport = runtime->private_data;
170 int ret = 0;
171
172 pr_debug("%s enter\n", __func__);
173 switch (cmd) {
174 case SNDRV_PCM_TRIGGER_START:
175 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
176 bf5xx_mmap_copy(substream, runtime->period_size);
177 snd_pcm_period_elapsed(substream);
178 sport->tx_delay_pos = 0;
179 sport_tx_start(sport);
180 }
181 else
182 sport_rx_start(sport);
183 break;
184 case SNDRV_PCM_TRIGGER_STOP:
185 case SNDRV_PCM_TRIGGER_SUSPEND:
186 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
187 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
188#if defined(CONFIG_SND_MMAP_SUPPORT)
189 sport->tx_pos = 0;
190#endif
191 sport_tx_stop(sport);
192 } else {
193#if defined(CONFIG_SND_MMAP_SUPPORT)
194 sport->rx_pos = 0;
195#endif
196 sport_rx_stop(sport);
197 }
198 break;
199 default:
200 ret = -EINVAL;
201 }
202 return ret;
203}
204
205static snd_pcm_uframes_t bf5xx_pcm_pointer(struct snd_pcm_substream *substream)
206{
207 struct snd_pcm_runtime *runtime = substream->runtime;
208 struct sport_device *sport = runtime->private_data;
209 unsigned int curr;
210
211#if defined(CONFIG_SND_MMAP_SUPPORT)
212 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
213 curr = sport->tx_delay_pos;
214 else
215 curr = sport->rx_pos;
216#else
217
218 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
219 curr = sport_curr_offset_tx(sport) / sizeof(struct ac97_frame);
220 else
221 curr = sport_curr_offset_rx(sport) / sizeof(struct ac97_frame);
222
223#endif
224 return curr;
225}
226
227static int bf5xx_pcm_open(struct snd_pcm_substream *substream)
228{
229 struct snd_pcm_runtime *runtime = substream->runtime;
230 int ret;
231
232 pr_debug("%s enter\n", __func__);
233 snd_soc_set_runtime_hwparams(substream, &bf5xx_pcm_hardware);
234
235 ret = snd_pcm_hw_constraint_integer(runtime,
236 SNDRV_PCM_HW_PARAM_PERIODS);
237 if (ret < 0)
238 goto out;
239
240 if (sport_handle != NULL)
241 runtime->private_data = sport_handle;
242 else {
243 pr_err("sport_handle is NULL\n");
244 return -1;
245 }
246 return 0;
247
248 out:
249 return ret;
250}
251
252static int bf5xx_pcm_close(struct snd_pcm_substream *substream)
253{
254 struct snd_pcm_runtime *runtime = substream->runtime;
255 struct sport_device *sport = runtime->private_data;
256
257 pr_debug("%s enter\n", __func__);
258 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
259 sport->once = 0;
260 memset(sport->tx_dma_buf, 0, runtime->buffer_size * sizeof(struct ac97_frame));
261 } else
262 memset(sport->rx_dma_buf, 0, runtime->buffer_size * sizeof(struct ac97_frame));
263
264 return 0;
265}
266
267#ifdef CONFIG_SND_MMAP_SUPPORT
268static int bf5xx_pcm_mmap(struct snd_pcm_substream *substream,
269 struct vm_area_struct *vma)
270{
271 struct snd_pcm_runtime *runtime = substream->runtime;
272 size_t size = vma->vm_end - vma->vm_start;
273 vma->vm_start = (unsigned long)runtime->dma_area;
274 vma->vm_end = vma->vm_start + size;
275 vma->vm_flags |= VM_SHARED;
276 return 0 ;
277}
278#else
279static int bf5xx_pcm_copy(struct snd_pcm_substream *substream, int channel,
280 snd_pcm_uframes_t pos,
281 void __user *buf, snd_pcm_uframes_t count)
282{
283 struct snd_pcm_runtime *runtime = substream->runtime;
284
285 pr_debug("%s copy pos:0x%lx count:0x%lx\n",
286 substream->stream ? "Capture" : "Playback", pos, count);
287
288 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
289 bf5xx_pcm_to_ac97(
290 (struct ac97_frame *)runtime->dma_area + pos,
291 buf, count);
292 else
293 bf5xx_ac97_to_pcm(
294 (struct ac97_frame *)runtime->dma_area + pos,
295 buf, count);
296 return 0;
297}
298#endif
299
300struct snd_pcm_ops bf5xx_pcm_ac97_ops = {
301 .open = bf5xx_pcm_open,
302 .close = bf5xx_pcm_close,
303 .ioctl = snd_pcm_lib_ioctl,
304 .hw_params = bf5xx_pcm_hw_params,
305 .hw_free = bf5xx_pcm_hw_free,
306 .prepare = bf5xx_pcm_prepare,
307 .trigger = bf5xx_pcm_trigger,
308 .pointer = bf5xx_pcm_pointer,
309#ifdef CONFIG_SND_MMAP_SUPPORT
310 .mmap = bf5xx_pcm_mmap,
311#else
312 .copy = bf5xx_pcm_copy,
313#endif
314};
315
316static int bf5xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
317{
318 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
319 struct snd_dma_buffer *buf = &substream->dma_buffer;
320 size_t size = bf5xx_pcm_hardware.buffer_bytes_max
321 * sizeof(struct ac97_frame) / 4;
322
323 buf->dev.type = SNDRV_DMA_TYPE_DEV;
324 buf->dev.dev = pcm->card->dev;
325 buf->private_data = NULL;
326 buf->area = dma_alloc_coherent(pcm->card->dev, size,
327 &buf->addr, GFP_KERNEL);
328 if (!buf->area) {
329 pr_err("Failed to allocate dma memory\n");
330 pr_err("Please increase uncached DMA memory region\n");
331 return -ENOMEM;
332 }
333 buf->bytes = size;
334
335 pr_debug("%s, area:%p, size:0x%08lx\n", __func__,
336 buf->area, buf->bytes);
337
338 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
339 sport_handle->tx_buf = buf->area;
340 else
341 sport_handle->rx_buf = buf->area;
342
343/*
344 * Need to allocate local buffer when enable
345 * MMAP for SPORT working in TMD mode (include AC97).
346 */
347#if defined(CONFIG_SND_MMAP_SUPPORT)
348 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
349 if (!sport_handle->tx_dma_buf) {
350 sport_handle->tx_dma_buf = dma_alloc_coherent(NULL, \
351 size, &sport_handle->tx_dma_phy, GFP_KERNEL);
352 if (!sport_handle->tx_dma_buf) {
353 pr_err("Failed to allocate memory for tx dma \
354 buf - Please increase uncached DMA \
355 memory region\n");
356 return -ENOMEM;
357 } else
358 memset(sport_handle->tx_dma_buf, 0, size);
359 } else
360 memset(sport_handle->tx_dma_buf, 0, size);
361 } else {
362 if (!sport_handle->rx_dma_buf) {
363 sport_handle->rx_dma_buf = dma_alloc_coherent(NULL, \
364 size, &sport_handle->rx_dma_phy, GFP_KERNEL);
365 if (!sport_handle->rx_dma_buf) {
366 pr_err("Failed to allocate memory for rx dma \
367 buf - Please increase uncached DMA \
368 memory region\n");
369 return -ENOMEM;
370 } else
371 memset(sport_handle->rx_dma_buf, 0, size);
372 } else
373 memset(sport_handle->rx_dma_buf, 0, size);
374 }
375#endif
376 return 0;
377}
378
379static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
380{
381 struct snd_pcm_substream *substream;
382 struct snd_dma_buffer *buf;
383 int stream;
384#if defined(CONFIG_SND_MMAP_SUPPORT)
385 size_t size = bf5xx_pcm_hardware.buffer_bytes_max *
386 sizeof(struct ac97_frame) / 4;
387#endif
388 for (stream = 0; stream < 2; stream++) {
389 substream = pcm->streams[stream].substream;
390 if (!substream)
391 continue;
392
393 buf = &substream->dma_buffer;
394 if (!buf->area)
395 continue;
396 dma_free_coherent(NULL, buf->bytes, buf->area, 0);
397 buf->area = NULL;
398#if defined(CONFIG_SND_MMAP_SUPPORT)
399 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
400 if (sport_handle->tx_dma_buf)
401 dma_free_coherent(NULL, size, \
402 sport_handle->tx_dma_buf, 0);
403 sport_handle->tx_dma_buf = NULL;
404 } else {
405
406 if (sport_handle->rx_dma_buf)
407 dma_free_coherent(NULL, size, \
408 sport_handle->rx_dma_buf, 0);
409 sport_handle->rx_dma_buf = NULL;
410 }
411#endif
412 }
413 if (sport_handle)
414 sport_done(sport_handle);
415}
416
417static u64 bf5xx_pcm_dmamask = DMA_32BIT_MASK;
418
419int bf5xx_pcm_ac97_new(struct snd_card *card, struct snd_soc_dai *dai,
420 struct snd_pcm *pcm)
421{
422 int ret = 0;
423
424 pr_debug("%s enter\n", __func__);
425 if (!card->dev->dma_mask)
426 card->dev->dma_mask = &bf5xx_pcm_dmamask;
427 if (!card->dev->coherent_dma_mask)
428 card->dev->coherent_dma_mask = DMA_32BIT_MASK;
429
430 if (dai->playback.channels_min) {
431 ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
432 SNDRV_PCM_STREAM_PLAYBACK);
433 if (ret)
434 goto out;
435 }
436
437 if (dai->capture.channels_min) {
438 ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
439 SNDRV_PCM_STREAM_CAPTURE);
440 if (ret)
441 goto out;
442 }
443 out:
444 return ret;
445}
446
447struct snd_soc_platform bf5xx_ac97_soc_platform = {
448 .name = "bf5xx-audio",
449 .pcm_ops = &bf5xx_pcm_ac97_ops,
450 .pcm_new = bf5xx_pcm_ac97_new,
451 .pcm_free = bf5xx_pcm_free_dma_buffers,
452};
453EXPORT_SYMBOL_GPL(bf5xx_ac97_soc_platform);
454
455MODULE_AUTHOR("Cliff Cai");
456MODULE_DESCRIPTION("ADI Blackfin AC97 PCM DMA module");
457MODULE_LICENSE("GPL");
diff --git a/sound/soc/blackfin/bf5xx-ac97-pcm.h b/sound/soc/blackfin/bf5xx-ac97-pcm.h
new file mode 100644
index 000000000000..350125a0ae21
--- /dev/null
+++ b/sound/soc/blackfin/bf5xx-ac97-pcm.h
@@ -0,0 +1,29 @@
1/*
2 * linux/sound/arm/bf5xx-ac97-pcm.h -- ALSA PCM interface for the Blackfin
3 *
4 * Copyright 2007 Analog Device Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef _BF5XX_AC97_PCM_H
12#define _BF5XX_AC97_PCM_H
13
14struct bf5xx_pcm_dma_params {
15 char *name; /* stream identifier */
16};
17
18struct bf5xx_gpio {
19 u32 sys;
20 u32 rx;
21 u32 tx;
22 u32 clk;
23 u32 frm;
24};
25
26/* platform data */
27extern struct snd_soc_platform bf5xx_ac97_soc_platform;
28
29#endif
diff --git a/sound/soc/blackfin/bf5xx-ac97.c b/sound/soc/blackfin/bf5xx-ac97.c
new file mode 100644
index 000000000000..5e5aafb6485f
--- /dev/null
+++ b/sound/soc/blackfin/bf5xx-ac97.c
@@ -0,0 +1,406 @@
1/*
2 * bf5xx-ac97.c -- AC97 support for the ADI blackfin chip.
3 *
4 * Author: Roy Huang
5 * Created: 11th. June 2007
6 * Copyright: Analog Device Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/init.h>
14#include <linux/module.h>
15#include <linux/platform_device.h>
16#include <linux/interrupt.h>
17#include <linux/wait.h>
18#include <linux/delay.h>
19
20#include <sound/core.h>
21#include <sound/pcm.h>
22#include <sound/ac97_codec.h>
23#include <sound/initval.h>
24#include <sound/soc.h>
25
26#include <asm/irq.h>
27#include <asm/portmux.h>
28#include <linux/mutex.h>
29#include <linux/gpio.h>
30
31#include "bf5xx-sport.h"
32#include "bf5xx-ac97.h"
33
34#if defined(CONFIG_BF54x)
35#define PIN_REQ_SPORT_0 {P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, \
36 P_SPORT0_RFS, P_SPORT0_DRPRI, P_SPORT0_RSCLK, 0}
37
38#define PIN_REQ_SPORT_1 {P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, \
39 P_SPORT1_RFS, P_SPORT1_DRPRI, P_SPORT1_RSCLK, 0}
40
41#define PIN_REQ_SPORT_2 {P_SPORT2_TFS, P_SPORT2_DTPRI, P_SPORT2_TSCLK, \
42 P_SPORT2_RFS, P_SPORT2_DRPRI, P_SPORT2_RSCLK, 0}
43
44#define PIN_REQ_SPORT_3 {P_SPORT3_TFS, P_SPORT3_DTPRI, P_SPORT3_TSCLK, \
45 P_SPORT3_RFS, P_SPORT3_DRPRI, P_SPORT3_RSCLK, 0}
46#else
47#define PIN_REQ_SPORT_0 {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, \
48 P_SPORT0_DRPRI, P_SPORT0_RSCLK, 0}
49
50#define PIN_REQ_SPORT_1 {P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, \
51 P_SPORT1_DRPRI, P_SPORT1_RSCLK, 0}
52#endif
53
54static int *cmd_count;
55static int sport_num = CONFIG_SND_BF5XX_SPORT_NUM;
56
57#if defined(CONFIG_BF54x)
58static struct sport_param sport_params[4] = {
59 {
60 .dma_rx_chan = CH_SPORT0_RX,
61 .dma_tx_chan = CH_SPORT0_TX,
62 .err_irq = IRQ_SPORT0_ERR,
63 .regs = (struct sport_register *)SPORT0_TCR1,
64 },
65 {
66 .dma_rx_chan = CH_SPORT1_RX,
67 .dma_tx_chan = CH_SPORT1_TX,
68 .err_irq = IRQ_SPORT1_ERR,
69 .regs = (struct sport_register *)SPORT1_TCR1,
70 },
71 {
72 .dma_rx_chan = CH_SPORT2_RX,
73 .dma_tx_chan = CH_SPORT2_TX,
74 .err_irq = IRQ_SPORT2_ERR,
75 .regs = (struct sport_register *)SPORT2_TCR1,
76 },
77 {
78 .dma_rx_chan = CH_SPORT3_RX,
79 .dma_tx_chan = CH_SPORT3_TX,
80 .err_irq = IRQ_SPORT3_ERR,
81 .regs = (struct sport_register *)SPORT3_TCR1,
82 }
83};
84#else
85static struct sport_param sport_params[2] = {
86 {
87 .dma_rx_chan = CH_SPORT0_RX,
88 .dma_tx_chan = CH_SPORT0_TX,
89 .err_irq = IRQ_SPORT0_ERROR,
90 .regs = (struct sport_register *)SPORT0_TCR1,
91 },
92 {
93 .dma_rx_chan = CH_SPORT1_RX,
94 .dma_tx_chan = CH_SPORT1_TX,
95 .err_irq = IRQ_SPORT1_ERROR,
96 .regs = (struct sport_register *)SPORT1_TCR1,
97 }
98};
99#endif
100
101void bf5xx_pcm_to_ac97(struct ac97_frame *dst, const __u32 *src, \
102 size_t count)
103{
104 while (count--) {
105 dst->ac97_tag = TAG_VALID | TAG_PCM;
106 (dst++)->ac97_pcm = *src++;
107 }
108}
109EXPORT_SYMBOL(bf5xx_pcm_to_ac97);
110
111void bf5xx_ac97_to_pcm(const struct ac97_frame *src, __u32 *dst, \
112 size_t count)
113{
114 while (count--)
115 *(dst++) = (src++)->ac97_pcm;
116}
117EXPORT_SYMBOL(bf5xx_ac97_to_pcm);
118
119static unsigned int sport_tx_curr_frag(struct sport_device *sport)
120{
121 return sport->tx_curr_frag = sport_curr_offset_tx(sport) / \
122 sport->tx_fragsize;
123}
124
125static void enqueue_cmd(struct snd_ac97 *ac97, __u16 addr, __u16 data)
126{
127 struct sport_device *sport = sport_handle;
128 int nextfrag = sport_tx_curr_frag(sport);
129 struct ac97_frame *nextwrite;
130
131 sport_incfrag(sport, &nextfrag, 1);
132
133 nextwrite = (struct ac97_frame *)(sport->tx_buf + \
134 nextfrag * sport->tx_fragsize);
135 pr_debug("sport->tx_buf:%p, nextfrag:0x%x nextwrite:%p, cmd_count:%d\n",
136 sport->tx_buf, nextfrag, nextwrite, cmd_count[nextfrag]);
137 nextwrite[cmd_count[nextfrag]].ac97_tag |= TAG_CMD;
138 nextwrite[cmd_count[nextfrag]].ac97_addr = addr;
139 nextwrite[cmd_count[nextfrag]].ac97_data = data;
140 ++cmd_count[nextfrag];
141 pr_debug("ac97_sport: Inserting %02x/%04x into fragment %d\n",
142 addr >> 8, data, nextfrag);
143}
144
145static unsigned short bf5xx_ac97_read(struct snd_ac97 *ac97,
146 unsigned short reg)
147{
148 struct ac97_frame out_frame[2], in_frame[2];
149
150 pr_debug("%s enter 0x%x\n", __func__, reg);
151
152 /* When dma descriptor is enabled, the register should not be read */
153 if (sport_handle->tx_run || sport_handle->rx_run) {
154 pr_err("Could you send a mail to cliff.cai@analog.com "
155 "to report this?\n");
156 return -EFAULT;
157 }
158
159 memset(&out_frame, 0, 2 * sizeof(struct ac97_frame));
160 memset(&in_frame, 0, 2 * sizeof(struct ac97_frame));
161 out_frame[0].ac97_tag = TAG_VALID | TAG_CMD;
162 out_frame[0].ac97_addr = ((reg << 8) | 0x8000);
163 sport_send_and_recv(sport_handle, (unsigned char *)&out_frame,
164 (unsigned char *)&in_frame,
165 2 * sizeof(struct ac97_frame));
166 return in_frame[1].ac97_data;
167}
168
169void bf5xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
170 unsigned short val)
171{
172 pr_debug("%s enter 0x%x:0x%04x\n", __func__, reg, val);
173
174 if (sport_handle->tx_run) {
175 enqueue_cmd(ac97, (reg << 8), val); /* write */
176 enqueue_cmd(ac97, (reg << 8) | 0x8000, 0); /* read back */
177 } else {
178 struct ac97_frame frame;
179 memset(&frame, 0, sizeof(struct ac97_frame));
180 frame.ac97_tag = TAG_VALID | TAG_CMD;
181 frame.ac97_addr = (reg << 8);
182 frame.ac97_data = val;
183 sport_send_and_recv(sport_handle, (unsigned char *)&frame, \
184 NULL, sizeof(struct ac97_frame));
185 }
186}
187
188static void bf5xx_ac97_warm_reset(struct snd_ac97 *ac97)
189{
190#if defined(CONFIG_BF54x) || defined(CONFIG_BF561) || \
191 (defined(BF537_FAMILY) && (CONFIG_SND_BF5XX_SPORT_NUM == 1))
192
193#define CONCAT(a, b, c) a ## b ## c
194#define BFIN_SPORT_RFS(x) CONCAT(P_SPORT, x, _RFS)
195
196 u16 per = BFIN_SPORT_RFS(CONFIG_SND_BF5XX_SPORT_NUM);
197 u16 gpio = P_IDENT(BFIN_SPORT_RFS(CONFIG_SND_BF5XX_SPORT_NUM));
198
199 pr_debug("%s enter\n", __func__);
200
201 peripheral_free(per);
202 gpio_request(gpio, "bf5xx-ac97");
203 gpio_direction_output(gpio, 1);
204 udelay(2);
205 gpio_set_value(gpio, 0);
206 udelay(1);
207 gpio_free(gpio);
208 peripheral_request(per, "soc-audio");
209#else
210 pr_info("%s: Not implemented\n", __func__);
211#endif
212}
213
214static void bf5xx_ac97_cold_reset(struct snd_ac97 *ac97)
215{
216#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
217 pr_debug("%s enter\n", __func__);
218
219 /* It is specified for bf548-ezkit */
220 gpio_set_value(CONFIG_SND_BF5XX_RESET_GPIO_NUM, 0);
221 /* Keep reset pin low for 1 ms */
222 mdelay(1);
223 gpio_set_value(CONFIG_SND_BF5XX_RESET_GPIO_NUM, 1);
224 /* Wait for bit clock recover */
225 mdelay(1);
226#else
227 pr_info("%s: Not implemented\n", __func__);
228#endif
229}
230
231struct snd_ac97_bus_ops soc_ac97_ops = {
232 .read = bf5xx_ac97_read,
233 .write = bf5xx_ac97_write,
234 .warm_reset = bf5xx_ac97_warm_reset,
235 .reset = bf5xx_ac97_cold_reset,
236};
237EXPORT_SYMBOL_GPL(soc_ac97_ops);
238
239#ifdef CONFIG_PM
240static int bf5xx_ac97_suspend(struct platform_device *pdev,
241 struct snd_soc_dai *dai)
242{
243 struct sport_device *sport =
244 (struct sport_device *)dai->private_data;
245
246 pr_debug("%s : sport %d\n", __func__, dai->id);
247 if (!dai->active)
248 return 0;
249 if (dai->capture.active)
250 sport_rx_stop(sport);
251 if (dai->playback.active)
252 sport_tx_stop(sport);
253 return 0;
254}
255
256static int bf5xx_ac97_resume(struct platform_device *pdev,
257 struct snd_soc_dai *dai)
258{
259 int ret;
260 struct sport_device *sport =
261 (struct sport_device *)dai->private_data;
262
263 pr_debug("%s : sport %d\n", __func__, dai->id);
264 if (!dai->active)
265 return 0;
266
267 ret = sport_set_multichannel(sport_handle, 16, 0x1F, 1);
268 if (ret) {
269 pr_err("SPORT is busy!\n");
270 return -EBUSY;
271 }
272
273 ret = sport_config_rx(sport_handle, IRFS, 0xF, 0, (16*16-1));
274 if (ret) {
275 pr_err("SPORT is busy!\n");
276 return -EBUSY;
277 }
278
279 ret = sport_config_tx(sport_handle, ITFS, 0xF, 0, (16*16-1));
280 if (ret) {
281 pr_err("SPORT is busy!\n");
282 return -EBUSY;
283 }
284
285 if (dai->capture.active)
286 sport_rx_start(sport);
287 if (dai->playback.active)
288 sport_tx_start(sport);
289 return 0;
290}
291
292#else
293#define bf5xx_ac97_suspend NULL
294#define bf5xx_ac97_resume NULL
295#endif
296
297static int bf5xx_ac97_probe(struct platform_device *pdev,
298 struct snd_soc_dai *dai)
299{
300 int ret;
301#if defined(CONFIG_BF54x)
302 u16 sport_req[][7] = {PIN_REQ_SPORT_0, PIN_REQ_SPORT_1,
303 PIN_REQ_SPORT_2, PIN_REQ_SPORT_3};
304#else
305 u16 sport_req[][7] = {PIN_REQ_SPORT_0, PIN_REQ_SPORT_1};
306#endif
307 cmd_count = (int *)get_zeroed_page(GFP_KERNEL);
308 if (cmd_count == NULL)
309 return -ENOMEM;
310
311 if (peripheral_request_list(&sport_req[sport_num][0], "soc-audio")) {
312 pr_err("Requesting Peripherals failed\n");
313 return -EFAULT;
314 }
315
316#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
317 /* Request PB3 as reset pin */
318 if (gpio_request(CONFIG_SND_BF5XX_RESET_GPIO_NUM, "SND_AD198x RESET")) {
319 pr_err("Failed to request GPIO_%d for reset\n",
320 CONFIG_SND_BF5XX_RESET_GPIO_NUM);
321 peripheral_free_list(&sport_req[sport_num][0]);
322 return -1;
323 }
324 gpio_direction_output(CONFIG_SND_BF5XX_RESET_GPIO_NUM, 1);
325#endif
326 sport_handle = sport_init(&sport_params[sport_num], 2, \
327 sizeof(struct ac97_frame), NULL);
328 if (!sport_handle) {
329 peripheral_free_list(&sport_req[sport_num][0]);
330#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
331 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
332#endif
333 return -ENODEV;
334 }
335 /*SPORT works in TDM mode to simulate AC97 transfers*/
336 ret = sport_set_multichannel(sport_handle, 16, 0x1F, 1);
337 if (ret) {
338 pr_err("SPORT is busy!\n");
339 kfree(sport_handle);
340 peripheral_free_list(&sport_req[sport_num][0]);
341#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
342 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
343#endif
344 return -EBUSY;
345 }
346
347 ret = sport_config_rx(sport_handle, IRFS, 0xF, 0, (16*16-1));
348 if (ret) {
349 pr_err("SPORT is busy!\n");
350 kfree(sport_handle);
351 peripheral_free_list(&sport_req[sport_num][0]);
352#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
353 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
354#endif
355 return -EBUSY;
356 }
357
358 ret = sport_config_tx(sport_handle, ITFS, 0xF, 0, (16*16-1));
359 if (ret) {
360 pr_err("SPORT is busy!\n");
361 kfree(sport_handle);
362 peripheral_free_list(&sport_req[sport_num][0]);
363#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
364 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
365#endif
366 return -EBUSY;
367 }
368 return 0;
369}
370
371static void bf5xx_ac97_remove(struct platform_device *pdev,
372 struct snd_soc_dai *dai)
373{
374 free_page((unsigned long)cmd_count);
375 cmd_count = NULL;
376#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
377 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
378#endif
379}
380
381struct snd_soc_dai bfin_ac97_dai = {
382 .name = "bf5xx-ac97",
383 .id = 0,
384 .type = SND_SOC_DAI_AC97,
385 .probe = bf5xx_ac97_probe,
386 .remove = bf5xx_ac97_remove,
387 .suspend = bf5xx_ac97_suspend,
388 .resume = bf5xx_ac97_resume,
389 .playback = {
390 .stream_name = "AC97 Playback",
391 .channels_min = 2,
392 .channels_max = 2,
393 .rates = SNDRV_PCM_RATE_48000,
394 .formats = SNDRV_PCM_FMTBIT_S16_LE, },
395 .capture = {
396 .stream_name = "AC97 Capture",
397 .channels_min = 2,
398 .channels_max = 2,
399 .rates = SNDRV_PCM_RATE_48000,
400 .formats = SNDRV_PCM_FMTBIT_S16_LE, },
401};
402EXPORT_SYMBOL_GPL(bfin_ac97_dai);
403
404MODULE_AUTHOR("Roy Huang");
405MODULE_DESCRIPTION("AC97 driver for ADI Blackfin");
406MODULE_LICENSE("GPL");
diff --git a/sound/soc/blackfin/bf5xx-ac97.h b/sound/soc/blackfin/bf5xx-ac97.h
new file mode 100644
index 000000000000..3f77cc558dc0
--- /dev/null
+++ b/sound/soc/blackfin/bf5xx-ac97.h
@@ -0,0 +1,36 @@
1/*
2 * linux/sound/arm/bf5xx-ac97.h
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#ifndef _BF5XX_AC97_H
10#define _BF5XX_AC97_H
11
12extern struct snd_ac97_bus_ops bf5xx_ac97_ops;
13extern struct snd_ac97 *ac97;
14/* Frame format in memory, only support stereo currently */
15struct ac97_frame {
16 u16 ac97_tag; /* slot 0 */
17 u16 ac97_addr; /* slot 1 */
18 u16 ac97_data; /* slot 2 */
19 u32 ac97_pcm; /* slot 3 and 4: left and right pcm data */
20} __attribute__ ((packed));
21
22#define TAG_VALID 0x8000
23#define TAG_CMD 0x6000
24#define TAG_PCM_LEFT 0x1000
25#define TAG_PCM_RIGHT 0x0800
26#define TAG_PCM (TAG_PCM_LEFT | TAG_PCM_RIGHT)
27
28extern struct snd_soc_dai bfin_ac97_dai;
29
30void bf5xx_pcm_to_ac97(struct ac97_frame *dst, const __u32 *src, \
31 size_t count);
32
33void bf5xx_ac97_to_pcm(const struct ac97_frame *src, __u32 *dst, \
34 size_t count);
35
36#endif
diff --git a/sound/soc/blackfin/bf5xx-ad1980.c b/sound/soc/blackfin/bf5xx-ad1980.c
new file mode 100644
index 000000000000..124425d22320
--- /dev/null
+++ b/sound/soc/blackfin/bf5xx-ad1980.c
@@ -0,0 +1,113 @@
1/*
2 * File: sound/soc/blackfin/bf5xx-ad1980.c
3 * Author: Cliff Cai <Cliff.Cai@analog.com>
4 *
5 * Created: Tue June 06 2008
6 * Description: Board driver for AD1980/1 audio codec
7 *
8 * Modified:
9 * Copyright 2008 Analog Devices Inc.
10 *
11 * Bugs: Enter bugs at http://blackfin.uclinux.org/
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, see the file COPYING, or write
25 * to the Free Software Foundation, Inc.,
26 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27 */
28
29#include <linux/module.h>
30#include <linux/moduleparam.h>
31#include <linux/device.h>
32#include <asm/dma.h>
33
34#include <sound/core.h>
35#include <sound/pcm.h>
36#include <sound/soc.h>
37
38#include <linux/gpio.h>
39#include <asm/portmux.h>
40
41#include "../codecs/ad1980.h"
42#include "bf5xx-sport.h"
43#include "bf5xx-ac97-pcm.h"
44#include "bf5xx-ac97.h"
45
46static struct snd_soc_machine bf5xx_board;
47
48static int bf5xx_board_startup(struct snd_pcm_substream *substream)
49{
50 struct snd_soc_pcm_runtime *rtd = substream->private_data;
51 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
52
53 pr_debug("%s enter\n", __func__);
54 cpu_dai->private_data = sport_handle;
55 return 0;
56}
57
58static struct snd_soc_ops bf5xx_board_ops = {
59 .startup = bf5xx_board_startup,
60};
61
62static struct snd_soc_dai_link bf5xx_board_dai = {
63 .name = "AC97",
64 .stream_name = "AC97 HiFi",
65 .cpu_dai = &bfin_ac97_dai,
66 .codec_dai = &ad1980_dai,
67 .ops = &bf5xx_board_ops,
68};
69
70static struct snd_soc_machine bf5xx_board = {
71 .name = "bf5xx-board",
72 .dai_link = &bf5xx_board_dai,
73 .num_links = 1,
74};
75
76static struct snd_soc_device bf5xx_board_snd_devdata = {
77 .machine = &bf5xx_board,
78 .platform = &bf5xx_ac97_soc_platform,
79 .codec_dev = &soc_codec_dev_ad1980,
80};
81
82static struct platform_device *bf5xx_board_snd_device;
83
84static int __init bf5xx_board_init(void)
85{
86 int ret;
87
88 bf5xx_board_snd_device = platform_device_alloc("soc-audio", -1);
89 if (!bf5xx_board_snd_device)
90 return -ENOMEM;
91
92 platform_set_drvdata(bf5xx_board_snd_device, &bf5xx_board_snd_devdata);
93 bf5xx_board_snd_devdata.dev = &bf5xx_board_snd_device->dev;
94 ret = platform_device_add(bf5xx_board_snd_device);
95
96 if (ret)
97 platform_device_put(bf5xx_board_snd_device);
98
99 return ret;
100}
101
102static void __exit bf5xx_board_exit(void)
103{
104 platform_device_unregister(bf5xx_board_snd_device);
105}
106
107module_init(bf5xx_board_init);
108module_exit(bf5xx_board_exit);
109
110/* Module information */
111MODULE_AUTHOR("Cliff Cai");
112MODULE_DESCRIPTION("ALSA SoC AD1980/1 BF5xx board");
113MODULE_LICENSE("GPL");
diff --git a/sound/soc/blackfin/bf5xx-ad73311.c b/sound/soc/blackfin/bf5xx-ad73311.c
new file mode 100644
index 000000000000..622c9b909532
--- /dev/null
+++ b/sound/soc/blackfin/bf5xx-ad73311.c
@@ -0,0 +1,240 @@
1/*
2 * File: sound/soc/blackfin/bf5xx-ad73311.c
3 * Author: Cliff Cai <Cliff.Cai@analog.com>
4 *
5 * Created: Thur Sep 25 2008
6 * Description: Board driver for ad73311 sound chip
7 *
8 * Modified:
9 * Copyright 2008 Analog Devices Inc.
10 *
11 * Bugs: Enter bugs at http://blackfin.uclinux.org/
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, see the file COPYING, or write
25 * to the Free Software Foundation, Inc.,
26 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27 */
28
29#include <linux/module.h>
30#include <linux/moduleparam.h>
31#include <linux/device.h>
32#include <linux/delay.h>
33#include <linux/gpio.h>
34
35#include <sound/core.h>
36#include <sound/pcm.h>
37#include <sound/soc.h>
38#include <sound/soc-dapm.h>
39#include <sound/pcm_params.h>
40
41#include <asm/blackfin.h>
42#include <asm/cacheflush.h>
43#include <asm/irq.h>
44#include <asm/dma.h>
45#include <asm/portmux.h>
46
47#include "../codecs/ad73311.h"
48#include "bf5xx-sport.h"
49#include "bf5xx-i2s-pcm.h"
50#include "bf5xx-i2s.h"
51
52#if CONFIG_SND_BF5XX_SPORT_NUM == 0
53#define bfin_write_SPORT_TCR1 bfin_write_SPORT0_TCR1
54#define bfin_read_SPORT_TCR1 bfin_read_SPORT0_TCR1
55#define bfin_write_SPORT_TCR2 bfin_write_SPORT0_TCR2
56#define bfin_write_SPORT_TX16 bfin_write_SPORT0_TX16
57#define bfin_read_SPORT_STAT bfin_read_SPORT0_STAT
58#else
59#define bfin_write_SPORT_TCR1 bfin_write_SPORT1_TCR1
60#define bfin_read_SPORT_TCR1 bfin_read_SPORT1_TCR1
61#define bfin_write_SPORT_TCR2 bfin_write_SPORT1_TCR2
62#define bfin_write_SPORT_TX16 bfin_write_SPORT1_TX16
63#define bfin_read_SPORT_STAT bfin_read_SPORT1_STAT
64#endif
65
66#define GPIO_SE CONFIG_SND_BFIN_AD73311_SE
67
68static struct snd_soc_machine bf5xx_ad73311;
69
70static int snd_ad73311_startup(void)
71{
72 pr_debug("%s enter\n", __func__);
73
74 /* Pull up SE pin on AD73311L */
75 gpio_set_value(GPIO_SE, 1);
76 return 0;
77}
78
79static int snd_ad73311_configure(void)
80{
81 unsigned short ctrl_regs[6];
82 unsigned short status = 0;
83 int count = 0;
84
85 /* DMCLK = MCLK = 16.384 MHz
86 * SCLK = DMCLK/8 = 2.048 MHz
87 * Sample Rate = DMCLK/2048 = 8 KHz
88 */
89 ctrl_regs[0] = AD_CONTROL | AD_WRITE | CTRL_REG_B | REGB_MCDIV(0) | \
90 REGB_SCDIV(0) | REGB_DIRATE(0);
91 ctrl_regs[1] = AD_CONTROL | AD_WRITE | CTRL_REG_C | REGC_PUDEV | \
92 REGC_PUADC | REGC_PUDAC | REGC_PUREF | REGC_REFUSE ;
93 ctrl_regs[2] = AD_CONTROL | AD_WRITE | CTRL_REG_D | REGD_OGS(2) | \
94 REGD_IGS(2);
95 ctrl_regs[3] = AD_CONTROL | AD_WRITE | CTRL_REG_E | REGE_DA(0x1f);
96 ctrl_regs[4] = AD_CONTROL | AD_WRITE | CTRL_REG_F | REGF_SEEN ;
97 ctrl_regs[5] = AD_CONTROL | AD_WRITE | CTRL_REG_A | REGA_MODE_DATA;
98
99 local_irq_disable();
100 snd_ad73311_startup();
101 udelay(1);
102
103 bfin_write_SPORT_TCR1(TFSR);
104 bfin_write_SPORT_TCR2(0xF);
105 SSYNC();
106
107 /* SPORT Tx Register is a 8 x 16 FIFO, all the data can be put to
108 * FIFO before enable SPORT to transfer the data
109 */
110 for (count = 0; count < 6; count++)
111 bfin_write_SPORT_TX16(ctrl_regs[count]);
112 SSYNC();
113 bfin_write_SPORT_TCR1(bfin_read_SPORT_TCR1() | TSPEN);
114 SSYNC();
115
116 /* When TUVF is set, the data is already send out */
117 while (!(status & TUVF) && count++ < 10000) {
118 udelay(1);
119 status = bfin_read_SPORT_STAT();
120 SSYNC();
121 }
122 bfin_write_SPORT_TCR1(bfin_read_SPORT_TCR1() & ~TSPEN);
123 SSYNC();
124 local_irq_enable();
125
126 if (count == 10000) {
127 printk(KERN_ERR "ad73311: failed to configure codec\n");
128 return -1;
129 }
130 return 0;
131}
132
133static int bf5xx_probe(struct platform_device *pdev)
134{
135 int err;
136 if (gpio_request(GPIO_SE, "AD73311_SE")) {
137 printk(KERN_ERR "%s: Failed ro request GPIO_%d\n", __func__, GPIO_SE);
138 return -EBUSY;
139 }
140
141 gpio_direction_output(GPIO_SE, 0);
142
143 err = snd_ad73311_configure();
144 if (err < 0)
145 return -EFAULT;
146
147 return 0;
148}
149
150static int bf5xx_ad73311_startup(struct snd_pcm_substream *substream)
151{
152 struct snd_soc_pcm_runtime *rtd = substream->private_data;
153 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
154
155 pr_debug("%s enter\n", __func__);
156 cpu_dai->private_data = sport_handle;
157 return 0;
158}
159
160static int bf5xx_ad73311_hw_params(struct snd_pcm_substream *substream,
161 struct snd_pcm_hw_params *params)
162{
163 struct snd_soc_pcm_runtime *rtd = substream->private_data;
164 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
165 int ret = 0;
166
167 pr_debug("%s rate %d format %x\n", __func__, params_rate(params),
168 params_format(params));
169
170 /* set cpu DAI configuration */
171 ret = cpu_dai->dai_ops.set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A |
172 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
173 if (ret < 0)
174 return ret;
175
176 return 0;
177}
178
179
180static struct snd_soc_ops bf5xx_ad73311_ops = {
181 .startup = bf5xx_ad73311_startup,
182 .hw_params = bf5xx_ad73311_hw_params,
183};
184
185static struct snd_soc_dai_link bf5xx_ad73311_dai = {
186 .name = "ad73311",
187 .stream_name = "AD73311",
188 .cpu_dai = &bf5xx_i2s_dai,
189 .codec_dai = &ad73311_dai,
190 .ops = &bf5xx_ad73311_ops,
191};
192
193static struct snd_soc_machine bf5xx_ad73311 = {
194 .name = "bf5xx_ad73311",
195 .probe = bf5xx_probe,
196 .dai_link = &bf5xx_ad73311_dai,
197 .num_links = 1,
198};
199
200static struct snd_soc_device bf5xx_ad73311_snd_devdata = {
201 .machine = &bf5xx_ad73311,
202 .platform = &bf5xx_i2s_soc_platform,
203 .codec_dev = &soc_codec_dev_ad73311,
204};
205
206static struct platform_device *bf52x_ad73311_snd_device;
207
208static int __init bf5xx_ad73311_init(void)
209{
210 int ret;
211
212 pr_debug("%s enter\n", __func__);
213 bf52x_ad73311_snd_device = platform_device_alloc("soc-audio", -1);
214 if (!bf52x_ad73311_snd_device)
215 return -ENOMEM;
216
217 platform_set_drvdata(bf52x_ad73311_snd_device, &bf5xx_ad73311_snd_devdata);
218 bf5xx_ad73311_snd_devdata.dev = &bf52x_ad73311_snd_device->dev;
219 ret = platform_device_add(bf52x_ad73311_snd_device);
220
221 if (ret)
222 platform_device_put(bf52x_ad73311_snd_device);
223
224 return ret;
225}
226
227static void __exit bf5xx_ad73311_exit(void)
228{
229 pr_debug("%s enter\n", __func__);
230 platform_device_unregister(bf52x_ad73311_snd_device);
231}
232
233module_init(bf5xx_ad73311_init);
234module_exit(bf5xx_ad73311_exit);
235
236/* Module information */
237MODULE_AUTHOR("Cliff Cai");
238MODULE_DESCRIPTION("ALSA SoC AD73311 Blackfin");
239MODULE_LICENSE("GPL");
240
diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.c b/sound/soc/blackfin/bf5xx-i2s-pcm.c
new file mode 100644
index 000000000000..61fccf925192
--- /dev/null
+++ b/sound/soc/blackfin/bf5xx-i2s-pcm.c
@@ -0,0 +1,288 @@
1/*
2 * File: sound/soc/blackfin/bf5xx-i2s-pcm.c
3 * Author: Cliff Cai <Cliff.Cai@analog.com>
4 *
5 * Created: Tue June 06 2008
6 * Description: DMA driver for i2s codec
7 *
8 * Modified:
9 * Copyright 2008 Analog Devices Inc.
10 *
11 * Bugs: Enter bugs at http://blackfin.uclinux.org/
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, see the file COPYING, or write
25 * to the Free Software Foundation, Inc.,
26 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27 */
28
29#include <linux/module.h>
30#include <linux/init.h>
31#include <linux/platform_device.h>
32#include <linux/slab.h>
33#include <linux/dma-mapping.h>
34
35#include <sound/core.h>
36#include <sound/pcm.h>
37#include <sound/pcm_params.h>
38#include <sound/soc.h>
39
40#include <asm/dma.h>
41
42#include "bf5xx-i2s-pcm.h"
43#include "bf5xx-i2s.h"
44#include "bf5xx-sport.h"
45
46static void bf5xx_dma_irq(void *data)
47{
48 struct snd_pcm_substream *pcm = data;
49 snd_pcm_period_elapsed(pcm);
50}
51
52static const struct snd_pcm_hardware bf5xx_pcm_hardware = {
53 .info = SNDRV_PCM_INFO_INTERLEAVED |
54 SNDRV_PCM_INFO_MMAP |
55 SNDRV_PCM_INFO_MMAP_VALID |
56 SNDRV_PCM_INFO_BLOCK_TRANSFER,
57 .formats = SNDRV_PCM_FMTBIT_S16_LE |
58 SNDRV_PCM_FMTBIT_S24_LE |
59 SNDRV_PCM_FMTBIT_S32_LE,
60 .period_bytes_min = 32,
61 .period_bytes_max = 0x10000,
62 .periods_min = 1,
63 .periods_max = PAGE_SIZE/32,
64 .buffer_bytes_max = 0x20000, /* 128 kbytes */
65 .fifo_size = 16,
66};
67
68static int bf5xx_pcm_hw_params(struct snd_pcm_substream *substream,
69 struct snd_pcm_hw_params *params)
70{
71 size_t size = bf5xx_pcm_hardware.buffer_bytes_max;
72 snd_pcm_lib_malloc_pages(substream, size);
73
74 return 0;
75}
76
77static int bf5xx_pcm_hw_free(struct snd_pcm_substream *substream)
78{
79 snd_pcm_lib_free_pages(substream);
80
81 return 0;
82}
83
84static int bf5xx_pcm_prepare(struct snd_pcm_substream *substream)
85{
86 struct snd_pcm_runtime *runtime = substream->runtime;
87 struct sport_device *sport = runtime->private_data;
88 int period_bytes = frames_to_bytes(runtime, runtime->period_size);
89
90 pr_debug("%s enter\n", __func__);
91 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
92 sport_set_tx_callback(sport, bf5xx_dma_irq, substream);
93 sport_config_tx_dma(sport, runtime->dma_area,
94 runtime->periods, period_bytes);
95 } else {
96 sport_set_rx_callback(sport, bf5xx_dma_irq, substream);
97 sport_config_rx_dma(sport, runtime->dma_area,
98 runtime->periods, period_bytes);
99 }
100
101 return 0;
102}
103
104static int bf5xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
105{
106 struct snd_pcm_runtime *runtime = substream->runtime;
107 struct sport_device *sport = runtime->private_data;
108 int ret = 0;
109
110 pr_debug("%s enter\n", __func__);
111 switch (cmd) {
112 case SNDRV_PCM_TRIGGER_START:
113 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
114 sport_tx_start(sport);
115 else
116 sport_rx_start(sport);
117 break;
118 case SNDRV_PCM_TRIGGER_STOP:
119 case SNDRV_PCM_TRIGGER_SUSPEND:
120 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
121 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
122 sport_tx_stop(sport);
123 else
124 sport_rx_stop(sport);
125 break;
126 default:
127 ret = -EINVAL;
128 }
129
130 return ret;
131}
132
133static snd_pcm_uframes_t bf5xx_pcm_pointer(struct snd_pcm_substream *substream)
134{
135 struct snd_pcm_runtime *runtime = substream->runtime;
136 struct sport_device *sport = runtime->private_data;
137 unsigned int diff;
138 snd_pcm_uframes_t frames;
139 pr_debug("%s enter\n", __func__);
140 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
141 diff = sport_curr_offset_tx(sport);
142 frames = bytes_to_frames(substream->runtime, diff);
143 } else {
144 diff = sport_curr_offset_rx(sport);
145 frames = bytes_to_frames(substream->runtime, diff);
146 }
147 return frames;
148}
149
150static int bf5xx_pcm_open(struct snd_pcm_substream *substream)
151{
152 struct snd_pcm_runtime *runtime = substream->runtime;
153 int ret;
154
155 pr_debug("%s enter\n", __func__);
156 snd_soc_set_runtime_hwparams(substream, &bf5xx_pcm_hardware);
157
158 ret = snd_pcm_hw_constraint_integer(runtime, \
159 SNDRV_PCM_HW_PARAM_PERIODS);
160 if (ret < 0)
161 goto out;
162
163 if (sport_handle != NULL)
164 runtime->private_data = sport_handle;
165 else {
166 pr_err("sport_handle is NULL\n");
167 return -1;
168 }
169 return 0;
170
171 out:
172 return ret;
173}
174
175static int bf5xx_pcm_mmap(struct snd_pcm_substream *substream,
176 struct vm_area_struct *vma)
177{
178 struct snd_pcm_runtime *runtime = substream->runtime;
179 size_t size = vma->vm_end - vma->vm_start;
180 vma->vm_start = (unsigned long)runtime->dma_area;
181 vma->vm_end = vma->vm_start + size;
182 vma->vm_flags |= VM_SHARED;
183
184 return 0 ;
185}
186
187struct snd_pcm_ops bf5xx_pcm_i2s_ops = {
188 .open = bf5xx_pcm_open,
189 .ioctl = snd_pcm_lib_ioctl,
190 .hw_params = bf5xx_pcm_hw_params,
191 .hw_free = bf5xx_pcm_hw_free,
192 .prepare = bf5xx_pcm_prepare,
193 .trigger = bf5xx_pcm_trigger,
194 .pointer = bf5xx_pcm_pointer,
195 .mmap = bf5xx_pcm_mmap,
196};
197
198static int bf5xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
199{
200 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
201 struct snd_dma_buffer *buf = &substream->dma_buffer;
202 size_t size = bf5xx_pcm_hardware.buffer_bytes_max;
203
204 buf->dev.type = SNDRV_DMA_TYPE_DEV;
205 buf->dev.dev = pcm->card->dev;
206 buf->private_data = NULL;
207 buf->area = dma_alloc_coherent(pcm->card->dev, size,
208 &buf->addr, GFP_KERNEL);
209 if (!buf->area) {
210 pr_err("Failed to allocate dma memory \
211 Please increase uncached DMA memory region\n");
212 return -ENOMEM;
213 }
214 buf->bytes = size;
215
216 pr_debug("%s, area:%p, size:0x%08lx\n", __func__,
217 buf->area, buf->bytes);
218
219 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
220 sport_handle->tx_buf = buf->area;
221 else
222 sport_handle->rx_buf = buf->area;
223
224 return 0;
225}
226
227static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
228{
229 struct snd_pcm_substream *substream;
230 struct snd_dma_buffer *buf;
231 int stream;
232
233 for (stream = 0; stream < 2; stream++) {
234 substream = pcm->streams[stream].substream;
235 if (!substream)
236 continue;
237
238 buf = &substream->dma_buffer;
239 if (!buf->area)
240 continue;
241 dma_free_coherent(NULL, buf->bytes, buf->area, 0);
242 buf->area = NULL;
243 }
244 if (sport_handle)
245 sport_done(sport_handle);
246}
247
248static u64 bf5xx_pcm_dmamask = DMA_32BIT_MASK;
249
250int bf5xx_pcm_i2s_new(struct snd_card *card, struct snd_soc_dai *dai,
251 struct snd_pcm *pcm)
252{
253 int ret = 0;
254
255 pr_debug("%s enter\n", __func__);
256 if (!card->dev->dma_mask)
257 card->dev->dma_mask = &bf5xx_pcm_dmamask;
258 if (!card->dev->coherent_dma_mask)
259 card->dev->coherent_dma_mask = DMA_32BIT_MASK;
260
261 if (dai->playback.channels_min) {
262 ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
263 SNDRV_PCM_STREAM_PLAYBACK);
264 if (ret)
265 goto out;
266 }
267
268 if (dai->capture.channels_min) {
269 ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
270 SNDRV_PCM_STREAM_CAPTURE);
271 if (ret)
272 goto out;
273 }
274 out:
275 return ret;
276}
277
278struct snd_soc_platform bf5xx_i2s_soc_platform = {
279 .name = "bf5xx-audio",
280 .pcm_ops = &bf5xx_pcm_i2s_ops,
281 .pcm_new = bf5xx_pcm_i2s_new,
282 .pcm_free = bf5xx_pcm_free_dma_buffers,
283};
284EXPORT_SYMBOL_GPL(bf5xx_i2s_soc_platform);
285
286MODULE_AUTHOR("Cliff Cai");
287MODULE_DESCRIPTION("ADI Blackfin I2S PCM DMA module");
288MODULE_LICENSE("GPL");
diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.h b/sound/soc/blackfin/bf5xx-i2s-pcm.h
new file mode 100644
index 000000000000..4d4609a97c59
--- /dev/null
+++ b/sound/soc/blackfin/bf5xx-i2s-pcm.h
@@ -0,0 +1,29 @@
1/*
2 * linux/sound/arm/bf5xx-i2s-pcm.h -- ALSA PCM interface for the Blackfin
3 *
4 * Copyright 2007 Analog Device Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef _BF5XX_I2S_PCM_H
12#define _BF5XX_I2S_PCM_H
13
14struct bf5xx_pcm_dma_params {
15 char *name; /* stream identifier */
16};
17
18struct bf5xx_gpio {
19 u32 sys;
20 u32 rx;
21 u32 tx;
22 u32 clk;
23 u32 frm;
24};
25
26/* platform data */
27extern struct snd_soc_platform bf5xx_i2s_soc_platform;
28
29#endif
diff --git a/sound/soc/blackfin/bf5xx-i2s.c b/sound/soc/blackfin/bf5xx-i2s.c
new file mode 100644
index 000000000000..827587f08180
--- /dev/null
+++ b/sound/soc/blackfin/bf5xx-i2s.c
@@ -0,0 +1,311 @@
1/*
2 * File: sound/soc/blackfin/bf5xx-i2s.c
3 * Author: Cliff Cai <Cliff.Cai@analog.com>
4 *
5 * Created: Tue June 06 2008
6 * Description: Blackfin I2S CPU DAI driver
7 *
8 * Modified:
9 * Copyright 2008 Analog Devices Inc.
10 *
11 * Bugs: Enter bugs at http://blackfin.uclinux.org/
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, see the file COPYING, or write
25 * to the Free Software Foundation, Inc.,
26 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27 */
28
29#include <linux/init.h>
30#include <linux/module.h>
31#include <linux/device.h>
32#include <linux/delay.h>
33#include <sound/core.h>
34#include <sound/pcm.h>
35#include <sound/pcm_params.h>
36#include <sound/initval.h>
37#include <sound/soc.h>
38
39#include <asm/irq.h>
40#include <asm/portmux.h>
41#include <linux/mutex.h>
42#include <linux/gpio.h>
43
44#include "bf5xx-sport.h"
45#include "bf5xx-i2s.h"
46
47struct bf5xx_i2s_port {
48 u16 tcr1;
49 u16 rcr1;
50 u16 tcr2;
51 u16 rcr2;
52 int counter;
53};
54
55static struct bf5xx_i2s_port bf5xx_i2s;
56static int sport_num = CONFIG_SND_BF5XX_SPORT_NUM;
57
58static struct sport_param sport_params[2] = {
59 {
60 .dma_rx_chan = CH_SPORT0_RX,
61 .dma_tx_chan = CH_SPORT0_TX,
62 .err_irq = IRQ_SPORT0_ERROR,
63 .regs = (struct sport_register *)SPORT0_TCR1,
64 },
65 {
66 .dma_rx_chan = CH_SPORT1_RX,
67 .dma_tx_chan = CH_SPORT1_TX,
68 .err_irq = IRQ_SPORT1_ERROR,
69 .regs = (struct sport_register *)SPORT1_TCR1,
70 }
71};
72
73static u16 sport_req[][7] = {
74 { P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
75 P_SPORT0_DRPRI, P_SPORT0_RSCLK, 0},
76 { P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
77 P_SPORT1_DRPRI, P_SPORT1_RSCLK, 0},
78};
79
80static int bf5xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
81 unsigned int fmt)
82{
83 int ret = 0;
84
85 /* interface format:support I2S,slave mode */
86 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
87 case SND_SOC_DAIFMT_I2S:
88 bf5xx_i2s.tcr1 |= TFSR | TCKFE;
89 bf5xx_i2s.rcr1 |= RFSR | RCKFE;
90 bf5xx_i2s.tcr2 |= TSFSE;
91 bf5xx_i2s.rcr2 |= RSFSE;
92 break;
93 case SND_SOC_DAIFMT_DSP_A:
94 bf5xx_i2s.tcr1 |= TFSR;
95 bf5xx_i2s.rcr1 |= RFSR;
96 break;
97 case SND_SOC_DAIFMT_LEFT_J:
98 ret = -EINVAL;
99 break;
100 default:
101 ret = -EINVAL;
102 break;
103 }
104
105 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
106 case SND_SOC_DAIFMT_CBS_CFS:
107 ret = -EINVAL;
108 break;
109 case SND_SOC_DAIFMT_CBM_CFS:
110 ret = -EINVAL;
111 break;
112 case SND_SOC_DAIFMT_CBM_CFM:
113 break;
114 case SND_SOC_DAIFMT_CBS_CFM:
115 ret = -EINVAL;
116 break;
117 default:
118 ret = -EINVAL;
119 break;
120 }
121
122 return ret;
123}
124
125static int bf5xx_i2s_startup(struct snd_pcm_substream *substream)
126{
127 pr_debug("%s enter\n", __func__);
128
129 /*this counter is used for counting how many pcm streams are opened*/
130 bf5xx_i2s.counter++;
131 return 0;
132}
133
134static int bf5xx_i2s_hw_params(struct snd_pcm_substream *substream,
135 struct snd_pcm_hw_params *params)
136{
137 int ret = 0;
138
139 bf5xx_i2s.tcr2 &= ~0x1f;
140 bf5xx_i2s.rcr2 &= ~0x1f;
141 switch (params_format(params)) {
142 case SNDRV_PCM_FORMAT_S16_LE:
143 bf5xx_i2s.tcr2 |= 15;
144 bf5xx_i2s.rcr2 |= 15;
145 sport_handle->wdsize = 2;
146 break;
147 case SNDRV_PCM_FORMAT_S24_LE:
148 bf5xx_i2s.tcr2 |= 23;
149 bf5xx_i2s.rcr2 |= 23;
150 sport_handle->wdsize = 3;
151 break;
152 case SNDRV_PCM_FORMAT_S32_LE:
153 bf5xx_i2s.tcr2 |= 31;
154 bf5xx_i2s.rcr2 |= 31;
155 sport_handle->wdsize = 4;
156 break;
157 }
158
159 if (bf5xx_i2s.counter == 1) {
160 /*
161 * TX and RX are not independent,they are enabled at the
162 * same time, even if only one side is running. So, we
163 * need to configure both of them at the time when the first
164 * stream is opened.
165 *
166 * CPU DAI:slave mode.
167 */
168 ret = sport_config_rx(sport_handle, bf5xx_i2s.rcr1,
169 bf5xx_i2s.rcr2, 0, 0);
170 if (ret) {
171 pr_err("SPORT is busy!\n");
172 return -EBUSY;
173 }
174
175 ret = sport_config_tx(sport_handle, bf5xx_i2s.tcr1,
176 bf5xx_i2s.tcr2, 0, 0);
177 if (ret) {
178 pr_err("SPORT is busy!\n");
179 return -EBUSY;
180 }
181 }
182
183 return 0;
184}
185
186static void bf5xx_i2s_shutdown(struct snd_pcm_substream *substream)
187{
188 pr_debug("%s enter\n", __func__);
189 bf5xx_i2s.counter--;
190}
191
192static int bf5xx_i2s_probe(struct platform_device *pdev,
193 struct snd_soc_dai *dai)
194{
195 pr_debug("%s enter\n", __func__);
196 if (peripheral_request_list(&sport_req[sport_num][0], "soc-audio")) {
197 pr_err("Requesting Peripherals failed\n");
198 return -EFAULT;
199 }
200
201 /* request DMA for SPORT */
202 sport_handle = sport_init(&sport_params[sport_num], 4, \
203 2 * sizeof(u32), NULL);
204 if (!sport_handle) {
205 peripheral_free_list(&sport_req[sport_num][0]);
206 return -ENODEV;
207 }
208
209 return 0;
210}
211
212static void bf5xx_i2s_remove(struct platform_device *pdev,
213 struct snd_soc_dai *dai)
214{
215 pr_debug("%s enter\n", __func__);
216 peripheral_free_list(&sport_req[sport_num][0]);
217}
218
219#ifdef CONFIG_PM
220static int bf5xx_i2s_suspend(struct platform_device *dev,
221 struct snd_soc_dai *dai)
222{
223 struct sport_device *sport =
224 (struct sport_device *)dai->private_data;
225
226 pr_debug("%s : sport %d\n", __func__, dai->id);
227 if (!dai->active)
228 return 0;
229 if (dai->capture.active)
230 sport_rx_stop(sport);
231 if (dai->playback.active)
232 sport_tx_stop(sport);
233 return 0;
234}
235
236static int bf5xx_i2s_resume(struct platform_device *pdev,
237 struct snd_soc_dai *dai)
238{
239 int ret;
240 struct sport_device *sport =
241 (struct sport_device *)dai->private_data;
242
243 pr_debug("%s : sport %d\n", __func__, dai->id);
244 if (!dai->active)
245 return 0;
246
247 ret = sport_config_rx(sport_handle, RFSR | RCKFE, RSFSE|0x1f, 0, 0);
248 if (ret) {
249 pr_err("SPORT is busy!\n");
250 return -EBUSY;
251 }
252
253 ret = sport_config_tx(sport_handle, TFSR | TCKFE, TSFSE|0x1f, 0, 0);
254 if (ret) {
255 pr_err("SPORT is busy!\n");
256 return -EBUSY;
257 }
258
259 if (dai->capture.active)
260 sport_rx_start(sport);
261 if (dai->playback.active)
262 sport_tx_start(sport);
263 return 0;
264}
265
266#else
267#define bf5xx_i2s_suspend NULL
268#define bf5xx_i2s_resume NULL
269#endif
270
271#define BF5XX_I2S_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
272 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \
273 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | \
274 SNDRV_PCM_RATE_96000)
275
276#define BF5XX_I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |\
277 SNDRV_PCM_FMTBIT_S32_LE)
278
279struct snd_soc_dai bf5xx_i2s_dai = {
280 .name = "bf5xx-i2s",
281 .id = 0,
282 .type = SND_SOC_DAI_I2S,
283 .probe = bf5xx_i2s_probe,
284 .remove = bf5xx_i2s_remove,
285 .suspend = bf5xx_i2s_suspend,
286 .resume = bf5xx_i2s_resume,
287 .playback = {
288 .channels_min = 1,
289 .channels_max = 2,
290 .rates = BF5XX_I2S_RATES,
291 .formats = BF5XX_I2S_FORMATS,},
292 .capture = {
293 .channels_min = 1,
294 .channels_max = 2,
295 .rates = BF5XX_I2S_RATES,
296 .formats = BF5XX_I2S_FORMATS,},
297 .ops = {
298 .startup = bf5xx_i2s_startup,
299 .shutdown = bf5xx_i2s_shutdown,
300 .hw_params = bf5xx_i2s_hw_params,},
301 .dai_ops = {
302 .set_fmt = bf5xx_i2s_set_dai_fmt,
303 },
304};
305EXPORT_SYMBOL_GPL(bf5xx_i2s_dai);
306
307/* Module information */
308MODULE_AUTHOR("Cliff Cai");
309MODULE_DESCRIPTION("I2S driver for ADI Blackfin");
310MODULE_LICENSE("GPL");
311
diff --git a/sound/soc/blackfin/bf5xx-i2s.h b/sound/soc/blackfin/bf5xx-i2s.h
new file mode 100644
index 000000000000..7107d1a0b06b
--- /dev/null
+++ b/sound/soc/blackfin/bf5xx-i2s.h
@@ -0,0 +1,14 @@
1/*
2 * linux/sound/arm/bf5xx-i2s.h
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#ifndef _BF5XX_I2S_H
10#define _BF5XX_I2S_H
11
12extern struct snd_soc_dai bf5xx_i2s_dai;
13
14#endif
diff --git a/sound/soc/blackfin/bf5xx-sport.c b/sound/soc/blackfin/bf5xx-sport.c
new file mode 100644
index 000000000000..3b99e484d555
--- /dev/null
+++ b/sound/soc/blackfin/bf5xx-sport.c
@@ -0,0 +1,1032 @@
1/*
2 * File: bf5xx_sport.c
3 * Based on:
4 * Author: Roy Huang <roy.huang@analog.com>
5 *
6 * Created: Tue Sep 21 10:52:42 CEST 2004
7 * Description:
8 * Blackfin SPORT Driver
9 *
10 * Copyright 2004-2007 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */
29
30#include <linux/kernel.h>
31#include <linux/slab.h>
32#include <linux/delay.h>
33#include <linux/dma-mapping.h>
34#include <linux/gpio.h>
35#include <linux/bug.h>
36#include <asm/portmux.h>
37#include <asm/dma.h>
38#include <asm/blackfin.h>
39#include <asm/cacheflush.h>
40
41#include "bf5xx-sport.h"
42/* delay between frame sync pulse and first data bit in multichannel mode */
43#define FRAME_DELAY (1<<12)
44
45struct sport_device *sport_handle;
46EXPORT_SYMBOL(sport_handle);
47/* note: multichannel is in units of 8 channels,
48 * tdm_count is # channels NOT / 8 ! */
49int sport_set_multichannel(struct sport_device *sport,
50 int tdm_count, u32 mask, int packed)
51{
52 pr_debug("%s tdm_count=%d mask:0x%08x packed=%d\n", __func__,
53 tdm_count, mask, packed);
54
55 if ((sport->regs->tcr1 & TSPEN) || (sport->regs->rcr1 & RSPEN))
56 return -EBUSY;
57
58 if (tdm_count & 0x7)
59 return -EINVAL;
60
61 if (tdm_count > 32)
62 return -EINVAL; /* Only support less than 32 channels now */
63
64 if (tdm_count) {
65 sport->regs->mcmc1 = ((tdm_count>>3)-1) << 12;
66 sport->regs->mcmc2 = FRAME_DELAY | MCMEN | \
67 (packed ? (MCDTXPE|MCDRXPE) : 0);
68
69 sport->regs->mtcs0 = mask;
70 sport->regs->mrcs0 = mask;
71 sport->regs->mtcs1 = 0;
72 sport->regs->mrcs1 = 0;
73 sport->regs->mtcs2 = 0;
74 sport->regs->mrcs2 = 0;
75 sport->regs->mtcs3 = 0;
76 sport->regs->mrcs3 = 0;
77 } else {
78 sport->regs->mcmc1 = 0;
79 sport->regs->mcmc2 = 0;
80
81 sport->regs->mtcs0 = 0;
82 sport->regs->mrcs0 = 0;
83 }
84
85 sport->regs->mtcs1 = 0; sport->regs->mtcs2 = 0; sport->regs->mtcs3 = 0;
86 sport->regs->mrcs1 = 0; sport->regs->mrcs2 = 0; sport->regs->mrcs3 = 0;
87
88 SSYNC();
89
90 return 0;
91}
92EXPORT_SYMBOL(sport_set_multichannel);
93
94int sport_config_rx(struct sport_device *sport, unsigned int rcr1,
95 unsigned int rcr2, unsigned int clkdiv, unsigned int fsdiv)
96{
97 if ((sport->regs->tcr1 & TSPEN) || (sport->regs->rcr1 & RSPEN))
98 return -EBUSY;
99
100 sport->regs->rcr1 = rcr1;
101 sport->regs->rcr2 = rcr2;
102 sport->regs->rclkdiv = clkdiv;
103 sport->regs->rfsdiv = fsdiv;
104
105 SSYNC();
106
107 return 0;
108}
109EXPORT_SYMBOL(sport_config_rx);
110
111int sport_config_tx(struct sport_device *sport, unsigned int tcr1,
112 unsigned int tcr2, unsigned int clkdiv, unsigned int fsdiv)
113{
114 if ((sport->regs->tcr1 & TSPEN) || (sport->regs->rcr1 & RSPEN))
115 return -EBUSY;
116
117 sport->regs->tcr1 = tcr1;
118 sport->regs->tcr2 = tcr2;
119 sport->regs->tclkdiv = clkdiv;
120 sport->regs->tfsdiv = fsdiv;
121
122 SSYNC();
123
124 return 0;
125}
126EXPORT_SYMBOL(sport_config_tx);
127
128static void setup_desc(struct dmasg *desc, void *buf, int fragcount,
129 size_t fragsize, unsigned int cfg,
130 unsigned int x_count, unsigned int ycount, size_t wdsize)
131{
132
133 int i;
134
135 for (i = 0; i < fragcount; ++i) {
136 desc[i].next_desc_addr = (unsigned long)&(desc[i + 1]);
137 desc[i].start_addr = (unsigned long)buf + i*fragsize;
138 desc[i].cfg = cfg;
139 desc[i].x_count = x_count;
140 desc[i].x_modify = wdsize;
141 desc[i].y_count = ycount;
142 desc[i].y_modify = wdsize;
143 }
144
145 /* make circular */
146 desc[fragcount-1].next_desc_addr = (unsigned long)desc;
147
148 pr_debug("setup desc: desc0=%p, next0=%lx, desc1=%p,"
149 "next1=%lx\nx_count=%x,y_count=%x,addr=0x%lx,cfs=0x%x\n",
150 &(desc[0]), desc[0].next_desc_addr,
151 &(desc[1]), desc[1].next_desc_addr,
152 desc[0].x_count, desc[0].y_count,
153 desc[0].start_addr, desc[0].cfg);
154}
155
156static int sport_start(struct sport_device *sport)
157{
158 enable_dma(sport->dma_rx_chan);
159 enable_dma(sport->dma_tx_chan);
160 sport->regs->rcr1 |= RSPEN;
161 sport->regs->tcr1 |= TSPEN;
162 SSYNC();
163
164 return 0;
165}
166
167static int sport_stop(struct sport_device *sport)
168{
169 sport->regs->tcr1 &= ~TSPEN;
170 sport->regs->rcr1 &= ~RSPEN;
171 SSYNC();
172
173 disable_dma(sport->dma_rx_chan);
174 disable_dma(sport->dma_tx_chan);
175 return 0;
176}
177
178static inline int sport_hook_rx_dummy(struct sport_device *sport)
179{
180 struct dmasg *desc, temp_desc;
181 unsigned long flags;
182
183 BUG_ON(sport->dummy_rx_desc == NULL);
184 BUG_ON(sport->curr_rx_desc == sport->dummy_rx_desc);
185
186 /* Maybe the dummy buffer descriptor ring is damaged */
187 sport->dummy_rx_desc->next_desc_addr = \
188 (unsigned long)(sport->dummy_rx_desc+1);
189
190 local_irq_save(flags);
191 desc = (struct dmasg *)get_dma_next_desc_ptr(sport->dma_rx_chan);
192 /* Copy the descriptor which will be damaged to backup */
193 temp_desc = *desc;
194 desc->x_count = 0xa;
195 desc->y_count = 0;
196 desc->next_desc_addr = (unsigned long)(sport->dummy_rx_desc);
197 local_irq_restore(flags);
198 /* Waiting for dummy buffer descriptor is already hooked*/
199 while ((get_dma_curr_desc_ptr(sport->dma_rx_chan) -
200 sizeof(struct dmasg)) !=
201 (unsigned long)sport->dummy_rx_desc)
202 ;
203 sport->curr_rx_desc = sport->dummy_rx_desc;
204 /* Restore the damaged descriptor */
205 *desc = temp_desc;
206
207 return 0;
208}
209
210static inline int sport_rx_dma_start(struct sport_device *sport, int dummy)
211{
212 if (dummy) {
213 sport->dummy_rx_desc->next_desc_addr = \
214 (unsigned long) sport->dummy_rx_desc;
215 sport->curr_rx_desc = sport->dummy_rx_desc;
216 } else
217 sport->curr_rx_desc = sport->dma_rx_desc;
218
219 set_dma_next_desc_addr(sport->dma_rx_chan, \
220 (unsigned long)(sport->curr_rx_desc));
221 set_dma_x_count(sport->dma_rx_chan, 0);
222 set_dma_x_modify(sport->dma_rx_chan, 0);
223 set_dma_config(sport->dma_rx_chan, (DMAFLOW_LARGE | NDSIZE_9 | \
224 WDSIZE_32 | WNR));
225 set_dma_curr_addr(sport->dma_rx_chan, sport->curr_rx_desc->start_addr);
226 SSYNC();
227
228 return 0;
229}
230
231static inline int sport_tx_dma_start(struct sport_device *sport, int dummy)
232{
233 if (dummy) {
234 sport->dummy_tx_desc->next_desc_addr = \
235 (unsigned long) sport->dummy_tx_desc;
236 sport->curr_tx_desc = sport->dummy_tx_desc;
237 } else
238 sport->curr_tx_desc = sport->dma_tx_desc;
239
240 set_dma_next_desc_addr(sport->dma_tx_chan, \
241 (unsigned long)(sport->curr_tx_desc));
242 set_dma_x_count(sport->dma_tx_chan, 0);
243 set_dma_x_modify(sport->dma_tx_chan, 0);
244 set_dma_config(sport->dma_tx_chan,
245 (DMAFLOW_LARGE | NDSIZE_9 | WDSIZE_32));
246 set_dma_curr_addr(sport->dma_tx_chan, sport->curr_tx_desc->start_addr);
247 SSYNC();
248
249 return 0;
250}
251
252int sport_rx_start(struct sport_device *sport)
253{
254 unsigned long flags;
255 pr_debug("%s enter\n", __func__);
256 if (sport->rx_run)
257 return -EBUSY;
258 if (sport->tx_run) {
259 /* tx is running, rx is not running */
260 BUG_ON(sport->dma_rx_desc == NULL);
261 BUG_ON(sport->curr_rx_desc != sport->dummy_rx_desc);
262 local_irq_save(flags);
263 while ((get_dma_curr_desc_ptr(sport->dma_rx_chan) -
264 sizeof(struct dmasg)) !=
265 (unsigned long)sport->dummy_rx_desc)
266 ;
267 sport->dummy_rx_desc->next_desc_addr =
268 (unsigned long)(sport->dma_rx_desc);
269 local_irq_restore(flags);
270 sport->curr_rx_desc = sport->dma_rx_desc;
271 } else {
272 sport_tx_dma_start(sport, 1);
273 sport_rx_dma_start(sport, 0);
274 sport_start(sport);
275 }
276
277 sport->rx_run = 1;
278
279 return 0;
280}
281EXPORT_SYMBOL(sport_rx_start);
282
283int sport_rx_stop(struct sport_device *sport)
284{
285 pr_debug("%s enter\n", __func__);
286
287 if (!sport->rx_run)
288 return 0;
289 if (sport->tx_run) {
290 /* TX dma is still running, hook the dummy buffer */
291 sport_hook_rx_dummy(sport);
292 } else {
293 /* Both rx and tx dma will be stopped */
294 sport_stop(sport);
295 sport->curr_rx_desc = NULL;
296 sport->curr_tx_desc = NULL;
297 }
298
299 sport->rx_run = 0;
300
301 return 0;
302}
303EXPORT_SYMBOL(sport_rx_stop);
304
305static inline int sport_hook_tx_dummy(struct sport_device *sport)
306{
307 struct dmasg *desc, temp_desc;
308 unsigned long flags;
309
310 BUG_ON(sport->dummy_tx_desc == NULL);
311 BUG_ON(sport->curr_tx_desc == sport->dummy_tx_desc);
312
313 sport->dummy_tx_desc->next_desc_addr = \
314 (unsigned long)(sport->dummy_tx_desc+1);
315
316 /* Shorten the time on last normal descriptor */
317 local_irq_save(flags);
318 desc = (struct dmasg *)get_dma_next_desc_ptr(sport->dma_tx_chan);
319 /* Store the descriptor which will be damaged */
320 temp_desc = *desc;
321 desc->x_count = 0xa;
322 desc->y_count = 0;
323 desc->next_desc_addr = (unsigned long)(sport->dummy_tx_desc);
324 local_irq_restore(flags);
325 /* Waiting for dummy buffer descriptor is already hooked*/
326 while ((get_dma_curr_desc_ptr(sport->dma_tx_chan) - \
327 sizeof(struct dmasg)) != \
328 (unsigned long)sport->dummy_tx_desc)
329 ;
330 sport->curr_tx_desc = sport->dummy_tx_desc;
331 /* Restore the damaged descriptor */
332 *desc = temp_desc;
333
334 return 0;
335}
336
337int sport_tx_start(struct sport_device *sport)
338{
339 unsigned flags;
340 pr_debug("%s: tx_run:%d, rx_run:%d\n", __func__,
341 sport->tx_run, sport->rx_run);
342 if (sport->tx_run)
343 return -EBUSY;
344 if (sport->rx_run) {
345 BUG_ON(sport->dma_tx_desc == NULL);
346 BUG_ON(sport->curr_tx_desc != sport->dummy_tx_desc);
347 /* Hook the normal buffer descriptor */
348 local_irq_save(flags);
349 while ((get_dma_curr_desc_ptr(sport->dma_tx_chan) -
350 sizeof(struct dmasg)) !=
351 (unsigned long)sport->dummy_tx_desc)
352 ;
353 sport->dummy_tx_desc->next_desc_addr =
354 (unsigned long)(sport->dma_tx_desc);
355 local_irq_restore(flags);
356 sport->curr_tx_desc = sport->dma_tx_desc;
357 } else {
358
359 sport_tx_dma_start(sport, 0);
360 /* Let rx dma run the dummy buffer */
361 sport_rx_dma_start(sport, 1);
362 sport_start(sport);
363 }
364 sport->tx_run = 1;
365 return 0;
366}
367EXPORT_SYMBOL(sport_tx_start);
368
369int sport_tx_stop(struct sport_device *sport)
370{
371 if (!sport->tx_run)
372 return 0;
373 if (sport->rx_run) {
374 /* RX is still running, hook the dummy buffer */
375 sport_hook_tx_dummy(sport);
376 } else {
377 /* Both rx and tx dma stopped */
378 sport_stop(sport);
379 sport->curr_rx_desc = NULL;
380 sport->curr_tx_desc = NULL;
381 }
382
383 sport->tx_run = 0;
384
385 return 0;
386}
387EXPORT_SYMBOL(sport_tx_stop);
388
389static inline int compute_wdsize(size_t wdsize)
390{
391 switch (wdsize) {
392 case 1:
393 return WDSIZE_8;
394 case 2:
395 return WDSIZE_16;
396 case 4:
397 default:
398 return WDSIZE_32;
399 }
400}
401
402int sport_config_rx_dma(struct sport_device *sport, void *buf,
403 int fragcount, size_t fragsize)
404{
405 unsigned int x_count;
406 unsigned int y_count;
407 unsigned int cfg;
408 dma_addr_t addr;
409
410 pr_debug("%s buf:%p, frag:%d, fragsize:0x%lx\n", __func__, \
411 buf, fragcount, fragsize);
412
413 x_count = fragsize / sport->wdsize;
414 y_count = 0;
415
416 /* for fragments larger than 64k words we use 2d dma,
417 * denote fragecount as two numbers' mutliply and both of them
418 * are less than 64k.*/
419 if (x_count >= 0x10000) {
420 int i, count = x_count;
421
422 for (i = 16; i > 0; i--) {
423 x_count = 1 << i;
424 if ((count & (x_count - 1)) == 0) {
425 y_count = count >> i;
426 if (y_count < 0x10000)
427 break;
428 }
429 }
430 if (i == 0)
431 return -EINVAL;
432 }
433 pr_debug("%s(x_count:0x%x, y_count:0x%x)\n", __func__,
434 x_count, y_count);
435
436 if (sport->dma_rx_desc)
437 dma_free_coherent(NULL, sport->rx_desc_bytes,
438 sport->dma_rx_desc, 0);
439
440 /* Allocate a new descritor ring as current one. */
441 sport->dma_rx_desc = dma_alloc_coherent(NULL, \
442 fragcount * sizeof(struct dmasg), &addr, 0);
443 sport->rx_desc_bytes = fragcount * sizeof(struct dmasg);
444
445 if (!sport->dma_rx_desc) {
446 pr_err("Failed to allocate memory for rx desc\n");
447 return -ENOMEM;
448 }
449
450 sport->rx_buf = buf;
451 sport->rx_fragsize = fragsize;
452 sport->rx_frags = fragcount;
453
454 cfg = 0x7000 | DI_EN | compute_wdsize(sport->wdsize) | WNR | \
455 (DESC_ELEMENT_COUNT << 8); /* large descriptor mode */
456
457 if (y_count != 0)
458 cfg |= DMA2D;
459
460 setup_desc(sport->dma_rx_desc, buf, fragcount, fragsize,
461 cfg|DMAEN, x_count, y_count, sport->wdsize);
462
463 return 0;
464}
465EXPORT_SYMBOL(sport_config_rx_dma);
466
467int sport_config_tx_dma(struct sport_device *sport, void *buf, \
468 int fragcount, size_t fragsize)
469{
470 unsigned int x_count;
471 unsigned int y_count;
472 unsigned int cfg;
473 dma_addr_t addr;
474
475 pr_debug("%s buf:%p, fragcount:%d, fragsize:0x%lx\n",
476 __func__, buf, fragcount, fragsize);
477
478 x_count = fragsize/sport->wdsize;
479 y_count = 0;
480
481 /* for fragments larger than 64k words we use 2d dma,
482 * denote fragecount as two numbers' mutliply and both of them
483 * are less than 64k.*/
484 if (x_count >= 0x10000) {
485 int i, count = x_count;
486
487 for (i = 16; i > 0; i--) {
488 x_count = 1 << i;
489 if ((count & (x_count - 1)) == 0) {
490 y_count = count >> i;
491 if (y_count < 0x10000)
492 break;
493 }
494 }
495 if (i == 0)
496 return -EINVAL;
497 }
498 pr_debug("%s x_count:0x%x, y_count:0x%x\n", __func__,
499 x_count, y_count);
500
501
502 if (sport->dma_tx_desc) {
503 dma_free_coherent(NULL, sport->tx_desc_bytes, \
504 sport->dma_tx_desc, 0);
505 }
506
507 sport->dma_tx_desc = dma_alloc_coherent(NULL, \
508 fragcount * sizeof(struct dmasg), &addr, 0);
509 sport->tx_desc_bytes = fragcount * sizeof(struct dmasg);
510 if (!sport->dma_tx_desc) {
511 pr_err("Failed to allocate memory for tx desc\n");
512 return -ENOMEM;
513 }
514
515 sport->tx_buf = buf;
516 sport->tx_fragsize = fragsize;
517 sport->tx_frags = fragcount;
518 cfg = 0x7000 | DI_EN | compute_wdsize(sport->wdsize) | \
519 (DESC_ELEMENT_COUNT << 8); /* large descriptor mode */
520
521 if (y_count != 0)
522 cfg |= DMA2D;
523
524 setup_desc(sport->dma_tx_desc, buf, fragcount, fragsize,
525 cfg|DMAEN, x_count, y_count, sport->wdsize);
526
527 return 0;
528}
529EXPORT_SYMBOL(sport_config_tx_dma);
530
531/* setup dummy dma descriptor ring, which don't generate interrupts,
532 * the x_modify is set to 0 */
533static int sport_config_rx_dummy(struct sport_device *sport)
534{
535 struct dmasg *desc;
536 unsigned config;
537
538 pr_debug("%s entered\n", __func__);
539#if L1_DATA_A_LENGTH != 0
540 desc = (struct dmasg *) l1_data_sram_alloc(2 * sizeof(*desc));
541#else
542 {
543 dma_addr_t addr;
544 desc = dma_alloc_coherent(NULL, 2 * sizeof(*desc), &addr, 0);
545 }
546#endif
547 if (desc == NULL) {
548 pr_err("Failed to allocate memory for dummy rx desc\n");
549 return -ENOMEM;
550 }
551 memset(desc, 0, 2 * sizeof(*desc));
552 sport->dummy_rx_desc = desc;
553 desc->start_addr = (unsigned long)sport->dummy_buf;
554 config = DMAFLOW_LARGE | NDSIZE_9 | compute_wdsize(sport->wdsize)
555 | WNR | DMAEN;
556 desc->cfg = config;
557 desc->x_count = sport->dummy_count/sport->wdsize;
558 desc->x_modify = sport->wdsize;
559 desc->y_count = 0;
560 desc->y_modify = 0;
561 memcpy(desc+1, desc, sizeof(*desc));
562 desc->next_desc_addr = (unsigned long)(desc+1);
563 desc[1].next_desc_addr = (unsigned long)desc;
564 return 0;
565}
566
567static int sport_config_tx_dummy(struct sport_device *sport)
568{
569 struct dmasg *desc;
570 unsigned int config;
571
572 pr_debug("%s entered\n", __func__);
573
574#if L1_DATA_A_LENGTH != 0
575 desc = (struct dmasg *) l1_data_sram_alloc(2 * sizeof(*desc));
576#else
577 {
578 dma_addr_t addr;
579 desc = dma_alloc_coherent(NULL, 2 * sizeof(*desc), &addr, 0);
580 }
581#endif
582 if (!desc) {
583 pr_err("Failed to allocate memory for dummy tx desc\n");
584 return -ENOMEM;
585 }
586 memset(desc, 0, 2 * sizeof(*desc));
587 sport->dummy_tx_desc = desc;
588 desc->start_addr = (unsigned long)sport->dummy_buf + \
589 sport->dummy_count;
590 config = DMAFLOW_LARGE | NDSIZE_9 |
591 compute_wdsize(sport->wdsize) | DMAEN;
592 desc->cfg = config;
593 desc->x_count = sport->dummy_count/sport->wdsize;
594 desc->x_modify = sport->wdsize;
595 desc->y_count = 0;
596 desc->y_modify = 0;
597 memcpy(desc+1, desc, sizeof(*desc));
598 desc->next_desc_addr = (unsigned long)(desc+1);
599 desc[1].next_desc_addr = (unsigned long)desc;
600 return 0;
601}
602
603unsigned long sport_curr_offset_rx(struct sport_device *sport)
604{
605 unsigned long curr = get_dma_curr_addr(sport->dma_rx_chan);
606
607 return (unsigned char *)curr - sport->rx_buf;
608}
609EXPORT_SYMBOL(sport_curr_offset_rx);
610
611unsigned long sport_curr_offset_tx(struct sport_device *sport)
612{
613 unsigned long curr = get_dma_curr_addr(sport->dma_tx_chan);
614
615 return (unsigned char *)curr - sport->tx_buf;
616}
617EXPORT_SYMBOL(sport_curr_offset_tx);
618
619void sport_incfrag(struct sport_device *sport, int *frag, int tx)
620{
621 ++(*frag);
622 if (tx == 1 && *frag == sport->tx_frags)
623 *frag = 0;
624
625 if (tx == 0 && *frag == sport->rx_frags)
626 *frag = 0;
627}
628EXPORT_SYMBOL(sport_incfrag);
629
630void sport_decfrag(struct sport_device *sport, int *frag, int tx)
631{
632 --(*frag);
633 if (tx == 1 && *frag == 0)
634 *frag = sport->tx_frags;
635
636 if (tx == 0 && *frag == 0)
637 *frag = sport->rx_frags;
638}
639EXPORT_SYMBOL(sport_decfrag);
640
641static int sport_check_status(struct sport_device *sport,
642 unsigned int *sport_stat,
643 unsigned int *rx_stat,
644 unsigned int *tx_stat)
645{
646 int status = 0;
647
648 if (sport_stat) {
649 SSYNC();
650 status = sport->regs->stat;
651 if (status & (TOVF|TUVF|ROVF|RUVF))
652 sport->regs->stat = (status & (TOVF|TUVF|ROVF|RUVF));
653 SSYNC();
654 *sport_stat = status;
655 }
656
657 if (rx_stat) {
658 SSYNC();
659 status = get_dma_curr_irqstat(sport->dma_rx_chan);
660 if (status & (DMA_DONE|DMA_ERR))
661 clear_dma_irqstat(sport->dma_rx_chan);
662 SSYNC();
663 *rx_stat = status;
664 }
665
666 if (tx_stat) {
667 SSYNC();
668 status = get_dma_curr_irqstat(sport->dma_tx_chan);
669 if (status & (DMA_DONE|DMA_ERR))
670 clear_dma_irqstat(sport->dma_tx_chan);
671 SSYNC();
672 *tx_stat = status;
673 }
674
675 return 0;
676}
677
678int sport_dump_stat(struct sport_device *sport, char *buf, size_t len)
679{
680 int ret;
681
682 ret = snprintf(buf, len,
683 "sts: 0x%04x\n"
684 "rx dma %d sts: 0x%04x tx dma %d sts: 0x%04x\n",
685 sport->regs->stat,
686 sport->dma_rx_chan,
687 get_dma_curr_irqstat(sport->dma_rx_chan),
688 sport->dma_tx_chan,
689 get_dma_curr_irqstat(sport->dma_tx_chan));
690 buf += ret;
691 len -= ret;
692
693 ret += snprintf(buf, len,
694 "curr_rx_desc:0x%p, curr_tx_desc:0x%p\n"
695 "dma_rx_desc:0x%p, dma_tx_desc:0x%p\n"
696 "dummy_rx_desc:0x%p, dummy_tx_desc:0x%p\n",
697 sport->curr_rx_desc, sport->curr_tx_desc,
698 sport->dma_rx_desc, sport->dma_tx_desc,
699 sport->dummy_rx_desc, sport->dummy_tx_desc);
700
701 return ret;
702}
703
704static irqreturn_t rx_handler(int irq, void *dev_id)
705{
706 unsigned int rx_stat;
707 struct sport_device *sport = dev_id;
708
709 pr_debug("%s enter\n", __func__);
710 sport_check_status(sport, NULL, &rx_stat, NULL);
711 if (!(rx_stat & DMA_DONE))
712 pr_err("rx dma is already stopped\n");
713
714 if (sport->rx_callback) {
715 sport->rx_callback(sport->rx_data);
716 return IRQ_HANDLED;
717 }
718
719 return IRQ_NONE;
720}
721
722static irqreturn_t tx_handler(int irq, void *dev_id)
723{
724 unsigned int tx_stat;
725 struct sport_device *sport = dev_id;
726 pr_debug("%s enter\n", __func__);
727 sport_check_status(sport, NULL, NULL, &tx_stat);
728 if (!(tx_stat & DMA_DONE)) {
729 pr_err("tx dma is already stopped\n");
730 return IRQ_HANDLED;
731 }
732 if (sport->tx_callback) {
733 sport->tx_callback(sport->tx_data);
734 return IRQ_HANDLED;
735 }
736
737 return IRQ_NONE;
738}
739
740static irqreturn_t err_handler(int irq, void *dev_id)
741{
742 unsigned int status = 0;
743 struct sport_device *sport = dev_id;
744
745 pr_debug("%s\n", __func__);
746 if (sport_check_status(sport, &status, NULL, NULL)) {
747 pr_err("error checking status ??");
748 return IRQ_NONE;
749 }
750
751 if (status & (TOVF|TUVF|ROVF|RUVF)) {
752 pr_info("sport status error:%s%s%s%s\n",
753 status & TOVF ? " TOVF" : "",
754 status & TUVF ? " TUVF" : "",
755 status & ROVF ? " ROVF" : "",
756 status & RUVF ? " RUVF" : "");
757 if (status & TOVF || status & TUVF) {
758 disable_dma(sport->dma_tx_chan);
759 if (sport->tx_run)
760 sport_tx_dma_start(sport, 0);
761 else
762 sport_tx_dma_start(sport, 1);
763 enable_dma(sport->dma_tx_chan);
764 } else {
765 disable_dma(sport->dma_rx_chan);
766 if (sport->rx_run)
767 sport_rx_dma_start(sport, 0);
768 else
769 sport_rx_dma_start(sport, 1);
770 enable_dma(sport->dma_rx_chan);
771 }
772 }
773 status = sport->regs->stat;
774 if (status & (TOVF|TUVF|ROVF|RUVF))
775 sport->regs->stat = (status & (TOVF|TUVF|ROVF|RUVF));
776 SSYNC();
777
778 if (sport->err_callback)
779 sport->err_callback(sport->err_data);
780
781 return IRQ_HANDLED;
782}
783
784int sport_set_rx_callback(struct sport_device *sport,
785 void (*rx_callback)(void *), void *rx_data)
786{
787 BUG_ON(rx_callback == NULL);
788 sport->rx_callback = rx_callback;
789 sport->rx_data = rx_data;
790
791 return 0;
792}
793EXPORT_SYMBOL(sport_set_rx_callback);
794
795int sport_set_tx_callback(struct sport_device *sport,
796 void (*tx_callback)(void *), void *tx_data)
797{
798 BUG_ON(tx_callback == NULL);
799 sport->tx_callback = tx_callback;
800 sport->tx_data = tx_data;
801
802 return 0;
803}
804EXPORT_SYMBOL(sport_set_tx_callback);
805
806int sport_set_err_callback(struct sport_device *sport,
807 void (*err_callback)(void *), void *err_data)
808{
809 BUG_ON(err_callback == NULL);
810 sport->err_callback = err_callback;
811 sport->err_data = err_data;
812
813 return 0;
814}
815EXPORT_SYMBOL(sport_set_err_callback);
816
817struct sport_device *sport_init(struct sport_param *param, unsigned wdsize,
818 unsigned dummy_count, void *private_data)
819{
820 int ret;
821 struct sport_device *sport;
822 pr_debug("%s enter\n", __func__);
823 BUG_ON(param == NULL);
824 BUG_ON(wdsize == 0 || dummy_count == 0);
825 sport = kmalloc(sizeof(struct sport_device), GFP_KERNEL);
826 if (!sport) {
827 pr_err("Failed to allocate for sport device\n");
828 return NULL;
829 }
830
831 memset(sport, 0, sizeof(struct sport_device));
832 sport->dma_rx_chan = param->dma_rx_chan;
833 sport->dma_tx_chan = param->dma_tx_chan;
834 sport->err_irq = param->err_irq;
835 sport->regs = param->regs;
836 sport->private_data = private_data;
837
838 if (request_dma(sport->dma_rx_chan, "SPORT RX Data") == -EBUSY) {
839 pr_err("Failed to request RX dma %d\n", \
840 sport->dma_rx_chan);
841 goto __init_err1;
842 }
843 if (set_dma_callback(sport->dma_rx_chan, rx_handler, sport) != 0) {
844 pr_err("Failed to request RX irq %d\n", \
845 sport->dma_rx_chan);
846 goto __init_err2;
847 }
848
849 if (request_dma(sport->dma_tx_chan, "SPORT TX Data") == -EBUSY) {
850 pr_err("Failed to request TX dma %d\n", \
851 sport->dma_tx_chan);
852 goto __init_err2;
853 }
854
855 if (set_dma_callback(sport->dma_tx_chan, tx_handler, sport) != 0) {
856 pr_err("Failed to request TX irq %d\n", \
857 sport->dma_tx_chan);
858 goto __init_err3;
859 }
860
861 if (request_irq(sport->err_irq, err_handler, IRQF_SHARED, "SPORT err",
862 sport) < 0) {
863 pr_err("Failed to request err irq:%d\n", \
864 sport->err_irq);
865 goto __init_err3;
866 }
867
868 pr_err("dma rx:%d tx:%d, err irq:%d, regs:%p\n",
869 sport->dma_rx_chan, sport->dma_tx_chan,
870 sport->err_irq, sport->regs);
871
872 sport->wdsize = wdsize;
873 sport->dummy_count = dummy_count;
874
875#if L1_DATA_A_LENGTH != 0
876 sport->dummy_buf = l1_data_sram_alloc(dummy_count * 2);
877#else
878 sport->dummy_buf = kmalloc(dummy_count * 2, GFP_KERNEL);
879#endif
880 if (sport->dummy_buf == NULL) {
881 pr_err("Failed to allocate dummy buffer\n");
882 goto __error;
883 }
884
885 memset(sport->dummy_buf, 0, dummy_count * 2);
886 ret = sport_config_rx_dummy(sport);
887 if (ret) {
888 pr_err("Failed to config rx dummy ring\n");
889 goto __error;
890 }
891 ret = sport_config_tx_dummy(sport);
892 if (ret) {
893 pr_err("Failed to config tx dummy ring\n");
894 goto __error;
895 }
896
897 return sport;
898__error:
899 free_irq(sport->err_irq, sport);
900__init_err3:
901 free_dma(sport->dma_tx_chan);
902__init_err2:
903 free_dma(sport->dma_rx_chan);
904__init_err1:
905 kfree(sport);
906 return NULL;
907}
908EXPORT_SYMBOL(sport_init);
909
910void sport_done(struct sport_device *sport)
911{
912 if (sport == NULL)
913 return;
914
915 sport_stop(sport);
916 if (sport->dma_rx_desc)
917 dma_free_coherent(NULL, sport->rx_desc_bytes,
918 sport->dma_rx_desc, 0);
919 if (sport->dma_tx_desc)
920 dma_free_coherent(NULL, sport->tx_desc_bytes,
921 sport->dma_tx_desc, 0);
922
923#if L1_DATA_A_LENGTH != 0
924 l1_data_sram_free(sport->dummy_rx_desc);
925 l1_data_sram_free(sport->dummy_tx_desc);
926 l1_data_sram_free(sport->dummy_buf);
927#else
928 dma_free_coherent(NULL, 2*sizeof(struct dmasg),
929 sport->dummy_rx_desc, 0);
930 dma_free_coherent(NULL, 2*sizeof(struct dmasg),
931 sport->dummy_tx_desc, 0);
932 kfree(sport->dummy_buf);
933#endif
934 free_dma(sport->dma_rx_chan);
935 free_dma(sport->dma_tx_chan);
936 free_irq(sport->err_irq, sport);
937
938 kfree(sport);
939 sport = NULL;
940}
941EXPORT_SYMBOL(sport_done);
942/*
943* It is only used to send several bytes when dma is not enabled
944 * sport controller is configured but not enabled.
945 * Multichannel cannot works with pio mode */
946/* Used by ac97 to write and read codec register */
947int sport_send_and_recv(struct sport_device *sport, u8 *out_data, \
948 u8 *in_data, int len)
949{
950 unsigned short dma_config;
951 unsigned short status;
952 unsigned long flags;
953 unsigned long wait = 0;
954
955 pr_debug("%s enter, out_data:%p, in_data:%p len:%d\n", \
956 __func__, out_data, in_data, len);
957 pr_debug("tcr1:0x%04x, tcr2:0x%04x, tclkdiv:0x%04x, tfsdiv:0x%04x\n"
958 "mcmc1:0x%04x, mcmc2:0x%04x\n",
959 sport->regs->tcr1, sport->regs->tcr2,
960 sport->regs->tclkdiv, sport->regs->tfsdiv,
961 sport->regs->mcmc1, sport->regs->mcmc2);
962 flush_dcache_range((unsigned)out_data, (unsigned)(out_data + len));
963
964 /* Enable tx dma */
965 dma_config = (RESTART | WDSIZE_16 | DI_EN);
966 set_dma_start_addr(sport->dma_tx_chan, (unsigned long)out_data);
967 set_dma_x_count(sport->dma_tx_chan, len/2);
968 set_dma_x_modify(sport->dma_tx_chan, 2);
969 set_dma_config(sport->dma_tx_chan, dma_config);
970 enable_dma(sport->dma_tx_chan);
971
972 if (in_data != NULL) {
973 invalidate_dcache_range((unsigned)in_data, \
974 (unsigned)(in_data + len));
975 /* Enable rx dma */
976 dma_config = (RESTART | WDSIZE_16 | WNR | DI_EN);
977 set_dma_start_addr(sport->dma_rx_chan, (unsigned long)in_data);
978 set_dma_x_count(sport->dma_rx_chan, len/2);
979 set_dma_x_modify(sport->dma_rx_chan, 2);
980 set_dma_config(sport->dma_rx_chan, dma_config);
981 enable_dma(sport->dma_rx_chan);
982 }
983
984 local_irq_save(flags);
985 sport->regs->tcr1 |= TSPEN;
986 sport->regs->rcr1 |= RSPEN;
987 SSYNC();
988
989 status = get_dma_curr_irqstat(sport->dma_tx_chan);
990 while (status & DMA_RUN) {
991 udelay(1);
992 status = get_dma_curr_irqstat(sport->dma_tx_chan);
993 pr_debug("DMA status:0x%04x\n", status);
994 if (wait++ > 100)
995 goto __over;
996 }
997 status = sport->regs->stat;
998 wait = 0;
999
1000 while (!(status & TXHRE)) {
1001 pr_debug("sport status:0x%04x\n", status);
1002 udelay(1);
1003 status = *(unsigned short *)&sport->regs->stat;
1004 if (wait++ > 1000)
1005 goto __over;
1006 }
1007 /* Wait for the last byte sent out */
1008 udelay(20);
1009 pr_debug("sport status:0x%04x\n", status);
1010
1011__over:
1012 sport->regs->tcr1 &= ~TSPEN;
1013 sport->regs->rcr1 &= ~RSPEN;
1014 SSYNC();
1015 disable_dma(sport->dma_tx_chan);
1016 /* Clear the status */
1017 clear_dma_irqstat(sport->dma_tx_chan);
1018 if (in_data != NULL) {
1019 disable_dma(sport->dma_rx_chan);
1020 clear_dma_irqstat(sport->dma_rx_chan);
1021 }
1022 SSYNC();
1023 local_irq_restore(flags);
1024
1025 return 0;
1026}
1027EXPORT_SYMBOL(sport_send_and_recv);
1028
1029MODULE_AUTHOR("Roy Huang");
1030MODULE_DESCRIPTION("SPORT driver for ADI Blackfin");
1031MODULE_LICENSE("GPL");
1032
diff --git a/sound/soc/blackfin/bf5xx-sport.h b/sound/soc/blackfin/bf5xx-sport.h
new file mode 100644
index 000000000000..fcadcc081f7f
--- /dev/null
+++ b/sound/soc/blackfin/bf5xx-sport.h
@@ -0,0 +1,194 @@
1/*
2 * File: bf5xx_ac97_sport.h
3 * Based on:
4 * Author: Roy Huang <roy.huang@analog.com>
5 *
6 * Created:
7 * Description:
8 *
9 * Copyright 2004-2007 Analog Devices Inc.
10 *
11 * Bugs: Enter bugs at http://blackfin.uclinux.org/
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, see the file COPYING, or write
25 * to the Free Software Foundation, Inc.,
26 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27 */
28
29
30#ifndef __BF5XX_SPORT_H__
31#define __BF5XX_SPORT_H__
32
33#include <linux/types.h>
34#include <linux/wait.h>
35#include <linux/workqueue.h>
36#include <asm/dma.h>
37
38struct sport_register {
39 u16 tcr1; u16 reserved0;
40 u16 tcr2; u16 reserved1;
41 u16 tclkdiv; u16 reserved2;
42 u16 tfsdiv; u16 reserved3;
43 u32 tx;
44 u32 reserved_l0;
45 u32 rx;
46 u32 reserved_l1;
47 u16 rcr1; u16 reserved4;
48 u16 rcr2; u16 reserved5;
49 u16 rclkdiv; u16 reserved6;
50 u16 rfsdiv; u16 reserved7;
51 u16 stat; u16 reserved8;
52 u16 chnl; u16 reserved9;
53 u16 mcmc1; u16 reserved10;
54 u16 mcmc2; u16 reserved11;
55 u32 mtcs0;
56 u32 mtcs1;
57 u32 mtcs2;
58 u32 mtcs3;
59 u32 mrcs0;
60 u32 mrcs1;
61 u32 mrcs2;
62 u32 mrcs3;
63};
64
65#define DESC_ELEMENT_COUNT 9
66
67struct sport_device {
68 int dma_rx_chan;
69 int dma_tx_chan;
70 int err_irq;
71 struct sport_register *regs;
72
73 unsigned char *rx_buf;
74 unsigned char *tx_buf;
75 unsigned int rx_fragsize;
76 unsigned int tx_fragsize;
77 unsigned int rx_frags;
78 unsigned int tx_frags;
79 unsigned int wdsize;
80
81 /* for dummy dma transfer */
82 void *dummy_buf;
83 unsigned int dummy_count;
84
85 /* DMA descriptor ring head of current audio stream*/
86 struct dmasg *dma_rx_desc;
87 struct dmasg *dma_tx_desc;
88 unsigned int rx_desc_bytes;
89 unsigned int tx_desc_bytes;
90
91 unsigned int rx_run:1; /* rx is running */
92 unsigned int tx_run:1; /* tx is running */
93
94 struct dmasg *dummy_rx_desc;
95 struct dmasg *dummy_tx_desc;
96
97 struct dmasg *curr_rx_desc;
98 struct dmasg *curr_tx_desc;
99
100 int rx_curr_frag;
101 int tx_curr_frag;
102
103 unsigned int rcr1;
104 unsigned int rcr2;
105 int rx_tdm_count;
106
107 unsigned int tcr1;
108 unsigned int tcr2;
109 int tx_tdm_count;
110
111 void (*rx_callback)(void *data);
112 void *rx_data;
113 void (*tx_callback)(void *data);
114 void *tx_data;
115 void (*err_callback)(void *data);
116 void *err_data;
117 unsigned char *tx_dma_buf;
118 unsigned char *rx_dma_buf;
119#ifdef CONFIG_SND_MMAP_SUPPORT
120 dma_addr_t tx_dma_phy;
121 dma_addr_t rx_dma_phy;
122 int tx_pos;/*pcm sample count*/
123 int rx_pos;
124 unsigned int tx_buffer_size;
125 unsigned int rx_buffer_size;
126 int tx_delay_pos;
127 int once;
128#endif
129 void *private_data;
130};
131
132extern struct sport_device *sport_handle;
133
134struct sport_param {
135 int dma_rx_chan;
136 int dma_tx_chan;
137 int err_irq;
138 struct sport_register *regs;
139};
140
141struct sport_device *sport_init(struct sport_param *param, unsigned wdsize,
142 unsigned dummy_count, void *private_data);
143
144void sport_done(struct sport_device *sport);
145
146/* first use these ...*/
147
148/* note: multichannel is in units of 8 channels, tdm_count is number of channels
149 * NOT / 8 ! all channels are enabled by default */
150int sport_set_multichannel(struct sport_device *sport, int tdm_count,
151 u32 mask, int packed);
152
153int sport_config_rx(struct sport_device *sport,
154 unsigned int rcr1, unsigned int rcr2,
155 unsigned int clkdiv, unsigned int fsdiv);
156
157int sport_config_tx(struct sport_device *sport,
158 unsigned int tcr1, unsigned int tcr2,
159 unsigned int clkdiv, unsigned int fsdiv);
160
161/* ... then these: */
162
163/* buffer size (in bytes) == fragcount * fragsize_bytes */
164
165/* this is not a very general api, it sets the dma to 2d autobuffer mode */
166
167int sport_config_rx_dma(struct sport_device *sport, void *buf,
168 int fragcount, size_t fragsize_bytes);
169
170int sport_config_tx_dma(struct sport_device *sport, void *buf,
171 int fragcount, size_t fragsize_bytes);
172
173int sport_tx_start(struct sport_device *sport);
174int sport_tx_stop(struct sport_device *sport);
175int sport_rx_start(struct sport_device *sport);
176int sport_rx_stop(struct sport_device *sport);
177
178/* for use in interrupt handler */
179unsigned long sport_curr_offset_rx(struct sport_device *sport);
180unsigned long sport_curr_offset_tx(struct sport_device *sport);
181
182void sport_incfrag(struct sport_device *sport, int *frag, int tx);
183void sport_decfrag(struct sport_device *sport, int *frag, int tx);
184
185int sport_set_rx_callback(struct sport_device *sport,
186 void (*rx_callback)(void *), void *rx_data);
187int sport_set_tx_callback(struct sport_device *sport,
188 void (*tx_callback)(void *), void *tx_data);
189int sport_set_err_callback(struct sport_device *sport,
190 void (*err_callback)(void *), void *err_data);
191
192int sport_send_and_recv(struct sport_device *sport, u8 *out_data, \
193 u8 *in_data, int len);
194#endif /* BF53X_SPORT_H */
diff --git a/sound/soc/blackfin/bf5xx-ssm2602.c b/sound/soc/blackfin/bf5xx-ssm2602.c
new file mode 100644
index 000000000000..e15f67fd7769
--- /dev/null
+++ b/sound/soc/blackfin/bf5xx-ssm2602.c
@@ -0,0 +1,186 @@
1/*
2 * File: sound/soc/blackfin/bf5xx-ssm2602.c
3 * Author: Cliff Cai <Cliff.Cai@analog.com>
4 *
5 * Created: Tue June 06 2008
6 * Description: board driver for SSM2602 sound chip
7 *
8 * Modified:
9 * Copyright 2008 Analog Devices Inc.
10 *
11 * Bugs: Enter bugs at http://blackfin.uclinux.org/
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, see the file COPYING, or write
25 * to the Free Software Foundation, Inc.,
26 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27 */
28
29#include <linux/module.h>
30#include <linux/moduleparam.h>
31#include <linux/device.h>
32
33#include <sound/core.h>
34#include <sound/pcm.h>
35#include <sound/soc.h>
36#include <sound/soc-dapm.h>
37#include <sound/pcm_params.h>
38
39#include <asm/dma.h>
40#include <asm/portmux.h>
41#include <linux/gpio.h>
42#include "../codecs/ssm2602.h"
43#include "bf5xx-sport.h"
44#include "bf5xx-i2s-pcm.h"
45#include "bf5xx-i2s.h"
46
47static struct snd_soc_machine bf5xx_ssm2602;
48
49static int bf5xx_ssm2602_startup(struct snd_pcm_substream *substream)
50{
51 struct snd_soc_pcm_runtime *rtd = substream->private_data;
52 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
53
54 pr_debug("%s enter\n", __func__);
55 cpu_dai->private_data = sport_handle;
56 return 0;
57}
58
59static int bf5xx_ssm2602_hw_params(struct snd_pcm_substream *substream,
60 struct snd_pcm_hw_params *params)
61{
62 struct snd_soc_pcm_runtime *rtd = substream->private_data;
63 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
64 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
65 unsigned int clk = 0;
66 int ret = 0;
67
68 pr_debug("%s rate %d format %x\n", __func__, params_rate(params),
69 params_format(params));
70 /*
71 * If you are using a crystal source which frequency is not 12MHz
72 * then modify the below case statement with frequency of the crystal.
73 *
74 * If you are using the SPORT to generate clocking then this is
75 * where to do it.
76 */
77
78 switch (params_rate(params)) {
79 case 8000:
80 case 16000:
81 case 48000:
82 case 96000:
83 case 11025:
84 case 22050:
85 case 44100:
86 clk = 12000000;
87 break;
88 }
89
90 /*
91 * CODEC is master for BCLK and LRC in this configuration.
92 */
93
94 /* set codec DAI configuration */
95 ret = codec_dai->dai_ops.set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
96 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
97 if (ret < 0)
98 return ret;
99 /* set cpu DAI configuration */
100 ret = cpu_dai->dai_ops.set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
101 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
102 if (ret < 0)
103 return ret;
104
105 ret = codec_dai->dai_ops.set_sysclk(codec_dai, SSM2602_SYSCLK, clk,
106 SND_SOC_CLOCK_IN);
107 if (ret < 0)
108 return ret;
109
110 return 0;
111}
112
113static struct snd_soc_ops bf5xx_ssm2602_ops = {
114 .startup = bf5xx_ssm2602_startup,
115 .hw_params = bf5xx_ssm2602_hw_params,
116};
117
118static struct snd_soc_dai_link bf5xx_ssm2602_dai = {
119 .name = "ssm2602",
120 .stream_name = "SSM2602",
121 .cpu_dai = &bf5xx_i2s_dai,
122 .codec_dai = &ssm2602_dai,
123 .ops = &bf5xx_ssm2602_ops,
124};
125
126/*
127 * SSM2602 2 wire address is determined by CSB
128 * state during powerup.
129 * low = 0x1a
130 * high = 0x1b
131 */
132
133static struct ssm2602_setup_data bf5xx_ssm2602_setup = {
134 .i2c_bus = 0,
135 .i2c_address = 0x1b,
136};
137
138static struct snd_soc_machine bf5xx_ssm2602 = {
139 .name = "bf5xx_ssm2602",
140 .dai_link = &bf5xx_ssm2602_dai,
141 .num_links = 1,
142};
143
144static struct snd_soc_device bf5xx_ssm2602_snd_devdata = {
145 .machine = &bf5xx_ssm2602,
146 .platform = &bf5xx_i2s_soc_platform,
147 .codec_dev = &soc_codec_dev_ssm2602,
148 .codec_data = &bf5xx_ssm2602_setup,
149};
150
151static struct platform_device *bf52x_ssm2602_snd_device;
152
153static int __init bf5xx_ssm2602_init(void)
154{
155 int ret;
156
157 pr_debug("%s enter\n", __func__);
158 bf52x_ssm2602_snd_device = platform_device_alloc("soc-audio", -1);
159 if (!bf52x_ssm2602_snd_device)
160 return -ENOMEM;
161
162 platform_set_drvdata(bf52x_ssm2602_snd_device,
163 &bf5xx_ssm2602_snd_devdata);
164 bf5xx_ssm2602_snd_devdata.dev = &bf52x_ssm2602_snd_device->dev;
165 ret = platform_device_add(bf52x_ssm2602_snd_device);
166
167 if (ret)
168 platform_device_put(bf52x_ssm2602_snd_device);
169
170 return ret;
171}
172
173static void __exit bf5xx_ssm2602_exit(void)
174{
175 pr_debug("%s enter\n", __func__);
176 platform_device_unregister(bf52x_ssm2602_snd_device);
177}
178
179module_init(bf5xx_ssm2602_init);
180module_exit(bf5xx_ssm2602_exit);
181
182/* Module information */
183MODULE_AUTHOR("Cliff Cai");
184MODULE_DESCRIPTION("ALSA SoC SSM2602 BF527-EZKIT");
185MODULE_LICENSE("GPL");
186
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 1db04a28a53d..4975d8573e4f 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -1,32 +1,45 @@
1config SND_SOC_AC97_CODEC 1config SND_SOC_ALL_CODECS
2 tristate 2 tristate "Build all ASoC CODEC drivers"
3 select SND_AC97_CODEC 3 depends on I2C
4 4 select SPI
5config SND_SOC_AK4535 5 select SPI_MASTER
6 tristate 6 select SND_SOC_AD73311
7 7 select SND_SOC_AK4535
8config SND_SOC_UDA1380 8 select SND_SOC_CS4270
9 tristate 9 select SND_SOC_SSM2602
10 select SND_SOC_TLV320AIC23
11 select SND_SOC_TLV320AIC26
12 select SND_SOC_TLV320AIC3X
13 select SND_SOC_UDA1380
14 select SND_SOC_WM8510
15 select SND_SOC_WM8580
16 select SND_SOC_WM8731
17 select SND_SOC_WM8750
18 select SND_SOC_WM8753
19 select SND_SOC_WM8900
20 select SND_SOC_WM8903
21 select SND_SOC_WM8971
22 select SND_SOC_WM8990
23 help
24 Normally ASoC codec drivers are only built if a machine driver which
25 uses them is also built since they are only usable with a machine
26 driver. Selecting this option will allow these drivers to be built
27 without an explicit machine driver for test and development purposes.
10 28
11config SND_SOC_WM8510 29 If unsure select "N".
12 tristate
13 30
14config SND_SOC_WM8731
15 tristate
16 31
17config SND_SOC_WM8750 32config SND_SOC_AC97_CODEC
18 tristate
19
20config SND_SOC_WM8753
21 tristate 33 tristate
34 select SND_AC97_CODEC
22 35
23config SND_SOC_WM8990 36config SND_SOC_AD1980
24 tristate 37 tristate
25 38
26config SND_SOC_WM9712 39config SND_SOC_AD73311
27 tristate 40 tristate
28 41
29config SND_SOC_WM9713 42config SND_SOC_AK4535
30 tristate 43 tristate
31 44
32# Cirrus Logic CS4270 Codec 45# Cirrus Logic CS4270 Codec
@@ -47,6 +60,53 @@ config SND_SOC_CS4270_VD33_ERRATA
47 bool 60 bool
48 depends on SND_SOC_CS4270 61 depends on SND_SOC_CS4270
49 62
63config SND_SOC_SSM2602
64 tristate
65
66config SND_SOC_TLV320AIC23
67 tristate
68 depends on I2C
69
70config SND_SOC_TLV320AIC26
71 tristate "TI TLV320AIC26 Codec support"
72 depends on SPI
73
50config SND_SOC_TLV320AIC3X 74config SND_SOC_TLV320AIC3X
51 tristate 75 tristate
52 depends on I2C 76 depends on I2C
77
78config SND_SOC_UDA1380
79 tristate
80
81config SND_SOC_WM8510
82 tristate
83
84config SND_SOC_WM8580
85 tristate
86
87config SND_SOC_WM8731
88 tristate
89
90config SND_SOC_WM8750
91 tristate
92
93config SND_SOC_WM8753
94 tristate
95
96config SND_SOC_WM8900
97 tristate
98
99config SND_SOC_WM8903
100 tristate
101
102config SND_SOC_WM8971
103 tristate
104
105config SND_SOC_WM8990
106 tristate
107
108config SND_SOC_WM9712
109 tristate
110
111config SND_SOC_WM9713
112 tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index d7b97abcf729..90f0a585fc70 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -1,25 +1,43 @@
1snd-soc-ac97-objs := ac97.o 1snd-soc-ac97-objs := ac97.o
2snd-soc-ad1980-objs := ad1980.o
3snd-soc-ad73311-objs := ad73311.o
2snd-soc-ak4535-objs := ak4535.o 4snd-soc-ak4535-objs := ak4535.o
5snd-soc-cs4270-objs := cs4270.o
6snd-soc-ssm2602-objs := ssm2602.o
7snd-soc-tlv320aic23-objs := tlv320aic23.o
8snd-soc-tlv320aic26-objs := tlv320aic26.o
9snd-soc-tlv320aic3x-objs := tlv320aic3x.o
3snd-soc-uda1380-objs := uda1380.o 10snd-soc-uda1380-objs := uda1380.o
4snd-soc-wm8510-objs := wm8510.o 11snd-soc-wm8510-objs := wm8510.o
12snd-soc-wm8580-objs := wm8580.o
5snd-soc-wm8731-objs := wm8731.o 13snd-soc-wm8731-objs := wm8731.o
6snd-soc-wm8750-objs := wm8750.o 14snd-soc-wm8750-objs := wm8750.o
7snd-soc-wm8753-objs := wm8753.o 15snd-soc-wm8753-objs := wm8753.o
16snd-soc-wm8900-objs := wm8900.o
17snd-soc-wm8903-objs := wm8903.o
18snd-soc-wm8971-objs := wm8971.o
8snd-soc-wm8990-objs := wm8990.o 19snd-soc-wm8990-objs := wm8990.o
9snd-soc-wm9712-objs := wm9712.o 20snd-soc-wm9712-objs := wm9712.o
10snd-soc-wm9713-objs := wm9713.o 21snd-soc-wm9713-objs := wm9713.o
11snd-soc-cs4270-objs := cs4270.o
12snd-soc-tlv320aic3x-objs := tlv320aic3x.o
13 22
14obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o 23obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o
24obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o
25obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o
15obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o 26obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o
27obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
28obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o
29obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o
30obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o
31obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o
16obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o 32obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o
17obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o 33obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o
34obj-$(CONFIG_SND_SOC_WM8580) += snd-soc-wm8580.o
18obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o 35obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o
19obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o 36obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o
20obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o 37obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o
38obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o
39obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o
40obj-$(CONFIG_SND_SOC_WM8971) += snd-soc-wm8971.o
21obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o 41obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o
22obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o 42obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o
23obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o 43obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o
24obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
25obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o
diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c
index 61fd96ca7bc7..bd1ebdc6c86c 100644
--- a/sound/soc/codecs/ac97.c
+++ b/sound/soc/codecs/ac97.c
@@ -2,8 +2,7 @@
2 * ac97.c -- ALSA Soc AC97 codec support 2 * ac97.c -- ALSA Soc AC97 codec support
3 * 3 *
4 * Copyright 2005 Wolfson Microelectronics PLC. 4 * Copyright 2005 Wolfson Microelectronics PLC.
5 * Author: Liam Girdwood 5 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
6 * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
7 * 6 *
8 * This program is free software; you can redistribute it and/or modify it 7 * 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 8 * under the terms of the GNU General Public License as published by the
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
new file mode 100644
index 000000000000..1397b8e06c0b
--- /dev/null
+++ b/sound/soc/codecs/ad1980.c
@@ -0,0 +1,308 @@
1/*
2 * ad1980.c -- ALSA Soc AD1980 codec support
3 *
4 * Copyright: Analog Device Inc.
5 * Author: Roy Huang <roy.huang@analog.com>
6 * Cliff Cai <cliff.cai@analog.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#include <linux/init.h>
15#include <linux/module.h>
16#include <linux/kernel.h>
17#include <linux/device.h>
18#include <sound/core.h>
19#include <sound/pcm.h>
20#include <sound/ac97_codec.h>
21#include <sound/initval.h>
22#include <sound/soc.h>
23#include <sound/soc-dapm.h>
24
25#include "ad1980.h"
26
27static unsigned int ac97_read(struct snd_soc_codec *codec,
28 unsigned int reg);
29static int ac97_write(struct snd_soc_codec *codec,
30 unsigned int reg, unsigned int val);
31
32/*
33 * AD1980 register cache
34 */
35static const u16 ad1980_reg[] = {
36 0x0090, 0x8000, 0x8000, 0x8000, /* 0 - 6 */
37 0x0000, 0x0000, 0x8008, 0x8008, /* 8 - e */
38 0x8808, 0x8808, 0x0000, 0x8808, /* 10 - 16 */
39 0x8808, 0x0000, 0x8000, 0x0000, /* 18 - 1e */
40 0x0000, 0x0000, 0x0000, 0x0000, /* 20 - 26 */
41 0x03c7, 0x0000, 0xbb80, 0xbb80, /* 28 - 2e */
42 0xbb80, 0xbb80, 0x0000, 0x8080, /* 30 - 36 */
43 0x8080, 0x2000, 0x0000, 0x0000, /* 38 - 3e */
44 0x0000, 0x0000, 0x0000, 0x0000, /* reserved */
45 0x0000, 0x0000, 0x0000, 0x0000, /* reserved */
46 0x0000, 0x0000, 0x0000, 0x0000, /* reserved */
47 0x0000, 0x0000, 0x0000, 0x0000, /* reserved */
48 0x8080, 0x0000, 0x0000, 0x0000, /* 60 - 66 */
49 0x0000, 0x0000, 0x0000, 0x0000, /* reserved */
50 0x0000, 0x0000, 0x1001, 0x0000, /* 70 - 76 */
51 0x0000, 0x0000, 0x4144, 0x5370 /* 78 - 7e */
52};
53
54static const char *ad1980_rec_sel[] = {"Mic", "CD", "NC", "AUX", "Line",
55 "Stereo Mix", "Mono Mix", "Phone"};
56
57static const struct soc_enum ad1980_cap_src =
58 SOC_ENUM_DOUBLE(AC97_REC_SEL, 8, 0, 7, ad1980_rec_sel);
59
60static const struct snd_kcontrol_new ad1980_snd_ac97_controls[] = {
61SOC_DOUBLE("Master Playback Volume", AC97_MASTER, 8, 0, 31, 1),
62SOC_SINGLE("Master Playback Switch", AC97_MASTER, 15, 1, 1),
63
64SOC_DOUBLE("Headphone Playback Volume", AC97_HEADPHONE, 8, 0, 31, 1),
65SOC_SINGLE("Headphone Playback Switch", AC97_HEADPHONE, 15, 1, 1),
66
67SOC_DOUBLE("PCM Playback Volume", AC97_PCM, 8, 0, 31, 1),
68SOC_SINGLE("PCM Playback Switch", AC97_PCM, 15, 1, 1),
69
70SOC_DOUBLE("PCM Capture Volume", AC97_REC_GAIN, 8, 0, 31, 0),
71SOC_SINGLE("PCM Capture Switch", AC97_REC_GAIN, 15, 1, 1),
72
73SOC_SINGLE("Mono Playback Volume", AC97_MASTER_MONO, 0, 31, 1),
74SOC_SINGLE("Mono Playback Switch", AC97_MASTER_MONO, 15, 1, 1),
75
76SOC_SINGLE("Phone Capture Volume", AC97_PHONE, 0, 31, 1),
77SOC_SINGLE("Phone Capture Switch", AC97_PHONE, 15, 1, 1),
78
79SOC_SINGLE("Mic Volume", AC97_MIC, 0, 31, 1),
80SOC_SINGLE("Mic Switch", AC97_MIC, 15, 1, 1),
81
82SOC_SINGLE("Stereo Mic Switch", AC97_AD_MISC, 6, 1, 0),
83SOC_DOUBLE("Line HP Swap Switch", AC97_AD_MISC, 10, 5, 1, 0),
84
85SOC_DOUBLE("Surround Playback Volume", AC97_SURROUND_MASTER, 8, 0, 31, 1),
86SOC_DOUBLE("Surround Playback Switch", AC97_SURROUND_MASTER, 15, 7, 1, 1),
87
88SOC_ENUM("Capture Source", ad1980_cap_src),
89
90SOC_SINGLE("Mic Boost Switch", AC97_MIC, 6, 1, 0),
91};
92
93/* add non dapm controls */
94static int ad1980_add_controls(struct snd_soc_codec *codec)
95{
96 int err, i;
97
98 for (i = 0; i < ARRAY_SIZE(ad1980_snd_ac97_controls); i++) {
99 err = snd_ctl_add(codec->card, snd_soc_cnew(
100 &ad1980_snd_ac97_controls[i], codec, NULL));
101 if (err < 0)
102 return err;
103 }
104 return 0;
105}
106
107static unsigned int ac97_read(struct snd_soc_codec *codec,
108 unsigned int reg)
109{
110 u16 *cache = codec->reg_cache;
111
112 switch (reg) {
113 case AC97_RESET:
114 case AC97_INT_PAGING:
115 case AC97_POWERDOWN:
116 case AC97_EXTENDED_STATUS:
117 case AC97_VENDOR_ID1:
118 case AC97_VENDOR_ID2:
119 return soc_ac97_ops.read(codec->ac97, reg);
120 default:
121 reg = reg >> 1;
122
123 if (reg >= (ARRAY_SIZE(ad1980_reg)))
124 return -EINVAL;
125
126 return cache[reg];
127 }
128}
129
130static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
131 unsigned int val)
132{
133 u16 *cache = codec->reg_cache;
134
135 soc_ac97_ops.write(codec->ac97, reg, val);
136 reg = reg >> 1;
137 if (reg < (ARRAY_SIZE(ad1980_reg)))
138 cache[reg] = val;
139
140 return 0;
141}
142
143struct snd_soc_dai ad1980_dai = {
144 .name = "AC97",
145 .playback = {
146 .stream_name = "Playback",
147 .channels_min = 2,
148 .channels_max = 2,
149 .rates = SNDRV_PCM_RATE_48000,
150 .formats = SNDRV_PCM_FMTBIT_S16_LE, },
151 .capture = {
152 .stream_name = "Capture",
153 .channels_min = 2,
154 .channels_max = 2,
155 .rates = SNDRV_PCM_RATE_48000,
156 .formats = SNDRV_PCM_FMTBIT_S16_LE, },
157};
158EXPORT_SYMBOL_GPL(ad1980_dai);
159
160static int ad1980_reset(struct snd_soc_codec *codec, int try_warm)
161{
162 u16 retry_cnt = 0;
163
164retry:
165 if (try_warm && soc_ac97_ops.warm_reset) {
166 soc_ac97_ops.warm_reset(codec->ac97);
167 if (ac97_read(codec, AC97_RESET) == 0x0090)
168 return 1;
169 }
170
171 soc_ac97_ops.reset(codec->ac97);
172 /* Set bit 16slot in register 74h, then every slot will has only 16
173 * bits. This command is sent out in 20bit mode, in which case the
174 * first nibble of data is eaten by the addr. (Tag is always 16 bit)*/
175 ac97_write(codec, AC97_AD_SERIAL_CFG, 0x9900);
176
177 if (ac97_read(codec, AC97_RESET) != 0x0090)
178 goto err;
179 return 0;
180
181err:
182 while (retry_cnt++ < 10)
183 goto retry;
184
185 printk(KERN_ERR "AD1980 AC97 reset failed\n");
186 return -EIO;
187}
188
189static int ad1980_soc_probe(struct platform_device *pdev)
190{
191 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
192 struct snd_soc_codec *codec;
193 int ret = 0;
194 u16 vendor_id2;
195
196 printk(KERN_INFO "AD1980 SoC Audio Codec\n");
197
198 socdev->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
199 if (socdev->codec == NULL)
200 return -ENOMEM;
201 codec = socdev->codec;
202 mutex_init(&codec->mutex);
203
204 codec->reg_cache =
205 kzalloc(sizeof(u16) * ARRAY_SIZE(ad1980_reg), GFP_KERNEL);
206 if (codec->reg_cache == NULL) {
207 ret = -ENOMEM;
208 goto cache_err;
209 }
210 memcpy(codec->reg_cache, ad1980_reg, sizeof(u16) * \
211 ARRAY_SIZE(ad1980_reg));
212 codec->reg_cache_size = sizeof(u16) * ARRAY_SIZE(ad1980_reg);
213 codec->reg_cache_step = 2;
214 codec->name = "AD1980";
215 codec->owner = THIS_MODULE;
216 codec->dai = &ad1980_dai;
217 codec->num_dai = 1;
218 codec->write = ac97_write;
219 codec->read = ac97_read;
220 INIT_LIST_HEAD(&codec->dapm_widgets);
221 INIT_LIST_HEAD(&codec->dapm_paths);
222
223 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
224 if (ret < 0) {
225 printk(KERN_ERR "ad1980: failed to register AC97 codec\n");
226 goto codec_err;
227 }
228
229 /* register pcms */
230 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
231 if (ret < 0)
232 goto pcm_err;
233
234
235 ret = ad1980_reset(codec, 0);
236 if (ret < 0) {
237 printk(KERN_ERR "AC97 link error\n");
238 goto reset_err;
239 }
240
241 /* Read out vendor ID to make sure it is ad1980 */
242 if (ac97_read(codec, AC97_VENDOR_ID1) != 0x4144)
243 goto reset_err;
244
245 vendor_id2 = ac97_read(codec, AC97_VENDOR_ID2);
246
247 if (vendor_id2 != 0x5370) {
248 if (vendor_id2 != 0x5374)
249 goto reset_err;
250 else
251 printk(KERN_WARNING "ad1980: "
252 "Found AD1981 - only 2/2 IN/OUT Channels "
253 "supported\n");
254 }
255
256 ac97_write(codec, AC97_MASTER, 0x0000); /* unmute line out volume */
257 ac97_write(codec, AC97_PCM, 0x0000); /* unmute PCM out volume */
258 ac97_write(codec, AC97_REC_GAIN, 0x0000);/* unmute record volume */
259
260 ad1980_add_controls(codec);
261 ret = snd_soc_register_card(socdev);
262 if (ret < 0) {
263 printk(KERN_ERR "ad1980: failed to register card\n");
264 goto reset_err;
265 }
266
267 return 0;
268
269reset_err:
270 snd_soc_free_pcms(socdev);
271
272pcm_err:
273 snd_soc_free_ac97_codec(codec);
274
275codec_err:
276 kfree(codec->reg_cache);
277
278cache_err:
279 kfree(socdev->codec);
280 socdev->codec = NULL;
281 return ret;
282}
283
284static int ad1980_soc_remove(struct platform_device *pdev)
285{
286 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
287 struct snd_soc_codec *codec = socdev->codec;
288
289 if (codec == NULL)
290 return 0;
291
292 snd_soc_dapm_free(socdev);
293 snd_soc_free_pcms(socdev);
294 snd_soc_free_ac97_codec(codec);
295 kfree(codec->reg_cache);
296 kfree(codec);
297 return 0;
298}
299
300struct snd_soc_codec_device soc_codec_dev_ad1980 = {
301 .probe = ad1980_soc_probe,
302 .remove = ad1980_soc_remove,
303};
304EXPORT_SYMBOL_GPL(soc_codec_dev_ad1980);
305
306MODULE_DESCRIPTION("ASoC ad1980 driver");
307MODULE_AUTHOR("Roy Huang, Cliff Cai");
308MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ad1980.h b/sound/soc/codecs/ad1980.h
new file mode 100644
index 000000000000..db6c8500d66b
--- /dev/null
+++ b/sound/soc/codecs/ad1980.h
@@ -0,0 +1,23 @@
1/*
2 * ad1980.h -- ad1980 Soc Audio driver
3 */
4
5#ifndef _AD1980_H
6#define _AD1980_H
7/* Bit definition of Power-Down Control/Status Register */
8#define ADC 0x0001
9#define DAC 0x0002
10#define ANL 0x0004
11#define REF 0x0008
12#define PR0 0x0100
13#define PR1 0x0200
14#define PR2 0x0400
15#define PR3 0x0800
16#define PR4 0x1000
17#define PR5 0x2000
18#define PR6 0x4000
19
20extern struct snd_soc_dai ad1980_dai;
21extern struct snd_soc_codec_device soc_codec_dev_ad1980;
22
23#endif
diff --git a/sound/soc/codecs/ad73311.c b/sound/soc/codecs/ad73311.c
new file mode 100644
index 000000000000..37af8607b00a
--- /dev/null
+++ b/sound/soc/codecs/ad73311.c
@@ -0,0 +1,107 @@
1/*
2 * ad73311.c -- ALSA Soc AD73311 codec support
3 *
4 * Copyright: Analog Device Inc.
5 * Author: Cliff Cai <cliff.cai@analog.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 * Revision history
13 * 25th Sep 2008 Initial version.
14 */
15
16#include <linux/init.h>
17#include <linux/module.h>
18#include <linux/version.h>
19#include <linux/kernel.h>
20#include <linux/device.h>
21#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/ac97_codec.h>
24#include <sound/initval.h>
25#include <sound/soc.h>
26
27#include "ad73311.h"
28
29struct snd_soc_dai ad73311_dai = {
30 .name = "AD73311",
31 .playback = {
32 .stream_name = "Playback",
33 .channels_min = 1,
34 .channels_max = 1,
35 .rates = SNDRV_PCM_RATE_8000,
36 .formats = SNDRV_PCM_FMTBIT_S16_LE, },
37 .capture = {
38 .stream_name = "Capture",
39 .channels_min = 1,
40 .channels_max = 1,
41 .rates = SNDRV_PCM_RATE_8000,
42 .formats = SNDRV_PCM_FMTBIT_S16_LE, },
43};
44EXPORT_SYMBOL_GPL(ad73311_dai);
45
46static int ad73311_soc_probe(struct platform_device *pdev)
47{
48 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
49 struct snd_soc_codec *codec;
50 int ret = 0;
51
52 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
53 if (codec == NULL)
54 return -ENOMEM;
55 mutex_init(&codec->mutex);
56 codec->name = "AD73311";
57 codec->owner = THIS_MODULE;
58 codec->dai = &ad73311_dai;
59 codec->num_dai = 1;
60 socdev->codec = codec;
61 INIT_LIST_HEAD(&codec->dapm_widgets);
62 INIT_LIST_HEAD(&codec->dapm_paths);
63
64 /* register pcms */
65 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
66 if (ret < 0) {
67 printk(KERN_ERR "ad73311: failed to create pcms\n");
68 goto pcm_err;
69 }
70
71 ret = snd_soc_register_card(socdev);
72 if (ret < 0) {
73 printk(KERN_ERR "ad73311: failed to register card\n");
74 goto register_err;
75 }
76
77 return ret;
78
79register_err:
80 snd_soc_free_pcms(socdev);
81pcm_err:
82 kfree(socdev->codec);
83 socdev->codec = NULL;
84 return ret;
85}
86
87static int ad73311_soc_remove(struct platform_device *pdev)
88{
89 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
90 struct snd_soc_codec *codec = socdev->codec;
91
92 if (codec == NULL)
93 return 0;
94 snd_soc_free_pcms(socdev);
95 kfree(codec);
96 return 0;
97}
98
99struct snd_soc_codec_device soc_codec_dev_ad73311 = {
100 .probe = ad73311_soc_probe,
101 .remove = ad73311_soc_remove,
102};
103EXPORT_SYMBOL_GPL(soc_codec_dev_ad73311);
104
105MODULE_DESCRIPTION("ASoC ad73311 driver");
106MODULE_AUTHOR("Cliff Cai ");
107MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ad73311.h b/sound/soc/codecs/ad73311.h
new file mode 100644
index 000000000000..507ce0c30edf
--- /dev/null
+++ b/sound/soc/codecs/ad73311.h
@@ -0,0 +1,90 @@
1/*
2 * File: sound/soc/codec/ad73311.h
3 * Based on:
4 * Author: Cliff Cai <cliff.cai@analog.com>
5 *
6 * Created: Thur Sep 25, 2008
7 * Description: definitions for AD73311 registers
8 *
9 *
10 * Modified:
11 * Copyright 2006 Analog Devices Inc.
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, see the file COPYING, or write
27 * to the Free Software Foundation, Inc.,
28 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 */
30
31#ifndef __AD73311_H__
32#define __AD73311_H__
33
34#define AD_CONTROL 0x8000
35#define AD_DATA 0x0000
36#define AD_READ 0x4000
37#define AD_WRITE 0x0000
38
39/* Control register A */
40#define CTRL_REG_A (0 << 8)
41
42#define REGA_MODE_PRO 0x00
43#define REGA_MODE_DATA 0x01
44#define REGA_MODE_MIXED 0x03
45#define REGA_DLB 0x04
46#define REGA_SLB 0x08
47#define REGA_DEVC(x) ((x & 0x7) << 4)
48#define REGA_RESET 0x80
49
50/* Control register B */
51#define CTRL_REG_B (1 << 8)
52
53#define REGB_DIRATE(x) (x & 0x3)
54#define REGB_SCDIV(x) ((x & 0x3) << 2)
55#define REGB_MCDIV(x) ((x & 0x7) << 4)
56#define REGB_CEE (1 << 7)
57
58/* Control register C */
59#define CTRL_REG_C (2 << 8)
60
61#define REGC_PUDEV (1 << 0)
62#define REGC_PUADC (1 << 3)
63#define REGC_PUDAC (1 << 4)
64#define REGC_PUREF (1 << 5)
65#define REGC_REFUSE (1 << 6)
66
67/* Control register D */
68#define CTRL_REG_D (3 << 8)
69
70#define REGD_IGS(x) (x & 0x7)
71#define REGD_RMOD (1 << 3)
72#define REGD_OGS(x) ((x & 0x7) << 4)
73#define REGD_MUTE (x << 7)
74
75/* Control register E */
76#define CTRL_REG_E (4 << 8)
77
78#define REGE_DA(x) (x & 0x1f)
79#define REGE_IBYP (1 << 5)
80
81/* Control register F */
82#define CTRL_REG_F (5 << 8)
83
84#define REGF_SEEN (1 << 5)
85#define REGF_INV (1 << 6)
86#define REGF_ALB (1 << 7)
87
88extern struct snd_soc_dai ad73311_dai;
89extern struct snd_soc_codec_device soc_codec_dev_ad73311;
90#endif
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
index 7da9f467b7b8..2a89b5888e11 100644
--- a/sound/soc/codecs/ak4535.c
+++ b/sound/soc/codecs/ak4535.c
@@ -28,7 +28,6 @@
28 28
29#include "ak4535.h" 29#include "ak4535.h"
30 30
31#define AUDIO_NAME "ak4535"
32#define AK4535_VERSION "0.3" 31#define AK4535_VERSION "0.3"
33 32
34struct snd_soc_codec_device soc_codec_dev_ak4535; 33struct snd_soc_codec_device soc_codec_dev_ak4535;
@@ -535,87 +534,85 @@ static struct snd_soc_device *ak4535_socdev;
535 534
536#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 535#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
537 536
538#define I2C_DRIVERID_AK4535 0xfefe /* liam - need a proper id */ 537static int ak4535_i2c_probe(struct i2c_client *i2c,
539 538 const struct i2c_device_id *id)
540static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
541
542/* Magic definition of all other variables and things */
543I2C_CLIENT_INSMOD;
544
545static struct i2c_driver ak4535_i2c_driver;
546static struct i2c_client client_template;
547
548/* If the i2c layer weren't so broken, we could pass this kind of data
549 around */
550static int ak4535_codec_probe(struct i2c_adapter *adap, int addr, int kind)
551{ 539{
552 struct snd_soc_device *socdev = ak4535_socdev; 540 struct snd_soc_device *socdev = ak4535_socdev;
553 struct ak4535_setup_data *setup = socdev->codec_data;
554 struct snd_soc_codec *codec = socdev->codec; 541 struct snd_soc_codec *codec = socdev->codec;
555 struct i2c_client *i2c;
556 int ret; 542 int ret;
557 543
558 if (addr != setup->i2c_address)
559 return -ENODEV;
560
561 client_template.adapter = adap;
562 client_template.addr = addr;
563
564 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
565 if (i2c == NULL)
566 return -ENOMEM;
567
568 i2c_set_clientdata(i2c, codec); 544 i2c_set_clientdata(i2c, codec);
569 codec->control_data = i2c; 545 codec->control_data = i2c;
570 546
571 ret = i2c_attach_client(i2c);
572 if (ret < 0) {
573 printk(KERN_ERR "failed to attach codec at addr %x\n", addr);
574 goto err;
575 }
576
577 ret = ak4535_init(socdev); 547 ret = ak4535_init(socdev);
578 if (ret < 0) { 548 if (ret < 0)
579 printk(KERN_ERR "failed to initialise AK4535\n"); 549 printk(KERN_ERR "failed to initialise AK4535\n");
580 goto err;
581 }
582 return ret;
583 550
584err:
585 kfree(i2c);
586 return ret; 551 return ret;
587} 552}
588 553
589static int ak4535_i2c_detach(struct i2c_client *client) 554static int ak4535_i2c_remove(struct i2c_client *client)
590{ 555{
591 struct snd_soc_codec *codec = i2c_get_clientdata(client); 556 struct snd_soc_codec *codec = i2c_get_clientdata(client);
592 i2c_detach_client(client);
593 kfree(codec->reg_cache); 557 kfree(codec->reg_cache);
594 kfree(client);
595 return 0; 558 return 0;
596} 559}
597 560
598static int ak4535_i2c_attach(struct i2c_adapter *adap) 561static const struct i2c_device_id ak4535_i2c_id[] = {
599{ 562 { "ak4535", 0 },
600 return i2c_probe(adap, &addr_data, ak4535_codec_probe); 563 { }
601} 564};
565MODULE_DEVICE_TABLE(i2c, ak4535_i2c_id);
602 566
603/* corgi i2c codec control layer */
604static struct i2c_driver ak4535_i2c_driver = { 567static struct i2c_driver ak4535_i2c_driver = {
605 .driver = { 568 .driver = {
606 .name = "AK4535 I2C Codec", 569 .name = "AK4535 I2C Codec",
607 .owner = THIS_MODULE, 570 .owner = THIS_MODULE,
608 }, 571 },
609 .id = I2C_DRIVERID_AK4535, 572 .probe = ak4535_i2c_probe,
610 .attach_adapter = ak4535_i2c_attach, 573 .remove = ak4535_i2c_remove,
611 .detach_client = ak4535_i2c_detach, 574 .id_table = ak4535_i2c_id,
612 .command = NULL,
613}; 575};
614 576
615static struct i2c_client client_template = { 577static int ak4535_add_i2c_device(struct platform_device *pdev,
616 .name = "AK4535", 578 const struct ak4535_setup_data *setup)
617 .driver = &ak4535_i2c_driver, 579{
618}; 580 struct i2c_board_info info;
581 struct i2c_adapter *adapter;
582 struct i2c_client *client;
583 int ret;
584
585 ret = i2c_add_driver(&ak4535_i2c_driver);
586 if (ret != 0) {
587 dev_err(&pdev->dev, "can't add i2c driver\n");
588 return ret;
589 }
590
591 memset(&info, 0, sizeof(struct i2c_board_info));
592 info.addr = setup->i2c_address;
593 strlcpy(info.type, "ak4535", I2C_NAME_SIZE);
594
595 adapter = i2c_get_adapter(setup->i2c_bus);
596 if (!adapter) {
597 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
598 setup->i2c_bus);
599 goto err_driver;
600 }
601
602 client = i2c_new_device(adapter, &info);
603 i2c_put_adapter(adapter);
604 if (!client) {
605 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
606 (unsigned int)info.addr);
607 goto err_driver;
608 }
609
610 return 0;
611
612err_driver:
613 i2c_del_driver(&ak4535_i2c_driver);
614 return -ENODEV;
615}
619#endif 616#endif
620 617
621static int ak4535_probe(struct platform_device *pdev) 618static int ak4535_probe(struct platform_device *pdev)
@@ -624,7 +621,7 @@ static int ak4535_probe(struct platform_device *pdev)
624 struct ak4535_setup_data *setup; 621 struct ak4535_setup_data *setup;
625 struct snd_soc_codec *codec; 622 struct snd_soc_codec *codec;
626 struct ak4535_priv *ak4535; 623 struct ak4535_priv *ak4535;
627 int ret = 0; 624 int ret;
628 625
629 printk(KERN_INFO "AK4535 Audio Codec %s", AK4535_VERSION); 626 printk(KERN_INFO "AK4535 Audio Codec %s", AK4535_VERSION);
630 627
@@ -646,17 +643,14 @@ static int ak4535_probe(struct platform_device *pdev)
646 INIT_LIST_HEAD(&codec->dapm_paths); 643 INIT_LIST_HEAD(&codec->dapm_paths);
647 644
648 ak4535_socdev = socdev; 645 ak4535_socdev = socdev;
646 ret = -ENODEV;
647
649#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 648#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
650 if (setup->i2c_address) { 649 if (setup->i2c_address) {
651 normal_i2c[0] = setup->i2c_address;
652 codec->hw_write = (hw_write_t)i2c_master_send; 650 codec->hw_write = (hw_write_t)i2c_master_send;
653 codec->hw_read = (hw_read_t)i2c_master_recv; 651 codec->hw_read = (hw_read_t)i2c_master_recv;
654 ret = i2c_add_driver(&ak4535_i2c_driver); 652 ret = ak4535_add_i2c_device(pdev, setup);
655 if (ret != 0)
656 printk(KERN_ERR "can't add i2c driver");
657 } 653 }
658#else
659 /* Add other interfaces here */
660#endif 654#endif
661 655
662 if (ret != 0) { 656 if (ret != 0) {
@@ -678,6 +672,7 @@ static int ak4535_remove(struct platform_device *pdev)
678 snd_soc_free_pcms(socdev); 672 snd_soc_free_pcms(socdev);
679 snd_soc_dapm_free(socdev); 673 snd_soc_dapm_free(socdev);
680#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 674#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
675 i2c_unregister_device(codec->control_data);
681 i2c_del_driver(&ak4535_i2c_driver); 676 i2c_del_driver(&ak4535_i2c_driver);
682#endif 677#endif
683 kfree(codec->private_data); 678 kfree(codec->private_data);
diff --git a/sound/soc/codecs/ak4535.h b/sound/soc/codecs/ak4535.h
index e9fe30e2c056..c7a58703ea39 100644
--- a/sound/soc/codecs/ak4535.h
+++ b/sound/soc/codecs/ak4535.h
@@ -37,6 +37,7 @@
37#define AK4535_CACHEREGNUM 0x10 37#define AK4535_CACHEREGNUM 0x10
38 38
39struct ak4535_setup_data { 39struct ak4535_setup_data {
40 int i2c_bus;
40 unsigned short i2c_address; 41 unsigned short i2c_address;
41}; 42};
42 43
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index 9deb8c74fdfd..0bbd94501d7e 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -490,34 +490,7 @@ static int cs4270_mute(struct snd_soc_dai *dai, int mute)
490 490
491#endif 491#endif
492 492
493static int cs4270_i2c_probe(struct i2c_adapter *adap, int addr, int kind); 493static int cs4270_i2c_probe(struct i2c_client *, const struct i2c_device_id *);
494
495/*
496 * Notify the driver that a new I2C bus has been found.
497 *
498 * This function is called for each I2C bus in the system. The function
499 * then asks the I2C subsystem to probe that bus at the addresses on which
500 * our device (the CS4270) could exist. If a device is found at one of
501 * those addresses, then our probe function (cs4270_i2c_probe) is called.
502 */
503static int cs4270_i2c_attach(struct i2c_adapter *adapter)
504{
505 return i2c_probe(adapter, &addr_data, cs4270_i2c_probe);
506}
507
508static int cs4270_i2c_detach(struct i2c_client *client)
509{
510 struct snd_soc_codec *codec = i2c_get_clientdata(client);
511
512 i2c_detach_client(client);
513 codec->control_data = NULL;
514
515 kfree(codec->reg_cache);
516 codec->reg_cache = NULL;
517
518 kfree(client);
519 return 0;
520}
521 494
522/* A list of non-DAPM controls that the CS4270 supports */ 495/* A list of non-DAPM controls that the CS4270 supports */
523static const struct snd_kcontrol_new cs4270_snd_controls[] = { 496static const struct snd_kcontrol_new cs4270_snd_controls[] = {
@@ -525,14 +498,19 @@ static const struct snd_kcontrol_new cs4270_snd_controls[] = {
525 CS4270_VOLA, CS4270_VOLB, 0, 0xFF, 1) 498 CS4270_VOLA, CS4270_VOLB, 0, 0xFF, 1)
526}; 499};
527 500
501static const struct i2c_device_id cs4270_id[] = {
502 {"cs4270", 0},
503 {}
504};
505MODULE_DEVICE_TABLE(i2c, cs4270_id);
506
528static struct i2c_driver cs4270_i2c_driver = { 507static struct i2c_driver cs4270_i2c_driver = {
529 .driver = { 508 .driver = {
530 .name = "CS4270 I2C", 509 .name = "CS4270 I2C",
531 .owner = THIS_MODULE, 510 .owner = THIS_MODULE,
532 }, 511 },
533 .id = I2C_DRIVERID_CS4270, 512 .id_table = cs4270_id,
534 .attach_adapter = cs4270_i2c_attach, 513 .probe = cs4270_i2c_probe,
535 .detach_client = cs4270_i2c_detach,
536}; 514};
537 515
538/* 516/*
@@ -561,11 +539,11 @@ static struct snd_soc_device *cs4270_socdev;
561 * Note: snd_soc_new_pcms() must be called before this function can be called, 539 * Note: snd_soc_new_pcms() must be called before this function can be called,
562 * because of snd_ctl_add(). 540 * because of snd_ctl_add().
563 */ 541 */
564static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind) 542static int cs4270_i2c_probe(struct i2c_client *i2c_client,
543 const struct i2c_device_id *id)
565{ 544{
566 struct snd_soc_device *socdev = cs4270_socdev; 545 struct snd_soc_device *socdev = cs4270_socdev;
567 struct snd_soc_codec *codec = socdev->codec; 546 struct snd_soc_codec *codec = socdev->codec;
568 struct i2c_client *i2c_client = NULL;
569 int i; 547 int i;
570 int ret = 0; 548 int ret = 0;
571 549
@@ -578,12 +556,6 @@ static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind)
578 556
579 /* Note: codec_dai->codec is NULL here */ 557 /* Note: codec_dai->codec is NULL here */
580 558
581 i2c_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
582 if (!i2c_client) {
583 printk(KERN_ERR "cs4270: could not allocate I2C client\n");
584 return -ENOMEM;
585 }
586
587 codec->reg_cache = kzalloc(CS4270_NUMREGS, GFP_KERNEL); 559 codec->reg_cache = kzalloc(CS4270_NUMREGS, GFP_KERNEL);
588 if (!codec->reg_cache) { 560 if (!codec->reg_cache) {
589 printk(KERN_ERR "cs4270: could not allocate register cache\n"); 561 printk(KERN_ERR "cs4270: could not allocate register cache\n");
@@ -591,13 +563,6 @@ static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind)
591 goto error; 563 goto error;
592 } 564 }
593 565
594 i2c_set_clientdata(i2c_client, codec);
595 strcpy(i2c_client->name, "CS4270");
596
597 i2c_client->driver = &cs4270_i2c_driver;
598 i2c_client->adapter = adapter;
599 i2c_client->addr = addr;
600
601 /* Verify that we have a CS4270 */ 566 /* Verify that we have a CS4270 */
602 567
603 ret = i2c_smbus_read_byte_data(i2c_client, CS4270_CHIPID); 568 ret = i2c_smbus_read_byte_data(i2c_client, CS4270_CHIPID);
@@ -612,18 +577,10 @@ static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind)
612 goto error; 577 goto error;
613 } 578 }
614 579
615 printk(KERN_INFO "cs4270: found device at I2C address %X\n", addr); 580 printk(KERN_INFO "cs4270: found device at I2C address %X\n",
581 i2c_client->addr);
616 printk(KERN_INFO "cs4270: hardware revision %X\n", ret & 0xF); 582 printk(KERN_INFO "cs4270: hardware revision %X\n", ret & 0xF);
617 583
618 /* Tell the I2C layer a new client has arrived */
619
620 ret = i2c_attach_client(i2c_client);
621 if (ret) {
622 printk(KERN_ERR "cs4270: could not attach codec, "
623 "I2C address %x, error code %i\n", addr, ret);
624 goto error;
625 }
626
627 codec->control_data = i2c_client; 584 codec->control_data = i2c_client;
628 codec->read = cs4270_read_reg_cache; 585 codec->read = cs4270_read_reg_cache;
629 codec->write = cs4270_i2c_write; 586 codec->write = cs4270_i2c_write;
@@ -648,20 +605,17 @@ static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind)
648 goto error; 605 goto error;
649 } 606 }
650 607
608 i2c_set_clientdata(i2c_client, codec);
609
651 return 0; 610 return 0;
652 611
653error: 612error:
654 if (codec->control_data) { 613 codec->control_data = NULL;
655 i2c_detach_client(i2c_client);
656 codec->control_data = NULL;
657 }
658 614
659 kfree(codec->reg_cache); 615 kfree(codec->reg_cache);
660 codec->reg_cache = NULL; 616 codec->reg_cache = NULL;
661 codec->reg_cache_size = 0; 617 codec->reg_cache_size = 0;
662 618
663 kfree(i2c_client);
664
665 return ret; 619 return ret;
666} 620}
667 621
@@ -727,7 +681,7 @@ static int cs4270_probe(struct platform_device *pdev)
727 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 681 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
728 if (ret < 0) { 682 if (ret < 0) {
729 printk(KERN_ERR "cs4270: failed to create PCMs\n"); 683 printk(KERN_ERR "cs4270: failed to create PCMs\n");
730 return ret; 684 goto error_free_codec;
731 } 685 }
732 686
733#ifdef USE_I2C 687#ifdef USE_I2C
@@ -736,8 +690,7 @@ static int cs4270_probe(struct platform_device *pdev)
736 ret = i2c_add_driver(&cs4270_i2c_driver); 690 ret = i2c_add_driver(&cs4270_i2c_driver);
737 if (ret) { 691 if (ret) {
738 printk(KERN_ERR "cs4270: failed to attach driver"); 692 printk(KERN_ERR "cs4270: failed to attach driver");
739 snd_soc_free_pcms(socdev); 693 goto error_free_pcms;
740 return ret;
741 } 694 }
742 695
743 /* Did we find a CS4270 on the I2C bus? */ 696 /* Did we find a CS4270 on the I2C bus? */
@@ -759,10 +712,23 @@ static int cs4270_probe(struct platform_device *pdev)
759 ret = snd_soc_register_card(socdev); 712 ret = snd_soc_register_card(socdev);
760 if (ret < 0) { 713 if (ret < 0) {
761 printk(KERN_ERR "cs4270: failed to register card\n"); 714 printk(KERN_ERR "cs4270: failed to register card\n");
762 snd_soc_free_pcms(socdev); 715 goto error_del_driver;
763 return ret;
764 } 716 }
765 717
718 return 0;
719
720error_del_driver:
721#ifdef USE_I2C
722 i2c_del_driver(&cs4270_i2c_driver);
723
724error_free_pcms:
725#endif
726 snd_soc_free_pcms(socdev);
727
728error_free_codec:
729 kfree(socdev->codec);
730 socdev->codec = NULL;
731
766 return ret; 732 return ret;
767} 733}
768 734
@@ -773,8 +739,7 @@ static int cs4270_remove(struct platform_device *pdev)
773 snd_soc_free_pcms(socdev); 739 snd_soc_free_pcms(socdev);
774 740
775#ifdef USE_I2C 741#ifdef USE_I2C
776 if (socdev->codec->control_data) 742 i2c_del_driver(&cs4270_i2c_driver);
777 i2c_del_driver(&cs4270_i2c_driver);
778#endif 743#endif
779 744
780 kfree(socdev->codec); 745 kfree(socdev->codec);
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
new file mode 100644
index 000000000000..44ef0dacd564
--- /dev/null
+++ b/sound/soc/codecs/ssm2602.c
@@ -0,0 +1,775 @@
1/*
2 * File: sound/soc/codecs/ssm2602.c
3 * Author: Cliff Cai <Cliff.Cai@analog.com>
4 *
5 * Created: Tue June 06 2008
6 * Description: Driver for ssm2602 sound chip
7 *
8 * Modified:
9 * Copyright 2008 Analog Devices Inc.
10 *
11 * Bugs: Enter bugs at http://blackfin.uclinux.org/
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, see the file COPYING, or write
25 * to the Free Software Foundation, Inc.,
26 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27 */
28
29#include <linux/module.h>
30#include <linux/moduleparam.h>
31#include <linux/init.h>
32#include <linux/delay.h>
33#include <linux/pm.h>
34#include <linux/i2c.h>
35#include <linux/platform_device.h>
36#include <sound/core.h>
37#include <sound/pcm.h>
38#include <sound/pcm_params.h>
39#include <sound/soc.h>
40#include <sound/soc-dapm.h>
41#include <sound/initval.h>
42
43#include "ssm2602.h"
44
45#define SSM2602_VERSION "0.1"
46
47struct snd_soc_codec_device soc_codec_dev_ssm2602;
48
49/* codec private data */
50struct ssm2602_priv {
51 unsigned int sysclk;
52 struct snd_pcm_substream *master_substream;
53 struct snd_pcm_substream *slave_substream;
54};
55
56/*
57 * ssm2602 register cache
58 * We can't read the ssm2602 register space when we are
59 * using 2 wire for device control, so we cache them instead.
60 * There is no point in caching the reset register
61 */
62static const u16 ssm2602_reg[SSM2602_CACHEREGNUM] = {
63 0x0017, 0x0017, 0x0079, 0x0079,
64 0x0000, 0x0000, 0x0000, 0x000a,
65 0x0000, 0x0000
66};
67
68/*
69 * read ssm2602 register cache
70 */
71static inline unsigned int ssm2602_read_reg_cache(struct snd_soc_codec *codec,
72 unsigned int reg)
73{
74 u16 *cache = codec->reg_cache;
75 if (reg == SSM2602_RESET)
76 return 0;
77 if (reg >= SSM2602_CACHEREGNUM)
78 return -1;
79 return cache[reg];
80}
81
82/*
83 * write ssm2602 register cache
84 */
85static inline void ssm2602_write_reg_cache(struct snd_soc_codec *codec,
86 u16 reg, unsigned int value)
87{
88 u16 *cache = codec->reg_cache;
89 if (reg >= SSM2602_CACHEREGNUM)
90 return;
91 cache[reg] = value;
92}
93
94/*
95 * write to the ssm2602 register space
96 */
97static int ssm2602_write(struct snd_soc_codec *codec, unsigned int reg,
98 unsigned int value)
99{
100 u8 data[2];
101
102 /* data is
103 * D15..D9 ssm2602 register offset
104 * D8...D0 register data
105 */
106 data[0] = (reg << 1) | ((value >> 8) & 0x0001);
107 data[1] = value & 0x00ff;
108
109 ssm2602_write_reg_cache(codec, reg, value);
110 if (codec->hw_write(codec->control_data, data, 2) == 2)
111 return 0;
112 else
113 return -EIO;
114}
115
116#define ssm2602_reset(c) ssm2602_write(c, SSM2602_RESET, 0)
117
118/*Appending several "None"s just for OSS mixer use*/
119static const char *ssm2602_input_select[] = {
120 "Line", "Mic", "None", "None", "None",
121 "None", "None", "None",
122};
123
124static const char *ssm2602_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"};
125
126static const struct soc_enum ssm2602_enum[] = {
127 SOC_ENUM_SINGLE(SSM2602_APANA, 2, 2, ssm2602_input_select),
128 SOC_ENUM_SINGLE(SSM2602_APDIGI, 1, 4, ssm2602_deemph),
129};
130
131static const struct snd_kcontrol_new ssm2602_snd_controls[] = {
132
133SOC_DOUBLE_R("Master Playback Volume", SSM2602_LOUT1V, SSM2602_ROUT1V,
134 0, 127, 0),
135SOC_DOUBLE_R("Master Playback ZC Switch", SSM2602_LOUT1V, SSM2602_ROUT1V,
136 7, 1, 0),
137
138SOC_DOUBLE_R("Capture Volume", SSM2602_LINVOL, SSM2602_RINVOL, 0, 31, 0),
139SOC_DOUBLE_R("Capture Switch", SSM2602_LINVOL, SSM2602_RINVOL, 7, 1, 1),
140
141SOC_SINGLE("Mic Boost (+20dB)", SSM2602_APANA, 0, 1, 0),
142SOC_SINGLE("Mic Switch", SSM2602_APANA, 1, 1, 1),
143
144SOC_SINGLE("Sidetone Playback Volume", SSM2602_APANA, 6, 3, 1),
145
146SOC_SINGLE("ADC High Pass Filter Switch", SSM2602_APDIGI, 0, 1, 1),
147SOC_SINGLE("Store DC Offset Switch", SSM2602_APDIGI, 4, 1, 0),
148
149SOC_ENUM("Capture Source", ssm2602_enum[0]),
150
151SOC_ENUM("Playback De-emphasis", ssm2602_enum[1]),
152};
153
154/* add non dapm controls */
155static int ssm2602_add_controls(struct snd_soc_codec *codec)
156{
157 int err, i;
158
159 for (i = 0; i < ARRAY_SIZE(ssm2602_snd_controls); i++) {
160 err = snd_ctl_add(codec->card,
161 snd_soc_cnew(&ssm2602_snd_controls[i], codec, NULL));
162 if (err < 0)
163 return err;
164 }
165
166 return 0;
167}
168
169/* Output Mixer */
170static const struct snd_kcontrol_new ssm2602_output_mixer_controls[] = {
171SOC_DAPM_SINGLE("Line Bypass Switch", SSM2602_APANA, 3, 1, 0),
172SOC_DAPM_SINGLE("Mic Sidetone Switch", SSM2602_APANA, 5, 1, 0),
173SOC_DAPM_SINGLE("HiFi Playback Switch", SSM2602_APANA, 4, 1, 0),
174};
175
176/* Input mux */
177static const struct snd_kcontrol_new ssm2602_input_mux_controls =
178SOC_DAPM_ENUM("Input Select", ssm2602_enum[0]);
179
180static const struct snd_soc_dapm_widget ssm2602_dapm_widgets[] = {
181SND_SOC_DAPM_MIXER("Output Mixer", SSM2602_PWR, 4, 1,
182 &ssm2602_output_mixer_controls[0],
183 ARRAY_SIZE(ssm2602_output_mixer_controls)),
184SND_SOC_DAPM_DAC("DAC", "HiFi Playback", SSM2602_PWR, 3, 1),
185SND_SOC_DAPM_OUTPUT("LOUT"),
186SND_SOC_DAPM_OUTPUT("LHPOUT"),
187SND_SOC_DAPM_OUTPUT("ROUT"),
188SND_SOC_DAPM_OUTPUT("RHPOUT"),
189SND_SOC_DAPM_ADC("ADC", "HiFi Capture", SSM2602_PWR, 2, 1),
190SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM, 0, 0, &ssm2602_input_mux_controls),
191SND_SOC_DAPM_PGA("Line Input", SSM2602_PWR, 0, 1, NULL, 0),
192SND_SOC_DAPM_MICBIAS("Mic Bias", SSM2602_PWR, 1, 1),
193SND_SOC_DAPM_INPUT("MICIN"),
194SND_SOC_DAPM_INPUT("RLINEIN"),
195SND_SOC_DAPM_INPUT("LLINEIN"),
196};
197
198static const struct snd_soc_dapm_route audio_conn[] = {
199 /* output mixer */
200 {"Output Mixer", "Line Bypass Switch", "Line Input"},
201 {"Output Mixer", "HiFi Playback Switch", "DAC"},
202 {"Output Mixer", "Mic Sidetone Switch", "Mic Bias"},
203
204 /* outputs */
205 {"RHPOUT", NULL, "Output Mixer"},
206 {"ROUT", NULL, "Output Mixer"},
207 {"LHPOUT", NULL, "Output Mixer"},
208 {"LOUT", NULL, "Output Mixer"},
209
210 /* input mux */
211 {"Input Mux", "Line", "Line Input"},
212 {"Input Mux", "Mic", "Mic Bias"},
213 {"ADC", NULL, "Input Mux"},
214
215 /* inputs */
216 {"Line Input", NULL, "LLINEIN"},
217 {"Line Input", NULL, "RLINEIN"},
218 {"Mic Bias", NULL, "MICIN"},
219};
220
221static int ssm2602_add_widgets(struct snd_soc_codec *codec)
222{
223 snd_soc_dapm_new_controls(codec, ssm2602_dapm_widgets,
224 ARRAY_SIZE(ssm2602_dapm_widgets));
225
226 snd_soc_dapm_add_routes(codec, audio_conn, ARRAY_SIZE(audio_conn));
227
228 snd_soc_dapm_new_widgets(codec);
229 return 0;
230}
231
232struct _coeff_div {
233 u32 mclk;
234 u32 rate;
235 u16 fs;
236 u8 sr:4;
237 u8 bosr:1;
238 u8 usb:1;
239};
240
241/* codec mclk clock divider coefficients */
242static const struct _coeff_div coeff_div[] = {
243 /* 48k */
244 {12288000, 48000, 256, 0x0, 0x0, 0x0},
245 {18432000, 48000, 384, 0x0, 0x1, 0x0},
246 {12000000, 48000, 250, 0x0, 0x0, 0x1},
247
248 /* 32k */
249 {12288000, 32000, 384, 0x6, 0x0, 0x0},
250 {18432000, 32000, 576, 0x6, 0x1, 0x0},
251 {12000000, 32000, 375, 0x6, 0x0, 0x1},
252
253 /* 8k */
254 {12288000, 8000, 1536, 0x3, 0x0, 0x0},
255 {18432000, 8000, 2304, 0x3, 0x1, 0x0},
256 {11289600, 8000, 1408, 0xb, 0x0, 0x0},
257 {16934400, 8000, 2112, 0xb, 0x1, 0x0},
258 {12000000, 8000, 1500, 0x3, 0x0, 0x1},
259
260 /* 96k */
261 {12288000, 96000, 128, 0x7, 0x0, 0x0},
262 {18432000, 96000, 192, 0x7, 0x1, 0x0},
263 {12000000, 96000, 125, 0x7, 0x0, 0x1},
264
265 /* 44.1k */
266 {11289600, 44100, 256, 0x8, 0x0, 0x0},
267 {16934400, 44100, 384, 0x8, 0x1, 0x0},
268 {12000000, 44100, 272, 0x8, 0x1, 0x1},
269
270 /* 88.2k */
271 {11289600, 88200, 128, 0xf, 0x0, 0x0},
272 {16934400, 88200, 192, 0xf, 0x1, 0x0},
273 {12000000, 88200, 136, 0xf, 0x1, 0x1},
274};
275
276static inline int get_coeff(int mclk, int rate)
277{
278 int i;
279
280 for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
281 if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
282 return i;
283 }
284 return i;
285}
286
287static int ssm2602_hw_params(struct snd_pcm_substream *substream,
288 struct snd_pcm_hw_params *params)
289{
290 u16 srate;
291 struct snd_soc_pcm_runtime *rtd = substream->private_data;
292 struct snd_soc_device *socdev = rtd->socdev;
293 struct snd_soc_codec *codec = socdev->codec;
294 struct ssm2602_priv *ssm2602 = codec->private_data;
295 u16 iface = ssm2602_read_reg_cache(codec, SSM2602_IFACE) & 0xfff3;
296 int i = get_coeff(ssm2602->sysclk, params_rate(params));
297
298 /*no match is found*/
299 if (i == ARRAY_SIZE(coeff_div))
300 return -EINVAL;
301
302 srate = (coeff_div[i].sr << 2) |
303 (coeff_div[i].bosr << 1) | coeff_div[i].usb;
304
305 ssm2602_write(codec, SSM2602_ACTIVE, 0);
306 ssm2602_write(codec, SSM2602_SRATE, srate);
307
308 /* bit size */
309 switch (params_format(params)) {
310 case SNDRV_PCM_FORMAT_S16_LE:
311 break;
312 case SNDRV_PCM_FORMAT_S20_3LE:
313 iface |= 0x0004;
314 break;
315 case SNDRV_PCM_FORMAT_S24_LE:
316 iface |= 0x0008;
317 break;
318 case SNDRV_PCM_FORMAT_S32_LE:
319 iface |= 0x000c;
320 break;
321 }
322 ssm2602_write(codec, SSM2602_IFACE, iface);
323 ssm2602_write(codec, SSM2602_ACTIVE, ACTIVE_ACTIVATE_CODEC);
324 return 0;
325}
326
327static int ssm2602_startup(struct snd_pcm_substream *substream)
328{
329 struct snd_soc_pcm_runtime *rtd = substream->private_data;
330 struct snd_soc_device *socdev = rtd->socdev;
331 struct snd_soc_codec *codec = socdev->codec;
332 struct ssm2602_priv *ssm2602 = codec->private_data;
333 struct snd_pcm_runtime *master_runtime;
334
335 /* The DAI has shared clocks so if we already have a playback or
336 * capture going then constrain this substream to match it.
337 */
338 if (ssm2602->master_substream) {
339 master_runtime = ssm2602->master_substream->runtime;
340 snd_pcm_hw_constraint_minmax(substream->runtime,
341 SNDRV_PCM_HW_PARAM_RATE,
342 master_runtime->rate,
343 master_runtime->rate);
344
345 snd_pcm_hw_constraint_minmax(substream->runtime,
346 SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
347 master_runtime->sample_bits,
348 master_runtime->sample_bits);
349
350 ssm2602->slave_substream = substream;
351 } else
352 ssm2602->master_substream = substream;
353
354 return 0;
355}
356
357static int ssm2602_pcm_prepare(struct snd_pcm_substream *substream)
358{
359 struct snd_soc_pcm_runtime *rtd = substream->private_data;
360 struct snd_soc_device *socdev = rtd->socdev;
361 struct snd_soc_codec *codec = socdev->codec;
362 /* set active */
363 ssm2602_write(codec, SSM2602_ACTIVE, ACTIVE_ACTIVATE_CODEC);
364
365 return 0;
366}
367
368static void ssm2602_shutdown(struct snd_pcm_substream *substream)
369{
370 struct snd_soc_pcm_runtime *rtd = substream->private_data;
371 struct snd_soc_device *socdev = rtd->socdev;
372 struct snd_soc_codec *codec = socdev->codec;
373 /* deactivate */
374 if (!codec->active)
375 ssm2602_write(codec, SSM2602_ACTIVE, 0);
376}
377
378static int ssm2602_mute(struct snd_soc_dai *dai, int mute)
379{
380 struct snd_soc_codec *codec = dai->codec;
381 u16 mute_reg = ssm2602_read_reg_cache(codec, SSM2602_APDIGI) & ~APDIGI_ENABLE_DAC_MUTE;
382 if (mute)
383 ssm2602_write(codec, SSM2602_APDIGI,
384 mute_reg | APDIGI_ENABLE_DAC_MUTE);
385 else
386 ssm2602_write(codec, SSM2602_APDIGI, mute_reg);
387 return 0;
388}
389
390static int ssm2602_set_dai_sysclk(struct snd_soc_dai *codec_dai,
391 int clk_id, unsigned int freq, int dir)
392{
393 struct snd_soc_codec *codec = codec_dai->codec;
394 struct ssm2602_priv *ssm2602 = codec->private_data;
395 switch (freq) {
396 case 11289600:
397 case 12000000:
398 case 12288000:
399 case 16934400:
400 case 18432000:
401 ssm2602->sysclk = freq;
402 return 0;
403 }
404 return -EINVAL;
405}
406
407static int ssm2602_set_dai_fmt(struct snd_soc_dai *codec_dai,
408 unsigned int fmt)
409{
410 struct snd_soc_codec *codec = codec_dai->codec;
411 u16 iface = 0;
412
413 /* set master/slave audio interface */
414 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
415 case SND_SOC_DAIFMT_CBM_CFM:
416 iface |= 0x0040;
417 break;
418 case SND_SOC_DAIFMT_CBS_CFS:
419 break;
420 default:
421 return -EINVAL;
422 }
423
424 /* interface format */
425 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
426 case SND_SOC_DAIFMT_I2S:
427 iface |= 0x0002;
428 break;
429 case SND_SOC_DAIFMT_RIGHT_J:
430 break;
431 case SND_SOC_DAIFMT_LEFT_J:
432 iface |= 0x0001;
433 break;
434 case SND_SOC_DAIFMT_DSP_A:
435 iface |= 0x0003;
436 break;
437 case SND_SOC_DAIFMT_DSP_B:
438 iface |= 0x0013;
439 break;
440 default:
441 return -EINVAL;
442 }
443
444 /* clock inversion */
445 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
446 case SND_SOC_DAIFMT_NB_NF:
447 break;
448 case SND_SOC_DAIFMT_IB_IF:
449 iface |= 0x0090;
450 break;
451 case SND_SOC_DAIFMT_IB_NF:
452 iface |= 0x0080;
453 break;
454 case SND_SOC_DAIFMT_NB_IF:
455 iface |= 0x0010;
456 break;
457 default:
458 return -EINVAL;
459 }
460
461 /* set iface */
462 ssm2602_write(codec, SSM2602_IFACE, iface);
463 return 0;
464}
465
466static int ssm2602_set_bias_level(struct snd_soc_codec *codec,
467 enum snd_soc_bias_level level)
468{
469 u16 reg = ssm2602_read_reg_cache(codec, SSM2602_PWR) & 0xff7f;
470
471 switch (level) {
472 case SND_SOC_BIAS_ON:
473 /* vref/mid, osc on, dac unmute */
474 ssm2602_write(codec, SSM2602_PWR, reg);
475 break;
476 case SND_SOC_BIAS_PREPARE:
477 break;
478 case SND_SOC_BIAS_STANDBY:
479 /* everything off except vref/vmid, */
480 ssm2602_write(codec, SSM2602_PWR, reg | PWR_CLK_OUT_PDN);
481 break;
482 case SND_SOC_BIAS_OFF:
483 /* everything off, dac mute, inactive */
484 ssm2602_write(codec, SSM2602_ACTIVE, 0);
485 ssm2602_write(codec, SSM2602_PWR, 0xffff);
486 break;
487
488 }
489 codec->bias_level = level;
490 return 0;
491}
492
493#define SSM2602_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
494 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
495 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
496 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
497 SNDRV_PCM_RATE_96000)
498
499struct snd_soc_dai ssm2602_dai = {
500 .name = "SSM2602",
501 .playback = {
502 .stream_name = "Playback",
503 .channels_min = 2,
504 .channels_max = 2,
505 .rates = SSM2602_RATES,
506 .formats = SNDRV_PCM_FMTBIT_S32_LE,},
507 .capture = {
508 .stream_name = "Capture",
509 .channels_min = 2,
510 .channels_max = 2,
511 .rates = SSM2602_RATES,
512 .formats = SNDRV_PCM_FMTBIT_S32_LE,},
513 .ops = {
514 .startup = ssm2602_startup,
515 .prepare = ssm2602_pcm_prepare,
516 .hw_params = ssm2602_hw_params,
517 .shutdown = ssm2602_shutdown,
518 },
519 .dai_ops = {
520 .digital_mute = ssm2602_mute,
521 .set_sysclk = ssm2602_set_dai_sysclk,
522 .set_fmt = ssm2602_set_dai_fmt,
523 }
524};
525EXPORT_SYMBOL_GPL(ssm2602_dai);
526
527static int ssm2602_suspend(struct platform_device *pdev, pm_message_t state)
528{
529 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
530 struct snd_soc_codec *codec = socdev->codec;
531
532 ssm2602_set_bias_level(codec, SND_SOC_BIAS_OFF);
533 return 0;
534}
535
536static int ssm2602_resume(struct platform_device *pdev)
537{
538 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
539 struct snd_soc_codec *codec = socdev->codec;
540 int i;
541 u8 data[2];
542 u16 *cache = codec->reg_cache;
543
544 /* Sync reg_cache with the hardware */
545 for (i = 0; i < ARRAY_SIZE(ssm2602_reg); i++) {
546 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
547 data[1] = cache[i] & 0x00ff;
548 codec->hw_write(codec->control_data, data, 2);
549 }
550 ssm2602_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
551 ssm2602_set_bias_level(codec, codec->suspend_bias_level);
552 return 0;
553}
554
555/*
556 * initialise the ssm2602 driver
557 * register the mixer and dsp interfaces with the kernel
558 */
559static int ssm2602_init(struct snd_soc_device *socdev)
560{
561 struct snd_soc_codec *codec = socdev->codec;
562 int reg, ret = 0;
563
564 codec->name = "SSM2602";
565 codec->owner = THIS_MODULE;
566 codec->read = ssm2602_read_reg_cache;
567 codec->write = ssm2602_write;
568 codec->set_bias_level = ssm2602_set_bias_level;
569 codec->dai = &ssm2602_dai;
570 codec->num_dai = 1;
571 codec->reg_cache_size = sizeof(ssm2602_reg);
572 codec->reg_cache = kmemdup(ssm2602_reg, sizeof(ssm2602_reg),
573 GFP_KERNEL);
574 if (codec->reg_cache == NULL)
575 return -ENOMEM;
576
577 ssm2602_reset(codec);
578
579 /* register pcms */
580 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
581 if (ret < 0) {
582 pr_err("ssm2602: failed to create pcms\n");
583 goto pcm_err;
584 }
585 /*power on device*/
586 ssm2602_write(codec, SSM2602_ACTIVE, 0);
587 /* set the update bits */
588 reg = ssm2602_read_reg_cache(codec, SSM2602_LINVOL);
589 ssm2602_write(codec, SSM2602_LINVOL, reg | LINVOL_LRIN_BOTH);
590 reg = ssm2602_read_reg_cache(codec, SSM2602_RINVOL);
591 ssm2602_write(codec, SSM2602_RINVOL, reg | RINVOL_RLIN_BOTH);
592 reg = ssm2602_read_reg_cache(codec, SSM2602_LOUT1V);
593 ssm2602_write(codec, SSM2602_LOUT1V, reg | LOUT1V_LRHP_BOTH);
594 reg = ssm2602_read_reg_cache(codec, SSM2602_ROUT1V);
595 ssm2602_write(codec, SSM2602_ROUT1V, reg | ROUT1V_RLHP_BOTH);
596 /*select Line in as default input*/
597 ssm2602_write(codec, SSM2602_APANA,
598 APANA_ENABLE_MIC_BOOST2 | APANA_SELECT_DAC |
599 APANA_ENABLE_MIC_BOOST);
600 ssm2602_write(codec, SSM2602_PWR, 0);
601
602 ssm2602_add_controls(codec);
603 ssm2602_add_widgets(codec);
604 ret = snd_soc_register_card(socdev);
605 if (ret < 0) {
606 pr_err("ssm2602: failed to register card\n");
607 goto card_err;
608 }
609
610 return ret;
611
612card_err:
613 snd_soc_free_pcms(socdev);
614 snd_soc_dapm_free(socdev);
615pcm_err:
616 kfree(codec->reg_cache);
617 return ret;
618}
619
620static struct snd_soc_device *ssm2602_socdev;
621
622#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
623/*
624 * ssm2602 2 wire address is determined by GPIO5
625 * state during powerup.
626 * low = 0x1a
627 * high = 0x1b
628 */
629static int ssm2602_i2c_probe(struct i2c_client *i2c,
630 const struct i2c_device_id *id)
631{
632 struct snd_soc_device *socdev = ssm2602_socdev;
633 struct snd_soc_codec *codec = socdev->codec;
634 int ret;
635
636 i2c_set_clientdata(i2c, codec);
637 codec->control_data = i2c;
638
639 ret = ssm2602_init(socdev);
640 if (ret < 0)
641 pr_err("failed to initialise SSM2602\n");
642
643 return ret;
644}
645
646static int ssm2602_i2c_remove(struct i2c_client *client)
647{
648 struct snd_soc_codec *codec = i2c_get_clientdata(client);
649 kfree(codec->reg_cache);
650 return 0;
651}
652
653static const struct i2c_device_id ssm2602_i2c_id[] = {
654 { "ssm2602", 0 },
655 { }
656};
657MODULE_DEVICE_TABLE(i2c, ssm2602_i2c_id);
658/* corgi i2c codec control layer */
659static struct i2c_driver ssm2602_i2c_driver = {
660 .driver = {
661 .name = "SSM2602 I2C Codec",
662 .owner = THIS_MODULE,
663 },
664 .probe = ssm2602_i2c_probe,
665 .remove = ssm2602_i2c_remove,
666 .id_table = ssm2602_i2c_id,
667};
668
669static int ssm2602_add_i2c_device(struct platform_device *pdev,
670 const struct ssm2602_setup_data *setup)
671{
672 struct i2c_board_info info;
673 struct i2c_adapter *adapter;
674 struct i2c_client *client;
675 int ret;
676
677 ret = i2c_add_driver(&ssm2602_i2c_driver);
678 if (ret != 0) {
679 dev_err(&pdev->dev, "can't add i2c driver\n");
680 return ret;
681 }
682 memset(&info, 0, sizeof(struct i2c_board_info));
683 info.addr = setup->i2c_address;
684 strlcpy(info.type, "ssm2602", I2C_NAME_SIZE);
685 adapter = i2c_get_adapter(setup->i2c_bus);
686 if (!adapter) {
687 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
688 setup->i2c_bus);
689 goto err_driver;
690 }
691 client = i2c_new_device(adapter, &info);
692 i2c_put_adapter(adapter);
693 if (!client) {
694 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
695 (unsigned int)info.addr);
696 goto err_driver;
697 }
698 return 0;
699err_driver:
700 i2c_del_driver(&ssm2602_i2c_driver);
701 return -ENODEV;
702}
703#endif
704
705static int ssm2602_probe(struct platform_device *pdev)
706{
707 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
708 struct ssm2602_setup_data *setup;
709 struct snd_soc_codec *codec;
710 struct ssm2602_priv *ssm2602;
711 int ret = 0;
712
713 pr_info("ssm2602 Audio Codec %s", SSM2602_VERSION);
714
715 setup = socdev->codec_data;
716 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
717 if (codec == NULL)
718 return -ENOMEM;
719
720 ssm2602 = kzalloc(sizeof(struct ssm2602_priv), GFP_KERNEL);
721 if (ssm2602 == NULL) {
722 kfree(codec);
723 return -ENOMEM;
724 }
725
726 codec->private_data = ssm2602;
727 socdev->codec = codec;
728 mutex_init(&codec->mutex);
729 INIT_LIST_HEAD(&codec->dapm_widgets);
730 INIT_LIST_HEAD(&codec->dapm_paths);
731
732 ssm2602_socdev = socdev;
733#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
734 if (setup->i2c_address) {
735 codec->hw_write = (hw_write_t)i2c_master_send;
736 ret = ssm2602_add_i2c_device(pdev, setup);
737 }
738#else
739 /* other interfaces */
740#endif
741 return ret;
742}
743
744/* remove everything here */
745static int ssm2602_remove(struct platform_device *pdev)
746{
747 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
748 struct snd_soc_codec *codec = socdev->codec;
749
750 if (codec->control_data)
751 ssm2602_set_bias_level(codec, SND_SOC_BIAS_OFF);
752
753 snd_soc_free_pcms(socdev);
754 snd_soc_dapm_free(socdev);
755#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
756 i2c_unregister_device(codec->control_data);
757 i2c_del_driver(&ssm2602_i2c_driver);
758#endif
759 kfree(codec->private_data);
760 kfree(codec);
761
762 return 0;
763}
764
765struct snd_soc_codec_device soc_codec_dev_ssm2602 = {
766 .probe = ssm2602_probe,
767 .remove = ssm2602_remove,
768 .suspend = ssm2602_suspend,
769 .resume = ssm2602_resume,
770};
771EXPORT_SYMBOL_GPL(soc_codec_dev_ssm2602);
772
773MODULE_DESCRIPTION("ASoC ssm2602 driver");
774MODULE_AUTHOR("Cliff Cai");
775MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ssm2602.h b/sound/soc/codecs/ssm2602.h
new file mode 100644
index 000000000000..f344e6d76e31
--- /dev/null
+++ b/sound/soc/codecs/ssm2602.h
@@ -0,0 +1,130 @@
1/*
2 * File: sound/soc/codecs/ssm2602.h
3 * Author: Cliff Cai <Cliff.Cai@analog.com>
4 *
5 * Created: Tue June 06 2008
6 *
7 * Modified:
8 * Copyright 2008 Analog Devices Inc.
9 *
10 * Bugs: Enter bugs at http://blackfin.uclinux.org/
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see the file COPYING, or write
24 * to the Free Software Foundation, Inc.,
25 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26 */
27
28#ifndef _SSM2602_H
29#define _SSM2602_H
30
31/* SSM2602 Codec Register definitions */
32
33#define SSM2602_LINVOL 0x00
34#define SSM2602_RINVOL 0x01
35#define SSM2602_LOUT1V 0x02
36#define SSM2602_ROUT1V 0x03
37#define SSM2602_APANA 0x04
38#define SSM2602_APDIGI 0x05
39#define SSM2602_PWR 0x06
40#define SSM2602_IFACE 0x07
41#define SSM2602_SRATE 0x08
42#define SSM2602_ACTIVE 0x09
43#define SSM2602_RESET 0x0f
44
45/*SSM2602 Codec Register Field definitions
46 *(Mask value to extract the corresponding Register field)
47 */
48
49/*Left ADC Volume Control (SSM2602_REG_LEFT_ADC_VOL)*/
50#define LINVOL_LIN_VOL 0x01F /* Left Channel PGA Volume control */
51#define LINVOL_LIN_ENABLE_MUTE 0x080 /* Left Channel Input Mute */
52#define LINVOL_LRIN_BOTH 0x100 /* Left Channel Line Input Volume update */
53
54/*Right ADC Volume Control (SSM2602_REG_RIGHT_ADC_VOL)*/
55#define RINVOL_RIN_VOL 0x01F /* Right Channel PGA Volume control */
56#define RINVOL_RIN_ENABLE_MUTE 0x080 /* Right Channel Input Mute */
57#define RINVOL_RLIN_BOTH 0x100 /* Right Channel Line Input Volume update */
58
59/*Left DAC Volume Control (SSM2602_REG_LEFT_DAC_VOL)*/
60#define LOUT1V_LHP_VOL 0x07F /* Left Channel Headphone volume control */
61#define LOUT1V_ENABLE_LZC 0x080 /* Left Channel Zero cross detect enable */
62#define LOUT1V_LRHP_BOTH 0x100 /* Left Channel Headphone volume update */
63
64/*Right DAC Volume Control (SSM2602_REG_RIGHT_DAC_VOL)*/
65#define ROUT1V_RHP_VOL 0x07F /* Right Channel Headphone volume control */
66#define ROUT1V_ENABLE_RZC 0x080 /* Right Channel Zero cross detect enable */
67#define ROUT1V_RLHP_BOTH 0x100 /* Right Channel Headphone volume update */
68
69/*Analogue Audio Path Control (SSM2602_REG_ANALOGUE_PATH)*/
70#define APANA_ENABLE_MIC_BOOST 0x001 /* Primary Microphone Amplifier gain booster control */
71#define APANA_ENABLE_MIC_MUTE 0x002 /* Microphone Mute Control */
72#define APANA_ADC_IN_SELECT 0x004 /* Microphone/Line IN select to ADC (1=MIC, 0=Line In) */
73#define APANA_ENABLE_BYPASS 0x008 /* Line input bypass to line output */
74#define APANA_SELECT_DAC 0x010 /* Select DAC (1=Select DAC, 0=Don't Select DAC) */
75#define APANA_ENABLE_SIDETONE 0x020 /* Enable/Disable Side Tone */
76#define APANA_SIDETONE_ATTN 0x0C0 /* Side Tone Attenuation */
77#define APANA_ENABLE_MIC_BOOST2 0x100 /* Secondary Microphone Amplifier gain booster control */
78
79/*Digital Audio Path Control (SSM2602_REG_DIGITAL_PATH)*/
80#define APDIGI_ENABLE_ADC_HPF 0x001 /* Enable/Disable ADC Highpass Filter */
81#define APDIGI_DE_EMPHASIS 0x006 /* De-Emphasis Control */
82#define APDIGI_ENABLE_DAC_MUTE 0x008 /* DAC Mute Control */
83#define APDIGI_STORE_OFFSET 0x010 /* Store/Clear DC offset when HPF is disabled */
84
85/*Power Down Control (SSM2602_REG_POWER)
86 *(1=Enable PowerDown, 0=Disable PowerDown)
87 */
88#define PWR_LINE_IN_PDN 0x001 /* Line Input Power Down */
89#define PWR_MIC_PDN 0x002 /* Microphone Input & Bias Power Down */
90#define PWR_ADC_PDN 0x004 /* ADC Power Down */
91#define PWR_DAC_PDN 0x008 /* DAC Power Down */
92#define PWR_OUT_PDN 0x010 /* Outputs Power Down */
93#define PWR_OSC_PDN 0x020 /* Oscillator Power Down */
94#define PWR_CLK_OUT_PDN 0x040 /* CLKOUT Power Down */
95#define PWR_POWER_OFF 0x080 /* POWEROFF Mode */
96
97/*Digital Audio Interface Format (SSM2602_REG_DIGITAL_IFACE)*/
98#define IFACE_IFACE_FORMAT 0x003 /* Digital Audio input format control */
99#define IFACE_AUDIO_DATA_LEN 0x00C /* Audio Data word length control */
100#define IFACE_DAC_LR_POLARITY 0x010 /* Polarity Control for clocks in RJ,LJ and I2S modes */
101#define IFACE_DAC_LR_SWAP 0x020 /* Swap DAC data control */
102#define IFACE_ENABLE_MASTER 0x040 /* Enable/Disable Master Mode */
103#define IFACE_BCLK_INVERT 0x080 /* Bit Clock Inversion control */
104
105/*Sampling Control (SSM2602_REG_SAMPLING_CTRL)*/
106#define SRATE_ENABLE_USB_MODE 0x001 /* Enable/Disable USB Mode */
107#define SRATE_BOS_RATE 0x002 /* Base Over-Sampling rate */
108#define SRATE_SAMPLE_RATE 0x03C /* Clock setting condition (Sampling rate control) */
109#define SRATE_CORECLK_DIV2 0x040 /* Core Clock divider select */
110#define SRATE_CLKOUT_DIV2 0x080 /* Clock Out divider select */
111
112/*Active Control (SSM2602_REG_ACTIVE_CTRL)*/
113#define ACTIVE_ACTIVATE_CODEC 0x001 /* Activate Codec Digital Audio Interface */
114
115/*********************************************************************/
116
117#define SSM2602_CACHEREGNUM 10
118
119#define SSM2602_SYSCLK 0
120#define SSM2602_DAI 0
121
122struct ssm2602_setup_data {
123 int i2c_bus;
124 unsigned short i2c_address;
125};
126
127extern struct snd_soc_dai ssm2602_dai;
128extern struct snd_soc_codec_device soc_codec_dev_ssm2602;
129
130#endif
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
new file mode 100644
index 000000000000..bac7815e00fb
--- /dev/null
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -0,0 +1,714 @@
1/*
2 * ALSA SoC TLV320AIC23 codec driver
3 *
4 * Author: Arun KS, <arunks@mistralsolutions.com>
5 * Copyright: (C) 2008 Mistral Solutions Pvt Ltd.,
6 *
7 * Based on sound/soc/codecs/wm8731.c by Richard Purdie
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 * Notes:
14 * The AIC23 is a driver for a low power stereo audio
15 * codec tlv320aic23
16 *
17 * The machine layer should disable unsupported inputs/outputs by
18 * snd_soc_dapm_disable_pin(codec, "LHPOUT"), etc.
19 */
20
21#include <linux/module.h>
22#include <linux/moduleparam.h>
23#include <linux/init.h>
24#include <linux/delay.h>
25#include <linux/pm.h>
26#include <linux/i2c.h>
27#include <linux/platform_device.h>
28#include <sound/core.h>
29#include <sound/pcm.h>
30#include <sound/pcm_params.h>
31#include <sound/soc.h>
32#include <sound/soc-dapm.h>
33#include <sound/tlv.h>
34#include <sound/initval.h>
35
36#include "tlv320aic23.h"
37
38#define AIC23_VERSION "0.1"
39
40struct tlv320aic23_srate_reg_info {
41 u32 sample_rate;
42 u8 control; /* SR3, SR2, SR1, SR0 and BOSR */
43 u8 divider; /* if 0 CLKIN = MCLK, if 1 CLKIN = MCLK/2 */
44};
45
46/*
47 * AIC23 register cache
48 */
49static const u16 tlv320aic23_reg[] = {
50 0x0097, 0x0097, 0x00F9, 0x00F9, /* 0 */
51 0x001A, 0x0004, 0x0007, 0x0001, /* 4 */
52 0x0020, 0x0000, 0x0000, 0x0000, /* 8 */
53 0x0000, 0x0000, 0x0000, 0x0000, /* 12 */
54};
55
56/*
57 * read tlv320aic23 register cache
58 */
59static inline unsigned int tlv320aic23_read_reg_cache(struct snd_soc_codec
60 *codec, unsigned int reg)
61{
62 u16 *cache = codec->reg_cache;
63 if (reg >= ARRAY_SIZE(tlv320aic23_reg))
64 return -1;
65 return cache[reg];
66}
67
68/*
69 * write tlv320aic23 register cache
70 */
71static inline void tlv320aic23_write_reg_cache(struct snd_soc_codec *codec,
72 u8 reg, u16 value)
73{
74 u16 *cache = codec->reg_cache;
75 if (reg >= ARRAY_SIZE(tlv320aic23_reg))
76 return;
77 cache[reg] = value;
78}
79
80/*
81 * write to the tlv320aic23 register space
82 */
83static int tlv320aic23_write(struct snd_soc_codec *codec, unsigned int reg,
84 unsigned int value)
85{
86
87 u8 data;
88
89 /* TLV320AIC23 has 7 bit address and 9 bits of data
90 * so we need to switch one data bit into reg and rest
91 * of data into val
92 */
93
94 if ((reg < 0 || reg > 9) && (reg != 15)) {
95 printk(KERN_WARNING "%s Invalid register R%d\n", __func__, reg);
96 return -1;
97 }
98
99 data = (reg << 1) | (value >> 8 & 0x01);
100
101 tlv320aic23_write_reg_cache(codec, reg, value);
102
103 if (codec->hw_write(codec->control_data, data,
104 (value & 0xff)) == 0)
105 return 0;
106
107 printk(KERN_ERR "%s cannot write %03x to register R%d\n", __func__,
108 value, reg);
109
110 return -EIO;
111}
112
113static const char *rec_src_text[] = { "Line", "Mic" };
114static const char *deemph_text[] = {"None", "32Khz", "44.1Khz", "48Khz"};
115
116static const struct soc_enum rec_src_enum =
117 SOC_ENUM_SINGLE(TLV320AIC23_ANLG, 2, 2, rec_src_text);
118
119static const struct snd_kcontrol_new tlv320aic23_rec_src_mux_controls =
120SOC_DAPM_ENUM("Input Select", rec_src_enum);
121
122static const struct soc_enum tlv320aic23_rec_src =
123 SOC_ENUM_SINGLE(TLV320AIC23_ANLG, 2, 2, rec_src_text);
124static const struct soc_enum tlv320aic23_deemph =
125 SOC_ENUM_SINGLE(TLV320AIC23_DIGT, 1, 4, deemph_text);
126
127static const DECLARE_TLV_DB_SCALE(out_gain_tlv, -12100, 100, 0);
128static const DECLARE_TLV_DB_SCALE(input_gain_tlv, -1725, 75, 0);
129static const DECLARE_TLV_DB_SCALE(sidetone_vol_tlv, -1800, 300, 0);
130
131static int snd_soc_tlv320aic23_put_volsw(struct snd_kcontrol *kcontrol,
132 struct snd_ctl_elem_value *ucontrol)
133{
134 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
135 u16 val, reg;
136
137 val = (ucontrol->value.integer.value[0] & 0x07);
138
139 /* linear conversion to userspace
140 * 000 = -6db
141 * 001 = -9db
142 * 010 = -12db
143 * 011 = -18db (Min)
144 * 100 = 0db (Max)
145 */
146 val = (val >= 4) ? 4 : (3 - val);
147
148 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_ANLG) & (~0x1C0);
149 tlv320aic23_write(codec, TLV320AIC23_ANLG, reg | (val << 6));
150
151 return 0;
152}
153
154static int snd_soc_tlv320aic23_get_volsw(struct snd_kcontrol *kcontrol,
155 struct snd_ctl_elem_value *ucontrol)
156{
157 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
158 u16 val;
159
160 val = tlv320aic23_read_reg_cache(codec, TLV320AIC23_ANLG) & (0x1C0);
161 val = val >> 6;
162 val = (val >= 4) ? 4 : (3 - val);
163 ucontrol->value.integer.value[0] = val;
164 return 0;
165
166}
167
168#define SOC_TLV320AIC23_SINGLE_TLV(xname, reg, shift, max, invert, tlv_array) \
169{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
170 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
171 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
172 .tlv.p = (tlv_array), \
173 .info = snd_soc_info_volsw, .get = snd_soc_tlv320aic23_get_volsw,\
174 .put = snd_soc_tlv320aic23_put_volsw, \
175 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
176
177static const struct snd_kcontrol_new tlv320aic23_snd_controls[] = {
178 SOC_DOUBLE_R_TLV("Digital Playback Volume", TLV320AIC23_LCHNVOL,
179 TLV320AIC23_RCHNVOL, 0, 127, 0, out_gain_tlv),
180 SOC_SINGLE("Digital Playback Switch", TLV320AIC23_DIGT, 3, 1, 1),
181 SOC_DOUBLE_R("Line Input Switch", TLV320AIC23_LINVOL,
182 TLV320AIC23_RINVOL, 7, 1, 0),
183 SOC_DOUBLE_R_TLV("Line Input Volume", TLV320AIC23_LINVOL,
184 TLV320AIC23_RINVOL, 0, 31, 0, input_gain_tlv),
185 SOC_SINGLE("Mic Input Switch", TLV320AIC23_ANLG, 1, 1, 1),
186 SOC_SINGLE("Mic Booster Switch", TLV320AIC23_ANLG, 0, 1, 0),
187 SOC_TLV320AIC23_SINGLE_TLV("Sidetone Volume", TLV320AIC23_ANLG,
188 6, 4, 0, sidetone_vol_tlv),
189 SOC_ENUM("Playback De-emphasis", tlv320aic23_deemph),
190};
191
192/* add non dapm controls */
193static int tlv320aic23_add_controls(struct snd_soc_codec *codec)
194{
195
196 int err, i;
197
198 for (i = 0; i < ARRAY_SIZE(tlv320aic23_snd_controls); i++) {
199 err = snd_ctl_add(codec->card,
200 snd_soc_cnew(&tlv320aic23_snd_controls[i],
201 codec, NULL));
202 if (err < 0)
203 return err;
204 }
205
206 return 0;
207
208}
209
210/* PGA Mixer controls for Line and Mic switch */
211static const struct snd_kcontrol_new tlv320aic23_output_mixer_controls[] = {
212 SOC_DAPM_SINGLE("Line Bypass Switch", TLV320AIC23_ANLG, 3, 1, 0),
213 SOC_DAPM_SINGLE("Mic Sidetone Switch", TLV320AIC23_ANLG, 5, 1, 0),
214 SOC_DAPM_SINGLE("Playback Switch", TLV320AIC23_ANLG, 4, 1, 0),
215};
216
217static const struct snd_soc_dapm_widget tlv320aic23_dapm_widgets[] = {
218 SND_SOC_DAPM_DAC("DAC", "Playback", TLV320AIC23_PWR, 3, 1),
219 SND_SOC_DAPM_ADC("ADC", "Capture", TLV320AIC23_PWR, 2, 1),
220 SND_SOC_DAPM_MUX("Capture Source", SND_SOC_NOPM, 0, 0,
221 &tlv320aic23_rec_src_mux_controls),
222 SND_SOC_DAPM_MIXER("Output Mixer", TLV320AIC23_PWR, 4, 1,
223 &tlv320aic23_output_mixer_controls[0],
224 ARRAY_SIZE(tlv320aic23_output_mixer_controls)),
225 SND_SOC_DAPM_PGA("Line Input", TLV320AIC23_PWR, 0, 1, NULL, 0),
226 SND_SOC_DAPM_PGA("Mic Input", TLV320AIC23_PWR, 1, 1, NULL, 0),
227
228 SND_SOC_DAPM_OUTPUT("LHPOUT"),
229 SND_SOC_DAPM_OUTPUT("RHPOUT"),
230 SND_SOC_DAPM_OUTPUT("LOUT"),
231 SND_SOC_DAPM_OUTPUT("ROUT"),
232
233 SND_SOC_DAPM_INPUT("LLINEIN"),
234 SND_SOC_DAPM_INPUT("RLINEIN"),
235
236 SND_SOC_DAPM_INPUT("MICIN"),
237};
238
239static const struct snd_soc_dapm_route intercon[] = {
240 /* Output Mixer */
241 {"Output Mixer", "Line Bypass Switch", "Line Input"},
242 {"Output Mixer", "Playback Switch", "DAC"},
243 {"Output Mixer", "Mic Sidetone Switch", "Mic Input"},
244
245 /* Outputs */
246 {"RHPOUT", NULL, "Output Mixer"},
247 {"LHPOUT", NULL, "Output Mixer"},
248 {"LOUT", NULL, "Output Mixer"},
249 {"ROUT", NULL, "Output Mixer"},
250
251 /* Inputs */
252 {"Line Input", "NULL", "LLINEIN"},
253 {"Line Input", "NULL", "RLINEIN"},
254
255 {"Mic Input", "NULL", "MICIN"},
256
257 /* input mux */
258 {"Capture Source", "Line", "Line Input"},
259 {"Capture Source", "Mic", "Mic Input"},
260 {"ADC", NULL, "Capture Source"},
261
262};
263
264/* tlv320aic23 related */
265static const struct tlv320aic23_srate_reg_info srate_reg_info[] = {
266 {4000, 0x06, 1}, /* 4000 */
267 {8000, 0x06, 0}, /* 8000 */
268 {16000, 0x0C, 1}, /* 16000 */
269 {22050, 0x11, 1}, /* 22050 */
270 {24000, 0x00, 1}, /* 24000 */
271 {32000, 0x0C, 0}, /* 32000 */
272 {44100, 0x11, 0}, /* 44100 */
273 {48000, 0x00, 0}, /* 48000 */
274 {88200, 0x1F, 0}, /* 88200 */
275 {96000, 0x0E, 0}, /* 96000 */
276};
277
278static int tlv320aic23_add_widgets(struct snd_soc_codec *codec)
279{
280 snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets,
281 ARRAY_SIZE(tlv320aic23_dapm_widgets));
282
283 /* set up audio path interconnects */
284 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
285
286 snd_soc_dapm_new_widgets(codec);
287 return 0;
288}
289
290static int tlv320aic23_hw_params(struct snd_pcm_substream *substream,
291 struct snd_pcm_hw_params *params)
292{
293 struct snd_soc_pcm_runtime *rtd = substream->private_data;
294 struct snd_soc_device *socdev = rtd->socdev;
295 struct snd_soc_codec *codec = socdev->codec;
296 u16 iface_reg, data;
297 u8 count = 0;
298
299 iface_reg =
300 tlv320aic23_read_reg_cache(codec,
301 TLV320AIC23_DIGT_FMT) & ~(0x03 << 2);
302
303 /* Search for the right sample rate */
304 /* Verify what happens if the rate is not supported
305 * now it goes to 96Khz */
306 while ((srate_reg_info[count].sample_rate != params_rate(params)) &&
307 (count < ARRAY_SIZE(srate_reg_info))) {
308 count++;
309 }
310
311 data = (srate_reg_info[count].divider << TLV320AIC23_CLKIN_SHIFT) |
312 (srate_reg_info[count]. control << TLV320AIC23_BOSR_SHIFT) |
313 TLV320AIC23_USB_CLK_ON;
314
315 tlv320aic23_write(codec, TLV320AIC23_SRATE, data);
316
317 switch (params_format(params)) {
318 case SNDRV_PCM_FORMAT_S16_LE:
319 break;
320 case SNDRV_PCM_FORMAT_S20_3LE:
321 iface_reg |= (0x01 << 2);
322 break;
323 case SNDRV_PCM_FORMAT_S24_LE:
324 iface_reg |= (0x02 << 2);
325 break;
326 case SNDRV_PCM_FORMAT_S32_LE:
327 iface_reg |= (0x03 << 2);
328 break;
329 }
330 tlv320aic23_write(codec, TLV320AIC23_DIGT_FMT, iface_reg);
331
332 return 0;
333}
334
335static int tlv320aic23_pcm_prepare(struct snd_pcm_substream *substream)
336{
337 struct snd_soc_pcm_runtime *rtd = substream->private_data;
338 struct snd_soc_device *socdev = rtd->socdev;
339 struct snd_soc_codec *codec = socdev->codec;
340
341 /* set active */
342 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0001);
343
344 return 0;
345}
346
347static void tlv320aic23_shutdown(struct snd_pcm_substream *substream)
348{
349 struct snd_soc_pcm_runtime *rtd = substream->private_data;
350 struct snd_soc_device *socdev = rtd->socdev;
351 struct snd_soc_codec *codec = socdev->codec;
352
353 /* deactivate */
354 if (!codec->active) {
355 udelay(50);
356 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0);
357 }
358}
359
360static int tlv320aic23_mute(struct snd_soc_dai *dai, int mute)
361{
362 struct snd_soc_codec *codec = dai->codec;
363 u16 reg;
364
365 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_DIGT);
366 if (mute)
367 reg |= TLV320AIC23_DACM_MUTE;
368
369 else
370 reg &= ~TLV320AIC23_DACM_MUTE;
371
372 tlv320aic23_write(codec, TLV320AIC23_DIGT, reg);
373
374 return 0;
375}
376
377static int tlv320aic23_set_dai_fmt(struct snd_soc_dai *codec_dai,
378 unsigned int fmt)
379{
380 struct snd_soc_codec *codec = codec_dai->codec;
381 u16 iface_reg;
382
383 iface_reg =
384 tlv320aic23_read_reg_cache(codec, TLV320AIC23_DIGT_FMT) & (~0x03);
385
386 /* set master/slave audio interface */
387 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
388 case SND_SOC_DAIFMT_CBM_CFM:
389 iface_reg |= TLV320AIC23_MS_MASTER;
390 break;
391 case SND_SOC_DAIFMT_CBS_CFS:
392 break;
393 default:
394 return -EINVAL;
395
396 }
397
398 /* interface format */
399 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
400 case SND_SOC_DAIFMT_I2S:
401 iface_reg |= TLV320AIC23_FOR_I2S;
402 break;
403 case SND_SOC_DAIFMT_DSP_A:
404 iface_reg |= TLV320AIC23_FOR_DSP;
405 break;
406 case SND_SOC_DAIFMT_RIGHT_J:
407 break;
408 case SND_SOC_DAIFMT_LEFT_J:
409 iface_reg |= TLV320AIC23_FOR_LJUST;
410 break;
411 default:
412 return -EINVAL;
413
414 }
415
416 tlv320aic23_write(codec, TLV320AIC23_DIGT_FMT, iface_reg);
417
418 return 0;
419}
420
421static int tlv320aic23_set_dai_sysclk(struct snd_soc_dai *codec_dai,
422 int clk_id, unsigned int freq, int dir)
423{
424 struct snd_soc_codec *codec = codec_dai->codec;
425
426 switch (freq) {
427 case 12000000:
428 return 0;
429 }
430 return -EINVAL;
431}
432
433static int tlv320aic23_set_bias_level(struct snd_soc_codec *codec,
434 enum snd_soc_bias_level level)
435{
436 u16 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_PWR) & 0xff7f;
437
438 switch (level) {
439 case SND_SOC_BIAS_ON:
440 /* vref/mid, osc on, dac unmute */
441 tlv320aic23_write(codec, TLV320AIC23_PWR, reg);
442 break;
443 case SND_SOC_BIAS_PREPARE:
444 break;
445 case SND_SOC_BIAS_STANDBY:
446 /* everything off except vref/vmid, */
447 tlv320aic23_write(codec, TLV320AIC23_PWR, reg | 0x0040);
448 break;
449 case SND_SOC_BIAS_OFF:
450 /* everything off, dac mute, inactive */
451 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0);
452 tlv320aic23_write(codec, TLV320AIC23_PWR, 0xffff);
453 break;
454 }
455 codec->bias_level = level;
456 return 0;
457}
458
459#define AIC23_RATES SNDRV_PCM_RATE_8000_96000
460#define AIC23_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
461 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
462
463struct snd_soc_dai tlv320aic23_dai = {
464 .name = "tlv320aic23",
465 .playback = {
466 .stream_name = "Playback",
467 .channels_min = 2,
468 .channels_max = 2,
469 .rates = AIC23_RATES,
470 .formats = AIC23_FORMATS,},
471 .capture = {
472 .stream_name = "Capture",
473 .channels_min = 2,
474 .channels_max = 2,
475 .rates = AIC23_RATES,
476 .formats = AIC23_FORMATS,},
477 .ops = {
478 .prepare = tlv320aic23_pcm_prepare,
479 .hw_params = tlv320aic23_hw_params,
480 .shutdown = tlv320aic23_shutdown,
481 },
482 .dai_ops = {
483 .digital_mute = tlv320aic23_mute,
484 .set_fmt = tlv320aic23_set_dai_fmt,
485 .set_sysclk = tlv320aic23_set_dai_sysclk,
486 }
487};
488EXPORT_SYMBOL_GPL(tlv320aic23_dai);
489
490static int tlv320aic23_suspend(struct platform_device *pdev,
491 pm_message_t state)
492{
493 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
494 struct snd_soc_codec *codec = socdev->codec;
495
496 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0);
497 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_OFF);
498
499 return 0;
500}
501
502static int tlv320aic23_resume(struct platform_device *pdev)
503{
504 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
505 struct snd_soc_codec *codec = socdev->codec;
506 int i;
507 u16 reg;
508
509 /* Sync reg_cache with the hardware */
510 for (reg = 0; reg < ARRAY_SIZE(tlv320aic23_reg); i++) {
511 u16 val = tlv320aic23_read_reg_cache(codec, reg);
512 tlv320aic23_write(codec, reg, val);
513 }
514
515 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
516 tlv320aic23_set_bias_level(codec, codec->suspend_bias_level);
517
518 return 0;
519}
520
521/*
522 * initialise the AIC23 driver
523 * register the mixer and dsp interfaces with the kernel
524 */
525static int tlv320aic23_init(struct snd_soc_device *socdev)
526{
527 struct snd_soc_codec *codec = socdev->codec;
528 int ret = 0;
529 u16 reg;
530
531 codec->name = "tlv320aic23";
532 codec->owner = THIS_MODULE;
533 codec->read = tlv320aic23_read_reg_cache;
534 codec->write = tlv320aic23_write;
535 codec->set_bias_level = tlv320aic23_set_bias_level;
536 codec->dai = &tlv320aic23_dai;
537 codec->num_dai = 1;
538 codec->reg_cache_size = ARRAY_SIZE(tlv320aic23_reg);
539 codec->reg_cache =
540 kmemdup(tlv320aic23_reg, sizeof(tlv320aic23_reg), GFP_KERNEL);
541 if (codec->reg_cache == NULL)
542 return -ENOMEM;
543
544 /* Reset codec */
545 tlv320aic23_write(codec, TLV320AIC23_RESET, 0);
546
547 /* register pcms */
548 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
549 if (ret < 0) {
550 printk(KERN_ERR "tlv320aic23: failed to create pcms\n");
551 goto pcm_err;
552 }
553
554 /* power on device */
555 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
556
557 tlv320aic23_write(codec, TLV320AIC23_DIGT, TLV320AIC23_DEEMP_44K);
558
559 /* Unmute input */
560 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_LINVOL);
561 tlv320aic23_write(codec, TLV320AIC23_LINVOL,
562 (reg & (~TLV320AIC23_LIM_MUTED)) |
563 (TLV320AIC23_LRS_ENABLED));
564
565 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_RINVOL);
566 tlv320aic23_write(codec, TLV320AIC23_RINVOL,
567 (reg & (~TLV320AIC23_LIM_MUTED)) |
568 TLV320AIC23_LRS_ENABLED);
569
570 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_ANLG);
571 tlv320aic23_write(codec, TLV320AIC23_ANLG,
572 (reg) & (~TLV320AIC23_BYPASS_ON) &
573 (~TLV320AIC23_MICM_MUTED));
574
575 /* Default output volume */
576 tlv320aic23_write(codec, TLV320AIC23_LCHNVOL,
577 TLV320AIC23_DEFAULT_OUT_VOL &
578 TLV320AIC23_OUT_VOL_MASK);
579 tlv320aic23_write(codec, TLV320AIC23_RCHNVOL,
580 TLV320AIC23_DEFAULT_OUT_VOL &
581 TLV320AIC23_OUT_VOL_MASK);
582
583 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x1);
584
585 tlv320aic23_add_controls(codec);
586 tlv320aic23_add_widgets(codec);
587 ret = snd_soc_register_card(socdev);
588 if (ret < 0) {
589 printk(KERN_ERR "tlv320aic23: failed to register card\n");
590 goto card_err;
591 }
592
593 return ret;
594
595card_err:
596 snd_soc_free_pcms(socdev);
597 snd_soc_dapm_free(socdev);
598pcm_err:
599 kfree(codec->reg_cache);
600 return ret;
601}
602static struct snd_soc_device *tlv320aic23_socdev;
603
604#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
605/*
606 * If the i2c layer weren't so broken, we could pass this kind of data
607 * around
608 */
609static int tlv320aic23_codec_probe(struct i2c_client *i2c,
610 const struct i2c_device_id *i2c_id)
611{
612 struct snd_soc_device *socdev = tlv320aic23_socdev;
613 struct snd_soc_codec *codec = socdev->codec;
614 int ret;
615
616 if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
617 return -EINVAL;
618
619 i2c_set_clientdata(i2c, codec);
620 codec->control_data = i2c;
621
622 ret = tlv320aic23_init(socdev);
623 if (ret < 0) {
624 printk(KERN_ERR "tlv320aic23: failed to initialise AIC23\n");
625 goto err;
626 }
627 return ret;
628
629err:
630 kfree(codec);
631 kfree(i2c);
632 return ret;
633}
634static int __exit tlv320aic23_i2c_remove(struct i2c_client *i2c)
635{
636 put_device(&i2c->dev);
637 return 0;
638}
639
640static const struct i2c_device_id tlv320aic23_id[] = {
641 {"tlv320aic23", 0},
642 {}
643};
644
645MODULE_DEVICE_TABLE(i2c, tlv320aic23_id);
646
647static struct i2c_driver tlv320aic23_i2c_driver = {
648 .driver = {
649 .name = "tlv320aic23",
650 },
651 .probe = tlv320aic23_codec_probe,
652 .remove = __exit_p(tlv320aic23_i2c_remove),
653 .id_table = tlv320aic23_id,
654};
655
656#endif
657
658static int tlv320aic23_probe(struct platform_device *pdev)
659{
660 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
661 struct snd_soc_codec *codec;
662 int ret = 0;
663
664 printk(KERN_INFO "AIC23 Audio Codec %s\n", AIC23_VERSION);
665
666 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
667 if (codec == NULL)
668 return -ENOMEM;
669
670 socdev->codec = codec;
671 mutex_init(&codec->mutex);
672 INIT_LIST_HEAD(&codec->dapm_widgets);
673 INIT_LIST_HEAD(&codec->dapm_paths);
674
675 tlv320aic23_socdev = socdev;
676#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
677 codec->hw_write = (hw_write_t) i2c_smbus_write_byte_data;
678 codec->hw_read = NULL;
679 ret = i2c_add_driver(&tlv320aic23_i2c_driver);
680 if (ret != 0)
681 printk(KERN_ERR "can't add i2c driver");
682#endif
683 return ret;
684}
685
686static int tlv320aic23_remove(struct platform_device *pdev)
687{
688 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
689 struct snd_soc_codec *codec = socdev->codec;
690
691 if (codec->control_data)
692 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_OFF);
693
694 snd_soc_free_pcms(socdev);
695 snd_soc_dapm_free(socdev);
696#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
697 i2c_del_driver(&tlv320aic23_i2c_driver);
698#endif
699 kfree(codec->reg_cache);
700 kfree(codec);
701
702 return 0;
703}
704struct snd_soc_codec_device soc_codec_dev_tlv320aic23 = {
705 .probe = tlv320aic23_probe,
706 .remove = tlv320aic23_remove,
707 .suspend = tlv320aic23_suspend,
708 .resume = tlv320aic23_resume,
709};
710EXPORT_SYMBOL_GPL(soc_codec_dev_tlv320aic23);
711
712MODULE_DESCRIPTION("ASoC TLV320AIC23 codec driver");
713MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>");
714MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/tlv320aic23.h b/sound/soc/codecs/tlv320aic23.h
new file mode 100644
index 000000000000..79d1faf8e570
--- /dev/null
+++ b/sound/soc/codecs/tlv320aic23.h
@@ -0,0 +1,122 @@
1/*
2 * ALSA SoC TLV320AIC23 codec driver
3 *
4 * Author: Arun KS, <arunks@mistralsolutions.com>
5 * Copyright: (C) 2008 Mistral Solutions Pvt Ltd
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef _TLV320AIC23_H
13#define _TLV320AIC23_H
14
15/* Codec TLV320AIC23 */
16#define TLV320AIC23_LINVOL 0x00
17#define TLV320AIC23_RINVOL 0x01
18#define TLV320AIC23_LCHNVOL 0x02
19#define TLV320AIC23_RCHNVOL 0x03
20#define TLV320AIC23_ANLG 0x04
21#define TLV320AIC23_DIGT 0x05
22#define TLV320AIC23_PWR 0x06
23#define TLV320AIC23_DIGT_FMT 0x07
24#define TLV320AIC23_SRATE 0x08
25#define TLV320AIC23_ACTIVE 0x09
26#define TLV320AIC23_RESET 0x0F
27
28/* Left (right) line input volume control register */
29#define TLV320AIC23_LRS_ENABLED 0x0100
30#define TLV320AIC23_LIM_MUTED 0x0080
31#define TLV320AIC23_LIV_DEFAULT 0x0017
32#define TLV320AIC23_LIV_MAX 0x001f
33#define TLV320AIC23_LIV_MIN 0x0000
34
35/* Left (right) channel headphone volume control register */
36#define TLV320AIC23_LZC_ON 0x0080
37#define TLV320AIC23_LHV_DEFAULT 0x0079
38#define TLV320AIC23_LHV_MAX 0x007f
39#define TLV320AIC23_LHV_MIN 0x0000
40
41/* Analog audio path control register */
42#define TLV320AIC23_STA_REG(x) ((x)<<6)
43#define TLV320AIC23_STE_ENABLED 0x0020
44#define TLV320AIC23_DAC_SELECTED 0x0010
45#define TLV320AIC23_BYPASS_ON 0x0008
46#define TLV320AIC23_INSEL_MIC 0x0004
47#define TLV320AIC23_MICM_MUTED 0x0002
48#define TLV320AIC23_MICB_20DB 0x0001
49
50/* Digital audio path control register */
51#define TLV320AIC23_DACM_MUTE 0x0008
52#define TLV320AIC23_DEEMP_32K 0x0002
53#define TLV320AIC23_DEEMP_44K 0x0004
54#define TLV320AIC23_DEEMP_48K 0x0006
55#define TLV320AIC23_ADCHP_ON 0x0001
56
57/* Power control down register */
58#define TLV320AIC23_DEVICE_PWR_OFF 0x0080
59#define TLV320AIC23_CLK_OFF 0x0040
60#define TLV320AIC23_OSC_OFF 0x0020
61#define TLV320AIC23_OUT_OFF 0x0010
62#define TLV320AIC23_DAC_OFF 0x0008
63#define TLV320AIC23_ADC_OFF 0x0004
64#define TLV320AIC23_MIC_OFF 0x0002
65#define TLV320AIC23_LINE_OFF 0x0001
66
67/* Digital audio interface register */
68#define TLV320AIC23_MS_MASTER 0x0040
69#define TLV320AIC23_LRSWAP_ON 0x0020
70#define TLV320AIC23_LRP_ON 0x0010
71#define TLV320AIC23_IWL_16 0x0000
72#define TLV320AIC23_IWL_20 0x0004
73#define TLV320AIC23_IWL_24 0x0008
74#define TLV320AIC23_IWL_32 0x000C
75#define TLV320AIC23_FOR_I2S 0x0002
76#define TLV320AIC23_FOR_DSP 0x0003
77#define TLV320AIC23_FOR_LJUST 0x0001
78
79/* Sample rate control register */
80#define TLV320AIC23_CLKOUT_HALF 0x0080
81#define TLV320AIC23_CLKIN_HALF 0x0040
82#define TLV320AIC23_BOSR_384fs 0x0002 /* BOSR_272fs in USB mode */
83#define TLV320AIC23_USB_CLK_ON 0x0001
84#define TLV320AIC23_SR_MASK 0xf
85#define TLV320AIC23_CLKOUT_SHIFT 7
86#define TLV320AIC23_CLKIN_SHIFT 6
87#define TLV320AIC23_SR_SHIFT 2
88#define TLV320AIC23_BOSR_SHIFT 1
89
90/* Digital interface register */
91#define TLV320AIC23_ACT_ON 0x0001
92
93/*
94 * AUDIO related MACROS
95 */
96
97#define TLV320AIC23_DEFAULT_OUT_VOL 0x70
98#define TLV320AIC23_DEFAULT_IN_VOLUME 0x10
99
100#define TLV320AIC23_OUT_VOL_MIN TLV320AIC23_LHV_MIN
101#define TLV320AIC23_OUT_VOL_MAX TLV320AIC23_LHV_MAX
102#define TLV320AIC23_OUT_VO_RANGE (TLV320AIC23_OUT_VOL_MAX - \
103 TLV320AIC23_OUT_VOL_MIN)
104#define TLV320AIC23_OUT_VOL_MASK TLV320AIC23_OUT_VOL_MAX
105
106#define TLV320AIC23_IN_VOL_MIN TLV320AIC23_LIV_MIN
107#define TLV320AIC23_IN_VOL_MAX TLV320AIC23_LIV_MAX
108#define TLV320AIC23_IN_VOL_RANGE (TLV320AIC23_IN_VOL_MAX - \
109 TLV320AIC23_IN_VOL_MIN)
110#define TLV320AIC23_IN_VOL_MASK TLV320AIC23_IN_VOL_MAX
111
112#define TLV320AIC23_SIDETONE_MASK 0x1c0
113#define TLV320AIC23_SIDETONE_0 0x100
114#define TLV320AIC23_SIDETONE_6 0x000
115#define TLV320AIC23_SIDETONE_9 0x040
116#define TLV320AIC23_SIDETONE_12 0x080
117#define TLV320AIC23_SIDETONE_18 0x0c0
118
119extern struct snd_soc_dai tlv320aic23_dai;
120extern struct snd_soc_codec_device soc_codec_dev_tlv320aic23;
121
122#endif /* _TLV320AIC23_H */
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c
new file mode 100644
index 000000000000..bed8a9e63ddc
--- /dev/null
+++ b/sound/soc/codecs/tlv320aic26.c
@@ -0,0 +1,520 @@
1/*
2 * Texas Instruments TLV320AIC26 low power audio CODEC
3 * ALSA SoC CODEC driver
4 *
5 * Copyright (C) 2008 Secret Lab Technologies Ltd.
6 */
7
8#include <linux/module.h>
9#include <linux/moduleparam.h>
10#include <linux/init.h>
11#include <linux/delay.h>
12#include <linux/pm.h>
13#include <linux/device.h>
14#include <linux/sysfs.h>
15#include <linux/spi/spi.h>
16#include <sound/core.h>
17#include <sound/pcm.h>
18#include <sound/pcm_params.h>
19#include <sound/soc.h>
20#include <sound/soc-dapm.h>
21#include <sound/soc-of-simple.h>
22#include <sound/initval.h>
23
24#include "tlv320aic26.h"
25
26MODULE_DESCRIPTION("ASoC TLV320AIC26 codec driver");
27MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
28MODULE_LICENSE("GPL");
29
30/* AIC26 driver private data */
31struct aic26 {
32 struct spi_device *spi;
33 struct snd_soc_codec codec;
34 u16 reg_cache[AIC26_NUM_REGS]; /* shadow registers */
35 int master;
36 int datfm;
37 int mclk;
38
39 /* Keyclick parameters */
40 int keyclick_amplitude;
41 int keyclick_freq;
42 int keyclick_len;
43};
44
45/* ---------------------------------------------------------------------
46 * Register access routines
47 */
48static unsigned int aic26_reg_read(struct snd_soc_codec *codec,
49 unsigned int reg)
50{
51 struct aic26 *aic26 = codec->private_data;
52 u16 *cache = codec->reg_cache;
53 u16 cmd, value;
54 u8 buffer[2];
55 int rc;
56
57 if (reg >= AIC26_NUM_REGS) {
58 WARN_ON_ONCE(1);
59 return 0;
60 }
61
62 /* Do SPI transfer; first 16bits are command; remaining is
63 * register contents */
64 cmd = AIC26_READ_COMMAND_WORD(reg);
65 buffer[0] = (cmd >> 8) & 0xff;
66 buffer[1] = cmd & 0xff;
67 rc = spi_write_then_read(aic26->spi, buffer, 2, buffer, 2);
68 if (rc) {
69 dev_err(&aic26->spi->dev, "AIC26 reg read error\n");
70 return -EIO;
71 }
72 value = (buffer[0] << 8) | buffer[1];
73
74 /* Update the cache before returning with the value */
75 cache[reg] = value;
76 return value;
77}
78
79static unsigned int aic26_reg_read_cache(struct snd_soc_codec *codec,
80 unsigned int reg)
81{
82 u16 *cache = codec->reg_cache;
83
84 if (reg >= AIC26_NUM_REGS) {
85 WARN_ON_ONCE(1);
86 return 0;
87 }
88
89 return cache[reg];
90}
91
92static int aic26_reg_write(struct snd_soc_codec *codec, unsigned int reg,
93 unsigned int value)
94{
95 struct aic26 *aic26 = codec->private_data;
96 u16 *cache = codec->reg_cache;
97 u16 cmd;
98 u8 buffer[4];
99 int rc;
100
101 if (reg >= AIC26_NUM_REGS) {
102 WARN_ON_ONCE(1);
103 return -EINVAL;
104 }
105
106 /* Do SPI transfer; first 16bits are command; remaining is data
107 * to write into register */
108 cmd = AIC26_WRITE_COMMAND_WORD(reg);
109 buffer[0] = (cmd >> 8) & 0xff;
110 buffer[1] = cmd & 0xff;
111 buffer[2] = value >> 8;
112 buffer[3] = value;
113 rc = spi_write(aic26->spi, buffer, 4);
114 if (rc) {
115 dev_err(&aic26->spi->dev, "AIC26 reg read error\n");
116 return -EIO;
117 }
118
119 /* update cache before returning */
120 cache[reg] = value;
121 return 0;
122}
123
124/* ---------------------------------------------------------------------
125 * Digital Audio Interface Operations
126 */
127static int aic26_hw_params(struct snd_pcm_substream *substream,
128 struct snd_pcm_hw_params *params)
129{
130 struct snd_soc_pcm_runtime *rtd = substream->private_data;
131 struct snd_soc_device *socdev = rtd->socdev;
132 struct snd_soc_codec *codec = socdev->codec;
133 struct aic26 *aic26 = codec->private_data;
134 int fsref, divisor, wlen, pval, jval, dval, qval;
135 u16 reg;
136
137 dev_dbg(&aic26->spi->dev, "aic26_hw_params(substream=%p, params=%p)\n",
138 substream, params);
139 dev_dbg(&aic26->spi->dev, "rate=%i format=%i\n", params_rate(params),
140 params_format(params));
141
142 switch (params_rate(params)) {
143 case 8000: fsref = 48000; divisor = AIC26_DIV_6; break;
144 case 11025: fsref = 44100; divisor = AIC26_DIV_4; break;
145 case 12000: fsref = 48000; divisor = AIC26_DIV_4; break;
146 case 16000: fsref = 48000; divisor = AIC26_DIV_3; break;
147 case 22050: fsref = 44100; divisor = AIC26_DIV_2; break;
148 case 24000: fsref = 48000; divisor = AIC26_DIV_2; break;
149 case 32000: fsref = 48000; divisor = AIC26_DIV_1_5; break;
150 case 44100: fsref = 44100; divisor = AIC26_DIV_1; break;
151 case 48000: fsref = 48000; divisor = AIC26_DIV_1; break;
152 default:
153 dev_dbg(&aic26->spi->dev, "bad rate\n"); return -EINVAL;
154 }
155
156 /* select data word length */
157 switch (params_format(params)) {
158 case SNDRV_PCM_FORMAT_S8: wlen = AIC26_WLEN_16; break;
159 case SNDRV_PCM_FORMAT_S16_BE: wlen = AIC26_WLEN_16; break;
160 case SNDRV_PCM_FORMAT_S24_BE: wlen = AIC26_WLEN_24; break;
161 case SNDRV_PCM_FORMAT_S32_BE: wlen = AIC26_WLEN_32; break;
162 default:
163 dev_dbg(&aic26->spi->dev, "bad format\n"); return -EINVAL;
164 }
165
166 /* Configure PLL */
167 pval = 1;
168 jval = (fsref == 44100) ? 7 : 8;
169 dval = (fsref == 44100) ? 5264 : 1920;
170 qval = 0;
171 reg = 0x8000 | qval << 11 | pval << 8 | jval << 2;
172 aic26_reg_write(codec, AIC26_REG_PLL_PROG1, reg);
173 reg = dval << 2;
174 aic26_reg_write(codec, AIC26_REG_PLL_PROG2, reg);
175
176 /* Audio Control 3 (master mode, fsref rate) */
177 reg = aic26_reg_read_cache(codec, AIC26_REG_AUDIO_CTRL3);
178 reg &= ~0xf800;
179 if (aic26->master)
180 reg |= 0x0800;
181 if (fsref == 48000)
182 reg |= 0x2000;
183 aic26_reg_write(codec, AIC26_REG_AUDIO_CTRL3, reg);
184
185 /* Audio Control 1 (FSref divisor) */
186 reg = aic26_reg_read_cache(codec, AIC26_REG_AUDIO_CTRL1);
187 reg &= ~0x0fff;
188 reg |= wlen | aic26->datfm | (divisor << 3) | divisor;
189 aic26_reg_write(codec, AIC26_REG_AUDIO_CTRL1, reg);
190
191 return 0;
192}
193
194/**
195 * aic26_mute - Mute control to reduce noise when changing audio format
196 */
197static int aic26_mute(struct snd_soc_dai *dai, int mute)
198{
199 struct snd_soc_codec *codec = dai->codec;
200 struct aic26 *aic26 = codec->private_data;
201 u16 reg = aic26_reg_read_cache(codec, AIC26_REG_DAC_GAIN);
202
203 dev_dbg(&aic26->spi->dev, "aic26_mute(dai=%p, mute=%i)\n",
204 dai, mute);
205
206 if (mute)
207 reg |= 0x8080;
208 else
209 reg &= ~0x8080;
210 aic26_reg_write(codec, AIC26_REG_DAC_GAIN, reg);
211
212 return 0;
213}
214
215static int aic26_set_sysclk(struct snd_soc_dai *codec_dai,
216 int clk_id, unsigned int freq, int dir)
217{
218 struct snd_soc_codec *codec = codec_dai->codec;
219 struct aic26 *aic26 = codec->private_data;
220
221 dev_dbg(&aic26->spi->dev, "aic26_set_sysclk(dai=%p, clk_id==%i,"
222 " freq=%i, dir=%i)\n",
223 codec_dai, clk_id, freq, dir);
224
225 /* MCLK needs to fall between 2MHz and 50 MHz */
226 if ((freq < 2000000) || (freq > 50000000))
227 return -EINVAL;
228
229 aic26->mclk = freq;
230 return 0;
231}
232
233static int aic26_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
234{
235 struct snd_soc_codec *codec = codec_dai->codec;
236 struct aic26 *aic26 = codec->private_data;
237
238 dev_dbg(&aic26->spi->dev, "aic26_set_fmt(dai=%p, fmt==%i)\n",
239 codec_dai, fmt);
240
241 /* set master/slave audio interface */
242 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
243 case SND_SOC_DAIFMT_CBM_CFM: aic26->master = 1; break;
244 case SND_SOC_DAIFMT_CBS_CFS: aic26->master = 0; break;
245 default:
246 dev_dbg(&aic26->spi->dev, "bad master\n"); return -EINVAL;
247 }
248
249 /* interface format */
250 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
251 case SND_SOC_DAIFMT_I2S: aic26->datfm = AIC26_DATFM_I2S; break;
252 case SND_SOC_DAIFMT_DSP_A: aic26->datfm = AIC26_DATFM_DSP; break;
253 case SND_SOC_DAIFMT_RIGHT_J: aic26->datfm = AIC26_DATFM_RIGHTJ; break;
254 case SND_SOC_DAIFMT_LEFT_J: aic26->datfm = AIC26_DATFM_LEFTJ; break;
255 default:
256 dev_dbg(&aic26->spi->dev, "bad format\n"); return -EINVAL;
257 }
258
259 return 0;
260}
261
262/* ---------------------------------------------------------------------
263 * Digital Audio Interface Definition
264 */
265#define AIC26_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
266 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
267 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
268 SNDRV_PCM_RATE_48000)
269#define AIC26_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_BE |\
270 SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S32_BE)
271
272struct snd_soc_dai aic26_dai = {
273 .name = "tlv320aic26",
274 .playback = {
275 .stream_name = "Playback",
276 .channels_min = 2,
277 .channels_max = 2,
278 .rates = AIC26_RATES,
279 .formats = AIC26_FORMATS,
280 },
281 .capture = {
282 .stream_name = "Capture",
283 .channels_min = 2,
284 .channels_max = 2,
285 .rates = AIC26_RATES,
286 .formats = AIC26_FORMATS,
287 },
288 .ops = {
289 .hw_params = aic26_hw_params,
290 },
291 .dai_ops = {
292 .digital_mute = aic26_mute,
293 .set_sysclk = aic26_set_sysclk,
294 .set_fmt = aic26_set_fmt,
295 },
296};
297EXPORT_SYMBOL_GPL(aic26_dai);
298
299/* ---------------------------------------------------------------------
300 * ALSA controls
301 */
302static const char *aic26_capture_src_text[] = {"Mic", "Aux"};
303static const struct soc_enum aic26_capture_src_enum =
304 SOC_ENUM_SINGLE(AIC26_REG_AUDIO_CTRL1, 12, 2, aic26_capture_src_text);
305
306static const struct snd_kcontrol_new aic26_snd_controls[] = {
307 /* Output */
308 SOC_DOUBLE("PCM Playback Volume", AIC26_REG_DAC_GAIN, 8, 0, 0x7f, 1),
309 SOC_DOUBLE("PCM Playback Switch", AIC26_REG_DAC_GAIN, 15, 7, 1, 1),
310 SOC_SINGLE("PCM Capture Volume", AIC26_REG_ADC_GAIN, 8, 0x7f, 0),
311 SOC_SINGLE("PCM Capture Mute", AIC26_REG_ADC_GAIN, 15, 1, 1),
312 SOC_SINGLE("Keyclick activate", AIC26_REG_AUDIO_CTRL2, 15, 0x1, 0),
313 SOC_SINGLE("Keyclick amplitude", AIC26_REG_AUDIO_CTRL2, 12, 0x7, 0),
314 SOC_SINGLE("Keyclick frequency", AIC26_REG_AUDIO_CTRL2, 8, 0x7, 0),
315 SOC_SINGLE("Keyclick period", AIC26_REG_AUDIO_CTRL2, 4, 0xf, 0),
316 SOC_ENUM("Capture Source", aic26_capture_src_enum),
317};
318
319/* ---------------------------------------------------------------------
320 * SoC CODEC portion of driver: probe and release routines
321 */
322static int aic26_probe(struct platform_device *pdev)
323{
324 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
325 struct snd_soc_codec *codec;
326 struct snd_kcontrol *kcontrol;
327 struct aic26 *aic26;
328 int i, ret, err;
329
330 dev_info(&pdev->dev, "Probing AIC26 SoC CODEC driver\n");
331 dev_dbg(&pdev->dev, "socdev=%p\n", socdev);
332 dev_dbg(&pdev->dev, "codec_data=%p\n", socdev->codec_data);
333
334 /* Fetch the relevant aic26 private data here (it's already been
335 * stored in the .codec pointer) */
336 aic26 = socdev->codec_data;
337 if (aic26 == NULL) {
338 dev_err(&pdev->dev, "aic26: missing codec pointer\n");
339 return -ENODEV;
340 }
341 codec = &aic26->codec;
342 socdev->codec = codec;
343
344 dev_dbg(&pdev->dev, "Registering PCMs, dev=%p, socdev->dev=%p\n",
345 &pdev->dev, socdev->dev);
346 /* register pcms */
347 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
348 if (ret < 0) {
349 dev_err(&pdev->dev, "aic26: failed to create pcms\n");
350 return -ENODEV;
351 }
352
353 /* register controls */
354 dev_dbg(&pdev->dev, "Registering controls\n");
355 for (i = 0; i < ARRAY_SIZE(aic26_snd_controls); i++) {
356 kcontrol = snd_soc_cnew(&aic26_snd_controls[i], codec, NULL);
357 err = snd_ctl_add(codec->card, kcontrol);
358 WARN_ON(err < 0);
359 }
360
361 /* CODEC is setup, we can register the card now */
362 dev_dbg(&pdev->dev, "Registering card\n");
363 ret = snd_soc_register_card(socdev);
364 if (ret < 0) {
365 dev_err(&pdev->dev, "aic26: failed to register card\n");
366 goto card_err;
367 }
368 return 0;
369
370 card_err:
371 snd_soc_free_pcms(socdev);
372 return ret;
373}
374
375static int aic26_remove(struct platform_device *pdev)
376{
377 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
378 snd_soc_free_pcms(socdev);
379 return 0;
380}
381
382struct snd_soc_codec_device aic26_soc_codec_dev = {
383 .probe = aic26_probe,
384 .remove = aic26_remove,
385};
386EXPORT_SYMBOL_GPL(aic26_soc_codec_dev);
387
388/* ---------------------------------------------------------------------
389 * SPI device portion of driver: sysfs files for debugging
390 */
391
392static ssize_t aic26_keyclick_show(struct device *dev,
393 struct device_attribute *attr, char *buf)
394{
395 struct aic26 *aic26 = dev_get_drvdata(dev);
396 int val, amp, freq, len;
397
398 val = aic26_reg_read_cache(&aic26->codec, AIC26_REG_AUDIO_CTRL2);
399 amp = (val >> 12) & 0x7;
400 freq = (125 << ((val >> 8) & 0x7)) >> 1;
401 len = 2 * (1 + ((val >> 4) & 0xf));
402
403 return sprintf(buf, "amp=%x freq=%iHz len=%iclks\n", amp, freq, len);
404}
405
406/* Any write to the keyclick attribute will trigger the keyclick event */
407static ssize_t aic26_keyclick_set(struct device *dev,
408 struct device_attribute *attr,
409 const char *buf, size_t count)
410{
411 struct aic26 *aic26 = dev_get_drvdata(dev);
412 int val;
413
414 val = aic26_reg_read_cache(&aic26->codec, AIC26_REG_AUDIO_CTRL2);
415 val |= 0x8000;
416 aic26_reg_write(&aic26->codec, AIC26_REG_AUDIO_CTRL2, val);
417
418 return count;
419}
420
421static DEVICE_ATTR(keyclick, 0644, aic26_keyclick_show, aic26_keyclick_set);
422
423/* ---------------------------------------------------------------------
424 * SPI device portion of driver: probe and release routines and SPI
425 * driver registration.
426 */
427static int aic26_spi_probe(struct spi_device *spi)
428{
429 struct aic26 *aic26;
430 int rc, i, reg;
431
432 dev_dbg(&spi->dev, "probing tlv320aic26 spi device\n");
433
434 /* Allocate driver data */
435 aic26 = kzalloc(sizeof *aic26, GFP_KERNEL);
436 if (!aic26)
437 return -ENOMEM;
438
439 /* Initialize the driver data */
440 aic26->spi = spi;
441 dev_set_drvdata(&spi->dev, aic26);
442
443 /* Setup what we can in the codec structure so that the register
444 * access functions will work as expected. More will be filled
445 * out when it is probed by the SoC CODEC part of this driver */
446 aic26->codec.private_data = aic26;
447 aic26->codec.name = "aic26";
448 aic26->codec.owner = THIS_MODULE;
449 aic26->codec.dai = &aic26_dai;
450 aic26->codec.num_dai = 1;
451 aic26->codec.read = aic26_reg_read;
452 aic26->codec.write = aic26_reg_write;
453 aic26->master = 1;
454 mutex_init(&aic26->codec.mutex);
455 INIT_LIST_HEAD(&aic26->codec.dapm_widgets);
456 INIT_LIST_HEAD(&aic26->codec.dapm_paths);
457 aic26->codec.reg_cache_size = AIC26_NUM_REGS;
458 aic26->codec.reg_cache = aic26->reg_cache;
459
460 /* Reset the codec to power on defaults */
461 aic26_reg_write(&aic26->codec, AIC26_REG_RESET, 0xBB00);
462
463 /* Power up CODEC */
464 aic26_reg_write(&aic26->codec, AIC26_REG_POWER_CTRL, 0);
465
466 /* Audio Control 3 (master mode, fsref rate) */
467 reg = aic26_reg_read(&aic26->codec, AIC26_REG_AUDIO_CTRL3);
468 reg &= ~0xf800;
469 reg |= 0x0800; /* set master mode */
470 aic26_reg_write(&aic26->codec, AIC26_REG_AUDIO_CTRL3, reg);
471
472 /* Fill register cache */
473 for (i = 0; i < ARRAY_SIZE(aic26->reg_cache); i++)
474 aic26_reg_read(&aic26->codec, i);
475
476 /* Register the sysfs files for debugging */
477 /* Create SysFS files */
478 rc = device_create_file(&spi->dev, &dev_attr_keyclick);
479 if (rc)
480 dev_info(&spi->dev, "error creating sysfs files\n");
481
482#if defined(CONFIG_SND_SOC_OF_SIMPLE)
483 /* Tell the of_soc helper about this codec */
484 of_snd_soc_register_codec(&aic26_soc_codec_dev, aic26, &aic26_dai,
485 spi->dev.archdata.of_node);
486#endif
487
488 dev_dbg(&spi->dev, "SPI device initialized\n");
489 return 0;
490}
491
492static int aic26_spi_remove(struct spi_device *spi)
493{
494 struct aic26 *aic26 = dev_get_drvdata(&spi->dev);
495
496 kfree(aic26);
497
498 return 0;
499}
500
501static struct spi_driver aic26_spi = {
502 .driver = {
503 .name = "tlv320aic26",
504 .owner = THIS_MODULE,
505 },
506 .probe = aic26_spi_probe,
507 .remove = aic26_spi_remove,
508};
509
510static int __init aic26_init(void)
511{
512 return spi_register_driver(&aic26_spi);
513}
514module_init(aic26_init);
515
516static void __exit aic26_exit(void)
517{
518 spi_unregister_driver(&aic26_spi);
519}
520module_exit(aic26_exit);
diff --git a/sound/soc/codecs/tlv320aic26.h b/sound/soc/codecs/tlv320aic26.h
new file mode 100644
index 000000000000..786ba16c945f
--- /dev/null
+++ b/sound/soc/codecs/tlv320aic26.h
@@ -0,0 +1,96 @@
1/*
2 * Texas Instruments TLV320AIC26 low power audio CODEC
3 * register definitions
4 *
5 * Copyright (C) 2008 Secret Lab Technologies Ltd.
6 */
7
8#ifndef _TLV320AIC16_H_
9#define _TLV320AIC16_H_
10
11/* AIC26 Registers */
12#define AIC26_READ_COMMAND_WORD(addr) ((1 << 15) | (addr << 5))
13#define AIC26_WRITE_COMMAND_WORD(addr) ((0 << 15) | (addr << 5))
14#define AIC26_PAGE_ADDR(page, offset) ((page << 6) | offset)
15#define AIC26_NUM_REGS AIC26_PAGE_ADDR(3, 0)
16
17/* Page 0: Auxillary data registers */
18#define AIC26_REG_BAT1 AIC26_PAGE_ADDR(0, 0x05)
19#define AIC26_REG_BAT2 AIC26_PAGE_ADDR(0, 0x06)
20#define AIC26_REG_AUX AIC26_PAGE_ADDR(0, 0x07)
21#define AIC26_REG_TEMP1 AIC26_PAGE_ADDR(0, 0x09)
22#define AIC26_REG_TEMP2 AIC26_PAGE_ADDR(0, 0x0A)
23
24/* Page 1: Auxillary control registers */
25#define AIC26_REG_AUX_ADC AIC26_PAGE_ADDR(1, 0x00)
26#define AIC26_REG_STATUS AIC26_PAGE_ADDR(1, 0x01)
27#define AIC26_REG_REFERENCE AIC26_PAGE_ADDR(1, 0x03)
28#define AIC26_REG_RESET AIC26_PAGE_ADDR(1, 0x04)
29
30/* Page 2: Audio control registers */
31#define AIC26_REG_AUDIO_CTRL1 AIC26_PAGE_ADDR(2, 0x00)
32#define AIC26_REG_ADC_GAIN AIC26_PAGE_ADDR(2, 0x01)
33#define AIC26_REG_DAC_GAIN AIC26_PAGE_ADDR(2, 0x02)
34#define AIC26_REG_SIDETONE AIC26_PAGE_ADDR(2, 0x03)
35#define AIC26_REG_AUDIO_CTRL2 AIC26_PAGE_ADDR(2, 0x04)
36#define AIC26_REG_POWER_CTRL AIC26_PAGE_ADDR(2, 0x05)
37#define AIC26_REG_AUDIO_CTRL3 AIC26_PAGE_ADDR(2, 0x06)
38
39#define AIC26_REG_FILTER_COEFF_L_N0 AIC26_PAGE_ADDR(2, 0x07)
40#define AIC26_REG_FILTER_COEFF_L_N1 AIC26_PAGE_ADDR(2, 0x08)
41#define AIC26_REG_FILTER_COEFF_L_N2 AIC26_PAGE_ADDR(2, 0x09)
42#define AIC26_REG_FILTER_COEFF_L_N3 AIC26_PAGE_ADDR(2, 0x0A)
43#define AIC26_REG_FILTER_COEFF_L_N4 AIC26_PAGE_ADDR(2, 0x0B)
44#define AIC26_REG_FILTER_COEFF_L_N5 AIC26_PAGE_ADDR(2, 0x0C)
45#define AIC26_REG_FILTER_COEFF_L_D1 AIC26_PAGE_ADDR(2, 0x0D)
46#define AIC26_REG_FILTER_COEFF_L_D2 AIC26_PAGE_ADDR(2, 0x0E)
47#define AIC26_REG_FILTER_COEFF_L_D4 AIC26_PAGE_ADDR(2, 0x0F)
48#define AIC26_REG_FILTER_COEFF_L_D5 AIC26_PAGE_ADDR(2, 0x10)
49#define AIC26_REG_FILTER_COEFF_R_N0 AIC26_PAGE_ADDR(2, 0x11)
50#define AIC26_REG_FILTER_COEFF_R_N1 AIC26_PAGE_ADDR(2, 0x12)
51#define AIC26_REG_FILTER_COEFF_R_N2 AIC26_PAGE_ADDR(2, 0x13)
52#define AIC26_REG_FILTER_COEFF_R_N3 AIC26_PAGE_ADDR(2, 0x14)
53#define AIC26_REG_FILTER_COEFF_R_N4 AIC26_PAGE_ADDR(2, 0x15)
54#define AIC26_REG_FILTER_COEFF_R_N5 AIC26_PAGE_ADDR(2, 0x16)
55#define AIC26_REG_FILTER_COEFF_R_D1 AIC26_PAGE_ADDR(2, 0x17)
56#define AIC26_REG_FILTER_COEFF_R_D2 AIC26_PAGE_ADDR(2, 0x18)
57#define AIC26_REG_FILTER_COEFF_R_D4 AIC26_PAGE_ADDR(2, 0x19)
58#define AIC26_REG_FILTER_COEFF_R_D5 AIC26_PAGE_ADDR(2, 0x1A)
59
60#define AIC26_REG_PLL_PROG1 AIC26_PAGE_ADDR(2, 0x1B)
61#define AIC26_REG_PLL_PROG2 AIC26_PAGE_ADDR(2, 0x1C)
62#define AIC26_REG_AUDIO_CTRL4 AIC26_PAGE_ADDR(2, 0x1D)
63#define AIC26_REG_AUDIO_CTRL5 AIC26_PAGE_ADDR(2, 0x1E)
64
65/* fsref dividers; used in register 'Audio Control 1' */
66enum aic26_divisors {
67 AIC26_DIV_1 = 0,
68 AIC26_DIV_1_5 = 1,
69 AIC26_DIV_2 = 2,
70 AIC26_DIV_3 = 3,
71 AIC26_DIV_4 = 4,
72 AIC26_DIV_5 = 5,
73 AIC26_DIV_5_5 = 6,
74 AIC26_DIV_6 = 7,
75};
76
77/* Digital data format */
78enum aic26_datfm {
79 AIC26_DATFM_I2S = 0 << 8,
80 AIC26_DATFM_DSP = 1 << 8,
81 AIC26_DATFM_RIGHTJ = 2 << 8, /* right justified */
82 AIC26_DATFM_LEFTJ = 3 << 8, /* left justified */
83};
84
85/* Sample word length in bits; used in register 'Audio Control 1' */
86enum aic26_wlen {
87 AIC26_WLEN_16 = 0 << 10,
88 AIC26_WLEN_20 = 1 << 10,
89 AIC26_WLEN_24 = 2 << 10,
90 AIC26_WLEN_32 = 3 << 10,
91};
92
93extern struct snd_soc_dai aic26_dai;
94extern struct snd_soc_codec_device aic26_soc_codec_dev;
95
96#endif /* _TLV320AIC16_H_ */
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 5f9abb199435..05336ed7e493 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * ALSA SoC TLV320AIC3X codec driver 2 * ALSA SoC TLV320AIC3X codec driver
3 * 3 *
4 * Author: Vladimir Barinov, <vbarinov@ru.mvista.com> 4 * Author: Vladimir Barinov, <vbarinov@embeddedalley.com>
5 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com> 5 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com>
6 * 6 *
7 * Based on sound/soc/codecs/wm8753.c by Liam Girdwood 7 * Based on sound/soc/codecs/wm8753.c by Liam Girdwood
@@ -48,7 +48,6 @@
48 48
49#include "tlv320aic3x.h" 49#include "tlv320aic3x.h"
50 50
51#define AUDIO_NAME "aic3x"
52#define AIC3X_VERSION "0.2" 51#define AIC3X_VERSION "0.2"
53 52
54/* codec private data */ 53/* codec private data */
@@ -991,7 +990,7 @@ EXPORT_SYMBOL_GPL(aic3x_headset_detected);
991 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) 990 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
992 991
993struct snd_soc_dai aic3x_dai = { 992struct snd_soc_dai aic3x_dai = {
994 .name = "aic3x", 993 .name = "tlv320aic3x",
995 .playback = { 994 .playback = {
996 .stream_name = "Playback", 995 .stream_name = "Playback",
997 .channels_min = 1, 996 .channels_min = 1,
@@ -1055,7 +1054,7 @@ static int aic3x_init(struct snd_soc_device *socdev)
1055 struct aic3x_setup_data *setup = socdev->codec_data; 1054 struct aic3x_setup_data *setup = socdev->codec_data;
1056 int reg, ret = 0; 1055 int reg, ret = 0;
1057 1056
1058 codec->name = "aic3x"; 1057 codec->name = "tlv320aic3x";
1059 codec->owner = THIS_MODULE; 1058 codec->owner = THIS_MODULE;
1060 codec->read = aic3x_read_reg_cache; 1059 codec->read = aic3x_read_reg_cache;
1061 codec->write = aic3x_write; 1060 codec->write = aic3x_write;
@@ -1172,71 +1171,39 @@ static struct snd_soc_device *aic3x_socdev;
1172 * AIC3X 2 wire address can be up to 4 devices with device addresses 1171 * AIC3X 2 wire address can be up to 4 devices with device addresses
1173 * 0x18, 0x19, 0x1A, 0x1B 1172 * 0x18, 0x19, 0x1A, 0x1B
1174 */ 1173 */
1175static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
1176
1177/* Magic definition of all other variables and things */
1178I2C_CLIENT_INSMOD;
1179
1180static struct i2c_driver aic3x_i2c_driver;
1181static struct i2c_client client_template;
1182 1174
1183/* 1175/*
1184 * If the i2c layer weren't so broken, we could pass this kind of data 1176 * If the i2c layer weren't so broken, we could pass this kind of data
1185 * around 1177 * around
1186 */ 1178 */
1187static int aic3x_codec_probe(struct i2c_adapter *adap, int addr, int kind) 1179static int aic3x_i2c_probe(struct i2c_client *i2c,
1180 const struct i2c_device_id *id)
1188{ 1181{
1189 struct snd_soc_device *socdev = aic3x_socdev; 1182 struct snd_soc_device *socdev = aic3x_socdev;
1190 struct aic3x_setup_data *setup = socdev->codec_data;
1191 struct snd_soc_codec *codec = socdev->codec; 1183 struct snd_soc_codec *codec = socdev->codec;
1192 struct i2c_client *i2c;
1193 int ret; 1184 int ret;
1194 1185
1195 if (addr != setup->i2c_address)
1196 return -ENODEV;
1197
1198 client_template.adapter = adap;
1199 client_template.addr = addr;
1200
1201 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
1202 if (i2c == NULL)
1203 return -ENOMEM;
1204
1205 i2c_set_clientdata(i2c, codec); 1186 i2c_set_clientdata(i2c, codec);
1206 codec->control_data = i2c; 1187 codec->control_data = i2c;
1207 1188
1208 ret = i2c_attach_client(i2c);
1209 if (ret < 0) {
1210 printk(KERN_ERR "aic3x: failed to attach codec at addr %x\n",
1211 addr);
1212 goto err;
1213 }
1214
1215 ret = aic3x_init(socdev); 1189 ret = aic3x_init(socdev);
1216 if (ret < 0) { 1190 if (ret < 0)
1217 printk(KERN_ERR "aic3x: failed to initialise AIC3X\n"); 1191 printk(KERN_ERR "aic3x: failed to initialise AIC3X\n");
1218 goto err;
1219 }
1220 return ret;
1221
1222err:
1223 kfree(i2c);
1224 return ret; 1192 return ret;
1225} 1193}
1226 1194
1227static int aic3x_i2c_detach(struct i2c_client *client) 1195static int aic3x_i2c_remove(struct i2c_client *client)
1228{ 1196{
1229 struct snd_soc_codec *codec = i2c_get_clientdata(client); 1197 struct snd_soc_codec *codec = i2c_get_clientdata(client);
1230 i2c_detach_client(client);
1231 kfree(codec->reg_cache); 1198 kfree(codec->reg_cache);
1232 kfree(client);
1233 return 0; 1199 return 0;
1234} 1200}
1235 1201
1236static int aic3x_i2c_attach(struct i2c_adapter *adap) 1202static const struct i2c_device_id aic3x_i2c_id[] = {
1237{ 1203 { "tlv320aic3x", 0 },
1238 return i2c_probe(adap, &addr_data, aic3x_codec_probe); 1204 { }
1239} 1205};
1206MODULE_DEVICE_TABLE(i2c, aic3x_i2c_id);
1240 1207
1241/* machine i2c codec control layer */ 1208/* machine i2c codec control layer */
1242static struct i2c_driver aic3x_i2c_driver = { 1209static struct i2c_driver aic3x_i2c_driver = {
@@ -1244,13 +1211,9 @@ static struct i2c_driver aic3x_i2c_driver = {
1244 .name = "aic3x I2C Codec", 1211 .name = "aic3x I2C Codec",
1245 .owner = THIS_MODULE, 1212 .owner = THIS_MODULE,
1246 }, 1213 },
1247 .attach_adapter = aic3x_i2c_attach, 1214 .probe = aic3x_i2c_probe,
1248 .detach_client = aic3x_i2c_detach, 1215 .remove = aic3x_i2c_remove,
1249}; 1216 .id_table = aic3x_i2c_id,
1250
1251static struct i2c_client client_template = {
1252 .name = "AIC3X",
1253 .driver = &aic3x_i2c_driver,
1254}; 1217};
1255 1218
1256static int aic3x_i2c_read(struct i2c_client *client, u8 *value, int len) 1219static int aic3x_i2c_read(struct i2c_client *client, u8 *value, int len)
@@ -1258,6 +1221,46 @@ static int aic3x_i2c_read(struct i2c_client *client, u8 *value, int len)
1258 value[0] = i2c_smbus_read_byte_data(client, value[0]); 1221 value[0] = i2c_smbus_read_byte_data(client, value[0]);
1259 return (len == 1); 1222 return (len == 1);
1260} 1223}
1224
1225static int aic3x_add_i2c_device(struct platform_device *pdev,
1226 const struct aic3x_setup_data *setup)
1227{
1228 struct i2c_board_info info;
1229 struct i2c_adapter *adapter;
1230 struct i2c_client *client;
1231 int ret;
1232
1233 ret = i2c_add_driver(&aic3x_i2c_driver);
1234 if (ret != 0) {
1235 dev_err(&pdev->dev, "can't add i2c driver\n");
1236 return ret;
1237 }
1238
1239 memset(&info, 0, sizeof(struct i2c_board_info));
1240 info.addr = setup->i2c_address;
1241 strlcpy(info.type, "tlv320aic3x", I2C_NAME_SIZE);
1242
1243 adapter = i2c_get_adapter(setup->i2c_bus);
1244 if (!adapter) {
1245 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
1246 setup->i2c_bus);
1247 goto err_driver;
1248 }
1249
1250 client = i2c_new_device(adapter, &info);
1251 i2c_put_adapter(adapter);
1252 if (!client) {
1253 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
1254 (unsigned int)info.addr);
1255 goto err_driver;
1256 }
1257
1258 return 0;
1259
1260err_driver:
1261 i2c_del_driver(&aic3x_i2c_driver);
1262 return -ENODEV;
1263}
1261#endif 1264#endif
1262 1265
1263static int aic3x_probe(struct platform_device *pdev) 1266static int aic3x_probe(struct platform_device *pdev)
@@ -1290,12 +1293,9 @@ static int aic3x_probe(struct platform_device *pdev)
1290 aic3x_socdev = socdev; 1293 aic3x_socdev = socdev;
1291#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1294#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1292 if (setup->i2c_address) { 1295 if (setup->i2c_address) {
1293 normal_i2c[0] = setup->i2c_address;
1294 codec->hw_write = (hw_write_t) i2c_master_send; 1296 codec->hw_write = (hw_write_t) i2c_master_send;
1295 codec->hw_read = (hw_read_t) aic3x_i2c_read; 1297 codec->hw_read = (hw_read_t) aic3x_i2c_read;
1296 ret = i2c_add_driver(&aic3x_i2c_driver); 1298 ret = aic3x_add_i2c_device(pdev, setup);
1297 if (ret != 0)
1298 printk(KERN_ERR "can't add i2c driver");
1299 } 1299 }
1300#else 1300#else
1301 /* Add other interfaces here */ 1301 /* Add other interfaces here */
@@ -1320,6 +1320,7 @@ static int aic3x_remove(struct platform_device *pdev)
1320 snd_soc_free_pcms(socdev); 1320 snd_soc_free_pcms(socdev);
1321 snd_soc_dapm_free(socdev); 1321 snd_soc_dapm_free(socdev);
1322#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1322#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1323 i2c_unregister_device(codec->control_data);
1323 i2c_del_driver(&aic3x_i2c_driver); 1324 i2c_del_driver(&aic3x_i2c_driver);
1324#endif 1325#endif
1325 kfree(codec->private_data); 1326 kfree(codec->private_data);
diff --git a/sound/soc/codecs/tlv320aic3x.h b/sound/soc/codecs/tlv320aic3x.h
index d76c079b86e7..00a195aa02e4 100644
--- a/sound/soc/codecs/tlv320aic3x.h
+++ b/sound/soc/codecs/tlv320aic3x.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * ALSA SoC TLV320AIC3X codec driver 2 * ALSA SoC TLV320AIC3X codec driver
3 * 3 *
4 * Author: Vladimir Barinov, <vbarinov@ru.mvista.com> 4 * Author: Vladimir Barinov, <vbarinov@embeddedalley.com>
5 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com> 5 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
@@ -224,6 +224,7 @@ int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio);
224int aic3x_headset_detected(struct snd_soc_codec *codec); 224int aic3x_headset_detected(struct snd_soc_codec *codec);
225 225
226struct aic3x_setup_data { 226struct aic3x_setup_data {
227 int i2c_bus;
227 unsigned short i2c_address; 228 unsigned short i2c_address;
228 unsigned int gpio_func[2]; 229 unsigned int gpio_func[2];
229}; 230};
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c
index 807318fbdc8f..a69ee72a7af5 100644
--- a/sound/soc/codecs/uda1380.c
+++ b/sound/soc/codecs/uda1380.c
@@ -36,7 +36,6 @@
36#include "uda1380.h" 36#include "uda1380.h"
37 37
38#define UDA1380_VERSION "0.6" 38#define UDA1380_VERSION "0.6"
39#define AUDIO_NAME "uda1380"
40 39
41/* 40/*
42 * uda1380 register cache 41 * uda1380 register cache
@@ -701,87 +700,86 @@ static struct snd_soc_device *uda1380_socdev;
701 700
702#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 701#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
703 702
704#define I2C_DRIVERID_UDA1380 0xfefe /* liam - need a proper id */ 703static int uda1380_i2c_probe(struct i2c_client *i2c,
705 704 const struct i2c_device_id *id)
706static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
707
708/* Magic definition of all other variables and things */
709I2C_CLIENT_INSMOD;
710
711static struct i2c_driver uda1380_i2c_driver;
712static struct i2c_client client_template;
713
714/* If the i2c layer weren't so broken, we could pass this kind of data
715 around */
716
717static int uda1380_codec_probe(struct i2c_adapter *adap, int addr, int kind)
718{ 705{
719 struct snd_soc_device *socdev = uda1380_socdev; 706 struct snd_soc_device *socdev = uda1380_socdev;
720 struct uda1380_setup_data *setup = socdev->codec_data; 707 struct uda1380_setup_data *setup = socdev->codec_data;
721 struct snd_soc_codec *codec = socdev->codec; 708 struct snd_soc_codec *codec = socdev->codec;
722 struct i2c_client *i2c;
723 int ret; 709 int ret;
724 710
725 if (addr != setup->i2c_address)
726 return -ENODEV;
727
728 client_template.adapter = adap;
729 client_template.addr = addr;
730
731 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
732 if (i2c == NULL)
733 return -ENOMEM;
734
735 i2c_set_clientdata(i2c, codec); 711 i2c_set_clientdata(i2c, codec);
736 codec->control_data = i2c; 712 codec->control_data = i2c;
737 713
738 ret = i2c_attach_client(i2c);
739 if (ret < 0) {
740 pr_err("uda1380: failed to attach codec at addr %x\n", addr);
741 goto err;
742 }
743
744 ret = uda1380_init(socdev, setup->dac_clk); 714 ret = uda1380_init(socdev, setup->dac_clk);
745 if (ret < 0) { 715 if (ret < 0)
746 pr_err("uda1380: failed to initialise UDA1380\n"); 716 pr_err("uda1380: failed to initialise UDA1380\n");
747 goto err;
748 }
749 return ret;
750 717
751err:
752 kfree(i2c);
753 return ret; 718 return ret;
754} 719}
755 720
756static int uda1380_i2c_detach(struct i2c_client *client) 721static int uda1380_i2c_remove(struct i2c_client *client)
757{ 722{
758 struct snd_soc_codec *codec = i2c_get_clientdata(client); 723 struct snd_soc_codec *codec = i2c_get_clientdata(client);
759 i2c_detach_client(client);
760 kfree(codec->reg_cache); 724 kfree(codec->reg_cache);
761 kfree(client);
762 return 0; 725 return 0;
763} 726}
764 727
765static int uda1380_i2c_attach(struct i2c_adapter *adap) 728static const struct i2c_device_id uda1380_i2c_id[] = {
766{ 729 { "uda1380", 0 },
767 return i2c_probe(adap, &addr_data, uda1380_codec_probe); 730 { }
768} 731};
732MODULE_DEVICE_TABLE(i2c, uda1380_i2c_id);
769 733
770static struct i2c_driver uda1380_i2c_driver = { 734static struct i2c_driver uda1380_i2c_driver = {
771 .driver = { 735 .driver = {
772 .name = "UDA1380 I2C Codec", 736 .name = "UDA1380 I2C Codec",
773 .owner = THIS_MODULE, 737 .owner = THIS_MODULE,
774 }, 738 },
775 .id = I2C_DRIVERID_UDA1380, 739 .probe = uda1380_i2c_probe,
776 .attach_adapter = uda1380_i2c_attach, 740 .remove = uda1380_i2c_remove,
777 .detach_client = uda1380_i2c_detach, 741 .id_table = uda1380_i2c_id,
778 .command = NULL,
779}; 742};
780 743
781static struct i2c_client client_template = { 744static int uda1380_add_i2c_device(struct platform_device *pdev,
782 .name = "UDA1380", 745 const struct uda1380_setup_data *setup)
783 .driver = &uda1380_i2c_driver, 746{
784}; 747 struct i2c_board_info info;
748 struct i2c_adapter *adapter;
749 struct i2c_client *client;
750 int ret;
751
752 ret = i2c_add_driver(&uda1380_i2c_driver);
753 if (ret != 0) {
754 dev_err(&pdev->dev, "can't add i2c driver\n");
755 return ret;
756 }
757
758 memset(&info, 0, sizeof(struct i2c_board_info));
759 info.addr = setup->i2c_address;
760 strlcpy(info.type, "uda1380", I2C_NAME_SIZE);
761
762 adapter = i2c_get_adapter(setup->i2c_bus);
763 if (!adapter) {
764 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
765 setup->i2c_bus);
766 goto err_driver;
767 }
768
769 client = i2c_new_device(adapter, &info);
770 i2c_put_adapter(adapter);
771 if (!client) {
772 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
773 (unsigned int)info.addr);
774 goto err_driver;
775 }
776
777 return 0;
778
779err_driver:
780 i2c_del_driver(&uda1380_i2c_driver);
781 return -ENODEV;
782}
785#endif 783#endif
786 784
787static int uda1380_probe(struct platform_device *pdev) 785static int uda1380_probe(struct platform_device *pdev)
@@ -789,7 +787,7 @@ static int uda1380_probe(struct platform_device *pdev)
789 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 787 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
790 struct uda1380_setup_data *setup; 788 struct uda1380_setup_data *setup;
791 struct snd_soc_codec *codec; 789 struct snd_soc_codec *codec;
792 int ret = 0; 790 int ret;
793 791
794 pr_info("UDA1380 Audio Codec %s", UDA1380_VERSION); 792 pr_info("UDA1380 Audio Codec %s", UDA1380_VERSION);
795 793
@@ -804,16 +802,13 @@ static int uda1380_probe(struct platform_device *pdev)
804 INIT_LIST_HEAD(&codec->dapm_paths); 802 INIT_LIST_HEAD(&codec->dapm_paths);
805 803
806 uda1380_socdev = socdev; 804 uda1380_socdev = socdev;
805 ret = -ENODEV;
806
807#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 807#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
808 if (setup->i2c_address) { 808 if (setup->i2c_address) {
809 normal_i2c[0] = setup->i2c_address;
810 codec->hw_write = (hw_write_t)i2c_master_send; 809 codec->hw_write = (hw_write_t)i2c_master_send;
811 ret = i2c_add_driver(&uda1380_i2c_driver); 810 ret = uda1380_add_i2c_device(pdev, setup);
812 if (ret != 0)
813 printk(KERN_ERR "can't add i2c driver");
814 } 811 }
815#else
816 /* Add other interfaces here */
817#endif 812#endif
818 813
819 if (ret != 0) 814 if (ret != 0)
@@ -833,6 +828,7 @@ static int uda1380_remove(struct platform_device *pdev)
833 snd_soc_free_pcms(socdev); 828 snd_soc_free_pcms(socdev);
834 snd_soc_dapm_free(socdev); 829 snd_soc_dapm_free(socdev);
835#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 830#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
831 i2c_unregister_device(codec->control_data);
836 i2c_del_driver(&uda1380_i2c_driver); 832 i2c_del_driver(&uda1380_i2c_driver);
837#endif 833#endif
838 kfree(codec); 834 kfree(codec);
diff --git a/sound/soc/codecs/uda1380.h b/sound/soc/codecs/uda1380.h
index 50c603e2c9f2..c55c17a52a12 100644
--- a/sound/soc/codecs/uda1380.h
+++ b/sound/soc/codecs/uda1380.h
@@ -73,6 +73,7 @@
73#define R23_AGC_EN 0x0001 73#define R23_AGC_EN 0x0001
74 74
75struct uda1380_setup_data { 75struct uda1380_setup_data {
76 int i2c_bus;
76 unsigned short i2c_address; 77 unsigned short i2c_address;
77 int dac_clk; 78 int dac_clk;
78#define UDA1380_DAC_CLK_SYSCLK 0 79#define UDA1380_DAC_CLK_SYSCLK 0
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c
index 3d998e6a997e..d8ca2da8d634 100644
--- a/sound/soc/codecs/wm8510.c
+++ b/sound/soc/codecs/wm8510.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright 2006 Wolfson Microelectronics PLC. 4 * Copyright 2006 Wolfson Microelectronics PLC.
5 * 5 *
6 * Author: Liam Girdwood <liam.girdwood@wolfsonmicro.com> 6 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
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
@@ -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/spi/spi.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>
@@ -27,7 +28,6 @@
27 28
28#include "wm8510.h" 29#include "wm8510.h"
29 30
30#define AUDIO_NAME "wm8510"
31#define WM8510_VERSION "0.6" 31#define WM8510_VERSION "0.6"
32 32
33struct snd_soc_codec_device soc_codec_dev_wm8510; 33struct snd_soc_codec_device soc_codec_dev_wm8510;
@@ -55,6 +55,9 @@ static const u16 wm8510_reg[WM8510_CACHEREGNUM] = {
55 0x0001, 55 0x0001,
56}; 56};
57 57
58#define WM8510_POWER1_BIASEN 0x08
59#define WM8510_POWER1_BUFIOEN 0x10
60
58/* 61/*
59 * read wm8510 register cache 62 * read wm8510 register cache
60 */ 63 */
@@ -199,7 +202,7 @@ SOC_DAPM_SINGLE("PCM Playback Switch", WM8510_MONOMIX, 0, 1, 0),
199}; 202};
200 203
201static const struct snd_kcontrol_new wm8510_boost_controls[] = { 204static const struct snd_kcontrol_new wm8510_boost_controls[] = {
202SOC_DAPM_SINGLE("Mic PGA Switch", WM8510_INPPGA, 6, 1, 0), 205SOC_DAPM_SINGLE("Mic PGA Switch", WM8510_INPPGA, 6, 1, 1),
203SOC_DAPM_SINGLE("Aux Volume", WM8510_ADCBOOST, 0, 7, 0), 206SOC_DAPM_SINGLE("Aux Volume", WM8510_ADCBOOST, 0, 7, 0),
204SOC_DAPM_SINGLE("Mic Volume", WM8510_ADCBOOST, 4, 7, 0), 207SOC_DAPM_SINGLE("Mic Volume", WM8510_ADCBOOST, 4, 7, 0),
205}; 208};
@@ -224,9 +227,9 @@ SND_SOC_DAPM_PGA("SpkN Out", WM8510_POWER3, 5, 0, NULL, 0),
224SND_SOC_DAPM_PGA("SpkP Out", WM8510_POWER3, 6, 0, NULL, 0), 227SND_SOC_DAPM_PGA("SpkP Out", WM8510_POWER3, 6, 0, NULL, 0),
225SND_SOC_DAPM_PGA("Mono Out", WM8510_POWER3, 7, 0, NULL, 0), 228SND_SOC_DAPM_PGA("Mono Out", WM8510_POWER3, 7, 0, NULL, 0),
226 229
227SND_SOC_DAPM_PGA("Mic PGA", WM8510_POWER2, 2, 0, 230SND_SOC_DAPM_MIXER("Mic PGA", WM8510_POWER2, 2, 0,
228 &wm8510_micpga_controls[0], 231 &wm8510_micpga_controls[0],
229 ARRAY_SIZE(wm8510_micpga_controls)), 232 ARRAY_SIZE(wm8510_micpga_controls)),
230SND_SOC_DAPM_MIXER("Boost Mixer", WM8510_POWER2, 4, 0, 233SND_SOC_DAPM_MIXER("Boost Mixer", WM8510_POWER2, 4, 0,
231 &wm8510_boost_controls[0], 234 &wm8510_boost_controls[0],
232 ARRAY_SIZE(wm8510_boost_controls)), 235 ARRAY_SIZE(wm8510_boost_controls)),
@@ -526,23 +529,35 @@ static int wm8510_mute(struct snd_soc_dai *dai, int mute)
526static int wm8510_set_bias_level(struct snd_soc_codec *codec, 529static int wm8510_set_bias_level(struct snd_soc_codec *codec,
527 enum snd_soc_bias_level level) 530 enum snd_soc_bias_level level)
528{ 531{
532 u16 power1 = wm8510_read_reg_cache(codec, WM8510_POWER1) & ~0x3;
529 533
530 switch (level) { 534 switch (level) {
531 case SND_SOC_BIAS_ON: 535 case SND_SOC_BIAS_ON:
532 wm8510_write(codec, WM8510_POWER1, 0x1ff);
533 wm8510_write(codec, WM8510_POWER2, 0x1ff);
534 wm8510_write(codec, WM8510_POWER3, 0x1ff);
535 break;
536 case SND_SOC_BIAS_PREPARE: 536 case SND_SOC_BIAS_PREPARE:
537 power1 |= 0x1; /* VMID 50k */
538 wm8510_write(codec, WM8510_POWER1, power1);
539 break;
540
537 case SND_SOC_BIAS_STANDBY: 541 case SND_SOC_BIAS_STANDBY:
542 power1 |= WM8510_POWER1_BIASEN | WM8510_POWER1_BUFIOEN;
543
544 if (codec->bias_level == SND_SOC_BIAS_OFF) {
545 /* Initial cap charge at VMID 5k */
546 wm8510_write(codec, WM8510_POWER1, power1 | 0x3);
547 mdelay(100);
548 }
549
550 power1 |= 0x2; /* VMID 500k */
551 wm8510_write(codec, WM8510_POWER1, power1);
538 break; 552 break;
553
539 case SND_SOC_BIAS_OFF: 554 case SND_SOC_BIAS_OFF:
540 /* everything off, dac mute, inactive */ 555 wm8510_write(codec, WM8510_POWER1, 0);
541 wm8510_write(codec, WM8510_POWER1, 0x0); 556 wm8510_write(codec, WM8510_POWER2, 0);
542 wm8510_write(codec, WM8510_POWER2, 0x0); 557 wm8510_write(codec, WM8510_POWER3, 0);
543 wm8510_write(codec, WM8510_POWER3, 0x0);
544 break; 558 break;
545 } 559 }
560
546 codec->bias_level = level; 561 codec->bias_level = level;
547 return 0; 562 return 0;
548} 563}
@@ -640,6 +655,7 @@ static int wm8510_init(struct snd_soc_device *socdev)
640 } 655 }
641 656
642 /* power on device */ 657 /* power on device */
658 codec->bias_level = SND_SOC_BIAS_OFF;
643 wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 659 wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
644 wm8510_add_controls(codec); 660 wm8510_add_controls(codec);
645 wm8510_add_widgets(codec); 661 wm8510_add_widgets(codec);
@@ -665,90 +681,144 @@ static struct snd_soc_device *wm8510_socdev;
665/* 681/*
666 * WM8510 2 wire address is 0x1a 682 * WM8510 2 wire address is 0x1a
667 */ 683 */
668#define I2C_DRIVERID_WM8510 0xfefe /* liam - need a proper id */
669
670static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
671 684
672/* Magic definition of all other variables and things */ 685static int wm8510_i2c_probe(struct i2c_client *i2c,
673I2C_CLIENT_INSMOD; 686 const struct i2c_device_id *id)
674
675static struct i2c_driver wm8510_i2c_driver;
676static struct i2c_client client_template;
677
678/* If the i2c layer weren't so broken, we could pass this kind of data
679 around */
680
681static int wm8510_codec_probe(struct i2c_adapter *adap, int addr, int kind)
682{ 687{
683 struct snd_soc_device *socdev = wm8510_socdev; 688 struct snd_soc_device *socdev = wm8510_socdev;
684 struct wm8510_setup_data *setup = socdev->codec_data;
685 struct snd_soc_codec *codec = socdev->codec; 689 struct snd_soc_codec *codec = socdev->codec;
686 struct i2c_client *i2c;
687 int ret; 690 int ret;
688 691
689 if (addr != setup->i2c_address)
690 return -ENODEV;
691
692 client_template.adapter = adap;
693 client_template.addr = addr;
694
695 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
696 if (i2c == NULL)
697 return -ENOMEM;
698
699 i2c_set_clientdata(i2c, codec); 692 i2c_set_clientdata(i2c, codec);
700 codec->control_data = i2c; 693 codec->control_data = i2c;
701 694
702 ret = i2c_attach_client(i2c);
703 if (ret < 0) {
704 pr_err("failed to attach codec at addr %x\n", addr);
705 goto err;
706 }
707
708 ret = wm8510_init(socdev); 695 ret = wm8510_init(socdev);
709 if (ret < 0) { 696 if (ret < 0)
710 pr_err("failed to initialise WM8510\n"); 697 pr_err("failed to initialise WM8510\n");
711 goto err;
712 }
713 return ret;
714 698
715err:
716 kfree(i2c);
717 return ret; 699 return ret;
718} 700}
719 701
720static int wm8510_i2c_detach(struct i2c_client *client) 702static int wm8510_i2c_remove(struct i2c_client *client)
721{ 703{
722 struct snd_soc_codec *codec = i2c_get_clientdata(client); 704 struct snd_soc_codec *codec = i2c_get_clientdata(client);
723 i2c_detach_client(client);
724 kfree(codec->reg_cache); 705 kfree(codec->reg_cache);
725 kfree(client);
726 return 0; 706 return 0;
727} 707}
728 708
729static int wm8510_i2c_attach(struct i2c_adapter *adap) 709static const struct i2c_device_id wm8510_i2c_id[] = {
730{ 710 { "wm8510", 0 },
731 return i2c_probe(adap, &addr_data, wm8510_codec_probe); 711 { }
732} 712};
713MODULE_DEVICE_TABLE(i2c, wm8510_i2c_id);
733 714
734/* corgi i2c codec control layer */
735static struct i2c_driver wm8510_i2c_driver = { 715static struct i2c_driver wm8510_i2c_driver = {
736 .driver = { 716 .driver = {
737 .name = "WM8510 I2C Codec", 717 .name = "WM8510 I2C Codec",
738 .owner = THIS_MODULE, 718 .owner = THIS_MODULE,
739 }, 719 },
740 .id = I2C_DRIVERID_WM8510, 720 .probe = wm8510_i2c_probe,
741 .attach_adapter = wm8510_i2c_attach, 721 .remove = wm8510_i2c_remove,
742 .detach_client = wm8510_i2c_detach, 722 .id_table = wm8510_i2c_id,
743 .command = NULL,
744}; 723};
745 724
746static struct i2c_client client_template = { 725static int wm8510_add_i2c_device(struct platform_device *pdev,
747 .name = "WM8510", 726 const struct wm8510_setup_data *setup)
748 .driver = &wm8510_i2c_driver, 727{
749}; 728 struct i2c_board_info info;
729 struct i2c_adapter *adapter;
730 struct i2c_client *client;
731 int ret;
732
733 ret = i2c_add_driver(&wm8510_i2c_driver);
734 if (ret != 0) {
735 dev_err(&pdev->dev, "can't add i2c driver\n");
736 return ret;
737 }
738
739 memset(&info, 0, sizeof(struct i2c_board_info));
740 info.addr = setup->i2c_address;
741 strlcpy(info.type, "wm8510", I2C_NAME_SIZE);
742
743 adapter = i2c_get_adapter(setup->i2c_bus);
744 if (!adapter) {
745 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
746 setup->i2c_bus);
747 goto err_driver;
748 }
749
750 client = i2c_new_device(adapter, &info);
751 i2c_put_adapter(adapter);
752 if (!client) {
753 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
754 (unsigned int)info.addr);
755 goto err_driver;
756 }
757
758 return 0;
759
760err_driver:
761 i2c_del_driver(&wm8510_i2c_driver);
762 return -ENODEV;
763}
750#endif 764#endif
751 765
766#if defined(CONFIG_SPI_MASTER)
767static int __devinit wm8510_spi_probe(struct spi_device *spi)
768{
769 struct snd_soc_device *socdev = wm8510_socdev;
770 struct snd_soc_codec *codec = socdev->codec;
771 int ret;
772
773 codec->control_data = spi;
774
775 ret = wm8510_init(socdev);
776 if (ret < 0)
777 dev_err(&spi->dev, "failed to initialise WM8510\n");
778
779 return ret;
780}
781
782static int __devexit wm8510_spi_remove(struct spi_device *spi)
783{
784 return 0;
785}
786
787static struct spi_driver wm8510_spi_driver = {
788 .driver = {
789 .name = "wm8510",
790 .bus = &spi_bus_type,
791 .owner = THIS_MODULE,
792 },
793 .probe = wm8510_spi_probe,
794 .remove = __devexit_p(wm8510_spi_remove),
795};
796
797static int wm8510_spi_write(struct spi_device *spi, const char *data, int len)
798{
799 struct spi_transfer t;
800 struct spi_message m;
801 u8 msg[2];
802
803 if (len <= 0)
804 return 0;
805
806 msg[0] = data[0];
807 msg[1] = data[1];
808
809 spi_message_init(&m);
810 memset(&t, 0, (sizeof t));
811
812 t.tx_buf = &msg[0];
813 t.len = len;
814
815 spi_message_add_tail(&t, &m);
816 spi_sync(spi, &m);
817
818 return len;
819}
820#endif /* CONFIG_SPI_MASTER */
821
752static int wm8510_probe(struct platform_device *pdev) 822static int wm8510_probe(struct platform_device *pdev)
753{ 823{
754 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 824 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
@@ -771,14 +841,17 @@ static int wm8510_probe(struct platform_device *pdev)
771 wm8510_socdev = socdev; 841 wm8510_socdev = socdev;
772#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 842#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
773 if (setup->i2c_address) { 843 if (setup->i2c_address) {
774 normal_i2c[0] = setup->i2c_address;
775 codec->hw_write = (hw_write_t)i2c_master_send; 844 codec->hw_write = (hw_write_t)i2c_master_send;
776 ret = i2c_add_driver(&wm8510_i2c_driver); 845 ret = wm8510_add_i2c_device(pdev, setup);
846 }
847#endif
848#if defined(CONFIG_SPI_MASTER)
849 if (setup->spi) {
850 codec->hw_write = (hw_write_t)wm8510_spi_write;
851 ret = spi_register_driver(&wm8510_spi_driver);
777 if (ret != 0) 852 if (ret != 0)
778 printk(KERN_ERR "can't add i2c driver"); 853 printk(KERN_ERR "can't add spi driver");
779 } 854 }
780#else
781 /* Add other interfaces here */
782#endif 855#endif
783 856
784 if (ret != 0) 857 if (ret != 0)
@@ -798,8 +871,12 @@ static int wm8510_remove(struct platform_device *pdev)
798 snd_soc_free_pcms(socdev); 871 snd_soc_free_pcms(socdev);
799 snd_soc_dapm_free(socdev); 872 snd_soc_dapm_free(socdev);
800#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 873#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
874 i2c_unregister_device(codec->control_data);
801 i2c_del_driver(&wm8510_i2c_driver); 875 i2c_del_driver(&wm8510_i2c_driver);
802#endif 876#endif
877#if defined(CONFIG_SPI_MASTER)
878 spi_unregister_driver(&wm8510_spi_driver);
879#endif
803 kfree(codec); 880 kfree(codec);
804 881
805 return 0; 882 return 0;
diff --git a/sound/soc/codecs/wm8510.h b/sound/soc/codecs/wm8510.h
index f5d2e42eb3f4..bdefcf5c69ff 100644
--- a/sound/soc/codecs/wm8510.h
+++ b/sound/soc/codecs/wm8510.h
@@ -94,6 +94,8 @@
94#define WM8510_MCLKDIV_12 (7 << 5) 94#define WM8510_MCLKDIV_12 (7 << 5)
95 95
96struct wm8510_setup_data { 96struct wm8510_setup_data {
97 int spi;
98 int i2c_bus;
97 unsigned short i2c_address; 99 unsigned short i2c_address;
98}; 100};
99 101
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
new file mode 100644
index 000000000000..627ebfb4209b
--- /dev/null
+++ b/sound/soc/codecs/wm8580.c
@@ -0,0 +1,1053 @@
1/*
2 * wm8580.c -- WM8580 ALSA Soc Audio driver
3 *
4 * Copyright 2008 Wolfson Microelectronics PLC.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 * Notes:
12 * The WM8580 is a multichannel codec with S/PDIF support, featuring six
13 * DAC channels and two ADC channels.
14 *
15 * Currently only the primary audio interface is supported - S/PDIF and
16 * the secondary audio interfaces are not.
17 */
18
19#include <linux/module.h>
20#include <linux/moduleparam.h>
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/delay.h>
24#include <linux/pm.h>
25#include <linux/i2c.h>
26#include <linux/platform_device.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/soc-dapm.h>
32#include <sound/tlv.h>
33#include <sound/initval.h>
34#include <asm/div64.h>
35
36#include "wm8580.h"
37
38#define WM8580_VERSION "0.1"
39
40struct pll_state {
41 unsigned int in;
42 unsigned int out;
43};
44
45/* codec private data */
46struct wm8580_priv {
47 struct pll_state a;
48 struct pll_state b;
49};
50
51/* WM8580 register space */
52#define WM8580_PLLA1 0x00
53#define WM8580_PLLA2 0x01
54#define WM8580_PLLA3 0x02
55#define WM8580_PLLA4 0x03
56#define WM8580_PLLB1 0x04
57#define WM8580_PLLB2 0x05
58#define WM8580_PLLB3 0x06
59#define WM8580_PLLB4 0x07
60#define WM8580_CLKSEL 0x08
61#define WM8580_PAIF1 0x09
62#define WM8580_PAIF2 0x0A
63#define WM8580_SAIF1 0x0B
64#define WM8580_PAIF3 0x0C
65#define WM8580_PAIF4 0x0D
66#define WM8580_SAIF2 0x0E
67#define WM8580_DAC_CONTROL1 0x0F
68#define WM8580_DAC_CONTROL2 0x10
69#define WM8580_DAC_CONTROL3 0x11
70#define WM8580_DAC_CONTROL4 0x12
71#define WM8580_DAC_CONTROL5 0x13
72#define WM8580_DIGITAL_ATTENUATION_DACL1 0x14
73#define WM8580_DIGITAL_ATTENUATION_DACR1 0x15
74#define WM8580_DIGITAL_ATTENUATION_DACL2 0x16
75#define WM8580_DIGITAL_ATTENUATION_DACR2 0x17
76#define WM8580_DIGITAL_ATTENUATION_DACL3 0x18
77#define WM8580_DIGITAL_ATTENUATION_DACR3 0x19
78#define WM8580_MASTER_DIGITAL_ATTENUATION 0x1C
79#define WM8580_ADC_CONTROL1 0x1D
80#define WM8580_SPDTXCHAN0 0x1E
81#define WM8580_SPDTXCHAN1 0x1F
82#define WM8580_SPDTXCHAN2 0x20
83#define WM8580_SPDTXCHAN3 0x21
84#define WM8580_SPDTXCHAN4 0x22
85#define WM8580_SPDTXCHAN5 0x23
86#define WM8580_SPDMODE 0x24
87#define WM8580_INTMASK 0x25
88#define WM8580_GPO1 0x26
89#define WM8580_GPO2 0x27
90#define WM8580_GPO3 0x28
91#define WM8580_GPO4 0x29
92#define WM8580_GPO5 0x2A
93#define WM8580_INTSTAT 0x2B
94#define WM8580_SPDRXCHAN1 0x2C
95#define WM8580_SPDRXCHAN2 0x2D
96#define WM8580_SPDRXCHAN3 0x2E
97#define WM8580_SPDRXCHAN4 0x2F
98#define WM8580_SPDRXCHAN5 0x30
99#define WM8580_SPDSTAT 0x31
100#define WM8580_PWRDN1 0x32
101#define WM8580_PWRDN2 0x33
102#define WM8580_READBACK 0x34
103#define WM8580_RESET 0x35
104
105/* PLLB4 (register 7h) */
106#define WM8580_PLLB4_MCLKOUTSRC_MASK 0x60
107#define WM8580_PLLB4_MCLKOUTSRC_PLLA 0x20
108#define WM8580_PLLB4_MCLKOUTSRC_PLLB 0x40
109#define WM8580_PLLB4_MCLKOUTSRC_OSC 0x60
110
111#define WM8580_PLLB4_CLKOUTSRC_MASK 0x180
112#define WM8580_PLLB4_CLKOUTSRC_PLLACLK 0x080
113#define WM8580_PLLB4_CLKOUTSRC_PLLBCLK 0x100
114#define WM8580_PLLB4_CLKOUTSRC_OSCCLK 0x180
115
116/* CLKSEL (register 8h) */
117#define WM8580_CLKSEL_DAC_CLKSEL_MASK 0x03
118#define WM8580_CLKSEL_DAC_CLKSEL_PLLA 0x01
119#define WM8580_CLKSEL_DAC_CLKSEL_PLLB 0x02
120
121/* AIF control 1 (registers 9h-bh) */
122#define WM8580_AIF_RATE_MASK 0x7
123#define WM8580_AIF_RATE_128 0x0
124#define WM8580_AIF_RATE_192 0x1
125#define WM8580_AIF_RATE_256 0x2
126#define WM8580_AIF_RATE_384 0x3
127#define WM8580_AIF_RATE_512 0x4
128#define WM8580_AIF_RATE_768 0x5
129#define WM8580_AIF_RATE_1152 0x6
130
131#define WM8580_AIF_BCLKSEL_MASK 0x18
132#define WM8580_AIF_BCLKSEL_64 0x00
133#define WM8580_AIF_BCLKSEL_128 0x08
134#define WM8580_AIF_BCLKSEL_256 0x10
135#define WM8580_AIF_BCLKSEL_SYSCLK 0x18
136
137#define WM8580_AIF_MS 0x20
138
139#define WM8580_AIF_CLKSRC_MASK 0xc0
140#define WM8580_AIF_CLKSRC_PLLA 0x40
141#define WM8580_AIF_CLKSRC_PLLB 0x40
142#define WM8580_AIF_CLKSRC_MCLK 0xc0
143
144/* AIF control 2 (registers ch-eh) */
145#define WM8580_AIF_FMT_MASK 0x03
146#define WM8580_AIF_FMT_RIGHTJ 0x00
147#define WM8580_AIF_FMT_LEFTJ 0x01
148#define WM8580_AIF_FMT_I2S 0x02
149#define WM8580_AIF_FMT_DSP 0x03
150
151#define WM8580_AIF_LENGTH_MASK 0x0c
152#define WM8580_AIF_LENGTH_16 0x00
153#define WM8580_AIF_LENGTH_20 0x04
154#define WM8580_AIF_LENGTH_24 0x08
155#define WM8580_AIF_LENGTH_32 0x0c
156
157#define WM8580_AIF_LRP 0x10
158#define WM8580_AIF_BCP 0x20
159
160/* Powerdown Register 1 (register 32h) */
161#define WM8580_PWRDN1_PWDN 0x001
162#define WM8580_PWRDN1_ALLDACPD 0x040
163
164/* Powerdown Register 2 (register 33h) */
165#define WM8580_PWRDN2_OSSCPD 0x001
166#define WM8580_PWRDN2_PLLAPD 0x002
167#define WM8580_PWRDN2_PLLBPD 0x004
168#define WM8580_PWRDN2_SPDIFPD 0x008
169#define WM8580_PWRDN2_SPDIFTXD 0x010
170#define WM8580_PWRDN2_SPDIFRXD 0x020
171
172#define WM8580_DAC_CONTROL5_MUTEALL 0x10
173
174/*
175 * wm8580 register cache
176 * We can't read the WM8580 register space when we
177 * are using 2 wire for device control, so we cache them instead.
178 */
179static const u16 wm8580_reg[] = {
180 0x0121, 0x017e, 0x007d, 0x0014, /*R3*/
181 0x0121, 0x017e, 0x007d, 0x0194, /*R7*/
182 0x001c, 0x0002, 0x0002, 0x00c2, /*R11*/
183 0x0182, 0x0082, 0x000a, 0x0024, /*R15*/
184 0x0009, 0x0000, 0x00ff, 0x0000, /*R19*/
185 0x00ff, 0x00ff, 0x00ff, 0x00ff, /*R23*/
186 0x00ff, 0x00ff, 0x00ff, 0x00ff, /*R27*/
187 0x01f0, 0x0040, 0x0000, 0x0000, /*R31(0x1F)*/
188 0x0000, 0x0000, 0x0031, 0x000b, /*R35*/
189 0x0039, 0x0000, 0x0010, 0x0032, /*R39*/
190 0x0054, 0x0076, 0x0098, 0x0000, /*R43(0x2B)*/
191 0x0000, 0x0000, 0x0000, 0x0000, /*R47*/
192 0x0000, 0x0000, 0x005e, 0x003e, /*R51(0x33)*/
193 0x0000, 0x0000 /*R53*/
194};
195
196/*
197 * read wm8580 register cache
198 */
199static inline unsigned int wm8580_read_reg_cache(struct snd_soc_codec *codec,
200 unsigned int reg)
201{
202 u16 *cache = codec->reg_cache;
203 BUG_ON(reg > ARRAY_SIZE(wm8580_reg));
204 return cache[reg];
205}
206
207/*
208 * write wm8580 register cache
209 */
210static inline void wm8580_write_reg_cache(struct snd_soc_codec *codec,
211 unsigned int reg, unsigned int value)
212{
213 u16 *cache = codec->reg_cache;
214
215 cache[reg] = value;
216}
217
218/*
219 * write to the WM8580 register space
220 */
221static int wm8580_write(struct snd_soc_codec *codec, unsigned int reg,
222 unsigned int value)
223{
224 u8 data[2];
225
226 BUG_ON(reg > ARRAY_SIZE(wm8580_reg));
227
228 /* Registers are 9 bits wide */
229 value &= 0x1ff;
230
231 switch (reg) {
232 case WM8580_RESET:
233 /* Uncached */
234 break;
235 default:
236 if (value == wm8580_read_reg_cache(codec, reg))
237 return 0;
238 }
239
240 /* data is
241 * D15..D9 WM8580 register offset
242 * D8...D0 register data
243 */
244 data[0] = (reg << 1) | ((value >> 8) & 0x0001);
245 data[1] = value & 0x00ff;
246
247 wm8580_write_reg_cache(codec, reg, value);
248 if (codec->hw_write(codec->control_data, data, 2) == 2)
249 return 0;
250 else
251 return -EIO;
252}
253
254static inline unsigned int wm8580_read(struct snd_soc_codec *codec,
255 unsigned int reg)
256{
257 switch (reg) {
258 default:
259 return wm8580_read_reg_cache(codec, reg);
260 }
261}
262
263static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1);
264
265static int wm8580_out_vu(struct snd_kcontrol *kcontrol,
266 struct snd_ctl_elem_value *ucontrol)
267{
268 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
269 int reg = kcontrol->private_value & 0xff;
270 int reg2 = (kcontrol->private_value >> 24) & 0xff;
271 int ret;
272 u16 val;
273
274 /* Clear the register cache so we write without VU set */
275 wm8580_write_reg_cache(codec, reg, 0);
276 wm8580_write_reg_cache(codec, reg2, 0);
277
278 ret = snd_soc_put_volsw_2r(kcontrol, ucontrol);
279 if (ret < 0)
280 return ret;
281
282 /* Now write again with the volume update bit set */
283 val = wm8580_read_reg_cache(codec, reg);
284 wm8580_write(codec, reg, val | 0x0100);
285
286 val = wm8580_read_reg_cache(codec, reg2);
287 wm8580_write(codec, reg2, val | 0x0100);
288
289 return 0;
290}
291
292#define SOC_WM8580_OUT_DOUBLE_R_TLV(xname, reg_left, reg_right, shift, max, invert, tlv_array) \
293{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
294 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
295 SNDRV_CTL_ELEM_ACCESS_READWRITE, \
296 .tlv.p = (tlv_array), \
297 .info = snd_soc_info_volsw_2r, \
298 .get = snd_soc_get_volsw_2r, .put = wm8580_out_vu, \
299 .private_value = (reg_left) | ((shift) << 8) | \
300 ((max) << 12) | ((invert) << 20) | ((reg_right) << 24) }
301
302static const struct snd_kcontrol_new wm8580_snd_controls[] = {
303SOC_WM8580_OUT_DOUBLE_R_TLV("DAC1 Playback Volume",
304 WM8580_DIGITAL_ATTENUATION_DACL1,
305 WM8580_DIGITAL_ATTENUATION_DACR1,
306 0, 0xff, 0, dac_tlv),
307SOC_WM8580_OUT_DOUBLE_R_TLV("DAC2 Playback Volume",
308 WM8580_DIGITAL_ATTENUATION_DACL2,
309 WM8580_DIGITAL_ATTENUATION_DACR2,
310 0, 0xff, 0, dac_tlv),
311SOC_WM8580_OUT_DOUBLE_R_TLV("DAC3 Playback Volume",
312 WM8580_DIGITAL_ATTENUATION_DACL3,
313 WM8580_DIGITAL_ATTENUATION_DACR3,
314 0, 0xff, 0, dac_tlv),
315
316SOC_SINGLE("DAC1 Deemphasis Switch", WM8580_DAC_CONTROL3, 0, 1, 0),
317SOC_SINGLE("DAC2 Deemphasis Switch", WM8580_DAC_CONTROL3, 1, 1, 0),
318SOC_SINGLE("DAC3 Deemphasis Switch", WM8580_DAC_CONTROL3, 2, 1, 0),
319
320SOC_DOUBLE("DAC1 Invert Switch", WM8580_DAC_CONTROL4, 0, 1, 1, 0),
321SOC_DOUBLE("DAC2 Invert Switch", WM8580_DAC_CONTROL4, 2, 3, 1, 0),
322SOC_DOUBLE("DAC3 Invert Switch", WM8580_DAC_CONTROL4, 4, 5, 1, 0),
323
324SOC_SINGLE("DAC ZC Switch", WM8580_DAC_CONTROL5, 5, 1, 0),
325SOC_SINGLE("DAC1 Switch", WM8580_DAC_CONTROL5, 0, 1, 0),
326SOC_SINGLE("DAC2 Switch", WM8580_DAC_CONTROL5, 1, 1, 0),
327SOC_SINGLE("DAC3 Switch", WM8580_DAC_CONTROL5, 2, 1, 0),
328
329SOC_DOUBLE("ADC Mute Switch", WM8580_ADC_CONTROL1, 0, 1, 1, 0),
330SOC_SINGLE("ADC High-Pass Filter Switch", WM8580_ADC_CONTROL1, 4, 1, 0),
331};
332
333/* Add non-DAPM controls */
334static int wm8580_add_controls(struct snd_soc_codec *codec)
335{
336 int err, i;
337
338 for (i = 0; i < ARRAY_SIZE(wm8580_snd_controls); i++) {
339 err = snd_ctl_add(codec->card,
340 snd_soc_cnew(&wm8580_snd_controls[i],
341 codec, NULL));
342 if (err < 0)
343 return err;
344 }
345 return 0;
346}
347static const struct snd_soc_dapm_widget wm8580_dapm_widgets[] = {
348SND_SOC_DAPM_DAC("DAC1", "Playback", WM8580_PWRDN1, 2, 1),
349SND_SOC_DAPM_DAC("DAC2", "Playback", WM8580_PWRDN1, 3, 1),
350SND_SOC_DAPM_DAC("DAC3", "Playback", WM8580_PWRDN1, 4, 1),
351
352SND_SOC_DAPM_OUTPUT("VOUT1L"),
353SND_SOC_DAPM_OUTPUT("VOUT1R"),
354SND_SOC_DAPM_OUTPUT("VOUT2L"),
355SND_SOC_DAPM_OUTPUT("VOUT2R"),
356SND_SOC_DAPM_OUTPUT("VOUT3L"),
357SND_SOC_DAPM_OUTPUT("VOUT3R"),
358
359SND_SOC_DAPM_ADC("ADC", "Capture", WM8580_PWRDN1, 1, 1),
360
361SND_SOC_DAPM_INPUT("AINL"),
362SND_SOC_DAPM_INPUT("AINR"),
363};
364
365static const struct snd_soc_dapm_route audio_map[] = {
366 { "VOUT1L", NULL, "DAC1" },
367 { "VOUT1R", NULL, "DAC1" },
368
369 { "VOUT2L", NULL, "DAC2" },
370 { "VOUT2R", NULL, "DAC2" },
371
372 { "VOUT3L", NULL, "DAC3" },
373 { "VOUT3R", NULL, "DAC3" },
374
375 { "ADC", NULL, "AINL" },
376 { "ADC", NULL, "AINR" },
377};
378
379static int wm8580_add_widgets(struct snd_soc_codec *codec)
380{
381 snd_soc_dapm_new_controls(codec, wm8580_dapm_widgets,
382 ARRAY_SIZE(wm8580_dapm_widgets));
383
384 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
385
386 snd_soc_dapm_new_widgets(codec);
387 return 0;
388}
389
390/* PLL divisors */
391struct _pll_div {
392 u32 prescale:1;
393 u32 postscale:1;
394 u32 freqmode:2;
395 u32 n:4;
396 u32 k:24;
397};
398
399/* The size in bits of the pll divide */
400#define FIXED_PLL_SIZE (1 << 22)
401
402/* PLL rate to output rate divisions */
403static struct {
404 unsigned int div;
405 unsigned int freqmode;
406 unsigned int postscale;
407} post_table[] = {
408 { 2, 0, 0 },
409 { 4, 0, 1 },
410 { 4, 1, 0 },
411 { 8, 1, 1 },
412 { 8, 2, 0 },
413 { 16, 2, 1 },
414 { 12, 3, 0 },
415 { 24, 3, 1 }
416};
417
418static int pll_factors(struct _pll_div *pll_div, unsigned int target,
419 unsigned int source)
420{
421 u64 Kpart;
422 unsigned int K, Ndiv, Nmod;
423 int i;
424
425 pr_debug("wm8580: PLL %dHz->%dHz\n", source, target);
426
427 /* Scale the output frequency up; the PLL should run in the
428 * region of 90-100MHz.
429 */
430 for (i = 0; i < ARRAY_SIZE(post_table); i++) {
431 if (target * post_table[i].div >= 90000000 &&
432 target * post_table[i].div <= 100000000) {
433 pll_div->freqmode = post_table[i].freqmode;
434 pll_div->postscale = post_table[i].postscale;
435 target *= post_table[i].div;
436 break;
437 }
438 }
439
440 if (i == ARRAY_SIZE(post_table)) {
441 printk(KERN_ERR "wm8580: Unable to scale output frequency "
442 "%u\n", target);
443 return -EINVAL;
444 }
445
446 Ndiv = target / source;
447
448 if (Ndiv < 5) {
449 source /= 2;
450 pll_div->prescale = 1;
451 Ndiv = target / source;
452 } else
453 pll_div->prescale = 0;
454
455 if ((Ndiv < 5) || (Ndiv > 13)) {
456 printk(KERN_ERR
457 "WM8580 N=%d outside supported range\n", Ndiv);
458 return -EINVAL;
459 }
460
461 pll_div->n = Ndiv;
462 Nmod = target % source;
463 Kpart = FIXED_PLL_SIZE * (long long)Nmod;
464
465 do_div(Kpart, source);
466
467 K = Kpart & 0xFFFFFFFF;
468
469 pll_div->k = K;
470
471 pr_debug("PLL %x.%x prescale %d freqmode %d postscale %d\n",
472 pll_div->n, pll_div->k, pll_div->prescale, pll_div->freqmode,
473 pll_div->postscale);
474
475 return 0;
476}
477
478static int wm8580_set_dai_pll(struct snd_soc_dai *codec_dai,
479 int pll_id, unsigned int freq_in, unsigned int freq_out)
480{
481 int offset;
482 struct snd_soc_codec *codec = codec_dai->codec;
483 struct wm8580_priv *wm8580 = codec->private_data;
484 struct pll_state *state;
485 struct _pll_div pll_div;
486 unsigned int reg;
487 unsigned int pwr_mask;
488 int ret;
489
490 /* GCC isn't able to work out the ifs below for initialising/using
491 * pll_div so suppress warnings.
492 */
493 memset(&pll_div, 0, sizeof(pll_div));
494
495 switch (pll_id) {
496 case WM8580_PLLA:
497 state = &wm8580->a;
498 offset = 0;
499 pwr_mask = WM8580_PWRDN2_PLLAPD;
500 break;
501 case WM8580_PLLB:
502 state = &wm8580->b;
503 offset = 4;
504 pwr_mask = WM8580_PWRDN2_PLLBPD;
505 break;
506 default:
507 return -ENODEV;
508 }
509
510 if (freq_in && freq_out) {
511 ret = pll_factors(&pll_div, freq_out, freq_in);
512 if (ret != 0)
513 return ret;
514 }
515
516 state->in = freq_in;
517 state->out = freq_out;
518
519 /* Always disable the PLL - it is not safe to leave it running
520 * while reprogramming it.
521 */
522 reg = wm8580_read(codec, WM8580_PWRDN2);
523 wm8580_write(codec, WM8580_PWRDN2, reg | pwr_mask);
524
525 if (!freq_in || !freq_out)
526 return 0;
527
528 wm8580_write(codec, WM8580_PLLA1 + offset, pll_div.k & 0x1ff);
529 wm8580_write(codec, WM8580_PLLA2 + offset, (pll_div.k >> 9) & 0xff);
530 wm8580_write(codec, WM8580_PLLA3 + offset,
531 (pll_div.k >> 18 & 0xf) | (pll_div.n << 4));
532
533 reg = wm8580_read(codec, WM8580_PLLA4 + offset);
534 reg &= ~0x3f;
535 reg |= pll_div.prescale | pll_div.postscale << 1 |
536 pll_div.freqmode << 4;
537
538 wm8580_write(codec, WM8580_PLLA4 + offset, reg);
539
540 /* All done, turn it on */
541 reg = wm8580_read(codec, WM8580_PWRDN2);
542 wm8580_write(codec, WM8580_PWRDN2, reg & ~pwr_mask);
543
544 return 0;
545}
546
547/*
548 * Set PCM DAI bit size and sample rate.
549 */
550static int wm8580_paif_hw_params(struct snd_pcm_substream *substream,
551 struct snd_pcm_hw_params *params)
552{
553 struct snd_soc_pcm_runtime *rtd = substream->private_data;
554 struct snd_soc_dai_link *dai = rtd->dai;
555 struct snd_soc_device *socdev = rtd->socdev;
556 struct snd_soc_codec *codec = socdev->codec;
557 u16 paifb = wm8580_read(codec, WM8580_PAIF3 + dai->codec_dai->id);
558
559 paifb &= ~WM8580_AIF_LENGTH_MASK;
560 /* bit size */
561 switch (params_format(params)) {
562 case SNDRV_PCM_FORMAT_S16_LE:
563 break;
564 case SNDRV_PCM_FORMAT_S20_3LE:
565 paifb |= WM8580_AIF_LENGTH_20;
566 break;
567 case SNDRV_PCM_FORMAT_S24_LE:
568 paifb |= WM8580_AIF_LENGTH_24;
569 break;
570 case SNDRV_PCM_FORMAT_S32_LE:
571 paifb |= WM8580_AIF_LENGTH_24;
572 break;
573 default:
574 return -EINVAL;
575 }
576
577 wm8580_write(codec, WM8580_PAIF3 + dai->codec_dai->id, paifb);
578 return 0;
579}
580
581static int wm8580_set_paif_dai_fmt(struct snd_soc_dai *codec_dai,
582 unsigned int fmt)
583{
584 struct snd_soc_codec *codec = codec_dai->codec;
585 unsigned int aifa;
586 unsigned int aifb;
587 int can_invert_lrclk;
588
589 aifa = wm8580_read(codec, WM8580_PAIF1 + codec_dai->id);
590 aifb = wm8580_read(codec, WM8580_PAIF3 + codec_dai->id);
591
592 aifb &= ~(WM8580_AIF_FMT_MASK | WM8580_AIF_LRP | WM8580_AIF_BCP);
593
594 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
595 case SND_SOC_DAIFMT_CBS_CFS:
596 aifa &= ~WM8580_AIF_MS;
597 break;
598 case SND_SOC_DAIFMT_CBM_CFM:
599 aifa |= WM8580_AIF_MS;
600 break;
601 default:
602 return -EINVAL;
603 }
604
605 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
606 case SND_SOC_DAIFMT_I2S:
607 can_invert_lrclk = 1;
608 aifb |= WM8580_AIF_FMT_I2S;
609 break;
610 case SND_SOC_DAIFMT_RIGHT_J:
611 can_invert_lrclk = 1;
612 aifb |= WM8580_AIF_FMT_RIGHTJ;
613 break;
614 case SND_SOC_DAIFMT_LEFT_J:
615 can_invert_lrclk = 1;
616 aifb |= WM8580_AIF_FMT_LEFTJ;
617 break;
618 case SND_SOC_DAIFMT_DSP_A:
619 can_invert_lrclk = 0;
620 aifb |= WM8580_AIF_FMT_DSP;
621 break;
622 case SND_SOC_DAIFMT_DSP_B:
623 can_invert_lrclk = 0;
624 aifb |= WM8580_AIF_FMT_DSP;
625 aifb |= WM8580_AIF_LRP;
626 break;
627 default:
628 return -EINVAL;
629 }
630
631 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
632 case SND_SOC_DAIFMT_NB_NF:
633 break;
634
635 case SND_SOC_DAIFMT_IB_IF:
636 if (!can_invert_lrclk)
637 return -EINVAL;
638 aifb |= WM8580_AIF_BCP;
639 aifb |= WM8580_AIF_LRP;
640 break;
641
642 case SND_SOC_DAIFMT_IB_NF:
643 aifb |= WM8580_AIF_BCP;
644 break;
645
646 case SND_SOC_DAIFMT_NB_IF:
647 if (!can_invert_lrclk)
648 return -EINVAL;
649 aifb |= WM8580_AIF_LRP;
650 break;
651
652 default:
653 return -EINVAL;
654 }
655
656 wm8580_write(codec, WM8580_PAIF1 + codec_dai->id, aifa);
657 wm8580_write(codec, WM8580_PAIF3 + codec_dai->id, aifb);
658
659 return 0;
660}
661
662static int wm8580_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
663 int div_id, int div)
664{
665 struct snd_soc_codec *codec = codec_dai->codec;
666 unsigned int reg;
667
668 switch (div_id) {
669 case WM8580_MCLK:
670 reg = wm8580_read(codec, WM8580_PLLB4);
671 reg &= ~WM8580_PLLB4_MCLKOUTSRC_MASK;
672
673 switch (div) {
674 case WM8580_CLKSRC_MCLK:
675 /* Input */
676 break;
677
678 case WM8580_CLKSRC_PLLA:
679 reg |= WM8580_PLLB4_MCLKOUTSRC_PLLA;
680 break;
681 case WM8580_CLKSRC_PLLB:
682 reg |= WM8580_PLLB4_MCLKOUTSRC_PLLB;
683 break;
684
685 case WM8580_CLKSRC_OSC:
686 reg |= WM8580_PLLB4_MCLKOUTSRC_OSC;
687 break;
688
689 default:
690 return -EINVAL;
691 }
692 wm8580_write(codec, WM8580_PLLB4, reg);
693 break;
694
695 case WM8580_DAC_CLKSEL:
696 reg = wm8580_read(codec, WM8580_CLKSEL);
697 reg &= ~WM8580_CLKSEL_DAC_CLKSEL_MASK;
698
699 switch (div) {
700 case WM8580_CLKSRC_MCLK:
701 break;
702
703 case WM8580_CLKSRC_PLLA:
704 reg |= WM8580_CLKSEL_DAC_CLKSEL_PLLA;
705 break;
706
707 case WM8580_CLKSRC_PLLB:
708 reg |= WM8580_CLKSEL_DAC_CLKSEL_PLLB;
709 break;
710
711 default:
712 return -EINVAL;
713 }
714 wm8580_write(codec, WM8580_CLKSEL, reg);
715 break;
716
717 case WM8580_CLKOUTSRC:
718 reg = wm8580_read(codec, WM8580_PLLB4);
719 reg &= ~WM8580_PLLB4_CLKOUTSRC_MASK;
720
721 switch (div) {
722 case WM8580_CLKSRC_NONE:
723 break;
724
725 case WM8580_CLKSRC_PLLA:
726 reg |= WM8580_PLLB4_CLKOUTSRC_PLLACLK;
727 break;
728
729 case WM8580_CLKSRC_PLLB:
730 reg |= WM8580_PLLB4_CLKOUTSRC_PLLBCLK;
731 break;
732
733 case WM8580_CLKSRC_OSC:
734 reg |= WM8580_PLLB4_CLKOUTSRC_OSCCLK;
735 break;
736
737 default:
738 return -EINVAL;
739 }
740 wm8580_write(codec, WM8580_PLLB4, reg);
741 break;
742
743 default:
744 return -EINVAL;
745 }
746
747 return 0;
748}
749
750static int wm8580_digital_mute(struct snd_soc_dai *codec_dai, int mute)
751{
752 struct snd_soc_codec *codec = codec_dai->codec;
753 unsigned int reg;
754
755 reg = wm8580_read(codec, WM8580_DAC_CONTROL5);
756
757 if (mute)
758 reg |= WM8580_DAC_CONTROL5_MUTEALL;
759 else
760 reg &= ~WM8580_DAC_CONTROL5_MUTEALL;
761
762 wm8580_write(codec, WM8580_DAC_CONTROL5, reg);
763
764 return 0;
765}
766
767static int wm8580_set_bias_level(struct snd_soc_codec *codec,
768 enum snd_soc_bias_level level)
769{
770 u16 reg;
771 switch (level) {
772 case SND_SOC_BIAS_ON:
773 case SND_SOC_BIAS_PREPARE:
774 case SND_SOC_BIAS_STANDBY:
775 break;
776 case SND_SOC_BIAS_OFF:
777 reg = wm8580_read(codec, WM8580_PWRDN1);
778 wm8580_write(codec, WM8580_PWRDN1, reg | WM8580_PWRDN1_PWDN);
779 break;
780 }
781 codec->bias_level = level;
782 return 0;
783}
784
785#define WM8580_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
786 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
787
788struct snd_soc_dai wm8580_dai[] = {
789 {
790 .name = "WM8580 PAIFRX",
791 .id = 0,
792 .playback = {
793 .stream_name = "Playback",
794 .channels_min = 1,
795 .channels_max = 6,
796 .rates = SNDRV_PCM_RATE_8000_192000,
797 .formats = WM8580_FORMATS,
798 },
799 .ops = {
800 .hw_params = wm8580_paif_hw_params,
801 },
802 .dai_ops = {
803 .set_fmt = wm8580_set_paif_dai_fmt,
804 .set_clkdiv = wm8580_set_dai_clkdiv,
805 .set_pll = wm8580_set_dai_pll,
806 .digital_mute = wm8580_digital_mute,
807 },
808 },
809 {
810 .name = "WM8580 PAIFTX",
811 .id = 1,
812 .capture = {
813 .stream_name = "Capture",
814 .channels_min = 2,
815 .channels_max = 2,
816 .rates = SNDRV_PCM_RATE_8000_192000,
817 .formats = WM8580_FORMATS,
818 },
819 .ops = {
820 .hw_params = wm8580_paif_hw_params,
821 },
822 .dai_ops = {
823 .set_fmt = wm8580_set_paif_dai_fmt,
824 .set_clkdiv = wm8580_set_dai_clkdiv,
825 .set_pll = wm8580_set_dai_pll,
826 },
827 },
828};
829EXPORT_SYMBOL_GPL(wm8580_dai);
830
831/*
832 * initialise the WM8580 driver
833 * register the mixer and dsp interfaces with the kernel
834 */
835static int wm8580_init(struct snd_soc_device *socdev)
836{
837 struct snd_soc_codec *codec = socdev->codec;
838 int ret = 0;
839
840 codec->name = "WM8580";
841 codec->owner = THIS_MODULE;
842 codec->read = wm8580_read_reg_cache;
843 codec->write = wm8580_write;
844 codec->set_bias_level = wm8580_set_bias_level;
845 codec->dai = wm8580_dai;
846 codec->num_dai = ARRAY_SIZE(wm8580_dai);
847 codec->reg_cache_size = ARRAY_SIZE(wm8580_reg);
848 codec->reg_cache = kmemdup(wm8580_reg, sizeof(wm8580_reg),
849 GFP_KERNEL);
850
851 if (codec->reg_cache == NULL)
852 return -ENOMEM;
853
854 /* Get the codec into a known state */
855 wm8580_write(codec, WM8580_RESET, 0);
856
857 /* Power up and get individual control of the DACs */
858 wm8580_write(codec, WM8580_PWRDN1, wm8580_read(codec, WM8580_PWRDN1) &
859 ~(WM8580_PWRDN1_PWDN | WM8580_PWRDN1_ALLDACPD));
860
861 /* Make VMID high impedence */
862 wm8580_write(codec, WM8580_ADC_CONTROL1,
863 wm8580_read(codec, WM8580_ADC_CONTROL1) & ~0x100);
864
865 /* register pcms */
866 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1,
867 SNDRV_DEFAULT_STR1);
868 if (ret < 0) {
869 printk(KERN_ERR "wm8580: failed to create pcms\n");
870 goto pcm_err;
871 }
872
873 wm8580_add_controls(codec);
874 wm8580_add_widgets(codec);
875
876 ret = snd_soc_register_card(socdev);
877 if (ret < 0) {
878 printk(KERN_ERR "wm8580: failed to register card\n");
879 goto card_err;
880 }
881 return ret;
882
883card_err:
884 snd_soc_free_pcms(socdev);
885 snd_soc_dapm_free(socdev);
886pcm_err:
887 kfree(codec->reg_cache);
888 return ret;
889}
890
891/* If the i2c layer weren't so broken, we could pass this kind of data
892 around */
893static struct snd_soc_device *wm8580_socdev;
894
895#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
896
897/*
898 * WM8580 2 wire address is determined by GPIO5
899 * state during powerup.
900 * low = 0x1a
901 * high = 0x1b
902 */
903static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
904
905/* Magic definition of all other variables and things */
906I2C_CLIENT_INSMOD;
907
908static struct i2c_driver wm8580_i2c_driver;
909static struct i2c_client client_template;
910
911static int wm8580_codec_probe(struct i2c_adapter *adap, int addr, int kind)
912{
913 struct snd_soc_device *socdev = wm8580_socdev;
914 struct wm8580_setup_data *setup = socdev->codec_data;
915 struct snd_soc_codec *codec = socdev->codec;
916 struct i2c_client *i2c;
917 int ret;
918
919 if (addr != setup->i2c_address)
920 return -ENODEV;
921
922 client_template.adapter = adap;
923 client_template.addr = addr;
924
925 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
926 if (i2c == NULL) {
927 kfree(codec);
928 return -ENOMEM;
929 }
930 i2c_set_clientdata(i2c, codec);
931 codec->control_data = i2c;
932
933 ret = i2c_attach_client(i2c);
934 if (ret < 0) {
935 dev_err(&i2c->dev, "failed to attach codec at addr %x\n", addr);
936 goto err;
937 }
938
939 ret = wm8580_init(socdev);
940 if (ret < 0) {
941 dev_err(&i2c->dev, "failed to initialise WM8580\n");
942 goto err;
943 }
944
945 return ret;
946
947err:
948 kfree(codec);
949 kfree(i2c);
950 return ret;
951}
952
953static int wm8580_i2c_detach(struct i2c_client *client)
954{
955 struct snd_soc_codec *codec = i2c_get_clientdata(client);
956 i2c_detach_client(client);
957 kfree(codec->reg_cache);
958 kfree(client);
959 return 0;
960}
961
962static int wm8580_i2c_attach(struct i2c_adapter *adap)
963{
964 return i2c_probe(adap, &addr_data, wm8580_codec_probe);
965}
966
967/* corgi i2c codec control layer */
968static struct i2c_driver wm8580_i2c_driver = {
969 .driver = {
970 .name = "WM8580 I2C Codec",
971 .owner = THIS_MODULE,
972 },
973 .attach_adapter = wm8580_i2c_attach,
974 .detach_client = wm8580_i2c_detach,
975 .command = NULL,
976};
977
978static struct i2c_client client_template = {
979 .name = "WM8580",
980 .driver = &wm8580_i2c_driver,
981};
982#endif
983
984static int wm8580_probe(struct platform_device *pdev)
985{
986 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
987 struct wm8580_setup_data *setup;
988 struct snd_soc_codec *codec;
989 struct wm8580_priv *wm8580;
990 int ret = 0;
991
992 pr_info("WM8580 Audio Codec %s\n", WM8580_VERSION);
993
994 setup = socdev->codec_data;
995 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
996 if (codec == NULL)
997 return -ENOMEM;
998
999 wm8580 = kzalloc(sizeof(struct wm8580_priv), GFP_KERNEL);
1000 if (wm8580 == NULL) {
1001 kfree(codec);
1002 return -ENOMEM;
1003 }
1004
1005 codec->private_data = wm8580;
1006 socdev->codec = codec;
1007 mutex_init(&codec->mutex);
1008 INIT_LIST_HEAD(&codec->dapm_widgets);
1009 INIT_LIST_HEAD(&codec->dapm_paths);
1010 wm8580_socdev = socdev;
1011
1012#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1013 if (setup->i2c_address) {
1014 normal_i2c[0] = setup->i2c_address;
1015 codec->hw_write = (hw_write_t)i2c_master_send;
1016 ret = i2c_add_driver(&wm8580_i2c_driver);
1017 if (ret != 0)
1018 printk(KERN_ERR "can't add i2c driver");
1019 }
1020#else
1021 /* Add other interfaces here */
1022#endif
1023 return ret;
1024}
1025
1026/* power down chip */
1027static int wm8580_remove(struct platform_device *pdev)
1028{
1029 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1030 struct snd_soc_codec *codec = socdev->codec;
1031
1032 if (codec->control_data)
1033 wm8580_set_bias_level(codec, SND_SOC_BIAS_OFF);
1034 snd_soc_free_pcms(socdev);
1035 snd_soc_dapm_free(socdev);
1036#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1037 i2c_del_driver(&wm8580_i2c_driver);
1038#endif
1039 kfree(codec->private_data);
1040 kfree(codec);
1041
1042 return 0;
1043}
1044
1045struct snd_soc_codec_device soc_codec_dev_wm8580 = {
1046 .probe = wm8580_probe,
1047 .remove = wm8580_remove,
1048};
1049EXPORT_SYMBOL_GPL(soc_codec_dev_wm8580);
1050
1051MODULE_DESCRIPTION("ASoC WM8580 driver");
1052MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
1053MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8580.h b/sound/soc/codecs/wm8580.h
new file mode 100644
index 000000000000..589ddaba21d7
--- /dev/null
+++ b/sound/soc/codecs/wm8580.h
@@ -0,0 +1,42 @@
1/*
2 * wm8580.h -- audio driver for WM8580
3 *
4 * Copyright 2008 Samsung Electronics.
5 * Author: Ryu Euiyoul
6 * ryu.real@gmail.com
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 */
14
15#ifndef _WM8580_H
16#define _WM8580_H
17
18#define WM8580_PLLA 1
19#define WM8580_PLLB 2
20
21#define WM8580_MCLK 1
22#define WM8580_DAC_CLKSEL 2
23#define WM8580_CLKOUTSRC 3
24
25#define WM8580_CLKSRC_MCLK 1
26#define WM8580_CLKSRC_PLLA 2
27#define WM8580_CLKSRC_PLLB 3
28#define WM8580_CLKSRC_OSC 4
29#define WM8580_CLKSRC_NONE 5
30
31struct wm8580_setup_data {
32 unsigned short i2c_address;
33};
34
35#define WM8580_DAI_PAIFRX 0
36#define WM8580_DAI_PAIFTX 1
37
38extern struct snd_soc_dai wm8580_dai[];
39extern struct snd_soc_codec_device soc_codec_dev_wm8580;
40
41#endif
42
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index 9402fcaf04fa..7f8a7e36b33e 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -19,6 +19,7 @@
19#include <linux/pm.h> 19#include <linux/pm.h>
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/spi/spi.h>
22#include <sound/core.h> 23#include <sound/core.h>
23#include <sound/pcm.h> 24#include <sound/pcm.h>
24#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
@@ -28,7 +29,6 @@
28 29
29#include "wm8731.h" 30#include "wm8731.h"
30 31
31#define AUDIO_NAME "wm8731"
32#define WM8731_VERSION "0.13" 32#define WM8731_VERSION "0.13"
33 33
34struct snd_soc_codec_device soc_codec_dev_wm8731; 34struct snd_soc_codec_device soc_codec_dev_wm8731;
@@ -570,88 +570,144 @@ static struct snd_soc_device *wm8731_socdev;
570 * low = 0x1a 570 * low = 0x1a
571 * high = 0x1b 571 * high = 0x1b
572 */ 572 */
573static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
574 573
575/* Magic definition of all other variables and things */ 574static int wm8731_i2c_probe(struct i2c_client *i2c,
576I2C_CLIENT_INSMOD; 575 const struct i2c_device_id *id)
577
578static struct i2c_driver wm8731_i2c_driver;
579static struct i2c_client client_template;
580
581/* If the i2c layer weren't so broken, we could pass this kind of data
582 around */
583
584static int wm8731_codec_probe(struct i2c_adapter *adap, int addr, int kind)
585{ 576{
586 struct snd_soc_device *socdev = wm8731_socdev; 577 struct snd_soc_device *socdev = wm8731_socdev;
587 struct wm8731_setup_data *setup = socdev->codec_data;
588 struct snd_soc_codec *codec = socdev->codec; 578 struct snd_soc_codec *codec = socdev->codec;
589 struct i2c_client *i2c;
590 int ret; 579 int ret;
591 580
592 if (addr != setup->i2c_address)
593 return -ENODEV;
594
595 client_template.adapter = adap;
596 client_template.addr = addr;
597
598 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
599 if (i2c == NULL)
600 return -ENOMEM;
601
602 i2c_set_clientdata(i2c, codec); 581 i2c_set_clientdata(i2c, codec);
603 codec->control_data = i2c; 582 codec->control_data = i2c;
604 583
605 ret = i2c_attach_client(i2c);
606 if (ret < 0) {
607 pr_err("failed to attach codec at addr %x\n", addr);
608 goto err;
609 }
610
611 ret = wm8731_init(socdev); 584 ret = wm8731_init(socdev);
612 if (ret < 0) { 585 if (ret < 0)
613 pr_err("failed to initialise WM8731\n"); 586 pr_err("failed to initialise WM8731\n");
614 goto err;
615 }
616 return ret;
617 587
618err:
619 kfree(i2c);
620 return ret; 588 return ret;
621} 589}
622 590
623static int wm8731_i2c_detach(struct i2c_client *client) 591static int wm8731_i2c_remove(struct i2c_client *client)
624{ 592{
625 struct snd_soc_codec *codec = i2c_get_clientdata(client); 593 struct snd_soc_codec *codec = i2c_get_clientdata(client);
626 i2c_detach_client(client);
627 kfree(codec->reg_cache); 594 kfree(codec->reg_cache);
628 kfree(client);
629 return 0; 595 return 0;
630} 596}
631 597
632static int wm8731_i2c_attach(struct i2c_adapter *adap) 598static const struct i2c_device_id wm8731_i2c_id[] = {
633{ 599 { "wm8731", 0 },
634 return i2c_probe(adap, &addr_data, wm8731_codec_probe); 600 { }
635} 601};
602MODULE_DEVICE_TABLE(i2c, wm8731_i2c_id);
636 603
637/* corgi i2c codec control layer */
638static struct i2c_driver wm8731_i2c_driver = { 604static struct i2c_driver wm8731_i2c_driver = {
639 .driver = { 605 .driver = {
640 .name = "WM8731 I2C Codec", 606 .name = "WM8731 I2C Codec",
641 .owner = THIS_MODULE, 607 .owner = THIS_MODULE,
642 }, 608 },
643 .id = I2C_DRIVERID_WM8731, 609 .probe = wm8731_i2c_probe,
644 .attach_adapter = wm8731_i2c_attach, 610 .remove = wm8731_i2c_remove,
645 .detach_client = wm8731_i2c_detach, 611 .id_table = wm8731_i2c_id,
646 .command = NULL,
647}; 612};
648 613
649static struct i2c_client client_template = { 614static int wm8731_add_i2c_device(struct platform_device *pdev,
650 .name = "WM8731", 615 const struct wm8731_setup_data *setup)
651 .driver = &wm8731_i2c_driver, 616{
652}; 617 struct i2c_board_info info;
618 struct i2c_adapter *adapter;
619 struct i2c_client *client;
620 int ret;
621
622 ret = i2c_add_driver(&wm8731_i2c_driver);
623 if (ret != 0) {
624 dev_err(&pdev->dev, "can't add i2c driver\n");
625 return ret;
626 }
627
628 memset(&info, 0, sizeof(struct i2c_board_info));
629 info.addr = setup->i2c_address;
630 strlcpy(info.type, "wm8731", I2C_NAME_SIZE);
631
632 adapter = i2c_get_adapter(setup->i2c_bus);
633 if (!adapter) {
634 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
635 setup->i2c_bus);
636 goto err_driver;
637 }
638
639 client = i2c_new_device(adapter, &info);
640 i2c_put_adapter(adapter);
641 if (!client) {
642 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
643 (unsigned int)info.addr);
644 goto err_driver;
645 }
646
647 return 0;
648
649err_driver:
650 i2c_del_driver(&wm8731_i2c_driver);
651 return -ENODEV;
652}
653#endif 653#endif
654 654
655#if defined(CONFIG_SPI_MASTER)
656static int __devinit wm8731_spi_probe(struct spi_device *spi)
657{
658 struct snd_soc_device *socdev = wm8731_socdev;
659 struct snd_soc_codec *codec = socdev->codec;
660 int ret;
661
662 codec->control_data = spi;
663
664 ret = wm8731_init(socdev);
665 if (ret < 0)
666 dev_err(&spi->dev, "failed to initialise WM8731\n");
667
668 return ret;
669}
670
671static int __devexit wm8731_spi_remove(struct spi_device *spi)
672{
673 return 0;
674}
675
676static struct spi_driver wm8731_spi_driver = {
677 .driver = {
678 .name = "wm8731",
679 .bus = &spi_bus_type,
680 .owner = THIS_MODULE,
681 },
682 .probe = wm8731_spi_probe,
683 .remove = __devexit_p(wm8731_spi_remove),
684};
685
686static int wm8731_spi_write(struct spi_device *spi, const char *data, int len)
687{
688 struct spi_transfer t;
689 struct spi_message m;
690 u8 msg[2];
691
692 if (len <= 0)
693 return 0;
694
695 msg[0] = data[0];
696 msg[1] = data[1];
697
698 spi_message_init(&m);
699 memset(&t, 0, (sizeof t));
700
701 t.tx_buf = &msg[0];
702 t.len = len;
703
704 spi_message_add_tail(&t, &m);
705 spi_sync(spi, &m);
706
707 return len;
708}
709#endif /* CONFIG_SPI_MASTER */
710
655static int wm8731_probe(struct platform_device *pdev) 711static int wm8731_probe(struct platform_device *pdev)
656{ 712{
657 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 713 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
@@ -680,16 +736,21 @@ static int wm8731_probe(struct platform_device *pdev)
680 INIT_LIST_HEAD(&codec->dapm_paths); 736 INIT_LIST_HEAD(&codec->dapm_paths);
681 737
682 wm8731_socdev = socdev; 738 wm8731_socdev = socdev;
739 ret = -ENODEV;
740
683#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 741#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
684 if (setup->i2c_address) { 742 if (setup->i2c_address) {
685 normal_i2c[0] = setup->i2c_address;
686 codec->hw_write = (hw_write_t)i2c_master_send; 743 codec->hw_write = (hw_write_t)i2c_master_send;
687 ret = i2c_add_driver(&wm8731_i2c_driver); 744 ret = wm8731_add_i2c_device(pdev, setup);
745 }
746#endif
747#if defined(CONFIG_SPI_MASTER)
748 if (setup->spi) {
749 codec->hw_write = (hw_write_t)wm8731_spi_write;
750 ret = spi_register_driver(&wm8731_spi_driver);
688 if (ret != 0) 751 if (ret != 0)
689 printk(KERN_ERR "can't add i2c driver"); 752 printk(KERN_ERR "can't add spi driver");
690 } 753 }
691#else
692 /* Add other interfaces here */
693#endif 754#endif
694 755
695 if (ret != 0) { 756 if (ret != 0) {
@@ -711,8 +772,12 @@ static int wm8731_remove(struct platform_device *pdev)
711 snd_soc_free_pcms(socdev); 772 snd_soc_free_pcms(socdev);
712 snd_soc_dapm_free(socdev); 773 snd_soc_dapm_free(socdev);
713#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 774#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
775 i2c_unregister_device(codec->control_data);
714 i2c_del_driver(&wm8731_i2c_driver); 776 i2c_del_driver(&wm8731_i2c_driver);
715#endif 777#endif
778#if defined(CONFIG_SPI_MASTER)
779 spi_unregister_driver(&wm8731_spi_driver);
780#endif
716 kfree(codec->private_data); 781 kfree(codec->private_data);
717 kfree(codec); 782 kfree(codec);
718 783
diff --git a/sound/soc/codecs/wm8731.h b/sound/soc/codecs/wm8731.h
index 99f2e3c60e33..95190e9c0c14 100644
--- a/sound/soc/codecs/wm8731.h
+++ b/sound/soc/codecs/wm8731.h
@@ -35,6 +35,8 @@
35#define WM8731_DAI 0 35#define WM8731_DAI 0
36 36
37struct wm8731_setup_data { 37struct wm8731_setup_data {
38 int spi;
39 int i2c_bus;
38 unsigned short i2c_address; 40 unsigned short i2c_address;
39}; 41};
40 42
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index dd1f55404b29..9b7296ee5b08 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.c
@@ -19,6 +19,7 @@
19#include <linux/pm.h> 19#include <linux/pm.h>
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/spi/spi.h>
22#include <sound/core.h> 23#include <sound/core.h>
23#include <sound/pcm.h> 24#include <sound/pcm.h>
24#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
@@ -28,7 +29,6 @@
28 29
29#include "wm8750.h" 30#include "wm8750.h"
30 31
31#define AUDIO_NAME "WM8750"
32#define WM8750_VERSION "0.12" 32#define WM8750_VERSION "0.12"
33 33
34/* codec private data */ 34/* codec private data */
@@ -841,88 +841,147 @@ static struct snd_soc_device *wm8750_socdev;
841#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 841#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
842 842
843/* 843/*
844 * WM8731 2 wire address is determined by GPIO5 844 * WM8750 2 wire address is determined by GPIO5
845 * state during powerup. 845 * state during powerup.
846 * low = 0x1a 846 * low = 0x1a
847 * high = 0x1b 847 * high = 0x1b
848 */ 848 */
849static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
850 849
851/* Magic definition of all other variables and things */ 850static int wm8750_i2c_probe(struct i2c_client *i2c,
852I2C_CLIENT_INSMOD; 851 const struct i2c_device_id *id)
853
854static struct i2c_driver wm8750_i2c_driver;
855static struct i2c_client client_template;
856
857static int wm8750_codec_probe(struct i2c_adapter *adap, int addr, int kind)
858{ 852{
859 struct snd_soc_device *socdev = wm8750_socdev; 853 struct snd_soc_device *socdev = wm8750_socdev;
860 struct wm8750_setup_data *setup = socdev->codec_data;
861 struct snd_soc_codec *codec = socdev->codec; 854 struct snd_soc_codec *codec = socdev->codec;
862 struct i2c_client *i2c;
863 int ret; 855 int ret;
864 856
865 if (addr != setup->i2c_address)
866 return -ENODEV;
867
868 client_template.adapter = adap;
869 client_template.addr = addr;
870
871 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
872 if (i2c == NULL)
873 return -ENOMEM;
874
875 i2c_set_clientdata(i2c, codec); 857 i2c_set_clientdata(i2c, codec);
876 codec->control_data = i2c; 858 codec->control_data = i2c;
877 859
878 ret = i2c_attach_client(i2c);
879 if (ret < 0) {
880 pr_err("failed to attach codec at addr %x\n", addr);
881 goto err;
882 }
883
884 ret = wm8750_init(socdev); 860 ret = wm8750_init(socdev);
885 if (ret < 0) { 861 if (ret < 0)
886 pr_err("failed to initialise WM8750\n"); 862 pr_err("failed to initialise WM8750\n");
887 goto err;
888 }
889 return ret;
890 863
891err:
892 kfree(i2c);
893 return ret; 864 return ret;
894} 865}
895 866
896static int wm8750_i2c_detach(struct i2c_client *client) 867static int wm8750_i2c_remove(struct i2c_client *client)
897{ 868{
898 struct snd_soc_codec *codec = i2c_get_clientdata(client); 869 struct snd_soc_codec *codec = i2c_get_clientdata(client);
899 i2c_detach_client(client);
900 kfree(codec->reg_cache); 870 kfree(codec->reg_cache);
901 kfree(client);
902 return 0; 871 return 0;
903} 872}
904 873
905static int wm8750_i2c_attach(struct i2c_adapter *adap) 874static const struct i2c_device_id wm8750_i2c_id[] = {
906{ 875 { "wm8750", 0 },
907 return i2c_probe(adap, &addr_data, wm8750_codec_probe); 876 { }
908} 877};
878MODULE_DEVICE_TABLE(i2c, wm8750_i2c_id);
909 879
910/* corgi i2c codec control layer */
911static struct i2c_driver wm8750_i2c_driver = { 880static struct i2c_driver wm8750_i2c_driver = {
912 .driver = { 881 .driver = {
913 .name = "WM8750 I2C Codec", 882 .name = "WM8750 I2C Codec",
914 .owner = THIS_MODULE, 883 .owner = THIS_MODULE,
915 }, 884 },
916 .id = I2C_DRIVERID_WM8750, 885 .probe = wm8750_i2c_probe,
917 .attach_adapter = wm8750_i2c_attach, 886 .remove = wm8750_i2c_remove,
918 .detach_client = wm8750_i2c_detach, 887 .id_table = wm8750_i2c_id,
919 .command = NULL,
920}; 888};
921 889
922static struct i2c_client client_template = { 890static int wm8750_add_i2c_device(struct platform_device *pdev,
923 .name = "WM8750", 891 const struct wm8750_setup_data *setup)
924 .driver = &wm8750_i2c_driver, 892{
893 struct i2c_board_info info;
894 struct i2c_adapter *adapter;
895 struct i2c_client *client;
896 int ret;
897
898 ret = i2c_add_driver(&wm8750_i2c_driver);
899 if (ret != 0) {
900 dev_err(&pdev->dev, "can't add i2c driver\n");
901 return ret;
902 }
903
904 memset(&info, 0, sizeof(struct i2c_board_info));
905 info.addr = setup->i2c_address;
906 strlcpy(info.type, "wm8750", I2C_NAME_SIZE);
907
908 adapter = i2c_get_adapter(setup->i2c_bus);
909 if (!adapter) {
910 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
911 setup->i2c_bus);
912 goto err_driver;
913 }
914
915 client = i2c_new_device(adapter, &info);
916 i2c_put_adapter(adapter);
917 if (!client) {
918 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
919 (unsigned int)info.addr);
920 goto err_driver;
921 }
922
923 return 0;
924
925err_driver:
926 i2c_del_driver(&wm8750_i2c_driver);
927 return -ENODEV;
928}
929#endif
930
931#if defined(CONFIG_SPI_MASTER)
932static int __devinit wm8750_spi_probe(struct spi_device *spi)
933{
934 struct snd_soc_device *socdev = wm8750_socdev;
935 struct snd_soc_codec *codec = socdev->codec;
936 int ret;
937
938 codec->control_data = spi;
939
940 ret = wm8750_init(socdev);
941 if (ret < 0)
942 dev_err(&spi->dev, "failed to initialise WM8750\n");
943
944 return ret;
945}
946
947static int __devexit wm8750_spi_remove(struct spi_device *spi)
948{
949 return 0;
950}
951
952static struct spi_driver wm8750_spi_driver = {
953 .driver = {
954 .name = "wm8750",
955 .bus = &spi_bus_type,
956 .owner = THIS_MODULE,
957 },
958 .probe = wm8750_spi_probe,
959 .remove = __devexit_p(wm8750_spi_remove),
925}; 960};
961
962static int wm8750_spi_write(struct spi_device *spi, const char *data, int len)
963{
964 struct spi_transfer t;
965 struct spi_message m;
966 u8 msg[2];
967
968 if (len <= 0)
969 return 0;
970
971 msg[0] = data[0];
972 msg[1] = data[1];
973
974 spi_message_init(&m);
975 memset(&t, 0, (sizeof t));
976
977 t.tx_buf = &msg[0];
978 t.len = len;
979
980 spi_message_add_tail(&t, &m);
981 spi_sync(spi, &m);
982
983 return len;
984}
926#endif 985#endif
927 986
928static int wm8750_probe(struct platform_device *pdev) 987static int wm8750_probe(struct platform_device *pdev)
@@ -931,7 +990,7 @@ static int wm8750_probe(struct platform_device *pdev)
931 struct wm8750_setup_data *setup = socdev->codec_data; 990 struct wm8750_setup_data *setup = socdev->codec_data;
932 struct snd_soc_codec *codec; 991 struct snd_soc_codec *codec;
933 struct wm8750_priv *wm8750; 992 struct wm8750_priv *wm8750;
934 int ret = 0; 993 int ret;
935 994
936 pr_info("WM8750 Audio Codec %s", WM8750_VERSION); 995 pr_info("WM8750 Audio Codec %s", WM8750_VERSION);
937 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 996 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
@@ -952,16 +1011,21 @@ static int wm8750_probe(struct platform_device *pdev)
952 wm8750_socdev = socdev; 1011 wm8750_socdev = socdev;
953 INIT_DELAYED_WORK(&codec->delayed_work, wm8750_work); 1012 INIT_DELAYED_WORK(&codec->delayed_work, wm8750_work);
954 1013
1014 ret = -ENODEV;
1015
955#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1016#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
956 if (setup->i2c_address) { 1017 if (setup->i2c_address) {
957 normal_i2c[0] = setup->i2c_address;
958 codec->hw_write = (hw_write_t)i2c_master_send; 1018 codec->hw_write = (hw_write_t)i2c_master_send;
959 ret = i2c_add_driver(&wm8750_i2c_driver); 1019 ret = wm8750_add_i2c_device(pdev, setup);
1020 }
1021#endif
1022#if defined(CONFIG_SPI_MASTER)
1023 if (setup->spi) {
1024 codec->hw_write = (hw_write_t)wm8750_spi_write;
1025 ret = spi_register_driver(&wm8750_spi_driver);
960 if (ret != 0) 1026 if (ret != 0)
961 printk(KERN_ERR "can't add i2c driver"); 1027 printk(KERN_ERR "can't add spi driver");
962 } 1028 }
963#else
964 /* Add other interfaces here */
965#endif 1029#endif
966 1030
967 if (ret != 0) { 1031 if (ret != 0) {
@@ -1002,8 +1066,12 @@ static int wm8750_remove(struct platform_device *pdev)
1002 snd_soc_free_pcms(socdev); 1066 snd_soc_free_pcms(socdev);
1003 snd_soc_dapm_free(socdev); 1067 snd_soc_dapm_free(socdev);
1004#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1068#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1069 i2c_unregister_device(codec->control_data);
1005 i2c_del_driver(&wm8750_i2c_driver); 1070 i2c_del_driver(&wm8750_i2c_driver);
1006#endif 1071#endif
1072#if defined(CONFIG_SPI_MASTER)
1073 spi_unregister_driver(&wm8750_spi_driver);
1074#endif
1007 kfree(codec->private_data); 1075 kfree(codec->private_data);
1008 kfree(codec); 1076 kfree(codec);
1009 1077
diff --git a/sound/soc/codecs/wm8750.h b/sound/soc/codecs/wm8750.h
index 8ef30e628b21..1dc100e19cfe 100644
--- a/sound/soc/codecs/wm8750.h
+++ b/sound/soc/codecs/wm8750.h
@@ -58,6 +58,8 @@
58#define WM8750_SYSCLK 0 58#define WM8750_SYSCLK 0
59 59
60struct wm8750_setup_data { 60struct wm8750_setup_data {
61 int spi;
62 int i2c_bus;
61 unsigned short i2c_address; 63 unsigned short i2c_address;
62}; 64};
63 65
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index 5761164fe16d..d426eaa22185 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -2,8 +2,7 @@
2 * wm8753.c -- WM8753 ALSA Soc Audio driver 2 * wm8753.c -- WM8753 ALSA Soc Audio driver
3 * 3 *
4 * Copyright 2003 Wolfson Microelectronics PLC. 4 * Copyright 2003 Wolfson Microelectronics PLC.
5 * Author: Liam Girdwood 5 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
6 * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
7 * 6 *
8 * This program is free software; you can redistribute it and/or modify it 7 * 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 8 * under the terms of the GNU General Public License as published by the
@@ -40,6 +39,7 @@
40#include <linux/pm.h> 39#include <linux/pm.h>
41#include <linux/i2c.h> 40#include <linux/i2c.h>
42#include <linux/platform_device.h> 41#include <linux/platform_device.h>
42#include <linux/spi/spi.h>
43#include <sound/core.h> 43#include <sound/core.h>
44#include <sound/pcm.h> 44#include <sound/pcm.h>
45#include <sound/pcm_params.h> 45#include <sound/pcm_params.h>
@@ -51,7 +51,6 @@
51 51
52#include "wm8753.h" 52#include "wm8753.h"
53 53
54#define AUDIO_NAME "wm8753"
55#define WM8753_VERSION "0.16" 54#define WM8753_VERSION "0.16"
56 55
57static int caps_charge = 2000; 56static int caps_charge = 2000;
@@ -583,7 +582,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
583 582
584 /* out 4 */ 583 /* out 4 */
585 {"Out4 Mux", "VREF", "VREF"}, 584 {"Out4 Mux", "VREF", "VREF"},
586 {"Out4 Mux", "Capture ST", "Capture ST Mixer"}, 585 {"Out4 Mux", "Capture ST", "Playback Mixer"},
587 {"Out4 Mux", "LOUT2", "LOUT2"}, 586 {"Out4 Mux", "LOUT2", "LOUT2"},
588 {"Out 4", NULL, "Out4 Mux"}, 587 {"Out 4", NULL, "Out4 Mux"},
589 {"OUT4", NULL, "Out 4"}, 588 {"OUT4", NULL, "Out 4"},
@@ -607,7 +606,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
607 /* Capture Right Mux */ 606 /* Capture Right Mux */
608 {"Capture Right Mux", "PGA", "Right Capture Volume"}, 607 {"Capture Right Mux", "PGA", "Right Capture Volume"},
609 {"Capture Right Mux", "Line or RXP-RXN", "Line Right Mux"}, 608 {"Capture Right Mux", "Line or RXP-RXN", "Line Right Mux"},
610 {"Capture Right Mux", "Sidetone", "Capture ST Mixer"}, 609 {"Capture Right Mux", "Sidetone", "Playback Mixer"},
611 610
612 /* Mono Capture mixer-mux */ 611 /* Mono Capture mixer-mux */
613 {"Capture Right Mixer", "Stereo", "Capture Right Mux"}, 612 {"Capture Right Mixer", "Stereo", "Capture Right Mux"},
@@ -1637,86 +1636,145 @@ static struct snd_soc_device *wm8753_socdev;
1637 * low = 0x1a 1636 * low = 0x1a
1638 * high = 0x1b 1637 * high = 0x1b
1639 */ 1638 */
1640static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
1641 1639
1642/* Magic definition of all other variables and things */ 1640static int wm8753_i2c_probe(struct i2c_client *i2c,
1643I2C_CLIENT_INSMOD; 1641 const struct i2c_device_id *id)
1644
1645static struct i2c_driver wm8753_i2c_driver;
1646static struct i2c_client client_template;
1647
1648static int wm8753_codec_probe(struct i2c_adapter *adap, int addr, int kind)
1649{ 1642{
1650 struct snd_soc_device *socdev = wm8753_socdev; 1643 struct snd_soc_device *socdev = wm8753_socdev;
1651 struct wm8753_setup_data *setup = socdev->codec_data;
1652 struct snd_soc_codec *codec = socdev->codec; 1644 struct snd_soc_codec *codec = socdev->codec;
1653 struct i2c_client *i2c;
1654 int ret; 1645 int ret;
1655 1646
1656 if (addr != setup->i2c_address)
1657 return -ENODEV;
1658
1659 client_template.adapter = adap;
1660 client_template.addr = addr;
1661
1662 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
1663 if (!i2c)
1664 return -ENOMEM;
1665
1666 i2c_set_clientdata(i2c, codec); 1647 i2c_set_clientdata(i2c, codec);
1667 codec->control_data = i2c; 1648 codec->control_data = i2c;
1668 1649
1669 ret = i2c_attach_client(i2c);
1670 if (ret < 0) {
1671 pr_err("failed to attach codec at addr %x\n", addr);
1672 goto err;
1673 }
1674
1675 ret = wm8753_init(socdev); 1650 ret = wm8753_init(socdev);
1676 if (ret < 0) { 1651 if (ret < 0)
1677 pr_err("failed to initialise WM8753\n"); 1652 pr_err("failed to initialise WM8753\n");
1678 goto err;
1679 }
1680
1681 return ret;
1682 1653
1683err:
1684 kfree(i2c);
1685 return ret; 1654 return ret;
1686} 1655}
1687 1656
1688static int wm8753_i2c_detach(struct i2c_client *client) 1657static int wm8753_i2c_remove(struct i2c_client *client)
1689{ 1658{
1690 struct snd_soc_codec *codec = i2c_get_clientdata(client); 1659 struct snd_soc_codec *codec = i2c_get_clientdata(client);
1691 i2c_detach_client(client);
1692 kfree(codec->reg_cache); 1660 kfree(codec->reg_cache);
1693 kfree(client);
1694 return 0; 1661 return 0;
1695} 1662}
1696 1663
1697static int wm8753_i2c_attach(struct i2c_adapter *adap) 1664static const struct i2c_device_id wm8753_i2c_id[] = {
1698{ 1665 { "wm8753", 0 },
1699 return i2c_probe(adap, &addr_data, wm8753_codec_probe); 1666 { }
1700} 1667};
1668MODULE_DEVICE_TABLE(i2c, wm8753_i2c_id);
1701 1669
1702/* corgi i2c codec control layer */
1703static struct i2c_driver wm8753_i2c_driver = { 1670static struct i2c_driver wm8753_i2c_driver = {
1704 .driver = { 1671 .driver = {
1705 .name = "WM8753 I2C Codec", 1672 .name = "WM8753 I2C Codec",
1706 .owner = THIS_MODULE, 1673 .owner = THIS_MODULE,
1707 }, 1674 },
1708 .id = I2C_DRIVERID_WM8753, 1675 .probe = wm8753_i2c_probe,
1709 .attach_adapter = wm8753_i2c_attach, 1676 .remove = wm8753_i2c_remove,
1710 .detach_client = wm8753_i2c_detach, 1677 .id_table = wm8753_i2c_id,
1711 .command = NULL,
1712}; 1678};
1713 1679
1714static struct i2c_client client_template = { 1680static int wm8753_add_i2c_device(struct platform_device *pdev,
1715 .name = "WM8753", 1681 const struct wm8753_setup_data *setup)
1716 .driver = &wm8753_i2c_driver, 1682{
1683 struct i2c_board_info info;
1684 struct i2c_adapter *adapter;
1685 struct i2c_client *client;
1686 int ret;
1687
1688 ret = i2c_add_driver(&wm8753_i2c_driver);
1689 if (ret != 0) {
1690 dev_err(&pdev->dev, "can't add i2c driver\n");
1691 return ret;
1692 }
1693
1694 memset(&info, 0, sizeof(struct i2c_board_info));
1695 info.addr = setup->i2c_address;
1696 strlcpy(info.type, "wm8753", I2C_NAME_SIZE);
1697
1698 adapter = i2c_get_adapter(setup->i2c_bus);
1699 if (!adapter) {
1700 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
1701 setup->i2c_bus);
1702 goto err_driver;
1703 }
1704
1705 client = i2c_new_device(adapter, &info);
1706 i2c_put_adapter(adapter);
1707 if (!client) {
1708 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
1709 (unsigned int)info.addr);
1710 goto err_driver;
1711 }
1712
1713 return 0;
1714
1715err_driver:
1716 i2c_del_driver(&wm8753_i2c_driver);
1717 return -ENODEV;
1718}
1719#endif
1720
1721#if defined(CONFIG_SPI_MASTER)
1722static int __devinit wm8753_spi_probe(struct spi_device *spi)
1723{
1724 struct snd_soc_device *socdev = wm8753_socdev;
1725 struct snd_soc_codec *codec = socdev->codec;
1726 int ret;
1727
1728 codec->control_data = spi;
1729
1730 ret = wm8753_init(socdev);
1731 if (ret < 0)
1732 dev_err(&spi->dev, "failed to initialise WM8753\n");
1733
1734 return ret;
1735}
1736
1737static int __devexit wm8753_spi_remove(struct spi_device *spi)
1738{
1739 return 0;
1740}
1741
1742static struct spi_driver wm8753_spi_driver = {
1743 .driver = {
1744 .name = "wm8753",
1745 .bus = &spi_bus_type,
1746 .owner = THIS_MODULE,
1747 },
1748 .probe = wm8753_spi_probe,
1749 .remove = __devexit_p(wm8753_spi_remove),
1717}; 1750};
1751
1752static int wm8753_spi_write(struct spi_device *spi, const char *data, int len)
1753{
1754 struct spi_transfer t;
1755 struct spi_message m;
1756 u8 msg[2];
1757
1758 if (len <= 0)
1759 return 0;
1760
1761 msg[0] = data[0];
1762 msg[1] = data[1];
1763
1764 spi_message_init(&m);
1765 memset(&t, 0, (sizeof t));
1766
1767 t.tx_buf = &msg[0];
1768 t.len = len;
1769
1770 spi_message_add_tail(&t, &m);
1771 spi_sync(spi, &m);
1772
1773 return len;
1774}
1718#endif 1775#endif
1719 1776
1777
1720static int wm8753_probe(struct platform_device *pdev) 1778static int wm8753_probe(struct platform_device *pdev)
1721{ 1779{
1722 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1780 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
@@ -1748,14 +1806,17 @@ static int wm8753_probe(struct platform_device *pdev)
1748 1806
1749#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1807#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1750 if (setup->i2c_address) { 1808 if (setup->i2c_address) {
1751 normal_i2c[0] = setup->i2c_address;
1752 codec->hw_write = (hw_write_t)i2c_master_send; 1809 codec->hw_write = (hw_write_t)i2c_master_send;
1753 ret = i2c_add_driver(&wm8753_i2c_driver); 1810 ret = wm8753_add_i2c_device(pdev, setup);
1811 }
1812#endif
1813#if defined(CONFIG_SPI_MASTER)
1814 if (setup->spi) {
1815 codec->hw_write = (hw_write_t)wm8753_spi_write;
1816 ret = spi_register_driver(&wm8753_spi_driver);
1754 if (ret != 0) 1817 if (ret != 0)
1755 printk(KERN_ERR "can't add i2c driver"); 1818 printk(KERN_ERR "can't add spi driver");
1756 } 1819 }
1757#else
1758 /* Add other interfaces here */
1759#endif 1820#endif
1760 1821
1761 if (ret != 0) { 1822 if (ret != 0) {
@@ -1796,8 +1857,12 @@ static int wm8753_remove(struct platform_device *pdev)
1796 snd_soc_free_pcms(socdev); 1857 snd_soc_free_pcms(socdev);
1797 snd_soc_dapm_free(socdev); 1858 snd_soc_dapm_free(socdev);
1798#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1859#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1860 i2c_unregister_device(codec->control_data);
1799 i2c_del_driver(&wm8753_i2c_driver); 1861 i2c_del_driver(&wm8753_i2c_driver);
1800#endif 1862#endif
1863#if defined(CONFIG_SPI_MASTER)
1864 spi_unregister_driver(&wm8753_spi_driver);
1865#endif
1801 kfree(codec->private_data); 1866 kfree(codec->private_data);
1802 kfree(codec); 1867 kfree(codec);
1803 1868
diff --git a/sound/soc/codecs/wm8753.h b/sound/soc/codecs/wm8753.h
index 44f5f1ff0cc7..f55704ce931b 100644
--- a/sound/soc/codecs/wm8753.h
+++ b/sound/soc/codecs/wm8753.h
@@ -2,8 +2,7 @@
2 * wm8753.h -- audio driver for WM8753 2 * wm8753.h -- audio driver for WM8753
3 * 3 *
4 * Copyright 2003 Wolfson Microelectronics PLC. 4 * Copyright 2003 Wolfson Microelectronics PLC.
5 * Author: Liam Girdwood 5 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
6 * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
7 * 6 *
8 * This program is free software; you can redistribute it and/or modify it 7 * 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 8 * under the terms of the GNU General Public License as published by the
@@ -79,6 +78,8 @@
79#define WM8753_ADCTL2 0x3f 78#define WM8753_ADCTL2 0x3f
80 79
81struct wm8753_setup_data { 80struct wm8753_setup_data {
81 int spi;
82 int i2c_bus;
82 unsigned short i2c_address; 83 unsigned short i2c_address;
83}; 84};
84 85
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c
new file mode 100644
index 000000000000..3b326c9b5586
--- /dev/null
+++ b/sound/soc/codecs/wm8900.c
@@ -0,0 +1,1541 @@
1/*
2 * wm8900.c -- WM8900 ALSA Soc Audio driver
3 *
4 * Copyright 2007, 2008 Wolfson Microelectronics PLC.
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * TODO:
13 * - Tristating.
14 * - TDM.
15 * - Jack detect.
16 * - FLL source configuration, currently only MCLK is supported.
17 */
18
19#include <linux/module.h>
20#include <linux/moduleparam.h>
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/delay.h>
24#include <linux/pm.h>
25#include <linux/i2c.h>
26#include <linux/platform_device.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/soc-dapm.h>
32#include <sound/initval.h>
33#include <sound/tlv.h>
34
35#include "wm8900.h"
36
37/* WM8900 register space */
38#define WM8900_REG_RESET 0x0
39#define WM8900_REG_ID 0x0
40#define WM8900_REG_POWER1 0x1
41#define WM8900_REG_POWER2 0x2
42#define WM8900_REG_POWER3 0x3
43#define WM8900_REG_AUDIO1 0x4
44#define WM8900_REG_AUDIO2 0x5
45#define WM8900_REG_CLOCKING1 0x6
46#define WM8900_REG_CLOCKING2 0x7
47#define WM8900_REG_AUDIO3 0x8
48#define WM8900_REG_AUDIO4 0x9
49#define WM8900_REG_DACCTRL 0xa
50#define WM8900_REG_LDAC_DV 0xb
51#define WM8900_REG_RDAC_DV 0xc
52#define WM8900_REG_SIDETONE 0xd
53#define WM8900_REG_ADCCTRL 0xe
54#define WM8900_REG_LADC_DV 0xf
55#define WM8900_REG_RADC_DV 0x10
56#define WM8900_REG_GPIO 0x12
57#define WM8900_REG_INCTL 0x15
58#define WM8900_REG_LINVOL 0x16
59#define WM8900_REG_RINVOL 0x17
60#define WM8900_REG_INBOOSTMIX1 0x18
61#define WM8900_REG_INBOOSTMIX2 0x19
62#define WM8900_REG_ADCPATH 0x1a
63#define WM8900_REG_AUXBOOST 0x1b
64#define WM8900_REG_ADDCTL 0x1e
65#define WM8900_REG_FLLCTL1 0x24
66#define WM8900_REG_FLLCTL2 0x25
67#define WM8900_REG_FLLCTL3 0x26
68#define WM8900_REG_FLLCTL4 0x27
69#define WM8900_REG_FLLCTL5 0x28
70#define WM8900_REG_FLLCTL6 0x29
71#define WM8900_REG_LOUTMIXCTL1 0x2c
72#define WM8900_REG_ROUTMIXCTL1 0x2d
73#define WM8900_REG_BYPASS1 0x2e
74#define WM8900_REG_BYPASS2 0x2f
75#define WM8900_REG_AUXOUT_CTL 0x30
76#define WM8900_REG_LOUT1CTL 0x33
77#define WM8900_REG_ROUT1CTL 0x34
78#define WM8900_REG_LOUT2CTL 0x35
79#define WM8900_REG_ROUT2CTL 0x36
80#define WM8900_REG_HPCTL1 0x3a
81#define WM8900_REG_OUTBIASCTL 0x73
82
83#define WM8900_MAXREG 0x80
84
85#define WM8900_REG_ADDCTL_OUT1_DIS 0x80
86#define WM8900_REG_ADDCTL_OUT2_DIS 0x40
87#define WM8900_REG_ADDCTL_VMID_DIS 0x20
88#define WM8900_REG_ADDCTL_BIAS_SRC 0x10
89#define WM8900_REG_ADDCTL_VMID_SOFTST 0x04
90#define WM8900_REG_ADDCTL_TEMP_SD 0x02
91
92#define WM8900_REG_GPIO_TEMP_ENA 0x2
93
94#define WM8900_REG_POWER1_STARTUP_BIAS_ENA 0x0100
95#define WM8900_REG_POWER1_BIAS_ENA 0x0008
96#define WM8900_REG_POWER1_VMID_BUF_ENA 0x0004
97#define WM8900_REG_POWER1_FLL_ENA 0x0040
98
99#define WM8900_REG_POWER2_SYSCLK_ENA 0x8000
100#define WM8900_REG_POWER2_ADCL_ENA 0x0002
101#define WM8900_REG_POWER2_ADCR_ENA 0x0001
102
103#define WM8900_REG_POWER3_DACL_ENA 0x0002
104#define WM8900_REG_POWER3_DACR_ENA 0x0001
105
106#define WM8900_REG_AUDIO1_AIF_FMT_MASK 0x0018
107#define WM8900_REG_AUDIO1_LRCLK_INV 0x0080
108#define WM8900_REG_AUDIO1_BCLK_INV 0x0100
109
110#define WM8900_REG_CLOCKING1_BCLK_DIR 0x1
111#define WM8900_REG_CLOCKING1_MCLK_SRC 0x100
112#define WM8900_REG_CLOCKING1_BCLK_MASK (~0x01e)
113#define WM8900_REG_CLOCKING1_OPCLK_MASK (~0x7000)
114
115#define WM8900_REG_CLOCKING2_ADC_CLKDIV 0xe0
116#define WM8900_REG_CLOCKING2_DAC_CLKDIV 0x1c
117
118#define WM8900_REG_DACCTRL_MUTE 0x004
119#define WM8900_REG_DACCTRL_AIF_LRCLKRATE 0x400
120
121#define WM8900_REG_AUDIO3_ADCLRC_DIR 0x0800
122
123#define WM8900_REG_AUDIO4_DACLRC_DIR 0x0800
124
125#define WM8900_REG_FLLCTL1_OSC_ENA 0x100
126
127#define WM8900_REG_FLLCTL6_FLL_SLOW_LOCK_REF 0x100
128
129#define WM8900_REG_HPCTL1_HP_IPSTAGE_ENA 0x80
130#define WM8900_REG_HPCTL1_HP_OPSTAGE_ENA 0x40
131#define WM8900_REG_HPCTL1_HP_CLAMP_IP 0x20
132#define WM8900_REG_HPCTL1_HP_CLAMP_OP 0x10
133#define WM8900_REG_HPCTL1_HP_SHORT 0x08
134#define WM8900_REG_HPCTL1_HP_SHORT2 0x04
135
136#define WM8900_LRC_MASK 0xfc00
137
138struct snd_soc_codec_device soc_codec_dev_wm8900;
139
140struct wm8900_priv {
141 u32 fll_in; /* FLL input frequency */
142 u32 fll_out; /* FLL output frequency */
143};
144
145/*
146 * wm8900 register cache. We can't read the entire register space and we
147 * have slow control buses so we cache the registers.
148 */
149static const u16 wm8900_reg_defaults[WM8900_MAXREG] = {
150 0x8900, 0x0000,
151 0xc000, 0x0000,
152 0x4050, 0x4000,
153 0x0008, 0x0000,
154 0x0040, 0x0040,
155 0x1004, 0x00c0,
156 0x00c0, 0x0000,
157 0x0100, 0x00c0,
158 0x00c0, 0x0000,
159 0xb001, 0x0000,
160 0x0000, 0x0044,
161 0x004c, 0x004c,
162 0x0044, 0x0044,
163 0x0000, 0x0044,
164 0x0000, 0x0000,
165 0x0002, 0x0000,
166 0x0000, 0x0000,
167 0x0000, 0x0000,
168 0x0008, 0x0000,
169 0x0000, 0x0008,
170 0x0097, 0x0100,
171 0x0000, 0x0000,
172 0x0050, 0x0050,
173 0x0055, 0x0055,
174 0x0055, 0x0000,
175 0x0000, 0x0079,
176 0x0079, 0x0079,
177 0x0079, 0x0000,
178 /* Remaining registers all zero */
179};
180
181/*
182 * read wm8900 register cache
183 */
184static inline unsigned int wm8900_read_reg_cache(struct snd_soc_codec *codec,
185 unsigned int reg)
186{
187 u16 *cache = codec->reg_cache;
188
189 BUG_ON(reg >= WM8900_MAXREG);
190
191 if (reg == WM8900_REG_ID)
192 return 0;
193
194 return cache[reg];
195}
196
197/*
198 * write wm8900 register cache
199 */
200static inline void wm8900_write_reg_cache(struct snd_soc_codec *codec,
201 u16 reg, unsigned int value)
202{
203 u16 *cache = codec->reg_cache;
204
205 BUG_ON(reg >= WM8900_MAXREG);
206
207 cache[reg] = value;
208}
209
210/*
211 * write to the WM8900 register space
212 */
213static int wm8900_write(struct snd_soc_codec *codec, unsigned int reg,
214 unsigned int value)
215{
216 u8 data[3];
217
218 if (value == wm8900_read_reg_cache(codec, reg))
219 return 0;
220
221 /* data is
222 * D15..D9 WM8900 register offset
223 * D8...D0 register data
224 */
225 data[0] = reg;
226 data[1] = value >> 8;
227 data[2] = value & 0x00ff;
228
229 wm8900_write_reg_cache(codec, reg, value);
230 if (codec->hw_write(codec->control_data, data, 3) == 3)
231 return 0;
232 else
233 return -EIO;
234}
235
236/*
237 * Read from the wm8900.
238 */
239static unsigned int wm8900_chip_read(struct snd_soc_codec *codec, u8 reg)
240{
241 struct i2c_msg xfer[2];
242 u16 data;
243 int ret;
244 struct i2c_client *client = codec->control_data;
245
246 BUG_ON(reg != WM8900_REG_ID && reg != WM8900_REG_POWER1);
247
248 /* Write register */
249 xfer[0].addr = client->addr;
250 xfer[0].flags = 0;
251 xfer[0].len = 1;
252 xfer[0].buf = &reg;
253
254 /* Read data */
255 xfer[1].addr = client->addr;
256 xfer[1].flags = I2C_M_RD;
257 xfer[1].len = 2;
258 xfer[1].buf = (u8 *)&data;
259
260 ret = i2c_transfer(client->adapter, xfer, 2);
261 if (ret != 2) {
262 printk(KERN_CRIT "i2c_transfer returned %d\n", ret);
263 return 0;
264 }
265
266 return (data >> 8) | ((data & 0xff) << 8);
267}
268
269/*
270 * Read from the WM8900 register space. Most registers can't be read
271 * and are therefore supplied from cache.
272 */
273static unsigned int wm8900_read(struct snd_soc_codec *codec, unsigned int reg)
274{
275 switch (reg) {
276 case WM8900_REG_ID:
277 return wm8900_chip_read(codec, reg);
278 default:
279 return wm8900_read_reg_cache(codec, reg);
280 }
281}
282
283static void wm8900_reset(struct snd_soc_codec *codec)
284{
285 wm8900_write(codec, WM8900_REG_RESET, 0);
286
287 memcpy(codec->reg_cache, wm8900_reg_defaults,
288 sizeof(codec->reg_cache));
289}
290
291static int wm8900_hp_event(struct snd_soc_dapm_widget *w,
292 struct snd_kcontrol *kcontrol, int event)
293{
294 struct snd_soc_codec *codec = w->codec;
295 u16 hpctl1 = wm8900_read(codec, WM8900_REG_HPCTL1);
296
297 switch (event) {
298 case SND_SOC_DAPM_PRE_PMU:
299 /* Clamp headphone outputs */
300 hpctl1 = WM8900_REG_HPCTL1_HP_CLAMP_IP |
301 WM8900_REG_HPCTL1_HP_CLAMP_OP;
302 wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1);
303 break;
304
305 case SND_SOC_DAPM_POST_PMU:
306 /* Enable the input stage */
307 hpctl1 &= ~WM8900_REG_HPCTL1_HP_CLAMP_IP;
308 hpctl1 |= WM8900_REG_HPCTL1_HP_SHORT |
309 WM8900_REG_HPCTL1_HP_SHORT2 |
310 WM8900_REG_HPCTL1_HP_IPSTAGE_ENA;
311 wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1);
312
313 msleep(400);
314
315 /* Enable the output stage */
316 hpctl1 &= ~WM8900_REG_HPCTL1_HP_CLAMP_OP;
317 hpctl1 |= WM8900_REG_HPCTL1_HP_OPSTAGE_ENA;
318 wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1);
319
320 /* Remove the shorts */
321 hpctl1 &= ~WM8900_REG_HPCTL1_HP_SHORT2;
322 wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1);
323 hpctl1 &= ~WM8900_REG_HPCTL1_HP_SHORT;
324 wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1);
325 break;
326
327 case SND_SOC_DAPM_PRE_PMD:
328 /* Short the output */
329 hpctl1 |= WM8900_REG_HPCTL1_HP_SHORT;
330 wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1);
331
332 /* Disable the output stage */
333 hpctl1 &= ~WM8900_REG_HPCTL1_HP_OPSTAGE_ENA;
334 wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1);
335
336 /* Clamp the outputs and power down input */
337 hpctl1 |= WM8900_REG_HPCTL1_HP_CLAMP_IP |
338 WM8900_REG_HPCTL1_HP_CLAMP_OP;
339 hpctl1 &= ~WM8900_REG_HPCTL1_HP_IPSTAGE_ENA;
340 wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1);
341 break;
342
343 case SND_SOC_DAPM_POST_PMD:
344 /* Disable everything */
345 wm8900_write(codec, WM8900_REG_HPCTL1, 0);
346 break;
347
348 default:
349 BUG();
350 }
351
352 return 0;
353}
354
355static const DECLARE_TLV_DB_SCALE(out_pga_tlv, -5700, 100, 0);
356
357static const DECLARE_TLV_DB_SCALE(out_mix_tlv, -1500, 300, 0);
358
359static const DECLARE_TLV_DB_SCALE(in_boost_tlv, -1200, 600, 0);
360
361static const DECLARE_TLV_DB_SCALE(in_pga_tlv, -1200, 100, 0);
362
363static const DECLARE_TLV_DB_SCALE(dac_boost_tlv, 0, 600, 0);
364
365static const DECLARE_TLV_DB_SCALE(dac_tlv, -7200, 75, 1);
366
367static const DECLARE_TLV_DB_SCALE(adc_svol_tlv, -3600, 300, 0);
368
369static const DECLARE_TLV_DB_SCALE(adc_tlv, -7200, 75, 1);
370
371static const char *mic_bias_level_txt[] = { "0.9*AVDD", "0.65*AVDD" };
372
373static const struct soc_enum mic_bias_level =
374SOC_ENUM_SINGLE(WM8900_REG_INCTL, 8, 2, mic_bias_level_txt);
375
376static const char *dac_mute_rate_txt[] = { "Fast", "Slow" };
377
378static const struct soc_enum dac_mute_rate =
379SOC_ENUM_SINGLE(WM8900_REG_DACCTRL, 7, 2, dac_mute_rate_txt);
380
381static const char *dac_deemphasis_txt[] = {
382 "Disabled", "32kHz", "44.1kHz", "48kHz"
383};
384
385static const struct soc_enum dac_deemphasis =
386SOC_ENUM_SINGLE(WM8900_REG_DACCTRL, 4, 4, dac_deemphasis_txt);
387
388static const char *adc_hpf_cut_txt[] = {
389 "Hi-fi mode", "Voice mode 1", "Voice mode 2", "Voice mode 3"
390};
391
392static const struct soc_enum adc_hpf_cut =
393SOC_ENUM_SINGLE(WM8900_REG_ADCCTRL, 5, 4, adc_hpf_cut_txt);
394
395static const char *lr_txt[] = {
396 "Left", "Right"
397};
398
399static const struct soc_enum aifl_src =
400SOC_ENUM_SINGLE(WM8900_REG_AUDIO1, 15, 2, lr_txt);
401
402static const struct soc_enum aifr_src =
403SOC_ENUM_SINGLE(WM8900_REG_AUDIO1, 14, 2, lr_txt);
404
405static const struct soc_enum dacl_src =
406SOC_ENUM_SINGLE(WM8900_REG_AUDIO2, 15, 2, lr_txt);
407
408static const struct soc_enum dacr_src =
409SOC_ENUM_SINGLE(WM8900_REG_AUDIO2, 14, 2, lr_txt);
410
411static const char *sidetone_txt[] = {
412 "Disabled", "Left ADC", "Right ADC"
413};
414
415static const struct soc_enum dacl_sidetone =
416SOC_ENUM_SINGLE(WM8900_REG_SIDETONE, 2, 3, sidetone_txt);
417
418static const struct soc_enum dacr_sidetone =
419SOC_ENUM_SINGLE(WM8900_REG_SIDETONE, 0, 3, sidetone_txt);
420
421static const struct snd_kcontrol_new wm8900_snd_controls[] = {
422SOC_ENUM("Mic Bias Level", mic_bias_level),
423
424SOC_SINGLE_TLV("Left Input PGA Volume", WM8900_REG_LINVOL, 0, 31, 0,
425 in_pga_tlv),
426SOC_SINGLE("Left Input PGA Switch", WM8900_REG_LINVOL, 6, 1, 1),
427SOC_SINGLE("Left Input PGA ZC Switch", WM8900_REG_LINVOL, 7, 1, 0),
428
429SOC_SINGLE_TLV("Right Input PGA Volume", WM8900_REG_RINVOL, 0, 31, 0,
430 in_pga_tlv),
431SOC_SINGLE("Right Input PGA Switch", WM8900_REG_RINVOL, 6, 1, 1),
432SOC_SINGLE("Right Input PGA ZC Switch", WM8900_REG_RINVOL, 7, 1, 0),
433
434SOC_SINGLE("DAC Soft Mute Switch", WM8900_REG_DACCTRL, 6, 1, 1),
435SOC_ENUM("DAC Mute Rate", dac_mute_rate),
436SOC_SINGLE("DAC Mono Switch", WM8900_REG_DACCTRL, 9, 1, 0),
437SOC_ENUM("DAC Deemphasis", dac_deemphasis),
438SOC_SINGLE("DAC Sloping Stopband Filter Switch", WM8900_REG_DACCTRL, 8, 1, 0),
439SOC_SINGLE("DAC Sigma-Delta Modulator Clock Switch", WM8900_REG_DACCTRL,
440 12, 1, 0),
441
442SOC_SINGLE("ADC HPF Switch", WM8900_REG_ADCCTRL, 8, 1, 0),
443SOC_ENUM("ADC HPF Cut-Off", adc_hpf_cut),
444SOC_DOUBLE("ADC Invert Switch", WM8900_REG_ADCCTRL, 1, 0, 1, 0),
445SOC_SINGLE_TLV("Left ADC Sidetone Volume", WM8900_REG_SIDETONE, 9, 12, 0,
446 adc_svol_tlv),
447SOC_SINGLE_TLV("Right ADC Sidetone Volume", WM8900_REG_SIDETONE, 5, 12, 0,
448 adc_svol_tlv),
449SOC_ENUM("Left Digital Audio Source", aifl_src),
450SOC_ENUM("Right Digital Audio Source", aifr_src),
451
452SOC_SINGLE_TLV("DAC Input Boost Volume", WM8900_REG_AUDIO2, 10, 4, 0,
453 dac_boost_tlv),
454SOC_ENUM("Left DAC Source", dacl_src),
455SOC_ENUM("Right DAC Source", dacr_src),
456SOC_ENUM("Left DAC Sidetone", dacl_sidetone),
457SOC_ENUM("Right DAC Sidetone", dacr_sidetone),
458SOC_DOUBLE("DAC Invert Switch", WM8900_REG_DACCTRL, 1, 0, 1, 0),
459
460SOC_DOUBLE_R_TLV("Digital Playback Volume",
461 WM8900_REG_LDAC_DV, WM8900_REG_RDAC_DV,
462 1, 96, 0, dac_tlv),
463SOC_DOUBLE_R_TLV("Digital Capture Volume",
464 WM8900_REG_LADC_DV, WM8900_REG_RADC_DV, 1, 119, 0, adc_tlv),
465
466SOC_SINGLE_TLV("LINPUT3 Bypass Volume", WM8900_REG_LOUTMIXCTL1, 4, 7, 0,
467 out_mix_tlv),
468SOC_SINGLE_TLV("RINPUT3 Bypass Volume", WM8900_REG_ROUTMIXCTL1, 4, 7, 0,
469 out_mix_tlv),
470SOC_SINGLE_TLV("Left AUX Bypass Volume", WM8900_REG_AUXOUT_CTL, 4, 7, 0,
471 out_mix_tlv),
472SOC_SINGLE_TLV("Right AUX Bypass Volume", WM8900_REG_AUXOUT_CTL, 0, 7, 0,
473 out_mix_tlv),
474
475SOC_SINGLE_TLV("LeftIn to RightOut Mixer Volume", WM8900_REG_BYPASS1, 0, 7, 0,
476 out_mix_tlv),
477SOC_SINGLE_TLV("LeftIn to LeftOut Mixer Volume", WM8900_REG_BYPASS1, 4, 7, 0,
478 out_mix_tlv),
479SOC_SINGLE_TLV("RightIn to LeftOut Mixer Volume", WM8900_REG_BYPASS2, 0, 7, 0,
480 out_mix_tlv),
481SOC_SINGLE_TLV("RightIn to RightOut Mixer Volume", WM8900_REG_BYPASS2, 4, 7, 0,
482 out_mix_tlv),
483
484SOC_SINGLE_TLV("IN2L Boost Volume", WM8900_REG_INBOOSTMIX1, 0, 3, 0,
485 in_boost_tlv),
486SOC_SINGLE_TLV("IN3L Boost Volume", WM8900_REG_INBOOSTMIX1, 4, 3, 0,
487 in_boost_tlv),
488SOC_SINGLE_TLV("IN2R Boost Volume", WM8900_REG_INBOOSTMIX2, 0, 3, 0,
489 in_boost_tlv),
490SOC_SINGLE_TLV("IN3R Boost Volume", WM8900_REG_INBOOSTMIX2, 4, 3, 0,
491 in_boost_tlv),
492SOC_SINGLE_TLV("Left AUX Boost Volume", WM8900_REG_AUXBOOST, 4, 3, 0,
493 in_boost_tlv),
494SOC_SINGLE_TLV("Right AUX Boost Volume", WM8900_REG_AUXBOOST, 0, 3, 0,
495 in_boost_tlv),
496
497SOC_DOUBLE_R_TLV("LINEOUT1 Volume", WM8900_REG_LOUT1CTL, WM8900_REG_ROUT1CTL,
498 0, 63, 0, out_pga_tlv),
499SOC_DOUBLE_R("LINEOUT1 Switch", WM8900_REG_LOUT1CTL, WM8900_REG_ROUT1CTL,
500 6, 1, 1),
501SOC_DOUBLE_R("LINEOUT1 ZC Switch", WM8900_REG_LOUT1CTL, WM8900_REG_ROUT1CTL,
502 7, 1, 0),
503
504SOC_DOUBLE_R_TLV("LINEOUT2 Volume",
505 WM8900_REG_LOUT2CTL, WM8900_REG_ROUT2CTL,
506 0, 63, 0, out_pga_tlv),
507SOC_DOUBLE_R("LINEOUT2 Switch",
508 WM8900_REG_LOUT2CTL, WM8900_REG_ROUT2CTL, 6, 1, 1),
509SOC_DOUBLE_R("LINEOUT2 ZC Switch",
510 WM8900_REG_LOUT2CTL, WM8900_REG_ROUT2CTL, 7, 1, 0),
511SOC_SINGLE("LINEOUT2 LP -12dB", WM8900_REG_LOUTMIXCTL1,
512 0, 1, 1),
513
514};
515
516/* add non dapm controls */
517static int wm8900_add_controls(struct snd_soc_codec *codec)
518{
519 int err, i;
520
521 for (i = 0; i < ARRAY_SIZE(wm8900_snd_controls); i++) {
522 err = snd_ctl_add(codec->card,
523 snd_soc_cnew(&wm8900_snd_controls[i],
524 codec, NULL));
525 if (err < 0)
526 return err;
527 }
528
529 return 0;
530}
531
532static const struct snd_kcontrol_new wm8900_dapm_loutput2_control =
533SOC_DAPM_SINGLE("LINEOUT2L Switch", WM8900_REG_POWER3, 6, 1, 0);
534
535static const struct snd_kcontrol_new wm8900_dapm_routput2_control =
536SOC_DAPM_SINGLE("LINEOUT2R Switch", WM8900_REG_POWER3, 5, 1, 0);
537
538static const struct snd_kcontrol_new wm8900_loutmix_controls[] = {
539SOC_DAPM_SINGLE("LINPUT3 Bypass Switch", WM8900_REG_LOUTMIXCTL1, 7, 1, 0),
540SOC_DAPM_SINGLE("AUX Bypass Switch", WM8900_REG_AUXOUT_CTL, 7, 1, 0),
541SOC_DAPM_SINGLE("Left Input Mixer Switch", WM8900_REG_BYPASS1, 7, 1, 0),
542SOC_DAPM_SINGLE("Right Input Mixer Switch", WM8900_REG_BYPASS2, 3, 1, 0),
543SOC_DAPM_SINGLE("DACL Switch", WM8900_REG_LOUTMIXCTL1, 8, 1, 0),
544};
545
546static const struct snd_kcontrol_new wm8900_routmix_controls[] = {
547SOC_DAPM_SINGLE("RINPUT3 Bypass Switch", WM8900_REG_ROUTMIXCTL1, 7, 1, 0),
548SOC_DAPM_SINGLE("AUX Bypass Switch", WM8900_REG_AUXOUT_CTL, 3, 1, 0),
549SOC_DAPM_SINGLE("Left Input Mixer Switch", WM8900_REG_BYPASS1, 3, 1, 0),
550SOC_DAPM_SINGLE("Right Input Mixer Switch", WM8900_REG_BYPASS2, 7, 1, 0),
551SOC_DAPM_SINGLE("DACR Switch", WM8900_REG_ROUTMIXCTL1, 8, 1, 0),
552};
553
554static const struct snd_kcontrol_new wm8900_linmix_controls[] = {
555SOC_DAPM_SINGLE("LINPUT2 Switch", WM8900_REG_INBOOSTMIX1, 2, 1, 1),
556SOC_DAPM_SINGLE("LINPUT3 Switch", WM8900_REG_INBOOSTMIX1, 6, 1, 1),
557SOC_DAPM_SINGLE("AUX Switch", WM8900_REG_AUXBOOST, 6, 1, 1),
558SOC_DAPM_SINGLE("Input PGA Switch", WM8900_REG_ADCPATH, 6, 1, 0),
559};
560
561static const struct snd_kcontrol_new wm8900_rinmix_controls[] = {
562SOC_DAPM_SINGLE("RINPUT2 Switch", WM8900_REG_INBOOSTMIX2, 2, 1, 1),
563SOC_DAPM_SINGLE("RINPUT3 Switch", WM8900_REG_INBOOSTMIX2, 6, 1, 1),
564SOC_DAPM_SINGLE("AUX Switch", WM8900_REG_AUXBOOST, 2, 1, 1),
565SOC_DAPM_SINGLE("Input PGA Switch", WM8900_REG_ADCPATH, 2, 1, 0),
566};
567
568static const struct snd_kcontrol_new wm8900_linpga_controls[] = {
569SOC_DAPM_SINGLE("LINPUT1 Switch", WM8900_REG_INCTL, 6, 1, 0),
570SOC_DAPM_SINGLE("LINPUT2 Switch", WM8900_REG_INCTL, 5, 1, 0),
571SOC_DAPM_SINGLE("LINPUT3 Switch", WM8900_REG_INCTL, 4, 1, 0),
572};
573
574static const struct snd_kcontrol_new wm8900_rinpga_controls[] = {
575SOC_DAPM_SINGLE("RINPUT1 Switch", WM8900_REG_INCTL, 2, 1, 0),
576SOC_DAPM_SINGLE("RINPUT2 Switch", WM8900_REG_INCTL, 1, 1, 0),
577SOC_DAPM_SINGLE("RINPUT3 Switch", WM8900_REG_INCTL, 0, 1, 0),
578};
579
580static const char *wm9700_lp_mux[] = { "Disabled", "Enabled" };
581
582static const struct soc_enum wm8900_lineout2_lp_mux =
583SOC_ENUM_SINGLE(WM8900_REG_LOUTMIXCTL1, 1, 2, wm9700_lp_mux);
584
585static const struct snd_kcontrol_new wm8900_lineout2_lp =
586SOC_DAPM_ENUM("Route", wm8900_lineout2_lp_mux);
587
588static const struct snd_soc_dapm_widget wm8900_dapm_widgets[] = {
589
590/* Externally visible pins */
591SND_SOC_DAPM_OUTPUT("LINEOUT1L"),
592SND_SOC_DAPM_OUTPUT("LINEOUT1R"),
593SND_SOC_DAPM_OUTPUT("LINEOUT2L"),
594SND_SOC_DAPM_OUTPUT("LINEOUT2R"),
595SND_SOC_DAPM_OUTPUT("HP_L"),
596SND_SOC_DAPM_OUTPUT("HP_R"),
597
598SND_SOC_DAPM_INPUT("RINPUT1"),
599SND_SOC_DAPM_INPUT("LINPUT1"),
600SND_SOC_DAPM_INPUT("RINPUT2"),
601SND_SOC_DAPM_INPUT("LINPUT2"),
602SND_SOC_DAPM_INPUT("RINPUT3"),
603SND_SOC_DAPM_INPUT("LINPUT3"),
604SND_SOC_DAPM_INPUT("AUX"),
605
606SND_SOC_DAPM_VMID("VMID"),
607
608/* Input */
609SND_SOC_DAPM_MIXER("Left Input PGA", WM8900_REG_POWER2, 3, 0,
610 wm8900_linpga_controls,
611 ARRAY_SIZE(wm8900_linpga_controls)),
612SND_SOC_DAPM_MIXER("Right Input PGA", WM8900_REG_POWER2, 2, 0,
613 wm8900_rinpga_controls,
614 ARRAY_SIZE(wm8900_rinpga_controls)),
615
616SND_SOC_DAPM_MIXER("Left Input Mixer", WM8900_REG_POWER2, 5, 0,
617 wm8900_linmix_controls,
618 ARRAY_SIZE(wm8900_linmix_controls)),
619SND_SOC_DAPM_MIXER("Right Input Mixer", WM8900_REG_POWER2, 4, 0,
620 wm8900_rinmix_controls,
621 ARRAY_SIZE(wm8900_rinmix_controls)),
622
623SND_SOC_DAPM_MICBIAS("Mic Bias", WM8900_REG_POWER1, 4, 0),
624
625SND_SOC_DAPM_ADC("ADCL", "Left HiFi Capture", WM8900_REG_POWER2, 1, 0),
626SND_SOC_DAPM_ADC("ADCR", "Right HiFi Capture", WM8900_REG_POWER2, 0, 0),
627
628/* Output */
629SND_SOC_DAPM_DAC("DACL", "Left HiFi Playback", WM8900_REG_POWER3, 1, 0),
630SND_SOC_DAPM_DAC("DACR", "Right HiFi Playback", WM8900_REG_POWER3, 0, 0),
631
632SND_SOC_DAPM_PGA_E("Headphone Amplifier", WM8900_REG_POWER3, 7, 0, NULL, 0,
633 wm8900_hp_event,
634 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
635 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
636
637SND_SOC_DAPM_PGA("LINEOUT1L PGA", WM8900_REG_POWER2, 8, 0, NULL, 0),
638SND_SOC_DAPM_PGA("LINEOUT1R PGA", WM8900_REG_POWER2, 7, 0, NULL, 0),
639
640SND_SOC_DAPM_MUX("LINEOUT2 LP", SND_SOC_NOPM, 0, 0, &wm8900_lineout2_lp),
641SND_SOC_DAPM_PGA("LINEOUT2L PGA", WM8900_REG_POWER3, 6, 0, NULL, 0),
642SND_SOC_DAPM_PGA("LINEOUT2R PGA", WM8900_REG_POWER3, 5, 0, NULL, 0),
643
644SND_SOC_DAPM_MIXER("Left Output Mixer", WM8900_REG_POWER3, 3, 0,
645 wm8900_loutmix_controls,
646 ARRAY_SIZE(wm8900_loutmix_controls)),
647SND_SOC_DAPM_MIXER("Right Output Mixer", WM8900_REG_POWER3, 2, 0,
648 wm8900_routmix_controls,
649 ARRAY_SIZE(wm8900_routmix_controls)),
650};
651
652/* Target, Path, Source */
653static const struct snd_soc_dapm_route audio_map[] = {
654/* Inputs */
655{"Left Input PGA", "LINPUT1 Switch", "LINPUT1"},
656{"Left Input PGA", "LINPUT2 Switch", "LINPUT2"},
657{"Left Input PGA", "LINPUT3 Switch", "LINPUT3"},
658
659{"Right Input PGA", "RINPUT1 Switch", "RINPUT1"},
660{"Right Input PGA", "RINPUT2 Switch", "RINPUT2"},
661{"Right Input PGA", "RINPUT3 Switch", "RINPUT3"},
662
663{"Left Input Mixer", "LINPUT2 Switch", "LINPUT2"},
664{"Left Input Mixer", "LINPUT3 Switch", "LINPUT3"},
665{"Left Input Mixer", "AUX Switch", "AUX"},
666{"Left Input Mixer", "Input PGA Switch", "Left Input PGA"},
667
668{"Right Input Mixer", "RINPUT2 Switch", "RINPUT2"},
669{"Right Input Mixer", "RINPUT3 Switch", "RINPUT3"},
670{"Right Input Mixer", "AUX Switch", "AUX"},
671{"Right Input Mixer", "Input PGA Switch", "Right Input PGA"},
672
673{"ADCL", NULL, "Left Input Mixer"},
674{"ADCR", NULL, "Right Input Mixer"},
675
676/* Outputs */
677{"LINEOUT1L", NULL, "LINEOUT1L PGA"},
678{"LINEOUT1L PGA", NULL, "Left Output Mixer"},
679{"LINEOUT1R", NULL, "LINEOUT1R PGA"},
680{"LINEOUT1R PGA", NULL, "Right Output Mixer"},
681
682{"LINEOUT2L PGA", NULL, "Left Output Mixer"},
683{"LINEOUT2 LP", "Disabled", "LINEOUT2L PGA"},
684{"LINEOUT2 LP", "Enabled", "Left Output Mixer"},
685{"LINEOUT2L", NULL, "LINEOUT2 LP"},
686
687{"LINEOUT2R PGA", NULL, "Right Output Mixer"},
688{"LINEOUT2 LP", "Disabled", "LINEOUT2R PGA"},
689{"LINEOUT2 LP", "Enabled", "Right Output Mixer"},
690{"LINEOUT2R", NULL, "LINEOUT2 LP"},
691
692{"Left Output Mixer", "LINPUT3 Bypass Switch", "LINPUT3"},
693{"Left Output Mixer", "AUX Bypass Switch", "AUX"},
694{"Left Output Mixer", "Left Input Mixer Switch", "Left Input Mixer"},
695{"Left Output Mixer", "Right Input Mixer Switch", "Right Input Mixer"},
696{"Left Output Mixer", "DACL Switch", "DACL"},
697
698{"Right Output Mixer", "RINPUT3 Bypass Switch", "RINPUT3"},
699{"Right Output Mixer", "AUX Bypass Switch", "AUX"},
700{"Right Output Mixer", "Left Input Mixer Switch", "Left Input Mixer"},
701{"Right Output Mixer", "Right Input Mixer Switch", "Right Input Mixer"},
702{"Right Output Mixer", "DACR Switch", "DACR"},
703
704/* Note that the headphone output stage needs to be connected
705 * externally to LINEOUT2 via DC blocking capacitors. Other
706 * configurations are not supported.
707 *
708 * Note also that left and right headphone paths are treated as a
709 * mono path.
710 */
711{"Headphone Amplifier", NULL, "LINEOUT2 LP"},
712{"Headphone Amplifier", NULL, "LINEOUT2 LP"},
713{"HP_L", NULL, "Headphone Amplifier"},
714{"HP_R", NULL, "Headphone Amplifier"},
715};
716
717static int wm8900_add_widgets(struct snd_soc_codec *codec)
718{
719 snd_soc_dapm_new_controls(codec, wm8900_dapm_widgets,
720 ARRAY_SIZE(wm8900_dapm_widgets));
721
722 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
723
724 snd_soc_dapm_new_widgets(codec);
725
726 return 0;
727}
728
729static int wm8900_hw_params(struct snd_pcm_substream *substream,
730 struct snd_pcm_hw_params *params)
731{
732 struct snd_soc_pcm_runtime *rtd = substream->private_data;
733 struct snd_soc_device *socdev = rtd->socdev;
734 struct snd_soc_codec *codec = socdev->codec;
735 u16 reg;
736
737 reg = wm8900_read(codec, WM8900_REG_AUDIO1) & ~0x60;
738
739 switch (params_format(params)) {
740 case SNDRV_PCM_FORMAT_S16_LE:
741 break;
742 case SNDRV_PCM_FORMAT_S20_3LE:
743 reg |= 0x20;
744 break;
745 case SNDRV_PCM_FORMAT_S24_LE:
746 reg |= 0x40;
747 break;
748 case SNDRV_PCM_FORMAT_S32_LE:
749 reg |= 0x60;
750 break;
751 default:
752 return -EINVAL;
753 }
754
755 wm8900_write(codec, WM8900_REG_AUDIO1, reg);
756
757 return 0;
758}
759
760/* FLL divisors */
761struct _fll_div {
762 u16 fll_ratio;
763 u16 fllclk_div;
764 u16 fll_slow_lock_ref;
765 u16 n;
766 u16 k;
767};
768
769/* The size in bits of the FLL divide multiplied by 10
770 * to allow rounding later */
771#define FIXED_FLL_SIZE ((1 << 16) * 10)
772
773static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
774 unsigned int Fout)
775{
776 u64 Kpart;
777 unsigned int K, Ndiv, Nmod, target;
778 unsigned int div;
779
780 BUG_ON(!Fout);
781
782 /* The FLL must run at 90-100MHz which is then scaled down to
783 * the output value by FLLCLK_DIV. */
784 target = Fout;
785 div = 1;
786 while (target < 90000000) {
787 div *= 2;
788 target *= 2;
789 }
790
791 if (target > 100000000)
792 printk(KERN_WARNING "wm8900: FLL rate %d out of range, Fref=%d"
793 " Fout=%d\n", target, Fref, Fout);
794 if (div > 32) {
795 printk(KERN_ERR "wm8900: Invalid FLL division rate %u, "
796 "Fref=%d, Fout=%d, target=%d\n",
797 div, Fref, Fout, target);
798 return -EINVAL;
799 }
800
801 fll_div->fllclk_div = div >> 2;
802
803 if (Fref < 48000)
804 fll_div->fll_slow_lock_ref = 1;
805 else
806 fll_div->fll_slow_lock_ref = 0;
807
808 Ndiv = target / Fref;
809
810 if (Fref < 1000000)
811 fll_div->fll_ratio = 8;
812 else
813 fll_div->fll_ratio = 1;
814
815 fll_div->n = Ndiv / fll_div->fll_ratio;
816 Nmod = (target / fll_div->fll_ratio) % Fref;
817
818 /* Calculate fractional part - scale up so we can round. */
819 Kpart = FIXED_FLL_SIZE * (long long)Nmod;
820
821 do_div(Kpart, Fref);
822
823 K = Kpart & 0xFFFFFFFF;
824
825 if ((K % 10) >= 5)
826 K += 5;
827
828 /* Move down to proper range now rounding is done */
829 fll_div->k = K / 10;
830
831 BUG_ON(target != Fout * (fll_div->fllclk_div << 2));
832 BUG_ON(!K && target != Fref * fll_div->fll_ratio * fll_div->n);
833
834 return 0;
835}
836
837static int wm8900_set_fll(struct snd_soc_codec *codec,
838 int fll_id, unsigned int freq_in, unsigned int freq_out)
839{
840 struct wm8900_priv *wm8900 = codec->private_data;
841 struct _fll_div fll_div;
842 unsigned int reg;
843
844 if (wm8900->fll_in == freq_in && wm8900->fll_out == freq_out)
845 return 0;
846
847 /* The digital side should be disabled during any change. */
848 reg = wm8900_read(codec, WM8900_REG_POWER1);
849 wm8900_write(codec, WM8900_REG_POWER1,
850 reg & (~WM8900_REG_POWER1_FLL_ENA));
851
852 /* Disable the FLL? */
853 if (!freq_in || !freq_out) {
854 reg = wm8900_read(codec, WM8900_REG_CLOCKING1);
855 wm8900_write(codec, WM8900_REG_CLOCKING1,
856 reg & (~WM8900_REG_CLOCKING1_MCLK_SRC));
857
858 reg = wm8900_read(codec, WM8900_REG_FLLCTL1);
859 wm8900_write(codec, WM8900_REG_FLLCTL1,
860 reg & (~WM8900_REG_FLLCTL1_OSC_ENA));
861
862 wm8900->fll_in = freq_in;
863 wm8900->fll_out = freq_out;
864
865 return 0;
866 }
867
868 if (fll_factors(&fll_div, freq_in, freq_out) != 0)
869 goto reenable;
870
871 wm8900->fll_in = freq_in;
872 wm8900->fll_out = freq_out;
873
874 /* The osclilator *MUST* be enabled before we enable the
875 * digital circuit. */
876 wm8900_write(codec, WM8900_REG_FLLCTL1,
877 fll_div.fll_ratio | WM8900_REG_FLLCTL1_OSC_ENA);
878
879 wm8900_write(codec, WM8900_REG_FLLCTL4, fll_div.n >> 5);
880 wm8900_write(codec, WM8900_REG_FLLCTL5,
881 (fll_div.fllclk_div << 6) | (fll_div.n & 0x1f));
882
883 if (fll_div.k) {
884 wm8900_write(codec, WM8900_REG_FLLCTL2,
885 (fll_div.k >> 8) | 0x100);
886 wm8900_write(codec, WM8900_REG_FLLCTL3, fll_div.k & 0xff);
887 } else
888 wm8900_write(codec, WM8900_REG_FLLCTL2, 0);
889
890 if (fll_div.fll_slow_lock_ref)
891 wm8900_write(codec, WM8900_REG_FLLCTL6,
892 WM8900_REG_FLLCTL6_FLL_SLOW_LOCK_REF);
893 else
894 wm8900_write(codec, WM8900_REG_FLLCTL6, 0);
895
896 reg = wm8900_read(codec, WM8900_REG_POWER1);
897 wm8900_write(codec, WM8900_REG_POWER1,
898 reg | WM8900_REG_POWER1_FLL_ENA);
899
900reenable:
901 reg = wm8900_read(codec, WM8900_REG_CLOCKING1);
902 wm8900_write(codec, WM8900_REG_CLOCKING1,
903 reg | WM8900_REG_CLOCKING1_MCLK_SRC);
904
905 return 0;
906}
907
908static int wm8900_set_dai_pll(struct snd_soc_dai *codec_dai,
909 int pll_id, unsigned int freq_in, unsigned int freq_out)
910{
911 return wm8900_set_fll(codec_dai->codec, pll_id, freq_in, freq_out);
912}
913
914static int wm8900_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
915 int div_id, int div)
916{
917 struct snd_soc_codec *codec = codec_dai->codec;
918 unsigned int reg;
919
920 switch (div_id) {
921 case WM8900_BCLK_DIV:
922 reg = wm8900_read(codec, WM8900_REG_CLOCKING1);
923 wm8900_write(codec, WM8900_REG_CLOCKING1,
924 div | (reg & WM8900_REG_CLOCKING1_BCLK_MASK));
925 break;
926 case WM8900_OPCLK_DIV:
927 reg = wm8900_read(codec, WM8900_REG_CLOCKING1);
928 wm8900_write(codec, WM8900_REG_CLOCKING1,
929 div | (reg & WM8900_REG_CLOCKING1_OPCLK_MASK));
930 break;
931 case WM8900_DAC_LRCLK:
932 reg = wm8900_read(codec, WM8900_REG_AUDIO4);
933 wm8900_write(codec, WM8900_REG_AUDIO4,
934 div | (reg & WM8900_LRC_MASK));
935 break;
936 case WM8900_ADC_LRCLK:
937 reg = wm8900_read(codec, WM8900_REG_AUDIO3);
938 wm8900_write(codec, WM8900_REG_AUDIO3,
939 div | (reg & WM8900_LRC_MASK));
940 break;
941 case WM8900_DAC_CLKDIV:
942 reg = wm8900_read(codec, WM8900_REG_CLOCKING2);
943 wm8900_write(codec, WM8900_REG_CLOCKING2,
944 div | (reg & WM8900_REG_CLOCKING2_DAC_CLKDIV));
945 break;
946 case WM8900_ADC_CLKDIV:
947 reg = wm8900_read(codec, WM8900_REG_CLOCKING2);
948 wm8900_write(codec, WM8900_REG_CLOCKING2,
949 div | (reg & WM8900_REG_CLOCKING2_ADC_CLKDIV));
950 break;
951 case WM8900_LRCLK_MODE:
952 reg = wm8900_read(codec, WM8900_REG_DACCTRL);
953 wm8900_write(codec, WM8900_REG_DACCTRL,
954 div | (reg & WM8900_REG_DACCTRL_AIF_LRCLKRATE));
955 break;
956 default:
957 return -EINVAL;
958 }
959
960 return 0;
961}
962
963
964static int wm8900_set_dai_fmt(struct snd_soc_dai *codec_dai,
965 unsigned int fmt)
966{
967 struct snd_soc_codec *codec = codec_dai->codec;
968 unsigned int clocking1, aif1, aif3, aif4;
969
970 clocking1 = wm8900_read(codec, WM8900_REG_CLOCKING1);
971 aif1 = wm8900_read(codec, WM8900_REG_AUDIO1);
972 aif3 = wm8900_read(codec, WM8900_REG_AUDIO3);
973 aif4 = wm8900_read(codec, WM8900_REG_AUDIO4);
974
975 /* set master/slave audio interface */
976 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
977 case SND_SOC_DAIFMT_CBS_CFS:
978 clocking1 &= ~WM8900_REG_CLOCKING1_BCLK_DIR;
979 aif3 &= ~WM8900_REG_AUDIO3_ADCLRC_DIR;
980 aif4 &= ~WM8900_REG_AUDIO4_DACLRC_DIR;
981 break;
982 case SND_SOC_DAIFMT_CBS_CFM:
983 clocking1 &= ~WM8900_REG_CLOCKING1_BCLK_DIR;
984 aif3 |= WM8900_REG_AUDIO3_ADCLRC_DIR;
985 aif4 |= WM8900_REG_AUDIO4_DACLRC_DIR;
986 break;
987 case SND_SOC_DAIFMT_CBM_CFM:
988 clocking1 |= WM8900_REG_CLOCKING1_BCLK_DIR;
989 aif3 |= WM8900_REG_AUDIO3_ADCLRC_DIR;
990 aif4 |= WM8900_REG_AUDIO4_DACLRC_DIR;
991 break;
992 case SND_SOC_DAIFMT_CBM_CFS:
993 clocking1 |= WM8900_REG_CLOCKING1_BCLK_DIR;
994 aif3 &= ~WM8900_REG_AUDIO3_ADCLRC_DIR;
995 aif4 &= ~WM8900_REG_AUDIO4_DACLRC_DIR;
996 break;
997 default:
998 return -EINVAL;
999 }
1000
1001 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1002 case SND_SOC_DAIFMT_DSP_A:
1003 aif1 |= WM8900_REG_AUDIO1_AIF_FMT_MASK;
1004 aif1 &= ~WM8900_REG_AUDIO1_LRCLK_INV;
1005 break;
1006 case SND_SOC_DAIFMT_DSP_B:
1007 aif1 |= WM8900_REG_AUDIO1_AIF_FMT_MASK;
1008 aif1 |= WM8900_REG_AUDIO1_LRCLK_INV;
1009 break;
1010 case SND_SOC_DAIFMT_I2S:
1011 aif1 &= ~WM8900_REG_AUDIO1_AIF_FMT_MASK;
1012 aif1 |= 0x10;
1013 break;
1014 case SND_SOC_DAIFMT_RIGHT_J:
1015 aif1 &= ~WM8900_REG_AUDIO1_AIF_FMT_MASK;
1016 break;
1017 case SND_SOC_DAIFMT_LEFT_J:
1018 aif1 &= ~WM8900_REG_AUDIO1_AIF_FMT_MASK;
1019 aif1 |= 0x8;
1020 break;
1021 default:
1022 return -EINVAL;
1023 }
1024
1025 /* Clock inversion */
1026 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1027 case SND_SOC_DAIFMT_DSP_A:
1028 case SND_SOC_DAIFMT_DSP_B:
1029 /* frame inversion not valid for DSP modes */
1030 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1031 case SND_SOC_DAIFMT_NB_NF:
1032 aif1 &= ~WM8900_REG_AUDIO1_BCLK_INV;
1033 break;
1034 case SND_SOC_DAIFMT_IB_NF:
1035 aif1 |= WM8900_REG_AUDIO1_BCLK_INV;
1036 break;
1037 default:
1038 return -EINVAL;
1039 }
1040 break;
1041 case SND_SOC_DAIFMT_I2S:
1042 case SND_SOC_DAIFMT_RIGHT_J:
1043 case SND_SOC_DAIFMT_LEFT_J:
1044 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1045 case SND_SOC_DAIFMT_NB_NF:
1046 aif1 &= ~WM8900_REG_AUDIO1_BCLK_INV;
1047 aif1 &= ~WM8900_REG_AUDIO1_LRCLK_INV;
1048 break;
1049 case SND_SOC_DAIFMT_IB_IF:
1050 aif1 |= WM8900_REG_AUDIO1_BCLK_INV;
1051 aif1 |= WM8900_REG_AUDIO1_LRCLK_INV;
1052 break;
1053 case SND_SOC_DAIFMT_IB_NF:
1054 aif1 |= WM8900_REG_AUDIO1_BCLK_INV;
1055 aif1 &= ~WM8900_REG_AUDIO1_LRCLK_INV;
1056 break;
1057 case SND_SOC_DAIFMT_NB_IF:
1058 aif1 &= ~WM8900_REG_AUDIO1_BCLK_INV;
1059 aif1 |= WM8900_REG_AUDIO1_LRCLK_INV;
1060 break;
1061 default:
1062 return -EINVAL;
1063 }
1064 break;
1065 default:
1066 return -EINVAL;
1067 }
1068
1069 wm8900_write(codec, WM8900_REG_CLOCKING1, clocking1);
1070 wm8900_write(codec, WM8900_REG_AUDIO1, aif1);
1071 wm8900_write(codec, WM8900_REG_AUDIO3, aif3);
1072 wm8900_write(codec, WM8900_REG_AUDIO4, aif4);
1073
1074 return 0;
1075}
1076
1077static int wm8900_digital_mute(struct snd_soc_dai *codec_dai, int mute)
1078{
1079 struct snd_soc_codec *codec = codec_dai->codec;
1080 u16 reg;
1081
1082 reg = wm8900_read(codec, WM8900_REG_DACCTRL);
1083
1084 if (mute)
1085 reg |= WM8900_REG_DACCTRL_MUTE;
1086 else
1087 reg &= ~WM8900_REG_DACCTRL_MUTE;
1088
1089 wm8900_write(codec, WM8900_REG_DACCTRL, reg);
1090
1091 return 0;
1092}
1093
1094#define WM8900_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
1095 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
1096 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
1097
1098#define WM8900_PCM_FORMATS \
1099 (SNDRV_PCM_FORMAT_S16_LE | SNDRV_PCM_FORMAT_S20_3LE | \
1100 SNDRV_PCM_FORMAT_S24_LE)
1101
1102struct snd_soc_dai wm8900_dai = {
1103 .name = "WM8900 HiFi",
1104 .playback = {
1105 .stream_name = "HiFi Playback",
1106 .channels_min = 1,
1107 .channels_max = 2,
1108 .rates = WM8900_RATES,
1109 .formats = WM8900_PCM_FORMATS,
1110 },
1111 .capture = {
1112 .stream_name = "HiFi Capture",
1113 .channels_min = 1,
1114 .channels_max = 2,
1115 .rates = WM8900_RATES,
1116 .formats = WM8900_PCM_FORMATS,
1117 },
1118 .ops = {
1119 .hw_params = wm8900_hw_params,
1120 },
1121 .dai_ops = {
1122 .set_clkdiv = wm8900_set_dai_clkdiv,
1123 .set_pll = wm8900_set_dai_pll,
1124 .set_fmt = wm8900_set_dai_fmt,
1125 .digital_mute = wm8900_digital_mute,
1126 },
1127};
1128EXPORT_SYMBOL_GPL(wm8900_dai);
1129
1130static int wm8900_set_bias_level(struct snd_soc_codec *codec,
1131 enum snd_soc_bias_level level)
1132{
1133 u16 reg;
1134
1135 switch (level) {
1136 case SND_SOC_BIAS_ON:
1137 /* Enable thermal shutdown */
1138 reg = wm8900_read(codec, WM8900_REG_GPIO);
1139 wm8900_write(codec, WM8900_REG_GPIO,
1140 reg | WM8900_REG_GPIO_TEMP_ENA);
1141 reg = wm8900_read(codec, WM8900_REG_ADDCTL);
1142 wm8900_write(codec, WM8900_REG_ADDCTL,
1143 reg | WM8900_REG_ADDCTL_TEMP_SD);
1144 break;
1145
1146 case SND_SOC_BIAS_PREPARE:
1147 break;
1148
1149 case SND_SOC_BIAS_STANDBY:
1150 /* Charge capacitors if initial power up */
1151 if (codec->bias_level == SND_SOC_BIAS_OFF) {
1152 /* STARTUP_BIAS_ENA on */
1153 wm8900_write(codec, WM8900_REG_POWER1,
1154 WM8900_REG_POWER1_STARTUP_BIAS_ENA);
1155
1156 /* Startup bias mode */
1157 wm8900_write(codec, WM8900_REG_ADDCTL,
1158 WM8900_REG_ADDCTL_BIAS_SRC |
1159 WM8900_REG_ADDCTL_VMID_SOFTST);
1160
1161 /* VMID 2x50k */
1162 wm8900_write(codec, WM8900_REG_POWER1,
1163 WM8900_REG_POWER1_STARTUP_BIAS_ENA | 0x1);
1164
1165 /* Allow capacitors to charge */
1166 schedule_timeout_interruptible(msecs_to_jiffies(400));
1167
1168 /* Enable bias */
1169 wm8900_write(codec, WM8900_REG_POWER1,
1170 WM8900_REG_POWER1_STARTUP_BIAS_ENA |
1171 WM8900_REG_POWER1_BIAS_ENA | 0x1);
1172
1173 wm8900_write(codec, WM8900_REG_ADDCTL, 0);
1174
1175 wm8900_write(codec, WM8900_REG_POWER1,
1176 WM8900_REG_POWER1_BIAS_ENA | 0x1);
1177 }
1178
1179 reg = wm8900_read(codec, WM8900_REG_POWER1);
1180 wm8900_write(codec, WM8900_REG_POWER1,
1181 (reg & WM8900_REG_POWER1_FLL_ENA) |
1182 WM8900_REG_POWER1_BIAS_ENA | 0x1);
1183 wm8900_write(codec, WM8900_REG_POWER2,
1184 WM8900_REG_POWER2_SYSCLK_ENA);
1185 wm8900_write(codec, WM8900_REG_POWER3, 0);
1186 break;
1187
1188 case SND_SOC_BIAS_OFF:
1189 /* Startup bias enable */
1190 reg = wm8900_read(codec, WM8900_REG_POWER1);
1191 wm8900_write(codec, WM8900_REG_POWER1,
1192 reg & WM8900_REG_POWER1_STARTUP_BIAS_ENA);
1193 wm8900_write(codec, WM8900_REG_ADDCTL,
1194 WM8900_REG_ADDCTL_BIAS_SRC |
1195 WM8900_REG_ADDCTL_VMID_SOFTST);
1196
1197 /* Discharge caps */
1198 wm8900_write(codec, WM8900_REG_POWER1,
1199 WM8900_REG_POWER1_STARTUP_BIAS_ENA);
1200 schedule_timeout_interruptible(msecs_to_jiffies(500));
1201
1202 /* Remove clamp */
1203 wm8900_write(codec, WM8900_REG_HPCTL1, 0);
1204
1205 /* Power down */
1206 wm8900_write(codec, WM8900_REG_ADDCTL, 0);
1207 wm8900_write(codec, WM8900_REG_POWER1, 0);
1208 wm8900_write(codec, WM8900_REG_POWER2, 0);
1209 wm8900_write(codec, WM8900_REG_POWER3, 0);
1210
1211 /* Need to let things settle before stopping the clock
1212 * to ensure that restart works, see "Stopping the
1213 * master clock" in the datasheet. */
1214 schedule_timeout_interruptible(msecs_to_jiffies(1));
1215 wm8900_write(codec, WM8900_REG_POWER2,
1216 WM8900_REG_POWER2_SYSCLK_ENA);
1217 break;
1218 }
1219 codec->bias_level = level;
1220 return 0;
1221}
1222
1223static int wm8900_suspend(struct platform_device *pdev, pm_message_t state)
1224{
1225 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1226 struct snd_soc_codec *codec = socdev->codec;
1227 struct wm8900_priv *wm8900 = codec->private_data;
1228 int fll_out = wm8900->fll_out;
1229 int fll_in = wm8900->fll_in;
1230 int ret;
1231
1232 /* Stop the FLL in an orderly fashion */
1233 ret = wm8900_set_fll(codec, 0, 0, 0);
1234 if (ret != 0) {
1235 dev_err(&pdev->dev, "Failed to stop FLL\n");
1236 return ret;
1237 }
1238
1239 wm8900->fll_out = fll_out;
1240 wm8900->fll_in = fll_in;
1241
1242 wm8900_set_bias_level(codec, SND_SOC_BIAS_OFF);
1243
1244 return 0;
1245}
1246
1247static int wm8900_resume(struct platform_device *pdev)
1248{
1249 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1250 struct snd_soc_codec *codec = socdev->codec;
1251 struct wm8900_priv *wm8900 = codec->private_data;
1252 u16 *cache;
1253 int i, ret;
1254
1255 cache = kmemdup(codec->reg_cache, sizeof(wm8900_reg_defaults),
1256 GFP_KERNEL);
1257
1258 wm8900_reset(codec);
1259 wm8900_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1260
1261 /* Restart the FLL? */
1262 if (wm8900->fll_out) {
1263 int fll_out = wm8900->fll_out;
1264 int fll_in = wm8900->fll_in;
1265
1266 wm8900->fll_in = 0;
1267 wm8900->fll_out = 0;
1268
1269 ret = wm8900_set_fll(codec, 0, fll_in, fll_out);
1270 if (ret != 0) {
1271 dev_err(&pdev->dev, "Failed to restart FLL\n");
1272 return ret;
1273 }
1274 }
1275
1276 if (cache) {
1277 for (i = 0; i < WM8900_MAXREG; i++)
1278 wm8900_write(codec, i, cache[i]);
1279 kfree(cache);
1280 } else
1281 dev_err(&pdev->dev, "Unable to allocate register cache\n");
1282
1283 return 0;
1284}
1285
1286/*
1287 * initialise the WM8900 driver
1288 * register the mixer and dsp interfaces with the kernel
1289 */
1290static int wm8900_init(struct snd_soc_device *socdev)
1291{
1292 struct snd_soc_codec *codec = socdev->codec;
1293 int ret = 0;
1294 unsigned int reg;
1295 struct i2c_client *i2c_client = socdev->codec->control_data;
1296
1297 codec->name = "WM8900";
1298 codec->owner = THIS_MODULE;
1299 codec->read = wm8900_read;
1300 codec->write = wm8900_write;
1301 codec->dai = &wm8900_dai;
1302 codec->num_dai = 1;
1303 codec->reg_cache_size = WM8900_MAXREG;
1304 codec->reg_cache = kmemdup(wm8900_reg_defaults,
1305 sizeof(wm8900_reg_defaults), GFP_KERNEL);
1306
1307 if (codec->reg_cache == NULL)
1308 return -ENOMEM;
1309
1310 reg = wm8900_read(codec, WM8900_REG_ID);
1311 if (reg != 0x8900) {
1312 dev_err(&i2c_client->dev, "Device is not a WM8900 - ID %x\n",
1313 reg);
1314 return -ENODEV;
1315 }
1316
1317 codec->private_data = kzalloc(sizeof(struct wm8900_priv), GFP_KERNEL);
1318 if (codec->private_data == NULL) {
1319 ret = -ENOMEM;
1320 goto priv_err;
1321 }
1322
1323 /* Read back from the chip */
1324 reg = wm8900_chip_read(codec, WM8900_REG_POWER1);
1325 reg = (reg >> 12) & 0xf;
1326 dev_info(&i2c_client->dev, "WM8900 revision %d\n", reg);
1327
1328 wm8900_reset(codec);
1329
1330 /* Latch the volume update bits */
1331 wm8900_write(codec, WM8900_REG_LINVOL,
1332 wm8900_read(codec, WM8900_REG_LINVOL) | 0x100);
1333 wm8900_write(codec, WM8900_REG_RINVOL,
1334 wm8900_read(codec, WM8900_REG_RINVOL) | 0x100);
1335 wm8900_write(codec, WM8900_REG_LOUT1CTL,
1336 wm8900_read(codec, WM8900_REG_LOUT1CTL) | 0x100);
1337 wm8900_write(codec, WM8900_REG_ROUT1CTL,
1338 wm8900_read(codec, WM8900_REG_ROUT1CTL) | 0x100);
1339 wm8900_write(codec, WM8900_REG_LOUT2CTL,
1340 wm8900_read(codec, WM8900_REG_LOUT2CTL) | 0x100);
1341 wm8900_write(codec, WM8900_REG_ROUT2CTL,
1342 wm8900_read(codec, WM8900_REG_ROUT2CTL) | 0x100);
1343 wm8900_write(codec, WM8900_REG_LDAC_DV,
1344 wm8900_read(codec, WM8900_REG_LDAC_DV) | 0x100);
1345 wm8900_write(codec, WM8900_REG_RDAC_DV,
1346 wm8900_read(codec, WM8900_REG_RDAC_DV) | 0x100);
1347 wm8900_write(codec, WM8900_REG_LADC_DV,
1348 wm8900_read(codec, WM8900_REG_LADC_DV) | 0x100);
1349 wm8900_write(codec, WM8900_REG_RADC_DV,
1350 wm8900_read(codec, WM8900_REG_RADC_DV) | 0x100);
1351
1352 /* Set the DAC and mixer output bias */
1353 wm8900_write(codec, WM8900_REG_OUTBIASCTL, 0x81);
1354
1355 /* Register pcms */
1356 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1357 if (ret < 0) {
1358 dev_err(&i2c_client->dev, "Failed to register new PCMs\n");
1359 goto pcm_err;
1360 }
1361
1362 /* Turn the chip on */
1363 codec->bias_level = SND_SOC_BIAS_OFF;
1364 wm8900_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1365
1366 wm8900_add_controls(codec);
1367 wm8900_add_widgets(codec);
1368
1369 ret = snd_soc_register_card(socdev);
1370 if (ret < 0) {
1371 dev_err(&i2c_client->dev, "Failed to register card\n");
1372 goto card_err;
1373 }
1374 return ret;
1375
1376card_err:
1377 snd_soc_free_pcms(socdev);
1378 snd_soc_dapm_free(socdev);
1379pcm_err:
1380 kfree(codec->reg_cache);
1381priv_err:
1382 kfree(codec->private_data);
1383 return ret;
1384}
1385
1386static struct snd_soc_device *wm8900_socdev;
1387
1388#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1389
1390static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
1391
1392/* Magic definition of all other variables and things */
1393I2C_CLIENT_INSMOD;
1394
1395static struct i2c_driver wm8900_i2c_driver;
1396static struct i2c_client client_template;
1397
1398/* If the i2c layer weren't so broken, we could pass this kind of data
1399 around */
1400static int wm8900_codec_probe(struct i2c_adapter *adap, int addr, int kind)
1401{
1402 struct snd_soc_device *socdev = wm8900_socdev;
1403 struct wm8900_setup_data *setup = socdev->codec_data;
1404 struct snd_soc_codec *codec = socdev->codec;
1405 struct i2c_client *i2c;
1406 int ret;
1407
1408 if (addr != setup->i2c_address)
1409 return -ENODEV;
1410
1411 dev_err(&adap->dev, "Probe on %x\n", addr);
1412
1413 client_template.adapter = adap;
1414 client_template.addr = addr;
1415
1416 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
1417 if (i2c == NULL) {
1418 kfree(codec);
1419 return -ENOMEM;
1420 }
1421 i2c_set_clientdata(i2c, codec);
1422 codec->control_data = i2c;
1423
1424 ret = i2c_attach_client(i2c);
1425 if (ret < 0) {
1426 dev_err(&adap->dev,
1427 "failed to attach codec at addr %x\n", addr);
1428 goto err;
1429 }
1430
1431 ret = wm8900_init(socdev);
1432 if (ret < 0) {
1433 dev_err(&adap->dev, "failed to initialise WM8900\n");
1434 goto err;
1435 }
1436 return ret;
1437
1438err:
1439 kfree(codec);
1440 kfree(i2c);
1441 return ret;
1442}
1443
1444static int wm8900_i2c_detach(struct i2c_client *client)
1445{
1446 struct snd_soc_codec *codec = i2c_get_clientdata(client);
1447 i2c_detach_client(client);
1448 kfree(codec->reg_cache);
1449 kfree(client);
1450 return 0;
1451}
1452
1453static int wm8900_i2c_attach(struct i2c_adapter *adap)
1454{
1455 return i2c_probe(adap, &addr_data, wm8900_codec_probe);
1456}
1457
1458/* corgi i2c codec control layer */
1459static struct i2c_driver wm8900_i2c_driver = {
1460 .driver = {
1461 .name = "WM8900 I2C codec",
1462 .owner = THIS_MODULE,
1463 },
1464 .attach_adapter = wm8900_i2c_attach,
1465 .detach_client = wm8900_i2c_detach,
1466 .command = NULL,
1467};
1468
1469static struct i2c_client client_template = {
1470 .name = "WM8900",
1471 .driver = &wm8900_i2c_driver,
1472};
1473#endif
1474
1475static int wm8900_probe(struct platform_device *pdev)
1476{
1477 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1478 struct wm8900_setup_data *setup;
1479 struct snd_soc_codec *codec;
1480 int ret = 0;
1481
1482 dev_info(&pdev->dev, "WM8900 Audio Codec\n");
1483
1484 setup = socdev->codec_data;
1485 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
1486 if (codec == NULL)
1487 return -ENOMEM;
1488
1489 mutex_init(&codec->mutex);
1490 INIT_LIST_HEAD(&codec->dapm_widgets);
1491 INIT_LIST_HEAD(&codec->dapm_paths);
1492
1493 socdev->codec = codec;
1494
1495 codec->set_bias_level = wm8900_set_bias_level;
1496
1497 wm8900_socdev = socdev;
1498#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1499 if (setup->i2c_address) {
1500 normal_i2c[0] = setup->i2c_address;
1501 codec->hw_write = (hw_write_t)i2c_master_send;
1502 ret = i2c_add_driver(&wm8900_i2c_driver);
1503 if (ret != 0)
1504 printk(KERN_ERR "can't add i2c driver");
1505 }
1506#else
1507#error Non-I2C interfaces not yet supported
1508#endif
1509 return ret;
1510}
1511
1512/* power down chip */
1513static int wm8900_remove(struct platform_device *pdev)
1514{
1515 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1516 struct snd_soc_codec *codec = socdev->codec;
1517
1518 if (codec->control_data)
1519 wm8900_set_bias_level(codec, SND_SOC_BIAS_OFF);
1520
1521 snd_soc_free_pcms(socdev);
1522 snd_soc_dapm_free(socdev);
1523#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1524 i2c_del_driver(&wm8900_i2c_driver);
1525#endif
1526 kfree(codec);
1527
1528 return 0;
1529}
1530
1531struct snd_soc_codec_device soc_codec_dev_wm8900 = {
1532 .probe = wm8900_probe,
1533 .remove = wm8900_remove,
1534 .suspend = wm8900_suspend,
1535 .resume = wm8900_resume,
1536};
1537EXPORT_SYMBOL_GPL(soc_codec_dev_wm8900);
1538
1539MODULE_DESCRIPTION("ASoC WM8900 driver");
1540MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfonmicro.com>");
1541MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8900.h b/sound/soc/codecs/wm8900.h
new file mode 100644
index 000000000000..ba450d99e902
--- /dev/null
+++ b/sound/soc/codecs/wm8900.h
@@ -0,0 +1,64 @@
1/*
2 * wm8900.h -- WM890 Soc Audio driver
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#ifndef _WM8900_H
10#define _WM8900_H
11
12#define WM8900_FLL 1
13
14#define WM8900_BCLK_DIV 1
15#define WM8900_ADC_CLKDIV 2
16#define WM8900_DAC_CLKDIV 3
17#define WM8900_ADC_LRCLK 4
18#define WM8900_DAC_LRCLK 5
19#define WM8900_OPCLK_DIV 6
20#define WM8900_LRCLK_MODE 7
21
22#define WM8900_BCLK_DIV_1 0x00
23#define WM8900_BCLK_DIV_1_5 0x02
24#define WM8900_BCLK_DIV_2 0x04
25#define WM8900_BCLK_DIV_3 0x06
26#define WM8900_BCLK_DIV_4 0x08
27#define WM8900_BCLK_DIV_5_5 0x0a
28#define WM8900_BCLK_DIV_6 0x0c
29#define WM8900_BCLK_DIV_8 0x0e
30#define WM8900_BCLK_DIV_11 0x10
31#define WM8900_BCLK_DIV_12 0x12
32#define WM8900_BCLK_DIV_16 0x14
33#define WM8900_BCLK_DIV_22 0x16
34#define WM8900_BCLK_DIV_24 0x18
35#define WM8900_BCLK_DIV_32 0x1a
36#define WM8900_BCLK_DIV_44 0x1c
37#define WM8900_BCLK_DIV_48 0x1e
38
39#define WM8900_ADC_CLKDIV_1 0x00
40#define WM8900_ADC_CLKDIV_1_5 0x20
41#define WM8900_ADC_CLKDIV_2 0x40
42#define WM8900_ADC_CLKDIV_3 0x60
43#define WM8900_ADC_CLKDIV_4 0x80
44#define WM8900_ADC_CLKDIV_5_5 0xa0
45#define WM8900_ADC_CLKDIV_6 0xc0
46
47#define WM8900_DAC_CLKDIV_1 0x00
48#define WM8900_DAC_CLKDIV_1_5 0x04
49#define WM8900_DAC_CLKDIV_2 0x08
50#define WM8900_DAC_CLKDIV_3 0x0c
51#define WM8900_DAC_CLKDIV_4 0x10
52#define WM8900_DAC_CLKDIV_5_5 0x14
53#define WM8900_DAC_CLKDIV_6 0x18
54
55#define WM8900_
56
57struct wm8900_setup_data {
58 unsigned short i2c_address;
59};
60
61extern struct snd_soc_dai wm8900_dai;
62extern struct snd_soc_codec_device soc_codec_dev_wm8900;
63
64#endif
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
new file mode 100644
index 000000000000..ce40d7877605
--- /dev/null
+++ b/sound/soc/codecs/wm8903.c
@@ -0,0 +1,1813 @@
1/*
2 * wm8903.c -- WM8903 ALSA SoC Audio driver
3 *
4 * Copyright 2008 Wolfson Microelectronics
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * TODO:
13 * - TDM mode configuration.
14 * - Mic detect.
15 * - Digital microphone support.
16 * - Interrupt support (mic detect and sequencer).
17 */
18
19#include <linux/module.h>
20#include <linux/moduleparam.h>
21#include <linux/init.h>
22#include <linux/delay.h>
23#include <linux/pm.h>
24#include <linux/i2c.h>
25#include <linux/platform_device.h>
26#include <sound/core.h>
27#include <sound/pcm.h>
28#include <sound/pcm_params.h>
29#include <sound/tlv.h>
30#include <sound/soc.h>
31#include <sound/soc-dapm.h>
32#include <sound/initval.h>
33
34#include "wm8903.h"
35
36struct wm8903_priv {
37 int sysclk;
38
39 /* Reference counts */
40 int charge_pump_users;
41 int class_w_users;
42 int playback_active;
43 int capture_active;
44
45 struct snd_pcm_substream *master_substream;
46 struct snd_pcm_substream *slave_substream;
47};
48
49/* Register defaults at reset */
50static u16 wm8903_reg_defaults[] = {
51 0x8903, /* R0 - SW Reset and ID */
52 0x0000, /* R1 - Revision Number */
53 0x0000, /* R2 */
54 0x0000, /* R3 */
55 0x0018, /* R4 - Bias Control 0 */
56 0x0000, /* R5 - VMID Control 0 */
57 0x0000, /* R6 - Mic Bias Control 0 */
58 0x0000, /* R7 */
59 0x0001, /* R8 - Analogue DAC 0 */
60 0x0000, /* R9 */
61 0x0001, /* R10 - Analogue ADC 0 */
62 0x0000, /* R11 */
63 0x0000, /* R12 - Power Management 0 */
64 0x0000, /* R13 - Power Management 1 */
65 0x0000, /* R14 - Power Management 2 */
66 0x0000, /* R15 - Power Management 3 */
67 0x0000, /* R16 - Power Management 4 */
68 0x0000, /* R17 - Power Management 5 */
69 0x0000, /* R18 - Power Management 6 */
70 0x0000, /* R19 */
71 0x0400, /* R20 - Clock Rates 0 */
72 0x0D07, /* R21 - Clock Rates 1 */
73 0x0000, /* R22 - Clock Rates 2 */
74 0x0000, /* R23 */
75 0x0050, /* R24 - Audio Interface 0 */
76 0x0242, /* R25 - Audio Interface 1 */
77 0x0008, /* R26 - Audio Interface 2 */
78 0x0022, /* R27 - Audio Interface 3 */
79 0x0000, /* R28 */
80 0x0000, /* R29 */
81 0x00C0, /* R30 - DAC Digital Volume Left */
82 0x00C0, /* R31 - DAC Digital Volume Right */
83 0x0000, /* R32 - DAC Digital 0 */
84 0x0000, /* R33 - DAC Digital 1 */
85 0x0000, /* R34 */
86 0x0000, /* R35 */
87 0x00C0, /* R36 - ADC Digital Volume Left */
88 0x00C0, /* R37 - ADC Digital Volume Right */
89 0x0000, /* R38 - ADC Digital 0 */
90 0x0073, /* R39 - Digital Microphone 0 */
91 0x09BF, /* R40 - DRC 0 */
92 0x3241, /* R41 - DRC 1 */
93 0x0020, /* R42 - DRC 2 */
94 0x0000, /* R43 - DRC 3 */
95 0x0085, /* R44 - Analogue Left Input 0 */
96 0x0085, /* R45 - Analogue Right Input 0 */
97 0x0044, /* R46 - Analogue Left Input 1 */
98 0x0044, /* R47 - Analogue Right Input 1 */
99 0x0000, /* R48 */
100 0x0000, /* R49 */
101 0x0008, /* R50 - Analogue Left Mix 0 */
102 0x0004, /* R51 - Analogue Right Mix 0 */
103 0x0000, /* R52 - Analogue Spk Mix Left 0 */
104 0x0000, /* R53 - Analogue Spk Mix Left 1 */
105 0x0000, /* R54 - Analogue Spk Mix Right 0 */
106 0x0000, /* R55 - Analogue Spk Mix Right 1 */
107 0x0000, /* R56 */
108 0x002D, /* R57 - Analogue OUT1 Left */
109 0x002D, /* R58 - Analogue OUT1 Right */
110 0x0039, /* R59 - Analogue OUT2 Left */
111 0x0039, /* R60 - Analogue OUT2 Right */
112 0x0100, /* R61 */
113 0x0139, /* R62 - Analogue OUT3 Left */
114 0x0139, /* R63 - Analogue OUT3 Right */
115 0x0000, /* R64 */
116 0x0000, /* R65 - Analogue SPK Output Control 0 */
117 0x0000, /* R66 */
118 0x0010, /* R67 - DC Servo 0 */
119 0x0100, /* R68 */
120 0x00A4, /* R69 - DC Servo 2 */
121 0x0807, /* R70 */
122 0x0000, /* R71 */
123 0x0000, /* R72 */
124 0x0000, /* R73 */
125 0x0000, /* R74 */
126 0x0000, /* R75 */
127 0x0000, /* R76 */
128 0x0000, /* R77 */
129 0x0000, /* R78 */
130 0x000E, /* R79 */
131 0x0000, /* R80 */
132 0x0000, /* R81 */
133 0x0000, /* R82 */
134 0x0000, /* R83 */
135 0x0000, /* R84 */
136 0x0000, /* R85 */
137 0x0000, /* R86 */
138 0x0006, /* R87 */
139 0x0000, /* R88 */
140 0x0000, /* R89 */
141 0x0000, /* R90 - Analogue HP 0 */
142 0x0060, /* R91 */
143 0x0000, /* R92 */
144 0x0000, /* R93 */
145 0x0000, /* R94 - Analogue Lineout 0 */
146 0x0060, /* R95 */
147 0x0000, /* R96 */
148 0x0000, /* R97 */
149 0x0000, /* R98 - Charge Pump 0 */
150 0x1F25, /* R99 */
151 0x2B19, /* R100 */
152 0x01C0, /* R101 */
153 0x01EF, /* R102 */
154 0x2B00, /* R103 */
155 0x0000, /* R104 - Class W 0 */
156 0x01C0, /* R105 */
157 0x1C10, /* R106 */
158 0x0000, /* R107 */
159 0x0000, /* R108 - Write Sequencer 0 */
160 0x0000, /* R109 - Write Sequencer 1 */
161 0x0000, /* R110 - Write Sequencer 2 */
162 0x0000, /* R111 - Write Sequencer 3 */
163 0x0000, /* R112 - Write Sequencer 4 */
164 0x0000, /* R113 */
165 0x0000, /* R114 - Control Interface */
166 0x0000, /* R115 */
167 0x00A8, /* R116 - GPIO Control 1 */
168 0x00A8, /* R117 - GPIO Control 2 */
169 0x00A8, /* R118 - GPIO Control 3 */
170 0x0220, /* R119 - GPIO Control 4 */
171 0x01A0, /* R120 - GPIO Control 5 */
172 0x0000, /* R121 - Interrupt Status 1 */
173 0xFFFF, /* R122 - Interrupt Status 1 Mask */
174 0x0000, /* R123 - Interrupt Polarity 1 */
175 0x0000, /* R124 */
176 0x0003, /* R125 */
177 0x0000, /* R126 - Interrupt Control */
178 0x0000, /* R127 */
179 0x0005, /* R128 */
180 0x0000, /* R129 - Control Interface Test 1 */
181 0x0000, /* R130 */
182 0x0000, /* R131 */
183 0x0000, /* R132 */
184 0x0000, /* R133 */
185 0x0000, /* R134 */
186 0x03FF, /* R135 */
187 0x0007, /* R136 */
188 0x0040, /* R137 */
189 0x0000, /* R138 */
190 0x0000, /* R139 */
191 0x0000, /* R140 */
192 0x0000, /* R141 */
193 0x0000, /* R142 */
194 0x0000, /* R143 */
195 0x0000, /* R144 */
196 0x0000, /* R145 */
197 0x0000, /* R146 */
198 0x0000, /* R147 */
199 0x4000, /* R148 */
200 0x6810, /* R149 - Charge Pump Test 1 */
201 0x0004, /* R150 */
202 0x0000, /* R151 */
203 0x0000, /* R152 */
204 0x0000, /* R153 */
205 0x0000, /* R154 */
206 0x0000, /* R155 */
207 0x0000, /* R156 */
208 0x0000, /* R157 */
209 0x0000, /* R158 */
210 0x0000, /* R159 */
211 0x0000, /* R160 */
212 0x0000, /* R161 */
213 0x0000, /* R162 */
214 0x0000, /* R163 */
215 0x0028, /* R164 - Clock Rate Test 4 */
216 0x0004, /* R165 */
217 0x0000, /* R166 */
218 0x0060, /* R167 */
219 0x0000, /* R168 */
220 0x0000, /* R169 */
221 0x0000, /* R170 */
222 0x0000, /* R171 */
223 0x0000, /* R172 - Analogue Output Bias 0 */
224};
225
226static unsigned int wm8903_read_reg_cache(struct snd_soc_codec *codec,
227 unsigned int reg)
228{
229 u16 *cache = codec->reg_cache;
230
231 BUG_ON(reg >= ARRAY_SIZE(wm8903_reg_defaults));
232
233 return cache[reg];
234}
235
236static unsigned int wm8903_hw_read(struct snd_soc_codec *codec, u8 reg)
237{
238 struct i2c_msg xfer[2];
239 u16 data;
240 int ret;
241 struct i2c_client *client = codec->control_data;
242
243 /* Write register */
244 xfer[0].addr = client->addr;
245 xfer[0].flags = 0;
246 xfer[0].len = 1;
247 xfer[0].buf = &reg;
248
249 /* Read data */
250 xfer[1].addr = client->addr;
251 xfer[1].flags = I2C_M_RD;
252 xfer[1].len = 2;
253 xfer[1].buf = (u8 *)&data;
254
255 ret = i2c_transfer(client->adapter, xfer, 2);
256 if (ret != 2) {
257 pr_err("i2c_transfer returned %d\n", ret);
258 return 0;
259 }
260
261 return (data >> 8) | ((data & 0xff) << 8);
262}
263
264static unsigned int wm8903_read(struct snd_soc_codec *codec,
265 unsigned int reg)
266{
267 switch (reg) {
268 case WM8903_SW_RESET_AND_ID:
269 case WM8903_REVISION_NUMBER:
270 case WM8903_INTERRUPT_STATUS_1:
271 case WM8903_WRITE_SEQUENCER_4:
272 return wm8903_hw_read(codec, reg);
273
274 default:
275 return wm8903_read_reg_cache(codec, reg);
276 }
277}
278
279static void wm8903_write_reg_cache(struct snd_soc_codec *codec,
280 u16 reg, unsigned int value)
281{
282 u16 *cache = codec->reg_cache;
283
284 BUG_ON(reg >= ARRAY_SIZE(wm8903_reg_defaults));
285
286 switch (reg) {
287 case WM8903_SW_RESET_AND_ID:
288 case WM8903_REVISION_NUMBER:
289 break;
290
291 default:
292 cache[reg] = value;
293 break;
294 }
295}
296
297static int wm8903_write(struct snd_soc_codec *codec, unsigned int reg,
298 unsigned int value)
299{
300 u8 data[3];
301
302 wm8903_write_reg_cache(codec, reg, value);
303
304 /* Data format is 1 byte of address followed by 2 bytes of data */
305 data[0] = reg;
306 data[1] = (value >> 8) & 0xff;
307 data[2] = value & 0xff;
308
309 if (codec->hw_write(codec->control_data, data, 3) == 2)
310 return 0;
311 else
312 return -EIO;
313}
314
315static int wm8903_run_sequence(struct snd_soc_codec *codec, unsigned int start)
316{
317 u16 reg[5];
318 struct i2c_client *i2c = codec->control_data;
319
320 BUG_ON(start > 48);
321
322 /* Enable the sequencer */
323 reg[0] = wm8903_read(codec, WM8903_WRITE_SEQUENCER_0);
324 reg[0] |= WM8903_WSEQ_ENA;
325 wm8903_write(codec, WM8903_WRITE_SEQUENCER_0, reg[0]);
326
327 dev_dbg(&i2c->dev, "Starting sequence at %d\n", start);
328
329 wm8903_write(codec, WM8903_WRITE_SEQUENCER_3,
330 start | WM8903_WSEQ_START);
331
332 /* Wait for it to complete. If we have the interrupt wired up then
333 * we could block waiting for an interrupt, though polling may still
334 * be desirable for diagnostic purposes.
335 */
336 do {
337 msleep(10);
338
339 reg[4] = wm8903_read(codec, WM8903_WRITE_SEQUENCER_4);
340 } while (reg[4] & WM8903_WSEQ_BUSY);
341
342 dev_dbg(&i2c->dev, "Sequence complete\n");
343
344 /* Disable the sequencer again */
345 wm8903_write(codec, WM8903_WRITE_SEQUENCER_0,
346 reg[0] & ~WM8903_WSEQ_ENA);
347
348 return 0;
349}
350
351static void wm8903_sync_reg_cache(struct snd_soc_codec *codec, u16 *cache)
352{
353 int i;
354
355 /* There really ought to be something better we can do here :/ */
356 for (i = 0; i < ARRAY_SIZE(wm8903_reg_defaults); i++)
357 cache[i] = wm8903_hw_read(codec, i);
358}
359
360static void wm8903_reset(struct snd_soc_codec *codec)
361{
362 wm8903_write(codec, WM8903_SW_RESET_AND_ID, 0);
363}
364
365#define WM8903_OUTPUT_SHORT 0x8
366#define WM8903_OUTPUT_OUT 0x4
367#define WM8903_OUTPUT_INT 0x2
368#define WM8903_OUTPUT_IN 0x1
369
370/*
371 * Event for headphone and line out amplifier power changes. Special
372 * power up/down sequences are required in order to maximise pop/click
373 * performance.
374 */
375static int wm8903_output_event(struct snd_soc_dapm_widget *w,
376 struct snd_kcontrol *kcontrol, int event)
377{
378 struct snd_soc_codec *codec = w->codec;
379 struct wm8903_priv *wm8903 = codec->private_data;
380 struct i2c_client *i2c = codec->control_data;
381 u16 val;
382 u16 reg;
383 int shift;
384 u16 cp_reg = wm8903_read(codec, WM8903_CHARGE_PUMP_0);
385
386 switch (w->reg) {
387 case WM8903_POWER_MANAGEMENT_2:
388 reg = WM8903_ANALOGUE_HP_0;
389 break;
390 case WM8903_POWER_MANAGEMENT_3:
391 reg = WM8903_ANALOGUE_LINEOUT_0;
392 break;
393 default:
394 BUG();
395 }
396
397 switch (w->shift) {
398 case 0:
399 shift = 0;
400 break;
401 case 1:
402 shift = 4;
403 break;
404 default:
405 BUG();
406 }
407
408 if (event & SND_SOC_DAPM_PRE_PMU) {
409 val = wm8903_read(codec, reg);
410
411 /* Short the output */
412 val &= ~(WM8903_OUTPUT_SHORT << shift);
413 wm8903_write(codec, reg, val);
414
415 wm8903->charge_pump_users++;
416
417 dev_dbg(&i2c->dev, "Charge pump use count now %d\n",
418 wm8903->charge_pump_users);
419
420 if (wm8903->charge_pump_users == 1) {
421 dev_dbg(&i2c->dev, "Enabling charge pump\n");
422 wm8903_write(codec, WM8903_CHARGE_PUMP_0,
423 cp_reg | WM8903_CP_ENA);
424 mdelay(4);
425 }
426 }
427
428 if (event & SND_SOC_DAPM_POST_PMU) {
429 val = wm8903_read(codec, reg);
430
431 val |= (WM8903_OUTPUT_IN << shift);
432 wm8903_write(codec, reg, val);
433
434 val |= (WM8903_OUTPUT_INT << shift);
435 wm8903_write(codec, reg, val);
436
437 /* Turn on the output ENA_OUTP */
438 val |= (WM8903_OUTPUT_OUT << shift);
439 wm8903_write(codec, reg, val);
440
441 /* Remove the short */
442 val |= (WM8903_OUTPUT_SHORT << shift);
443 wm8903_write(codec, reg, val);
444 }
445
446 if (event & SND_SOC_DAPM_PRE_PMD) {
447 val = wm8903_read(codec, reg);
448
449 /* Short the output */
450 val &= ~(WM8903_OUTPUT_SHORT << shift);
451 wm8903_write(codec, reg, val);
452
453 /* Then disable the intermediate and output stages */
454 val &= ~((WM8903_OUTPUT_OUT | WM8903_OUTPUT_INT |
455 WM8903_OUTPUT_IN) << shift);
456 wm8903_write(codec, reg, val);
457 }
458
459 if (event & SND_SOC_DAPM_POST_PMD) {
460 wm8903->charge_pump_users--;
461
462 dev_dbg(&i2c->dev, "Charge pump use count now %d\n",
463 wm8903->charge_pump_users);
464
465 if (wm8903->charge_pump_users == 0) {
466 dev_dbg(&i2c->dev, "Disabling charge pump\n");
467 wm8903_write(codec, WM8903_CHARGE_PUMP_0,
468 cp_reg & ~WM8903_CP_ENA);
469 }
470 }
471
472 return 0;
473}
474
475/*
476 * When used with DAC outputs only the WM8903 charge pump supports
477 * operation in class W mode, providing very low power consumption
478 * when used with digital sources. Enable and disable this mode
479 * automatically depending on the mixer configuration.
480 *
481 * All the relevant controls are simple switches.
482 */
483static int wm8903_class_w_put(struct snd_kcontrol *kcontrol,
484 struct snd_ctl_elem_value *ucontrol)
485{
486 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
487 struct snd_soc_codec *codec = widget->codec;
488 struct wm8903_priv *wm8903 = codec->private_data;
489 struct i2c_client *i2c = codec->control_data;
490 u16 reg;
491 int ret;
492
493 reg = wm8903_read(codec, WM8903_CLASS_W_0);
494
495 /* Turn it off if we're about to enable bypass */
496 if (ucontrol->value.integer.value[0]) {
497 if (wm8903->class_w_users == 0) {
498 dev_dbg(&i2c->dev, "Disabling Class W\n");
499 wm8903_write(codec, WM8903_CLASS_W_0, reg &
500 ~(WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V));
501 }
502 wm8903->class_w_users++;
503 }
504
505 /* Implement the change */
506 ret = snd_soc_dapm_put_volsw(kcontrol, ucontrol);
507
508 /* If we've just disabled the last bypass path turn Class W on */
509 if (!ucontrol->value.integer.value[0]) {
510 if (wm8903->class_w_users == 1) {
511 dev_dbg(&i2c->dev, "Enabling Class W\n");
512 wm8903_write(codec, WM8903_CLASS_W_0, reg |
513 WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V);
514 }
515 wm8903->class_w_users--;
516 }
517
518 dev_dbg(&i2c->dev, "Bypass use count now %d\n",
519 wm8903->class_w_users);
520
521 return ret;
522}
523
524#define SOC_DAPM_SINGLE_W(xname, reg, shift, max, invert) \
525{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
526 .info = snd_soc_info_volsw, \
527 .get = snd_soc_dapm_get_volsw, .put = wm8903_class_w_put, \
528 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
529
530
531/* ALSA can only do steps of .01dB */
532static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
533
534static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0);
535
536static const DECLARE_TLV_DB_SCALE(drc_tlv_thresh, 0, 75, 0);
537static const DECLARE_TLV_DB_SCALE(drc_tlv_amp, -2250, 75, 0);
538static const DECLARE_TLV_DB_SCALE(drc_tlv_min, 0, 600, 0);
539static const DECLARE_TLV_DB_SCALE(drc_tlv_max, 1200, 600, 0);
540static const DECLARE_TLV_DB_SCALE(drc_tlv_startup, -300, 50, 0);
541
542static const char *drc_slope_text[] = {
543 "1", "1/2", "1/4", "1/8", "1/16", "0"
544};
545
546static const struct soc_enum drc_slope_r0 =
547 SOC_ENUM_SINGLE(WM8903_DRC_2, 3, 6, drc_slope_text);
548
549static const struct soc_enum drc_slope_r1 =
550 SOC_ENUM_SINGLE(WM8903_DRC_2, 0, 6, drc_slope_text);
551
552static const char *drc_attack_text[] = {
553 "instantaneous",
554 "363us", "762us", "1.45ms", "2.9ms", "5.8ms", "11.6ms", "23.2ms",
555 "46.4ms", "92.8ms", "185.6ms"
556};
557
558static const struct soc_enum drc_attack =
559 SOC_ENUM_SINGLE(WM8903_DRC_1, 12, 11, drc_attack_text);
560
561static const char *drc_decay_text[] = {
562 "186ms", "372ms", "743ms", "1.49s", "2.97s", "5.94s", "11.89s",
563 "23.87s", "47.56s"
564};
565
566static const struct soc_enum drc_decay =
567 SOC_ENUM_SINGLE(WM8903_DRC_1, 8, 9, drc_decay_text);
568
569static const char *drc_ff_delay_text[] = {
570 "5 samples", "9 samples"
571};
572
573static const struct soc_enum drc_ff_delay =
574 SOC_ENUM_SINGLE(WM8903_DRC_0, 5, 2, drc_ff_delay_text);
575
576static const char *drc_qr_decay_text[] = {
577 "0.725ms", "1.45ms", "5.8ms"
578};
579
580static const struct soc_enum drc_qr_decay =
581 SOC_ENUM_SINGLE(WM8903_DRC_1, 4, 3, drc_qr_decay_text);
582
583static const char *drc_smoothing_text[] = {
584 "Low", "Medium", "High"
585};
586
587static const struct soc_enum drc_smoothing =
588 SOC_ENUM_SINGLE(WM8903_DRC_0, 11, 3, drc_smoothing_text);
589
590static const char *soft_mute_text[] = {
591 "Fast (fs/2)", "Slow (fs/32)"
592};
593
594static const struct soc_enum soft_mute =
595 SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 10, 2, soft_mute_text);
596
597static const char *mute_mode_text[] = {
598 "Hard", "Soft"
599};
600
601static const struct soc_enum mute_mode =
602 SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 9, 2, mute_mode_text);
603
604static const char *dac_deemphasis_text[] = {
605 "Disabled", "32kHz", "44.1kHz", "48kHz"
606};
607
608static const struct soc_enum dac_deemphasis =
609 SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 1, 4, dac_deemphasis_text);
610
611static const char *companding_text[] = {
612 "ulaw", "alaw"
613};
614
615static const struct soc_enum dac_companding =
616 SOC_ENUM_SINGLE(WM8903_AUDIO_INTERFACE_0, 0, 2, companding_text);
617
618static const struct soc_enum adc_companding =
619 SOC_ENUM_SINGLE(WM8903_AUDIO_INTERFACE_0, 2, 2, companding_text);
620
621static const char *input_mode_text[] = {
622 "Single-Ended", "Differential Line", "Differential Mic"
623};
624
625static const struct soc_enum linput_mode_enum =
626 SOC_ENUM_SINGLE(WM8903_ANALOGUE_LEFT_INPUT_1, 0, 3, input_mode_text);
627
628static const struct soc_enum rinput_mode_enum =
629 SOC_ENUM_SINGLE(WM8903_ANALOGUE_RIGHT_INPUT_1, 0, 3, input_mode_text);
630
631static const char *linput_mux_text[] = {
632 "IN1L", "IN2L", "IN3L"
633};
634
635static const struct soc_enum linput_enum =
636 SOC_ENUM_SINGLE(WM8903_ANALOGUE_LEFT_INPUT_1, 2, 3, linput_mux_text);
637
638static const struct soc_enum linput_inv_enum =
639 SOC_ENUM_SINGLE(WM8903_ANALOGUE_LEFT_INPUT_1, 4, 3, linput_mux_text);
640
641static const char *rinput_mux_text[] = {
642 "IN1R", "IN2R", "IN3R"
643};
644
645static const struct soc_enum rinput_enum =
646 SOC_ENUM_SINGLE(WM8903_ANALOGUE_RIGHT_INPUT_1, 2, 3, rinput_mux_text);
647
648static const struct soc_enum rinput_inv_enum =
649 SOC_ENUM_SINGLE(WM8903_ANALOGUE_RIGHT_INPUT_1, 4, 3, rinput_mux_text);
650
651
652static const struct snd_kcontrol_new wm8903_snd_controls[] = {
653
654/* Input PGAs - No TLV since the scale depends on PGA mode */
655SOC_SINGLE("Left Input PGA Switch", WM8903_ANALOGUE_LEFT_INPUT_0,
656 7, 1, 1),
657SOC_SINGLE("Left Input PGA Volume", WM8903_ANALOGUE_LEFT_INPUT_0,
658 0, 31, 0),
659SOC_SINGLE("Left Input PGA Common Mode Switch", WM8903_ANALOGUE_LEFT_INPUT_1,
660 6, 1, 0),
661
662SOC_SINGLE("Right Input PGA Switch", WM8903_ANALOGUE_RIGHT_INPUT_0,
663 7, 1, 1),
664SOC_SINGLE("Right Input PGA Volume", WM8903_ANALOGUE_RIGHT_INPUT_0,
665 0, 31, 0),
666SOC_SINGLE("Right Input PGA Common Mode Switch", WM8903_ANALOGUE_RIGHT_INPUT_1,
667 6, 1, 0),
668
669/* ADCs */
670SOC_SINGLE("DRC Switch", WM8903_DRC_0, 15, 1, 0),
671SOC_ENUM("DRC Compressor Slope R0", drc_slope_r0),
672SOC_ENUM("DRC Compressor Slope R1", drc_slope_r1),
673SOC_SINGLE_TLV("DRC Compressor Threashold Volume", WM8903_DRC_3, 5, 124, 1,
674 drc_tlv_thresh),
675SOC_SINGLE_TLV("DRC Volume", WM8903_DRC_3, 0, 30, 1, drc_tlv_amp),
676SOC_SINGLE_TLV("DRC Minimum Gain Volume", WM8903_DRC_1, 2, 3, 1, drc_tlv_min),
677SOC_SINGLE_TLV("DRC Maximum Gain Volume", WM8903_DRC_1, 0, 3, 0, drc_tlv_max),
678SOC_ENUM("DRC Attack Rate", drc_attack),
679SOC_ENUM("DRC Decay Rate", drc_decay),
680SOC_ENUM("DRC FF Delay", drc_ff_delay),
681SOC_SINGLE("DRC Anticlip Switch", WM8903_DRC_0, 1, 1, 0),
682SOC_SINGLE("DRC QR Switch", WM8903_DRC_0, 2, 1, 0),
683SOC_SINGLE_TLV("DRC QR Threashold Volume", WM8903_DRC_0, 6, 3, 0, drc_tlv_max),
684SOC_ENUM("DRC QR Decay Rate", drc_qr_decay),
685SOC_SINGLE("DRC Smoothing Switch", WM8903_DRC_0, 3, 1, 0),
686SOC_SINGLE("DRC Smoothing Hysteresis Switch", WM8903_DRC_0, 0, 1, 0),
687SOC_ENUM("DRC Smoothing Threashold", drc_smoothing),
688SOC_SINGLE_TLV("DRC Startup Volume", WM8903_DRC_0, 6, 18, 0, drc_tlv_startup),
689
690SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8903_ADC_DIGITAL_VOLUME_LEFT,
691 WM8903_ADC_DIGITAL_VOLUME_RIGHT, 1, 96, 0, digital_tlv),
692SOC_ENUM("ADC Companding Mode", adc_companding),
693SOC_SINGLE("ADC Companding Switch", WM8903_AUDIO_INTERFACE_0, 3, 1, 0),
694
695/* DAC */
696SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8903_DAC_DIGITAL_VOLUME_LEFT,
697 WM8903_DAC_DIGITAL_VOLUME_RIGHT, 1, 120, 0, digital_tlv),
698SOC_ENUM("DAC Soft Mute Rate", soft_mute),
699SOC_ENUM("DAC Mute Mode", mute_mode),
700SOC_SINGLE("DAC Mono Switch", WM8903_DAC_DIGITAL_1, 12, 1, 0),
701SOC_ENUM("DAC De-emphasis", dac_deemphasis),
702SOC_SINGLE("DAC Sloping Stopband Filter Switch",
703 WM8903_DAC_DIGITAL_1, 11, 1, 0),
704SOC_ENUM("DAC Companding Mode", dac_companding),
705SOC_SINGLE("DAC Companding Switch", WM8903_AUDIO_INTERFACE_0, 1, 1, 0),
706
707/* Headphones */
708SOC_DOUBLE_R("Headphone Switch",
709 WM8903_ANALOGUE_OUT1_LEFT, WM8903_ANALOGUE_OUT1_RIGHT,
710 8, 1, 1),
711SOC_DOUBLE_R("Headphone ZC Switch",
712 WM8903_ANALOGUE_OUT1_LEFT, WM8903_ANALOGUE_OUT1_RIGHT,
713 6, 1, 0),
714SOC_DOUBLE_R_TLV("Headphone Volume",
715 WM8903_ANALOGUE_OUT1_LEFT, WM8903_ANALOGUE_OUT1_RIGHT,
716 0, 63, 0, out_tlv),
717
718/* Line out */
719SOC_DOUBLE_R("Line Out Switch",
720 WM8903_ANALOGUE_OUT2_LEFT, WM8903_ANALOGUE_OUT2_RIGHT,
721 8, 1, 1),
722SOC_DOUBLE_R("Line Out ZC Switch",
723 WM8903_ANALOGUE_OUT2_LEFT, WM8903_ANALOGUE_OUT2_RIGHT,
724 6, 1, 0),
725SOC_DOUBLE_R_TLV("Line Out Volume",
726 WM8903_ANALOGUE_OUT2_LEFT, WM8903_ANALOGUE_OUT2_RIGHT,
727 0, 63, 0, out_tlv),
728
729/* Speaker */
730SOC_DOUBLE_R("Speaker Switch",
731 WM8903_ANALOGUE_OUT3_LEFT, WM8903_ANALOGUE_OUT3_RIGHT, 8, 1, 1),
732SOC_DOUBLE_R("Speaker ZC Switch",
733 WM8903_ANALOGUE_OUT3_LEFT, WM8903_ANALOGUE_OUT3_RIGHT, 6, 1, 0),
734SOC_DOUBLE_R_TLV("Speaker Volume",
735 WM8903_ANALOGUE_OUT3_LEFT, WM8903_ANALOGUE_OUT3_RIGHT,
736 0, 63, 0, out_tlv),
737};
738
739static int wm8903_add_controls(struct snd_soc_codec *codec)
740{
741 int err, i;
742
743 for (i = 0; i < ARRAY_SIZE(wm8903_snd_controls); i++) {
744 err = snd_ctl_add(codec->card,
745 snd_soc_cnew(&wm8903_snd_controls[i],
746 codec, NULL));
747 if (err < 0)
748 return err;
749 }
750
751 return 0;
752}
753
754static const struct snd_kcontrol_new linput_mode_mux =
755 SOC_DAPM_ENUM("Left Input Mode Mux", linput_mode_enum);
756
757static const struct snd_kcontrol_new rinput_mode_mux =
758 SOC_DAPM_ENUM("Right Input Mode Mux", rinput_mode_enum);
759
760static const struct snd_kcontrol_new linput_mux =
761 SOC_DAPM_ENUM("Left Input Mux", linput_enum);
762
763static const struct snd_kcontrol_new linput_inv_mux =
764 SOC_DAPM_ENUM("Left Inverting Input Mux", linput_inv_enum);
765
766static const struct snd_kcontrol_new rinput_mux =
767 SOC_DAPM_ENUM("Right Input Mux", rinput_enum);
768
769static const struct snd_kcontrol_new rinput_inv_mux =
770 SOC_DAPM_ENUM("Right Inverting Input Mux", rinput_inv_enum);
771
772static const struct snd_kcontrol_new left_output_mixer[] = {
773SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_LEFT_MIX_0, 3, 1, 0),
774SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_LEFT_MIX_0, 2, 1, 0),
775SOC_DAPM_SINGLE_W("Left Bypass Switch", WM8903_ANALOGUE_LEFT_MIX_0, 1, 1, 0),
776SOC_DAPM_SINGLE_W("Right Bypass Switch", WM8903_ANALOGUE_LEFT_MIX_0, 1, 1, 0),
777};
778
779static const struct snd_kcontrol_new right_output_mixer[] = {
780SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_RIGHT_MIX_0, 3, 1, 0),
781SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_RIGHT_MIX_0, 2, 1, 0),
782SOC_DAPM_SINGLE_W("Left Bypass Switch", WM8903_ANALOGUE_RIGHT_MIX_0, 1, 1, 0),
783SOC_DAPM_SINGLE_W("Right Bypass Switch", WM8903_ANALOGUE_RIGHT_MIX_0, 1, 1, 0),
784};
785
786static const struct snd_kcontrol_new left_speaker_mixer[] = {
787SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_SPK_MIX_LEFT_0, 3, 1, 0),
788SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_SPK_MIX_LEFT_0, 2, 1, 0),
789SOC_DAPM_SINGLE("Left Bypass Switch", WM8903_ANALOGUE_SPK_MIX_LEFT_0, 1, 1, 0),
790SOC_DAPM_SINGLE("Right Bypass Switch", WM8903_ANALOGUE_SPK_MIX_LEFT_0,
791 1, 1, 0),
792};
793
794static const struct snd_kcontrol_new right_speaker_mixer[] = {
795SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_SPK_MIX_RIGHT_0, 3, 1, 0),
796SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_SPK_MIX_RIGHT_0, 2, 1, 0),
797SOC_DAPM_SINGLE("Left Bypass Switch", WM8903_ANALOGUE_SPK_MIX_RIGHT_0,
798 1, 1, 0),
799SOC_DAPM_SINGLE("Right Bypass Switch", WM8903_ANALOGUE_SPK_MIX_RIGHT_0,
800 1, 1, 0),
801};
802
803static const struct snd_soc_dapm_widget wm8903_dapm_widgets[] = {
804SND_SOC_DAPM_INPUT("IN1L"),
805SND_SOC_DAPM_INPUT("IN1R"),
806SND_SOC_DAPM_INPUT("IN2L"),
807SND_SOC_DAPM_INPUT("IN2R"),
808SND_SOC_DAPM_INPUT("IN3L"),
809SND_SOC_DAPM_INPUT("IN3R"),
810
811SND_SOC_DAPM_OUTPUT("HPOUTL"),
812SND_SOC_DAPM_OUTPUT("HPOUTR"),
813SND_SOC_DAPM_OUTPUT("LINEOUTL"),
814SND_SOC_DAPM_OUTPUT("LINEOUTR"),
815SND_SOC_DAPM_OUTPUT("LOP"),
816SND_SOC_DAPM_OUTPUT("LON"),
817SND_SOC_DAPM_OUTPUT("ROP"),
818SND_SOC_DAPM_OUTPUT("RON"),
819
820SND_SOC_DAPM_MICBIAS("Mic Bias", WM8903_MIC_BIAS_CONTROL_0, 0, 0),
821
822SND_SOC_DAPM_MUX("Left Input Mux", SND_SOC_NOPM, 0, 0, &linput_mux),
823SND_SOC_DAPM_MUX("Left Input Inverting Mux", SND_SOC_NOPM, 0, 0,
824 &linput_inv_mux),
825SND_SOC_DAPM_MUX("Left Input Mode Mux", SND_SOC_NOPM, 0, 0, &linput_mode_mux),
826
827SND_SOC_DAPM_MUX("Right Input Mux", SND_SOC_NOPM, 0, 0, &rinput_mux),
828SND_SOC_DAPM_MUX("Right Input Inverting Mux", SND_SOC_NOPM, 0, 0,
829 &rinput_inv_mux),
830SND_SOC_DAPM_MUX("Right Input Mode Mux", SND_SOC_NOPM, 0, 0, &rinput_mode_mux),
831
832SND_SOC_DAPM_PGA("Left Input PGA", WM8903_POWER_MANAGEMENT_0, 1, 0, NULL, 0),
833SND_SOC_DAPM_PGA("Right Input PGA", WM8903_POWER_MANAGEMENT_0, 0, 0, NULL, 0),
834
835SND_SOC_DAPM_ADC("ADCL", "Left HiFi Capture", WM8903_POWER_MANAGEMENT_6, 1, 0),
836SND_SOC_DAPM_ADC("ADCR", "Right HiFi Capture", WM8903_POWER_MANAGEMENT_6, 0, 0),
837
838SND_SOC_DAPM_DAC("DACL", "Left Playback", WM8903_POWER_MANAGEMENT_6, 3, 0),
839SND_SOC_DAPM_DAC("DACR", "Right Playback", WM8903_POWER_MANAGEMENT_6, 2, 0),
840
841SND_SOC_DAPM_MIXER("Left Output Mixer", WM8903_POWER_MANAGEMENT_1, 1, 0,
842 left_output_mixer, ARRAY_SIZE(left_output_mixer)),
843SND_SOC_DAPM_MIXER("Right Output Mixer", WM8903_POWER_MANAGEMENT_1, 0, 0,
844 right_output_mixer, ARRAY_SIZE(right_output_mixer)),
845
846SND_SOC_DAPM_MIXER("Left Speaker Mixer", WM8903_POWER_MANAGEMENT_4, 1, 0,
847 left_speaker_mixer, ARRAY_SIZE(left_speaker_mixer)),
848SND_SOC_DAPM_MIXER("Right Speaker Mixer", WM8903_POWER_MANAGEMENT_4, 0, 0,
849 right_speaker_mixer, ARRAY_SIZE(right_speaker_mixer)),
850
851SND_SOC_DAPM_PGA_E("Left Headphone Output PGA", WM8903_POWER_MANAGEMENT_2,
852 1, 0, NULL, 0, wm8903_output_event,
853 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
854 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
855SND_SOC_DAPM_PGA_E("Right Headphone Output PGA", WM8903_POWER_MANAGEMENT_2,
856 0, 0, NULL, 0, wm8903_output_event,
857 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
858 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
859
860SND_SOC_DAPM_PGA_E("Left Line Output PGA", WM8903_POWER_MANAGEMENT_3, 1, 0,
861 NULL, 0, wm8903_output_event,
862 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
863 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
864SND_SOC_DAPM_PGA_E("Right Line Output PGA", WM8903_POWER_MANAGEMENT_3, 0, 0,
865 NULL, 0, wm8903_output_event,
866 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
867 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
868
869SND_SOC_DAPM_PGA("Left Speaker PGA", WM8903_POWER_MANAGEMENT_5, 1, 0,
870 NULL, 0),
871SND_SOC_DAPM_PGA("Right Speaker PGA", WM8903_POWER_MANAGEMENT_5, 0, 0,
872 NULL, 0),
873
874};
875
876static const struct snd_soc_dapm_route intercon[] = {
877
878 { "Left Input Mux", "IN1L", "IN1L" },
879 { "Left Input Mux", "IN2L", "IN2L" },
880 { "Left Input Mux", "IN3L", "IN3L" },
881
882 { "Left Input Inverting Mux", "IN1L", "IN1L" },
883 { "Left Input Inverting Mux", "IN2L", "IN2L" },
884 { "Left Input Inverting Mux", "IN3L", "IN3L" },
885
886 { "Right Input Mux", "IN1R", "IN1R" },
887 { "Right Input Mux", "IN2R", "IN2R" },
888 { "Right Input Mux", "IN3R", "IN3R" },
889
890 { "Right Input Inverting Mux", "IN1R", "IN1R" },
891 { "Right Input Inverting Mux", "IN2R", "IN2R" },
892 { "Right Input Inverting Mux", "IN3R", "IN3R" },
893
894 { "Left Input Mode Mux", "Single-Ended", "Left Input Inverting Mux" },
895 { "Left Input Mode Mux", "Differential Line",
896 "Left Input Mux" },
897 { "Left Input Mode Mux", "Differential Line",
898 "Left Input Inverting Mux" },
899 { "Left Input Mode Mux", "Differential Mic",
900 "Left Input Mux" },
901 { "Left Input Mode Mux", "Differential Mic",
902 "Left Input Inverting Mux" },
903
904 { "Right Input Mode Mux", "Single-Ended",
905 "Right Input Inverting Mux" },
906 { "Right Input Mode Mux", "Differential Line",
907 "Right Input Mux" },
908 { "Right Input Mode Mux", "Differential Line",
909 "Right Input Inverting Mux" },
910 { "Right Input Mode Mux", "Differential Mic",
911 "Right Input Mux" },
912 { "Right Input Mode Mux", "Differential Mic",
913 "Right Input Inverting Mux" },
914
915 { "Left Input PGA", NULL, "Left Input Mode Mux" },
916 { "Right Input PGA", NULL, "Right Input Mode Mux" },
917
918 { "ADCL", NULL, "Left Input PGA" },
919 { "ADCR", NULL, "Right Input PGA" },
920
921 { "Left Output Mixer", "Left Bypass Switch", "Left Input PGA" },
922 { "Left Output Mixer", "Right Bypass Switch", "Right Input PGA" },
923 { "Left Output Mixer", "DACL Switch", "DACL" },
924 { "Left Output Mixer", "DACR Switch", "DACR" },
925
926 { "Right Output Mixer", "Left Bypass Switch", "Left Input PGA" },
927 { "Right Output Mixer", "Right Bypass Switch", "Right Input PGA" },
928 { "Right Output Mixer", "DACL Switch", "DACL" },
929 { "Right Output Mixer", "DACR Switch", "DACR" },
930
931 { "Left Speaker Mixer", "Left Bypass Switch", "Left Input PGA" },
932 { "Left Speaker Mixer", "Right Bypass Switch", "Right Input PGA" },
933 { "Left Speaker Mixer", "DACL Switch", "DACL" },
934 { "Left Speaker Mixer", "DACR Switch", "DACR" },
935
936 { "Right Speaker Mixer", "Left Bypass Switch", "Left Input PGA" },
937 { "Right Speaker Mixer", "Right Bypass Switch", "Right Input PGA" },
938 { "Right Speaker Mixer", "DACL Switch", "DACL" },
939 { "Right Speaker Mixer", "DACR Switch", "DACR" },
940
941 { "Left Line Output PGA", NULL, "Left Output Mixer" },
942 { "Right Line Output PGA", NULL, "Right Output Mixer" },
943
944 { "Left Headphone Output PGA", NULL, "Left Output Mixer" },
945 { "Right Headphone Output PGA", NULL, "Right Output Mixer" },
946
947 { "Left Speaker PGA", NULL, "Left Speaker Mixer" },
948 { "Right Speaker PGA", NULL, "Right Speaker Mixer" },
949
950 { "HPOUTL", NULL, "Left Headphone Output PGA" },
951 { "HPOUTR", NULL, "Right Headphone Output PGA" },
952
953 { "LINEOUTL", NULL, "Left Line Output PGA" },
954 { "LINEOUTR", NULL, "Right Line Output PGA" },
955
956 { "LOP", NULL, "Left Speaker PGA" },
957 { "LON", NULL, "Left Speaker PGA" },
958
959 { "ROP", NULL, "Right Speaker PGA" },
960 { "RON", NULL, "Right Speaker PGA" },
961};
962
963static int wm8903_add_widgets(struct snd_soc_codec *codec)
964{
965 snd_soc_dapm_new_controls(codec, wm8903_dapm_widgets,
966 ARRAY_SIZE(wm8903_dapm_widgets));
967
968 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
969
970 snd_soc_dapm_new_widgets(codec);
971
972 return 0;
973}
974
975static int wm8903_set_bias_level(struct snd_soc_codec *codec,
976 enum snd_soc_bias_level level)
977{
978 struct i2c_client *i2c = codec->control_data;
979 u16 reg, reg2;
980
981 switch (level) {
982 case SND_SOC_BIAS_ON:
983 case SND_SOC_BIAS_PREPARE:
984 reg = wm8903_read(codec, WM8903_VMID_CONTROL_0);
985 reg &= ~(WM8903_VMID_RES_MASK);
986 reg |= WM8903_VMID_RES_50K;
987 wm8903_write(codec, WM8903_VMID_CONTROL_0, reg);
988 break;
989
990 case SND_SOC_BIAS_STANDBY:
991 if (codec->bias_level == SND_SOC_BIAS_OFF) {
992 wm8903_run_sequence(codec, 0);
993 wm8903_sync_reg_cache(codec, codec->reg_cache);
994
995 /* Enable low impedence charge pump output */
996 reg = wm8903_read(codec,
997 WM8903_CONTROL_INTERFACE_TEST_1);
998 wm8903_write(codec, WM8903_CONTROL_INTERFACE_TEST_1,
999 reg | WM8903_TEST_KEY);
1000 reg2 = wm8903_read(codec, WM8903_CHARGE_PUMP_TEST_1);
1001 wm8903_write(codec, WM8903_CHARGE_PUMP_TEST_1,
1002 reg2 | WM8903_CP_SW_KELVIN_MODE_MASK);
1003 wm8903_write(codec, WM8903_CONTROL_INTERFACE_TEST_1,
1004 reg);
1005
1006 /* By default no bypass paths are enabled so
1007 * enable Class W support.
1008 */
1009 dev_dbg(&i2c->dev, "Enabling Class W\n");
1010 wm8903_write(codec, WM8903_CLASS_W_0, reg |
1011 WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V);
1012 }
1013
1014 reg = wm8903_read(codec, WM8903_VMID_CONTROL_0);
1015 reg &= ~(WM8903_VMID_RES_MASK);
1016 reg |= WM8903_VMID_RES_250K;
1017 wm8903_write(codec, WM8903_VMID_CONTROL_0, reg);
1018 break;
1019
1020 case SND_SOC_BIAS_OFF:
1021 wm8903_run_sequence(codec, 32);
1022 break;
1023 }
1024
1025 codec->bias_level = level;
1026
1027 return 0;
1028}
1029
1030static int wm8903_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1031 int clk_id, unsigned int freq, int dir)
1032{
1033 struct snd_soc_codec *codec = codec_dai->codec;
1034 struct wm8903_priv *wm8903 = codec->private_data;
1035
1036 wm8903->sysclk = freq;
1037
1038 return 0;
1039}
1040
1041static int wm8903_set_dai_fmt(struct snd_soc_dai *codec_dai,
1042 unsigned int fmt)
1043{
1044 struct snd_soc_codec *codec = codec_dai->codec;
1045 u16 aif1 = wm8903_read(codec, WM8903_AUDIO_INTERFACE_1);
1046
1047 aif1 &= ~(WM8903_LRCLK_DIR | WM8903_BCLK_DIR | WM8903_AIF_FMT_MASK |
1048 WM8903_AIF_LRCLK_INV | WM8903_AIF_BCLK_INV);
1049
1050 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1051 case SND_SOC_DAIFMT_CBS_CFS:
1052 break;
1053 case SND_SOC_DAIFMT_CBS_CFM:
1054 aif1 |= WM8903_LRCLK_DIR;
1055 break;
1056 case SND_SOC_DAIFMT_CBM_CFM:
1057 aif1 |= WM8903_LRCLK_DIR | WM8903_BCLK_DIR;
1058 break;
1059 case SND_SOC_DAIFMT_CBM_CFS:
1060 aif1 |= WM8903_BCLK_DIR;
1061 break;
1062 default:
1063 return -EINVAL;
1064 }
1065
1066 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1067 case SND_SOC_DAIFMT_DSP_A:
1068 aif1 |= 0x3;
1069 break;
1070 case SND_SOC_DAIFMT_DSP_B:
1071 aif1 |= 0x3 | WM8903_AIF_LRCLK_INV;
1072 break;
1073 case SND_SOC_DAIFMT_I2S:
1074 aif1 |= 0x2;
1075 break;
1076 case SND_SOC_DAIFMT_RIGHT_J:
1077 aif1 |= 0x1;
1078 break;
1079 case SND_SOC_DAIFMT_LEFT_J:
1080 break;
1081 default:
1082 return -EINVAL;
1083 }
1084
1085 /* Clock inversion */
1086 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1087 case SND_SOC_DAIFMT_DSP_A:
1088 case SND_SOC_DAIFMT_DSP_B:
1089 /* frame inversion not valid for DSP modes */
1090 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1091 case SND_SOC_DAIFMT_NB_NF:
1092 break;
1093 case SND_SOC_DAIFMT_IB_NF:
1094 aif1 |= WM8903_AIF_BCLK_INV;
1095 break;
1096 default:
1097 return -EINVAL;
1098 }
1099 break;
1100 case SND_SOC_DAIFMT_I2S:
1101 case SND_SOC_DAIFMT_RIGHT_J:
1102 case SND_SOC_DAIFMT_LEFT_J:
1103 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1104 case SND_SOC_DAIFMT_NB_NF:
1105 break;
1106 case SND_SOC_DAIFMT_IB_IF:
1107 aif1 |= WM8903_AIF_BCLK_INV | WM8903_AIF_LRCLK_INV;
1108 break;
1109 case SND_SOC_DAIFMT_IB_NF:
1110 aif1 |= WM8903_AIF_BCLK_INV;
1111 break;
1112 case SND_SOC_DAIFMT_NB_IF:
1113 aif1 |= WM8903_AIF_LRCLK_INV;
1114 break;
1115 default:
1116 return -EINVAL;
1117 }
1118 break;
1119 default:
1120 return -EINVAL;
1121 }
1122
1123 wm8903_write(codec, WM8903_AUDIO_INTERFACE_1, aif1);
1124
1125 return 0;
1126}
1127
1128static int wm8903_digital_mute(struct snd_soc_dai *codec_dai, int mute)
1129{
1130 struct snd_soc_codec *codec = codec_dai->codec;
1131 u16 reg;
1132
1133 reg = wm8903_read(codec, WM8903_DAC_DIGITAL_1);
1134
1135 if (mute)
1136 reg |= WM8903_DAC_MUTE;
1137 else
1138 reg &= ~WM8903_DAC_MUTE;
1139
1140 wm8903_write(codec, WM8903_DAC_DIGITAL_1, reg);
1141
1142 return 0;
1143}
1144
1145/* Lookup table for CLK_SYS/fs ratio. 256fs or more is recommended
1146 * for optimal performance so we list the lower rates first and match
1147 * on the last match we find. */
1148static struct {
1149 int div;
1150 int rate;
1151 int mode;
1152 int mclk_div;
1153} clk_sys_ratios[] = {
1154 { 64, 0x0, 0x0, 1 },
1155 { 68, 0x0, 0x1, 1 },
1156 { 125, 0x0, 0x2, 1 },
1157 { 128, 0x1, 0x0, 1 },
1158 { 136, 0x1, 0x1, 1 },
1159 { 192, 0x2, 0x0, 1 },
1160 { 204, 0x2, 0x1, 1 },
1161
1162 { 64, 0x0, 0x0, 2 },
1163 { 68, 0x0, 0x1, 2 },
1164 { 125, 0x0, 0x2, 2 },
1165 { 128, 0x1, 0x0, 2 },
1166 { 136, 0x1, 0x1, 2 },
1167 { 192, 0x2, 0x0, 2 },
1168 { 204, 0x2, 0x1, 2 },
1169
1170 { 250, 0x2, 0x2, 1 },
1171 { 256, 0x3, 0x0, 1 },
1172 { 272, 0x3, 0x1, 1 },
1173 { 384, 0x4, 0x0, 1 },
1174 { 408, 0x4, 0x1, 1 },
1175 { 375, 0x4, 0x2, 1 },
1176 { 512, 0x5, 0x0, 1 },
1177 { 544, 0x5, 0x1, 1 },
1178 { 500, 0x5, 0x2, 1 },
1179 { 768, 0x6, 0x0, 1 },
1180 { 816, 0x6, 0x1, 1 },
1181 { 750, 0x6, 0x2, 1 },
1182 { 1024, 0x7, 0x0, 1 },
1183 { 1088, 0x7, 0x1, 1 },
1184 { 1000, 0x7, 0x2, 1 },
1185 { 1408, 0x8, 0x0, 1 },
1186 { 1496, 0x8, 0x1, 1 },
1187 { 1536, 0x9, 0x0, 1 },
1188 { 1632, 0x9, 0x1, 1 },
1189 { 1500, 0x9, 0x2, 1 },
1190
1191 { 250, 0x2, 0x2, 2 },
1192 { 256, 0x3, 0x0, 2 },
1193 { 272, 0x3, 0x1, 2 },
1194 { 384, 0x4, 0x0, 2 },
1195 { 408, 0x4, 0x1, 2 },
1196 { 375, 0x4, 0x2, 2 },
1197 { 512, 0x5, 0x0, 2 },
1198 { 544, 0x5, 0x1, 2 },
1199 { 500, 0x5, 0x2, 2 },
1200 { 768, 0x6, 0x0, 2 },
1201 { 816, 0x6, 0x1, 2 },
1202 { 750, 0x6, 0x2, 2 },
1203 { 1024, 0x7, 0x0, 2 },
1204 { 1088, 0x7, 0x1, 2 },
1205 { 1000, 0x7, 0x2, 2 },
1206 { 1408, 0x8, 0x0, 2 },
1207 { 1496, 0x8, 0x1, 2 },
1208 { 1536, 0x9, 0x0, 2 },
1209 { 1632, 0x9, 0x1, 2 },
1210 { 1500, 0x9, 0x2, 2 },
1211};
1212
1213/* CLK_SYS/BCLK ratios - multiplied by 10 due to .5s */
1214static struct {
1215 int ratio;
1216 int div;
1217} bclk_divs[] = {
1218 { 10, 0 },
1219 { 15, 1 },
1220 { 20, 2 },
1221 { 30, 3 },
1222 { 40, 4 },
1223 { 50, 5 },
1224 { 55, 6 },
1225 { 60, 7 },
1226 { 80, 8 },
1227 { 100, 9 },
1228 { 110, 10 },
1229 { 120, 11 },
1230 { 160, 12 },
1231 { 200, 13 },
1232 { 220, 14 },
1233 { 240, 15 },
1234 { 250, 16 },
1235 { 300, 17 },
1236 { 320, 18 },
1237 { 440, 19 },
1238 { 480, 20 },
1239};
1240
1241/* Sample rates for DSP */
1242static struct {
1243 int rate;
1244 int value;
1245} sample_rates[] = {
1246 { 8000, 0 },
1247 { 11025, 1 },
1248 { 12000, 2 },
1249 { 16000, 3 },
1250 { 22050, 4 },
1251 { 24000, 5 },
1252 { 32000, 6 },
1253 { 44100, 7 },
1254 { 48000, 8 },
1255 { 88200, 9 },
1256 { 96000, 10 },
1257 { 0, 0 },
1258};
1259
1260static int wm8903_startup(struct snd_pcm_substream *substream)
1261{
1262 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1263 struct snd_soc_device *socdev = rtd->socdev;
1264 struct snd_soc_codec *codec = socdev->codec;
1265 struct wm8903_priv *wm8903 = codec->private_data;
1266 struct i2c_client *i2c = codec->control_data;
1267 struct snd_pcm_runtime *master_runtime;
1268
1269 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1270 wm8903->playback_active++;
1271 else
1272 wm8903->capture_active++;
1273
1274 /* The DAI has shared clocks so if we already have a playback or
1275 * capture going then constrain this substream to match it.
1276 */
1277 if (wm8903->master_substream) {
1278 master_runtime = wm8903->master_substream->runtime;
1279
1280 dev_dbg(&i2c->dev, "Constraining to %d bits at %dHz\n",
1281 master_runtime->sample_bits,
1282 master_runtime->rate);
1283
1284 snd_pcm_hw_constraint_minmax(substream->runtime,
1285 SNDRV_PCM_HW_PARAM_RATE,
1286 master_runtime->rate,
1287 master_runtime->rate);
1288
1289 snd_pcm_hw_constraint_minmax(substream->runtime,
1290 SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
1291 master_runtime->sample_bits,
1292 master_runtime->sample_bits);
1293
1294 wm8903->slave_substream = substream;
1295 } else
1296 wm8903->master_substream = substream;
1297
1298 return 0;
1299}
1300
1301static void wm8903_shutdown(struct snd_pcm_substream *substream)
1302{
1303 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1304 struct snd_soc_device *socdev = rtd->socdev;
1305 struct snd_soc_codec *codec = socdev->codec;
1306 struct wm8903_priv *wm8903 = codec->private_data;
1307
1308 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1309 wm8903->playback_active--;
1310 else
1311 wm8903->capture_active--;
1312
1313 if (wm8903->master_substream == substream)
1314 wm8903->master_substream = wm8903->slave_substream;
1315
1316 wm8903->slave_substream = NULL;
1317}
1318
1319static int wm8903_hw_params(struct snd_pcm_substream *substream,
1320 struct snd_pcm_hw_params *params)
1321{
1322 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1323 struct snd_soc_device *socdev = rtd->socdev;
1324 struct snd_soc_codec *codec = socdev->codec;
1325 struct wm8903_priv *wm8903 = codec->private_data;
1326 struct i2c_client *i2c = codec->control_data;
1327 int fs = params_rate(params);
1328 int bclk;
1329 int bclk_div;
1330 int i;
1331 int dsp_config;
1332 int clk_config;
1333 int best_val;
1334 int cur_val;
1335 int clk_sys;
1336
1337 u16 aif1 = wm8903_read(codec, WM8903_AUDIO_INTERFACE_1);
1338 u16 aif2 = wm8903_read(codec, WM8903_AUDIO_INTERFACE_2);
1339 u16 aif3 = wm8903_read(codec, WM8903_AUDIO_INTERFACE_3);
1340 u16 clock0 = wm8903_read(codec, WM8903_CLOCK_RATES_0);
1341 u16 clock1 = wm8903_read(codec, WM8903_CLOCK_RATES_1);
1342
1343 if (substream == wm8903->slave_substream) {
1344 dev_dbg(&i2c->dev, "Ignoring hw_params for slave substream\n");
1345 return 0;
1346 }
1347
1348 /* Configure sample rate logic for DSP - choose nearest rate */
1349 dsp_config = 0;
1350 best_val = abs(sample_rates[dsp_config].rate - fs);
1351 for (i = 1; i < ARRAY_SIZE(sample_rates); i++) {
1352 cur_val = abs(sample_rates[i].rate - fs);
1353 if (cur_val <= best_val) {
1354 dsp_config = i;
1355 best_val = cur_val;
1356 }
1357 }
1358
1359 /* Constraints should stop us hitting this but let's make sure */
1360 if (wm8903->capture_active)
1361 switch (sample_rates[dsp_config].rate) {
1362 case 88200:
1363 case 96000:
1364 dev_err(&i2c->dev, "%dHz unsupported by ADC\n",
1365 fs);
1366 return -EINVAL;
1367
1368 default:
1369 break;
1370 }
1371
1372 dev_dbg(&i2c->dev, "DSP fs = %dHz\n", sample_rates[dsp_config].rate);
1373 clock1 &= ~WM8903_SAMPLE_RATE_MASK;
1374 clock1 |= sample_rates[dsp_config].value;
1375
1376 aif1 &= ~WM8903_AIF_WL_MASK;
1377 bclk = 2 * fs;
1378 switch (params_format(params)) {
1379 case SNDRV_PCM_FORMAT_S16_LE:
1380 bclk *= 16;
1381 break;
1382 case SNDRV_PCM_FORMAT_S20_3LE:
1383 bclk *= 20;
1384 aif1 |= 0x4;
1385 break;
1386 case SNDRV_PCM_FORMAT_S24_LE:
1387 bclk *= 24;
1388 aif1 |= 0x8;
1389 break;
1390 case SNDRV_PCM_FORMAT_S32_LE:
1391 bclk *= 32;
1392 aif1 |= 0xc;
1393 break;
1394 default:
1395 return -EINVAL;
1396 }
1397
1398 dev_dbg(&i2c->dev, "MCLK = %dHz, target sample rate = %dHz\n",
1399 wm8903->sysclk, fs);
1400
1401 /* We may not have an MCLK which allows us to generate exactly
1402 * the clock we want, particularly with USB derived inputs, so
1403 * approximate.
1404 */
1405 clk_config = 0;
1406 best_val = abs((wm8903->sysclk /
1407 (clk_sys_ratios[0].mclk_div *
1408 clk_sys_ratios[0].div)) - fs);
1409 for (i = 1; i < ARRAY_SIZE(clk_sys_ratios); i++) {
1410 cur_val = abs((wm8903->sysclk /
1411 (clk_sys_ratios[i].mclk_div *
1412 clk_sys_ratios[i].div)) - fs);
1413
1414 if (cur_val <= best_val) {
1415 clk_config = i;
1416 best_val = cur_val;
1417 }
1418 }
1419
1420 if (clk_sys_ratios[clk_config].mclk_div == 2) {
1421 clock0 |= WM8903_MCLKDIV2;
1422 clk_sys = wm8903->sysclk / 2;
1423 } else {
1424 clock0 &= ~WM8903_MCLKDIV2;
1425 clk_sys = wm8903->sysclk;
1426 }
1427
1428 clock1 &= ~(WM8903_CLK_SYS_RATE_MASK |
1429 WM8903_CLK_SYS_MODE_MASK);
1430 clock1 |= clk_sys_ratios[clk_config].rate << WM8903_CLK_SYS_RATE_SHIFT;
1431 clock1 |= clk_sys_ratios[clk_config].mode << WM8903_CLK_SYS_MODE_SHIFT;
1432
1433 dev_dbg(&i2c->dev, "CLK_SYS_RATE=%x, CLK_SYS_MODE=%x div=%d\n",
1434 clk_sys_ratios[clk_config].rate,
1435 clk_sys_ratios[clk_config].mode,
1436 clk_sys_ratios[clk_config].div);
1437
1438 dev_dbg(&i2c->dev, "Actual CLK_SYS = %dHz\n", clk_sys);
1439
1440 /* We may not get quite the right frequency if using
1441 * approximate clocks so look for the closest match that is
1442 * higher than the target (we need to ensure that there enough
1443 * BCLKs to clock out the samples).
1444 */
1445 bclk_div = 0;
1446 best_val = ((clk_sys * 10) / bclk_divs[0].ratio) - bclk;
1447 i = 1;
1448 while (i < ARRAY_SIZE(bclk_divs)) {
1449 cur_val = ((clk_sys * 10) / bclk_divs[i].ratio) - bclk;
1450 if (cur_val < 0) /* BCLK table is sorted */
1451 break;
1452 bclk_div = i;
1453 best_val = cur_val;
1454 i++;
1455 }
1456
1457 aif2 &= ~WM8903_BCLK_DIV_MASK;
1458 aif3 &= ~WM8903_LRCLK_RATE_MASK;
1459
1460 dev_dbg(&i2c->dev, "BCLK ratio %d for %dHz - actual BCLK = %dHz\n",
1461 bclk_divs[bclk_div].ratio / 10, bclk,
1462 (clk_sys * 10) / bclk_divs[bclk_div].ratio);
1463
1464 aif2 |= bclk_divs[bclk_div].div;
1465 aif3 |= bclk / fs;
1466
1467 wm8903_write(codec, WM8903_CLOCK_RATES_0, clock0);
1468 wm8903_write(codec, WM8903_CLOCK_RATES_1, clock1);
1469 wm8903_write(codec, WM8903_AUDIO_INTERFACE_1, aif1);
1470 wm8903_write(codec, WM8903_AUDIO_INTERFACE_2, aif2);
1471 wm8903_write(codec, WM8903_AUDIO_INTERFACE_3, aif3);
1472
1473 return 0;
1474}
1475
1476#define WM8903_PLAYBACK_RATES (SNDRV_PCM_RATE_8000 |\
1477 SNDRV_PCM_RATE_11025 | \
1478 SNDRV_PCM_RATE_16000 | \
1479 SNDRV_PCM_RATE_22050 | \
1480 SNDRV_PCM_RATE_32000 | \
1481 SNDRV_PCM_RATE_44100 | \
1482 SNDRV_PCM_RATE_48000 | \
1483 SNDRV_PCM_RATE_88200 | \
1484 SNDRV_PCM_RATE_96000)
1485
1486#define WM8903_CAPTURE_RATES (SNDRV_PCM_RATE_8000 |\
1487 SNDRV_PCM_RATE_11025 | \
1488 SNDRV_PCM_RATE_16000 | \
1489 SNDRV_PCM_RATE_22050 | \
1490 SNDRV_PCM_RATE_32000 | \
1491 SNDRV_PCM_RATE_44100 | \
1492 SNDRV_PCM_RATE_48000)
1493
1494#define WM8903_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
1495 SNDRV_PCM_FMTBIT_S20_3LE |\
1496 SNDRV_PCM_FMTBIT_S24_LE)
1497
1498struct snd_soc_dai wm8903_dai = {
1499 .name = "WM8903",
1500 .playback = {
1501 .stream_name = "Playback",
1502 .channels_min = 2,
1503 .channels_max = 2,
1504 .rates = WM8903_PLAYBACK_RATES,
1505 .formats = WM8903_FORMATS,
1506 },
1507 .capture = {
1508 .stream_name = "Capture",
1509 .channels_min = 2,
1510 .channels_max = 2,
1511 .rates = WM8903_CAPTURE_RATES,
1512 .formats = WM8903_FORMATS,
1513 },
1514 .ops = {
1515 .startup = wm8903_startup,
1516 .shutdown = wm8903_shutdown,
1517 .hw_params = wm8903_hw_params,
1518 },
1519 .dai_ops = {
1520 .digital_mute = wm8903_digital_mute,
1521 .set_fmt = wm8903_set_dai_fmt,
1522 .set_sysclk = wm8903_set_dai_sysclk
1523 }
1524};
1525EXPORT_SYMBOL_GPL(wm8903_dai);
1526
1527static int wm8903_suspend(struct platform_device *pdev, pm_message_t state)
1528{
1529 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1530 struct snd_soc_codec *codec = socdev->codec;
1531
1532 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF);
1533
1534 return 0;
1535}
1536
1537static int wm8903_resume(struct platform_device *pdev)
1538{
1539 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1540 struct snd_soc_codec *codec = socdev->codec;
1541 struct i2c_client *i2c = codec->control_data;
1542 int i;
1543 u16 *reg_cache = codec->reg_cache;
1544 u16 *tmp_cache = kmemdup(codec->reg_cache, sizeof(wm8903_reg_defaults),
1545 GFP_KERNEL);
1546
1547 /* Bring the codec back up to standby first to minimise pop/clicks */
1548 wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1549 wm8903_set_bias_level(codec, codec->suspend_bias_level);
1550
1551 /* Sync back everything else */
1552 if (tmp_cache) {
1553 for (i = 2; i < ARRAY_SIZE(wm8903_reg_defaults); i++)
1554 if (tmp_cache[i] != reg_cache[i])
1555 wm8903_write(codec, i, tmp_cache[i]);
1556 } else {
1557 dev_err(&i2c->dev, "Failed to allocate temporary cache\n");
1558 }
1559
1560 return 0;
1561}
1562
1563/*
1564 * initialise the WM8903 driver
1565 * register the mixer and dsp interfaces with the kernel
1566 */
1567static int wm8903_init(struct snd_soc_device *socdev)
1568{
1569 struct snd_soc_codec *codec = socdev->codec;
1570 struct i2c_client *i2c = codec->control_data;
1571 int ret = 0;
1572 u16 val;
1573
1574 val = wm8903_hw_read(codec, WM8903_SW_RESET_AND_ID);
1575 if (val != wm8903_reg_defaults[WM8903_SW_RESET_AND_ID]) {
1576 dev_err(&i2c->dev,
1577 "Device with ID register %x is not a WM8903\n", val);
1578 return -ENODEV;
1579 }
1580
1581 codec->name = "WM8903";
1582 codec->owner = THIS_MODULE;
1583 codec->read = wm8903_read;
1584 codec->write = wm8903_write;
1585 codec->bias_level = SND_SOC_BIAS_OFF;
1586 codec->set_bias_level = wm8903_set_bias_level;
1587 codec->dai = &wm8903_dai;
1588 codec->num_dai = 1;
1589 codec->reg_cache_size = ARRAY_SIZE(wm8903_reg_defaults);
1590 codec->reg_cache = kmemdup(wm8903_reg_defaults,
1591 sizeof(wm8903_reg_defaults),
1592 GFP_KERNEL);
1593 if (codec->reg_cache == NULL) {
1594 dev_err(&i2c->dev, "Failed to allocate register cache\n");
1595 return -ENOMEM;
1596 }
1597
1598 val = wm8903_read(codec, WM8903_REVISION_NUMBER);
1599 dev_info(&i2c->dev, "WM8903 revision %d\n",
1600 val & WM8903_CHIP_REV_MASK);
1601
1602 wm8903_reset(codec);
1603
1604 /* register pcms */
1605 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1606 if (ret < 0) {
1607 dev_err(&i2c->dev, "failed to create pcms\n");
1608 goto pcm_err;
1609 }
1610
1611 /* SYSCLK is required for pretty much anything */
1612 wm8903_write(codec, WM8903_CLOCK_RATES_2, WM8903_CLK_SYS_ENA);
1613
1614 /* power on device */
1615 wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1616
1617 /* Latch volume update bits */
1618 val = wm8903_read(codec, WM8903_ADC_DIGITAL_VOLUME_LEFT);
1619 val |= WM8903_ADCVU;
1620 wm8903_write(codec, WM8903_ADC_DIGITAL_VOLUME_LEFT, val);
1621 wm8903_write(codec, WM8903_ADC_DIGITAL_VOLUME_RIGHT, val);
1622
1623 val = wm8903_read(codec, WM8903_DAC_DIGITAL_VOLUME_LEFT);
1624 val |= WM8903_DACVU;
1625 wm8903_write(codec, WM8903_DAC_DIGITAL_VOLUME_LEFT, val);
1626 wm8903_write(codec, WM8903_DAC_DIGITAL_VOLUME_RIGHT, val);
1627
1628 val = wm8903_read(codec, WM8903_ANALOGUE_OUT1_LEFT);
1629 val |= WM8903_HPOUTVU;
1630 wm8903_write(codec, WM8903_ANALOGUE_OUT1_LEFT, val);
1631 wm8903_write(codec, WM8903_ANALOGUE_OUT1_RIGHT, val);
1632
1633 val = wm8903_read(codec, WM8903_ANALOGUE_OUT2_LEFT);
1634 val |= WM8903_LINEOUTVU;
1635 wm8903_write(codec, WM8903_ANALOGUE_OUT2_LEFT, val);
1636 wm8903_write(codec, WM8903_ANALOGUE_OUT2_RIGHT, val);
1637
1638 val = wm8903_read(codec, WM8903_ANALOGUE_OUT3_LEFT);
1639 val |= WM8903_SPKVU;
1640 wm8903_write(codec, WM8903_ANALOGUE_OUT3_LEFT, val);
1641 wm8903_write(codec, WM8903_ANALOGUE_OUT3_RIGHT, val);
1642
1643 /* Enable DAC soft mute by default */
1644 val = wm8903_read(codec, WM8903_DAC_DIGITAL_1);
1645 val |= WM8903_DAC_MUTEMODE;
1646 wm8903_write(codec, WM8903_DAC_DIGITAL_1, val);
1647
1648 wm8903_add_controls(codec);
1649 wm8903_add_widgets(codec);
1650 ret = snd_soc_register_card(socdev);
1651 if (ret < 0) {
1652 dev_err(&i2c->dev, "wm8903: failed to register card\n");
1653 goto card_err;
1654 }
1655
1656 return ret;
1657
1658card_err:
1659 snd_soc_free_pcms(socdev);
1660 snd_soc_dapm_free(socdev);
1661pcm_err:
1662 kfree(codec->reg_cache);
1663 return ret;
1664}
1665
1666static struct snd_soc_device *wm8903_socdev;
1667
1668static int wm8903_i2c_probe(struct i2c_client *i2c,
1669 const struct i2c_device_id *id)
1670{
1671 struct snd_soc_device *socdev = wm8903_socdev;
1672 struct snd_soc_codec *codec = socdev->codec;
1673 int ret;
1674
1675 i2c_set_clientdata(i2c, codec);
1676 codec->control_data = i2c;
1677
1678 ret = wm8903_init(socdev);
1679 if (ret < 0)
1680 dev_err(&i2c->dev, "Device initialisation failed\n");
1681
1682 return ret;
1683}
1684
1685static int wm8903_i2c_remove(struct i2c_client *client)
1686{
1687 struct snd_soc_codec *codec = i2c_get_clientdata(client);
1688 kfree(codec->reg_cache);
1689 return 0;
1690}
1691
1692/* i2c codec control layer */
1693static const struct i2c_device_id wm8903_i2c_id[] = {
1694 { "wm8903", 0 },
1695 { }
1696};
1697MODULE_DEVICE_TABLE(i2c, wm8903_i2c_id);
1698
1699static struct i2c_driver wm8903_i2c_driver = {
1700 .driver = {
1701 .name = "WM8903",
1702 .owner = THIS_MODULE,
1703 },
1704 .probe = wm8903_i2c_probe,
1705 .remove = wm8903_i2c_remove,
1706 .id_table = wm8903_i2c_id,
1707};
1708
1709static int wm8903_probe(struct platform_device *pdev)
1710{
1711 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1712 struct wm8903_setup_data *setup;
1713 struct snd_soc_codec *codec;
1714 struct wm8903_priv *wm8903;
1715 struct i2c_board_info board_info;
1716 struct i2c_adapter *adapter;
1717 struct i2c_client *i2c_client;
1718 int ret = 0;
1719
1720 setup = socdev->codec_data;
1721
1722 if (!setup->i2c_address) {
1723 dev_err(&pdev->dev, "No codec address provided\n");
1724 return -ENODEV;
1725 }
1726
1727 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
1728 if (codec == NULL)
1729 return -ENOMEM;
1730
1731 wm8903 = kzalloc(sizeof(struct wm8903_priv), GFP_KERNEL);
1732 if (wm8903 == NULL) {
1733 ret = -ENOMEM;
1734 goto err_codec;
1735 }
1736
1737 codec->private_data = wm8903;
1738 socdev->codec = codec;
1739 mutex_init(&codec->mutex);
1740 INIT_LIST_HEAD(&codec->dapm_widgets);
1741 INIT_LIST_HEAD(&codec->dapm_paths);
1742
1743 wm8903_socdev = socdev;
1744
1745 codec->hw_write = (hw_write_t)i2c_master_send;
1746 ret = i2c_add_driver(&wm8903_i2c_driver);
1747 if (ret != 0) {
1748 dev_err(&pdev->dev, "can't add i2c driver\n");
1749 goto err_priv;
1750 } else {
1751 memset(&board_info, 0, sizeof(board_info));
1752 strlcpy(board_info.type, "wm8903", I2C_NAME_SIZE);
1753 board_info.addr = setup->i2c_address;
1754
1755 adapter = i2c_get_adapter(setup->i2c_bus);
1756 if (!adapter) {
1757 dev_err(&pdev->dev, "Can't get I2C bus %d\n",
1758 setup->i2c_bus);
1759 ret = -ENODEV;
1760 goto err_adapter;
1761 }
1762
1763 i2c_client = i2c_new_device(adapter, &board_info);
1764 i2c_put_adapter(adapter);
1765 if (i2c_client == NULL) {
1766 dev_err(&pdev->dev,
1767 "I2C driver registration failed\n");
1768 ret = -ENODEV;
1769 goto err_adapter;
1770 }
1771 }
1772
1773 return ret;
1774
1775err_adapter:
1776 i2c_del_driver(&wm8903_i2c_driver);
1777err_priv:
1778 kfree(codec->private_data);
1779err_codec:
1780 kfree(codec);
1781 return ret;
1782}
1783
1784/* power down chip */
1785static int wm8903_remove(struct platform_device *pdev)
1786{
1787 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1788 struct snd_soc_codec *codec = socdev->codec;
1789
1790 if (codec->control_data)
1791 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF);
1792
1793 snd_soc_free_pcms(socdev);
1794 snd_soc_dapm_free(socdev);
1795 i2c_unregister_device(socdev->codec->control_data);
1796 i2c_del_driver(&wm8903_i2c_driver);
1797 kfree(codec->private_data);
1798 kfree(codec);
1799
1800 return 0;
1801}
1802
1803struct snd_soc_codec_device soc_codec_dev_wm8903 = {
1804 .probe = wm8903_probe,
1805 .remove = wm8903_remove,
1806 .suspend = wm8903_suspend,
1807 .resume = wm8903_resume,
1808};
1809EXPORT_SYMBOL_GPL(soc_codec_dev_wm8903);
1810
1811MODULE_DESCRIPTION("ASoC WM8903 driver");
1812MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.cm>");
1813MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8903.h b/sound/soc/codecs/wm8903.h
new file mode 100644
index 000000000000..cec622f2f660
--- /dev/null
+++ b/sound/soc/codecs/wm8903.h
@@ -0,0 +1,1463 @@
1/*
2 * wm8903.h - WM8903 audio codec interface
3 *
4 * Copyright 2008 Wolfson Microelectronics PLC.
5 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#ifndef _WM8903_H
14#define _WM8903_H
15
16#include <linux/i2c.h>
17
18extern struct snd_soc_dai wm8903_dai;
19extern struct snd_soc_codec_device soc_codec_dev_wm8903;
20
21struct wm8903_setup_data {
22 int i2c_bus;
23 int i2c_address;
24};
25
26#define WM8903_MCLK_DIV_2 1
27#define WM8903_CLK_SYS 2
28#define WM8903_BCLK 3
29#define WM8903_LRCLK 4
30
31/*
32 * Register values.
33 */
34#define WM8903_SW_RESET_AND_ID 0x00
35#define WM8903_REVISION_NUMBER 0x01
36#define WM8903_BIAS_CONTROL_0 0x04
37#define WM8903_VMID_CONTROL_0 0x05
38#define WM8903_MIC_BIAS_CONTROL_0 0x06
39#define WM8903_ANALOGUE_DAC_0 0x08
40#define WM8903_ANALOGUE_ADC_0 0x0A
41#define WM8903_POWER_MANAGEMENT_0 0x0C
42#define WM8903_POWER_MANAGEMENT_1 0x0D
43#define WM8903_POWER_MANAGEMENT_2 0x0E
44#define WM8903_POWER_MANAGEMENT_3 0x0F
45#define WM8903_POWER_MANAGEMENT_4 0x10
46#define WM8903_POWER_MANAGEMENT_5 0x11
47#define WM8903_POWER_MANAGEMENT_6 0x12
48#define WM8903_CLOCK_RATES_0 0x14
49#define WM8903_CLOCK_RATES_1 0x15
50#define WM8903_CLOCK_RATES_2 0x16
51#define WM8903_AUDIO_INTERFACE_0 0x18
52#define WM8903_AUDIO_INTERFACE_1 0x19
53#define WM8903_AUDIO_INTERFACE_2 0x1A
54#define WM8903_AUDIO_INTERFACE_3 0x1B
55#define WM8903_DAC_DIGITAL_VOLUME_LEFT 0x1E
56#define WM8903_DAC_DIGITAL_VOLUME_RIGHT 0x1F
57#define WM8903_DAC_DIGITAL_0 0x20
58#define WM8903_DAC_DIGITAL_1 0x21
59#define WM8903_ADC_DIGITAL_VOLUME_LEFT 0x24
60#define WM8903_ADC_DIGITAL_VOLUME_RIGHT 0x25
61#define WM8903_ADC_DIGITAL_0 0x26
62#define WM8903_DIGITAL_MICROPHONE_0 0x27
63#define WM8903_DRC_0 0x28
64#define WM8903_DRC_1 0x29
65#define WM8903_DRC_2 0x2A
66#define WM8903_DRC_3 0x2B
67#define WM8903_ANALOGUE_LEFT_INPUT_0 0x2C
68#define WM8903_ANALOGUE_RIGHT_INPUT_0 0x2D
69#define WM8903_ANALOGUE_LEFT_INPUT_1 0x2E
70#define WM8903_ANALOGUE_RIGHT_INPUT_1 0x2F
71#define WM8903_ANALOGUE_LEFT_MIX_0 0x32
72#define WM8903_ANALOGUE_RIGHT_MIX_0 0x33
73#define WM8903_ANALOGUE_SPK_MIX_LEFT_0 0x34
74#define WM8903_ANALOGUE_SPK_MIX_LEFT_1 0x35
75#define WM8903_ANALOGUE_SPK_MIX_RIGHT_0 0x36
76#define WM8903_ANALOGUE_SPK_MIX_RIGHT_1 0x37
77#define WM8903_ANALOGUE_OUT1_LEFT 0x39
78#define WM8903_ANALOGUE_OUT1_RIGHT 0x3A
79#define WM8903_ANALOGUE_OUT2_LEFT 0x3B
80#define WM8903_ANALOGUE_OUT2_RIGHT 0x3C
81#define WM8903_ANALOGUE_OUT3_LEFT 0x3E
82#define WM8903_ANALOGUE_OUT3_RIGHT 0x3F
83#define WM8903_ANALOGUE_SPK_OUTPUT_CONTROL_0 0x41
84#define WM8903_DC_SERVO_0 0x43
85#define WM8903_DC_SERVO_2 0x45
86#define WM8903_ANALOGUE_HP_0 0x5A
87#define WM8903_ANALOGUE_LINEOUT_0 0x5E
88#define WM8903_CHARGE_PUMP_0 0x62
89#define WM8903_CLASS_W_0 0x68
90#define WM8903_WRITE_SEQUENCER_0 0x6C
91#define WM8903_WRITE_SEQUENCER_1 0x6D
92#define WM8903_WRITE_SEQUENCER_2 0x6E
93#define WM8903_WRITE_SEQUENCER_3 0x6F
94#define WM8903_WRITE_SEQUENCER_4 0x70
95#define WM8903_CONTROL_INTERFACE 0x72
96#define WM8903_GPIO_CONTROL_1 0x74
97#define WM8903_GPIO_CONTROL_2 0x75
98#define WM8903_GPIO_CONTROL_3 0x76
99#define WM8903_GPIO_CONTROL_4 0x77
100#define WM8903_GPIO_CONTROL_5 0x78
101#define WM8903_INTERRUPT_STATUS_1 0x79
102#define WM8903_INTERRUPT_STATUS_1_MASK 0x7A
103#define WM8903_INTERRUPT_POLARITY_1 0x7B
104#define WM8903_INTERRUPT_CONTROL 0x7E
105#define WM8903_CONTROL_INTERFACE_TEST_1 0x81
106#define WM8903_CHARGE_PUMP_TEST_1 0x95
107#define WM8903_CLOCK_RATE_TEST_4 0xA4
108#define WM8903_ANALOGUE_OUTPUT_BIAS_0 0xAC
109
110#define WM8903_REGISTER_COUNT 75
111#define WM8903_MAX_REGISTER 0xAC
112
113/*
114 * Field Definitions.
115 */
116
117/*
118 * R0 (0x00) - SW Reset and ID
119 */
120#define WM8903_SW_RESET_DEV_ID1_MASK 0xFFFF /* SW_RESET_DEV_ID1 - [15:0] */
121#define WM8903_SW_RESET_DEV_ID1_SHIFT 0 /* SW_RESET_DEV_ID1 - [15:0] */
122#define WM8903_SW_RESET_DEV_ID1_WIDTH 16 /* SW_RESET_DEV_ID1 - [15:0] */
123
124/*
125 * R1 (0x01) - Revision Number
126 */
127#define WM8903_CHIP_REV_MASK 0x000F /* CHIP_REV - [3:0] */
128#define WM8903_CHIP_REV_SHIFT 0 /* CHIP_REV - [3:0] */
129#define WM8903_CHIP_REV_WIDTH 4 /* CHIP_REV - [3:0] */
130
131/*
132 * R4 (0x04) - Bias Control 0
133 */
134#define WM8903_POBCTRL 0x0010 /* POBCTRL */
135#define WM8903_POBCTRL_MASK 0x0010 /* POBCTRL */
136#define WM8903_POBCTRL_SHIFT 4 /* POBCTRL */
137#define WM8903_POBCTRL_WIDTH 1 /* POBCTRL */
138#define WM8903_ISEL_MASK 0x000C /* ISEL - [3:2] */
139#define WM8903_ISEL_SHIFT 2 /* ISEL - [3:2] */
140#define WM8903_ISEL_WIDTH 2 /* ISEL - [3:2] */
141#define WM8903_STARTUP_BIAS_ENA 0x0002 /* STARTUP_BIAS_ENA */
142#define WM8903_STARTUP_BIAS_ENA_MASK 0x0002 /* STARTUP_BIAS_ENA */
143#define WM8903_STARTUP_BIAS_ENA_SHIFT 1 /* STARTUP_BIAS_ENA */
144#define WM8903_STARTUP_BIAS_ENA_WIDTH 1 /* STARTUP_BIAS_ENA */
145#define WM8903_BIAS_ENA 0x0001 /* BIAS_ENA */
146#define WM8903_BIAS_ENA_MASK 0x0001 /* BIAS_ENA */
147#define WM8903_BIAS_ENA_SHIFT 0 /* BIAS_ENA */
148#define WM8903_BIAS_ENA_WIDTH 1 /* BIAS_ENA */
149
150/*
151 * R5 (0x05) - VMID Control 0
152 */
153#define WM8903_VMID_TIE_ENA 0x0080 /* VMID_TIE_ENA */
154#define WM8903_VMID_TIE_ENA_MASK 0x0080 /* VMID_TIE_ENA */
155#define WM8903_VMID_TIE_ENA_SHIFT 7 /* VMID_TIE_ENA */
156#define WM8903_VMID_TIE_ENA_WIDTH 1 /* VMID_TIE_ENA */
157#define WM8903_BUFIO_ENA 0x0040 /* BUFIO_ENA */
158#define WM8903_BUFIO_ENA_MASK 0x0040 /* BUFIO_ENA */
159#define WM8903_BUFIO_ENA_SHIFT 6 /* BUFIO_ENA */
160#define WM8903_BUFIO_ENA_WIDTH 1 /* BUFIO_ENA */
161#define WM8903_VMID_IO_ENA 0x0020 /* VMID_IO_ENA */
162#define WM8903_VMID_IO_ENA_MASK 0x0020 /* VMID_IO_ENA */
163#define WM8903_VMID_IO_ENA_SHIFT 5 /* VMID_IO_ENA */
164#define WM8903_VMID_IO_ENA_WIDTH 1 /* VMID_IO_ENA */
165#define WM8903_VMID_SOFT_MASK 0x0018 /* VMID_SOFT - [4:3] */
166#define WM8903_VMID_SOFT_SHIFT 3 /* VMID_SOFT - [4:3] */
167#define WM8903_VMID_SOFT_WIDTH 2 /* VMID_SOFT - [4:3] */
168#define WM8903_VMID_RES_MASK 0x0006 /* VMID_RES - [2:1] */
169#define WM8903_VMID_RES_SHIFT 1 /* VMID_RES - [2:1] */
170#define WM8903_VMID_RES_WIDTH 2 /* VMID_RES - [2:1] */
171#define WM8903_VMID_BUF_ENA 0x0001 /* VMID_BUF_ENA */
172#define WM8903_VMID_BUF_ENA_MASK 0x0001 /* VMID_BUF_ENA */
173#define WM8903_VMID_BUF_ENA_SHIFT 0 /* VMID_BUF_ENA */
174#define WM8903_VMID_BUF_ENA_WIDTH 1 /* VMID_BUF_ENA */
175
176#define WM8903_VMID_RES_50K 2
177#define WM8903_VMID_RES_250K 3
178#define WM8903_VMID_RES_5K 4
179
180/*
181 * R6 (0x06) - Mic Bias Control 0
182 */
183#define WM8903_MICDET_HYST_ENA 0x0080 /* MICDET_HYST_ENA */
184#define WM8903_MICDET_HYST_ENA_MASK 0x0080 /* MICDET_HYST_ENA */
185#define WM8903_MICDET_HYST_ENA_SHIFT 7 /* MICDET_HYST_ENA */
186#define WM8903_MICDET_HYST_ENA_WIDTH 1 /* MICDET_HYST_ENA */
187#define WM8903_MICDET_THR_MASK 0x0070 /* MICDET_THR - [6:4] */
188#define WM8903_MICDET_THR_SHIFT 4 /* MICDET_THR - [6:4] */
189#define WM8903_MICDET_THR_WIDTH 3 /* MICDET_THR - [6:4] */
190#define WM8903_MICSHORT_THR_MASK 0x000C /* MICSHORT_THR - [3:2] */
191#define WM8903_MICSHORT_THR_SHIFT 2 /* MICSHORT_THR - [3:2] */
192#define WM8903_MICSHORT_THR_WIDTH 2 /* MICSHORT_THR - [3:2] */
193#define WM8903_MICDET_ENA 0x0002 /* MICDET_ENA */
194#define WM8903_MICDET_ENA_MASK 0x0002 /* MICDET_ENA */
195#define WM8903_MICDET_ENA_SHIFT 1 /* MICDET_ENA */
196#define WM8903_MICDET_ENA_WIDTH 1 /* MICDET_ENA */
197#define WM8903_MICBIAS_ENA 0x0001 /* MICBIAS_ENA */
198#define WM8903_MICBIAS_ENA_MASK 0x0001 /* MICBIAS_ENA */
199#define WM8903_MICBIAS_ENA_SHIFT 0 /* MICBIAS_ENA */
200#define WM8903_MICBIAS_ENA_WIDTH 1 /* MICBIAS_ENA */
201
202/*
203 * R8 (0x08) - Analogue DAC 0
204 */
205#define WM8903_DACBIAS_SEL_MASK 0x0018 /* DACBIAS_SEL - [4:3] */
206#define WM8903_DACBIAS_SEL_SHIFT 3 /* DACBIAS_SEL - [4:3] */
207#define WM8903_DACBIAS_SEL_WIDTH 2 /* DACBIAS_SEL - [4:3] */
208#define WM8903_DACVMID_BIAS_SEL_MASK 0x0006 /* DACVMID_BIAS_SEL - [2:1] */
209#define WM8903_DACVMID_BIAS_SEL_SHIFT 1 /* DACVMID_BIAS_SEL - [2:1] */
210#define WM8903_DACVMID_BIAS_SEL_WIDTH 2 /* DACVMID_BIAS_SEL - [2:1] */
211
212/*
213 * R10 (0x0A) - Analogue ADC 0
214 */
215#define WM8903_ADC_OSR128 0x0001 /* ADC_OSR128 */
216#define WM8903_ADC_OSR128_MASK 0x0001 /* ADC_OSR128 */
217#define WM8903_ADC_OSR128_SHIFT 0 /* ADC_OSR128 */
218#define WM8903_ADC_OSR128_WIDTH 1 /* ADC_OSR128 */
219
220/*
221 * R12 (0x0C) - Power Management 0
222 */
223#define WM8903_INL_ENA 0x0002 /* INL_ENA */
224#define WM8903_INL_ENA_MASK 0x0002 /* INL_ENA */
225#define WM8903_INL_ENA_SHIFT 1 /* INL_ENA */
226#define WM8903_INL_ENA_WIDTH 1 /* INL_ENA */
227#define WM8903_INR_ENA 0x0001 /* INR_ENA */
228#define WM8903_INR_ENA_MASK 0x0001 /* INR_ENA */
229#define WM8903_INR_ENA_SHIFT 0 /* INR_ENA */
230#define WM8903_INR_ENA_WIDTH 1 /* INR_ENA */
231
232/*
233 * R13 (0x0D) - Power Management 1
234 */
235#define WM8903_MIXOUTL_ENA 0x0002 /* MIXOUTL_ENA */
236#define WM8903_MIXOUTL_ENA_MASK 0x0002 /* MIXOUTL_ENA */
237#define WM8903_MIXOUTL_ENA_SHIFT 1 /* MIXOUTL_ENA */
238#define WM8903_MIXOUTL_ENA_WIDTH 1 /* MIXOUTL_ENA */
239#define WM8903_MIXOUTR_ENA 0x0001 /* MIXOUTR_ENA */
240#define WM8903_MIXOUTR_ENA_MASK 0x0001 /* MIXOUTR_ENA */
241#define WM8903_MIXOUTR_ENA_SHIFT 0 /* MIXOUTR_ENA */
242#define WM8903_MIXOUTR_ENA_WIDTH 1 /* MIXOUTR_ENA */
243
244/*
245 * R14 (0x0E) - Power Management 2
246 */
247#define WM8903_HPL_PGA_ENA 0x0002 /* HPL_PGA_ENA */
248#define WM8903_HPL_PGA_ENA_MASK 0x0002 /* HPL_PGA_ENA */
249#define WM8903_HPL_PGA_ENA_SHIFT 1 /* HPL_PGA_ENA */
250#define WM8903_HPL_PGA_ENA_WIDTH 1 /* HPL_PGA_ENA */
251#define WM8903_HPR_PGA_ENA 0x0001 /* HPR_PGA_ENA */
252#define WM8903_HPR_PGA_ENA_MASK 0x0001 /* HPR_PGA_ENA */
253#define WM8903_HPR_PGA_ENA_SHIFT 0 /* HPR_PGA_ENA */
254#define WM8903_HPR_PGA_ENA_WIDTH 1 /* HPR_PGA_ENA */
255
256/*
257 * R15 (0x0F) - Power Management 3
258 */
259#define WM8903_LINEOUTL_PGA_ENA 0x0002 /* LINEOUTL_PGA_ENA */
260#define WM8903_LINEOUTL_PGA_ENA_MASK 0x0002 /* LINEOUTL_PGA_ENA */
261#define WM8903_LINEOUTL_PGA_ENA_SHIFT 1 /* LINEOUTL_PGA_ENA */
262#define WM8903_LINEOUTL_PGA_ENA_WIDTH 1 /* LINEOUTL_PGA_ENA */
263#define WM8903_LINEOUTR_PGA_ENA 0x0001 /* LINEOUTR_PGA_ENA */
264#define WM8903_LINEOUTR_PGA_ENA_MASK 0x0001 /* LINEOUTR_PGA_ENA */
265#define WM8903_LINEOUTR_PGA_ENA_SHIFT 0 /* LINEOUTR_PGA_ENA */
266#define WM8903_LINEOUTR_PGA_ENA_WIDTH 1 /* LINEOUTR_PGA_ENA */
267
268/*
269 * R16 (0x10) - Power Management 4
270 */
271#define WM8903_MIXSPKL_ENA 0x0002 /* MIXSPKL_ENA */
272#define WM8903_MIXSPKL_ENA_MASK 0x0002 /* MIXSPKL_ENA */
273#define WM8903_MIXSPKL_ENA_SHIFT 1 /* MIXSPKL_ENA */
274#define WM8903_MIXSPKL_ENA_WIDTH 1 /* MIXSPKL_ENA */
275#define WM8903_MIXSPKR_ENA 0x0001 /* MIXSPKR_ENA */
276#define WM8903_MIXSPKR_ENA_MASK 0x0001 /* MIXSPKR_ENA */
277#define WM8903_MIXSPKR_ENA_SHIFT 0 /* MIXSPKR_ENA */
278#define WM8903_MIXSPKR_ENA_WIDTH 1 /* MIXSPKR_ENA */
279
280/*
281 * R17 (0x11) - Power Management 5
282 */
283#define WM8903_SPKL_ENA 0x0002 /* SPKL_ENA */
284#define WM8903_SPKL_ENA_MASK 0x0002 /* SPKL_ENA */
285#define WM8903_SPKL_ENA_SHIFT 1 /* SPKL_ENA */
286#define WM8903_SPKL_ENA_WIDTH 1 /* SPKL_ENA */
287#define WM8903_SPKR_ENA 0x0001 /* SPKR_ENA */
288#define WM8903_SPKR_ENA_MASK 0x0001 /* SPKR_ENA */
289#define WM8903_SPKR_ENA_SHIFT 0 /* SPKR_ENA */
290#define WM8903_SPKR_ENA_WIDTH 1 /* SPKR_ENA */
291
292/*
293 * R18 (0x12) - Power Management 6
294 */
295#define WM8903_DACL_ENA 0x0008 /* DACL_ENA */
296#define WM8903_DACL_ENA_MASK 0x0008 /* DACL_ENA */
297#define WM8903_DACL_ENA_SHIFT 3 /* DACL_ENA */
298#define WM8903_DACL_ENA_WIDTH 1 /* DACL_ENA */
299#define WM8903_DACR_ENA 0x0004 /* DACR_ENA */
300#define WM8903_DACR_ENA_MASK 0x0004 /* DACR_ENA */
301#define WM8903_DACR_ENA_SHIFT 2 /* DACR_ENA */
302#define WM8903_DACR_ENA_WIDTH 1 /* DACR_ENA */
303#define WM8903_ADCL_ENA 0x0002 /* ADCL_ENA */
304#define WM8903_ADCL_ENA_MASK 0x0002 /* ADCL_ENA */
305#define WM8903_ADCL_ENA_SHIFT 1 /* ADCL_ENA */
306#define WM8903_ADCL_ENA_WIDTH 1 /* ADCL_ENA */
307#define WM8903_ADCR_ENA 0x0001 /* ADCR_ENA */
308#define WM8903_ADCR_ENA_MASK 0x0001 /* ADCR_ENA */
309#define WM8903_ADCR_ENA_SHIFT 0 /* ADCR_ENA */
310#define WM8903_ADCR_ENA_WIDTH 1 /* ADCR_ENA */
311
312/*
313 * R20 (0x14) - Clock Rates 0
314 */
315#define WM8903_MCLKDIV2 0x0001 /* MCLKDIV2 */
316#define WM8903_MCLKDIV2_MASK 0x0001 /* MCLKDIV2 */
317#define WM8903_MCLKDIV2_SHIFT 0 /* MCLKDIV2 */
318#define WM8903_MCLKDIV2_WIDTH 1 /* MCLKDIV2 */
319
320/*
321 * R21 (0x15) - Clock Rates 1
322 */
323#define WM8903_CLK_SYS_RATE_MASK 0x3C00 /* CLK_SYS_RATE - [13:10] */
324#define WM8903_CLK_SYS_RATE_SHIFT 10 /* CLK_SYS_RATE - [13:10] */
325#define WM8903_CLK_SYS_RATE_WIDTH 4 /* CLK_SYS_RATE - [13:10] */
326#define WM8903_CLK_SYS_MODE_MASK 0x0300 /* CLK_SYS_MODE - [9:8] */
327#define WM8903_CLK_SYS_MODE_SHIFT 8 /* CLK_SYS_MODE - [9:8] */
328#define WM8903_CLK_SYS_MODE_WIDTH 2 /* CLK_SYS_MODE - [9:8] */
329#define WM8903_SAMPLE_RATE_MASK 0x000F /* SAMPLE_RATE - [3:0] */
330#define WM8903_SAMPLE_RATE_SHIFT 0 /* SAMPLE_RATE - [3:0] */
331#define WM8903_SAMPLE_RATE_WIDTH 4 /* SAMPLE_RATE - [3:0] */
332
333/*
334 * R22 (0x16) - Clock Rates 2
335 */
336#define WM8903_CLK_SYS_ENA 0x0004 /* CLK_SYS_ENA */
337#define WM8903_CLK_SYS_ENA_MASK 0x0004 /* CLK_SYS_ENA */
338#define WM8903_CLK_SYS_ENA_SHIFT 2 /* CLK_SYS_ENA */
339#define WM8903_CLK_SYS_ENA_WIDTH 1 /* CLK_SYS_ENA */
340#define WM8903_CLK_DSP_ENA 0x0002 /* CLK_DSP_ENA */
341#define WM8903_CLK_DSP_ENA_MASK 0x0002 /* CLK_DSP_ENA */
342#define WM8903_CLK_DSP_ENA_SHIFT 1 /* CLK_DSP_ENA */
343#define WM8903_CLK_DSP_ENA_WIDTH 1 /* CLK_DSP_ENA */
344#define WM8903_TO_ENA 0x0001 /* TO_ENA */
345#define WM8903_TO_ENA_MASK 0x0001 /* TO_ENA */
346#define WM8903_TO_ENA_SHIFT 0 /* TO_ENA */
347#define WM8903_TO_ENA_WIDTH 1 /* TO_ENA */
348
349/*
350 * R24 (0x18) - Audio Interface 0
351 */
352#define WM8903_DACL_DATINV 0x1000 /* DACL_DATINV */
353#define WM8903_DACL_DATINV_MASK 0x1000 /* DACL_DATINV */
354#define WM8903_DACL_DATINV_SHIFT 12 /* DACL_DATINV */
355#define WM8903_DACL_DATINV_WIDTH 1 /* DACL_DATINV */
356#define WM8903_DACR_DATINV 0x0800 /* DACR_DATINV */
357#define WM8903_DACR_DATINV_MASK 0x0800 /* DACR_DATINV */
358#define WM8903_DACR_DATINV_SHIFT 11 /* DACR_DATINV */
359#define WM8903_DACR_DATINV_WIDTH 1 /* DACR_DATINV */
360#define WM8903_DAC_BOOST_MASK 0x0600 /* DAC_BOOST - [10:9] */
361#define WM8903_DAC_BOOST_SHIFT 9 /* DAC_BOOST - [10:9] */
362#define WM8903_DAC_BOOST_WIDTH 2 /* DAC_BOOST - [10:9] */
363#define WM8903_LOOPBACK 0x0100 /* LOOPBACK */
364#define WM8903_LOOPBACK_MASK 0x0100 /* LOOPBACK */
365#define WM8903_LOOPBACK_SHIFT 8 /* LOOPBACK */
366#define WM8903_LOOPBACK_WIDTH 1 /* LOOPBACK */
367#define WM8903_AIFADCL_SRC 0x0080 /* AIFADCL_SRC */
368#define WM8903_AIFADCL_SRC_MASK 0x0080 /* AIFADCL_SRC */
369#define WM8903_AIFADCL_SRC_SHIFT 7 /* AIFADCL_SRC */
370#define WM8903_AIFADCL_SRC_WIDTH 1 /* AIFADCL_SRC */
371#define WM8903_AIFADCR_SRC 0x0040 /* AIFADCR_SRC */
372#define WM8903_AIFADCR_SRC_MASK 0x0040 /* AIFADCR_SRC */
373#define WM8903_AIFADCR_SRC_SHIFT 6 /* AIFADCR_SRC */
374#define WM8903_AIFADCR_SRC_WIDTH 1 /* AIFADCR_SRC */
375#define WM8903_AIFDACL_SRC 0x0020 /* AIFDACL_SRC */
376#define WM8903_AIFDACL_SRC_MASK 0x0020 /* AIFDACL_SRC */
377#define WM8903_AIFDACL_SRC_SHIFT 5 /* AIFDACL_SRC */
378#define WM8903_AIFDACL_SRC_WIDTH 1 /* AIFDACL_SRC */
379#define WM8903_AIFDACR_SRC 0x0010 /* AIFDACR_SRC */
380#define WM8903_AIFDACR_SRC_MASK 0x0010 /* AIFDACR_SRC */
381#define WM8903_AIFDACR_SRC_SHIFT 4 /* AIFDACR_SRC */
382#define WM8903_AIFDACR_SRC_WIDTH 1 /* AIFDACR_SRC */
383#define WM8903_ADC_COMP 0x0008 /* ADC_COMP */
384#define WM8903_ADC_COMP_MASK 0x0008 /* ADC_COMP */
385#define WM8903_ADC_COMP_SHIFT 3 /* ADC_COMP */
386#define WM8903_ADC_COMP_WIDTH 1 /* ADC_COMP */
387#define WM8903_ADC_COMPMODE 0x0004 /* ADC_COMPMODE */
388#define WM8903_ADC_COMPMODE_MASK 0x0004 /* ADC_COMPMODE */
389#define WM8903_ADC_COMPMODE_SHIFT 2 /* ADC_COMPMODE */
390#define WM8903_ADC_COMPMODE_WIDTH 1 /* ADC_COMPMODE */
391#define WM8903_DAC_COMP 0x0002 /* DAC_COMP */
392#define WM8903_DAC_COMP_MASK 0x0002 /* DAC_COMP */
393#define WM8903_DAC_COMP_SHIFT 1 /* DAC_COMP */
394#define WM8903_DAC_COMP_WIDTH 1 /* DAC_COMP */
395#define WM8903_DAC_COMPMODE 0x0001 /* DAC_COMPMODE */
396#define WM8903_DAC_COMPMODE_MASK 0x0001 /* DAC_COMPMODE */
397#define WM8903_DAC_COMPMODE_SHIFT 0 /* DAC_COMPMODE */
398#define WM8903_DAC_COMPMODE_WIDTH 1 /* DAC_COMPMODE */
399
400/*
401 * R25 (0x19) - Audio Interface 1
402 */
403#define WM8903_AIFDAC_TDM 0x2000 /* AIFDAC_TDM */
404#define WM8903_AIFDAC_TDM_MASK 0x2000 /* AIFDAC_TDM */
405#define WM8903_AIFDAC_TDM_SHIFT 13 /* AIFDAC_TDM */
406#define WM8903_AIFDAC_TDM_WIDTH 1 /* AIFDAC_TDM */
407#define WM8903_AIFDAC_TDM_CHAN 0x1000 /* AIFDAC_TDM_CHAN */
408#define WM8903_AIFDAC_TDM_CHAN_MASK 0x1000 /* AIFDAC_TDM_CHAN */
409#define WM8903_AIFDAC_TDM_CHAN_SHIFT 12 /* AIFDAC_TDM_CHAN */
410#define WM8903_AIFDAC_TDM_CHAN_WIDTH 1 /* AIFDAC_TDM_CHAN */
411#define WM8903_AIFADC_TDM 0x0800 /* AIFADC_TDM */
412#define WM8903_AIFADC_TDM_MASK 0x0800 /* AIFADC_TDM */
413#define WM8903_AIFADC_TDM_SHIFT 11 /* AIFADC_TDM */
414#define WM8903_AIFADC_TDM_WIDTH 1 /* AIFADC_TDM */
415#define WM8903_AIFADC_TDM_CHAN 0x0400 /* AIFADC_TDM_CHAN */
416#define WM8903_AIFADC_TDM_CHAN_MASK 0x0400 /* AIFADC_TDM_CHAN */
417#define WM8903_AIFADC_TDM_CHAN_SHIFT 10 /* AIFADC_TDM_CHAN */
418#define WM8903_AIFADC_TDM_CHAN_WIDTH 1 /* AIFADC_TDM_CHAN */
419#define WM8903_LRCLK_DIR 0x0200 /* LRCLK_DIR */
420#define WM8903_LRCLK_DIR_MASK 0x0200 /* LRCLK_DIR */
421#define WM8903_LRCLK_DIR_SHIFT 9 /* LRCLK_DIR */
422#define WM8903_LRCLK_DIR_WIDTH 1 /* LRCLK_DIR */
423#define WM8903_AIF_BCLK_INV 0x0080 /* AIF_BCLK_INV */
424#define WM8903_AIF_BCLK_INV_MASK 0x0080 /* AIF_BCLK_INV */
425#define WM8903_AIF_BCLK_INV_SHIFT 7 /* AIF_BCLK_INV */
426#define WM8903_AIF_BCLK_INV_WIDTH 1 /* AIF_BCLK_INV */
427#define WM8903_BCLK_DIR 0x0040 /* BCLK_DIR */
428#define WM8903_BCLK_DIR_MASK 0x0040 /* BCLK_DIR */
429#define WM8903_BCLK_DIR_SHIFT 6 /* BCLK_DIR */
430#define WM8903_BCLK_DIR_WIDTH 1 /* BCLK_DIR */
431#define WM8903_AIF_LRCLK_INV 0x0010 /* AIF_LRCLK_INV */
432#define WM8903_AIF_LRCLK_INV_MASK 0x0010 /* AIF_LRCLK_INV */
433#define WM8903_AIF_LRCLK_INV_SHIFT 4 /* AIF_LRCLK_INV */
434#define WM8903_AIF_LRCLK_INV_WIDTH 1 /* AIF_LRCLK_INV */
435#define WM8903_AIF_WL_MASK 0x000C /* AIF_WL - [3:2] */
436#define WM8903_AIF_WL_SHIFT 2 /* AIF_WL - [3:2] */
437#define WM8903_AIF_WL_WIDTH 2 /* AIF_WL - [3:2] */
438#define WM8903_AIF_FMT_MASK 0x0003 /* AIF_FMT - [1:0] */
439#define WM8903_AIF_FMT_SHIFT 0 /* AIF_FMT - [1:0] */
440#define WM8903_AIF_FMT_WIDTH 2 /* AIF_FMT - [1:0] */
441
442/*
443 * R26 (0x1A) - Audio Interface 2
444 */
445#define WM8903_BCLK_DIV_MASK 0x001F /* BCLK_DIV - [4:0] */
446#define WM8903_BCLK_DIV_SHIFT 0 /* BCLK_DIV - [4:0] */
447#define WM8903_BCLK_DIV_WIDTH 5 /* BCLK_DIV - [4:0] */
448
449/*
450 * R27 (0x1B) - Audio Interface 3
451 */
452#define WM8903_LRCLK_RATE_MASK 0x07FF /* LRCLK_RATE - [10:0] */
453#define WM8903_LRCLK_RATE_SHIFT 0 /* LRCLK_RATE - [10:0] */
454#define WM8903_LRCLK_RATE_WIDTH 11 /* LRCLK_RATE - [10:0] */
455
456/*
457 * R30 (0x1E) - DAC Digital Volume Left
458 */
459#define WM8903_DACVU 0x0100 /* DACVU */
460#define WM8903_DACVU_MASK 0x0100 /* DACVU */
461#define WM8903_DACVU_SHIFT 8 /* DACVU */
462#define WM8903_DACVU_WIDTH 1 /* DACVU */
463#define WM8903_DACL_VOL_MASK 0x00FF /* DACL_VOL - [7:0] */
464#define WM8903_DACL_VOL_SHIFT 0 /* DACL_VOL - [7:0] */
465#define WM8903_DACL_VOL_WIDTH 8 /* DACL_VOL - [7:0] */
466
467/*
468 * R31 (0x1F) - DAC Digital Volume Right
469 */
470#define WM8903_DACVU 0x0100 /* DACVU */
471#define WM8903_DACVU_MASK 0x0100 /* DACVU */
472#define WM8903_DACVU_SHIFT 8 /* DACVU */
473#define WM8903_DACVU_WIDTH 1 /* DACVU */
474#define WM8903_DACR_VOL_MASK 0x00FF /* DACR_VOL - [7:0] */
475#define WM8903_DACR_VOL_SHIFT 0 /* DACR_VOL - [7:0] */
476#define WM8903_DACR_VOL_WIDTH 8 /* DACR_VOL - [7:0] */
477
478/*
479 * R32 (0x20) - DAC Digital 0
480 */
481#define WM8903_ADCL_DAC_SVOL_MASK 0x0F00 /* ADCL_DAC_SVOL - [11:8] */
482#define WM8903_ADCL_DAC_SVOL_SHIFT 8 /* ADCL_DAC_SVOL - [11:8] */
483#define WM8903_ADCL_DAC_SVOL_WIDTH 4 /* ADCL_DAC_SVOL - [11:8] */
484#define WM8903_ADCR_DAC_SVOL_MASK 0x00F0 /* ADCR_DAC_SVOL - [7:4] */
485#define WM8903_ADCR_DAC_SVOL_SHIFT 4 /* ADCR_DAC_SVOL - [7:4] */
486#define WM8903_ADCR_DAC_SVOL_WIDTH 4 /* ADCR_DAC_SVOL - [7:4] */
487#define WM8903_ADC_TO_DACL_MASK 0x000C /* ADC_TO_DACL - [3:2] */
488#define WM8903_ADC_TO_DACL_SHIFT 2 /* ADC_TO_DACL - [3:2] */
489#define WM8903_ADC_TO_DACL_WIDTH 2 /* ADC_TO_DACL - [3:2] */
490#define WM8903_ADC_TO_DACR_MASK 0x0003 /* ADC_TO_DACR - [1:0] */
491#define WM8903_ADC_TO_DACR_SHIFT 0 /* ADC_TO_DACR - [1:0] */
492#define WM8903_ADC_TO_DACR_WIDTH 2 /* ADC_TO_DACR - [1:0] */
493
494/*
495 * R33 (0x21) - DAC Digital 1
496 */
497#define WM8903_DAC_MONO 0x1000 /* DAC_MONO */
498#define WM8903_DAC_MONO_MASK 0x1000 /* DAC_MONO */
499#define WM8903_DAC_MONO_SHIFT 12 /* DAC_MONO */
500#define WM8903_DAC_MONO_WIDTH 1 /* DAC_MONO */
501#define WM8903_DAC_SB_FILT 0x0800 /* DAC_SB_FILT */
502#define WM8903_DAC_SB_FILT_MASK 0x0800 /* DAC_SB_FILT */
503#define WM8903_DAC_SB_FILT_SHIFT 11 /* DAC_SB_FILT */
504#define WM8903_DAC_SB_FILT_WIDTH 1 /* DAC_SB_FILT */
505#define WM8903_DAC_MUTERATE 0x0400 /* DAC_MUTERATE */
506#define WM8903_DAC_MUTERATE_MASK 0x0400 /* DAC_MUTERATE */
507#define WM8903_DAC_MUTERATE_SHIFT 10 /* DAC_MUTERATE */
508#define WM8903_DAC_MUTERATE_WIDTH 1 /* DAC_MUTERATE */
509#define WM8903_DAC_MUTEMODE 0x0200 /* DAC_MUTEMODE */
510#define WM8903_DAC_MUTEMODE_MASK 0x0200 /* DAC_MUTEMODE */
511#define WM8903_DAC_MUTEMODE_SHIFT 9 /* DAC_MUTEMODE */
512#define WM8903_DAC_MUTEMODE_WIDTH 1 /* DAC_MUTEMODE */
513#define WM8903_DAC_MUTE 0x0008 /* DAC_MUTE */
514#define WM8903_DAC_MUTE_MASK 0x0008 /* DAC_MUTE */
515#define WM8903_DAC_MUTE_SHIFT 3 /* DAC_MUTE */
516#define WM8903_DAC_MUTE_WIDTH 1 /* DAC_MUTE */
517#define WM8903_DEEMPH_MASK 0x0006 /* DEEMPH - [2:1] */
518#define WM8903_DEEMPH_SHIFT 1 /* DEEMPH - [2:1] */
519#define WM8903_DEEMPH_WIDTH 2 /* DEEMPH - [2:1] */
520
521/*
522 * R36 (0x24) - ADC Digital Volume Left
523 */
524#define WM8903_ADCVU 0x0100 /* ADCVU */
525#define WM8903_ADCVU_MASK 0x0100 /* ADCVU */
526#define WM8903_ADCVU_SHIFT 8 /* ADCVU */
527#define WM8903_ADCVU_WIDTH 1 /* ADCVU */
528#define WM8903_ADCL_VOL_MASK 0x00FF /* ADCL_VOL - [7:0] */
529#define WM8903_ADCL_VOL_SHIFT 0 /* ADCL_VOL - [7:0] */
530#define WM8903_ADCL_VOL_WIDTH 8 /* ADCL_VOL - [7:0] */
531
532/*
533 * R37 (0x25) - ADC Digital Volume Right
534 */
535#define WM8903_ADCVU 0x0100 /* ADCVU */
536#define WM8903_ADCVU_MASK 0x0100 /* ADCVU */
537#define WM8903_ADCVU_SHIFT 8 /* ADCVU */
538#define WM8903_ADCVU_WIDTH 1 /* ADCVU */
539#define WM8903_ADCR_VOL_MASK 0x00FF /* ADCR_VOL - [7:0] */
540#define WM8903_ADCR_VOL_SHIFT 0 /* ADCR_VOL - [7:0] */
541#define WM8903_ADCR_VOL_WIDTH 8 /* ADCR_VOL - [7:0] */
542
543/*
544 * R38 (0x26) - ADC Digital 0
545 */
546#define WM8903_ADC_HPF_CUT_MASK 0x0060 /* ADC_HPF_CUT - [6:5] */
547#define WM8903_ADC_HPF_CUT_SHIFT 5 /* ADC_HPF_CUT - [6:5] */
548#define WM8903_ADC_HPF_CUT_WIDTH 2 /* ADC_HPF_CUT - [6:5] */
549#define WM8903_ADC_HPF_ENA 0x0010 /* ADC_HPF_ENA */
550#define WM8903_ADC_HPF_ENA_MASK 0x0010 /* ADC_HPF_ENA */
551#define WM8903_ADC_HPF_ENA_SHIFT 4 /* ADC_HPF_ENA */
552#define WM8903_ADC_HPF_ENA_WIDTH 1 /* ADC_HPF_ENA */
553#define WM8903_ADCL_DATINV 0x0002 /* ADCL_DATINV */
554#define WM8903_ADCL_DATINV_MASK 0x0002 /* ADCL_DATINV */
555#define WM8903_ADCL_DATINV_SHIFT 1 /* ADCL_DATINV */
556#define WM8903_ADCL_DATINV_WIDTH 1 /* ADCL_DATINV */
557#define WM8903_ADCR_DATINV 0x0001 /* ADCR_DATINV */
558#define WM8903_ADCR_DATINV_MASK 0x0001 /* ADCR_DATINV */
559#define WM8903_ADCR_DATINV_SHIFT 0 /* ADCR_DATINV */
560#define WM8903_ADCR_DATINV_WIDTH 1 /* ADCR_DATINV */
561
562/*
563 * R39 (0x27) - Digital Microphone 0
564 */
565#define WM8903_DIGMIC_MODE_SEL 0x0100 /* DIGMIC_MODE_SEL */
566#define WM8903_DIGMIC_MODE_SEL_MASK 0x0100 /* DIGMIC_MODE_SEL */
567#define WM8903_DIGMIC_MODE_SEL_SHIFT 8 /* DIGMIC_MODE_SEL */
568#define WM8903_DIGMIC_MODE_SEL_WIDTH 1 /* DIGMIC_MODE_SEL */
569#define WM8903_DIGMIC_CLK_SEL_L_MASK 0x00C0 /* DIGMIC_CLK_SEL_L - [7:6] */
570#define WM8903_DIGMIC_CLK_SEL_L_SHIFT 6 /* DIGMIC_CLK_SEL_L - [7:6] */
571#define WM8903_DIGMIC_CLK_SEL_L_WIDTH 2 /* DIGMIC_CLK_SEL_L - [7:6] */
572#define WM8903_DIGMIC_CLK_SEL_R_MASK 0x0030 /* DIGMIC_CLK_SEL_R - [5:4] */
573#define WM8903_DIGMIC_CLK_SEL_R_SHIFT 4 /* DIGMIC_CLK_SEL_R - [5:4] */
574#define WM8903_DIGMIC_CLK_SEL_R_WIDTH 2 /* DIGMIC_CLK_SEL_R - [5:4] */
575#define WM8903_DIGMIC_CLK_SEL_RT_MASK 0x000C /* DIGMIC_CLK_SEL_RT - [3:2] */
576#define WM8903_DIGMIC_CLK_SEL_RT_SHIFT 2 /* DIGMIC_CLK_SEL_RT - [3:2] */
577#define WM8903_DIGMIC_CLK_SEL_RT_WIDTH 2 /* DIGMIC_CLK_SEL_RT - [3:2] */
578#define WM8903_DIGMIC_CLK_SEL_MASK 0x0003 /* DIGMIC_CLK_SEL - [1:0] */
579#define WM8903_DIGMIC_CLK_SEL_SHIFT 0 /* DIGMIC_CLK_SEL - [1:0] */
580#define WM8903_DIGMIC_CLK_SEL_WIDTH 2 /* DIGMIC_CLK_SEL - [1:0] */
581
582/*
583 * R40 (0x28) - DRC 0
584 */
585#define WM8903_DRC_ENA 0x8000 /* DRC_ENA */
586#define WM8903_DRC_ENA_MASK 0x8000 /* DRC_ENA */
587#define WM8903_DRC_ENA_SHIFT 15 /* DRC_ENA */
588#define WM8903_DRC_ENA_WIDTH 1 /* DRC_ENA */
589#define WM8903_DRC_THRESH_HYST_MASK 0x1800 /* DRC_THRESH_HYST - [12:11] */
590#define WM8903_DRC_THRESH_HYST_SHIFT 11 /* DRC_THRESH_HYST - [12:11] */
591#define WM8903_DRC_THRESH_HYST_WIDTH 2 /* DRC_THRESH_HYST - [12:11] */
592#define WM8903_DRC_STARTUP_GAIN_MASK 0x07C0 /* DRC_STARTUP_GAIN - [10:6] */
593#define WM8903_DRC_STARTUP_GAIN_SHIFT 6 /* DRC_STARTUP_GAIN - [10:6] */
594#define WM8903_DRC_STARTUP_GAIN_WIDTH 5 /* DRC_STARTUP_GAIN - [10:6] */
595#define WM8903_DRC_FF_DELAY 0x0020 /* DRC_FF_DELAY */
596#define WM8903_DRC_FF_DELAY_MASK 0x0020 /* DRC_FF_DELAY */
597#define WM8903_DRC_FF_DELAY_SHIFT 5 /* DRC_FF_DELAY */
598#define WM8903_DRC_FF_DELAY_WIDTH 1 /* DRC_FF_DELAY */
599#define WM8903_DRC_SMOOTH_ENA 0x0008 /* DRC_SMOOTH_ENA */
600#define WM8903_DRC_SMOOTH_ENA_MASK 0x0008 /* DRC_SMOOTH_ENA */
601#define WM8903_DRC_SMOOTH_ENA_SHIFT 3 /* DRC_SMOOTH_ENA */
602#define WM8903_DRC_SMOOTH_ENA_WIDTH 1 /* DRC_SMOOTH_ENA */
603#define WM8903_DRC_QR_ENA 0x0004 /* DRC_QR_ENA */
604#define WM8903_DRC_QR_ENA_MASK 0x0004 /* DRC_QR_ENA */
605#define WM8903_DRC_QR_ENA_SHIFT 2 /* DRC_QR_ENA */
606#define WM8903_DRC_QR_ENA_WIDTH 1 /* DRC_QR_ENA */
607#define WM8903_DRC_ANTICLIP_ENA 0x0002 /* DRC_ANTICLIP_ENA */
608#define WM8903_DRC_ANTICLIP_ENA_MASK 0x0002 /* DRC_ANTICLIP_ENA */
609#define WM8903_DRC_ANTICLIP_ENA_SHIFT 1 /* DRC_ANTICLIP_ENA */
610#define WM8903_DRC_ANTICLIP_ENA_WIDTH 1 /* DRC_ANTICLIP_ENA */
611#define WM8903_DRC_HYST_ENA 0x0001 /* DRC_HYST_ENA */
612#define WM8903_DRC_HYST_ENA_MASK 0x0001 /* DRC_HYST_ENA */
613#define WM8903_DRC_HYST_ENA_SHIFT 0 /* DRC_HYST_ENA */
614#define WM8903_DRC_HYST_ENA_WIDTH 1 /* DRC_HYST_ENA */
615
616/*
617 * R41 (0x29) - DRC 1
618 */
619#define WM8903_DRC_ATTACK_RATE_MASK 0xF000 /* DRC_ATTACK_RATE - [15:12] */
620#define WM8903_DRC_ATTACK_RATE_SHIFT 12 /* DRC_ATTACK_RATE - [15:12] */
621#define WM8903_DRC_ATTACK_RATE_WIDTH 4 /* DRC_ATTACK_RATE - [15:12] */
622#define WM8903_DRC_DECAY_RATE_MASK 0x0F00 /* DRC_DECAY_RATE - [11:8] */
623#define WM8903_DRC_DECAY_RATE_SHIFT 8 /* DRC_DECAY_RATE - [11:8] */
624#define WM8903_DRC_DECAY_RATE_WIDTH 4 /* DRC_DECAY_RATE - [11:8] */
625#define WM8903_DRC_THRESH_QR_MASK 0x00C0 /* DRC_THRESH_QR - [7:6] */
626#define WM8903_DRC_THRESH_QR_SHIFT 6 /* DRC_THRESH_QR - [7:6] */
627#define WM8903_DRC_THRESH_QR_WIDTH 2 /* DRC_THRESH_QR - [7:6] */
628#define WM8903_DRC_RATE_QR_MASK 0x0030 /* DRC_RATE_QR - [5:4] */
629#define WM8903_DRC_RATE_QR_SHIFT 4 /* DRC_RATE_QR - [5:4] */
630#define WM8903_DRC_RATE_QR_WIDTH 2 /* DRC_RATE_QR - [5:4] */
631#define WM8903_DRC_MINGAIN_MASK 0x000C /* DRC_MINGAIN - [3:2] */
632#define WM8903_DRC_MINGAIN_SHIFT 2 /* DRC_MINGAIN - [3:2] */
633#define WM8903_DRC_MINGAIN_WIDTH 2 /* DRC_MINGAIN - [3:2] */
634#define WM8903_DRC_MAXGAIN_MASK 0x0003 /* DRC_MAXGAIN - [1:0] */
635#define WM8903_DRC_MAXGAIN_SHIFT 0 /* DRC_MAXGAIN - [1:0] */
636#define WM8903_DRC_MAXGAIN_WIDTH 2 /* DRC_MAXGAIN - [1:0] */
637
638/*
639 * R42 (0x2A) - DRC 2
640 */
641#define WM8903_DRC_R0_SLOPE_COMP_MASK 0x0038 /* DRC_R0_SLOPE_COMP - [5:3] */
642#define WM8903_DRC_R0_SLOPE_COMP_SHIFT 3 /* DRC_R0_SLOPE_COMP - [5:3] */
643#define WM8903_DRC_R0_SLOPE_COMP_WIDTH 3 /* DRC_R0_SLOPE_COMP - [5:3] */
644#define WM8903_DRC_R1_SLOPE_COMP_MASK 0x0007 /* DRC_R1_SLOPE_COMP - [2:0] */
645#define WM8903_DRC_R1_SLOPE_COMP_SHIFT 0 /* DRC_R1_SLOPE_COMP - [2:0] */
646#define WM8903_DRC_R1_SLOPE_COMP_WIDTH 3 /* DRC_R1_SLOPE_COMP - [2:0] */
647
648/*
649 * R43 (0x2B) - DRC 3
650 */
651#define WM8903_DRC_THRESH_COMP_MASK 0x07E0 /* DRC_THRESH_COMP - [10:5] */
652#define WM8903_DRC_THRESH_COMP_SHIFT 5 /* DRC_THRESH_COMP - [10:5] */
653#define WM8903_DRC_THRESH_COMP_WIDTH 6 /* DRC_THRESH_COMP - [10:5] */
654#define WM8903_DRC_AMP_COMP_MASK 0x001F /* DRC_AMP_COMP - [4:0] */
655#define WM8903_DRC_AMP_COMP_SHIFT 0 /* DRC_AMP_COMP - [4:0] */
656#define WM8903_DRC_AMP_COMP_WIDTH 5 /* DRC_AMP_COMP - [4:0] */
657
658/*
659 * R44 (0x2C) - Analogue Left Input 0
660 */
661#define WM8903_LINMUTE 0x0080 /* LINMUTE */
662#define WM8903_LINMUTE_MASK 0x0080 /* LINMUTE */
663#define WM8903_LINMUTE_SHIFT 7 /* LINMUTE */
664#define WM8903_LINMUTE_WIDTH 1 /* LINMUTE */
665#define WM8903_LIN_VOL_MASK 0x001F /* LIN_VOL - [4:0] */
666#define WM8903_LIN_VOL_SHIFT 0 /* LIN_VOL - [4:0] */
667#define WM8903_LIN_VOL_WIDTH 5 /* LIN_VOL - [4:0] */
668
669/*
670 * R45 (0x2D) - Analogue Right Input 0
671 */
672#define WM8903_RINMUTE 0x0080 /* RINMUTE */
673#define WM8903_RINMUTE_MASK 0x0080 /* RINMUTE */
674#define WM8903_RINMUTE_SHIFT 7 /* RINMUTE */
675#define WM8903_RINMUTE_WIDTH 1 /* RINMUTE */
676#define WM8903_RIN_VOL_MASK 0x001F /* RIN_VOL - [4:0] */
677#define WM8903_RIN_VOL_SHIFT 0 /* RIN_VOL - [4:0] */
678#define WM8903_RIN_VOL_WIDTH 5 /* RIN_VOL - [4:0] */
679
680/*
681 * R46 (0x2E) - Analogue Left Input 1
682 */
683#define WM8903_INL_CM_ENA 0x0040 /* INL_CM_ENA */
684#define WM8903_INL_CM_ENA_MASK 0x0040 /* INL_CM_ENA */
685#define WM8903_INL_CM_ENA_SHIFT 6 /* INL_CM_ENA */
686#define WM8903_INL_CM_ENA_WIDTH 1 /* INL_CM_ENA */
687#define WM8903_L_IP_SEL_N_MASK 0x0030 /* L_IP_SEL_N - [5:4] */
688#define WM8903_L_IP_SEL_N_SHIFT 4 /* L_IP_SEL_N - [5:4] */
689#define WM8903_L_IP_SEL_N_WIDTH 2 /* L_IP_SEL_N - [5:4] */
690#define WM8903_L_IP_SEL_P_MASK 0x000C /* L_IP_SEL_P - [3:2] */
691#define WM8903_L_IP_SEL_P_SHIFT 2 /* L_IP_SEL_P - [3:2] */
692#define WM8903_L_IP_SEL_P_WIDTH 2 /* L_IP_SEL_P - [3:2] */
693#define WM8903_L_MODE_MASK 0x0003 /* L_MODE - [1:0] */
694#define WM8903_L_MODE_SHIFT 0 /* L_MODE - [1:0] */
695#define WM8903_L_MODE_WIDTH 2 /* L_MODE - [1:0] */
696
697/*
698 * R47 (0x2F) - Analogue Right Input 1
699 */
700#define WM8903_INR_CM_ENA 0x0040 /* INR_CM_ENA */
701#define WM8903_INR_CM_ENA_MASK 0x0040 /* INR_CM_ENA */
702#define WM8903_INR_CM_ENA_SHIFT 6 /* INR_CM_ENA */
703#define WM8903_INR_CM_ENA_WIDTH 1 /* INR_CM_ENA */
704#define WM8903_R_IP_SEL_N_MASK 0x0030 /* R_IP_SEL_N - [5:4] */
705#define WM8903_R_IP_SEL_N_SHIFT 4 /* R_IP_SEL_N - [5:4] */
706#define WM8903_R_IP_SEL_N_WIDTH 2 /* R_IP_SEL_N - [5:4] */
707#define WM8903_R_IP_SEL_P_MASK 0x000C /* R_IP_SEL_P - [3:2] */
708#define WM8903_R_IP_SEL_P_SHIFT 2 /* R_IP_SEL_P - [3:2] */
709#define WM8903_R_IP_SEL_P_WIDTH 2 /* R_IP_SEL_P - [3:2] */
710#define WM8903_R_MODE_MASK 0x0003 /* R_MODE - [1:0] */
711#define WM8903_R_MODE_SHIFT 0 /* R_MODE - [1:0] */
712#define WM8903_R_MODE_WIDTH 2 /* R_MODE - [1:0] */
713
714/*
715 * R50 (0x32) - Analogue Left Mix 0
716 */
717#define WM8903_DACL_TO_MIXOUTL 0x0008 /* DACL_TO_MIXOUTL */
718#define WM8903_DACL_TO_MIXOUTL_MASK 0x0008 /* DACL_TO_MIXOUTL */
719#define WM8903_DACL_TO_MIXOUTL_SHIFT 3 /* DACL_TO_MIXOUTL */
720#define WM8903_DACL_TO_MIXOUTL_WIDTH 1 /* DACL_TO_MIXOUTL */
721#define WM8903_DACR_TO_MIXOUTL 0x0004 /* DACR_TO_MIXOUTL */
722#define WM8903_DACR_TO_MIXOUTL_MASK 0x0004 /* DACR_TO_MIXOUTL */
723#define WM8903_DACR_TO_MIXOUTL_SHIFT 2 /* DACR_TO_MIXOUTL */
724#define WM8903_DACR_TO_MIXOUTL_WIDTH 1 /* DACR_TO_MIXOUTL */
725#define WM8903_BYPASSL_TO_MIXOUTL 0x0002 /* BYPASSL_TO_MIXOUTL */
726#define WM8903_BYPASSL_TO_MIXOUTL_MASK 0x0002 /* BYPASSL_TO_MIXOUTL */
727#define WM8903_BYPASSL_TO_MIXOUTL_SHIFT 1 /* BYPASSL_TO_MIXOUTL */
728#define WM8903_BYPASSL_TO_MIXOUTL_WIDTH 1 /* BYPASSL_TO_MIXOUTL */
729#define WM8903_BYPASSR_TO_MIXOUTL 0x0001 /* BYPASSR_TO_MIXOUTL */
730#define WM8903_BYPASSR_TO_MIXOUTL_MASK 0x0001 /* BYPASSR_TO_MIXOUTL */
731#define WM8903_BYPASSR_TO_MIXOUTL_SHIFT 0 /* BYPASSR_TO_MIXOUTL */
732#define WM8903_BYPASSR_TO_MIXOUTL_WIDTH 1 /* BYPASSR_TO_MIXOUTL */
733
734/*
735 * R51 (0x33) - Analogue Right Mix 0
736 */
737#define WM8903_DACL_TO_MIXOUTR 0x0008 /* DACL_TO_MIXOUTR */
738#define WM8903_DACL_TO_MIXOUTR_MASK 0x0008 /* DACL_TO_MIXOUTR */
739#define WM8903_DACL_TO_MIXOUTR_SHIFT 3 /* DACL_TO_MIXOUTR */
740#define WM8903_DACL_TO_MIXOUTR_WIDTH 1 /* DACL_TO_MIXOUTR */
741#define WM8903_DACR_TO_MIXOUTR 0x0004 /* DACR_TO_MIXOUTR */
742#define WM8903_DACR_TO_MIXOUTR_MASK 0x0004 /* DACR_TO_MIXOUTR */
743#define WM8903_DACR_TO_MIXOUTR_SHIFT 2 /* DACR_TO_MIXOUTR */
744#define WM8903_DACR_TO_MIXOUTR_WIDTH 1 /* DACR_TO_MIXOUTR */
745#define WM8903_BYPASSL_TO_MIXOUTR 0x0002 /* BYPASSL_TO_MIXOUTR */
746#define WM8903_BYPASSL_TO_MIXOUTR_MASK 0x0002 /* BYPASSL_TO_MIXOUTR */
747#define WM8903_BYPASSL_TO_MIXOUTR_SHIFT 1 /* BYPASSL_TO_MIXOUTR */
748#define WM8903_BYPASSL_TO_MIXOUTR_WIDTH 1 /* BYPASSL_TO_MIXOUTR */
749#define WM8903_BYPASSR_TO_MIXOUTR 0x0001 /* BYPASSR_TO_MIXOUTR */
750#define WM8903_BYPASSR_TO_MIXOUTR_MASK 0x0001 /* BYPASSR_TO_MIXOUTR */
751#define WM8903_BYPASSR_TO_MIXOUTR_SHIFT 0 /* BYPASSR_TO_MIXOUTR */
752#define WM8903_BYPASSR_TO_MIXOUTR_WIDTH 1 /* BYPASSR_TO_MIXOUTR */
753
754/*
755 * R52 (0x34) - Analogue Spk Mix Left 0
756 */
757#define WM8903_DACL_TO_MIXSPKL 0x0008 /* DACL_TO_MIXSPKL */
758#define WM8903_DACL_TO_MIXSPKL_MASK 0x0008 /* DACL_TO_MIXSPKL */
759#define WM8903_DACL_TO_MIXSPKL_SHIFT 3 /* DACL_TO_MIXSPKL */
760#define WM8903_DACL_TO_MIXSPKL_WIDTH 1 /* DACL_TO_MIXSPKL */
761#define WM8903_DACR_TO_MIXSPKL 0x0004 /* DACR_TO_MIXSPKL */
762#define WM8903_DACR_TO_MIXSPKL_MASK 0x0004 /* DACR_TO_MIXSPKL */
763#define WM8903_DACR_TO_MIXSPKL_SHIFT 2 /* DACR_TO_MIXSPKL */
764#define WM8903_DACR_TO_MIXSPKL_WIDTH 1 /* DACR_TO_MIXSPKL */
765#define WM8903_BYPASSL_TO_MIXSPKL 0x0002 /* BYPASSL_TO_MIXSPKL */
766#define WM8903_BYPASSL_TO_MIXSPKL_MASK 0x0002 /* BYPASSL_TO_MIXSPKL */
767#define WM8903_BYPASSL_TO_MIXSPKL_SHIFT 1 /* BYPASSL_TO_MIXSPKL */
768#define WM8903_BYPASSL_TO_MIXSPKL_WIDTH 1 /* BYPASSL_TO_MIXSPKL */
769#define WM8903_BYPASSR_TO_MIXSPKL 0x0001 /* BYPASSR_TO_MIXSPKL */
770#define WM8903_BYPASSR_TO_MIXSPKL_MASK 0x0001 /* BYPASSR_TO_MIXSPKL */
771#define WM8903_BYPASSR_TO_MIXSPKL_SHIFT 0 /* BYPASSR_TO_MIXSPKL */
772#define WM8903_BYPASSR_TO_MIXSPKL_WIDTH 1 /* BYPASSR_TO_MIXSPKL */
773
774/*
775 * R53 (0x35) - Analogue Spk Mix Left 1
776 */
777#define WM8903_DACL_MIXSPKL_VOL 0x0008 /* DACL_MIXSPKL_VOL */
778#define WM8903_DACL_MIXSPKL_VOL_MASK 0x0008 /* DACL_MIXSPKL_VOL */
779#define WM8903_DACL_MIXSPKL_VOL_SHIFT 3 /* DACL_MIXSPKL_VOL */
780#define WM8903_DACL_MIXSPKL_VOL_WIDTH 1 /* DACL_MIXSPKL_VOL */
781#define WM8903_DACR_MIXSPKL_VOL 0x0004 /* DACR_MIXSPKL_VOL */
782#define WM8903_DACR_MIXSPKL_VOL_MASK 0x0004 /* DACR_MIXSPKL_VOL */
783#define WM8903_DACR_MIXSPKL_VOL_SHIFT 2 /* DACR_MIXSPKL_VOL */
784#define WM8903_DACR_MIXSPKL_VOL_WIDTH 1 /* DACR_MIXSPKL_VOL */
785#define WM8903_BYPASSL_MIXSPKL_VOL 0x0002 /* BYPASSL_MIXSPKL_VOL */
786#define WM8903_BYPASSL_MIXSPKL_VOL_MASK 0x0002 /* BYPASSL_MIXSPKL_VOL */
787#define WM8903_BYPASSL_MIXSPKL_VOL_SHIFT 1 /* BYPASSL_MIXSPKL_VOL */
788#define WM8903_BYPASSL_MIXSPKL_VOL_WIDTH 1 /* BYPASSL_MIXSPKL_VOL */
789#define WM8903_BYPASSR_MIXSPKL_VOL 0x0001 /* BYPASSR_MIXSPKL_VOL */
790#define WM8903_BYPASSR_MIXSPKL_VOL_MASK 0x0001 /* BYPASSR_MIXSPKL_VOL */
791#define WM8903_BYPASSR_MIXSPKL_VOL_SHIFT 0 /* BYPASSR_MIXSPKL_VOL */
792#define WM8903_BYPASSR_MIXSPKL_VOL_WIDTH 1 /* BYPASSR_MIXSPKL_VOL */
793
794/*
795 * R54 (0x36) - Analogue Spk Mix Right 0
796 */
797#define WM8903_DACL_TO_MIXSPKR 0x0008 /* DACL_TO_MIXSPKR */
798#define WM8903_DACL_TO_MIXSPKR_MASK 0x0008 /* DACL_TO_MIXSPKR */
799#define WM8903_DACL_TO_MIXSPKR_SHIFT 3 /* DACL_TO_MIXSPKR */
800#define WM8903_DACL_TO_MIXSPKR_WIDTH 1 /* DACL_TO_MIXSPKR */
801#define WM8903_DACR_TO_MIXSPKR 0x0004 /* DACR_TO_MIXSPKR */
802#define WM8903_DACR_TO_MIXSPKR_MASK 0x0004 /* DACR_TO_MIXSPKR */
803#define WM8903_DACR_TO_MIXSPKR_SHIFT 2 /* DACR_TO_MIXSPKR */
804#define WM8903_DACR_TO_MIXSPKR_WIDTH 1 /* DACR_TO_MIXSPKR */
805#define WM8903_BYPASSL_TO_MIXSPKR 0x0002 /* BYPASSL_TO_MIXSPKR */
806#define WM8903_BYPASSL_TO_MIXSPKR_MASK 0x0002 /* BYPASSL_TO_MIXSPKR */
807#define WM8903_BYPASSL_TO_MIXSPKR_SHIFT 1 /* BYPASSL_TO_MIXSPKR */
808#define WM8903_BYPASSL_TO_MIXSPKR_WIDTH 1 /* BYPASSL_TO_MIXSPKR */
809#define WM8903_BYPASSR_TO_MIXSPKR 0x0001 /* BYPASSR_TO_MIXSPKR */
810#define WM8903_BYPASSR_TO_MIXSPKR_MASK 0x0001 /* BYPASSR_TO_MIXSPKR */
811#define WM8903_BYPASSR_TO_MIXSPKR_SHIFT 0 /* BYPASSR_TO_MIXSPKR */
812#define WM8903_BYPASSR_TO_MIXSPKR_WIDTH 1 /* BYPASSR_TO_MIXSPKR */
813
814/*
815 * R55 (0x37) - Analogue Spk Mix Right 1
816 */
817#define WM8903_DACL_MIXSPKR_VOL 0x0008 /* DACL_MIXSPKR_VOL */
818#define WM8903_DACL_MIXSPKR_VOL_MASK 0x0008 /* DACL_MIXSPKR_VOL */
819#define WM8903_DACL_MIXSPKR_VOL_SHIFT 3 /* DACL_MIXSPKR_VOL */
820#define WM8903_DACL_MIXSPKR_VOL_WIDTH 1 /* DACL_MIXSPKR_VOL */
821#define WM8903_DACR_MIXSPKR_VOL 0x0004 /* DACR_MIXSPKR_VOL */
822#define WM8903_DACR_MIXSPKR_VOL_MASK 0x0004 /* DACR_MIXSPKR_VOL */
823#define WM8903_DACR_MIXSPKR_VOL_SHIFT 2 /* DACR_MIXSPKR_VOL */
824#define WM8903_DACR_MIXSPKR_VOL_WIDTH 1 /* DACR_MIXSPKR_VOL */
825#define WM8903_BYPASSL_MIXSPKR_VOL 0x0002 /* BYPASSL_MIXSPKR_VOL */
826#define WM8903_BYPASSL_MIXSPKR_VOL_MASK 0x0002 /* BYPASSL_MIXSPKR_VOL */
827#define WM8903_BYPASSL_MIXSPKR_VOL_SHIFT 1 /* BYPASSL_MIXSPKR_VOL */
828#define WM8903_BYPASSL_MIXSPKR_VOL_WIDTH 1 /* BYPASSL_MIXSPKR_VOL */
829#define WM8903_BYPASSR_MIXSPKR_VOL 0x0001 /* BYPASSR_MIXSPKR_VOL */
830#define WM8903_BYPASSR_MIXSPKR_VOL_MASK 0x0001 /* BYPASSR_MIXSPKR_VOL */
831#define WM8903_BYPASSR_MIXSPKR_VOL_SHIFT 0 /* BYPASSR_MIXSPKR_VOL */
832#define WM8903_BYPASSR_MIXSPKR_VOL_WIDTH 1 /* BYPASSR_MIXSPKR_VOL */
833
834/*
835 * R57 (0x39) - Analogue OUT1 Left
836 */
837#define WM8903_HPL_MUTE 0x0100 /* HPL_MUTE */
838#define WM8903_HPL_MUTE_MASK 0x0100 /* HPL_MUTE */
839#define WM8903_HPL_MUTE_SHIFT 8 /* HPL_MUTE */
840#define WM8903_HPL_MUTE_WIDTH 1 /* HPL_MUTE */
841#define WM8903_HPOUTVU 0x0080 /* HPOUTVU */
842#define WM8903_HPOUTVU_MASK 0x0080 /* HPOUTVU */
843#define WM8903_HPOUTVU_SHIFT 7 /* HPOUTVU */
844#define WM8903_HPOUTVU_WIDTH 1 /* HPOUTVU */
845#define WM8903_HPOUTLZC 0x0040 /* HPOUTLZC */
846#define WM8903_HPOUTLZC_MASK 0x0040 /* HPOUTLZC */
847#define WM8903_HPOUTLZC_SHIFT 6 /* HPOUTLZC */
848#define WM8903_HPOUTLZC_WIDTH 1 /* HPOUTLZC */
849#define WM8903_HPOUTL_VOL_MASK 0x003F /* HPOUTL_VOL - [5:0] */
850#define WM8903_HPOUTL_VOL_SHIFT 0 /* HPOUTL_VOL - [5:0] */
851#define WM8903_HPOUTL_VOL_WIDTH 6 /* HPOUTL_VOL - [5:0] */
852
853/*
854 * R58 (0x3A) - Analogue OUT1 Right
855 */
856#define WM8903_HPR_MUTE 0x0100 /* HPR_MUTE */
857#define WM8903_HPR_MUTE_MASK 0x0100 /* HPR_MUTE */
858#define WM8903_HPR_MUTE_SHIFT 8 /* HPR_MUTE */
859#define WM8903_HPR_MUTE_WIDTH 1 /* HPR_MUTE */
860#define WM8903_HPOUTVU 0x0080 /* HPOUTVU */
861#define WM8903_HPOUTVU_MASK 0x0080 /* HPOUTVU */
862#define WM8903_HPOUTVU_SHIFT 7 /* HPOUTVU */
863#define WM8903_HPOUTVU_WIDTH 1 /* HPOUTVU */
864#define WM8903_HPOUTRZC 0x0040 /* HPOUTRZC */
865#define WM8903_HPOUTRZC_MASK 0x0040 /* HPOUTRZC */
866#define WM8903_HPOUTRZC_SHIFT 6 /* HPOUTRZC */
867#define WM8903_HPOUTRZC_WIDTH 1 /* HPOUTRZC */
868#define WM8903_HPOUTR_VOL_MASK 0x003F /* HPOUTR_VOL - [5:0] */
869#define WM8903_HPOUTR_VOL_SHIFT 0 /* HPOUTR_VOL - [5:0] */
870#define WM8903_HPOUTR_VOL_WIDTH 6 /* HPOUTR_VOL - [5:0] */
871
872/*
873 * R59 (0x3B) - Analogue OUT2 Left
874 */
875#define WM8903_LINEOUTL_MUTE 0x0100 /* LINEOUTL_MUTE */
876#define WM8903_LINEOUTL_MUTE_MASK 0x0100 /* LINEOUTL_MUTE */
877#define WM8903_LINEOUTL_MUTE_SHIFT 8 /* LINEOUTL_MUTE */
878#define WM8903_LINEOUTL_MUTE_WIDTH 1 /* LINEOUTL_MUTE */
879#define WM8903_LINEOUTVU 0x0080 /* LINEOUTVU */
880#define WM8903_LINEOUTVU_MASK 0x0080 /* LINEOUTVU */
881#define WM8903_LINEOUTVU_SHIFT 7 /* LINEOUTVU */
882#define WM8903_LINEOUTVU_WIDTH 1 /* LINEOUTVU */
883#define WM8903_LINEOUTLZC 0x0040 /* LINEOUTLZC */
884#define WM8903_LINEOUTLZC_MASK 0x0040 /* LINEOUTLZC */
885#define WM8903_LINEOUTLZC_SHIFT 6 /* LINEOUTLZC */
886#define WM8903_LINEOUTLZC_WIDTH 1 /* LINEOUTLZC */
887#define WM8903_LINEOUTL_VOL_MASK 0x003F /* LINEOUTL_VOL - [5:0] */
888#define WM8903_LINEOUTL_VOL_SHIFT 0 /* LINEOUTL_VOL - [5:0] */
889#define WM8903_LINEOUTL_VOL_WIDTH 6 /* LINEOUTL_VOL - [5:0] */
890
891/*
892 * R60 (0x3C) - Analogue OUT2 Right
893 */
894#define WM8903_LINEOUTR_MUTE 0x0100 /* LINEOUTR_MUTE */
895#define WM8903_LINEOUTR_MUTE_MASK 0x0100 /* LINEOUTR_MUTE */
896#define WM8903_LINEOUTR_MUTE_SHIFT 8 /* LINEOUTR_MUTE */
897#define WM8903_LINEOUTR_MUTE_WIDTH 1 /* LINEOUTR_MUTE */
898#define WM8903_LINEOUTVU 0x0080 /* LINEOUTVU */
899#define WM8903_LINEOUTVU_MASK 0x0080 /* LINEOUTVU */
900#define WM8903_LINEOUTVU_SHIFT 7 /* LINEOUTVU */
901#define WM8903_LINEOUTVU_WIDTH 1 /* LINEOUTVU */
902#define WM8903_LINEOUTRZC 0x0040 /* LINEOUTRZC */
903#define WM8903_LINEOUTRZC_MASK 0x0040 /* LINEOUTRZC */
904#define WM8903_LINEOUTRZC_SHIFT 6 /* LINEOUTRZC */
905#define WM8903_LINEOUTRZC_WIDTH 1 /* LINEOUTRZC */
906#define WM8903_LINEOUTR_VOL_MASK 0x003F /* LINEOUTR_VOL - [5:0] */
907#define WM8903_LINEOUTR_VOL_SHIFT 0 /* LINEOUTR_VOL - [5:0] */
908#define WM8903_LINEOUTR_VOL_WIDTH 6 /* LINEOUTR_VOL - [5:0] */
909
910/*
911 * R62 (0x3E) - Analogue OUT3 Left
912 */
913#define WM8903_SPKL_MUTE 0x0100 /* SPKL_MUTE */
914#define WM8903_SPKL_MUTE_MASK 0x0100 /* SPKL_MUTE */
915#define WM8903_SPKL_MUTE_SHIFT 8 /* SPKL_MUTE */
916#define WM8903_SPKL_MUTE_WIDTH 1 /* SPKL_MUTE */
917#define WM8903_SPKVU 0x0080 /* SPKVU */
918#define WM8903_SPKVU_MASK 0x0080 /* SPKVU */
919#define WM8903_SPKVU_SHIFT 7 /* SPKVU */
920#define WM8903_SPKVU_WIDTH 1 /* SPKVU */
921#define WM8903_SPKLZC 0x0040 /* SPKLZC */
922#define WM8903_SPKLZC_MASK 0x0040 /* SPKLZC */
923#define WM8903_SPKLZC_SHIFT 6 /* SPKLZC */
924#define WM8903_SPKLZC_WIDTH 1 /* SPKLZC */
925#define WM8903_SPKL_VOL_MASK 0x003F /* SPKL_VOL - [5:0] */
926#define WM8903_SPKL_VOL_SHIFT 0 /* SPKL_VOL - [5:0] */
927#define WM8903_SPKL_VOL_WIDTH 6 /* SPKL_VOL - [5:0] */
928
929/*
930 * R63 (0x3F) - Analogue OUT3 Right
931 */
932#define WM8903_SPKR_MUTE 0x0100 /* SPKR_MUTE */
933#define WM8903_SPKR_MUTE_MASK 0x0100 /* SPKR_MUTE */
934#define WM8903_SPKR_MUTE_SHIFT 8 /* SPKR_MUTE */
935#define WM8903_SPKR_MUTE_WIDTH 1 /* SPKR_MUTE */
936#define WM8903_SPKVU 0x0080 /* SPKVU */
937#define WM8903_SPKVU_MASK 0x0080 /* SPKVU */
938#define WM8903_SPKVU_SHIFT 7 /* SPKVU */
939#define WM8903_SPKVU_WIDTH 1 /* SPKVU */
940#define WM8903_SPKRZC 0x0040 /* SPKRZC */
941#define WM8903_SPKRZC_MASK 0x0040 /* SPKRZC */
942#define WM8903_SPKRZC_SHIFT 6 /* SPKRZC */
943#define WM8903_SPKRZC_WIDTH 1 /* SPKRZC */
944#define WM8903_SPKR_VOL_MASK 0x003F /* SPKR_VOL - [5:0] */
945#define WM8903_SPKR_VOL_SHIFT 0 /* SPKR_VOL - [5:0] */
946#define WM8903_SPKR_VOL_WIDTH 6 /* SPKR_VOL - [5:0] */
947
948/*
949 * R65 (0x41) - Analogue SPK Output Control 0
950 */
951#define WM8903_SPK_DISCHARGE 0x0002 /* SPK_DISCHARGE */
952#define WM8903_SPK_DISCHARGE_MASK 0x0002 /* SPK_DISCHARGE */
953#define WM8903_SPK_DISCHARGE_SHIFT 1 /* SPK_DISCHARGE */
954#define WM8903_SPK_DISCHARGE_WIDTH 1 /* SPK_DISCHARGE */
955#define WM8903_VROI 0x0001 /* VROI */
956#define WM8903_VROI_MASK 0x0001 /* VROI */
957#define WM8903_VROI_SHIFT 0 /* VROI */
958#define WM8903_VROI_WIDTH 1 /* VROI */
959
960/*
961 * R67 (0x43) - DC Servo 0
962 */
963#define WM8903_DCS_MASTER_ENA 0x0010 /* DCS_MASTER_ENA */
964#define WM8903_DCS_MASTER_ENA_MASK 0x0010 /* DCS_MASTER_ENA */
965#define WM8903_DCS_MASTER_ENA_SHIFT 4 /* DCS_MASTER_ENA */
966#define WM8903_DCS_MASTER_ENA_WIDTH 1 /* DCS_MASTER_ENA */
967#define WM8903_DCS_ENA_MASK 0x000F /* DCS_ENA - [3:0] */
968#define WM8903_DCS_ENA_SHIFT 0 /* DCS_ENA - [3:0] */
969#define WM8903_DCS_ENA_WIDTH 4 /* DCS_ENA - [3:0] */
970
971/*
972 * R69 (0x45) - DC Servo 2
973 */
974#define WM8903_DCS_MODE_MASK 0x0003 /* DCS_MODE - [1:0] */
975#define WM8903_DCS_MODE_SHIFT 0 /* DCS_MODE - [1:0] */
976#define WM8903_DCS_MODE_WIDTH 2 /* DCS_MODE - [1:0] */
977
978/*
979 * R90 (0x5A) - Analogue HP 0
980 */
981#define WM8903_HPL_RMV_SHORT 0x0080 /* HPL_RMV_SHORT */
982#define WM8903_HPL_RMV_SHORT_MASK 0x0080 /* HPL_RMV_SHORT */
983#define WM8903_HPL_RMV_SHORT_SHIFT 7 /* HPL_RMV_SHORT */
984#define WM8903_HPL_RMV_SHORT_WIDTH 1 /* HPL_RMV_SHORT */
985#define WM8903_HPL_ENA_OUTP 0x0040 /* HPL_ENA_OUTP */
986#define WM8903_HPL_ENA_OUTP_MASK 0x0040 /* HPL_ENA_OUTP */
987#define WM8903_HPL_ENA_OUTP_SHIFT 6 /* HPL_ENA_OUTP */
988#define WM8903_HPL_ENA_OUTP_WIDTH 1 /* HPL_ENA_OUTP */
989#define WM8903_HPL_ENA_DLY 0x0020 /* HPL_ENA_DLY */
990#define WM8903_HPL_ENA_DLY_MASK 0x0020 /* HPL_ENA_DLY */
991#define WM8903_HPL_ENA_DLY_SHIFT 5 /* HPL_ENA_DLY */
992#define WM8903_HPL_ENA_DLY_WIDTH 1 /* HPL_ENA_DLY */
993#define WM8903_HPL_ENA 0x0010 /* HPL_ENA */
994#define WM8903_HPL_ENA_MASK 0x0010 /* HPL_ENA */
995#define WM8903_HPL_ENA_SHIFT 4 /* HPL_ENA */
996#define WM8903_HPL_ENA_WIDTH 1 /* HPL_ENA */
997#define WM8903_HPR_RMV_SHORT 0x0008 /* HPR_RMV_SHORT */
998#define WM8903_HPR_RMV_SHORT_MASK 0x0008 /* HPR_RMV_SHORT */
999#define WM8903_HPR_RMV_SHORT_SHIFT 3 /* HPR_RMV_SHORT */
1000#define WM8903_HPR_RMV_SHORT_WIDTH 1 /* HPR_RMV_SHORT */
1001#define WM8903_HPR_ENA_OUTP 0x0004 /* HPR_ENA_OUTP */
1002#define WM8903_HPR_ENA_OUTP_MASK 0x0004 /* HPR_ENA_OUTP */
1003#define WM8903_HPR_ENA_OUTP_SHIFT 2 /* HPR_ENA_OUTP */
1004#define WM8903_HPR_ENA_OUTP_WIDTH 1 /* HPR_ENA_OUTP */
1005#define WM8903_HPR_ENA_DLY 0x0002 /* HPR_ENA_DLY */
1006#define WM8903_HPR_ENA_DLY_MASK 0x0002 /* HPR_ENA_DLY */
1007#define WM8903_HPR_ENA_DLY_SHIFT 1 /* HPR_ENA_DLY */
1008#define WM8903_HPR_ENA_DLY_WIDTH 1 /* HPR_ENA_DLY */
1009#define WM8903_HPR_ENA 0x0001 /* HPR_ENA */
1010#define WM8903_HPR_ENA_MASK 0x0001 /* HPR_ENA */
1011#define WM8903_HPR_ENA_SHIFT 0 /* HPR_ENA */
1012#define WM8903_HPR_ENA_WIDTH 1 /* HPR_ENA */
1013
1014/*
1015 * R94 (0x5E) - Analogue Lineout 0
1016 */
1017#define WM8903_LINEOUTL_RMV_SHORT 0x0080 /* LINEOUTL_RMV_SHORT */
1018#define WM8903_LINEOUTL_RMV_SHORT_MASK 0x0080 /* LINEOUTL_RMV_SHORT */
1019#define WM8903_LINEOUTL_RMV_SHORT_SHIFT 7 /* LINEOUTL_RMV_SHORT */
1020#define WM8903_LINEOUTL_RMV_SHORT_WIDTH 1 /* LINEOUTL_RMV_SHORT */
1021#define WM8903_LINEOUTL_ENA_OUTP 0x0040 /* LINEOUTL_ENA_OUTP */
1022#define WM8903_LINEOUTL_ENA_OUTP_MASK 0x0040 /* LINEOUTL_ENA_OUTP */
1023#define WM8903_LINEOUTL_ENA_OUTP_SHIFT 6 /* LINEOUTL_ENA_OUTP */
1024#define WM8903_LINEOUTL_ENA_OUTP_WIDTH 1 /* LINEOUTL_ENA_OUTP */
1025#define WM8903_LINEOUTL_ENA_DLY 0x0020 /* LINEOUTL_ENA_DLY */
1026#define WM8903_LINEOUTL_ENA_DLY_MASK 0x0020 /* LINEOUTL_ENA_DLY */
1027#define WM8903_LINEOUTL_ENA_DLY_SHIFT 5 /* LINEOUTL_ENA_DLY */
1028#define WM8903_LINEOUTL_ENA_DLY_WIDTH 1 /* LINEOUTL_ENA_DLY */
1029#define WM8903_LINEOUTL_ENA 0x0010 /* LINEOUTL_ENA */
1030#define WM8903_LINEOUTL_ENA_MASK 0x0010 /* LINEOUTL_ENA */
1031#define WM8903_LINEOUTL_ENA_SHIFT 4 /* LINEOUTL_ENA */
1032#define WM8903_LINEOUTL_ENA_WIDTH 1 /* LINEOUTL_ENA */
1033#define WM8903_LINEOUTR_RMV_SHORT 0x0008 /* LINEOUTR_RMV_SHORT */
1034#define WM8903_LINEOUTR_RMV_SHORT_MASK 0x0008 /* LINEOUTR_RMV_SHORT */
1035#define WM8903_LINEOUTR_RMV_SHORT_SHIFT 3 /* LINEOUTR_RMV_SHORT */
1036#define WM8903_LINEOUTR_RMV_SHORT_WIDTH 1 /* LINEOUTR_RMV_SHORT */
1037#define WM8903_LINEOUTR_ENA_OUTP 0x0004 /* LINEOUTR_ENA_OUTP */
1038#define WM8903_LINEOUTR_ENA_OUTP_MASK 0x0004 /* LINEOUTR_ENA_OUTP */
1039#define WM8903_LINEOUTR_ENA_OUTP_SHIFT 2 /* LINEOUTR_ENA_OUTP */
1040#define WM8903_LINEOUTR_ENA_OUTP_WIDTH 1 /* LINEOUTR_ENA_OUTP */
1041#define WM8903_LINEOUTR_ENA_DLY 0x0002 /* LINEOUTR_ENA_DLY */
1042#define WM8903_LINEOUTR_ENA_DLY_MASK 0x0002 /* LINEOUTR_ENA_DLY */
1043#define WM8903_LINEOUTR_ENA_DLY_SHIFT 1 /* LINEOUTR_ENA_DLY */
1044#define WM8903_LINEOUTR_ENA_DLY_WIDTH 1 /* LINEOUTR_ENA_DLY */
1045#define WM8903_LINEOUTR_ENA 0x0001 /* LINEOUTR_ENA */
1046#define WM8903_LINEOUTR_ENA_MASK 0x0001 /* LINEOUTR_ENA */
1047#define WM8903_LINEOUTR_ENA_SHIFT 0 /* LINEOUTR_ENA */
1048#define WM8903_LINEOUTR_ENA_WIDTH 1 /* LINEOUTR_ENA */
1049
1050/*
1051 * R98 (0x62) - Charge Pump 0
1052 */
1053#define WM8903_CP_ENA 0x0001 /* CP_ENA */
1054#define WM8903_CP_ENA_MASK 0x0001 /* CP_ENA */
1055#define WM8903_CP_ENA_SHIFT 0 /* CP_ENA */
1056#define WM8903_CP_ENA_WIDTH 1 /* CP_ENA */
1057
1058/*
1059 * R104 (0x68) - Class W 0
1060 */
1061#define WM8903_CP_DYN_FREQ 0x0002 /* CP_DYN_FREQ */
1062#define WM8903_CP_DYN_FREQ_MASK 0x0002 /* CP_DYN_FREQ */
1063#define WM8903_CP_DYN_FREQ_SHIFT 1 /* CP_DYN_FREQ */
1064#define WM8903_CP_DYN_FREQ_WIDTH 1 /* CP_DYN_FREQ */
1065#define WM8903_CP_DYN_V 0x0001 /* CP_DYN_V */
1066#define WM8903_CP_DYN_V_MASK 0x0001 /* CP_DYN_V */
1067#define WM8903_CP_DYN_V_SHIFT 0 /* CP_DYN_V */
1068#define WM8903_CP_DYN_V_WIDTH 1 /* CP_DYN_V */
1069
1070/*
1071 * R108 (0x6C) - Write Sequencer 0
1072 */
1073#define WM8903_WSEQ_ENA 0x0100 /* WSEQ_ENA */
1074#define WM8903_WSEQ_ENA_MASK 0x0100 /* WSEQ_ENA */
1075#define WM8903_WSEQ_ENA_SHIFT 8 /* WSEQ_ENA */
1076#define WM8903_WSEQ_ENA_WIDTH 1 /* WSEQ_ENA */
1077#define WM8903_WSEQ_WRITE_INDEX_MASK 0x001F /* WSEQ_WRITE_INDEX - [4:0] */
1078#define WM8903_WSEQ_WRITE_INDEX_SHIFT 0 /* WSEQ_WRITE_INDEX - [4:0] */
1079#define WM8903_WSEQ_WRITE_INDEX_WIDTH 5 /* WSEQ_WRITE_INDEX - [4:0] */
1080
1081/*
1082 * R109 (0x6D) - Write Sequencer 1
1083 */
1084#define WM8903_WSEQ_DATA_WIDTH_MASK 0x7000 /* WSEQ_DATA_WIDTH - [14:12] */
1085#define WM8903_WSEQ_DATA_WIDTH_SHIFT 12 /* WSEQ_DATA_WIDTH - [14:12] */
1086#define WM8903_WSEQ_DATA_WIDTH_WIDTH 3 /* WSEQ_DATA_WIDTH - [14:12] */
1087#define WM8903_WSEQ_DATA_START_MASK 0x0F00 /* WSEQ_DATA_START - [11:8] */
1088#define WM8903_WSEQ_DATA_START_SHIFT 8 /* WSEQ_DATA_START - [11:8] */
1089#define WM8903_WSEQ_DATA_START_WIDTH 4 /* WSEQ_DATA_START - [11:8] */
1090#define WM8903_WSEQ_ADDR_MASK 0x00FF /* WSEQ_ADDR - [7:0] */
1091#define WM8903_WSEQ_ADDR_SHIFT 0 /* WSEQ_ADDR - [7:0] */
1092#define WM8903_WSEQ_ADDR_WIDTH 8 /* WSEQ_ADDR - [7:0] */
1093
1094/*
1095 * R110 (0x6E) - Write Sequencer 2
1096 */
1097#define WM8903_WSEQ_EOS 0x4000 /* WSEQ_EOS */
1098#define WM8903_WSEQ_EOS_MASK 0x4000 /* WSEQ_EOS */
1099#define WM8903_WSEQ_EOS_SHIFT 14 /* WSEQ_EOS */
1100#define WM8903_WSEQ_EOS_WIDTH 1 /* WSEQ_EOS */
1101#define WM8903_WSEQ_DELAY_MASK 0x0F00 /* WSEQ_DELAY - [11:8] */
1102#define WM8903_WSEQ_DELAY_SHIFT 8 /* WSEQ_DELAY - [11:8] */
1103#define WM8903_WSEQ_DELAY_WIDTH 4 /* WSEQ_DELAY - [11:8] */
1104#define WM8903_WSEQ_DATA_MASK 0x00FF /* WSEQ_DATA - [7:0] */
1105#define WM8903_WSEQ_DATA_SHIFT 0 /* WSEQ_DATA - [7:0] */
1106#define WM8903_WSEQ_DATA_WIDTH 8 /* WSEQ_DATA - [7:0] */
1107
1108/*
1109 * R111 (0x6F) - Write Sequencer 3
1110 */
1111#define WM8903_WSEQ_ABORT 0x0200 /* WSEQ_ABORT */
1112#define WM8903_WSEQ_ABORT_MASK 0x0200 /* WSEQ_ABORT */
1113#define WM8903_WSEQ_ABORT_SHIFT 9 /* WSEQ_ABORT */
1114#define WM8903_WSEQ_ABORT_WIDTH 1 /* WSEQ_ABORT */
1115#define WM8903_WSEQ_START 0x0100 /* WSEQ_START */
1116#define WM8903_WSEQ_START_MASK 0x0100 /* WSEQ_START */
1117#define WM8903_WSEQ_START_SHIFT 8 /* WSEQ_START */
1118#define WM8903_WSEQ_START_WIDTH 1 /* WSEQ_START */
1119#define WM8903_WSEQ_START_INDEX_MASK 0x003F /* WSEQ_START_INDEX - [5:0] */
1120#define WM8903_WSEQ_START_INDEX_SHIFT 0 /* WSEQ_START_INDEX - [5:0] */
1121#define WM8903_WSEQ_START_INDEX_WIDTH 6 /* WSEQ_START_INDEX - [5:0] */
1122
1123/*
1124 * R112 (0x70) - Write Sequencer 4
1125 */
1126#define WM8903_WSEQ_CURRENT_INDEX_MASK 0x03F0 /* WSEQ_CURRENT_INDEX - [9:4] */
1127#define WM8903_WSEQ_CURRENT_INDEX_SHIFT 4 /* WSEQ_CURRENT_INDEX - [9:4] */
1128#define WM8903_WSEQ_CURRENT_INDEX_WIDTH 6 /* WSEQ_CURRENT_INDEX - [9:4] */
1129#define WM8903_WSEQ_BUSY 0x0001 /* WSEQ_BUSY */
1130#define WM8903_WSEQ_BUSY_MASK 0x0001 /* WSEQ_BUSY */
1131#define WM8903_WSEQ_BUSY_SHIFT 0 /* WSEQ_BUSY */
1132#define WM8903_WSEQ_BUSY_WIDTH 1 /* WSEQ_BUSY */
1133
1134/*
1135 * R114 (0x72) - Control Interface
1136 */
1137#define WM8903_MASK_WRITE_ENA 0x0001 /* MASK_WRITE_ENA */
1138#define WM8903_MASK_WRITE_ENA_MASK 0x0001 /* MASK_WRITE_ENA */
1139#define WM8903_MASK_WRITE_ENA_SHIFT 0 /* MASK_WRITE_ENA */
1140#define WM8903_MASK_WRITE_ENA_WIDTH 1 /* MASK_WRITE_ENA */
1141
1142/*
1143 * R116 (0x74) - GPIO Control 1
1144 */
1145#define WM8903_GP1_FN_MASK 0x1F00 /* GP1_FN - [12:8] */
1146#define WM8903_GP1_FN_SHIFT 8 /* GP1_FN - [12:8] */
1147#define WM8903_GP1_FN_WIDTH 5 /* GP1_FN - [12:8] */
1148#define WM8903_GP1_DIR 0x0080 /* GP1_DIR */
1149#define WM8903_GP1_DIR_MASK 0x0080 /* GP1_DIR */
1150#define WM8903_GP1_DIR_SHIFT 7 /* GP1_DIR */
1151#define WM8903_GP1_DIR_WIDTH 1 /* GP1_DIR */
1152#define WM8903_GP1_OP_CFG 0x0040 /* GP1_OP_CFG */
1153#define WM8903_GP1_OP_CFG_MASK 0x0040 /* GP1_OP_CFG */
1154#define WM8903_GP1_OP_CFG_SHIFT 6 /* GP1_OP_CFG */
1155#define WM8903_GP1_OP_CFG_WIDTH 1 /* GP1_OP_CFG */
1156#define WM8903_GP1_IP_CFG 0x0020 /* GP1_IP_CFG */
1157#define WM8903_GP1_IP_CFG_MASK 0x0020 /* GP1_IP_CFG */
1158#define WM8903_GP1_IP_CFG_SHIFT 5 /* GP1_IP_CFG */
1159#define WM8903_GP1_IP_CFG_WIDTH 1 /* GP1_IP_CFG */
1160#define WM8903_GP1_LVL 0x0010 /* GP1_LVL */
1161#define WM8903_GP1_LVL_MASK 0x0010 /* GP1_LVL */
1162#define WM8903_GP1_LVL_SHIFT 4 /* GP1_LVL */
1163#define WM8903_GP1_LVL_WIDTH 1 /* GP1_LVL */
1164#define WM8903_GP1_PD 0x0008 /* GP1_PD */
1165#define WM8903_GP1_PD_MASK 0x0008 /* GP1_PD */
1166#define WM8903_GP1_PD_SHIFT 3 /* GP1_PD */
1167#define WM8903_GP1_PD_WIDTH 1 /* GP1_PD */
1168#define WM8903_GP1_PU 0x0004 /* GP1_PU */
1169#define WM8903_GP1_PU_MASK 0x0004 /* GP1_PU */
1170#define WM8903_GP1_PU_SHIFT 2 /* GP1_PU */
1171#define WM8903_GP1_PU_WIDTH 1 /* GP1_PU */
1172#define WM8903_GP1_INTMODE 0x0002 /* GP1_INTMODE */
1173#define WM8903_GP1_INTMODE_MASK 0x0002 /* GP1_INTMODE */
1174#define WM8903_GP1_INTMODE_SHIFT 1 /* GP1_INTMODE */
1175#define WM8903_GP1_INTMODE_WIDTH 1 /* GP1_INTMODE */
1176#define WM8903_GP1_DB 0x0001 /* GP1_DB */
1177#define WM8903_GP1_DB_MASK 0x0001 /* GP1_DB */
1178#define WM8903_GP1_DB_SHIFT 0 /* GP1_DB */
1179#define WM8903_GP1_DB_WIDTH 1 /* GP1_DB */
1180
1181/*
1182 * R117 (0x75) - GPIO Control 2
1183 */
1184#define WM8903_GP2_FN_MASK 0x1F00 /* GP2_FN - [12:8] */
1185#define WM8903_GP2_FN_SHIFT 8 /* GP2_FN - [12:8] */
1186#define WM8903_GP2_FN_WIDTH 5 /* GP2_FN - [12:8] */
1187#define WM8903_GP2_DIR 0x0080 /* GP2_DIR */
1188#define WM8903_GP2_DIR_MASK 0x0080 /* GP2_DIR */
1189#define WM8903_GP2_DIR_SHIFT 7 /* GP2_DIR */
1190#define WM8903_GP2_DIR_WIDTH 1 /* GP2_DIR */
1191#define WM8903_GP2_OP_CFG 0x0040 /* GP2_OP_CFG */
1192#define WM8903_GP2_OP_CFG_MASK 0x0040 /* GP2_OP_CFG */
1193#define WM8903_GP2_OP_CFG_SHIFT 6 /* GP2_OP_CFG */
1194#define WM8903_GP2_OP_CFG_WIDTH 1 /* GP2_OP_CFG */
1195#define WM8903_GP2_IP_CFG 0x0020 /* GP2_IP_CFG */
1196#define WM8903_GP2_IP_CFG_MASK 0x0020 /* GP2_IP_CFG */
1197#define WM8903_GP2_IP_CFG_SHIFT 5 /* GP2_IP_CFG */
1198#define WM8903_GP2_IP_CFG_WIDTH 1 /* GP2_IP_CFG */
1199#define WM8903_GP2_LVL 0x0010 /* GP2_LVL */
1200#define WM8903_GP2_LVL_MASK 0x0010 /* GP2_LVL */
1201#define WM8903_GP2_LVL_SHIFT 4 /* GP2_LVL */
1202#define WM8903_GP2_LVL_WIDTH 1 /* GP2_LVL */
1203#define WM8903_GP2_PD 0x0008 /* GP2_PD */
1204#define WM8903_GP2_PD_MASK 0x0008 /* GP2_PD */
1205#define WM8903_GP2_PD_SHIFT 3 /* GP2_PD */
1206#define WM8903_GP2_PD_WIDTH 1 /* GP2_PD */
1207#define WM8903_GP2_PU 0x0004 /* GP2_PU */
1208#define WM8903_GP2_PU_MASK 0x0004 /* GP2_PU */
1209#define WM8903_GP2_PU_SHIFT 2 /* GP2_PU */
1210#define WM8903_GP2_PU_WIDTH 1 /* GP2_PU */
1211#define WM8903_GP2_INTMODE 0x0002 /* GP2_INTMODE */
1212#define WM8903_GP2_INTMODE_MASK 0x0002 /* GP2_INTMODE */
1213#define WM8903_GP2_INTMODE_SHIFT 1 /* GP2_INTMODE */
1214#define WM8903_GP2_INTMODE_WIDTH 1 /* GP2_INTMODE */
1215#define WM8903_GP2_DB 0x0001 /* GP2_DB */
1216#define WM8903_GP2_DB_MASK 0x0001 /* GP2_DB */
1217#define WM8903_GP2_DB_SHIFT 0 /* GP2_DB */
1218#define WM8903_GP2_DB_WIDTH 1 /* GP2_DB */
1219
1220/*
1221 * R118 (0x76) - GPIO Control 3
1222 */
1223#define WM8903_GP3_FN_MASK 0x1F00 /* GP3_FN - [12:8] */
1224#define WM8903_GP3_FN_SHIFT 8 /* GP3_FN - [12:8] */
1225#define WM8903_GP3_FN_WIDTH 5 /* GP3_FN - [12:8] */
1226#define WM8903_GP3_DIR 0x0080 /* GP3_DIR */
1227#define WM8903_GP3_DIR_MASK 0x0080 /* GP3_DIR */
1228#define WM8903_GP3_DIR_SHIFT 7 /* GP3_DIR */
1229#define WM8903_GP3_DIR_WIDTH 1 /* GP3_DIR */
1230#define WM8903_GP3_OP_CFG 0x0040 /* GP3_OP_CFG */
1231#define WM8903_GP3_OP_CFG_MASK 0x0040 /* GP3_OP_CFG */
1232#define WM8903_GP3_OP_CFG_SHIFT 6 /* GP3_OP_CFG */
1233#define WM8903_GP3_OP_CFG_WIDTH 1 /* GP3_OP_CFG */
1234#define WM8903_GP3_IP_CFG 0x0020 /* GP3_IP_CFG */
1235#define WM8903_GP3_IP_CFG_MASK 0x0020 /* GP3_IP_CFG */
1236#define WM8903_GP3_IP_CFG_SHIFT 5 /* GP3_IP_CFG */
1237#define WM8903_GP3_IP_CFG_WIDTH 1 /* GP3_IP_CFG */
1238#define WM8903_GP3_LVL 0x0010 /* GP3_LVL */
1239#define WM8903_GP3_LVL_MASK 0x0010 /* GP3_LVL */
1240#define WM8903_GP3_LVL_SHIFT 4 /* GP3_LVL */
1241#define WM8903_GP3_LVL_WIDTH 1 /* GP3_LVL */
1242#define WM8903_GP3_PD 0x0008 /* GP3_PD */
1243#define WM8903_GP3_PD_MASK 0x0008 /* GP3_PD */
1244#define WM8903_GP3_PD_SHIFT 3 /* GP3_PD */
1245#define WM8903_GP3_PD_WIDTH 1 /* GP3_PD */
1246#define WM8903_GP3_PU 0x0004 /* GP3_PU */
1247#define WM8903_GP3_PU_MASK 0x0004 /* GP3_PU */
1248#define WM8903_GP3_PU_SHIFT 2 /* GP3_PU */
1249#define WM8903_GP3_PU_WIDTH 1 /* GP3_PU */
1250#define WM8903_GP3_INTMODE 0x0002 /* GP3_INTMODE */
1251#define WM8903_GP3_INTMODE_MASK 0x0002 /* GP3_INTMODE */
1252#define WM8903_GP3_INTMODE_SHIFT 1 /* GP3_INTMODE */
1253#define WM8903_GP3_INTMODE_WIDTH 1 /* GP3_INTMODE */
1254#define WM8903_GP3_DB 0x0001 /* GP3_DB */
1255#define WM8903_GP3_DB_MASK 0x0001 /* GP3_DB */
1256#define WM8903_GP3_DB_SHIFT 0 /* GP3_DB */
1257#define WM8903_GP3_DB_WIDTH 1 /* GP3_DB */
1258
1259/*
1260 * R119 (0x77) - GPIO Control 4
1261 */
1262#define WM8903_GP4_FN_MASK 0x1F00 /* GP4_FN - [12:8] */
1263#define WM8903_GP4_FN_SHIFT 8 /* GP4_FN - [12:8] */
1264#define WM8903_GP4_FN_WIDTH 5 /* GP4_FN - [12:8] */
1265#define WM8903_GP4_DIR 0x0080 /* GP4_DIR */
1266#define WM8903_GP4_DIR_MASK 0x0080 /* GP4_DIR */
1267#define WM8903_GP4_DIR_SHIFT 7 /* GP4_DIR */
1268#define WM8903_GP4_DIR_WIDTH 1 /* GP4_DIR */
1269#define WM8903_GP4_OP_CFG 0x0040 /* GP4_OP_CFG */
1270#define WM8903_GP4_OP_CFG_MASK 0x0040 /* GP4_OP_CFG */
1271#define WM8903_GP4_OP_CFG_SHIFT 6 /* GP4_OP_CFG */
1272#define WM8903_GP4_OP_CFG_WIDTH 1 /* GP4_OP_CFG */
1273#define WM8903_GP4_IP_CFG 0x0020 /* GP4_IP_CFG */
1274#define WM8903_GP4_IP_CFG_MASK 0x0020 /* GP4_IP_CFG */
1275#define WM8903_GP4_IP_CFG_SHIFT 5 /* GP4_IP_CFG */
1276#define WM8903_GP4_IP_CFG_WIDTH 1 /* GP4_IP_CFG */
1277#define WM8903_GP4_LVL 0x0010 /* GP4_LVL */
1278#define WM8903_GP4_LVL_MASK 0x0010 /* GP4_LVL */
1279#define WM8903_GP4_LVL_SHIFT 4 /* GP4_LVL */
1280#define WM8903_GP4_LVL_WIDTH 1 /* GP4_LVL */
1281#define WM8903_GP4_PD 0x0008 /* GP4_PD */
1282#define WM8903_GP4_PD_MASK 0x0008 /* GP4_PD */
1283#define WM8903_GP4_PD_SHIFT 3 /* GP4_PD */
1284#define WM8903_GP4_PD_WIDTH 1 /* GP4_PD */
1285#define WM8903_GP4_PU 0x0004 /* GP4_PU */
1286#define WM8903_GP4_PU_MASK 0x0004 /* GP4_PU */
1287#define WM8903_GP4_PU_SHIFT 2 /* GP4_PU */
1288#define WM8903_GP4_PU_WIDTH 1 /* GP4_PU */
1289#define WM8903_GP4_INTMODE 0x0002 /* GP4_INTMODE */
1290#define WM8903_GP4_INTMODE_MASK 0x0002 /* GP4_INTMODE */
1291#define WM8903_GP4_INTMODE_SHIFT 1 /* GP4_INTMODE */
1292#define WM8903_GP4_INTMODE_WIDTH 1 /* GP4_INTMODE */
1293#define WM8903_GP4_DB 0x0001 /* GP4_DB */
1294#define WM8903_GP4_DB_MASK 0x0001 /* GP4_DB */
1295#define WM8903_GP4_DB_SHIFT 0 /* GP4_DB */
1296#define WM8903_GP4_DB_WIDTH 1 /* GP4_DB */
1297
1298/*
1299 * R120 (0x78) - GPIO Control 5
1300 */
1301#define WM8903_GP5_FN_MASK 0x1F00 /* GP5_FN - [12:8] */
1302#define WM8903_GP5_FN_SHIFT 8 /* GP5_FN - [12:8] */
1303#define WM8903_GP5_FN_WIDTH 5 /* GP5_FN - [12:8] */
1304#define WM8903_GP5_DIR 0x0080 /* GP5_DIR */
1305#define WM8903_GP5_DIR_MASK 0x0080 /* GP5_DIR */
1306#define WM8903_GP5_DIR_SHIFT 7 /* GP5_DIR */
1307#define WM8903_GP5_DIR_WIDTH 1 /* GP5_DIR */
1308#define WM8903_GP5_OP_CFG 0x0040 /* GP5_OP_CFG */
1309#define WM8903_GP5_OP_CFG_MASK 0x0040 /* GP5_OP_CFG */
1310#define WM8903_GP5_OP_CFG_SHIFT 6 /* GP5_OP_CFG */
1311#define WM8903_GP5_OP_CFG_WIDTH 1 /* GP5_OP_CFG */
1312#define WM8903_GP5_IP_CFG 0x0020 /* GP5_IP_CFG */
1313#define WM8903_GP5_IP_CFG_MASK 0x0020 /* GP5_IP_CFG */
1314#define WM8903_GP5_IP_CFG_SHIFT 5 /* GP5_IP_CFG */
1315#define WM8903_GP5_IP_CFG_WIDTH 1 /* GP5_IP_CFG */
1316#define WM8903_GP5_LVL 0x0010 /* GP5_LVL */
1317#define WM8903_GP5_LVL_MASK 0x0010 /* GP5_LVL */
1318#define WM8903_GP5_LVL_SHIFT 4 /* GP5_LVL */
1319#define WM8903_GP5_LVL_WIDTH 1 /* GP5_LVL */
1320#define WM8903_GP5_PD 0x0008 /* GP5_PD */
1321#define WM8903_GP5_PD_MASK 0x0008 /* GP5_PD */
1322#define WM8903_GP5_PD_SHIFT 3 /* GP5_PD */
1323#define WM8903_GP5_PD_WIDTH 1 /* GP5_PD */
1324#define WM8903_GP5_PU 0x0004 /* GP5_PU */
1325#define WM8903_GP5_PU_MASK 0x0004 /* GP5_PU */
1326#define WM8903_GP5_PU_SHIFT 2 /* GP5_PU */
1327#define WM8903_GP5_PU_WIDTH 1 /* GP5_PU */
1328#define WM8903_GP5_INTMODE 0x0002 /* GP5_INTMODE */
1329#define WM8903_GP5_INTMODE_MASK 0x0002 /* GP5_INTMODE */
1330#define WM8903_GP5_INTMODE_SHIFT 1 /* GP5_INTMODE */
1331#define WM8903_GP5_INTMODE_WIDTH 1 /* GP5_INTMODE */
1332#define WM8903_GP5_DB 0x0001 /* GP5_DB */
1333#define WM8903_GP5_DB_MASK 0x0001 /* GP5_DB */
1334#define WM8903_GP5_DB_SHIFT 0 /* GP5_DB */
1335#define WM8903_GP5_DB_WIDTH 1 /* GP5_DB */
1336
1337/*
1338 * R121 (0x79) - Interrupt Status 1
1339 */
1340#define WM8903_MICSHRT_EINT 0x8000 /* MICSHRT_EINT */
1341#define WM8903_MICSHRT_EINT_MASK 0x8000 /* MICSHRT_EINT */
1342#define WM8903_MICSHRT_EINT_SHIFT 15 /* MICSHRT_EINT */
1343#define WM8903_MICSHRT_EINT_WIDTH 1 /* MICSHRT_EINT */
1344#define WM8903_MICDET_EINT 0x4000 /* MICDET_EINT */
1345#define WM8903_MICDET_EINT_MASK 0x4000 /* MICDET_EINT */
1346#define WM8903_MICDET_EINT_SHIFT 14 /* MICDET_EINT */
1347#define WM8903_MICDET_EINT_WIDTH 1 /* MICDET_EINT */
1348#define WM8903_WSEQ_BUSY_EINT 0x2000 /* WSEQ_BUSY_EINT */
1349#define WM8903_WSEQ_BUSY_EINT_MASK 0x2000 /* WSEQ_BUSY_EINT */
1350#define WM8903_WSEQ_BUSY_EINT_SHIFT 13 /* WSEQ_BUSY_EINT */
1351#define WM8903_WSEQ_BUSY_EINT_WIDTH 1 /* WSEQ_BUSY_EINT */
1352#define WM8903_GP5_EINT 0x0010 /* GP5_EINT */
1353#define WM8903_GP5_EINT_MASK 0x0010 /* GP5_EINT */
1354#define WM8903_GP5_EINT_SHIFT 4 /* GP5_EINT */
1355#define WM8903_GP5_EINT_WIDTH 1 /* GP5_EINT */
1356#define WM8903_GP4_EINT 0x0008 /* GP4_EINT */
1357#define WM8903_GP4_EINT_MASK 0x0008 /* GP4_EINT */
1358#define WM8903_GP4_EINT_SHIFT 3 /* GP4_EINT */
1359#define WM8903_GP4_EINT_WIDTH 1 /* GP4_EINT */
1360#define WM8903_GP3_EINT 0x0004 /* GP3_EINT */
1361#define WM8903_GP3_EINT_MASK 0x0004 /* GP3_EINT */
1362#define WM8903_GP3_EINT_SHIFT 2 /* GP3_EINT */
1363#define WM8903_GP3_EINT_WIDTH 1 /* GP3_EINT */
1364#define WM8903_GP2_EINT 0x0002 /* GP2_EINT */
1365#define WM8903_GP2_EINT_MASK 0x0002 /* GP2_EINT */
1366#define WM8903_GP2_EINT_SHIFT 1 /* GP2_EINT */
1367#define WM8903_GP2_EINT_WIDTH 1 /* GP2_EINT */
1368#define WM8903_GP1_EINT 0x0001 /* GP1_EINT */
1369#define WM8903_GP1_EINT_MASK 0x0001 /* GP1_EINT */
1370#define WM8903_GP1_EINT_SHIFT 0 /* GP1_EINT */
1371#define WM8903_GP1_EINT_WIDTH 1 /* GP1_EINT */
1372
1373/*
1374 * R122 (0x7A) - Interrupt Status 1 Mask
1375 */
1376#define WM8903_IM_MICSHRT_EINT 0x8000 /* IM_MICSHRT_EINT */
1377#define WM8903_IM_MICSHRT_EINT_MASK 0x8000 /* IM_MICSHRT_EINT */
1378#define WM8903_IM_MICSHRT_EINT_SHIFT 15 /* IM_MICSHRT_EINT */
1379#define WM8903_IM_MICSHRT_EINT_WIDTH 1 /* IM_MICSHRT_EINT */
1380#define WM8903_IM_MICDET_EINT 0x4000 /* IM_MICDET_EINT */
1381#define WM8903_IM_MICDET_EINT_MASK 0x4000 /* IM_MICDET_EINT */
1382#define WM8903_IM_MICDET_EINT_SHIFT 14 /* IM_MICDET_EINT */
1383#define WM8903_IM_MICDET_EINT_WIDTH 1 /* IM_MICDET_EINT */
1384#define WM8903_IM_WSEQ_BUSY_EINT 0x2000 /* IM_WSEQ_BUSY_EINT */
1385#define WM8903_IM_WSEQ_BUSY_EINT_MASK 0x2000 /* IM_WSEQ_BUSY_EINT */
1386#define WM8903_IM_WSEQ_BUSY_EINT_SHIFT 13 /* IM_WSEQ_BUSY_EINT */
1387#define WM8903_IM_WSEQ_BUSY_EINT_WIDTH 1 /* IM_WSEQ_BUSY_EINT */
1388#define WM8903_IM_GP5_EINT 0x0010 /* IM_GP5_EINT */
1389#define WM8903_IM_GP5_EINT_MASK 0x0010 /* IM_GP5_EINT */
1390#define WM8903_IM_GP5_EINT_SHIFT 4 /* IM_GP5_EINT */
1391#define WM8903_IM_GP5_EINT_WIDTH 1 /* IM_GP5_EINT */
1392#define WM8903_IM_GP4_EINT 0x0008 /* IM_GP4_EINT */
1393#define WM8903_IM_GP4_EINT_MASK 0x0008 /* IM_GP4_EINT */
1394#define WM8903_IM_GP4_EINT_SHIFT 3 /* IM_GP4_EINT */
1395#define WM8903_IM_GP4_EINT_WIDTH 1 /* IM_GP4_EINT */
1396#define WM8903_IM_GP3_EINT 0x0004 /* IM_GP3_EINT */
1397#define WM8903_IM_GP3_EINT_MASK 0x0004 /* IM_GP3_EINT */
1398#define WM8903_IM_GP3_EINT_SHIFT 2 /* IM_GP3_EINT */
1399#define WM8903_IM_GP3_EINT_WIDTH 1 /* IM_GP3_EINT */
1400#define WM8903_IM_GP2_EINT 0x0002 /* IM_GP2_EINT */
1401#define WM8903_IM_GP2_EINT_MASK 0x0002 /* IM_GP2_EINT */
1402#define WM8903_IM_GP2_EINT_SHIFT 1 /* IM_GP2_EINT */
1403#define WM8903_IM_GP2_EINT_WIDTH 1 /* IM_GP2_EINT */
1404#define WM8903_IM_GP1_EINT 0x0001 /* IM_GP1_EINT */
1405#define WM8903_IM_GP1_EINT_MASK 0x0001 /* IM_GP1_EINT */
1406#define WM8903_IM_GP1_EINT_SHIFT 0 /* IM_GP1_EINT */
1407#define WM8903_IM_GP1_EINT_WIDTH 1 /* IM_GP1_EINT */
1408
1409/*
1410 * R123 (0x7B) - Interrupt Polarity 1
1411 */
1412#define WM8903_MICSHRT_INV 0x8000 /* MICSHRT_INV */
1413#define WM8903_MICSHRT_INV_MASK 0x8000 /* MICSHRT_INV */
1414#define WM8903_MICSHRT_INV_SHIFT 15 /* MICSHRT_INV */
1415#define WM8903_MICSHRT_INV_WIDTH 1 /* MICSHRT_INV */
1416#define WM8903_MICDET_INV 0x4000 /* MICDET_INV */
1417#define WM8903_MICDET_INV_MASK 0x4000 /* MICDET_INV */
1418#define WM8903_MICDET_INV_SHIFT 14 /* MICDET_INV */
1419#define WM8903_MICDET_INV_WIDTH 1 /* MICDET_INV */
1420
1421/*
1422 * R126 (0x7E) - Interrupt Control
1423 */
1424#define WM8903_IRQ_POL 0x0001 /* IRQ_POL */
1425#define WM8903_IRQ_POL_MASK 0x0001 /* IRQ_POL */
1426#define WM8903_IRQ_POL_SHIFT 0 /* IRQ_POL */
1427#define WM8903_IRQ_POL_WIDTH 1 /* IRQ_POL */
1428
1429/*
1430 * R129 (0x81) - Control Interface Test 1
1431 */
1432#define WM8903_USER_KEY 0x0002 /* USER_KEY */
1433#define WM8903_USER_KEY_MASK 0x0002 /* USER_KEY */
1434#define WM8903_USER_KEY_SHIFT 1 /* USER_KEY */
1435#define WM8903_USER_KEY_WIDTH 1 /* USER_KEY */
1436#define WM8903_TEST_KEY 0x0001 /* TEST_KEY */
1437#define WM8903_TEST_KEY_MASK 0x0001 /* TEST_KEY */
1438#define WM8903_TEST_KEY_SHIFT 0 /* TEST_KEY */
1439#define WM8903_TEST_KEY_WIDTH 1 /* TEST_KEY */
1440
1441/*
1442 * R149 (0x95) - Charge Pump Test 1
1443 */
1444#define WM8903_CP_SW_KELVIN_MODE_MASK 0x0006 /* CP_SW_KELVIN_MODE - [2:1] */
1445#define WM8903_CP_SW_KELVIN_MODE_SHIFT 1 /* CP_SW_KELVIN_MODE - [2:1] */
1446#define WM8903_CP_SW_KELVIN_MODE_WIDTH 2 /* CP_SW_KELVIN_MODE - [2:1] */
1447
1448/*
1449 * R164 (0xA4) - Clock Rate Test 4
1450 */
1451#define WM8903_ADC_DIG_MIC 0x0200 /* ADC_DIG_MIC */
1452#define WM8903_ADC_DIG_MIC_MASK 0x0200 /* ADC_DIG_MIC */
1453#define WM8903_ADC_DIG_MIC_SHIFT 9 /* ADC_DIG_MIC */
1454#define WM8903_ADC_DIG_MIC_WIDTH 1 /* ADC_DIG_MIC */
1455
1456/*
1457 * R172 (0xAC) - Analogue Output Bias 0
1458 */
1459#define WM8903_PGA_BIAS_MASK 0x0070 /* PGA_BIAS - [6:4] */
1460#define WM8903_PGA_BIAS_SHIFT 4 /* PGA_BIAS - [6:4] */
1461#define WM8903_PGA_BIAS_WIDTH 3 /* PGA_BIAS - [6:4] */
1462
1463#endif
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
new file mode 100644
index 000000000000..f41a578ddd4f
--- /dev/null
+++ b/sound/soc/codecs/wm8971.c
@@ -0,0 +1,941 @@
1/*
2 * wm8971.c -- WM8971 ALSA SoC Audio driver
3 *
4 * Copyright 2005 Lab126, Inc.
5 *
6 * Author: Kenneth Kiraly <kiraly@lab126.com>
7 *
8 * Based on wm8753.c by Liam Girdwood
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 */
15
16#include <linux/module.h>
17#include <linux/moduleparam.h>
18#include <linux/init.h>
19#include <linux/delay.h>
20#include <linux/pm.h>
21#include <linux/i2c.h>
22#include <linux/platform_device.h>
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/initval.h>
29
30#include "wm8971.h"
31
32#define WM8971_VERSION "0.9"
33
34#define WM8971_REG_COUNT 43
35
36static struct workqueue_struct *wm8971_workq = NULL;
37
38/* codec private data */
39struct wm8971_priv {
40 unsigned int sysclk;
41};
42
43/*
44 * wm8971 register cache
45 * We can't read the WM8971 register space when we
46 * are using 2 wire for device control, so we cache them instead.
47 */
48static const u16 wm8971_reg[] = {
49 0x0097, 0x0097, 0x0079, 0x0079, /* 0 */
50 0x0000, 0x0008, 0x0000, 0x000a, /* 4 */
51 0x0000, 0x0000, 0x00ff, 0x00ff, /* 8 */
52 0x000f, 0x000f, 0x0000, 0x0000, /* 12 */
53 0x0000, 0x007b, 0x0000, 0x0032, /* 16 */
54 0x0000, 0x00c3, 0x00c3, 0x00c0, /* 20 */
55 0x0000, 0x0000, 0x0000, 0x0000, /* 24 */
56 0x0000, 0x0000, 0x0000, 0x0000, /* 28 */
57 0x0000, 0x0000, 0x0050, 0x0050, /* 32 */
58 0x0050, 0x0050, 0x0050, 0x0050, /* 36 */
59 0x0079, 0x0079, 0x0079, /* 40 */
60};
61
62static inline unsigned int wm8971_read_reg_cache(struct snd_soc_codec *codec,
63 unsigned int reg)
64{
65 u16 *cache = codec->reg_cache;
66 if (reg < WM8971_REG_COUNT)
67 return cache[reg];
68
69 return -1;
70}
71
72static inline void wm8971_write_reg_cache(struct snd_soc_codec *codec,
73 unsigned int reg, unsigned int value)
74{
75 u16 *cache = codec->reg_cache;
76 if (reg < WM8971_REG_COUNT)
77 cache[reg] = value;
78}
79
80static int wm8971_write(struct snd_soc_codec *codec, unsigned int reg,
81 unsigned int value)
82{
83 u8 data[2];
84
85 /* data is
86 * D15..D9 WM8753 register offset
87 * D8...D0 register data
88 */
89 data[0] = (reg << 1) | ((value >> 8) & 0x0001);
90 data[1] = value & 0x00ff;
91
92 wm8971_write_reg_cache (codec, reg, value);
93 if (codec->hw_write(codec->control_data, data, 2) == 2)
94 return 0;
95 else
96 return -EIO;
97}
98
99#define wm8971_reset(c) wm8971_write(c, WM8971_RESET, 0)
100
101/* WM8971 Controls */
102static const char *wm8971_bass[] = { "Linear Control", "Adaptive Boost" };
103static const char *wm8971_bass_filter[] = { "130Hz @ 48kHz",
104 "200Hz @ 48kHz" };
105static const char *wm8971_treble[] = { "8kHz", "4kHz" };
106static const char *wm8971_alc_func[] = { "Off", "Right", "Left", "Stereo" };
107static const char *wm8971_ng_type[] = { "Constant PGA Gain",
108 "Mute ADC Output" };
109static const char *wm8971_deemp[] = { "None", "32kHz", "44.1kHz", "48kHz" };
110static const char *wm8971_mono_mux[] = {"Stereo", "Mono (Left)",
111 "Mono (Right)", "Digital Mono"};
112static const char *wm8971_dac_phase[] = { "Non Inverted", "Inverted" };
113static const char *wm8971_lline_mux[] = {"Line", "NC", "NC", "PGA",
114 "Differential"};
115static const char *wm8971_rline_mux[] = {"Line", "Mic", "NC", "PGA",
116 "Differential"};
117static const char *wm8971_lpga_sel[] = {"Line", "NC", "NC", "Differential"};
118static const char *wm8971_rpga_sel[] = {"Line", "Mic", "NC", "Differential"};
119static const char *wm8971_adcpol[] = {"Normal", "L Invert", "R Invert",
120 "L + R Invert"};
121
122static const struct soc_enum wm8971_enum[] = {
123 SOC_ENUM_SINGLE(WM8971_BASS, 7, 2, wm8971_bass), /* 0 */
124 SOC_ENUM_SINGLE(WM8971_BASS, 6, 2, wm8971_bass_filter),
125 SOC_ENUM_SINGLE(WM8971_TREBLE, 6, 2, wm8971_treble),
126 SOC_ENUM_SINGLE(WM8971_ALC1, 7, 4, wm8971_alc_func),
127 SOC_ENUM_SINGLE(WM8971_NGATE, 1, 2, wm8971_ng_type), /* 4 */
128 SOC_ENUM_SINGLE(WM8971_ADCDAC, 1, 4, wm8971_deemp),
129 SOC_ENUM_SINGLE(WM8971_ADCTL1, 4, 4, wm8971_mono_mux),
130 SOC_ENUM_SINGLE(WM8971_ADCTL1, 1, 2, wm8971_dac_phase),
131 SOC_ENUM_SINGLE(WM8971_LOUTM1, 0, 5, wm8971_lline_mux), /* 8 */
132 SOC_ENUM_SINGLE(WM8971_ROUTM1, 0, 5, wm8971_rline_mux),
133 SOC_ENUM_SINGLE(WM8971_LADCIN, 6, 4, wm8971_lpga_sel),
134 SOC_ENUM_SINGLE(WM8971_RADCIN, 6, 4, wm8971_rpga_sel),
135 SOC_ENUM_SINGLE(WM8971_ADCDAC, 5, 4, wm8971_adcpol), /* 12 */
136 SOC_ENUM_SINGLE(WM8971_ADCIN, 6, 4, wm8971_mono_mux),
137};
138
139static const struct snd_kcontrol_new wm8971_snd_controls[] = {
140 SOC_DOUBLE_R("Capture Volume", WM8971_LINVOL, WM8971_RINVOL, 0, 63, 0),
141 SOC_DOUBLE_R("Capture ZC Switch", WM8971_LINVOL, WM8971_RINVOL,
142 6, 1, 0),
143 SOC_DOUBLE_R("Capture Switch", WM8971_LINVOL, WM8971_RINVOL, 7, 1, 1),
144
145 SOC_DOUBLE_R("Headphone Playback ZC Switch", WM8971_LOUT1V,
146 WM8971_ROUT1V, 7, 1, 0),
147 SOC_DOUBLE_R("Speaker Playback ZC Switch", WM8971_LOUT2V,
148 WM8971_ROUT2V, 7, 1, 0),
149 SOC_SINGLE("Mono Playback ZC Switch", WM8971_MOUTV, 7, 1, 0),
150
151 SOC_DOUBLE_R("PCM Volume", WM8971_LDAC, WM8971_RDAC, 0, 255, 0),
152
153 SOC_DOUBLE_R("Bypass Left Playback Volume", WM8971_LOUTM1,
154 WM8971_LOUTM2, 4, 7, 1),
155 SOC_DOUBLE_R("Bypass Right Playback Volume", WM8971_ROUTM1,
156 WM8971_ROUTM2, 4, 7, 1),
157 SOC_DOUBLE_R("Bypass Mono Playback Volume", WM8971_MOUTM1,
158 WM8971_MOUTM2, 4, 7, 1),
159
160 SOC_DOUBLE_R("Headphone Playback Volume", WM8971_LOUT1V,
161 WM8971_ROUT1V, 0, 127, 0),
162 SOC_DOUBLE_R("Speaker Playback Volume", WM8971_LOUT2V,
163 WM8971_ROUT2V, 0, 127, 0),
164
165 SOC_ENUM("Bass Boost", wm8971_enum[0]),
166 SOC_ENUM("Bass Filter", wm8971_enum[1]),
167 SOC_SINGLE("Bass Volume", WM8971_BASS, 0, 7, 1),
168
169 SOC_SINGLE("Treble Volume", WM8971_TREBLE, 0, 7, 0),
170 SOC_ENUM("Treble Cut-off", wm8971_enum[2]),
171
172 SOC_SINGLE("Capture Filter Switch", WM8971_ADCDAC, 0, 1, 1),
173
174 SOC_SINGLE("ALC Target Volume", WM8971_ALC1, 0, 7, 0),
175 SOC_SINGLE("ALC Max Volume", WM8971_ALC1, 4, 7, 0),
176
177 SOC_SINGLE("ALC Capture Target Volume", WM8971_ALC1, 0, 7, 0),
178 SOC_SINGLE("ALC Capture Max Volume", WM8971_ALC1, 4, 7, 0),
179 SOC_ENUM("ALC Capture Function", wm8971_enum[3]),
180 SOC_SINGLE("ALC Capture ZC Switch", WM8971_ALC2, 7, 1, 0),
181 SOC_SINGLE("ALC Capture Hold Time", WM8971_ALC2, 0, 15, 0),
182 SOC_SINGLE("ALC Capture Decay Time", WM8971_ALC3, 4, 15, 0),
183 SOC_SINGLE("ALC Capture Attack Time", WM8971_ALC3, 0, 15, 0),
184 SOC_SINGLE("ALC Capture NG Threshold", WM8971_NGATE, 3, 31, 0),
185 SOC_ENUM("ALC Capture NG Type", wm8971_enum[4]),
186 SOC_SINGLE("ALC Capture NG Switch", WM8971_NGATE, 0, 1, 0),
187
188 SOC_SINGLE("Capture 6dB Attenuate", WM8971_ADCDAC, 8, 1, 0),
189 SOC_SINGLE("Playback 6dB Attenuate", WM8971_ADCDAC, 7, 1, 0),
190
191 SOC_ENUM("Playback De-emphasis", wm8971_enum[5]),
192 SOC_ENUM("Playback Function", wm8971_enum[6]),
193 SOC_ENUM("Playback Phase", wm8971_enum[7]),
194
195 SOC_DOUBLE_R("Mic Boost", WM8971_LADCIN, WM8971_RADCIN, 4, 3, 0),
196};
197
198/* add non-DAPM controls */
199static int wm8971_add_controls(struct snd_soc_codec *codec)
200{
201 int err, i;
202
203 for (i = 0; i < ARRAY_SIZE(wm8971_snd_controls); i++) {
204 err = snd_ctl_add(codec->card,
205 snd_soc_cnew(&wm8971_snd_controls[i],
206 codec, NULL));
207 if (err < 0)
208 return err;
209 }
210 return 0;
211}
212
213/*
214 * DAPM Controls
215 */
216
217/* Left Mixer */
218static const struct snd_kcontrol_new wm8971_left_mixer_controls[] = {
219SOC_DAPM_SINGLE("Playback Switch", WM8971_LOUTM1, 8, 1, 0),
220SOC_DAPM_SINGLE("Left Bypass Switch", WM8971_LOUTM1, 7, 1, 0),
221SOC_DAPM_SINGLE("Right Playback Switch", WM8971_LOUTM2, 8, 1, 0),
222SOC_DAPM_SINGLE("Right Bypass Switch", WM8971_LOUTM2, 7, 1, 0),
223};
224
225/* Right Mixer */
226static const struct snd_kcontrol_new wm8971_right_mixer_controls[] = {
227SOC_DAPM_SINGLE("Left Playback Switch", WM8971_ROUTM1, 8, 1, 0),
228SOC_DAPM_SINGLE("Left Bypass Switch", WM8971_ROUTM1, 7, 1, 0),
229SOC_DAPM_SINGLE("Playback Switch", WM8971_ROUTM2, 8, 1, 0),
230SOC_DAPM_SINGLE("Right Bypass Switch", WM8971_ROUTM2, 7, 1, 0),
231};
232
233/* Mono Mixer */
234static const struct snd_kcontrol_new wm8971_mono_mixer_controls[] = {
235SOC_DAPM_SINGLE("Left Playback Switch", WM8971_MOUTM1, 8, 1, 0),
236SOC_DAPM_SINGLE("Left Bypass Switch", WM8971_MOUTM1, 7, 1, 0),
237SOC_DAPM_SINGLE("Right Playback Switch", WM8971_MOUTM2, 8, 1, 0),
238SOC_DAPM_SINGLE("Right Bypass Switch", WM8971_MOUTM2, 7, 1, 0),
239};
240
241/* Left Line Mux */
242static const struct snd_kcontrol_new wm8971_left_line_controls =
243SOC_DAPM_ENUM("Route", wm8971_enum[8]);
244
245/* Right Line Mux */
246static const struct snd_kcontrol_new wm8971_right_line_controls =
247SOC_DAPM_ENUM("Route", wm8971_enum[9]);
248
249/* Left PGA Mux */
250static const struct snd_kcontrol_new wm8971_left_pga_controls =
251SOC_DAPM_ENUM("Route", wm8971_enum[10]);
252
253/* Right PGA Mux */
254static const struct snd_kcontrol_new wm8971_right_pga_controls =
255SOC_DAPM_ENUM("Route", wm8971_enum[11]);
256
257/* Mono ADC Mux */
258static const struct snd_kcontrol_new wm8971_monomux_controls =
259SOC_DAPM_ENUM("Route", wm8971_enum[13]);
260
261static const struct snd_soc_dapm_widget wm8971_dapm_widgets[] = {
262 SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0,
263 &wm8971_left_mixer_controls[0],
264 ARRAY_SIZE(wm8971_left_mixer_controls)),
265 SND_SOC_DAPM_MIXER("Right Mixer", SND_SOC_NOPM, 0, 0,
266 &wm8971_right_mixer_controls[0],
267 ARRAY_SIZE(wm8971_right_mixer_controls)),
268 SND_SOC_DAPM_MIXER("Mono Mixer", WM8971_PWR2, 2, 0,
269 &wm8971_mono_mixer_controls[0],
270 ARRAY_SIZE(wm8971_mono_mixer_controls)),
271
272 SND_SOC_DAPM_PGA("Right Out 2", WM8971_PWR2, 3, 0, NULL, 0),
273 SND_SOC_DAPM_PGA("Left Out 2", WM8971_PWR2, 4, 0, NULL, 0),
274 SND_SOC_DAPM_PGA("Right Out 1", WM8971_PWR2, 5, 0, NULL, 0),
275 SND_SOC_DAPM_PGA("Left Out 1", WM8971_PWR2, 6, 0, NULL, 0),
276 SND_SOC_DAPM_DAC("Right DAC", "Right Playback", WM8971_PWR2, 7, 0),
277 SND_SOC_DAPM_DAC("Left DAC", "Left Playback", WM8971_PWR2, 8, 0),
278 SND_SOC_DAPM_PGA("Mono Out 1", WM8971_PWR2, 2, 0, NULL, 0),
279
280 SND_SOC_DAPM_MICBIAS("Mic Bias", WM8971_PWR1, 1, 0),
281 SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8971_PWR1, 2, 0),
282 SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8971_PWR1, 3, 0),
283
284 SND_SOC_DAPM_MUX("Left PGA Mux", WM8971_PWR1, 5, 0,
285 &wm8971_left_pga_controls),
286 SND_SOC_DAPM_MUX("Right PGA Mux", WM8971_PWR1, 4, 0,
287 &wm8971_right_pga_controls),
288 SND_SOC_DAPM_MUX("Left Line Mux", SND_SOC_NOPM, 0, 0,
289 &wm8971_left_line_controls),
290 SND_SOC_DAPM_MUX("Right Line Mux", SND_SOC_NOPM, 0, 0,
291 &wm8971_right_line_controls),
292
293 SND_SOC_DAPM_MUX("Left ADC Mux", SND_SOC_NOPM, 0, 0,
294 &wm8971_monomux_controls),
295 SND_SOC_DAPM_MUX("Right ADC Mux", SND_SOC_NOPM, 0, 0,
296 &wm8971_monomux_controls),
297
298 SND_SOC_DAPM_OUTPUT("LOUT1"),
299 SND_SOC_DAPM_OUTPUT("ROUT1"),
300 SND_SOC_DAPM_OUTPUT("LOUT2"),
301 SND_SOC_DAPM_OUTPUT("ROUT2"),
302 SND_SOC_DAPM_OUTPUT("MONO"),
303
304 SND_SOC_DAPM_INPUT("LINPUT1"),
305 SND_SOC_DAPM_INPUT("RINPUT1"),
306 SND_SOC_DAPM_INPUT("MIC"),
307};
308
309static const struct snd_soc_dapm_route audio_map[] = {
310 /* left mixer */
311 {"Left Mixer", "Playback Switch", "Left DAC"},
312 {"Left Mixer", "Left Bypass Switch", "Left Line Mux"},
313 {"Left Mixer", "Right Playback Switch", "Right DAC"},
314 {"Left Mixer", "Right Bypass Switch", "Right Line Mux"},
315
316 /* right mixer */
317 {"Right Mixer", "Left Playback Switch", "Left DAC"},
318 {"Right Mixer", "Left Bypass Switch", "Left Line Mux"},
319 {"Right Mixer", "Playback Switch", "Right DAC"},
320 {"Right Mixer", "Right Bypass Switch", "Right Line Mux"},
321
322 /* left out 1 */
323 {"Left Out 1", NULL, "Left Mixer"},
324 {"LOUT1", NULL, "Left Out 1"},
325
326 /* left out 2 */
327 {"Left Out 2", NULL, "Left Mixer"},
328 {"LOUT2", NULL, "Left Out 2"},
329
330 /* right out 1 */
331 {"Right Out 1", NULL, "Right Mixer"},
332 {"ROUT1", NULL, "Right Out 1"},
333
334 /* right out 2 */
335 {"Right Out 2", NULL, "Right Mixer"},
336 {"ROUT2", NULL, "Right Out 2"},
337
338 /* mono mixer */
339 {"Mono Mixer", "Left Playback Switch", "Left DAC"},
340 {"Mono Mixer", "Left Bypass Switch", "Left Line Mux"},
341 {"Mono Mixer", "Right Playback Switch", "Right DAC"},
342 {"Mono Mixer", "Right Bypass Switch", "Right Line Mux"},
343
344 /* mono out */
345 {"Mono Out", NULL, "Mono Mixer"},
346 {"MONO1", NULL, "Mono Out"},
347
348 /* Left Line Mux */
349 {"Left Line Mux", "Line", "LINPUT1"},
350 {"Left Line Mux", "PGA", "Left PGA Mux"},
351 {"Left Line Mux", "Differential", "Differential Mux"},
352
353 /* Right Line Mux */
354 {"Right Line Mux", "Line", "RINPUT1"},
355 {"Right Line Mux", "Mic", "MIC"},
356 {"Right Line Mux", "PGA", "Right PGA Mux"},
357 {"Right Line Mux", "Differential", "Differential Mux"},
358
359 /* Left PGA Mux */
360 {"Left PGA Mux", "Line", "LINPUT1"},
361 {"Left PGA Mux", "Differential", "Differential Mux"},
362
363 /* Right PGA Mux */
364 {"Right PGA Mux", "Line", "RINPUT1"},
365 {"Right PGA Mux", "Differential", "Differential Mux"},
366
367 /* Differential Mux */
368 {"Differential Mux", "Line", "LINPUT1"},
369 {"Differential Mux", "Line", "RINPUT1"},
370
371 /* Left ADC Mux */
372 {"Left ADC Mux", "Stereo", "Left PGA Mux"},
373 {"Left ADC Mux", "Mono (Left)", "Left PGA Mux"},
374 {"Left ADC Mux", "Digital Mono", "Left PGA Mux"},
375
376 /* Right ADC Mux */
377 {"Right ADC Mux", "Stereo", "Right PGA Mux"},
378 {"Right ADC Mux", "Mono (Right)", "Right PGA Mux"},
379 {"Right ADC Mux", "Digital Mono", "Right PGA Mux"},
380
381 /* ADC */
382 {"Left ADC", NULL, "Left ADC Mux"},
383 {"Right ADC", NULL, "Right ADC Mux"},
384};
385
386static int wm8971_add_widgets(struct snd_soc_codec *codec)
387{
388 snd_soc_dapm_new_controls(codec, wm8971_dapm_widgets,
389 ARRAY_SIZE(wm8971_dapm_widgets));
390
391 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
392
393 snd_soc_dapm_new_widgets(codec);
394
395 return 0;
396}
397
398struct _coeff_div {
399 u32 mclk;
400 u32 rate;
401 u16 fs;
402 u8 sr:5;
403 u8 usb:1;
404};
405
406/* codec hifi mclk clock divider coefficients */
407static const struct _coeff_div coeff_div[] = {
408 /* 8k */
409 {12288000, 8000, 1536, 0x6, 0x0},
410 {11289600, 8000, 1408, 0x16, 0x0},
411 {18432000, 8000, 2304, 0x7, 0x0},
412 {16934400, 8000, 2112, 0x17, 0x0},
413 {12000000, 8000, 1500, 0x6, 0x1},
414
415 /* 11.025k */
416 {11289600, 11025, 1024, 0x18, 0x0},
417 {16934400, 11025, 1536, 0x19, 0x0},
418 {12000000, 11025, 1088, 0x19, 0x1},
419
420 /* 16k */
421 {12288000, 16000, 768, 0xa, 0x0},
422 {18432000, 16000, 1152, 0xb, 0x0},
423 {12000000, 16000, 750, 0xa, 0x1},
424
425 /* 22.05k */
426 {11289600, 22050, 512, 0x1a, 0x0},
427 {16934400, 22050, 768, 0x1b, 0x0},
428 {12000000, 22050, 544, 0x1b, 0x1},
429
430 /* 32k */
431 {12288000, 32000, 384, 0xc, 0x0},
432 {18432000, 32000, 576, 0xd, 0x0},
433 {12000000, 32000, 375, 0xa, 0x1},
434
435 /* 44.1k */
436 {11289600, 44100, 256, 0x10, 0x0},
437 {16934400, 44100, 384, 0x11, 0x0},
438 {12000000, 44100, 272, 0x11, 0x1},
439
440 /* 48k */
441 {12288000, 48000, 256, 0x0, 0x0},
442 {18432000, 48000, 384, 0x1, 0x0},
443 {12000000, 48000, 250, 0x0, 0x1},
444
445 /* 88.2k */
446 {11289600, 88200, 128, 0x1e, 0x0},
447 {16934400, 88200, 192, 0x1f, 0x0},
448 {12000000, 88200, 136, 0x1f, 0x1},
449
450 /* 96k */
451 {12288000, 96000, 128, 0xe, 0x0},
452 {18432000, 96000, 192, 0xf, 0x0},
453 {12000000, 96000, 125, 0xe, 0x1},
454};
455
456static int get_coeff(int mclk, int rate)
457{
458 int i;
459
460 for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
461 if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
462 return i;
463 }
464 return -EINVAL;
465}
466
467static int wm8971_set_dai_sysclk(struct snd_soc_dai *codec_dai,
468 int clk_id, unsigned int freq, int dir)
469{
470 struct snd_soc_codec *codec = codec_dai->codec;
471 struct wm8971_priv *wm8971 = codec->private_data;
472
473 switch (freq) {
474 case 11289600:
475 case 12000000:
476 case 12288000:
477 case 16934400:
478 case 18432000:
479 wm8971->sysclk = freq;
480 return 0;
481 }
482 return -EINVAL;
483}
484
485static int wm8971_set_dai_fmt(struct snd_soc_dai *codec_dai,
486 unsigned int fmt)
487{
488 struct snd_soc_codec *codec = codec_dai->codec;
489 u16 iface = 0;
490
491 /* set master/slave audio interface */
492 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
493 case SND_SOC_DAIFMT_CBM_CFM:
494 iface = 0x0040;
495 break;
496 case SND_SOC_DAIFMT_CBS_CFS:
497 break;
498 default:
499 return -EINVAL;
500 }
501
502 /* interface format */
503 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
504 case SND_SOC_DAIFMT_I2S:
505 iface |= 0x0002;
506 break;
507 case SND_SOC_DAIFMT_RIGHT_J:
508 break;
509 case SND_SOC_DAIFMT_LEFT_J:
510 iface |= 0x0001;
511 break;
512 case SND_SOC_DAIFMT_DSP_A:
513 iface |= 0x0003;
514 break;
515 case SND_SOC_DAIFMT_DSP_B:
516 iface |= 0x0013;
517 break;
518 default:
519 return -EINVAL;
520 }
521
522 /* clock inversion */
523 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
524 case SND_SOC_DAIFMT_NB_NF:
525 break;
526 case SND_SOC_DAIFMT_IB_IF:
527 iface |= 0x0090;
528 break;
529 case SND_SOC_DAIFMT_IB_NF:
530 iface |= 0x0080;
531 break;
532 case SND_SOC_DAIFMT_NB_IF:
533 iface |= 0x0010;
534 break;
535 default:
536 return -EINVAL;
537 }
538
539 wm8971_write(codec, WM8971_IFACE, iface);
540 return 0;
541}
542
543static int wm8971_pcm_hw_params(struct snd_pcm_substream *substream,
544 struct snd_pcm_hw_params *params)
545{
546 struct snd_soc_pcm_runtime *rtd = substream->private_data;
547 struct snd_soc_device *socdev = rtd->socdev;
548 struct snd_soc_codec *codec = socdev->codec;
549 struct wm8971_priv *wm8971 = codec->private_data;
550 u16 iface = wm8971_read_reg_cache(codec, WM8971_IFACE) & 0x1f3;
551 u16 srate = wm8971_read_reg_cache(codec, WM8971_SRATE) & 0x1c0;
552 int coeff = get_coeff(wm8971->sysclk, params_rate(params));
553
554 /* bit size */
555 switch (params_format(params)) {
556 case SNDRV_PCM_FORMAT_S16_LE:
557 break;
558 case SNDRV_PCM_FORMAT_S20_3LE:
559 iface |= 0x0004;
560 break;
561 case SNDRV_PCM_FORMAT_S24_LE:
562 iface |= 0x0008;
563 break;
564 case SNDRV_PCM_FORMAT_S32_LE:
565 iface |= 0x000c;
566 break;
567 }
568
569 /* set iface & srate */
570 wm8971_write(codec, WM8971_IFACE, iface);
571 if (coeff >= 0)
572 wm8971_write(codec, WM8971_SRATE, srate |
573 (coeff_div[coeff].sr << 1) | coeff_div[coeff].usb);
574
575 return 0;
576}
577
578static int wm8971_mute(struct snd_soc_dai *dai, int mute)
579{
580 struct snd_soc_codec *codec = dai->codec;
581 u16 mute_reg = wm8971_read_reg_cache(codec, WM8971_ADCDAC) & 0xfff7;
582
583 if (mute)
584 wm8971_write(codec, WM8971_ADCDAC, mute_reg | 0x8);
585 else
586 wm8971_write(codec, WM8971_ADCDAC, mute_reg);
587 return 0;
588}
589
590static int wm8971_set_bias_level(struct snd_soc_codec *codec,
591 enum snd_soc_bias_level level)
592{
593 u16 pwr_reg = wm8971_read_reg_cache(codec, WM8971_PWR1) & 0xfe3e;
594
595 switch (level) {
596 case SND_SOC_BIAS_ON:
597 /* set vmid to 50k and unmute dac */
598 wm8971_write(codec, WM8971_PWR1, pwr_reg | 0x00c1);
599 break;
600 case SND_SOC_BIAS_PREPARE:
601 break;
602 case SND_SOC_BIAS_STANDBY:
603 /* mute dac and set vmid to 500k, enable VREF */
604 wm8971_write(codec, WM8971_PWR1, pwr_reg | 0x0140);
605 break;
606 case SND_SOC_BIAS_OFF:
607 wm8971_write(codec, WM8971_PWR1, 0x0001);
608 break;
609 }
610 codec->bias_level = level;
611 return 0;
612}
613
614#define WM8971_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
615 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \
616 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
617
618#define WM8971_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
619 SNDRV_PCM_FMTBIT_S24_LE)
620
621struct snd_soc_dai wm8971_dai = {
622 .name = "WM8971",
623 .playback = {
624 .stream_name = "Playback",
625 .channels_min = 1,
626 .channels_max = 2,
627 .rates = WM8971_RATES,
628 .formats = WM8971_FORMATS,},
629 .capture = {
630 .stream_name = "Capture",
631 .channels_min = 1,
632 .channels_max = 2,
633 .rates = WM8971_RATES,
634 .formats = WM8971_FORMATS,},
635 .ops = {
636 .hw_params = wm8971_pcm_hw_params,
637 },
638 .dai_ops = {
639 .digital_mute = wm8971_mute,
640 .set_fmt = wm8971_set_dai_fmt,
641 .set_sysclk = wm8971_set_dai_sysclk,
642 },
643};
644EXPORT_SYMBOL_GPL(wm8971_dai);
645
646static void wm8971_work(struct work_struct *work)
647{
648 struct snd_soc_codec *codec =
649 container_of(work, struct snd_soc_codec, delayed_work.work);
650 wm8971_set_bias_level(codec, codec->bias_level);
651}
652
653static int wm8971_suspend(struct platform_device *pdev, pm_message_t state)
654{
655 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
656 struct snd_soc_codec *codec = socdev->codec;
657
658 wm8971_set_bias_level(codec, SND_SOC_BIAS_OFF);
659 return 0;
660}
661
662static int wm8971_resume(struct platform_device *pdev)
663{
664 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
665 struct snd_soc_codec *codec = socdev->codec;
666 int i;
667 u8 data[2];
668 u16 *cache = codec->reg_cache;
669 u16 reg;
670
671 /* Sync reg_cache with the hardware */
672 for (i = 0; i < ARRAY_SIZE(wm8971_reg); i++) {
673 if (i + 1 == WM8971_RESET)
674 continue;
675 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
676 data[1] = cache[i] & 0x00ff;
677 codec->hw_write(codec->control_data, data, 2);
678 }
679
680 wm8971_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
681
682 /* charge wm8971 caps */
683 if (codec->suspend_bias_level == SND_SOC_BIAS_ON) {
684 reg = wm8971_read_reg_cache(codec, WM8971_PWR1) & 0xfe3e;
685 wm8971_write(codec, WM8971_PWR1, reg | 0x01c0);
686 codec->bias_level = SND_SOC_BIAS_ON;
687 queue_delayed_work(wm8971_workq, &codec->delayed_work,
688 msecs_to_jiffies(1000));
689 }
690
691 return 0;
692}
693
694static int wm8971_init(struct snd_soc_device *socdev)
695{
696 struct snd_soc_codec *codec = socdev->codec;
697 int reg, ret = 0;
698
699 codec->name = "WM8971";
700 codec->owner = THIS_MODULE;
701 codec->read = wm8971_read_reg_cache;
702 codec->write = wm8971_write;
703 codec->set_bias_level = wm8971_set_bias_level;
704 codec->dai = &wm8971_dai;
705 codec->reg_cache_size = ARRAY_SIZE(wm8971_reg);
706 codec->num_dai = 1;
707 codec->reg_cache = kmemdup(wm8971_reg, sizeof(wm8971_reg), GFP_KERNEL);
708
709 if (codec->reg_cache == NULL)
710 return -ENOMEM;
711
712 wm8971_reset(codec);
713
714 /* register pcms */
715 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
716 if (ret < 0) {
717 printk(KERN_ERR "wm8971: failed to create pcms\n");
718 goto pcm_err;
719 }
720
721 /* charge output caps - set vmid to 5k for quick power up */
722 reg = wm8971_read_reg_cache(codec, WM8971_PWR1) & 0xfe3e;
723 wm8971_write(codec, WM8971_PWR1, reg | 0x01c0);
724 codec->bias_level = SND_SOC_BIAS_STANDBY;
725 queue_delayed_work(wm8971_workq, &codec->delayed_work,
726 msecs_to_jiffies(1000));
727
728 /* set the update bits */
729 reg = wm8971_read_reg_cache(codec, WM8971_LDAC);
730 wm8971_write(codec, WM8971_LDAC, reg | 0x0100);
731 reg = wm8971_read_reg_cache(codec, WM8971_RDAC);
732 wm8971_write(codec, WM8971_RDAC, reg | 0x0100);
733
734 reg = wm8971_read_reg_cache(codec, WM8971_LOUT1V);
735 wm8971_write(codec, WM8971_LOUT1V, reg | 0x0100);
736 reg = wm8971_read_reg_cache(codec, WM8971_ROUT1V);
737 wm8971_write(codec, WM8971_ROUT1V, reg | 0x0100);
738
739 reg = wm8971_read_reg_cache(codec, WM8971_LOUT2V);
740 wm8971_write(codec, WM8971_LOUT2V, reg | 0x0100);
741 reg = wm8971_read_reg_cache(codec, WM8971_ROUT2V);
742 wm8971_write(codec, WM8971_ROUT2V, reg | 0x0100);
743
744 reg = wm8971_read_reg_cache(codec, WM8971_LINVOL);
745 wm8971_write(codec, WM8971_LINVOL, reg | 0x0100);
746 reg = wm8971_read_reg_cache(codec, WM8971_RINVOL);
747 wm8971_write(codec, WM8971_RINVOL, reg | 0x0100);
748
749 wm8971_add_controls(codec);
750 wm8971_add_widgets(codec);
751 ret = snd_soc_register_card(socdev);
752 if (ret < 0) {
753 printk(KERN_ERR "wm8971: failed to register card\n");
754 goto card_err;
755 }
756 return ret;
757
758card_err:
759 snd_soc_free_pcms(socdev);
760 snd_soc_dapm_free(socdev);
761pcm_err:
762 kfree(codec->reg_cache);
763 return ret;
764}
765
766/* If the i2c layer weren't so broken, we could pass this kind of data
767 around */
768static struct snd_soc_device *wm8971_socdev;
769
770#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
771
772static int wm8971_i2c_probe(struct i2c_client *i2c,
773 const struct i2c_device_id *id)
774{
775 struct snd_soc_device *socdev = wm8971_socdev;
776 struct snd_soc_codec *codec = socdev->codec;
777 int ret;
778
779 i2c_set_clientdata(i2c, codec);
780
781 codec->control_data = i2c;
782
783 ret = wm8971_init(socdev);
784 if (ret < 0)
785 pr_err("failed to initialise WM8971\n");
786
787 return ret;
788}
789
790static int wm8971_i2c_remove(struct i2c_client *client)
791{
792 struct snd_soc_codec *codec = i2c_get_clientdata(client);
793 kfree(codec->reg_cache);
794 return 0;
795}
796
797static const struct i2c_device_id wm8971_i2c_id[] = {
798 { "wm8971", 0 },
799 { }
800};
801MODULE_DEVICE_TABLE(i2c, wm8971_i2c_id);
802
803static struct i2c_driver wm8971_i2c_driver = {
804 .driver = {
805 .name = "WM8971 I2C Codec",
806 .owner = THIS_MODULE,
807 },
808 .probe = wm8971_i2c_probe,
809 .remove = wm8971_i2c_remove,
810 .id_table = wm8971_i2c_id,
811};
812
813static int wm8971_add_i2c_device(struct platform_device *pdev,
814 const struct wm8971_setup_data *setup)
815{
816 struct i2c_board_info info;
817 struct i2c_adapter *adapter;
818 struct i2c_client *client;
819 int ret;
820
821 ret = i2c_add_driver(&wm8971_i2c_driver);
822 if (ret != 0) {
823 dev_err(&pdev->dev, "can't add i2c driver\n");
824 return ret;
825 }
826
827 memset(&info, 0, sizeof(struct i2c_board_info));
828 info.addr = setup->i2c_address;
829 strlcpy(info.type, "wm8971", I2C_NAME_SIZE);
830
831 adapter = i2c_get_adapter(setup->i2c_bus);
832 if (!adapter) {
833 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
834 setup->i2c_bus);
835 goto err_driver;
836 }
837
838 client = i2c_new_device(adapter, &info);
839 i2c_put_adapter(adapter);
840 if (!client) {
841 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
842 (unsigned int)info.addr);
843 goto err_driver;
844 }
845
846 return 0;
847
848err_driver:
849 i2c_del_driver(&wm8971_i2c_driver);
850 return -ENODEV;
851}
852
853#endif
854
855static int wm8971_probe(struct platform_device *pdev)
856{
857 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
858 struct wm8971_setup_data *setup;
859 struct snd_soc_codec *codec;
860 struct wm8971_priv *wm8971;
861 int ret = 0;
862
863 pr_info("WM8971 Audio Codec %s", WM8971_VERSION);
864
865 setup = socdev->codec_data;
866 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
867 if (codec == NULL)
868 return -ENOMEM;
869
870 wm8971 = kzalloc(sizeof(struct wm8971_priv), GFP_KERNEL);
871 if (wm8971 == NULL) {
872 kfree(codec);
873 return -ENOMEM;
874 }
875
876 codec->private_data = wm8971;
877 socdev->codec = codec;
878 mutex_init(&codec->mutex);
879 INIT_LIST_HEAD(&codec->dapm_widgets);
880 INIT_LIST_HEAD(&codec->dapm_paths);
881 wm8971_socdev = socdev;
882
883 INIT_DELAYED_WORK(&codec->delayed_work, wm8971_work);
884 wm8971_workq = create_workqueue("wm8971");
885 if (wm8971_workq == NULL) {
886 kfree(codec->private_data);
887 kfree(codec);
888 return -ENOMEM;
889 }
890
891#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
892 if (setup->i2c_address) {
893 codec->hw_write = (hw_write_t)i2c_master_send;
894 ret = wm8971_add_i2c_device(pdev, setup);
895 }
896#endif
897 /* Add other interfaces here */
898
899 if (ret != 0) {
900 destroy_workqueue(wm8971_workq);
901 kfree(codec->private_data);
902 kfree(codec);
903 }
904
905 return ret;
906}
907
908/* power down chip */
909static int wm8971_remove(struct platform_device *pdev)
910{
911 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
912 struct snd_soc_codec *codec = socdev->codec;
913
914 if (codec->control_data)
915 wm8971_set_bias_level(codec, SND_SOC_BIAS_OFF);
916 if (wm8971_workq)
917 destroy_workqueue(wm8971_workq);
918 snd_soc_free_pcms(socdev);
919 snd_soc_dapm_free(socdev);
920#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
921 i2c_unregister_device(codec->control_data);
922 i2c_del_driver(&wm8971_i2c_driver);
923#endif
924 kfree(codec->private_data);
925 kfree(codec);
926
927 return 0;
928}
929
930struct snd_soc_codec_device soc_codec_dev_wm8971 = {
931 .probe = wm8971_probe,
932 .remove = wm8971_remove,
933 .suspend = wm8971_suspend,
934 .resume = wm8971_resume,
935};
936
937EXPORT_SYMBOL_GPL(soc_codec_dev_wm8971);
938
939MODULE_DESCRIPTION("ASoC WM8971 driver");
940MODULE_AUTHOR("Lab126");
941MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8971.h b/sound/soc/codecs/wm8971.h
new file mode 100644
index 000000000000..ef4f08f9f344
--- /dev/null
+++ b/sound/soc/codecs/wm8971.h
@@ -0,0 +1,64 @@
1/*
2 * wm8971.h -- audio driver for WM8971
3 *
4 * Copyright 2005 Lab126, Inc.
5 *
6 * Author: Kenneth Kiraly <kiraly@lab126.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 */
14
15#ifndef _WM8971_H
16#define _WM8971_H
17
18#define WM8971_LINVOL 0x00
19#define WM8971_RINVOL 0x01
20#define WM8971_LOUT1V 0x02
21#define WM8971_ROUT1V 0x03
22#define WM8971_ADCDAC 0x05
23#define WM8971_IFACE 0x07
24#define WM8971_SRATE 0x08
25#define WM8971_LDAC 0x0a
26#define WM8971_RDAC 0x0b
27#define WM8971_BASS 0x0c
28#define WM8971_TREBLE 0x0d
29#define WM8971_RESET 0x0f
30#define WM8971_ALC1 0x11
31#define WM8971_ALC2 0x12
32#define WM8971_ALC3 0x13
33#define WM8971_NGATE 0x14
34#define WM8971_LADC 0x15
35#define WM8971_RADC 0x16
36#define WM8971_ADCTL1 0x17
37#define WM8971_ADCTL2 0x18
38#define WM8971_PWR1 0x19
39#define WM8971_PWR2 0x1a
40#define WM8971_ADCTL3 0x1b
41#define WM8971_ADCIN 0x1f
42#define WM8971_LADCIN 0x20
43#define WM8971_RADCIN 0x21
44#define WM8971_LOUTM1 0x22
45#define WM8971_LOUTM2 0x23
46#define WM8971_ROUTM1 0x24
47#define WM8971_ROUTM2 0x25
48#define WM8971_MOUTM1 0x26
49#define WM8971_MOUTM2 0x27
50#define WM8971_LOUT2V 0x28
51#define WM8971_ROUT2V 0x29
52#define WM8971_MOUTV 0x2A
53
54#define WM8971_SYSCLK 0
55
56struct wm8971_setup_data {
57 int i2c_bus;
58 unsigned short i2c_address;
59};
60
61extern struct snd_soc_dai wm8971_dai;
62extern struct snd_soc_codec_device soc_codec_dev_wm8971;
63
64#endif
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index dd995ef448b4..572d22b0880b 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -30,7 +30,6 @@
30 30
31#include "wm8990.h" 31#include "wm8990.h"
32 32
33#define AUDIO_NAME "wm8990"
34#define WM8990_VERSION "0.2" 33#define WM8990_VERSION "0.2"
35 34
36/* codec private data */ 35/* codec private data */
@@ -1477,81 +1476,86 @@ static struct snd_soc_device *wm8990_socdev;
1477 * low = 0x34 1476 * low = 0x34
1478 * high = 0x36 1477 * high = 0x36
1479 */ 1478 */
1480static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
1481 1479
1482/* Magic definition of all other variables and things */ 1480static int wm8990_i2c_probe(struct i2c_client *i2c,
1483I2C_CLIENT_INSMOD; 1481 const struct i2c_device_id *id)
1484
1485static struct i2c_driver wm8990_i2c_driver;
1486static struct i2c_client client_template;
1487
1488static int wm8990_codec_probe(struct i2c_adapter *adap, int addr, int kind)
1489{ 1482{
1490 struct snd_soc_device *socdev = wm8990_socdev; 1483 struct snd_soc_device *socdev = wm8990_socdev;
1491 struct wm8990_setup_data *setup = socdev->codec_data;
1492 struct snd_soc_codec *codec = socdev->codec; 1484 struct snd_soc_codec *codec = socdev->codec;
1493 struct i2c_client *i2c;
1494 int ret; 1485 int ret;
1495 1486
1496 if (addr != setup->i2c_address)
1497 return -ENODEV;
1498
1499 client_template.adapter = adap;
1500 client_template.addr = addr;
1501
1502 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
1503 if (i2c == NULL)
1504 return -ENOMEM;
1505
1506 i2c_set_clientdata(i2c, codec); 1487 i2c_set_clientdata(i2c, codec);
1507 codec->control_data = i2c; 1488 codec->control_data = i2c;
1508 1489
1509 ret = i2c_attach_client(i2c);
1510 if (ret < 0) {
1511 pr_err("failed to attach codec at addr %x\n", addr);
1512 goto err;
1513 }
1514
1515 ret = wm8990_init(socdev); 1490 ret = wm8990_init(socdev);
1516 if (ret < 0) { 1491 if (ret < 0)
1517 pr_err("failed to initialise WM8990\n"); 1492 pr_err("failed to initialise WM8990\n");
1518 goto err;
1519 }
1520 return ret;
1521 1493
1522err:
1523 kfree(i2c);
1524 return ret; 1494 return ret;
1525} 1495}
1526 1496
1527static int wm8990_i2c_detach(struct i2c_client *client) 1497static int wm8990_i2c_remove(struct i2c_client *client)
1528{ 1498{
1529 struct snd_soc_codec *codec = i2c_get_clientdata(client); 1499 struct snd_soc_codec *codec = i2c_get_clientdata(client);
1530 i2c_detach_client(client);
1531 kfree(codec->reg_cache); 1500 kfree(codec->reg_cache);
1532 kfree(client);
1533 return 0; 1501 return 0;
1534} 1502}
1535 1503
1536static int wm8990_i2c_attach(struct i2c_adapter *adap) 1504static const struct i2c_device_id wm8990_i2c_id[] = {
1537{ 1505 { "wm8990", 0 },
1538 return i2c_probe(adap, &addr_data, wm8990_codec_probe); 1506 { }
1539} 1507};
1508MODULE_DEVICE_TABLE(i2c, wm8990_i2c_id);
1540 1509
1541static struct i2c_driver wm8990_i2c_driver = { 1510static struct i2c_driver wm8990_i2c_driver = {
1542 .driver = { 1511 .driver = {
1543 .name = "WM8990 I2C Codec", 1512 .name = "WM8990 I2C Codec",
1544 .owner = THIS_MODULE, 1513 .owner = THIS_MODULE,
1545 }, 1514 },
1546 .attach_adapter = wm8990_i2c_attach, 1515 .probe = wm8990_i2c_probe,
1547 .detach_client = wm8990_i2c_detach, 1516 .remove = wm8990_i2c_remove,
1548 .command = NULL, 1517 .id_table = wm8990_i2c_id,
1549}; 1518};
1550 1519
1551static struct i2c_client client_template = { 1520static int wm8990_add_i2c_device(struct platform_device *pdev,
1552 .name = "WM8990", 1521 const struct wm8990_setup_data *setup)
1553 .driver = &wm8990_i2c_driver, 1522{
1554}; 1523 struct i2c_board_info info;
1524 struct i2c_adapter *adapter;
1525 struct i2c_client *client;
1526 int ret;
1527
1528 ret = i2c_add_driver(&wm8990_i2c_driver);
1529 if (ret != 0) {
1530 dev_err(&pdev->dev, "can't add i2c driver\n");
1531 return ret;
1532 }
1533
1534 memset(&info, 0, sizeof(struct i2c_board_info));
1535 info.addr = setup->i2c_address;
1536 strlcpy(info.type, "wm8990", I2C_NAME_SIZE);
1537
1538 adapter = i2c_get_adapter(setup->i2c_bus);
1539 if (!adapter) {
1540 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
1541 setup->i2c_bus);
1542 goto err_driver;
1543 }
1544
1545 client = i2c_new_device(adapter, &info);
1546 i2c_put_adapter(adapter);
1547 if (!client) {
1548 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
1549 (unsigned int)info.addr);
1550 goto err_driver;
1551 }
1552
1553 return 0;
1554
1555err_driver:
1556 i2c_del_driver(&wm8990_i2c_driver);
1557 return -ENODEV;
1558}
1555#endif 1559#endif
1556 1560
1557static int wm8990_probe(struct platform_device *pdev) 1561static int wm8990_probe(struct platform_device *pdev)
@@ -1560,7 +1564,7 @@ static int wm8990_probe(struct platform_device *pdev)
1560 struct wm8990_setup_data *setup; 1564 struct wm8990_setup_data *setup;
1561 struct snd_soc_codec *codec; 1565 struct snd_soc_codec *codec;
1562 struct wm8990_priv *wm8990; 1566 struct wm8990_priv *wm8990;
1563 int ret = 0; 1567 int ret;
1564 1568
1565 pr_info("WM8990 Audio Codec %s\n", WM8990_VERSION); 1569 pr_info("WM8990 Audio Codec %s\n", WM8990_VERSION);
1566 1570
@@ -1582,16 +1586,13 @@ static int wm8990_probe(struct platform_device *pdev)
1582 INIT_LIST_HEAD(&codec->dapm_paths); 1586 INIT_LIST_HEAD(&codec->dapm_paths);
1583 wm8990_socdev = socdev; 1587 wm8990_socdev = socdev;
1584 1588
1589 ret = -ENODEV;
1590
1585#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1591#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1586 if (setup->i2c_address) { 1592 if (setup->i2c_address) {
1587 normal_i2c[0] = setup->i2c_address;
1588 codec->hw_write = (hw_write_t)i2c_master_send; 1593 codec->hw_write = (hw_write_t)i2c_master_send;
1589 ret = i2c_add_driver(&wm8990_i2c_driver); 1594 ret = wm8990_add_i2c_device(pdev, setup);
1590 if (ret != 0)
1591 printk(KERN_ERR "can't add i2c driver");
1592 } 1595 }
1593#else
1594 /* Add other interfaces here */
1595#endif 1596#endif
1596 1597
1597 if (ret != 0) { 1598 if (ret != 0) {
@@ -1612,6 +1613,7 @@ static int wm8990_remove(struct platform_device *pdev)
1612 snd_soc_free_pcms(socdev); 1613 snd_soc_free_pcms(socdev);
1613 snd_soc_dapm_free(socdev); 1614 snd_soc_dapm_free(socdev);
1614#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1615#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1616 i2c_unregister_device(codec->control_data);
1615 i2c_del_driver(&wm8990_i2c_driver); 1617 i2c_del_driver(&wm8990_i2c_driver);
1616#endif 1618#endif
1617 kfree(codec->private_data); 1619 kfree(codec->private_data);
diff --git a/sound/soc/codecs/wm8990.h b/sound/soc/codecs/wm8990.h
index 0a08325d5443..0e192f3b0788 100644
--- a/sound/soc/codecs/wm8990.h
+++ b/sound/soc/codecs/wm8990.h
@@ -827,6 +827,7 @@
827#define WM8990_AINRMUX_PWR_BIT 3 827#define WM8990_AINRMUX_PWR_BIT 3
828 828
829struct wm8990_setup_data { 829struct wm8990_setup_data {
830 unsigned i2c_bus;
830 unsigned short i2c_address; 831 unsigned short i2c_address;
831}; 832};
832 833
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index 2f1c91b1d556..ffb471e420e2 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -2,8 +2,7 @@
2 * wm9712.c -- ALSA Soc WM9712 codec support 2 * wm9712.c -- ALSA Soc WM9712 codec support
3 * 3 *
4 * Copyright 2006 Wolfson Microelectronics PLC. 4 * Copyright 2006 Wolfson Microelectronics PLC.
5 * Author: Liam Girdwood 5 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
6 * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
7 * 6 *
8 * This program is free software; you can redistribute it and/or modify it 7 * 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 8 * under the terms of the GNU General Public License as published by the
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index 38d1fe0971fc..aba402b3c999 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -2,8 +2,7 @@
2 * wm9713.c -- ALSA Soc WM9713 codec support 2 * wm9713.c -- ALSA Soc WM9713 codec support
3 * 3 *
4 * Copyright 2006 Wolfson Microelectronics PLC. 4 * Copyright 2006 Wolfson Microelectronics PLC.
5 * Author: Liam Girdwood 5 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
6 * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
7 * 6 *
8 * This program is free software; you can redistribute it and/or modify it 7 * 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 8 * under the terms of the GNU General Public License as published by the
@@ -419,8 +418,12 @@ SND_SOC_DAPM_MIXER("Line Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
419SND_SOC_DAPM_MIXER("Capture Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), 418SND_SOC_DAPM_MIXER("Capture Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
420SND_SOC_DAPM_DAC("Voice DAC", "Voice Playback", AC97_EXTENDED_MID, 12, 1), 419SND_SOC_DAPM_DAC("Voice DAC", "Voice Playback", AC97_EXTENDED_MID, 12, 1),
421SND_SOC_DAPM_DAC("Aux DAC", "Aux Playback", AC97_EXTENDED_MID, 11, 1), 420SND_SOC_DAPM_DAC("Aux DAC", "Aux Playback", AC97_EXTENDED_MID, 11, 1),
422SND_SOC_DAPM_ADC("Left ADC", "Left HiFi Capture", AC97_EXTENDED_MID, 5, 1), 421SND_SOC_DAPM_PGA("Left ADC", AC97_EXTENDED_MID, 5, 1, NULL, 0),
423SND_SOC_DAPM_ADC("Right ADC", "Right HiFi Capture", AC97_EXTENDED_MID, 4, 1), 422SND_SOC_DAPM_PGA("Right ADC", AC97_EXTENDED_MID, 4, 1, NULL, 0),
423SND_SOC_DAPM_ADC("Left HiFi ADC", "Left HiFi Capture", SND_SOC_NOPM, 0, 0),
424SND_SOC_DAPM_ADC("Right HiFi ADC", "Right HiFi Capture", SND_SOC_NOPM, 0, 0),
425SND_SOC_DAPM_ADC("Left Voice ADC", "Left Voice Capture", SND_SOC_NOPM, 0, 0),
426SND_SOC_DAPM_ADC("Right Voice ADC", "Right Voice Capture", SND_SOC_NOPM, 0, 0),
424SND_SOC_DAPM_PGA("Left Headphone", AC97_EXTENDED_MSTATUS, 10, 1, NULL, 0), 427SND_SOC_DAPM_PGA("Left Headphone", AC97_EXTENDED_MSTATUS, 10, 1, NULL, 0),
425SND_SOC_DAPM_PGA("Right Headphone", AC97_EXTENDED_MSTATUS, 9, 1, NULL, 0), 428SND_SOC_DAPM_PGA("Right Headphone", AC97_EXTENDED_MSTATUS, 9, 1, NULL, 0),
426SND_SOC_DAPM_PGA("Left Speaker", AC97_EXTENDED_MSTATUS, 8, 1, NULL, 0), 429SND_SOC_DAPM_PGA("Left Speaker", AC97_EXTENDED_MSTATUS, 8, 1, NULL, 0),
@@ -583,9 +586,13 @@ static const struct snd_soc_dapm_route audio_map[] = {
583 586
584 /* left ADC */ 587 /* left ADC */
585 {"Left ADC", NULL, "Left Capture Source"}, 588 {"Left ADC", NULL, "Left Capture Source"},
589 {"Left Voice ADC", NULL, "Left ADC"},
590 {"Left HiFi ADC", NULL, "Left ADC"},
586 591
587 /* right ADC */ 592 /* right ADC */
588 {"Right ADC", NULL, "Right Capture Source"}, 593 {"Right ADC", NULL, "Right Capture Source"},
594 {"Right Voice ADC", NULL, "Right ADC"},
595 {"Right HiFi ADC", NULL, "Right ADC"},
589 596
590 /* mic */ 597 /* mic */
591 {"Mic A Pre Amp", NULL, "Mic A Source"}, 598 {"Mic A Pre Amp", NULL, "Mic A Source"},
@@ -949,17 +956,17 @@ static int wm9713_pcm_hw_params(struct snd_pcm_substream *substream,
949 956
950static void wm9713_voiceshutdown(struct snd_pcm_substream *substream) 957static void wm9713_voiceshutdown(struct snd_pcm_substream *substream)
951{ 958{
952 struct snd_soc_pcm_runtime *rtd = substream->private_data; 959 struct snd_soc_pcm_runtime *rtd = substream->private_data;
953 struct snd_soc_device *socdev = rtd->socdev; 960 struct snd_soc_device *socdev = rtd->socdev;
954 struct snd_soc_codec *codec = socdev->codec; 961 struct snd_soc_codec *codec = socdev->codec;
955 u16 status; 962 u16 status;
956 963
957 /* Gracefully shut down the voice interface. */ 964 /* Gracefully shut down the voice interface. */
958 status = ac97_read(codec, AC97_EXTENDED_STATUS) | 0x1000; 965 status = ac97_read(codec, AC97_EXTENDED_STATUS) | 0x1000;
959 ac97_write(codec, AC97_HANDSET_RATE, 0x0280); 966 ac97_write(codec, AC97_HANDSET_RATE, 0x0280);
960 schedule_timeout_interruptible(msecs_to_jiffies(1)); 967 schedule_timeout_interruptible(msecs_to_jiffies(1));
961 ac97_write(codec, AC97_HANDSET_RATE, 0x0F80); 968 ac97_write(codec, AC97_HANDSET_RATE, 0x0F80);
962 ac97_write(codec, AC97_EXTENDED_MID, status); 969 ac97_write(codec, AC97_EXTENDED_MID, status);
963} 970}
964 971
965static int ac97_hifi_prepare(struct snd_pcm_substream *substream) 972static int ac97_hifi_prepare(struct snd_pcm_substream *substream)
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c
index 65fdbd81a379..9e6062cd6b59 100644
--- a/sound/soc/davinci/davinci-evm.c
+++ b/sound/soc/davinci/davinci-evm.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * ASoC driver for TI DAVINCI EVM platform 2 * ASoC driver for TI DAVINCI EVM platform
3 * 3 *
4 * Author: Vladimir Barinov, <vbarinov@ru.mvista.com> 4 * Author: Vladimir Barinov, <vbarinov@embeddedalley.com>
5 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com> 5 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
@@ -136,6 +136,7 @@ static struct snd_soc_machine snd_soc_machine_evm = {
136 136
137/* evm audio private data */ 137/* evm audio private data */
138static struct aic3x_setup_data evm_aic3x_setup = { 138static struct aic3x_setup_data evm_aic3x_setup = {
139 .i2c_bus = 0,
139 .i2c_address = 0x1b, 140 .i2c_address = 0x1b,
140}; 141};
141 142
diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c
index 5ebf1ff71c4c..abb5fedb0b1e 100644
--- a/sound/soc/davinci/davinci-i2s.c
+++ b/sound/soc/davinci/davinci-i2s.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * ALSA SoC I2S (McBSP) Audio Layer for TI DAVINCI processor 2 * ALSA SoC I2S (McBSP) Audio Layer for TI DAVINCI processor
3 * 3 *
4 * Author: Vladimir Barinov, <vbarinov@ru.mvista.com> 4 * Author: Vladimir Barinov, <vbarinov@embeddedalley.com>
5 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com> 5 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
@@ -256,7 +256,7 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
256 mcbsp_word_length = DAVINCI_MCBSP_WORD_32; 256 mcbsp_word_length = DAVINCI_MCBSP_WORD_32;
257 break; 257 break;
258 default: 258 default:
259 printk(KERN_WARNING "davinci-i2s: unsupported PCM format"); 259 printk(KERN_WARNING "davinci-i2s: unsupported PCM format\n");
260 return -EINVAL; 260 return -EINVAL;
261 } 261 }
262 262
diff --git a/sound/soc/davinci/davinci-i2s.h b/sound/soc/davinci/davinci-i2s.h
index c5b091807eec..241648ce8873 100644
--- a/sound/soc/davinci/davinci-i2s.h
+++ b/sound/soc/davinci/davinci-i2s.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * ALSA SoC I2S (McBSP) Audio Layer for TI DAVINCI processor 2 * ALSA SoC I2S (McBSP) Audio Layer for TI DAVINCI processor
3 * 3 *
4 * Author: Vladimir Barinov, <vbarinov@ru.mvista.com> 4 * Author: Vladimir Barinov, <vbarinov@embeddedalley.com>
5 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com> 5 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c
index 6a5e56a782bb..76feaa657375 100644
--- a/sound/soc/davinci/davinci-pcm.c
+++ b/sound/soc/davinci/davinci-pcm.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * ALSA PCM interface for the TI DAVINCI processor 2 * ALSA PCM interface for the TI DAVINCI processor
3 * 3 *
4 * Author: Vladimir Barinov, <vbarinov@ru.mvista.com> 4 * Author: Vladimir Barinov, <vbarinov@embeddedalley.com>
5 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com> 5 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
diff --git a/sound/soc/davinci/davinci-pcm.h b/sound/soc/davinci/davinci-pcm.h
index 8d6a45e75a6e..62cb4eb07e34 100644
--- a/sound/soc/davinci/davinci-pcm.h
+++ b/sound/soc/davinci/davinci-pcm.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * ALSA PCM interface for the TI DAVINCI processor 2 * ALSA PCM interface for the TI DAVINCI processor
3 * 3 *
4 * Author: Vladimir Barinov, <vbarinov@ru.mvista.com> 4 * Author: Vladimir Barinov, <vbarinov@embeddedalley.com>
5 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com> 5 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 3368ace60977..bba9546ba5f5 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -1,3 +1,6 @@
1config SND_SOC_OF_SIMPLE
2 tristate
3
1config SND_SOC_MPC8610 4config SND_SOC_MPC8610
2 bool "ALSA SoC support for the MPC8610 SOC" 5 bool "ALSA SoC support for the MPC8610 SOC"
3 depends on MPC8610_HPCD 6 depends on MPC8610_HPCD
@@ -14,3 +17,10 @@ config SND_SOC_MPC8610_HPCD
14 default y if MPC8610_HPCD 17 default y if MPC8610_HPCD
15 help 18 help
16 Say Y if you want to enable audio on the Freescale MPC8610 HPCD. 19 Say Y if you want to enable audio on the Freescale MPC8610 HPCD.
20
21config SND_SOC_MPC5200_I2S
22 tristate "Freescale MPC5200 PSC in I2S mode driver"
23 select SND_SOC_OF_SIMPLE
24 depends on SND_SOC && PPC_MPC52xx
25 help
26 Say Y here to support the MPC5200 PSCs in I2S mode.
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index 62f680a4a776..035da4afec34 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -1,6 +1,11 @@
1# Simple machine driver that extracts configuration from the OF device tree
2obj-$(CONFIG_SND_SOC_OF_SIMPLE) += soc-of-simple.o
3
1# MPC8610 HPCD Machine Support 4# MPC8610 HPCD Machine Support
2obj-$(CONFIG_SND_SOC_MPC8610_HPCD) += mpc8610_hpcd.o 5obj-$(CONFIG_SND_SOC_MPC8610_HPCD) += mpc8610_hpcd.o
3 6
4# MPC8610 Platform Support 7# MPC8610 Platform Support
5obj-$(CONFIG_SND_SOC_MPC8610) += fsl_ssi.o fsl_dma.o 8obj-$(CONFIG_SND_SOC_MPC8610) += fsl_ssi.o fsl_dma.o
6 9
10obj-$(CONFIG_SND_SOC_MPC5200_I2S) += mpc5200_psc_i2s.o
11
diff --git a/sound/soc/fsl/mpc5200_psc_i2s.c b/sound/soc/fsl/mpc5200_psc_i2s.c
new file mode 100644
index 000000000000..86923299bc10
--- /dev/null
+++ b/sound/soc/fsl/mpc5200_psc_i2s.c
@@ -0,0 +1,884 @@
1/*
2 * Freescale MPC5200 PSC in I2S mode
3 * ALSA SoC Digital Audio Interface (DAI) driver
4 *
5 * Copyright (C) 2008 Secret Lab Technologies Ltd.
6 */
7
8#include <linux/init.h>
9#include <linux/module.h>
10#include <linux/interrupt.h>
11#include <linux/device.h>
12#include <linux/delay.h>
13#include <linux/of_device.h>
14#include <linux/of_platform.h>
15#include <linux/dma-mapping.h>
16
17#include <sound/core.h>
18#include <sound/pcm.h>
19#include <sound/pcm_params.h>
20#include <sound/initval.h>
21#include <sound/soc.h>
22#include <sound/soc-of-simple.h>
23
24#include <sysdev/bestcomm/bestcomm.h>
25#include <sysdev/bestcomm/gen_bd.h>
26#include <asm/mpc52xx_psc.h>
27
28MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
29MODULE_DESCRIPTION("Freescale MPC5200 PSC in I2S mode ASoC Driver");
30MODULE_LICENSE("GPL");
31
32/**
33 * PSC_I2S_RATES: sample rates supported by the I2S
34 *
35 * This driver currently only supports the PSC running in I2S slave mode,
36 * which means the codec determines the sample rate. Therefore, we tell
37 * ALSA that we support all rates and let the codec driver decide what rates
38 * are really supported.
39 */
40#define PSC_I2S_RATES (SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_192000 | \
41 SNDRV_PCM_RATE_CONTINUOUS)
42
43/**
44 * PSC_I2S_FORMATS: audio formats supported by the PSC I2S mode
45 */
46#define PSC_I2S_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_BE | \
47 SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S24_BE | \
48 SNDRV_PCM_FMTBIT_S32_BE)
49
50/**
51 * psc_i2s_stream - Data specific to a single stream (playback or capture)
52 * @active: flag indicating if the stream is active
53 * @psc_i2s: pointer back to parent psc_i2s data structure
54 * @bcom_task: bestcomm task structure
55 * @irq: irq number for bestcomm task
56 * @period_start: physical address of start of DMA region
57 * @period_end: physical address of end of DMA region
58 * @period_next_pt: physical address of next DMA buffer to enqueue
59 * @period_bytes: size of DMA period in bytes
60 */
61struct psc_i2s_stream {
62 int active;
63 struct psc_i2s *psc_i2s;
64 struct bcom_task *bcom_task;
65 int irq;
66 struct snd_pcm_substream *stream;
67 dma_addr_t period_start;
68 dma_addr_t period_end;
69 dma_addr_t period_next_pt;
70 dma_addr_t period_current_pt;
71 int period_bytes;
72};
73
74/**
75 * psc_i2s - Private driver data
76 * @name: short name for this device ("PSC0", "PSC1", etc)
77 * @psc_regs: pointer to the PSC's registers
78 * @fifo_regs: pointer to the PSC's FIFO registers
79 * @irq: IRQ of this PSC
80 * @dev: struct device pointer
81 * @dai: the CPU DAI for this device
82 * @sicr: Base value used in serial interface control register; mode is ORed
83 * with this value.
84 * @playback: Playback stream context data
85 * @capture: Capture stream context data
86 */
87struct psc_i2s {
88 char name[32];
89 struct mpc52xx_psc __iomem *psc_regs;
90 struct mpc52xx_psc_fifo __iomem *fifo_regs;
91 unsigned int irq;
92 struct device *dev;
93 struct snd_soc_dai dai;
94 spinlock_t lock;
95 u32 sicr;
96
97 /* per-stream data */
98 struct psc_i2s_stream playback;
99 struct psc_i2s_stream capture;
100
101 /* Statistics */
102 struct {
103 int overrun_count;
104 int underrun_count;
105 } stats;
106};
107
108/*
109 * Interrupt handlers
110 */
111static irqreturn_t psc_i2s_status_irq(int irq, void *_psc_i2s)
112{
113 struct psc_i2s *psc_i2s = _psc_i2s;
114 struct mpc52xx_psc __iomem *regs = psc_i2s->psc_regs;
115 u16 isr;
116
117 isr = in_be16(&regs->mpc52xx_psc_isr);
118
119 /* Playback underrun error */
120 if (psc_i2s->playback.active && (isr & MPC52xx_PSC_IMR_TXEMP))
121 psc_i2s->stats.underrun_count++;
122
123 /* Capture overrun error */
124 if (psc_i2s->capture.active && (isr & MPC52xx_PSC_IMR_ORERR))
125 psc_i2s->stats.overrun_count++;
126
127 out_8(&regs->command, 4 << 4); /* reset the error status */
128
129 return IRQ_HANDLED;
130}
131
132/**
133 * psc_i2s_bcom_enqueue_next_buffer - Enqueue another audio buffer
134 * @s: pointer to stream private data structure
135 *
136 * Enqueues another audio period buffer into the bestcomm queue.
137 *
138 * Note: The routine must only be called when there is space available in
139 * the queue. Otherwise the enqueue will fail and the audio ring buffer
140 * will get out of sync
141 */
142static void psc_i2s_bcom_enqueue_next_buffer(struct psc_i2s_stream *s)
143{
144 struct bcom_bd *bd;
145
146 /* Prepare and enqueue the next buffer descriptor */
147 bd = bcom_prepare_next_buffer(s->bcom_task);
148 bd->status = s->period_bytes;
149 bd->data[0] = s->period_next_pt;
150 bcom_submit_next_buffer(s->bcom_task, NULL);
151
152 /* Update for next period */
153 s->period_next_pt += s->period_bytes;
154 if (s->period_next_pt >= s->period_end)
155 s->period_next_pt = s->period_start;
156}
157
158/* Bestcomm DMA irq handler */
159static irqreturn_t psc_i2s_bcom_irq(int irq, void *_psc_i2s_stream)
160{
161 struct psc_i2s_stream *s = _psc_i2s_stream;
162
163 /* For each finished period, dequeue the completed period buffer
164 * and enqueue a new one in it's place. */
165 while (bcom_buffer_done(s->bcom_task)) {
166 bcom_retrieve_buffer(s->bcom_task, NULL, NULL);
167 s->period_current_pt += s->period_bytes;
168 if (s->period_current_pt >= s->period_end)
169 s->period_current_pt = s->period_start;
170 psc_i2s_bcom_enqueue_next_buffer(s);
171 bcom_enable(s->bcom_task);
172 }
173
174 /* If the stream is active, then also inform the PCM middle layer
175 * of the period finished event. */
176 if (s->active)
177 snd_pcm_period_elapsed(s->stream);
178
179 return IRQ_HANDLED;
180}
181
182/**
183 * psc_i2s_startup: create a new substream
184 *
185 * This is the first function called when a stream is opened.
186 *
187 * If this is the first stream open, then grab the IRQ and program most of
188 * the PSC registers.
189 */
190static int psc_i2s_startup(struct snd_pcm_substream *substream)
191{
192 struct snd_soc_pcm_runtime *rtd = substream->private_data;
193 struct psc_i2s *psc_i2s = rtd->dai->cpu_dai->private_data;
194 int rc;
195
196 dev_dbg(psc_i2s->dev, "psc_i2s_startup(substream=%p)\n", substream);
197
198 if (!psc_i2s->playback.active &&
199 !psc_i2s->capture.active) {
200 /* Setup the IRQs */
201 rc = request_irq(psc_i2s->irq, &psc_i2s_status_irq, IRQF_SHARED,
202 "psc-i2s-status", psc_i2s);
203 rc |= request_irq(psc_i2s->capture.irq,
204 &psc_i2s_bcom_irq, IRQF_SHARED,
205 "psc-i2s-capture", &psc_i2s->capture);
206 rc |= request_irq(psc_i2s->playback.irq,
207 &psc_i2s_bcom_irq, IRQF_SHARED,
208 "psc-i2s-playback", &psc_i2s->playback);
209 if (rc) {
210 free_irq(psc_i2s->irq, psc_i2s);
211 free_irq(psc_i2s->capture.irq,
212 &psc_i2s->capture);
213 free_irq(psc_i2s->playback.irq,
214 &psc_i2s->playback);
215 return -ENODEV;
216 }
217 }
218
219 return 0;
220}
221
222static int psc_i2s_hw_params(struct snd_pcm_substream *substream,
223 struct snd_pcm_hw_params *params)
224{
225 struct snd_soc_pcm_runtime *rtd = substream->private_data;
226 struct psc_i2s *psc_i2s = rtd->dai->cpu_dai->private_data;
227 u32 mode;
228
229 dev_dbg(psc_i2s->dev, "%s(substream=%p) p_size=%i p_bytes=%i"
230 " periods=%i buffer_size=%i buffer_bytes=%i\n",
231 __func__, substream, params_period_size(params),
232 params_period_bytes(params), params_periods(params),
233 params_buffer_size(params), params_buffer_bytes(params));
234
235 switch (params_format(params)) {
236 case SNDRV_PCM_FORMAT_S8:
237 mode = MPC52xx_PSC_SICR_SIM_CODEC_8;
238 break;
239 case SNDRV_PCM_FORMAT_S16_BE:
240 mode = MPC52xx_PSC_SICR_SIM_CODEC_16;
241 break;
242 case SNDRV_PCM_FORMAT_S24_BE:
243 mode = MPC52xx_PSC_SICR_SIM_CODEC_24;
244 break;
245 case SNDRV_PCM_FORMAT_S32_BE:
246 mode = MPC52xx_PSC_SICR_SIM_CODEC_32;
247 break;
248 default:
249 dev_dbg(psc_i2s->dev, "invalid format\n");
250 return -EINVAL;
251 }
252 out_be32(&psc_i2s->psc_regs->sicr, psc_i2s->sicr | mode);
253
254 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
255
256 return 0;
257}
258
259static int psc_i2s_hw_free(struct snd_pcm_substream *substream)
260{
261 snd_pcm_set_runtime_buffer(substream, NULL);
262 return 0;
263}
264
265/**
266 * psc_i2s_trigger: start and stop the DMA transfer.
267 *
268 * This function is called by ALSA to start, stop, pause, and resume the DMA
269 * transfer of data.
270 */
271static int psc_i2s_trigger(struct snd_pcm_substream *substream, int cmd)
272{
273 struct snd_soc_pcm_runtime *rtd = substream->private_data;
274 struct psc_i2s *psc_i2s = rtd->dai->cpu_dai->private_data;
275 struct snd_pcm_runtime *runtime = substream->runtime;
276 struct psc_i2s_stream *s;
277 struct mpc52xx_psc __iomem *regs = psc_i2s->psc_regs;
278 u16 imr;
279 u8 psc_cmd;
280 long flags;
281
282 if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE)
283 s = &psc_i2s->capture;
284 else
285 s = &psc_i2s->playback;
286
287 dev_dbg(psc_i2s->dev, "psc_i2s_trigger(substream=%p, cmd=%i)"
288 " stream_id=%i\n",
289 substream, cmd, substream->pstr->stream);
290
291 switch (cmd) {
292 case SNDRV_PCM_TRIGGER_START:
293 s->period_bytes = frames_to_bytes(runtime,
294 runtime->period_size);
295 s->period_start = virt_to_phys(runtime->dma_area);
296 s->period_end = s->period_start +
297 (s->period_bytes * runtime->periods);
298 s->period_next_pt = s->period_start;
299 s->period_current_pt = s->period_start;
300 s->active = 1;
301
302 /* First; reset everything */
303 if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE) {
304 out_8(&regs->command, MPC52xx_PSC_RST_RX);
305 out_8(&regs->command, MPC52xx_PSC_RST_ERR_STAT);
306 } else {
307 out_8(&regs->command, MPC52xx_PSC_RST_TX);
308 out_8(&regs->command, MPC52xx_PSC_RST_ERR_STAT);
309 }
310
311 /* Next, fill up the bestcomm bd queue and enable DMA.
312 * This will begin filling the PSC's fifo. */
313 if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE)
314 bcom_gen_bd_rx_reset(s->bcom_task);
315 else
316 bcom_gen_bd_tx_reset(s->bcom_task);
317 while (!bcom_queue_full(s->bcom_task))
318 psc_i2s_bcom_enqueue_next_buffer(s);
319 bcom_enable(s->bcom_task);
320
321 /* Due to errata in the i2s mode; need to line up enabling
322 * the transmitter with a transition on the frame sync
323 * line */
324
325 spin_lock_irqsave(&psc_i2s->lock, flags);
326 /* first make sure it is low */
327 while ((in_8(&regs->ipcr_acr.ipcr) & 0x80) != 0)
328 ;
329 /* then wait for the transition to high */
330 while ((in_8(&regs->ipcr_acr.ipcr) & 0x80) == 0)
331 ;
332 /* Finally, enable the PSC.
333 * Receiver must always be enabled; even when we only want
334 * transmit. (see 15.3.2.3 of MPC5200B User's Guide) */
335 psc_cmd = MPC52xx_PSC_RX_ENABLE;
336 if (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK)
337 psc_cmd |= MPC52xx_PSC_TX_ENABLE;
338 out_8(&regs->command, psc_cmd);
339 spin_unlock_irqrestore(&psc_i2s->lock, flags);
340
341 break;
342
343 case SNDRV_PCM_TRIGGER_STOP:
344 /* Turn off the PSC */
345 s->active = 0;
346 if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE) {
347 if (!psc_i2s->playback.active) {
348 out_8(&regs->command, 2 << 4); /* reset rx */
349 out_8(&regs->command, 3 << 4); /* reset tx */
350 out_8(&regs->command, 4 << 4); /* reset err */
351 }
352 } else {
353 out_8(&regs->command, 3 << 4); /* reset tx */
354 out_8(&regs->command, 4 << 4); /* reset err */
355 if (!psc_i2s->capture.active)
356 out_8(&regs->command, 2 << 4); /* reset rx */
357 }
358
359 bcom_disable(s->bcom_task);
360 while (!bcom_queue_empty(s->bcom_task))
361 bcom_retrieve_buffer(s->bcom_task, NULL, NULL);
362
363 break;
364
365 default:
366 dev_dbg(psc_i2s->dev, "invalid command\n");
367 return -EINVAL;
368 }
369
370 /* Update interrupt enable settings */
371 imr = 0;
372 if (psc_i2s->playback.active)
373 imr |= MPC52xx_PSC_IMR_TXEMP;
374 if (psc_i2s->capture.active)
375 imr |= MPC52xx_PSC_IMR_ORERR;
376 out_be16(&regs->isr_imr.imr, imr);
377
378 return 0;
379}
380
381/**
382 * psc_i2s_shutdown: shutdown the data transfer on a stream
383 *
384 * Shutdown the PSC if there are no other substreams open.
385 */
386static void psc_i2s_shutdown(struct snd_pcm_substream *substream)
387{
388 struct snd_soc_pcm_runtime *rtd = substream->private_data;
389 struct psc_i2s *psc_i2s = rtd->dai->cpu_dai->private_data;
390
391 dev_dbg(psc_i2s->dev, "psc_i2s_shutdown(substream=%p)\n", substream);
392
393 /*
394 * If this is the last active substream, disable the PSC and release
395 * the IRQ.
396 */
397 if (!psc_i2s->playback.active &&
398 !psc_i2s->capture.active) {
399
400 /* Disable all interrupts and reset the PSC */
401 out_be16(&psc_i2s->psc_regs->isr_imr.imr, 0);
402 out_8(&psc_i2s->psc_regs->command, 3 << 4); /* reset tx */
403 out_8(&psc_i2s->psc_regs->command, 2 << 4); /* reset rx */
404 out_8(&psc_i2s->psc_regs->command, 1 << 4); /* reset mode */
405 out_8(&psc_i2s->psc_regs->command, 4 << 4); /* reset error */
406
407 /* Release irqs */
408 free_irq(psc_i2s->irq, psc_i2s);
409 free_irq(psc_i2s->capture.irq, &psc_i2s->capture);
410 free_irq(psc_i2s->playback.irq, &psc_i2s->playback);
411 }
412}
413
414/**
415 * psc_i2s_set_sysclk: set the clock frequency and direction
416 *
417 * This function is called by the machine driver to tell us what the clock
418 * frequency and direction are.
419 *
420 * Currently, we only support operating as a clock slave (SND_SOC_CLOCK_IN),
421 * and we don't care about the frequency. Return an error if the direction
422 * is not SND_SOC_CLOCK_IN.
423 *
424 * @clk_id: reserved, should be zero
425 * @freq: the frequency of the given clock ID, currently ignored
426 * @dir: SND_SOC_CLOCK_IN (clock slave) or SND_SOC_CLOCK_OUT (clock master)
427 */
428static int psc_i2s_set_sysclk(struct snd_soc_dai *cpu_dai,
429 int clk_id, unsigned int freq, int dir)
430{
431 struct psc_i2s *psc_i2s = cpu_dai->private_data;
432 dev_dbg(psc_i2s->dev, "psc_i2s_set_sysclk(cpu_dai=%p, dir=%i)\n",
433 cpu_dai, dir);
434 return (dir == SND_SOC_CLOCK_IN) ? 0 : -EINVAL;
435}
436
437/**
438 * psc_i2s_set_fmt: set the serial format.
439 *
440 * This function is called by the machine driver to tell us what serial
441 * format to use.
442 *
443 * This driver only supports I2S mode. Return an error if the format is
444 * not SND_SOC_DAIFMT_I2S.
445 *
446 * @format: one of SND_SOC_DAIFMT_xxx
447 */
448static int psc_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int format)
449{
450 struct psc_i2s *psc_i2s = cpu_dai->private_data;
451 dev_dbg(psc_i2s->dev, "psc_i2s_set_fmt(cpu_dai=%p, format=%i)\n",
452 cpu_dai, format);
453 return (format == SND_SOC_DAIFMT_I2S) ? 0 : -EINVAL;
454}
455
456/* ---------------------------------------------------------------------
457 * ALSA SoC Bindings
458 *
459 * - Digital Audio Interface (DAI) template
460 * - create/destroy dai hooks
461 */
462
463/**
464 * psc_i2s_dai_template: template CPU Digital Audio Interface
465 */
466static struct snd_soc_dai psc_i2s_dai_template = {
467 .type = SND_SOC_DAI_I2S,
468 .playback = {
469 .channels_min = 2,
470 .channels_max = 2,
471 .rates = PSC_I2S_RATES,
472 .formats = PSC_I2S_FORMATS,
473 },
474 .capture = {
475 .channels_min = 2,
476 .channels_max = 2,
477 .rates = PSC_I2S_RATES,
478 .formats = PSC_I2S_FORMATS,
479 },
480 .ops = {
481 .startup = psc_i2s_startup,
482 .hw_params = psc_i2s_hw_params,
483 .hw_free = psc_i2s_hw_free,
484 .shutdown = psc_i2s_shutdown,
485 .trigger = psc_i2s_trigger,
486 },
487 .dai_ops = {
488 .set_sysclk = psc_i2s_set_sysclk,
489 .set_fmt = psc_i2s_set_fmt,
490 },
491};
492
493/* ---------------------------------------------------------------------
494 * The PSC I2S 'ASoC platform' driver
495 *
496 * Can be referenced by an 'ASoC machine' driver
497 * This driver only deals with the audio bus; it doesn't have any
498 * interaction with the attached codec
499 */
500
501static const struct snd_pcm_hardware psc_i2s_pcm_hardware = {
502 .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
503 SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER,
504 .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_BE |
505 SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S32_BE,
506 .rate_min = 8000,
507 .rate_max = 48000,
508 .channels_min = 2,
509 .channels_max = 2,
510 .period_bytes_max = 1024 * 1024,
511 .period_bytes_min = 32,
512 .periods_min = 2,
513 .periods_max = 256,
514 .buffer_bytes_max = 2 * 1024 * 1024,
515 .fifo_size = 0,
516};
517
518static int psc_i2s_pcm_open(struct snd_pcm_substream *substream)
519{
520 struct snd_soc_pcm_runtime *rtd = substream->private_data;
521 struct psc_i2s *psc_i2s = rtd->dai->cpu_dai->private_data;
522 struct psc_i2s_stream *s;
523
524 dev_dbg(psc_i2s->dev, "psc_i2s_pcm_open(substream=%p)\n", substream);
525
526 if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE)
527 s = &psc_i2s->capture;
528 else
529 s = &psc_i2s->playback;
530
531 snd_soc_set_runtime_hwparams(substream, &psc_i2s_pcm_hardware);
532
533 s->stream = substream;
534 return 0;
535}
536
537static int psc_i2s_pcm_close(struct snd_pcm_substream *substream)
538{
539 struct snd_soc_pcm_runtime *rtd = substream->private_data;
540 struct psc_i2s *psc_i2s = rtd->dai->cpu_dai->private_data;
541 struct psc_i2s_stream *s;
542
543 dev_dbg(psc_i2s->dev, "psc_i2s_pcm_close(substream=%p)\n", substream);
544
545 if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE)
546 s = &psc_i2s->capture;
547 else
548 s = &psc_i2s->playback;
549
550 s->stream = NULL;
551 return 0;
552}
553
554static snd_pcm_uframes_t
555psc_i2s_pcm_pointer(struct snd_pcm_substream *substream)
556{
557 struct snd_soc_pcm_runtime *rtd = substream->private_data;
558 struct psc_i2s *psc_i2s = rtd->dai->cpu_dai->private_data;
559 struct psc_i2s_stream *s;
560 dma_addr_t count;
561
562 if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE)
563 s = &psc_i2s->capture;
564 else
565 s = &psc_i2s->playback;
566
567 count = s->period_current_pt - s->period_start;
568
569 return bytes_to_frames(substream->runtime, count);
570}
571
572static struct snd_pcm_ops psc_i2s_pcm_ops = {
573 .open = psc_i2s_pcm_open,
574 .close = psc_i2s_pcm_close,
575 .ioctl = snd_pcm_lib_ioctl,
576 .pointer = psc_i2s_pcm_pointer,
577};
578
579static u64 psc_i2s_pcm_dmamask = 0xffffffff;
580static int psc_i2s_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
581 struct snd_pcm *pcm)
582{
583 struct snd_soc_pcm_runtime *rtd = pcm->private_data;
584 size_t size = psc_i2s_pcm_hardware.buffer_bytes_max;
585 int rc = 0;
586
587 dev_dbg(rtd->socdev->dev, "psc_i2s_pcm_new(card=%p, dai=%p, pcm=%p)\n",
588 card, dai, pcm);
589
590 if (!card->dev->dma_mask)
591 card->dev->dma_mask = &psc_i2s_pcm_dmamask;
592 if (!card->dev->coherent_dma_mask)
593 card->dev->coherent_dma_mask = 0xffffffff;
594
595 if (pcm->streams[0].substream) {
596 rc = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, pcm->dev, size,
597 &pcm->streams[0].substream->dma_buffer);
598 if (rc)
599 goto playback_alloc_err;
600 }
601
602 if (pcm->streams[1].substream) {
603 rc = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, pcm->dev, size,
604 &pcm->streams[1].substream->dma_buffer);
605 if (rc)
606 goto capture_alloc_err;
607 }
608
609 return 0;
610
611 capture_alloc_err:
612 if (pcm->streams[0].substream)
613 snd_dma_free_pages(&pcm->streams[0].substream->dma_buffer);
614 playback_alloc_err:
615 dev_err(card->dev, "Cannot allocate buffer(s)\n");
616 return -ENOMEM;
617}
618
619static void psc_i2s_pcm_free(struct snd_pcm *pcm)
620{
621 struct snd_soc_pcm_runtime *rtd = pcm->private_data;
622 struct snd_pcm_substream *substream;
623 int stream;
624
625 dev_dbg(rtd->socdev->dev, "psc_i2s_pcm_free(pcm=%p)\n", pcm);
626
627 for (stream = 0; stream < 2; stream++) {
628 substream = pcm->streams[stream].substream;
629 if (substream) {
630 snd_dma_free_pages(&substream->dma_buffer);
631 substream->dma_buffer.area = NULL;
632 substream->dma_buffer.addr = 0;
633 }
634 }
635}
636
637struct snd_soc_platform psc_i2s_pcm_soc_platform = {
638 .name = "mpc5200-psc-audio",
639 .pcm_ops = &psc_i2s_pcm_ops,
640 .pcm_new = &psc_i2s_pcm_new,
641 .pcm_free = &psc_i2s_pcm_free,
642};
643
644/* ---------------------------------------------------------------------
645 * Sysfs attributes for debugging
646 */
647
648static ssize_t psc_i2s_status_show(struct device *dev,
649 struct device_attribute *attr, char *buf)
650{
651 struct psc_i2s *psc_i2s = dev_get_drvdata(dev);
652
653 return sprintf(buf, "status=%.4x sicr=%.8x rfnum=%i rfstat=0x%.4x "
654 "tfnum=%i tfstat=0x%.4x\n",
655 in_be16(&psc_i2s->psc_regs->sr_csr.status),
656 in_be32(&psc_i2s->psc_regs->sicr),
657 in_be16(&psc_i2s->fifo_regs->rfnum) & 0x1ff,
658 in_be16(&psc_i2s->fifo_regs->rfstat),
659 in_be16(&psc_i2s->fifo_regs->tfnum) & 0x1ff,
660 in_be16(&psc_i2s->fifo_regs->tfstat));
661}
662
663static int *psc_i2s_get_stat_attr(struct psc_i2s *psc_i2s, const char *name)
664{
665 if (strcmp(name, "playback_underrun") == 0)
666 return &psc_i2s->stats.underrun_count;
667 if (strcmp(name, "capture_overrun") == 0)
668 return &psc_i2s->stats.overrun_count;
669
670 return NULL;
671}
672
673static ssize_t psc_i2s_stat_show(struct device *dev,
674 struct device_attribute *attr, char *buf)
675{
676 struct psc_i2s *psc_i2s = dev_get_drvdata(dev);
677 int *attrib;
678
679 attrib = psc_i2s_get_stat_attr(psc_i2s, attr->attr.name);
680 if (!attrib)
681 return 0;
682
683 return sprintf(buf, "%i\n", *attrib);
684}
685
686static ssize_t psc_i2s_stat_store(struct device *dev,
687 struct device_attribute *attr,
688 const char *buf,
689 size_t count)
690{
691 struct psc_i2s *psc_i2s = dev_get_drvdata(dev);
692 int *attrib;
693
694 attrib = psc_i2s_get_stat_attr(psc_i2s, attr->attr.name);
695 if (!attrib)
696 return 0;
697
698 *attrib = simple_strtoul(buf, NULL, 0);
699 return count;
700}
701
702DEVICE_ATTR(status, 0644, psc_i2s_status_show, NULL);
703DEVICE_ATTR(playback_underrun, 0644, psc_i2s_stat_show, psc_i2s_stat_store);
704DEVICE_ATTR(capture_overrun, 0644, psc_i2s_stat_show, psc_i2s_stat_store);
705
706/* ---------------------------------------------------------------------
707 * OF platform bus binding code:
708 * - Probe/remove operations
709 * - OF device match table
710 */
711static int __devinit psc_i2s_of_probe(struct of_device *op,
712 const struct of_device_id *match)
713{
714 phys_addr_t fifo;
715 struct psc_i2s *psc_i2s;
716 struct resource res;
717 int size, psc_id, irq, rc;
718 const __be32 *prop;
719 void __iomem *regs;
720
721 dev_dbg(&op->dev, "probing psc i2s device\n");
722
723 /* Get the PSC ID */
724 prop = of_get_property(op->node, "cell-index", &size);
725 if (!prop || size < sizeof *prop)
726 return -ENODEV;
727 psc_id = be32_to_cpu(*prop);
728
729 /* Fetch the registers and IRQ of the PSC */
730 irq = irq_of_parse_and_map(op->node, 0);
731 if (of_address_to_resource(op->node, 0, &res)) {
732 dev_err(&op->dev, "Missing reg property\n");
733 return -ENODEV;
734 }
735 regs = ioremap(res.start, 1 + res.end - res.start);
736 if (!regs) {
737 dev_err(&op->dev, "Could not map registers\n");
738 return -ENODEV;
739 }
740
741 /* Allocate and initialize the driver private data */
742 psc_i2s = kzalloc(sizeof *psc_i2s, GFP_KERNEL);
743 if (!psc_i2s) {
744 iounmap(regs);
745 return -ENOMEM;
746 }
747 spin_lock_init(&psc_i2s->lock);
748 psc_i2s->irq = irq;
749 psc_i2s->psc_regs = regs;
750 psc_i2s->fifo_regs = regs + sizeof *psc_i2s->psc_regs;
751 psc_i2s->dev = &op->dev;
752 psc_i2s->playback.psc_i2s = psc_i2s;
753 psc_i2s->capture.psc_i2s = psc_i2s;
754 snprintf(psc_i2s->name, sizeof psc_i2s->name, "PSC%u", psc_id+1);
755
756 /* Fill out the CPU DAI structure */
757 memcpy(&psc_i2s->dai, &psc_i2s_dai_template, sizeof psc_i2s->dai);
758 psc_i2s->dai.private_data = psc_i2s;
759 psc_i2s->dai.name = psc_i2s->name;
760 psc_i2s->dai.id = psc_id;
761
762 /* Find the address of the fifo data registers and setup the
763 * DMA tasks */
764 fifo = res.start + offsetof(struct mpc52xx_psc, buffer.buffer_32);
765 psc_i2s->capture.bcom_task =
766 bcom_psc_gen_bd_rx_init(psc_id, 10, fifo, 512);
767 psc_i2s->playback.bcom_task =
768 bcom_psc_gen_bd_tx_init(psc_id, 10, fifo);
769 if (!psc_i2s->capture.bcom_task ||
770 !psc_i2s->playback.bcom_task) {
771 dev_err(&op->dev, "Could not allocate bestcomm tasks\n");
772 iounmap(regs);
773 kfree(psc_i2s);
774 return -ENODEV;
775 }
776
777 /* Disable all interrupts and reset the PSC */
778 out_be16(&psc_i2s->psc_regs->isr_imr.imr, 0);
779 out_8(&psc_i2s->psc_regs->command, 3 << 4); /* reset transmitter */
780 out_8(&psc_i2s->psc_regs->command, 2 << 4); /* reset receiver */
781 out_8(&psc_i2s->psc_regs->command, 1 << 4); /* reset mode */
782 out_8(&psc_i2s->psc_regs->command, 4 << 4); /* reset error */
783
784 /* Configure the serial interface mode; defaulting to CODEC8 mode */
785 psc_i2s->sicr = MPC52xx_PSC_SICR_DTS1 | MPC52xx_PSC_SICR_I2S |
786 MPC52xx_PSC_SICR_CLKPOL;
787 if (of_get_property(op->node, "fsl,cellslave", NULL))
788 psc_i2s->sicr |= MPC52xx_PSC_SICR_CELLSLAVE |
789 MPC52xx_PSC_SICR_GENCLK;
790 out_be32(&psc_i2s->psc_regs->sicr,
791 psc_i2s->sicr | MPC52xx_PSC_SICR_SIM_CODEC_8);
792
793 /* Check for the codec handle. If it is not present then we
794 * are done */
795 if (!of_get_property(op->node, "codec-handle", NULL))
796 return 0;
797
798 /* Set up mode register;
799 * First write: RxRdy (FIFO Alarm) generates rx FIFO irq
800 * Second write: register Normal mode for non loopback
801 */
802 out_8(&psc_i2s->psc_regs->mode, 0);
803 out_8(&psc_i2s->psc_regs->mode, 0);
804
805 /* Set the TX and RX fifo alarm thresholds */
806 out_be16(&psc_i2s->fifo_regs->rfalarm, 0x100);
807 out_8(&psc_i2s->fifo_regs->rfcntl, 0x4);
808 out_be16(&psc_i2s->fifo_regs->tfalarm, 0x100);
809 out_8(&psc_i2s->fifo_regs->tfcntl, 0x7);
810
811 /* Lookup the IRQ numbers */
812 psc_i2s->playback.irq =
813 bcom_get_task_irq(psc_i2s->playback.bcom_task);
814 psc_i2s->capture.irq =
815 bcom_get_task_irq(psc_i2s->capture.bcom_task);
816
817 /* Save what we've done so it can be found again later */
818 dev_set_drvdata(&op->dev, psc_i2s);
819
820 /* Register the SYSFS files */
821 rc = device_create_file(psc_i2s->dev, &dev_attr_status);
822 rc = device_create_file(psc_i2s->dev, &dev_attr_capture_overrun);
823 rc = device_create_file(psc_i2s->dev, &dev_attr_playback_underrun);
824 if (rc)
825 dev_info(psc_i2s->dev, "error creating sysfs files\n");
826
827 /* Tell the ASoC OF helpers about it */
828 of_snd_soc_register_platform(&psc_i2s_pcm_soc_platform, op->node,
829 &psc_i2s->dai);
830
831 return 0;
832}
833
834static int __devexit psc_i2s_of_remove(struct of_device *op)
835{
836 struct psc_i2s *psc_i2s = dev_get_drvdata(&op->dev);
837
838 dev_dbg(&op->dev, "psc_i2s_remove()\n");
839
840 bcom_gen_bd_rx_release(psc_i2s->capture.bcom_task);
841 bcom_gen_bd_tx_release(psc_i2s->playback.bcom_task);
842
843 iounmap(psc_i2s->psc_regs);
844 iounmap(psc_i2s->fifo_regs);
845 kfree(psc_i2s);
846 dev_set_drvdata(&op->dev, NULL);
847
848 return 0;
849}
850
851/* Match table for of_platform binding */
852static struct of_device_id psc_i2s_match[] __devinitdata = {
853 { .compatible = "fsl,mpc5200-psc-i2s", },
854 {}
855};
856MODULE_DEVICE_TABLE(of, psc_i2s_match);
857
858static struct of_platform_driver psc_i2s_driver = {
859 .match_table = psc_i2s_match,
860 .probe = psc_i2s_of_probe,
861 .remove = __devexit_p(psc_i2s_of_remove),
862 .driver = {
863 .name = "mpc5200-psc-i2s",
864 .owner = THIS_MODULE,
865 },
866};
867
868/* ---------------------------------------------------------------------
869 * Module setup and teardown; simply register the of_platform driver
870 * for the PSC in I2S mode.
871 */
872static int __init psc_i2s_init(void)
873{
874 return of_register_platform_driver(&psc_i2s_driver);
875}
876module_init(psc_i2s_init);
877
878static void __exit psc_i2s_exit(void)
879{
880 of_unregister_platform_driver(&psc_i2s_driver);
881}
882module_exit(psc_i2s_exit);
883
884
diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c
index 4bdc9d8fc90e..94f89debde1f 100644
--- a/sound/soc/fsl/mpc8610_hpcd.c
+++ b/sound/soc/fsl/mpc8610_hpcd.c
@@ -68,10 +68,6 @@ static int mpc8610_hpcd_machine_probe(struct platform_device *sound_device)
68 guts_set_pmuxcr_dma(machine_data->guts, machine_data->dma_id, 68 guts_set_pmuxcr_dma(machine_data->guts, machine_data->dma_id,
69 machine_data->dma_channel_id[1], 0); 69 machine_data->dma_channel_id[1], 0);
70 70
71 guts_set_pmuxcr_dma(machine_data->guts, 1, 0, 0);
72 guts_set_pmuxcr_dma(machine_data->guts, 1, 3, 0);
73 guts_set_pmuxcr_dma(machine_data->guts, 0, 3, 0);
74
75 switch (machine_data->ssi_id) { 71 switch (machine_data->ssi_id) {
76 case 0: 72 case 0:
77 clrsetbits_be32(&machine_data->guts->pmuxcr, 73 clrsetbits_be32(&machine_data->guts->pmuxcr,
@@ -230,6 +226,8 @@ static int mpc8610_hpcd_probe(struct of_device *ofdev,
230 struct fsl_ssi_info ssi_info; 226 struct fsl_ssi_info ssi_info;
231 struct fsl_dma_info dma_info; 227 struct fsl_dma_info dma_info;
232 int ret = -ENODEV; 228 int ret = -ENODEV;
229 unsigned int playback_dma_channel;
230 unsigned int capture_dma_channel;
233 231
234 machine_data = kzalloc(sizeof(struct mpc8610_hpcd_data), GFP_KERNEL); 232 machine_data = kzalloc(sizeof(struct mpc8610_hpcd_data), GFP_KERNEL);
235 if (!machine_data) 233 if (!machine_data)
@@ -381,8 +379,9 @@ static int mpc8610_hpcd_probe(struct of_device *ofdev,
381 goto error; 379 goto error;
382 } 380 }
383 381
384 /* Find the DMA channels to use. For now, we always use the first DMA 382 /* Find the DMA channels to use. Both SSIs need to use the same DMA
385 controller. */ 383 * controller, so let's use DMA#1.
384 */
386 for_each_compatible_node(dma_np, NULL, "fsl,mpc8610-dma") { 385 for_each_compatible_node(dma_np, NULL, "fsl,mpc8610-dma") {
387 iprop = of_get_property(dma_np, "cell-index", NULL); 386 iprop = of_get_property(dma_np, "cell-index", NULL);
388 if (iprop && (*iprop == 0)) { 387 if (iprop && (*iprop == 0)) {
@@ -397,14 +396,19 @@ static int mpc8610_hpcd_probe(struct of_device *ofdev,
397 } 396 }
398 machine_data->dma_id = *iprop; 397 machine_data->dma_id = *iprop;
399 398
399 /* SSI1 needs to use DMA Channels 0 and 1, and SSI2 needs to use DMA
400 * channels 2 and 3. This is just how the MPC8610 is wired
401 * internally.
402 */
403 playback_dma_channel = (machine_data->ssi_id == 0) ? 0 : 2;
404 capture_dma_channel = (machine_data->ssi_id == 0) ? 1 : 3;
405
400 /* 406 /*
401 * Find the DMA channels to use. For now, we always use DMA channel 0 407 * Find the DMA channels to use.
402 * for playback, and DMA channel 1 for capture.
403 */ 408 */
404 while ((dma_channel_np = of_get_next_child(dma_np, dma_channel_np))) { 409 while ((dma_channel_np = of_get_next_child(dma_np, dma_channel_np))) {
405 iprop = of_get_property(dma_channel_np, "cell-index", NULL); 410 iprop = of_get_property(dma_channel_np, "cell-index", NULL);
406 /* Is it DMA channel 0? */ 411 if (iprop && (*iprop == playback_dma_channel)) {
407 if (iprop && (*iprop == 0)) {
408 /* dma_channel[0] and dma_irq[0] are for playback */ 412 /* dma_channel[0] and dma_irq[0] are for playback */
409 dma_info.dma_channel[0] = of_iomap(dma_channel_np, 0); 413 dma_info.dma_channel[0] = of_iomap(dma_channel_np, 0);
410 dma_info.dma_irq[0] = 414 dma_info.dma_irq[0] =
@@ -412,7 +416,7 @@ static int mpc8610_hpcd_probe(struct of_device *ofdev,
412 machine_data->dma_channel_id[0] = *iprop; 416 machine_data->dma_channel_id[0] = *iprop;
413 continue; 417 continue;
414 } 418 }
415 if (iprop && (*iprop == 1)) { 419 if (iprop && (*iprop == capture_dma_channel)) {
416 /* dma_channel[1] and dma_irq[1] are for capture */ 420 /* dma_channel[1] and dma_irq[1] are for capture */
417 dma_info.dma_channel[1] = of_iomap(dma_channel_np, 0); 421 dma_info.dma_channel[1] = of_iomap(dma_channel_np, 0);
418 dma_info.dma_irq[1] = 422 dma_info.dma_irq[1] =
diff --git a/sound/soc/fsl/soc-of-simple.c b/sound/soc/fsl/soc-of-simple.c
new file mode 100644
index 000000000000..0382fdac51cd
--- /dev/null
+++ b/sound/soc/fsl/soc-of-simple.c
@@ -0,0 +1,171 @@
1/*
2 * OF helpers for ALSA SoC Layer
3 *
4 * Copyright (C) 2008, Secret Lab Technologies Ltd.
5 */
6
7#include <linux/module.h>
8#include <linux/moduleparam.h>
9#include <linux/init.h>
10#include <linux/delay.h>
11#include <linux/pm.h>
12#include <linux/bitops.h>
13#include <linux/platform_device.h>
14#include <linux/of.h>
15#include <sound/core.h>
16#include <sound/pcm.h>
17#include <sound/pcm_params.h>
18#include <sound/soc.h>
19#include <sound/soc-of-simple.h>
20#include <sound/initval.h>
21
22MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
23MODULE_LICENSE("GPL");
24MODULE_DESCRIPTION("ALSA SoC OpenFirmware bindings");
25
26static DEFINE_MUTEX(of_snd_soc_mutex);
27static LIST_HEAD(of_snd_soc_device_list);
28static int of_snd_soc_next_index;
29
30struct of_snd_soc_device {
31 int id;
32 struct list_head list;
33 struct snd_soc_device device;
34 struct snd_soc_machine machine;
35 struct snd_soc_dai_link dai_link;
36 struct platform_device *pdev;
37 struct device_node *platform_node;
38 struct device_node *codec_node;
39};
40
41static struct snd_soc_ops of_snd_soc_ops = {
42};
43
44static struct of_snd_soc_device *
45of_snd_soc_get_device(struct device_node *codec_node)
46{
47 struct of_snd_soc_device *of_soc;
48
49 list_for_each_entry(of_soc, &of_snd_soc_device_list, list) {
50 if (of_soc->codec_node == codec_node)
51 return of_soc;
52 }
53
54 of_soc = kzalloc(sizeof(struct of_snd_soc_device), GFP_KERNEL);
55 if (!of_soc)
56 return NULL;
57
58 /* Initialize the structure and add it to the global list */
59 of_soc->codec_node = codec_node;
60 of_soc->id = of_snd_soc_next_index++;
61 of_soc->machine.dai_link = &of_soc->dai_link;
62 of_soc->machine.num_links = 1;
63 of_soc->device.machine = &of_soc->machine;
64 of_soc->dai_link.ops = &of_snd_soc_ops;
65 list_add(&of_soc->list, &of_snd_soc_device_list);
66
67 return of_soc;
68}
69
70static void of_snd_soc_register_device(struct of_snd_soc_device *of_soc)
71{
72 struct platform_device *pdev;
73 int rc;
74
75 /* Only register the device if both the codec and platform have
76 * been registered */
77 if ((!of_soc->device.codec_data) || (!of_soc->platform_node))
78 return;
79
80 pr_info("platform<-->codec match achieved; registering machine\n");
81
82 pdev = platform_device_alloc("soc-audio", of_soc->id);
83 if (!pdev) {
84 pr_err("of_soc: platform_device_alloc() failed\n");
85 return;
86 }
87
88 pdev->dev.platform_data = of_soc;
89 platform_set_drvdata(pdev, &of_soc->device);
90 of_soc->device.dev = &pdev->dev;
91
92 /* The ASoC device is complete; register it */
93 rc = platform_device_add(pdev);
94 if (rc) {
95 pr_err("of_soc: platform_device_add() failed\n");
96 return;
97 }
98
99}
100
101int of_snd_soc_register_codec(struct snd_soc_codec_device *codec_dev,
102 void *codec_data, struct snd_soc_dai *dai,
103 struct device_node *node)
104{
105 struct of_snd_soc_device *of_soc;
106 int rc = 0;
107
108 pr_info("registering ASoC codec driver: %s\n", node->full_name);
109
110 mutex_lock(&of_snd_soc_mutex);
111 of_soc = of_snd_soc_get_device(node);
112 if (!of_soc) {
113 rc = -ENOMEM;
114 goto out;
115 }
116
117 /* Store the codec data */
118 of_soc->device.codec_data = codec_data;
119 of_soc->device.codec_dev = codec_dev;
120 of_soc->dai_link.name = (char *)node->name;
121 of_soc->dai_link.stream_name = (char *)node->name;
122 of_soc->dai_link.codec_dai = dai;
123
124 /* Now try to register the SoC device */
125 of_snd_soc_register_device(of_soc);
126
127 out:
128 mutex_unlock(&of_snd_soc_mutex);
129 return rc;
130}
131EXPORT_SYMBOL_GPL(of_snd_soc_register_codec);
132
133int of_snd_soc_register_platform(struct snd_soc_platform *platform,
134 struct device_node *node,
135 struct snd_soc_dai *cpu_dai)
136{
137 struct of_snd_soc_device *of_soc;
138 struct device_node *codec_node;
139 const phandle *handle;
140 int len, rc = 0;
141
142 pr_info("registering ASoC platform driver: %s\n", node->full_name);
143
144 handle = of_get_property(node, "codec-handle", &len);
145 if (!handle || len < sizeof(handle))
146 return -ENODEV;
147 codec_node = of_find_node_by_phandle(*handle);
148 if (!codec_node)
149 return -ENODEV;
150 pr_info("looking for codec: %s\n", codec_node->full_name);
151
152 mutex_lock(&of_snd_soc_mutex);
153 of_soc = of_snd_soc_get_device(codec_node);
154 if (!of_soc) {
155 rc = -ENOMEM;
156 goto out;
157 }
158
159 of_soc->platform_node = node;
160 of_soc->dai_link.cpu_dai = cpu_dai;
161 of_soc->device.platform = platform;
162 of_soc->machine.name = of_soc->dai_link.cpu_dai->name;
163
164 /* Now try to register the SoC device */
165 of_snd_soc_register_device(of_soc);
166
167 out:
168 mutex_unlock(&of_snd_soc_mutex);
169 return rc;
170}
171EXPORT_SYMBOL_GPL(of_snd_soc_register_platform);
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
index aea27e70043c..8b7766b998d7 100644
--- a/sound/soc/omap/Kconfig
+++ b/sound/soc/omap/Kconfig
@@ -13,3 +13,11 @@ config SND_OMAP_SOC_N810
13 select SND_SOC_TLV320AIC3X 13 select SND_SOC_TLV320AIC3X
14 help 14 help
15 Say Y if you want to add support for SoC audio on Nokia N810. 15 Say Y if you want to add support for SoC audio on Nokia N810.
16
17config SND_OMAP_SOC_OSK5912
18 tristate "SoC Audio support for omap osk5912"
19 depends on SND_OMAP_SOC && MACH_OMAP_OSK
20 select SND_OMAP_SOC_MCBSP
21 select SND_SOC_TLV320AIC23
22 help
23 Say Y if you want to add support for SoC audio on osk5912.
diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile
index d8d8d58075e3..e09d1f297f64 100644
--- a/sound/soc/omap/Makefile
+++ b/sound/soc/omap/Makefile
@@ -7,5 +7,7 @@ obj-$(CONFIG_SND_OMAP_SOC_MCBSP) += snd-soc-omap-mcbsp.o
7 7
8# OMAP Machine Support 8# OMAP Machine Support
9snd-soc-n810-objs := n810.o 9snd-soc-n810-objs := n810.o
10snd-soc-osk5912-objs := osk5912.o
10 11
11obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o 12obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o
13obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c
index 87d0ed01f65a..fae3ad36e0bf 100644
--- a/sound/soc/omap/n810.c
+++ b/sound/soc/omap/n810.c
@@ -247,9 +247,9 @@ static int n810_aic33_init(struct snd_soc_codec *codec)
247 int i, err; 247 int i, err;
248 248
249 /* Not connected */ 249 /* Not connected */
250 snd_soc_dapm_disable_pin(codec, "MONO_LOUT"); 250 snd_soc_dapm_nc_pin(codec, "MONO_LOUT");
251 snd_soc_dapm_disable_pin(codec, "HPLCOM"); 251 snd_soc_dapm_nc_pin(codec, "HPLCOM");
252 snd_soc_dapm_disable_pin(codec, "HPRCOM"); 252 snd_soc_dapm_nc_pin(codec, "HPRCOM");
253 253
254 /* Add N810 specific controls */ 254 /* Add N810 specific controls */
255 for (i = 0; i < ARRAY_SIZE(aic33_n810_controls); i++) { 255 for (i = 0; i < ARRAY_SIZE(aic33_n810_controls); i++) {
@@ -290,6 +290,7 @@ static struct snd_soc_machine snd_soc_machine_n810 = {
290 290
291/* Audio private data */ 291/* Audio private data */
292static struct aic3x_setup_data n810_aic33_setup = { 292static struct aic3x_setup_data n810_aic33_setup = {
293 .i2c_bus = 2,
293 .i2c_address = 0x18, 294 .i2c_address = 0x18,
294 .gpio_func[0] = AIC3X_GPIO1_FUNC_DISABLED, 295 .gpio_func[0] = AIC3X_GPIO1_FUNC_DISABLED,
295 .gpio_func[1] = AIC3X_GPIO2_FUNC_DIGITAL_MIC_INPUT, 296 .gpio_func[1] = AIC3X_GPIO2_FUNC_DIGITAL_MIC_INPUT,
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index 35310e16d7f3..0a063a98a661 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -59,12 +59,7 @@ static struct omap_mcbsp_data mcbsp_data[NUM_LINKS];
59 * Stream DMA parameters. DMA request line and port address are set runtime 59 * Stream DMA parameters. DMA request line and port address are set runtime
60 * since they are different between OMAP1 and later OMAPs 60 * since they are different between OMAP1 and later OMAPs
61 */ 61 */
62static struct omap_pcm_dma_data omap_mcbsp_dai_dma_params[NUM_LINKS][2] = { 62static struct omap_pcm_dma_data omap_mcbsp_dai_dma_params[NUM_LINKS][2];
63{
64 { .name = "I2S PCM Stereo out", },
65 { .name = "I2S PCM Stereo in", },
66},
67};
68 63
69#if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) 64#if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX)
70static const int omap1_dma_reqs[][2] = { 65static const int omap1_dma_reqs[][2] = {
@@ -84,11 +79,22 @@ static const unsigned long omap1_mcbsp_port[][2] = {
84static const int omap1_dma_reqs[][2] = {}; 79static const int omap1_dma_reqs[][2] = {};
85static const unsigned long omap1_mcbsp_port[][2] = {}; 80static const unsigned long omap1_mcbsp_port[][2] = {};
86#endif 81#endif
87#if defined(CONFIG_ARCH_OMAP2420) 82
88static const int omap2420_dma_reqs[][2] = { 83#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
84static const int omap24xx_dma_reqs[][2] = {
89 { OMAP24XX_DMA_MCBSP1_TX, OMAP24XX_DMA_MCBSP1_RX }, 85 { OMAP24XX_DMA_MCBSP1_TX, OMAP24XX_DMA_MCBSP1_RX },
90 { OMAP24XX_DMA_MCBSP2_TX, OMAP24XX_DMA_MCBSP2_RX }, 86 { OMAP24XX_DMA_MCBSP2_TX, OMAP24XX_DMA_MCBSP2_RX },
87#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX)
88 { OMAP24XX_DMA_MCBSP3_TX, OMAP24XX_DMA_MCBSP3_RX },
89 { OMAP24XX_DMA_MCBSP4_TX, OMAP24XX_DMA_MCBSP4_RX },
90 { OMAP24XX_DMA_MCBSP5_TX, OMAP24XX_DMA_MCBSP5_RX },
91#endif
91}; 92};
93#else
94static const int omap24xx_dma_reqs[][2] = {};
95#endif
96
97#if defined(CONFIG_ARCH_OMAP2420)
92static const unsigned long omap2420_mcbsp_port[][2] = { 98static const unsigned long omap2420_mcbsp_port[][2] = {
93 { OMAP24XX_MCBSP1_BASE + OMAP_MCBSP_REG_DXR1, 99 { OMAP24XX_MCBSP1_BASE + OMAP_MCBSP_REG_DXR1,
94 OMAP24XX_MCBSP1_BASE + OMAP_MCBSP_REG_DRR1 }, 100 OMAP24XX_MCBSP1_BASE + OMAP_MCBSP_REG_DRR1 },
@@ -96,10 +102,43 @@ static const unsigned long omap2420_mcbsp_port[][2] = {
96 OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DRR1 }, 102 OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DRR1 },
97}; 103};
98#else 104#else
99static const int omap2420_dma_reqs[][2] = {};
100static const unsigned long omap2420_mcbsp_port[][2] = {}; 105static const unsigned long omap2420_mcbsp_port[][2] = {};
101#endif 106#endif
102 107
108#if defined(CONFIG_ARCH_OMAP2430)
109static const unsigned long omap2430_mcbsp_port[][2] = {
110 { OMAP24XX_MCBSP1_BASE + OMAP_MCBSP_REG_DXR,
111 OMAP24XX_MCBSP1_BASE + OMAP_MCBSP_REG_DRR },
112 { OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DXR,
113 OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DRR },
114 { OMAP2430_MCBSP3_BASE + OMAP_MCBSP_REG_DXR,
115 OMAP2430_MCBSP3_BASE + OMAP_MCBSP_REG_DRR },
116 { OMAP2430_MCBSP4_BASE + OMAP_MCBSP_REG_DXR,
117 OMAP2430_MCBSP4_BASE + OMAP_MCBSP_REG_DRR },
118 { OMAP2430_MCBSP5_BASE + OMAP_MCBSP_REG_DXR,
119 OMAP2430_MCBSP5_BASE + OMAP_MCBSP_REG_DRR },
120};
121#else
122static const unsigned long omap2430_mcbsp_port[][2] = {};
123#endif
124
125#if defined(CONFIG_ARCH_OMAP34XX)
126static const unsigned long omap34xx_mcbsp_port[][2] = {
127 { OMAP34XX_MCBSP1_BASE + OMAP_MCBSP_REG_DXR,
128 OMAP34XX_MCBSP1_BASE + OMAP_MCBSP_REG_DRR },
129 { OMAP34XX_MCBSP2_BASE + OMAP_MCBSP_REG_DXR,
130 OMAP34XX_MCBSP2_BASE + OMAP_MCBSP_REG_DRR },
131 { OMAP34XX_MCBSP3_BASE + OMAP_MCBSP_REG_DXR,
132 OMAP34XX_MCBSP3_BASE + OMAP_MCBSP_REG_DRR },
133 { OMAP34XX_MCBSP4_BASE + OMAP_MCBSP_REG_DXR,
134 OMAP34XX_MCBSP4_BASE + OMAP_MCBSP_REG_DRR },
135 { OMAP34XX_MCBSP5_BASE + OMAP_MCBSP_REG_DXR,
136 OMAP34XX_MCBSP5_BASE + OMAP_MCBSP_REG_DRR },
137};
138#else
139static const unsigned long omap34xx_mcbsp_port[][2] = {};
140#endif
141
103static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream) 142static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream)
104{ 143{
105 struct snd_soc_pcm_runtime *rtd = substream->private_data; 144 struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -167,14 +206,19 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
167 dma = omap1_dma_reqs[bus_id][substream->stream]; 206 dma = omap1_dma_reqs[bus_id][substream->stream];
168 port = omap1_mcbsp_port[bus_id][substream->stream]; 207 port = omap1_mcbsp_port[bus_id][substream->stream];
169 } else if (cpu_is_omap2420()) { 208 } else if (cpu_is_omap2420()) {
170 dma = omap2420_dma_reqs[bus_id][substream->stream]; 209 dma = omap24xx_dma_reqs[bus_id][substream->stream];
171 port = omap2420_mcbsp_port[bus_id][substream->stream]; 210 port = omap2420_mcbsp_port[bus_id][substream->stream];
211 } else if (cpu_is_omap2430()) {
212 dma = omap24xx_dma_reqs[bus_id][substream->stream];
213 port = omap2430_mcbsp_port[bus_id][substream->stream];
214 } else if (cpu_is_omap343x()) {
215 dma = omap24xx_dma_reqs[bus_id][substream->stream];
216 port = omap34xx_mcbsp_port[bus_id][substream->stream];
172 } else { 217 } else {
173 /*
174 * TODO: Add support for 2430 and 3430
175 */
176 return -ENODEV; 218 return -ENODEV;
177 } 219 }
220 omap_mcbsp_dai_dma_params[id][substream->stream].name =
221 substream->stream ? "Audio Capture" : "Audio Playback";
178 omap_mcbsp_dai_dma_params[id][substream->stream].dma_req = dma; 222 omap_mcbsp_dai_dma_params[id][substream->stream].dma_req = dma;
179 omap_mcbsp_dai_dma_params[id][substream->stream].port_addr = port; 223 omap_mcbsp_dai_dma_params[id][substream->stream].port_addr = port;
180 cpu_dai->dma_data = &omap_mcbsp_dai_dma_params[id][substream->stream]; 224 cpu_dai->dma_data = &omap_mcbsp_dai_dma_params[id][substream->stream];
@@ -245,6 +289,11 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
245 regs->rcr2 |= RDATDLY(1); 289 regs->rcr2 |= RDATDLY(1);
246 regs->xcr2 |= XDATDLY(1); 290 regs->xcr2 |= XDATDLY(1);
247 break; 291 break;
292 case SND_SOC_DAIFMT_DSP_A:
293 /* 0-bit data delay */
294 regs->rcr2 |= RDATDLY(0);
295 regs->xcr2 |= XDATDLY(0);
296 break;
248 default: 297 default:
249 /* Unsupported data format */ 298 /* Unsupported data format */
250 return -EINVAL; 299 return -EINVAL;
@@ -310,7 +359,7 @@ static int omap_mcbsp_dai_set_clks_src(struct omap_mcbsp_data *mcbsp_data,
310 int clk_id) 359 int clk_id)
311{ 360{
312 int sel_bit; 361 int sel_bit;
313 u16 reg; 362 u16 reg, reg_devconf1 = OMAP243X_CONTROL_DEVCONF1;
314 363
315 if (cpu_class_is_omap1()) { 364 if (cpu_class_is_omap1()) {
316 /* OMAP1's can use only external source clock */ 365 /* OMAP1's can use only external source clock */
@@ -320,6 +369,12 @@ static int omap_mcbsp_dai_set_clks_src(struct omap_mcbsp_data *mcbsp_data,
320 return 0; 369 return 0;
321 } 370 }
322 371
372 if (cpu_is_omap2420() && mcbsp_data->bus_id > 1)
373 return -EINVAL;
374
375 if (cpu_is_omap343x())
376 reg_devconf1 = OMAP343X_CONTROL_DEVCONF1;
377
323 switch (mcbsp_data->bus_id) { 378 switch (mcbsp_data->bus_id) {
324 case 0: 379 case 0:
325 reg = OMAP2_CONTROL_DEVCONF0; 380 reg = OMAP2_CONTROL_DEVCONF0;
@@ -329,20 +384,26 @@ static int omap_mcbsp_dai_set_clks_src(struct omap_mcbsp_data *mcbsp_data,
329 reg = OMAP2_CONTROL_DEVCONF0; 384 reg = OMAP2_CONTROL_DEVCONF0;
330 sel_bit = 6; 385 sel_bit = 6;
331 break; 386 break;
332 /* TODO: Support for ports 3 - 5 in OMAP2430 and OMAP34xx */ 387 case 2:
388 reg = reg_devconf1;
389 sel_bit = 0;
390 break;
391 case 3:
392 reg = reg_devconf1;
393 sel_bit = 2;
394 break;
395 case 4:
396 reg = reg_devconf1;
397 sel_bit = 4;
398 break;
333 default: 399 default:
334 return -EINVAL; 400 return -EINVAL;
335 } 401 }
336 402
337 if (cpu_class_is_omap2()) { 403 if (clk_id == OMAP_MCBSP_SYSCLK_CLKS_FCLK)
338 if (clk_id == OMAP_MCBSP_SYSCLK_CLKS_FCLK) { 404 omap_ctrl_writel(omap_ctrl_readl(reg) & ~(1 << sel_bit), reg);
339 omap_ctrl_writel(omap_ctrl_readl(reg) & 405 else
340 ~(1 << sel_bit), reg); 406 omap_ctrl_writel(omap_ctrl_readl(reg) | (1 << sel_bit), reg);
341 } else {
342 omap_ctrl_writel(omap_ctrl_readl(reg) |
343 (1 << sel_bit), reg);
344 }
345 }
346 407
347 return 0; 408 return 0;
348} 409}
@@ -376,37 +437,49 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
376 return err; 437 return err;
377} 438}
378 439
379struct snd_soc_dai omap_mcbsp_dai[NUM_LINKS] = { 440#define OMAP_MCBSP_DAI_BUILDER(link_id) \
380{ 441{ \
381 .name = "omap-mcbsp-dai", 442 .name = "omap-mcbsp-dai-(link_id)", \
382 .id = 0, 443 .id = (link_id), \
383 .type = SND_SOC_DAI_I2S, 444 .type = SND_SOC_DAI_I2S, \
384 .playback = { 445 .playback = { \
385 .channels_min = 2, 446 .channels_min = 2, \
386 .channels_max = 2, 447 .channels_max = 2, \
387 .rates = OMAP_MCBSP_RATES, 448 .rates = OMAP_MCBSP_RATES, \
388 .formats = SNDRV_PCM_FMTBIT_S16_LE, 449 .formats = SNDRV_PCM_FMTBIT_S16_LE, \
389 }, 450 }, \
390 .capture = { 451 .capture = { \
391 .channels_min = 2, 452 .channels_min = 2, \
392 .channels_max = 2, 453 .channels_max = 2, \
393 .rates = OMAP_MCBSP_RATES, 454 .rates = OMAP_MCBSP_RATES, \
394 .formats = SNDRV_PCM_FMTBIT_S16_LE, 455 .formats = SNDRV_PCM_FMTBIT_S16_LE, \
395 }, 456 }, \
396 .ops = { 457 .ops = { \
397 .startup = omap_mcbsp_dai_startup, 458 .startup = omap_mcbsp_dai_startup, \
398 .shutdown = omap_mcbsp_dai_shutdown, 459 .shutdown = omap_mcbsp_dai_shutdown, \
399 .trigger = omap_mcbsp_dai_trigger, 460 .trigger = omap_mcbsp_dai_trigger, \
400 .hw_params = omap_mcbsp_dai_hw_params, 461 .hw_params = omap_mcbsp_dai_hw_params, \
401 }, 462 }, \
402 .dai_ops = { 463 .dai_ops = { \
403 .set_fmt = omap_mcbsp_dai_set_dai_fmt, 464 .set_fmt = omap_mcbsp_dai_set_dai_fmt, \
404 .set_clkdiv = omap_mcbsp_dai_set_clkdiv, 465 .set_clkdiv = omap_mcbsp_dai_set_clkdiv, \
405 .set_sysclk = omap_mcbsp_dai_set_dai_sysclk, 466 .set_sysclk = omap_mcbsp_dai_set_dai_sysclk, \
406 }, 467 }, \
407 .private_data = &mcbsp_data[0].bus_id, 468 .private_data = &mcbsp_data[(link_id)].bus_id, \
408}, 469}
470
471struct snd_soc_dai omap_mcbsp_dai[] = {
472 OMAP_MCBSP_DAI_BUILDER(0),
473 OMAP_MCBSP_DAI_BUILDER(1),
474#if NUM_LINKS >= 3
475 OMAP_MCBSP_DAI_BUILDER(2),
476#endif
477#if NUM_LINKS == 5
478 OMAP_MCBSP_DAI_BUILDER(3),
479 OMAP_MCBSP_DAI_BUILDER(4),
480#endif
409}; 481};
482
410EXPORT_SYMBOL_GPL(omap_mcbsp_dai); 483EXPORT_SYMBOL_GPL(omap_mcbsp_dai);
411 484
412MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@nokia.com>"); 485MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@nokia.com>");
diff --git a/sound/soc/omap/omap-mcbsp.h b/sound/soc/omap/omap-mcbsp.h
index ed8afb550671..df7ad13ba73d 100644
--- a/sound/soc/omap/omap-mcbsp.h
+++ b/sound/soc/omap/omap-mcbsp.h
@@ -38,11 +38,17 @@ enum omap_mcbsp_div {
38 OMAP_MCBSP_CLKGDV, /* Sample rate generator divider */ 38 OMAP_MCBSP_CLKGDV, /* Sample rate generator divider */
39}; 39};
40 40
41/* 41#if defined(CONFIG_ARCH_OMAP2420)
42 * REVISIT: Preparation for the ASoC v2. Let the number of available links to 42#define NUM_LINKS 2
43 * be same than number of McBSP ports found in OMAP(s) we are compiling for. 43#endif
44 */ 44#if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX)
45#define NUM_LINKS 1 45#undef NUM_LINKS
46#define NUM_LINKS 3
47#endif
48#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX)
49#undef NUM_LINKS
50#define NUM_LINKS 5
51#endif
46 52
47extern struct snd_soc_dai omap_mcbsp_dai[NUM_LINKS]; 53extern struct snd_soc_dai omap_mcbsp_dai[NUM_LINKS];
48 54
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c
index 690bfeaec4a0..e9084fdd2082 100644
--- a/sound/soc/omap/omap-pcm.c
+++ b/sound/soc/omap/omap-pcm.c
@@ -97,7 +97,7 @@ static int omap_pcm_hw_params(struct snd_pcm_substream *substream,
97 prtd->dma_data = dma_data; 97 prtd->dma_data = dma_data;
98 err = omap_request_dma(dma_data->dma_req, dma_data->name, 98 err = omap_request_dma(dma_data->dma_req, dma_data->name,
99 omap_pcm_dma_irq, substream, &prtd->dma_ch); 99 omap_pcm_dma_irq, substream, &prtd->dma_ch);
100 if (!cpu_is_omap1510()) { 100 if (!err & !cpu_is_omap1510()) {
101 /* 101 /*
102 * Link channel with itself so DMA doesn't need any 102 * Link channel with itself so DMA doesn't need any
103 * reprogramming while looping the buffer 103 * reprogramming while looping the buffer
@@ -147,12 +147,14 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream)
147 dma_params.src_or_dst_synch = OMAP_DMA_DST_SYNC; 147 dma_params.src_or_dst_synch = OMAP_DMA_DST_SYNC;
148 dma_params.src_start = runtime->dma_addr; 148 dma_params.src_start = runtime->dma_addr;
149 dma_params.dst_start = dma_data->port_addr; 149 dma_params.dst_start = dma_data->port_addr;
150 dma_params.dst_port = OMAP_DMA_PORT_MPUI;
150 } else { 151 } else {
151 dma_params.src_amode = OMAP_DMA_AMODE_CONSTANT; 152 dma_params.src_amode = OMAP_DMA_AMODE_CONSTANT;
152 dma_params.dst_amode = OMAP_DMA_AMODE_POST_INC; 153 dma_params.dst_amode = OMAP_DMA_AMODE_POST_INC;
153 dma_params.src_or_dst_synch = OMAP_DMA_SRC_SYNC; 154 dma_params.src_or_dst_synch = OMAP_DMA_SRC_SYNC;
154 dma_params.src_start = dma_data->port_addr; 155 dma_params.src_start = dma_data->port_addr;
155 dma_params.dst_start = runtime->dma_addr; 156 dma_params.dst_start = runtime->dma_addr;
157 dma_params.src_port = OMAP_DMA_PORT_MPUI;
156 } 158 }
157 /* 159 /*
158 * Set DMA transfer frame size equal to ALSA period size and frame 160 * Set DMA transfer frame size equal to ALSA period size and frame
diff --git a/sound/soc/omap/osk5912.c b/sound/soc/omap/osk5912.c
new file mode 100644
index 000000000000..0fe733796898
--- /dev/null
+++ b/sound/soc/omap/osk5912.c
@@ -0,0 +1,232 @@
1/*
2 * osk5912.c -- SoC audio for OSK 5912
3 *
4 * Copyright (C) 2008 Mistral Solutions
5 *
6 * Contact: Arun KS <arunks@mistralsolutions.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#include <linux/clk.h>
25#include <linux/platform_device.h>
26#include <sound/core.h>
27#include <sound/pcm.h>
28#include <sound/soc.h>
29#include <sound/soc-dapm.h>
30
31#include <asm/mach-types.h>
32#include <mach/hardware.h>
33#include <linux/gpio.h>
34#include <mach/mcbsp.h>
35
36#include "omap-mcbsp.h"
37#include "omap-pcm.h"
38#include "../codecs/tlv320aic23.h"
39
40#define CODEC_CLOCK 12000000
41
42static struct clk *tlv320aic23_mclk;
43
44static int osk_startup(struct snd_pcm_substream *substream)
45{
46 return clk_enable(tlv320aic23_mclk);
47}
48
49static void osk_shutdown(struct snd_pcm_substream *substream)
50{
51 clk_disable(tlv320aic23_mclk);
52}
53
54static int osk_hw_params(struct snd_pcm_substream *substream,
55 struct snd_pcm_hw_params *params)
56{
57 struct snd_soc_pcm_runtime *rtd = substream->private_data;
58 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
59 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
60 int err;
61
62 /* Set codec DAI configuration */
63 err = snd_soc_dai_set_fmt(codec_dai,
64 SND_SOC_DAIFMT_DSP_A |
65 SND_SOC_DAIFMT_NB_IF |
66 SND_SOC_DAIFMT_CBM_CFM);
67 if (err < 0) {
68 printk(KERN_ERR "can't set codec DAI configuration\n");
69 return err;
70 }
71
72 /* Set cpu DAI configuration */
73 err = snd_soc_dai_set_fmt(cpu_dai,
74 SND_SOC_DAIFMT_DSP_A |
75 SND_SOC_DAIFMT_NB_IF |
76 SND_SOC_DAIFMT_CBM_CFM);
77 if (err < 0) {
78 printk(KERN_ERR "can't set cpu DAI configuration\n");
79 return err;
80 }
81
82 /* Set the codec system clock for DAC and ADC */
83 err =
84 snd_soc_dai_set_sysclk(codec_dai, 0, CODEC_CLOCK, SND_SOC_CLOCK_IN);
85
86 if (err < 0) {
87 printk(KERN_ERR "can't set codec system clock\n");
88 return err;
89 }
90
91 return err;
92}
93
94static struct snd_soc_ops osk_ops = {
95 .startup = osk_startup,
96 .hw_params = osk_hw_params,
97 .shutdown = osk_shutdown,
98};
99
100static const struct snd_soc_dapm_widget tlv320aic23_dapm_widgets[] = {
101 SND_SOC_DAPM_HP("Headphone Jack", NULL),
102 SND_SOC_DAPM_LINE("Line In", NULL),
103 SND_SOC_DAPM_MIC("Mic Jack", NULL),
104};
105
106static const struct snd_soc_dapm_route audio_map[] = {
107 {"Headphone Jack", NULL, "LHPOUT"},
108 {"Headphone Jack", NULL, "RHPOUT"},
109
110 {"LLINEIN", NULL, "Line In"},
111 {"RLINEIN", NULL, "Line In"},
112
113 {"MICIN", NULL, "Mic Jack"},
114};
115
116static int osk_tlv320aic23_init(struct snd_soc_codec *codec)
117{
118
119 /* Add osk5912 specific widgets */
120 snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets,
121 ARRAY_SIZE(tlv320aic23_dapm_widgets));
122
123 /* Set up osk5912 specific audio path audio_map */
124 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
125
126 snd_soc_dapm_enable_pin(codec, "Headphone Jack");
127 snd_soc_dapm_enable_pin(codec, "Line In");
128 snd_soc_dapm_enable_pin(codec, "Mic Jack");
129
130 snd_soc_dapm_sync(codec);
131
132 return 0;
133}
134
135/* Digital audio interface glue - connects codec <--> CPU */
136static struct snd_soc_dai_link osk_dai = {
137 .name = "TLV320AIC23",
138 .stream_name = "AIC23",
139 .cpu_dai = &omap_mcbsp_dai[0],
140 .codec_dai = &tlv320aic23_dai,
141 .init = osk_tlv320aic23_init,
142 .ops = &osk_ops,
143};
144
145/* Audio machine driver */
146static struct snd_soc_machine snd_soc_machine_osk = {
147 .name = "OSK5912",
148 .dai_link = &osk_dai,
149 .num_links = 1,
150};
151
152/* Audio subsystem */
153static struct snd_soc_device osk_snd_devdata = {
154 .machine = &snd_soc_machine_osk,
155 .platform = &omap_soc_platform,
156 .codec_dev = &soc_codec_dev_tlv320aic23,
157};
158
159static struct platform_device *osk_snd_device;
160
161static int __init osk_soc_init(void)
162{
163 int err;
164 u32 curRate;
165 struct device *dev;
166
167 if (!(machine_is_omap_osk()))
168 return -ENODEV;
169
170 osk_snd_device = platform_device_alloc("soc-audio", -1);
171 if (!osk_snd_device)
172 return -ENOMEM;
173
174 platform_set_drvdata(osk_snd_device, &osk_snd_devdata);
175 osk_snd_devdata.dev = &osk_snd_device->dev;
176 *(unsigned int *)osk_dai.cpu_dai->private_data = 0; /* McBSP1 */
177 err = platform_device_add(osk_snd_device);
178 if (err)
179 goto err1;
180
181 dev = &osk_snd_device->dev;
182
183 tlv320aic23_mclk = clk_get(dev, "mclk");
184 if (IS_ERR(tlv320aic23_mclk)) {
185 printk(KERN_ERR "Could not get mclk clock\n");
186 return -ENODEV;
187 }
188
189 if (clk_get_usecount(tlv320aic23_mclk) > 0) {
190 /* MCLK is already in use */
191 printk(KERN_WARNING
192 "MCLK in use at %d Hz. We change it to %d Hz\n",
193 (uint) clk_get_rate(tlv320aic23_mclk), CODEC_CLOCK);
194 }
195
196 /*
197 * Configure 12 MHz output on MCLK.
198 */
199 curRate = (uint) clk_get_rate(tlv320aic23_mclk);
200 if (curRate != CODEC_CLOCK) {
201 if (clk_set_rate(tlv320aic23_mclk, CODEC_CLOCK)) {
202 printk(KERN_ERR "Cannot set MCLK for AIC23 CODEC\n");
203 err = -ECANCELED;
204 goto err1;
205 }
206 }
207
208 printk(KERN_INFO "MCLK = %d [%d], usecount = %d\n",
209 (uint) clk_get_rate(tlv320aic23_mclk), CODEC_CLOCK,
210 clk_get_usecount(tlv320aic23_mclk));
211
212 return 0;
213err1:
214 clk_put(tlv320aic23_mclk);
215 platform_device_del(osk_snd_device);
216 platform_device_put(osk_snd_device);
217
218 return err;
219
220}
221
222static void __exit osk_soc_exit(void)
223{
224 platform_device_unregister(osk_snd_device);
225}
226
227module_init(osk_soc_init);
228module_exit(osk_soc_exit);
229
230MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>");
231MODULE_DESCRIPTION("ALSA SoC OSK 5912");
232MODULE_LICENSE("GPL");
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index 9212c37a33b8..f8c1cdd940ac 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -1,6 +1,7 @@
1config SND_PXA2XX_SOC 1config SND_PXA2XX_SOC
2 tristate "SoC Audio for the Intel PXA2xx chip" 2 tristate "SoC Audio for the Intel PXA2xx chip"
3 depends on ARCH_PXA 3 depends on ARCH_PXA
4 select SND_PXA2XX_LIB
4 help 5 help
5 Say Y or M if you want to add support for codecs attached to 6 Say Y or M if you want to add support for codecs attached to
6 the PXA2xx AC97, I2S or SSP interface. You will also need 7 the PXA2xx AC97, I2S or SSP interface. You will also need
@@ -13,6 +14,8 @@ config SND_PXA2XX_AC97
13config SND_PXA2XX_SOC_AC97 14config SND_PXA2XX_SOC_AC97
14 tristate 15 tristate
15 select AC97_BUS 16 select AC97_BUS
17 select SND_ARM
18 select SND_PXA2XX_LIB_AC97
16 select SND_SOC_AC97_BUS 19 select SND_SOC_AC97_BUS
17 20
18config SND_PXA2XX_SOC_I2S 21config SND_PXA2XX_SOC_I2S
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c
index 0a53f72077fd..2718eaf7895f 100644
--- a/sound/soc/pxa/corgi.c
+++ b/sound/soc/pxa/corgi.c
@@ -4,7 +4,7 @@
4 * Copyright 2005 Wolfson Microelectronics PLC. 4 * Copyright 2005 Wolfson Microelectronics PLC.
5 * Copyright 2005 Openedhand Ltd. 5 * Copyright 2005 Openedhand Ltd.
6 * 6 *
7 * Authors: Liam Girdwood <liam.girdwood@wolfsonmicro.com> 7 * Authors: Liam Girdwood <lrg@slimlogic.co.uk>
8 * Richard Purdie <richard@openedhand.com> 8 * Richard Purdie <richard@openedhand.com>
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify it 10 * This program is free software; you can redistribute it and/or modify it
@@ -18,13 +18,13 @@
18#include <linux/timer.h> 18#include <linux/timer.h>
19#include <linux/interrupt.h> 19#include <linux/interrupt.h>
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/gpio.h>
21#include <sound/core.h> 22#include <sound/core.h>
22#include <sound/pcm.h> 23#include <sound/pcm.h>
23#include <sound/soc.h> 24#include <sound/soc.h>
24#include <sound/soc-dapm.h> 25#include <sound/soc-dapm.h>
25 26
26#include <asm/mach-types.h> 27#include <asm/mach-types.h>
27#include <asm/hardware/scoop.h>
28#include <mach/pxa-regs.h> 28#include <mach/pxa-regs.h>
29#include <mach/hardware.h> 29#include <mach/hardware.h>
30#include <mach/corgi.h> 30#include <mach/corgi.h>
@@ -54,8 +54,8 @@ static void corgi_ext_control(struct snd_soc_codec *codec)
54 switch (corgi_jack_func) { 54 switch (corgi_jack_func) {
55 case CORGI_HP: 55 case CORGI_HP:
56 /* set = unmute headphone */ 56 /* set = unmute headphone */
57 set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L); 57 gpio_set_value(CORGI_GPIO_MUTE_L, 1);
58 set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R); 58 gpio_set_value(CORGI_GPIO_MUTE_R, 1);
59 snd_soc_dapm_disable_pin(codec, "Mic Jack"); 59 snd_soc_dapm_disable_pin(codec, "Mic Jack");
60 snd_soc_dapm_disable_pin(codec, "Line Jack"); 60 snd_soc_dapm_disable_pin(codec, "Line Jack");
61 snd_soc_dapm_enable_pin(codec, "Headphone Jack"); 61 snd_soc_dapm_enable_pin(codec, "Headphone Jack");
@@ -63,24 +63,24 @@ static void corgi_ext_control(struct snd_soc_codec *codec)
63 break; 63 break;
64 case CORGI_MIC: 64 case CORGI_MIC:
65 /* reset = mute headphone */ 65 /* reset = mute headphone */
66 reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L); 66 gpio_set_value(CORGI_GPIO_MUTE_L, 0);
67 reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R); 67 gpio_set_value(CORGI_GPIO_MUTE_R, 0);
68 snd_soc_dapm_enable_pin(codec, "Mic Jack"); 68 snd_soc_dapm_enable_pin(codec, "Mic Jack");
69 snd_soc_dapm_disable_pin(codec, "Line Jack"); 69 snd_soc_dapm_disable_pin(codec, "Line Jack");
70 snd_soc_dapm_disable_pin(codec, "Headphone Jack"); 70 snd_soc_dapm_disable_pin(codec, "Headphone Jack");
71 snd_soc_dapm_disable_pin(codec, "Headset Jack"); 71 snd_soc_dapm_disable_pin(codec, "Headset Jack");
72 break; 72 break;
73 case CORGI_LINE: 73 case CORGI_LINE:
74 reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L); 74 gpio_set_value(CORGI_GPIO_MUTE_L, 0);
75 reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R); 75 gpio_set_value(CORGI_GPIO_MUTE_R, 0);
76 snd_soc_dapm_disable_pin(codec, "Mic Jack"); 76 snd_soc_dapm_disable_pin(codec, "Mic Jack");
77 snd_soc_dapm_enable_pin(codec, "Line Jack"); 77 snd_soc_dapm_enable_pin(codec, "Line Jack");
78 snd_soc_dapm_disable_pin(codec, "Headphone Jack"); 78 snd_soc_dapm_disable_pin(codec, "Headphone Jack");
79 snd_soc_dapm_disable_pin(codec, "Headset Jack"); 79 snd_soc_dapm_disable_pin(codec, "Headset Jack");
80 break; 80 break;
81 case CORGI_HEADSET: 81 case CORGI_HEADSET:
82 reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L); 82 gpio_set_value(CORGI_GPIO_MUTE_L, 0);
83 set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R); 83 gpio_set_value(CORGI_GPIO_MUTE_R, 1);
84 snd_soc_dapm_enable_pin(codec, "Mic Jack"); 84 snd_soc_dapm_enable_pin(codec, "Mic Jack");
85 snd_soc_dapm_disable_pin(codec, "Line Jack"); 85 snd_soc_dapm_disable_pin(codec, "Line Jack");
86 snd_soc_dapm_disable_pin(codec, "Headphone Jack"); 86 snd_soc_dapm_disable_pin(codec, "Headphone Jack");
@@ -114,8 +114,8 @@ static int corgi_shutdown(struct snd_pcm_substream *substream)
114 struct snd_soc_codec *codec = rtd->socdev->codec; 114 struct snd_soc_codec *codec = rtd->socdev->codec;
115 115
116 /* set = unmute headphone */ 116 /* set = unmute headphone */
117 set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L); 117 gpio_set_value(CORGI_GPIO_MUTE_L, 1);
118 set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R); 118 gpio_set_value(CORGI_GPIO_MUTE_R, 1);
119 return 0; 119 return 0;
120} 120}
121 121
@@ -218,22 +218,14 @@ static int corgi_set_spk(struct snd_kcontrol *kcontrol,
218static int corgi_amp_event(struct snd_soc_dapm_widget *w, 218static int corgi_amp_event(struct snd_soc_dapm_widget *w,
219 struct snd_kcontrol *k, int event) 219 struct snd_kcontrol *k, int event)
220{ 220{
221 if (SND_SOC_DAPM_EVENT_ON(event)) 221 gpio_set_value(CORGI_GPIO_APM_ON, SND_SOC_DAPM_EVENT_ON(event));
222 set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_APM_ON);
223 else
224 reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_APM_ON);
225
226 return 0; 222 return 0;
227} 223}
228 224
229static int corgi_mic_event(struct snd_soc_dapm_widget *w, 225static int corgi_mic_event(struct snd_soc_dapm_widget *w,
230 struct snd_kcontrol *k, int event) 226 struct snd_kcontrol *k, int event)
231{ 227{
232 if (SND_SOC_DAPM_EVENT_ON(event)) 228 gpio_set_value(CORGI_GPIO_MIC_BIAS, SND_SOC_DAPM_EVENT_ON(event));
233 set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MIC_BIAS);
234 else
235 reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MIC_BIAS);
236
237 return 0; 229 return 0;
238} 230}
239 231
@@ -289,8 +281,8 @@ static int corgi_wm8731_init(struct snd_soc_codec *codec)
289{ 281{
290 int i, err; 282 int i, err;
291 283
292 snd_soc_dapm_disable_pin(codec, "LLINEIN"); 284 snd_soc_dapm_nc_pin(codec, "LLINEIN");
293 snd_soc_dapm_disable_pin(codec, "RLINEIN"); 285 snd_soc_dapm_nc_pin(codec, "RLINEIN");
294 286
295 /* Add corgi specific controls */ 287 /* Add corgi specific controls */
296 for (i = 0; i < ARRAY_SIZE(wm8731_corgi_controls); i++) { 288 for (i = 0; i < ARRAY_SIZE(wm8731_corgi_controls); i++) {
@@ -330,6 +322,7 @@ static struct snd_soc_machine snd_soc_machine_corgi = {
330 322
331/* corgi audio private data */ 323/* corgi audio private data */
332static struct wm8731_setup_data corgi_wm8731_setup = { 324static struct wm8731_setup_data corgi_wm8731_setup = {
325 .i2c_bus = 0,
333 .i2c_address = 0x1b, 326 .i2c_address = 0x1b,
334}; 327};
335 328
diff --git a/sound/soc/pxa/em-x270.c b/sound/soc/pxa/em-x270.c
index d9c3f7b28be2..e6ff6929ab4b 100644
--- a/sound/soc/pxa/em-x270.c
+++ b/sound/soc/pxa/em-x270.c
@@ -9,7 +9,7 @@
9 * Copyright 2005 Wolfson Microelectronics PLC. 9 * Copyright 2005 Wolfson Microelectronics PLC.
10 * Copyright 2005 Openedhand Ltd. 10 * Copyright 2005 Openedhand Ltd.
11 * 11 *
12 * Authors: Liam Girdwood <liam.girdwood@wolfsonmicro.com> 12 * Authors: Liam Girdwood <lrg@slimlogic.co.uk>
13 * Richard Purdie <richard@openedhand.com> 13 * Richard Purdie <richard@openedhand.com>
14 * 14 *
15 * This program is free software; you can redistribute it and/or modify it 15 * This program is free software; you can redistribute it and/or modify it
diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c
index a4697f7e2921..4d9930c52789 100644
--- a/sound/soc/pxa/poodle.c
+++ b/sound/soc/pxa/poodle.c
@@ -4,7 +4,7 @@
4 * Copyright 2005 Wolfson Microelectronics PLC. 4 * Copyright 2005 Wolfson Microelectronics PLC.
5 * Copyright 2005 Openedhand Ltd. 5 * Copyright 2005 Openedhand Ltd.
6 * 6 *
7 * Authors: Liam Girdwood <liam.girdwood@wolfsonmicro.com> 7 * Authors: Liam Girdwood <lrg@slimlogic.co.uk>
8 * Richard Purdie <richard@openedhand.com> 8 * Richard Purdie <richard@openedhand.com>
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify it 10 * This program is free software; you can redistribute it and/or modify it
@@ -242,8 +242,8 @@ static int poodle_wm8731_init(struct snd_soc_codec *codec)
242{ 242{
243 int i, err; 243 int i, err;
244 244
245 snd_soc_dapm_disable_pin(codec, "LLINEIN"); 245 snd_soc_dapm_nc_pin(codec, "LLINEIN");
246 snd_soc_dapm_disable_pin(codec, "RLINEIN"); 246 snd_soc_dapm_nc_pin(codec, "RLINEIN");
247 snd_soc_dapm_enable_pin(codec, "MICIN"); 247 snd_soc_dapm_enable_pin(codec, "MICIN");
248 248
249 /* Add poodle specific controls */ 249 /* Add poodle specific controls */
@@ -284,6 +284,7 @@ static struct snd_soc_machine snd_soc_machine_poodle = {
284 284
285/* poodle audio private data */ 285/* poodle audio private data */
286static struct wm8731_setup_data poodle_wm8731_setup = { 286static struct wm8731_setup_data poodle_wm8731_setup = {
287 .i2c_bus = 0,
287 .i2c_address = 0x1b, 288 .i2c_address = 0x1b,
288}; 289};
289 290
diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c
index d94a495bd6bd..a7a3a9c5c6ff 100644
--- a/sound/soc/pxa/pxa2xx-ac97.c
+++ b/sound/soc/pxa/pxa2xx-ac97.c
@@ -13,225 +13,30 @@
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/platform_device.h> 15#include <linux/platform_device.h>
16#include <linux/interrupt.h>
17#include <linux/wait.h>
18#include <linux/clk.h>
19#include <linux/delay.h>
20 16
21#include <sound/core.h> 17#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/ac97_codec.h> 18#include <sound/ac97_codec.h>
24#include <sound/initval.h>
25#include <sound/soc.h> 19#include <sound/soc.h>
20#include <sound/pxa2xx-lib.h>
26 21
27#include <asm/irq.h>
28#include <linux/mutex.h>
29#include <mach/hardware.h> 22#include <mach/hardware.h>
30#include <mach/pxa-regs.h> 23#include <mach/pxa-regs.h>
31#include <mach/pxa2xx-gpio.h>
32#include <mach/audio.h>
33 24
34#include "pxa2xx-pcm.h" 25#include "pxa2xx-pcm.h"
35#include "pxa2xx-ac97.h" 26#include "pxa2xx-ac97.h"
36 27
37static DEFINE_MUTEX(car_mutex);
38static DECLARE_WAIT_QUEUE_HEAD(gsr_wq);
39static volatile long gsr_bits;
40static struct clk *ac97_clk;
41#ifdef CONFIG_PXA27x
42static struct clk *ac97conf_clk;
43#endif
44
45/*
46 * Beware PXA27x bugs:
47 *
48 * o Slot 12 read from modem space will hang controller.
49 * o CDONE, SDONE interrupt fails after any slot 12 IO.
50 *
51 * We therefore have an hybrid approach for waiting on SDONE (interrupt or
52 * 1 jiffy timeout if interrupt never comes).
53 */
54
55static unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97,
56 unsigned short reg)
57{
58 unsigned short val = -1;
59 volatile u32 *reg_addr;
60
61 mutex_lock(&car_mutex);
62
63 /* set up primary or secondary codec/modem space */
64#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
65 reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE;
66#else
67 if (reg == AC97_GPIO_STATUS)
68 reg_addr = ac97->num ? &SMC_REG_BASE : &PMC_REG_BASE;
69 else
70 reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE;
71#endif
72 reg_addr += (reg >> 1);
73
74#ifndef CONFIG_PXA27x
75 if (reg == AC97_GPIO_STATUS) {
76 /* read from controller cache */
77 val = *reg_addr;
78 goto out;
79 }
80#endif
81
82 /* start read access across the ac97 link */
83 GSR = GSR_CDONE | GSR_SDONE;
84 gsr_bits = 0;
85 val = *reg_addr;
86
87 wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1);
88 if (!((GSR | gsr_bits) & GSR_SDONE)) {
89 printk(KERN_ERR "%s: read error (ac97_reg=%x GSR=%#lx)\n",
90 __func__, reg, GSR | gsr_bits);
91 val = -1;
92 goto out;
93 }
94
95 /* valid data now */
96 GSR = GSR_CDONE | GSR_SDONE;
97 gsr_bits = 0;
98 val = *reg_addr;
99 /* but we've just started another cycle... */
100 wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1);
101
102out: mutex_unlock(&car_mutex);
103 return val;
104}
105
106static void pxa2xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
107 unsigned short val)
108{
109 volatile u32 *reg_addr;
110
111 mutex_lock(&car_mutex);
112
113 /* set up primary or secondary codec/modem space */
114#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
115 reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE;
116#else
117 if (reg == AC97_GPIO_STATUS)
118 reg_addr = ac97->num ? &SMC_REG_BASE : &PMC_REG_BASE;
119 else
120 reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE;
121#endif
122 reg_addr += (reg >> 1);
123
124 GSR = GSR_CDONE | GSR_SDONE;
125 gsr_bits = 0;
126 *reg_addr = val;
127 wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_CDONE, 1);
128 if (!((GSR | gsr_bits) & GSR_CDONE))
129 printk(KERN_ERR "%s: write error (ac97_reg=%x GSR=%#lx)\n",
130 __func__, reg, GSR | gsr_bits);
131
132 mutex_unlock(&car_mutex);
133}
134
135static void pxa2xx_ac97_warm_reset(struct snd_ac97 *ac97) 28static void pxa2xx_ac97_warm_reset(struct snd_ac97 *ac97)
136{ 29{
137#ifdef CONFIG_PXA3xx 30 pxa2xx_ac97_try_warm_reset(ac97);
138 int timeout = 100;
139#endif
140 gsr_bits = 0;
141
142#ifdef CONFIG_PXA27x
143 /* warm reset broken on Bulverde,
144 so manually keep AC97 reset high */
145 pxa_gpio_mode(113 | GPIO_OUT | GPIO_DFLT_HIGH);
146 udelay(10);
147 GCR |= GCR_WARM_RST;
148 pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT);
149 udelay(500);
150#elif defined(CONFIG_PXA3xx)
151 /* Can't use interrupts */
152 GCR |= GCR_WARM_RST;
153 while (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR)) && timeout--)
154 mdelay(1);
155#else
156 GCR |= GCR_WARM_RST | GCR_PRIRDY_IEN | GCR_SECRDY_IEN;
157 wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1);
158#endif
159
160 if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR)))
161 printk(KERN_INFO "%s: warm reset timeout (GSR=%#lx)\n",
162 __func__, gsr_bits);
163 31
164 GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN); 32 pxa2xx_ac97_finish_reset(ac97);
165 GCR |= GCR_SDONE_IE|GCR_CDONE_IE;
166} 33}
167 34
168static void pxa2xx_ac97_cold_reset(struct snd_ac97 *ac97) 35static void pxa2xx_ac97_cold_reset(struct snd_ac97 *ac97)
169{ 36{
170#ifdef CONFIG_PXA3xx 37 pxa2xx_ac97_try_cold_reset(ac97);
171 int timeout = 1000;
172
173 /* Hold CLKBPB for 100us */
174 GCR = 0;
175 GCR = GCR_CLKBPB;
176 udelay(100);
177 GCR = 0;
178#endif
179 38
180 GCR &= GCR_COLD_RST; /* clear everything but nCRST */ 39 pxa2xx_ac97_finish_reset(ac97);
181 GCR &= ~GCR_COLD_RST; /* then assert nCRST */
182
183 gsr_bits = 0;
184#ifdef CONFIG_PXA27x
185 /* PXA27x Developers Manual section 13.5.2.2.1 */
186 clk_enable(ac97conf_clk);
187 udelay(5);
188 clk_disable(ac97conf_clk);
189 GCR = GCR_COLD_RST;
190 udelay(50);
191#elif defined(CONFIG_PXA3xx)
192 /* Can't use interrupts on PXA3xx */
193 GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN);
194
195 GCR = GCR_WARM_RST | GCR_COLD_RST;
196 while (!(GSR & (GSR_PCR | GSR_SCR)) && timeout--)
197 mdelay(10);
198#else
199 GCR = GCR_COLD_RST;
200 GCR |= GCR_CDONE_IE|GCR_SDONE_IE;
201 wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1);
202#endif
203
204 if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR)))
205 printk(KERN_INFO "%s: cold reset timeout (GSR=%#lx)\n",
206 __func__, gsr_bits);
207
208 GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN);
209 GCR |= GCR_SDONE_IE|GCR_CDONE_IE;
210}
211
212static irqreturn_t pxa2xx_ac97_irq(int irq, void *dev_id)
213{
214 long status;
215
216 status = GSR;
217 if (status) {
218 GSR = status;
219 gsr_bits |= status;
220 wake_up(&gsr_wq);
221
222#ifdef CONFIG_PXA27x
223 /* Although we don't use those we still need to clear them
224 since they tend to spuriously trigger when MMC is used
225 (hardware bug? go figure)... */
226 MISR = MISR_EOC;
227 PISR = PISR_EOC;
228 MCSR = MCSR_EOC;
229#endif
230
231 return IRQ_HANDLED;
232 }
233
234 return IRQ_NONE;
235} 40}
236 41
237struct snd_ac97_bus_ops soc_ac97_ops = { 42struct snd_ac97_bus_ops soc_ac97_ops = {
@@ -244,7 +49,7 @@ struct snd_ac97_bus_ops soc_ac97_ops = {
244static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_out = { 49static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_out = {
245 .name = "AC97 PCM Stereo out", 50 .name = "AC97 PCM Stereo out",
246 .dev_addr = __PREG(PCDR), 51 .dev_addr = __PREG(PCDR),
247 .drcmr = &DRCMRTXPCDR, 52 .drcmr = &DRCMR(12),
248 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG | 53 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
249 DCMD_BURST32 | DCMD_WIDTH4, 54 DCMD_BURST32 | DCMD_WIDTH4,
250}; 55};
@@ -252,7 +57,7 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_out = {
252static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_in = { 57static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_in = {
253 .name = "AC97 PCM Stereo in", 58 .name = "AC97 PCM Stereo in",
254 .dev_addr = __PREG(PCDR), 59 .dev_addr = __PREG(PCDR),
255 .drcmr = &DRCMRRXPCDR, 60 .drcmr = &DRCMR(11),
256 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | 61 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
257 DCMD_BURST32 | DCMD_WIDTH4, 62 DCMD_BURST32 | DCMD_WIDTH4,
258}; 63};
@@ -260,7 +65,7 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_in = {
260static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_aux_mono_out = { 65static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_aux_mono_out = {
261 .name = "AC97 Aux PCM (Slot 5) Mono out", 66 .name = "AC97 Aux PCM (Slot 5) Mono out",
262 .dev_addr = __PREG(MODR), 67 .dev_addr = __PREG(MODR),
263 .drcmr = &DRCMRTXMODR, 68 .drcmr = &DRCMR(10),
264 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG | 69 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
265 DCMD_BURST16 | DCMD_WIDTH2, 70 DCMD_BURST16 | DCMD_WIDTH2,
266}; 71};
@@ -268,7 +73,7 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_aux_mono_out = {
268static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_aux_mono_in = { 73static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_aux_mono_in = {
269 .name = "AC97 Aux PCM (Slot 5) Mono in", 74 .name = "AC97 Aux PCM (Slot 5) Mono in",
270 .dev_addr = __PREG(MODR), 75 .dev_addr = __PREG(MODR),
271 .drcmr = &DRCMRRXMODR, 76 .drcmr = &DRCMR(9),
272 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | 77 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
273 DCMD_BURST16 | DCMD_WIDTH2, 78 DCMD_BURST16 | DCMD_WIDTH2,
274}; 79};
@@ -276,7 +81,7 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_aux_mono_in = {
276static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_mic_mono_in = { 81static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_mic_mono_in = {
277 .name = "AC97 Mic PCM (Slot 6) Mono in", 82 .name = "AC97 Mic PCM (Slot 6) Mono in",
278 .dev_addr = __PREG(MCDR), 83 .dev_addr = __PREG(MCDR),
279 .drcmr = &DRCMRRXMCDR, 84 .drcmr = &DRCMR(8),
280 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | 85 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
281 DCMD_BURST16 | DCMD_WIDTH2, 86 DCMD_BURST16 | DCMD_WIDTH2,
282}; 87};
@@ -285,24 +90,13 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_mic_mono_in = {
285static int pxa2xx_ac97_suspend(struct platform_device *pdev, 90static int pxa2xx_ac97_suspend(struct platform_device *pdev,
286 struct snd_soc_dai *dai) 91 struct snd_soc_dai *dai)
287{ 92{
288 GCR |= GCR_ACLINK_OFF; 93 return pxa2xx_ac97_hw_suspend();
289 clk_disable(ac97_clk);
290 return 0;
291} 94}
292 95
293static int pxa2xx_ac97_resume(struct platform_device *pdev, 96static int pxa2xx_ac97_resume(struct platform_device *pdev,
294 struct snd_soc_dai *dai) 97 struct snd_soc_dai *dai)
295{ 98{
296 pxa_gpio_mode(GPIO31_SYNC_AC97_MD); 99 return pxa2xx_ac97_hw_resume();
297 pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD);
298 pxa_gpio_mode(GPIO28_BITCLK_AC97_MD);
299 pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD);
300#ifdef CONFIG_PXA27x
301 /* Use GPIO 113 as AC97 Reset on Bulverde */
302 pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT);
303#endif
304 clk_enable(ac97_clk);
305 return 0;
306} 100}
307 101
308#else 102#else
@@ -313,61 +107,13 @@ static int pxa2xx_ac97_resume(struct platform_device *pdev,
313static int pxa2xx_ac97_probe(struct platform_device *pdev, 107static int pxa2xx_ac97_probe(struct platform_device *pdev,
314 struct snd_soc_dai *dai) 108 struct snd_soc_dai *dai)
315{ 109{
316 int ret; 110 return pxa2xx_ac97_hw_probe(pdev);
317
318 ret = request_irq(IRQ_AC97, pxa2xx_ac97_irq, IRQF_DISABLED, "AC97", NULL);
319 if (ret < 0)
320 goto err;
321
322 pxa_gpio_mode(GPIO31_SYNC_AC97_MD);
323 pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD);
324 pxa_gpio_mode(GPIO28_BITCLK_AC97_MD);
325 pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD);
326#ifdef CONFIG_PXA27x
327 /* Use GPIO 113 as AC97 Reset on Bulverde */
328 pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT);
329
330 ac97conf_clk = clk_get(&pdev->dev, "AC97CONFCLK");
331 if (IS_ERR(ac97conf_clk)) {
332 ret = PTR_ERR(ac97conf_clk);
333 ac97conf_clk = NULL;
334 goto err_irq;
335 }
336#endif
337 ac97_clk = clk_get(&pdev->dev, "AC97CLK");
338 if (IS_ERR(ac97_clk)) {
339 ret = PTR_ERR(ac97_clk);
340 ac97_clk = NULL;
341 goto err_irq;
342 }
343 clk_enable(ac97_clk);
344 return 0;
345
346 err_irq:
347 GCR |= GCR_ACLINK_OFF;
348#ifdef CONFIG_PXA27x
349 if (ac97conf_clk) {
350 clk_put(ac97conf_clk);
351 ac97conf_clk = NULL;
352 }
353#endif
354 free_irq(IRQ_AC97, NULL);
355 err:
356 return ret;
357} 111}
358 112
359static void pxa2xx_ac97_remove(struct platform_device *pdev, 113static void pxa2xx_ac97_remove(struct platform_device *pdev,
360 struct snd_soc_dai *dai) 114 struct snd_soc_dai *dai)
361{ 115{
362 GCR |= GCR_ACLINK_OFF; 116 pxa2xx_ac97_hw_remove(pdev);
363 free_irq(IRQ_AC97, NULL);
364#ifdef CONFIG_PXA27x
365 clk_put(ac97conf_clk);
366 ac97conf_clk = NULL;
367#endif
368 clk_disable(ac97_clk);
369 clk_put(ac97_clk);
370 ac97_clk = NULL;
371} 117}
372 118
373static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream, 119static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream,
diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c
index c796b1882776..e758034db5c3 100644
--- a/sound/soc/pxa/pxa2xx-i2s.c
+++ b/sound/soc/pxa/pxa2xx-i2s.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright 2005 Wolfson Microelectronics PLC. 4 * Copyright 2005 Wolfson Microelectronics PLC.
5 * Author: Liam Girdwood 5 * Author: Liam Girdwood
6 * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com 6 * lrg@slimlogic.co.uk
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
@@ -21,6 +21,7 @@
21#include <sound/pcm.h> 21#include <sound/pcm.h>
22#include <sound/initval.h> 22#include <sound/initval.h>
23#include <sound/soc.h> 23#include <sound/soc.h>
24#include <sound/pxa2xx-lib.h>
24 25
25#include <mach/hardware.h> 26#include <mach/hardware.h>
26#include <mach/pxa-regs.h> 27#include <mach/pxa-regs.h>
@@ -30,6 +31,54 @@
30#include "pxa2xx-pcm.h" 31#include "pxa2xx-pcm.h"
31#include "pxa2xx-i2s.h" 32#include "pxa2xx-i2s.h"
32 33
34struct pxa2xx_gpio {
35 u32 sys;
36 u32 rx;
37 u32 tx;
38 u32 clk;
39 u32 frm;
40};
41
42/*
43 * I2S Controller Register and Bit Definitions
44 */
45#define SACR0 __REG(0x40400000) /* Global Control Register */
46#define SACR1 __REG(0x40400004) /* Serial Audio I 2 S/MSB-Justified Control Register */
47#define SASR0 __REG(0x4040000C) /* Serial Audio I 2 S/MSB-Justified Interface and FIFO Status Register */
48#define SAIMR __REG(0x40400014) /* Serial Audio Interrupt Mask Register */
49#define SAICR __REG(0x40400018) /* Serial Audio Interrupt Clear Register */
50#define SADIV __REG(0x40400060) /* Audio Clock Divider Register. */
51#define SADR __REG(0x40400080) /* Serial Audio Data Register (TX and RX FIFO access Register). */
52
53#define SACR0_RFTH(x) ((x) << 12) /* Rx FIFO Interrupt or DMA Trigger Threshold */
54#define SACR0_TFTH(x) ((x) << 8) /* Tx FIFO Interrupt or DMA Trigger Threshold */
55#define SACR0_STRF (1 << 5) /* FIFO Select for EFWR Special Function */
56#define SACR0_EFWR (1 << 4) /* Enable EFWR Function */
57#define SACR0_RST (1 << 3) /* FIFO, i2s Register Reset */
58#define SACR0_BCKD (1 << 2) /* Bit Clock Direction */
59#define SACR0_ENB (1 << 0) /* Enable I2S Link */
60#define SACR1_ENLBF (1 << 5) /* Enable Loopback */
61#define SACR1_DRPL (1 << 4) /* Disable Replaying Function */
62#define SACR1_DREC (1 << 3) /* Disable Recording Function */
63#define SACR1_AMSL (1 << 0) /* Specify Alternate Mode */
64
65#define SASR0_I2SOFF (1 << 7) /* Controller Status */
66#define SASR0_ROR (1 << 6) /* Rx FIFO Overrun */
67#define SASR0_TUR (1 << 5) /* Tx FIFO Underrun */
68#define SASR0_RFS (1 << 4) /* Rx FIFO Service Request */
69#define SASR0_TFS (1 << 3) /* Tx FIFO Service Request */
70#define SASR0_BSY (1 << 2) /* I2S Busy */
71#define SASR0_RNE (1 << 1) /* Rx FIFO Not Empty */
72#define SASR0_TNF (1 << 0) /* Tx FIFO Not Empty */
73
74#define SAICR_ROR (1 << 6) /* Clear Rx FIFO Overrun Interrupt */
75#define SAICR_TUR (1 << 5) /* Clear Tx FIFO Underrun Interrupt */
76
77#define SAIMR_ROR (1 << 6) /* Enable Rx FIFO Overrun Condition Interrupt */
78#define SAIMR_TUR (1 << 5) /* Enable Tx FIFO Underrun Condition Interrupt */
79#define SAIMR_RFS (1 << 4) /* Enable Rx FIFO Service Interrupt */
80#define SAIMR_TFS (1 << 3) /* Enable Tx FIFO Service Interrupt */
81
33struct pxa_i2s_port { 82struct pxa_i2s_port {
34 u32 sadiv; 83 u32 sadiv;
35 u32 sacr0; 84 u32 sacr0;
@@ -44,7 +93,7 @@ static struct clk *clk_i2s;
44static struct pxa2xx_pcm_dma_params pxa2xx_i2s_pcm_stereo_out = { 93static struct pxa2xx_pcm_dma_params pxa2xx_i2s_pcm_stereo_out = {
45 .name = "I2S PCM Stereo out", 94 .name = "I2S PCM Stereo out",
46 .dev_addr = __PREG(SADR), 95 .dev_addr = __PREG(SADR),
47 .drcmr = &DRCMRTXSADR, 96 .drcmr = &DRCMR(3),
48 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG | 97 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
49 DCMD_BURST32 | DCMD_WIDTH4, 98 DCMD_BURST32 | DCMD_WIDTH4,
50}; 99};
@@ -52,7 +101,7 @@ static struct pxa2xx_pcm_dma_params pxa2xx_i2s_pcm_stereo_out = {
52static struct pxa2xx_pcm_dma_params pxa2xx_i2s_pcm_stereo_in = { 101static struct pxa2xx_pcm_dma_params pxa2xx_i2s_pcm_stereo_in = {
53 .name = "I2S PCM Stereo in", 102 .name = "I2S PCM Stereo in",
54 .dev_addr = __PREG(SADR), 103 .dev_addr = __PREG(SADR),
55 .drcmr = &DRCMRRXSADR, 104 .drcmr = &DRCMR(2),
56 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | 105 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
57 DCMD_BURST32 | DCMD_WIDTH4, 106 DCMD_BURST32 | DCMD_WIDTH4,
58}; 107};
@@ -65,11 +114,6 @@ static struct pxa2xx_gpio gpio_bus[] = {
65 .frm = GPIO31_SYNC_I2S_MD, 114 .frm = GPIO31_SYNC_I2S_MD,
66 }, 115 },
67 { /* I2S SoC Master */ 116 { /* I2S SoC Master */
68#ifdef CONFIG_PXA27x
69 .sys = GPIO113_I2S_SYSCLK_MD,
70#else
71 .sys = GPIO32_SYSCLK_I2S_MD,
72#endif
73 .rx = GPIO29_SDATA_IN_I2S_MD, 117 .rx = GPIO29_SDATA_IN_I2S_MD,
74 .tx = GPIO30_SDATA_OUT_I2S_MD, 118 .tx = GPIO30_SDATA_OUT_I2S_MD,
75 .clk = GPIO28_BITCLK_OUT_I2S_MD, 119 .clk = GPIO28_BITCLK_OUT_I2S_MD,
@@ -343,6 +387,11 @@ static struct platform_driver pxa2xx_i2s_driver = {
343 387
344static int __init pxa2xx_i2s_init(void) 388static int __init pxa2xx_i2s_init(void)
345{ 389{
390 if (cpu_is_pxa27x())
391 gpio_bus[1].sys = GPIO113_I2S_SYSCLK_MD;
392 else
393 gpio_bus[1].sys = GPIO32_SYSCLK_I2S_MD;
394
346 clk_i2s = ERR_PTR(-ENOENT); 395 clk_i2s = ERR_PTR(-ENOENT);
347 return platform_driver_register(&pxa2xx_i2s_driver); 396 return platform_driver_register(&pxa2xx_i2s_driver);
348} 397}
@@ -356,6 +405,6 @@ module_init(pxa2xx_i2s_init);
356module_exit(pxa2xx_i2s_exit); 405module_exit(pxa2xx_i2s_exit);
357 406
358/* Module information */ 407/* Module information */
359MODULE_AUTHOR("Liam Girdwood, liam.girdwood@wolfsonmicro.com, www.wolfsonmicro.com"); 408MODULE_AUTHOR("Liam Girdwood, lrg@slimlogic.co.uk");
360MODULE_DESCRIPTION("pxa2xx I2S SoC Interface"); 409MODULE_DESCRIPTION("pxa2xx I2S SoC Interface");
361MODULE_LICENSE("GPL"); 410MODULE_LICENSE("GPL");
diff --git a/sound/soc/pxa/pxa2xx-pcm.c b/sound/soc/pxa/pxa2xx-pcm.c
index 4345f387fe41..afcd892cd2fa 100644
--- a/sound/soc/pxa/pxa2xx-pcm.c
+++ b/sound/soc/pxa/pxa2xx-pcm.c
@@ -10,64 +10,14 @@
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11 */ 11 */
12 12
13#include <linux/module.h>
14#include <linux/init.h>
15#include <linux/platform_device.h>
16#include <linux/slab.h>
17#include <linux/dma-mapping.h> 13#include <linux/dma-mapping.h>
18 14
19#include <sound/core.h> 15#include <sound/core.h>
20#include <sound/pcm.h>
21#include <sound/pcm_params.h>
22#include <sound/soc.h> 16#include <sound/soc.h>
23 17#include <sound/pxa2xx-lib.h>
24#include <asm/dma.h>
25#include <mach/hardware.h>
26#include <mach/pxa-regs.h>
27#include <mach/audio.h>
28 18
29#include "pxa2xx-pcm.h" 19#include "pxa2xx-pcm.h"
30 20#include "../../arm/pxa2xx-pcm.h"
31static const struct snd_pcm_hardware pxa2xx_pcm_hardware = {
32 .info = SNDRV_PCM_INFO_MMAP |
33 SNDRV_PCM_INFO_MMAP_VALID |
34 SNDRV_PCM_INFO_INTERLEAVED |
35 SNDRV_PCM_INFO_PAUSE |
36 SNDRV_PCM_INFO_RESUME,
37 .formats = SNDRV_PCM_FMTBIT_S16_LE |
38 SNDRV_PCM_FMTBIT_S24_LE |
39 SNDRV_PCM_FMTBIT_S32_LE,
40 .period_bytes_min = 32,
41 .period_bytes_max = 8192 - 32,
42 .periods_min = 1,
43 .periods_max = PAGE_SIZE/sizeof(pxa_dma_desc),
44 .buffer_bytes_max = 128 * 1024,
45 .fifo_size = 32,
46};
47
48struct pxa2xx_runtime_data {
49 int dma_ch;
50 struct pxa2xx_pcm_dma_params *params;
51 pxa_dma_desc *dma_desc_array;
52 dma_addr_t dma_desc_array_phys;
53};
54
55static void pxa2xx_pcm_dma_irq(int dma_ch, void *dev_id)
56{
57 struct snd_pcm_substream *substream = dev_id;
58 struct pxa2xx_runtime_data *prtd = substream->runtime->private_data;
59 int dcsr;
60
61 dcsr = DCSR(dma_ch);
62 DCSR(dma_ch) = dcsr & ~DCSR_STOPIRQEN;
63
64 if (dcsr & DCSR_ENDINTR) {
65 snd_pcm_period_elapsed(substream);
66 } else {
67 printk(KERN_ERR "%s: DMA error on channel %d (DCSR=%#x)\n",
68 prtd->params->name, dma_ch, dcsr);
69 }
70}
71 21
72static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream, 22static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
73 struct snd_pcm_hw_params *params) 23 struct snd_pcm_hw_params *params)
@@ -76,10 +26,6 @@ static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
76 struct pxa2xx_runtime_data *prtd = runtime->private_data; 26 struct pxa2xx_runtime_data *prtd = runtime->private_data;
77 struct snd_soc_pcm_runtime *rtd = substream->private_data; 27 struct snd_soc_pcm_runtime *rtd = substream->private_data;
78 struct pxa2xx_pcm_dma_params *dma = rtd->dai->cpu_dai->dma_data; 28 struct pxa2xx_pcm_dma_params *dma = rtd->dai->cpu_dai->dma_data;
79 size_t totsize = params_buffer_bytes(params);
80 size_t period = params_period_bytes(params);
81 pxa_dma_desc *dma_desc;
82 dma_addr_t dma_buff_phys, next_desc_phys;
83 int ret; 29 int ret;
84 30
85 /* return if this is a bufferless transfer e.g. 31 /* return if this is a bufferless transfer e.g.
@@ -106,42 +52,16 @@ static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
106 prtd->dma_ch = ret; 52 prtd->dma_ch = ret;
107 } 53 }
108 54
109 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); 55 return __pxa2xx_pcm_hw_params(substream, params);
110 runtime->dma_bytes = totsize;
111
112 dma_desc = prtd->dma_desc_array;
113 next_desc_phys = prtd->dma_desc_array_phys;
114 dma_buff_phys = runtime->dma_addr;
115 do {
116 next_desc_phys += sizeof(pxa_dma_desc);
117 dma_desc->ddadr = next_desc_phys;
118 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
119 dma_desc->dsadr = dma_buff_phys;
120 dma_desc->dtadr = prtd->params->dev_addr;
121 } else {
122 dma_desc->dsadr = prtd->params->dev_addr;
123 dma_desc->dtadr = dma_buff_phys;
124 }
125 if (period > totsize)
126 period = totsize;
127 dma_desc->dcmd = prtd->params->dcmd | period | DCMD_ENDIRQEN;
128 dma_desc++;
129 dma_buff_phys += period;
130 } while (totsize -= period);
131 dma_desc[-1].ddadr = prtd->dma_desc_array_phys;
132
133 return 0;
134} 56}
135 57
136static int pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream) 58static int pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream)
137{ 59{
138 struct pxa2xx_runtime_data *prtd = substream->runtime->private_data; 60 struct pxa2xx_runtime_data *prtd = substream->runtime->private_data;
139 61
140 if (prtd && prtd->params) 62 __pxa2xx_pcm_hw_free(substream);
141 *prtd->params->drcmr = 0;
142 63
143 if (prtd->dma_ch) { 64 if (prtd->dma_ch) {
144 snd_pcm_set_runtime_buffer(substream, NULL);
145 pxa_free_dma(prtd->dma_ch); 65 pxa_free_dma(prtd->dma_ch);
146 prtd->dma_ch = 0; 66 prtd->dma_ch = 0;
147 } 67 }
@@ -149,188 +69,21 @@ static int pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream)
149 return 0; 69 return 0;
150} 70}
151 71
152static int pxa2xx_pcm_prepare(struct snd_pcm_substream *substream)
153{
154 struct pxa2xx_runtime_data *prtd = substream->runtime->private_data;
155
156 DCSR(prtd->dma_ch) &= ~DCSR_RUN;
157 DCSR(prtd->dma_ch) = 0;
158 DCMD(prtd->dma_ch) = 0;
159 *prtd->params->drcmr = prtd->dma_ch | DRCMR_MAPVLD;
160
161 return 0;
162}
163
164static int pxa2xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
165{
166 struct pxa2xx_runtime_data *prtd = substream->runtime->private_data;
167 int ret = 0;
168
169 switch (cmd) {
170 case SNDRV_PCM_TRIGGER_START:
171 DDADR(prtd->dma_ch) = prtd->dma_desc_array_phys;
172 DCSR(prtd->dma_ch) = DCSR_RUN;
173 break;
174
175 case SNDRV_PCM_TRIGGER_STOP:
176 case SNDRV_PCM_TRIGGER_SUSPEND:
177 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
178 DCSR(prtd->dma_ch) &= ~DCSR_RUN;
179 break;
180
181 case SNDRV_PCM_TRIGGER_RESUME:
182 DCSR(prtd->dma_ch) |= DCSR_RUN;
183 break;
184 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
185 DDADR(prtd->dma_ch) = prtd->dma_desc_array_phys;
186 DCSR(prtd->dma_ch) |= DCSR_RUN;
187 break;
188
189 default:
190 ret = -EINVAL;
191 }
192
193 return ret;
194}
195
196static snd_pcm_uframes_t
197pxa2xx_pcm_pointer(struct snd_pcm_substream *substream)
198{
199 struct snd_pcm_runtime *runtime = substream->runtime;
200 struct pxa2xx_runtime_data *prtd = runtime->private_data;
201
202 dma_addr_t ptr = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
203 DSADR(prtd->dma_ch) : DTADR(prtd->dma_ch);
204 snd_pcm_uframes_t x = bytes_to_frames(runtime, ptr - runtime->dma_addr);
205
206 if (x == runtime->buffer_size)
207 x = 0;
208 return x;
209}
210
211static int pxa2xx_pcm_open(struct snd_pcm_substream *substream)
212{
213 struct snd_pcm_runtime *runtime = substream->runtime;
214 struct pxa2xx_runtime_data *prtd;
215 int ret;
216
217 snd_soc_set_runtime_hwparams(substream, &pxa2xx_pcm_hardware);
218
219 /*
220 * For mysterious reasons (and despite what the manual says)
221 * playback samples are lost if the DMA count is not a multiple
222 * of the DMA burst size. Let's add a rule to enforce that.
223 */
224 ret = snd_pcm_hw_constraint_step(runtime, 0,
225 SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32);
226 if (ret)
227 goto out;
228
229 ret = snd_pcm_hw_constraint_step(runtime, 0,
230 SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 32);
231 if (ret)
232 goto out;
233
234 ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
235 if (ret < 0)
236 goto out;
237
238 prtd = kzalloc(sizeof(struct pxa2xx_runtime_data), GFP_KERNEL);
239 if (prtd == NULL) {
240 ret = -ENOMEM;
241 goto out;
242 }
243
244 prtd->dma_desc_array =
245 dma_alloc_writecombine(substream->pcm->card->dev, PAGE_SIZE,
246 &prtd->dma_desc_array_phys, GFP_KERNEL);
247 if (!prtd->dma_desc_array) {
248 ret = -ENOMEM;
249 goto err1;
250 }
251
252 runtime->private_data = prtd;
253 return 0;
254
255 err1:
256 kfree(prtd);
257 out:
258 return ret;
259}
260
261static int pxa2xx_pcm_close(struct snd_pcm_substream *substream)
262{
263 struct snd_pcm_runtime *runtime = substream->runtime;
264 struct pxa2xx_runtime_data *prtd = runtime->private_data;
265
266 dma_free_writecombine(substream->pcm->card->dev, PAGE_SIZE,
267 prtd->dma_desc_array, prtd->dma_desc_array_phys);
268 kfree(prtd);
269 return 0;
270}
271
272static int pxa2xx_pcm_mmap(struct snd_pcm_substream *substream,
273 struct vm_area_struct *vma)
274{
275 struct snd_pcm_runtime *runtime = substream->runtime;
276 return dma_mmap_writecombine(substream->pcm->card->dev, vma,
277 runtime->dma_area,
278 runtime->dma_addr,
279 runtime->dma_bytes);
280}
281
282struct snd_pcm_ops pxa2xx_pcm_ops = { 72struct snd_pcm_ops pxa2xx_pcm_ops = {
283 .open = pxa2xx_pcm_open, 73 .open = __pxa2xx_pcm_open,
284 .close = pxa2xx_pcm_close, 74 .close = __pxa2xx_pcm_close,
285 .ioctl = snd_pcm_lib_ioctl, 75 .ioctl = snd_pcm_lib_ioctl,
286 .hw_params = pxa2xx_pcm_hw_params, 76 .hw_params = pxa2xx_pcm_hw_params,
287 .hw_free = pxa2xx_pcm_hw_free, 77 .hw_free = pxa2xx_pcm_hw_free,
288 .prepare = pxa2xx_pcm_prepare, 78 .prepare = __pxa2xx_pcm_prepare,
289 .trigger = pxa2xx_pcm_trigger, 79 .trigger = pxa2xx_pcm_trigger,
290 .pointer = pxa2xx_pcm_pointer, 80 .pointer = pxa2xx_pcm_pointer,
291 .mmap = pxa2xx_pcm_mmap, 81 .mmap = pxa2xx_pcm_mmap,
292}; 82};
293 83
294static int pxa2xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
295{
296 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
297 struct snd_dma_buffer *buf = &substream->dma_buffer;
298 size_t size = pxa2xx_pcm_hardware.buffer_bytes_max;
299 buf->dev.type = SNDRV_DMA_TYPE_DEV;
300 buf->dev.dev = pcm->card->dev;
301 buf->private_data = NULL;
302 buf->area = dma_alloc_writecombine(pcm->card->dev, size,
303 &buf->addr, GFP_KERNEL);
304 if (!buf->area)
305 return -ENOMEM;
306 buf->bytes = size;
307 return 0;
308}
309
310static void pxa2xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
311{
312 struct snd_pcm_substream *substream;
313 struct snd_dma_buffer *buf;
314 int stream;
315
316 for (stream = 0; stream < 2; stream++) {
317 substream = pcm->streams[stream].substream;
318 if (!substream)
319 continue;
320
321 buf = &substream->dma_buffer;
322 if (!buf->area)
323 continue;
324
325 dma_free_writecombine(pcm->card->dev, buf->bytes,
326 buf->area, buf->addr);
327 buf->area = NULL;
328 }
329}
330
331static u64 pxa2xx_pcm_dmamask = DMA_32BIT_MASK; 84static u64 pxa2xx_pcm_dmamask = DMA_32BIT_MASK;
332 85
333int pxa2xx_pcm_new(struct snd_card *card, struct snd_soc_dai *dai, 86static int pxa2xx_soc_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
334 struct snd_pcm *pcm) 87 struct snd_pcm *pcm)
335{ 88{
336 int ret = 0; 89 int ret = 0;
@@ -360,7 +113,7 @@ int pxa2xx_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
360struct snd_soc_platform pxa2xx_soc_platform = { 113struct snd_soc_platform pxa2xx_soc_platform = {
361 .name = "pxa2xx-audio", 114 .name = "pxa2xx-audio",
362 .pcm_ops = &pxa2xx_pcm_ops, 115 .pcm_ops = &pxa2xx_pcm_ops,
363 .pcm_new = pxa2xx_pcm_new, 116 .pcm_new = pxa2xx_soc_pcm_new,
364 .pcm_free = pxa2xx_pcm_free_dma_buffers, 117 .pcm_free = pxa2xx_pcm_free_dma_buffers,
365}; 118};
366EXPORT_SYMBOL_GPL(pxa2xx_soc_platform); 119EXPORT_SYMBOL_GPL(pxa2xx_soc_platform);
diff --git a/sound/soc/pxa/pxa2xx-pcm.h b/sound/soc/pxa/pxa2xx-pcm.h
index 54c9c755e508..60c3b20aeeb4 100644
--- a/sound/soc/pxa/pxa2xx-pcm.h
+++ b/sound/soc/pxa/pxa2xx-pcm.h
@@ -13,21 +13,6 @@
13#ifndef _PXA2XX_PCM_H 13#ifndef _PXA2XX_PCM_H
14#define _PXA2XX_PCM_H 14#define _PXA2XX_PCM_H
15 15
16struct pxa2xx_pcm_dma_params {
17 char *name; /* stream identifier */
18 u32 dcmd; /* DMA descriptor dcmd field */
19 volatile u32 *drcmr; /* the DMA request channel to use */
20 u32 dev_addr; /* device physical address for DMA */
21};
22
23struct pxa2xx_gpio {
24 u32 sys;
25 u32 rx;
26 u32 tx;
27 u32 clk;
28 u32 frm;
29};
30
31/* platform data */ 16/* platform data */
32extern struct snd_soc_platform pxa2xx_soc_platform; 17extern struct snd_soc_platform pxa2xx_soc_platform;
33 18
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c
index 37cb768fc933..d307b6757e95 100644
--- a/sound/soc/pxa/spitz.c
+++ b/sound/soc/pxa/spitz.c
@@ -4,7 +4,7 @@
4 * Copyright 2005 Wolfson Microelectronics PLC. 4 * Copyright 2005 Wolfson Microelectronics PLC.
5 * Copyright 2005 Openedhand Ltd. 5 * Copyright 2005 Openedhand Ltd.
6 * 6 *
7 * Authors: Liam Girdwood <liam.girdwood@wolfsonmicro.com> 7 * Authors: Liam Girdwood <lrg@slimlogic.co.uk>
8 * Richard Purdie <richard@openedhand.com> 8 * Richard Purdie <richard@openedhand.com>
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify it 10 * This program is free software; you can redistribute it and/or modify it
@@ -19,16 +19,15 @@
19#include <linux/timer.h> 19#include <linux/timer.h>
20#include <linux/interrupt.h> 20#include <linux/interrupt.h>
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/gpio.h>
22#include <sound/core.h> 23#include <sound/core.h>
23#include <sound/pcm.h> 24#include <sound/pcm.h>
24#include <sound/soc.h> 25#include <sound/soc.h>
25#include <sound/soc-dapm.h> 26#include <sound/soc-dapm.h>
26 27
27#include <asm/mach-types.h> 28#include <asm/mach-types.h>
28#include <asm/hardware/scoop.h>
29#include <mach/pxa-regs.h> 29#include <mach/pxa-regs.h>
30#include <mach/hardware.h> 30#include <mach/hardware.h>
31#include <mach/akita.h>
32#include <mach/spitz.h> 31#include <mach/spitz.h>
33#include "../codecs/wm8750.h" 32#include "../codecs/wm8750.h"
34#include "pxa2xx-pcm.h" 33#include "pxa2xx-pcm.h"
@@ -63,8 +62,8 @@ static void spitz_ext_control(struct snd_soc_codec *codec)
63 snd_soc_dapm_disable_pin(codec, "Mic Jack"); 62 snd_soc_dapm_disable_pin(codec, "Mic Jack");
64 snd_soc_dapm_disable_pin(codec, "Line Jack"); 63 snd_soc_dapm_disable_pin(codec, "Line Jack");
65 snd_soc_dapm_enable_pin(codec, "Headphone Jack"); 64 snd_soc_dapm_enable_pin(codec, "Headphone Jack");
66 set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L); 65 gpio_set_value(SPITZ_GPIO_MUTE_L, 1);
67 set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R); 66 gpio_set_value(SPITZ_GPIO_MUTE_R, 1);
68 break; 67 break;
69 case SPITZ_MIC: 68 case SPITZ_MIC:
70 /* enable mic jack and bias, mute hp */ 69 /* enable mic jack and bias, mute hp */
@@ -72,8 +71,8 @@ static void spitz_ext_control(struct snd_soc_codec *codec)
72 snd_soc_dapm_disable_pin(codec, "Headset Jack"); 71 snd_soc_dapm_disable_pin(codec, "Headset Jack");
73 snd_soc_dapm_disable_pin(codec, "Line Jack"); 72 snd_soc_dapm_disable_pin(codec, "Line Jack");
74 snd_soc_dapm_enable_pin(codec, "Mic Jack"); 73 snd_soc_dapm_enable_pin(codec, "Mic Jack");
75 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L); 74 gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
76 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R); 75 gpio_set_value(SPITZ_GPIO_MUTE_R, 0);
77 break; 76 break;
78 case SPITZ_LINE: 77 case SPITZ_LINE:
79 /* enable line jack, disable mic bias and mute hp */ 78 /* enable line jack, disable mic bias and mute hp */
@@ -81,8 +80,8 @@ static void spitz_ext_control(struct snd_soc_codec *codec)
81 snd_soc_dapm_disable_pin(codec, "Headset Jack"); 80 snd_soc_dapm_disable_pin(codec, "Headset Jack");
82 snd_soc_dapm_disable_pin(codec, "Mic Jack"); 81 snd_soc_dapm_disable_pin(codec, "Mic Jack");
83 snd_soc_dapm_enable_pin(codec, "Line Jack"); 82 snd_soc_dapm_enable_pin(codec, "Line Jack");
84 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L); 83 gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
85 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R); 84 gpio_set_value(SPITZ_GPIO_MUTE_R, 0);
86 break; 85 break;
87 case SPITZ_HEADSET: 86 case SPITZ_HEADSET:
88 /* enable and unmute headset jack enable mic bias, mute L hp */ 87 /* enable and unmute headset jack enable mic bias, mute L hp */
@@ -90,8 +89,8 @@ static void spitz_ext_control(struct snd_soc_codec *codec)
90 snd_soc_dapm_enable_pin(codec, "Mic Jack"); 89 snd_soc_dapm_enable_pin(codec, "Mic Jack");
91 snd_soc_dapm_disable_pin(codec, "Line Jack"); 90 snd_soc_dapm_disable_pin(codec, "Line Jack");
92 snd_soc_dapm_enable_pin(codec, "Headset Jack"); 91 snd_soc_dapm_enable_pin(codec, "Headset Jack");
93 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L); 92 gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
94 set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R); 93 gpio_set_value(SPITZ_GPIO_MUTE_R, 1);
95 break; 94 break;
96 case SPITZ_HP_OFF: 95 case SPITZ_HP_OFF:
97 96
@@ -100,8 +99,8 @@ static void spitz_ext_control(struct snd_soc_codec *codec)
100 snd_soc_dapm_disable_pin(codec, "Headset Jack"); 99 snd_soc_dapm_disable_pin(codec, "Headset Jack");
101 snd_soc_dapm_disable_pin(codec, "Mic Jack"); 100 snd_soc_dapm_disable_pin(codec, "Mic Jack");
102 snd_soc_dapm_disable_pin(codec, "Line Jack"); 101 snd_soc_dapm_disable_pin(codec, "Line Jack");
103 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L); 102 gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
104 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R); 103 gpio_set_value(SPITZ_GPIO_MUTE_R, 0);
105 break; 104 break;
106 } 105 }
107 snd_soc_dapm_sync(codec); 106 snd_soc_dapm_sync(codec);
@@ -215,23 +214,14 @@ static int spitz_set_spk(struct snd_kcontrol *kcontrol,
215static int spitz_mic_bias(struct snd_soc_dapm_widget *w, 214static int spitz_mic_bias(struct snd_soc_dapm_widget *w,
216 struct snd_kcontrol *k, int event) 215 struct snd_kcontrol *k, int event)
217{ 216{
218 if (machine_is_borzoi() || machine_is_spitz()) { 217 if (machine_is_borzoi() || machine_is_spitz())
219 if (SND_SOC_DAPM_EVENT_ON(event)) 218 gpio_set_value(SPITZ_GPIO_MIC_BIAS,
220 set_scoop_gpio(&spitzscoop2_device.dev, 219 SND_SOC_DAPM_EVENT_ON(event));
221 SPITZ_SCP2_MIC_BIAS); 220
222 else 221 if (machine_is_akita())
223 reset_scoop_gpio(&spitzscoop2_device.dev, 222 gpio_set_value(AKITA_GPIO_MIC_BIAS,
224 SPITZ_SCP2_MIC_BIAS); 223 SND_SOC_DAPM_EVENT_ON(event));
225 }
226 224
227 if (machine_is_akita()) {
228 if (SND_SOC_DAPM_EVENT_ON(event))
229 akita_set_ioexp(&akitaioexp_device.dev,
230 AKITA_IOEXP_MIC_BIAS);
231 else
232 akita_reset_ioexp(&akitaioexp_device.dev,
233 AKITA_IOEXP_MIC_BIAS);
234 }
235 return 0; 225 return 0;
236} 226}
237 227
@@ -291,13 +281,13 @@ static int spitz_wm8750_init(struct snd_soc_codec *codec)
291 int i, err; 281 int i, err;
292 282
293 /* NC codec pins */ 283 /* NC codec pins */
294 snd_soc_dapm_disable_pin(codec, "RINPUT1"); 284 snd_soc_dapm_nc_pin(codec, "RINPUT1");
295 snd_soc_dapm_disable_pin(codec, "LINPUT2"); 285 snd_soc_dapm_nc_pin(codec, "LINPUT2");
296 snd_soc_dapm_disable_pin(codec, "RINPUT2"); 286 snd_soc_dapm_nc_pin(codec, "RINPUT2");
297 snd_soc_dapm_disable_pin(codec, "LINPUT3"); 287 snd_soc_dapm_nc_pin(codec, "LINPUT3");
298 snd_soc_dapm_disable_pin(codec, "RINPUT3"); 288 snd_soc_dapm_nc_pin(codec, "RINPUT3");
299 snd_soc_dapm_disable_pin(codec, "OUT3"); 289 snd_soc_dapm_nc_pin(codec, "OUT3");
300 snd_soc_dapm_disable_pin(codec, "MONO1"); 290 snd_soc_dapm_nc_pin(codec, "MONO1");
301 291
302 /* Add spitz specific controls */ 292 /* Add spitz specific controls */
303 for (i = 0; i < ARRAY_SIZE(wm8750_spitz_controls); i++) { 293 for (i = 0; i < ARRAY_SIZE(wm8750_spitz_controls); i++) {
@@ -337,6 +327,7 @@ static struct snd_soc_machine snd_soc_machine_spitz = {
337 327
338/* spitz audio private data */ 328/* spitz audio private data */
339static struct wm8750_setup_data spitz_wm8750_setup = { 329static struct wm8750_setup_data spitz_wm8750_setup = {
330 .i2c_bus = 0,
340 .i2c_address = 0x1b, 331 .i2c_address = 0x1b,
341}; 332};
342 333
diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c
index 2baaa750f123..afefe41b8c46 100644
--- a/sound/soc/pxa/tosa.c
+++ b/sound/soc/pxa/tosa.c
@@ -4,7 +4,7 @@
4 * Copyright 2005 Wolfson Microelectronics PLC. 4 * Copyright 2005 Wolfson Microelectronics PLC.
5 * Copyright 2005 Openedhand Ltd. 5 * Copyright 2005 Openedhand Ltd.
6 * 6 *
7 * Authors: Liam Girdwood <liam.girdwood@wolfsonmicro.com> 7 * Authors: Liam Girdwood <lrg@slimlogic.co.uk>
8 * Richard Purdie <richard@openedhand.com> 8 * Richard Purdie <richard@openedhand.com>
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify it 10 * This program is free software; you can redistribute it and/or modify it
@@ -190,8 +190,8 @@ static int tosa_ac97_init(struct snd_soc_codec *codec)
190{ 190{
191 int i, err; 191 int i, err;
192 192
193 snd_soc_dapm_disable_pin(codec, "OUT3"); 193 snd_soc_dapm_nc_pin(codec, "OUT3");
194 snd_soc_dapm_disable_pin(codec, "MONOOUT"); 194 snd_soc_dapm_nc_pin(codec, "MONOOUT");
195 195
196 /* add tosa specific controls */ 196 /* add tosa specific controls */
197 for (i = 0; i < ARRAY_SIZE(tosa_controls); i++) { 197 for (i = 0; i < ARRAY_SIZE(tosa_controls); i++) {
diff --git a/sound/soc/s3c24xx/neo1973_wm8753.c b/sound/soc/s3c24xx/neo1973_wm8753.c
index 8089f8ee05c0..87ddfefcc2fb 100644
--- a/sound/soc/s3c24xx/neo1973_wm8753.c
+++ b/sound/soc/s3c24xx/neo1973_wm8753.c
@@ -24,6 +24,7 @@
24#include <sound/soc-dapm.h> 24#include <sound/soc-dapm.h>
25#include <sound/tlv.h> 25#include <sound/tlv.h>
26 26
27#include <asm/mach-types.h>
27#include <asm/hardware/scoop.h> 28#include <asm/hardware/scoop.h>
28#include <mach/regs-clock.h> 29#include <mach/regs-clock.h>
29#include <mach/regs-gpio.h> 30#include <mach/regs-gpio.h>
@@ -510,21 +511,20 @@ static int neo1973_wm8753_init(struct snd_soc_codec *codec)
510 DBG("Entered %s\n", __func__); 511 DBG("Entered %s\n", __func__);
511 512
512 /* set up NC codec pins */ 513 /* set up NC codec pins */
513 snd_soc_dapm_disable_pin(codec, "LOUT2"); 514 snd_soc_dapm_nc_pin(codec, "LOUT2");
514 snd_soc_dapm_disable_pin(codec, "ROUT2"); 515 snd_soc_dapm_nc_pin(codec, "ROUT2");
515 snd_soc_dapm_disable_pin(codec, "OUT3"); 516 snd_soc_dapm_nc_pin(codec, "OUT3");
516 snd_soc_dapm_disable_pin(codec, "OUT4"); 517 snd_soc_dapm_nc_pin(codec, "OUT4");
517 snd_soc_dapm_disable_pin(codec, "LINE1"); 518 snd_soc_dapm_nc_pin(codec, "LINE1");
518 snd_soc_dapm_disable_pin(codec, "LINE2"); 519 snd_soc_dapm_nc_pin(codec, "LINE2");
519
520
521 /* set endpoints to default mode */
522 set_scenario_endpoints(codec, NEO_AUDIO_OFF);
523 520
524 /* Add neo1973 specific widgets */ 521 /* Add neo1973 specific widgets */
525 snd_soc_dapm_new_controls(codec, wm8753_dapm_widgets, 522 snd_soc_dapm_new_controls(codec, wm8753_dapm_widgets,
526 ARRAY_SIZE(wm8753_dapm_widgets)); 523 ARRAY_SIZE(wm8753_dapm_widgets));
527 524
525 /* set endpoints to default mode */
526 set_scenario_endpoints(codec, NEO_AUDIO_OFF);
527
528 /* add neo1973 specific controls */ 528 /* add neo1973 specific controls */
529 for (i = 0; i < ARRAY_SIZE(wm8753_neo1973_controls); i++) { 529 for (i = 0; i < ARRAY_SIZE(wm8753_neo1973_controls); i++) {
530 err = snd_ctl_add(codec->card, 530 err = snd_ctl_add(codec->card,
@@ -586,6 +586,7 @@ static struct snd_soc_machine neo1973 = {
586}; 586};
587 587
588static struct wm8753_setup_data neo1973_wm8753_setup = { 588static struct wm8753_setup_data neo1973_wm8753_setup = {
589 .i2c_bus = 0,
589 .i2c_address = 0x1a, 590 .i2c_address = 0x1a,
590}; 591};
591 592
@@ -596,54 +597,24 @@ static struct snd_soc_device neo1973_snd_devdata = {
596 .codec_data = &neo1973_wm8753_setup, 597 .codec_data = &neo1973_wm8753_setup,
597}; 598};
598 599
599static struct i2c_client client_template; 600static int lm4857_i2c_probe(struct i2c_client *client,
600 601 const struct i2c_device_id *id)
601static const unsigned short normal_i2c[] = { 0x7C, I2C_CLIENT_END };
602
603/* Magic definition of all other variables and things */
604I2C_CLIENT_INSMOD;
605
606static int lm4857_amp_probe(struct i2c_adapter *adap, int addr, int kind)
607{ 602{
608 int ret;
609
610 DBG("Entered %s\n", __func__); 603 DBG("Entered %s\n", __func__);
611 604
612 client_template.adapter = adap; 605 i2c = client;
613 client_template.addr = addr;
614
615 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
616 if (i2c == NULL)
617 return -ENOMEM;
618
619 ret = i2c_attach_client(i2c);
620 if (ret < 0) {
621 printk(KERN_ERR "LM4857 failed to attach at addr %x\n", addr);
622 goto exit_err;
623 }
624 606
625 lm4857_write_regs(); 607 lm4857_write_regs();
626 return ret;
627
628exit_err:
629 kfree(i2c);
630 return ret;
631}
632
633static int lm4857_i2c_detach(struct i2c_client *client)
634{
635 DBG("Entered %s\n", __func__);
636
637 i2c_detach_client(client);
638 kfree(client);
639 return 0; 608 return 0;
640} 609}
641 610
642static int lm4857_i2c_attach(struct i2c_adapter *adap) 611static int lm4857_i2c_remove(struct i2c_client *client)
643{ 612{
644 DBG("Entered %s\n", __func__); 613 DBG("Entered %s\n", __func__);
645 614
646 return i2c_probe(adap, &addr_data, lm4857_amp_probe); 615 i2c = NULL;
616
617 return 0;
647} 618}
648 619
649static u8 lm4857_state; 620static u8 lm4857_state;
@@ -681,24 +652,22 @@ static void lm4857_shutdown(struct i2c_client *dev)
681 lm4857_write_regs(); 652 lm4857_write_regs();
682} 653}
683 654
684/* corgi i2c codec control layer */ 655static const struct i2c_device_id lm4857_i2c_id[] = {
656 { "neo1973_lm4857", 0 },
657 { }
658};
659
685static struct i2c_driver lm4857_i2c_driver = { 660static struct i2c_driver lm4857_i2c_driver = {
686 .driver = { 661 .driver = {
687 .name = "LM4857 I2C Amp", 662 .name = "LM4857 I2C Amp",
688 .owner = THIS_MODULE, 663 .owner = THIS_MODULE,
689 }, 664 },
690 .id = I2C_DRIVERID_LM4857,
691 .suspend = lm4857_suspend, 665 .suspend = lm4857_suspend,
692 .resume = lm4857_resume, 666 .resume = lm4857_resume,
693 .shutdown = lm4857_shutdown, 667 .shutdown = lm4857_shutdown,
694 .attach_adapter = lm4857_i2c_attach, 668 .probe = lm4857_i2c_probe,
695 .detach_client = lm4857_i2c_detach, 669 .remove = lm4857_i2c_remove,
696 .command = NULL, 670 .id_table = lm4857_i2c_id,
697};
698
699static struct i2c_client client_template = {
700 .name = "LM4857",
701 .driver = &lm4857_i2c_driver,
702}; 671};
703 672
704static struct platform_device *neo1973_snd_device; 673static struct platform_device *neo1973_snd_device;
@@ -709,6 +678,12 @@ static int __init neo1973_init(void)
709 678
710 DBG("Entered %s\n", __func__); 679 DBG("Entered %s\n", __func__);
711 680
681 if (!machine_is_neo1973_gta01()) {
682 printk(KERN_INFO
683 "Only GTA01 hardware supported by ASoC driver\n");
684 return -ENODEV;
685 }
686
712 neo1973_snd_device = platform_device_alloc("soc-audio", -1); 687 neo1973_snd_device = platform_device_alloc("soc-audio", -1);
713 if (!neo1973_snd_device) 688 if (!neo1973_snd_device)
714 return -ENOMEM; 689 return -ENOMEM;
@@ -717,12 +692,15 @@ static int __init neo1973_init(void)
717 neo1973_snd_devdata.dev = &neo1973_snd_device->dev; 692 neo1973_snd_devdata.dev = &neo1973_snd_device->dev;
718 ret = platform_device_add(neo1973_snd_device); 693 ret = platform_device_add(neo1973_snd_device);
719 694
720 if (ret) 695 if (ret) {
721 platform_device_put(neo1973_snd_device); 696 platform_device_put(neo1973_snd_device);
697 return ret;
698 }
722 699
723 ret = i2c_add_driver(&lm4857_i2c_driver); 700 ret = i2c_add_driver(&lm4857_i2c_driver);
701
724 if (ret != 0) 702 if (ret != 0)
725 printk(KERN_ERR "can't add i2c driver"); 703 platform_device_unregister(neo1973_snd_device);
726 704
727 return ret; 705 return ret;
728} 706}
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 83f1190293a8..462e635dfc74 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -4,8 +4,7 @@
4 * Copyright 2005 Wolfson Microelectronics PLC. 4 * Copyright 2005 Wolfson Microelectronics PLC.
5 * Copyright 2005 Openedhand Ltd. 5 * Copyright 2005 Openedhand Ltd.
6 * 6 *
7 * Author: Liam Girdwood 7 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
8 * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
9 * with code, comments and ideas from :- 8 * with code, comments and ideas from :-
10 * Richard Purdie <richard@openedhand.com> 9 * Richard Purdie <richard@openedhand.com>
11 * 10 *
@@ -340,6 +339,12 @@ static int soc_codec_close(struct snd_pcm_substream *substream)
340 } 339 }
341 codec->active--; 340 codec->active--;
342 341
342 /* Muting the DAC suppresses artifacts caused during digital
343 * shutdown, for example from stopping clocks.
344 */
345 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
346 snd_soc_dai_digital_mute(codec_dai, 1);
347
343 if (cpu_dai->ops.shutdown) 348 if (cpu_dai->ops.shutdown)
344 cpu_dai->ops.shutdown(substream); 349 cpu_dai->ops.shutdown(substream);
345 350
@@ -970,9 +975,29 @@ static ssize_t codec_reg_show(struct device *dev,
970 step = codec->reg_cache_step; 975 step = codec->reg_cache_step;
971 976
972 count += sprintf(buf, "%s registers\n", codec->name); 977 count += sprintf(buf, "%s registers\n", codec->name);
973 for (i = 0; i < codec->reg_cache_size; i += step) 978 for (i = 0; i < codec->reg_cache_size; i += step) {
974 count += sprintf(buf + count, "%2x: %4x\n", i, 979 count += sprintf(buf + count, "%2x: ", i);
975 codec->read(codec, i)); 980 if (count >= PAGE_SIZE - 1)
981 break;
982
983 if (codec->display_register)
984 count += codec->display_register(codec, buf + count,
985 PAGE_SIZE - count, i);
986 else
987 count += snprintf(buf + count, PAGE_SIZE - count,
988 "%4x", codec->read(codec, i));
989
990 if (count >= PAGE_SIZE - 1)
991 break;
992
993 count += snprintf(buf + count, PAGE_SIZE - count, "\n");
994 if (count >= PAGE_SIZE - 1)
995 break;
996 }
997
998 /* Truncate count; min() would cause a warning */
999 if (count >= PAGE_SIZE)
1000 count = PAGE_SIZE - 1;
976 1001
977 return count; 1002 return count;
978} 1003}
@@ -1296,10 +1321,10 @@ int snd_soc_info_enum_double(struct snd_kcontrol *kcontrol,
1296 1321
1297 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 1322 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1298 uinfo->count = e->shift_l == e->shift_r ? 1 : 2; 1323 uinfo->count = e->shift_l == e->shift_r ? 1 : 2;
1299 uinfo->value.enumerated.items = e->mask; 1324 uinfo->value.enumerated.items = e->max;
1300 1325
1301 if (uinfo->value.enumerated.item > e->mask - 1) 1326 if (uinfo->value.enumerated.item > e->max - 1)
1302 uinfo->value.enumerated.item = e->mask - 1; 1327 uinfo->value.enumerated.item = e->max - 1;
1303 strcpy(uinfo->value.enumerated.name, 1328 strcpy(uinfo->value.enumerated.name,
1304 e->texts[uinfo->value.enumerated.item]); 1329 e->texts[uinfo->value.enumerated.item]);
1305 return 0; 1330 return 0;
@@ -1322,7 +1347,7 @@ int snd_soc_get_enum_double(struct snd_kcontrol *kcontrol,
1322 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 1347 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1323 unsigned short val, bitmask; 1348 unsigned short val, bitmask;
1324 1349
1325 for (bitmask = 1; bitmask < e->mask; bitmask <<= 1) 1350 for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
1326 ; 1351 ;
1327 val = snd_soc_read(codec, e->reg); 1352 val = snd_soc_read(codec, e->reg);
1328 ucontrol->value.enumerated.item[0] 1353 ucontrol->value.enumerated.item[0]
@@ -1352,14 +1377,14 @@ int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol,
1352 unsigned short val; 1377 unsigned short val;
1353 unsigned short mask, bitmask; 1378 unsigned short mask, bitmask;
1354 1379
1355 for (bitmask = 1; bitmask < e->mask; bitmask <<= 1) 1380 for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
1356 ; 1381 ;
1357 if (ucontrol->value.enumerated.item[0] > e->mask - 1) 1382 if (ucontrol->value.enumerated.item[0] > e->max - 1)
1358 return -EINVAL; 1383 return -EINVAL;
1359 val = ucontrol->value.enumerated.item[0] << e->shift_l; 1384 val = ucontrol->value.enumerated.item[0] << e->shift_l;
1360 mask = (bitmask - 1) << e->shift_l; 1385 mask = (bitmask - 1) << e->shift_l;
1361 if (e->shift_l != e->shift_r) { 1386 if (e->shift_l != e->shift_r) {
1362 if (ucontrol->value.enumerated.item[1] > e->mask - 1) 1387 if (ucontrol->value.enumerated.item[1] > e->max - 1)
1363 return -EINVAL; 1388 return -EINVAL;
1364 val |= ucontrol->value.enumerated.item[1] << e->shift_r; 1389 val |= ucontrol->value.enumerated.item[1] << e->shift_r;
1365 mask |= (bitmask - 1) << e->shift_r; 1390 mask |= (bitmask - 1) << e->shift_r;
@@ -1386,10 +1411,10 @@ int snd_soc_info_enum_ext(struct snd_kcontrol *kcontrol,
1386 1411
1387 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 1412 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1388 uinfo->count = 1; 1413 uinfo->count = 1;
1389 uinfo->value.enumerated.items = e->mask; 1414 uinfo->value.enumerated.items = e->max;
1390 1415
1391 if (uinfo->value.enumerated.item > e->mask - 1) 1416 if (uinfo->value.enumerated.item > e->max - 1)
1392 uinfo->value.enumerated.item = e->mask - 1; 1417 uinfo->value.enumerated.item = e->max - 1;
1393 strcpy(uinfo->value.enumerated.name, 1418 strcpy(uinfo->value.enumerated.name,
1394 e->texts[uinfo->value.enumerated.item]); 1419 e->texts[uinfo->value.enumerated.item]);
1395 return 0; 1420 return 0;
@@ -1434,9 +1459,11 @@ EXPORT_SYMBOL_GPL(snd_soc_info_volsw_ext);
1434int snd_soc_info_volsw(struct snd_kcontrol *kcontrol, 1459int snd_soc_info_volsw(struct snd_kcontrol *kcontrol,
1435 struct snd_ctl_elem_info *uinfo) 1460 struct snd_ctl_elem_info *uinfo)
1436{ 1461{
1437 int max = (kcontrol->private_value >> 16) & 0xff; 1462 struct soc_mixer_control *mc =
1438 int shift = (kcontrol->private_value >> 8) & 0x0f; 1463 (struct soc_mixer_control *)kcontrol->private_value;
1439 int rshift = (kcontrol->private_value >> 12) & 0x0f; 1464 int max = mc->max;
1465 unsigned int shift = mc->min;
1466 unsigned int rshift = mc->rshift;
1440 1467
1441 if (max == 1) 1468 if (max == 1)
1442 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 1469 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
@@ -1462,13 +1489,15 @@ EXPORT_SYMBOL_GPL(snd_soc_info_volsw);
1462int snd_soc_get_volsw(struct snd_kcontrol *kcontrol, 1489int snd_soc_get_volsw(struct snd_kcontrol *kcontrol,
1463 struct snd_ctl_elem_value *ucontrol) 1490 struct snd_ctl_elem_value *ucontrol)
1464{ 1491{
1492 struct soc_mixer_control *mc =
1493 (struct soc_mixer_control *)kcontrol->private_value;
1465 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1494 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1466 int reg = kcontrol->private_value & 0xff; 1495 unsigned int reg = mc->reg;
1467 int shift = (kcontrol->private_value >> 8) & 0x0f; 1496 unsigned int shift = mc->shift;
1468 int rshift = (kcontrol->private_value >> 12) & 0x0f; 1497 unsigned int rshift = mc->rshift;
1469 int max = (kcontrol->private_value >> 16) & 0xff; 1498 int max = mc->max;
1470 int mask = (1 << fls(max)) - 1; 1499 unsigned int mask = (1 << fls(max)) - 1;
1471 int invert = (kcontrol->private_value >> 24) & 0x01; 1500 unsigned int invert = mc->invert;
1472 1501
1473 ucontrol->value.integer.value[0] = 1502 ucontrol->value.integer.value[0] =
1474 (snd_soc_read(codec, reg) >> shift) & mask; 1503 (snd_soc_read(codec, reg) >> shift) & mask;
@@ -1499,13 +1528,15 @@ EXPORT_SYMBOL_GPL(snd_soc_get_volsw);
1499int snd_soc_put_volsw(struct snd_kcontrol *kcontrol, 1528int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
1500 struct snd_ctl_elem_value *ucontrol) 1529 struct snd_ctl_elem_value *ucontrol)
1501{ 1530{
1531 struct soc_mixer_control *mc =
1532 (struct soc_mixer_control *)kcontrol->private_value;
1502 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1533 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1503 int reg = kcontrol->private_value & 0xff; 1534 unsigned int reg = mc->reg;
1504 int shift = (kcontrol->private_value >> 8) & 0x0f; 1535 unsigned int shift = mc->shift;
1505 int rshift = (kcontrol->private_value >> 12) & 0x0f; 1536 unsigned int rshift = mc->rshift;
1506 int max = (kcontrol->private_value >> 16) & 0xff; 1537 int max = mc->max;
1507 int mask = (1 << fls(max)) - 1; 1538 unsigned int mask = (1 << fls(max)) - 1;
1508 int invert = (kcontrol->private_value >> 24) & 0x01; 1539 unsigned int invert = mc->invert;
1509 unsigned short val, val2, val_mask; 1540 unsigned short val, val2, val_mask;
1510 1541
1511 val = (ucontrol->value.integer.value[0] & mask); 1542 val = (ucontrol->value.integer.value[0] & mask);
@@ -1537,7 +1568,9 @@ EXPORT_SYMBOL_GPL(snd_soc_put_volsw);
1537int snd_soc_info_volsw_2r(struct snd_kcontrol *kcontrol, 1568int snd_soc_info_volsw_2r(struct snd_kcontrol *kcontrol,
1538 struct snd_ctl_elem_info *uinfo) 1569 struct snd_ctl_elem_info *uinfo)
1539{ 1570{
1540 int max = (kcontrol->private_value >> 12) & 0xff; 1571 struct soc_mixer_control *mc =
1572 (struct soc_mixer_control *)kcontrol->private_value;
1573 int max = mc->max;
1541 1574
1542 if (max == 1) 1575 if (max == 1)
1543 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 1576 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
@@ -1563,13 +1596,15 @@ EXPORT_SYMBOL_GPL(snd_soc_info_volsw_2r);
1563int snd_soc_get_volsw_2r(struct snd_kcontrol *kcontrol, 1596int snd_soc_get_volsw_2r(struct snd_kcontrol *kcontrol,
1564 struct snd_ctl_elem_value *ucontrol) 1597 struct snd_ctl_elem_value *ucontrol)
1565{ 1598{
1599 struct soc_mixer_control *mc =
1600 (struct soc_mixer_control *)kcontrol->private_value;
1566 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1601 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1567 int reg = kcontrol->private_value & 0xff; 1602 unsigned int reg = mc->reg;
1568 int reg2 = (kcontrol->private_value >> 24) & 0xff; 1603 unsigned int reg2 = mc->rreg;
1569 int shift = (kcontrol->private_value >> 8) & 0x0f; 1604 unsigned int shift = mc->shift;
1570 int max = (kcontrol->private_value >> 12) & 0xff; 1605 int max = mc->max;
1571 int mask = (1<<fls(max))-1; 1606 unsigned int mask = (1<<fls(max))-1;
1572 int invert = (kcontrol->private_value >> 20) & 0x01; 1607 unsigned int invert = mc->invert;
1573 1608
1574 ucontrol->value.integer.value[0] = 1609 ucontrol->value.integer.value[0] =
1575 (snd_soc_read(codec, reg) >> shift) & mask; 1610 (snd_soc_read(codec, reg) >> shift) & mask;
@@ -1598,13 +1633,15 @@ EXPORT_SYMBOL_GPL(snd_soc_get_volsw_2r);
1598int snd_soc_put_volsw_2r(struct snd_kcontrol *kcontrol, 1633int snd_soc_put_volsw_2r(struct snd_kcontrol *kcontrol,
1599 struct snd_ctl_elem_value *ucontrol) 1634 struct snd_ctl_elem_value *ucontrol)
1600{ 1635{
1636 struct soc_mixer_control *mc =
1637 (struct soc_mixer_control *)kcontrol->private_value;
1601 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1638 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1602 int reg = kcontrol->private_value & 0xff; 1639 unsigned int reg = mc->reg;
1603 int reg2 = (kcontrol->private_value >> 24) & 0xff; 1640 unsigned int reg2 = mc->rreg;
1604 int shift = (kcontrol->private_value >> 8) & 0x0f; 1641 unsigned int shift = mc->shift;
1605 int max = (kcontrol->private_value >> 12) & 0xff; 1642 int max = mc->max;
1606 int mask = (1 << fls(max)) - 1; 1643 unsigned int mask = (1 << fls(max)) - 1;
1607 int invert = (kcontrol->private_value >> 20) & 0x01; 1644 unsigned int invert = mc->invert;
1608 int err; 1645 int err;
1609 unsigned short val, val2, val_mask; 1646 unsigned short val, val2, val_mask;
1610 1647
@@ -1641,8 +1678,10 @@ EXPORT_SYMBOL_GPL(snd_soc_put_volsw_2r);
1641int snd_soc_info_volsw_s8(struct snd_kcontrol *kcontrol, 1678int snd_soc_info_volsw_s8(struct snd_kcontrol *kcontrol,
1642 struct snd_ctl_elem_info *uinfo) 1679 struct snd_ctl_elem_info *uinfo)
1643{ 1680{
1644 int max = (signed char)((kcontrol->private_value >> 16) & 0xff); 1681 struct soc_mixer_control *mc =
1645 int min = (signed char)((kcontrol->private_value >> 24) & 0xff); 1682 (struct soc_mixer_control *)kcontrol->private_value;
1683 int max = mc->max;
1684 int min = mc->min;
1646 1685
1647 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 1686 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1648 uinfo->count = 2; 1687 uinfo->count = 2;
@@ -1664,9 +1703,11 @@ EXPORT_SYMBOL_GPL(snd_soc_info_volsw_s8);
1664int snd_soc_get_volsw_s8(struct snd_kcontrol *kcontrol, 1703int snd_soc_get_volsw_s8(struct snd_kcontrol *kcontrol,
1665 struct snd_ctl_elem_value *ucontrol) 1704 struct snd_ctl_elem_value *ucontrol)
1666{ 1705{
1706 struct soc_mixer_control *mc =
1707 (struct soc_mixer_control *)kcontrol->private_value;
1667 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1708 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1668 int reg = kcontrol->private_value & 0xff; 1709 unsigned int reg = mc->reg;
1669 int min = (signed char)((kcontrol->private_value >> 24) & 0xff); 1710 int min = mc->min;
1670 int val = snd_soc_read(codec, reg); 1711 int val = snd_soc_read(codec, reg);
1671 1712
1672 ucontrol->value.integer.value[0] = 1713 ucontrol->value.integer.value[0] =
@@ -1689,9 +1730,11 @@ EXPORT_SYMBOL_GPL(snd_soc_get_volsw_s8);
1689int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol, 1730int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol,
1690 struct snd_ctl_elem_value *ucontrol) 1731 struct snd_ctl_elem_value *ucontrol)
1691{ 1732{
1733 struct soc_mixer_control *mc =
1734 (struct soc_mixer_control *)kcontrol->private_value;
1692 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1735 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1693 int reg = kcontrol->private_value & 0xff; 1736 unsigned int reg = mc->reg;
1694 int min = (signed char)((kcontrol->private_value >> 24) & 0xff); 1737 int min = mc->min;
1695 unsigned short val; 1738 unsigned short val;
1696 1739
1697 val = (ucontrol->value.integer.value[0]+min) & 0xff; 1740 val = (ucontrol->value.integer.value[0]+min) & 0xff;
@@ -1842,7 +1885,7 @@ module_init(snd_soc_init);
1842module_exit(snd_soc_exit); 1885module_exit(snd_soc_exit);
1843 1886
1844/* Module information */ 1887/* Module information */
1845MODULE_AUTHOR("Liam Girdwood, liam.girdwood@wolfsonmicro.com, www.wolfsonmicro.com"); 1888MODULE_AUTHOR("Liam Girdwood, lrg@slimlogic.co.uk");
1846MODULE_DESCRIPTION("ALSA SoC Core"); 1889MODULE_DESCRIPTION("ALSA SoC Core");
1847MODULE_LICENSE("GPL"); 1890MODULE_LICENSE("GPL");
1848MODULE_ALIAS("platform:soc-audio"); 1891MODULE_ALIAS("platform:soc-audio");
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index f9d100bc8479..efbd0b37810a 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -2,8 +2,7 @@
2 * soc-dapm.c -- ALSA SoC Dynamic Audio Power Management 2 * soc-dapm.c -- ALSA SoC Dynamic Audio Power Management
3 * 3 *
4 * Copyright 2005 Wolfson Microelectronics PLC. 4 * Copyright 2005 Wolfson Microelectronics PLC.
5 * Author: Liam Girdwood 5 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
6 * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
7 * 6 *
8 * This program is free software; you can redistribute it and/or modify it 7 * 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 8 * under the terms of the GNU General Public License as published by the
@@ -38,6 +37,7 @@
38#include <linux/bitops.h> 37#include <linux/bitops.h>
39#include <linux/platform_device.h> 38#include <linux/platform_device.h>
40#include <linux/jiffies.h> 39#include <linux/jiffies.h>
40#include <linux/debugfs.h>
41#include <sound/core.h> 41#include <sound/core.h>
42#include <sound/pcm.h> 42#include <sound/pcm.h>
43#include <sound/pcm_params.h> 43#include <sound/pcm_params.h>
@@ -67,7 +67,9 @@ static int dapm_status = 1;
67module_param(dapm_status, int, 0); 67module_param(dapm_status, int, 0);
68MODULE_PARM_DESC(dapm_status, "enable DPM sysfs entries"); 68MODULE_PARM_DESC(dapm_status, "enable DPM sysfs entries");
69 69
70static unsigned int pop_time; 70static struct dentry *asoc_debugfs;
71
72static u32 pop_time;
71 73
72static void pop_wait(void) 74static void pop_wait(void)
73{ 75{
@@ -104,10 +106,13 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
104 case snd_soc_dapm_switch: 106 case snd_soc_dapm_switch:
105 case snd_soc_dapm_mixer: { 107 case snd_soc_dapm_mixer: {
106 int val; 108 int val;
107 int reg = w->kcontrols[i].private_value & 0xff; 109 struct soc_mixer_control *mc = (struct soc_mixer_control *)
108 int shift = (w->kcontrols[i].private_value >> 8) & 0x0f; 110 w->kcontrols[i].private_value;
109 int mask = (w->kcontrols[i].private_value >> 16) & 0xff; 111 unsigned int reg = mc->reg;
110 int invert = (w->kcontrols[i].private_value >> 24) & 0x01; 112 unsigned int shift = mc->shift;
113 int max = mc->max;
114 unsigned int mask = (1 << fls(max)) - 1;
115 unsigned int invert = mc->invert;
111 116
112 val = snd_soc_read(w->codec, reg); 117 val = snd_soc_read(w->codec, reg);
113 val = (val >> shift) & mask; 118 val = (val >> shift) & mask;
@@ -122,13 +127,13 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
122 struct soc_enum *e = (struct soc_enum *)w->kcontrols[i].private_value; 127 struct soc_enum *e = (struct soc_enum *)w->kcontrols[i].private_value;
123 int val, item, bitmask; 128 int val, item, bitmask;
124 129
125 for (bitmask = 1; bitmask < e->mask; bitmask <<= 1) 130 for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
126 ; 131 ;
127 val = snd_soc_read(w->codec, e->reg); 132 val = snd_soc_read(w->codec, e->reg);
128 item = (val >> e->shift_l) & (bitmask - 1); 133 item = (val >> e->shift_l) & (bitmask - 1);
129 134
130 p->connect = 0; 135 p->connect = 0;
131 for (i = 0; i < e->mask; i++) { 136 for (i = 0; i < e->max; i++) {
132 if (!(strcmp(p->name, e->texts[i])) && item == i) 137 if (!(strcmp(p->name, e->texts[i])) && item == i)
133 p->connect = 1; 138 p->connect = 1;
134 } 139 }
@@ -165,7 +170,7 @@ static int dapm_connect_mux(struct snd_soc_codec *codec,
165 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 170 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
166 int i; 171 int i;
167 172
168 for (i = 0; i < e->mask; i++) { 173 for (i = 0; i < e->max; i++) {
169 if (!(strcmp(control_name, e->texts[i]))) { 174 if (!(strcmp(control_name, e->texts[i]))) {
170 list_add(&path->list, &codec->dapm_paths); 175 list_add(&path->list, &codec->dapm_paths);
171 list_add(&path->list_sink, &dest->sources); 176 list_add(&path->list_sink, &dest->sources);
@@ -247,16 +252,19 @@ static int dapm_set_pga(struct snd_soc_dapm_widget *widget, int power)
247 return 0; 252 return 0;
248 253
249 if (widget->num_kcontrols && k) { 254 if (widget->num_kcontrols && k) {
250 int reg = k->private_value & 0xff; 255 struct soc_mixer_control *mc =
251 int shift = (k->private_value >> 8) & 0x0f; 256 (struct soc_mixer_control *)k->private_value;
252 int mask = (k->private_value >> 16) & 0xff; 257 unsigned int reg = mc->reg;
253 int invert = (k->private_value >> 24) & 0x01; 258 unsigned int shift = mc->shift;
259 int max = mc->max;
260 unsigned int mask = (1 << fls(max)) - 1;
261 unsigned int invert = mc->invert;
254 262
255 if (power) { 263 if (power) {
256 int i; 264 int i;
257 /* power up has happended, increase volume to last level */ 265 /* power up has happended, increase volume to last level */
258 if (invert) { 266 if (invert) {
259 for (i = mask; i > widget->saved_value; i--) 267 for (i = max; i > widget->saved_value; i--)
260 snd_soc_update_bits(widget->codec, reg, mask, i); 268 snd_soc_update_bits(widget->codec, reg, mask, i);
261 } else { 269 } else {
262 for (i = 0; i < widget->saved_value; i++) 270 for (i = 0; i < widget->saved_value; i++)
@@ -684,7 +692,7 @@ static void dbg_dump_dapm(struct snd_soc_codec* codec, const char *action)
684/* test and update the power status of a mux widget */ 692/* test and update the power status of a mux widget */
685static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget, 693static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
686 struct snd_kcontrol *kcontrol, int mask, 694 struct snd_kcontrol *kcontrol, int mask,
687 int val, struct soc_enum* e) 695 int mux, int val, struct soc_enum *e)
688{ 696{
689 struct snd_soc_dapm_path *path; 697 struct snd_soc_dapm_path *path;
690 int found = 0; 698 int found = 0;
@@ -700,12 +708,12 @@ static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
700 if (path->kcontrol != kcontrol) 708 if (path->kcontrol != kcontrol)
701 continue; 709 continue;
702 710
703 if (!path->name || ! e->texts[val]) 711 if (!path->name || !e->texts[mux])
704 continue; 712 continue;
705 713
706 found = 1; 714 found = 1;
707 /* we now need to match the string in the enum to the path */ 715 /* we now need to match the string in the enum to the path */
708 if (!(strcmp(path->name, e->texts[val]))) 716 if (!(strcmp(path->name, e->texts[mux])))
709 path->connect = 1; /* new connection */ 717 path->connect = 1; /* new connection */
710 else 718 else
711 path->connect = 0; /* old connection must be powered down */ 719 path->connect = 0; /* old connection must be powered down */
@@ -811,51 +819,35 @@ static ssize_t dapm_widget_show(struct device *dev,
811 819
812static DEVICE_ATTR(dapm_widget, 0444, dapm_widget_show, NULL); 820static DEVICE_ATTR(dapm_widget, 0444, dapm_widget_show, NULL);
813 821
814/* pop/click delay times */
815static ssize_t dapm_pop_time_show(struct device *dev,
816 struct device_attribute *attr, char *buf)
817{
818 return sprintf(buf, "%d\n", pop_time);
819}
820
821static ssize_t dapm_pop_time_store(struct device *dev,
822 struct device_attribute *attr,
823 const char *buf, size_t count)
824
825{
826 unsigned long val;
827
828 if (strict_strtoul(buf, 10, &val) >= 0)
829 pop_time = val;
830 else
831 printk(KERN_ERR "Unable to parse pop_time setting\n");
832
833 return count;
834}
835
836static DEVICE_ATTR(dapm_pop_time, 0744, dapm_pop_time_show,
837 dapm_pop_time_store);
838
839int snd_soc_dapm_sys_add(struct device *dev) 822int snd_soc_dapm_sys_add(struct device *dev)
840{ 823{
841 int ret = 0; 824 int ret = 0;
842 825
843 if (dapm_status) { 826 if (!dapm_status)
844 ret = device_create_file(dev, &dev_attr_dapm_widget); 827 return 0;
845 828
846 if (ret == 0) 829 ret = device_create_file(dev, &dev_attr_dapm_widget);
847 ret = device_create_file(dev, &dev_attr_dapm_pop_time); 830 if (ret != 0)
848 } 831 return ret;
849 832
850 return ret; 833 asoc_debugfs = debugfs_create_dir("asoc", NULL);
834 if (!IS_ERR(asoc_debugfs))
835 debugfs_create_u32("dapm_pop_time", 0744, asoc_debugfs,
836 &pop_time);
837 else
838 asoc_debugfs = NULL;
839
840 return 0;
851} 841}
852 842
853static void snd_soc_dapm_sys_remove(struct device *dev) 843static void snd_soc_dapm_sys_remove(struct device *dev)
854{ 844{
855 if (dapm_status) { 845 if (dapm_status) {
856 device_remove_file(dev, &dev_attr_dapm_pop_time);
857 device_remove_file(dev, &dev_attr_dapm_widget); 846 device_remove_file(dev, &dev_attr_dapm_widget);
858 } 847 }
848
849 if (asoc_debugfs)
850 debugfs_remove_recursive(asoc_debugfs);
859} 851}
860 852
861/* free all dapm widgets and resources */ 853/* free all dapm widgets and resources */
@@ -1133,12 +1125,14 @@ int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol,
1133 struct snd_ctl_elem_value *ucontrol) 1125 struct snd_ctl_elem_value *ucontrol)
1134{ 1126{
1135 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 1127 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
1136 int reg = kcontrol->private_value & 0xff; 1128 struct soc_mixer_control *mc =
1137 int shift = (kcontrol->private_value >> 8) & 0x0f; 1129 (struct soc_mixer_control *)kcontrol->private_value;
1138 int rshift = (kcontrol->private_value >> 12) & 0x0f; 1130 unsigned int reg = mc->reg;
1139 int max = (kcontrol->private_value >> 16) & 0xff; 1131 unsigned int shift = mc->shift;
1140 int invert = (kcontrol->private_value >> 24) & 0x01; 1132 unsigned int rshift = mc->rshift;
1141 int mask = (1 << fls(max)) - 1; 1133 int max = mc->max;
1134 unsigned int invert = mc->invert;
1135 unsigned int mask = (1 << fls(max)) - 1;
1142 1136
1143 /* return the saved value if we are powered down */ 1137 /* return the saved value if we are powered down */
1144 if (widget->id == snd_soc_dapm_pga && !widget->power) { 1138 if (widget->id == snd_soc_dapm_pga && !widget->power) {
@@ -1176,12 +1170,14 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
1176 struct snd_ctl_elem_value *ucontrol) 1170 struct snd_ctl_elem_value *ucontrol)
1177{ 1171{
1178 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 1172 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
1179 int reg = kcontrol->private_value & 0xff; 1173 struct soc_mixer_control *mc =
1180 int shift = (kcontrol->private_value >> 8) & 0x0f; 1174 (struct soc_mixer_control *)kcontrol->private_value;
1181 int rshift = (kcontrol->private_value >> 12) & 0x0f; 1175 unsigned int reg = mc->reg;
1182 int max = (kcontrol->private_value >> 16) & 0xff; 1176 unsigned int shift = mc->shift;
1183 int mask = (1 << fls(max)) - 1; 1177 unsigned int rshift = mc->rshift;
1184 int invert = (kcontrol->private_value >> 24) & 0x01; 1178 int max = mc->max;
1179 unsigned int mask = (1 << fls(max)) - 1;
1180 unsigned int invert = mc->invert;
1185 unsigned short val, val2, val_mask; 1181 unsigned short val, val2, val_mask;
1186 int ret; 1182 int ret;
1187 1183
@@ -1248,7 +1244,7 @@ int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol,
1248 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 1244 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1249 unsigned short val, bitmask; 1245 unsigned short val, bitmask;
1250 1246
1251 for (bitmask = 1; bitmask < e->mask; bitmask <<= 1) 1247 for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
1252 ; 1248 ;
1253 val = snd_soc_read(widget->codec, e->reg); 1249 val = snd_soc_read(widget->codec, e->reg);
1254 ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & (bitmask - 1); 1250 ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & (bitmask - 1);
@@ -1278,15 +1274,15 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
1278 unsigned short mask, bitmask; 1274 unsigned short mask, bitmask;
1279 int ret = 0; 1275 int ret = 0;
1280 1276
1281 for (bitmask = 1; bitmask < e->mask; bitmask <<= 1) 1277 for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
1282 ; 1278 ;
1283 if (ucontrol->value.enumerated.item[0] > e->mask - 1) 1279 if (ucontrol->value.enumerated.item[0] > e->max - 1)
1284 return -EINVAL; 1280 return -EINVAL;
1285 mux = ucontrol->value.enumerated.item[0]; 1281 mux = ucontrol->value.enumerated.item[0];
1286 val = mux << e->shift_l; 1282 val = mux << e->shift_l;
1287 mask = (bitmask - 1) << e->shift_l; 1283 mask = (bitmask - 1) << e->shift_l;
1288 if (e->shift_l != e->shift_r) { 1284 if (e->shift_l != e->shift_r) {
1289 if (ucontrol->value.enumerated.item[1] > e->mask - 1) 1285 if (ucontrol->value.enumerated.item[1] > e->max - 1)
1290 return -EINVAL; 1286 return -EINVAL;
1291 val |= ucontrol->value.enumerated.item[1] << e->shift_r; 1287 val |= ucontrol->value.enumerated.item[1] << e->shift_r;
1292 mask |= (bitmask - 1) << e->shift_r; 1288 mask |= (bitmask - 1) << e->shift_r;
@@ -1294,7 +1290,7 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
1294 1290
1295 mutex_lock(&widget->codec->mutex); 1291 mutex_lock(&widget->codec->mutex);
1296 widget->value = val; 1292 widget->value = val;
1297 dapm_mux_update_power(widget, kcontrol, mask, mux, e); 1293 dapm_mux_update_power(widget, kcontrol, mask, mux, val, e);
1298 if (widget->event) { 1294 if (widget->event) {
1299 if (widget->event_flags & SND_SOC_DAPM_PRE_REG) { 1295 if (widget->event_flags & SND_SOC_DAPM_PRE_REG) {
1300 ret = widget->event(widget, 1296 ret = widget->event(widget,
@@ -1487,6 +1483,26 @@ int snd_soc_dapm_disable_pin(struct snd_soc_codec *codec, char *pin)
1487EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin); 1483EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin);
1488 1484
1489/** 1485/**
1486 * snd_soc_dapm_nc_pin - permanently disable pin.
1487 * @codec: SoC codec
1488 * @pin: pin name
1489 *
1490 * Marks the specified pin as being not connected, disabling it along
1491 * any parent or child widgets. At present this is identical to
1492 * snd_soc_dapm_disable_pin() but in future it will be extended to do
1493 * additional things such as disabling controls which only affect
1494 * paths through the pin.
1495 *
1496 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
1497 * do any widget power switching.
1498 */
1499int snd_soc_dapm_nc_pin(struct snd_soc_codec *codec, char *pin)
1500{
1501 return snd_soc_dapm_set_pin(codec, pin, 0);
1502}
1503EXPORT_SYMBOL_GPL(snd_soc_dapm_nc_pin);
1504
1505/**
1490 * snd_soc_dapm_get_pin_status - get audio pin status 1506 * snd_soc_dapm_get_pin_status - get audio pin status
1491 * @codec: audio codec 1507 * @codec: audio codec
1492 * @pin: audio signal pin endpoint (or start point) 1508 * @pin: audio signal pin endpoint (or start point)
@@ -1524,6 +1540,6 @@ void snd_soc_dapm_free(struct snd_soc_device *socdev)
1524EXPORT_SYMBOL_GPL(snd_soc_dapm_free); 1540EXPORT_SYMBOL_GPL(snd_soc_dapm_free);
1525 1541
1526/* Module information */ 1542/* Module information */
1527MODULE_AUTHOR("Liam Girdwood, liam.girdwood@wolfsonmicro.com, www.wolfsonmicro.com"); 1543MODULE_AUTHOR("Liam Girdwood, lrg@slimlogic.co.uk");
1528MODULE_DESCRIPTION("Dynamic Audio Power Management core for ALSA SoC"); 1544MODULE_DESCRIPTION("Dynamic Audio Power Management core for ALSA SoC");
1529MODULE_LICENSE("GPL"); 1545MODULE_LICENSE("GPL");
diff --git a/sound/sound_core.c b/sound/sound_core.c
index 1b04259a4328..4ae07e236b36 100644
--- a/sound/sound_core.c
+++ b/sound/sound_core.c
@@ -1,5 +1,61 @@
1/* 1/*
2 * Sound core handling. Breaks out sound functions to submodules 2 * Sound core. This file is composed of two parts. sound_class
3 * which is common to both OSS and ALSA and OSS sound core which
4 * is used OSS or emulation of it.
5 */
6
7/*
8 * First, the common part.
9 */
10#include <linux/module.h>
11#include <linux/device.h>
12#include <linux/err.h>
13
14#ifdef CONFIG_SOUND_OSS_CORE
15static int __init init_oss_soundcore(void);
16static void cleanup_oss_soundcore(void);
17#else
18static inline int init_oss_soundcore(void) { return 0; }
19static inline void cleanup_oss_soundcore(void) { }
20#endif
21
22struct class *sound_class;
23EXPORT_SYMBOL(sound_class);
24
25MODULE_DESCRIPTION("Core sound module");
26MODULE_AUTHOR("Alan Cox");
27MODULE_LICENSE("GPL");
28
29static int __init init_soundcore(void)
30{
31 int rc;
32
33 rc = init_oss_soundcore();
34 if (rc)
35 return rc;
36
37 sound_class = class_create(THIS_MODULE, "sound");
38 if (IS_ERR(sound_class)) {
39 cleanup_oss_soundcore();
40 return PTR_ERR(sound_class);
41 }
42
43 return 0;
44}
45
46static void __exit cleanup_soundcore(void)
47{
48 cleanup_oss_soundcore();
49 class_destroy(sound_class);
50}
51
52module_init(init_soundcore);
53module_exit(cleanup_soundcore);
54
55
56#ifdef CONFIG_SOUND_OSS_CORE
57/*
58 * OSS sound core handling. Breaks out sound functions to submodules
3 * 59 *
4 * Author: Alan Cox <alan.cox@linux.org> 60 * Author: Alan Cox <alan.cox@linux.org>
5 * 61 *
@@ -34,21 +90,17 @@
34 * locking at some point in 2.3.x. 90 * locking at some point in 2.3.x.
35 */ 91 */
36 92
37#include <linux/module.h>
38#include <linux/init.h> 93#include <linux/init.h>
39#include <linux/slab.h> 94#include <linux/slab.h>
40#include <linux/smp_lock.h> 95#include <linux/smp_lock.h>
41#include <linux/types.h> 96#include <linux/types.h>
42#include <linux/kernel.h> 97#include <linux/kernel.h>
43#include <linux/fs.h>
44#include <linux/sound.h> 98#include <linux/sound.h>
45#include <linux/major.h> 99#include <linux/major.h>
46#include <linux/kmod.h> 100#include <linux/kmod.h>
47#include <linux/device.h>
48 101
49#define SOUND_STEP 16 102#define SOUND_STEP 16
50 103
51
52struct sound_unit 104struct sound_unit
53{ 105{
54 int unit_minor; 106 int unit_minor;
@@ -64,9 +116,6 @@ extern int msnd_classic_init(void);
64extern int msnd_pinnacle_init(void); 116extern int msnd_pinnacle_init(void);
65#endif 117#endif
66 118
67struct class *sound_class;
68EXPORT_SYMBOL(sound_class);
69
70/* 119/*
71 * Low level list operator. Scan the ordered list, find a hole and 120 * Low level list operator. Scan the ordered list, find a hole and
72 * join into it. Called with the lock asserted 121 * join into it. Called with the lock asserted
@@ -523,31 +572,23 @@ int soundcore_open(struct inode *inode, struct file *file)
523 return -ENODEV; 572 return -ENODEV;
524} 573}
525 574
526MODULE_DESCRIPTION("Core sound module");
527MODULE_AUTHOR("Alan Cox");
528MODULE_LICENSE("GPL");
529MODULE_ALIAS_CHARDEV_MAJOR(SOUND_MAJOR); 575MODULE_ALIAS_CHARDEV_MAJOR(SOUND_MAJOR);
530 576
531static void __exit cleanup_soundcore(void) 577static void cleanup_oss_soundcore(void)
532{ 578{
533 /* We have nothing to really do here - we know the lists must be 579 /* We have nothing to really do here - we know the lists must be
534 empty */ 580 empty */
535 unregister_chrdev(SOUND_MAJOR, "sound"); 581 unregister_chrdev(SOUND_MAJOR, "sound");
536 class_destroy(sound_class);
537} 582}
538 583
539static int __init init_soundcore(void) 584static int __init init_oss_soundcore(void)
540{ 585{
541 if (register_chrdev(SOUND_MAJOR, "sound", &soundcore_fops)==-1) { 586 if (register_chrdev(SOUND_MAJOR, "sound", &soundcore_fops)==-1) {
542 printk(KERN_ERR "soundcore: sound device already in use.\n"); 587 printk(KERN_ERR "soundcore: sound device already in use.\n");
543 return -EBUSY; 588 return -EBUSY;
544 } 589 }
545 sound_class = class_create(THIS_MODULE, "sound");
546 if (IS_ERR(sound_class))
547 return PTR_ERR(sound_class);
548 590
549 return 0; 591 return 0;
550} 592}
551 593
552module_init(init_soundcore); 594#endif /* CONFIG_SOUND_OSS_CORE */
553module_exit(cleanup_soundcore);
diff --git a/sound/sparc/amd7930.c b/sound/sparc/amd7930.c
index 0c63e0585b15..f87933e48812 100644
--- a/sound/sparc/amd7930.c
+++ b/sound/sparc/amd7930.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Driver for AMD7930 sound chips found on Sparcs. 2 * Driver for AMD7930 sound chips found on Sparcs.
3 * Copyright (C) 2002 David S. Miller <davem@redhat.com> 3 * Copyright (C) 2002, 2008 David S. Miller <davem@davemloft.net>
4 * 4 *
5 * Based entirely upon drivers/sbus/audio/amd7930.c which is: 5 * Based entirely upon drivers/sbus/audio/amd7930.c which is:
6 * Copyright (C) 1996,1997 Thomas K. Dyas (tdyas@eden.rutgers.edu) 6 * Copyright (C) 1996,1997 Thomas K. Dyas (tdyas@eden.rutgers.edu)
@@ -35,6 +35,8 @@
35#include <linux/init.h> 35#include <linux/init.h>
36#include <linux/interrupt.h> 36#include <linux/interrupt.h>
37#include <linux/moduleparam.h> 37#include <linux/moduleparam.h>
38#include <linux/of.h>
39#include <linux/of_device.h>
38 40
39#include <sound/core.h> 41#include <sound/core.h>
40#include <sound/pcm.h> 42#include <sound/pcm.h>
@@ -44,7 +46,6 @@
44 46
45#include <asm/io.h> 47#include <asm/io.h>
46#include <asm/irq.h> 48#include <asm/irq.h>
47#include <asm/sbus.h>
48#include <asm/prom.h> 49#include <asm/prom.h>
49 50
50static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ 51static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
@@ -335,8 +336,8 @@ struct snd_amd7930 {
335 int pgain; 336 int pgain;
336 int mgain; 337 int mgain;
337 338
339 struct of_device *op;
338 unsigned int irq; 340 unsigned int irq;
339 unsigned int regs_size;
340 struct snd_amd7930 *next; 341 struct snd_amd7930 *next;
341}; 342};
342 343
@@ -765,7 +766,6 @@ static int __devinit snd_amd7930_pcm(struct snd_amd7930 *amd)
765 /* playback count */ 1, 766 /* playback count */ 1,
766 /* capture count */ 1, &pcm)) < 0) 767 /* capture count */ 1, &pcm)) < 0)
767 return err; 768 return err;
768 snd_assert(pcm != NULL, return -EINVAL);
769 769
770 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_amd7930_playback_ops); 770 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_amd7930_playback_ops);
771 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_amd7930_capture_ops); 771 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_amd7930_capture_ops);
@@ -788,13 +788,6 @@ static int __devinit snd_amd7930_pcm(struct snd_amd7930 *amd)
788 788
789static int snd_amd7930_info_volume(struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo) 789static int snd_amd7930_info_volume(struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo)
790{ 790{
791 int type = kctl->private_value;
792
793 snd_assert(type == VOLUME_MONITOR ||
794 type == VOLUME_CAPTURE ||
795 type == VOLUME_PLAYBACK, return -EINVAL);
796 (void) type;
797
798 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 791 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
799 uinfo->count = 1; 792 uinfo->count = 1;
800 uinfo->value.integer.min = 0; 793 uinfo->value.integer.min = 0;
@@ -809,10 +802,6 @@ static int snd_amd7930_get_volume(struct snd_kcontrol *kctl, struct snd_ctl_elem
809 int type = kctl->private_value; 802 int type = kctl->private_value;
810 int *swval; 803 int *swval;
811 804
812 snd_assert(type == VOLUME_MONITOR ||
813 type == VOLUME_CAPTURE ||
814 type == VOLUME_PLAYBACK, return -EINVAL);
815
816 switch (type) { 805 switch (type) {
817 case VOLUME_MONITOR: 806 case VOLUME_MONITOR:
818 swval = &amd->mgain; 807 swval = &amd->mgain;
@@ -838,10 +827,6 @@ static int snd_amd7930_put_volume(struct snd_kcontrol *kctl, struct snd_ctl_elem
838 int type = kctl->private_value; 827 int type = kctl->private_value;
839 int *swval, change; 828 int *swval, change;
840 829
841 snd_assert(type == VOLUME_MONITOR ||
842 type == VOLUME_CAPTURE ||
843 type == VOLUME_PLAYBACK, return -EINVAL);
844
845 switch (type) { 830 switch (type) {
846 case VOLUME_MONITOR: 831 case VOLUME_MONITOR:
847 swval = &amd->mgain; 832 swval = &amd->mgain;
@@ -904,7 +889,8 @@ static int __devinit snd_amd7930_mixer(struct snd_amd7930 *amd)
904 struct snd_card *card; 889 struct snd_card *card;
905 int idx, err; 890 int idx, err;
906 891
907 snd_assert(amd != NULL && amd->card != NULL, return -EINVAL); 892 if (snd_BUG_ON(!amd || !amd->card))
893 return -EINVAL;
908 894
909 card = amd->card; 895 card = amd->card;
910 strcpy(card->mixername, card->shortname); 896 strcpy(card->mixername, card->shortname);
@@ -920,13 +906,16 @@ static int __devinit snd_amd7930_mixer(struct snd_amd7930 *amd)
920 906
921static int snd_amd7930_free(struct snd_amd7930 *amd) 907static int snd_amd7930_free(struct snd_amd7930 *amd)
922{ 908{
909 struct of_device *op = amd->op;
910
923 amd7930_idle(amd); 911 amd7930_idle(amd);
924 912
925 if (amd->irq) 913 if (amd->irq)
926 free_irq(amd->irq, amd); 914 free_irq(amd->irq, amd);
927 915
928 if (amd->regs) 916 if (amd->regs)
929 sbus_iounmap(amd->regs, amd->regs_size); 917 of_iounmap(&op->resource[0], amd->regs,
918 resource_size(&op->resource[0]));
930 919
931 kfree(amd); 920 kfree(amd);
932 921
@@ -945,13 +934,12 @@ static struct snd_device_ops snd_amd7930_dev_ops = {
945}; 934};
946 935
947static int __devinit snd_amd7930_create(struct snd_card *card, 936static int __devinit snd_amd7930_create(struct snd_card *card,
948 struct resource *rp, 937 struct of_device *op,
949 unsigned int reg_size,
950 int irq, int dev, 938 int irq, int dev,
951 struct snd_amd7930 **ramd) 939 struct snd_amd7930 **ramd)
952{ 940{
953 unsigned long flags;
954 struct snd_amd7930 *amd; 941 struct snd_amd7930 *amd;
942 unsigned long flags;
955 int err; 943 int err;
956 944
957 *ramd = NULL; 945 *ramd = NULL;
@@ -961,9 +949,10 @@ static int __devinit snd_amd7930_create(struct snd_card *card,
961 949
962 spin_lock_init(&amd->lock); 950 spin_lock_init(&amd->lock);
963 amd->card = card; 951 amd->card = card;
964 amd->regs_size = reg_size; 952 amd->op = op;
965 953
966 amd->regs = sbus_ioremap(rp, 0, amd->regs_size, "amd7930"); 954 amd->regs = of_ioremap(&op->resource[0], 0,
955 resource_size(&op->resource[0]), "amd7930");
967 if (!amd->regs) { 956 if (!amd->regs) {
968 snd_printk("amd7930-%d: Unable to map chip registers.\n", dev); 957 snd_printk("amd7930-%d: Unable to map chip registers.\n", dev);
969 return -EIO; 958 return -EIO;
@@ -1012,12 +1001,15 @@ static int __devinit snd_amd7930_create(struct snd_card *card,
1012 return 0; 1001 return 0;
1013} 1002}
1014 1003
1015static int __devinit amd7930_attach_common(struct resource *rp, int irq) 1004static int __devinit amd7930_sbus_probe(struct of_device *op, const struct of_device_id *match)
1016{ 1005{
1006 struct resource *rp = &op->resource[0];
1017 static int dev_num; 1007 static int dev_num;
1018 struct snd_card *card; 1008 struct snd_card *card;
1019 struct snd_amd7930 *amd; 1009 struct snd_amd7930 *amd;
1020 int err; 1010 int err, irq;
1011
1012 irq = op->irqs[0];
1021 1013
1022 if (dev_num >= SNDRV_CARDS) 1014 if (dev_num >= SNDRV_CARDS)
1023 return -ENODEV; 1015 return -ENODEV;
@@ -1038,8 +1030,7 @@ static int __devinit amd7930_attach_common(struct resource *rp, int irq)
1038 (unsigned long long)rp->start, 1030 (unsigned long long)rp->start,
1039 irq); 1031 irq);
1040 1032
1041 if ((err = snd_amd7930_create(card, rp, 1033 if ((err = snd_amd7930_create(card, op,
1042 (rp->end - rp->start) + 1,
1043 irq, dev_num, &amd)) < 0) 1034 irq, dev_num, &amd)) < 0)
1044 goto out_err; 1035 goto out_err;
1045 1036
@@ -1064,43 +1055,7 @@ out_err:
1064 return err; 1055 return err;
1065} 1056}
1066 1057
1067static int __devinit amd7930_obio_attach(struct device_node *dp) 1058static const struct of_device_id amd7930_match[] = {
1068{
1069 const struct linux_prom_registers *regs;
1070 const struct linux_prom_irqs *irqp;
1071 struct resource res, *rp;
1072 int len;
1073
1074 irqp = of_get_property(dp, "intr", &len);
1075 if (!irqp) {
1076 snd_printk("%s: Firmware node lacks IRQ property.\n",
1077 dp->full_name);
1078 return -ENODEV;
1079 }
1080
1081 regs = of_get_property(dp, "reg", &len);
1082 if (!regs) {
1083 snd_printk("%s: Firmware node lacks register property.\n",
1084 dp->full_name);
1085 return -ENODEV;
1086 }
1087
1088 rp = &res;
1089 rp->start = regs->phys_addr;
1090 rp->end = rp->start + regs->reg_size - 1;
1091 rp->flags = IORESOURCE_IO | (regs->which_io & 0xff);
1092
1093 return amd7930_attach_common(rp, irqp->pri);
1094}
1095
1096static int __devinit amd7930_sbus_probe(struct of_device *dev, const struct of_device_id *match)
1097{
1098 struct sbus_dev *sdev = to_sbus_device(&dev->dev);
1099
1100 return amd7930_attach_common(&sdev->resource[0], sdev->irqs[0]);
1101}
1102
1103static struct of_device_id amd7930_match[] = {
1104 { 1059 {
1105 .name = "audio", 1060 .name = "audio",
1106 }, 1061 },
@@ -1115,20 +1070,7 @@ static struct of_platform_driver amd7930_sbus_driver = {
1115 1070
1116static int __init amd7930_init(void) 1071static int __init amd7930_init(void)
1117{ 1072{
1118 struct device_node *dp; 1073 return of_register_driver(&amd7930_sbus_driver, &of_bus_type);
1119
1120 /* Try to find the sun4c "audio" node first. */
1121 dp = of_find_node_by_path("/");
1122 dp = dp->child;
1123 while (dp) {
1124 if (!strcmp(dp->name, "audio"))
1125 amd7930_obio_attach(dp);
1126
1127 dp = dp->sibling;
1128 }
1129
1130 /* Probe each SBUS for amd7930 chips. */
1131 return of_register_driver(&amd7930_sbus_driver, &sbus_bus_type);
1132} 1074}
1133 1075
1134static void __exit amd7930_exit(void) 1076static void __exit amd7930_exit(void)
diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c
index 1c4797be72ee..d44bf98e965e 100644
--- a/sound/sparc/cs4231.c
+++ b/sound/sparc/cs4231.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Driver for CS4231 sound chips found on Sparcs. 2 * Driver for CS4231 sound chips found on Sparcs.
3 * Copyright (C) 2002 David S. Miller <davem@redhat.com> 3 * Copyright (C) 2002, 2008 David S. Miller <davem@davemloft.net>
4 * 4 *
5 * Based entirely upon drivers/sbus/audio/cs4231.c which is: 5 * Based entirely upon drivers/sbus/audio/cs4231.c which is:
6 * Copyright (C) 1996, 1997, 1998 Derrick J Brashear (shadow@andrew.cmu.edu) 6 * Copyright (C) 1996, 1997, 1998 Derrick J Brashear (shadow@andrew.cmu.edu)
@@ -17,7 +17,8 @@
17#include <linux/moduleparam.h> 17#include <linux/moduleparam.h>
18#include <linux/irq.h> 18#include <linux/irq.h>
19#include <linux/io.h> 19#include <linux/io.h>
20 20#include <linux/of.h>
21#include <linux/of_device.h>
21 22
22#include <sound/core.h> 23#include <sound/core.h>
23#include <sound/pcm.h> 24#include <sound/pcm.h>
@@ -29,13 +30,12 @@
29 30
30#ifdef CONFIG_SBUS 31#ifdef CONFIG_SBUS
31#define SBUS_SUPPORT 32#define SBUS_SUPPORT
32#include <asm/sbus.h>
33#endif 33#endif
34 34
35#if defined(CONFIG_PCI) && defined(CONFIG_SPARC64) 35#if defined(CONFIG_PCI) && defined(CONFIG_SPARC64)
36#define EBUS_SUPPORT 36#define EBUS_SUPPORT
37#include <linux/pci.h> 37#include <linux/pci.h>
38#include <asm/ebus.h> 38#include <asm/ebus_dma.h>
39#endif 39#endif
40 40
41static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ 41static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
@@ -70,8 +70,6 @@ struct cs4231_dma_control {
70 int (*request)(struct cs4231_dma_control *dma_cont, 70 int (*request)(struct cs4231_dma_control *dma_cont,
71 dma_addr_t bus_addr, size_t len); 71 dma_addr_t bus_addr, size_t len);
72 unsigned int (*address)(struct cs4231_dma_control *dma_cont); 72 unsigned int (*address)(struct cs4231_dma_control *dma_cont);
73 void (*preallocate)(struct snd_cs4231 *chip,
74 struct snd_pcm *pcm);
75#ifdef EBUS_SUPPORT 73#ifdef EBUS_SUPPORT
76 struct ebus_dma_info ebus_info; 74 struct ebus_dma_info ebus_info;
77#endif 75#endif
@@ -114,21 +112,12 @@ struct snd_cs4231 {
114 struct mutex mce_mutex; /* mutex for mce register */ 112 struct mutex mce_mutex; /* mutex for mce register */
115 struct mutex open_mutex; /* mutex for ALSA open/close */ 113 struct mutex open_mutex; /* mutex for ALSA open/close */
116 114
117 union { 115 struct of_device *op;
118#ifdef SBUS_SUPPORT
119 struct sbus_dev *sdev;
120#endif
121#ifdef EBUS_SUPPORT
122 struct pci_dev *pdev;
123#endif
124 } dev_u;
125 unsigned int irq[2]; 116 unsigned int irq[2];
126 unsigned int regs_size; 117 unsigned int regs_size;
127 struct snd_cs4231 *next; 118 struct snd_cs4231 *next;
128}; 119};
129 120
130static struct snd_cs4231 *cs4231_list;
131
132/* Eventually we can use sound/isa/cs423x/cs4231_lib.c directly, but for 121/* Eventually we can use sound/isa/cs423x/cs4231_lib.c directly, but for
133 * now.... -DaveM 122 * now.... -DaveM
134 */ 123 */
@@ -267,27 +256,19 @@ static unsigned char snd_cs4231_original_image[32] =
267 256
268static u8 __cs4231_readb(struct snd_cs4231 *cp, void __iomem *reg_addr) 257static u8 __cs4231_readb(struct snd_cs4231 *cp, void __iomem *reg_addr)
269{ 258{
270#ifdef EBUS_SUPPORT
271 if (cp->flags & CS4231_FLAG_EBUS) 259 if (cp->flags & CS4231_FLAG_EBUS)
272 return readb(reg_addr); 260 return readb(reg_addr);
273 else 261 else
274#endif
275#ifdef SBUS_SUPPORT
276 return sbus_readb(reg_addr); 262 return sbus_readb(reg_addr);
277#endif
278} 263}
279 264
280static void __cs4231_writeb(struct snd_cs4231 *cp, u8 val, 265static void __cs4231_writeb(struct snd_cs4231 *cp, u8 val,
281 void __iomem *reg_addr) 266 void __iomem *reg_addr)
282{ 267{
283#ifdef EBUS_SUPPORT
284 if (cp->flags & CS4231_FLAG_EBUS) 268 if (cp->flags & CS4231_FLAG_EBUS)
285 return writeb(val, reg_addr); 269 return writeb(val, reg_addr);
286 else 270 else
287#endif
288#ifdef SBUS_SUPPORT
289 return sbus_writeb(val, reg_addr); 271 return sbus_writeb(val, reg_addr);
290#endif
291} 272}
292 273
293/* 274/*
@@ -1258,7 +1239,9 @@ static int __init snd_cs4231_pcm(struct snd_card *card)
1258 pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX; 1239 pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
1259 strcpy(pcm->name, "CS4231"); 1240 strcpy(pcm->name, "CS4231");
1260 1241
1261 chip->p_dma.preallocate(chip, pcm); 1242 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1243 &chip->op->dev,
1244 64 * 1024, 128 * 1024);
1262 1245
1263 chip->pcm = pcm; 1246 chip->pcm = pcm;
1264 1247
@@ -1560,7 +1543,8 @@ static int __init snd_cs4231_mixer(struct snd_card *card)
1560 struct snd_cs4231 *chip = card->private_data; 1543 struct snd_cs4231 *chip = card->private_data;
1561 int err, idx; 1544 int err, idx;
1562 1545
1563 snd_assert(chip != NULL && chip->pcm != NULL, return -EINVAL); 1546 if (snd_BUG_ON(!chip || !chip->pcm))
1547 return -EINVAL;
1564 1548
1565 strcpy(card->mixername, chip->pcm->name); 1549 strcpy(card->mixername, chip->pcm->name);
1566 1550
@@ -1626,8 +1610,7 @@ static int __init cs4231_attach_finish(struct snd_card *card)
1626 if (err < 0) 1610 if (err < 0)
1627 goto out_err; 1611 goto out_err;
1628 1612
1629 chip->next = cs4231_list; 1613 dev_set_drvdata(&chip->op->dev, chip);
1630 cs4231_list = chip;
1631 1614
1632 dev++; 1615 dev++;
1633 return 0; 1616 return 0;
@@ -1782,24 +1765,19 @@ static unsigned int sbus_dma_addr(struct cs4231_dma_control *dma_cont)
1782 return sbus_readl(base->regs + base->dir + APCVA); 1765 return sbus_readl(base->regs + base->dir + APCVA);
1783} 1766}
1784 1767
1785static void sbus_dma_preallocate(struct snd_cs4231 *chip, struct snd_pcm *pcm)
1786{
1787 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_SBUS,
1788 snd_dma_sbus_data(chip->dev_u.sdev),
1789 64 * 1024, 128 * 1024);
1790}
1791
1792/* 1768/*
1793 * Init and exit routines 1769 * Init and exit routines
1794 */ 1770 */
1795 1771
1796static int snd_cs4231_sbus_free(struct snd_cs4231 *chip) 1772static int snd_cs4231_sbus_free(struct snd_cs4231 *chip)
1797{ 1773{
1774 struct of_device *op = chip->op;
1775
1798 if (chip->irq[0]) 1776 if (chip->irq[0])
1799 free_irq(chip->irq[0], chip); 1777 free_irq(chip->irq[0], chip);
1800 1778
1801 if (chip->port) 1779 if (chip->port)
1802 sbus_iounmap(chip->port, chip->regs_size); 1780 of_iounmap(&op->resource[0], chip->port, chip->regs_size);
1803 1781
1804 return 0; 1782 return 0;
1805} 1783}
@@ -1816,7 +1794,7 @@ static struct snd_device_ops snd_cs4231_sbus_dev_ops = {
1816}; 1794};
1817 1795
1818static int __init snd_cs4231_sbus_create(struct snd_card *card, 1796static int __init snd_cs4231_sbus_create(struct snd_card *card,
1819 struct sbus_dev *sdev, 1797 struct of_device *op,
1820 int dev) 1798 int dev)
1821{ 1799{
1822 struct snd_cs4231 *chip = card->private_data; 1800 struct snd_cs4231 *chip = card->private_data;
@@ -1827,13 +1805,13 @@ static int __init snd_cs4231_sbus_create(struct snd_card *card,
1827 spin_lock_init(&chip->p_dma.sbus_info.lock); 1805 spin_lock_init(&chip->p_dma.sbus_info.lock);
1828 mutex_init(&chip->mce_mutex); 1806 mutex_init(&chip->mce_mutex);
1829 mutex_init(&chip->open_mutex); 1807 mutex_init(&chip->open_mutex);
1830 chip->dev_u.sdev = sdev; 1808 chip->op = op;
1831 chip->regs_size = sdev->reg_addrs[0].reg_size; 1809 chip->regs_size = resource_size(&op->resource[0]);
1832 memcpy(&chip->image, &snd_cs4231_original_image, 1810 memcpy(&chip->image, &snd_cs4231_original_image,
1833 sizeof(snd_cs4231_original_image)); 1811 sizeof(snd_cs4231_original_image));
1834 1812
1835 chip->port = sbus_ioremap(&sdev->resource[0], 0, 1813 chip->port = of_ioremap(&op->resource[0], 0,
1836 chip->regs_size, "cs4231"); 1814 chip->regs_size, "cs4231");
1837 if (!chip->port) { 1815 if (!chip->port) {
1838 snd_printdd("cs4231-%d: Unable to map chip registers.\n", dev); 1816 snd_printdd("cs4231-%d: Unable to map chip registers.\n", dev);
1839 return -EIO; 1817 return -EIO;
@@ -1848,22 +1826,20 @@ static int __init snd_cs4231_sbus_create(struct snd_card *card,
1848 chip->p_dma.enable = sbus_dma_enable; 1826 chip->p_dma.enable = sbus_dma_enable;
1849 chip->p_dma.request = sbus_dma_request; 1827 chip->p_dma.request = sbus_dma_request;
1850 chip->p_dma.address = sbus_dma_addr; 1828 chip->p_dma.address = sbus_dma_addr;
1851 chip->p_dma.preallocate = sbus_dma_preallocate;
1852 1829
1853 chip->c_dma.prepare = sbus_dma_prepare; 1830 chip->c_dma.prepare = sbus_dma_prepare;
1854 chip->c_dma.enable = sbus_dma_enable; 1831 chip->c_dma.enable = sbus_dma_enable;
1855 chip->c_dma.request = sbus_dma_request; 1832 chip->c_dma.request = sbus_dma_request;
1856 chip->c_dma.address = sbus_dma_addr; 1833 chip->c_dma.address = sbus_dma_addr;
1857 chip->c_dma.preallocate = sbus_dma_preallocate;
1858 1834
1859 if (request_irq(sdev->irqs[0], snd_cs4231_sbus_interrupt, 1835 if (request_irq(op->irqs[0], snd_cs4231_sbus_interrupt,
1860 IRQF_SHARED, "cs4231", chip)) { 1836 IRQF_SHARED, "cs4231", chip)) {
1861 snd_printdd("cs4231-%d: Unable to grab SBUS IRQ %d\n", 1837 snd_printdd("cs4231-%d: Unable to grab SBUS IRQ %d\n",
1862 dev, sdev->irqs[0]); 1838 dev, op->irqs[0]);
1863 snd_cs4231_sbus_free(chip); 1839 snd_cs4231_sbus_free(chip);
1864 return -EBUSY; 1840 return -EBUSY;
1865 } 1841 }
1866 chip->irq[0] = sdev->irqs[0]; 1842 chip->irq[0] = op->irqs[0];
1867 1843
1868 if (snd_cs4231_probe(chip) < 0) { 1844 if (snd_cs4231_probe(chip) < 0) {
1869 snd_cs4231_sbus_free(chip); 1845 snd_cs4231_sbus_free(chip);
@@ -1880,9 +1856,9 @@ static int __init snd_cs4231_sbus_create(struct snd_card *card,
1880 return 0; 1856 return 0;
1881} 1857}
1882 1858
1883static int __init cs4231_sbus_attach(struct sbus_dev *sdev) 1859static int __devinit cs4231_sbus_probe(struct of_device *op, const struct of_device_id *match)
1884{ 1860{
1885 struct resource *rp = &sdev->resource[0]; 1861 struct resource *rp = &op->resource[0];
1886 struct snd_card *card; 1862 struct snd_card *card;
1887 int err; 1863 int err;
1888 1864
@@ -1894,9 +1870,9 @@ static int __init cs4231_sbus_attach(struct sbus_dev *sdev)
1894 card->shortname, 1870 card->shortname,
1895 rp->flags & 0xffL, 1871 rp->flags & 0xffL,
1896 (unsigned long long)rp->start, 1872 (unsigned long long)rp->start,
1897 sdev->irqs[0]); 1873 op->irqs[0]);
1898 1874
1899 err = snd_cs4231_sbus_create(card, sdev, dev); 1875 err = snd_cs4231_sbus_create(card, op, dev);
1900 if (err < 0) { 1876 if (err < 0) {
1901 snd_card_free(card); 1877 snd_card_free(card);
1902 return err; 1878 return err;
@@ -1949,30 +1925,25 @@ static unsigned int _ebus_dma_addr(struct cs4231_dma_control *dma_cont)
1949 return ebus_dma_addr(&dma_cont->ebus_info); 1925 return ebus_dma_addr(&dma_cont->ebus_info);
1950} 1926}
1951 1927
1952static void _ebus_dma_preallocate(struct snd_cs4231 *chip, struct snd_pcm *pcm)
1953{
1954 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1955 snd_dma_pci_data(chip->dev_u.pdev),
1956 64*1024, 128*1024);
1957}
1958
1959/* 1928/*
1960 * Init and exit routines 1929 * Init and exit routines
1961 */ 1930 */
1962 1931
1963static int snd_cs4231_ebus_free(struct snd_cs4231 *chip) 1932static int snd_cs4231_ebus_free(struct snd_cs4231 *chip)
1964{ 1933{
1934 struct of_device *op = chip->op;
1935
1965 if (chip->c_dma.ebus_info.regs) { 1936 if (chip->c_dma.ebus_info.regs) {
1966 ebus_dma_unregister(&chip->c_dma.ebus_info); 1937 ebus_dma_unregister(&chip->c_dma.ebus_info);
1967 iounmap(chip->c_dma.ebus_info.regs); 1938 of_iounmap(&op->resource[2], chip->c_dma.ebus_info.regs, 0x10);
1968 } 1939 }
1969 if (chip->p_dma.ebus_info.regs) { 1940 if (chip->p_dma.ebus_info.regs) {
1970 ebus_dma_unregister(&chip->p_dma.ebus_info); 1941 ebus_dma_unregister(&chip->p_dma.ebus_info);
1971 iounmap(chip->p_dma.ebus_info.regs); 1942 of_iounmap(&op->resource[1], chip->p_dma.ebus_info.regs, 0x10);
1972 } 1943 }
1973 1944
1974 if (chip->port) 1945 if (chip->port)
1975 iounmap(chip->port); 1946 of_iounmap(&op->resource[0], chip->port, 0x10);
1976 1947
1977 return 0; 1948 return 0;
1978} 1949}
@@ -1989,7 +1960,7 @@ static struct snd_device_ops snd_cs4231_ebus_dev_ops = {
1989}; 1960};
1990 1961
1991static int __init snd_cs4231_ebus_create(struct snd_card *card, 1962static int __init snd_cs4231_ebus_create(struct snd_card *card,
1992 struct linux_ebus_device *edev, 1963 struct of_device *op,
1993 int dev) 1964 int dev)
1994{ 1965{
1995 struct snd_cs4231 *chip = card->private_data; 1966 struct snd_cs4231 *chip = card->private_data;
@@ -2001,35 +1972,35 @@ static int __init snd_cs4231_ebus_create(struct snd_card *card,
2001 mutex_init(&chip->mce_mutex); 1972 mutex_init(&chip->mce_mutex);
2002 mutex_init(&chip->open_mutex); 1973 mutex_init(&chip->open_mutex);
2003 chip->flags |= CS4231_FLAG_EBUS; 1974 chip->flags |= CS4231_FLAG_EBUS;
2004 chip->dev_u.pdev = edev->bus->self; 1975 chip->op = op;
2005 memcpy(&chip->image, &snd_cs4231_original_image, 1976 memcpy(&chip->image, &snd_cs4231_original_image,
2006 sizeof(snd_cs4231_original_image)); 1977 sizeof(snd_cs4231_original_image));
2007 strcpy(chip->c_dma.ebus_info.name, "cs4231(capture)"); 1978 strcpy(chip->c_dma.ebus_info.name, "cs4231(capture)");
2008 chip->c_dma.ebus_info.flags = EBUS_DMA_FLAG_USE_EBDMA_HANDLER; 1979 chip->c_dma.ebus_info.flags = EBUS_DMA_FLAG_USE_EBDMA_HANDLER;
2009 chip->c_dma.ebus_info.callback = snd_cs4231_ebus_capture_callback; 1980 chip->c_dma.ebus_info.callback = snd_cs4231_ebus_capture_callback;
2010 chip->c_dma.ebus_info.client_cookie = chip; 1981 chip->c_dma.ebus_info.client_cookie = chip;
2011 chip->c_dma.ebus_info.irq = edev->irqs[0]; 1982 chip->c_dma.ebus_info.irq = op->irqs[0];
2012 strcpy(chip->p_dma.ebus_info.name, "cs4231(play)"); 1983 strcpy(chip->p_dma.ebus_info.name, "cs4231(play)");
2013 chip->p_dma.ebus_info.flags = EBUS_DMA_FLAG_USE_EBDMA_HANDLER; 1984 chip->p_dma.ebus_info.flags = EBUS_DMA_FLAG_USE_EBDMA_HANDLER;
2014 chip->p_dma.ebus_info.callback = snd_cs4231_ebus_play_callback; 1985 chip->p_dma.ebus_info.callback = snd_cs4231_ebus_play_callback;
2015 chip->p_dma.ebus_info.client_cookie = chip; 1986 chip->p_dma.ebus_info.client_cookie = chip;
2016 chip->p_dma.ebus_info.irq = edev->irqs[1]; 1987 chip->p_dma.ebus_info.irq = op->irqs[1];
2017 1988
2018 chip->p_dma.prepare = _ebus_dma_prepare; 1989 chip->p_dma.prepare = _ebus_dma_prepare;
2019 chip->p_dma.enable = _ebus_dma_enable; 1990 chip->p_dma.enable = _ebus_dma_enable;
2020 chip->p_dma.request = _ebus_dma_request; 1991 chip->p_dma.request = _ebus_dma_request;
2021 chip->p_dma.address = _ebus_dma_addr; 1992 chip->p_dma.address = _ebus_dma_addr;
2022 chip->p_dma.preallocate = _ebus_dma_preallocate;
2023 1993
2024 chip->c_dma.prepare = _ebus_dma_prepare; 1994 chip->c_dma.prepare = _ebus_dma_prepare;
2025 chip->c_dma.enable = _ebus_dma_enable; 1995 chip->c_dma.enable = _ebus_dma_enable;
2026 chip->c_dma.request = _ebus_dma_request; 1996 chip->c_dma.request = _ebus_dma_request;
2027 chip->c_dma.address = _ebus_dma_addr; 1997 chip->c_dma.address = _ebus_dma_addr;
2028 chip->c_dma.preallocate = _ebus_dma_preallocate;
2029 1998
2030 chip->port = ioremap(edev->resource[0].start, 0x10); 1999 chip->port = of_ioremap(&op->resource[0], 0, 0x10, "cs4231");
2031 chip->p_dma.ebus_info.regs = ioremap(edev->resource[1].start, 0x10); 2000 chip->p_dma.ebus_info.regs =
2032 chip->c_dma.ebus_info.regs = ioremap(edev->resource[2].start, 0x10); 2001 of_ioremap(&op->resource[1], 0, 0x10, "cs4231_pdma");
2002 chip->c_dma.ebus_info.regs =
2003 of_ioremap(&op->resource[2], 0, 0x10, "cs4231_cdma");
2033 if (!chip->port || !chip->p_dma.ebus_info.regs || 2004 if (!chip->port || !chip->p_dma.ebus_info.regs ||
2034 !chip->c_dma.ebus_info.regs) { 2005 !chip->c_dma.ebus_info.regs) {
2035 snd_cs4231_ebus_free(chip); 2006 snd_cs4231_ebus_free(chip);
@@ -2077,7 +2048,7 @@ static int __init snd_cs4231_ebus_create(struct snd_card *card,
2077 return 0; 2048 return 0;
2078} 2049}
2079 2050
2080static int __init cs4231_ebus_attach(struct linux_ebus_device *edev) 2051static int __devinit cs4231_ebus_probe(struct of_device *op, const struct of_device_id *match)
2081{ 2052{
2082 struct snd_card *card; 2053 struct snd_card *card;
2083 int err; 2054 int err;
@@ -2088,10 +2059,10 @@ static int __init cs4231_ebus_attach(struct linux_ebus_device *edev)
2088 2059
2089 sprintf(card->longname, "%s at 0x%lx, irq %d", 2060 sprintf(card->longname, "%s at 0x%lx, irq %d",
2090 card->shortname, 2061 card->shortname,
2091 edev->resource[0].start, 2062 op->resource[0].start,
2092 edev->irqs[0]); 2063 op->irqs[0]);
2093 2064
2094 err = snd_cs4231_ebus_create(card, edev, dev); 2065 err = snd_cs4231_ebus_create(card, op, dev);
2095 if (err < 0) { 2066 if (err < 0) {
2096 snd_card_free(card); 2067 snd_card_free(card);
2097 return err; 2068 return err;
@@ -2101,68 +2072,57 @@ static int __init cs4231_ebus_attach(struct linux_ebus_device *edev)
2101} 2072}
2102#endif 2073#endif
2103 2074
2104static int __init cs4231_init(void) 2075static int __devinit cs4231_probe(struct of_device *op, const struct of_device_id *match)
2105{ 2076{
2106#ifdef SBUS_SUPPORT
2107 struct sbus_bus *sbus;
2108 struct sbus_dev *sdev;
2109#endif
2110#ifdef EBUS_SUPPORT 2077#ifdef EBUS_SUPPORT
2111 struct linux_ebus *ebus; 2078 if (!strcmp(op->node->parent->name, "ebus"))
2112 struct linux_ebus_device *edev; 2079 return cs4231_ebus_probe(op, match);
2113#endif 2080#endif
2114 int found;
2115
2116 found = 0;
2117
2118#ifdef SBUS_SUPPORT 2081#ifdef SBUS_SUPPORT
2119 for_all_sbusdev(sdev, sbus) { 2082 if (!strcmp(op->node->parent->name, "sbus") ||
2120 if (!strcmp(sdev->prom_name, "SUNW,CS4231")) { 2083 !strcmp(op->node->parent->name, "sbi"))
2121 if (cs4231_sbus_attach(sdev) == 0) 2084 return cs4231_sbus_probe(op, match);
2122 found++;
2123 }
2124 }
2125#endif 2085#endif
2126#ifdef EBUS_SUPPORT 2086 return -ENODEV;
2127 for_each_ebus(ebus) { 2087}
2128 for_each_ebusdev(edev, ebus) {
2129 int match = 0;
2130
2131 if (!strcmp(edev->prom_node->name, "SUNW,CS4231")) {
2132 match = 1;
2133 } else if (!strcmp(edev->prom_node->name, "audio")) {
2134 const char *compat;
2135
2136 compat = of_get_property(edev->prom_node,
2137 "compatible", NULL);
2138 if (compat && !strcmp(compat, "SUNW,CS4231"))
2139 match = 1;
2140 }
2141 2088
2142 if (match && 2089static int __devexit cs4231_remove(struct of_device *op)
2143 cs4231_ebus_attach(edev) == 0) 2090{
2144 found++; 2091 struct snd_cs4231 *chip = dev_get_drvdata(&op->dev);
2145 }
2146 }
2147#endif
2148 2092
2093 snd_card_free(chip->card);
2149 2094
2150 return (found > 0) ? 0 : -EIO; 2095 return 0;
2151} 2096}
2152 2097
2153static void __exit cs4231_exit(void) 2098static const struct of_device_id cs4231_match[] = {
2154{ 2099 {
2155 struct snd_cs4231 *p = cs4231_list; 2100 .name = "SUNW,CS4231",
2101 },
2102 {
2103 .name = "audio",
2104 .compatible = "SUNW,CS4231",
2105 },
2106 {},
2107};
2156 2108
2157 while (p != NULL) { 2109MODULE_DEVICE_TABLE(of, cs4231_match);
2158 struct snd_cs4231 *next = p->next;
2159 2110
2160 snd_card_free(p->card); 2111static struct of_platform_driver cs4231_driver = {
2112 .name = "audio",
2113 .match_table = cs4231_match,
2114 .probe = cs4231_probe,
2115 .remove = __devexit_p(cs4231_remove),
2116};
2161 2117
2162 p = next; 2118static int __init cs4231_init(void)
2163 } 2119{
2120 return of_register_driver(&cs4231_driver, &of_bus_type);
2121}
2164 2122
2165 cs4231_list = NULL; 2123static void __exit cs4231_exit(void)
2124{
2125 of_unregister_driver(&cs4231_driver);
2166} 2126}
2167 2127
2168module_init(cs4231_init); 2128module_init(cs4231_init);
diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c
index ee2e1b4f3551..c257ad8bdfbc 100644
--- a/sound/sparc/dbri.c
+++ b/sound/sparc/dbri.c
@@ -57,6 +57,7 @@
57#include <linux/delay.h> 57#include <linux/delay.h>
58#include <linux/irq.h> 58#include <linux/irq.h>
59#include <linux/io.h> 59#include <linux/io.h>
60#include <linux/dma-mapping.h>
60 61
61#include <sound/core.h> 62#include <sound/core.h>
62#include <sound/pcm.h> 63#include <sound/pcm.h>
@@ -66,7 +67,7 @@
66#include <sound/initval.h> 67#include <sound/initval.h>
67 68
68#include <linux/of.h> 69#include <linux/of.h>
69#include <asm/sbus.h> 70#include <linux/of_device.h>
70#include <asm/atomic.h> 71#include <asm/atomic.h>
71 72
72MODULE_AUTHOR("Rudolf Koenig, Brent Baccala and Martin Habets"); 73MODULE_AUTHOR("Rudolf Koenig, Brent Baccala and Martin Habets");
@@ -297,7 +298,7 @@ struct dbri_streaminfo {
297/* This structure holds the information for both chips (DBRI & CS4215) */ 298/* This structure holds the information for both chips (DBRI & CS4215) */
298struct snd_dbri { 299struct snd_dbri {
299 int regs_size, irq; /* Needed for unload */ 300 int regs_size, irq; /* Needed for unload */
300 struct sbus_dev *sdev; /* SBUS device info */ 301 struct of_device *op; /* OF device info */
301 spinlock_t lock; 302 spinlock_t lock;
302 303
303 struct dbri_dma *dma; /* Pointer to our DMA block */ 304 struct dbri_dma *dma; /* Pointer to our DMA block */
@@ -2093,14 +2094,15 @@ static int snd_dbri_hw_params(struct snd_pcm_substream *substream,
2093 */ 2094 */
2094 if (info->dvma_buffer == 0) { 2095 if (info->dvma_buffer == 0) {
2095 if (DBRI_STREAMNO(substream) == DBRI_PLAY) 2096 if (DBRI_STREAMNO(substream) == DBRI_PLAY)
2096 direction = SBUS_DMA_TODEVICE; 2097 direction = DMA_TO_DEVICE;
2097 else 2098 else
2098 direction = SBUS_DMA_FROMDEVICE; 2099 direction = DMA_FROM_DEVICE;
2099 2100
2100 info->dvma_buffer = sbus_map_single(dbri->sdev, 2101 info->dvma_buffer =
2101 runtime->dma_area, 2102 dma_map_single(&dbri->op->dev,
2102 params_buffer_bytes(hw_params), 2103 runtime->dma_area,
2103 direction); 2104 params_buffer_bytes(hw_params),
2105 direction);
2104 } 2106 }
2105 2107
2106 direction = params_buffer_bytes(hw_params); 2108 direction = params_buffer_bytes(hw_params);
@@ -2121,12 +2123,12 @@ static int snd_dbri_hw_free(struct snd_pcm_substream *substream)
2121 */ 2123 */
2122 if (info->dvma_buffer) { 2124 if (info->dvma_buffer) {
2123 if (DBRI_STREAMNO(substream) == DBRI_PLAY) 2125 if (DBRI_STREAMNO(substream) == DBRI_PLAY)
2124 direction = SBUS_DMA_TODEVICE; 2126 direction = DMA_TO_DEVICE;
2125 else 2127 else
2126 direction = SBUS_DMA_FROMDEVICE; 2128 direction = DMA_FROM_DEVICE;
2127 2129
2128 sbus_unmap_single(dbri->sdev, info->dvma_buffer, 2130 dma_unmap_single(&dbri->op->dev, info->dvma_buffer,
2129 substream->runtime->buffer_size, direction); 2131 substream->runtime->buffer_size, direction);
2130 info->dvma_buffer = 0; 2132 info->dvma_buffer = 0;
2131 } 2133 }
2132 if (info->pipe != -1) { 2134 if (info->pipe != -1) {
@@ -2223,7 +2225,6 @@ static int __devinit snd_dbri_pcm(struct snd_card *card)
2223 /* playback count */ 1, 2225 /* playback count */ 1,
2224 /* capture count */ 1, &pcm)) < 0) 2226 /* capture count */ 1, &pcm)) < 0)
2225 return err; 2227 return err;
2226 snd_assert(pcm != NULL, return -EINVAL);
2227 2228
2228 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_dbri_ops); 2229 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_dbri_ops);
2229 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_dbri_ops); 2230 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_dbri_ops);
@@ -2263,9 +2264,10 @@ static int snd_cs4215_get_volume(struct snd_kcontrol *kcontrol,
2263{ 2264{
2264 struct snd_dbri *dbri = snd_kcontrol_chip(kcontrol); 2265 struct snd_dbri *dbri = snd_kcontrol_chip(kcontrol);
2265 struct dbri_streaminfo *info; 2266 struct dbri_streaminfo *info;
2266 snd_assert(dbri != NULL, return -EINVAL); 2267
2268 if (snd_BUG_ON(!dbri))
2269 return -EINVAL;
2267 info = &dbri->stream_info[kcontrol->private_value]; 2270 info = &dbri->stream_info[kcontrol->private_value];
2268 snd_assert(info != NULL, return -EINVAL);
2269 2271
2270 ucontrol->value.integer.value[0] = info->left_gain; 2272 ucontrol->value.integer.value[0] = info->left_gain;
2271 ucontrol->value.integer.value[1] = info->right_gain; 2273 ucontrol->value.integer.value[1] = info->right_gain;
@@ -2331,7 +2333,9 @@ static int snd_cs4215_get_single(struct snd_kcontrol *kcontrol,
2331 int shift = (kcontrol->private_value >> 8) & 0xff; 2333 int shift = (kcontrol->private_value >> 8) & 0xff;
2332 int mask = (kcontrol->private_value >> 16) & 0xff; 2334 int mask = (kcontrol->private_value >> 16) & 0xff;
2333 int invert = (kcontrol->private_value >> 24) & 1; 2335 int invert = (kcontrol->private_value >> 24) & 1;
2334 snd_assert(dbri != NULL, return -EINVAL); 2336
2337 if (snd_BUG_ON(!dbri))
2338 return -EINVAL;
2335 2339
2336 if (elem < 4) 2340 if (elem < 4)
2337 ucontrol->value.integer.value[0] = 2341 ucontrol->value.integer.value[0] =
@@ -2356,7 +2360,9 @@ static int snd_cs4215_put_single(struct snd_kcontrol *kcontrol,
2356 int invert = (kcontrol->private_value >> 24) & 1; 2360 int invert = (kcontrol->private_value >> 24) & 1;
2357 int changed = 0; 2361 int changed = 0;
2358 unsigned short val; 2362 unsigned short val;
2359 snd_assert(dbri != NULL, return -EINVAL); 2363
2364 if (snd_BUG_ON(!dbri))
2365 return -EINVAL;
2360 2366
2361 val = (ucontrol->value.integer.value[0] & mask); 2367 val = (ucontrol->value.integer.value[0] & mask);
2362 if (invert == 1) 2368 if (invert == 1)
@@ -2432,7 +2438,8 @@ static int __devinit snd_dbri_mixer(struct snd_card *card)
2432 int idx, err; 2438 int idx, err;
2433 struct snd_dbri *dbri; 2439 struct snd_dbri *dbri;
2434 2440
2435 snd_assert(card != NULL && card->private_data != NULL, return -EINVAL); 2441 if (snd_BUG_ON(!card || !card->private_data))
2442 return -EINVAL;
2436 dbri = card->private_data; 2443 dbri = card->private_data;
2437 2444
2438 strcpy(card->mixername, card->shortname); 2445 strcpy(card->mixername, card->shortname);
@@ -2514,31 +2521,32 @@ static void __devinit snd_dbri_proc(struct snd_card *card)
2514static void snd_dbri_free(struct snd_dbri *dbri); 2521static void snd_dbri_free(struct snd_dbri *dbri);
2515 2522
2516static int __devinit snd_dbri_create(struct snd_card *card, 2523static int __devinit snd_dbri_create(struct snd_card *card,
2517 struct sbus_dev *sdev, 2524 struct of_device *op,
2518 int irq, int dev) 2525 int irq, int dev)
2519{ 2526{
2520 struct snd_dbri *dbri = card->private_data; 2527 struct snd_dbri *dbri = card->private_data;
2521 int err; 2528 int err;
2522 2529
2523 spin_lock_init(&dbri->lock); 2530 spin_lock_init(&dbri->lock);
2524 dbri->sdev = sdev; 2531 dbri->op = op;
2525 dbri->irq = irq; 2532 dbri->irq = irq;
2526 2533
2527 dbri->dma = sbus_alloc_consistent(sdev, sizeof(struct dbri_dma), 2534 dbri->dma = dma_alloc_coherent(&op->dev,
2528 &dbri->dma_dvma); 2535 sizeof(struct dbri_dma),
2536 &dbri->dma_dvma, GFP_ATOMIC);
2529 memset((void *)dbri->dma, 0, sizeof(struct dbri_dma)); 2537 memset((void *)dbri->dma, 0, sizeof(struct dbri_dma));
2530 2538
2531 dprintk(D_GEN, "DMA Cmd Block 0x%p (0x%08x)\n", 2539 dprintk(D_GEN, "DMA Cmd Block 0x%p (0x%08x)\n",
2532 dbri->dma, dbri->dma_dvma); 2540 dbri->dma, dbri->dma_dvma);
2533 2541
2534 /* Map the registers into memory. */ 2542 /* Map the registers into memory. */
2535 dbri->regs_size = sdev->reg_addrs[0].reg_size; 2543 dbri->regs_size = resource_size(&op->resource[0]);
2536 dbri->regs = sbus_ioremap(&sdev->resource[0], 0, 2544 dbri->regs = of_ioremap(&op->resource[0], 0,
2537 dbri->regs_size, "DBRI Registers"); 2545 dbri->regs_size, "DBRI Registers");
2538 if (!dbri->regs) { 2546 if (!dbri->regs) {
2539 printk(KERN_ERR "DBRI: could not allocate registers\n"); 2547 printk(KERN_ERR "DBRI: could not allocate registers\n");
2540 sbus_free_consistent(sdev, sizeof(struct dbri_dma), 2548 dma_free_coherent(&op->dev, sizeof(struct dbri_dma),
2541 (void *)dbri->dma, dbri->dma_dvma); 2549 (void *)dbri->dma, dbri->dma_dvma);
2542 return -EIO; 2550 return -EIO;
2543 } 2551 }
2544 2552
@@ -2546,9 +2554,9 @@ static int __devinit snd_dbri_create(struct snd_card *card,
2546 "DBRI audio", dbri); 2554 "DBRI audio", dbri);
2547 if (err) { 2555 if (err) {
2548 printk(KERN_ERR "DBRI: Can't get irq %d\n", dbri->irq); 2556 printk(KERN_ERR "DBRI: Can't get irq %d\n", dbri->irq);
2549 sbus_iounmap(dbri->regs, dbri->regs_size); 2557 of_iounmap(&op->resource[0], dbri->regs, dbri->regs_size);
2550 sbus_free_consistent(sdev, sizeof(struct dbri_dma), 2558 dma_free_coherent(&op->dev, sizeof(struct dbri_dma),
2551 (void *)dbri->dma, dbri->dma_dvma); 2559 (void *)dbri->dma, dbri->dma_dvma);
2552 return err; 2560 return err;
2553 } 2561 }
2554 2562
@@ -2572,27 +2580,23 @@ static void snd_dbri_free(struct snd_dbri *dbri)
2572 free_irq(dbri->irq, dbri); 2580 free_irq(dbri->irq, dbri);
2573 2581
2574 if (dbri->regs) 2582 if (dbri->regs)
2575 sbus_iounmap(dbri->regs, dbri->regs_size); 2583 of_iounmap(&dbri->op->resource[0], dbri->regs, dbri->regs_size);
2576 2584
2577 if (dbri->dma) 2585 if (dbri->dma)
2578 sbus_free_consistent(dbri->sdev, sizeof(struct dbri_dma), 2586 dma_free_coherent(&dbri->op->dev,
2579 (void *)dbri->dma, dbri->dma_dvma); 2587 sizeof(struct dbri_dma),
2588 (void *)dbri->dma, dbri->dma_dvma);
2580} 2589}
2581 2590
2582static int __devinit dbri_probe(struct of_device *of_dev, 2591static int __devinit dbri_probe(struct of_device *op, const struct of_device_id *match)
2583 const struct of_device_id *match)
2584{ 2592{
2585 struct sbus_dev *sdev = to_sbus_device(&of_dev->dev);
2586 struct snd_dbri *dbri; 2593 struct snd_dbri *dbri;
2587 int irq;
2588 struct resource *rp; 2594 struct resource *rp;
2589 struct snd_card *card; 2595 struct snd_card *card;
2590 static int dev = 0; 2596 static int dev = 0;
2597 int irq;
2591 int err; 2598 int err;
2592 2599
2593 dprintk(D_GEN, "DBRI: Found %s in SBUS slot %d\n",
2594 sdev->prom_name, sdev->slot);
2595
2596 if (dev >= SNDRV_CARDS) 2600 if (dev >= SNDRV_CARDS)
2597 return -ENODEV; 2601 return -ENODEV;
2598 if (!enable[dev]) { 2602 if (!enable[dev]) {
@@ -2600,7 +2604,7 @@ static int __devinit dbri_probe(struct of_device *of_dev,
2600 return -ENOENT; 2604 return -ENOENT;
2601 } 2605 }
2602 2606
2603 irq = sdev->irqs[0]; 2607 irq = op->irqs[0];
2604 if (irq <= 0) { 2608 if (irq <= 0) {
2605 printk(KERN_ERR "DBRI-%d: No IRQ.\n", dev); 2609 printk(KERN_ERR "DBRI-%d: No IRQ.\n", dev);
2606 return -ENODEV; 2610 return -ENODEV;
@@ -2613,12 +2617,12 @@ static int __devinit dbri_probe(struct of_device *of_dev,
2613 2617
2614 strcpy(card->driver, "DBRI"); 2618 strcpy(card->driver, "DBRI");
2615 strcpy(card->shortname, "Sun DBRI"); 2619 strcpy(card->shortname, "Sun DBRI");
2616 rp = &sdev->resource[0]; 2620 rp = &op->resource[0];
2617 sprintf(card->longname, "%s at 0x%02lx:0x%016Lx, irq %d", 2621 sprintf(card->longname, "%s at 0x%02lx:0x%016Lx, irq %d",
2618 card->shortname, 2622 card->shortname,
2619 rp->flags & 0xffL, (unsigned long long)rp->start, irq); 2623 rp->flags & 0xffL, (unsigned long long)rp->start, irq);
2620 2624
2621 err = snd_dbri_create(card, sdev, irq, dev); 2625 err = snd_dbri_create(card, op, irq, dev);
2622 if (err < 0) { 2626 if (err < 0) {
2623 snd_card_free(card); 2627 snd_card_free(card);
2624 return err; 2628 return err;
@@ -2635,7 +2639,7 @@ static int __devinit dbri_probe(struct of_device *of_dev,
2635 2639
2636 /* /proc file handling */ 2640 /* /proc file handling */
2637 snd_dbri_proc(card); 2641 snd_dbri_proc(card);
2638 dev_set_drvdata(&of_dev->dev, card); 2642 dev_set_drvdata(&op->dev, card);
2639 2643
2640 err = snd_card_register(card); 2644 err = snd_card_register(card);
2641 if (err < 0) 2645 if (err < 0)
@@ -2643,7 +2647,7 @@ static int __devinit dbri_probe(struct of_device *of_dev,
2643 2647
2644 printk(KERN_INFO "audio%d at %p (irq %d) is DBRI(%c)+CS4215(%d)\n", 2648 printk(KERN_INFO "audio%d at %p (irq %d) is DBRI(%c)+CS4215(%d)\n",
2645 dev, dbri->regs, 2649 dev, dbri->regs,
2646 dbri->irq, sdev->prom_name[9], dbri->mm.version); 2650 dbri->irq, op->node->name[9], dbri->mm.version);
2647 dev++; 2651 dev++;
2648 2652
2649 return 0; 2653 return 0;
@@ -2654,19 +2658,19 @@ _err:
2654 return err; 2658 return err;
2655} 2659}
2656 2660
2657static int __devexit dbri_remove(struct of_device *dev) 2661static int __devexit dbri_remove(struct of_device *op)
2658{ 2662{
2659 struct snd_card *card = dev_get_drvdata(&dev->dev); 2663 struct snd_card *card = dev_get_drvdata(&op->dev);
2660 2664
2661 snd_dbri_free(card->private_data); 2665 snd_dbri_free(card->private_data);
2662 snd_card_free(card); 2666 snd_card_free(card);
2663 2667
2664 dev_set_drvdata(&dev->dev, NULL); 2668 dev_set_drvdata(&op->dev, NULL);
2665 2669
2666 return 0; 2670 return 0;
2667} 2671}
2668 2672
2669static struct of_device_id dbri_match[] = { 2673static const struct of_device_id dbri_match[] = {
2670 { 2674 {
2671 .name = "SUNW,DBRIe", 2675 .name = "SUNW,DBRIe",
2672 }, 2676 },
@@ -2688,7 +2692,7 @@ static struct of_platform_driver dbri_sbus_driver = {
2688/* Probe for the dbri chip and then attach the driver. */ 2692/* Probe for the dbri chip and then attach the driver. */
2689static int __init dbri_init(void) 2693static int __init dbri_init(void)
2690{ 2694{
2691 return of_register_driver(&dbri_sbus_driver, &sbus_bus_type); 2695 return of_register_driver(&dbri_sbus_driver, &of_bus_type);
2692} 2696}
2693 2697
2694static void __exit dbri_exit(void) 2698static void __exit dbri_exit(void)
diff --git a/sound/synth/emux/emux.c b/sound/synth/emux/emux.c
index c89d2ea594b9..f16a3fce4597 100644
--- a/sound/synth/emux/emux.c
+++ b/sound/synth/emux/emux.c
@@ -93,10 +93,10 @@ int snd_emux_register(struct snd_emux *emu, struct snd_card *card, int index, ch
93 int err; 93 int err;
94 struct snd_sf_callback sf_cb; 94 struct snd_sf_callback sf_cb;
95 95
96 snd_assert(emu->hw != NULL, return -EINVAL); 96 if (snd_BUG_ON(!emu->hw || emu->max_voices <= 0))
97 snd_assert(emu->max_voices > 0, return -EINVAL); 97 return -EINVAL;
98 snd_assert(card != NULL, return -EINVAL); 98 if (snd_BUG_ON(!card || !name))
99 snd_assert(name != NULL, return -EINVAL); 99 return -EINVAL;
100 100
101 emu->card = card; 101 emu->card = card;
102 emu->name = kstrdup(name, GFP_KERNEL); 102 emu->name = kstrdup(name, GFP_KERNEL);
diff --git a/sound/synth/emux/emux_nrpn.c b/sound/synth/emux/emux_nrpn.c
index c6917ba2c934..00fc005ecf6e 100644
--- a/sound/synth/emux/emux_nrpn.c
+++ b/sound/synth/emux/emux_nrpn.c
@@ -289,8 +289,8 @@ snd_emux_nrpn(void *p, struct snd_midi_channel *chan,
289 struct snd_emux_port *port; 289 struct snd_emux_port *port;
290 290
291 port = p; 291 port = p;
292 snd_assert(port != NULL, return); 292 if (snd_BUG_ON(!port || !chan))
293 snd_assert(chan != NULL, return); 293 return;
294 294
295 if (chan->control[MIDI_CTL_NONREG_PARM_NUM_MSB] == 127 && 295 if (chan->control[MIDI_CTL_NONREG_PARM_NUM_MSB] == 127 &&
296 chan->control[MIDI_CTL_NONREG_PARM_NUM_LSB] <= 26) { 296 chan->control[MIDI_CTL_NONREG_PARM_NUM_LSB] <= 26) {
@@ -379,8 +379,8 @@ snd_emux_sysex(void *p, unsigned char *buf, int len, int parsed,
379 struct snd_emux *emu; 379 struct snd_emux *emu;
380 380
381 port = p; 381 port = p;
382 snd_assert(port != NULL, return); 382 if (snd_BUG_ON(!port || !chset))
383 snd_assert(chset != NULL, return); 383 return;
384 emu = port->emu; 384 emu = port->emu;
385 385
386 switch (parsed) { 386 switch (parsed) {
diff --git a/sound/synth/emux/emux_oss.c b/sound/synth/emux/emux_oss.c
index f60a98ef7dec..5c47b6c09264 100644
--- a/sound/synth/emux/emux_oss.c
+++ b/sound/synth/emux/emux_oss.c
@@ -114,7 +114,8 @@ snd_emux_open_seq_oss(struct snd_seq_oss_arg *arg, void *closure)
114 char tmpname[64]; 114 char tmpname[64];
115 115
116 emu = closure; 116 emu = closure;
117 snd_assert(arg != NULL && emu != NULL, return -ENXIO); 117 if (snd_BUG_ON(!arg || !emu))
118 return -ENXIO;
118 119
119 mutex_lock(&emu->register_mutex); 120 mutex_lock(&emu->register_mutex);
120 121
@@ -183,12 +184,15 @@ snd_emux_close_seq_oss(struct snd_seq_oss_arg *arg)
183 struct snd_emux *emu; 184 struct snd_emux *emu;
184 struct snd_emux_port *p; 185 struct snd_emux_port *p;
185 186
186 snd_assert(arg != NULL, return -ENXIO); 187 if (snd_BUG_ON(!arg))
188 return -ENXIO;
187 p = arg->private_data; 189 p = arg->private_data;
188 snd_assert(p != NULL, return -ENXIO); 190 if (snd_BUG_ON(!p))
191 return -ENXIO;
189 192
190 emu = p->emu; 193 emu = p->emu;
191 snd_assert(emu != NULL, return -ENXIO); 194 if (snd_BUG_ON(!emu))
195 return -ENXIO;
192 196
193 mutex_lock(&emu->register_mutex); 197 mutex_lock(&emu->register_mutex);
194 snd_emux_sounds_off_all(p); 198 snd_emux_sounds_off_all(p);
@@ -212,12 +216,15 @@ snd_emux_load_patch_seq_oss(struct snd_seq_oss_arg *arg, int format,
212 struct snd_emux_port *p; 216 struct snd_emux_port *p;
213 int rc; 217 int rc;
214 218
215 snd_assert(arg != NULL, return -ENXIO); 219 if (snd_BUG_ON(!arg))
220 return -ENXIO;
216 p = arg->private_data; 221 p = arg->private_data;
217 snd_assert(p != NULL, return -ENXIO); 222 if (snd_BUG_ON(!p))
223 return -ENXIO;
218 224
219 emu = p->emu; 225 emu = p->emu;
220 snd_assert(emu != NULL, return -ENXIO); 226 if (snd_BUG_ON(!emu))
227 return -ENXIO;
221 228
222 if (format == GUS_PATCH) 229 if (format == GUS_PATCH)
223 rc = snd_soundfont_load_guspatch(emu->sflist, buf, count, 230 rc = snd_soundfont_load_guspatch(emu->sflist, buf, count,
@@ -252,12 +259,15 @@ snd_emux_ioctl_seq_oss(struct snd_seq_oss_arg *arg, unsigned int cmd, unsigned l
252 struct snd_emux_port *p; 259 struct snd_emux_port *p;
253 struct snd_emux *emu; 260 struct snd_emux *emu;
254 261
255 snd_assert(arg != NULL, return -ENXIO); 262 if (snd_BUG_ON(!arg))
263 return -ENXIO;
256 p = arg->private_data; 264 p = arg->private_data;
257 snd_assert(p != NULL, return -ENXIO); 265 if (snd_BUG_ON(!p))
266 return -ENXIO;
258 267
259 emu = p->emu; 268 emu = p->emu;
260 snd_assert(emu != NULL, return -ENXIO); 269 if (snd_BUG_ON(!emu))
270 return -ENXIO;
261 271
262 switch (cmd) { 272 switch (cmd) {
263 case SNDCTL_SEQ_RESETSAMPLES: 273 case SNDCTL_SEQ_RESETSAMPLES:
@@ -282,9 +292,11 @@ snd_emux_reset_seq_oss(struct snd_seq_oss_arg *arg)
282{ 292{
283 struct snd_emux_port *p; 293 struct snd_emux_port *p;
284 294
285 snd_assert(arg != NULL, return -ENXIO); 295 if (snd_BUG_ON(!arg))
296 return -ENXIO;
286 p = arg->private_data; 297 p = arg->private_data;
287 snd_assert(p != NULL, return -ENXIO); 298 if (snd_BUG_ON(!p))
299 return -ENXIO;
288 snd_emux_reset_port(p); 300 snd_emux_reset_port(p);
289 return 0; 301 return 0;
290} 302}
@@ -302,9 +314,11 @@ snd_emux_event_oss_input(struct snd_seq_event *ev, int direct, void *private_dat
302 unsigned char cmd, *data; 314 unsigned char cmd, *data;
303 315
304 p = private_data; 316 p = private_data;
305 snd_assert(p != NULL, return -EINVAL); 317 if (snd_BUG_ON(!p))
318 return -EINVAL;
306 emu = p->emu; 319 emu = p->emu;
307 snd_assert(emu != NULL, return -EINVAL); 320 if (snd_BUG_ON(!emu))
321 return -EINVAL;
308 if (ev->type != SNDRV_SEQ_EVENT_OSS) 322 if (ev->type != SNDRV_SEQ_EVENT_OSS)
309 return snd_emux_event_input(ev, direct, private_data, atomic, hop); 323 return snd_emux_event_input(ev, direct, private_data, atomic, hop);
310 324
diff --git a/sound/synth/emux/emux_seq.c b/sound/synth/emux/emux_seq.c
index d176cc01742d..335aa2ce2574 100644
--- a/sound/synth/emux/emux_seq.c
+++ b/sound/synth/emux/emux_seq.c
@@ -257,7 +257,8 @@ snd_emux_event_input(struct snd_seq_event *ev, int direct, void *private_data,
257 struct snd_emux_port *port; 257 struct snd_emux_port *port;
258 258
259 port = private_data; 259 port = private_data;
260 snd_assert(port != NULL && ev != NULL, return -EINVAL); 260 if (snd_BUG_ON(!port || !ev))
261 return -EINVAL;
261 262
262 snd_midi_process_event(&emux_ops, ev, &port->chset); 263 snd_midi_process_event(&emux_ops, ev, &port->chset);
263 264
@@ -308,9 +309,11 @@ snd_emux_use(void *private_data, struct snd_seq_port_subscribe *info)
308 struct snd_emux *emu; 309 struct snd_emux *emu;
309 310
310 p = private_data; 311 p = private_data;
311 snd_assert(p != NULL, return -EINVAL); 312 if (snd_BUG_ON(!p))
313 return -EINVAL;
312 emu = p->emu; 314 emu = p->emu;
313 snd_assert(emu != NULL, return -EINVAL); 315 if (snd_BUG_ON(!emu))
316 return -EINVAL;
314 317
315 mutex_lock(&emu->register_mutex); 318 mutex_lock(&emu->register_mutex);
316 snd_emux_init_port(p); 319 snd_emux_init_port(p);
@@ -329,9 +332,11 @@ snd_emux_unuse(void *private_data, struct snd_seq_port_subscribe *info)
329 struct snd_emux *emu; 332 struct snd_emux *emu;
330 333
331 p = private_data; 334 p = private_data;
332 snd_assert(p != NULL, return -EINVAL); 335 if (snd_BUG_ON(!p))
336 return -EINVAL;
333 emu = p->emu; 337 emu = p->emu;
334 snd_assert(emu != NULL, return -EINVAL); 338 if (snd_BUG_ON(!emu))
339 return -EINVAL;
335 340
336 mutex_lock(&emu->register_mutex); 341 mutex_lock(&emu->register_mutex);
337 snd_emux_sounds_off_all(p); 342 snd_emux_sounds_off_all(p);
diff --git a/sound/synth/emux/emux_synth.c b/sound/synth/emux/emux_synth.c
index b343818dbb96..2cc6f6f79065 100644
--- a/sound/synth/emux/emux_synth.c
+++ b/sound/synth/emux/emux_synth.c
@@ -66,12 +66,12 @@ snd_emux_note_on(void *p, int note, int vel, struct snd_midi_channel *chan)
66 struct snd_emux_port *port; 66 struct snd_emux_port *port;
67 67
68 port = p; 68 port = p;
69 snd_assert(port != NULL && chan != NULL, return); 69 if (snd_BUG_ON(!port || !chan))
70 return;
70 71
71 emu = port->emu; 72 emu = port->emu;
72 snd_assert(emu != NULL, return); 73 if (snd_BUG_ON(!emu || !emu->ops.get_voice || !emu->ops.trigger))
73 snd_assert(emu->ops.get_voice != NULL, return); 74 return;
74 snd_assert(emu->ops.trigger != NULL, return);
75 75
76 key = note; /* remember the original note */ 76 key = note; /* remember the original note */
77 nvoices = get_zone(emu, port, &note, vel, chan, table); 77 nvoices = get_zone(emu, port, &note, vel, chan, table);
@@ -164,11 +164,12 @@ snd_emux_note_off(void *p, int note, int vel, struct snd_midi_channel *chan)
164 struct snd_emux_port *port; 164 struct snd_emux_port *port;
165 165
166 port = p; 166 port = p;
167 snd_assert(port != NULL && chan != NULL, return); 167 if (snd_BUG_ON(!port || !chan))
168 return;
168 169
169 emu = port->emu; 170 emu = port->emu;
170 snd_assert(emu != NULL, return); 171 if (snd_BUG_ON(!emu || !emu->ops.release))
171 snd_assert(emu->ops.release != NULL, return); 172 return;
172 173
173 spin_lock_irqsave(&emu->voice_lock, flags); 174 spin_lock_irqsave(&emu->voice_lock, flags);
174 for (ch = 0; ch < emu->max_voices; ch++) { 175 for (ch = 0; ch < emu->max_voices; ch++) {
@@ -242,11 +243,12 @@ snd_emux_key_press(void *p, int note, int vel, struct snd_midi_channel *chan)
242 struct snd_emux_port *port; 243 struct snd_emux_port *port;
243 244
244 port = p; 245 port = p;
245 snd_assert(port != NULL && chan != NULL, return); 246 if (snd_BUG_ON(!port || !chan))
247 return;
246 248
247 emu = port->emu; 249 emu = port->emu;
248 snd_assert(emu != NULL, return); 250 if (snd_BUG_ON(!emu || !emu->ops.update))
249 snd_assert(emu->ops.update != NULL, return); 251 return;
250 252
251 spin_lock_irqsave(&emu->voice_lock, flags); 253 spin_lock_irqsave(&emu->voice_lock, flags);
252 for (ch = 0; ch < emu->max_voices; ch++) { 254 for (ch = 0; ch < emu->max_voices; ch++) {
@@ -276,8 +278,8 @@ snd_emux_update_channel(struct snd_emux_port *port, struct snd_midi_channel *cha
276 return; 278 return;
277 279
278 emu = port->emu; 280 emu = port->emu;
279 snd_assert(emu != NULL, return); 281 if (snd_BUG_ON(!emu || !emu->ops.update))
280 snd_assert(emu->ops.update != NULL, return); 282 return;
281 283
282 spin_lock_irqsave(&emu->voice_lock, flags); 284 spin_lock_irqsave(&emu->voice_lock, flags);
283 for (i = 0; i < emu->max_voices; i++) { 285 for (i = 0; i < emu->max_voices; i++) {
@@ -303,8 +305,8 @@ snd_emux_update_port(struct snd_emux_port *port, int update)
303 return; 305 return;
304 306
305 emu = port->emu; 307 emu = port->emu;
306 snd_assert(emu != NULL, return); 308 if (snd_BUG_ON(!emu || !emu->ops.update))
307 snd_assert(emu->ops.update != NULL, return); 309 return;
308 310
309 spin_lock_irqsave(&emu->voice_lock, flags); 311 spin_lock_irqsave(&emu->voice_lock, flags);
310 for (i = 0; i < emu->max_voices; i++) { 312 for (i = 0; i < emu->max_voices; i++) {
@@ -326,7 +328,8 @@ snd_emux_control(void *p, int type, struct snd_midi_channel *chan)
326 struct snd_emux_port *port; 328 struct snd_emux_port *port;
327 329
328 port = p; 330 port = p;
329 snd_assert(port != NULL && chan != NULL, return); 331 if (snd_BUG_ON(!port || !chan))
332 return;
330 333
331 switch (type) { 334 switch (type) {
332 case MIDI_CTL_MSB_MAIN_VOLUME: 335 case MIDI_CTL_MSB_MAIN_VOLUME:
@@ -400,11 +403,12 @@ snd_emux_terminate_note(void *p, int note, struct snd_midi_channel *chan)
400 struct snd_emux_port *port; 403 struct snd_emux_port *port;
401 404
402 port = p; 405 port = p;
403 snd_assert(port != NULL && chan != NULL, return); 406 if (snd_BUG_ON(!port || !chan))
407 return;
404 408
405 emu = port->emu; 409 emu = port->emu;
406 snd_assert(emu != NULL, return); 410 if (snd_BUG_ON(!emu || !emu->ops.terminate))
407 snd_assert(emu->ops.terminate != NULL, return); 411 return;
408 412
409 terminate_note1(emu, note, chan, 1); 413 terminate_note1(emu, note, chan, 1);
410} 414}
@@ -451,10 +455,11 @@ snd_emux_sounds_off_all(struct snd_emux_port *port)
451 struct snd_emux_voice *vp; 455 struct snd_emux_voice *vp;
452 unsigned long flags; 456 unsigned long flags;
453 457
454 snd_assert(port != NULL, return); 458 if (snd_BUG_ON(!port))
459 return;
455 emu = port->emu; 460 emu = port->emu;
456 snd_assert(emu != NULL, return); 461 if (snd_BUG_ON(!emu || !emu->ops.terminate))
457 snd_assert(emu->ops.terminate != NULL, return); 462 return;
458 463
459 spin_lock_irqsave(&emu->voice_lock, flags); 464 spin_lock_irqsave(&emu->voice_lock, flags);
460 for (i = 0; i < emu->max_voices; i++) { 465 for (i = 0; i < emu->max_voices; i++) {
diff --git a/sound/synth/util_mem.c b/sound/synth/util_mem.c
index deabe5f899c4..c85522e3808d 100644
--- a/sound/synth/util_mem.c
+++ b/sound/synth/util_mem.c
@@ -55,7 +55,8 @@ void snd_util_memhdr_free(struct snd_util_memhdr *hdr)
55{ 55{
56 struct list_head *p; 56 struct list_head *p;
57 57
58 snd_assert(hdr != NULL, return); 58 if (!hdr)
59 return;
59 /* release all blocks */ 60 /* release all blocks */
60 while ((p = hdr->block.next) != &hdr->block) { 61 while ((p = hdr->block.next) != &hdr->block) {
61 list_del(p); 62 list_del(p);
@@ -74,8 +75,8 @@ __snd_util_mem_alloc(struct snd_util_memhdr *hdr, int size)
74 unsigned int units, prev_offset; 75 unsigned int units, prev_offset;
75 struct list_head *p; 76 struct list_head *p;
76 77
77 snd_assert(hdr != NULL, return NULL); 78 if (snd_BUG_ON(!hdr || size <= 0))
78 snd_assert(size > 0, return NULL); 79 return NULL;
79 80
80 /* word alignment */ 81 /* word alignment */
81 units = size; 82 units = size;
@@ -161,7 +162,8 @@ __snd_util_mem_free(struct snd_util_memhdr *hdr, struct snd_util_memblk *blk)
161 */ 162 */
162int snd_util_mem_free(struct snd_util_memhdr *hdr, struct snd_util_memblk *blk) 163int snd_util_mem_free(struct snd_util_memhdr *hdr, struct snd_util_memblk *blk)
163{ 164{
164 snd_assert(hdr && blk, return -EINVAL); 165 if (snd_BUG_ON(!hdr || !blk))
166 return -EINVAL;
165 167
166 mutex_lock(&hdr->block_mutex); 168 mutex_lock(&hdr->block_mutex);
167 __snd_util_mem_free(hdr, blk); 169 __snd_util_mem_free(hdr, blk);
diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig
index ffcdc8f4ef66..4f0eac9bff1e 100644
--- a/sound/usb/Kconfig
+++ b/sound/usb/Kconfig
@@ -67,5 +67,17 @@ config SND_USB_CAIAQ_INPUT
67 * Native Instruments Kore Controller 2 67 * Native Instruments Kore Controller 2
68 * Native Instruments Audio Kontrol 1 68 * Native Instruments Audio Kontrol 1
69 69
70config SND_USB_US122L
71 tristate "Tascam US-122L USB driver"
72 depends on X86 && EXPERIMENTAL
73 select SND_HWDEP
74 select SND_RAWMIDI
75 help
76 Say Y here to include support for Tascam US-122L USB Audio/MIDI
77 interfaces.
78
79 To compile this driver as a module, choose M here: the module
80 will be called snd-usb-us122l.
81
70endif # SND_USB 82endif # SND_USB
71 83
diff --git a/sound/usb/Makefile b/sound/usb/Makefile
index aa252ef2ebfb..abb288bfe35d 100644
--- a/sound/usb/Makefile
+++ b/sound/usb/Makefile
@@ -8,5 +8,6 @@ snd-usb-lib-objs := usbmidi.o
8# Toplevel Module Dependency 8# Toplevel Module Dependency
9obj-$(CONFIG_SND_USB_AUDIO) += snd-usb-audio.o snd-usb-lib.o 9obj-$(CONFIG_SND_USB_AUDIO) += snd-usb-audio.o snd-usb-lib.o
10obj-$(CONFIG_SND_USB_USX2Y) += snd-usb-lib.o 10obj-$(CONFIG_SND_USB_USX2Y) += snd-usb-lib.o
11obj-$(CONFIG_SND_USB_US122L) += snd-usb-lib.o
11 12
12obj-$(CONFIG_SND) += usx2y/ caiaq/ 13obj-$(CONFIG_SND) += usx2y/ caiaq/
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index b8cfb7c22768..bbd70d5814a0 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -71,6 +71,7 @@ static int pid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 };
71static int nrpacks = 8; /* max. number of packets per urb */ 71static int nrpacks = 8; /* max. number of packets per urb */
72static int async_unlink = 1; 72static int async_unlink = 1;
73static int device_setup[SNDRV_CARDS]; /* device parameter for this card*/ 73static int device_setup[SNDRV_CARDS]; /* device parameter for this card*/
74static int ignore_ctl_error;
74 75
75module_param_array(index, int, NULL, 0444); 76module_param_array(index, int, NULL, 0444);
76MODULE_PARM_DESC(index, "Index value for the USB audio adapter."); 77MODULE_PARM_DESC(index, "Index value for the USB audio adapter.");
@@ -88,7 +89,9 @@ module_param(async_unlink, bool, 0444);
88MODULE_PARM_DESC(async_unlink, "Use async unlink mode."); 89MODULE_PARM_DESC(async_unlink, "Use async unlink mode.");
89module_param_array(device_setup, int, NULL, 0444); 90module_param_array(device_setup, int, NULL, 0444);
90MODULE_PARM_DESC(device_setup, "Specific device setup (if needed)."); 91MODULE_PARM_DESC(device_setup, "Specific device setup (if needed).");
91 92module_param(ignore_ctl_error, bool, 0444);
93MODULE_PARM_DESC(ignore_ctl_error,
94 "Ignore errors from USB controller for mixer interfaces.");
92 95
93/* 96/*
94 * debug the h/w constraints 97 * debug the h/w constraints
@@ -481,7 +484,7 @@ static int retire_playback_sync_urb_hs(struct snd_usb_substream *subs,
481} 484}
482 485
483/* 486/*
484 * process after E-Mu 0202/0404 high speed playback sync complete 487 * process after E-Mu 0202/0404/Tracker Pre high speed playback sync complete
485 * 488 *
486 * These devices return the number of samples per packet instead of the number 489 * These devices return the number of samples per packet instead of the number
487 * of samples per microframe. 490 * of samples per microframe.
@@ -841,7 +844,8 @@ static int start_urbs(struct snd_usb_substream *subs, struct snd_pcm_runtime *ru
841 return -EBADFD; 844 return -EBADFD;
842 845
843 for (i = 0; i < subs->nurbs; i++) { 846 for (i = 0; i < subs->nurbs; i++) {
844 snd_assert(subs->dataurb[i].urb, return -EINVAL); 847 if (snd_BUG_ON(!subs->dataurb[i].urb))
848 return -EINVAL;
845 if (subs->ops.prepare(subs, runtime, subs->dataurb[i].urb) < 0) { 849 if (subs->ops.prepare(subs, runtime, subs->dataurb[i].urb) < 0) {
846 snd_printk(KERN_ERR "cannot prepare datapipe for urb %d\n", i); 850 snd_printk(KERN_ERR "cannot prepare datapipe for urb %d\n", i);
847 goto __error; 851 goto __error;
@@ -849,7 +853,8 @@ static int start_urbs(struct snd_usb_substream *subs, struct snd_pcm_runtime *ru
849 } 853 }
850 if (subs->syncpipe) { 854 if (subs->syncpipe) {
851 for (i = 0; i < SYNC_URBS; i++) { 855 for (i = 0; i < SYNC_URBS; i++) {
852 snd_assert(subs->syncurb[i].urb, return -EINVAL); 856 if (snd_BUG_ON(!subs->syncurb[i].urb))
857 return -EINVAL;
853 if (subs->ops.prepare_sync(subs, runtime, subs->syncurb[i].urb) < 0) { 858 if (subs->ops.prepare_sync(subs, runtime, subs->syncurb[i].urb) < 0) {
854 snd_printk(KERN_ERR "cannot prepare syncpipe for urb %d\n", i); 859 snd_printk(KERN_ERR "cannot prepare syncpipe for urb %d\n", i);
855 goto __error; 860 goto __error;
@@ -1321,10 +1326,12 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
1321 int err; 1326 int err;
1322 1327
1323 iface = usb_ifnum_to_if(dev, fmt->iface); 1328 iface = usb_ifnum_to_if(dev, fmt->iface);
1324 snd_assert(iface, return -EINVAL); 1329 if (WARN_ON(!iface))
1330 return -EINVAL;
1325 alts = &iface->altsetting[fmt->altset_idx]; 1331 alts = &iface->altsetting[fmt->altset_idx];
1326 altsd = get_iface_desc(alts); 1332 altsd = get_iface_desc(alts);
1327 snd_assert(altsd->bAlternateSetting == fmt->altsetting, return -EINVAL); 1333 if (WARN_ON(altsd->bAlternateSetting != fmt->altsetting))
1334 return -EINVAL;
1328 1335
1329 if (fmt == subs->cur_audiofmt) 1336 if (fmt == subs->cur_audiofmt)
1330 return 0; 1337 return 0;
@@ -2257,6 +2264,7 @@ static void init_substream(struct snd_usb_stream *as, int stream, struct audiofo
2257 switch (as->chip->usb_id) { 2264 switch (as->chip->usb_id) {
2258 case USB_ID(0x041e, 0x3f02): /* E-Mu 0202 USB */ 2265 case USB_ID(0x041e, 0x3f02): /* E-Mu 0202 USB */
2259 case USB_ID(0x041e, 0x3f04): /* E-Mu 0404 USB */ 2266 case USB_ID(0x041e, 0x3f04): /* E-Mu 0404 USB */
2267 case USB_ID(0x041e, 0x3f0a): /* E-Mu Tracker Pre */
2260 subs->ops.retire_sync = retire_playback_sync_urb_hs_emu; 2268 subs->ops.retire_sync = retire_playback_sync_urb_hs_emu;
2261 break; 2269 break;
2262 } 2270 }
@@ -2989,12 +2997,12 @@ static int create_standard_audio_quirk(struct snd_usb_audio *chip,
2989} 2997}
2990 2998
2991/* 2999/*
2992 * Create a stream for an Edirol UA-700/UA-25 interface. The only way 3000 * Create a stream for an Edirol UA-700/UA-25/UA-4FX interface.
2993 * to detect the sample rate is by looking at wMaxPacketSize. 3001 * The only way to detect the sample rate is by looking at wMaxPacketSize.
2994 */ 3002 */
2995static int create_ua700_ua25_quirk(struct snd_usb_audio *chip, 3003static int create_uaxx_quirk(struct snd_usb_audio *chip,
2996 struct usb_interface *iface, 3004 struct usb_interface *iface,
2997 const struct snd_usb_audio_quirk *quirk) 3005 const struct snd_usb_audio_quirk *quirk)
2998{ 3006{
2999 static const struct audioformat ua_format = { 3007 static const struct audioformat ua_format = {
3000 .format = SNDRV_PCM_FORMAT_S24_3LE, 3008 .format = SNDRV_PCM_FORMAT_S24_3LE,
@@ -3009,8 +3017,8 @@ static int create_ua700_ua25_quirk(struct snd_usb_audio *chip,
3009 struct audioformat *fp; 3017 struct audioformat *fp;
3010 int stream, err; 3018 int stream, err;
3011 3019
3012 /* both PCM and MIDI interfaces have 2 altsettings */ 3020 /* both PCM and MIDI interfaces have 2 or more altsettings */
3013 if (iface->num_altsetting != 2) 3021 if (iface->num_altsetting < 2)
3014 return -ENXIO; 3022 return -ENXIO;
3015 alts = &iface->altsetting[1]; 3023 alts = &iface->altsetting[1];
3016 altsd = get_iface_desc(alts); 3024 altsd = get_iface_desc(alts);
@@ -3024,20 +3032,20 @@ static int create_ua700_ua25_quirk(struct snd_usb_audio *chip,
3024 .type = QUIRK_MIDI_FIXED_ENDPOINT, 3032 .type = QUIRK_MIDI_FIXED_ENDPOINT,
3025 .data = &ua700_ep 3033 .data = &ua700_ep
3026 }; 3034 };
3027 static const struct snd_usb_midi_endpoint_info ua25_ep = { 3035 static const struct snd_usb_midi_endpoint_info uaxx_ep = {
3028 .out_cables = 0x0001, 3036 .out_cables = 0x0001,
3029 .in_cables = 0x0001 3037 .in_cables = 0x0001
3030 }; 3038 };
3031 static const struct snd_usb_audio_quirk ua25_quirk = { 3039 static const struct snd_usb_audio_quirk uaxx_quirk = {
3032 .type = QUIRK_MIDI_FIXED_ENDPOINT, 3040 .type = QUIRK_MIDI_FIXED_ENDPOINT,
3033 .data = &ua25_ep 3041 .data = &uaxx_ep
3034 }; 3042 };
3035 if (chip->usb_id == USB_ID(0x0582, 0x002b)) 3043 if (chip->usb_id == USB_ID(0x0582, 0x002b))
3036 return snd_usb_create_midi_interface(chip, iface, 3044 return snd_usb_create_midi_interface(chip, iface,
3037 &ua700_quirk); 3045 &ua700_quirk);
3038 else 3046 else
3039 return snd_usb_create_midi_interface(chip, iface, 3047 return snd_usb_create_midi_interface(chip, iface,
3040 &ua25_quirk); 3048 &uaxx_quirk);
3041 } 3049 }
3042 3050
3043 if (altsd->bNumEndpoints != 1) 3051 if (altsd->bNumEndpoints != 1)
@@ -3369,9 +3377,9 @@ static int snd_usb_create_quirk(struct snd_usb_audio *chip,
3369 [QUIRK_MIDI_CME] = snd_usb_create_midi_interface, 3377 [QUIRK_MIDI_CME] = snd_usb_create_midi_interface,
3370 [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk, 3378 [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk,
3371 [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk, 3379 [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk,
3372 [QUIRK_AUDIO_EDIROL_UA700_UA25] = create_ua700_ua25_quirk,
3373 [QUIRK_AUDIO_EDIROL_UA1000] = create_ua1000_quirk, 3380 [QUIRK_AUDIO_EDIROL_UA1000] = create_ua1000_quirk,
3374 [QUIRK_AUDIO_EDIROL_UA101] = create_ua101_quirk, 3381 [QUIRK_AUDIO_EDIROL_UA101] = create_ua101_quirk,
3382 [QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk
3375 }; 3383 };
3376 3384
3377 if (quirk->type < QUIRK_TYPE_COUNT) { 3385 if (quirk->type < QUIRK_TYPE_COUNT) {
@@ -3629,7 +3637,7 @@ static void *snd_usb_audio_probe(struct usb_device *dev,
3629 if (err > 0) { 3637 if (err > 0) {
3630 /* create normal USB audio interfaces */ 3638 /* create normal USB audio interfaces */
3631 if (snd_usb_create_streams(chip, ifnum) < 0 || 3639 if (snd_usb_create_streams(chip, ifnum) < 0 ||
3632 snd_usb_create_mixer(chip, ifnum) < 0) { 3640 snd_usb_create_mixer(chip, ifnum, ignore_ctl_error) < 0) {
3633 goto __error; 3641 goto __error;
3634 } 3642 }
3635 } 3643 }
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
index 7cf18c38dc42..36e4f7a29adc 100644
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -156,11 +156,12 @@ enum quirk_type {
156 QUIRK_MIDI_RAW, 156 QUIRK_MIDI_RAW,
157 QUIRK_MIDI_EMAGIC, 157 QUIRK_MIDI_EMAGIC,
158 QUIRK_MIDI_CME, 158 QUIRK_MIDI_CME,
159 QUIRK_MIDI_US122L,
159 QUIRK_AUDIO_STANDARD_INTERFACE, 160 QUIRK_AUDIO_STANDARD_INTERFACE,
160 QUIRK_AUDIO_FIXED_ENDPOINT, 161 QUIRK_AUDIO_FIXED_ENDPOINT,
161 QUIRK_AUDIO_EDIROL_UA700_UA25,
162 QUIRK_AUDIO_EDIROL_UA1000, 162 QUIRK_AUDIO_EDIROL_UA1000,
163 QUIRK_AUDIO_EDIROL_UA101, 163 QUIRK_AUDIO_EDIROL_UA101,
164 QUIRK_AUDIO_EDIROL_UAXX,
164 165
165 QUIRK_TYPE_COUNT 166 QUIRK_TYPE_COUNT
166}; 167};
@@ -222,7 +223,8 @@ int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe,
222 __u8 request, __u8 requesttype, __u16 value, __u16 index, 223 __u8 request, __u8 requesttype, __u16 value, __u16 index,
223 void *data, __u16 size, int timeout); 224 void *data, __u16 size, int timeout);
224 225
225int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif); 226int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
227 int ignore_error);
226void snd_usb_mixer_disconnect(struct list_head *p); 228void snd_usb_mixer_disconnect(struct list_head *p);
227 229
228int snd_usb_create_midi_interface(struct snd_usb_audio *chip, struct usb_interface *iface, 230int snd_usb_create_midi_interface(struct snd_usb_audio *chip, struct usb_interface *iface,
diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c
index 6676a177c99e..5962e4b84423 100644
--- a/sound/usb/usbmidi.c
+++ b/sound/usb/usbmidi.c
@@ -669,6 +669,42 @@ static struct usb_protocol_ops snd_usbmidi_raw_ops = {
669 .output = snd_usbmidi_raw_output, 669 .output = snd_usbmidi_raw_output,
670}; 670};
671 671
672static void snd_usbmidi_us122l_input(struct snd_usb_midi_in_endpoint *ep,
673 uint8_t *buffer, int buffer_length)
674{
675 if (buffer_length != 9)
676 return;
677 buffer_length = 8;
678 while (buffer_length && buffer[buffer_length - 1] == 0xFD)
679 buffer_length--;
680 if (buffer_length)
681 snd_usbmidi_input_data(ep, 0, buffer, buffer_length);
682}
683
684static void snd_usbmidi_us122l_output(struct snd_usb_midi_out_endpoint *ep)
685{
686 int count;
687
688 if (!ep->ports[0].active)
689 return;
690 count = ep->urb->dev->speed == USB_SPEED_HIGH ? 1 : 2;
691 count = snd_rawmidi_transmit(ep->ports[0].substream,
692 ep->urb->transfer_buffer,
693 count);
694 if (count < 1) {
695 ep->ports[0].active = 0;
696 return;
697 }
698
699 memset(ep->urb->transfer_buffer + count, 0xFD, 9 - count);
700 ep->urb->transfer_buffer_length = count;
701}
702
703static struct usb_protocol_ops snd_usbmidi_122l_ops = {
704 .input = snd_usbmidi_us122l_input,
705 .output = snd_usbmidi_us122l_output,
706};
707
672/* 708/*
673 * Emagic USB MIDI protocol: raw MIDI with "F5 xx" port switching. 709 * Emagic USB MIDI protocol: raw MIDI with "F5 xx" port switching.
674 */ 710 */
@@ -1076,6 +1112,15 @@ void snd_usbmidi_disconnect(struct list_head* p)
1076 } 1112 }
1077 if (ep->in) 1113 if (ep->in)
1078 usb_kill_urb(ep->in->urb); 1114 usb_kill_urb(ep->in->urb);
1115 /* free endpoints here; later call can result in Oops */
1116 if (ep->out) {
1117 snd_usbmidi_out_endpoint_delete(ep->out);
1118 ep->out = NULL;
1119 }
1120 if (ep->in) {
1121 snd_usbmidi_in_endpoint_delete(ep->in);
1122 ep->in = NULL;
1123 }
1079 } 1124 }
1080 del_timer_sync(&umidi->error_timer); 1125 del_timer_sync(&umidi->error_timer);
1081} 1126}
@@ -1714,6 +1759,9 @@ int snd_usb_create_midi_interface(struct snd_usb_audio* chip,
1714 umidi->usb_protocol_ops = 1759 umidi->usb_protocol_ops =
1715 &snd_usbmidi_maudio_broken_running_status_ops; 1760 &snd_usbmidi_maudio_broken_running_status_ops;
1716 break; 1761 break;
1762 case QUIRK_MIDI_US122L:
1763 umidi->usb_protocol_ops = &snd_usbmidi_122l_ops;
1764 /* fall through */
1717 case QUIRK_MIDI_FIXED_ENDPOINT: 1765 case QUIRK_MIDI_FIXED_ENDPOINT:
1718 memcpy(&endpoints[0], quirk->data, 1766 memcpy(&endpoints[0], quirk->data,
1719 sizeof(struct snd_usb_midi_endpoint_info)); 1767 sizeof(struct snd_usb_midi_endpoint_info));
diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c
index 89c63d073cc6..a49246113e75 100644
--- a/sound/usb/usbmixer.c
+++ b/sound/usb/usbmixer.c
@@ -59,12 +59,13 @@ static const struct rc_config {
59 u8 offset; 59 u8 offset;
60 u8 length; 60 u8 length;
61 u8 packet_length; 61 u8 packet_length;
62 u8 min_packet_length; /* minimum accepted length of the URB result */
62 u8 mute_mixer_id; 63 u8 mute_mixer_id;
63 u32 mute_code; 64 u32 mute_code;
64} rc_configs[] = { 65} rc_configs[] = {
65 { USB_ID(0x041e, 0x3000), 0, 1, 2, 18, 0x0013 }, /* Extigy */ 66 { USB_ID(0x041e, 0x3000), 0, 1, 2, 1, 18, 0x0013 }, /* Extigy */
66 { USB_ID(0x041e, 0x3020), 2, 1, 6, 18, 0x0013 }, /* Audigy 2 NX */ 67 { USB_ID(0x041e, 0x3020), 2, 1, 6, 6, 18, 0x0013 }, /* Audigy 2 NX */
67 { USB_ID(0x041e, 0x3040), 2, 2, 6, 2, 0x6e91 }, /* Live! 24-bit */ 68 { USB_ID(0x041e, 0x3040), 2, 2, 6, 6, 2, 0x6e91 }, /* Live! 24-bit */
68}; 69};
69 70
70struct usb_mixer_interface { 71struct usb_mixer_interface {
@@ -1388,7 +1389,8 @@ static int mixer_ctl_selector_info(struct snd_kcontrol *kcontrol, struct snd_ctl
1388 struct usb_mixer_elem_info *cval = kcontrol->private_data; 1389 struct usb_mixer_elem_info *cval = kcontrol->private_data;
1389 char **itemlist = (char **)kcontrol->private_value; 1390 char **itemlist = (char **)kcontrol->private_value;
1390 1391
1391 snd_assert(itemlist, return -EINVAL); 1392 if (snd_BUG_ON(!itemlist))
1393 return -EINVAL;
1392 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 1394 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1393 uinfo->count = 1; 1395 uinfo->count = 1;
1394 uinfo->value.enumerated.items = cval->max; 1396 uinfo->value.enumerated.items = cval->max;
@@ -1781,7 +1783,7 @@ static void snd_usb_soundblaster_remote_complete(struct urb *urb)
1781 const struct rc_config *rc = mixer->rc_cfg; 1783 const struct rc_config *rc = mixer->rc_cfg;
1782 u32 code; 1784 u32 code;
1783 1785
1784 if (urb->status < 0 || urb->actual_length < rc->packet_length) 1786 if (urb->status < 0 || urb->actual_length < rc->min_packet_length)
1785 return; 1787 return;
1786 1788
1787 code = mixer->rc_buffer[rc->offset]; 1789 code = mixer->rc_buffer[rc->offset];
@@ -2012,7 +2014,8 @@ static void snd_audigy2nx_proc_read(struct snd_info_entry *entry,
2012 } 2014 }
2013} 2015}
2014 2016
2015int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif) 2017int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
2018 int ignore_error)
2016{ 2019{
2017 static struct snd_device_ops dev_ops = { 2020 static struct snd_device_ops dev_ops = {
2018 .dev_free = snd_usb_mixer_dev_free 2021 .dev_free = snd_usb_mixer_dev_free
@@ -2027,9 +2030,7 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif)
2027 return -ENOMEM; 2030 return -ENOMEM;
2028 mixer->chip = chip; 2031 mixer->chip = chip;
2029 mixer->ctrlif = ctrlif; 2032 mixer->ctrlif = ctrlif;
2030#ifdef IGNORE_CTL_ERROR 2033 mixer->ignore_ctl_error = ignore_error;
2031 mixer->ignore_ctl_error = 1;
2032#endif
2033 mixer->id_elems = kcalloc(256, sizeof(*mixer->id_elems), GFP_KERNEL); 2034 mixer->id_elems = kcalloc(256, sizeof(*mixer->id_elems), GFP_KERNEL);
2034 if (!mixer->id_elems) { 2035 if (!mixer->id_elems) {
2035 kfree(mixer); 2036 kfree(mixer);
diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h
index 9ea726c049c6..69689e79bf79 100644
--- a/sound/usb/usbquirks.h
+++ b/sound/usb/usbquirks.h
@@ -62,6 +62,13 @@
62 .idProduct = 0x3f04, 62 .idProduct = 0x3f04,
63 .bInterfaceClass = USB_CLASS_AUDIO, 63 .bInterfaceClass = USB_CLASS_AUDIO,
64}, 64},
65{
66 /* E-Mu Tracker Pre */
67 .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
68 .idVendor = 0x041e,
69 .idProduct = 0x3f0a,
70 .bInterfaceClass = USB_CLASS_AUDIO,
71},
65 72
66/* 73/*
67 * Logitech QuickCam: bDeviceClass is vendor-specific, so generic interface 74 * Logitech QuickCam: bDeviceClass is vendor-specific, so generic interface
@@ -855,15 +862,15 @@ YAMAHA_DEVICE(0x7010, "UB99"),
855 .data = (const struct snd_usb_audio_quirk[]) { 862 .data = (const struct snd_usb_audio_quirk[]) {
856 { 863 {
857 .ifnum = 1, 864 .ifnum = 1,
858 .type = QUIRK_AUDIO_EDIROL_UA700_UA25 865 .type = QUIRK_AUDIO_EDIROL_UAXX
859 }, 866 },
860 { 867 {
861 .ifnum = 2, 868 .ifnum = 2,
862 .type = QUIRK_AUDIO_EDIROL_UA700_UA25 869 .type = QUIRK_AUDIO_EDIROL_UAXX
863 }, 870 },
864 { 871 {
865 .ifnum = 3, 872 .ifnum = 3,
866 .type = QUIRK_AUDIO_EDIROL_UA700_UA25 873 .type = QUIRK_AUDIO_EDIROL_UAXX
867 }, 874 },
868 { 875 {
869 .ifnum = -1 876 .ifnum = -1
@@ -1197,15 +1204,15 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1197 .data = (const struct snd_usb_audio_quirk[]) { 1204 .data = (const struct snd_usb_audio_quirk[]) {
1198 { 1205 {
1199 .ifnum = 0, 1206 .ifnum = 0,
1200 .type = QUIRK_AUDIO_EDIROL_UA700_UA25 1207 .type = QUIRK_AUDIO_EDIROL_UAXX
1201 }, 1208 },
1202 { 1209 {
1203 .ifnum = 1, 1210 .ifnum = 1,
1204 .type = QUIRK_AUDIO_EDIROL_UA700_UA25 1211 .type = QUIRK_AUDIO_EDIROL_UAXX
1205 }, 1212 },
1206 { 1213 {
1207 .ifnum = 2, 1214 .ifnum = 2,
1208 .type = QUIRK_AUDIO_EDIROL_UA700_UA25 1215 .type = QUIRK_AUDIO_EDIROL_UAXX
1209 }, 1216 },
1210 { 1217 {
1211 .ifnum = -1 1218 .ifnum = -1
@@ -1338,6 +1345,36 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1338 } 1345 }
1339 } 1346 }
1340}, 1347},
1348{
1349 /*
1350 * This quirk is for the "Advanced Driver" mode. If off, the UA-4FX
1351 * is standard compliant, but has only 16-bit PCM and no MIDI.
1352 */
1353 USB_DEVICE(0x0582, 0x00a3),
1354 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1355 .vendor_name = "EDIROL",
1356 .product_name = "UA-4FX",
1357 .ifnum = QUIRK_ANY_INTERFACE,
1358 .type = QUIRK_COMPOSITE,
1359 .data = (const struct snd_usb_audio_quirk[]) {
1360 {
1361 .ifnum = 0,
1362 .type = QUIRK_AUDIO_EDIROL_UAXX
1363 },
1364 {
1365 .ifnum = 1,
1366 .type = QUIRK_AUDIO_EDIROL_UAXX
1367 },
1368 {
1369 .ifnum = 2,
1370 .type = QUIRK_AUDIO_EDIROL_UAXX
1371 },
1372 {
1373 .ifnum = -1
1374 }
1375 }
1376 }
1377},
1341 /* TODO: add Edirol MD-P1 support */ 1378 /* TODO: add Edirol MD-P1 support */
1342{ 1379{
1343 USB_DEVICE(0x582, 0x00a6), 1380 USB_DEVICE(0x582, 0x00a6),
@@ -1383,7 +1420,6 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1383 } 1420 }
1384 } 1421 }
1385}, 1422},
1386
1387{ 1423{
1388 /* Roland SonicCell */ 1424 /* Roland SonicCell */
1389 USB_DEVICE(0x0582, 0x00c2), 1425 USB_DEVICE(0x0582, 0x00c2),
@@ -1415,7 +1451,35 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1415 } 1451 }
1416 } 1452 }
1417}, 1453},
1418 1454{
1455 /* BOSS GT-10 */
1456 USB_DEVICE(0x0582, 0x00da),
1457 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1458 .ifnum = QUIRK_ANY_INTERFACE,
1459 .type = QUIRK_COMPOSITE,
1460 .data = (const struct snd_usb_audio_quirk[]) {
1461 {
1462 .ifnum = 0,
1463 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1464 },
1465 {
1466 .ifnum = 1,
1467 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1468 },
1469 {
1470 .ifnum = 2,
1471 .type = QUIRK_MIDI_FIXED_ENDPOINT,
1472 .data = & (const struct snd_usb_midi_endpoint_info) {
1473 .out_cables = 0x0001,
1474 .in_cables = 0x0001
1475 }
1476 },
1477 {
1478 .ifnum = -1
1479 }
1480 }
1481 }
1482},
1419 1483
1420/* Guillemot devices */ 1484/* Guillemot devices */
1421{ 1485{
diff --git a/sound/usb/usx2y/Makefile b/sound/usb/usx2y/Makefile
index 9ac22bce1124..748933054b6c 100644
--- a/sound/usb/usx2y/Makefile
+++ b/sound/usb/usx2y/Makefile
@@ -1,3 +1,5 @@
1snd-usb-usx2y-objs := usbusx2y.o usX2Yhwdep.o usx2yhwdeppcm.o 1snd-usb-usx2y-objs := usbusx2y.o usX2Yhwdep.o usx2yhwdeppcm.o
2snd-usb-us122l-objs := us122l.o
2 3
3obj-$(CONFIG_SND_USB_USX2Y) += snd-usb-usx2y.o 4obj-$(CONFIG_SND_USB_USX2Y) += snd-usb-usx2y.o
5obj-$(CONFIG_SND_USB_US122L) += snd-usb-us122l.o
diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c
new file mode 100644
index 000000000000..b441fe2cd190
--- /dev/null
+++ b/sound/usb/usx2y/us122l.c
@@ -0,0 +1,692 @@
1/*
2 * Copyright (C) 2007, 2008 Karsten Wiese <fzu@wemgehoertderstaat.de>
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19#include <sound/core.h>
20#include <sound/hwdep.h>
21#include <sound/pcm.h>
22#include <sound/initval.h>
23#define MODNAME "US122L"
24#include "usb_stream.c"
25#include "../usbaudio.h"
26#include "us122l.h"
27
28MODULE_AUTHOR("Karsten Wiese <fzu@wemgehoertderstaat.de>");
29MODULE_DESCRIPTION("TASCAM "NAME_ALLCAPS" Version 0.5");
30MODULE_LICENSE("GPL");
31
32static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */
33static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */
34 /* Enable this card */
35static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
36
37module_param_array(index, int, NULL, 0444);
38MODULE_PARM_DESC(index, "Index value for "NAME_ALLCAPS".");
39module_param_array(id, charp, NULL, 0444);
40MODULE_PARM_DESC(id, "ID string for "NAME_ALLCAPS".");
41module_param_array(enable, bool, NULL, 0444);
42MODULE_PARM_DESC(enable, "Enable "NAME_ALLCAPS".");
43
44static int snd_us122l_card_used[SNDRV_CARDS];
45
46
47static int us122l_create_usbmidi(struct snd_card *card)
48{
49 static struct snd_usb_midi_endpoint_info quirk_data = {
50 .out_ep = 4,
51 .in_ep = 3,
52 .out_cables = 0x001,
53 .in_cables = 0x001
54 };
55 static struct snd_usb_audio_quirk quirk = {
56 .vendor_name = "US122L",
57 .product_name = NAME_ALLCAPS,
58 .ifnum = 1,
59 .type = QUIRK_MIDI_US122L,
60 .data = &quirk_data
61 };
62 struct usb_device *dev = US122L(card)->chip.dev;
63 struct usb_interface *iface = usb_ifnum_to_if(dev, 1);
64
65 return snd_usb_create_midi_interface(&US122L(card)->chip,
66 iface, &quirk);
67}
68
69/*
70 * Wrapper for usb_control_msg().
71 * Allocates a temp buffer to prevent dmaing from/to the stack.
72 */
73static int us122l_ctl_msg(struct usb_device *dev, unsigned int pipe,
74 __u8 request, __u8 requesttype,
75 __u16 value, __u16 index, void *data,
76 __u16 size, int timeout)
77{
78 int err;
79 void *buf = NULL;
80
81 if (size > 0) {
82 buf = kmemdup(data, size, GFP_KERNEL);
83 if (!buf)
84 return -ENOMEM;
85 }
86 err = usb_control_msg(dev, pipe, request, requesttype,
87 value, index, buf, size, timeout);
88 if (size > 0) {
89 memcpy(data, buf, size);
90 kfree(buf);
91 }
92 return err;
93}
94
95static void pt_info_set(struct usb_device *dev, u8 v)
96{
97 int ret;
98
99 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
100 'I',
101 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
102 v, 0, NULL, 0, 1000);
103 snd_printdd(KERN_DEBUG "%i\n", ret);
104}
105
106static void usb_stream_hwdep_vm_open(struct vm_area_struct *area)
107{
108 struct us122l *us122l = area->vm_private_data;
109 atomic_inc(&us122l->mmap_count);
110 snd_printdd(KERN_DEBUG "%i\n", atomic_read(&us122l->mmap_count));
111}
112
113static int usb_stream_hwdep_vm_fault(struct vm_area_struct *area,
114 struct vm_fault *vmf)
115{
116 unsigned long offset;
117 struct page *page;
118 void *vaddr;
119 struct us122l *us122l = area->vm_private_data;
120 struct usb_stream *s;
121 int vm_f = VM_FAULT_SIGBUS;
122
123 mutex_lock(&us122l->mutex);
124 s = us122l->sk.s;
125 if (!s)
126 goto out;
127
128 offset = vmf->pgoff << PAGE_SHIFT;
129 if (offset < PAGE_ALIGN(s->read_size))
130 vaddr = (char *)s + offset;
131 else {
132 offset -= PAGE_ALIGN(s->read_size);
133 if (offset >= PAGE_ALIGN(s->write_size))
134 goto out;
135
136 vaddr = us122l->sk.write_page + offset;
137 }
138 page = virt_to_page(vaddr);
139
140 get_page(page);
141 mutex_unlock(&us122l->mutex);
142
143 vmf->page = page;
144 vm_f = 0;
145out:
146 return vm_f;
147}
148
149static void usb_stream_hwdep_vm_close(struct vm_area_struct *area)
150{
151 struct us122l *us122l = area->vm_private_data;
152 atomic_dec(&us122l->mmap_count);
153 snd_printdd(KERN_DEBUG "%i\n", atomic_read(&us122l->mmap_count));
154}
155
156static struct vm_operations_struct usb_stream_hwdep_vm_ops = {
157 .open = usb_stream_hwdep_vm_open,
158 .fault = usb_stream_hwdep_vm_fault,
159 .close = usb_stream_hwdep_vm_close,
160};
161
162
163static int usb_stream_hwdep_open(struct snd_hwdep *hw, struct file *file)
164{
165 struct us122l *us122l = hw->private_data;
166 struct usb_interface *iface;
167 snd_printdd(KERN_DEBUG "%p %p\n", hw, file);
168 if (hw->used >= 2)
169 return -EBUSY;
170
171 if (!us122l->first)
172 us122l->first = file;
173 iface = usb_ifnum_to_if(us122l->chip.dev, 1);
174 usb_autopm_get_interface(iface);
175 return 0;
176}
177
178static int usb_stream_hwdep_release(struct snd_hwdep *hw, struct file *file)
179{
180 struct us122l *us122l = hw->private_data;
181 struct usb_interface *iface = usb_ifnum_to_if(us122l->chip.dev, 1);
182 snd_printdd(KERN_DEBUG "%p %p\n", hw, file);
183 usb_autopm_put_interface(iface);
184 if (us122l->first == file)
185 us122l->first = NULL;
186 mutex_lock(&us122l->mutex);
187 if (us122l->master == file)
188 us122l->master = us122l->slave;
189
190 us122l->slave = NULL;
191 mutex_unlock(&us122l->mutex);
192 return 0;
193}
194
195static int usb_stream_hwdep_mmap(struct snd_hwdep *hw,
196 struct file *filp, struct vm_area_struct *area)
197{
198 unsigned long size = area->vm_end - area->vm_start;
199 struct us122l *us122l = hw->private_data;
200 unsigned long offset;
201 struct usb_stream *s;
202 int err = 0;
203 bool read;
204
205 offset = area->vm_pgoff << PAGE_SHIFT;
206 mutex_lock(&us122l->mutex);
207 s = us122l->sk.s;
208 read = offset < s->read_size;
209 if (read && area->vm_flags & VM_WRITE) {
210 err = -EPERM;
211 goto out;
212 }
213 snd_printdd(KERN_DEBUG "%lu %u\n", size,
214 read ? s->read_size : s->write_size);
215 /* if userspace tries to mmap beyond end of our buffer, fail */
216 if (size > PAGE_ALIGN(read ? s->read_size : s->write_size)) {
217 snd_printk(KERN_WARNING "%lu > %u\n", size,
218 read ? s->read_size : s->write_size);
219 err = -EINVAL;
220 goto out;
221 }
222
223 area->vm_ops = &usb_stream_hwdep_vm_ops;
224 area->vm_flags |= VM_RESERVED;
225 area->vm_private_data = us122l;
226 atomic_inc(&us122l->mmap_count);
227out:
228 mutex_unlock(&us122l->mutex);
229 return err;
230}
231
232static unsigned int usb_stream_hwdep_poll(struct snd_hwdep *hw,
233 struct file *file, poll_table *wait)
234{
235 struct us122l *us122l = hw->private_data;
236 struct usb_stream *s = us122l->sk.s;
237 unsigned *polled;
238 unsigned int mask;
239
240 poll_wait(file, &us122l->sk.sleep, wait);
241
242 switch (s->state) {
243 case usb_stream_ready:
244 if (us122l->first == file)
245 polled = &s->periods_polled;
246 else
247 polled = &us122l->second_periods_polled;
248 if (*polled != s->periods_done) {
249 *polled = s->periods_done;
250 mask = POLLIN | POLLOUT | POLLWRNORM;
251 break;
252 }
253 /* Fall through */
254 mask = 0;
255 break;
256 default:
257 mask = POLLIN | POLLOUT | POLLWRNORM | POLLERR;
258 break;
259 }
260 return mask;
261}
262
263static void us122l_stop(struct us122l *us122l)
264{
265 struct list_head *p;
266 list_for_each(p, &us122l->chip.midi_list)
267 snd_usbmidi_input_stop(p);
268
269 usb_stream_stop(&us122l->sk);
270 usb_stream_free(&us122l->sk);
271}
272
273static int us122l_set_sample_rate(struct usb_device *dev, int rate)
274{
275 unsigned int ep = 0x81;
276 unsigned char data[3];
277 int err;
278
279 data[0] = rate;
280 data[1] = rate >> 8;
281 data[2] = rate >> 16;
282 err = us122l_ctl_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR,
283 USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT,
284 SAMPLING_FREQ_CONTROL << 8, ep, data, 3, 1000);
285 if (err < 0)
286 snd_printk(KERN_ERR "%d: cannot set freq %d to ep 0x%x\n",
287 dev->devnum, rate, ep);
288 return err;
289}
290
291static bool us122l_start(struct us122l *us122l,
292 unsigned rate, unsigned period_frames)
293{
294 struct list_head *p;
295 int err;
296 unsigned use_packsize = 0;
297 bool success = false;
298
299 if (us122l->chip.dev->speed == USB_SPEED_HIGH) {
300 /* The us-122l's descriptor defaults to iso max_packsize 78,
301 which isn't needed for samplerates <= 48000.
302 Lets save some memory:
303 */
304 switch (rate) {
305 case 44100:
306 use_packsize = 36;
307 break;
308 case 48000:
309 use_packsize = 42;
310 break;
311 case 88200:
312 use_packsize = 72;
313 break;
314 }
315 }
316 if (!usb_stream_new(&us122l->sk, us122l->chip.dev, 1, 2,
317 rate, use_packsize, period_frames, 6))
318 goto out;
319
320 err = us122l_set_sample_rate(us122l->chip.dev, rate);
321 if (err < 0) {
322 us122l_stop(us122l);
323 snd_printk(KERN_ERR "us122l_set_sample_rate error \n");
324 goto out;
325 }
326 err = usb_stream_start(&us122l->sk);
327 if (err < 0) {
328 us122l_stop(us122l);
329 snd_printk(KERN_ERR "us122l_start error %i \n", err);
330 goto out;
331 }
332 list_for_each(p, &us122l->chip.midi_list)
333 snd_usbmidi_input_start(p);
334 success = true;
335out:
336 return success;
337}
338
339static int usb_stream_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
340 unsigned cmd, unsigned long arg)
341{
342 struct usb_stream_config *cfg;
343 struct us122l *us122l = hw->private_data;
344 unsigned min_period_frames;
345 int err = 0;
346 bool high_speed;
347
348 if (cmd != SNDRV_USB_STREAM_IOCTL_SET_PARAMS)
349 return -ENOTTY;
350
351 cfg = kmalloc(sizeof(*cfg), GFP_KERNEL);
352 if (!cfg)
353 return -ENOMEM;
354
355 if (copy_from_user(cfg, (void *)arg, sizeof(*cfg))) {
356 err = -EFAULT;
357 goto free;
358 }
359 if (cfg->version != USB_STREAM_INTERFACE_VERSION) {
360 err = -ENXIO;
361 goto free;
362 }
363 high_speed = us122l->chip.dev->speed == USB_SPEED_HIGH;
364 if ((cfg->sample_rate != 44100 && cfg->sample_rate != 48000 &&
365 (!high_speed ||
366 (cfg->sample_rate != 88200 && cfg->sample_rate != 96000))) ||
367 cfg->frame_size != 6 ||
368 cfg->period_frames > 0x3000) {
369 err = -EINVAL;
370 goto free;
371 }
372 switch (cfg->sample_rate) {
373 case 44100:
374 min_period_frames = 48;
375 break;
376 case 48000:
377 min_period_frames = 52;
378 break;
379 default:
380 min_period_frames = 104;
381 break;
382 }
383 if (!high_speed)
384 min_period_frames <<= 1;
385 if (cfg->period_frames < min_period_frames) {
386 err = -EINVAL;
387 goto free;
388 }
389
390 snd_power_wait(hw->card, SNDRV_CTL_POWER_D0);
391
392 mutex_lock(&us122l->mutex);
393 if (!us122l->master)
394 us122l->master = file;
395 else if (us122l->master != file) {
396 if (memcmp(cfg, &us122l->sk.s->cfg, sizeof(*cfg))) {
397 err = -EIO;
398 goto unlock;
399 }
400 us122l->slave = file;
401 }
402 if (!us122l->sk.s ||
403 memcmp(cfg, &us122l->sk.s->cfg, sizeof(*cfg)) ||
404 us122l->sk.s->state == usb_stream_xrun) {
405 us122l_stop(us122l);
406 if (!us122l_start(us122l, cfg->sample_rate, cfg->period_frames))
407 err = -EIO;
408 else
409 err = 1;
410 }
411unlock:
412 mutex_unlock(&us122l->mutex);
413free:
414 kfree(cfg);
415 return err;
416}
417
418#define SND_USB_STREAM_ID "USB STREAM"
419static int usb_stream_hwdep_new(struct snd_card *card)
420{
421 int err;
422 struct snd_hwdep *hw;
423 struct usb_device *dev = US122L(card)->chip.dev;
424
425 err = snd_hwdep_new(card, SND_USB_STREAM_ID, 0, &hw);
426 if (err < 0)
427 return err;
428
429 hw->iface = SNDRV_HWDEP_IFACE_USB_STREAM;
430 hw->private_data = US122L(card);
431 hw->ops.open = usb_stream_hwdep_open;
432 hw->ops.release = usb_stream_hwdep_release;
433 hw->ops.ioctl = usb_stream_hwdep_ioctl;
434 hw->ops.ioctl_compat = usb_stream_hwdep_ioctl;
435 hw->ops.mmap = usb_stream_hwdep_mmap;
436 hw->ops.poll = usb_stream_hwdep_poll;
437
438 sprintf(hw->name, "/proc/bus/usb/%03d/%03d/hwdeppcm",
439 dev->bus->busnum, dev->devnum);
440 return 0;
441}
442
443
444static bool us122l_create_card(struct snd_card *card)
445{
446 int err;
447 struct us122l *us122l = US122L(card);
448
449 err = usb_set_interface(us122l->chip.dev, 1, 1);
450 if (err) {
451 snd_printk(KERN_ERR "usb_set_interface error \n");
452 return false;
453 }
454
455 pt_info_set(us122l->chip.dev, 0x11);
456 pt_info_set(us122l->chip.dev, 0x10);
457
458 if (!us122l_start(us122l, 44100, 256))
459 return false;
460
461 err = us122l_create_usbmidi(card);
462 if (err < 0) {
463 snd_printk(KERN_ERR "us122l_create_usbmidi error %i \n", err);
464 us122l_stop(us122l);
465 return false;
466 }
467 err = usb_stream_hwdep_new(card);
468 if (err < 0) {
469/* release the midi resources */
470 struct list_head *p;
471 list_for_each(p, &us122l->chip.midi_list)
472 snd_usbmidi_disconnect(p);
473
474 us122l_stop(us122l);
475 return false;
476 }
477 return true;
478}
479
480static struct snd_card *usx2y_create_card(struct usb_device *device)
481{
482 int dev;
483 struct snd_card *card;
484 for (dev = 0; dev < SNDRV_CARDS; ++dev)
485 if (enable[dev] && !snd_us122l_card_used[dev])
486 break;
487 if (dev >= SNDRV_CARDS)
488 return NULL;
489 card = snd_card_new(index[dev], id[dev], THIS_MODULE,
490 sizeof(struct us122l));
491 if (!card)
492 return NULL;
493 snd_us122l_card_used[US122L(card)->chip.index = dev] = 1;
494
495 US122L(card)->chip.dev = device;
496 US122L(card)->chip.card = card;
497 mutex_init(&US122L(card)->mutex);
498 init_waitqueue_head(&US122L(card)->sk.sleep);
499 INIT_LIST_HEAD(&US122L(card)->chip.midi_list);
500 strcpy(card->driver, "USB "NAME_ALLCAPS"");
501 sprintf(card->shortname, "TASCAM "NAME_ALLCAPS"");
502 sprintf(card->longname, "%s (%x:%x if %d at %03d/%03d)",
503 card->shortname,
504 le16_to_cpu(device->descriptor.idVendor),
505 le16_to_cpu(device->descriptor.idProduct),
506 0,
507 US122L(card)->chip.dev->bus->busnum,
508 US122L(card)->chip.dev->devnum
509 );
510 snd_card_set_dev(card, &device->dev);
511 return card;
512}
513
514static void *us122l_usb_probe(struct usb_interface *intf,
515 const struct usb_device_id *device_id)
516{
517 struct usb_device *device = interface_to_usbdev(intf);
518 struct snd_card *card = usx2y_create_card(device);
519
520 if (!card)
521 return NULL;
522
523 if (!us122l_create_card(card) ||
524 snd_card_register(card) < 0) {
525 snd_card_free(card);
526 return NULL;
527 }
528
529 usb_get_dev(device);
530 return card;
531}
532
533static int snd_us122l_probe(struct usb_interface *intf,
534 const struct usb_device_id *id)
535{
536 struct snd_card *card;
537 snd_printdd(KERN_DEBUG"%p:%i\n",
538 intf, intf->cur_altsetting->desc.bInterfaceNumber);
539 if (intf->cur_altsetting->desc.bInterfaceNumber != 1)
540 return 0;
541
542 card = us122l_usb_probe(usb_get_intf(intf), id);
543
544 if (card) {
545 usb_set_intfdata(intf, card);
546 return 0;
547 }
548
549 usb_put_intf(intf);
550 return -EIO;
551}
552
553static void snd_us122l_disconnect(struct usb_interface *intf)
554{
555 struct snd_card *card;
556 struct us122l *us122l;
557 struct list_head *p;
558
559 card = usb_get_intfdata(intf);
560 if (!card)
561 return;
562
563 snd_card_disconnect(card);
564
565 us122l = US122L(card);
566 mutex_lock(&us122l->mutex);
567 us122l_stop(us122l);
568 mutex_unlock(&us122l->mutex);
569 us122l->chip.shutdown = 1;
570
571/* release the midi resources */
572 list_for_each(p, &us122l->chip.midi_list) {
573 snd_usbmidi_disconnect(p);
574 }
575
576 usb_put_intf(intf);
577 usb_put_dev(US122L(card)->chip.dev);
578
579 while (atomic_read(&us122l->mmap_count))
580 msleep(500);
581
582 snd_card_free(card);
583}
584
585static int snd_us122l_suspend(struct usb_interface *intf, pm_message_t message)
586{
587 struct snd_card *card;
588 struct us122l *us122l;
589 struct list_head *p;
590
591 card = dev_get_drvdata(&intf->dev);
592 if (!card)
593 return 0;
594 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
595
596 us122l = US122L(card);
597 if (!us122l)
598 return 0;
599
600 list_for_each(p, &us122l->chip.midi_list)
601 snd_usbmidi_input_stop(p);
602
603 mutex_lock(&us122l->mutex);
604 usb_stream_stop(&us122l->sk);
605 mutex_unlock(&us122l->mutex);
606
607 return 0;
608}
609
610static int snd_us122l_resume(struct usb_interface *intf)
611{
612 struct snd_card *card;
613 struct us122l *us122l;
614 struct list_head *p;
615 int err;
616
617 card = dev_get_drvdata(&intf->dev);
618 if (!card)
619 return 0;
620
621 us122l = US122L(card);
622 if (!us122l)
623 return 0;
624
625 mutex_lock(&us122l->mutex);
626 /* needed, doesn't restart without: */
627 err = usb_set_interface(us122l->chip.dev, 1, 1);
628 if (err) {
629 snd_printk(KERN_ERR "usb_set_interface error \n");
630 goto unlock;
631 }
632
633 pt_info_set(us122l->chip.dev, 0x11);
634 pt_info_set(us122l->chip.dev, 0x10);
635
636 err = us122l_set_sample_rate(us122l->chip.dev,
637 us122l->sk.s->cfg.sample_rate);
638 if (err < 0) {
639 snd_printk(KERN_ERR "us122l_set_sample_rate error \n");
640 goto unlock;
641 }
642 err = usb_stream_start(&us122l->sk);
643 if (err)
644 goto unlock;
645
646 list_for_each(p, &us122l->chip.midi_list)
647 snd_usbmidi_input_start(p);
648unlock:
649 mutex_unlock(&us122l->mutex);
650 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
651 return err;
652}
653
654static struct usb_device_id snd_us122l_usb_id_table[] = {
655 {
656 .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
657 .idVendor = 0x0644,
658 .idProduct = USB_ID_US122L
659 },
660/* { */ /* US-144 maybe works when @USB1.1. Untested. */
661/* .match_flags = USB_DEVICE_ID_MATCH_DEVICE, */
662/* .idVendor = 0x0644, */
663/* .idProduct = USB_ID_US144 */
664/* }, */
665 { /* terminator */ }
666};
667
668MODULE_DEVICE_TABLE(usb, snd_us122l_usb_id_table);
669static struct usb_driver snd_us122l_usb_driver = {
670 .name = "snd-usb-us122l",
671 .probe = snd_us122l_probe,
672 .disconnect = snd_us122l_disconnect,
673 .suspend = snd_us122l_suspend,
674 .resume = snd_us122l_resume,
675 .reset_resume = snd_us122l_resume,
676 .id_table = snd_us122l_usb_id_table,
677 .supports_autosuspend = 1
678};
679
680
681static int __init snd_us122l_module_init(void)
682{
683 return usb_register(&snd_us122l_usb_driver);
684}
685
686static void __exit snd_us122l_module_exit(void)
687{
688 usb_deregister(&snd_us122l_usb_driver);
689}
690
691module_init(snd_us122l_module_init)
692module_exit(snd_us122l_module_exit)
diff --git a/sound/usb/usx2y/us122l.h b/sound/usb/usx2y/us122l.h
new file mode 100644
index 000000000000..3d10c4b2a0f5
--- /dev/null
+++ b/sound/usb/usx2y/us122l.h
@@ -0,0 +1,27 @@
1#ifndef US122L_H
2#define US122L_H
3
4
5struct us122l {
6 struct snd_usb_audio chip;
7 int stride;
8 struct usb_stream_kernel sk;
9
10 struct mutex mutex;
11 struct file *first;
12 unsigned second_periods_polled;
13 struct file *master;
14 struct file *slave;
15
16 atomic_t mmap_count;
17};
18
19
20#define US122L(c) ((struct us122l *)(c)->private_data)
21
22#define NAME_ALLCAPS "US-122L"
23
24#define USB_ID_US122L 0x800E
25#define USB_ID_US144 0x800F
26
27#endif
diff --git a/sound/usb/usx2y/usb_stream.c b/sound/usb/usx2y/usb_stream.c
new file mode 100644
index 000000000000..ff23cc1ce3b9
--- /dev/null
+++ b/sound/usb/usx2y/usb_stream.c
@@ -0,0 +1,761 @@
1/*
2 * Copyright (C) 2007, 2008 Karsten Wiese <fzu@wemgehoertderstaat.de>
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19#include <linux/usb.h>
20
21#include "usb_stream.h"
22
23
24/* setup */
25
26static unsigned usb_stream_next_packet_size(struct usb_stream_kernel *sk)
27{
28 struct usb_stream *s = sk->s;
29 sk->out_phase_peeked = (sk->out_phase & 0xffff) + sk->freqn;
30 return (sk->out_phase_peeked >> 16) * s->cfg.frame_size;
31}
32
33static void playback_prep_freqn(struct usb_stream_kernel *sk, struct urb *urb)
34{
35 struct usb_stream *s = sk->s;
36 unsigned l = 0;
37 int pack;
38
39 urb->iso_frame_desc[0].offset = 0;
40 urb->iso_frame_desc[0].length = usb_stream_next_packet_size(sk);
41 sk->out_phase = sk->out_phase_peeked;
42 urb->transfer_buffer_length = urb->iso_frame_desc[0].length;
43
44 for (pack = 1; pack < sk->n_o_ps; pack++) {
45 l = usb_stream_next_packet_size(sk);
46 if (s->idle_outsize + urb->transfer_buffer_length + l >
47 s->period_size)
48 goto check;
49
50 sk->out_phase = sk->out_phase_peeked;
51 urb->iso_frame_desc[pack].offset = urb->transfer_buffer_length;
52 urb->iso_frame_desc[pack].length = l;
53 urb->transfer_buffer_length += l;
54 }
55 snd_printdd(KERN_DEBUG "%i\n", urb->transfer_buffer_length);
56
57check:
58 urb->number_of_packets = pack;
59 s->idle_outsize += urb->transfer_buffer_length - s->period_size;
60 snd_printdd(KERN_DEBUG "idle=%i ul=%i ps=%i\n", s->idle_outsize,
61 urb->transfer_buffer_length, s->period_size);
62}
63
64static void init_pipe_urbs(struct usb_stream_kernel *sk, unsigned use_packsize,
65 struct urb **urbs, char *transfer,
66 struct usb_device *dev, int pipe)
67{
68 int u, p;
69 int maxpacket = use_packsize ?
70 use_packsize : usb_maxpacket(dev, pipe, usb_pipeout(pipe));
71 int transfer_length = maxpacket * sk->n_o_ps;
72
73 for (u = 0; u < USB_STREAM_NURBS;
74 ++u, transfer += transfer_length) {
75 struct urb *urb = urbs[u];
76 struct usb_iso_packet_descriptor *desc;
77 urb->transfer_flags = URB_ISO_ASAP;
78 urb->transfer_buffer = transfer;
79 urb->dev = dev;
80 urb->pipe = pipe;
81 urb->number_of_packets = sk->n_o_ps;
82 urb->context = sk;
83 urb->interval = 1;
84 if (usb_pipeout(pipe))
85 continue;
86
87 urb->transfer_buffer_length = transfer_length;
88 desc = urb->iso_frame_desc;
89 desc->offset = 0;
90 desc->length = maxpacket;
91 for (p = 1; p < sk->n_o_ps; ++p) {
92 desc[p].offset = desc[p - 1].offset + maxpacket;
93 desc[p].length = maxpacket;
94 }
95 }
96}
97
98static void init_urbs(struct usb_stream_kernel *sk, unsigned use_packsize,
99 struct usb_device *dev, int in_pipe, int out_pipe)
100{
101 struct usb_stream *s = sk->s;
102 char *indata = (char *)s + sizeof(*s) +
103 sizeof(struct usb_stream_packet) *
104 s->inpackets;
105 int u;
106
107 for (u = 0; u < USB_STREAM_NURBS; ++u) {
108 sk->inurb[u] = usb_alloc_urb(sk->n_o_ps, GFP_KERNEL);
109 sk->outurb[u] = usb_alloc_urb(sk->n_o_ps, GFP_KERNEL);
110 }
111
112 init_pipe_urbs(sk, use_packsize, sk->inurb, indata, dev, in_pipe);
113 init_pipe_urbs(sk, use_packsize, sk->outurb, sk->write_page, dev,
114 out_pipe);
115}
116
117
118/*
119 * convert a sampling rate into our full speed format (fs/1000 in Q16.16)
120 * this will overflow at approx 524 kHz
121 */
122static inline unsigned get_usb_full_speed_rate(unsigned rate)
123{
124 return ((rate << 13) + 62) / 125;
125}
126
127/*
128 * convert a sampling rate into USB high speed format (fs/8000 in Q16.16)
129 * this will overflow at approx 4 MHz
130 */
131static inline unsigned get_usb_high_speed_rate(unsigned rate)
132{
133 return ((rate << 10) + 62) / 125;
134}
135
136void usb_stream_free(struct usb_stream_kernel *sk)
137{
138 struct usb_stream *s;
139 unsigned u;
140
141 for (u = 0; u < USB_STREAM_NURBS; ++u) {
142 usb_free_urb(sk->inurb[u]);
143 sk->inurb[u] = NULL;
144 usb_free_urb(sk->outurb[u]);
145 sk->outurb[u] = NULL;
146 }
147
148 s = sk->s;
149 if (!s)
150 return;
151
152 free_pages((unsigned long)sk->write_page, get_order(s->write_size));
153 sk->write_page = NULL;
154 free_pages((unsigned long)s, get_order(s->read_size));
155 sk->s = NULL;
156}
157
158struct usb_stream *usb_stream_new(struct usb_stream_kernel *sk,
159 struct usb_device *dev,
160 unsigned in_endpoint, unsigned out_endpoint,
161 unsigned sample_rate, unsigned use_packsize,
162 unsigned period_frames, unsigned frame_size)
163{
164 int packets, max_packsize;
165 int in_pipe, out_pipe;
166 int read_size = sizeof(struct usb_stream);
167 int write_size;
168 int usb_frames = dev->speed == USB_SPEED_HIGH ? 8000 : 1000;
169 int pg;
170
171 in_pipe = usb_rcvisocpipe(dev, in_endpoint);
172 out_pipe = usb_sndisocpipe(dev, out_endpoint);
173
174 max_packsize = use_packsize ?
175 use_packsize : usb_maxpacket(dev, in_pipe, 0);
176
177 /*
178 t_period = period_frames / sample_rate
179 iso_packs = t_period / t_iso_frame
180 = (period_frames / sample_rate) * (1 / t_iso_frame)
181 */
182
183 packets = period_frames * usb_frames / sample_rate + 1;
184
185 if (dev->speed == USB_SPEED_HIGH)
186 packets = (packets + 7) & ~7;
187
188 read_size += packets * USB_STREAM_URBDEPTH *
189 (max_packsize + sizeof(struct usb_stream_packet));
190
191 max_packsize = usb_maxpacket(dev, out_pipe, 1);
192 write_size = max_packsize * packets * USB_STREAM_URBDEPTH;
193
194 if (read_size >= 256*PAGE_SIZE || write_size >= 256*PAGE_SIZE) {
195 snd_printk(KERN_WARNING "a size exceeds 128*PAGE_SIZE\n");
196 goto out;
197 }
198
199 pg = get_order(read_size);
200 sk->s = (void *) __get_free_pages(GFP_KERNEL|__GFP_COMP|__GFP_ZERO, pg);
201 if (!sk->s) {
202 snd_printk(KERN_WARNING "couldn't __get_free_pages()\n");
203 goto out;
204 }
205 sk->s->cfg.version = USB_STREAM_INTERFACE_VERSION;
206
207 sk->s->read_size = read_size;
208
209 sk->s->cfg.sample_rate = sample_rate;
210 sk->s->cfg.frame_size = frame_size;
211 sk->n_o_ps = packets;
212 sk->s->inpackets = packets * USB_STREAM_URBDEPTH;
213 sk->s->cfg.period_frames = period_frames;
214 sk->s->period_size = frame_size * period_frames;
215
216 sk->s->write_size = write_size;
217 pg = get_order(write_size);
218
219 sk->write_page =
220 (void *)__get_free_pages(GFP_KERNEL|__GFP_COMP|__GFP_ZERO, pg);
221 if (!sk->write_page) {
222 snd_printk(KERN_WARNING "couldn't __get_free_pages()\n");
223 usb_stream_free(sk);
224 return NULL;
225 }
226
227 /* calculate the frequency in 16.16 format */
228 if (dev->speed == USB_SPEED_FULL)
229 sk->freqn = get_usb_full_speed_rate(sample_rate);
230 else
231 sk->freqn = get_usb_high_speed_rate(sample_rate);
232
233 init_urbs(sk, use_packsize, dev, in_pipe, out_pipe);
234 sk->s->state = usb_stream_stopped;
235out:
236 return sk->s;
237}
238
239
240/* start */
241
242static bool balance_check(struct usb_stream_kernel *sk, struct urb *urb)
243{
244 bool r;
245 if (unlikely(urb->status)) {
246 if (urb->status != -ESHUTDOWN && urb->status != -ENOENT)
247 snd_printk(KERN_WARNING "status=%i\n", urb->status);
248 sk->iso_frame_balance = 0x7FFFFFFF;
249 return false;
250 }
251 r = sk->iso_frame_balance == 0;
252 if (!r)
253 sk->i_urb = urb;
254 return r;
255}
256
257static bool balance_playback(struct usb_stream_kernel *sk, struct urb *urb)
258{
259 sk->iso_frame_balance += urb->number_of_packets;
260 return balance_check(sk, urb);
261}
262
263static bool balance_capture(struct usb_stream_kernel *sk, struct urb *urb)
264{
265 sk->iso_frame_balance -= urb->number_of_packets;
266 return balance_check(sk, urb);
267}
268
269static void subs_set_complete(struct urb **urbs, void (*complete)(struct urb *))
270{
271 int u;
272
273 for (u = 0; u < USB_STREAM_NURBS; u++) {
274 struct urb *urb = urbs[u];
275 urb->complete = complete;
276 }
277}
278
279int usb_stream_prepare_playback(struct usb_stream_kernel *sk, struct urb *inurb)
280{
281 struct usb_stream *s = sk->s;
282 struct urb *io;
283 struct usb_iso_packet_descriptor *id, *od;
284 int p, l = 0;
285
286 io = sk->idle_outurb;
287 od = io->iso_frame_desc;
288 io->transfer_buffer_length = 0;
289
290 for (p = 0; s->sync_packet < 0; ++p, ++s->sync_packet) {
291 struct urb *ii = sk->completed_inurb;
292 id = ii->iso_frame_desc +
293 ii->number_of_packets + s->sync_packet;
294 l = id->actual_length;
295
296 od[p].length = l;
297 od[p].offset = io->transfer_buffer_length;
298 io->transfer_buffer_length += l;
299 }
300
301 for (;
302 s->sync_packet < inurb->number_of_packets && p < sk->n_o_ps;
303 ++p, ++s->sync_packet) {
304 l = inurb->iso_frame_desc[s->sync_packet].actual_length;
305
306 if (s->idle_outsize + io->transfer_buffer_length + l >
307 s->period_size)
308 goto check_ok;
309
310 od[p].length = l;
311 od[p].offset = io->transfer_buffer_length;
312 io->transfer_buffer_length += l;
313 }
314
315check_ok:
316 s->sync_packet -= inurb->number_of_packets;
317 if (s->sync_packet < -2 || s->sync_packet > 0) {
318 snd_printk(KERN_WARNING "invalid sync_packet = %i;"
319 " p=%i nop=%i %i %x %x %x > %x\n",
320 s->sync_packet, p, inurb->number_of_packets,
321 s->idle_outsize + io->transfer_buffer_length + l,
322 s->idle_outsize, io->transfer_buffer_length, l,
323 s->period_size);
324 return -1;
325 }
326 if (io->transfer_buffer_length % s->cfg.frame_size) {
327 snd_printk(KERN_WARNING"invalid outsize = %i\n",
328 io->transfer_buffer_length);
329 return -1;
330 }
331 s->idle_outsize += io->transfer_buffer_length - s->period_size;
332 io->number_of_packets = p;
333 if (s->idle_outsize > 0) {
334 snd_printk(KERN_WARNING "idle=%i\n", s->idle_outsize);
335 return -1;
336 }
337 return 0;
338}
339
340static void prepare_inurb(int number_of_packets, struct urb *iu)
341{
342 struct usb_iso_packet_descriptor *id;
343 int p;
344
345 iu->number_of_packets = number_of_packets;
346 id = iu->iso_frame_desc;
347 id->offset = 0;
348 for (p = 0; p < iu->number_of_packets - 1; ++p)
349 id[p + 1].offset = id[p].offset + id[p].length;
350
351 iu->transfer_buffer_length =
352 id[0].length * iu->number_of_packets;
353}
354
355static int submit_urbs(struct usb_stream_kernel *sk,
356 struct urb *inurb, struct urb *outurb)
357{
358 int err;
359 prepare_inurb(sk->idle_outurb->number_of_packets, sk->idle_inurb);
360 err = usb_submit_urb(sk->idle_inurb, GFP_ATOMIC);
361 if (err < 0) {
362 snd_printk(KERN_ERR "%i\n", err);
363 return err;
364 }
365 sk->idle_inurb = sk->completed_inurb;
366 sk->completed_inurb = inurb;
367 err = usb_submit_urb(sk->idle_outurb, GFP_ATOMIC);
368 if (err < 0) {
369 snd_printk(KERN_ERR "%i\n", err);
370 return err;
371 }
372 sk->idle_outurb = sk->completed_outurb;
373 sk->completed_outurb = outurb;
374 return 0;
375}
376
377#ifdef DEBUG_LOOP_BACK
378/*
379 This loop_back() shows how to read/write the period data.
380 */
381static void loop_back(struct usb_stream *s)
382{
383 char *i, *o;
384 int il, ol, l, p;
385 struct urb *iu;
386 struct usb_iso_packet_descriptor *id;
387
388 o = s->playback1st_to;
389 ol = s->playback1st_size;
390 l = 0;
391
392 if (s->insplit_pack >= 0) {
393 iu = sk->idle_inurb;
394 id = iu->iso_frame_desc;
395 p = s->insplit_pack;
396 } else
397 goto second;
398loop:
399 for (; p < iu->number_of_packets && l < s->period_size; ++p) {
400 i = iu->transfer_buffer + id[p].offset;
401 il = id[p].actual_length;
402 if (l + il > s->period_size)
403 il = s->period_size - l;
404 if (il <= ol) {
405 memcpy(o, i, il);
406 o += il;
407 ol -= il;
408 } else {
409 memcpy(o, i, ol);
410 singen_6pack(o, ol);
411 o = s->playback_to;
412 memcpy(o, i + ol, il - ol);
413 o += il - ol;
414 ol = s->period_size - s->playback1st_size;
415 }
416 l += il;
417 }
418 if (iu == sk->completed_inurb) {
419 if (l != s->period_size)
420 printk(KERN_DEBUG"%s:%i %i\n", __func__, __LINE__,
421 l/(int)s->cfg.frame_size);
422
423 return;
424 }
425second:
426 iu = sk->completed_inurb;
427 id = iu->iso_frame_desc;
428 p = 0;
429 goto loop;
430
431}
432#else
433static void loop_back(struct usb_stream *s)
434{
435}
436#endif
437
438static void stream_idle(struct usb_stream_kernel *sk,
439 struct urb *inurb, struct urb *outurb)
440{
441 struct usb_stream *s = sk->s;
442 int l, p;
443 int insize = s->idle_insize;
444 int urb_size = 0;
445
446 s->inpacket_split = s->next_inpacket_split;
447 s->inpacket_split_at = s->next_inpacket_split_at;
448 s->next_inpacket_split = -1;
449 s->next_inpacket_split_at = 0;
450
451 for (p = 0; p < inurb->number_of_packets; ++p) {
452 struct usb_iso_packet_descriptor *id = inurb->iso_frame_desc;
453 l = id[p].actual_length;
454 if (unlikely(l == 0 || id[p].status)) {
455 snd_printk(KERN_WARNING "underrun, status=%u\n",
456 id[p].status);
457 goto err_out;
458 }
459 s->inpacket_head++;
460 s->inpacket_head %= s->inpackets;
461 if (s->inpacket_split == -1)
462 s->inpacket_split = s->inpacket_head;
463
464 s->inpacket[s->inpacket_head].offset =
465 id[p].offset + (inurb->transfer_buffer - (void *)s);
466 s->inpacket[s->inpacket_head].length = l;
467 if (insize + l > s->period_size &&
468 s->next_inpacket_split == -1) {
469 s->next_inpacket_split = s->inpacket_head;
470 s->next_inpacket_split_at = s->period_size - insize;
471 }
472 insize += l;
473 urb_size += l;
474 }
475 s->idle_insize += urb_size - s->period_size;
476 if (s->idle_insize < 0) {
477 snd_printk(KERN_WARNING "%i\n",
478 (s->idle_insize)/(int)s->cfg.frame_size);
479 goto err_out;
480 }
481 s->insize_done += urb_size;
482
483 l = s->idle_outsize;
484 s->outpacket[0].offset = (sk->idle_outurb->transfer_buffer -
485 sk->write_page) - l;
486
487 if (usb_stream_prepare_playback(sk, inurb) < 0)
488 goto err_out;
489
490 s->outpacket[0].length = sk->idle_outurb->transfer_buffer_length + l;
491 s->outpacket[1].offset = sk->completed_outurb->transfer_buffer -
492 sk->write_page;
493
494 if (submit_urbs(sk, inurb, outurb) < 0)
495 goto err_out;
496
497 loop_back(s);
498 s->periods_done++;
499 wake_up_all(&sk->sleep);
500 return;
501err_out:
502 s->state = usb_stream_xrun;
503 wake_up_all(&sk->sleep);
504}
505
506static void i_capture_idle(struct urb *urb)
507{
508 struct usb_stream_kernel *sk = urb->context;
509 if (balance_capture(sk, urb))
510 stream_idle(sk, urb, sk->i_urb);
511}
512
513static void i_playback_idle(struct urb *urb)
514{
515 struct usb_stream_kernel *sk = urb->context;
516 if (balance_playback(sk, urb))
517 stream_idle(sk, sk->i_urb, urb);
518}
519
520static void stream_start(struct usb_stream_kernel *sk,
521 struct urb *inurb, struct urb *outurb)
522{
523 struct usb_stream *s = sk->s;
524 if (s->state >= usb_stream_sync1) {
525 int l, p, max_diff, max_diff_0;
526 int urb_size = 0;
527 unsigned frames_per_packet, min_frames = 0;
528 frames_per_packet = (s->period_size - s->idle_insize);
529 frames_per_packet <<= 8;
530 frames_per_packet /=
531 s->cfg.frame_size * inurb->number_of_packets;
532 frames_per_packet++;
533
534 max_diff_0 = s->cfg.frame_size;
535 if (s->cfg.period_frames >= 256)
536 max_diff_0 <<= 1;
537 if (s->cfg.period_frames >= 1024)
538 max_diff_0 <<= 1;
539 max_diff = max_diff_0;
540 for (p = 0; p < inurb->number_of_packets; ++p) {
541 int diff;
542 l = inurb->iso_frame_desc[p].actual_length;
543 urb_size += l;
544
545 min_frames += frames_per_packet;
546 diff = urb_size -
547 (min_frames >> 8) * s->cfg.frame_size;
548 if (diff < max_diff) {
549 snd_printdd(KERN_DEBUG "%i %i %i %i\n",
550 s->insize_done,
551 urb_size / (int)s->cfg.frame_size,
552 inurb->number_of_packets, diff);
553 max_diff = diff;
554 }
555 }
556 s->idle_insize -= max_diff - max_diff_0;
557 s->idle_insize += urb_size - s->period_size;
558 if (s->idle_insize < 0) {
559 snd_printk("%i %i %i\n",
560 s->idle_insize, urb_size, s->period_size);
561 return;
562 } else if (s->idle_insize == 0) {
563 s->next_inpacket_split =
564 (s->inpacket_head + 1) % s->inpackets;
565 s->next_inpacket_split_at = 0;
566 } else {
567 unsigned split = s->inpacket_head;
568 l = s->idle_insize;
569 while (l > s->inpacket[split].length) {
570 l -= s->inpacket[split].length;
571 if (split == 0)
572 split = s->inpackets - 1;
573 else
574 split--;
575 }
576 s->next_inpacket_split = split;
577 s->next_inpacket_split_at =
578 s->inpacket[split].length - l;
579 }
580
581 s->insize_done += urb_size;
582
583 if (usb_stream_prepare_playback(sk, inurb) < 0)
584 return;
585
586 } else
587 playback_prep_freqn(sk, sk->idle_outurb);
588
589 if (submit_urbs(sk, inurb, outurb) < 0)
590 return;
591
592 if (s->state == usb_stream_sync1 && s->insize_done > 360000) {
593 /* just guesswork ^^^^^^ */
594 s->state = usb_stream_ready;
595 subs_set_complete(sk->inurb, i_capture_idle);
596 subs_set_complete(sk->outurb, i_playback_idle);
597 }
598}
599
600static void i_capture_start(struct urb *urb)
601{
602 struct usb_iso_packet_descriptor *id = urb->iso_frame_desc;
603 struct usb_stream_kernel *sk = urb->context;
604 struct usb_stream *s = sk->s;
605 int p;
606 int empty = 0;
607
608 if (urb->status) {
609 snd_printk(KERN_WARNING "status=%i\n", urb->status);
610 return;
611 }
612
613 for (p = 0; p < urb->number_of_packets; ++p) {
614 int l = id[p].actual_length;
615 if (l < s->cfg.frame_size) {
616 ++empty;
617 if (s->state >= usb_stream_sync0) {
618 snd_printk(KERN_WARNING "%i\n", l);
619 return;
620 }
621 }
622 s->inpacket_head++;
623 s->inpacket_head %= s->inpackets;
624 s->inpacket[s->inpacket_head].offset =
625 id[p].offset + (urb->transfer_buffer - (void *)s);
626 s->inpacket[s->inpacket_head].length = l;
627 }
628#ifdef SHOW_EMPTY
629 if (empty) {
630 printk(KERN_DEBUG"%s:%i: %i", __func__, __LINE__,
631 urb->iso_frame_desc[0].actual_length);
632 for (pack = 1; pack < urb->number_of_packets; ++pack) {
633 int l = urb->iso_frame_desc[pack].actual_length;
634 printk(" %i", l);
635 }
636 printk("\n");
637 }
638#endif
639 if (!empty && s->state < usb_stream_sync1)
640 ++s->state;
641
642 if (balance_capture(sk, urb))
643 stream_start(sk, urb, sk->i_urb);
644}
645
646static void i_playback_start(struct urb *urb)
647{
648 struct usb_stream_kernel *sk = urb->context;
649 if (balance_playback(sk, urb))
650 stream_start(sk, sk->i_urb, urb);
651}
652
653int usb_stream_start(struct usb_stream_kernel *sk)
654{
655 struct usb_stream *s = sk->s;
656 int frame = 0, iters = 0;
657 int u, err;
658 int try = 0;
659
660 if (s->state != usb_stream_stopped)
661 return -EAGAIN;
662
663 subs_set_complete(sk->inurb, i_capture_start);
664 subs_set_complete(sk->outurb, i_playback_start);
665 memset(sk->write_page, 0, s->write_size);
666dotry:
667 s->insize_done = 0;
668 s->idle_insize = 0;
669 s->idle_outsize = 0;
670 s->sync_packet = -1;
671 s->inpacket_head = -1;
672 sk->iso_frame_balance = 0;
673 ++try;
674 for (u = 0; u < 2; u++) {
675 struct urb *inurb = sk->inurb[u];
676 struct urb *outurb = sk->outurb[u];
677 playback_prep_freqn(sk, outurb);
678 inurb->number_of_packets = outurb->number_of_packets;
679 inurb->transfer_buffer_length =
680 inurb->number_of_packets *
681 inurb->iso_frame_desc[0].length;
682 preempt_disable();
683 if (u == 0) {
684 int now;
685 struct usb_device *dev = inurb->dev;
686 frame = usb_get_current_frame_number(dev);
687 do {
688 now = usb_get_current_frame_number(dev);
689 ++iters;
690 } while (now > -1 && now == frame);
691 }
692 err = usb_submit_urb(inurb, GFP_ATOMIC);
693 if (err < 0) {
694 preempt_enable();
695 snd_printk(KERN_ERR"usb_submit_urb(sk->inurb[%i])"
696 " returned %i\n", u, err);
697 return err;
698 }
699 err = usb_submit_urb(outurb, GFP_ATOMIC);
700 if (err < 0) {
701 preempt_enable();
702 snd_printk(KERN_ERR"usb_submit_urb(sk->outurb[%i])"
703 " returned %i\n", u, err);
704 return err;
705 }
706 preempt_enable();
707 if (inurb->start_frame != outurb->start_frame) {
708 snd_printd(KERN_DEBUG
709 "u[%i] start_frames differ in:%u out:%u\n",
710 u, inurb->start_frame, outurb->start_frame);
711 goto check_retry;
712 }
713 }
714 snd_printdd(KERN_DEBUG "%i %i\n", frame, iters);
715 try = 0;
716check_retry:
717 if (try) {
718 usb_stream_stop(sk);
719 if (try < 5) {
720 msleep(1500);
721 snd_printd(KERN_DEBUG "goto dotry;\n");
722 goto dotry;
723 }
724 snd_printk(KERN_WARNING"couldn't start"
725 " all urbs on the same start_frame.\n");
726 return -EFAULT;
727 }
728
729 sk->idle_inurb = sk->inurb[USB_STREAM_NURBS - 2];
730 sk->idle_outurb = sk->outurb[USB_STREAM_NURBS - 2];
731 sk->completed_inurb = sk->inurb[USB_STREAM_NURBS - 1];
732 sk->completed_outurb = sk->outurb[USB_STREAM_NURBS - 1];
733
734/* wait, check */
735 {
736 int wait_ms = 3000;
737 while (s->state != usb_stream_ready && wait_ms > 0) {
738 snd_printdd(KERN_DEBUG "%i\n", s->state);
739 msleep(200);
740 wait_ms -= 200;
741 }
742 }
743
744 return s->state == usb_stream_ready ? 0 : -EFAULT;
745}
746
747
748/* stop */
749
750void usb_stream_stop(struct usb_stream_kernel *sk)
751{
752 int u;
753 if (!sk->s)
754 return;
755 for (u = 0; u < USB_STREAM_NURBS; ++u) {
756 usb_kill_urb(sk->inurb[u]);
757 usb_kill_urb(sk->outurb[u]);
758 }
759 sk->s->state = usb_stream_stopped;
760 msleep(400);
761}
diff --git a/sound/usb/usx2y/usb_stream.h b/sound/usb/usx2y/usb_stream.h
new file mode 100644
index 000000000000..4dd74ab1e9cc
--- /dev/null
+++ b/sound/usb/usx2y/usb_stream.h
@@ -0,0 +1,112 @@
1/*
2 * Copyright (C) 2007, 2008 Karsten Wiese <fzu@wemgehoertderstaat.de>
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19#define USB_STREAM_INTERFACE_VERSION 2
20
21#define SNDRV_USB_STREAM_IOCTL_SET_PARAMS \
22 _IOW('H', 0x90, struct usb_stream_config)
23
24struct usb_stream_packet {
25 unsigned offset;
26 unsigned length;
27};
28
29
30struct usb_stream_config {
31 unsigned version;
32 unsigned sample_rate;
33 unsigned period_frames;
34 unsigned frame_size;
35};
36
37struct usb_stream {
38 struct usb_stream_config cfg;
39 unsigned read_size;
40 unsigned write_size;
41
42 int period_size;
43
44 unsigned state;
45
46 int idle_insize;
47 int idle_outsize;
48 int sync_packet;
49 unsigned insize_done;
50 unsigned periods_done;
51 unsigned periods_polled;
52
53 struct usb_stream_packet outpacket[2];
54 unsigned inpackets;
55 unsigned inpacket_head;
56 unsigned inpacket_split;
57 unsigned inpacket_split_at;
58 unsigned next_inpacket_split;
59 unsigned next_inpacket_split_at;
60 struct usb_stream_packet inpacket[0];
61};
62
63enum usb_stream_state {
64 usb_stream_invalid,
65 usb_stream_stopped,
66 usb_stream_sync0,
67 usb_stream_sync1,
68 usb_stream_ready,
69 usb_stream_running,
70 usb_stream_xrun,
71};
72
73#if __KERNEL__
74
75#define USB_STREAM_NURBS 4
76#define USB_STREAM_URBDEPTH 4
77
78struct usb_stream_kernel {
79 struct usb_stream *s;
80
81 void *write_page;
82
83 unsigned n_o_ps;
84
85 struct urb *inurb[USB_STREAM_NURBS];
86 struct urb *idle_inurb;
87 struct urb *completed_inurb;
88 struct urb *outurb[USB_STREAM_NURBS];
89 struct urb *idle_outurb;
90 struct urb *completed_outurb;
91 struct urb *i_urb;
92
93 int iso_frame_balance;
94
95 wait_queue_head_t sleep;
96
97 unsigned out_phase;
98 unsigned out_phase_peeked;
99 unsigned freqn;
100};
101
102struct usb_stream *usb_stream_new(struct usb_stream_kernel *sk,
103 struct usb_device *dev,
104 unsigned in_endpoint, unsigned out_endpoint,
105 unsigned sample_rate, unsigned use_packsize,
106 unsigned period_frames, unsigned frame_size);
107void usb_stream_free(struct usb_stream_kernel *);
108int usb_stream_start(struct usb_stream_kernel *);
109void usb_stream_stop(struct usb_stream_kernel *);
110
111
112#endif