aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/cpu-freq/user-guide.txt6
-rw-r--r--Documentation/sh/kgdb.txt179
-rw-r--r--Documentation/sound/alsa/ALSA-Configuration.txt330
-rw-r--r--Documentation/sound/alsa/HD-Audio-Models.txt348
-rw-r--r--Documentation/sound/alsa/HD-Audio.txt577
-rw-r--r--Documentation/sound/alsa/Procfile.txt10
-rw-r--r--Documentation/sound/alsa/soc/machine.txt8
-rw-r--r--MAINTAINERS2
-rw-r--r--arch/arm/mach-pxa/include/mach/palmasoc.h13
-rw-r--r--arch/sh/Kconfig83
-rw-r--r--arch/sh/Kconfig.debug104
-rw-r--r--arch/sh/Makefile33
-rw-r--r--arch/sh/boards/Kconfig11
-rw-r--r--arch/sh/boards/Makefile1
-rw-r--r--arch/sh/boards/board-ap325rxa.c7
-rw-r--r--arch/sh/boards/board-shmin.c14
-rw-r--r--arch/sh/boards/mach-cayman/Makefile1
-rw-r--r--arch/sh/boards/mach-cayman/irq.c35
-rw-r--r--arch/sh/boards/mach-cayman/led.c51
-rw-r--r--arch/sh/boards/mach-dreamcast/irq.c192
-rw-r--r--arch/sh/boards/mach-dreamcast/setup.c5
-rw-r--r--arch/sh/boards/mach-edosk7705/Makefile1
-rw-r--r--arch/sh/boards/mach-edosk7705/io.c61
-rw-r--r--arch/sh/boards/mach-edosk7705/setup.c9
-rw-r--r--arch/sh/boards/mach-hp6xx/pm.c78
-rw-r--r--arch/sh/boards/mach-microdev/Makefile5
-rw-r--r--arch/sh/boards/mach-microdev/fdc37c93xapm.c160
-rw-r--r--arch/sh/boards/mach-microdev/irq.c36
-rw-r--r--arch/sh/boards/mach-microdev/led.c101
-rw-r--r--arch/sh/boards/mach-microdev/setup.c196
-rw-r--r--arch/sh/boards/mach-migor/setup.c21
-rw-r--r--arch/sh/boards/mach-rsk/Kconfig18
-rw-r--r--arch/sh/boards/mach-rsk/Makefile2
-rw-r--r--arch/sh/boards/mach-rsk/devices-rsk7203.c (renamed from arch/sh/boards/board-rsk7203.c)76
-rw-r--r--arch/sh/boards/mach-rsk/setup.c106
-rw-r--r--arch/sh/boards/mach-se/7343/Makefile2
-rw-r--r--arch/sh/boards/mach-se/7343/io.c273
-rw-r--r--arch/sh/boards/mach-se/7343/setup.c126
-rw-r--r--arch/sh/boards/mach-se/770x/setup.c4
-rw-r--r--arch/sh/boards/mach-se/7721/setup.c7
-rw-r--r--arch/sh/boards/mach-se/7722/setup.c10
-rw-r--r--arch/sh/boards/mach-sh03/setup.c59
-rw-r--r--arch/sh/boards/mach-systemh/irq.c37
-rw-r--r--arch/sh/cchips/hd6446x/hd64461.c115
-rw-r--r--arch/sh/configs/edosk7705_defconfig438
-rw-r--r--arch/sh/configs/rsk7201_defconfig703
-rw-r--r--arch/sh/configs/rsk7203_defconfig65
-rw-r--r--arch/sh/configs/rts7751r2dplus_qemu_defconfig949
-rw-r--r--arch/sh/configs/se7343_defconfig303
-rw-r--r--arch/sh/drivers/dma/Makefile1
-rw-r--r--arch/sh/drivers/dma/dma-isa.c106
-rw-r--r--arch/sh/drivers/dma/dma-sh.c3
-rw-r--r--arch/sh/drivers/dma/dma-sh.h1
-rw-r--r--arch/sh/drivers/pci/ops-sh03.c3
-rw-r--r--arch/sh/drivers/pci/pci-sh7780.c12
-rw-r--r--arch/sh/include/asm/addrspace.h11
-rw-r--r--arch/sh/include/asm/bitops-grb.h3
-rw-r--r--arch/sh/include/asm/bitops-irq.h91
-rw-r--r--arch/sh/include/asm/bitops-llsc.h2
-rw-r--r--arch/sh/include/asm/bitops-op32.h142
-rw-r--r--arch/sh/include/asm/bitops.h9
-rw-r--r--arch/sh/include/asm/bugs.h2
-rw-r--r--arch/sh/include/asm/elf.h2
-rw-r--r--arch/sh/include/asm/ftrace.h28
-rw-r--r--arch/sh/include/asm/io.h4
-rw-r--r--arch/sh/include/asm/kgdb.h66
-rw-r--r--arch/sh/include/asm/machvec.h5
-rw-r--r--arch/sh/include/asm/mmu_context.h4
-rw-r--r--arch/sh/include/asm/mutex-llsc.h112
-rw-r--r--arch/sh/include/asm/mutex.h5
-rw-r--r--arch/sh/include/asm/pm.h17
-rw-r--r--arch/sh/include/asm/processor.h5
-rw-r--r--arch/sh/include/asm/processor_32.h12
-rw-r--r--arch/sh/include/asm/processor_64.h4
-rw-r--r--arch/sh/include/asm/ptrace.h2
-rw-r--r--arch/sh/include/asm/sh_bios.h1
-rw-r--r--arch/sh/include/asm/string_64.h21
-rw-r--r--arch/sh/include/asm/syscall_32.h2
-rw-r--r--arch/sh/include/asm/syscall_64.h76
-rw-r--r--arch/sh/include/asm/system.h2
-rw-r--r--arch/sh/include/asm/unaligned-sh4a.h258
-rw-r--r--arch/sh/include/asm/unaligned.h7
-rw-r--r--arch/sh/include/cpu-sh3/cpu/gpio.h14
-rw-r--r--arch/sh/include/mach-common/mach/edosk7705.h31
-rw-r--r--arch/sh/include/mach-se/mach/mrshpc.h52
-rw-r--r--arch/sh/include/mach-se/mach/se.h18
-rw-r--r--arch/sh/include/mach-se/mach/se7343.h9
-rw-r--r--arch/sh/kernel/Makefile_3218
-rw-r--r--arch/sh/kernel/Makefile_645
-rw-r--r--arch/sh/kernel/cf-enabler.c168
-rw-r--r--arch/sh/kernel/cpu/clock.c10
-rw-r--r--arch/sh/kernel/cpu/init.c2
-rw-r--r--arch/sh/kernel/cpu/sh2a/Makefile3
-rw-r--r--arch/sh/kernel/cpu/sh2a/clock-sh7201.c85
-rw-r--r--arch/sh/kernel/cpu/sh2a/probe.c7
-rw-r--r--arch/sh/kernel/cpu/sh2a/setup-sh7201.c331
-rw-r--r--arch/sh/kernel/cpu/sh3/entry.S14
-rw-r--r--arch/sh/kernel/cpu/sh3/ex.S2
-rw-r--r--arch/sh/kernel/cpu/sh4/softfloat.c73
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7722.c310
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7343.c37
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7366.c19
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7722.c50
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7723.c19
-rw-r--r--arch/sh/kernel/debugtraps.S13
-rw-r--r--arch/sh/kernel/disassemble.c573
-rw-r--r--arch/sh/kernel/entry-common.S54
-rw-r--r--arch/sh/kernel/ftrace.c133
-rw-r--r--arch/sh/kernel/head_32.S12
-rw-r--r--arch/sh/kernel/idle.c81
-rw-r--r--arch/sh/kernel/kgdb.c285
-rw-r--r--arch/sh/kernel/kgdb_jmp.S33
-rw-r--r--arch/sh/kernel/kgdb_stub.c1052
-rw-r--r--arch/sh/kernel/pm.c88
-rw-r--r--arch/sh/kernel/process_32.c81
-rw-r--r--arch/sh/kernel/process_64.c111
-rw-r--r--arch/sh/kernel/ptrace_64.c186
-rw-r--r--arch/sh/kernel/setup.c1
-rw-r--r--arch/sh/kernel/sh_bios.c65
-rw-r--r--arch/sh/kernel/sh_ksyms_32.c37
-rw-r--r--arch/sh/kernel/sh_ksyms_64.c5
-rw-r--r--arch/sh/kernel/signal_32.c1
-rw-r--r--arch/sh/kernel/signal_64.c154
-rw-r--r--arch/sh/kernel/sys_sh.c92
-rw-r--r--arch/sh/kernel/time_32.c12
-rw-r--r--arch/sh/kernel/time_64.c5
-rw-r--r--arch/sh/kernel/timers/timer-mtu2.c5
-rw-r--r--arch/sh/kernel/traps_32.c36
-rw-r--r--arch/sh/lib/Makefile16
-rw-r--r--arch/sh/lib/ashiftrt.S149
-rw-r--r--arch/sh/lib/ashldi3.c29
-rw-r--r--arch/sh/lib/ashlsi3.S193
-rw-r--r--arch/sh/lib/ashrdi3.c31
-rw-r--r--arch/sh/lib/ashrsi3.S185
-rw-r--r--arch/sh/lib/libgcc.h26
-rw-r--r--arch/sh/lib/lshrdi3.c29
-rw-r--r--arch/sh/lib/lshrsi3.S193
-rw-r--r--arch/sh/lib/mcount.S90
-rw-r--r--arch/sh/lib/movmem.S238
-rw-r--r--arch/sh/lib/udiv_qrnnd.S81
-rw-r--r--arch/sh/lib/udivsi3.S87
-rw-r--r--arch/sh/lib/udivsi3_i4i-Os.S149
-rw-r--r--arch/sh/lib/udivsi3_i4i.S666
-rw-r--r--arch/sh/lib64/Makefile8
-rw-r--r--arch/sh/lib64/c-checksum.c4
-rw-r--r--arch/sh/lib64/memcpy.S201
-rw-r--r--arch/sh/lib64/memcpy.c81
-rw-r--r--arch/sh/lib64/memset.S91
-rw-r--r--arch/sh/lib64/sdivsi3.S131
-rw-r--r--arch/sh/lib64/strcpy.S97
-rw-r--r--arch/sh/lib64/strlen.S33
-rw-r--r--arch/sh/lib64/udivdi3.S120
-rw-r--r--arch/sh/lib64/udivsi3.S59
-rw-r--r--arch/sh/mm/Makefile_321
-rw-r--r--arch/sh/mm/Makefile_641
-rw-r--r--arch/sh/mm/asids-debugfs.c79
-rw-r--r--arch/sh/mm/consistent.c7
-rw-r--r--arch/sh/mm/fault_32.c17
-rw-r--r--arch/sh/mm/ioremap_32.c3
-rw-r--r--arch/sh/mm/mmap.c94
-rw-r--r--arch/sh/oprofile/Makefile13
-rw-r--r--arch/sh/oprofile/backtrace.c114
-rw-r--r--arch/sh/oprofile/common.c150
-rw-r--r--arch/sh/oprofile/op_impl.h33
-rw-r--r--arch/sh/oprofile/op_model_null.c23
-rw-r--r--arch/sh/oprofile/op_model_sh7750.c172
-rw-r--r--arch/sh/tools/mach-types2
-rw-r--r--arch/x86/crypto/crc32c-intel.c121
-rw-r--r--crypto/Kconfig29
-rw-r--r--crypto/Makefile1
-rw-r--r--crypto/aes_generic.c1145
-rw-r--r--crypto/ahash.c38
-rw-r--r--crypto/ansi_cprng.c35
-rw-r--r--crypto/api.c121
-rw-r--r--crypto/authenc.c3
-rw-r--r--crypto/camellia.c84
-rw-r--r--crypto/crc32c.c290
-rw-r--r--crypto/crypto_null.c64
-rw-r--r--crypto/des_generic.c5
-rw-r--r--crypto/fcrypt.c8
-rw-r--r--crypto/hmac.c10
-rw-r--r--crypto/internal.h2
-rw-r--r--crypto/md4.c56
-rw-r--r--crypto/md5.c50
-rw-r--r--crypto/michael_mic.c72
-rw-r--r--crypto/proc.c20
-rw-r--r--crypto/rmd128.c61
-rw-r--r--crypto/rmd160.c61
-rw-r--r--crypto/rmd256.c61
-rw-r--r--crypto/rmd320.c61
-rw-r--r--crypto/salsa20_generic.c75
-rw-r--r--crypto/sha1_generic.c56
-rw-r--r--crypto/sha256_generic.c104
-rw-r--r--crypto/sha512_generic.c127
-rw-r--r--crypto/shash.c508
-rw-r--r--crypto/testmgr.c76
-rw-r--r--crypto/testmgr.h2
-rw-r--r--crypto/tgr192.c135
-rw-r--r--crypto/wp512.c121
-rw-r--r--drivers/crypto/hifn_795x.c494
-rw-r--r--drivers/crypto/padlock-aes.c52
-rw-r--r--drivers/crypto/talitos.c153
-rw-r--r--drivers/crypto/talitos.h85
-rw-r--r--drivers/i2c/busses/i2c-sh_mobile.c73
-rw-r--r--drivers/input/keyboard/sh_keysc.c28
-rw-r--r--drivers/media/video/Kconfig2
-rw-r--r--drivers/media/video/sh_mobile_ceu_camera.c20
-rw-r--r--drivers/serial/sh-sci.c563
-rw-r--r--drivers/serial/sh-sci.h45
-rw-r--r--drivers/usb/gadget/m66592-udc.c34
-rw-r--r--drivers/usb/gadget/m66592-udc.h27
-rw-r--r--drivers/usb/host/r8a66597-hcd.c34
-rw-r--r--drivers/usb/host/r8a66597.h8
-rw-r--r--drivers/video/Kconfig33
-rw-r--r--drivers/video/fb_defio.c27
-rw-r--r--drivers/video/sh7760fb.c86
-rw-r--r--drivers/video/sh_mobile_lcdcfb.c198
-rw-r--r--include/crypto/aes.h8
-rw-r--r--include/crypto/algapi.h16
-rw-r--r--include/crypto/hash.h125
-rw-r--r--include/crypto/internal/hash.h16
-rw-r--r--include/linux/crc32c.h6
-rw-r--r--include/linux/crypto.h10
-rw-r--r--include/linux/fb.h2
-rw-r--r--include/linux/input.h2
-rw-r--r--include/linux/mfd/wm8350/audio.h38
-rw-r--r--include/sound/ac97_codec.h2
-rw-r--r--include/sound/asound.h1
-rw-r--r--include/sound/core.h28
-rw-r--r--include/sound/info.h106
-rw-r--r--include/sound/jack.h2
-rw-r--r--include/sound/l3.h18
-rw-r--r--include/sound/s3c24xx_uda134x.h14
-rw-r--r--include/sound/soc-dai.h231
-rw-r--r--include/sound/soc-dapm.h2
-rw-r--r--include/sound/soc.h206
-rw-r--r--include/sound/uda134x.h26
-rw-r--r--include/sound/version.h2
-rw-r--r--include/video/sh_mobile_lcdc.h1
-rw-r--r--lib/Kconfig2
-rw-r--r--lib/libcrc32c.c182
-rwxr-xr-xscripts/recordmcount.pl11
-rw-r--r--sound/ac97_bus.c1
-rw-r--r--sound/aoa/codecs/Makefile4
-rw-r--r--sound/aoa/codecs/onyx.c (renamed from sound/aoa/codecs/snd-aoa-codec-onyx.c)12
-rw-r--r--sound/aoa/codecs/onyx.h (renamed from sound/aoa/codecs/snd-aoa-codec-onyx.h)0
-rw-r--r--sound/aoa/codecs/tas-basstreble.h (renamed from sound/aoa/codecs/snd-aoa-codec-tas-basstreble.h)0
-rw-r--r--sound/aoa/codecs/tas-gain-table.h (renamed from sound/aoa/codecs/snd-aoa-codec-tas-gain-table.h)0
-rw-r--r--sound/aoa/codecs/tas.c (renamed from sound/aoa/codecs/snd-aoa-codec-tas.c)8
-rw-r--r--sound/aoa/codecs/tas.h (renamed from sound/aoa/codecs/snd-aoa-codec-tas.h)0
-rw-r--r--sound/aoa/codecs/toonie.c (renamed from sound/aoa/codecs/snd-aoa-codec-toonie.c)2
-rw-r--r--sound/aoa/core/Makefile8
-rw-r--r--sound/aoa/core/alsa.c (renamed from sound/aoa/core/snd-aoa-alsa.c)4
-rw-r--r--sound/aoa/core/alsa.h (renamed from sound/aoa/core/snd-aoa-alsa.h)0
-rw-r--r--sound/aoa/core/core.c (renamed from sound/aoa/core/snd-aoa-core.c)2
-rw-r--r--sound/aoa/core/gpio-feature.c (renamed from sound/aoa/core/snd-aoa-gpio-feature.c)2
-rw-r--r--sound/aoa/core/gpio-pmf.c (renamed from sound/aoa/core/snd-aoa-gpio-pmf.c)0
-rw-r--r--sound/aoa/fabrics/Makefile2
-rw-r--r--sound/aoa/fabrics/layout.c (renamed from sound/aoa/fabrics/snd-aoa-fabric-layout.c)2
-rw-r--r--sound/aoa/soundbus/i2sbus/Makefile2
-rw-r--r--sound/aoa/soundbus/i2sbus/control.c (renamed from sound/aoa/soundbus/i2sbus/i2sbus-control.c)0
-rw-r--r--sound/aoa/soundbus/i2sbus/core.c (renamed from sound/aoa/soundbus/i2sbus/i2sbus-core.c)4
-rw-r--r--sound/aoa/soundbus/i2sbus/i2sbus.h2
-rw-r--r--sound/aoa/soundbus/i2sbus/interface.h (renamed from sound/aoa/soundbus/i2sbus/i2sbus-interface.h)0
-rw-r--r--sound/aoa/soundbus/i2sbus/pcm.c (renamed from sound/aoa/soundbus/i2sbus/i2sbus-pcm.c)0
-rw-r--r--sound/core/Kconfig21
-rw-r--r--sound/core/Makefile2
-rw-r--r--sound/core/device.c4
-rw-r--r--sound/core/hrtimer.c155
-rw-r--r--sound/core/info.c17
-rw-r--r--sound/core/init.c71
-rw-r--r--sound/core/jack.c15
-rw-r--r--sound/core/rawmidi.c4
-rw-r--r--sound/core/rtctimer.c2
-rw-r--r--sound/core/seq/seq.c4
-rw-r--r--sound/core/timer.c2
-rw-r--r--sound/drivers/Kconfig2
-rw-r--r--sound/drivers/pcsp/pcsp.c8
-rw-r--r--sound/drivers/pcsp/pcsp.h3
-rw-r--r--sound/drivers/pcsp/pcsp_lib.c168
-rw-r--r--sound/drivers/vx/vx_core.c2
-rw-r--r--sound/drivers/vx/vx_pcm.c2
-rw-r--r--sound/isa/sb/sb8.c4
-rw-r--r--sound/pci/Kconfig127
-rw-r--r--sound/pci/ac97/ac97_codec.c2
-rw-r--r--sound/pci/ac97/ac97_patch.c7
-rw-r--r--sound/pci/ca0106/ca0106.h30
-rw-r--r--sound/pci/ca0106/ca0106_main.c550
-rw-r--r--sound/pci/ca0106/ca0106_mixer.c263
-rw-r--r--sound/pci/cs46xx/cs46xx_lib.c5
-rw-r--r--sound/pci/cs5535audio/Makefile3
-rw-r--r--sound/pci/cs5535audio/cs5535audio.c12
-rw-r--r--sound/pci/cs5535audio/cs5535audio.h39
-rw-r--r--sound/pci/cs5535audio/cs5535audio_olpc.c179
-rw-r--r--sound/pci/cs5535audio/cs5535audio_pcm.c15
-rw-r--r--sound/pci/emu10k1/emu10k1_main.c494
-rw-r--r--sound/pci/emu10k1/emumixer.c46
-rw-r--r--sound/pci/es1968.c2
-rw-r--r--sound/pci/hda/Kconfig188
-rw-r--r--sound/pci/hda/Makefile75
-rw-r--r--sound/pci/hda/hda_beep.c2
-rw-r--r--sound/pci/hda/hda_codec.c781
-rw-r--r--sound/pci/hda/hda_codec.h107
-rw-r--r--sound/pci/hda/hda_eld.c590
-rw-r--r--sound/pci/hda/hda_generic.c21
-rw-r--r--sound/pci/hda/hda_hwdep.c234
-rw-r--r--sound/pci/hda/hda_intel.c348
-rw-r--r--sound/pci/hda/hda_local.h100
-rw-r--r--sound/pci/hda/hda_patch.h22
-rw-r--r--sound/pci/hda/hda_proc.c91
-rw-r--r--sound/pci/hda/patch_analog.c132
-rw-r--r--sound/pci/hda/patch_atihdmi.c40
-rw-r--r--sound/pci/hda/patch_cmedia.c27
-rw-r--r--sound/pci/hda/patch_conexant.c39
-rw-r--r--sound/pci/hda/patch_intelhdmi.c711
-rw-r--r--sound/pci/hda/patch_nvhdmi.c32
-rw-r--r--sound/pci/hda/patch_realtek.c1663
-rw-r--r--sound/pci/hda/patch_si3054.c35
-rw-r--r--sound/pci/hda/patch_sigmatel.c1318
-rw-r--r--sound/pci/hda/patch_via.c171
-rw-r--r--sound/pci/ice1712/ice1724.c23
-rw-r--r--sound/pci/maestro3.c2
-rw-r--r--sound/pci/mixart/mixart.c4
-rw-r--r--sound/pci/mixart/mixart_core.c2
-rw-r--r--sound/pci/oxygen/oxygen.c4
-rw-r--r--sound/pci/pcxhr/Makefile2
-rw-r--r--sound/pci/pcxhr/pcxhr.c558
-rw-r--r--sound/pci/pcxhr/pcxhr.h76
-rw-r--r--sound/pci/pcxhr/pcxhr_core.c293
-rw-r--r--sound/pci/pcxhr/pcxhr_core.h5
-rw-r--r--sound/pci/pcxhr/pcxhr_hwdep.c158
-rw-r--r--sound/pci/pcxhr/pcxhr_mix22.c820
-rw-r--r--sound/pci/pcxhr/pcxhr_mix22.h56
-rw-r--r--sound/pci/pcxhr/pcxhr_mixer.c556
-rw-r--r--sound/pci/riptide/riptide.c4
-rw-r--r--sound/pci/rme9652/hdsp.c4
-rw-r--r--sound/pci/rme9652/hdspm.c4
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf_irq.c2
-rw-r--r--sound/ppc/pmac.c2
-rw-r--r--sound/ppc/tumbler.c3
-rw-r--r--sound/soc/Kconfig13
-rw-r--r--sound/soc/Makefile12
-rw-r--r--sound/soc/at32/Kconfig34
-rw-r--r--sound/soc/at32/Makefile11
-rw-r--r--sound/soc/at32/at32-pcm.c492
-rw-r--r--sound/soc/at32/at32-pcm.h79
-rw-r--r--sound/soc/at32/at32-ssc.c849
-rw-r--r--sound/soc/at32/at32-ssc.h59
-rw-r--r--sound/soc/at91/Kconfig10
-rw-r--r--sound/soc/at91/Makefile6
-rw-r--r--sound/soc/at91/at91-pcm.c434
-rw-r--r--sound/soc/at91/at91-pcm.h72
-rw-r--r--sound/soc/at91/at91-ssc.c791
-rw-r--r--sound/soc/at91/at91-ssc.h27
-rw-r--r--sound/soc/atmel/Kconfig43
-rw-r--r--sound/soc/atmel/Makefile15
-rw-r--r--sound/soc/atmel/atmel-pcm.c494
-rw-r--r--sound/soc/atmel/atmel-pcm.h86
-rw-r--r--sound/soc/atmel/atmel_ssc_dai.c790
-rw-r--r--sound/soc/atmel/atmel_ssc_dai.h121
-rw-r--r--sound/soc/atmel/playpaq_wm8510.c (renamed from sound/soc/at32/playpaq_wm8510.c)11
-rw-r--r--sound/soc/atmel/sam9g20_wm8731.c328
-rw-r--r--sound/soc/au1x/dbdma2.c3
-rw-r--r--sound/soc/au1x/psc-ac97.c16
-rw-r--r--sound/soc/au1x/psc-i2s.c18
-rw-r--r--sound/soc/au1x/sample-ac97.c4
-rw-r--r--sound/soc/blackfin/Kconfig22
-rw-r--r--sound/soc/blackfin/bf5xx-ac97-pcm.c113
-rw-r--r--sound/soc/blackfin/bf5xx-ac97.c178
-rw-r--r--sound/soc/blackfin/bf5xx-ac97.h35
-rw-r--r--sound/soc/blackfin/bf5xx-ad1980.c8
-rw-r--r--sound/soc/blackfin/bf5xx-ad73311.c10
-rw-r--r--sound/soc/blackfin/bf5xx-i2s-pcm.c12
-rw-r--r--sound/soc/blackfin/bf5xx-i2s.c31
-rw-r--r--sound/soc/blackfin/bf5xx-sport.h2
-rw-r--r--sound/soc/blackfin/bf5xx-ssm2602.c14
-rw-r--r--sound/soc/codecs/Kconfig69
-rw-r--r--sound/soc/codecs/Makefile12
-rw-r--r--sound/soc/codecs/ac97.c7
-rw-r--r--sound/soc/codecs/ad1980.c24
-rw-r--r--sound/soc/codecs/ad73311.c18
-rw-r--r--sound/soc/codecs/ak4535.c19
-rw-r--r--sound/soc/codecs/cs4270.c38
-rw-r--r--sound/soc/codecs/l3.c91
-rw-r--r--sound/soc/codecs/pcm3008.c212
-rw-r--r--sound/soc/codecs/pcm3008.h25
-rw-r--r--sound/soc/codecs/ssm2602.c57
-rw-r--r--sound/soc/codecs/tlv320aic23.c262
-rw-r--r--sound/soc/codecs/tlv320aic26.c22
-rw-r--r--sound/soc/codecs/tlv320aic3x.c166
-rw-r--r--sound/soc/codecs/tlv320aic3x.h60
-rw-r--r--sound/soc/codecs/twl4030.c1317
-rw-r--r--sound/soc/codecs/twl4030.h219
-rw-r--r--sound/soc/codecs/uda134x.c668
-rw-r--r--sound/soc/codecs/uda134x.h36
-rw-r--r--sound/soc/codecs/uda1380.c29
-rw-r--r--sound/soc/codecs/wm8350.c1583
-rw-r--r--sound/soc/codecs/wm8350.h20
-rw-r--r--sound/soc/codecs/wm8510.c19
-rw-r--r--sound/soc/codecs/wm8580.c134
-rw-r--r--sound/soc/codecs/wm8580.h1
-rw-r--r--sound/soc/codecs/wm8728.c585
-rw-r--r--sound/soc/codecs/wm8728.h30
-rw-r--r--sound/soc/codecs/wm8731.c25
-rw-r--r--sound/soc/codecs/wm8750.c19
-rw-r--r--sound/soc/codecs/wm8753.c39
-rw-r--r--sound/soc/codecs/wm8900.c262
-rw-r--r--sound/soc/codecs/wm8900.h6
-rw-r--r--sound/soc/codecs/wm8903.c268
-rw-r--r--sound/soc/codecs/wm8903.h5
-rw-r--r--sound/soc/codecs/wm8971.c19
-rw-r--r--sound/soc/codecs/wm8990.c43
-rw-r--r--sound/soc/codecs/wm8990.h4
-rw-r--r--sound/soc/codecs/wm9712.c12
-rw-r--r--sound/soc/codecs/wm9713.c46
-rw-r--r--sound/soc/davinci/Kconfig10
-rw-r--r--sound/soc/davinci/Makefile2
-rw-r--r--sound/soc/davinci/davinci-evm.c14
-rw-r--r--sound/soc/davinci/davinci-i2s.c257
-rw-r--r--sound/soc/davinci/davinci-pcm.c30
-rw-r--r--sound/soc/davinci/davinci-sffsdr.c157
-rw-r--r--sound/soc/fsl/Kconfig2
-rw-r--r--sound/soc/fsl/fsl_dma.c14
-rw-r--r--sound/soc/fsl/fsl_ssi.c24
-rw-r--r--sound/soc/fsl/mpc5200_psc_i2s.c22
-rw-r--r--sound/soc/fsl/mpc8610_hpcd.c8
-rw-r--r--sound/soc/fsl/soc-of-simple.c12
-rw-r--r--sound/soc/omap/Kconfig35
-rw-r--r--sound/soc/omap/Makefile8
-rw-r--r--sound/soc/omap/n810.c10
-rw-r--r--sound/soc/omap/omap-mcbsp.c61
-rw-r--r--sound/soc/omap/omap-pcm.c14
-rw-r--r--sound/soc/omap/omap2evm.c151
-rw-r--r--sound/soc/omap/omap3beagle.c149
-rw-r--r--sound/soc/omap/omap3pandora.c311
-rw-r--r--sound/soc/omap/osk5912.c10
-rw-r--r--sound/soc/omap/overo.c148
-rw-r--r--sound/soc/omap/sdp3430.c152
-rw-r--r--sound/soc/pxa/Kconfig22
-rw-r--r--sound/soc/pxa/Makefile6
-rw-r--r--sound/soc/pxa/corgi.c12
-rw-r--r--sound/soc/pxa/e800_wm9712.c8
-rw-r--r--sound/soc/pxa/em-x270.c7
-rw-r--r--sound/soc/pxa/palm27x.c269
-rw-r--r--sound/soc/pxa/poodle.c6
-rw-r--r--sound/soc/pxa/pxa-ssp.c931
-rw-r--r--sound/soc/pxa/pxa-ssp.h47
-rw-r--r--sound/soc/pxa/pxa2xx-ac97.c33
-rw-r--r--sound/soc/pxa/pxa2xx-i2s.c35
-rw-r--r--sound/soc/pxa/pxa2xx-pcm.c14
-rw-r--r--sound/soc/pxa/spitz.c6
-rw-r--r--sound/soc/pxa/tosa.c38
-rw-r--r--sound/soc/pxa/zylonite.c219
-rw-r--r--sound/soc/s3c24xx/Kconfig5
-rw-r--r--sound/soc/s3c24xx/Makefile2
-rw-r--r--sound/soc/s3c24xx/ln2440sbc_alc650.c8
-rw-r--r--sound/soc/s3c24xx/neo1973_wm8753.c9
-rw-r--r--sound/soc/s3c24xx/s3c2412-i2s.c38
-rw-r--r--sound/soc/s3c24xx/s3c2443-ac97.c30
-rw-r--r--sound/soc/s3c24xx/s3c24xx-i2s.c35
-rw-r--r--sound/soc/s3c24xx/s3c24xx-pcm.c12
-rw-r--r--sound/soc/s3c24xx/s3c24xx_uda134x.c373
-rw-r--r--sound/soc/s3c24xx/smdk2443_wm9710.c8
-rw-r--r--sound/soc/sh/dma-sh7760.c12
-rw-r--r--sound/soc/sh/hac.c19
-rw-r--r--sound/soc/sh/sh7760-ac97.c6
-rw-r--r--sound/soc/sh/ssi.c30
-rw-r--r--sound/soc/soc-core.c840
-rw-r--r--sound/soc/soc-dapm.c82
-rw-r--r--sound/sound_core.c1
-rw-r--r--sound/usb/caiaq/caiaq-control.c73
-rw-r--r--sound/usb/caiaq/caiaq-device.c2
-rw-r--r--sound/usb/usbmidi.c2
-rw-r--r--sound/usb/usx2y/usb_stream.c3
474 files changed, 34735 insertions, 15142 deletions
diff --git a/Documentation/cpu-freq/user-guide.txt b/Documentation/cpu-freq/user-guide.txt
index 4f3f3840320e..e3443ddcfb89 100644
--- a/Documentation/cpu-freq/user-guide.txt
+++ b/Documentation/cpu-freq/user-guide.txt
@@ -93,10 +93,8 @@ Several "PowerBook" and "iBook2" notebooks are supported.
931.5 SuperH 931.5 SuperH
94---------- 94----------
95 95
96The following SuperH processors are supported by cpufreq: 96All SuperH processors supporting rate rounding through the clock
97 97framework are supported by cpufreq.
98SH-3
99SH-4
100 98
1011.6 Blackfin 991.6 Blackfin
102------------ 100------------
diff --git a/Documentation/sh/kgdb.txt b/Documentation/sh/kgdb.txt
deleted file mode 100644
index 05b4ba89d28c..000000000000
--- a/Documentation/sh/kgdb.txt
+++ /dev/null
@@ -1,179 +0,0 @@
1
2This file describes the configuration and behavior of KGDB for the SH
3kernel. Based on a description from Henry Bell <henry.bell@st.com>, it
4has been modified to account for quirks in the current implementation.
5
6Version
7=======
8
9This version of KGDB was written for 2.4.xx kernels for the SH architecture.
10Further documentation is available from the linux-sh project website.
11
12
13Debugging Setup: Host
14======================
15
16The two machines will be connected together via a serial line - this
17should be a null modem cable i.e. with a twist.
18
19On your DEVELOPMENT machine, go to your kernel source directory and
20build the kernel, enabling KGDB support in the "kernel hacking" section.
21This includes the KGDB code, and also makes the kernel be compiled with
22the "-g" option set -- necessary for debugging.
23
24To install this new kernel, use the following installation procedure.
25
26Decide on which tty port you want the machines to communicate, then
27cable them up back-to-back using the null modem. On the DEVELOPMENT
28machine, you may wish to create an initialization file called .gdbinit
29(in the kernel source directory or in your home directory) to execute
30commonly-used commands at startup.
31
32A minimal .gdbinit might look like this:
33
34 file vmlinux
35 set remotebaud 115200
36 target remote /dev/ttyS0
37
38Change the "target" definition so that it specifies the tty port that
39you intend to use. Change the "remotebaud" definition to match the
40data rate that you are going to use for the com line (115200 is the
41default).
42
43Debugging Setup: Target
44========================
45
46By default, the KGDB stub will communicate with the host GDB using
47ttySC1 at 115200 baud, 8 databits, no parity; these defaults can be
48changed in the kernel configuration. As the kernel starts up, KGDB will
49initialize so that breakpoints, kernel segfaults, and so forth will
50generally enter the debugger.
51
52This behavior can be modified by including the "kgdb" option in the
53kernel command line; this option has the general form:
54
55 kgdb=<ttyspec>,<action>
56
57The <ttyspec> indicates the port to use, and can optionally specify
58baud, parity and databits -- e.g. "ttySC0,9600N8" or "ttySC1,19200".
59
60The <action> can be "halt" or "disabled". The "halt" action enters the
61debugger via a breakpoint as soon as kgdb is initialized; the "disabled"
62action causes kgdb to ignore kernel segfaults and such until explicitly
63entered by a breakpoint in the code or by external action (sysrq or NMI).
64
65(Both <ttyspec> and <action> can appear alone, w/o the separating comma.)
66
67For example, if you wish to debug early in kernel startup code, you
68might specify the halt option:
69
70 kgdb=halt
71
72Boot the TARGET machine, which will appear to hang.
73
74On your DEVELOPMENT machine, cd to the source directory and run the gdb
75program. (This is likely to be a cross GDB which runs on your host but
76is built for an SH target.) If everything is working correctly you
77should see gdb print out a few lines indicating that a breakpoint has
78been taken. It will actually show a line of code in the target kernel
79inside the gdbstub activation code.
80
81NOTE: BE SURE TO TERMINATE OR SUSPEND any other host application which
82may be using the same serial port (for example, a terminal emulator you
83have been using to connect to the target boot code.) Otherwise, data
84from the target may not all get to GDB!
85
86You can now use whatever gdb commands you like to set breakpoints.
87Enter "continue" to start your target machine executing again. At this
88point the target system will run at full speed until it encounters
89your breakpoint or gets a segment violation in the kernel, or whatever.
90
91Serial Ports: KGDB, Console
92============================
93
94This version of KGDB may not gracefully handle conflict with other
95drivers in the kernel using the same port. If KGDB is configured on the
96same port (and with the same parameters) as the kernel console, or if
97CONFIG_SH_KGDB_CONSOLE is configured, things should be fine (though in
98some cases console messages may appear twice through GDB). But if the
99KGDB port is not the kernel console and used by another serial driver
100which assumes different serial parameters (e.g. baud rate) KGDB may not
101recover.
102
103Also, when KGDB is entered via sysrq-g (requires CONFIG_KGDB_SYSRQ) and
104the kgdb port uses the same port as the console, detaching GDB will not
105restore the console to working order without the port being re-opened.
106
107Another serious consequence of this is that GDB currently CANNOT break
108into KGDB externally (e.g. via ^C or <BREAK>); unless a breakpoint or
109error is encountered, the only way to enter KGDB after the initial halt
110(see above) is via NMI (CONFIG_KGDB_NMI) or sysrq-g (CONFIG_KGDB_SYSRQ).
111
112Code is included for the basic Hitachi Solution Engine boards to allow
113the use of ttyS0 for KGDB if desired; this is less robust, but may be
114useful in some cases. (This cannot be selected using the config file,
115but only through the kernel command line, e.g. "kgdb=ttyS0", though the
116configured defaults for baud rate etc. still apply if not overridden.)
117
118If gdbstub Does Not Work
119========================
120
121If it doesn't work, you will have to troubleshoot it. Do the easy
122things first like double checking your cabling and data rates. You
123might try some non-kernel based programs to see if the back-to-back
124connection works properly. Just something simple like cat /etc/hosts
125/dev/ttyS0 on one machine and cat /dev/ttyS0 on the other will tell you
126if you can send data from one machine to the other. There is no point
127in tearing out your hair in the kernel if the line doesn't work.
128
129If you need to debug the GDB/KGDB communication itself, the gdb commands
130"set debug remote 1" and "set debug serial 1" may be useful, but be
131warned: they produce a lot of output.
132
133Threads
134=======
135
136Each process in a target machine is seen as a gdb thread. gdb thread related
137commands (info threads, thread n) can be used. CONFIG_KGDB_THREAD must
138be defined for this to work.
139
140In this version, kgdb reports PID_MAX (32768) as the process ID for the
141idle process (pid 0), since GDB does not accept 0 as an ID.
142
143Detaching (exiting KGDB)
144=========================
145
146There are two ways to resume full-speed target execution: "continue" and
147"detach". With "continue", GDB inserts any specified breakpoints in the
148target code and resumes execution; the target is still in "gdb mode".
149If a breakpoint or other debug event (e.g. NMI) happens, the target
150halts and communicates with GDB again, which is waiting for it.
151
152With "detach", GDB does *not* insert any breakpoints; target execution
153is resumed and GDB stops communicating (does not wait for the target).
154In this case, the target is no longer in "gdb mode" -- for example,
155console messages no longer get sent separately to the KGDB port, or
156encapsulated for GDB. If a debug event (e.g. NMI) occurs, the target
157will re-enter "gdb mode" and will display this fact on the console; you
158must give a new "target remote" command to gdb.
159
160NOTE: TO AVOID LOSSING CONSOLE MESSAGES IN CASE THE KERNEL CONSOLE AND
161KGDB USING THE SAME PORT, THE TARGET WAITS FOR ANY INPUT CHARACTER ON
162THE KGDB PORT AFTER A DETACH COMMAND. For example, after the detach you
163could start a terminal emulator on the same host port and enter a <cr>;
164however, this program must then be terminated or suspended in order to
165use GBD again if KGDB is re-entered.
166
167
168Acknowledgements
169================
170
171This code was mostly generated by Henry Bell <henry.bell@st.com>;
172largely from KGDB by Amit S. Kale <akale@veritas.com> - extracts from
173code by Glenn Engel, Jim Kingdon, David Grothe <dave@gcom.com>, Tigran
174Aivazian <tigran@sco.com>, William Gatliff <bgat@open-widgets.com>, Ben
175Lee, Steve Chamberlain and Benoit Miller <fulg@iname.com> are also
176included.
177
178Jeremy Siegel
179<jsiegel@mvista.com>
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
index 394d7d378dc7..841a9365d5fd 100644
--- a/Documentation/sound/alsa/ALSA-Configuration.txt
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt
@@ -757,6 +757,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
757 model - force the model name 757 model - force the model name
758 position_fix - Fix DMA pointer (0 = auto, 1 = use LPIB, 2 = POSBUF) 758 position_fix - Fix DMA pointer (0 = auto, 1 = use LPIB, 2 = POSBUF)
759 probe_mask - Bitmask to probe codecs (default = -1, meaning all slots) 759 probe_mask - Bitmask to probe codecs (default = -1, meaning all slots)
760 probe_only - Only probing and no codec initialization (default=off);
761 Useful to check the initial codec status for debugging
760 bdl_pos_adj - Specifies the DMA IRQ timing delay in samples. 762 bdl_pos_adj - Specifies the DMA IRQ timing delay in samples.
761 Passing -1 will make the driver to choose the appropriate 763 Passing -1 will make the driver to choose the appropriate
762 value based on the controller chip. 764 value based on the controller chip.
@@ -772,327 +774,23 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
772 774
773 This module supports multiple cards and autoprobe. 775 This module supports multiple cards and autoprobe.
774 776
777 See Documentation/sound/alsa/HD-Audio.txt for more details about
778 HD-audio driver.
779
775 Each codec may have a model table for different configurations. 780 Each codec may have a model table for different configurations.
776 If your machine isn't listed there, the default (usually minimal) 781 If your machine isn't listed there, the default (usually minimal)
777 configuration is set up. You can pass "model=<name>" option to 782 configuration is set up. You can pass "model=<name>" option to
778 specify a certain model in such a case. There are different 783 specify a certain model in such a case. There are different
779 models depending on the codec chip. 784 models depending on the codec chip. The list of available models
780 785 is found in HD-Audio-Models.txt
781 Model name Description
782 ---------- -----------
783 ALC880
784 3stack 3-jack in back and a headphone out
785 3stack-digout 3-jack in back, a HP out and a SPDIF out
786 5stack 5-jack in back, 2-jack in front
787 5stack-digout 5-jack in back, 2-jack in front, a SPDIF out
788 6stack 6-jack in back, 2-jack in front
789 6stack-digout 6-jack with a SPDIF out
790 w810 3-jack
791 z71v 3-jack (HP shared SPDIF)
792 asus 3-jack (ASUS Mobo)
793 asus-w1v ASUS W1V
794 asus-dig ASUS with SPDIF out
795 asus-dig2 ASUS with SPDIF out (using GPIO2)
796 uniwill 3-jack
797 fujitsu Fujitsu Laptops (Pi1536)
798 F1734 2-jack
799 lg LG laptop (m1 express dual)
800 lg-lw LG LW20/LW25 laptop
801 tcl TCL S700
802 clevo Clevo laptops (m520G, m665n)
803 medion Medion Rim 2150
804 test for testing/debugging purpose, almost all controls can be
805 adjusted. Appearing only when compiled with
806 $CONFIG_SND_DEBUG=y
807 auto auto-config reading BIOS (default)
808
809 ALC260
810 hp HP machines
811 hp-3013 HP machines (3013-variant)
812 hp-dc7600 HP DC7600
813 fujitsu Fujitsu S7020
814 acer Acer TravelMate
815 will Will laptops (PB V7900)
816 replacer Replacer 672V
817 basic fixed pin assignment (old default model)
818 test for testing/debugging purpose, almost all controls can
819 adjusted. Appearing only when compiled with
820 $CONFIG_SND_DEBUG=y
821 auto auto-config reading BIOS (default)
822
823 ALC262
824 fujitsu Fujitsu Laptop
825 hp-bpc HP xw4400/6400/8400/9400 laptops
826 hp-bpc-d7000 HP BPC D7000
827 hp-tc-t5735 HP Thin Client T5735
828 hp-rp5700 HP RP5700
829 benq Benq ED8
830 benq-t31 Benq T31
831 hippo Hippo (ATI) with jack detection, Sony UX-90s
832 hippo_1 Hippo (Benq) with jack detection
833 sony-assamd Sony ASSAMD
834 toshiba-s06 Toshiba S06
835 toshiba-rx1 Toshiba RX1
836 ultra Samsung Q1 Ultra Vista model
837 lenovo-3000 Lenovo 3000 y410
838 nec NEC Versa S9100
839 basic fixed pin assignment w/o SPDIF
840 auto auto-config reading BIOS (default)
841
842 ALC267/268
843 quanta-il1 Quanta IL1 mini-notebook
844 3stack 3-stack model
845 toshiba Toshiba A205
846 acer Acer laptops
847 acer-aspire Acer Aspire One
848 dell Dell OEM laptops (Vostro 1200)
849 zepto Zepto laptops
850 test for testing/debugging purpose, almost all controls can
851 adjusted. Appearing only when compiled with
852 $CONFIG_SND_DEBUG=y
853 auto auto-config reading BIOS (default)
854
855 ALC269
856 basic Basic preset
857 quanta Quanta FL1
858 eeepc-p703 ASUS Eeepc P703 P900A
859 eeepc-p901 ASUS Eeepc P901 S101
860
861 ALC662/663
862 3stack-dig 3-stack (2-channel) with SPDIF
863 3stack-6ch 3-stack (6-channel)
864 3stack-6ch-dig 3-stack (6-channel) with SPDIF
865 6stack-dig 6-stack with SPDIF
866 lenovo-101e Lenovo laptop
867 eeepc-p701 ASUS Eeepc P701
868 eeepc-ep20 ASUS Eeepc EP20
869 ecs ECS/Foxconn mobo
870 m51va ASUS M51VA
871 g71v ASUS G71V
872 h13 ASUS H13
873 g50v ASUS G50V
874 asus-mode1 ASUS
875 asus-mode2 ASUS
876 asus-mode3 ASUS
877 asus-mode4 ASUS
878 asus-mode5 ASUS
879 asus-mode6 ASUS
880 auto auto-config reading BIOS (default)
881
882 ALC882/885
883 3stack-dig 3-jack with SPDIF I/O
884 6stack-dig 6-jack digital with SPDIF I/O
885 arima Arima W820Di1
886 targa Targa T8, MSI-1049 T8
887 asus-a7j ASUS A7J
888 asus-a7m ASUS A7M
889 macpro MacPro support
890 mbp3 Macbook Pro rev3
891 imac24 iMac 24'' with jack detection
892 w2jc ASUS W2JC
893 auto auto-config reading BIOS (default)
894
895 ALC883/888
896 3stack-dig 3-jack with SPDIF I/O
897 6stack-dig 6-jack digital with SPDIF I/O
898 3stack-6ch 3-jack 6-channel
899 3stack-6ch-dig 3-jack 6-channel with SPDIF I/O
900 6stack-dig-demo 6-jack digital for Intel demo board
901 acer Acer laptops (Travelmate 3012WTMi, Aspire 5600, etc)
902 acer-aspire Acer Aspire 9810
903 medion Medion Laptops
904 medion-md2 Medion MD2
905 targa-dig Targa/MSI
906 targa-2ch-dig Targs/MSI with 2-channel
907 laptop-eapd 3-jack with SPDIF I/O and EAPD (Clevo M540JE, M550JE)
908 lenovo-101e Lenovo 101E
909 lenovo-nb0763 Lenovo NB0763
910 lenovo-ms7195-dig Lenovo MS7195
911 lenovo-sky Lenovo Sky
912 haier-w66 Haier W66
913 3stack-hp HP machines with 3stack (Lucknow, Samba boards)
914 6stack-dell Dell machines with 6stack (Inspiron 530)
915 mitac Mitac 8252D
916 clevo-m720 Clevo M720 laptop series
917 fujitsu-pi2515 Fujitsu AMILO Pi2515
918 3stack-6ch-intel Intel DG33* boards
919 auto auto-config reading BIOS (default)
920
921 ALC861/660
922 3stack 3-jack
923 3stack-dig 3-jack with SPDIF I/O
924 6stack-dig 6-jack with SPDIF I/O
925 3stack-660 3-jack (for ALC660)
926 uniwill-m31 Uniwill M31 laptop
927 toshiba Toshiba laptop support
928 asus Asus laptop support
929 asus-laptop ASUS F2/F3 laptops
930 auto auto-config reading BIOS (default)
931
932 ALC861VD/660VD
933 3stack 3-jack
934 3stack-dig 3-jack with SPDIF OUT
935 6stack-dig 6-jack with SPDIF OUT
936 3stack-660 3-jack (for ALC660VD)
937 3stack-660-digout 3-jack with SPDIF OUT (for ALC660VD)
938 lenovo Lenovo 3000 C200
939 dallas Dallas laptops
940 hp HP TX1000
941 auto auto-config reading BIOS (default)
942
943 CMI9880
944 minimal 3-jack in back
945 min_fp 3-jack in back, 2-jack in front
946 full 6-jack in back, 2-jack in front
947 full_dig 6-jack in back, 2-jack in front, SPDIF I/O
948 allout 5-jack in back, 2-jack in front, SPDIF out
949 auto auto-config reading BIOS (default)
950
951 AD1882 / AD1882A
952 3stack 3-stack mode (default)
953 6stack 6-stack mode
954
955 AD1884A / AD1883 / AD1984A / AD1984B
956 desktop 3-stack desktop (default)
957 laptop laptop with HP jack sensing
958 mobile mobile devices with HP jack sensing
959 thinkpad Lenovo Thinkpad X300
960
961 AD1884
962 N/A
963
964 AD1981
965 basic 3-jack (default)
966 hp HP nx6320
967 thinkpad Lenovo Thinkpad T60/X60/Z60
968 toshiba Toshiba U205
969
970 AD1983
971 N/A
972
973 AD1984
974 basic default configuration
975 thinkpad Lenovo Thinkpad T61/X61
976 dell Dell T3400
977
978 AD1986A
979 6stack 6-jack, separate surrounds (default)
980 3stack 3-stack, shared surrounds
981 laptop 2-channel only (FSC V2060, Samsung M50)
982 laptop-eapd 2-channel with EAPD (Samsung R65, ASUS A6J)
983 laptop-automute 2-channel with EAPD and HP-automute (Lenovo N100)
984 ultra 2-channel with EAPD (Samsung Ultra tablet PC)
985
986 AD1988/AD1988B/AD1989A/AD1989B
987 6stack 6-jack
988 6stack-dig ditto with SPDIF
989 3stack 3-jack
990 3stack-dig ditto with SPDIF
991 laptop 3-jack with hp-jack automute
992 laptop-dig ditto with SPDIF
993 auto auto-config reading BIOS (default)
994
995 Conexant 5045
996 laptop-hpsense Laptop with HP sense (old model laptop)
997 laptop-micsense Laptop with Mic sense (old model fujitsu)
998 laptop-hpmicsense Laptop with HP and Mic senses
999 benq Benq R55E
1000 test for testing/debugging purpose, almost all controls
1001 can be adjusted. Appearing only when compiled with
1002 $CONFIG_SND_DEBUG=y
1003
1004 Conexant 5047
1005 laptop Basic Laptop config
1006 laptop-hp Laptop config for some HP models (subdevice 30A5)
1007 laptop-eapd Laptop config with EAPD support
1008 test for testing/debugging purpose, almost all controls
1009 can be adjusted. Appearing only when compiled with
1010 $CONFIG_SND_DEBUG=y
1011
1012 Conexant 5051
1013 laptop Basic Laptop config (default)
1014 hp HP Spartan laptop
1015
1016 STAC9200
1017 ref Reference board
1018 dell-d21 Dell (unknown)
1019 dell-d22 Dell (unknown)
1020 dell-d23 Dell (unknown)
1021 dell-m21 Dell Inspiron 630m, Dell Inspiron 640m
1022 dell-m22 Dell Latitude D620, Dell Latitude D820
1023 dell-m23 Dell XPS M1710, Dell Precision M90
1024 dell-m24 Dell Latitude 120L
1025 dell-m25 Dell Inspiron E1505n
1026 dell-m26 Dell Inspiron 1501
1027 dell-m27 Dell Inspiron E1705/9400
1028 gateway Gateway laptops with EAPD control
1029 panasonic Panasonic CF-74
1030
1031 STAC9205/9254
1032 ref Reference board
1033 dell-m42 Dell (unknown)
1034 dell-m43 Dell Precision
1035 dell-m44 Dell Inspiron
1036
1037 STAC9220/9221
1038 ref Reference board
1039 3stack D945 3stack
1040 5stack D945 5stack + SPDIF
1041 intel-mac-v1 Intel Mac Type 1
1042 intel-mac-v2 Intel Mac Type 2
1043 intel-mac-v3 Intel Mac Type 3
1044 intel-mac-v4 Intel Mac Type 4
1045 intel-mac-v5 Intel Mac Type 5
1046 intel-mac-auto Intel Mac (detect type according to subsystem id)
1047 macmini Intel Mac Mini (equivalent with type 3)
1048 macbook Intel Mac Book (eq. type 5)
1049 macbook-pro-v1 Intel Mac Book Pro 1st generation (eq. type 3)
1050 macbook-pro Intel Mac Book Pro 2nd generation (eq. type 3)
1051 imac-intel Intel iMac (eq. type 2)
1052 imac-intel-20 Intel iMac (newer version) (eq. type 3)
1053 dell-d81 Dell (unknown)
1054 dell-d82 Dell (unknown)
1055 dell-m81 Dell (unknown)
1056 dell-m82 Dell XPS M1210
1057
1058 STAC9202/9250/9251
1059 ref Reference board, base config
1060 m2-2 Some Gateway MX series laptops
1061 m6 Some Gateway NX series laptops
1062 pa6 Gateway NX860 series
1063
1064 STAC9227/9228/9229/927x
1065 ref Reference board
1066 ref-no-jd Reference board without HP/Mic jack detection
1067 3stack D965 3stack
1068 5stack D965 5stack + SPDIF
1069 dell-3stack Dell Dimension E520
1070 dell-bios Fixes with Dell BIOS setup
1071
1072 STAC92HD71B*
1073 ref Reference board
1074 dell-m4-1 Dell desktops
1075 dell-m4-2 Dell desktops
1076 dell-m4-3 Dell desktops
1077
1078 STAC92HD73*
1079 ref Reference board
1080 no-jd BIOS setup but without jack-detection
1081 dell-m6-amic Dell desktops/laptops with analog mics
1082 dell-m6-dmic Dell desktops/laptops with digital mics
1083 dell-m6 Dell desktops/laptops with both type of mics
1084
1085 STAC9872
1086 vaio Setup for VAIO FE550G/SZ110
1087 vaio-ar Setup for VAIO AR
1088 786
1089 The model name "genric" is treated as a special case. When this 787 The model name "genric" is treated as a special case. When this
1090 model is given, the driver uses the generic codec parser without 788 model is given, the driver uses the generic codec parser without
1091 "codec-patch". It's sometimes good for testing and debugging. 789 "codec-patch". It's sometimes good for testing and debugging.
1092 790
1093 If the default configuration doesn't work and one of the above 791 If the default configuration doesn't work and one of the above
1094 matches with your device, report it together with the PCI 792 matches with your device, report it together with alsa-info.sh
1095 subsystem ID (output of "lspci -nv") to ALSA BTS or alsa-devel 793 output (with --no-upload option) to kernel bugzilla or alsa-devel
1096 ML (see the section "Links and Addresses"). 794 ML (see the section "Links and Addresses").
1097 795
1098 power_save and power_save_controller options are for power-saving 796 power_save and power_save_controller options are for power-saving
@@ -1652,7 +1350,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
1652 * AuzenTech X-Meridian 1350 * AuzenTech X-Meridian
1653 * Bgears b-Enspirer 1351 * Bgears b-Enspirer
1654 * Club3D Theatron DTS 1352 * Club3D Theatron DTS
1655 * HT-Omega Claro 1353 * HT-Omega Claro (plus)
1354 * HT-Omega Claro halo (XT)
1656 * Razer Barracuda AC-1 1355 * Razer Barracuda AC-1
1657 * Sondigo Inferno 1356 * Sondigo Inferno
1658 1357
@@ -2409,8 +2108,11 @@ Links and Addresses
2409 ALSA project homepage 2108 ALSA project homepage
2410 http://www.alsa-project.org 2109 http://www.alsa-project.org
2411 2110
2412 ALSA Bug Tracking System 2111 Kernel Bugzilla
2413 https://bugtrack.alsa-project.org/bugs/ 2112 http://bugzilla.kernel.org/
2414 2113
2415 ALSA Developers ML 2114 ALSA Developers ML
2416 mailto:alsa-devel@alsa-project.org 2115 mailto:alsa-devel@alsa-project.org
2116
2117 alsa-info.sh script
2118 http://www.alsa-project.org/alsa-info.sh
diff --git a/Documentation/sound/alsa/HD-Audio-Models.txt b/Documentation/sound/alsa/HD-Audio-Models.txt
new file mode 100644
index 000000000000..4b7ac21ea9eb
--- /dev/null
+++ b/Documentation/sound/alsa/HD-Audio-Models.txt
@@ -0,0 +1,348 @@
1 Model name Description
2 ---------- -----------
3ALC880
4======
5 3stack 3-jack in back and a headphone out
6 3stack-digout 3-jack in back, a HP out and a SPDIF out
7 5stack 5-jack in back, 2-jack in front
8 5stack-digout 5-jack in back, 2-jack in front, a SPDIF out
9 6stack 6-jack in back, 2-jack in front
10 6stack-digout 6-jack with a SPDIF out
11 w810 3-jack
12 z71v 3-jack (HP shared SPDIF)
13 asus 3-jack (ASUS Mobo)
14 asus-w1v ASUS W1V
15 asus-dig ASUS with SPDIF out
16 asus-dig2 ASUS with SPDIF out (using GPIO2)
17 uniwill 3-jack
18 fujitsu Fujitsu Laptops (Pi1536)
19 F1734 2-jack
20 lg LG laptop (m1 express dual)
21 lg-lw LG LW20/LW25 laptop
22 tcl TCL S700
23 clevo Clevo laptops (m520G, m665n)
24 medion Medion Rim 2150
25 test for testing/debugging purpose, almost all controls can be
26 adjusted. Appearing only when compiled with
27 $CONFIG_SND_DEBUG=y
28 auto auto-config reading BIOS (default)
29
30ALC260
31======
32 hp HP machines
33 hp-3013 HP machines (3013-variant)
34 hp-dc7600 HP DC7600
35 fujitsu Fujitsu S7020
36 acer Acer TravelMate
37 will Will laptops (PB V7900)
38 replacer Replacer 672V
39 basic fixed pin assignment (old default model)
40 test for testing/debugging purpose, almost all controls can
41 adjusted. Appearing only when compiled with
42 $CONFIG_SND_DEBUG=y
43 auto auto-config reading BIOS (default)
44
45ALC262
46======
47 fujitsu Fujitsu Laptop
48 hp-bpc HP xw4400/6400/8400/9400 laptops
49 hp-bpc-d7000 HP BPC D7000
50 hp-tc-t5735 HP Thin Client T5735
51 hp-rp5700 HP RP5700
52 benq Benq ED8
53 benq-t31 Benq T31
54 hippo Hippo (ATI) with jack detection, Sony UX-90s
55 hippo_1 Hippo (Benq) with jack detection
56 sony-assamd Sony ASSAMD
57 toshiba-s06 Toshiba S06
58 toshiba-rx1 Toshiba RX1
59 ultra Samsung Q1 Ultra Vista model
60 lenovo-3000 Lenovo 3000 y410
61 nec NEC Versa S9100
62 basic fixed pin assignment w/o SPDIF
63 auto auto-config reading BIOS (default)
64
65ALC267/268
66==========
67 quanta-il1 Quanta IL1 mini-notebook
68 3stack 3-stack model
69 toshiba Toshiba A205
70 acer Acer laptops
71 acer-dmic Acer laptops with digital-mic
72 acer-aspire Acer Aspire One
73 dell Dell OEM laptops (Vostro 1200)
74 zepto Zepto laptops
75 test for testing/debugging purpose, almost all controls can
76 adjusted. Appearing only when compiled with
77 $CONFIG_SND_DEBUG=y
78 auto auto-config reading BIOS (default)
79
80ALC269
81======
82 basic Basic preset
83 quanta Quanta FL1
84 eeepc-p703 ASUS Eeepc P703 P900A
85 eeepc-p901 ASUS Eeepc P901 S101
86 fujitsu FSC Amilo
87 auto auto-config reading BIOS (default)
88
89ALC662/663
90==========
91 3stack-dig 3-stack (2-channel) with SPDIF
92 3stack-6ch 3-stack (6-channel)
93 3stack-6ch-dig 3-stack (6-channel) with SPDIF
94 6stack-dig 6-stack with SPDIF
95 lenovo-101e Lenovo laptop
96 eeepc-p701 ASUS Eeepc P701
97 eeepc-ep20 ASUS Eeepc EP20
98 ecs ECS/Foxconn mobo
99 m51va ASUS M51VA
100 g71v ASUS G71V
101 h13 ASUS H13
102 g50v ASUS G50V
103 asus-mode1 ASUS
104 asus-mode2 ASUS
105 asus-mode3 ASUS
106 asus-mode4 ASUS
107 asus-mode5 ASUS
108 asus-mode6 ASUS
109 auto auto-config reading BIOS (default)
110
111ALC882/885
112==========
113 3stack-dig 3-jack with SPDIF I/O
114 6stack-dig 6-jack digital with SPDIF I/O
115 arima Arima W820Di1
116 targa Targa T8, MSI-1049 T8
117 asus-a7j ASUS A7J
118 asus-a7m ASUS A7M
119 macpro MacPro support
120 mbp3 Macbook Pro rev3
121 imac24 iMac 24'' with jack detection
122 w2jc ASUS W2JC
123 auto auto-config reading BIOS (default)
124
125ALC883/888
126==========
127 3stack-dig 3-jack with SPDIF I/O
128 6stack-dig 6-jack digital with SPDIF I/O
129 3stack-6ch 3-jack 6-channel
130 3stack-6ch-dig 3-jack 6-channel with SPDIF I/O
131 6stack-dig-demo 6-jack digital for Intel demo board
132 acer Acer laptops (Travelmate 3012WTMi, Aspire 5600, etc)
133 acer-aspire Acer Aspire 9810
134 acer-aspire-4930g Acer Aspire 4930G
135 medion Medion Laptops
136 medion-md2 Medion MD2
137 targa-dig Targa/MSI
138 targa-2ch-dig Targs/MSI with 2-channel
139 laptop-eapd 3-jack with SPDIF I/O and EAPD (Clevo M540JE, M550JE)
140 lenovo-101e Lenovo 101E
141 lenovo-nb0763 Lenovo NB0763
142 lenovo-ms7195-dig Lenovo MS7195
143 lenovo-sky Lenovo Sky
144 haier-w66 Haier W66
145 3stack-hp HP machines with 3stack (Lucknow, Samba boards)
146 6stack-dell Dell machines with 6stack (Inspiron 530)
147 mitac Mitac 8252D
148 clevo-m720 Clevo M720 laptop series
149 fujitsu-pi2515 Fujitsu AMILO Pi2515
150 fujitsu-xa3530 Fujitsu AMILO XA3530
151 3stack-6ch-intel Intel DG33* boards
152 auto auto-config reading BIOS (default)
153
154ALC861/660
155==========
156 3stack 3-jack
157 3stack-dig 3-jack with SPDIF I/O
158 6stack-dig 6-jack with SPDIF I/O
159 3stack-660 3-jack (for ALC660)
160 uniwill-m31 Uniwill M31 laptop
161 toshiba Toshiba laptop support
162 asus Asus laptop support
163 asus-laptop ASUS F2/F3 laptops
164 auto auto-config reading BIOS (default)
165
166ALC861VD/660VD
167==============
168 3stack 3-jack
169 3stack-dig 3-jack with SPDIF OUT
170 6stack-dig 6-jack with SPDIF OUT
171 3stack-660 3-jack (for ALC660VD)
172 3stack-660-digout 3-jack with SPDIF OUT (for ALC660VD)
173 lenovo Lenovo 3000 C200
174 dallas Dallas laptops
175 hp HP TX1000
176 asus-v1s ASUS V1Sn
177 auto auto-config reading BIOS (default)
178
179CMI9880
180=======
181 minimal 3-jack in back
182 min_fp 3-jack in back, 2-jack in front
183 full 6-jack in back, 2-jack in front
184 full_dig 6-jack in back, 2-jack in front, SPDIF I/O
185 allout 5-jack in back, 2-jack in front, SPDIF out
186 auto auto-config reading BIOS (default)
187
188AD1882 / AD1882A
189================
190 3stack 3-stack mode (default)
191 6stack 6-stack mode
192
193AD1884A / AD1883 / AD1984A / AD1984B
194====================================
195 desktop 3-stack desktop (default)
196 laptop laptop with HP jack sensing
197 mobile mobile devices with HP jack sensing
198 thinkpad Lenovo Thinkpad X300
199
200AD1884
201======
202 N/A
203
204AD1981
205======
206 basic 3-jack (default)
207 hp HP nx6320
208 thinkpad Lenovo Thinkpad T60/X60/Z60
209 toshiba Toshiba U205
210
211AD1983
212======
213 N/A
214
215AD1984
216======
217 basic default configuration
218 thinkpad Lenovo Thinkpad T61/X61
219 dell Dell T3400
220
221AD1986A
222=======
223 6stack 6-jack, separate surrounds (default)
224 3stack 3-stack, shared surrounds
225 laptop 2-channel only (FSC V2060, Samsung M50)
226 laptop-eapd 2-channel with EAPD (ASUS A6J)
227 laptop-automute 2-channel with EAPD and HP-automute (Lenovo N100)
228 ultra 2-channel with EAPD (Samsung Ultra tablet PC)
229 samsung 2-channel with EAPD (Samsung R65)
230
231AD1988/AD1988B/AD1989A/AD1989B
232==============================
233 6stack 6-jack
234 6stack-dig ditto with SPDIF
235 3stack 3-jack
236 3stack-dig ditto with SPDIF
237 laptop 3-jack with hp-jack automute
238 laptop-dig ditto with SPDIF
239 auto auto-config reading BIOS (default)
240
241Conexant 5045
242=============
243 laptop-hpsense Laptop with HP sense (old model laptop)
244 laptop-micsense Laptop with Mic sense (old model fujitsu)
245 laptop-hpmicsense Laptop with HP and Mic senses
246 benq Benq R55E
247 test for testing/debugging purpose, almost all controls
248 can be adjusted. Appearing only when compiled with
249 $CONFIG_SND_DEBUG=y
250
251Conexant 5047
252=============
253 laptop Basic Laptop config
254 laptop-hp Laptop config for some HP models (subdevice 30A5)
255 laptop-eapd Laptop config with EAPD support
256 test for testing/debugging purpose, almost all controls
257 can be adjusted. Appearing only when compiled with
258 $CONFIG_SND_DEBUG=y
259
260Conexant 5051
261=============
262 laptop Basic Laptop config (default)
263 hp HP Spartan laptop
264
265STAC9200
266========
267 ref Reference board
268 dell-d21 Dell (unknown)
269 dell-d22 Dell (unknown)
270 dell-d23 Dell (unknown)
271 dell-m21 Dell Inspiron 630m, Dell Inspiron 640m
272 dell-m22 Dell Latitude D620, Dell Latitude D820
273 dell-m23 Dell XPS M1710, Dell Precision M90
274 dell-m24 Dell Latitude 120L
275 dell-m25 Dell Inspiron E1505n
276 dell-m26 Dell Inspiron 1501
277 dell-m27 Dell Inspiron E1705/9400
278 gateway Gateway laptops with EAPD control
279 panasonic Panasonic CF-74
280
281STAC9205/9254
282=============
283 ref Reference board
284 dell-m42 Dell (unknown)
285 dell-m43 Dell Precision
286 dell-m44 Dell Inspiron
287
288STAC9220/9221
289=============
290 ref Reference board
291 3stack D945 3stack
292 5stack D945 5stack + SPDIF
293 intel-mac-v1 Intel Mac Type 1
294 intel-mac-v2 Intel Mac Type 2
295 intel-mac-v3 Intel Mac Type 3
296 intel-mac-v4 Intel Mac Type 4
297 intel-mac-v5 Intel Mac Type 5
298 intel-mac-auto Intel Mac (detect type according to subsystem id)
299 macmini Intel Mac Mini (equivalent with type 3)
300 macbook Intel Mac Book (eq. type 5)
301 macbook-pro-v1 Intel Mac Book Pro 1st generation (eq. type 3)
302 macbook-pro Intel Mac Book Pro 2nd generation (eq. type 3)
303 imac-intel Intel iMac (eq. type 2)
304 imac-intel-20 Intel iMac (newer version) (eq. type 3)
305 dell-d81 Dell (unknown)
306 dell-d82 Dell (unknown)
307 dell-m81 Dell (unknown)
308 dell-m82 Dell XPS M1210
309
310STAC9202/9250/9251
311==================
312 ref Reference board, base config
313 m2-2 Some Gateway MX series laptops
314 m6 Some Gateway NX series laptops
315 pa6 Gateway NX860 series
316
317STAC9227/9228/9229/927x
318=======================
319 ref Reference board
320 ref-no-jd Reference board without HP/Mic jack detection
321 3stack D965 3stack
322 5stack D965 5stack + SPDIF
323 dell-3stack Dell Dimension E520
324 dell-bios Fixes with Dell BIOS setup
325
326STAC92HD71B*
327============
328 ref Reference board
329 dell-m4-1 Dell desktops
330 dell-m4-2 Dell desktops
331 dell-m4-3 Dell desktops
332
333STAC92HD73*
334===========
335 ref Reference board
336 no-jd BIOS setup but without jack-detection
337 dell-m6-amic Dell desktops/laptops with analog mics
338 dell-m6-dmic Dell desktops/laptops with digital mics
339 dell-m6 Dell desktops/laptops with both type of mics
340
341STAC92HD83*
342===========
343 ref Reference board
344
345STAC9872
346========
347 vaio Setup for VAIO FE550G/SZ110
348 vaio-ar Setup for VAIO AR
diff --git a/Documentation/sound/alsa/HD-Audio.txt b/Documentation/sound/alsa/HD-Audio.txt
new file mode 100644
index 000000000000..8d68fff71839
--- /dev/null
+++ b/Documentation/sound/alsa/HD-Audio.txt
@@ -0,0 +1,577 @@
1MORE NOTES ON HD-AUDIO DRIVER
2=============================
3 Takashi Iwai <tiwai@suse.de>
4
5
6GENERAL
7-------
8
9HD-audio is the new standard on-board audio component on modern PCs
10after AC97. Although Linux has been supporting HD-audio since long
11time ago, there are often problems with new machines. A part of the
12problem is broken BIOS, and the rest is the driver implementation.
13This document explains the brief trouble-shooting and debugging
14methods for the HD-audio hardware.
15
16The HD-audio component consists of two parts: the controller chip and
17the codec chips on the HD-audio bus. Linux provides a single driver
18for all controllers, snd-hda-intel. Although the driver name contains
19a word of a well-known harware vendor, it's not specific to it but for
20all controller chips by other companies. Since the HD-audio
21controllers are supposed to be compatible, the single snd-hda-driver
22should work in most cases. But, not surprisingly, there are known
23bugs and issues specific to each controller type. The snd-hda-intel
24driver has a bunch of workarounds for these as described below.
25
26A controller may have multiple codecs. Usually you have one audio
27codec and optionally one modem codec. In theory, there might be
28multiple audio codecs, e.g. for analog and digital outputs, and the
29driver might not work properly because of conflict of mixer elements.
30This should be fixed in future if such hardware really exists.
31
32The snd-hda-intel driver has several different codec parsers depending
33on the codec. It has a generic parser as a fallback, but this
34functionality is fairly limited until now. Instead of the generic
35parser, usually the codec-specific parser (coded in patch_*.c) is used
36for the codec-specific implementations. The details about the
37codec-specific problems are explained in the later sections.
38
39If you are interested in the deep debugging of HD-audio, read the
40HD-audio specification at first. The specification is found on
41Intel's web page, for example:
42
43- http://www.intel.com/standards/hdaudio/
44
45
46HD-AUDIO CONTROLLER
47-------------------
48
49DMA-Position Problem
50~~~~~~~~~~~~~~~~~~~~
51The most common problem of the controller is the inaccurate DMA
52pointer reporting. The DMA pointer for playback and capture can be
53read in two ways, either via a LPIB register or via a position-buffer
54map. As default the driver tries to read from the io-mapped
55position-buffer, and falls back to LPIB if the position-buffer appears
56dead. However, this detection isn't perfect on some devices. In such
57a case, you can change the default method via `position_fix` option.
58
59`position_fix=1` means to use LPIB method explicitly.
60`position_fix=2` means to use the position-buffer. 0 is the default
61value, the automatic check and fallback to LPIB as described in the
62above. If you get a problem of repeated sounds, this option might
63help.
64
65In addition to that, every controller is known to be broken regarding
66the wake-up timing. It wakes up a few samples before actually
67processing the data on the buffer. This caused a lot of problems, for
68example, with ALSA dmix or JACK. Since 2.6.27 kernel, the driver puts
69an artificial delay to the wake up timing. This delay is controlled
70via `bdl_pos_adj` option.
71
72When `bdl_pos_adj` is a negative value (as default), it's assigned to
73an appropriate value depending on the controller chip. For Intel
74chips, it'd be 1 while it'd be 32 for others. Usually this works.
75Only in case it doesn't work and you get warning messages, you should
76change this parameter to other values.
77
78
79Codec-Probing Problem
80~~~~~~~~~~~~~~~~~~~~~
81A less often but a more severe problem is the codec probing. When
82BIOS reports the available codec slots wrongly, the driver gets
83confused and tries to access the non-existing codec slot. This often
84results in the total screw-up, and destructs the further communication
85with the codec chips. The symptom appears usually as error messages
86like:
87------------------------------------------------------------------------
88 hda_intel: azx_get_response timeout, switching to polling mode:
89 last cmd=0x12345678
90 hda_intel: azx_get_response timeout, switching to single_cmd mode:
91 last cmd=0x12345678
92------------------------------------------------------------------------
93
94The first line is a warning, and this is usually relatively harmless.
95It means that the codec response isn't notified via an IRQ. The
96driver uses explicit polling method to read the response. It gives
97very slight CPU overhead, but you'd unlikely notice it.
98
99The second line is, however, a fatal error. If this happens, usually
100it means that something is really wrong. Most likely you are
101accessing a non-existing codec slot.
102
103Thus, if the second error message appears, try to narrow the probed
104codec slots via `probe_mask` option. It's a bitmask, and each bit
105corresponds to the codec slot. For example, to probe only the first
106slot, pass `probe_mask=1`. For the first and the third slots, pass
107`probe_mask=5` (where 5 = 1 | 4), and so on.
108
109Since 2.6.29 kernel, the driver has a more robust probing method, so
110this error might happen rarely, though.
111
112
113Interrupt Handling
114~~~~~~~~~~~~~~~~~~
115In rare but some cases, the interrupt isn't properly handled as
116default. You would notice this by the DMA transfer error reported by
117ALSA PCM core, for example. Using MSI might help in such a case.
118Pass `enable_msi=1` option for enabling MSI.
119
120
121HD-AUDIO CODEC
122--------------
123
124Model Option
125~~~~~~~~~~~~
126The most common problem regarding the HD-audio driver is the
127unsupported codec features or the mismatched device configuration.
128Most of codec-specific code has several preset models, either to
129override the BIOS setup or to provide more comprehensive features.
130
131The driver checks PCI SSID and looks through the static configuration
132table until any matching entry is found. If you have a new machine,
133you may see a message like below:
134------------------------------------------------------------------------
135 hda_codec: Unknown model for ALC880, trying auto-probe from BIOS...
136------------------------------------------------------------------------
137Even if you see such a message, DON'T PANIC. Take a deep breath and
138keep your towel. First of all, it's an informational message, no
139warning, no error. This means that the PCI SSID of your device isn't
140listed in the known preset model (white-)list. But, this doesn't mean
141that the driver is broken. Many codec-drivers provide the automatic
142configuration mechanism based on the BIOS setup.
143
144The HD-audio codec has usually "pin" widgets, and BIOS sets the default
145configuration of each pin, which indicates the location, the
146connection type, the jack color, etc. The HD-audio driver can guess
147the right connection judging from these default configuration values.
148However -- some codec-support codes, such as patch_analog.c, don't
149support the automatic probing (yet as of 2.6.28). And, BIOS is often,
150yes, pretty often broken. It sets up wrong values and screws up the
151driver.
152
153The preset model is provided basically to overcome such a situation.
154When the matching preset model is found in the white-list, the driver
155assumes the static configuration of that preset and builds the mixer
156elements and PCM streams based on the static information. Thus, if
157you have a newer machine with a slightly different PCI SSID from the
158existing one, you may have a good chance to re-use the same model.
159You can pass the `model` option to specify the preset model instead of
160PCI SSID look-up.
161
162What `model` option values are available depends on the codec chip.
163Check your codec chip from the codec proc file (see "Codec Proc-File"
164section below). It will show the vendor/product name of your codec
165chip. Then, see Documentation/sound/alsa/HD-Audio-Modelstxt file,
166the section of HD-audio driver. You can find a list of codecs
167and `model` options belonging to each codec. For example, for Realtek
168ALC262 codec chip, pass `model=ultra` for devices that are compatible
169with Samsung Q1 Ultra.
170
171Thus, the first thing you can do for any brand-new, unsupported and
172non-working HD-audio hardware is to check HD-audio codec and several
173different `model` option values. If you have a luck, some of them
174might suit with your device well.
175
176Some codecs such as ALC880 have a special model option `model=test`.
177This configures the driver to provide as many mixer controls as
178possible for every single pin feature except for the unsolicited
179events (and maybe some other specials). Adjust each mixer element and
180try the I/O in the way of trial-and-error until figuring out the whole
181I/O pin mappings.
182
183Note that `model=generic` has a special meaning. It means to use the
184generic parser regardless of the codec. Usually the codec-specific
185parser is much better than the generic parser (as now). Thus this
186option is more about the debugging purpose.
187
188
189Speaker and Headphone Output
190~~~~~~~~~~~~~~~~~~~~~~~~~~~~
191One of the most frequent (and obvious) bugs with HD-audio is the
192silent output from either or both of a built-in speaker and a
193headphone jack. In general, you should try a headphone output at
194first. A speaker output often requires more additional controls like
195the external amplifier bits. Thus a headphone output has a slightly
196better chance.
197
198Before making a bug report, double-check whether the mixer is set up
199correctly. The recent version of snd-hda-intel driver provides mostly
200"Master" volume control as well as "Front" volume (where Front
201indicates the front-channels). In addition, there can be individual
202"Headphone" and "Speaker" controls.
203
204Ditto for the speaker output. There can be "External Amplifier"
205switch on some codecs. Turn on this if present.
206
207Another related problem is the automatic mute of speaker output by
208headphone plugging. This feature is implemented in most cases, but
209not on every preset model or codec-support code.
210
211In anyway, try a different model option if you have such a problem.
212Some other models may match better and give you more matching
213functionality. If none of the available models works, send a bug
214report. See the bug report section for details.
215
216If you are masochistic enough to debug the driver problem, note the
217following:
218
219- The speaker (and the headphone, too) output often requires the
220 external amplifier. This can be set usually via EAPD verb or a
221 certain GPIO. If the codec pin supports EAPD, you have a better
222 chance via SET_EAPD_BTL verb (0x70c). On others, GPIO pin (mostly
223 it's either GPIO0 or GPIO1) may turn on/off EAPD.
224- Some Realtek codecs require special vendor-specific coefficients to
225 turn on the amplifier. See patch_realtek.c.
226- IDT codecs may have extra power-enable/disable controls on each
227 analog pin. See patch_sigmatel.c.
228- Very rare but some devices don't accept the pin-detection verb until
229 triggered. Issuing GET_PIN_SENSE verb (0xf09) may result in the
230 codec-communication stall. Some examples are found in
231 patch_realtek.c.
232
233
234Capture Problems
235~~~~~~~~~~~~~~~~
236The capture problems are often because of missing setups of mixers.
237Thus, before submitting a bug report, make sure that you set up the
238mixer correctly. For example, both "Capture Volume" and "Capture
239Switch" have to be set properly in addition to the right "Capture
240Source" or "Input Source" selection. Some devices have "Mic Boost"
241volume or switch.
242
243When the PCM device is opened via "default" PCM (without pulse-audio
244plugin), you'll likely have "Digital Capture Volume" control as well.
245This is provided for the extra gain/attenuation of the signal in
246software, especially for the inputs without the hardware volume
247control such as digital microphones. Unless really needed, this
248should be set to exactly 50%, corresponding to 0dB -- neither extra
249gain nor attenuation. When you use "hw" PCM, i.e., a raw access PCM,
250this control will have no influence, though.
251
252It's known that some codecs / devices have fairly bad analog circuits,
253and the recorded sound contains a certain DC-offset. This is no bug
254of the driver.
255
256Most of modern laptops have no analog CD-input connection. Thus, the
257recording from CD input won't work in many cases although the driver
258provides it as the capture source. Use CDDA instead.
259
260The automatic switching of the built-in and external mic per plugging
261is implemented on some codec models but not on every model. Partly
262because of my laziness but mostly lack of testers. Feel free to
263submit the improvement patch to the author.
264
265
266Direct Debugging
267~~~~~~~~~~~~~~~~
268If no model option gives you a better result, and you are a tough guy
269to fight against evil, try debugging via hitting the raw HD-audio
270codec verbs to the device. Some tools are available: hda-emu and
271hda-analyzer. The detailed description is found in the sections
272below. You'd need to enable hwdep for using these tools. See "Kernel
273Configuration" section.
274
275
276OTHER ISSUES
277------------
278
279Kernel Configuration
280~~~~~~~~~~~~~~~~~~~~
281In general, I recommend you to enable the sound debug option,
282`CONFIG_SND_DEBUG=y`, no matter whether you are debugging or not.
283This enables snd_printd() macro and others, and you'll get additional
284kernel messages at probing.
285
286In addition, you can enable `CONFIG_SND_DEBUG_VERBOSE=y`. But this
287will give you far more messages. Thus turn this on only when you are
288sure to want it.
289
290Don't forget to turn on the appropriate `CONFIG_SND_HDA_CODEC_*`
291options. Note that each of them corresponds to the codec chip, not
292the controller chip. Thus, even if lspci shows the Nvidia controller,
293you may need to choose the option for other vendors. If you are
294unsure, just select all yes.
295
296`CONFIG_SND_HDA_HWDEP` is a useful option for debugging the driver.
297When this is enabled, the driver creates hardware-dependent devices
298(one per each codec), and you have a raw access to the device via
299these device files. For example, `hwC0D2` will be created for the
300codec slot #2 of the first card (#0). For debug-tools such as
301hda-verb and hda-analyzer, the hwdep device has to be enabled.
302Thus, it'd be better to turn this on always.
303
304`CONFIG_SND_HDA_RECONFIG` is a new option, and this depends on the
305hwdep option above. When enabled, you'll have some sysfs files under
306the corresponding hwdep directory. See "HD-audio reconfiguration"
307section below.
308
309`CONFIG_SND_HDA_POWER_SAVE` option enables the power-saving feature.
310See "Power-saving" section below.
311
312
313Codec Proc-File
314~~~~~~~~~~~~~~~
315The codec proc-file is a treasure-chest for debugging HD-audio.
316It shows most of useful information of each codec widget.
317
318The proc file is located in /proc/asound/card*/codec#*, one file per
319each codec slot. You can know the codec vendor, product id and
320names, the type of each widget, capabilities and so on.
321This file, however, doesn't show the jack sensing state, so far. This
322is because the jack-sensing might be depending on the trigger state.
323
324This file will be picked up by the debug tools, and also it can be fed
325to the emulator as the primary codec information. See the debug tools
326section below.
327
328This proc file can be also used to check whether the generic parser is
329used. When the generic parser is used, the vendor/product ID name
330will appear as "Realtek ID 0262", instead of "Realtek ALC262".
331
332
333HD-Audio Reconfiguration
334~~~~~~~~~~~~~~~~~~~~~~~~
335This is an experimental feature to allow you re-configure the HD-audio
336codec dynamically without reloading the driver. The following sysfs
337files are available under each codec-hwdep device directory (e.g.
338/sys/class/sound/hwC0D0):
339
340vendor_id::
341 Shows the 32bit codec vendor-id hex number. You can change the
342 vendor-id value by writing to this file.
343subsystem_id::
344 Shows the 32bit codec subsystem-id hex number. You can change the
345 subsystem-id value by writing to this file.
346revision_id::
347 Shows the 32bit codec revision-id hex number. You can change the
348 revision-id value by writing to this file.
349afg::
350 Shows the AFG ID. This is read-only.
351mfg::
352 Shows the MFG ID. This is read-only.
353name::
354 Shows the codec name string. Can be changed by writing to this
355 file.
356modelname::
357 Shows the currently set `model` option. Can be changed by writing
358 to this file.
359init_verbs::
360 The extra verbs to execute at initialization. You can add a verb by
361 writing to this file. Pass tree numbers, nid, verb and parameter.
362hints::
363 Shows hint strings for codec parsers for any use. Right now it's
364 not used.
365reconfig::
366 Triggers the codec re-configuration. When any value is written to
367 this file, the driver re-initialize and parses the codec tree
368 again. All the changes done by the sysfs entries above are taken
369 into account.
370clear::
371 Resets the codec, removes the mixer elements and PCM stuff of the
372 specified codec, and clear all init verbs and hints.
373
374
375Power-Saving
376~~~~~~~~~~~~
377The power-saving is a kind of auto-suspend of the device. When the
378device is inactive for a certain time, the device is automatically
379turned off to save the power. The time to go down is specified via
380`power_save` module option, and this option can be changed dynamically
381via sysfs.
382
383The power-saving won't work when the analog loopback is enabled on
384some codecs. Make sure that you mute all unneeded signal routes when
385you want the power-saving.
386
387The power-saving feature might cause audible click noises at each
388power-down/up depending on the device. Some of them might be
389solvable, but some are hard, I'm afraid. Some distros such as
390openSUSE enables the power-saving feature automatically when the power
391cable is unplugged. Thus, if you hear noises, suspect first the
392power-saving. See /sys/module/snd_hda_intel/parameters/power_save to
393check the current value. If it's non-zero, the feature is turned on.
394
395
396Development Tree
397~~~~~~~~~~~~~~~~
398The latest development codes for HD-audio are found on sound git tree:
399
400- git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6.git
401
402The master branch or for-next branches can be used as the main
403development branches in general while the HD-audio specific patches
404are committed in topic/hda branch.
405
406If you are using the latest Linus tree, it'd be better to pull the
407above GIT tree onto it. If you are using the older kernels, an easy
408way to try the latest ALSA code is to build from the snapshot
409tarball. There are daily tarballs and the latest snapshot tarball.
410All can be built just like normal alsa-driver release packages, that
411is, installed via the usual spells: configure, make and make
412install(-modules). See INSTALL in the package. The snapshot tarballs
413are found at:
414
415- ftp://ftp.kernel.org/pub/linux/kernel/people/tiwai/snapshot/
416
417
418Sending a Bug Report
419~~~~~~~~~~~~~~~~~~~~
420If any model or module options don't work for your device, it's time
421to send a bug report to the developers. Give the following in your
422bug report:
423
424- Hardware vendor, product and model names
425- Kernel version (and ALSA-driver version if you built externally)
426- `alsa-info.sh` output; run with `--no-upload` option. See the
427 section below about alsa-info
428
429If it's a regression, at best, send alsa-info outputs of both working
430and non-working kernels. This is really helpful because we can
431compare the codec registers directly.
432
433Send a bug report either the followings:
434
435kernel-bugzilla::
436 http://bugme.linux-foundation.org/
437alsa-devel ML::
438 alsa-devel@alsa-project.org
439
440
441DEBUG TOOLS
442-----------
443
444This section describes some tools available for debugging HD-audio
445problems.
446
447alsa-info
448~~~~~~~~~
449The script `alsa-info.sh` is a very useful tool to gather the audio
450device information. You can fetch the latest version from:
451
452- http://www.alsa-project.org/alsa-info.sh
453
454Run this script as root, and it will gather the important information
455such as the module lists, module parameters, proc file contents
456including the codec proc files, mixer outputs and the control
457elements. As default, it will store the information onto a web server
458on alsa-project.org. But, if you send a bug report, it'd be better to
459run with `--no-upload` option, and attach the generated file.
460
461There are some other useful options. See `--help` option output for
462details.
463
464
465hda-verb
466~~~~~~~~
467hda-verb is a tiny program that allows you to access the HD-audio
468codec directly. You can execute a raw HD-audio codec verb with this.
469This program accesses the hwdep device, thus you need to enable the
470kernel config `CONFIG_SND_HDA_HWDEP=y` beforehand.
471
472The hda-verb program takes four arguments: the hwdep device file, the
473widget NID, the verb and the parameter. When you access to the codec
474on the slot 2 of the card 0, pass /dev/snd/hwC0D2 to the first
475argument, typically. (However, the real path name depends on the
476system.)
477
478The second parameter is the widget number-id to access. The third
479parameter can be either a hex/digit number or a string corresponding
480to a verb. Similarly, the last parameter is the value to write, or
481can be a string for the parameter type.
482
483------------------------------------------------------------------------
484 % hda-verb /dev/snd/hwC0D0 0x12 0x701 2
485 nid = 0x12, verb = 0x701, param = 0x2
486 value = 0x0
487
488 % hda-verb /dev/snd/hwC0D0 0x0 PARAMETERS VENDOR_ID
489 nid = 0x0, verb = 0xf00, param = 0x0
490 value = 0x10ec0262
491
492 % hda-verb /dev/snd/hwC0D0 2 set_a 0xb080
493 nid = 0x2, verb = 0x300, param = 0xb080
494 value = 0x0
495------------------------------------------------------------------------
496
497Although you can issue any verbs with this program, the driver state
498won't be always updated. For example, the volume values are usually
499cached in the driver, and thus changing the widget amp value directly
500via hda-verb won't change the mixer value.
501
502The hda-verb program is found in the ftp directory:
503
504- ftp://ftp.kernel.org/pub/linux/kernel/people/tiwai/misc/
505
506Also a git repository is available:
507
508- git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/hda-verb.git
509
510See README file in the tarball for more details about hda-verb
511program.
512
513
514hda-analyzer
515~~~~~~~~~~~~
516hda-analyzer provides a graphical interface to access the raw HD-audio
517control, based on pyGTK2 binding. It's a more powerful version of
518hda-verb. The program gives you an easy-to-use GUI stuff for showing
519the widget information and adjusting the amp values, as well as the
520proc-compatible output.
521
522The hda-analyzer is a part of alsa.git repository in
523alsa-project.org:
524
525- http://git.alsa-project.org/?p=alsa.git;a=tree;f=hda-analyzer
526
527
528Codecgraph
529~~~~~~~~~~
530Codecgraph is a utility program to generate a graph and visualizes the
531codec-node connection of a codec chip. It's especially useful when
532you analyze or debug a codec without a proper datasheet. The program
533parses the given codec proc file and converts to SVG via graphiz
534program.
535
536The tarball and GIT trees are found in the web page at:
537
538- http://helllabs.org/codecgraph/
539
540
541hda-emu
542~~~~~~~
543hda-emu is an HD-audio emulator. The main purpose of this program is
544to debug an HD-audio codec without the real hardware. Thus, it
545doesn't emulate the behavior with the real audio I/O, but it just
546dumps the codec register changes and the ALSA-driver internal changes
547at probing and operating the HD-audio driver.
548
549The program requires a codec proc-file to simulate. Get a proc file
550for the target codec beforehand, or pick up an example codec from the
551codec proc collections in the tarball. Then, run the program with the
552proc file, and the hda-emu program will start parsing the codec file
553and simulates the HD-audio driver:
554
555------------------------------------------------------------------------
556 % hda-emu codecs/stac9200-dell-d820-laptop
557 # Parsing..
558 hda_codec: Unknown model for STAC9200, using BIOS defaults
559 hda_codec: pin nid 08 bios pin config 40c003fa
560 ....
561------------------------------------------------------------------------
562
563The program gives you only a very dumb command-line interface. You
564can get a proc-file dump at the current state, get a list of control
565(mixer) elements, set/get the control element value, simulate the PCM
566operation, the jack plugging simulation, etc.
567
568The package is found in:
569
570- ftp://ftp.kernel.org/pub/linux/kernel/people/tiwai/misc/
571
572A git repository is available:
573
574- git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/hda-emu.git
575
576See README file in the tarball for more details about hda-emu
577program.
diff --git a/Documentation/sound/alsa/Procfile.txt b/Documentation/sound/alsa/Procfile.txt
index f738b296440a..bba2dbb79d81 100644
--- a/Documentation/sound/alsa/Procfile.txt
+++ b/Documentation/sound/alsa/Procfile.txt
@@ -153,6 +153,16 @@ card*/codec#*
153 Shows the general codec information and the attribute of each 153 Shows the general codec information and the attribute of each
154 widget node. 154 widget node.
155 155
156card*/eld#*
157 Available for HDMI or DisplayPort interfaces.
158 Shows ELD(EDID Like Data) info retrieved from the attached HDMI sink,
159 and describes its audio capabilities and configurations.
160
161 Some ELD fields may be modified by doing `echo name hex_value > eld#*`.
162 Only do this if you are sure the HDMI sink provided value is wrong.
163 And if that makes your HDMI audio work, please report to us so that we
164 can fix it in future kernel releases.
165
156 166
157Sequencer Information 167Sequencer Information
158--------------------- 168---------------------
diff --git a/Documentation/sound/alsa/soc/machine.txt b/Documentation/sound/alsa/soc/machine.txt
index f370e7db86af..bab7711ce963 100644
--- a/Documentation/sound/alsa/soc/machine.txt
+++ b/Documentation/sound/alsa/soc/machine.txt
@@ -9,7 +9,7 @@ the audio subsystem with the kernel as a platform device and is represented by
9the following struct:- 9the following struct:-
10 10
11/* SoC machine */ 11/* SoC machine */
12struct snd_soc_machine { 12struct snd_soc_card {
13 char *name; 13 char *name;
14 14
15 int (*probe)(struct platform_device *pdev); 15 int (*probe)(struct platform_device *pdev);
@@ -67,10 +67,10 @@ static struct snd_soc_dai_link corgi_dai = {
67 .ops = &corgi_ops, 67 .ops = &corgi_ops,
68}; 68};
69 69
70struct snd_soc_machine then sets up the machine with it's DAIs. e.g. 70struct snd_soc_card then sets up the machine with it's DAIs. e.g.
71 71
72/* corgi audio machine driver */ 72/* corgi audio machine driver */
73static struct snd_soc_machine snd_soc_machine_corgi = { 73static struct snd_soc_card snd_soc_corgi = {
74 .name = "Corgi", 74 .name = "Corgi",
75 .dai_link = &corgi_dai, 75 .dai_link = &corgi_dai,
76 .num_links = 1, 76 .num_links = 1,
@@ -90,7 +90,7 @@ static struct wm8731_setup_data corgi_wm8731_setup = {
90 90
91/* corgi audio subsystem */ 91/* corgi audio subsystem */
92static struct snd_soc_device corgi_snd_devdata = { 92static struct snd_soc_device corgi_snd_devdata = {
93 .machine = &snd_soc_machine_corgi, 93 .machine = &snd_soc_corgi,
94 .platform = &pxa2xx_soc_platform, 94 .platform = &pxa2xx_soc_platform,
95 .codec_dev = &soc_codec_dev_wm8731, 95 .codec_dev = &soc_codec_dev_wm8731,
96 .codec_data = &corgi_wm8731_setup, 96 .codec_data = &corgi_wm8731_setup,
diff --git a/MAINTAINERS b/MAINTAINERS
index fbc8fa58d56d..701025701514 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3977,7 +3977,7 @@ M: tiwai@suse.de
3977L: alsa-devel@alsa-project.org (subscribers-only) 3977L: alsa-devel@alsa-project.org (subscribers-only)
3978S: Maintained 3978S: Maintained
3979 3979
3980SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEMENT 3980SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEMENT (ASoC)
3981P: Liam Girdwood 3981P: Liam Girdwood
3982M: lrg@slimlogic.co.uk 3982M: lrg@slimlogic.co.uk
3983P: Mark Brown 3983P: Mark Brown
diff --git a/arch/arm/mach-pxa/include/mach/palmasoc.h b/arch/arm/mach-pxa/include/mach/palmasoc.h
new file mode 100644
index 000000000000..6c4b1f7de20a
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/palmasoc.h
@@ -0,0 +1,13 @@
1#ifndef _INCLUDE_PALMASOC_H_
2#define _INCLUDE_PALMASOC_H_
3struct palm27x_asoc_info {
4 int jack_gpio;
5};
6
7#ifdef CONFIG_SND_PXA2XX_SOC_PALM27X
8void __init palm27x_asoc_set_pdata(struct palm27x_asoc_info *data);
9#else
10static inline void palm27x_asoc_set_pdata(struct palm27x_asoc_info *data) {}
11#endif
12
13#endif
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 5c9cbfc14c4d..f32a5197128d 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -13,6 +13,7 @@ config SUPERH
13 select HAVE_OPROFILE 13 select HAVE_OPROFILE
14 select HAVE_GENERIC_DMA_COHERENT 14 select HAVE_GENERIC_DMA_COHERENT
15 select HAVE_IOREMAP_PROT if MMU 15 select HAVE_IOREMAP_PROT if MMU
16 select HAVE_ARCH_TRACEHOOK
16 help 17 help
17 The SuperH is a RISC processor targeted for use in embedded systems 18 The SuperH is a RISC processor targeted for use in embedded systems
18 and consumer electronics; it was also used in the Sega Dreamcast 19 and consumer electronics; it was also used in the Sega Dreamcast
@@ -23,8 +24,10 @@ config SUPERH32
23 def_bool !SUPERH64 24 def_bool !SUPERH64
24 select HAVE_KPROBES 25 select HAVE_KPROBES
25 select HAVE_KRETPROBES 26 select HAVE_KRETPROBES
26 select HAVE_ARCH_TRACEHOOK
27 select HAVE_FUNCTION_TRACER 27 select HAVE_FUNCTION_TRACER
28 select HAVE_FTRACE_MCOUNT_RECORD
29 select HAVE_DYNAMIC_FTRACE
30 select HAVE_ARCH_KGDB
28 31
29config SUPERH64 32config SUPERH64
30 def_bool y if CPU_SH5 33 def_bool y if CPU_SH5
@@ -55,8 +58,6 @@ config GENERIC_HARDIRQS
55 58
56config GENERIC_HARDIRQS_NO__DO_IRQ 59config GENERIC_HARDIRQS_NO__DO_IRQ
57 def_bool y 60 def_bool y
58 depends on SUPERH32 && (!SH_DREAMCAST && !SH_SH4202_MICRODEV && \
59 !SH_7751_SYSTEMH && !HD64461)
60 61
61config GENERIC_IRQ_PROBE 62config GENERIC_IRQ_PROBE
62 def_bool y 63 def_bool y
@@ -85,10 +86,17 @@ config GENERIC_LOCKBREAK
85 86
86config SYS_SUPPORTS_PM 87config SYS_SUPPORTS_PM
87 bool 88 bool
89 depends on !SMP
90
91config ARCH_SUSPEND_POSSIBLE
92 def_bool n
93
94config ARCH_HIBERNATION_POSSIBLE
95 def_bool n
88 96
89config SYS_SUPPORTS_APM_EMULATION 97config SYS_SUPPORTS_APM_EMULATION
90 bool 98 bool
91 select SYS_SUPPORTS_PM 99 select ARCH_SUSPEND_POSSIBLE
92 100
93config SYS_SUPPORTS_SMP 101config SYS_SUPPORTS_SMP
94 bool 102 bool
@@ -183,6 +191,11 @@ config CPU_SUBTYPE_SH7619
183 191
184# SH-2A Processor Support 192# SH-2A Processor Support
185 193
194config CPU_SUBTYPE_SH7201
195 bool "Support SH7201 processor"
196 select CPU_SH2A
197 select CPU_HAS_FPU
198
186config CPU_SUBTYPE_SH7203 199config CPU_SUBTYPE_SH7203
187 bool "Support SH7203 processor" 200 bool "Support SH7203 processor"
188 select CPU_SH2A 201 select CPU_SH2A
@@ -456,8 +469,12 @@ config SH_CPU_FREQ
456 depends on CPU_FREQ 469 depends on CPU_FREQ
457 select CPU_FREQ_TABLE 470 select CPU_FREQ_TABLE
458 help 471 help
459 This adds the cpufreq driver for SuperH. At present, only 472 This adds the cpufreq driver for SuperH. Any CPU that supports
460 the SH-4 is supported. 473 clock rate rounding through the clock framework can use this
474 driver. While it will make the kernel slightly larger, this is
475 harmless for CPUs that don't support rate rounding. The driver
476 will also generate a notice in the boot log before disabling
477 itself if the CPU in question is not capable of rate rounding.
461 478
462 For details, take a look at <file:Documentation/cpu-freq>. 479 For details, take a look at <file:Documentation/cpu-freq>.
463 480
@@ -469,9 +486,6 @@ source "arch/sh/drivers/Kconfig"
469 486
470endmenu 487endmenu
471 488
472config ISA_DMA_API
473 bool
474
475menu "Kernel features" 489menu "Kernel features"
476 490
477source kernel/Kconfig.hz 491source kernel/Kconfig.hz
@@ -688,49 +702,6 @@ config MAPLE
688 Dreamcast with a serial line terminal or a remote network 702 Dreamcast with a serial line terminal or a remote network
689 connection. 703 connection.
690 704
691config CF_ENABLER
692 bool "Compact Flash Enabler support"
693 depends on SOLUTION_ENGINE || SH_SH03
694 ---help---
695 Compact Flash is a small, removable mass storage device introduced
696 in 1994 originally as a PCMCIA device. If you say `Y' here, you
697 compile in support for Compact Flash devices directly connected to
698 a SuperH processor. A Compact Flash FAQ is available at
699 <http://www.compactflash.org/faqs/faq.htm>.
700
701 If your board has "Directly Connected" CompactFlash at area 5 or 6,
702 you may want to enable this option. Then, you can use CF as
703 primary IDE drive (only tested for SanDisk).
704
705 If in doubt, select 'N'.
706
707choice
708 prompt "Compact Flash Connection Area"
709 depends on CF_ENABLER
710 default CF_AREA6
711
712config CF_AREA5
713 bool "Area5"
714 help
715 If your board has "Directly Connected" CompactFlash, You should
716 select the area where your CF is connected to.
717
718 - "Area5" if CompactFlash is connected to Area 5 (0x14000000)
719 - "Area6" if it is connected to Area 6 (0x18000000)
720
721 "Area6" will work for most boards.
722
723config CF_AREA6
724 bool "Area6"
725
726endchoice
727
728config CF_BASE_ADDR
729 hex
730 depends on CF_ENABLER
731 default "0xb8000000" if CF_AREA6
732 default "0xb4000000" if CF_AREA5
733
734source "arch/sh/drivers/pci/Kconfig" 705source "arch/sh/drivers/pci/Kconfig"
735 706
736source "drivers/pci/Kconfig" 707source "drivers/pci/Kconfig"
@@ -748,13 +719,11 @@ source "fs/Kconfig.binfmt"
748endmenu 719endmenu
749 720
750menu "Power management options (EXPERIMENTAL)" 721menu "Power management options (EXPERIMENTAL)"
751depends on EXPERIMENTAL && SYS_SUPPORTS_PM 722depends on EXPERIMENTAL
752 723
753config ARCH_SUSPEND_POSSIBLE 724source "kernel/power/Kconfig"
754 def_bool y
755 depends on !SMP
756 725
757source kernel/power/Kconfig 726source "drivers/cpuidle/Kconfig"
758 727
759endmenu 728endmenu
760 729
diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug
index e6d2c8b11abd..0d62681f72a0 100644
--- a/arch/sh/Kconfig.debug
+++ b/arch/sh/Kconfig.debug
@@ -98,18 +98,29 @@ config IRQSTACKS
98 for handling hard and soft interrupts. This can help avoid 98 for handling hard and soft interrupts. This can help avoid
99 overflowing the process kernel stacks. 99 overflowing the process kernel stacks.
100 100
101config SH_KGDB 101config DUMP_CODE
102 bool "Include KGDB kernel debugger" 102 bool "Show disassembly of nearby code in register dumps"
103 select FRAME_POINTER 103 depends on DEBUG_KERNEL && SUPERH32
104 select DEBUG_INFO 104 default y if DEBUG_BUGVERBOSE
105 depends on CPU_SH3 || CPU_SH4 105 default n
106 help
107 This prints out a code trace of the instructions leading up to
108 the faulting instruction as a debugging aid. As this does grow
109 the kernel in size a bit, most users will want to say N here.
110
111 Those looking for more verbose debugging output should say Y.
112
113config SH_NO_BSS_INIT
114 bool "Avoid zeroing BSS (to speed-up startup on suitable platforms)"
115 depends on DEBUG_KERNEL
116 default n
106 help 117 help
107 Include in-kernel hooks for kgdb, the Linux kernel source level 118 If running in painfully slow environments, such as an RTL
108 debugger. See <http://kgdb.sourceforge.net/> for more information. 119 simulation or from remote memory via SHdebug, where the memory
109 Unless you are intending to debug the kernel, say N here. 120 can already be gauranteed to ber zeroed on boot, say Y.
110 121
111menu "KGDB configuration options" 122 For all other cases, say N. If this option seems perplexing, or
112 depends on SH_KGDB 123 you aren't sure, say N.
113 124
114config MORE_COMPILE_OPTIONS 125config MORE_COMPILE_OPTIONS
115 bool "Add any additional compile options" 126 bool "Add any additional compile options"
@@ -122,85 +133,16 @@ config COMPILE_OPTIONS
122 string "Additional compile arguments" 133 string "Additional compile arguments"
123 depends on MORE_COMPILE_OPTIONS 134 depends on MORE_COMPILE_OPTIONS
124 135
125config KGDB_NMI
126 def_bool n
127 prompt "Enter KGDB on NMI"
128
129config SH_KGDB_CONSOLE
130 def_bool n
131 prompt "Console messages through GDB"
132 depends on !SERIAL_SH_SCI_CONSOLE && SERIAL_SH_SCI=y
133 select SERIAL_CORE_CONSOLE
134
135config KGDB_SYSRQ
136 def_bool y
137 prompt "Allow SysRq 'G' to enter KGDB"
138 depends on MAGIC_SYSRQ
139
140comment "Serial port setup"
141
142config KGDB_DEFPORT
143 int "Port number (ttySCn)"
144 default "1"
145
146config KGDB_DEFBAUD
147 int "Baud rate"
148 default "115200"
149
150choice
151 prompt "Parity"
152 depends on SH_KGDB
153 default KGDB_DEFPARITY_N
154
155config KGDB_DEFPARITY_N
156 bool "None"
157
158config KGDB_DEFPARITY_E
159 bool "Even"
160
161config KGDB_DEFPARITY_O
162 bool "Odd"
163
164endchoice
165
166choice
167 prompt "Data bits"
168 depends on SH_KGDB
169 default KGDB_DEFBITS_8
170
171config KGDB_DEFBITS_8
172 bool "8"
173
174config KGDB_DEFBITS_7
175 bool "7"
176
177endchoice
178
179endmenu
180
181if SUPERH64
182
183config SH64_PROC_ASIDS
184 bool "Debug: report ASIDs through /proc/asids"
185 depends on PROC_FS && MMU
186
187config SH64_SR_WATCH 136config SH64_SR_WATCH
188 bool "Debug: set SR.WATCH to enable hardware watchpoints and trace" 137 bool "Debug: set SR.WATCH to enable hardware watchpoints and trace"
138 depends on SUPERH64
189 139
190config POOR_MANS_STRACE 140config POOR_MANS_STRACE
191 bool "Debug: enable rudimentary strace facility" 141 bool "Debug: enable rudimentary strace facility"
142 depends on SUPERH64
192 help 143 help
193 This option allows system calls to be traced to the console. It also 144 This option allows system calls to be traced to the console. It also
194 aids in detecting kernel stack underflow. It is useful for debugging 145 aids in detecting kernel stack underflow. It is useful for debugging
195 early-userland problems (e.g. init incurring fatal exceptions.) 146 early-userland problems (e.g. init incurring fatal exceptions.)
196 147
197config SH_ALPHANUMERIC
198 bool "Enable debug outputs to on-board alphanumeric display"
199 depends on SH_CAYMAN
200
201config SH_NO_BSS_INIT
202 bool "Avoid zeroing BSS (to speed-up startup on suitable platforms)"
203
204endif
205
206endmenu 148endmenu
diff --git a/arch/sh/Makefile b/arch/sh/Makefile
index c43eb0d7fa3b..4067b0d9287b 100644
--- a/arch/sh/Makefile
+++ b/arch/sh/Makefile
@@ -32,6 +32,7 @@ cflags-$(CONFIG_CPU_SH4) := $(call cc-option,-m4,) \
32 $(call cc-option,-mno-implicit-fp,-m4-nofpu) 32 $(call cc-option,-mno-implicit-fp,-m4-nofpu)
33cflags-$(CONFIG_CPU_SH4A) += $(call cc-option,-m4a,) \ 33cflags-$(CONFIG_CPU_SH4A) += $(call cc-option,-m4a,) \
34 $(call cc-option,-m4a-nofpu,) 34 $(call cc-option,-m4a-nofpu,)
35cflags-$(CONFIG_CPU_SH4AL_DSP) += $(call cc-option,-m4al,)
35cflags-$(CONFIG_CPU_SH5) := $(call cc-option,-m5-32media-nofpu,) 36cflags-$(CONFIG_CPU_SH5) := $(call cc-option,-m5-32media-nofpu,)
36 37
37ifeq ($(cflags-y),) 38ifeq ($(cflags-y),)
@@ -39,22 +40,16 @@ ifeq ($(cflags-y),)
39# In the case where we are stuck with a compiler that has been uselessly 40# In the case where we are stuck with a compiler that has been uselessly
40# restricted to a particular ISA, a favourite default of newer GCCs when 41# restricted to a particular ISA, a favourite default of newer GCCs when
41# extensive multilib targets are not provided, ensure we get the best fit 42# extensive multilib targets are not provided, ensure we get the best fit
42# regarding FP generation. This is necessary to avoid references to FP 43# regarding FP generation. This is intentionally stupid (albeit many
43# variants in libgcc where integer variants exist, which otherwise result 44# orders of magnitude less than GCC's default behaviour), as anything
44# in link errors. This is intentionally stupid (albeit many orders of 45# with a large number of multilib targets better have been built
45# magnitude less than GCC's default behaviour), as anything with a large 46# correctly for the target in mind.
46# number of multilib targets better have been built correctly for
47# the target in mind.
48# 47#
49cflags-y += $(shell $(CC) $(KBUILD_CFLAGS) -print-multi-lib | \ 48cflags-y += $(shell $(CC) $(KBUILD_CFLAGS) -print-multi-lib | \
50 grep nofpu | sed q | sed -e 's/^/-/;s/;.*$$//') 49 grep nofpu | sed q | sed -e 's/^/-/;s/;.*$$//')
51endif 50# At this point, anything goes.
52 51isaflags-y := $(call as-option,-Wa$(comma)-isa=any,)
53cflags-$(CONFIG_CPU_BIG_ENDIAN) += -mb 52else
54cflags-$(CONFIG_CPU_LITTLE_ENDIAN) += -ml
55
56cflags-y += $(call cc-option,-mno-fdpic)
57
58# 53#
59# -Wa,-isa= tuning implies -Wa,-dsp for the versions of binutils that 54# -Wa,-isa= tuning implies -Wa,-dsp for the versions of binutils that
60# support it, while -Wa,-dsp by itself limits the range of usable opcodes 55# support it, while -Wa,-dsp by itself limits the range of usable opcodes
@@ -67,7 +62,12 @@ isaflags-y := $(call as-option,-Wa$(comma)-isa=$(isa-y),)
67 62
68isaflags-$(CONFIG_SH_DSP) := \ 63isaflags-$(CONFIG_SH_DSP) := \
69 $(call as-option,-Wa$(comma)-isa=$(isa-y),-Wa$(comma)-dsp) 64 $(call as-option,-Wa$(comma)-isa=$(isa-y),-Wa$(comma)-dsp)
65endif
70 66
67cflags-$(CONFIG_CPU_BIG_ENDIAN) += -mb
68cflags-$(CONFIG_CPU_LITTLE_ENDIAN) += -ml
69
70cflags-y += $(call cc-option,-mno-fdpic)
71cflags-y += $(isaflags-y) -ffreestanding 71cflags-y += $(isaflags-y) -ffreestanding
72 72
73cflags-$(CONFIG_MORE_COMPILE_OPTIONS) += \ 73cflags-$(CONFIG_MORE_COMPILE_OPTIONS) += \
@@ -79,6 +79,9 @@ OBJCOPYFLAGS := -O binary -R .note -R .note.gnu.build-id -R .comment \
79# Give the various platforms the opportunity to set default image types 79# Give the various platforms the opportunity to set default image types
80defaultimage-$(CONFIG_SUPERH32) := zImage 80defaultimage-$(CONFIG_SUPERH32) := zImage
81defaultimage-$(CONFIG_SH_SH7785LCR) := uImage 81defaultimage-$(CONFIG_SH_SH7785LCR) := uImage
82defaultimage-$(CONFIG_SH_RSK) := uImage
83defaultimage-$(CONFIG_SH_7206_SOLUTION_ENGINE) := vmlinux
84defaultimage-$(CONFIG_SH_7619_SOLUTION_ENGINE) := vmlinux
82 85
83# Set some sensible Kbuild defaults 86# Set some sensible Kbuild defaults
84KBUILD_DEFCONFIG := shx3_defconfig 87KBUILD_DEFCONFIG := shx3_defconfig
@@ -132,6 +135,7 @@ machdir-$(CONFIG_SH_LANDISK) += mach-landisk
132machdir-$(CONFIG_SH_TITAN) += mach-titan 135machdir-$(CONFIG_SH_TITAN) += mach-titan
133machdir-$(CONFIG_SH_LBOX_RE2) += mach-lboxre2 136machdir-$(CONFIG_SH_LBOX_RE2) += mach-lboxre2
134machdir-$(CONFIG_SH_CAYMAN) += mach-cayman 137machdir-$(CONFIG_SH_CAYMAN) += mach-cayman
138machdir-$(CONFIG_SH_RSK) += mach-rsk
135 139
136ifneq ($(machdir-y),) 140ifneq ($(machdir-y),)
137core-y += $(addprefix arch/sh/boards/, \ 141core-y += $(addprefix arch/sh/boards/, \
@@ -173,11 +177,8 @@ KBUILD_CFLAGS += -pipe $(cflags-y)
173KBUILD_CPPFLAGS += $(cflags-y) 177KBUILD_CPPFLAGS += $(cflags-y)
174KBUILD_AFLAGS += $(cflags-y) 178KBUILD_AFLAGS += $(cflags-y)
175 179
176LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
177
178libs-$(CONFIG_SUPERH32) := arch/sh/lib/ $(libs-y) 180libs-$(CONFIG_SUPERH32) := arch/sh/lib/ $(libs-y)
179libs-$(CONFIG_SUPERH64) := arch/sh/lib64/ $(libs-y) 181libs-$(CONFIG_SUPERH64) := arch/sh/lib64/ $(libs-y)
180libs-y += $(LIBGCC)
181 182
182PHONY += maketools FORCE 183PHONY += maketools FORCE
183 184
diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig
index 50467f9d0d0b..861914747e4e 100644
--- a/arch/sh/boards/Kconfig
+++ b/arch/sh/boards/Kconfig
@@ -126,10 +126,12 @@ config SH_RTS7751R2D
126 Select RTS7751R2D if configuring for a Renesas Technology 126 Select RTS7751R2D if configuring for a Renesas Technology
127 Sales SH-Graphics board. 127 Sales SH-Graphics board.
128 128
129config SH_RSK7203 129config SH_RSK
130 bool "RSK7203" 130 bool "Renesas Starter Kit"
131 select GENERIC_GPIO 131 depends on CPU_SUBTYPE_SH7201 || CPU_SUBTYPE_SH7203
132 depends on CPU_SUBTYPE_SH7203 132 help
133 Select this option if configuring for any of the RSK+ MCU
134 evaluation platforms.
133 135
134config SH_SDK7780 136config SH_SDK7780
135 bool "SDK7780R3" 137 bool "SDK7780R3"
@@ -253,6 +255,7 @@ source "arch/sh/boards/mach-r2d/Kconfig"
253source "arch/sh/boards/mach-highlander/Kconfig" 255source "arch/sh/boards/mach-highlander/Kconfig"
254source "arch/sh/boards/mach-sdk7780/Kconfig" 256source "arch/sh/boards/mach-sdk7780/Kconfig"
255source "arch/sh/boards/mach-migor/Kconfig" 257source "arch/sh/boards/mach-migor/Kconfig"
258source "arch/sh/boards/mach-rsk/Kconfig"
256 259
257if SH_MAGIC_PANEL_R2 260if SH_MAGIC_PANEL_R2
258 261
diff --git a/arch/sh/boards/Makefile b/arch/sh/boards/Makefile
index d9efa3923721..269ae2be49ef 100644
--- a/arch/sh/boards/Makefile
+++ b/arch/sh/boards/Makefile
@@ -3,7 +3,6 @@
3# 3#
4obj-$(CONFIG_SH_AP325RXA) += board-ap325rxa.o 4obj-$(CONFIG_SH_AP325RXA) += board-ap325rxa.o
5obj-$(CONFIG_SH_MAGIC_PANEL_R2) += board-magicpanelr2.o 5obj-$(CONFIG_SH_MAGIC_PANEL_R2) += board-magicpanelr2.o
6obj-$(CONFIG_SH_RSK7203) += board-rsk7203.o
7obj-$(CONFIG_SH_SH7785LCR) += board-sh7785lcr.o 6obj-$(CONFIG_SH_SH7785LCR) += board-sh7785lcr.o
8obj-$(CONFIG_SH_SHMIN) += board-shmin.o 7obj-$(CONFIG_SH_SHMIN) += board-shmin.o
9obj-$(CONFIG_SH_EDOSK7760) += board-edosk7760.o 8obj-$(CONFIG_SH_EDOSK7760) += board-edosk7760.o
diff --git a/arch/sh/boards/board-ap325rxa.c b/arch/sh/boards/board-ap325rxa.c
index 8881a643ac32..1c67cba6e34f 100644
--- a/arch/sh/boards/board-ap325rxa.c
+++ b/arch/sh/boards/board-ap325rxa.c
@@ -197,6 +197,10 @@ static struct resource lcdc_resources[] = {
197 .end = 0xfe941fff, 197 .end = 0xfe941fff,
198 .flags = IORESOURCE_MEM, 198 .flags = IORESOURCE_MEM,
199 }, 199 },
200 [1] = {
201 .start = 28,
202 .flags = IORESOURCE_IRQ,
203 },
200}; 204};
201 205
202static struct platform_device lcdc_device = { 206static struct platform_device lcdc_device = {
@@ -303,6 +307,7 @@ static struct resource ceu_resources[] = {
303 307
304static struct platform_device ceu_device = { 308static struct platform_device ceu_device = {
305 .name = "sh_mobile_ceu", 309 .name = "sh_mobile_ceu",
310 .id = 0, /* "ceu0" clock */
306 .num_resources = ARRAY_SIZE(ceu_resources), 311 .num_resources = ARRAY_SIZE(ceu_resources),
307 .resource = ceu_resources, 312 .resource = ceu_resources,
308 .dev = { 313 .dev = {
@@ -344,7 +349,6 @@ static int __init ap325rxa_devices_setup(void)
344 gpio_export(GPIO_PTF7, 0); 349 gpio_export(GPIO_PTF7, 0);
345 350
346 /* LCDC */ 351 /* LCDC */
347 clk_always_enable("mstp200");
348 gpio_request(GPIO_FN_LCDD15, NULL); 352 gpio_request(GPIO_FN_LCDD15, NULL);
349 gpio_request(GPIO_FN_LCDD14, NULL); 353 gpio_request(GPIO_FN_LCDD14, NULL);
350 gpio_request(GPIO_FN_LCDD13, NULL); 354 gpio_request(GPIO_FN_LCDD13, NULL);
@@ -375,7 +379,6 @@ static int __init ap325rxa_devices_setup(void)
375 gpio_direction_output(GPIO_PTS3, 1); 379 gpio_direction_output(GPIO_PTS3, 1);
376 380
377 /* CEU */ 381 /* CEU */
378 clk_always_enable("mstp203");
379 gpio_request(GPIO_FN_VIO_CLK2, NULL); 382 gpio_request(GPIO_FN_VIO_CLK2, NULL);
380 gpio_request(GPIO_FN_VIO_VD2, NULL); 383 gpio_request(GPIO_FN_VIO_VD2, NULL);
381 gpio_request(GPIO_FN_VIO_HD2, NULL); 384 gpio_request(GPIO_FN_VIO_HD2, NULL);
diff --git a/arch/sh/boards/board-shmin.c b/arch/sh/boards/board-shmin.c
index 5cc0867de5ab..b1dcbbc89188 100644
--- a/arch/sh/boards/board-shmin.c
+++ b/arch/sh/boards/board-shmin.c
@@ -22,21 +22,13 @@ static void __init init_shmin_irq(void)
22 plat_irq_setup_pins(IRQ_MODE_IRQ); 22 plat_irq_setup_pins(IRQ_MODE_IRQ);
23} 23}
24 24
25static void __iomem *shmin_ioport_map(unsigned long port, unsigned int size) 25static void __init shmin_setup(char **cmdline_p)
26{ 26{
27 static int dummy; 27 __set_io_port_base(SHMIN_IO_BASE);
28
29 if ((port & ~0x1f) == SHMIN_NE_BASE)
30 return (void __iomem *)(SHMIN_IO_BASE + port);
31
32 dummy = 0;
33
34 return &dummy;
35
36} 28}
37 29
38static struct sh_machine_vector mv_shmin __initmv = { 30static struct sh_machine_vector mv_shmin __initmv = {
39 .mv_name = "SHMIN", 31 .mv_name = "SHMIN",
32 .mv_setup = shmin_setup,
40 .mv_init_irq = init_shmin_irq, 33 .mv_init_irq = init_shmin_irq,
41 .mv_ioport_map = shmin_ioport_map,
42}; 34};
diff --git a/arch/sh/boards/mach-cayman/Makefile b/arch/sh/boards/mach-cayman/Makefile
index 489a8f867368..cafe1ac3b29c 100644
--- a/arch/sh/boards/mach-cayman/Makefile
+++ b/arch/sh/boards/mach-cayman/Makefile
@@ -2,4 +2,3 @@
2# Makefile for the Hitachi Cayman specific parts of the kernel 2# Makefile for the Hitachi Cayman specific parts of the kernel
3# 3#
4obj-y := setup.o irq.o 4obj-y := setup.o irq.o
5obj-$(CONFIG_HEARTBEAT) += led.o
diff --git a/arch/sh/boards/mach-cayman/irq.c b/arch/sh/boards/mach-cayman/irq.c
index ceb37ae92c70..da62ad516994 100644
--- a/arch/sh/boards/mach-cayman/irq.c
+++ b/arch/sh/boards/mach-cayman/irq.c
@@ -94,31 +94,11 @@ static void ack_cayman_irq(unsigned int irq)
94 disable_cayman_irq(irq); 94 disable_cayman_irq(irq);
95} 95}
96 96
97static void end_cayman_irq(unsigned int irq) 97struct irq_chip cayman_irq_type = {
98{ 98 .name = "Cayman-IRQ",
99 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) 99 .unmask = enable_cayman_irq,
100 enable_cayman_irq(irq); 100 .mask = disable_cayman_irq,
101} 101 .mask_ack = ack_cayman_irq,
102
103static unsigned int startup_cayman_irq(unsigned int irq)
104{
105 enable_cayman_irq(irq);
106 return 0; /* never anything pending */
107}
108
109static void shutdown_cayman_irq(unsigned int irq)
110{
111 disable_cayman_irq(irq);
112}
113
114struct hw_interrupt_type cayman_irq_type = {
115 .typename = "Cayman-IRQ",
116 .startup = startup_cayman_irq,
117 .shutdown = shutdown_cayman_irq,
118 .enable = enable_cayman_irq,
119 .disable = disable_cayman_irq,
120 .ack = ack_cayman_irq,
121 .end = end_cayman_irq,
122}; 102};
123 103
124int cayman_irq_demux(int evt) 104int cayman_irq_demux(int evt)
@@ -187,8 +167,9 @@ void init_cayman_irq(void)
187 return; 167 return;
188 } 168 }
189 169
190 for (i=0; i<NR_EXT_IRQS; i++) { 170 for (i = 0; i < NR_EXT_IRQS; i++) {
191 irq_desc[START_EXT_IRQS + i].chip = &cayman_irq_type; 171 set_irq_chip_and_handler(START_EXT_IRQS + i, &cayman_irq_type,
172 handle_level_irq);
192 } 173 }
193 174
194 /* Setup the SMSC interrupt */ 175 /* Setup the SMSC interrupt */
diff --git a/arch/sh/boards/mach-cayman/led.c b/arch/sh/boards/mach-cayman/led.c
deleted file mode 100644
index a808eac4ecd6..000000000000
--- a/arch/sh/boards/mach-cayman/led.c
+++ /dev/null
@@ -1,51 +0,0 @@
1/*
2 * arch/sh/boards/cayman/led.c
3 *
4 * Copyright (C) 2002 Stuart Menefy <stuart.menefy@st.com>
5 *
6 * May be copied or modified under the terms of the GNU General Public
7 * License. See linux/COPYING for more information.
8 *
9 * Flash the LEDs
10 */
11#include <asm/io.h>
12
13/*
14** It is supposed these functions to be used for a low level
15** debugging (via Cayman LEDs), hence to be available as soon
16** as possible.
17** Unfortunately Cayman LEDs relies on Cayman EPLD to be mapped
18** (this happen when IRQ are initialized... quite late).
19** These triky dependencies should be removed. Temporary, it
20** may be enough to NOP until EPLD is mapped.
21*/
22
23extern unsigned long epld_virt;
24
25#define LED_ADDR (epld_virt + 0x008)
26#define HDSP2534_ADDR (epld_virt + 0x100)
27
28void mach_led(int position, int value)
29{
30 if (!epld_virt)
31 return;
32
33 if (value)
34 ctrl_outl(0, LED_ADDR);
35 else
36 ctrl_outl(1, LED_ADDR);
37
38}
39
40void mach_alphanum(int position, unsigned char value)
41{
42 if (!epld_virt)
43 return;
44
45 ctrl_outb(value, HDSP2534_ADDR + 0xe0 + (position << 2));
46}
47
48void mach_alphanum_brightness(int setting)
49{
50 ctrl_outb(setting & 7, HDSP2534_ADDR + 0xc0);
51}
diff --git a/arch/sh/boards/mach-dreamcast/irq.c b/arch/sh/boards/mach-dreamcast/irq.c
index 67bdc33dd411..f55fc8e795e9 100644
--- a/arch/sh/boards/mach-dreamcast/irq.c
+++ b/arch/sh/boards/mach-dreamcast/irq.c
@@ -10,106 +10,90 @@
10 */ 10 */
11 11
12#include <linux/irq.h> 12#include <linux/irq.h>
13#include <asm/io.h> 13#include <linux/io.h>
14#include <asm/irq.h> 14#include <asm/irq.h>
15#include <mach/sysasic.h> 15#include <mach/sysasic.h>
16 16
17/* Dreamcast System ASIC Hardware Events - 17/*
18 18 * Dreamcast System ASIC Hardware Events -
19 The Dreamcast's System ASIC (a.k.a. Holly) is responsible for receiving 19 *
20 hardware events from system peripherals and triggering an SH7750 IRQ. 20 * The Dreamcast's System ASIC (a.k.a. Holly) is responsible for receiving
21 Hardware events can trigger IRQs 13, 11, or 9 depending on which bits are 21 * hardware events from system peripherals and triggering an SH7750 IRQ.
22 set in the Event Mask Registers (EMRs). When a hardware event is 22 * Hardware events can trigger IRQs 13, 11, or 9 depending on which bits are
23 triggered, it's corresponding bit in the Event Status Registers (ESRs) 23 * set in the Event Mask Registers (EMRs). When a hardware event is
24 is set, and that bit should be rewritten to the ESR to acknowledge that 24 * triggered, its corresponding bit in the Event Status Registers (ESRs)
25 event. 25 * is set, and that bit should be rewritten to the ESR to acknowledge that
26 26 * event.
27 There are three 32-bit ESRs located at 0xa05f8900 - 0xa05f6908. Event 27 *
28 types can be found in include/asm-sh/dreamcast/sysasic.h. There are three 28 * There are three 32-bit ESRs located at 0xa05f6900 - 0xa05f6908. Event
29 groups of EMRs that parallel the ESRs. Each EMR group corresponds to an 29 * types can be found in arch/sh/include/mach-dreamcast/mach/sysasic.h.
30 IRQ, so 0xa05f6910 - 0xa05f6918 triggers IRQ 13, 0xa05f6920 - 0xa05f6928 30 * There are three groups of EMRs that parallel the ESRs. Each EMR group
31 triggers IRQ 11, and 0xa05f6930 - 0xa05f6938 triggers IRQ 9. 31 * corresponds to an IRQ, so 0xa05f6910 - 0xa05f6918 triggers IRQ 13,
32 32 * 0xa05f6920 - 0xa05f6928 triggers IRQ 11, and 0xa05f6930 - 0xa05f6938
33 In the kernel, these events are mapped to virtual IRQs so that drivers can 33 * triggers IRQ 9.
34 respond to them as they would a normal interrupt. In order to keep this 34 *
35 mapping simple, the events are mapped as: 35 * In the kernel, these events are mapped to virtual IRQs so that drivers can
36 36 * respond to them as they would a normal interrupt. In order to keep this
37 6900/6910 - Events 0-31, IRQ 13 37 * mapping simple, the events are mapped as:
38 6904/6924 - Events 32-63, IRQ 11 38 *
39 6908/6938 - Events 64-95, IRQ 9 39 * 6900/6910 - Events 0-31, IRQ 13
40 40 * 6904/6924 - Events 32-63, IRQ 11
41*/ 41 * 6908/6938 - Events 64-95, IRQ 9
42 *
43 */
42 44
43#define ESR_BASE 0x005f6900 /* Base event status register */ 45#define ESR_BASE 0x005f6900 /* Base event status register */
44#define EMR_BASE 0x005f6910 /* Base event mask register */ 46#define EMR_BASE 0x005f6910 /* Base event mask register */
45 47
46/* Helps us determine the EMR group that this event belongs to: 0 = 0x6910, 48/*
47 1 = 0x6920, 2 = 0x6930; also determine the event offset */ 49 * Helps us determine the EMR group that this event belongs to: 0 = 0x6910,
50 * 1 = 0x6920, 2 = 0x6930; also determine the event offset.
51 */
48#define LEVEL(event) (((event) - HW_EVENT_IRQ_BASE) / 32) 52#define LEVEL(event) (((event) - HW_EVENT_IRQ_BASE) / 32)
49 53
50/* Return the hardware event's bit positon within the EMR/ESR */ 54/* Return the hardware event's bit positon within the EMR/ESR */
51#define EVENT_BIT(event) (((event) - HW_EVENT_IRQ_BASE) & 31) 55#define EVENT_BIT(event) (((event) - HW_EVENT_IRQ_BASE) & 31)
52 56
53/* For each of these *_irq routines, the IRQ passed in is the virtual IRQ 57/*
54 (logically mapped to the corresponding bit for the hardware event). */ 58 * For each of these *_irq routines, the IRQ passed in is the virtual IRQ
59 * (logically mapped to the corresponding bit for the hardware event).
60 */
55 61
56/* Disable the hardware event by masking its bit in its EMR */ 62/* Disable the hardware event by masking its bit in its EMR */
57static inline void disable_systemasic_irq(unsigned int irq) 63static inline void disable_systemasic_irq(unsigned int irq)
58{ 64{
59 __u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2); 65 __u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2);
60 __u32 mask; 66 __u32 mask;
61 67
62 mask = inl(emr); 68 mask = inl(emr);
63 mask &= ~(1 << EVENT_BIT(irq)); 69 mask &= ~(1 << EVENT_BIT(irq));
64 outl(mask, emr); 70 outl(mask, emr);
65} 71}
66 72
67/* Enable the hardware event by setting its bit in its EMR */ 73/* Enable the hardware event by setting its bit in its EMR */
68static inline void enable_systemasic_irq(unsigned int irq) 74static inline void enable_systemasic_irq(unsigned int irq)
69{ 75{
70 __u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2); 76 __u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2);
71 __u32 mask; 77 __u32 mask;
72 78
73 mask = inl(emr); 79 mask = inl(emr);
74 mask |= (1 << EVENT_BIT(irq)); 80 mask |= (1 << EVENT_BIT(irq));
75 outl(mask, emr); 81 outl(mask, emr);
76} 82}
77 83
78/* Acknowledge a hardware event by writing its bit back to its ESR */ 84/* Acknowledge a hardware event by writing its bit back to its ESR */
79static void ack_systemasic_irq(unsigned int irq) 85static void mask_ack_systemasic_irq(unsigned int irq)
80{
81 __u32 esr = ESR_BASE + (LEVEL(irq) << 2);
82 disable_systemasic_irq(irq);
83 outl((1 << EVENT_BIT(irq)), esr);
84}
85
86/* After a IRQ has been ack'd and responded to, it needs to be renabled */
87static void end_systemasic_irq(unsigned int irq)
88{
89 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
90 enable_systemasic_irq(irq);
91}
92
93static unsigned int startup_systemasic_irq(unsigned int irq)
94{
95 enable_systemasic_irq(irq);
96
97 return 0;
98}
99
100static void shutdown_systemasic_irq(unsigned int irq)
101{ 86{
102 disable_systemasic_irq(irq); 87 __u32 esr = ESR_BASE + (LEVEL(irq) << 2);
88 disable_systemasic_irq(irq);
89 outl((1 << EVENT_BIT(irq)), esr);
103} 90}
104 91
105struct hw_interrupt_type systemasic_int = { 92struct irq_chip systemasic_int = {
106 .typename = "System ASIC", 93 .name = "System ASIC",
107 .startup = startup_systemasic_irq, 94 .mask = disable_systemasic_irq,
108 .shutdown = shutdown_systemasic_irq, 95 .mask_ack = mask_ack_systemasic_irq,
109 .enable = enable_systemasic_irq, 96 .unmask = enable_systemasic_irq,
110 .disable = disable_systemasic_irq,
111 .ack = ack_systemasic_irq,
112 .end = end_systemasic_irq,
113}; 97};
114 98
115/* 99/*
@@ -117,37 +101,37 @@ struct hw_interrupt_type systemasic_int = {
117 */ 101 */
118int systemasic_irq_demux(int irq) 102int systemasic_irq_demux(int irq)
119{ 103{
120 __u32 emr, esr, status, level; 104 __u32 emr, esr, status, level;
121 __u32 j, bit; 105 __u32 j, bit;
122 106
123 switch (irq) { 107 switch (irq) {
124 case 13: 108 case 13:
125 level = 0; 109 level = 0;
126 break; 110 break;
127 case 11: 111 case 11:
128 level = 1; 112 level = 1;
129 break; 113 break;
130 case 9: 114 case 9:
131 level = 2; 115 level = 2;
132 break; 116 break;
133 default: 117 default:
134 return irq; 118 return irq;
135 } 119 }
136 emr = EMR_BASE + (level << 4) + (level << 2); 120 emr = EMR_BASE + (level << 4) + (level << 2);
137 esr = ESR_BASE + (level << 2); 121 esr = ESR_BASE + (level << 2);
138 122
139 /* Mask the ESR to filter any spurious, unwanted interrupts */ 123 /* Mask the ESR to filter any spurious, unwanted interrupts */
140 status = inl(esr); 124 status = inl(esr);
141 status &= inl(emr); 125 status &= inl(emr);
142 126
143 /* Now scan and find the first set bit as the event to map */ 127 /* Now scan and find the first set bit as the event to map */
144 for (bit = 1, j = 0; j < 32; bit <<= 1, j++) { 128 for (bit = 1, j = 0; j < 32; bit <<= 1, j++) {
145 if (status & bit) { 129 if (status & bit) {
146 irq = HW_EVENT_IRQ_BASE + j + (level << 5); 130 irq = HW_EVENT_IRQ_BASE + j + (level << 5);
147 return irq; 131 return irq;
148 } 132 }
149 } 133 }
150 134
151 /* Not reached */ 135 /* Not reached */
152 return irq; 136 return irq;
153} 137}
diff --git a/arch/sh/boards/mach-dreamcast/setup.c b/arch/sh/boards/mach-dreamcast/setup.c
index 7d944fc75e93..d1bee4884cd6 100644
--- a/arch/sh/boards/mach-dreamcast/setup.c
+++ b/arch/sh/boards/mach-dreamcast/setup.c
@@ -28,7 +28,7 @@
28#include <asm/machvec.h> 28#include <asm/machvec.h>
29#include <mach/sysasic.h> 29#include <mach/sysasic.h>
30 30
31extern struct hw_interrupt_type systemasic_int; 31extern struct irq_chip systemasic_int;
32extern void aica_time_init(void); 32extern void aica_time_init(void);
33extern int gapspci_init(void); 33extern int gapspci_init(void);
34extern int systemasic_irq_demux(int); 34extern int systemasic_irq_demux(int);
@@ -47,7 +47,8 @@ static void __init dreamcast_setup(char **cmdline_p)
47 47
48 /* Assign all virtual IRQs to the System ASIC int. handler */ 48 /* Assign all virtual IRQs to the System ASIC int. handler */
49 for (i = HW_EVENT_IRQ_BASE; i < HW_EVENT_IRQ_MAX; i++) 49 for (i = HW_EVENT_IRQ_BASE; i < HW_EVENT_IRQ_MAX; i++)
50 irq_desc[i].chip = &systemasic_int; 50 set_irq_chip_and_handler(i, &systemasic_int,
51 handle_level_irq);
51 52
52 board_time_init = aica_time_init; 53 board_time_init = aica_time_init;
53 54
diff --git a/arch/sh/boards/mach-edosk7705/Makefile b/arch/sh/boards/mach-edosk7705/Makefile
index 14bdd531f116..cd54acb51499 100644
--- a/arch/sh/boards/mach-edosk7705/Makefile
+++ b/arch/sh/boards/mach-edosk7705/Makefile
@@ -3,4 +3,3 @@
3# 3#
4 4
5obj-y := setup.o io.o 5obj-y := setup.o io.o
6
diff --git a/arch/sh/boards/mach-edosk7705/io.c b/arch/sh/boards/mach-edosk7705/io.c
index 7d153e50a01b..5b9c57c43241 100644
--- a/arch/sh/boards/mach-edosk7705/io.c
+++ b/arch/sh/boards/mach-edosk7705/io.c
@@ -10,28 +10,24 @@
10 10
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/types.h> 12#include <linux/types.h>
13#include <asm/io.h> 13#include <linux/io.h>
14#include <mach/edosk7705.h> 14#include <mach/edosk7705.h>
15#include <asm/addrspace.h> 15#include <asm/addrspace.h>
16 16
17#define SMC_IOADDR 0xA2000000 17#define SMC_IOADDR 0xA2000000
18 18
19#define maybebadio(name,port) \
20 printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \
21 #name, (port), (__u32) __builtin_return_address(0))
22
23/* Map the Ethernet addresses as if it is at 0x300 - 0x320 */ 19/* Map the Ethernet addresses as if it is at 0x300 - 0x320 */
24unsigned long sh_edosk7705_isa_port2addr(unsigned long port) 20static unsigned long sh_edosk7705_isa_port2addr(unsigned long port)
25{ 21{
26 if (port >= 0x300 && port < 0x320) { 22 /*
27 /* SMC91C96 registers are 4 byte aligned rather than the 23 * SMC91C96 registers are 4 byte aligned rather than the
28 * usual 2 byte! 24 * usual 2 byte!
29 */ 25 */
30 return SMC_IOADDR + ( (port - 0x300) * 2); 26 if (port >= 0x300 && port < 0x320)
31 } 27 return SMC_IOADDR + ((port - 0x300) * 2);
32 28
33 maybebadio(sh_edosk7705_isa_port2addr, port); 29 maybebadio(port);
34 return port; 30 return port;
35} 31}
36 32
37/* Trying to read / write bytes on odd-byte boundaries to the Ethernet 33/* Trying to read / write bytes on odd-byte boundaries to the Ethernet
@@ -42,53 +38,34 @@ unsigned long sh_edosk7705_isa_port2addr(unsigned long port)
42 */ 38 */
43unsigned char sh_edosk7705_inb(unsigned long port) 39unsigned char sh_edosk7705_inb(unsigned long port)
44{ 40{
45 if (port >= 0x300 && port < 0x320 && port & 0x01) { 41 if (port >= 0x300 && port < 0x320 && port & 0x01)
46 return (volatile unsigned char)(generic_inw(port -1) >> 8); 42 return __raw_readw(port - 1) >> 8;
47 }
48 return *(volatile unsigned char *)sh_edosk7705_isa_port2addr(port);
49}
50 43
51unsigned int sh_edosk7705_inl(unsigned long port) 44 return __raw_readb(sh_edosk7705_isa_port2addr(port));
52{
53 return *(volatile unsigned long *)port;
54} 45}
55 46
56void sh_edosk7705_outb(unsigned char value, unsigned long port) 47void sh_edosk7705_outb(unsigned char value, unsigned long port)
57{ 48{
58 if (port >= 0x300 && port < 0x320 && port & 0x01) { 49 if (port >= 0x300 && port < 0x320 && port & 0x01) {
59 generic_outw(((unsigned short)value << 8), port -1); 50 __raw_writew(((unsigned short)value << 8), port - 1);
60 return; 51 return;
61 } 52 }
62 *(volatile unsigned char *)sh_edosk7705_isa_port2addr(port) = value;
63}
64 53
65void sh_edosk7705_outl(unsigned int value, unsigned long port) 54 __raw_writeb(value, sh_edosk7705_isa_port2addr(port));
66{
67 *(volatile unsigned long *)port = value;
68} 55}
69 56
70void sh_edosk7705_insb(unsigned long port, void *addr, unsigned long count) 57void sh_edosk7705_insb(unsigned long port, void *addr, unsigned long count)
71{ 58{
72 unsigned char *p = addr; 59 unsigned char *p = addr;
73 while (count--) *p++ = sh_edosk7705_inb(port);
74}
75 60
76void sh_edosk7705_insl(unsigned long port, void *addr, unsigned long count)
77{
78 unsigned long *p = (unsigned long*)addr;
79 while (count--) 61 while (count--)
80 *p++ = *(volatile unsigned long *)port; 62 *p++ = sh_edosk7705_inb(port);
81} 63}
82 64
83void sh_edosk7705_outsb(unsigned long port, const void *addr, unsigned long count) 65void sh_edosk7705_outsb(unsigned long port, const void *addr, unsigned long count)
84{ 66{
85 unsigned char *p = (unsigned char*)addr; 67 unsigned char *p = (unsigned char *)addr;
86 while (count--) sh_edosk7705_outb(*p++, port);
87}
88 68
89void sh_edosk7705_outsl(unsigned long port, const void *addr, unsigned long count) 69 while (count--)
90{ 70 sh_edosk7705_outb(*p++, port);
91 unsigned long *p = (unsigned long*)addr;
92 while (count--) sh_edosk7705_outl(*p++, port);
93} 71}
94
diff --git a/arch/sh/boards/mach-edosk7705/setup.c b/arch/sh/boards/mach-edosk7705/setup.c
index ab3f47bffdf3..d59225e26fb9 100644
--- a/arch/sh/boards/mach-edosk7705/setup.c
+++ b/arch/sh/boards/mach-edosk7705/setup.c
@@ -9,6 +9,7 @@
9 * board by S. Dunn, 2003. 9 * board by S. Dunn, 2003.
10 */ 10 */
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/irq.h>
12#include <asm/machvec.h> 13#include <asm/machvec.h>
13#include <mach/edosk7705.h> 14#include <mach/edosk7705.h>
14 15
@@ -26,18 +27,10 @@ static struct sh_machine_vector mv_edosk7705 __initmv = {
26 .mv_nr_irqs = 80, 27 .mv_nr_irqs = 80,
27 28
28 .mv_inb = sh_edosk7705_inb, 29 .mv_inb = sh_edosk7705_inb,
29 .mv_inl = sh_edosk7705_inl,
30 .mv_outb = sh_edosk7705_outb, 30 .mv_outb = sh_edosk7705_outb,
31 .mv_outl = sh_edosk7705_outl,
32
33 .mv_inl_p = sh_edosk7705_inl,
34 .mv_outl_p = sh_edosk7705_outl,
35 31
36 .mv_insb = sh_edosk7705_insb, 32 .mv_insb = sh_edosk7705_insb,
37 .mv_insl = sh_edosk7705_insl,
38 .mv_outsb = sh_edosk7705_outsb, 33 .mv_outsb = sh_edosk7705_outsb,
39 .mv_outsl = sh_edosk7705_outsl,
40 34
41 .mv_isa_port2addr = sh_edosk7705_isa_port2addr,
42 .mv_init_irq = sh_edosk7705_init_irq, 35 .mv_init_irq = sh_edosk7705_init_irq,
43}; 36};
diff --git a/arch/sh/boards/mach-hp6xx/pm.c b/arch/sh/boards/mach-hp6xx/pm.c
index 64af1f2eef05..d936c1af7620 100644
--- a/arch/sh/boards/mach-hp6xx/pm.c
+++ b/arch/sh/boards/mach-hp6xx/pm.c
@@ -10,15 +10,91 @@
10#include <linux/suspend.h> 10#include <linux/suspend.h>
11#include <linux/errno.h> 11#include <linux/errno.h>
12#include <linux/time.h> 12#include <linux/time.h>
13#include <linux/delay.h>
14#include <linux/gfp.h>
13#include <asm/io.h> 15#include <asm/io.h>
14#include <asm/hd64461.h> 16#include <asm/hd64461.h>
15#include <mach/hp6xx.h> 17#include <mach/hp6xx.h>
16#include <cpu/dac.h> 18#include <cpu/dac.h>
17#include <asm/pm.h> 19#include <asm/freq.h>
20#include <asm/watchdog.h>
21
22#define INTR_OFFSET 0x600
18 23
19#define STBCR 0xffffff82 24#define STBCR 0xffffff82
20#define STBCR2 0xffffff88 25#define STBCR2 0xffffff88
21 26
27#define STBCR_STBY 0x80
28#define STBCR_MSTP2 0x04
29
30#define MCR 0xffffff68
31#define RTCNT 0xffffff70
32
33#define MCR_RMODE 2
34#define MCR_RFSH 4
35
36extern u8 wakeup_start;
37extern u8 wakeup_end;
38
39static void pm_enter(void)
40{
41 u8 stbcr, csr;
42 u16 frqcr, mcr;
43 u32 vbr_new, vbr_old;
44
45 set_bl_bit();
46
47 /* set wdt */
48 csr = sh_wdt_read_csr();
49 csr &= ~WTCSR_TME;
50 csr |= WTCSR_CKS_4096;
51 sh_wdt_write_csr(csr);
52 csr = sh_wdt_read_csr();
53 sh_wdt_write_cnt(0);
54
55 /* disable PLL1 */
56 frqcr = ctrl_inw(FRQCR);
57 frqcr &= ~(FRQCR_PLLEN | FRQCR_PSTBY);
58 ctrl_outw(frqcr, FRQCR);
59
60 /* enable standby */
61 stbcr = ctrl_inb(STBCR);
62 ctrl_outb(stbcr | STBCR_STBY | STBCR_MSTP2, STBCR);
63
64 /* set self-refresh */
65 mcr = ctrl_inw(MCR);
66 ctrl_outw(mcr & ~MCR_RFSH, MCR);
67
68 /* set interrupt handler */
69 asm volatile("stc vbr, %0" : "=r" (vbr_old));
70 vbr_new = get_zeroed_page(GFP_ATOMIC);
71 udelay(50);
72 memcpy((void*)(vbr_new + INTR_OFFSET),
73 &wakeup_start, &wakeup_end - &wakeup_start);
74 asm volatile("ldc %0, vbr" : : "r" (vbr_new));
75
76 ctrl_outw(0, RTCNT);
77 ctrl_outw(mcr | MCR_RFSH | MCR_RMODE, MCR);
78
79 cpu_sleep();
80
81 asm volatile("ldc %0, vbr" : : "r" (vbr_old));
82
83 free_page(vbr_new);
84
85 /* enable PLL1 */
86 frqcr = ctrl_inw(FRQCR);
87 frqcr |= FRQCR_PSTBY;
88 ctrl_outw(frqcr, FRQCR);
89 udelay(50);
90 frqcr |= FRQCR_PLLEN;
91 ctrl_outw(frqcr, FRQCR);
92
93 ctrl_outb(stbcr, STBCR);
94
95 clear_bl_bit();
96}
97
22static int hp6x0_pm_enter(suspend_state_t state) 98static int hp6x0_pm_enter(suspend_state_t state)
23{ 99{
24 u8 stbcr, stbcr2; 100 u8 stbcr, stbcr2;
diff --git a/arch/sh/boards/mach-microdev/Makefile b/arch/sh/boards/mach-microdev/Makefile
index 1387dd6c85eb..4e3588e8806b 100644
--- a/arch/sh/boards/mach-microdev/Makefile
+++ b/arch/sh/boards/mach-microdev/Makefile
@@ -2,7 +2,4 @@
2# Makefile for the SuperH MicroDev specific parts of the kernel 2# Makefile for the SuperH MicroDev specific parts of the kernel
3# 3#
4 4
5obj-y := setup.o irq.o io.o 5obj-y := setup.o irq.o io.o fdc37c93xapm.o
6
7obj-$(CONFIG_HEARTBEAT) += led.o
8
diff --git a/arch/sh/boards/mach-microdev/fdc37c93xapm.c b/arch/sh/boards/mach-microdev/fdc37c93xapm.c
new file mode 100644
index 000000000000..458a7cf5fb46
--- /dev/null
+++ b/arch/sh/boards/mach-microdev/fdc37c93xapm.c
@@ -0,0 +1,160 @@
1/*
2 *
3 * Setup for the SMSC FDC37C93xAPM
4 *
5 * Copyright (C) 2003 Sean McGoogan (Sean.McGoogan@superh.com)
6 * Copyright (C) 2003, 2004 SuperH, Inc.
7 * Copyright (C) 2004, 2005 Paul Mundt
8 *
9 * SuperH SH4-202 MicroDev board support.
10 *
11 * May be copied or modified under the terms of the GNU General Public
12 * License. See linux/COPYING for more information.
13 */
14#include <linux/init.h>
15#include <linux/ioport.h>
16#include <linux/io.h>
17#include <linux/err.h>
18#include <mach/microdev.h>
19
20#define SMSC_CONFIG_PORT_ADDR (0x3F0)
21#define SMSC_INDEX_PORT_ADDR SMSC_CONFIG_PORT_ADDR
22#define SMSC_DATA_PORT_ADDR (SMSC_INDEX_PORT_ADDR + 1)
23
24#define SMSC_ENTER_CONFIG_KEY 0x55
25#define SMSC_EXIT_CONFIG_KEY 0xaa
26
27#define SMCS_LOGICAL_DEV_INDEX 0x07 /* Logical Device Number */
28#define SMSC_DEVICE_ID_INDEX 0x20 /* Device ID */
29#define SMSC_DEVICE_REV_INDEX 0x21 /* Device Revision */
30#define SMSC_ACTIVATE_INDEX 0x30 /* Activate */
31#define SMSC_PRIMARY_BASE_INDEX 0x60 /* Primary Base Address */
32#define SMSC_SECONDARY_BASE_INDEX 0x62 /* Secondary Base Address */
33#define SMSC_PRIMARY_INT_INDEX 0x70 /* Primary Interrupt Select */
34#define SMSC_SECONDARY_INT_INDEX 0x72 /* Secondary Interrupt Select */
35#define SMSC_HDCS0_INDEX 0xf0 /* HDCS0 Address Decoder */
36#define SMSC_HDCS1_INDEX 0xf1 /* HDCS1 Address Decoder */
37
38#define SMSC_IDE1_DEVICE 1 /* IDE #1 logical device */
39#define SMSC_IDE2_DEVICE 2 /* IDE #2 logical device */
40#define SMSC_PARALLEL_DEVICE 3 /* Parallel Port logical device */
41#define SMSC_SERIAL1_DEVICE 4 /* Serial #1 logical device */
42#define SMSC_SERIAL2_DEVICE 5 /* Serial #2 logical device */
43#define SMSC_KEYBOARD_DEVICE 7 /* Keyboard logical device */
44#define SMSC_CONFIG_REGISTERS 8 /* Configuration Registers (Aux I/O) */
45
46#define SMSC_READ_INDEXED(index) ({ \
47 outb((index), SMSC_INDEX_PORT_ADDR); \
48 inb(SMSC_DATA_PORT_ADDR); })
49#define SMSC_WRITE_INDEXED(val, index) ({ \
50 outb((index), SMSC_INDEX_PORT_ADDR); \
51 outb((val), SMSC_DATA_PORT_ADDR); })
52
53#define IDE1_PRIMARY_BASE 0x01f0 /* Task File Registe base for IDE #1 */
54#define IDE1_SECONDARY_BASE 0x03f6 /* Miscellaneous AT registers for IDE #1 */
55#define IDE2_PRIMARY_BASE 0x0170 /* Task File Registe base for IDE #2 */
56#define IDE2_SECONDARY_BASE 0x0376 /* Miscellaneous AT registers for IDE #2 */
57
58#define SERIAL1_PRIMARY_BASE 0x03f8
59#define SERIAL2_PRIMARY_BASE 0x02f8
60
61#define MSB(x) ( (x) >> 8 )
62#define LSB(x) ( (x) & 0xff )
63
64 /* General-Purpose base address on CPU-board FPGA */
65#define MICRODEV_FPGA_GP_BASE 0xa6100000ul
66
67static int __init smsc_superio_setup(void)
68{
69
70 unsigned char devid, devrev;
71
72 /* Initially the chip is in run state */
73 /* Put it into configuration state */
74 outb(SMSC_ENTER_CONFIG_KEY, SMSC_CONFIG_PORT_ADDR);
75
76 /* Read device ID info */
77 devid = SMSC_READ_INDEXED(SMSC_DEVICE_ID_INDEX);
78 devrev = SMSC_READ_INDEXED(SMSC_DEVICE_REV_INDEX);
79
80 if ((devid == 0x30) && (devrev == 0x01))
81 printk("SMSC FDC37C93xAPM SuperIO device detected\n");
82 else
83 return -ENODEV;
84
85 /* Select the keyboard device */
86 SMSC_WRITE_INDEXED(SMSC_KEYBOARD_DEVICE, SMCS_LOGICAL_DEV_INDEX);
87 /* enable it */
88 SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
89 /* enable the interrupts */
90 SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_KEYBOARD, SMSC_PRIMARY_INT_INDEX);
91 SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_MOUSE, SMSC_SECONDARY_INT_INDEX);
92
93 /* Select the Serial #1 device */
94 SMSC_WRITE_INDEXED(SMSC_SERIAL1_DEVICE, SMCS_LOGICAL_DEV_INDEX);
95 /* enable it */
96 SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
97 /* program with port addresses */
98 SMSC_WRITE_INDEXED(MSB(SERIAL1_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+0);
99 SMSC_WRITE_INDEXED(LSB(SERIAL1_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+1);
100 SMSC_WRITE_INDEXED(0x00, SMSC_HDCS0_INDEX);
101 /* enable the interrupts */
102 SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_SERIAL1, SMSC_PRIMARY_INT_INDEX);
103
104 /* Select the Serial #2 device */
105 SMSC_WRITE_INDEXED(SMSC_SERIAL2_DEVICE, SMCS_LOGICAL_DEV_INDEX);
106 /* enable it */
107 SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
108 /* program with port addresses */
109 SMSC_WRITE_INDEXED(MSB(SERIAL2_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+0);
110 SMSC_WRITE_INDEXED(LSB(SERIAL2_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+1);
111 SMSC_WRITE_INDEXED(0x00, SMSC_HDCS0_INDEX);
112 /* enable the interrupts */
113 SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_SERIAL2, SMSC_PRIMARY_INT_INDEX);
114
115 /* Select the IDE#1 device */
116 SMSC_WRITE_INDEXED(SMSC_IDE1_DEVICE, SMCS_LOGICAL_DEV_INDEX);
117 /* enable it */
118 SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
119 /* program with port addresses */
120 SMSC_WRITE_INDEXED(MSB(IDE1_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+0);
121 SMSC_WRITE_INDEXED(LSB(IDE1_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+1);
122 SMSC_WRITE_INDEXED(MSB(IDE1_SECONDARY_BASE), SMSC_SECONDARY_BASE_INDEX+0);
123 SMSC_WRITE_INDEXED(LSB(IDE1_SECONDARY_BASE), SMSC_SECONDARY_BASE_INDEX+1);
124 SMSC_WRITE_INDEXED(0x0c, SMSC_HDCS0_INDEX);
125 SMSC_WRITE_INDEXED(0x00, SMSC_HDCS1_INDEX);
126 /* select the interrupt */
127 SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_IDE1, SMSC_PRIMARY_INT_INDEX);
128
129 /* Select the IDE#2 device */
130 SMSC_WRITE_INDEXED(SMSC_IDE2_DEVICE, SMCS_LOGICAL_DEV_INDEX);
131 /* enable it */
132 SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
133 /* program with port addresses */
134 SMSC_WRITE_INDEXED(MSB(IDE2_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+0);
135 SMSC_WRITE_INDEXED(LSB(IDE2_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+1);
136 SMSC_WRITE_INDEXED(MSB(IDE2_SECONDARY_BASE), SMSC_SECONDARY_BASE_INDEX+0);
137 SMSC_WRITE_INDEXED(LSB(IDE2_SECONDARY_BASE), SMSC_SECONDARY_BASE_INDEX+1);
138 /* select the interrupt */
139 SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_IDE2, SMSC_PRIMARY_INT_INDEX);
140
141 /* Select the configuration registers */
142 SMSC_WRITE_INDEXED(SMSC_CONFIG_REGISTERS, SMCS_LOGICAL_DEV_INDEX);
143 /* enable the appropriate GPIO pins for IDE functionality:
144 * bit[0] In/Out 1==input; 0==output
145 * bit[1] Polarity 1==invert; 0==no invert
146 * bit[2] Int Enb #1 1==Enable Combined IRQ #1; 0==disable
147 * bit[3:4] Function Select 00==original; 01==Alternate Function #1
148 */
149 SMSC_WRITE_INDEXED(0x00, 0xc2); /* GP42 = nIDE1_OE */
150 SMSC_WRITE_INDEXED(0x01, 0xc5); /* GP45 = IDE1_IRQ */
151 SMSC_WRITE_INDEXED(0x00, 0xc6); /* GP46 = nIOROP */
152 SMSC_WRITE_INDEXED(0x00, 0xc7); /* GP47 = nIOWOP */
153 SMSC_WRITE_INDEXED(0x08, 0xe8); /* GP20 = nIDE2_OE */
154
155 /* Exit the configuration state */
156 outb(SMSC_EXIT_CONFIG_KEY, SMSC_CONFIG_PORT_ADDR);
157
158 return 0;
159}
160device_initcall(smsc_superio_setup);
diff --git a/arch/sh/boards/mach-microdev/irq.c b/arch/sh/boards/mach-microdev/irq.c
index 702753cbd28f..b551963579c1 100644
--- a/arch/sh/boards/mach-microdev/irq.c
+++ b/arch/sh/boards/mach-microdev/irq.c
@@ -67,27 +67,13 @@ static const struct {
67 67
68static void enable_microdev_irq(unsigned int irq); 68static void enable_microdev_irq(unsigned int irq);
69static void disable_microdev_irq(unsigned int irq); 69static void disable_microdev_irq(unsigned int irq);
70
71 /* shutdown is same as "disable" */
72#define shutdown_microdev_irq disable_microdev_irq
73
74static void mask_and_ack_microdev(unsigned int); 70static void mask_and_ack_microdev(unsigned int);
75static void end_microdev_irq(unsigned int irq);
76
77static unsigned int startup_microdev_irq(unsigned int irq)
78{
79 enable_microdev_irq(irq);
80 return 0; /* never anything pending */
81}
82 71
83static struct hw_interrupt_type microdev_irq_type = { 72static struct irq_chip microdev_irq_type = {
84 .typename = "MicroDev-IRQ", 73 .name = "MicroDev-IRQ",
85 .startup = startup_microdev_irq, 74 .unmask = enable_microdev_irq,
86 .shutdown = shutdown_microdev_irq, 75 .mask = disable_microdev_irq,
87 .enable = enable_microdev_irq,
88 .disable = disable_microdev_irq,
89 .ack = mask_and_ack_microdev, 76 .ack = mask_and_ack_microdev,
90 .end = end_microdev_irq
91}; 77};
92 78
93static void disable_microdev_irq(unsigned int irq) 79static void disable_microdev_irq(unsigned int irq)
@@ -130,11 +116,11 @@ static void enable_microdev_irq(unsigned int irq)
130 ctrl_outl(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTENB_REG); 116 ctrl_outl(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTENB_REG);
131} 117}
132 118
133 /* This functions sets the desired irq handler to be a MicroDev type */ 119/* This function sets the desired irq handler to be a MicroDev type */
134static void __init make_microdev_irq(unsigned int irq) 120static void __init make_microdev_irq(unsigned int irq)
135{ 121{
136 disable_irq_nosync(irq); 122 disable_irq_nosync(irq);
137 irq_desc[irq].chip = &microdev_irq_type; 123 set_irq_chip_and_handler(irq, &microdev_irq_type, handle_level_irq);
138 disable_microdev_irq(irq); 124 disable_microdev_irq(irq);
139} 125}
140 126
@@ -143,17 +129,11 @@ static void mask_and_ack_microdev(unsigned int irq)
143 disable_microdev_irq(irq); 129 disable_microdev_irq(irq);
144} 130}
145 131
146static void end_microdev_irq(unsigned int irq)
147{
148 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
149 enable_microdev_irq(irq);
150}
151
152extern void __init init_microdev_irq(void) 132extern void __init init_microdev_irq(void)
153{ 133{
154 int i; 134 int i;
155 135
156 /* disable interrupts on the FPGA INTC register */ 136 /* disable interrupts on the FPGA INTC register */
157 ctrl_outl(~0ul, MICRODEV_FPGA_INTDSB_REG); 137 ctrl_outl(~0ul, MICRODEV_FPGA_INTDSB_REG);
158 138
159 for (i = 0; i < NUM_EXTERNAL_IRQS; i++) 139 for (i = 0; i < NUM_EXTERNAL_IRQS; i++)
@@ -179,5 +159,3 @@ extern void microdev_print_fpga_intc_status(void)
179 printk("FPGA_INTPRI[3..0] = %08x:%08x:%08x:%08x\n", *intprid, *intpric, *intprib, *intpria); 159 printk("FPGA_INTPRI[3..0] = %08x:%08x:%08x:%08x\n", *intprid, *intpric, *intprib, *intpria);
180 printk("-------------------------------------------------------------------------------\n"); 160 printk("-------------------------------------------------------------------------------\n");
181} 161}
182
183
diff --git a/arch/sh/boards/mach-microdev/led.c b/arch/sh/boards/mach-microdev/led.c
deleted file mode 100644
index 36e54b47a752..000000000000
--- a/arch/sh/boards/mach-microdev/led.c
+++ /dev/null
@@ -1,101 +0,0 @@
1/*
2 * linux/arch/sh/boards/superh/microdev/led.c
3 *
4 * Copyright (C) 2002 Stuart Menefy <stuart.menefy@st.com>
5 * Copyright (C) 2003 Richard Curnow (Richard.Curnow@superh.com)
6 *
7 * May be copied or modified under the terms of the GNU General Public
8 * License. See linux/COPYING for more information.
9 *
10 */
11
12#include <asm/io.h>
13
14#define LED_REGISTER 0xa6104d20
15
16static void mach_led_d9(int value)
17{
18 unsigned long reg;
19 reg = ctrl_inl(LED_REGISTER);
20 reg &= ~1;
21 reg |= (value & 1);
22 ctrl_outl(reg, LED_REGISTER);
23 return;
24}
25
26static void mach_led_d10(int value)
27{
28 unsigned long reg;
29 reg = ctrl_inl(LED_REGISTER);
30 reg &= ~2;
31 reg |= ((value & 1) << 1);
32 ctrl_outl(reg, LED_REGISTER);
33 return;
34}
35
36
37#ifdef CONFIG_HEARTBEAT
38#include <linux/sched.h>
39
40static unsigned char banner_table[] = {
41 0x11, 0x01, 0x11, 0x01, 0x11, 0x03,
42 0x11, 0x01, 0x11, 0x01, 0x13, 0x03,
43 0x11, 0x01, 0x13, 0x01, 0x13, 0x01, 0x11, 0x03,
44 0x11, 0x03,
45 0x11, 0x01, 0x13, 0x01, 0x11, 0x03,
46 0x11, 0x01, 0x11, 0x01, 0x11, 0x01, 0x11, 0x07,
47 0x13, 0x01, 0x13, 0x03,
48 0x11, 0x01, 0x11, 0x03,
49 0x13, 0x01, 0x11, 0x01, 0x13, 0x01, 0x11, 0x03,
50 0x11, 0x01, 0x13, 0x01, 0x11, 0x03,
51 0x13, 0x01, 0x13, 0x01, 0x13, 0x03,
52 0x13, 0x01, 0x11, 0x01, 0x11, 0x03,
53 0x11, 0x03,
54 0x11, 0x01, 0x11, 0x01, 0x11, 0x01, 0x13, 0x07,
55 0xff
56};
57
58static void banner(void)
59{
60 static int pos = 0;
61 static int count = 0;
62
63 if (count) {
64 count--;
65 } else {
66 int val = banner_table[pos];
67 if (val == 0xff) {
68 pos = 0;
69 val = banner_table[pos];
70 }
71 pos++;
72 mach_led_d10((val >> 4) & 1);
73 count = 10 * (val & 0xf);
74 }
75}
76
77/* From heartbeat_harp in the stboards directory */
78/* acts like an actual heart beat -- ie thump-thump-pause... */
79void microdev_heartbeat(void)
80{
81 static unsigned cnt = 0, period = 0, dist = 0;
82
83 if (cnt == 0 || cnt == dist)
84 mach_led_d9(1);
85 else if (cnt == 7 || cnt == dist+7)
86 mach_led_d9(0);
87
88 if (++cnt > period) {
89 cnt = 0;
90 /* The hyperbolic function below modifies the heartbeat period
91 * length in dependency of the current (5min) load. It goes
92 * through the points f(0)=126, f(1)=86, f(5)=51,
93 * f(inf)->30. */
94 period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30;
95 dist = period / 4;
96 }
97
98 banner();
99}
100
101#endif
diff --git a/arch/sh/boards/mach-microdev/setup.c b/arch/sh/boards/mach-microdev/setup.c
index a9202fe3cb59..d1df2a4fb9b8 100644
--- a/arch/sh/boards/mach-microdev/setup.c
+++ b/arch/sh/boards/mach-microdev/setup.c
@@ -17,70 +17,12 @@
17#include <mach/microdev.h> 17#include <mach/microdev.h>
18#include <asm/io.h> 18#include <asm/io.h>
19#include <asm/machvec.h> 19#include <asm/machvec.h>
20 20#include <asm/sizes.h>
21extern void microdev_heartbeat(void);
22
23
24/****************************************************************************/
25
26
27 /*
28 * Setup for the SMSC FDC37C93xAPM
29 */
30#define SMSC_CONFIG_PORT_ADDR (0x3F0)
31#define SMSC_INDEX_PORT_ADDR SMSC_CONFIG_PORT_ADDR
32#define SMSC_DATA_PORT_ADDR (SMSC_INDEX_PORT_ADDR + 1)
33
34#define SMSC_ENTER_CONFIG_KEY 0x55
35#define SMSC_EXIT_CONFIG_KEY 0xaa
36
37#define SMCS_LOGICAL_DEV_INDEX 0x07 /* Logical Device Number */
38#define SMSC_DEVICE_ID_INDEX 0x20 /* Device ID */
39#define SMSC_DEVICE_REV_INDEX 0x21 /* Device Revision */
40#define SMSC_ACTIVATE_INDEX 0x30 /* Activate */
41#define SMSC_PRIMARY_BASE_INDEX 0x60 /* Primary Base Address */
42#define SMSC_SECONDARY_BASE_INDEX 0x62 /* Secondary Base Address */
43#define SMSC_PRIMARY_INT_INDEX 0x70 /* Primary Interrupt Select */
44#define SMSC_SECONDARY_INT_INDEX 0x72 /* Secondary Interrupt Select */
45#define SMSC_HDCS0_INDEX 0xf0 /* HDCS0 Address Decoder */
46#define SMSC_HDCS1_INDEX 0xf1 /* HDCS1 Address Decoder */
47
48#define SMSC_IDE1_DEVICE 1 /* IDE #1 logical device */
49#define SMSC_IDE2_DEVICE 2 /* IDE #2 logical device */
50#define SMSC_PARALLEL_DEVICE 3 /* Parallel Port logical device */
51#define SMSC_SERIAL1_DEVICE 4 /* Serial #1 logical device */
52#define SMSC_SERIAL2_DEVICE 5 /* Serial #2 logical device */
53#define SMSC_KEYBOARD_DEVICE 7 /* Keyboard logical device */
54#define SMSC_CONFIG_REGISTERS 8 /* Configuration Registers (Aux I/O) */
55
56#define SMSC_READ_INDEXED(index) ({ \
57 outb((index), SMSC_INDEX_PORT_ADDR); \
58 inb(SMSC_DATA_PORT_ADDR); })
59#define SMSC_WRITE_INDEXED(val, index) ({ \
60 outb((index), SMSC_INDEX_PORT_ADDR); \
61 outb((val), SMSC_DATA_PORT_ADDR); })
62
63#define IDE1_PRIMARY_BASE 0x01f0 /* Task File Registe base for IDE #1 */
64#define IDE1_SECONDARY_BASE 0x03f6 /* Miscellaneous AT registers for IDE #1 */
65#define IDE2_PRIMARY_BASE 0x0170 /* Task File Registe base for IDE #2 */
66#define IDE2_SECONDARY_BASE 0x0376 /* Miscellaneous AT registers for IDE #2 */
67
68#define SERIAL1_PRIMARY_BASE 0x03f8
69#define SERIAL2_PRIMARY_BASE 0x02f8
70
71#define MSB(x) ( (x) >> 8 )
72#define LSB(x) ( (x) & 0xff )
73
74 /* General-Purpose base address on CPU-board FPGA */
75#define MICRODEV_FPGA_GP_BASE 0xa6100000ul
76
77 /* assume a Keyboard Controller is present */
78int microdev_kbd_controller_present = 1;
79 21
80static struct resource smc91x_resources[] = { 22static struct resource smc91x_resources[] = {
81 [0] = { 23 [0] = {
82 .start = 0x300, 24 .start = 0x300,
83 .end = 0x300 + 0x0001000 - 1, 25 .end = 0x300 + SZ_4K - 1,
84 .flags = IORESOURCE_MEM, 26 .flags = IORESOURCE_MEM,
85 }, 27 },
86 [1] = { 28 [1] = {
@@ -97,7 +39,6 @@ static struct platform_device smc91x_device = {
97 .resource = smc91x_resources, 39 .resource = smc91x_resources,
98}; 40};
99 41
100#ifdef CONFIG_FB_S1D13XXX
101static struct s1d13xxxfb_regval s1d13806_initregs[] = { 42static struct s1d13xxxfb_regval s1d13806_initregs[] = {
102 { S1DREG_MISC, 0x00 }, 43 { S1DREG_MISC, 0x00 },
103 { S1DREG_COM_DISP_MODE, 0x00 }, 44 { S1DREG_COM_DISP_MODE, 0x00 },
@@ -216,12 +157,12 @@ static struct s1d13xxxfb_pdata s1d13806_platform_data = {
216static struct resource s1d13806_resources[] = { 157static struct resource s1d13806_resources[] = {
217 [0] = { 158 [0] = {
218 .start = 0x07200000, 159 .start = 0x07200000,
219 .end = 0x07200000 + 0x00200000 - 1, 160 .end = 0x07200000 + SZ_2M - 1,
220 .flags = IORESOURCE_MEM, 161 .flags = IORESOURCE_MEM,
221 }, 162 },
222 [1] = { 163 [1] = {
223 .start = 0x07000000, 164 .start = 0x07000000,
224 .end = 0x07000000 + 0x00200000 - 1, 165 .end = 0x07000000 + SZ_2M - 1,
225 .flags = IORESOURCE_MEM, 166 .flags = IORESOURCE_MEM,
226 }, 167 },
227}; 168};
@@ -236,145 +177,24 @@ static struct platform_device s1d13806_device = {
236 .platform_data = &s1d13806_platform_data, 177 .platform_data = &s1d13806_platform_data,
237 }, 178 },
238}; 179};
239#endif
240 180
241static struct platform_device *microdev_devices[] __initdata = { 181static struct platform_device *microdev_devices[] __initdata = {
242 &smc91x_device, 182 &smc91x_device,
243#ifdef CONFIG_FB_S1D13XXX
244 &s1d13806_device, 183 &s1d13806_device,
245#endif
246}; 184};
247 185
248static int __init microdev_devices_setup(void) 186static int __init microdev_devices_setup(void)
249{ 187{
250 return platform_add_devices(microdev_devices, ARRAY_SIZE(microdev_devices)); 188 return platform_add_devices(microdev_devices, ARRAY_SIZE(microdev_devices));
251} 189}
252 190device_initcall(microdev_devices_setup);
253/*
254 * Setup for the SMSC FDC37C93xAPM
255 */
256static int __init smsc_superio_setup(void)
257{
258
259 unsigned char devid, devrev;
260
261 /* Initially the chip is in run state */
262 /* Put it into configuration state */
263 outb(SMSC_ENTER_CONFIG_KEY, SMSC_CONFIG_PORT_ADDR);
264
265 /* Read device ID info */
266 devid = SMSC_READ_INDEXED(SMSC_DEVICE_ID_INDEX);
267 devrev = SMSC_READ_INDEXED(SMSC_DEVICE_REV_INDEX);
268 if ( (devid==0x30) && (devrev==0x01) )
269 {
270 printk("SMSC FDC37C93xAPM SuperIO device detected\n");
271 }
272 else
273 { /* not the device identity we expected */
274 printk("Not detected a SMSC FDC37C93xAPM SuperIO device (devid=0x%02x, rev=0x%02x)\n",
275 devid, devrev);
276 /* inform the keyboard driver that we have no keyboard controller */
277 microdev_kbd_controller_present = 0;
278 /* little point in doing anything else in this functon */
279 return 0;
280 }
281
282 /* Select the keyboard device */
283 SMSC_WRITE_INDEXED(SMSC_KEYBOARD_DEVICE, SMCS_LOGICAL_DEV_INDEX);
284 /* enable it */
285 SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
286 /* enable the interrupts */
287 SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_KEYBOARD, SMSC_PRIMARY_INT_INDEX);
288 SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_MOUSE, SMSC_SECONDARY_INT_INDEX);
289
290 /* Select the Serial #1 device */
291 SMSC_WRITE_INDEXED(SMSC_SERIAL1_DEVICE, SMCS_LOGICAL_DEV_INDEX);
292 /* enable it */
293 SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
294 /* program with port addresses */
295 SMSC_WRITE_INDEXED(MSB(SERIAL1_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+0);
296 SMSC_WRITE_INDEXED(LSB(SERIAL1_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+1);
297 SMSC_WRITE_INDEXED(0x00, SMSC_HDCS0_INDEX);
298 /* enable the interrupts */
299 SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_SERIAL1, SMSC_PRIMARY_INT_INDEX);
300
301 /* Select the Serial #2 device */
302 SMSC_WRITE_INDEXED(SMSC_SERIAL2_DEVICE, SMCS_LOGICAL_DEV_INDEX);
303 /* enable it */
304 SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
305 /* program with port addresses */
306 SMSC_WRITE_INDEXED(MSB(SERIAL2_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+0);
307 SMSC_WRITE_INDEXED(LSB(SERIAL2_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+1);
308 SMSC_WRITE_INDEXED(0x00, SMSC_HDCS0_INDEX);
309 /* enable the interrupts */
310 SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_SERIAL2, SMSC_PRIMARY_INT_INDEX);
311
312 /* Select the IDE#1 device */
313 SMSC_WRITE_INDEXED(SMSC_IDE1_DEVICE, SMCS_LOGICAL_DEV_INDEX);
314 /* enable it */
315 SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
316 /* program with port addresses */
317 SMSC_WRITE_INDEXED(MSB(IDE1_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+0);
318 SMSC_WRITE_INDEXED(LSB(IDE1_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+1);
319 SMSC_WRITE_INDEXED(MSB(IDE1_SECONDARY_BASE), SMSC_SECONDARY_BASE_INDEX+0);
320 SMSC_WRITE_INDEXED(LSB(IDE1_SECONDARY_BASE), SMSC_SECONDARY_BASE_INDEX+1);
321 SMSC_WRITE_INDEXED(0x0c, SMSC_HDCS0_INDEX);
322 SMSC_WRITE_INDEXED(0x00, SMSC_HDCS1_INDEX);
323 /* select the interrupt */
324 SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_IDE1, SMSC_PRIMARY_INT_INDEX);
325
326 /* Select the IDE#2 device */
327 SMSC_WRITE_INDEXED(SMSC_IDE2_DEVICE, SMCS_LOGICAL_DEV_INDEX);
328 /* enable it */
329 SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
330 /* program with port addresses */
331 SMSC_WRITE_INDEXED(MSB(IDE2_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+0);
332 SMSC_WRITE_INDEXED(LSB(IDE2_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+1);
333 SMSC_WRITE_INDEXED(MSB(IDE2_SECONDARY_BASE), SMSC_SECONDARY_BASE_INDEX+0);
334 SMSC_WRITE_INDEXED(LSB(IDE2_SECONDARY_BASE), SMSC_SECONDARY_BASE_INDEX+1);
335 /* select the interrupt */
336 SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_IDE2, SMSC_PRIMARY_INT_INDEX);
337
338 /* Select the configuration registers */
339 SMSC_WRITE_INDEXED(SMSC_CONFIG_REGISTERS, SMCS_LOGICAL_DEV_INDEX);
340 /* enable the appropriate GPIO pins for IDE functionality:
341 * bit[0] In/Out 1==input; 0==output
342 * bit[1] Polarity 1==invert; 0==no invert
343 * bit[2] Int Enb #1 1==Enable Combined IRQ #1; 0==disable
344 * bit[3:4] Function Select 00==original; 01==Alternate Function #1
345 */
346 SMSC_WRITE_INDEXED(0x00, 0xc2); /* GP42 = nIDE1_OE */
347 SMSC_WRITE_INDEXED(0x01, 0xc5); /* GP45 = IDE1_IRQ */
348 SMSC_WRITE_INDEXED(0x00, 0xc6); /* GP46 = nIOROP */
349 SMSC_WRITE_INDEXED(0x00, 0xc7); /* GP47 = nIOWOP */
350 SMSC_WRITE_INDEXED(0x08, 0xe8); /* GP20 = nIDE2_OE */
351
352 /* Exit the configuration state */
353 outb(SMSC_EXIT_CONFIG_KEY, SMSC_CONFIG_PORT_ADDR);
354
355 return 0;
356}
357
358static void __init microdev_setup(char **cmdline_p)
359{
360 int * const fpgaRevisionRegister = (int*)(MICRODEV_FPGA_GP_BASE + 0x8ul);
361 const int fpgaRevision = *fpgaRevisionRegister;
362 int * const CacheControlRegister = (int*)CCR;
363
364 device_initcall(microdev_devices_setup);
365 device_initcall(smsc_superio_setup);
366
367 printk("SuperH %s board (FPGA rev: 0x%0x, CCR: 0x%0x)\n",
368 get_system_type(), fpgaRevision, *CacheControlRegister);
369}
370 191
371/* 192/*
372 * The Machine Vector 193 * The Machine Vector
373 */ 194 */
374static struct sh_machine_vector mv_sh4202_microdev __initmv = { 195static struct sh_machine_vector mv_sh4202_microdev __initmv = {
375 .mv_name = "SH4-202 MicroDev", 196 .mv_name = "SH4-202 MicroDev",
376 .mv_setup = microdev_setup, 197 .mv_nr_irqs = 72,
377 .mv_nr_irqs = 72, /* QQQ need to check this - use the MACRO */
378 198
379 .mv_inb = microdev_inb, 199 .mv_inb = microdev_inb,
380 .mv_inw = microdev_inw, 200 .mv_inw = microdev_inw,
@@ -398,8 +218,4 @@ static struct sh_machine_vector mv_sh4202_microdev __initmv = {
398 .mv_outsl = microdev_outsl, 218 .mv_outsl = microdev_outsl,
399 219
400 .mv_init_irq = init_microdev_irq, 220 .mv_init_irq = init_microdev_irq,
401
402#ifdef CONFIG_HEARTBEAT
403 .mv_heartbeat = microdev_heartbeat,
404#endif
405}; 221};
diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c
index 975281980299..cc1408119c24 100644
--- a/arch/sh/boards/mach-migor/setup.c
+++ b/arch/sh/boards/mach-migor/setup.c
@@ -89,6 +89,7 @@ static struct resource sh_keysc_resources[] = {
89 89
90static struct platform_device sh_keysc_device = { 90static struct platform_device sh_keysc_device = {
91 .name = "sh_keysc", 91 .name = "sh_keysc",
92 .id = 0, /* "keysc0" clock */
92 .num_resources = ARRAY_SIZE(sh_keysc_resources), 93 .num_resources = ARRAY_SIZE(sh_keysc_resources),
93 .resource = sh_keysc_resources, 94 .resource = sh_keysc_resources,
94 .dev = { 95 .dev = {
@@ -261,6 +262,8 @@ static struct sh_mobile_lcdc_info sh_mobile_lcdc_info = {
261 .sys_bus_cfg = { 262 .sys_bus_cfg = {
262 .ldmt2r = 0x06000a09, 263 .ldmt2r = 0x06000a09,
263 .ldmt3r = 0x180e3418, 264 .ldmt3r = 0x180e3418,
265 /* set 1s delay to encourage fsync() */
266 .deferred_io_msec = 1000,
264 }, 267 },
265 } 268 }
266#endif 269#endif
@@ -273,6 +276,10 @@ static struct resource migor_lcdc_resources[] = {
273 .end = 0xfe941fff, 276 .end = 0xfe941fff,
274 .flags = IORESOURCE_MEM, 277 .flags = IORESOURCE_MEM,
275 }, 278 },
279 [1] = {
280 .start = 28,
281 .flags = IORESOURCE_IRQ,
282 },
276}; 283};
277 284
278static struct platform_device migor_lcdc_device = { 285static struct platform_device migor_lcdc_device = {
@@ -300,6 +307,7 @@ static void camera_power_on(void)
300 gpio_set_value(GPIO_PTT3, 0); 307 gpio_set_value(GPIO_PTT3, 0);
301 mdelay(10); 308 mdelay(10);
302 gpio_set_value(GPIO_PTT3, 1); 309 gpio_set_value(GPIO_PTT3, 1);
310 mdelay(10); /* wait to let chip come out of reset */
303} 311}
304 312
305static void camera_power_off(void) 313static void camera_power_off(void)
@@ -432,6 +440,7 @@ static struct resource migor_ceu_resources[] = {
432 440
433static struct platform_device migor_ceu_device = { 441static struct platform_device migor_ceu_device = {
434 .name = "sh_mobile_ceu", 442 .name = "sh_mobile_ceu",
443 .id = 0, /* "ceu0" clock */
435 .num_resources = ARRAY_SIZE(migor_ceu_resources), 444 .num_resources = ARRAY_SIZE(migor_ceu_resources),
436 .resource = migor_ceu_resources, 445 .resource = migor_ceu_resources,
437 .dev = { 446 .dev = {
@@ -479,7 +488,6 @@ static int __init migor_devices_setup(void)
479 ctrl_outl(0x00110080, BSC_CS4WCR); 488 ctrl_outl(0x00110080, BSC_CS4WCR);
480 489
481 /* KEYSC */ 490 /* KEYSC */
482 clk_always_enable("mstp214"); /* KEYSC */
483 gpio_request(GPIO_FN_KEYOUT0, NULL); 491 gpio_request(GPIO_FN_KEYOUT0, NULL);
484 gpio_request(GPIO_FN_KEYOUT1, NULL); 492 gpio_request(GPIO_FN_KEYOUT1, NULL);
485 gpio_request(GPIO_FN_KEYOUT2, NULL); 493 gpio_request(GPIO_FN_KEYOUT2, NULL);
@@ -501,7 +509,6 @@ static int __init migor_devices_setup(void)
501 gpio_request(GPIO_FN_IRQ6, NULL); 509 gpio_request(GPIO_FN_IRQ6, NULL);
502 510
503 /* LCD Panel */ 511 /* LCD Panel */
504 clk_always_enable("mstp200"); /* LCDC */
505#ifdef CONFIG_SH_MIGOR_QVGA /* LCDC - QVGA - Enable SYS Interface signals */ 512#ifdef CONFIG_SH_MIGOR_QVGA /* LCDC - QVGA - Enable SYS Interface signals */
506 gpio_request(GPIO_FN_LCDD17, NULL); 513 gpio_request(GPIO_FN_LCDD17, NULL);
507 gpio_request(GPIO_FN_LCDD16, NULL); 514 gpio_request(GPIO_FN_LCDD16, NULL);
@@ -554,7 +561,6 @@ static int __init migor_devices_setup(void)
554#endif 561#endif
555 562
556 /* CEU */ 563 /* CEU */
557 clk_always_enable("mstp203"); /* CEU */
558 gpio_request(GPIO_FN_VIO_CLK2, NULL); 564 gpio_request(GPIO_FN_VIO_CLK2, NULL);
559 gpio_request(GPIO_FN_VIO_VD2, NULL); 565 gpio_request(GPIO_FN_VIO_VD2, NULL);
560 gpio_request(GPIO_FN_VIO_HD2, NULL); 566 gpio_request(GPIO_FN_VIO_HD2, NULL);
@@ -589,12 +595,3 @@ static int __init migor_devices_setup(void)
589 return platform_add_devices(migor_devices, ARRAY_SIZE(migor_devices)); 595 return platform_add_devices(migor_devices, ARRAY_SIZE(migor_devices));
590} 596}
591__initcall(migor_devices_setup); 597__initcall(migor_devices_setup);
592
593static void __init migor_setup(char **cmdline_p)
594{
595}
596
597static struct sh_machine_vector mv_migor __initmv = {
598 .mv_name = "Migo-R",
599 .mv_setup = migor_setup,
600};
diff --git a/arch/sh/boards/mach-rsk/Kconfig b/arch/sh/boards/mach-rsk/Kconfig
new file mode 100644
index 000000000000..bff095dffc02
--- /dev/null
+++ b/arch/sh/boards/mach-rsk/Kconfig
@@ -0,0 +1,18 @@
1if SH_RSK
2
3choice
4 prompt "RSK+ options"
5 default SH_RSK7203
6
7config SH_RSK7201
8 bool "RSK7201"
9 depends on CPU_SUBTYPE_SH7201
10
11config SH_RSK7203
12 bool "RSK7203"
13 select GENERIC_GPIO
14 depends on CPU_SUBTYPE_SH7203
15
16endchoice
17
18endif
diff --git a/arch/sh/boards/mach-rsk/Makefile b/arch/sh/boards/mach-rsk/Makefile
new file mode 100644
index 000000000000..498da75ce38b
--- /dev/null
+++ b/arch/sh/boards/mach-rsk/Makefile
@@ -0,0 +1,2 @@
1obj-y := setup.o
2obj-$(CONFIG_SH_RSK7203) += devices-rsk7203.o
diff --git a/arch/sh/boards/board-rsk7203.c b/arch/sh/boards/mach-rsk/devices-rsk7203.c
index 58266f06134a..73f743b9be8d 100644
--- a/arch/sh/boards/board-rsk7203.c
+++ b/arch/sh/boards/mach-rsk/devices-rsk7203.c
@@ -50,73 +50,6 @@ static struct platform_device smc911x_device = {
50 }, 50 },
51}; 51};
52 52
53static const char *probes[] = { "cmdlinepart", NULL };
54
55static struct mtd_partition *parsed_partitions;
56
57static struct mtd_partition rsk7203_partitions[] = {
58 {
59 .name = "Bootloader",
60 .offset = 0x00000000,
61 .size = 0x00040000,
62 .mask_flags = MTD_WRITEABLE,
63 }, {
64 .name = "Kernel",
65 .offset = MTDPART_OFS_NXTBLK,
66 .size = 0x001c0000,
67 }, {
68 .name = "Flash_FS",
69 .offset = MTDPART_OFS_NXTBLK,
70 .size = MTDPART_SIZ_FULL,
71 }
72};
73
74static struct physmap_flash_data flash_data = {
75 .width = 2,
76};
77
78static struct resource flash_resource = {
79 .start = 0x20000000,
80 .end = 0x20400000,
81 .flags = IORESOURCE_MEM,
82};
83
84static struct platform_device flash_device = {
85 .name = "physmap-flash",
86 .id = -1,
87 .resource = &flash_resource,
88 .num_resources = 1,
89 .dev = {
90 .platform_data = &flash_data,
91 },
92};
93
94static struct mtd_info *flash_mtd;
95
96static struct map_info rsk7203_flash_map = {
97 .name = "RSK+ Flash",
98 .size = 0x400000,
99 .bankwidth = 2,
100};
101
102static void __init set_mtd_partitions(void)
103{
104 int nr_parts = 0;
105
106 simple_map_init(&rsk7203_flash_map);
107 flash_mtd = do_map_probe("cfi_probe", &rsk7203_flash_map);
108 nr_parts = parse_mtd_partitions(flash_mtd, probes,
109 &parsed_partitions, 0);
110 /* If there is no partition table, used the hard coded table */
111 if (nr_parts <= 0) {
112 flash_data.parts = rsk7203_partitions;
113 flash_data.nr_parts = ARRAY_SIZE(rsk7203_partitions);
114 } else {
115 flash_data.nr_parts = nr_parts;
116 flash_data.parts = parsed_partitions;
117 }
118}
119
120static struct gpio_led rsk7203_gpio_leds[] = { 53static struct gpio_led rsk7203_gpio_leds[] = {
121 { 54 {
122 .name = "green", 55 .name = "green",
@@ -155,7 +88,6 @@ static struct platform_device led_device = {
155 88
156static struct platform_device *rsk7203_devices[] __initdata = { 89static struct platform_device *rsk7203_devices[] __initdata = {
157 &smc911x_device, 90 &smc911x_device,
158 &flash_device,
159 &led_device, 91 &led_device,
160}; 92};
161 93
@@ -165,15 +97,7 @@ static int __init rsk7203_devices_setup(void)
165 gpio_request(GPIO_FN_TXD0, NULL); 97 gpio_request(GPIO_FN_TXD0, NULL);
166 gpio_request(GPIO_FN_RXD0, NULL); 98 gpio_request(GPIO_FN_RXD0, NULL);
167 99
168 set_mtd_partitions();
169 return platform_add_devices(rsk7203_devices, 100 return platform_add_devices(rsk7203_devices,
170 ARRAY_SIZE(rsk7203_devices)); 101 ARRAY_SIZE(rsk7203_devices));
171} 102}
172device_initcall(rsk7203_devices_setup); 103device_initcall(rsk7203_devices_setup);
173
174/*
175 * The Machine Vector
176 */
177static struct sh_machine_vector mv_rsk7203 __initmv = {
178 .mv_name = "RSK+7203",
179};
diff --git a/arch/sh/boards/mach-rsk/setup.c b/arch/sh/boards/mach-rsk/setup.c
new file mode 100644
index 000000000000..af64d030a5c7
--- /dev/null
+++ b/arch/sh/boards/mach-rsk/setup.c
@@ -0,0 +1,106 @@
1/*
2 * Renesas Technology Europe RSK+ Support.
3 *
4 * Copyright (C) 2008 Paul Mundt
5 * Copyright (C) 2008 Peter Griffin <pgriffin@mpc-data.co.uk>
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details.
10 */
11#include <linux/init.h>
12#include <linux/types.h>
13#include <linux/platform_device.h>
14#include <linux/interrupt.h>
15#include <linux/mtd/mtd.h>
16#include <linux/mtd/partitions.h>
17#include <linux/mtd/physmap.h>
18#include <linux/mtd/map.h>
19#include <asm/machvec.h>
20#include <asm/io.h>
21
22static const char *probes[] = { "cmdlinepart", NULL };
23
24static struct mtd_partition *parsed_partitions;
25
26static struct mtd_partition rsk_partitions[] = {
27 {
28 .name = "Bootloader",
29 .offset = 0x00000000,
30 .size = 0x00040000,
31 .mask_flags = MTD_WRITEABLE,
32 }, {
33 .name = "Kernel",
34 .offset = MTDPART_OFS_NXTBLK,
35 .size = 0x001c0000,
36 }, {
37 .name = "Flash_FS",
38 .offset = MTDPART_OFS_NXTBLK,
39 .size = MTDPART_SIZ_FULL,
40 }
41};
42
43static struct physmap_flash_data flash_data = {
44 .width = 2,
45};
46
47static struct resource flash_resource = {
48 .start = 0x20000000,
49 .end = 0x20400000,
50 .flags = IORESOURCE_MEM,
51};
52
53static struct platform_device flash_device = {
54 .name = "physmap-flash",
55 .id = -1,
56 .resource = &flash_resource,
57 .num_resources = 1,
58 .dev = {
59 .platform_data = &flash_data,
60 },
61};
62
63static struct mtd_info *flash_mtd;
64
65static struct map_info rsk_flash_map = {
66 .name = "RSK+ Flash",
67 .size = 0x400000,
68 .bankwidth = 2,
69};
70
71static void __init set_mtd_partitions(void)
72{
73 int nr_parts = 0;
74
75 simple_map_init(&rsk_flash_map);
76 flash_mtd = do_map_probe("cfi_probe", &rsk_flash_map);
77 nr_parts = parse_mtd_partitions(flash_mtd, probes,
78 &parsed_partitions, 0);
79 /* If there is no partition table, used the hard coded table */
80 if (nr_parts <= 0) {
81 flash_data.parts = rsk_partitions;
82 flash_data.nr_parts = ARRAY_SIZE(rsk_partitions);
83 } else {
84 flash_data.nr_parts = nr_parts;
85 flash_data.parts = parsed_partitions;
86 }
87}
88
89static struct platform_device *rsk_devices[] __initdata = {
90 &flash_device,
91};
92
93static int __init rsk_devices_setup(void)
94{
95 set_mtd_partitions();
96 return platform_add_devices(rsk_devices,
97 ARRAY_SIZE(rsk_devices));
98}
99device_initcall(rsk_devices_setup);
100
101/*
102 * The Machine Vector
103 */
104static struct sh_machine_vector mv_rsk __initmv = {
105 .mv_name = "RSK+",
106};
diff --git a/arch/sh/boards/mach-se/7343/Makefile b/arch/sh/boards/mach-se/7343/Makefile
index 3024796c6203..4c3666a93790 100644
--- a/arch/sh/boards/mach-se/7343/Makefile
+++ b/arch/sh/boards/mach-se/7343/Makefile
@@ -2,4 +2,4 @@
2# Makefile for the 7343 SolutionEngine specific parts of the kernel 2# Makefile for the 7343 SolutionEngine specific parts of the kernel
3# 3#
4 4
5obj-y := setup.o io.o irq.o 5obj-y := setup.o irq.o
diff --git a/arch/sh/boards/mach-se/7343/io.c b/arch/sh/boards/mach-se/7343/io.c
deleted file mode 100644
index 8741abc1da7b..000000000000
--- a/arch/sh/boards/mach-se/7343/io.c
+++ /dev/null
@@ -1,273 +0,0 @@
1/*
2 * arch/sh/boards/se/7343/io.c
3 *
4 * I/O routine for SH-Mobile3AS 7343 SolutionEngine.
5 *
6 */
7#include <linux/kernel.h>
8#include <asm/io.h>
9#include <mach-se/mach/se7343.h>
10
11#define badio(fn, a) panic("bad i/o operation %s for %08lx.", #fn, a)
12
13struct iop {
14 unsigned long start, end;
15 unsigned long base;
16 struct iop *(*check) (struct iop * p, unsigned long port);
17 unsigned char (*inb) (struct iop * p, unsigned long port);
18 unsigned short (*inw) (struct iop * p, unsigned long port);
19 void (*outb) (struct iop * p, unsigned char value, unsigned long port);
20 void (*outw) (struct iop * p, unsigned short value, unsigned long port);
21};
22
23struct iop *
24simple_check(struct iop *p, unsigned long port)
25{
26 static int count;
27
28 if (count < 100)
29 count++;
30
31 port &= 0xFFFF;
32
33 if ((p->start <= port) && (port <= p->end))
34 return p;
35 else
36 badio(check, port);
37}
38
39struct iop *
40ide_check(struct iop *p, unsigned long port)
41{
42 if (((0x1f0 <= port) && (port <= 0x1f7)) || (port == 0x3f7))
43 return p;
44 return NULL;
45}
46
47unsigned char
48simple_inb(struct iop *p, unsigned long port)
49{
50 return *(unsigned char *) (p->base + port);
51}
52
53unsigned short
54simple_inw(struct iop *p, unsigned long port)
55{
56 return *(unsigned short *) (p->base + port);
57}
58
59void
60simple_outb(struct iop *p, unsigned char value, unsigned long port)
61{
62 *(unsigned char *) (p->base + port) = value;
63}
64
65void
66simple_outw(struct iop *p, unsigned short value, unsigned long port)
67{
68 *(unsigned short *) (p->base + port) = value;
69}
70
71unsigned char
72pcc_inb(struct iop *p, unsigned long port)
73{
74 unsigned long addr = p->base + port + 0x40000;
75 unsigned long v;
76
77 if (port & 1)
78 addr += 0x00400000;
79 v = *(volatile unsigned char *) addr;
80 return v;
81}
82
83void
84pcc_outb(struct iop *p, unsigned char value, unsigned long port)
85{
86 unsigned long addr = p->base + port + 0x40000;
87
88 if (port & 1)
89 addr += 0x00400000;
90 *(volatile unsigned char *) addr = value;
91}
92
93unsigned char
94bad_inb(struct iop *p, unsigned long port)
95{
96 badio(inb, port);
97}
98
99void
100bad_outb(struct iop *p, unsigned char value, unsigned long port)
101{
102 badio(inw, port);
103}
104
105#ifdef CONFIG_SMC91X
106/* MSTLANEX01 LAN at 0xb400:0000 */
107static struct iop laniop = {
108 .start = 0x00,
109 .end = 0x0F,
110 .base = 0x04000000,
111 .check = simple_check,
112 .inb = simple_inb,
113 .inw = simple_inw,
114 .outb = simple_outb,
115 .outw = simple_outw,
116};
117#endif
118
119#ifdef CONFIG_NE2000
120/* NE2000 pc card NIC */
121static struct iop neiop = {
122 .start = 0x280,
123 .end = 0x29f,
124 .base = 0xb0600000 + 0x80, /* soft 0x280 -> hard 0x300 */
125 .check = simple_check,
126 .inb = pcc_inb,
127 .inw = simple_inw,
128 .outb = pcc_outb,
129 .outw = simple_outw,
130};
131#endif
132
133#ifdef CONFIG_IDE
134/* CF in CF slot */
135static struct iop cfiop = {
136 .base = 0xb0600000,
137 .check = ide_check,
138 .inb = pcc_inb,
139 .inw = simple_inw,
140 .outb = pcc_outb,
141 .outw = simple_outw,
142};
143#endif
144
145static __inline__ struct iop *
146port2iop(unsigned long port)
147{
148 if (0) ;
149#if defined(CONFIG_SMC91X)
150 else if (laniop.check(&laniop, port))
151 return &laniop;
152#endif
153#if defined(CONFIG_NE2000)
154 else if (neiop.check(&neiop, port))
155 return &neiop;
156#endif
157#if defined(CONFIG_IDE)
158 else if (cfiop.check(&cfiop, port))
159 return &cfiop;
160#endif
161 else
162 return NULL;
163}
164
165static inline void
166delay(void)
167{
168 ctrl_inw(0xac000000);
169 ctrl_inw(0xac000000);
170}
171
172unsigned char
173sh7343se_inb(unsigned long port)
174{
175 struct iop *p = port2iop(port);
176 return (p->inb) (p, port);
177}
178
179unsigned char
180sh7343se_inb_p(unsigned long port)
181{
182 unsigned char v = sh7343se_inb(port);
183 delay();
184 return v;
185}
186
187unsigned short
188sh7343se_inw(unsigned long port)
189{
190 struct iop *p = port2iop(port);
191 return (p->inw) (p, port);
192}
193
194unsigned int
195sh7343se_inl(unsigned long port)
196{
197 badio(inl, port);
198}
199
200void
201sh7343se_outb(unsigned char value, unsigned long port)
202{
203 struct iop *p = port2iop(port);
204 (p->outb) (p, value, port);
205}
206
207void
208sh7343se_outb_p(unsigned char value, unsigned long port)
209{
210 sh7343se_outb(value, port);
211 delay();
212}
213
214void
215sh7343se_outw(unsigned short value, unsigned long port)
216{
217 struct iop *p = port2iop(port);
218 (p->outw) (p, value, port);
219}
220
221void
222sh7343se_outl(unsigned int value, unsigned long port)
223{
224 badio(outl, port);
225}
226
227void
228sh7343se_insb(unsigned long port, void *addr, unsigned long count)
229{
230 unsigned char *a = addr;
231 struct iop *p = port2iop(port);
232 while (count--)
233 *a++ = (p->inb) (p, port);
234}
235
236void
237sh7343se_insw(unsigned long port, void *addr, unsigned long count)
238{
239 unsigned short *a = addr;
240 struct iop *p = port2iop(port);
241 while (count--)
242 *a++ = (p->inw) (p, port);
243}
244
245void
246sh7343se_insl(unsigned long port, void *addr, unsigned long count)
247{
248 badio(insl, port);
249}
250
251void
252sh7343se_outsb(unsigned long port, const void *addr, unsigned long count)
253{
254 unsigned char *a = (unsigned char *) addr;
255 struct iop *p = port2iop(port);
256 while (count--)
257 (p->outb) (p, *a++, port);
258}
259
260void
261sh7343se_outsw(unsigned long port, const void *addr, unsigned long count)
262{
263 unsigned short *a = (unsigned short *) addr;
264 struct iop *p = port2iop(port);
265 while (count--)
266 (p->outw) (p, *a++, port);
267}
268
269void
270sh7343se_outsl(unsigned long port, const void *addr, unsigned long count)
271{
272 badio(outsw, port);
273}
diff --git a/arch/sh/boards/mach-se/7343/setup.c b/arch/sh/boards/mach-se/7343/setup.c
index 486f40bf9274..4de56f35f419 100644
--- a/arch/sh/boards/mach-se/7343/setup.c
+++ b/arch/sh/boards/mach-se/7343/setup.c
@@ -1,36 +1,16 @@
1#include <linux/init.h> 1#include <linux/init.h>
2#include <linux/platform_device.h> 2#include <linux/platform_device.h>
3#include <linux/mtd/physmap.h> 3#include <linux/mtd/physmap.h>
4#include <linux/serial_8250.h>
5#include <linux/serial_reg.h>
6#include <linux/usb/isp116x.h>
7#include <linux/delay.h>
4#include <asm/machvec.h> 8#include <asm/machvec.h>
5#include <mach-se/mach/se7343.h> 9#include <mach-se/mach/se7343.h>
6#include <asm/heartbeat.h> 10#include <asm/heartbeat.h>
7#include <asm/irq.h> 11#include <asm/irq.h>
8#include <asm/io.h> 12#include <asm/io.h>
9 13
10static struct resource smc91x_resources[] = {
11 [0] = {
12 .start = 0x10000000,
13 .end = 0x1000000F,
14 .flags = IORESOURCE_MEM,
15 },
16 [1] = {
17 /*
18 * shared with other devices via externel
19 * interrupt controller in FPGA...
20 */
21 .start = SMC_IRQ,
22 .end = SMC_IRQ,
23 .flags = IORESOURCE_IRQ,
24 },
25};
26
27static struct platform_device smc91x_device = {
28 .name = "smc91x",
29 .id = 0,
30 .num_resources = ARRAY_SIZE(smc91x_resources),
31 .resource = smc91x_resources,
32};
33
34static struct resource heartbeat_resources[] = { 14static struct resource heartbeat_resources[] = {
35 [0] = { 15 [0] = {
36 .start = PA_LED, 16 .start = PA_LED,
@@ -94,10 +74,83 @@ static struct platform_device nor_flash_device = {
94 .resource = nor_flash_resources, 74 .resource = nor_flash_resources,
95}; 75};
96 76
77#define ST16C2550C_FLAGS (UPF_BOOT_AUTOCONF | UPF_IOREMAP)
78
79static struct plat_serial8250_port serial_platform_data[] = {
80 [0] = {
81 .iotype = UPIO_MEM,
82 .mapbase = 0x16000000,
83 .regshift = 1,
84 .flags = ST16C2550C_FLAGS,
85 .irq = UARTA_IRQ,
86 .uartclk = 7372800,
87 },
88 [1] = {
89 .iotype = UPIO_MEM,
90 .mapbase = 0x17000000,
91 .regshift = 1,
92 .flags = ST16C2550C_FLAGS,
93 .irq = UARTB_IRQ,
94 .uartclk = 7372800,
95 },
96 { },
97};
98
99static struct platform_device uart_device = {
100 .name = "serial8250",
101 .id = PLAT8250_DEV_PLATFORM,
102 .dev = {
103 .platform_data = serial_platform_data,
104 },
105};
106
107static void isp116x_delay(struct device *dev, int delay)
108{
109 ndelay(delay);
110}
111
112static struct resource usb_resources[] = {
113 [0] = {
114 .start = 0x11800000,
115 .end = 0x11800001,
116 .flags = IORESOURCE_MEM,
117 },
118 [1] = {
119 .start = 0x11800002,
120 .end = 0x11800003,
121 .flags = IORESOURCE_MEM,
122 },
123 [2] = {
124 .start = USB_IRQ,
125 .flags = IORESOURCE_IRQ,
126 },
127};
128
129static struct isp116x_platform_data usb_platform_data = {
130 .sel15Kres = 1,
131 .oc_enable = 1,
132 .int_act_high = 0,
133 .int_edge_triggered = 0,
134 .remote_wakeup_enable = 0,
135 .delay = isp116x_delay,
136};
137
138static struct platform_device usb_device = {
139 .name = "isp116x-hcd",
140 .id = -1,
141 .num_resources = ARRAY_SIZE(usb_resources),
142 .resource = usb_resources,
143 .dev = {
144 .platform_data = &usb_platform_data,
145 },
146
147};
148
97static struct platform_device *sh7343se_platform_devices[] __initdata = { 149static struct platform_device *sh7343se_platform_devices[] __initdata = {
98 &smc91x_device,
99 &heartbeat_device, 150 &heartbeat_device,
100 &nor_flash_device, 151 &nor_flash_device,
152 &uart_device,
153 &usb_device,
101}; 154};
102 155
103static int __init sh7343se_devices_setup(void) 156static int __init sh7343se_devices_setup(void)
@@ -126,27 +179,6 @@ static void __init sh7343se_setup(char **cmdline_p)
126static struct sh_machine_vector mv_7343se __initmv = { 179static struct sh_machine_vector mv_7343se __initmv = {
127 .mv_name = "SolutionEngine 7343", 180 .mv_name = "SolutionEngine 7343",
128 .mv_setup = sh7343se_setup, 181 .mv_setup = sh7343se_setup,
129 .mv_nr_irqs = 108, 182 .mv_nr_irqs = SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_NR,
130 .mv_inb = sh7343se_inb,
131 .mv_inw = sh7343se_inw,
132 .mv_inl = sh7343se_inl,
133 .mv_outb = sh7343se_outb,
134 .mv_outw = sh7343se_outw,
135 .mv_outl = sh7343se_outl,
136
137 .mv_inb_p = sh7343se_inb_p,
138 .mv_inw_p = sh7343se_inw,
139 .mv_inl_p = sh7343se_inl,
140 .mv_outb_p = sh7343se_outb_p,
141 .mv_outw_p = sh7343se_outw,
142 .mv_outl_p = sh7343se_outl,
143
144 .mv_insb = sh7343se_insb,
145 .mv_insw = sh7343se_insw,
146 .mv_insl = sh7343se_insl,
147 .mv_outsb = sh7343se_outsb,
148 .mv_outsw = sh7343se_outsw,
149 .mv_outsl = sh7343se_outsl,
150
151 .mv_init_irq = init_7343se_IRQ, 183 .mv_init_irq = init_7343se_IRQ,
152}; 184};
diff --git a/arch/sh/boards/mach-se/770x/setup.c b/arch/sh/boards/mach-se/770x/setup.c
index 9123d9687bf7..527eb6b12610 100644
--- a/arch/sh/boards/mach-se/770x/setup.c
+++ b/arch/sh/boards/mach-se/770x/setup.c
@@ -8,8 +8,9 @@
8 */ 8 */
9#include <linux/init.h> 9#include <linux/init.h>
10#include <linux/platform_device.h> 10#include <linux/platform_device.h>
11#include <asm/machvec.h>
12#include <mach-se/mach/se.h> 11#include <mach-se/mach/se.h>
12#include <mach-se/mach/mrshpc.h>
13#include <asm/machvec.h>
13#include <asm/io.h> 14#include <asm/io.h>
14#include <asm/smc37c93x.h> 15#include <asm/smc37c93x.h>
15#include <asm/heartbeat.h> 16#include <asm/heartbeat.h>
@@ -175,6 +176,7 @@ static struct platform_device *se_devices[] __initdata = {
175 176
176static int __init se_devices_setup(void) 177static int __init se_devices_setup(void)
177{ 178{
179 mrshpc_setup_windows();
178 return platform_add_devices(se_devices, ARRAY_SIZE(se_devices)); 180 return platform_add_devices(se_devices, ARRAY_SIZE(se_devices));
179} 181}
180device_initcall(se_devices_setup); 182device_initcall(se_devices_setup);
diff --git a/arch/sh/boards/mach-se/7721/setup.c b/arch/sh/boards/mach-se/7721/setup.c
index d3fc80ff4d83..55af4c36b43a 100644
--- a/arch/sh/boards/mach-se/7721/setup.c
+++ b/arch/sh/boards/mach-se/7721/setup.c
@@ -12,8 +12,9 @@
12 */ 12 */
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/platform_device.h> 14#include <linux/platform_device.h>
15#include <asm/machvec.h>
16#include <mach-se/mach/se7721.h> 15#include <mach-se/mach/se7721.h>
16#include <mach-se/mach/mrshpc.h>
17#include <asm/machvec.h>
17#include <asm/io.h> 18#include <asm/io.h>
18#include <asm/heartbeat.h> 19#include <asm/heartbeat.h>
19 20
@@ -74,8 +75,8 @@ static struct platform_device *se7721_devices[] __initdata = {
74 75
75static int __init se7721_devices_setup(void) 76static int __init se7721_devices_setup(void)
76{ 77{
77 return platform_add_devices(se7721_devices, 78 mrshpc_setup_windows();
78 ARRAY_SIZE(se7721_devices)); 79 return platform_add_devices(se7721_devices, ARRAY_SIZE(se7721_devices));
79} 80}
80device_initcall(se7721_devices_setup); 81device_initcall(se7721_devices_setup);
81 82
diff --git a/arch/sh/boards/mach-se/7722/setup.c b/arch/sh/boards/mach-se/7722/setup.c
index fe6f96517e12..af84904ed86f 100644
--- a/arch/sh/boards/mach-se/7722/setup.c
+++ b/arch/sh/boards/mach-se/7722/setup.c
@@ -15,9 +15,10 @@
15#include <linux/ata_platform.h> 15#include <linux/ata_platform.h>
16#include <linux/input.h> 16#include <linux/input.h>
17#include <linux/smc91x.h> 17#include <linux/smc91x.h>
18#include <mach-se/mach/se7722.h>
19#include <mach-se/mach/mrshpc.h>
18#include <asm/machvec.h> 20#include <asm/machvec.h>
19#include <asm/clock.h> 21#include <asm/clock.h>
20#include <mach-se/mach/se7722.h>
21#include <asm/io.h> 22#include <asm/io.h>
22#include <asm/heartbeat.h> 23#include <asm/heartbeat.h>
23#include <asm/sh_keysc.h> 24#include <asm/sh_keysc.h>
@@ -130,6 +131,7 @@ static struct resource sh_keysc_resources[] = {
130 131
131static struct platform_device sh_keysc_device = { 132static struct platform_device sh_keysc_device = {
132 .name = "sh_keysc", 133 .name = "sh_keysc",
134 .id = 0, /* "keysc0" clock */
133 .num_resources = ARRAY_SIZE(sh_keysc_resources), 135 .num_resources = ARRAY_SIZE(sh_keysc_resources),
134 .resource = sh_keysc_resources, 136 .resource = sh_keysc_resources,
135 .dev = { 137 .dev = {
@@ -146,10 +148,8 @@ static struct platform_device *se7722_devices[] __initdata = {
146 148
147static int __init se7722_devices_setup(void) 149static int __init se7722_devices_setup(void)
148{ 150{
149 clk_always_enable("mstp214"); /* KEYSC */ 151 mrshpc_setup_windows();
150 152 return platform_add_devices(se7722_devices, ARRAY_SIZE(se7722_devices));
151 return platform_add_devices(se7722_devices,
152 ARRAY_SIZE(se7722_devices));
153} 153}
154device_initcall(se7722_devices_setup); 154device_initcall(se7722_devices_setup);
155 155
diff --git a/arch/sh/boards/mach-sh03/setup.c b/arch/sh/boards/mach-sh03/setup.c
index 5771219be3fd..74cfb4b8b03d 100644
--- a/arch/sh/boards/mach-sh03/setup.c
+++ b/arch/sh/boards/mach-sh03/setup.c
@@ -9,6 +9,7 @@
9#include <linux/irq.h> 9#include <linux/irq.h>
10#include <linux/pci.h> 10#include <linux/pci.h>
11#include <linux/platform_device.h> 11#include <linux/platform_device.h>
12#include <linux/ata_platform.h>
12#include <asm/io.h> 13#include <asm/io.h>
13#include <asm/rtc.h> 14#include <asm/rtc.h>
14#include <mach-sh03/mach/io.h> 15#include <mach-sh03/mach/io.h>
@@ -20,19 +21,6 @@ static void __init init_sh03_IRQ(void)
20 plat_irq_setup_pins(IRQ_MODE_IRQ); 21 plat_irq_setup_pins(IRQ_MODE_IRQ);
21} 22}
22 23
23extern void *cf_io_base;
24
25static void __iomem *sh03_ioport_map(unsigned long port, unsigned int size)
26{
27 if (PXSEG(port))
28 return (void __iomem *)port;
29 /* CompactFlash (IDE) */
30 if (((port >= 0x1f0) && (port <= 0x1f7)) || (port == 0x3f6))
31 return (void __iomem *)((unsigned long)cf_io_base + port);
32
33 return (void __iomem *)(port + PCI_IO_BASE);
34}
35
36/* arch/sh/boards/sh03/rtc.c */ 24/* arch/sh/boards/sh03/rtc.c */
37void sh03_time_init(void); 25void sh03_time_init(void);
38 26
@@ -41,6 +29,30 @@ static void __init sh03_setup(char **cmdline_p)
41 board_time_init = sh03_time_init; 29 board_time_init = sh03_time_init;
42} 30}
43 31
32static struct resource cf_ide_resources[] = {
33 [0] = {
34 .start = 0x1f0,
35 .end = 0x1f0 + 8,
36 .flags = IORESOURCE_IO,
37 },
38 [1] = {
39 .start = 0x1f0 + 0x206,
40 .end = 0x1f0 +8 + 0x206 + 8,
41 .flags = IORESOURCE_IO,
42 },
43 [2] = {
44 .start = IRL2_IRQ,
45 .flags = IORESOURCE_IRQ,
46 },
47};
48
49static struct platform_device cf_ide_device = {
50 .name = "pata_platform",
51 .id = -1,
52 .num_resources = ARRAY_SIZE(cf_ide_resources),
53 .resource = cf_ide_resources,
54};
55
44static struct resource heartbeat_resources[] = { 56static struct resource heartbeat_resources[] = {
45 [0] = { 57 [0] = {
46 .start = 0xa0800000, 58 .start = 0xa0800000,
@@ -58,10 +70,30 @@ static struct platform_device heartbeat_device = {
58 70
59static struct platform_device *sh03_devices[] __initdata = { 71static struct platform_device *sh03_devices[] __initdata = {
60 &heartbeat_device, 72 &heartbeat_device,
73 &cf_ide_device,
61}; 74};
62 75
63static int __init sh03_devices_setup(void) 76static int __init sh03_devices_setup(void)
64{ 77{
78 pgprot_t prot;
79 unsigned long paddrbase;
80 void *cf_ide_base;
81
82 /* open I/O area window */
83 paddrbase = virt_to_phys((void *)PA_AREA5_IO);
84 prot = PAGE_KERNEL_PCC(1, _PAGE_PCC_IO16);
85 cf_ide_base = p3_ioremap(paddrbase, PAGE_SIZE, prot.pgprot);
86 if (!cf_ide_base) {
87 printk("allocate_cf_area : can't open CF I/O window!\n");
88 return -ENOMEM;
89 }
90
91 /* IDE cmd address : 0x1f0-0x1f7 and 0x3f6 */
92 cf_ide_resources[0].start += (unsigned long)cf_ide_base;
93 cf_ide_resources[0].end += (unsigned long)cf_ide_base;
94 cf_ide_resources[1].start += (unsigned long)cf_ide_base;
95 cf_ide_resources[1].end += (unsigned long)cf_ide_base;
96
65 return platform_add_devices(sh03_devices, ARRAY_SIZE(sh03_devices)); 97 return platform_add_devices(sh03_devices, ARRAY_SIZE(sh03_devices));
66} 98}
67__initcall(sh03_devices_setup); 99__initcall(sh03_devices_setup);
@@ -70,6 +102,5 @@ static struct sh_machine_vector mv_sh03 __initmv = {
70 .mv_name = "Interface (CTP/PCI-SH03)", 102 .mv_name = "Interface (CTP/PCI-SH03)",
71 .mv_setup = sh03_setup, 103 .mv_setup = sh03_setup,
72 .mv_nr_irqs = 48, 104 .mv_nr_irqs = 48,
73 .mv_ioport_map = sh03_ioport_map,
74 .mv_init_irq = init_sh03_IRQ, 105 .mv_init_irq = init_sh03_IRQ,
75}; 106};
diff --git a/arch/sh/boards/mach-systemh/irq.c b/arch/sh/boards/mach-systemh/irq.c
index 538406872a89..986a0e71d220 100644
--- a/arch/sh/boards/mach-systemh/irq.c
+++ b/arch/sh/boards/mach-systemh/irq.c
@@ -12,8 +12,8 @@
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/irq.h> 13#include <linux/irq.h>
14#include <linux/interrupt.h> 14#include <linux/interrupt.h>
15#include <linux/io.h>
15 16
16#include <asm/io.h>
17#include <mach/systemh7751.h> 17#include <mach/systemh7751.h>
18#include <asm/smc37c93x.h> 18#include <asm/smc37c93x.h>
19 19
@@ -24,35 +24,17 @@ static unsigned long *systemh_irq_mask_register = (unsigned long *)0xB3F10004;
24static unsigned long *systemh_irq_request_register = (unsigned long *)0xB3F10000; 24static unsigned long *systemh_irq_request_register = (unsigned long *)0xB3F10000;
25 25
26/* forward declaration */ 26/* forward declaration */
27static unsigned int startup_systemh_irq(unsigned int irq);
28static void shutdown_systemh_irq(unsigned int irq);
29static void enable_systemh_irq(unsigned int irq); 27static void enable_systemh_irq(unsigned int irq);
30static void disable_systemh_irq(unsigned int irq); 28static void disable_systemh_irq(unsigned int irq);
31static void mask_and_ack_systemh(unsigned int); 29static void mask_and_ack_systemh(unsigned int);
32static void end_systemh_irq(unsigned int irq);
33 30
34/* hw_interrupt_type */ 31static struct irq_chip systemh_irq_type = {
35static struct hw_interrupt_type systemh_irq_type = { 32 .name = " SystemH Register",
36 .typename = " SystemH Register", 33 .unmask = enable_systemh_irq,
37 .startup = startup_systemh_irq, 34 .mask = disable_systemh_irq,
38 .shutdown = shutdown_systemh_irq,
39 .enable = enable_systemh_irq,
40 .disable = disable_systemh_irq,
41 .ack = mask_and_ack_systemh, 35 .ack = mask_and_ack_systemh,
42 .end = end_systemh_irq
43}; 36};
44 37
45static unsigned int startup_systemh_irq(unsigned int irq)
46{
47 enable_systemh_irq(irq);
48 return 0; /* never anything pending */
49}
50
51static void shutdown_systemh_irq(unsigned int irq)
52{
53 disable_systemh_irq(irq);
54}
55
56static void disable_systemh_irq(unsigned int irq) 38static void disable_systemh_irq(unsigned int irq)
57{ 39{
58 if (systemh_irq_mask_register) { 40 if (systemh_irq_mask_register) {
@@ -86,16 +68,9 @@ static void mask_and_ack_systemh(unsigned int irq)
86 disable_systemh_irq(irq); 68 disable_systemh_irq(irq);
87} 69}
88 70
89static void end_systemh_irq(unsigned int irq)
90{
91 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
92 enable_systemh_irq(irq);
93}
94
95void make_systemh_irq(unsigned int irq) 71void make_systemh_irq(unsigned int irq)
96{ 72{
97 disable_irq_nosync(irq); 73 disable_irq_nosync(irq);
98 irq_desc[irq].chip = &systemh_irq_type; 74 set_irq_chip_and_handler(irq, &systemh_irq_type, handle_level_irq);
99 disable_systemh_irq(irq); 75 disable_systemh_irq(irq);
100} 76}
101
diff --git a/arch/sh/cchips/hd6446x/hd64461.c b/arch/sh/cchips/hd6446x/hd64461.c
index f1a4a0763c59..27ceeb948bb1 100644
--- a/arch/sh/cchips/hd6446x/hd64461.c
+++ b/arch/sh/cchips/hd6446x/hd64461.c
@@ -10,99 +10,49 @@
10#include <linux/interrupt.h> 10#include <linux/interrupt.h>
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/irq.h> 12#include <linux/irq.h>
13#include <asm/io.h> 13#include <linux/io.h>
14#include <asm/irq.h> 14#include <asm/irq.h>
15#include <asm/hd64461.h> 15#include <asm/hd64461.h>
16 16
17/* This belongs in cpu specific */ 17/* This belongs in cpu specific */
18#define INTC_ICR1 0xA4140010UL 18#define INTC_ICR1 0xA4140010UL
19 19
20static void disable_hd64461_irq(unsigned int irq) 20static void hd64461_mask_irq(unsigned int irq)
21{ 21{
22 unsigned short nimr; 22 unsigned short nimr;
23 unsigned short mask = 1 << (irq - HD64461_IRQBASE); 23 unsigned short mask = 1 << (irq - HD64461_IRQBASE);
24 24
25 nimr = inw(HD64461_NIMR); 25 nimr = __raw_readw(HD64461_NIMR);
26 nimr |= mask; 26 nimr |= mask;
27 outw(nimr, HD64461_NIMR); 27 __raw_writew(nimr, HD64461_NIMR);
28} 28}
29 29
30static void enable_hd64461_irq(unsigned int irq) 30static void hd64461_unmask_irq(unsigned int irq)
31{ 31{
32 unsigned short nimr; 32 unsigned short nimr;
33 unsigned short mask = 1 << (irq - HD64461_IRQBASE); 33 unsigned short mask = 1 << (irq - HD64461_IRQBASE);
34 34
35 nimr = inw(HD64461_NIMR); 35 nimr = __raw_readw(HD64461_NIMR);
36 nimr &= ~mask; 36 nimr &= ~mask;
37 outw(nimr, HD64461_NIMR); 37 __raw_writew(nimr, HD64461_NIMR);
38} 38}
39 39
40static void mask_and_ack_hd64461(unsigned int irq) 40static void hd64461_mask_and_ack_irq(unsigned int irq)
41{ 41{
42 disable_hd64461_irq(irq); 42 hd64461_mask_irq(irq);
43#ifdef CONFIG_HD64461_ENABLER 43#ifdef CONFIG_HD64461_ENABLER
44 if (irq == HD64461_IRQBASE + 13) 44 if (irq == HD64461_IRQBASE + 13)
45 outb(0x00, HD64461_PCC1CSCR); 45 __raw_writeb(0x00, HD64461_PCC1CSCR);
46#endif 46#endif
47} 47}
48 48
49static void end_hd64461_irq(unsigned int irq) 49static struct irq_chip hd64461_irq_chip = {
50{ 50 .name = "HD64461-IRQ",
51 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) 51 .mask = hd64461_mask_irq,
52 enable_hd64461_irq(irq); 52 .mask_ack = hd64461_mask_and_ack_irq,
53} 53 .unmask = hd64461_unmask_irq,
54
55static unsigned int startup_hd64461_irq(unsigned int irq)
56{
57 enable_hd64461_irq(irq);
58 return 0;
59}
60
61static void shutdown_hd64461_irq(unsigned int irq)
62{
63 disable_hd64461_irq(irq);
64}
65
66static struct hw_interrupt_type hd64461_irq_type = {
67 .typename = "HD64461-IRQ",
68 .startup = startup_hd64461_irq,
69 .shutdown = shutdown_hd64461_irq,
70 .enable = enable_hd64461_irq,
71 .disable = disable_hd64461_irq,
72 .ack = mask_and_ack_hd64461,
73 .end = end_hd64461_irq,
74}; 54};
75 55
76static irqreturn_t hd64461_interrupt(int irq, void *dev_id)
77{
78 printk(KERN_INFO
79 "HD64461: spurious interrupt, nirr: 0x%x nimr: 0x%x\n",
80 inw(HD64461_NIRR), inw(HD64461_NIMR));
81
82 return IRQ_NONE;
83}
84
85static struct {
86 int (*func) (int, void *);
87 void *dev;
88} hd64461_demux[HD64461_IRQ_NUM];
89
90void hd64461_register_irq_demux(int irq,
91 int (*demux) (int irq, void *dev), void *dev)
92{
93 hd64461_demux[irq - HD64461_IRQBASE].func = demux;
94 hd64461_demux[irq - HD64461_IRQBASE].dev = dev;
95}
96
97EXPORT_SYMBOL(hd64461_register_irq_demux);
98
99void hd64461_unregister_irq_demux(int irq)
100{
101 hd64461_demux[irq - HD64461_IRQBASE].func = 0;
102}
103
104EXPORT_SYMBOL(hd64461_unregister_irq_demux);
105
106int hd64461_irq_demux(int irq) 56int hd64461_irq_demux(int irq)
107{ 57{
108 if (irq == CONFIG_HD64461_IRQ) { 58 if (irq == CONFIG_HD64461_IRQ) {
@@ -115,25 +65,11 @@ int hd64461_irq_demux(int irq)
115 for (bit = 1, i = 0; i < 16; bit <<= 1, i++) 65 for (bit = 1, i = 0; i < 16; bit <<= 1, i++)
116 if (nirr & bit) 66 if (nirr & bit)
117 break; 67 break;
118 if (i == 16) 68 irq = HD64461_IRQBASE + i;
119 irq = CONFIG_HD64461_IRQ;
120 else {
121 irq = HD64461_IRQBASE + i;
122 if (hd64461_demux[i].func != 0) {
123 irq = hd64461_demux[i].func(irq, hd64461_demux[i].dev);
124 }
125 }
126 } 69 }
127 return irq; 70 return irq;
128} 71}
129 72
130static struct irqaction irq0 = {
131 .handler = hd64461_interrupt,
132 .flags = IRQF_DISABLED,
133 .mask = CPU_MASK_NONE,
134 .name = "HD64461",
135};
136
137int __init setup_hd64461(void) 73int __init setup_hd64461(void)
138{ 74{
139 int i; 75 int i;
@@ -146,22 +82,21 @@ int __init setup_hd64461(void)
146 CONFIG_HD64461_IOBASE, CONFIG_HD64461_IRQ, HD64461_IRQBASE, 82 CONFIG_HD64461_IOBASE, CONFIG_HD64461_IRQ, HD64461_IRQBASE,
147 HD64461_IRQBASE + 15); 83 HD64461_IRQBASE + 15);
148 84
149#if defined(CONFIG_CPU_SUBTYPE_SH7709) /* Should be at processor specific part.. */ 85/* Should be at processor specific part.. */
150 outw(0x2240, INTC_ICR1); 86#if defined(CONFIG_CPU_SUBTYPE_SH7709)
87 __raw_writew(0x2240, INTC_ICR1);
151#endif 88#endif
152 outw(0xffff, HD64461_NIMR); 89 __raw_writew(0xffff, HD64461_NIMR);
153 90
154 /* IRQ 80 -> 95 belongs to HD64461 */ 91 /* IRQ 80 -> 95 belongs to HD64461 */
155 for (i = HD64461_IRQBASE; i < HD64461_IRQBASE + 16; i++) { 92 for (i = HD64461_IRQBASE; i < HD64461_IRQBASE + 16; i++)
156 irq_desc[i].chip = &hd64461_irq_type; 93 set_irq_chip_and_handler(i, &hd64461_irq_chip,
157 } 94 handle_level_irq);
158
159 setup_irq(CONFIG_HD64461_IRQ, &irq0);
160 95
161#ifdef CONFIG_HD64461_ENABLER 96#ifdef CONFIG_HD64461_ENABLER
162 printk(KERN_INFO "HD64461: enabling PCMCIA devices\n"); 97 printk(KERN_INFO "HD64461: enabling PCMCIA devices\n");
163 outb(0x4c, HD64461_PCC1CSCIER); 98 __raw_writeb(0x4c, HD64461_PCC1CSCIER);
164 outb(0x00, HD64461_PCC1CSCR); 99 __raw_writeb(0x00, HD64461_PCC1CSCR);
165#endif 100#endif
166 101
167 return 0; 102 return 0;
diff --git a/arch/sh/configs/edosk7705_defconfig b/arch/sh/configs/edosk7705_defconfig
new file mode 100644
index 000000000000..8f4329fbbd39
--- /dev/null
+++ b/arch/sh/configs/edosk7705_defconfig
@@ -0,0 +1,438 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.28-rc6
4# Wed Dec 17 13:53:02 2008
5#
6CONFIG_SUPERH=y
7CONFIG_SUPERH32=y
8CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
9CONFIG_RWSEM_GENERIC_SPINLOCK=y
10CONFIG_GENERIC_FIND_NEXT_BIT=y
11CONFIG_GENERIC_HWEIGHT=y
12CONFIG_GENERIC_HARDIRQS=y
13CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
14CONFIG_GENERIC_IRQ_PROBE=y
15# CONFIG_GENERIC_GPIO is not set
16CONFIG_GENERIC_TIME=y
17CONFIG_GENERIC_CLOCKEVENTS=y
18# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
19# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
20CONFIG_STACKTRACE_SUPPORT=y
21CONFIG_LOCKDEP_SUPPORT=y
22CONFIG_HAVE_LATENCYTOP_SUPPORT=y
23# CONFIG_ARCH_HAS_ILOG2_U32 is not set
24# CONFIG_ARCH_HAS_ILOG2_U64 is not set
25CONFIG_ARCH_NO_VIRT_TO_BUS=y
26CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
27
28#
29# General setup
30#
31# CONFIG_EXPERIMENTAL is not set
32CONFIG_BROKEN_ON_SMP=y
33CONFIG_INIT_ENV_ARG_LIMIT=32
34CONFIG_LOCALVERSION=""
35# CONFIG_LOCALVERSION_AUTO is not set
36# CONFIG_SYSVIPC is not set
37# CONFIG_BSD_PROCESS_ACCT is not set
38# CONFIG_IKCONFIG is not set
39CONFIG_LOG_BUF_SHIFT=17
40# CONFIG_CGROUPS is not set
41# CONFIG_RELAY is not set
42# CONFIG_NAMESPACES is not set
43# CONFIG_BLK_DEV_INITRD is not set
44# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
45CONFIG_EMBEDDED=y
46# CONFIG_UID16 is not set
47# CONFIG_SYSCTL_SYSCALL is not set
48# CONFIG_KALLSYMS is not set
49# CONFIG_HOTPLUG is not set
50# CONFIG_PRINTK is not set
51# CONFIG_BUG is not set
52# CONFIG_ELF_CORE is not set
53# CONFIG_COMPAT_BRK is not set
54# CONFIG_BASE_FULL is not set
55# CONFIG_FUTEX is not set
56# CONFIG_EPOLL is not set
57# CONFIG_SIGNALFD is not set
58# CONFIG_TIMERFD is not set
59# CONFIG_EVENTFD is not set
60CONFIG_SHMEM=y
61# CONFIG_AIO is not set
62# CONFIG_VM_EVENT_COUNTERS is not set
63# CONFIG_SLAB is not set
64CONFIG_SLUB=y
65# CONFIG_SLOB is not set
66# CONFIG_PROFILING is not set
67# CONFIG_MARKERS is not set
68CONFIG_HAVE_OPROFILE=y
69CONFIG_HAVE_IOREMAP_PROT=y
70CONFIG_HAVE_KPROBES=y
71CONFIG_HAVE_KRETPROBES=y
72CONFIG_HAVE_ARCH_TRACEHOOK=y
73CONFIG_HAVE_CLK=y
74CONFIG_HAVE_GENERIC_DMA_COHERENT=y
75# CONFIG_TINY_SHMEM is not set
76CONFIG_BASE_SMALL=1
77# CONFIG_MODULES is not set
78# CONFIG_BLOCK is not set
79CONFIG_CLASSIC_RCU=y
80# CONFIG_FREEZER is not set
81
82#
83# System type
84#
85CONFIG_CPU_SH3=y
86# CONFIG_CPU_SUBTYPE_SH7619 is not set
87# CONFIG_CPU_SUBTYPE_SH7201 is not set
88# CONFIG_CPU_SUBTYPE_SH7203 is not set
89# CONFIG_CPU_SUBTYPE_SH7206 is not set
90# CONFIG_CPU_SUBTYPE_SH7263 is not set
91# CONFIG_CPU_SUBTYPE_MXG is not set
92CONFIG_CPU_SUBTYPE_SH7705=y
93# CONFIG_CPU_SUBTYPE_SH7706 is not set
94# CONFIG_CPU_SUBTYPE_SH7707 is not set
95# CONFIG_CPU_SUBTYPE_SH7708 is not set
96# CONFIG_CPU_SUBTYPE_SH7709 is not set
97# CONFIG_CPU_SUBTYPE_SH7710 is not set
98# CONFIG_CPU_SUBTYPE_SH7712 is not set
99# CONFIG_CPU_SUBTYPE_SH7720 is not set
100# CONFIG_CPU_SUBTYPE_SH7721 is not set
101# CONFIG_CPU_SUBTYPE_SH7750 is not set
102# CONFIG_CPU_SUBTYPE_SH7091 is not set
103# CONFIG_CPU_SUBTYPE_SH7750R is not set
104# CONFIG_CPU_SUBTYPE_SH7750S is not set
105# CONFIG_CPU_SUBTYPE_SH7751 is not set
106# CONFIG_CPU_SUBTYPE_SH7751R is not set
107# CONFIG_CPU_SUBTYPE_SH7760 is not set
108# CONFIG_CPU_SUBTYPE_SH4_202 is not set
109# CONFIG_CPU_SUBTYPE_SH7723 is not set
110# CONFIG_CPU_SUBTYPE_SH7763 is not set
111# CONFIG_CPU_SUBTYPE_SH7770 is not set
112# CONFIG_CPU_SUBTYPE_SH7780 is not set
113# CONFIG_CPU_SUBTYPE_SH7785 is not set
114# CONFIG_CPU_SUBTYPE_SHX3 is not set
115# CONFIG_CPU_SUBTYPE_SH7343 is not set
116# CONFIG_CPU_SUBTYPE_SH7722 is not set
117# CONFIG_CPU_SUBTYPE_SH7366 is not set
118# CONFIG_CPU_SUBTYPE_SH5_101 is not set
119# CONFIG_CPU_SUBTYPE_SH5_103 is not set
120
121#
122# Memory management options
123#
124CONFIG_QUICKLIST=y
125CONFIG_MMU=y
126CONFIG_PAGE_OFFSET=0x80000000
127CONFIG_MEMORY_START=0x08000000
128CONFIG_MEMORY_SIZE=0x04000000
129CONFIG_29BIT=y
130CONFIG_VSYSCALL=y
131CONFIG_ARCH_FLATMEM_ENABLE=y
132CONFIG_ARCH_SPARSEMEM_ENABLE=y
133CONFIG_ARCH_SPARSEMEM_DEFAULT=y
134CONFIG_MAX_ACTIVE_REGIONS=1
135CONFIG_ARCH_POPULATES_NODE_MAP=y
136CONFIG_ARCH_SELECT_MEMORY_MODEL=y
137CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
138CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
139CONFIG_PAGE_SIZE_4KB=y
140# CONFIG_PAGE_SIZE_8KB is not set
141# CONFIG_PAGE_SIZE_16KB is not set
142# CONFIG_PAGE_SIZE_64KB is not set
143CONFIG_ENTRY_OFFSET=0x00001000
144CONFIG_SELECT_MEMORY_MODEL=y
145# CONFIG_FLATMEM_MANUAL is not set
146# CONFIG_DISCONTIGMEM_MANUAL is not set
147CONFIG_SPARSEMEM_MANUAL=y
148CONFIG_SPARSEMEM=y
149CONFIG_HAVE_MEMORY_PRESENT=y
150CONFIG_SPARSEMEM_STATIC=y
151CONFIG_PAGEFLAGS_EXTENDED=y
152CONFIG_SPLIT_PTLOCK_CPUS=4
153CONFIG_MIGRATION=y
154# CONFIG_RESOURCES_64BIT is not set
155# CONFIG_PHYS_ADDR_T_64BIT is not set
156CONFIG_ZONE_DMA_FLAG=0
157CONFIG_NR_QUICK=2
158CONFIG_UNEVICTABLE_LRU=y
159
160#
161# Cache configuration
162#
163CONFIG_SH7705_CACHE_32KB=y
164# CONFIG_SH_DIRECT_MAPPED is not set
165CONFIG_CACHE_WRITEBACK=y
166# CONFIG_CACHE_WRITETHROUGH is not set
167# CONFIG_CACHE_OFF is not set
168
169#
170# Processor features
171#
172CONFIG_CPU_LITTLE_ENDIAN=y
173# CONFIG_CPU_BIG_ENDIAN is not set
174CONFIG_SH_ADC=y
175CONFIG_CPU_HAS_INTEVT=y
176CONFIG_CPU_HAS_SR_RB=y
177
178#
179# Board support
180#
181# CONFIG_SH_SOLUTION_ENGINE is not set
182CONFIG_SH_EDOSK7705=y
183
184#
185# Timer and clock configuration
186#
187CONFIG_SH_TMU=y
188CONFIG_SH_TIMER_IRQ=16
189CONFIG_SH_PCLK_FREQ=31250000
190# CONFIG_NO_HZ is not set
191# CONFIG_HIGH_RES_TIMERS is not set
192CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
193
194#
195# CPU Frequency scaling
196#
197# CONFIG_CPU_FREQ is not set
198
199#
200# DMA support
201#
202# CONFIG_SH_DMA is not set
203
204#
205# Companion Chips
206#
207
208#
209# Additional SuperH Device Drivers
210#
211# CONFIG_HEARTBEAT is not set
212# CONFIG_PUSH_SWITCH is not set
213
214#
215# Kernel features
216#
217# CONFIG_HZ_100 is not set
218CONFIG_HZ_250=y
219# CONFIG_HZ_300 is not set
220# CONFIG_HZ_1000 is not set
221CONFIG_HZ=250
222# CONFIG_SCHED_HRTICK is not set
223CONFIG_PREEMPT_NONE=y
224# CONFIG_PREEMPT_VOLUNTARY is not set
225# CONFIG_PREEMPT is not set
226CONFIG_GUSA=y
227# CONFIG_GUSA_RB is not set
228
229#
230# Boot options
231#
232CONFIG_ZERO_PAGE_OFFSET=0x00001000
233CONFIG_BOOT_LINK_OFFSET=0x00800000
234# CONFIG_CMDLINE_BOOL is not set
235
236#
237# Bus options
238#
239# CONFIG_ARCH_SUPPORTS_MSI is not set
240
241#
242# Executable file formats
243#
244CONFIG_BINFMT_ELF=y
245# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
246# CONFIG_HAVE_AOUT is not set
247# CONFIG_BINFMT_MISC is not set
248# CONFIG_NET is not set
249
250#
251# Device Drivers
252#
253
254#
255# Generic Driver Options
256#
257CONFIG_STANDALONE=y
258# CONFIG_PREVENT_FIRMWARE_BUILD is not set
259# CONFIG_SYS_HYPERVISOR is not set
260# CONFIG_MTD is not set
261# CONFIG_PARPORT is not set
262# CONFIG_MISC_DEVICES is not set
263CONFIG_HAVE_IDE=y
264
265#
266# SCSI device support
267#
268# CONFIG_SCSI_DMA is not set
269# CONFIG_SCSI_NETLINK is not set
270# CONFIG_PHONE is not set
271
272#
273# Input device support
274#
275# CONFIG_INPUT is not set
276
277#
278# Hardware I/O ports
279#
280# CONFIG_SERIO is not set
281# CONFIG_GAMEPORT is not set
282
283#
284# Character devices
285#
286# CONFIG_VT is not set
287# CONFIG_DEVKMEM is not set
288# CONFIG_SERIAL_NONSTANDARD is not set
289
290#
291# Serial drivers
292#
293# CONFIG_SERIAL_8250 is not set
294
295#
296# Non-8250 serial port support
297#
298# CONFIG_SERIAL_SH_SCI is not set
299# CONFIG_UNIX98_PTYS is not set
300# CONFIG_LEGACY_PTYS is not set
301# CONFIG_IPMI_HANDLER is not set
302# CONFIG_HW_RANDOM is not set
303# CONFIG_R3964 is not set
304# CONFIG_I2C is not set
305# CONFIG_SPI is not set
306# CONFIG_W1 is not set
307# CONFIG_POWER_SUPPLY is not set
308# CONFIG_HWMON is not set
309# CONFIG_THERMAL is not set
310# CONFIG_THERMAL_HWMON is not set
311# CONFIG_WATCHDOG is not set
312CONFIG_SSB_POSSIBLE=y
313
314#
315# Sonics Silicon Backplane
316#
317# CONFIG_SSB is not set
318
319#
320# Multifunction device drivers
321#
322# CONFIG_MFD_CORE is not set
323# CONFIG_MFD_SM501 is not set
324# CONFIG_HTC_PASIC3 is not set
325# CONFIG_MFD_TMIO is not set
326# CONFIG_REGULATOR is not set
327
328#
329# Multimedia devices
330#
331
332#
333# Multimedia core support
334#
335# CONFIG_VIDEO_DEV is not set
336# CONFIG_VIDEO_MEDIA is not set
337
338#
339# Multimedia drivers
340#
341# CONFIG_DAB is not set
342
343#
344# Graphics support
345#
346# CONFIG_VGASTATE is not set
347# CONFIG_VIDEO_OUTPUT_CONTROL is not set
348# CONFIG_FB is not set
349# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
350
351#
352# Display device support
353#
354# CONFIG_DISPLAY_SUPPORT is not set
355# CONFIG_SOUND is not set
356# CONFIG_USB_SUPPORT is not set
357# CONFIG_MMC is not set
358# CONFIG_MEMSTICK is not set
359# CONFIG_NEW_LEDS is not set
360# CONFIG_ACCESSIBILITY is not set
361# CONFIG_RTC_CLASS is not set
362# CONFIG_DMADEVICES is not set
363# CONFIG_UIO is not set
364# CONFIG_STAGING is not set
365CONFIG_STAGING_EXCLUDE_BUILD=y
366
367#
368# File systems
369#
370# CONFIG_DNOTIFY is not set
371# CONFIG_INOTIFY is not set
372# CONFIG_QUOTA is not set
373# CONFIG_AUTOFS_FS is not set
374# CONFIG_AUTOFS4_FS is not set
375# CONFIG_FUSE_FS is not set
376
377#
378# Pseudo filesystems
379#
380# CONFIG_PROC_FS is not set
381# CONFIG_SYSFS is not set
382# CONFIG_TMPFS is not set
383# CONFIG_HUGETLBFS is not set
384# CONFIG_HUGETLB_PAGE is not set
385
386#
387# Miscellaneous filesystems
388#
389# CONFIG_NLS is not set
390
391#
392# Kernel hacking
393#
394CONFIG_TRACE_IRQFLAGS_SUPPORT=y
395# CONFIG_ENABLE_WARN_DEPRECATED is not set
396# CONFIG_ENABLE_MUST_CHECK is not set
397CONFIG_FRAME_WARN=1024
398# CONFIG_MAGIC_SYSRQ is not set
399# CONFIG_UNUSED_SYMBOLS is not set
400# CONFIG_HEADERS_CHECK is not set
401# CONFIG_DEBUG_KERNEL is not set
402# CONFIG_DEBUG_MEMORY_INIT is not set
403# CONFIG_RCU_CPU_STALL_DETECTOR is not set
404# CONFIG_LATENCYTOP is not set
405CONFIG_HAVE_FUNCTION_TRACER=y
406CONFIG_HAVE_DYNAMIC_FTRACE=y
407CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
408
409#
410# Tracers
411#
412# CONFIG_SAMPLES is not set
413CONFIG_HAVE_ARCH_KGDB=y
414# CONFIG_SH_STANDARD_BIOS is not set
415# CONFIG_EARLY_SCIF_CONSOLE is not set
416# CONFIG_MORE_COMPILE_OPTIONS is not set
417
418#
419# Security options
420#
421# CONFIG_KEYS is not set
422# CONFIG_SECURITYFS is not set
423# CONFIG_SECURITY_FILE_CAPABILITIES is not set
424# CONFIG_CRYPTO is not set
425
426#
427# Library routines
428#
429# CONFIG_CRC_CCITT is not set
430# CONFIG_CRC16 is not set
431# CONFIG_CRC_T10DIF is not set
432# CONFIG_CRC_ITU_T is not set
433# CONFIG_CRC32 is not set
434# CONFIG_CRC7 is not set
435# CONFIG_LIBCRC32C is not set
436CONFIG_HAS_IOMEM=y
437CONFIG_HAS_IOPORT=y
438CONFIG_HAS_DMA=y
diff --git a/arch/sh/configs/rsk7201_defconfig b/arch/sh/configs/rsk7201_defconfig
new file mode 100644
index 000000000000..014c18cbf46a
--- /dev/null
+++ b/arch/sh/configs/rsk7201_defconfig
@@ -0,0 +1,703 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.28-rc6
4# Mon Dec 8 14:48:02 2008
5#
6CONFIG_SUPERH=y
7CONFIG_SUPERH32=y
8CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
9CONFIG_RWSEM_GENERIC_SPINLOCK=y
10CONFIG_GENERIC_BUG=y
11CONFIG_GENERIC_FIND_NEXT_BIT=y
12CONFIG_GENERIC_HWEIGHT=y
13CONFIG_GENERIC_HARDIRQS=y
14CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
15CONFIG_GENERIC_IRQ_PROBE=y
16# CONFIG_GENERIC_GPIO is not set
17# CONFIG_GENERIC_TIME is not set
18# CONFIG_GENERIC_CLOCKEVENTS is not set
19# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
20# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
21CONFIG_STACKTRACE_SUPPORT=y
22CONFIG_LOCKDEP_SUPPORT=y
23CONFIG_HAVE_LATENCYTOP_SUPPORT=y
24# CONFIG_ARCH_HAS_ILOG2_U32 is not set
25# CONFIG_ARCH_HAS_ILOG2_U64 is not set
26CONFIG_ARCH_NO_VIRT_TO_BUS=y
27CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
28
29#
30# General setup
31#
32CONFIG_EXPERIMENTAL=y
33CONFIG_BROKEN_ON_SMP=y
34CONFIG_INIT_ENV_ARG_LIMIT=32
35CONFIG_LOCALVERSION=""
36# CONFIG_LOCALVERSION_AUTO is not set
37CONFIG_SYSVIPC=y
38CONFIG_SYSVIPC_SYSCTL=y
39CONFIG_BSD_PROCESS_ACCT=y
40# CONFIG_BSD_PROCESS_ACCT_V3 is not set
41CONFIG_IKCONFIG=y
42# CONFIG_IKCONFIG_PROC is not set
43CONFIG_LOG_BUF_SHIFT=14
44# CONFIG_CGROUPS is not set
45# CONFIG_GROUP_SCHED is not set
46# CONFIG_SYSFS_DEPRECATED_V2 is not set
47# CONFIG_RELAY is not set
48CONFIG_NAMESPACES=y
49CONFIG_UTS_NS=y
50CONFIG_IPC_NS=y
51CONFIG_USER_NS=y
52CONFIG_PID_NS=y
53CONFIG_BLK_DEV_INITRD=y
54CONFIG_INITRAMFS_SOURCE=""
55CONFIG_CC_OPTIMIZE_FOR_SIZE=y
56CONFIG_SYSCTL=y
57CONFIG_EMBEDDED=y
58CONFIG_UID16=y
59CONFIG_SYSCTL_SYSCALL=y
60CONFIG_KALLSYMS=y
61# CONFIG_KALLSYMS_EXTRA_PASS is not set
62CONFIG_HOTPLUG=y
63CONFIG_PRINTK=y
64CONFIG_BUG=y
65CONFIG_ELF_CORE=y
66CONFIG_COMPAT_BRK=y
67CONFIG_BASE_FULL=y
68CONFIG_FUTEX=y
69CONFIG_ANON_INODES=y
70CONFIG_EPOLL=y
71CONFIG_SIGNALFD=y
72CONFIG_TIMERFD=y
73CONFIG_EVENTFD=y
74# CONFIG_AIO is not set
75CONFIG_VM_EVENT_COUNTERS=y
76# CONFIG_SLAB is not set
77# CONFIG_SLUB is not set
78CONFIG_SLOB=y
79CONFIG_PROFILING=y
80# CONFIG_MARKERS is not set
81CONFIG_OPROFILE=y
82CONFIG_HAVE_OPROFILE=y
83# CONFIG_KPROBES is not set
84CONFIG_HAVE_KPROBES=y
85CONFIG_HAVE_KRETPROBES=y
86CONFIG_HAVE_ARCH_TRACEHOOK=y
87CONFIG_HAVE_CLK=y
88CONFIG_HAVE_GENERIC_DMA_COHERENT=y
89CONFIG_RT_MUTEXES=y
90CONFIG_TINY_SHMEM=y
91CONFIG_BASE_SMALL=0
92CONFIG_MODULES=y
93# CONFIG_MODULE_FORCE_LOAD is not set
94# CONFIG_MODULE_UNLOAD is not set
95# CONFIG_MODVERSIONS is not set
96# CONFIG_MODULE_SRCVERSION_ALL is not set
97CONFIG_KMOD=y
98CONFIG_BLOCK=y
99# CONFIG_LBD is not set
100# CONFIG_BLK_DEV_IO_TRACE is not set
101# CONFIG_LSF is not set
102# CONFIG_BLK_DEV_BSG is not set
103# CONFIG_BLK_DEV_INTEGRITY is not set
104
105#
106# IO Schedulers
107#
108CONFIG_IOSCHED_NOOP=y
109# CONFIG_IOSCHED_AS is not set
110# CONFIG_IOSCHED_DEADLINE is not set
111# CONFIG_IOSCHED_CFQ is not set
112# CONFIG_DEFAULT_AS is not set
113# CONFIG_DEFAULT_DEADLINE is not set
114# CONFIG_DEFAULT_CFQ is not set
115CONFIG_DEFAULT_NOOP=y
116CONFIG_DEFAULT_IOSCHED="noop"
117CONFIG_CLASSIC_RCU=y
118# CONFIG_FREEZER is not set
119
120#
121# System type
122#
123CONFIG_CPU_SH2=y
124CONFIG_CPU_SH2A=y
125# CONFIG_CPU_SUBTYPE_SH7619 is not set
126CONFIG_CPU_SUBTYPE_SH7201=y
127# CONFIG_CPU_SUBTYPE_SH7203 is not set
128# CONFIG_CPU_SUBTYPE_SH7206 is not set
129# CONFIG_CPU_SUBTYPE_SH7263 is not set
130# CONFIG_CPU_SUBTYPE_MXG is not set
131# CONFIG_CPU_SUBTYPE_SH7705 is not set
132# CONFIG_CPU_SUBTYPE_SH7706 is not set
133# CONFIG_CPU_SUBTYPE_SH7707 is not set
134# CONFIG_CPU_SUBTYPE_SH7708 is not set
135# CONFIG_CPU_SUBTYPE_SH7709 is not set
136# CONFIG_CPU_SUBTYPE_SH7710 is not set
137# CONFIG_CPU_SUBTYPE_SH7712 is not set
138# CONFIG_CPU_SUBTYPE_SH7720 is not set
139# CONFIG_CPU_SUBTYPE_SH7721 is not set
140# CONFIG_CPU_SUBTYPE_SH7750 is not set
141# CONFIG_CPU_SUBTYPE_SH7091 is not set
142# CONFIG_CPU_SUBTYPE_SH7750R is not set
143# CONFIG_CPU_SUBTYPE_SH7750S is not set
144# CONFIG_CPU_SUBTYPE_SH7751 is not set
145# CONFIG_CPU_SUBTYPE_SH7751R is not set
146# CONFIG_CPU_SUBTYPE_SH7760 is not set
147# CONFIG_CPU_SUBTYPE_SH4_202 is not set
148# CONFIG_CPU_SUBTYPE_SH7723 is not set
149# CONFIG_CPU_SUBTYPE_SH7763 is not set
150# CONFIG_CPU_SUBTYPE_SH7770 is not set
151# CONFIG_CPU_SUBTYPE_SH7780 is not set
152# CONFIG_CPU_SUBTYPE_SH7785 is not set
153# CONFIG_CPU_SUBTYPE_SHX3 is not set
154# CONFIG_CPU_SUBTYPE_SH7343 is not set
155# CONFIG_CPU_SUBTYPE_SH7722 is not set
156# CONFIG_CPU_SUBTYPE_SH7366 is not set
157# CONFIG_CPU_SUBTYPE_SH5_101 is not set
158# CONFIG_CPU_SUBTYPE_SH5_103 is not set
159
160#
161# Memory management options
162#
163CONFIG_QUICKLIST=y
164CONFIG_PAGE_OFFSET=0x00000000
165CONFIG_MEMORY_START=0x08000000
166CONFIG_MEMORY_SIZE=0x01000000
167CONFIG_29BIT=y
168CONFIG_ARCH_FLATMEM_ENABLE=y
169CONFIG_ARCH_SPARSEMEM_ENABLE=y
170CONFIG_ARCH_SPARSEMEM_DEFAULT=y
171CONFIG_MAX_ACTIVE_REGIONS=1
172CONFIG_ARCH_POPULATES_NODE_MAP=y
173CONFIG_ARCH_SELECT_MEMORY_MODEL=y
174CONFIG_PAGE_SIZE_4KB=y
175# CONFIG_PAGE_SIZE_8KB is not set
176# CONFIG_PAGE_SIZE_16KB is not set
177# CONFIG_PAGE_SIZE_64KB is not set
178CONFIG_ENTRY_OFFSET=0x00001000
179CONFIG_SELECT_MEMORY_MODEL=y
180CONFIG_FLATMEM_MANUAL=y
181# CONFIG_DISCONTIGMEM_MANUAL is not set
182# CONFIG_SPARSEMEM_MANUAL is not set
183CONFIG_FLATMEM=y
184CONFIG_FLAT_NODE_MEM_MAP=y
185CONFIG_SPARSEMEM_STATIC=y
186CONFIG_PAGEFLAGS_EXTENDED=y
187CONFIG_SPLIT_PTLOCK_CPUS=4
188# CONFIG_RESOURCES_64BIT is not set
189# CONFIG_PHYS_ADDR_T_64BIT is not set
190CONFIG_ZONE_DMA_FLAG=0
191CONFIG_NR_QUICK=2
192
193#
194# Cache configuration
195#
196# CONFIG_SH_DIRECT_MAPPED is not set
197CONFIG_CACHE_WRITEBACK=y
198# CONFIG_CACHE_WRITETHROUGH is not set
199# CONFIG_CACHE_OFF is not set
200
201#
202# Processor features
203#
204# CONFIG_CPU_LITTLE_ENDIAN is not set
205CONFIG_CPU_BIG_ENDIAN=y
206CONFIG_SH_FPU=y
207CONFIG_CPU_HAS_FPU=y
208
209#
210# Board support
211#
212CONFIG_SH_RSK=y
213CONFIG_SH_RSK7201=y
214# CONFIG_SH_RSK7203 is not set
215
216#
217# Timer and clock configuration
218#
219# CONFIG_SH_CMT is not set
220CONFIG_SH_MTU2=y
221CONFIG_SH_TIMER_IRQ=16
222CONFIG_SH_PCLK_FREQ=40000000
223CONFIG_SH_CLK_MD=0
224
225#
226# CPU Frequency scaling
227#
228# CONFIG_CPU_FREQ is not set
229
230#
231# DMA support
232#
233
234#
235# Companion Chips
236#
237
238#
239# Additional SuperH Device Drivers
240#
241# CONFIG_HEARTBEAT is not set
242# CONFIG_PUSH_SWITCH is not set
243
244#
245# Kernel features
246#
247# CONFIG_HZ_100 is not set
248# CONFIG_HZ_250 is not set
249# CONFIG_HZ_300 is not set
250CONFIG_HZ_1000=y
251CONFIG_HZ=1000
252# CONFIG_SCHED_HRTICK is not set
253# CONFIG_KEXEC is not set
254# CONFIG_CRASH_DUMP is not set
255# CONFIG_SECCOMP is not set
256CONFIG_PREEMPT_NONE=y
257# CONFIG_PREEMPT_VOLUNTARY is not set
258# CONFIG_PREEMPT is not set
259CONFIG_GUSA=y
260
261#
262# Boot options
263#
264CONFIG_ZERO_PAGE_OFFSET=0x00001000
265CONFIG_BOOT_LINK_OFFSET=0x00800000
266CONFIG_CMDLINE_BOOL=y
267CONFIG_CMDLINE="console=ttySC0,115200 earlyprintk=serial ignore_loglevel"
268
269#
270# Bus options
271#
272# CONFIG_ARCH_SUPPORTS_MSI is not set
273# CONFIG_PCCARD is not set
274
275#
276# Executable file formats
277#
278CONFIG_BINFMT_ELF_FDPIC=y
279CONFIG_BINFMT_FLAT=y
280CONFIG_BINFMT_ZFLAT=y
281CONFIG_BINFMT_SHARED_FLAT=y
282# CONFIG_HAVE_AOUT is not set
283# CONFIG_BINFMT_MISC is not set
284
285#
286# Power management options (EXPERIMENTAL)
287#
288CONFIG_PM=y
289# CONFIG_PM_DEBUG is not set
290CONFIG_CPU_IDLE=y
291CONFIG_CPU_IDLE_GOV_LADDER=y
292# CONFIG_NET is not set
293
294#
295# Device Drivers
296#
297
298#
299# Generic Driver Options
300#
301CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
302# CONFIG_STANDALONE is not set
303# CONFIG_PREVENT_FIRMWARE_BUILD is not set
304# CONFIG_FW_LOADER is not set
305# CONFIG_SYS_HYPERVISOR is not set
306CONFIG_MTD=y
307# CONFIG_MTD_DEBUG is not set
308CONFIG_MTD_CONCAT=y
309CONFIG_MTD_PARTITIONS=y
310CONFIG_MTD_REDBOOT_PARTS=y
311CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
312# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
313# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
314# CONFIG_MTD_CMDLINE_PARTS is not set
315# CONFIG_MTD_AR7_PARTS is not set
316
317#
318# User Modules And Translation Layers
319#
320CONFIG_MTD_CHAR=y
321CONFIG_MTD_BLKDEVS=y
322CONFIG_MTD_BLOCK=y
323# CONFIG_FTL is not set
324# CONFIG_NFTL is not set
325# CONFIG_INFTL is not set
326# CONFIG_RFD_FTL is not set
327# CONFIG_SSFDC is not set
328# CONFIG_MTD_OOPS is not set
329
330#
331# RAM/ROM/Flash chip drivers
332#
333CONFIG_MTD_CFI=y
334# CONFIG_MTD_JEDECPROBE is not set
335CONFIG_MTD_GEN_PROBE=y
336# CONFIG_MTD_CFI_ADV_OPTIONS is not set
337CONFIG_MTD_MAP_BANK_WIDTH_1=y
338CONFIG_MTD_MAP_BANK_WIDTH_2=y
339CONFIG_MTD_MAP_BANK_WIDTH_4=y
340# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
341# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
342# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
343CONFIG_MTD_CFI_I1=y
344CONFIG_MTD_CFI_I2=y
345# CONFIG_MTD_CFI_I4 is not set
346# CONFIG_MTD_CFI_I8 is not set
347# CONFIG_MTD_CFI_INTELEXT is not set
348CONFIG_MTD_CFI_AMDSTD=y
349# CONFIG_MTD_CFI_STAA is not set
350CONFIG_MTD_CFI_UTIL=y
351# CONFIG_MTD_RAM is not set
352# CONFIG_MTD_ROM is not set
353# CONFIG_MTD_ABSENT is not set
354
355#
356# Mapping drivers for chip access
357#
358# CONFIG_MTD_COMPLEX_MAPPINGS is not set
359CONFIG_MTD_PHYSMAP=y
360CONFIG_MTD_PHYSMAP_START=0x0
361CONFIG_MTD_PHYSMAP_LEN=0x0
362CONFIG_MTD_PHYSMAP_BANKWIDTH=4
363# CONFIG_MTD_PLATRAM is not set
364
365#
366# Self-contained MTD device drivers
367#
368# CONFIG_MTD_SLRAM is not set
369# CONFIG_MTD_PHRAM is not set
370# CONFIG_MTD_MTDRAM is not set
371# CONFIG_MTD_BLOCK2MTD is not set
372
373#
374# Disk-On-Chip Device Drivers
375#
376# CONFIG_MTD_DOC2000 is not set
377# CONFIG_MTD_DOC2001 is not set
378# CONFIG_MTD_DOC2001PLUS is not set
379# CONFIG_MTD_NAND is not set
380# CONFIG_MTD_ONENAND is not set
381
382#
383# UBI - Unsorted block images
384#
385# CONFIG_MTD_UBI is not set
386# CONFIG_PARPORT is not set
387CONFIG_BLK_DEV=y
388# CONFIG_BLK_DEV_COW_COMMON is not set
389# CONFIG_BLK_DEV_LOOP is not set
390# CONFIG_BLK_DEV_RAM is not set
391# CONFIG_CDROM_PKTCDVD is not set
392# CONFIG_BLK_DEV_HD is not set
393CONFIG_MISC_DEVICES=y
394# CONFIG_EEPROM_93CX6 is not set
395# CONFIG_ENCLOSURE_SERVICES is not set
396# CONFIG_C2PORT is not set
397CONFIG_HAVE_IDE=y
398# CONFIG_IDE is not set
399
400#
401# SCSI device support
402#
403# CONFIG_RAID_ATTRS is not set
404# CONFIG_SCSI is not set
405# CONFIG_SCSI_DMA is not set
406# CONFIG_SCSI_NETLINK is not set
407# CONFIG_ATA is not set
408# CONFIG_MD is not set
409# CONFIG_PHONE is not set
410
411#
412# Input device support
413#
414CONFIG_INPUT=y
415# CONFIG_INPUT_FF_MEMLESS is not set
416# CONFIG_INPUT_POLLDEV is not set
417
418#
419# Userland interfaces
420#
421# CONFIG_INPUT_MOUSEDEV is not set
422# CONFIG_INPUT_JOYDEV is not set
423# CONFIG_INPUT_EVDEV is not set
424# CONFIG_INPUT_EVBUG is not set
425
426#
427# Input Device Drivers
428#
429# CONFIG_INPUT_KEYBOARD is not set
430# CONFIG_INPUT_MOUSE is not set
431# CONFIG_INPUT_JOYSTICK is not set
432# CONFIG_INPUT_TABLET is not set
433# CONFIG_INPUT_TOUCHSCREEN is not set
434# CONFIG_INPUT_MISC is not set
435
436#
437# Hardware I/O ports
438#
439# CONFIG_SERIO is not set
440# CONFIG_GAMEPORT is not set
441
442#
443# Character devices
444#
445# CONFIG_VT is not set
446CONFIG_DEVKMEM=y
447# CONFIG_SERIAL_NONSTANDARD is not set
448
449#
450# Serial drivers
451#
452# CONFIG_SERIAL_8250 is not set
453
454#
455# Non-8250 serial port support
456#
457CONFIG_SERIAL_SH_SCI=y
458CONFIG_SERIAL_SH_SCI_NR_UARTS=8
459CONFIG_SERIAL_SH_SCI_CONSOLE=y
460CONFIG_SERIAL_CORE=y
461CONFIG_SERIAL_CORE_CONSOLE=y
462# CONFIG_UNIX98_PTYS is not set
463# CONFIG_LEGACY_PTYS is not set
464# CONFIG_IPMI_HANDLER is not set
465# CONFIG_HW_RANDOM is not set
466# CONFIG_R3964 is not set
467# CONFIG_RAW_DRIVER is not set
468# CONFIG_TCG_TPM is not set
469# CONFIG_I2C is not set
470# CONFIG_SPI is not set
471# CONFIG_W1 is not set
472# CONFIG_POWER_SUPPLY is not set
473# CONFIG_HWMON is not set
474CONFIG_THERMAL=y
475# CONFIG_WATCHDOG is not set
476CONFIG_SSB_POSSIBLE=y
477
478#
479# Sonics Silicon Backplane
480#
481# CONFIG_SSB is not set
482
483#
484# Multifunction device drivers
485#
486# CONFIG_MFD_CORE is not set
487# CONFIG_MFD_SM501 is not set
488# CONFIG_HTC_PASIC3 is not set
489# CONFIG_MFD_TMIO is not set
490# CONFIG_REGULATOR is not set
491
492#
493# Multimedia devices
494#
495
496#
497# Multimedia core support
498#
499# CONFIG_VIDEO_DEV is not set
500# CONFIG_VIDEO_MEDIA is not set
501
502#
503# Multimedia drivers
504#
505CONFIG_DAB=y
506
507#
508# Graphics support
509#
510# CONFIG_VGASTATE is not set
511CONFIG_VIDEO_OUTPUT_CONTROL=y
512# CONFIG_FB is not set
513# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
514
515#
516# Display device support
517#
518# CONFIG_DISPLAY_SUPPORT is not set
519# CONFIG_SOUND is not set
520# CONFIG_HID_SUPPORT is not set
521# CONFIG_USB_SUPPORT is not set
522# CONFIG_MMC is not set
523# CONFIG_MEMSTICK is not set
524# CONFIG_NEW_LEDS is not set
525# CONFIG_ACCESSIBILITY is not set
526CONFIG_RTC_LIB=y
527CONFIG_RTC_CLASS=y
528CONFIG_RTC_HCTOSYS=y
529CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
530# CONFIG_RTC_DEBUG is not set
531
532#
533# RTC interfaces
534#
535CONFIG_RTC_INTF_SYSFS=y
536CONFIG_RTC_INTF_PROC=y
537CONFIG_RTC_INTF_DEV=y
538# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
539# CONFIG_RTC_DRV_TEST is not set
540
541#
542# SPI RTC drivers
543#
544
545#
546# Platform RTC drivers
547#
548# CONFIG_RTC_DRV_DS1286 is not set
549# CONFIG_RTC_DRV_DS1511 is not set
550# CONFIG_RTC_DRV_DS1553 is not set
551# CONFIG_RTC_DRV_DS1742 is not set
552# CONFIG_RTC_DRV_STK17TA8 is not set
553# CONFIG_RTC_DRV_M48T86 is not set
554# CONFIG_RTC_DRV_M48T35 is not set
555# CONFIG_RTC_DRV_M48T59 is not set
556# CONFIG_RTC_DRV_BQ4802 is not set
557# CONFIG_RTC_DRV_V3020 is not set
558
559#
560# on-CPU RTC drivers
561#
562CONFIG_RTC_DRV_SH=y
563# CONFIG_DMADEVICES is not set
564# CONFIG_UIO is not set
565# CONFIG_STAGING is not set
566CONFIG_STAGING_EXCLUDE_BUILD=y
567
568#
569# File systems
570#
571CONFIG_EXT2_FS=y
572# CONFIG_EXT2_FS_XATTR is not set
573# CONFIG_EXT3_FS is not set
574# CONFIG_EXT4_FS is not set
575# CONFIG_REISERFS_FS is not set
576# CONFIG_JFS_FS is not set
577# CONFIG_FS_POSIX_ACL is not set
578# CONFIG_FILE_LOCKING is not set
579# CONFIG_XFS_FS is not set
580# CONFIG_DNOTIFY is not set
581# CONFIG_INOTIFY is not set
582# CONFIG_QUOTA is not set
583# CONFIG_AUTOFS_FS is not set
584# CONFIG_AUTOFS4_FS is not set
585# CONFIG_FUSE_FS is not set
586
587#
588# CD-ROM/DVD Filesystems
589#
590# CONFIG_ISO9660_FS is not set
591# CONFIG_UDF_FS is not set
592
593#
594# DOS/FAT/NT Filesystems
595#
596# CONFIG_MSDOS_FS is not set
597# CONFIG_VFAT_FS is not set
598# CONFIG_NTFS_FS is not set
599
600#
601# Pseudo filesystems
602#
603CONFIG_PROC_FS=y
604CONFIG_PROC_SYSCTL=y
605CONFIG_SYSFS=y
606# CONFIG_TMPFS is not set
607# CONFIG_HUGETLB_PAGE is not set
608# CONFIG_CONFIGFS_FS is not set
609
610#
611# Miscellaneous filesystems
612#
613# CONFIG_ADFS_FS is not set
614# CONFIG_AFFS_FS is not set
615# CONFIG_HFS_FS is not set
616# CONFIG_HFSPLUS_FS is not set
617# CONFIG_BEFS_FS is not set
618# CONFIG_BFS_FS is not set
619# CONFIG_EFS_FS is not set
620CONFIG_JFFS2_FS=y
621CONFIG_JFFS2_FS_DEBUG=0
622CONFIG_JFFS2_FS_WRITEBUFFER=y
623# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
624# CONFIG_JFFS2_SUMMARY is not set
625# CONFIG_JFFS2_FS_XATTR is not set
626# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
627CONFIG_JFFS2_ZLIB=y
628# CONFIG_JFFS2_LZO is not set
629CONFIG_JFFS2_RTIME=y
630# CONFIG_JFFS2_RUBIN is not set
631# CONFIG_CRAMFS is not set
632# CONFIG_VXFS_FS is not set
633# CONFIG_MINIX_FS is not set
634# CONFIG_OMFS_FS is not set
635# CONFIG_HPFS_FS is not set
636# CONFIG_QNX4FS_FS is not set
637CONFIG_ROMFS_FS=y
638# CONFIG_SYSV_FS is not set
639# CONFIG_UFS_FS is not set
640
641#
642# Partition Types
643#
644# CONFIG_PARTITION_ADVANCED is not set
645CONFIG_MSDOS_PARTITION=y
646# CONFIG_NLS is not set
647
648#
649# Kernel hacking
650#
651CONFIG_TRACE_IRQFLAGS_SUPPORT=y
652# CONFIG_PRINTK_TIME is not set
653CONFIG_ENABLE_WARN_DEPRECATED=y
654# CONFIG_ENABLE_MUST_CHECK is not set
655CONFIG_FRAME_WARN=1024
656CONFIG_MAGIC_SYSRQ=y
657# CONFIG_UNUSED_SYMBOLS is not set
658CONFIG_DEBUG_FS=y
659# CONFIG_HEADERS_CHECK is not set
660# CONFIG_DEBUG_KERNEL is not set
661# CONFIG_DEBUG_BUGVERBOSE is not set
662# CONFIG_DEBUG_MEMORY_INIT is not set
663# CONFIG_RCU_CPU_STALL_DETECTOR is not set
664# CONFIG_LATENCYTOP is not set
665CONFIG_SYSCTL_SYSCALL_CHECK=y
666CONFIG_HAVE_FUNCTION_TRACER=y
667CONFIG_HAVE_DYNAMIC_FTRACE=y
668CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
669
670#
671# Tracers
672#
673# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
674# CONFIG_SAMPLES is not set
675# CONFIG_SH_STANDARD_BIOS is not set
676# CONFIG_EARLY_SCIF_CONSOLE is not set
677
678#
679# Security options
680#
681# CONFIG_KEYS is not set
682# CONFIG_SECURITY is not set
683# CONFIG_SECURITYFS is not set
684# CONFIG_SECURITY_FILE_CAPABILITIES is not set
685# CONFIG_CRYPTO is not set
686
687#
688# Library routines
689#
690CONFIG_BITREVERSE=y
691# CONFIG_CRC_CCITT is not set
692# CONFIG_CRC16 is not set
693# CONFIG_CRC_T10DIF is not set
694# CONFIG_CRC_ITU_T is not set
695CONFIG_CRC32=y
696# CONFIG_CRC7 is not set
697# CONFIG_LIBCRC32C is not set
698CONFIG_ZLIB_INFLATE=y
699CONFIG_ZLIB_DEFLATE=y
700CONFIG_PLIST=y
701CONFIG_HAS_IOMEM=y
702CONFIG_HAS_IOPORT=y
703CONFIG_HAS_DMA=y
diff --git a/arch/sh/configs/rsk7203_defconfig b/arch/sh/configs/rsk7203_defconfig
index 85b0ac4fc667..dcdef31cf19b 100644
--- a/arch/sh/configs/rsk7203_defconfig
+++ b/arch/sh/configs/rsk7203_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.27 3# Linux kernel version: 2.6.28-rc6
4# Tue Oct 21 12:58:47 2008 4# Mon Dec 8 14:35:03 2008
5# 5#
6CONFIG_SUPERH=y 6CONFIG_SUPERH=y
7CONFIG_SUPERH32=y 7CONFIG_SUPERH32=y
@@ -16,6 +16,8 @@ CONFIG_GENERIC_IRQ_PROBE=y
16CONFIG_GENERIC_GPIO=y 16CONFIG_GENERIC_GPIO=y
17# CONFIG_GENERIC_TIME is not set 17# CONFIG_GENERIC_TIME is not set
18# CONFIG_GENERIC_CLOCKEVENTS is not set 18# CONFIG_GENERIC_CLOCKEVENTS is not set
19# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
20# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
19CONFIG_STACKTRACE_SUPPORT=y 21CONFIG_STACKTRACE_SUPPORT=y
20CONFIG_LOCKDEP_SUPPORT=y 22CONFIG_LOCKDEP_SUPPORT=y
21CONFIG_HAVE_LATENCYTOP_SUPPORT=y 23CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -75,7 +77,6 @@ CONFIG_TIMERFD=y
75CONFIG_EVENTFD=y 77CONFIG_EVENTFD=y
76CONFIG_AIO=y 78CONFIG_AIO=y
77CONFIG_VM_EVENT_COUNTERS=y 79CONFIG_VM_EVENT_COUNTERS=y
78CONFIG_PCI_QUIRKS=y
79# CONFIG_SLAB is not set 80# CONFIG_SLAB is not set
80# CONFIG_SLUB is not set 81# CONFIG_SLUB is not set
81CONFIG_SLOB=y 82CONFIG_SLOB=y
@@ -126,6 +127,7 @@ CONFIG_CLASSIC_RCU=y
126CONFIG_CPU_SH2=y 127CONFIG_CPU_SH2=y
127CONFIG_CPU_SH2A=y 128CONFIG_CPU_SH2A=y
128# CONFIG_CPU_SUBTYPE_SH7619 is not set 129# CONFIG_CPU_SUBTYPE_SH7619 is not set
130# CONFIG_CPU_SUBTYPE_SH7201 is not set
129CONFIG_CPU_SUBTYPE_SH7203=y 131CONFIG_CPU_SUBTYPE_SH7203=y
130# CONFIG_CPU_SUBTYPE_SH7206 is not set 132# CONFIG_CPU_SUBTYPE_SH7206 is not set
131# CONFIG_CPU_SUBTYPE_SH7263 is not set 133# CONFIG_CPU_SUBTYPE_SH7263 is not set
@@ -211,6 +213,8 @@ CONFIG_CPU_HAS_FPU=y
211# 213#
212# Board support 214# Board support
213# 215#
216CONFIG_SH_RSK=y
217# CONFIG_SH_RSK7201 is not set
214CONFIG_SH_RSK7203=y 218CONFIG_SH_RSK7203=y
215 219
216# 220#
@@ -296,6 +300,14 @@ CONFIG_BINFMT_ZFLAT=y
296CONFIG_BINFMT_SHARED_FLAT=y 300CONFIG_BINFMT_SHARED_FLAT=y
297# CONFIG_HAVE_AOUT is not set 301# CONFIG_HAVE_AOUT is not set
298# CONFIG_BINFMT_MISC is not set 302# CONFIG_BINFMT_MISC is not set
303
304#
305# Power management options (EXPERIMENTAL)
306#
307CONFIG_PM=y
308# CONFIG_PM_DEBUG is not set
309CONFIG_CPU_IDLE=y
310CONFIG_CPU_IDLE_GOV_LADDER=y
299CONFIG_NET=y 311CONFIG_NET=y
300 312
301# 313#
@@ -477,6 +489,7 @@ CONFIG_BLK_DEV=y
477CONFIG_MISC_DEVICES=y 489CONFIG_MISC_DEVICES=y
478# CONFIG_EEPROM_93CX6 is not set 490# CONFIG_EEPROM_93CX6 is not set
479# CONFIG_ENCLOSURE_SERVICES is not set 491# CONFIG_ENCLOSURE_SERVICES is not set
492# CONFIG_C2PORT is not set
480CONFIG_HAVE_IDE=y 493CONFIG_HAVE_IDE=y
481# CONFIG_IDE is not set 494# CONFIG_IDE is not set
482 495
@@ -603,11 +616,11 @@ CONFIG_SERIAL_CORE_CONSOLE=y
603# CONFIG_HWMON is not set 616# CONFIG_HWMON is not set
604CONFIG_THERMAL=y 617CONFIG_THERMAL=y
605# CONFIG_WATCHDOG is not set 618# CONFIG_WATCHDOG is not set
619CONFIG_SSB_POSSIBLE=y
606 620
607# 621#
608# Sonics Silicon Backplane 622# Sonics Silicon Backplane
609# 623#
610CONFIG_SSB_POSSIBLE=y
611# CONFIG_SSB is not set 624# CONFIG_SSB is not set
612 625
613# 626#
@@ -617,7 +630,11 @@ CONFIG_SSB_POSSIBLE=y
617# CONFIG_MFD_SM501 is not set 630# CONFIG_MFD_SM501 is not set
618# CONFIG_HTC_PASIC3 is not set 631# CONFIG_HTC_PASIC3 is not set
619# CONFIG_MFD_TMIO is not set 632# CONFIG_MFD_TMIO is not set
620# CONFIG_MFD_WM8400 is not set 633CONFIG_REGULATOR=y
634# CONFIG_REGULATOR_DEBUG is not set
635# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
636# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
637# CONFIG_REGULATOR_BQ24022 is not set
621 638
622# 639#
623# Multimedia devices 640# Multimedia devices
@@ -702,19 +719,22 @@ CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
702CONFIG_USB_DEVICEFS=y 719CONFIG_USB_DEVICEFS=y
703CONFIG_USB_DEVICE_CLASS=y 720CONFIG_USB_DEVICE_CLASS=y
704# CONFIG_USB_DYNAMIC_MINORS is not set 721# CONFIG_USB_DYNAMIC_MINORS is not set
722# CONFIG_USB_SUSPEND is not set
705# CONFIG_USB_OTG is not set 723# CONFIG_USB_OTG is not set
706# CONFIG_USB_OTG_WHITELIST is not set 724# CONFIG_USB_OTG_WHITELIST is not set
707# CONFIG_USB_OTG_BLACKLIST_HUB is not set 725# CONFIG_USB_OTG_BLACKLIST_HUB is not set
708CONFIG_USB_MON=y 726CONFIG_USB_MON=y
727# CONFIG_USB_WUSB is not set
728# CONFIG_USB_WUSB_CBAF is not set
709 729
710# 730#
711# USB Host Controller Drivers 731# USB Host Controller Drivers
712# 732#
713# CONFIG_USB_C67X00_HCD is not set 733# CONFIG_USB_C67X00_HCD is not set
714# CONFIG_USB_ISP116X_HCD is not set 734# CONFIG_USB_ISP116X_HCD is not set
715# CONFIG_USB_ISP1760_HCD is not set
716# CONFIG_USB_SL811_HCD is not set 735# CONFIG_USB_SL811_HCD is not set
717CONFIG_USB_R8A66597_HCD=y 736CONFIG_USB_R8A66597_HCD=y
737# CONFIG_USB_HWA_HCD is not set
718 738
719# 739#
720# USB Device Class drivers 740# USB Device Class drivers
@@ -725,11 +745,11 @@ CONFIG_USB_R8A66597_HCD=y
725# CONFIG_USB_TMC is not set 745# CONFIG_USB_TMC is not set
726 746
727# 747#
728# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' 748# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
729# 749#
730 750
731# 751#
732# may also be needed; see USB_STORAGE Help for more information 752# see USB_STORAGE Help for more information
733# 753#
734# CONFIG_USB_LIBUSUAL is not set 754# CONFIG_USB_LIBUSUAL is not set
735 755
@@ -770,7 +790,22 @@ CONFIG_USB_R8A66597_HCD=y
770# CONFIG_USB_GADGET is not set 790# CONFIG_USB_GADGET is not set
771# CONFIG_MMC is not set 791# CONFIG_MMC is not set
772# CONFIG_MEMSTICK is not set 792# CONFIG_MEMSTICK is not set
773# CONFIG_NEW_LEDS is not set 793CONFIG_NEW_LEDS=y
794CONFIG_LEDS_CLASS=y
795
796#
797# LED drivers
798#
799CONFIG_LEDS_GPIO=y
800
801#
802# LED Triggers
803#
804CONFIG_LEDS_TRIGGERS=y
805CONFIG_LEDS_TRIGGER_TIMER=y
806CONFIG_LEDS_TRIGGER_HEARTBEAT=y
807CONFIG_LEDS_TRIGGER_BACKLIGHT=y
808CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
774# CONFIG_ACCESSIBILITY is not set 809# CONFIG_ACCESSIBILITY is not set
775CONFIG_RTC_LIB=y 810CONFIG_RTC_LIB=y
776CONFIG_RTC_CLASS=y 811CONFIG_RTC_CLASS=y
@@ -812,6 +847,7 @@ CONFIG_RTC_DRV_SH=y
812# CONFIG_DMADEVICES is not set 847# CONFIG_DMADEVICES is not set
813# CONFIG_UIO is not set 848# CONFIG_UIO is not set
814# CONFIG_STAGING is not set 849# CONFIG_STAGING is not set
850CONFIG_STAGING_EXCLUDE_BUILD=y
815 851
816# 852#
817# File systems 853# File systems
@@ -950,9 +986,14 @@ CONFIG_FRAME_POINTER=y
950# CONFIG_FAULT_INJECTION is not set 986# CONFIG_FAULT_INJECTION is not set
951# CONFIG_LATENCYTOP is not set 987# CONFIG_LATENCYTOP is not set
952CONFIG_SYSCTL_SYSCALL_CHECK=y 988CONFIG_SYSCTL_SYSCALL_CHECK=y
953CONFIG_NOP_TRACER=y 989CONFIG_HAVE_FUNCTION_TRACER=y
954CONFIG_HAVE_FTRACE=y 990CONFIG_HAVE_DYNAMIC_FTRACE=y
955# CONFIG_FTRACE is not set 991CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
992
993#
994# Tracers
995#
996# CONFIG_FUNCTION_TRACER is not set
956# CONFIG_SCHED_TRACER is not set 997# CONFIG_SCHED_TRACER is not set
957# CONFIG_CONTEXT_SWITCH_TRACER is not set 998# CONFIG_CONTEXT_SWITCH_TRACER is not set
958# CONFIG_BOOT_TRACER is not set 999# CONFIG_BOOT_TRACER is not set
diff --git a/arch/sh/configs/rts7751r2dplus_qemu_defconfig b/arch/sh/configs/rts7751r2dplus_qemu_defconfig
deleted file mode 100644
index ae8f63000fbf..000000000000
--- a/arch/sh/configs/rts7751r2dplus_qemu_defconfig
+++ /dev/null
@@ -1,949 +0,0 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.27
4# Wed Oct 22 18:51:20 2008
5#
6CONFIG_SUPERH=y
7CONFIG_SUPERH32=y
8CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
9CONFIG_RWSEM_GENERIC_SPINLOCK=y
10CONFIG_GENERIC_BUG=y
11CONFIG_GENERIC_FIND_NEXT_BIT=y
12CONFIG_GENERIC_HWEIGHT=y
13CONFIG_GENERIC_HARDIRQS=y
14CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
15CONFIG_GENERIC_IRQ_PROBE=y
16# CONFIG_GENERIC_GPIO is not set
17CONFIG_GENERIC_TIME=y
18CONFIG_GENERIC_CLOCKEVENTS=y
19CONFIG_SYS_SUPPORTS_PCI=y
20CONFIG_STACKTRACE_SUPPORT=y
21CONFIG_LOCKDEP_SUPPORT=y
22CONFIG_HAVE_LATENCYTOP_SUPPORT=y
23# CONFIG_ARCH_HAS_ILOG2_U32 is not set
24# CONFIG_ARCH_HAS_ILOG2_U64 is not set
25CONFIG_ARCH_NO_VIRT_TO_BUS=y
26CONFIG_IO_TRAPPED=y
27CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
28
29#
30# General setup
31#
32CONFIG_EXPERIMENTAL=y
33CONFIG_BROKEN_ON_SMP=y
34CONFIG_INIT_ENV_ARG_LIMIT=32
35CONFIG_LOCALVERSION=""
36CONFIG_LOCALVERSION_AUTO=y
37CONFIG_SWAP=y
38CONFIG_SYSVIPC=y
39CONFIG_SYSVIPC_SYSCTL=y
40# CONFIG_BSD_PROCESS_ACCT is not set
41CONFIG_IKCONFIG=y
42CONFIG_IKCONFIG_PROC=y
43CONFIG_LOG_BUF_SHIFT=14
44# CONFIG_CGROUPS is not set
45CONFIG_GROUP_SCHED=y
46CONFIG_FAIR_GROUP_SCHED=y
47# CONFIG_RT_GROUP_SCHED is not set
48CONFIG_USER_SCHED=y
49# CONFIG_CGROUP_SCHED is not set
50CONFIG_SYSFS_DEPRECATED=y
51CONFIG_SYSFS_DEPRECATED_V2=y
52# CONFIG_RELAY is not set
53# CONFIG_NAMESPACES is not set
54CONFIG_BLK_DEV_INITRD=y
55CONFIG_INITRAMFS_SOURCE=""
56# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
57CONFIG_SYSCTL=y
58CONFIG_EMBEDDED=y
59CONFIG_UID16=y
60# CONFIG_SYSCTL_SYSCALL is not set
61CONFIG_KALLSYMS=y
62# CONFIG_KALLSYMS_ALL is not set
63# CONFIG_KALLSYMS_EXTRA_PASS is not set
64# CONFIG_HOTPLUG is not set
65CONFIG_PRINTK=y
66CONFIG_BUG=y
67CONFIG_ELF_CORE=y
68CONFIG_COMPAT_BRK=y
69CONFIG_BASE_FULL=y
70CONFIG_FUTEX=y
71CONFIG_ANON_INODES=y
72CONFIG_EPOLL=y
73CONFIG_SIGNALFD=y
74CONFIG_TIMERFD=y
75CONFIG_EVENTFD=y
76CONFIG_SHMEM=y
77CONFIG_AIO=y
78CONFIG_VM_EVENT_COUNTERS=y
79CONFIG_PCI_QUIRKS=y
80CONFIG_SLAB=y
81# CONFIG_SLUB is not set
82# CONFIG_SLOB is not set
83CONFIG_PROFILING=y
84# CONFIG_MARKERS is not set
85CONFIG_OPROFILE=y
86CONFIG_HAVE_OPROFILE=y
87# CONFIG_KPROBES is not set
88CONFIG_HAVE_IOREMAP_PROT=y
89CONFIG_HAVE_KPROBES=y
90CONFIG_HAVE_KRETPROBES=y
91CONFIG_HAVE_ARCH_TRACEHOOK=y
92CONFIG_HAVE_CLK=y
93CONFIG_HAVE_GENERIC_DMA_COHERENT=y
94CONFIG_SLABINFO=y
95CONFIG_RT_MUTEXES=y
96# CONFIG_TINY_SHMEM is not set
97CONFIG_BASE_SMALL=0
98CONFIG_MODULES=y
99# CONFIG_MODULE_FORCE_LOAD is not set
100# CONFIG_MODULE_UNLOAD is not set
101# CONFIG_MODVERSIONS is not set
102# CONFIG_MODULE_SRCVERSION_ALL is not set
103CONFIG_KMOD=y
104CONFIG_BLOCK=y
105# CONFIG_LBD is not set
106# CONFIG_BLK_DEV_IO_TRACE is not set
107# CONFIG_LSF is not set
108# CONFIG_BLK_DEV_BSG is not set
109# CONFIG_BLK_DEV_INTEGRITY is not set
110
111#
112# IO Schedulers
113#
114CONFIG_IOSCHED_NOOP=y
115CONFIG_IOSCHED_AS=y
116CONFIG_IOSCHED_DEADLINE=y
117CONFIG_IOSCHED_CFQ=y
118CONFIG_DEFAULT_AS=y
119# CONFIG_DEFAULT_DEADLINE is not set
120# CONFIG_DEFAULT_CFQ is not set
121# CONFIG_DEFAULT_NOOP is not set
122CONFIG_DEFAULT_IOSCHED="anticipatory"
123CONFIG_CLASSIC_RCU=y
124# CONFIG_FREEZER is not set
125
126#
127# System type
128#
129CONFIG_CPU_SH4=y
130# CONFIG_CPU_SUBTYPE_SH7619 is not set
131# CONFIG_CPU_SUBTYPE_SH7203 is not set
132# CONFIG_CPU_SUBTYPE_SH7206 is not set
133# CONFIG_CPU_SUBTYPE_SH7263 is not set
134# CONFIG_CPU_SUBTYPE_MXG is not set
135# CONFIG_CPU_SUBTYPE_SH7705 is not set
136# CONFIG_CPU_SUBTYPE_SH7706 is not set
137# CONFIG_CPU_SUBTYPE_SH7707 is not set
138# CONFIG_CPU_SUBTYPE_SH7708 is not set
139# CONFIG_CPU_SUBTYPE_SH7709 is not set
140# CONFIG_CPU_SUBTYPE_SH7710 is not set
141# CONFIG_CPU_SUBTYPE_SH7712 is not set
142# CONFIG_CPU_SUBTYPE_SH7720 is not set
143# CONFIG_CPU_SUBTYPE_SH7721 is not set
144# CONFIG_CPU_SUBTYPE_SH7750 is not set
145# CONFIG_CPU_SUBTYPE_SH7091 is not set
146# CONFIG_CPU_SUBTYPE_SH7750R is not set
147# CONFIG_CPU_SUBTYPE_SH7750S is not set
148# CONFIG_CPU_SUBTYPE_SH7751 is not set
149CONFIG_CPU_SUBTYPE_SH7751R=y
150# CONFIG_CPU_SUBTYPE_SH7760 is not set
151# CONFIG_CPU_SUBTYPE_SH4_202 is not set
152# CONFIG_CPU_SUBTYPE_SH7723 is not set
153# CONFIG_CPU_SUBTYPE_SH7763 is not set
154# CONFIG_CPU_SUBTYPE_SH7770 is not set
155# CONFIG_CPU_SUBTYPE_SH7780 is not set
156# CONFIG_CPU_SUBTYPE_SH7785 is not set
157# CONFIG_CPU_SUBTYPE_SHX3 is not set
158# CONFIG_CPU_SUBTYPE_SH7343 is not set
159# CONFIG_CPU_SUBTYPE_SH7722 is not set
160# CONFIG_CPU_SUBTYPE_SH7366 is not set
161# CONFIG_CPU_SUBTYPE_SH5_101 is not set
162# CONFIG_CPU_SUBTYPE_SH5_103 is not set
163
164#
165# Memory management options
166#
167CONFIG_QUICKLIST=y
168CONFIG_MMU=y
169CONFIG_PAGE_OFFSET=0x80000000
170CONFIG_MEMORY_START=0x0c000000
171CONFIG_MEMORY_SIZE=0x04000000
172CONFIG_29BIT=y
173CONFIG_VSYSCALL=y
174CONFIG_ARCH_FLATMEM_ENABLE=y
175CONFIG_ARCH_SPARSEMEM_ENABLE=y
176CONFIG_ARCH_SPARSEMEM_DEFAULT=y
177CONFIG_MAX_ACTIVE_REGIONS=1
178CONFIG_ARCH_POPULATES_NODE_MAP=y
179CONFIG_ARCH_SELECT_MEMORY_MODEL=y
180CONFIG_PAGE_SIZE_4KB=y
181# CONFIG_PAGE_SIZE_8KB is not set
182# CONFIG_PAGE_SIZE_16KB is not set
183# CONFIG_PAGE_SIZE_64KB is not set
184CONFIG_ENTRY_OFFSET=0x00001000
185CONFIG_SELECT_MEMORY_MODEL=y
186CONFIG_FLATMEM_MANUAL=y
187# CONFIG_DISCONTIGMEM_MANUAL is not set
188# CONFIG_SPARSEMEM_MANUAL is not set
189CONFIG_FLATMEM=y
190CONFIG_FLAT_NODE_MEM_MAP=y
191CONFIG_SPARSEMEM_STATIC=y
192CONFIG_PAGEFLAGS_EXTENDED=y
193CONFIG_SPLIT_PTLOCK_CPUS=4
194# CONFIG_RESOURCES_64BIT is not set
195# CONFIG_PHYS_ADDR_T_64BIT is not set
196CONFIG_ZONE_DMA_FLAG=0
197CONFIG_NR_QUICK=2
198CONFIG_UNEVICTABLE_LRU=y
199
200#
201# Cache configuration
202#
203# CONFIG_SH_DIRECT_MAPPED is not set
204CONFIG_CACHE_WRITEBACK=y
205# CONFIG_CACHE_WRITETHROUGH is not set
206# CONFIG_CACHE_OFF is not set
207
208#
209# Processor features
210#
211CONFIG_CPU_LITTLE_ENDIAN=y
212# CONFIG_CPU_BIG_ENDIAN is not set
213CONFIG_SH_FPU=y
214# CONFIG_SH_STORE_QUEUES is not set
215CONFIG_CPU_HAS_INTEVT=y
216CONFIG_CPU_HAS_SR_RB=y
217CONFIG_CPU_HAS_PTEA=y
218CONFIG_CPU_HAS_FPU=y
219
220#
221# Board support
222#
223# CONFIG_SH_7751_SYSTEMH is not set
224# CONFIG_SH_SECUREEDGE5410 is not set
225CONFIG_SH_RTS7751R2D=y
226# CONFIG_SH_LANDISK is not set
227# CONFIG_SH_TITAN is not set
228# CONFIG_SH_LBOX_RE2 is not set
229
230#
231# RTS7751R2D Board Revision
232#
233CONFIG_RTS7751R2D_PLUS=y
234# CONFIG_RTS7751R2D_1 is not set
235
236#
237# Timer and clock configuration
238#
239CONFIG_SH_TMU=y
240CONFIG_SH_TIMER_IRQ=16
241CONFIG_SH_PCLK_FREQ=60000000
242# CONFIG_NO_HZ is not set
243# CONFIG_HIGH_RES_TIMERS is not set
244CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
245
246#
247# CPU Frequency scaling
248#
249# CONFIG_CPU_FREQ is not set
250
251#
252# DMA support
253#
254# CONFIG_SH_DMA is not set
255
256#
257# Companion Chips
258#
259
260#
261# Additional SuperH Device Drivers
262#
263CONFIG_HEARTBEAT=y
264# CONFIG_PUSH_SWITCH is not set
265
266#
267# Kernel features
268#
269# CONFIG_HZ_100 is not set
270CONFIG_HZ_250=y
271# CONFIG_HZ_300 is not set
272# CONFIG_HZ_1000 is not set
273CONFIG_HZ=250
274# CONFIG_SCHED_HRTICK is not set
275# CONFIG_KEXEC is not set
276# CONFIG_CRASH_DUMP is not set
277CONFIG_SECCOMP=y
278CONFIG_PREEMPT_NONE=y
279# CONFIG_PREEMPT_VOLUNTARY is not set
280# CONFIG_PREEMPT is not set
281CONFIG_GUSA=y
282# CONFIG_GUSA_RB is not set
283
284#
285# Boot options
286#
287CONFIG_ZERO_PAGE_OFFSET=0x00010000
288CONFIG_BOOT_LINK_OFFSET=0x00800000
289# CONFIG_UBC_WAKEUP is not set
290CONFIG_CMDLINE_BOOL=y
291CONFIG_CMDLINE="console=tty0 console=ttySC0,115200 root=/dev/sda1 earlyprintk=serial"
292
293#
294# Bus options
295#
296# CONFIG_PCI is not set
297# CONFIG_ARCH_SUPPORTS_MSI is not set
298
299#
300# Executable file formats
301#
302CONFIG_BINFMT_ELF=y
303# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
304# CONFIG_HAVE_AOUT is not set
305# CONFIG_BINFMT_MISC is not set
306# CONFIG_NET is not set
307
308#
309# Device Drivers
310#
311
312#
313# Generic Driver Options
314#
315CONFIG_STANDALONE=y
316CONFIG_PREVENT_FIRMWARE_BUILD=y
317# CONFIG_DEBUG_DRIVER is not set
318# CONFIG_DEBUG_DEVRES is not set
319# CONFIG_SYS_HYPERVISOR is not set
320# CONFIG_MTD is not set
321# CONFIG_PARPORT is not set
322CONFIG_BLK_DEV=y
323# CONFIG_BLK_DEV_COW_COMMON is not set
324# CONFIG_BLK_DEV_LOOP is not set
325CONFIG_BLK_DEV_RAM=y
326CONFIG_BLK_DEV_RAM_COUNT=16
327CONFIG_BLK_DEV_RAM_SIZE=4096
328# CONFIG_BLK_DEV_XIP is not set
329# CONFIG_CDROM_PKTCDVD is not set
330# CONFIG_BLK_DEV_HD is not set
331CONFIG_MISC_DEVICES=y
332# CONFIG_EEPROM_93CX6 is not set
333# CONFIG_ENCLOSURE_SERVICES is not set
334CONFIG_HAVE_IDE=y
335# CONFIG_IDE is not set
336
337#
338# SCSI device support
339#
340# CONFIG_RAID_ATTRS is not set
341CONFIG_SCSI=y
342CONFIG_SCSI_DMA=y
343# CONFIG_SCSI_TGT is not set
344# CONFIG_SCSI_NETLINK is not set
345CONFIG_SCSI_PROC_FS=y
346
347#
348# SCSI support type (disk, tape, CD-ROM)
349#
350CONFIG_BLK_DEV_SD=y
351# CONFIG_CHR_DEV_ST is not set
352# CONFIG_CHR_DEV_OSST is not set
353# CONFIG_BLK_DEV_SR is not set
354# CONFIG_CHR_DEV_SG is not set
355# CONFIG_CHR_DEV_SCH is not set
356
357#
358# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
359#
360# CONFIG_SCSI_MULTI_LUN is not set
361# CONFIG_SCSI_CONSTANTS is not set
362# CONFIG_SCSI_LOGGING is not set
363# CONFIG_SCSI_SCAN_ASYNC is not set
364CONFIG_SCSI_WAIT_SCAN=m
365
366#
367# SCSI Transports
368#
369# CONFIG_SCSI_SPI_ATTRS is not set
370# CONFIG_SCSI_FC_ATTRS is not set
371# CONFIG_SCSI_SAS_LIBSAS is not set
372# CONFIG_SCSI_SRP_ATTRS is not set
373CONFIG_SCSI_LOWLEVEL=y
374# CONFIG_SCSI_DEBUG is not set
375# CONFIG_SCSI_DH is not set
376CONFIG_ATA=y
377# CONFIG_ATA_NONSTANDARD is not set
378CONFIG_SATA_PMP=y
379CONFIG_ATA_SFF=y
380# CONFIG_SATA_MV is not set
381# CONFIG_PATA_PLATFORM is not set
382# CONFIG_MD is not set
383# CONFIG_PHONE is not set
384
385#
386# Input device support
387#
388CONFIG_INPUT=y
389# CONFIG_INPUT_FF_MEMLESS is not set
390# CONFIG_INPUT_POLLDEV is not set
391
392#
393# Userland interfaces
394#
395# CONFIG_INPUT_MOUSEDEV is not set
396# CONFIG_INPUT_JOYDEV is not set
397# CONFIG_INPUT_EVDEV is not set
398# CONFIG_INPUT_EVBUG is not set
399
400#
401# Input Device Drivers
402#
403# CONFIG_INPUT_KEYBOARD is not set
404# CONFIG_INPUT_MOUSE is not set
405# CONFIG_INPUT_JOYSTICK is not set
406# CONFIG_INPUT_TABLET is not set
407# CONFIG_INPUT_TOUCHSCREEN is not set
408# CONFIG_INPUT_MISC is not set
409
410#
411# Hardware I/O ports
412#
413# CONFIG_SERIO is not set
414# CONFIG_GAMEPORT is not set
415
416#
417# Character devices
418#
419CONFIG_VT=y
420CONFIG_CONSOLE_TRANSLATIONS=y
421CONFIG_VT_CONSOLE=y
422CONFIG_HW_CONSOLE=y
423CONFIG_VT_HW_CONSOLE_BINDING=y
424CONFIG_DEVKMEM=y
425# CONFIG_SERIAL_NONSTANDARD is not set
426
427#
428# Serial drivers
429#
430CONFIG_SERIAL_8250=y
431# CONFIG_SERIAL_8250_CONSOLE is not set
432CONFIG_SERIAL_8250_NR_UARTS=4
433CONFIG_SERIAL_8250_RUNTIME_UARTS=4
434# CONFIG_SERIAL_8250_EXTENDED is not set
435
436#
437# Non-8250 serial port support
438#
439CONFIG_SERIAL_SH_SCI=y
440CONFIG_SERIAL_SH_SCI_NR_UARTS=1
441CONFIG_SERIAL_SH_SCI_CONSOLE=y
442CONFIG_SERIAL_CORE=y
443CONFIG_SERIAL_CORE_CONSOLE=y
444CONFIG_UNIX98_PTYS=y
445CONFIG_LEGACY_PTYS=y
446CONFIG_LEGACY_PTY_COUNT=256
447# CONFIG_IPMI_HANDLER is not set
448CONFIG_HW_RANDOM=y
449# CONFIG_R3964 is not set
450# CONFIG_RAW_DRIVER is not set
451# CONFIG_TCG_TPM is not set
452# CONFIG_I2C is not set
453CONFIG_SPI=y
454# CONFIG_SPI_DEBUG is not set
455CONFIG_SPI_MASTER=y
456
457#
458# SPI Master Controller Drivers
459#
460CONFIG_SPI_BITBANG=y
461# CONFIG_SPI_SH_SCI is not set
462
463#
464# SPI Protocol Masters
465#
466# CONFIG_SPI_AT25 is not set
467# CONFIG_SPI_SPIDEV is not set
468# CONFIG_SPI_TLE62X0 is not set
469# CONFIG_W1 is not set
470# CONFIG_POWER_SUPPLY is not set
471CONFIG_HWMON=y
472# CONFIG_HWMON_VID is not set
473# CONFIG_SENSORS_ADCXX is not set
474# CONFIG_SENSORS_F71805F is not set
475# CONFIG_SENSORS_F71882FG is not set
476# CONFIG_SENSORS_IT87 is not set
477# CONFIG_SENSORS_LM70 is not set
478# CONFIG_SENSORS_MAX1111 is not set
479# CONFIG_SENSORS_PC87360 is not set
480# CONFIG_SENSORS_PC87427 is not set
481# CONFIG_SENSORS_SMSC47M1 is not set
482# CONFIG_SENSORS_SMSC47B397 is not set
483# CONFIG_SENSORS_VT1211 is not set
484# CONFIG_SENSORS_W83627HF is not set
485# CONFIG_SENSORS_W83627EHF is not set
486# CONFIG_HWMON_DEBUG_CHIP is not set
487# CONFIG_THERMAL is not set
488# CONFIG_THERMAL_HWMON is not set
489# CONFIG_WATCHDOG is not set
490
491#
492# Sonics Silicon Backplane
493#
494CONFIG_SSB_POSSIBLE=y
495# CONFIG_SSB is not set
496
497#
498# Multifunction device drivers
499#
500# CONFIG_MFD_CORE is not set
501CONFIG_MFD_SM501=y
502# CONFIG_HTC_PASIC3 is not set
503# CONFIG_MFD_TMIO is not set
504# CONFIG_MFD_WM8400 is not set
505
506#
507# Multimedia devices
508#
509
510#
511# Multimedia core support
512#
513# CONFIG_VIDEO_DEV is not set
514# CONFIG_VIDEO_MEDIA is not set
515
516#
517# Multimedia drivers
518#
519CONFIG_DAB=y
520
521#
522# Graphics support
523#
524# CONFIG_VGASTATE is not set
525CONFIG_VIDEO_OUTPUT_CONTROL=m
526CONFIG_FB=y
527# CONFIG_FIRMWARE_EDID is not set
528# CONFIG_FB_DDC is not set
529# CONFIG_FB_BOOT_VESA_SUPPORT is not set
530CONFIG_FB_CFB_FILLRECT=y
531CONFIG_FB_CFB_COPYAREA=y
532CONFIG_FB_CFB_IMAGEBLIT=y
533# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
534# CONFIG_FB_SYS_FILLRECT is not set
535# CONFIG_FB_SYS_COPYAREA is not set
536# CONFIG_FB_SYS_IMAGEBLIT is not set
537# CONFIG_FB_FOREIGN_ENDIAN is not set
538# CONFIG_FB_SYS_FOPS is not set
539# CONFIG_FB_SVGALIB is not set
540# CONFIG_FB_MACMODES is not set
541# CONFIG_FB_BACKLIGHT is not set
542# CONFIG_FB_MODE_HELPERS is not set
543# CONFIG_FB_TILEBLITTING is not set
544
545#
546# Frame buffer hardware drivers
547#
548# CONFIG_FB_S1D13XXX is not set
549CONFIG_FB_SH_MOBILE_LCDC=m
550CONFIG_FB_SM501=y
551# CONFIG_FB_VIRTUAL is not set
552# CONFIG_FB_METRONOME is not set
553# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
554
555#
556# Display device support
557#
558# CONFIG_DISPLAY_SUPPORT is not set
559
560#
561# Console display driver support
562#
563CONFIG_DUMMY_CONSOLE=y
564CONFIG_FRAMEBUFFER_CONSOLE=y
565# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
566# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
567# CONFIG_FONTS is not set
568CONFIG_FONT_8x8=y
569CONFIG_FONT_8x16=y
570CONFIG_LOGO=y
571# CONFIG_LOGO_LINUX_MONO is not set
572# CONFIG_LOGO_LINUX_VGA16 is not set
573# CONFIG_LOGO_LINUX_CLUT224 is not set
574# CONFIG_LOGO_SUPERH_MONO is not set
575# CONFIG_LOGO_SUPERH_VGA16 is not set
576CONFIG_LOGO_SUPERH_CLUT224=y
577CONFIG_SOUND=y
578CONFIG_SOUND_OSS_CORE=y
579CONFIG_SND=m
580# CONFIG_SND_SEQUENCER is not set
581# CONFIG_SND_MIXER_OSS is not set
582# CONFIG_SND_PCM_OSS is not set
583# CONFIG_SND_DYNAMIC_MINORS is not set
584CONFIG_SND_SUPPORT_OLD_API=y
585CONFIG_SND_VERBOSE_PROCFS=y
586# CONFIG_SND_VERBOSE_PRINTK is not set
587# CONFIG_SND_DEBUG is not set
588CONFIG_SND_DRIVERS=y
589# CONFIG_SND_DUMMY is not set
590# CONFIG_SND_MTPAV is not set
591# CONFIG_SND_SERIAL_U16550 is not set
592# CONFIG_SND_MPU401 is not set
593CONFIG_SND_SPI=y
594CONFIG_SND_SUPERH=y
595# CONFIG_SND_SOC is not set
596CONFIG_SOUND_PRIME=m
597CONFIG_HID_SUPPORT=y
598CONFIG_HID=y
599# CONFIG_HID_DEBUG is not set
600# CONFIG_HIDRAW is not set
601# CONFIG_HID_PID is not set
602
603#
604# Special HID drivers
605#
606CONFIG_HID_COMPAT=y
607# CONFIG_USB_SUPPORT is not set
608# CONFIG_MMC is not set
609# CONFIG_MEMSTICK is not set
610# CONFIG_NEW_LEDS is not set
611# CONFIG_ACCESSIBILITY is not set
612CONFIG_RTC_LIB=y
613CONFIG_RTC_CLASS=y
614CONFIG_RTC_HCTOSYS=y
615CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
616# CONFIG_RTC_DEBUG is not set
617
618#
619# RTC interfaces
620#
621CONFIG_RTC_INTF_SYSFS=y
622CONFIG_RTC_INTF_PROC=y
623CONFIG_RTC_INTF_DEV=y
624# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
625# CONFIG_RTC_DRV_TEST is not set
626
627#
628# SPI RTC drivers
629#
630# CONFIG_RTC_DRV_M41T94 is not set
631# CONFIG_RTC_DRV_DS1305 is not set
632# CONFIG_RTC_DRV_MAX6902 is not set
633CONFIG_RTC_DRV_R9701=y
634# CONFIG_RTC_DRV_RS5C348 is not set
635# CONFIG_RTC_DRV_DS3234 is not set
636
637#
638# Platform RTC drivers
639#
640# CONFIG_RTC_DRV_DS1286 is not set
641# CONFIG_RTC_DRV_DS1511 is not set
642# CONFIG_RTC_DRV_DS1553 is not set
643# CONFIG_RTC_DRV_DS1742 is not set
644# CONFIG_RTC_DRV_STK17TA8 is not set
645# CONFIG_RTC_DRV_M48T86 is not set
646# CONFIG_RTC_DRV_M48T35 is not set
647# CONFIG_RTC_DRV_M48T59 is not set
648# CONFIG_RTC_DRV_BQ4802 is not set
649# CONFIG_RTC_DRV_V3020 is not set
650
651#
652# on-CPU RTC drivers
653#
654# CONFIG_RTC_DRV_SH is not set
655# CONFIG_DMADEVICES is not set
656# CONFIG_UIO is not set
657# CONFIG_STAGING is not set
658
659#
660# File systems
661#
662CONFIG_EXT2_FS=y
663# CONFIG_EXT2_FS_XATTR is not set
664# CONFIG_EXT2_FS_XIP is not set
665# CONFIG_EXT3_FS is not set
666# CONFIG_EXT4_FS is not set
667# CONFIG_REISERFS_FS is not set
668# CONFIG_JFS_FS is not set
669# CONFIG_FS_POSIX_ACL is not set
670CONFIG_FILE_LOCKING=y
671# CONFIG_XFS_FS is not set
672CONFIG_DNOTIFY=y
673CONFIG_INOTIFY=y
674CONFIG_INOTIFY_USER=y
675# CONFIG_QUOTA is not set
676# CONFIG_AUTOFS_FS is not set
677# CONFIG_AUTOFS4_FS is not set
678# CONFIG_FUSE_FS is not set
679
680#
681# CD-ROM/DVD Filesystems
682#
683# CONFIG_ISO9660_FS is not set
684# CONFIG_UDF_FS is not set
685
686#
687# DOS/FAT/NT Filesystems
688#
689CONFIG_FAT_FS=y
690CONFIG_MSDOS_FS=y
691CONFIG_VFAT_FS=y
692CONFIG_FAT_DEFAULT_CODEPAGE=437
693CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
694# CONFIG_NTFS_FS is not set
695
696#
697# Pseudo filesystems
698#
699CONFIG_PROC_FS=y
700CONFIG_PROC_KCORE=y
701CONFIG_PROC_SYSCTL=y
702CONFIG_PROC_PAGE_MONITOR=y
703CONFIG_SYSFS=y
704CONFIG_TMPFS=y
705# CONFIG_TMPFS_POSIX_ACL is not set
706# CONFIG_HUGETLBFS is not set
707# CONFIG_HUGETLB_PAGE is not set
708# CONFIG_CONFIGFS_FS is not set
709
710#
711# Miscellaneous filesystems
712#
713# CONFIG_ADFS_FS is not set
714# CONFIG_AFFS_FS is not set
715# CONFIG_HFS_FS is not set
716# CONFIG_HFSPLUS_FS is not set
717# CONFIG_BEFS_FS is not set
718# CONFIG_BFS_FS is not set
719# CONFIG_EFS_FS is not set
720# CONFIG_CRAMFS is not set
721# CONFIG_VXFS_FS is not set
722CONFIG_MINIX_FS=y
723# CONFIG_OMFS_FS is not set
724# CONFIG_HPFS_FS is not set
725# CONFIG_QNX4FS_FS is not set
726# CONFIG_ROMFS_FS is not set
727# CONFIG_SYSV_FS is not set
728# CONFIG_UFS_FS is not set
729
730#
731# Partition Types
732#
733# CONFIG_PARTITION_ADVANCED is not set
734CONFIG_MSDOS_PARTITION=y
735CONFIG_NLS=y
736CONFIG_NLS_DEFAULT="iso8859-1"
737# CONFIG_NLS_CODEPAGE_437 is not set
738# CONFIG_NLS_CODEPAGE_737 is not set
739# CONFIG_NLS_CODEPAGE_775 is not set
740# CONFIG_NLS_CODEPAGE_850 is not set
741# CONFIG_NLS_CODEPAGE_852 is not set
742# CONFIG_NLS_CODEPAGE_855 is not set
743# CONFIG_NLS_CODEPAGE_857 is not set
744# CONFIG_NLS_CODEPAGE_860 is not set
745# CONFIG_NLS_CODEPAGE_861 is not set
746# CONFIG_NLS_CODEPAGE_862 is not set
747# CONFIG_NLS_CODEPAGE_863 is not set
748# CONFIG_NLS_CODEPAGE_864 is not set
749# CONFIG_NLS_CODEPAGE_865 is not set
750# CONFIG_NLS_CODEPAGE_866 is not set
751# CONFIG_NLS_CODEPAGE_869 is not set
752# CONFIG_NLS_CODEPAGE_936 is not set
753# CONFIG_NLS_CODEPAGE_950 is not set
754CONFIG_NLS_CODEPAGE_932=y
755# CONFIG_NLS_CODEPAGE_949 is not set
756# CONFIG_NLS_CODEPAGE_874 is not set
757# CONFIG_NLS_ISO8859_8 is not set
758# CONFIG_NLS_CODEPAGE_1250 is not set
759# CONFIG_NLS_CODEPAGE_1251 is not set
760# CONFIG_NLS_ASCII is not set
761# CONFIG_NLS_ISO8859_1 is not set
762# CONFIG_NLS_ISO8859_2 is not set
763# CONFIG_NLS_ISO8859_3 is not set
764# CONFIG_NLS_ISO8859_4 is not set
765# CONFIG_NLS_ISO8859_5 is not set
766# CONFIG_NLS_ISO8859_6 is not set
767# CONFIG_NLS_ISO8859_7 is not set
768# CONFIG_NLS_ISO8859_9 is not set
769# CONFIG_NLS_ISO8859_13 is not set
770# CONFIG_NLS_ISO8859_14 is not set
771# CONFIG_NLS_ISO8859_15 is not set
772# CONFIG_NLS_KOI8_R is not set
773# CONFIG_NLS_KOI8_U is not set
774# CONFIG_NLS_UTF8 is not set
775
776#
777# Kernel hacking
778#
779CONFIG_TRACE_IRQFLAGS_SUPPORT=y
780# CONFIG_PRINTK_TIME is not set
781CONFIG_ENABLE_WARN_DEPRECATED=y
782CONFIG_ENABLE_MUST_CHECK=y
783CONFIG_FRAME_WARN=1024
784# CONFIG_MAGIC_SYSRQ is not set
785# CONFIG_UNUSED_SYMBOLS is not set
786CONFIG_DEBUG_FS=y
787# CONFIG_HEADERS_CHECK is not set
788CONFIG_DEBUG_KERNEL=y
789# CONFIG_DEBUG_SHIRQ is not set
790CONFIG_DETECT_SOFTLOCKUP=y
791# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
792CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
793CONFIG_SCHED_DEBUG=y
794# CONFIG_SCHEDSTATS is not set
795# CONFIG_TIMER_STATS is not set
796# CONFIG_DEBUG_OBJECTS is not set
797# CONFIG_DEBUG_SLAB is not set
798# CONFIG_DEBUG_RT_MUTEXES is not set
799# CONFIG_RT_MUTEX_TESTER is not set
800# CONFIG_DEBUG_SPINLOCK is not set
801# CONFIG_DEBUG_MUTEXES is not set
802# CONFIG_DEBUG_LOCK_ALLOC is not set
803# CONFIG_PROVE_LOCKING is not set
804# CONFIG_LOCK_STAT is not set
805# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
806# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
807# CONFIG_DEBUG_KOBJECT is not set
808# CONFIG_DEBUG_BUGVERBOSE is not set
809CONFIG_DEBUG_INFO=y
810# CONFIG_DEBUG_VM is not set
811# CONFIG_DEBUG_WRITECOUNT is not set
812# CONFIG_DEBUG_MEMORY_INIT is not set
813# CONFIG_DEBUG_LIST is not set
814# CONFIG_DEBUG_SG is not set
815# CONFIG_FRAME_POINTER is not set
816# CONFIG_RCU_TORTURE_TEST is not set
817# CONFIG_RCU_CPU_STALL_DETECTOR is not set
818# CONFIG_BACKTRACE_SELF_TEST is not set
819# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
820# CONFIG_FAULT_INJECTION is not set
821# CONFIG_LATENCYTOP is not set
822CONFIG_NOP_TRACER=y
823CONFIG_HAVE_FTRACE=y
824# CONFIG_FTRACE is not set
825# CONFIG_IRQSOFF_TRACER is not set
826# CONFIG_SCHED_TRACER is not set
827# CONFIG_CONTEXT_SWITCH_TRACER is not set
828# CONFIG_BOOT_TRACER is not set
829# CONFIG_STACK_TRACER is not set
830# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
831# CONFIG_SAMPLES is not set
832# CONFIG_SH_STANDARD_BIOS is not set
833CONFIG_EARLY_SCIF_CONSOLE=y
834CONFIG_EARLY_SCIF_CONSOLE_PORT=0xffe80000
835CONFIG_EARLY_PRINTK=y
836# CONFIG_DEBUG_BOOTMEM is not set
837# CONFIG_DEBUG_STACKOVERFLOW is not set
838# CONFIG_DEBUG_STACK_USAGE is not set
839# CONFIG_4KSTACKS is not set
840# CONFIG_IRQSTACKS is not set
841# CONFIG_SH_KGDB is not set
842
843#
844# Security options
845#
846# CONFIG_KEYS is not set
847# CONFIG_SECURITY is not set
848# CONFIG_SECURITYFS is not set
849# CONFIG_SECURITY_FILE_CAPABILITIES is not set
850CONFIG_CRYPTO=y
851
852#
853# Crypto core or helper
854#
855# CONFIG_CRYPTO_FIPS is not set
856# CONFIG_CRYPTO_MANAGER is not set
857# CONFIG_CRYPTO_GF128MUL is not set
858# CONFIG_CRYPTO_NULL is not set
859# CONFIG_CRYPTO_CRYPTD is not set
860# CONFIG_CRYPTO_AUTHENC is not set
861# CONFIG_CRYPTO_TEST is not set
862
863#
864# Authenticated Encryption with Associated Data
865#
866# CONFIG_CRYPTO_CCM is not set
867# CONFIG_CRYPTO_GCM is not set
868# CONFIG_CRYPTO_SEQIV is not set
869
870#
871# Block modes
872#
873# CONFIG_CRYPTO_CBC is not set
874# CONFIG_CRYPTO_CTR is not set
875# CONFIG_CRYPTO_CTS is not set
876# CONFIG_CRYPTO_ECB is not set
877# CONFIG_CRYPTO_LRW is not set
878# CONFIG_CRYPTO_PCBC is not set
879# CONFIG_CRYPTO_XTS is not set
880
881#
882# Hash modes
883#
884# CONFIG_CRYPTO_HMAC is not set
885# CONFIG_CRYPTO_XCBC is not set
886
887#
888# Digest
889#
890# CONFIG_CRYPTO_CRC32C is not set
891# CONFIG_CRYPTO_MD4 is not set
892# CONFIG_CRYPTO_MD5 is not set
893# CONFIG_CRYPTO_MICHAEL_MIC is not set
894# CONFIG_CRYPTO_RMD128 is not set
895# CONFIG_CRYPTO_RMD160 is not set
896# CONFIG_CRYPTO_RMD256 is not set
897# CONFIG_CRYPTO_RMD320 is not set
898# CONFIG_CRYPTO_SHA1 is not set
899# CONFIG_CRYPTO_SHA256 is not set
900# CONFIG_CRYPTO_SHA512 is not set
901# CONFIG_CRYPTO_TGR192 is not set
902# CONFIG_CRYPTO_WP512 is not set
903
904#
905# Ciphers
906#
907# CONFIG_CRYPTO_AES is not set
908# CONFIG_CRYPTO_ANUBIS is not set
909# CONFIG_CRYPTO_ARC4 is not set
910# CONFIG_CRYPTO_BLOWFISH is not set
911# CONFIG_CRYPTO_CAMELLIA is not set
912# CONFIG_CRYPTO_CAST5 is not set
913# CONFIG_CRYPTO_CAST6 is not set
914# CONFIG_CRYPTO_DES is not set
915# CONFIG_CRYPTO_FCRYPT is not set
916# CONFIG_CRYPTO_KHAZAD is not set
917# CONFIG_CRYPTO_SALSA20 is not set
918# CONFIG_CRYPTO_SEED is not set
919# CONFIG_CRYPTO_SERPENT is not set
920# CONFIG_CRYPTO_TEA is not set
921# CONFIG_CRYPTO_TWOFISH is not set
922
923#
924# Compression
925#
926# CONFIG_CRYPTO_DEFLATE is not set
927# CONFIG_CRYPTO_LZO is not set
928
929#
930# Random Number Generation
931#
932# CONFIG_CRYPTO_ANSI_CPRNG is not set
933CONFIG_CRYPTO_HW=y
934
935#
936# Library routines
937#
938CONFIG_BITREVERSE=y
939# CONFIG_CRC_CCITT is not set
940# CONFIG_CRC16 is not set
941CONFIG_CRC_T10DIF=y
942# CONFIG_CRC_ITU_T is not set
943CONFIG_CRC32=y
944# CONFIG_CRC7 is not set
945# CONFIG_LIBCRC32C is not set
946CONFIG_PLIST=y
947CONFIG_HAS_IOMEM=y
948CONFIG_HAS_IOPORT=y
949CONFIG_HAS_DMA=y
diff --git a/arch/sh/configs/se7343_defconfig b/arch/sh/configs/se7343_defconfig
index 075f42ed5b09..be246f381507 100644
--- a/arch/sh/configs/se7343_defconfig
+++ b/arch/sh/configs/se7343_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.27 3# Linux kernel version: 2.6.28-rc6
4# Wed Oct 22 19:00:21 2008 4# Thu Dec 4 16:40:25 2008
5# 5#
6CONFIG_SUPERH=y 6CONFIG_SUPERH=y
7CONFIG_SUPERH32=y 7CONFIG_SUPERH32=y
@@ -74,7 +74,6 @@ CONFIG_EVENTFD=y
74# CONFIG_SHMEM is not set 74# CONFIG_SHMEM is not set
75CONFIG_AIO=y 75CONFIG_AIO=y
76CONFIG_VM_EVENT_COUNTERS=y 76CONFIG_VM_EVENT_COUNTERS=y
77CONFIG_PCI_QUIRKS=y
78CONFIG_SLAB=y 77CONFIG_SLAB=y
79# CONFIG_SLUB is not set 78# CONFIG_SLUB is not set
80# CONFIG_SLOB is not set 79# CONFIG_SLOB is not set
@@ -127,6 +126,7 @@ CONFIG_CPU_SH4=y
127CONFIG_CPU_SH4A=y 126CONFIG_CPU_SH4A=y
128CONFIG_CPU_SH4AL_DSP=y 127CONFIG_CPU_SH4AL_DSP=y
129# CONFIG_CPU_SUBTYPE_SH7619 is not set 128# CONFIG_CPU_SUBTYPE_SH7619 is not set
129# CONFIG_CPU_SUBTYPE_SH7201 is not set
130# CONFIG_CPU_SUBTYPE_SH7203 is not set 130# CONFIG_CPU_SUBTYPE_SH7203 is not set
131# CONFIG_CPU_SUBTYPE_SH7206 is not set 131# CONFIG_CPU_SUBTYPE_SH7206 is not set
132# CONFIG_CPU_SUBTYPE_SH7263 is not set 132# CONFIG_CPU_SUBTYPE_SH7263 is not set
@@ -227,7 +227,7 @@ CONFIG_SH_7343_SOLUTION_ENGINE=y
227# 227#
228CONFIG_SH_TMU=y 228CONFIG_SH_TMU=y
229CONFIG_SH_TIMER_IRQ=16 229CONFIG_SH_TIMER_IRQ=16
230CONFIG_SH_PCLK_FREQ=27000000 230CONFIG_SH_PCLK_FREQ=33333333
231# CONFIG_NO_HZ is not set 231# CONFIG_NO_HZ is not set
232# CONFIG_HIGH_RES_TIMERS is not set 232# CONFIG_HIGH_RES_TIMERS is not set
233CONFIG_GENERIC_CLOCKEVENTS_BUILD=y 233CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
@@ -274,7 +274,8 @@ CONFIG_GUSA=y
274# 274#
275CONFIG_ZERO_PAGE_OFFSET=0x00001000 275CONFIG_ZERO_PAGE_OFFSET=0x00001000
276CONFIG_BOOT_LINK_OFFSET=0x00800000 276CONFIG_BOOT_LINK_OFFSET=0x00800000
277# CONFIG_CMDLINE_BOOL is not set 277CONFIG_CMDLINE_BOOL=y
278CONFIG_CMDLINE="console=ttySC0,115200"
278 279
279# 280#
280# Bus options 281# Bus options
@@ -463,6 +464,7 @@ CONFIG_BLK_DEV=y
463# CONFIG_BLK_DEV_COW_COMMON is not set 464# CONFIG_BLK_DEV_COW_COMMON is not set
464# CONFIG_BLK_DEV_LOOP is not set 465# CONFIG_BLK_DEV_LOOP is not set
465# CONFIG_BLK_DEV_NBD is not set 466# CONFIG_BLK_DEV_NBD is not set
467# CONFIG_BLK_DEV_UB is not set
466# CONFIG_BLK_DEV_RAM is not set 468# CONFIG_BLK_DEV_RAM is not set
467# CONFIG_CDROM_PKTCDVD is not set 469# CONFIG_CDROM_PKTCDVD is not set
468# CONFIG_ATA_OVER_ETH is not set 470# CONFIG_ATA_OVER_ETH is not set
@@ -519,23 +521,10 @@ CONFIG_NETDEVICES=y
519# CONFIG_EQUALIZER is not set 521# CONFIG_EQUALIZER is not set
520# CONFIG_TUN is not set 522# CONFIG_TUN is not set
521# CONFIG_VETH is not set 523# CONFIG_VETH is not set
522# CONFIG_PHYLIB is not set 524# CONFIG_NET_ETHERNET is not set
523CONFIG_NET_ETHERNET=y
524CONFIG_MII=y 525CONFIG_MII=y
525# CONFIG_AX88796 is not set 526# CONFIG_NETDEV_1000 is not set
526# CONFIG_STNIC is not set 527# CONFIG_NETDEV_10000 is not set
527CONFIG_SMC91X=y
528# CONFIG_SMC911X is not set
529# CONFIG_IBM_NEW_EMAC_ZMII is not set
530# CONFIG_IBM_NEW_EMAC_RGMII is not set
531# CONFIG_IBM_NEW_EMAC_TAH is not set
532# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
533# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
534# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
535# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
536# CONFIG_B44 is not set
537CONFIG_NETDEV_1000=y
538CONFIG_NETDEV_10000=y
539 528
540# 529#
541# Wireless LAN 530# Wireless LAN
@@ -543,6 +532,26 @@ CONFIG_NETDEV_10000=y
543# CONFIG_WLAN_PRE80211 is not set 532# CONFIG_WLAN_PRE80211 is not set
544# CONFIG_WLAN_80211 is not set 533# CONFIG_WLAN_80211 is not set
545# CONFIG_IWLWIFI_LEDS is not set 534# CONFIG_IWLWIFI_LEDS is not set
535
536#
537# USB Network Adapters
538#
539# CONFIG_USB_CATC is not set
540# CONFIG_USB_KAWETH is not set
541# CONFIG_USB_PEGASUS is not set
542# CONFIG_USB_RTL8150 is not set
543CONFIG_USB_USBNET=y
544# CONFIG_USB_NET_AX8817X is not set
545CONFIG_USB_NET_CDCETHER=y
546CONFIG_USB_NET_DM9601=y
547# CONFIG_USB_NET_SMSC95XX is not set
548# CONFIG_USB_NET_GL620A is not set
549# CONFIG_USB_NET_NET1080 is not set
550# CONFIG_USB_NET_PLUSB is not set
551# CONFIG_USB_NET_MCS7830 is not set
552# CONFIG_USB_NET_RNDIS_HOST is not set
553# CONFIG_USB_NET_CDC_SUBSET is not set
554# CONFIG_USB_NET_ZAURUS is not set
546# CONFIG_WAN is not set 555# CONFIG_WAN is not set
547# CONFIG_PPP is not set 556# CONFIG_PPP is not set
548# CONFIG_SLIP is not set 557# CONFIG_SLIP is not set
@@ -597,13 +606,17 @@ CONFIG_DEVKMEM=y
597# 606#
598# Serial drivers 607# Serial drivers
599# 608#
600# CONFIG_SERIAL_8250 is not set 609CONFIG_SERIAL_8250=y
610# CONFIG_SERIAL_8250_CONSOLE is not set
611CONFIG_SERIAL_8250_NR_UARTS=2
612CONFIG_SERIAL_8250_RUNTIME_UARTS=2
613# CONFIG_SERIAL_8250_EXTENDED is not set
601 614
602# 615#
603# Non-8250 serial port support 616# Non-8250 serial port support
604# 617#
605CONFIG_SERIAL_SH_SCI=y 618CONFIG_SERIAL_SH_SCI=y
606CONFIG_SERIAL_SH_SCI_NR_UARTS=2 619CONFIG_SERIAL_SH_SCI_NR_UARTS=4
607CONFIG_SERIAL_SH_SCI_CONSOLE=y 620CONFIG_SERIAL_SH_SCI_CONSOLE=y
608CONFIG_SERIAL_CORE=y 621CONFIG_SERIAL_CORE=y
609CONFIG_SERIAL_CORE_CONSOLE=y 622CONFIG_SERIAL_CORE_CONSOLE=y
@@ -615,7 +628,51 @@ CONFIG_HW_RANDOM=y
615# CONFIG_R3964 is not set 628# CONFIG_R3964 is not set
616# CONFIG_RAW_DRIVER is not set 629# CONFIG_RAW_DRIVER is not set
617# CONFIG_TCG_TPM is not set 630# CONFIG_TCG_TPM is not set
618# CONFIG_I2C is not set 631CONFIG_I2C=y
632CONFIG_I2C_BOARDINFO=y
633# CONFIG_I2C_CHARDEV is not set
634CONFIG_I2C_HELPER_AUTO=y
635
636#
637# I2C Hardware Bus support
638#
639
640#
641# I2C system bus drivers (mostly embedded / system-on-chip)
642#
643# CONFIG_I2C_OCORES is not set
644CONFIG_I2C_SH_MOBILE=y
645# CONFIG_I2C_SIMTEC is not set
646
647#
648# External I2C/SMBus adapter drivers
649#
650# CONFIG_I2C_PARPORT_LIGHT is not set
651# CONFIG_I2C_TAOS_EVM is not set
652# CONFIG_I2C_TINY_USB is not set
653
654#
655# Other I2C/SMBus bus drivers
656#
657# CONFIG_I2C_PCA_PLATFORM is not set
658# CONFIG_I2C_STUB is not set
659
660#
661# Miscellaneous I2C Chip support
662#
663# CONFIG_DS1682 is not set
664# CONFIG_AT24 is not set
665# CONFIG_SENSORS_EEPROM is not set
666# CONFIG_SENSORS_PCF8574 is not set
667# CONFIG_PCF8575 is not set
668# CONFIG_SENSORS_PCA9539 is not set
669# CONFIG_SENSORS_PCF8591 is not set
670# CONFIG_SENSORS_MAX6875 is not set
671# CONFIG_SENSORS_TSL2550 is not set
672# CONFIG_I2C_DEBUG_CORE is not set
673# CONFIG_I2C_DEBUG_ALGO is not set
674# CONFIG_I2C_DEBUG_BUS is not set
675# CONFIG_I2C_DEBUG_CHIP is not set
619# CONFIG_SPI is not set 676# CONFIG_SPI is not set
620# CONFIG_W1 is not set 677# CONFIG_W1 is not set
621# CONFIG_POWER_SUPPLY is not set 678# CONFIG_POWER_SUPPLY is not set
@@ -623,11 +680,11 @@ CONFIG_HW_RANDOM=y
623# CONFIG_THERMAL is not set 680# CONFIG_THERMAL is not set
624# CONFIG_THERMAL_HWMON is not set 681# CONFIG_THERMAL_HWMON is not set
625# CONFIG_WATCHDOG is not set 682# CONFIG_WATCHDOG is not set
683CONFIG_SSB_POSSIBLE=y
626 684
627# 685#
628# Sonics Silicon Backplane 686# Sonics Silicon Backplane
629# 687#
630CONFIG_SSB_POSSIBLE=y
631# CONFIG_SSB is not set 688# CONFIG_SSB is not set
632 689
633# 690#
@@ -637,7 +694,10 @@ CONFIG_SSB_POSSIBLE=y
637# CONFIG_MFD_SM501 is not set 694# CONFIG_MFD_SM501 is not set
638# CONFIG_HTC_PASIC3 is not set 695# CONFIG_HTC_PASIC3 is not set
639# CONFIG_MFD_TMIO is not set 696# CONFIG_MFD_TMIO is not set
697# CONFIG_PMIC_DA903X is not set
640# CONFIG_MFD_WM8400 is not set 698# CONFIG_MFD_WM8400 is not set
699# CONFIG_MFD_WM8350_I2C is not set
700# CONFIG_REGULATOR is not set
641 701
642# 702#
643# Multimedia devices 703# Multimedia devices
@@ -657,6 +717,16 @@ CONFIG_VIDEO_MEDIA=y
657# Multimedia drivers 717# Multimedia drivers
658# 718#
659# CONFIG_MEDIA_ATTACH is not set 719# CONFIG_MEDIA_ATTACH is not set
720CONFIG_MEDIA_TUNER=y
721# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
722CONFIG_MEDIA_TUNER_SIMPLE=y
723CONFIG_MEDIA_TUNER_TDA8290=y
724CONFIG_MEDIA_TUNER_TDA9887=y
725CONFIG_MEDIA_TUNER_TEA5761=y
726CONFIG_MEDIA_TUNER_TEA5767=y
727CONFIG_MEDIA_TUNER_MT20XX=y
728CONFIG_MEDIA_TUNER_XC2028=y
729CONFIG_MEDIA_TUNER_XC5000=y
660CONFIG_VIDEO_V4L2=y 730CONFIG_VIDEO_V4L2=y
661CONFIG_VIDEO_V4L1=y 731CONFIG_VIDEO_V4L1=y
662CONFIG_VIDEO_CAPTURE_DRIVERS=y 732CONFIG_VIDEO_CAPTURE_DRIVERS=y
@@ -665,8 +735,57 @@ CONFIG_VIDEO_CAPTURE_DRIVERS=y
665CONFIG_VIDEO_HELPER_CHIPS_AUTO=y 735CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
666# CONFIG_VIDEO_VIVI is not set 736# CONFIG_VIDEO_VIVI is not set
667# CONFIG_VIDEO_CPIA is not set 737# CONFIG_VIDEO_CPIA is not set
738# CONFIG_VIDEO_CPIA2 is not set
739# CONFIG_VIDEO_SAA5246A is not set
740# CONFIG_VIDEO_SAA5249 is not set
668# CONFIG_SOC_CAMERA is not set 741# CONFIG_SOC_CAMERA is not set
742CONFIG_V4L_USB_DRIVERS=y
743# CONFIG_USB_VIDEO_CLASS is not set
744CONFIG_USB_GSPCA=m
745# CONFIG_USB_M5602 is not set
746# CONFIG_USB_GSPCA_CONEX is not set
747# CONFIG_USB_GSPCA_ETOMS is not set
748# CONFIG_USB_GSPCA_FINEPIX is not set
749# CONFIG_USB_GSPCA_MARS is not set
750# CONFIG_USB_GSPCA_OV519 is not set
751# CONFIG_USB_GSPCA_PAC207 is not set
752# CONFIG_USB_GSPCA_PAC7311 is not set
753# CONFIG_USB_GSPCA_SONIXB is not set
754# CONFIG_USB_GSPCA_SONIXJ is not set
755# CONFIG_USB_GSPCA_SPCA500 is not set
756# CONFIG_USB_GSPCA_SPCA501 is not set
757# CONFIG_USB_GSPCA_SPCA505 is not set
758# CONFIG_USB_GSPCA_SPCA506 is not set
759# CONFIG_USB_GSPCA_SPCA508 is not set
760# CONFIG_USB_GSPCA_SPCA561 is not set
761# CONFIG_USB_GSPCA_STK014 is not set
762# CONFIG_USB_GSPCA_SUNPLUS is not set
763# CONFIG_USB_GSPCA_T613 is not set
764# CONFIG_USB_GSPCA_TV8532 is not set
765# CONFIG_USB_GSPCA_VC032X is not set
766# CONFIG_USB_GSPCA_ZC3XX is not set
767# CONFIG_VIDEO_PVRUSB2 is not set
768# CONFIG_VIDEO_EM28XX is not set
769# CONFIG_VIDEO_USBVISION is not set
770# CONFIG_USB_VICAM is not set
771# CONFIG_USB_IBMCAM is not set
772# CONFIG_USB_KONICAWC is not set
773# CONFIG_USB_QUICKCAM_MESSENGER is not set
774# CONFIG_USB_ET61X251 is not set
775# CONFIG_VIDEO_OVCAMCHIP is not set
776# CONFIG_USB_OV511 is not set
777# CONFIG_USB_SE401 is not set
778# CONFIG_USB_SN9C102 is not set
779# CONFIG_USB_STV680 is not set
780# CONFIG_USB_ZC0301 is not set
781# CONFIG_USB_PWC is not set
782# CONFIG_USB_ZR364XX is not set
783# CONFIG_USB_STKWEBCAM is not set
784# CONFIG_USB_S2255 is not set
669CONFIG_RADIO_ADAPTERS=y 785CONFIG_RADIO_ADAPTERS=y
786# CONFIG_USB_DSBR is not set
787# CONFIG_USB_SI470X is not set
788# CONFIG_USB_MR800 is not set
670# CONFIG_DAB is not set 789# CONFIG_DAB is not set
671 790
672# 791#
@@ -700,6 +819,7 @@ CONFIG_FB_CFB_IMAGEBLIT=m
700CONFIG_FB_SH_MOBILE_LCDC=m 819CONFIG_FB_SH_MOBILE_LCDC=m
701# CONFIG_FB_VIRTUAL is not set 820# CONFIG_FB_VIRTUAL is not set
702# CONFIG_FB_METRONOME is not set 821# CONFIG_FB_METRONOME is not set
822# CONFIG_FB_MB862XX is not set
703# CONFIG_BACKLIGHT_LCD_SUPPORT is not set 823# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
704 824
705# 825#
@@ -737,27 +857,147 @@ CONFIG_SND_DRIVERS=y
737# CONFIG_SND_SERIAL_U16550 is not set 857# CONFIG_SND_SERIAL_U16550 is not set
738# CONFIG_SND_MPU401 is not set 858# CONFIG_SND_MPU401 is not set
739CONFIG_SND_SUPERH=y 859CONFIG_SND_SUPERH=y
860CONFIG_SND_USB=y
861# CONFIG_SND_USB_AUDIO is not set
862# CONFIG_SND_USB_CAIAQ is not set
740# CONFIG_SND_SOC is not set 863# CONFIG_SND_SOC is not set
741# CONFIG_SOUND_PRIME is not set 864# CONFIG_SOUND_PRIME is not set
742CONFIG_HID_SUPPORT=y 865CONFIG_HID_SUPPORT=y
743CONFIG_HID=y 866CONFIG_HID=y
744# CONFIG_HID_DEBUG is not set 867# CONFIG_HID_DEBUG is not set
745# CONFIG_HIDRAW is not set 868# CONFIG_HIDRAW is not set
869
870#
871# USB Input Devices
872#
873CONFIG_USB_HID=y
746# CONFIG_HID_PID is not set 874# CONFIG_HID_PID is not set
875# CONFIG_USB_HIDDEV is not set
747 876
748# 877#
749# Special HID drivers 878# Special HID drivers
750# 879#
751CONFIG_HID_COMPAT=y 880CONFIG_HID_COMPAT=y
752# CONFIG_USB_SUPPORT is not set 881CONFIG_HID_A4TECH=y
882CONFIG_HID_APPLE=y
883CONFIG_HID_BELKIN=y
884CONFIG_HID_BRIGHT=y
885CONFIG_HID_CHERRY=y
886CONFIG_HID_CHICONY=y
887CONFIG_HID_CYPRESS=y
888CONFIG_HID_DELL=y
889CONFIG_HID_EZKEY=y
890CONFIG_HID_GYRATION=y
891CONFIG_HID_LOGITECH=y
892# CONFIG_LOGITECH_FF is not set
893# CONFIG_LOGIRUMBLEPAD2_FF is not set
894CONFIG_HID_MICROSOFT=y
895CONFIG_HID_MONTEREY=y
896CONFIG_HID_PANTHERLORD=y
897# CONFIG_PANTHERLORD_FF is not set
898CONFIG_HID_PETALYNX=y
899CONFIG_HID_SAMSUNG=y
900CONFIG_HID_SONY=y
901CONFIG_HID_SUNPLUS=y
902# CONFIG_THRUSTMASTER_FF is not set
903# CONFIG_ZEROPLUS_FF is not set
904CONFIG_USB_SUPPORT=y
905CONFIG_USB_ARCH_HAS_HCD=y
906# CONFIG_USB_ARCH_HAS_OHCI is not set
907# CONFIG_USB_ARCH_HAS_EHCI is not set
908CONFIG_USB=y
909CONFIG_USB_DEBUG=y
910CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
911
912#
913# Miscellaneous USB options
914#
915CONFIG_USB_DEVICEFS=y
916CONFIG_USB_DEVICE_CLASS=y
917# CONFIG_USB_DYNAMIC_MINORS is not set
918# CONFIG_USB_OTG is not set
919# CONFIG_USB_OTG_WHITELIST is not set
920# CONFIG_USB_OTG_BLACKLIST_HUB is not set
921# CONFIG_USB_MON is not set
922# CONFIG_USB_WUSB is not set
923# CONFIG_USB_WUSB_CBAF is not set
924
925#
926# USB Host Controller Drivers
927#
928# CONFIG_USB_C67X00_HCD is not set
929CONFIG_USB_ISP116X_HCD=y
930# CONFIG_USB_SL811_HCD is not set
931# CONFIG_USB_R8A66597_HCD is not set
932# CONFIG_USB_HWA_HCD is not set
933
934#
935# USB Device Class drivers
936#
937# CONFIG_USB_ACM is not set
938# CONFIG_USB_PRINTER is not set
939# CONFIG_USB_WDM is not set
940# CONFIG_USB_TMC is not set
941
942#
943# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
944#
945
946#
947# see USB_STORAGE Help for more information
948#
949# CONFIG_USB_STORAGE is not set
950# CONFIG_USB_LIBUSUAL is not set
951
952#
953# USB Imaging devices
954#
955# CONFIG_USB_MDC800 is not set
956# CONFIG_USB_MICROTEK is not set
957
958#
959# USB port drivers
960#
961# CONFIG_USB_SERIAL is not set
962
963#
964# USB Miscellaneous drivers
965#
966# CONFIG_USB_EMI62 is not set
967# CONFIG_USB_EMI26 is not set
968# CONFIG_USB_ADUTUX is not set
969# CONFIG_USB_SEVSEG is not set
970# CONFIG_USB_RIO500 is not set
971# CONFIG_USB_LEGOTOWER is not set
972# CONFIG_USB_LCD is not set
973# CONFIG_USB_BERRY_CHARGE is not set
974# CONFIG_USB_LED is not set
975# CONFIG_USB_CYPRESS_CY7C63 is not set
976# CONFIG_USB_CYTHERM is not set
977# CONFIG_USB_PHIDGET is not set
978# CONFIG_USB_IDMOUSE is not set
979# CONFIG_USB_FTDI_ELAN is not set
980# CONFIG_USB_APPLEDISPLAY is not set
981# CONFIG_USB_LD is not set
982# CONFIG_USB_TRANCEVIBRATOR is not set
983# CONFIG_USB_IOWARRIOR is not set
984# CONFIG_USB_TEST is not set
985# CONFIG_USB_ISIGHTFW is not set
986# CONFIG_USB_VST is not set
987# CONFIG_USB_GADGET is not set
753# CONFIG_MMC is not set 988# CONFIG_MMC is not set
754# CONFIG_MEMSTICK is not set 989# CONFIG_MEMSTICK is not set
755# CONFIG_NEW_LEDS is not set 990# CONFIG_NEW_LEDS is not set
756# CONFIG_ACCESSIBILITY is not set 991# CONFIG_ACCESSIBILITY is not set
757# CONFIG_RTC_CLASS is not set 992# CONFIG_RTC_CLASS is not set
758# CONFIG_DMADEVICES is not set 993# CONFIG_DMADEVICES is not set
759# CONFIG_UIO is not set 994CONFIG_UIO=y
995# CONFIG_UIO_PDRV is not set
996# CONFIG_UIO_PDRV_GENIRQ is not set
997# CONFIG_UIO_SMX is not set
998# CONFIG_UIO_SERCOS3 is not set
760# CONFIG_STAGING is not set 999# CONFIG_STAGING is not set
1000CONFIG_STAGING_EXCLUDE_BUILD=y
761 1001
762# 1002#
763# File systems 1003# File systems
@@ -889,8 +1129,13 @@ CONFIG_FRAME_WARN=1024
889# CONFIG_DEBUG_MEMORY_INIT is not set 1129# CONFIG_DEBUG_MEMORY_INIT is not set
890# CONFIG_RCU_CPU_STALL_DETECTOR is not set 1130# CONFIG_RCU_CPU_STALL_DETECTOR is not set
891# CONFIG_LATENCYTOP is not set 1131# CONFIG_LATENCYTOP is not set
892CONFIG_NOP_TRACER=y 1132CONFIG_HAVE_FUNCTION_TRACER=y
893CONFIG_HAVE_FTRACE=y 1133CONFIG_HAVE_DYNAMIC_FTRACE=y
1134CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
1135
1136#
1137# Tracers
1138#
894# CONFIG_DYNAMIC_PRINTK_DEBUG is not set 1139# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
895# CONFIG_SAMPLES is not set 1140# CONFIG_SAMPLES is not set
896# CONFIG_SH_STANDARD_BIOS is not set 1141# CONFIG_SH_STANDARD_BIOS is not set
diff --git a/arch/sh/drivers/dma/Makefile b/arch/sh/drivers/dma/Makefile
index 1ac812d24488..ab956adacb47 100644
--- a/arch/sh/drivers/dma/Makefile
+++ b/arch/sh/drivers/dma/Makefile
@@ -3,7 +3,6 @@
3# 3#
4 4
5obj-$(CONFIG_SH_DMA_API) += dma-api.o dma-sysfs.o 5obj-$(CONFIG_SH_DMA_API) += dma-api.o dma-sysfs.o
6obj-$(CONFIG_ISA_DMA_API) += dma-isa.o
7obj-$(CONFIG_SH_DMA) += dma-sh.o 6obj-$(CONFIG_SH_DMA) += dma-sh.o
8obj-$(CONFIG_SH_DREAMCAST) += dma-pvr2.o dma-g2.o 7obj-$(CONFIG_SH_DREAMCAST) += dma-pvr2.o dma-g2.o
9obj-$(CONFIG_SH_DMABRG) += dmabrg.o 8obj-$(CONFIG_SH_DMABRG) += dmabrg.o
diff --git a/arch/sh/drivers/dma/dma-isa.c b/arch/sh/drivers/dma/dma-isa.c
deleted file mode 100644
index 5fb044b791c3..000000000000
--- a/arch/sh/drivers/dma/dma-isa.c
+++ /dev/null
@@ -1,106 +0,0 @@
1/*
2 * arch/sh/drivers/dma/dma-isa.c
3 *
4 * Generic ISA DMA wrapper for SH DMA API
5 *
6 * Copyright (C) 2003, 2004 Paul Mundt
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 */
12#include <linux/kernel.h>
13#include <linux/module.h>
14#include <asm/dma.h>
15
16/*
17 * This implements a small wrapper set to make code using the old ISA DMA API
18 * work with the SH DMA API. Since most of the work in the new API happens
19 * at ops->xfer() time, we simply use the various set_dma_xxx() routines to
20 * fill in per-channel info, and then hand hand this off to ops->xfer() at
21 * enable_dma() time.
22 *
23 * For channels that are doing on-demand data transfer via cascading, the
24 * channel itself will still need to be configured through the new API. As
25 * such, this code is meant for only the simplest of tasks (and shouldn't be
26 * used in any new drivers at all).
27 *
28 * NOTE: ops->xfer() is the preferred way of doing things. However, there
29 * are some users of the ISA DMA API that exist in common code that we
30 * don't necessarily want to go out of our way to break, so we still
31 * allow for some compatibility at that level. Any new code is strongly
32 * advised to run far away from the ISA DMA API and use the SH DMA API
33 * directly.
34 */
35unsigned long claim_dma_lock(void)
36{
37 unsigned long flags;
38
39 spin_lock_irqsave(&dma_spin_lock, flags);
40
41 return flags;
42}
43EXPORT_SYMBOL(claim_dma_lock);
44
45void release_dma_lock(unsigned long flags)
46{
47 spin_unlock_irqrestore(&dma_spin_lock, flags);
48}
49EXPORT_SYMBOL(release_dma_lock);
50
51void disable_dma(unsigned int chan)
52{
53 /* Nothing */
54}
55EXPORT_SYMBOL(disable_dma);
56
57void enable_dma(unsigned int chan)
58{
59 struct dma_info *info = get_dma_info(chan);
60 struct dma_channel *channel = &info->channels[chan];
61
62 info->ops->xfer(channel);
63}
64EXPORT_SYMBOL(enable_dma);
65
66void clear_dma_ff(unsigned int chan)
67{
68 /* Nothing */
69}
70EXPORT_SYMBOL(clear_dma_ff);
71
72void set_dma_mode(unsigned int chan, char mode)
73{
74 struct dma_info *info = get_dma_info(chan);
75 struct dma_channel *channel = &info->channels[chan];
76
77 channel->mode = mode;
78}
79EXPORT_SYMBOL(set_dma_mode);
80
81void set_dma_addr(unsigned int chan, unsigned int addr)
82{
83 struct dma_info *info = get_dma_info(chan);
84 struct dma_channel *channel = &info->channels[chan];
85
86 /*
87 * Single address mode is the only thing supported through
88 * this interface.
89 */
90 if ((channel->mode & DMA_MODE_MASK) == DMA_MODE_READ) {
91 channel->sar = addr;
92 } else {
93 channel->dar = addr;
94 }
95}
96EXPORT_SYMBOL(set_dma_addr);
97
98void set_dma_count(unsigned int chan, unsigned int count)
99{
100 struct dma_info *info = get_dma_info(chan);
101 struct dma_channel *channel = &info->channels[chan];
102
103 channel->count = count;
104}
105EXPORT_SYMBOL(set_dma_count);
106
diff --git a/arch/sh/drivers/dma/dma-sh.c b/arch/sh/drivers/dma/dma-sh.c
index b2ffe649c7c0..50887a592dd0 100644
--- a/arch/sh/drivers/dma/dma-sh.c
+++ b/arch/sh/drivers/dma/dma-sh.c
@@ -205,7 +205,8 @@ static int sh_dmac_get_dma_residue(struct dma_channel *chan)
205 205
206#if defined(CONFIG_CPU_SUBTYPE_SH7720) || \ 206#if defined(CONFIG_CPU_SUBTYPE_SH7720) || \
207 defined(CONFIG_CPU_SUBTYPE_SH7721) || \ 207 defined(CONFIG_CPU_SUBTYPE_SH7721) || \
208 defined(CONFIG_CPU_SUBTYPE_SH7780) 208 defined(CONFIG_CPU_SUBTYPE_SH7780) || \
209 defined(CONFIG_CPU_SUBTYPE_SH7709)
209#define dmaor_read_reg() ctrl_inw(DMAOR) 210#define dmaor_read_reg() ctrl_inw(DMAOR)
210#define dmaor_write_reg(data) ctrl_outw(data, DMAOR) 211#define dmaor_write_reg(data) ctrl_outw(data, DMAOR)
211#else 212#else
diff --git a/arch/sh/drivers/dma/dma-sh.h b/arch/sh/drivers/dma/dma-sh.h
index b05af34fc15d..05fecd5428e4 100644
--- a/arch/sh/drivers/dma/dma-sh.h
+++ b/arch/sh/drivers/dma/dma-sh.h
@@ -29,6 +29,7 @@
29#define RS_IN 0x00000200 29#define RS_IN 0x00000200
30#define RS_OUT 0x00000300 30#define RS_OUT 0x00000300
31#define TS_BLK 0x00000040 31#define TS_BLK 0x00000040
32#define TM_BUR 0x00000020
32#define CHCR_DE 0x00000001 33#define CHCR_DE 0x00000001
33#define CHCR_TE 0x00000002 34#define CHCR_TE 0x00000002
34#define CHCR_IE 0x00000004 35#define CHCR_IE 0x00000004
diff --git a/arch/sh/drivers/pci/ops-sh03.c b/arch/sh/drivers/pci/ops-sh03.c
index ebb58e605d9d..e1703ff5a4d2 100644
--- a/arch/sh/drivers/pci/ops-sh03.c
+++ b/arch/sh/drivers/pci/ops-sh03.c
@@ -18,7 +18,8 @@
18 */ 18 */
19int __init pcibios_init_platform(void) 19int __init pcibios_init_platform(void)
20{ 20{
21 return 1; 21 __set_io_port_base(SH7751_PCI_IO_BASE);
22 return 1;
22} 23}
23 24
24static struct resource sh7751_io_resource = { 25static struct resource sh7751_io_resource = {
diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c
index b2a2bfa3c1bd..078dc44d6b08 100644
--- a/arch/sh/drivers/pci/pci-sh7780.c
+++ b/arch/sh/drivers/pci/pci-sh7780.c
@@ -123,16 +123,14 @@ int __init sh7780_pcic_init(struct sh4_pci_address_map *map)
123 * Window0 = map->window0.size @ non-cached area base = SDRAM 123 * Window0 = map->window0.size @ non-cached area base = SDRAM
124 * Window1 = map->window1.size @ cached area base = SDRAM 124 * Window1 = map->window1.size @ cached area base = SDRAM
125 */ 125 */
126 word = ((map->window0.size - 1) & 0x1ff00001) | 0x01; 126 word = (CONFIG_MEMORY_SIZE - 0x00100000) | 0x00000001;
127 pci_write_reg(0x07f00001, SH4_PCILSR0); 127 pci_write_reg(word, SH4_PCILSR0);
128 word = ((map->window1.size - 1) & 0x1ff00001) | 0x01;
129 pci_write_reg(0x00000001, SH4_PCILSR1); 128 pci_write_reg(0x00000001, SH4_PCILSR1);
130 /* Set the values on window 0 PCI config registers */ 129 /* Set the values on window 0 PCI config registers */
131 word = P2SEGADDR(map->window0.base); 130 word = (CONFIG_MEMORY_SIZE > 0x08000000) ? 0x10000000 : 0x08000000;
132 pci_write_reg(0xa8000000, SH4_PCILAR0); 131 pci_write_reg(word | 0xa0000000, SH4_PCILAR0);
133 pci_write_reg(0x08000000, SH7780_PCIMBAR0); 132 pci_write_reg(word, SH7780_PCIMBAR0);
134 /* Set the values on window 1 PCI config registers */ 133 /* Set the values on window 1 PCI config registers */
135 word = P2SEGADDR(map->window1.base);
136 pci_write_reg(0x00000000, SH4_PCILAR1); 134 pci_write_reg(0x00000000, SH4_PCILAR1);
137 pci_write_reg(0x00000000, SH7780_PCIMBAR1); 135 pci_write_reg(0x00000000, SH7780_PCIMBAR1);
138 136
diff --git a/arch/sh/include/asm/addrspace.h b/arch/sh/include/asm/addrspace.h
index 2702d81bfc0d..36736c7e93db 100644
--- a/arch/sh/include/asm/addrspace.h
+++ b/arch/sh/include/asm/addrspace.h
@@ -49,5 +49,16 @@
49/* Check if an address can be reached in 29 bits */ 49/* Check if an address can be reached in 29 bits */
50#define IS_29BIT(a) (((unsigned long)(a)) < 0x20000000) 50#define IS_29BIT(a) (((unsigned long)(a)) < 0x20000000)
51 51
52#ifdef CONFIG_SH_STORE_QUEUES
53/*
54 * This is a special case for the SH-4 store queues, as pages for this
55 * space still need to be faulted in before it's possible to flush the
56 * store queue cache for writeout to the remapped region.
57 */
58#define P3_ADDR_MAX (P4SEG_STORE_QUE + 0x04000000)
59#else
60#define P3_ADDR_MAX P4SEG
61#endif
62
52#endif /* __KERNEL__ */ 63#endif /* __KERNEL__ */
53#endif /* __ASM_SH_ADDRSPACE_H */ 64#endif /* __ASM_SH_ADDRSPACE_H */
diff --git a/arch/sh/include/asm/bitops-grb.h b/arch/sh/include/asm/bitops-grb.h
index a5907b94395b..e73af33acbf4 100644
--- a/arch/sh/include/asm/bitops-grb.h
+++ b/arch/sh/include/asm/bitops-grb.h
@@ -166,4 +166,7 @@ static inline int test_and_change_bit(int nr, volatile void * addr)
166 166
167 return retval; 167 return retval;
168} 168}
169
170#include <asm-generic/bitops/non-atomic.h>
171
169#endif /* __ASM_SH_BITOPS_GRB_H */ 172#endif /* __ASM_SH_BITOPS_GRB_H */
diff --git a/arch/sh/include/asm/bitops-irq.h b/arch/sh/include/asm/bitops-irq.h
deleted file mode 100644
index 653a12750584..000000000000
--- a/arch/sh/include/asm/bitops-irq.h
+++ /dev/null
@@ -1,91 +0,0 @@
1#ifndef __ASM_SH_BITOPS_IRQ_H
2#define __ASM_SH_BITOPS_IRQ_H
3
4static inline void set_bit(int nr, volatile void *addr)
5{
6 int mask;
7 volatile unsigned int *a = addr;
8 unsigned long flags;
9
10 a += nr >> 5;
11 mask = 1 << (nr & 0x1f);
12 local_irq_save(flags);
13 *a |= mask;
14 local_irq_restore(flags);
15}
16
17static inline void clear_bit(int nr, volatile void *addr)
18{
19 int mask;
20 volatile unsigned int *a = addr;
21 unsigned long flags;
22
23 a += nr >> 5;
24 mask = 1 << (nr & 0x1f);
25 local_irq_save(flags);
26 *a &= ~mask;
27 local_irq_restore(flags);
28}
29
30static inline void change_bit(int nr, volatile void *addr)
31{
32 int mask;
33 volatile unsigned int *a = addr;
34 unsigned long flags;
35
36 a += nr >> 5;
37 mask = 1 << (nr & 0x1f);
38 local_irq_save(flags);
39 *a ^= mask;
40 local_irq_restore(flags);
41}
42
43static inline int test_and_set_bit(int nr, volatile void *addr)
44{
45 int mask, retval;
46 volatile unsigned int *a = addr;
47 unsigned long flags;
48
49 a += nr >> 5;
50 mask = 1 << (nr & 0x1f);
51 local_irq_save(flags);
52 retval = (mask & *a) != 0;
53 *a |= mask;
54 local_irq_restore(flags);
55
56 return retval;
57}
58
59static inline int test_and_clear_bit(int nr, volatile void *addr)
60{
61 int mask, retval;
62 volatile unsigned int *a = addr;
63 unsigned long flags;
64
65 a += nr >> 5;
66 mask = 1 << (nr & 0x1f);
67 local_irq_save(flags);
68 retval = (mask & *a) != 0;
69 *a &= ~mask;
70 local_irq_restore(flags);
71
72 return retval;
73}
74
75static inline int test_and_change_bit(int nr, volatile void *addr)
76{
77 int mask, retval;
78 volatile unsigned int *a = addr;
79 unsigned long flags;
80
81 a += nr >> 5;
82 mask = 1 << (nr & 0x1f);
83 local_irq_save(flags);
84 retval = (mask & *a) != 0;
85 *a ^= mask;
86 local_irq_restore(flags);
87
88 return retval;
89}
90
91#endif /* __ASM_SH_BITOPS_IRQ_H */
diff --git a/arch/sh/include/asm/bitops-llsc.h b/arch/sh/include/asm/bitops-llsc.h
index 43b8e1a8239e..1d2fc0b010ad 100644
--- a/arch/sh/include/asm/bitops-llsc.h
+++ b/arch/sh/include/asm/bitops-llsc.h
@@ -141,4 +141,6 @@ static inline int test_and_change_bit(int nr, volatile void * addr)
141 return retval != 0; 141 return retval != 0;
142} 142}
143 143
144#include <asm-generic/bitops/non-atomic.h>
145
144#endif /* __ASM_SH_BITOPS_LLSC_H */ 146#endif /* __ASM_SH_BITOPS_LLSC_H */
diff --git a/arch/sh/include/asm/bitops-op32.h b/arch/sh/include/asm/bitops-op32.h
new file mode 100644
index 000000000000..f0ae7e9218e0
--- /dev/null
+++ b/arch/sh/include/asm/bitops-op32.h
@@ -0,0 +1,142 @@
1#ifndef __ASM_SH_BITOPS_OP32_H
2#define __ASM_SH_BITOPS_OP32_H
3
4/*
5 * The bit modifying instructions on SH-2A are only capable of working
6 * with a 3-bit immediate, which signifies the shift position for the bit
7 * being worked on.
8 */
9#if defined(__BIG_ENDIAN)
10#define BITOP_LE_SWIZZLE ((BITS_PER_LONG-1) & ~0x7)
11#define BYTE_NUMBER(nr) ((nr ^ BITOP_LE_SWIZZLE) / BITS_PER_BYTE)
12#define BYTE_OFFSET(nr) ((nr ^ BITOP_LE_SWIZZLE) % BITS_PER_BYTE)
13#else
14#define BYTE_NUMBER(nr) ((nr) / BITS_PER_BYTE)
15#define BYTE_OFFSET(nr) ((nr) % BITS_PER_BYTE)
16#endif
17
18#define IS_IMMEDIATE(nr) (__builtin_constant_p(nr))
19
20static inline void __set_bit(int nr, volatile unsigned long *addr)
21{
22 if (IS_IMMEDIATE(nr)) {
23 __asm__ __volatile__ (
24 "bset.b %1, @(%O2,%0) ! __set_bit\n\t"
25 : "+r" (addr)
26 : "i" (BYTE_OFFSET(nr)), "i" (BYTE_NUMBER(nr))
27 : "t", "memory"
28 );
29 } else {
30 unsigned long mask = BIT_MASK(nr);
31 unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
32
33 *p |= mask;
34 }
35}
36
37static inline void __clear_bit(int nr, volatile unsigned long *addr)
38{
39 if (IS_IMMEDIATE(nr)) {
40 __asm__ __volatile__ (
41 "bclr.b %1, @(%O2,%0) ! __clear_bit\n\t"
42 : "+r" (addr)
43 : "i" (BYTE_OFFSET(nr)),
44 "i" (BYTE_NUMBER(nr))
45 : "t", "memory"
46 );
47 } else {
48 unsigned long mask = BIT_MASK(nr);
49 unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
50
51 *p &= ~mask;
52 }
53}
54
55/**
56 * __change_bit - Toggle a bit in memory
57 * @nr: the bit to change
58 * @addr: the address to start counting from
59 *
60 * Unlike change_bit(), this function is non-atomic and may be reordered.
61 * If it's called on the same region of memory simultaneously, the effect
62 * may be that only one operation succeeds.
63 */
64static inline void __change_bit(int nr, volatile unsigned long *addr)
65{
66 if (IS_IMMEDIATE(nr)) {
67 __asm__ __volatile__ (
68 "bxor.b %1, @(%O2,%0) ! __change_bit\n\t"
69 : "+r" (addr)
70 : "i" (BYTE_OFFSET(nr)),
71 "i" (BYTE_NUMBER(nr))
72 : "t", "memory"
73 );
74 } else {
75 unsigned long mask = BIT_MASK(nr);
76 unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
77
78 *p ^= mask;
79 }
80}
81
82/**
83 * __test_and_set_bit - Set a bit and return its old value
84 * @nr: Bit to set
85 * @addr: Address to count from
86 *
87 * This operation is non-atomic and can be reordered.
88 * If two examples of this operation race, one can appear to succeed
89 * but actually fail. You must protect multiple accesses with a lock.
90 */
91static inline int __test_and_set_bit(int nr, volatile unsigned long *addr)
92{
93 unsigned long mask = BIT_MASK(nr);
94 unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
95 unsigned long old = *p;
96
97 *p = old | mask;
98 return (old & mask) != 0;
99}
100
101/**
102 * __test_and_clear_bit - Clear a bit and return its old value
103 * @nr: Bit to clear
104 * @addr: Address to count from
105 *
106 * This operation is non-atomic and can be reordered.
107 * If two examples of this operation race, one can appear to succeed
108 * but actually fail. You must protect multiple accesses with a lock.
109 */
110static inline int __test_and_clear_bit(int nr, volatile unsigned long *addr)
111{
112 unsigned long mask = BIT_MASK(nr);
113 unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
114 unsigned long old = *p;
115
116 *p = old & ~mask;
117 return (old & mask) != 0;
118}
119
120/* WARNING: non atomic and it can be reordered! */
121static inline int __test_and_change_bit(int nr,
122 volatile unsigned long *addr)
123{
124 unsigned long mask = BIT_MASK(nr);
125 unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
126 unsigned long old = *p;
127
128 *p = old ^ mask;
129 return (old & mask) != 0;
130}
131
132/**
133 * test_bit - Determine whether a bit is set
134 * @nr: bit number to test
135 * @addr: Address to start counting from
136 */
137static inline int test_bit(int nr, const volatile unsigned long *addr)
138{
139 return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
140}
141
142#endif /* __ASM_SH_BITOPS_OP32_H */
diff --git a/arch/sh/include/asm/bitops.h b/arch/sh/include/asm/bitops.h
index 367930d8e5ae..ebe595b7ab1f 100644
--- a/arch/sh/include/asm/bitops.h
+++ b/arch/sh/include/asm/bitops.h
@@ -13,21 +13,22 @@
13 13
14#ifdef CONFIG_GUSA_RB 14#ifdef CONFIG_GUSA_RB
15#include <asm/bitops-grb.h> 15#include <asm/bitops-grb.h>
16#elif defined(CONFIG_CPU_SH2A)
17#include <asm-generic/bitops/atomic.h>
18#include <asm/bitops-op32.h>
16#elif defined(CONFIG_CPU_SH4A) 19#elif defined(CONFIG_CPU_SH4A)
17#include <asm/bitops-llsc.h> 20#include <asm/bitops-llsc.h>
18#else 21#else
19#include <asm/bitops-irq.h> 22#include <asm-generic/bitops/atomic.h>
23#include <asm-generic/bitops/non-atomic.h>
20#endif 24#endif
21 25
22
23/* 26/*
24 * clear_bit() doesn't provide any barrier for the compiler. 27 * clear_bit() doesn't provide any barrier for the compiler.
25 */ 28 */
26#define smp_mb__before_clear_bit() barrier() 29#define smp_mb__before_clear_bit() barrier()
27#define smp_mb__after_clear_bit() barrier() 30#define smp_mb__after_clear_bit() barrier()
28 31
29#include <asm-generic/bitops/non-atomic.h>
30
31#ifdef CONFIG_SUPERH32 32#ifdef CONFIG_SUPERH32
32static inline unsigned long ffz(unsigned long word) 33static inline unsigned long ffz(unsigned long word)
33{ 34{
diff --git a/arch/sh/include/asm/bugs.h b/arch/sh/include/asm/bugs.h
index 121b2ecddfc3..4924ff6f5439 100644
--- a/arch/sh/include/asm/bugs.h
+++ b/arch/sh/include/asm/bugs.h
@@ -25,7 +25,7 @@ static void __init check_bugs(void)
25 case CPU_SH7619: 25 case CPU_SH7619:
26 *p++ = '2'; 26 *p++ = '2';
27 break; 27 break;
28 case CPU_SH7203 ... CPU_MXG: 28 case CPU_SH7201 ... CPU_MXG:
29 *p++ = '2'; 29 *p++ = '2';
30 *p++ = 'a'; 30 *p++ = 'a';
31 break; 31 break;
diff --git a/arch/sh/include/asm/elf.h b/arch/sh/include/asm/elf.h
index 9eb9036a1bdc..b809f22ea638 100644
--- a/arch/sh/include/asm/elf.h
+++ b/arch/sh/include/asm/elf.h
@@ -108,13 +108,11 @@ typedef struct user_fpu_struct elf_fpregset_t;
108#define elf_check_fdpic(x) ((x)->e_flags & EF_SH_FDPIC) 108#define elf_check_fdpic(x) ((x)->e_flags & EF_SH_FDPIC)
109#define elf_check_const_displacement(x) ((x)->e_flags & EF_SH_PIC) 109#define elf_check_const_displacement(x) ((x)->e_flags & EF_SH_PIC)
110 110
111#ifdef CONFIG_SUPERH32
112/* 111/*
113 * Enable dump using regset. 112 * Enable dump using regset.
114 * This covers all of general/DSP/FPU regs. 113 * This covers all of general/DSP/FPU regs.
115 */ 114 */
116#define CORE_DUMP_USE_REGSET 115#define CORE_DUMP_USE_REGSET
117#endif
118 116
119#define USE_ELF_CORE_DUMP 117#define USE_ELF_CORE_DUMP
120#define ELF_FDPIC_CORE_EFLAGS EF_SH_FDPIC 118#define ELF_FDPIC_CORE_EFLAGS EF_SH_FDPIC
diff --git a/arch/sh/include/asm/ftrace.h b/arch/sh/include/asm/ftrace.h
index 3aed362c9463..8fea7d8c8258 100644
--- a/arch/sh/include/asm/ftrace.h
+++ b/arch/sh/include/asm/ftrace.h
@@ -1,8 +1,34 @@
1#ifndef __ASM_SH_FTRACE_H 1#ifndef __ASM_SH_FTRACE_H
2#define __ASM_SH_FTRACE_H 2#define __ASM_SH_FTRACE_H
3 3
4#ifdef CONFIG_FUNCTION_TRACER
5
6#define MCOUNT_INSN_SIZE 4 /* sizeof mcount call */
7
4#ifndef __ASSEMBLY__ 8#ifndef __ASSEMBLY__
5extern void mcount(void); 9extern void mcount(void);
6#endif 10
11#define MCOUNT_ADDR ((long)(mcount))
12
13#ifdef CONFIG_DYNAMIC_FTRACE
14#define CALLER_ADDR ((long)(ftrace_caller))
15#define STUB_ADDR ((long)(ftrace_stub))
16
17#define MCOUNT_INSN_OFFSET ((STUB_ADDR - CALLER_ADDR) >> 1)
18
19struct dyn_arch_ftrace {
20 /* No extra data needed on sh */
21};
22
23#endif /* CONFIG_DYNAMIC_FTRACE */
24
25static inline unsigned long ftrace_call_adjust(unsigned long addr)
26{
27 /* 'addr' is the memory table address. */
28 return addr;
29}
30
31#endif /* __ASSEMBLY__ */
32#endif /* CONFIG_FUNCTION_TRACER */
7 33
8#endif /* __ASM_SH_FTRACE_H */ 34#endif /* __ASM_SH_FTRACE_H */
diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h
index 65eaae34e753..61f6dae40534 100644
--- a/arch/sh/include/asm/io.h
+++ b/arch/sh/include/asm/io.h
@@ -260,6 +260,10 @@ __ioremap_mode(unsigned long offset, unsigned long size, unsigned long flags)
260 260
261 return (void __iomem *)P2SEGADDR(offset); 261 return (void __iomem *)P2SEGADDR(offset);
262 } 262 }
263
264 /* P4 above the store queues are always mapped. */
265 if (unlikely(offset >= P3_ADDR_MAX))
266 return (void __iomem *)P4SEGADDR(offset);
263#endif 267#endif
264 268
265 return __ioremap(offset, size, flags); 269 return __ioremap(offset, size, flags);
diff --git a/arch/sh/include/asm/kgdb.h b/arch/sh/include/asm/kgdb.h
index 24e42078f36f..72704ed725e5 100644
--- a/arch/sh/include/asm/kgdb.h
+++ b/arch/sh/include/asm/kgdb.h
@@ -1,21 +1,7 @@
1/* 1#ifndef __ASM_SH_KGDB_H
2 * May be copied or modified under the terms of the GNU General Public 2#define __ASM_SH_KGDB_H
3 * License. See linux/COPYING for more information.
4 *
5 * Based on original code by Glenn Engel, Jim Kingdon,
6 * David Grothe <dave@gcom.com>, Tigran Aivazian, <tigran@sco.com> and
7 * Amit S. Kale <akale@veritas.com>
8 *
9 * Super-H port based on sh-stub.c (Ben Lee and Steve Chamberlain) by
10 * Henry Bell <henry.bell@st.com>
11 *
12 * Header file for low-level support for remote debug using GDB.
13 *
14 */
15
16#ifndef __KGDB_H
17#define __KGDB_H
18 3
4#include <asm/cacheflush.h>
19#include <asm/ptrace.h> 5#include <asm/ptrace.h>
20 6
21/* Same as pt_regs but has vbr in place of syscall_nr */ 7/* Same as pt_regs but has vbr in place of syscall_nr */
@@ -30,40 +16,26 @@ struct kgdb_regs {
30 unsigned long vbr; 16 unsigned long vbr;
31}; 17};
32 18
33/* State info */ 19enum regnames {
34extern char kgdb_in_gdb_mode; 20 GDB_R0, GDB_R1, GDB_R2, GDB_R3, GDB_R4, GDB_R5, GDB_R6, GDB_R7,
35extern int kgdb_nofault; /* Ignore bus errors (in gdb mem access) */ 21 GDB_R8, GDB_R9, GDB_R10, GDB_R11, GDB_R12, GDB_R13, GDB_R14, GDB_R15,
36extern char in_nmi; /* Debounce flag to prevent NMI reentry*/
37 22
38/* SCI */ 23 GDB_PC, GDB_PR, GDB_SR, GDB_GBR, GDB_MACH, GDB_MACL, GDB_VBR,
39extern int kgdb_portnum; 24};
40extern int kgdb_baud;
41extern char kgdb_parity;
42extern char kgdb_bits;
43 25
44/* Init and interface stuff */ 26#define NUMREGBYTES ((GDB_VBR + 1) * 4)
45extern int kgdb_init(void);
46extern int (*kgdb_getchar)(void);
47extern void (*kgdb_putchar)(int);
48 27
49/* Trap functions */ 28static inline void arch_kgdb_breakpoint(void)
50typedef void (kgdb_debug_hook_t)(struct pt_regs *regs); 29{
51typedef void (kgdb_bus_error_hook_t)(void); 30 __asm__ __volatile__ ("trapa #0x3c\n");
52extern kgdb_debug_hook_t *kgdb_debug_hook; 31}
53extern kgdb_bus_error_hook_t *kgdb_bus_err_hook;
54 32
55/* Console */ 33/* State info */
56struct console; 34extern char in_nmi; /* Debounce flag to prevent NMI reentry*/
57void kgdb_console_write(struct console *co, const char *s, unsigned count);
58extern int kgdb_console_setup(struct console *, char *);
59 35
60/* Prototypes for jmp fns */ 36#define BUFMAX 2048
61#define _JBLEN 9
62typedef int jmp_buf[_JBLEN];
63extern void longjmp(jmp_buf __jmpb, int __retval);
64extern int setjmp(jmp_buf __jmpb);
65 37
66/* Forced breakpoint */ 38#define CACHE_FLUSH_IS_SAFE 1
67#define breakpoint() __asm__ __volatile__("trapa #0x3c") 39#define BREAK_INSTR_SIZE 2
68 40
69#endif 41#endif /* __ASM_SH_KGDB_H */
diff --git a/arch/sh/include/asm/machvec.h b/arch/sh/include/asm/machvec.h
index f1bae02ef7b6..64b1c16a0f03 100644
--- a/arch/sh/include/asm/machvec.h
+++ b/arch/sh/include/asm/machvec.h
@@ -14,8 +14,6 @@
14#include <linux/time.h> 14#include <linux/time.h>
15#include <asm/machtypes.h> 15#include <asm/machtypes.h>
16 16
17struct device;
18
19struct sh_machine_vector { 17struct sh_machine_vector {
20 void (*mv_setup)(char **cmdline_p); 18 void (*mv_setup)(char **cmdline_p);
21 const char *mv_name; 19 const char *mv_name;
@@ -45,9 +43,6 @@ struct sh_machine_vector {
45 int (*mv_irq_demux)(int irq); 43 int (*mv_irq_demux)(int irq);
46 44
47 void (*mv_init_irq)(void); 45 void (*mv_init_irq)(void);
48 void (*mv_init_pci)(void);
49
50 void (*mv_heartbeat)(void);
51 46
52 void __iomem *(*mv_ioport_map)(unsigned long port, unsigned int size); 47 void __iomem *(*mv_ioport_map)(unsigned long port, unsigned int size);
53 void (*mv_ioport_unmap)(void __iomem *); 48 void (*mv_ioport_unmap)(void __iomem *);
diff --git a/arch/sh/include/asm/mmu_context.h b/arch/sh/include/asm/mmu_context.h
index 04c0c9733ad6..5d9157bd474d 100644
--- a/arch/sh/include/asm/mmu_context.h
+++ b/arch/sh/include/asm/mmu_context.h
@@ -22,7 +22,7 @@
22#define MMU_CONTEXT_ASID_MASK 0x000000ff 22#define MMU_CONTEXT_ASID_MASK 0x000000ff
23#define MMU_CONTEXT_VERSION_MASK 0xffffff00 23#define MMU_CONTEXT_VERSION_MASK 0xffffff00
24#define MMU_CONTEXT_FIRST_VERSION 0x00000100 24#define MMU_CONTEXT_FIRST_VERSION 0x00000100
25#define NO_CONTEXT 0 25#define NO_CONTEXT 0UL
26 26
27/* ASID is 8-bit value, so it can't be 0x100 */ 27/* ASID is 8-bit value, so it can't be 0x100 */
28#define MMU_NO_ASID 0x100 28#define MMU_NO_ASID 0x100
@@ -130,7 +130,7 @@ static inline void switch_mm(struct mm_struct *prev,
130#define destroy_context(mm) do { } while (0) 130#define destroy_context(mm) do { } while (0)
131#define set_asid(asid) do { } while (0) 131#define set_asid(asid) do { } while (0)
132#define get_asid() (0) 132#define get_asid() (0)
133#define cpu_asid(cpu, mm) ({ (void)cpu; 0; }) 133#define cpu_asid(cpu, mm) ({ (void)cpu; NO_CONTEXT; })
134#define switch_and_save_asid(asid) (0) 134#define switch_and_save_asid(asid) (0)
135#define set_TTB(pgd) do { } while (0) 135#define set_TTB(pgd) do { } while (0)
136#define get_TTB() (0) 136#define get_TTB() (0)
diff --git a/arch/sh/include/asm/mutex-llsc.h b/arch/sh/include/asm/mutex-llsc.h
new file mode 100644
index 000000000000..ee839ee58ac8
--- /dev/null
+++ b/arch/sh/include/asm/mutex-llsc.h
@@ -0,0 +1,112 @@
1/*
2 * arch/sh/include/asm/mutex-llsc.h
3 *
4 * SH-4A optimized mutex locking primitives
5 *
6 * Please look into asm-generic/mutex-xchg.h for a formal definition.
7 */
8#ifndef __ASM_SH_MUTEX_LLSC_H
9#define __ASM_SH_MUTEX_LLSC_H
10
11/*
12 * Attempting to lock a mutex on SH4A is done like in ARMv6+ architecure.
13 * with a bastardized atomic decrement (it is not a reliable atomic decrement
14 * but it satisfies the defined semantics for our purpose, while being
15 * smaller and faster than a real atomic decrement or atomic swap.
16 * The idea is to attempt decrementing the lock value only once. If once
17 * decremented it isn't zero, or if its store-back fails due to a dispute
18 * on the exclusive store, we simply bail out immediately through the slow
19 * path where the lock will be reattempted until it succeeds.
20 */
21static inline void
22__mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *))
23{
24 int __ex_flag, __res;
25
26 __asm__ __volatile__ (
27 "movli.l @%2, %0 \n"
28 "add #-1, %0 \n"
29 "movco.l %0, @%2 \n"
30 "movt %1 \n"
31 : "=&z" (__res), "=&r" (__ex_flag)
32 : "r" (&(count)->counter)
33 : "t");
34
35 __res |= !__ex_flag;
36 if (unlikely(__res != 0))
37 fail_fn(count);
38}
39
40static inline int
41__mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
42{
43 int __ex_flag, __res;
44
45 __asm__ __volatile__ (
46 "movli.l @%2, %0 \n"
47 "add #-1, %0 \n"
48 "movco.l %0, @%2 \n"
49 "movt %1 \n"
50 : "=&z" (__res), "=&r" (__ex_flag)
51 : "r" (&(count)->counter)
52 : "t");
53
54 __res |= !__ex_flag;
55 if (unlikely(__res != 0))
56 __res = fail_fn(count);
57
58 return __res;
59}
60
61static inline void
62__mutex_fastpath_unlock(atomic_t *count, void (*fail_fn)(atomic_t *))
63{
64 int __ex_flag, __res;
65
66 __asm__ __volatile__ (
67 "movli.l @%2, %0 \n\t"
68 "add #1, %0 \n\t"
69 "movco.l %0, @%2 \n\t"
70 "movt %1 \n\t"
71 : "=&z" (__res), "=&r" (__ex_flag)
72 : "r" (&(count)->counter)
73 : "t");
74
75 __res |= !__ex_flag;
76 if (unlikely(__res <= 0))
77 fail_fn(count);
78}
79
80/*
81 * If the unlock was done on a contended lock, or if the unlock simply fails
82 * then the mutex remains locked.
83 */
84#define __mutex_slowpath_needs_to_unlock() 1
85
86/*
87 * For __mutex_fastpath_trylock we do an atomic decrement and check the
88 * result and put it in the __res variable.
89 */
90static inline int
91__mutex_fastpath_trylock(atomic_t *count, int (*fail_fn)(atomic_t *))
92{
93 int __res, __orig;
94
95 __asm__ __volatile__ (
96 "1: movli.l @%2, %0 \n\t"
97 "dt %0 \n\t"
98 "movco.l %0,@%2 \n\t"
99 "bf 1b \n\t"
100 "cmp/eq #0,%0 \n\t"
101 "bt 2f \n\t"
102 "mov #0, %1 \n\t"
103 "bf 3f \n\t"
104 "2: mov #1, %1 \n\t"
105 "3: "
106 : "=&z" (__orig), "=&r" (__res)
107 : "r" (&count->counter)
108 : "t");
109
110 return __res;
111}
112#endif /* __ASM_SH_MUTEX_LLSC_H */
diff --git a/arch/sh/include/asm/mutex.h b/arch/sh/include/asm/mutex.h
index 458c1f7fbc18..d8e37716a4a0 100644
--- a/arch/sh/include/asm/mutex.h
+++ b/arch/sh/include/asm/mutex.h
@@ -5,5 +5,8 @@
5 * implementation in place, or pick the atomic_xchg() based generic 5 * implementation in place, or pick the atomic_xchg() based generic
6 * implementation. (see asm-generic/mutex-xchg.h for details) 6 * implementation. (see asm-generic/mutex-xchg.h for details)
7 */ 7 */
8 8#if defined(CONFIG_CPU_SH4A)
9#include <asm/mutex-llsc.h>
10#else
9#include <asm-generic/mutex-dec.h> 11#include <asm-generic/mutex-dec.h>
12#endif
diff --git a/arch/sh/include/asm/pm.h b/arch/sh/include/asm/pm.h
deleted file mode 100644
index 56fdbd6b1c94..000000000000
--- a/arch/sh/include/asm/pm.h
+++ /dev/null
@@ -1,17 +0,0 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright 2006 (c) Andriy Skulysh <askulysh@gmail.com>
7 *
8 */
9#ifndef __ASM_SH_PM_H
10#define __ASM_SH_PM_H
11
12extern u8 wakeup_start;
13extern u8 wakeup_end;
14
15void pm_enter(void);
16
17#endif
diff --git a/arch/sh/include/asm/processor.h b/arch/sh/include/asm/processor.h
index 693364a20ad7..1ef4b24d7619 100644
--- a/arch/sh/include/asm/processor.h
+++ b/arch/sh/include/asm/processor.h
@@ -18,7 +18,7 @@ enum cpu_type {
18 CPU_SH7619, 18 CPU_SH7619,
19 19
20 /* SH-2A types */ 20 /* SH-2A types */
21 CPU_SH7203, CPU_SH7206, CPU_SH7263, CPU_MXG, 21 CPU_SH7201, CPU_SH7203, CPU_SH7206, CPU_SH7263, CPU_MXG,
22 22
23 /* SH-3 types */ 23 /* SH-3 types */
24 CPU_SH7705, CPU_SH7706, CPU_SH7707, 24 CPU_SH7705, CPU_SH7706, CPU_SH7707,
@@ -82,6 +82,9 @@ extern struct sh_cpuinfo cpu_data[];
82#define current_cpu_data cpu_data[smp_processor_id()] 82#define current_cpu_data cpu_data[smp_processor_id()]
83#define raw_current_cpu_data cpu_data[raw_smp_processor_id()] 83#define raw_current_cpu_data cpu_data[raw_smp_processor_id()]
84 84
85#define cpu_sleep() __asm__ __volatile__ ("sleep" : : : "memory")
86#define cpu_relax() barrier()
87
85/* Forward decl */ 88/* Forward decl */
86struct seq_operations; 89struct seq_operations;
87 90
diff --git a/arch/sh/include/asm/processor_32.h b/arch/sh/include/asm/processor_32.h
index a46a0207e977..d79063c5eb9c 100644
--- a/arch/sh/include/asm/processor_32.h
+++ b/arch/sh/include/asm/processor_32.h
@@ -175,6 +175,15 @@ static __inline__ void enable_fpu(void)
175 175
176void show_trace(struct task_struct *tsk, unsigned long *sp, 176void show_trace(struct task_struct *tsk, unsigned long *sp,
177 struct pt_regs *regs); 177 struct pt_regs *regs);
178
179#ifdef CONFIG_DUMP_CODE
180void show_code(struct pt_regs *regs);
181#else
182static inline void show_code(struct pt_regs *regs)
183{
184}
185#endif
186
178extern unsigned long get_wchan(struct task_struct *p); 187extern unsigned long get_wchan(struct task_struct *p);
179 188
180#define KSTK_EIP(tsk) (task_pt_regs(tsk)->pc) 189#define KSTK_EIP(tsk) (task_pt_regs(tsk)->pc)
@@ -182,9 +191,6 @@ extern unsigned long get_wchan(struct task_struct *p);
182 191
183#define user_stack_pointer(regs) ((regs)->regs[15]) 192#define user_stack_pointer(regs) ((regs)->regs[15])
184 193
185#define cpu_sleep() __asm__ __volatile__ ("sleep" : : : "memory")
186#define cpu_relax() barrier()
187
188#if defined(CONFIG_CPU_SH2A) || defined(CONFIG_CPU_SH3) || \ 194#if defined(CONFIG_CPU_SH2A) || defined(CONFIG_CPU_SH3) || \
189 defined(CONFIG_CPU_SH4) 195 defined(CONFIG_CPU_SH4)
190#define PREFETCH_STRIDE L1_CACHE_BYTES 196#define PREFETCH_STRIDE L1_CACHE_BYTES
diff --git a/arch/sh/include/asm/processor_64.h b/arch/sh/include/asm/processor_64.h
index b0b4824dfc4c..803177fcf086 100644
--- a/arch/sh/include/asm/processor_64.h
+++ b/arch/sh/include/asm/processor_64.h
@@ -226,9 +226,7 @@ extern unsigned long get_wchan(struct task_struct *p);
226#define KSTK_EIP(tsk) ((tsk)->thread.pc) 226#define KSTK_EIP(tsk) ((tsk)->thread.pc)
227#define KSTK_ESP(tsk) ((tsk)->thread.sp) 227#define KSTK_ESP(tsk) ((tsk)->thread.sp)
228 228
229#define user_stack_pointer(regs) ((regs)->sp) 229#define user_stack_pointer(regs) ((regs)->regs[15])
230
231#define cpu_relax() barrier()
232 230
233#endif /* __ASSEMBLY__ */ 231#endif /* __ASSEMBLY__ */
234#endif /* __ASM_SH_PROCESSOR_64_H */ 232#endif /* __ASM_SH_PROCESSOR_64_H */
diff --git a/arch/sh/include/asm/ptrace.h b/arch/sh/include/asm/ptrace.h
index 3ad18e91bca6..12912ab80c15 100644
--- a/arch/sh/include/asm/ptrace.h
+++ b/arch/sh/include/asm/ptrace.h
@@ -86,6 +86,7 @@ struct pt_dspregs {
86 unsigned long re; 86 unsigned long re;
87 unsigned long mod; 87 unsigned long mod;
88}; 88};
89#endif
89 90
90#define PTRACE_GETREGS 12 /* General registers */ 91#define PTRACE_GETREGS 12 /* General registers */
91#define PTRACE_SETREGS 13 92#define PTRACE_SETREGS 13
@@ -100,7 +101,6 @@ struct pt_dspregs {
100 101
101#define PTRACE_GETDSPREGS 55 /* DSP registers */ 102#define PTRACE_GETDSPREGS 55 /* DSP registers */
102#define PTRACE_SETDSPREGS 56 103#define PTRACE_SETDSPREGS 56
103#endif
104 104
105#ifdef __KERNEL__ 105#ifdef __KERNEL__
106#include <asm/addrspace.h> 106#include <asm/addrspace.h>
diff --git a/arch/sh/include/asm/sh_bios.h b/arch/sh/include/asm/sh_bios.h
index 0ca261956e3d..d9c96d7cf6c7 100644
--- a/arch/sh/include/asm/sh_bios.h
+++ b/arch/sh/include/asm/sh_bios.h
@@ -10,7 +10,6 @@
10 10
11extern void sh_bios_console_write(const char *buf, unsigned int len); 11extern void sh_bios_console_write(const char *buf, unsigned int len);
12extern void sh_bios_char_out(char ch); 12extern void sh_bios_char_out(char ch);
13extern int sh_bios_in_gdb_mode(void);
14extern void sh_bios_gdb_detach(void); 13extern void sh_bios_gdb_detach(void);
15 14
16extern void sh_bios_get_node_addr(unsigned char *node_addr); 15extern void sh_bios_get_node_addr(unsigned char *node_addr);
diff --git a/arch/sh/include/asm/string_64.h b/arch/sh/include/asm/string_64.h
index aa1fef229c78..742007172624 100644
--- a/arch/sh/include/asm/string_64.h
+++ b/arch/sh/include/asm/string_64.h
@@ -1,17 +1,20 @@
1#ifndef __ASM_SH_STRING_64_H 1#ifndef __ASM_SH_STRING_64_H
2#define __ASM_SH_STRING_64_H 2#define __ASM_SH_STRING_64_H
3 3
4/* 4#ifdef __KERNEL__
5 * include/asm-sh/string_64.h 5
6 * 6#define __HAVE_ARCH_MEMSET
7 * Copyright (C) 2000, 2001 Paolo Alberelli 7extern void *memset(void *__s, int __c, size_t __count);
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file "COPYING" in the main directory of this archive
11 * for more details.
12 */
13 8
14#define __HAVE_ARCH_MEMCPY 9#define __HAVE_ARCH_MEMCPY
15extern void *memcpy(void *dest, const void *src, size_t count); 10extern void *memcpy(void *dest, const void *src, size_t count);
16 11
12#define __HAVE_ARCH_STRLEN
13extern size_t strlen(const char *);
14
15#define __HAVE_ARCH_STRCPY
16extern char *strcpy(char *__dest, const char *__src);
17
18#endif /* __KERNEL__ */
19
17#endif /* __ASM_SH_STRING_64_H */ 20#endif /* __ASM_SH_STRING_64_H */
diff --git a/arch/sh/include/asm/syscall_32.h b/arch/sh/include/asm/syscall_32.h
index 54773f26cd44..05a868a71ef5 100644
--- a/arch/sh/include/asm/syscall_32.h
+++ b/arch/sh/include/asm/syscall_32.h
@@ -5,7 +5,7 @@
5#include <linux/sched.h> 5#include <linux/sched.h>
6#include <asm/ptrace.h> 6#include <asm/ptrace.h>
7 7
8/* The system call number is given by the user in %g1 */ 8/* The system call number is given by the user in R3 */
9static inline long syscall_get_nr(struct task_struct *task, 9static inline long syscall_get_nr(struct task_struct *task,
10 struct pt_regs *regs) 10 struct pt_regs *regs)
11{ 11{
diff --git a/arch/sh/include/asm/syscall_64.h b/arch/sh/include/asm/syscall_64.h
index bcaaa8ca4d70..e1143b9784d6 100644
--- a/arch/sh/include/asm/syscall_64.h
+++ b/arch/sh/include/asm/syscall_64.h
@@ -1,6 +1,80 @@
1#ifndef __ASM_SH_SYSCALL_64_H 1#ifndef __ASM_SH_SYSCALL_64_H
2#define __ASM_SH_SYSCALL_64_H 2#define __ASM_SH_SYSCALL_64_H
3 3
4#include <asm-generic/syscall.h> 4#include <linux/kernel.h>
5#include <linux/sched.h>
6#include <asm/ptrace.h>
7
8/* The system call number is given by the user in R9 */
9static inline long syscall_get_nr(struct task_struct *task,
10 struct pt_regs *regs)
11{
12 return (regs->syscall_nr >= 0) ? regs->regs[9] : -1L;
13}
14
15static inline void syscall_rollback(struct task_struct *task,
16 struct pt_regs *regs)
17{
18 /*
19 * XXX: This needs some thought. On SH we don't
20 * save away the original R9 value anywhere.
21 */
22}
23
24static inline bool syscall_has_error(struct pt_regs *regs)
25{
26 return (regs->sr & 0x1) ? true : false;
27}
28static inline void syscall_set_error(struct pt_regs *regs)
29{
30 regs->sr |= 0x1;
31}
32static inline void syscall_clear_error(struct pt_regs *regs)
33{
34 regs->sr &= ~0x1;
35}
36
37static inline long syscall_get_error(struct task_struct *task,
38 struct pt_regs *regs)
39{
40 return syscall_has_error(regs) ? regs->regs[9] : 0;
41}
42
43static inline long syscall_get_return_value(struct task_struct *task,
44 struct pt_regs *regs)
45{
46 return regs->regs[9];
47}
48
49static inline void syscall_set_return_value(struct task_struct *task,
50 struct pt_regs *regs,
51 int error, long val)
52{
53 if (error) {
54 syscall_set_error(regs);
55 regs->regs[9] = -error;
56 } else {
57 syscall_clear_error(regs);
58 regs->regs[9] = val;
59 }
60}
61
62static inline void syscall_get_arguments(struct task_struct *task,
63 struct pt_regs *regs,
64 unsigned int i, unsigned int n,
65 unsigned long *args)
66{
67 BUG_ON(i + n > 6);
68 memcpy(args, &regs->regs[2 + i], n * sizeof(args[0]));
69}
70
71static inline void syscall_set_arguments(struct task_struct *task,
72 struct pt_regs *regs,
73 unsigned int i, unsigned int n,
74 const unsigned long *args)
75{
76 BUG_ON(i + n > 6);
77 memcpy(&regs->regs[2 + i], args, n * sizeof(args[0]));
78}
5 79
6#endif /* __ASM_SH_SYSCALL_64_H */ 80#endif /* __ASM_SH_SYSCALL_64_H */
diff --git a/arch/sh/include/asm/system.h b/arch/sh/include/asm/system.h
index 6160fe445161..c9ec6af8e745 100644
--- a/arch/sh/include/asm/system.h
+++ b/arch/sh/include/asm/system.h
@@ -175,6 +175,8 @@ asmlinkage void name##_trap_handler(unsigned int vec, struct pt_regs *regs)
175BUILD_TRAP_HANDLER(address_error); 175BUILD_TRAP_HANDLER(address_error);
176BUILD_TRAP_HANDLER(debug); 176BUILD_TRAP_HANDLER(debug);
177BUILD_TRAP_HANDLER(bug); 177BUILD_TRAP_HANDLER(bug);
178BUILD_TRAP_HANDLER(breakpoint);
179BUILD_TRAP_HANDLER(singlestep);
178BUILD_TRAP_HANDLER(fpu_error); 180BUILD_TRAP_HANDLER(fpu_error);
179BUILD_TRAP_HANDLER(fpu_state_restore); 181BUILD_TRAP_HANDLER(fpu_state_restore);
180 182
diff --git a/arch/sh/include/asm/unaligned-sh4a.h b/arch/sh/include/asm/unaligned-sh4a.h
new file mode 100644
index 000000000000..d8f89770275b
--- /dev/null
+++ b/arch/sh/include/asm/unaligned-sh4a.h
@@ -0,0 +1,258 @@
1#ifndef __ASM_SH_UNALIGNED_SH4A_H
2#define __ASM_SH_UNALIGNED_SH4A_H
3
4/*
5 * SH-4A has support for unaligned 32-bit loads, and 32-bit loads only.
6 * Support for 16 and 64-bit accesses are done through shifting and
7 * masking relative to the endianness. Unaligned stores are not supported
8 * by the instruction encoding, so these continue to use the packed
9 * struct.
10 *
11 * The same note as with the movli.l/movco.l pair applies here, as long
12 * as the load is gauranteed to be inlined, nothing else will hook in to
13 * r0 and we get the return value for free.
14 *
15 * NOTE: Due to the fact we require r0 encoding, care should be taken to
16 * avoid mixing these heavily with other r0 consumers, such as the atomic
17 * ops. Failure to adhere to this can result in the compiler running out
18 * of spill registers and blowing up when building at low optimization
19 * levels. See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34777.
20 */
21#include <linux/types.h>
22#include <asm/byteorder.h>
23
24static __always_inline u32 __get_unaligned_cpu32(const u8 *p)
25{
26 unsigned long unaligned;
27
28 __asm__ __volatile__ (
29 "movua.l @%1, %0\n\t"
30 : "=z" (unaligned)
31 : "r" (p)
32 );
33
34 return unaligned;
35}
36
37struct __una_u16 { u16 x __attribute__((packed)); };
38struct __una_u32 { u32 x __attribute__((packed)); };
39struct __una_u64 { u64 x __attribute__((packed)); };
40
41static inline u16 __get_unaligned_cpu16(const u8 *p)
42{
43#ifdef __LITTLE_ENDIAN
44 return __get_unaligned_cpu32(p) & 0xffff;
45#else
46 return __get_unaligned_cpu32(p) >> 16;
47#endif
48}
49
50/*
51 * Even though movua.l supports auto-increment on the read side, it can
52 * only store to r0 due to instruction encoding constraints, so just let
53 * the compiler sort it out on its own.
54 */
55static inline u64 __get_unaligned_cpu64(const u8 *p)
56{
57#ifdef __LITTLE_ENDIAN
58 return (u64)__get_unaligned_cpu32(p + 4) << 32 |
59 __get_unaligned_cpu32(p);
60#else
61 return (u64)__get_unaligned_cpu32(p) << 32 |
62 __get_unaligned_cpu32(p + 4);
63#endif
64}
65
66static inline u16 get_unaligned_le16(const void *p)
67{
68 return le16_to_cpu(__get_unaligned_cpu16(p));
69}
70
71static inline u32 get_unaligned_le32(const void *p)
72{
73 return le32_to_cpu(__get_unaligned_cpu32(p));
74}
75
76static inline u64 get_unaligned_le64(const void *p)
77{
78 return le64_to_cpu(__get_unaligned_cpu64(p));
79}
80
81static inline u16 get_unaligned_be16(const void *p)
82{
83 return be16_to_cpu(__get_unaligned_cpu16(p));
84}
85
86static inline u32 get_unaligned_be32(const void *p)
87{
88 return be32_to_cpu(__get_unaligned_cpu32(p));
89}
90
91static inline u64 get_unaligned_be64(const void *p)
92{
93 return be64_to_cpu(__get_unaligned_cpu64(p));
94}
95
96static inline void __put_le16_noalign(u8 *p, u16 val)
97{
98 *p++ = val;
99 *p++ = val >> 8;
100}
101
102static inline void __put_le32_noalign(u8 *p, u32 val)
103{
104 __put_le16_noalign(p, val);
105 __put_le16_noalign(p + 2, val >> 16);
106}
107
108static inline void __put_le64_noalign(u8 *p, u64 val)
109{
110 __put_le32_noalign(p, val);
111 __put_le32_noalign(p + 4, val >> 32);
112}
113
114static inline void __put_be16_noalign(u8 *p, u16 val)
115{
116 *p++ = val >> 8;
117 *p++ = val;
118}
119
120static inline void __put_be32_noalign(u8 *p, u32 val)
121{
122 __put_be16_noalign(p, val >> 16);
123 __put_be16_noalign(p + 2, val);
124}
125
126static inline void __put_be64_noalign(u8 *p, u64 val)
127{
128 __put_be32_noalign(p, val >> 32);
129 __put_be32_noalign(p + 4, val);
130}
131
132static inline void put_unaligned_le16(u16 val, void *p)
133{
134#ifdef __LITTLE_ENDIAN
135 ((struct __una_u16 *)p)->x = val;
136#else
137 __put_le16_noalign(p, val);
138#endif
139}
140
141static inline void put_unaligned_le32(u32 val, void *p)
142{
143#ifdef __LITTLE_ENDIAN
144 ((struct __una_u32 *)p)->x = val;
145#else
146 __put_le32_noalign(p, val);
147#endif
148}
149
150static inline void put_unaligned_le64(u64 val, void *p)
151{
152#ifdef __LITTLE_ENDIAN
153 ((struct __una_u64 *)p)->x = val;
154#else
155 __put_le64_noalign(p, val);
156#endif
157}
158
159static inline void put_unaligned_be16(u16 val, void *p)
160{
161#ifdef __BIG_ENDIAN
162 ((struct __una_u16 *)p)->x = val;
163#else
164 __put_be16_noalign(p, val);
165#endif
166}
167
168static inline void put_unaligned_be32(u32 val, void *p)
169{
170#ifdef __BIG_ENDIAN
171 ((struct __una_u32 *)p)->x = val;
172#else
173 __put_be32_noalign(p, val);
174#endif
175}
176
177static inline void put_unaligned_be64(u64 val, void *p)
178{
179#ifdef __BIG_ENDIAN
180 ((struct __una_u64 *)p)->x = val;
181#else
182 __put_be64_noalign(p, val);
183#endif
184}
185
186/*
187 * Cause a link-time error if we try an unaligned access other than
188 * 1,2,4 or 8 bytes long
189 */
190extern void __bad_unaligned_access_size(void);
191
192#define __get_unaligned_le(ptr) ((__force typeof(*(ptr)))({ \
193 __builtin_choose_expr(sizeof(*(ptr)) == 1, *(ptr), \
194 __builtin_choose_expr(sizeof(*(ptr)) == 2, get_unaligned_le16((ptr)), \
195 __builtin_choose_expr(sizeof(*(ptr)) == 4, get_unaligned_le32((ptr)), \
196 __builtin_choose_expr(sizeof(*(ptr)) == 8, get_unaligned_le64((ptr)), \
197 __bad_unaligned_access_size())))); \
198 }))
199
200#define __get_unaligned_be(ptr) ((__force typeof(*(ptr)))({ \
201 __builtin_choose_expr(sizeof(*(ptr)) == 1, *(ptr), \
202 __builtin_choose_expr(sizeof(*(ptr)) == 2, get_unaligned_be16((ptr)), \
203 __builtin_choose_expr(sizeof(*(ptr)) == 4, get_unaligned_be32((ptr)), \
204 __builtin_choose_expr(sizeof(*(ptr)) == 8, get_unaligned_be64((ptr)), \
205 __bad_unaligned_access_size())))); \
206 }))
207
208#define __put_unaligned_le(val, ptr) ({ \
209 void *__gu_p = (ptr); \
210 switch (sizeof(*(ptr))) { \
211 case 1: \
212 *(u8 *)__gu_p = (__force u8)(val); \
213 break; \
214 case 2: \
215 put_unaligned_le16((__force u16)(val), __gu_p); \
216 break; \
217 case 4: \
218 put_unaligned_le32((__force u32)(val), __gu_p); \
219 break; \
220 case 8: \
221 put_unaligned_le64((__force u64)(val), __gu_p); \
222 break; \
223 default: \
224 __bad_unaligned_access_size(); \
225 break; \
226 } \
227 (void)0; })
228
229#define __put_unaligned_be(val, ptr) ({ \
230 void *__gu_p = (ptr); \
231 switch (sizeof(*(ptr))) { \
232 case 1: \
233 *(u8 *)__gu_p = (__force u8)(val); \
234 break; \
235 case 2: \
236 put_unaligned_be16((__force u16)(val), __gu_p); \
237 break; \
238 case 4: \
239 put_unaligned_be32((__force u32)(val), __gu_p); \
240 break; \
241 case 8: \
242 put_unaligned_be64((__force u64)(val), __gu_p); \
243 break; \
244 default: \
245 __bad_unaligned_access_size(); \
246 break; \
247 } \
248 (void)0; })
249
250#ifdef __LITTLE_ENDIAN
251# define get_unaligned __get_unaligned_le
252# define put_unaligned __put_unaligned_le
253#else
254# define get_unaligned __get_unaligned_be
255# define put_unaligned __put_unaligned_be
256#endif
257
258#endif /* __ASM_SH_UNALIGNED_SH4A_H */
diff --git a/arch/sh/include/asm/unaligned.h b/arch/sh/include/asm/unaligned.h
index c1641a01d50f..8c0ad5e4487a 100644
--- a/arch/sh/include/asm/unaligned.h
+++ b/arch/sh/include/asm/unaligned.h
@@ -1,7 +1,11 @@
1#ifndef _ASM_SH_UNALIGNED_H 1#ifndef _ASM_SH_UNALIGNED_H
2#define _ASM_SH_UNALIGNED_H 2#define _ASM_SH_UNALIGNED_H
3 3
4/* SH can't handle unaligned accesses. */ 4#ifdef CONFIG_CPU_SH4A
5/* SH-4A can handle unaligned loads in a relatively neutered fashion. */
6#include <asm/unaligned-sh4a.h>
7#else
8/* Otherwise, SH can't handle unaligned accesses. */
5#ifdef __LITTLE_ENDIAN__ 9#ifdef __LITTLE_ENDIAN__
6# include <linux/unaligned/le_struct.h> 10# include <linux/unaligned/le_struct.h>
7# include <linux/unaligned/be_byteshift.h> 11# include <linux/unaligned/be_byteshift.h>
@@ -15,5 +19,6 @@
15# define get_unaligned __get_unaligned_be 19# define get_unaligned __get_unaligned_be
16# define put_unaligned __put_unaligned_be 20# define put_unaligned __put_unaligned_be
17#endif 21#endif
22#endif
18 23
19#endif /* _ASM_SH_UNALIGNED_H */ 24#endif /* _ASM_SH_UNALIGNED_H */
diff --git a/arch/sh/include/cpu-sh3/cpu/gpio.h b/arch/sh/include/cpu-sh3/cpu/gpio.h
index 4e53eb314b8f..9a22b882f3dc 100644
--- a/arch/sh/include/cpu-sh3/cpu/gpio.h
+++ b/arch/sh/include/cpu-sh3/cpu/gpio.h
@@ -62,6 +62,20 @@
62#define PORT_PSELC 0xA4050128UL 62#define PORT_PSELC 0xA4050128UL
63#define PORT_PSELD 0xA405012AUL 63#define PORT_PSELD 0xA405012AUL
64 64
65#elif defined(CONFIG_CPU_SUBTYPE_SH7709)
66
67/* Control registers */
68#define PORT_PACR 0xa4000100UL
69#define PORT_PBCR 0xa4000102UL
70#define PORT_PCCR 0xa4000104UL
71#define PORT_PFCR 0xa400010aUL
72
73/* Data registers */
74#define PORT_PADR 0xa4000120UL
75#define PORT_PBDR 0xa4000122UL
76#define PORT_PCDR 0xa4000124UL
77#define PORT_PFDR 0xa400012aUL
78
65#endif 79#endif
66 80
67#endif 81#endif
diff --git a/arch/sh/include/mach-common/mach/edosk7705.h b/arch/sh/include/mach-common/mach/edosk7705.h
index 5bdc9d9be3de..efc43b323466 100644
--- a/arch/sh/include/mach-common/mach/edosk7705.h
+++ b/arch/sh/include/mach-common/mach/edosk7705.h
@@ -1,30 +1,7 @@
1/* 1#ifndef __ASM_SH_EDOSK7705_H
2 * include/asm-sh/edosk7705.h 2#define __ASM_SH_EDOSK7705_H
3 *
4 * Modified version of io_se.h for the EDOSK7705 specific functions.
5 *
6 * May be copied or modified under the terms of the GNU General Public
7 * License. See linux/COPYING for more information.
8 *
9 * IO functions for an Hitachi EDOSK7705 development board
10 */
11
12#ifndef __ASM_SH_EDOSK7705_IO_H
13#define __ASM_SH_EDOSK7705_IO_H
14 3
4#define __IO_PREFIX sh_edosk7705
15#include <asm/io_generic.h> 5#include <asm/io_generic.h>
16 6
17extern unsigned char sh_edosk7705_inb(unsigned long port); 7#endif /* __ASM_SH_EDOSK7705_H */
18extern unsigned int sh_edosk7705_inl(unsigned long port);
19
20extern void sh_edosk7705_outb(unsigned char value, unsigned long port);
21extern void sh_edosk7705_outl(unsigned int value, unsigned long port);
22
23extern void sh_edosk7705_insb(unsigned long port, void *addr, unsigned long count);
24extern void sh_edosk7705_insl(unsigned long port, void *addr, unsigned long count);
25extern void sh_edosk7705_outsb(unsigned long port, const void *addr, unsigned long count);
26extern void sh_edosk7705_outsl(unsigned long port, const void *addr, unsigned long count);
27
28extern unsigned long sh_edosk7705_isa_port2addr(unsigned long offset);
29
30#endif /* __ASM_SH_EDOSK7705_IO_H */
diff --git a/arch/sh/include/mach-se/mach/mrshpc.h b/arch/sh/include/mach-se/mach/mrshpc.h
new file mode 100644
index 000000000000..56287ee8563a
--- /dev/null
+++ b/arch/sh/include/mach-se/mach/mrshpc.h
@@ -0,0 +1,52 @@
1#ifndef __MACH_SE_MRSHPC_H
2#define __MACH_SE_MRSHPC_H
3
4#include <linux/io.h>
5
6static inline void __init mrshpc_setup_windows(void)
7{
8 if ((__raw_readw(MRSHPC_CSR) & 0x000c) != 0)
9 return; /* Not detected */
10
11 if ((__raw_readw(MRSHPC_CSR) & 0x0080) == 0) {
12 __raw_writew(0x0674, MRSHPC_CPWCR); /* Card Vcc is 3.3v? */
13 } else {
14 __raw_writew(0x0678, MRSHPC_CPWCR); /* Card Vcc is 5V */
15 }
16
17 /*
18 * PC-Card window open
19 * flag == COMMON/ATTRIBUTE/IO
20 */
21 /* common window open */
22 __raw_writew(0x8a84, MRSHPC_MW0CR1);
23 if((__raw_readw(MRSHPC_CSR) & 0x4000) != 0)
24 /* common mode & bus width 16bit SWAP = 1*/
25 __raw_writew(0x0b00, MRSHPC_MW0CR2);
26 else
27 /* common mode & bus width 16bit SWAP = 0*/
28 __raw_writew(0x0300, MRSHPC_MW0CR2);
29
30 /* attribute window open */
31 __raw_writew(0x8a85, MRSHPC_MW1CR1);
32 if ((__raw_readw(MRSHPC_CSR) & 0x4000) != 0)
33 /* attribute mode & bus width 16bit SWAP = 1*/
34 __raw_writew(0x0a00, MRSHPC_MW1CR2);
35 else
36 /* attribute mode & bus width 16bit SWAP = 0*/
37 __raw_writew(0x0200, MRSHPC_MW1CR2);
38
39 /* I/O window open */
40 __raw_writew(0x8a86, MRSHPC_IOWCR1);
41 __raw_writew(0x0008, MRSHPC_CDCR); /* I/O card mode */
42 if ((__raw_readw(MRSHPC_CSR) & 0x4000) != 0)
43 __raw_writew(0x0a00, MRSHPC_IOWCR2); /* bus width 16bit SWAP = 1*/
44 else
45 __raw_writew(0x0200, MRSHPC_IOWCR2); /* bus width 16bit SWAP = 0*/
46
47 __raw_writew(0x2000, MRSHPC_ICR);
48 __raw_writeb(0x00, PA_MRSHPC_MW2 + 0x206);
49 __raw_writeb(0x42, PA_MRSHPC_MW2 + 0x200);
50}
51
52#endif /* __MACH_SE_MRSHPC_H */
diff --git a/arch/sh/include/mach-se/mach/se.h b/arch/sh/include/mach-se/mach/se.h
index eb23000e1bbe..14be91c5a2f0 100644
--- a/arch/sh/include/mach-se/mach/se.h
+++ b/arch/sh/include/mach-se/mach/se.h
@@ -68,6 +68,24 @@
68#define BCR_ILCRF (PA_BCR + 10) 68#define BCR_ILCRF (PA_BCR + 10)
69#define BCR_ILCRG (PA_BCR + 12) 69#define BCR_ILCRG (PA_BCR + 12)
70 70
71#if defined(CONFIG_CPU_SUBTYPE_SH7709)
72#define INTC_IRR0 0xa4000004UL
73#define INTC_IRR1 0xa4000006UL
74#define INTC_IRR2 0xa4000008UL
75
76#define INTC_ICR0 0xfffffee0UL
77#define INTC_ICR1 0xa4000010UL
78#define INTC_ICR2 0xa4000012UL
79#define INTC_INTER 0xa4000014UL
80
81#define INTC_IPRC 0xa4000016UL
82#define INTC_IPRD 0xa4000018UL
83#define INTC_IPRE 0xa400001aUL
84
85#define IRQ0_IRQ 32
86#define IRQ1_IRQ 33
87#endif
88
71#if defined(CONFIG_CPU_SUBTYPE_SH7705) 89#if defined(CONFIG_CPU_SUBTYPE_SH7705)
72#define IRQ_STNIC 12 90#define IRQ_STNIC 12
73#define IRQ_CFCARD 14 91#define IRQ_CFCARD 14
diff --git a/arch/sh/include/mach-se/mach/se7343.h b/arch/sh/include/mach-se/mach/se7343.h
index 98458460e632..749914b400fb 100644
--- a/arch/sh/include/mach-se/mach/se7343.h
+++ b/arch/sh/include/mach-se/mach/se7343.h
@@ -118,9 +118,6 @@
118#define FPGA_IN 0xb1400000 118#define FPGA_IN 0xb1400000
119#define FPGA_OUT 0xb1400002 119#define FPGA_OUT 0xb1400002
120 120
121#define __IO_PREFIX sh7343se
122#include <asm/io_generic.h>
123
124#define IRQ0_IRQ 32 121#define IRQ0_IRQ 32
125#define IRQ1_IRQ 33 122#define IRQ1_IRQ 33
126#define IRQ4_IRQ 36 123#define IRQ4_IRQ 36
@@ -132,8 +129,10 @@
132#define SE7343_FPGA_IRQ_MRSHPC3 3 129#define SE7343_FPGA_IRQ_MRSHPC3 3
133#define SE7343_FPGA_IRQ_SMC 6 /* EXT_IRQ2 */ 130#define SE7343_FPGA_IRQ_SMC 6 /* EXT_IRQ2 */
134#define SE7343_FPGA_IRQ_USB 8 131#define SE7343_FPGA_IRQ_USB 8
132#define SE7343_FPGA_IRQ_UARTA 10
133#define SE7343_FPGA_IRQ_UARTB 11
135 134
136#define SE7343_FPGA_IRQ_NR 11 135#define SE7343_FPGA_IRQ_NR 12
137#define SE7343_FPGA_IRQ_BASE 120 136#define SE7343_FPGA_IRQ_BASE 120
138 137
139#define MRSHPC_IRQ3 (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_MRSHPC3) 138#define MRSHPC_IRQ3 (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_MRSHPC3)
@@ -142,6 +141,8 @@
142#define MRSHPC_IRQ0 (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_MRSHPC0) 141#define MRSHPC_IRQ0 (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_MRSHPC0)
143#define SMC_IRQ (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_SMC) 142#define SMC_IRQ (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_SMC)
144#define USB_IRQ (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_USB) 143#define USB_IRQ (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_USB)
144#define UARTA_IRQ (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_UARTA)
145#define UARTB_IRQ (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_UARTB)
145 146
146/* arch/sh/boards/se/7343/irq.c */ 147/* arch/sh/boards/se/7343/irq.c */
147void init_7343se_IRQ(void); 148void init_7343se_IRQ(void);
diff --git a/arch/sh/kernel/Makefile_32 b/arch/sh/kernel/Makefile_32
index 48edfb145fb4..2e1b86e16ab5 100644
--- a/arch/sh/kernel/Makefile_32
+++ b/arch/sh/kernel/Makefile_32
@@ -4,25 +4,31 @@
4 4
5extra-y := head_32.o init_task.o vmlinux.lds 5extra-y := head_32.o init_task.o vmlinux.lds
6 6
7obj-y := debugtraps.o io.o io_generic.o irq.o machvec.o process_32.o \ 7ifdef CONFIG_FUNCTION_TRACER
8 ptrace_32.o setup.o signal_32.o sys_sh.o sys_sh32.o \ 8# Do not profile debug and lowlevel utilities
9 syscalls_32.o time_32.o topology.o traps.o traps_32.o 9CFLAGS_REMOVE_ftrace.o = -pg
10endif
11
12obj-y := debugtraps.o idle.o io.o io_generic.o irq.o \
13 machvec.o process_32.o ptrace_32.o setup.o signal_32.o \
14 sys_sh.o sys_sh32.o syscalls_32.o time_32.o topology.o \
15 traps.o traps_32.o
10 16
11obj-y += cpu/ timers/ 17obj-y += cpu/ timers/
12obj-$(CONFIG_VSYSCALL) += vsyscall/ 18obj-$(CONFIG_VSYSCALL) += vsyscall/
13obj-$(CONFIG_SMP) += smp.o 19obj-$(CONFIG_SMP) += smp.o
14obj-$(CONFIG_CF_ENABLER) += cf-enabler.o
15obj-$(CONFIG_SH_STANDARD_BIOS) += sh_bios.o 20obj-$(CONFIG_SH_STANDARD_BIOS) += sh_bios.o
16obj-$(CONFIG_SH_KGDB) += kgdb_stub.o kgdb_jmp.o 21obj-$(CONFIG_KGDB) += kgdb.o
17obj-$(CONFIG_SH_CPU_FREQ) += cpufreq.o 22obj-$(CONFIG_SH_CPU_FREQ) += cpufreq.o
18obj-$(CONFIG_MODULES) += sh_ksyms_32.o module.o 23obj-$(CONFIG_MODULES) += sh_ksyms_32.o module.o
19obj-$(CONFIG_EARLY_PRINTK) += early_printk.o 24obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
20obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o 25obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
21obj-$(CONFIG_CRASH_DUMP) += crash_dump.o 26obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
22obj-$(CONFIG_PM) += pm.o
23obj-$(CONFIG_STACKTRACE) += stacktrace.o 27obj-$(CONFIG_STACKTRACE) += stacktrace.o
24obj-$(CONFIG_IO_TRAPPED) += io_trapped.o 28obj-$(CONFIG_IO_TRAPPED) += io_trapped.o
25obj-$(CONFIG_KPROBES) += kprobes.o 29obj-$(CONFIG_KPROBES) += kprobes.o
26obj-$(CONFIG_GENERIC_GPIO) += gpio.o 30obj-$(CONFIG_GENERIC_GPIO) += gpio.o
31obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
32obj-$(CONFIG_DUMP_CODE) += disassemble.o
27 33
28EXTRA_CFLAGS += -Werror 34EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/kernel/Makefile_64 b/arch/sh/kernel/Makefile_64
index c97660b2b48d..fe425d7f6871 100644
--- a/arch/sh/kernel/Makefile_64
+++ b/arch/sh/kernel/Makefile_64
@@ -1,21 +1,18 @@
1extra-y := head_64.o init_task.o vmlinux.lds 1extra-y := head_64.o init_task.o vmlinux.lds
2 2
3obj-y := debugtraps.o io.o io_generic.o irq.o machvec.o process_64.o \ 3obj-y := debugtraps.o idle.o io.o io_generic.o irq.o machvec.o process_64.o \
4 ptrace_64.o setup.o signal_64.o sys_sh.o sys_sh64.o \ 4 ptrace_64.o setup.o signal_64.o sys_sh.o sys_sh64.o \
5 syscalls_64.o time_64.o topology.o traps.o traps_64.o 5 syscalls_64.o time_64.o topology.o traps.o traps_64.o
6 6
7obj-y += cpu/ timers/ 7obj-y += cpu/ timers/
8obj-$(CONFIG_VSYSCALL) += vsyscall/ 8obj-$(CONFIG_VSYSCALL) += vsyscall/
9obj-$(CONFIG_SMP) += smp.o 9obj-$(CONFIG_SMP) += smp.o
10obj-$(CONFIG_CF_ENABLER) += cf-enabler.o
11obj-$(CONFIG_SH_STANDARD_BIOS) += sh_bios.o 10obj-$(CONFIG_SH_STANDARD_BIOS) += sh_bios.o
12obj-$(CONFIG_SH_KGDB) += kgdb_stub.o kgdb_jmp.o
13obj-$(CONFIG_SH_CPU_FREQ) += cpufreq.o 11obj-$(CONFIG_SH_CPU_FREQ) += cpufreq.o
14obj-$(CONFIG_MODULES) += sh_ksyms_64.o module.o 12obj-$(CONFIG_MODULES) += sh_ksyms_64.o module.o
15obj-$(CONFIG_EARLY_PRINTK) += early_printk.o 13obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
16obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o 14obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
17obj-$(CONFIG_CRASH_DUMP) += crash_dump.o 15obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
18obj-$(CONFIG_PM) += pm.o
19obj-$(CONFIG_STACKTRACE) += stacktrace.o 16obj-$(CONFIG_STACKTRACE) += stacktrace.o
20obj-$(CONFIG_IO_TRAPPED) += io_trapped.o 17obj-$(CONFIG_IO_TRAPPED) += io_trapped.o
21obj-$(CONFIG_GENERIC_GPIO) += gpio.o 18obj-$(CONFIG_GENERIC_GPIO) += gpio.o
diff --git a/arch/sh/kernel/cf-enabler.c b/arch/sh/kernel/cf-enabler.c
deleted file mode 100644
index bea40339919b..000000000000
--- a/arch/sh/kernel/cf-enabler.c
+++ /dev/null
@@ -1,168 +0,0 @@
1/* $Id: cf-enabler.c,v 1.4 2004/02/22 22:44:36 kkojima Exp $
2 *
3 * linux/drivers/block/cf-enabler.c
4 *
5 * Copyright (C) 1999 Niibe Yutaka
6 * Copyright (C) 2000 Toshiharu Nozawa
7 * Copyright (C) 2001 A&D Co., Ltd.
8 *
9 * Enable the CF configuration.
10 */
11
12#include <linux/init.h>
13#include <linux/mm.h>
14#include <linux/vmalloc.h>
15#include <linux/interrupt.h>
16#include <asm/io.h>
17#include <asm/irq.h>
18
19/*
20 * You can connect Compact Flash directly to the bus of SuperH.
21 * This is the enabler for that.
22 *
23 * SIM: How generic is this really? It looks pretty board, or at
24 * least SH sub-type, specific to me.
25 * I know it doesn't work on the Overdrive!
26 */
27
28/*
29 * 0xB8000000 : Attribute
30 * 0xB8001000 : Common Memory
31 * 0xBA000000 : I/O
32 */
33#if defined(CONFIG_CPU_SH4)
34/* SH4 can't access PCMCIA interface through P2 area.
35 * we must remap it with appropriate attribute bit of the page set.
36 * this part is based on Greg Banks' hd64465_ss.c implementation - Masahiro Abe */
37
38#if defined(CONFIG_CF_AREA6)
39#define slot_no 0
40#else
41#define slot_no 1
42#endif
43
44/* use this pointer to access to directly connected compact flash io area*/
45void *cf_io_base;
46
47static int __init allocate_cf_area(void)
48{
49 pgprot_t prot;
50 unsigned long paddrbase, psize;
51
52 /* open I/O area window */
53 paddrbase = virt_to_phys((void*)CONFIG_CF_BASE_ADDR);
54 psize = PAGE_SIZE;
55 prot = PAGE_KERNEL_PCC(slot_no, _PAGE_PCC_IO16);
56 cf_io_base = p3_ioremap(paddrbase, psize, prot.pgprot);
57 if (!cf_io_base) {
58 printk("allocate_cf_area : can't open CF I/O window!\n");
59 return -ENOMEM;
60 }
61/* printk("p3_ioremap(paddr=0x%08lx, psize=0x%08lx, prot=0x%08lx)=0x%08lx\n",
62 paddrbase, psize, prot.pgprot, cf_io_base);*/
63
64 /* XXX : do we need attribute and common-memory area also? */
65
66 return 0;
67}
68#endif
69
70static int __init cf_init_default(void)
71{
72/* You must have enabled the card, and set the level interrupt
73 * before reaching this point. Possibly in boot ROM or boot loader.
74 */
75#if defined(CONFIG_CPU_SH4)
76 allocate_cf_area();
77#endif
78
79 return 0;
80}
81
82#if defined(CONFIG_SH_SOLUTION_ENGINE)
83#include <mach-se/mach/se.h>
84#elif defined(CONFIG_SH_7722_SOLUTION_ENGINE)
85#include <mach-se/mach/se7722.h>
86#elif defined(CONFIG_SH_7721_SOLUTION_ENGINE)
87#include <mach-se/mach/se7721.h>
88#endif
89
90/*
91 * SolutionEngine Seriese
92 *
93 * about MS770xSE
94 * 0xB8400000 : Common Memory
95 * 0xB8500000 : Attribute
96 * 0xB8600000 : I/O
97 *
98 * about MS7722SE
99 * 0xB0400000 : Common Memory
100 * 0xB0500000 : Attribute
101 * 0xB0600000 : I/O
102 */
103
104#if defined(CONFIG_SH_SOLUTION_ENGINE) || \
105 defined(CONFIG_SH_7722_SOLUTION_ENGINE) || \
106 defined(CONFIG_SH_7721_SOLUTION_ENGINE)
107static int __init cf_init_se(void)
108{
109 if ((ctrl_inw(MRSHPC_CSR) & 0x000c) != 0)
110 return 0; /* Not detected */
111
112 if ((ctrl_inw(MRSHPC_CSR) & 0x0080) == 0) {
113 ctrl_outw(0x0674, MRSHPC_CPWCR); /* Card Vcc is 3.3v? */
114 } else {
115 ctrl_outw(0x0678, MRSHPC_CPWCR); /* Card Vcc is 5V */
116 }
117
118 /*
119 * PC-Card window open
120 * flag == COMMON/ATTRIBUTE/IO
121 */
122 /* common window open */
123 ctrl_outw(0x8a84, MRSHPC_MW0CR1);
124 if((ctrl_inw(MRSHPC_CSR) & 0x4000) != 0)
125 /* common mode & bus width 16bit SWAP = 1*/
126 ctrl_outw(0x0b00, MRSHPC_MW0CR2);
127 else
128 /* common mode & bus width 16bit SWAP = 0*/
129 ctrl_outw(0x0300, MRSHPC_MW0CR2);
130
131 /* attribute window open */
132 ctrl_outw(0x8a85, MRSHPC_MW1CR1);
133 if ((ctrl_inw(MRSHPC_CSR) & 0x4000) != 0)
134 /* attribute mode & bus width 16bit SWAP = 1*/
135 ctrl_outw(0x0a00, MRSHPC_MW1CR2);
136 else
137 /* attribute mode & bus width 16bit SWAP = 0*/
138 ctrl_outw(0x0200, MRSHPC_MW1CR2);
139
140 /* I/O window open */
141 ctrl_outw(0x8a86, MRSHPC_IOWCR1);
142 ctrl_outw(0x0008, MRSHPC_CDCR); /* I/O card mode */
143 if ((ctrl_inw(MRSHPC_CSR) & 0x4000) != 0)
144 ctrl_outw(0x0a00, MRSHPC_IOWCR2); /* bus width 16bit SWAP = 1*/
145 else
146 ctrl_outw(0x0200, MRSHPC_IOWCR2); /* bus width 16bit SWAP = 0*/
147
148 ctrl_outw(0x2000, MRSHPC_ICR);
149 ctrl_outb(0x00, PA_MRSHPC_MW2 + 0x206);
150 ctrl_outb(0x42, PA_MRSHPC_MW2 + 0x200);
151 return 0;
152}
153#else
154static int __init cf_init_se(void)
155{
156 return -1;
157}
158#endif
159
160static int __init cf_init(void)
161{
162 if (mach_is_se() || mach_is_7722se() || mach_is_7721se())
163 return cf_init_se();
164
165 return cf_init_default();
166}
167
168__initcall (cf_init);
diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c
index b7e46d5bba43..7b17137536d6 100644
--- a/arch/sh/kernel/cpu/clock.c
+++ b/arch/sh/kernel/cpu/clock.c
@@ -117,6 +117,11 @@ int clk_enable(struct clk *clk)
117 unsigned long flags; 117 unsigned long flags;
118 int ret; 118 int ret;
119 119
120 if (!clk)
121 return -EINVAL;
122
123 clk_enable(clk->parent);
124
120 spin_lock_irqsave(&clock_lock, flags); 125 spin_lock_irqsave(&clock_lock, flags);
121 ret = __clk_enable(clk); 126 ret = __clk_enable(clk);
122 spin_unlock_irqrestore(&clock_lock, flags); 127 spin_unlock_irqrestore(&clock_lock, flags);
@@ -147,9 +152,14 @@ void clk_disable(struct clk *clk)
147{ 152{
148 unsigned long flags; 153 unsigned long flags;
149 154
155 if (!clk)
156 return;
157
150 spin_lock_irqsave(&clock_lock, flags); 158 spin_lock_irqsave(&clock_lock, flags);
151 __clk_disable(clk); 159 __clk_disable(clk);
152 spin_unlock_irqrestore(&clock_lock, flags); 160 spin_unlock_irqrestore(&clock_lock, flags);
161
162 clk_disable(clk->parent);
153} 163}
154EXPORT_SYMBOL_GPL(clk_disable); 164EXPORT_SYMBOL_GPL(clk_disable);
155 165
diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c
index 75fb03d35670..d29e69c156f0 100644
--- a/arch/sh/kernel/cpu/init.c
+++ b/arch/sh/kernel/cpu/init.c
@@ -261,9 +261,11 @@ asmlinkage void __init sh_cpu_init(void)
261 cache_init(); 261 cache_init();
262 262
263 if (raw_smp_processor_id() == 0) { 263 if (raw_smp_processor_id() == 0) {
264#ifdef CONFIG_MMU
264 shm_align_mask = max_t(unsigned long, 265 shm_align_mask = max_t(unsigned long,
265 current_cpu_data.dcache.way_size - 1, 266 current_cpu_data.dcache.way_size - 1,
266 PAGE_SIZE - 1); 267 PAGE_SIZE - 1);
268#endif
267 269
268 /* Boot CPU sets the cache shape */ 270 /* Boot CPU sets the cache shape */
269 detect_cache_shape(); 271 detect_cache_shape();
diff --git a/arch/sh/kernel/cpu/sh2a/Makefile b/arch/sh/kernel/cpu/sh2a/Makefile
index 428450cc0809..45f85c77ef75 100644
--- a/arch/sh/kernel/cpu/sh2a/Makefile
+++ b/arch/sh/kernel/cpu/sh2a/Makefile
@@ -8,9 +8,10 @@ common-y += ex.o entry.o
8 8
9obj-$(CONFIG_SH_FPU) += fpu.o 9obj-$(CONFIG_SH_FPU) += fpu.o
10 10
11obj-$(CONFIG_CPU_SUBTYPE_SH7206) += setup-sh7206.o clock-sh7206.o 11obj-$(CONFIG_CPU_SUBTYPE_SH7201) += setup-sh7201.o clock-sh7201.o
12obj-$(CONFIG_CPU_SUBTYPE_SH7203) += setup-sh7203.o clock-sh7203.o 12obj-$(CONFIG_CPU_SUBTYPE_SH7203) += setup-sh7203.o clock-sh7203.o
13obj-$(CONFIG_CPU_SUBTYPE_SH7263) += setup-sh7203.o clock-sh7203.o 13obj-$(CONFIG_CPU_SUBTYPE_SH7263) += setup-sh7203.o clock-sh7203.o
14obj-$(CONFIG_CPU_SUBTYPE_SH7206) += setup-sh7206.o clock-sh7206.o
14obj-$(CONFIG_CPU_SUBTYPE_MXG) += setup-mxg.o clock-sh7206.o 15obj-$(CONFIG_CPU_SUBTYPE_MXG) += setup-mxg.o clock-sh7206.o
15 16
16# Pinmux setup 17# Pinmux setup
diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7201.c b/arch/sh/kernel/cpu/sh2a/clock-sh7201.c
new file mode 100644
index 000000000000..020a96fe961a
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh2a/clock-sh7201.c
@@ -0,0 +1,85 @@
1/*
2 * arch/sh/kernel/cpu/sh2a/clock-sh7201.c
3 *
4 * SH7201 support for the clock framework
5 *
6 * Copyright (C) 2008 Peter Griffin <pgriffin@mpc-data.co.uk>
7 *
8 * Based on clock-sh4.c
9 * Copyright (C) 2005 Paul Mundt
10 *
11 * This file is subject to the terms and conditions of the GNU General Public
12 * License. See the file "COPYING" in the main directory of this archive
13 * for more details.
14 */
15#include <linux/init.h>
16#include <linux/kernel.h>
17#include <asm/clock.h>
18#include <asm/freq.h>
19#include <asm/io.h>
20
21const static int pll1rate[]={1,2,3,4,6,8};
22const static int pfc_divisors[]={1,2,3,4,6,8,12};
23#define ifc_divisors pfc_divisors
24
25#if (CONFIG_SH_CLK_MD == 0)
26#define PLL2 (4)
27#elif (CONFIG_SH_CLK_MD == 2)
28#define PLL2 (2)
29#elif (CONFIG_SH_CLK_MD == 3)
30#define PLL2 (1)
31#else
32#error "Illegal Clock Mode!"
33#endif
34
35static void master_clk_init(struct clk *clk)
36{
37 clk->rate = 10000000 * PLL2 * pll1rate[(ctrl_inw(FREQCR) >> 8) & 0x0007];
38}
39
40static struct clk_ops sh7201_master_clk_ops = {
41 .init = master_clk_init,
42};
43
44static void module_clk_recalc(struct clk *clk)
45{
46 int idx = (ctrl_inw(FREQCR) & 0x0007);
47 clk->rate = clk->parent->rate / pfc_divisors[idx];
48}
49
50static struct clk_ops sh7201_module_clk_ops = {
51 .recalc = module_clk_recalc,
52};
53
54static void bus_clk_recalc(struct clk *clk)
55{
56 int idx = (ctrl_inw(FREQCR) & 0x0007);
57 clk->rate = clk->parent->rate / pfc_divisors[idx];
58}
59
60static struct clk_ops sh7201_bus_clk_ops = {
61 .recalc = bus_clk_recalc,
62};
63
64static void cpu_clk_recalc(struct clk *clk)
65{
66 int idx = ((ctrl_inw(FREQCR) >> 4) & 0x0007);
67 clk->rate = clk->parent->rate / ifc_divisors[idx];
68}
69
70static struct clk_ops sh7201_cpu_clk_ops = {
71 .recalc = cpu_clk_recalc,
72};
73
74static struct clk_ops *sh7201_clk_ops[] = {
75 &sh7201_master_clk_ops,
76 &sh7201_module_clk_ops,
77 &sh7201_bus_clk_ops,
78 &sh7201_cpu_clk_ops,
79};
80
81void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
82{
83 if (idx < ARRAY_SIZE(sh7201_clk_ops))
84 *ops = sh7201_clk_ops[idx];
85}
diff --git a/arch/sh/kernel/cpu/sh2a/probe.c b/arch/sh/kernel/cpu/sh2a/probe.c
index 6e79132f6f30..e098e2f6aa08 100644
--- a/arch/sh/kernel/cpu/sh2a/probe.c
+++ b/arch/sh/kernel/cpu/sh2a/probe.c
@@ -18,16 +18,17 @@ int __init detect_cpu_and_cache_system(void)
18 /* All SH-2A CPUs have support for 16 and 32-bit opcodes.. */ 18 /* All SH-2A CPUs have support for 16 and 32-bit opcodes.. */
19 boot_cpu_data.flags |= CPU_HAS_OP32; 19 boot_cpu_data.flags |= CPU_HAS_OP32;
20 20
21#if defined(CONFIG_CPU_SUBTYPE_SH7203) 21#if defined(CONFIG_CPU_SUBTYPE_SH7201)
22 boot_cpu_data.type = CPU_SH7201;
23 boot_cpu_data.flags |= CPU_HAS_FPU;
24#elif defined(CONFIG_CPU_SUBTYPE_SH7203)
22 boot_cpu_data.type = CPU_SH7203; 25 boot_cpu_data.type = CPU_SH7203;
23 /* SH7203 has an FPU.. */
24 boot_cpu_data.flags |= CPU_HAS_FPU; 26 boot_cpu_data.flags |= CPU_HAS_FPU;
25#elif defined(CONFIG_CPU_SUBTYPE_SH7263) 27#elif defined(CONFIG_CPU_SUBTYPE_SH7263)
26 boot_cpu_data.type = CPU_SH7263; 28 boot_cpu_data.type = CPU_SH7263;
27 boot_cpu_data.flags |= CPU_HAS_FPU; 29 boot_cpu_data.flags |= CPU_HAS_FPU;
28#elif defined(CONFIG_CPU_SUBTYPE_SH7206) 30#elif defined(CONFIG_CPU_SUBTYPE_SH7206)
29 boot_cpu_data.type = CPU_SH7206; 31 boot_cpu_data.type = CPU_SH7206;
30 /* While SH7206 has a DSP.. */
31 boot_cpu_data.flags |= CPU_HAS_DSP; 32 boot_cpu_data.flags |= CPU_HAS_DSP;
32#elif defined(CONFIG_CPU_SUBTYPE_MXG) 33#elif defined(CONFIG_CPU_SUBTYPE_MXG)
33 boot_cpu_data.type = CPU_MXG; 34 boot_cpu_data.type = CPU_MXG;
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7201.c b/arch/sh/kernel/cpu/sh2a/setup-sh7201.c
new file mode 100644
index 000000000000..0631e421c022
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh2a/setup-sh7201.c
@@ -0,0 +1,331 @@
1/*
2 * SH7201 setup
3 *
4 * Copyright (C) 2008 Peter Griffin pgriffin@mpc-data.co.uk
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10#include <linux/platform_device.h>
11#include <linux/init.h>
12#include <linux/serial.h>
13#include <linux/serial_sci.h>
14
15enum {
16 UNUSED = 0,
17
18 /* interrupt sources */
19 IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
20 PINT0, PINT1, PINT2, PINT3, PINT4, PINT5, PINT6, PINT7,
21 ADC_ADI,
22 MTU2_TGI0A, MTU2_TGI0B, MTU2_TGI0C, MTU2_TGI0D,
23 MTU2_TCI0V, MTU2_TGI0E, MTU2_TGI0F,
24 MTU2_TGI1A, MTU2_TGI1B, MTU2_TCI1V, MTU2_TCI1U,
25 MTU2_TGI2A, MTU2_TGI2B, MTU2_TCI2V, MTU2_TCI2U,
26 MTU2_TGI3A, MTU2_TGI3B, MTU2_TGI3C, MTU2_TGI3D, MTU2_TCI3V,
27 MTU2_TGI4A, MTU2_TGI4B, MTU2_TGI4C, MTU2_TGI4D, MTU2_TCI4V,
28 MTU2_TGI5U, MTU2_TGI5V, MTU2_TGI5W,
29 RTC_ARM, RTC_PRD, RTC_CUP,
30 WDT,
31 IIC30_STPI, IIC30_NAKI, IIC30_RXI, IIC30_TXI, IIC30_TEI,
32 IIC31_STPI, IIC31_NAKI, IIC31_RXI, IIC31_TXI, IIC31_TEI,
33 IIC32_STPI, IIC32_NAKI, IIC32_RXI, IIC32_TXI, IIC32_TEI,
34
35 DMAC0_DMINT0, DMAC1_DMINT1,
36 DMAC2_DMINT2, DMAC3_DMINT3,
37
38 SCIF0_BRI, SCIF0_ERI, SCIF0_RXI, SCIF0_TXI,
39 SCIF1_BRI, SCIF1_ERI, SCIF1_RXI, SCIF1_TXI,
40 SCIF2_BRI, SCIF2_ERI, SCIF2_RXI, SCIF2_TXI,
41 SCIF3_BRI, SCIF3_ERI, SCIF3_RXI, SCIF3_TXI,
42 SCIF4_BRI, SCIF4_ERI, SCIF4_RXI, SCIF4_TXI,
43 SCIF5_BRI, SCIF5_ERI, SCIF5_RXI, SCIF5_TXI,
44 SCIF6_BRI, SCIF6_ERI, SCIF6_RXI, SCIF6_TXI,
45 SCIF7_BRI, SCIF7_ERI, SCIF7_RXI, SCIF7_TXI,
46
47 DMAC0_DMINTA, DMAC4_DMINT4, DMAC5_DMINT5, DMAC6_DMINT6,
48 DMAC7_DMINT7,
49
50 RCAN0_ERS, RCAN0_OVR,
51 RCAN0_SLE,
52 RCAN0_RM0, RCAN0_RM1,
53
54 RCAN1_ERS, RCAN1_OVR,
55 RCAN1_SLE,
56 RCAN1_RM0, RCAN1_RM1,
57
58 SSI0_SSII, SSI1_SSII,
59
60 TMR0_CMIA0, TMR0_CMIB0, TMR0_OVI0,
61 TMR1_CMIA1, TMR1_CMIB1, TMR1_OVI1,
62
63 /* interrupt groups */
64
65 IRQ, PINT, ADC,
66 MTU20_ABCD, MTU20_VEF, MTU21_AB, MTU21_VU, MTU22_AB, MTU22_VU,
67 MTU23_ABCD, MTU24_ABCD, MTU25_UVW,
68 RTC, IIC30, IIC31, IIC32,
69 SCIF0, SCIF1, SCIF2, SCIF3, SCIF4, SCIF5, SCIF6, SCIF7,
70 RCAN0, RCAN1, TMR0, TMR1
71
72};
73
74static struct intc_vect vectors[] __initdata = {
75 INTC_IRQ(IRQ0, 64), INTC_IRQ(IRQ1, 65),
76 INTC_IRQ(IRQ2, 66), INTC_IRQ(IRQ3, 67),
77 INTC_IRQ(IRQ4, 68), INTC_IRQ(IRQ5, 69),
78 INTC_IRQ(IRQ6, 70), INTC_IRQ(IRQ7, 71),
79 INTC_IRQ(PINT0, 80), INTC_IRQ(PINT1, 81),
80 INTC_IRQ(PINT2, 82), INTC_IRQ(PINT3, 83),
81 INTC_IRQ(PINT4, 84), INTC_IRQ(PINT5, 85),
82 INTC_IRQ(PINT6, 86), INTC_IRQ(PINT7, 87),
83
84 INTC_IRQ(ADC_ADI, 92),
85
86 INTC_IRQ(MTU2_TGI0A, 108), INTC_IRQ(MTU2_TGI0B, 109),
87 INTC_IRQ(MTU2_TGI0C, 110), INTC_IRQ(MTU2_TGI0D, 111),
88 INTC_IRQ(MTU2_TCI0V, 112),
89 INTC_IRQ(MTU2_TGI0E, 113), INTC_IRQ(MTU2_TGI0F, 114),
90
91 INTC_IRQ(MTU2_TGI1A, 116), INTC_IRQ(MTU2_TGI1B, 117),
92 INTC_IRQ(MTU2_TCI1V, 120), INTC_IRQ(MTU2_TCI1U, 121),
93
94 INTC_IRQ(MTU2_TGI2A, 124), INTC_IRQ(MTU2_TGI2B, 125),
95 INTC_IRQ(MTU2_TCI2V, 128), INTC_IRQ(MTU2_TCI2U, 129),
96
97 INTC_IRQ(MTU2_TGI3A, 132), INTC_IRQ(MTU2_TGI3B, 133),
98 INTC_IRQ(MTU2_TGI3C, 134), INTC_IRQ(MTU2_TGI3D, 135),
99 INTC_IRQ(MTU2_TCI3V, 136),
100
101 INTC_IRQ(MTU2_TGI4A, 140), INTC_IRQ(MTU2_TGI4B, 141),
102 INTC_IRQ(MTU2_TGI4C, 142), INTC_IRQ(MTU2_TGI4D, 143),
103 INTC_IRQ(MTU2_TCI4V, 144),
104
105 INTC_IRQ(MTU2_TGI5U, 148), INTC_IRQ(MTU2_TGI5V, 149),
106 INTC_IRQ(MTU2_TGI5W, 150),
107
108 INTC_IRQ(RTC_ARM, 152), INTC_IRQ(RTC_PRD, 153),
109 INTC_IRQ(RTC_CUP, 154), INTC_IRQ(WDT, 156),
110
111 INTC_IRQ(IIC30_STPI, 157), INTC_IRQ(IIC30_NAKI, 158),
112 INTC_IRQ(IIC30_RXI, 159), INTC_IRQ(IIC30_TXI, 160),
113 INTC_IRQ(IIC30_TEI, 161),
114
115 INTC_IRQ(IIC31_STPI, 164), INTC_IRQ(IIC31_NAKI, 165),
116 INTC_IRQ(IIC31_RXI, 166), INTC_IRQ(IIC31_TXI, 167),
117 INTC_IRQ(IIC31_TEI, 168),
118
119 INTC_IRQ(IIC32_STPI, 170), INTC_IRQ(IIC32_NAKI, 171),
120 INTC_IRQ(IIC32_RXI, 172), INTC_IRQ(IIC32_TXI, 173),
121 INTC_IRQ(IIC32_TEI, 174),
122
123 INTC_IRQ(DMAC0_DMINT0, 176), INTC_IRQ(DMAC1_DMINT1, 177),
124 INTC_IRQ(DMAC2_DMINT2, 178), INTC_IRQ(DMAC3_DMINT3, 179),
125
126 INTC_IRQ(SCIF0_BRI, 180), INTC_IRQ(SCIF0_ERI, 181),
127 INTC_IRQ(SCIF0_RXI, 182), INTC_IRQ(SCIF0_TXI, 183),
128 INTC_IRQ(SCIF1_BRI, 184), INTC_IRQ(SCIF1_ERI, 185),
129 INTC_IRQ(SCIF1_RXI, 186), INTC_IRQ(SCIF1_TXI, 187),
130 INTC_IRQ(SCIF2_BRI, 188), INTC_IRQ(SCIF2_ERI, 189),
131 INTC_IRQ(SCIF2_RXI, 190), INTC_IRQ(SCIF2_TXI, 191),
132 INTC_IRQ(SCIF3_BRI, 192), INTC_IRQ(SCIF3_ERI, 193),
133 INTC_IRQ(SCIF3_RXI, 194), INTC_IRQ(SCIF3_TXI, 195),
134 INTC_IRQ(SCIF4_BRI, 196), INTC_IRQ(SCIF4_ERI, 197),
135 INTC_IRQ(SCIF4_RXI, 198), INTC_IRQ(SCIF4_TXI, 199),
136 INTC_IRQ(SCIF5_BRI, 200), INTC_IRQ(SCIF5_ERI, 201),
137 INTC_IRQ(SCIF5_RXI, 202), INTC_IRQ(SCIF5_TXI, 203),
138 INTC_IRQ(SCIF6_BRI, 204), INTC_IRQ(SCIF6_ERI, 205),
139 INTC_IRQ(SCIF6_RXI, 206), INTC_IRQ(SCIF6_TXI, 207),
140 INTC_IRQ(SCIF7_BRI, 208), INTC_IRQ(SCIF7_ERI, 209),
141 INTC_IRQ(SCIF7_RXI, 210), INTC_IRQ(SCIF7_TXI, 211),
142
143 INTC_IRQ(DMAC0_DMINTA, 212), INTC_IRQ(DMAC4_DMINT4, 216),
144 INTC_IRQ(DMAC5_DMINT5, 217), INTC_IRQ(DMAC6_DMINT6, 218),
145 INTC_IRQ(DMAC7_DMINT7, 219),
146
147 INTC_IRQ(RCAN0_ERS, 228), INTC_IRQ(RCAN0_OVR, 229),
148 INTC_IRQ(RCAN0_SLE, 230),
149 INTC_IRQ(RCAN0_RM0, 231), INTC_IRQ(RCAN0_RM1, 232),
150
151 INTC_IRQ(RCAN1_ERS, 234), INTC_IRQ(RCAN1_OVR, 235),
152 INTC_IRQ(RCAN1_SLE, 236),
153 INTC_IRQ(RCAN1_RM0, 237), INTC_IRQ(RCAN1_RM1, 238),
154
155 INTC_IRQ(SSI0_SSII, 244), INTC_IRQ(SSI1_SSII, 245),
156
157 INTC_IRQ(TMR0_CMIA0, 246), INTC_IRQ(TMR0_CMIB0, 247),
158 INTC_IRQ(TMR0_OVI0, 248),
159
160 INTC_IRQ(TMR1_CMIA1, 252), INTC_IRQ(TMR1_CMIB1, 253),
161 INTC_IRQ(TMR1_OVI1, 254),
162
163};
164
165static struct intc_group groups[] __initdata = {
166 INTC_GROUP(PINT, PINT0, PINT1, PINT2, PINT3,
167 PINT4, PINT5, PINT6, PINT7),
168 INTC_GROUP(MTU20_ABCD, MTU2_TGI0A, MTU2_TGI0B, MTU2_TGI0C, MTU2_TGI0D),
169 INTC_GROUP(MTU20_VEF, MTU2_TCI0V, MTU2_TGI0E, MTU2_TGI0F),
170
171 INTC_GROUP(MTU21_AB, MTU2_TGI1A, MTU2_TGI1B),
172 INTC_GROUP(MTU21_VU, MTU2_TCI1V, MTU2_TCI1U),
173 INTC_GROUP(MTU22_AB, MTU2_TGI2A, MTU2_TGI2B),
174 INTC_GROUP(MTU22_VU, MTU2_TCI2V, MTU2_TCI2U),
175 INTC_GROUP(MTU23_ABCD, MTU2_TGI3A, MTU2_TGI3B, MTU2_TGI3C, MTU2_TGI3D),
176 INTC_GROUP(MTU24_ABCD, MTU2_TGI4A, MTU2_TGI4B, MTU2_TGI4C, MTU2_TGI4D),
177 INTC_GROUP(MTU25_UVW, MTU2_TGI5U, MTU2_TGI5V, MTU2_TGI5W),
178 INTC_GROUP(RTC, RTC_ARM, RTC_PRD, RTC_CUP ),
179
180 INTC_GROUP(IIC30, IIC30_STPI, IIC30_NAKI, IIC30_RXI, IIC30_TXI,
181 IIC30_TEI),
182 INTC_GROUP(IIC31, IIC31_STPI, IIC31_NAKI, IIC31_RXI, IIC31_TXI,
183 IIC31_TEI),
184 INTC_GROUP(IIC32, IIC32_STPI, IIC32_NAKI, IIC32_RXI, IIC32_TXI,
185 IIC32_TEI),
186
187 INTC_GROUP(SCIF0, SCIF0_BRI, SCIF0_ERI, SCIF0_RXI, SCIF0_TXI),
188 INTC_GROUP(SCIF1, SCIF1_BRI, SCIF1_ERI, SCIF1_RXI, SCIF1_TXI),
189 INTC_GROUP(SCIF2, SCIF2_BRI, SCIF2_ERI, SCIF2_RXI, SCIF2_TXI),
190 INTC_GROUP(SCIF3, SCIF3_BRI, SCIF3_ERI, SCIF3_RXI, SCIF3_TXI),
191 INTC_GROUP(SCIF4, SCIF4_BRI, SCIF4_ERI, SCIF4_RXI, SCIF4_TXI),
192 INTC_GROUP(SCIF5, SCIF5_BRI, SCIF5_ERI, SCIF5_RXI, SCIF5_TXI),
193 INTC_GROUP(SCIF6, SCIF6_BRI, SCIF6_ERI, SCIF6_RXI, SCIF6_TXI),
194 INTC_GROUP(SCIF7, SCIF7_BRI, SCIF7_ERI, SCIF7_RXI, SCIF7_TXI),
195
196 INTC_GROUP(RCAN0, RCAN0_ERS, RCAN0_OVR, RCAN0_RM0, RCAN0_RM1,
197 RCAN0_SLE),
198 INTC_GROUP(RCAN1, RCAN1_ERS, RCAN1_OVR, RCAN1_RM0, RCAN1_RM1,
199 RCAN1_SLE),
200
201 INTC_GROUP(TMR0, TMR0_CMIA0, TMR0_CMIB0, TMR0_OVI0),
202 INTC_GROUP(TMR1, TMR1_CMIA1, TMR1_CMIB1, TMR1_OVI1),
203};
204
205static struct intc_prio_reg prio_registers[] __initdata = {
206 { 0xfffe9418, 0, 16, 4, /* IPR01 */ { IRQ0, IRQ1, IRQ2, IRQ3 } },
207 { 0xfffe941a, 0, 16, 4, /* IPR02 */ { IRQ4, IRQ5, IRQ6, IRQ7 } },
208 { 0xfffe9420, 0, 16, 4, /* IPR05 */ { PINT, 0, ADC_ADI, 0 } },
209 { 0xfffe9800, 0, 16, 4, /* IPR06 */ { 0, MTU20_ABCD, MTU20_VEF, MTU21_AB } },
210 { 0xfffe9802, 0, 16, 4, /* IPR07 */ { MTU21_VU, MTU22_AB, MTU22_VU, MTU23_ABCD } },
211 { 0xfffe9804, 0, 16, 4, /* IPR08 */ { MTU2_TCI3V, MTU24_ABCD, MTU2_TCI4V, MTU25_UVW } },
212
213 { 0xfffe9806, 0, 16, 4, /* IPR09 */ { RTC, WDT, IIC30, 0 } },
214 { 0xfffe9808, 0, 16, 4, /* IPR10 */ { IIC31, IIC32, DMAC0_DMINT0, DMAC1_DMINT1 } },
215 { 0xfffe980a, 0, 16, 4, /* IPR11 */ { DMAC2_DMINT2, DMAC3_DMINT3, SCIF0 , SCIF1 } },
216 { 0xfffe980c, 0, 16, 4, /* IPR12 */ { SCIF2, SCIF3, SCIF4, SCIF5 } },
217 { 0xfffe980e, 0, 16, 4, /* IPR13 */ { SCIF6, SCIF7, DMAC0_DMINTA, DMAC4_DMINT4 } },
218 { 0xfffe9810, 0, 16, 4, /* IPR14 */ { DMAC5_DMINT5, DMAC6_DMINT6, DMAC7_DMINT7, 0 } },
219 { 0xfffe9812, 0, 16, 4, /* IPR15 */ { 0, RCAN0, RCAN1, 0 } },
220 { 0xfffe9814, 0, 16, 4, /* IPR16 */ { SSI0_SSII, SSI1_SSII, TMR0, TMR1 } },
221};
222
223static struct intc_mask_reg mask_registers[] __initdata = {
224 { 0xfffe9408, 0, 16, /* PINTER */
225 { 0, 0, 0, 0, 0, 0, 0, 0,
226 PINT7, PINT6, PINT5, PINT4, PINT3, PINT2, PINT1, PINT0 } },
227};
228
229static DECLARE_INTC_DESC(intc_desc, "sh7201", vectors, groups,
230 mask_registers, prio_registers, NULL);
231
232static struct plat_sci_port sci_platform_data[] = {
233 {
234 .mapbase = 0xfffe8000,
235 .flags = UPF_BOOT_AUTOCONF,
236 .type = PORT_SCIF,
237 .irqs = { 181, 182, 183, 180}
238 }, {
239 .mapbase = 0xfffe8800,
240 .flags = UPF_BOOT_AUTOCONF,
241 .type = PORT_SCIF,
242 .irqs = { 185, 186, 187, 184}
243 }, {
244 .mapbase = 0xfffe9000,
245 .flags = UPF_BOOT_AUTOCONF,
246 .type = PORT_SCIF,
247 .irqs = { 189, 186, 187, 188}
248 }, {
249 .mapbase = 0xfffe9800,
250 .flags = UPF_BOOT_AUTOCONF,
251 .type = PORT_SCIF,
252 .irqs = { 193, 194, 195, 192}
253 }, {
254 .mapbase = 0xfffea000,
255 .flags = UPF_BOOT_AUTOCONF,
256 .type = PORT_SCIF,
257 .irqs = { 196, 198, 199, 196}
258 }, {
259 .mapbase = 0xfffea800,
260 .flags = UPF_BOOT_AUTOCONF,
261 .type = PORT_SCIF,
262 .irqs = { 201, 202, 203, 200}
263 }, {
264 .mapbase = 0xfffeb000,
265 .flags = UPF_BOOT_AUTOCONF,
266 .type = PORT_SCIF,
267 .irqs = { 205, 206, 207, 204}
268 }, {
269 .mapbase = 0xfffeb800,
270 .flags = UPF_BOOT_AUTOCONF,
271 .type = PORT_SCIF,
272 .irqs = { 209, 210, 211, 208}
273 }, {
274 .flags = 0,
275 }
276};
277
278static struct platform_device sci_device = {
279 .name = "sh-sci",
280 .id = -1,
281 .dev = {
282 .platform_data = sci_platform_data,
283 },
284};
285
286static struct resource rtc_resources[] = {
287 [0] = {
288 .start = 0xffff0800,
289 .end = 0xffff2000 + 0x58 - 1,
290 .flags = IORESOURCE_IO,
291 },
292 [1] = {
293 /* Period IRQ */
294 .start = 153,
295 .flags = IORESOURCE_IRQ,
296 },
297 [2] = {
298 /* Carry IRQ */
299 .start = 154,
300 .flags = IORESOURCE_IRQ,
301 },
302 [3] = {
303 /* Alarm IRQ */
304 .start = 152,
305 .flags = IORESOURCE_IRQ,
306 },
307};
308
309static struct platform_device rtc_device = {
310 .name = "sh-rtc",
311 .id = -1,
312 .num_resources = ARRAY_SIZE(rtc_resources),
313 .resource = rtc_resources,
314};
315
316static struct platform_device *sh7201_devices[] __initdata = {
317 &sci_device,
318 &rtc_device,
319};
320
321static int __init sh7201_devices_setup(void)
322{
323 return platform_add_devices(sh7201_devices,
324 ARRAY_SIZE(sh7201_devices));
325}
326__initcall(sh7201_devices_setup);
327
328void __init plat_irq_setup(void)
329{
330 register_intc_controller(&intc_desc);
331}
diff --git a/arch/sh/kernel/cpu/sh3/entry.S b/arch/sh/kernel/cpu/sh3/entry.S
index 3fe482dd05c1..b4106d0c68ec 100644
--- a/arch/sh/kernel/cpu/sh3/entry.S
+++ b/arch/sh/kernel/cpu/sh3/entry.S
@@ -52,7 +52,7 @@
52 * syscall # 52 * syscall #
53 * 53 *
54 */ 54 */
55#if defined(CONFIG_KGDB_NMI) 55#if defined(CONFIG_KGDB)
56NMI_VEC = 0x1c0 ! Must catch early for debounce 56NMI_VEC = 0x1c0 ! Must catch early for debounce
57#endif 57#endif
58 58
@@ -307,7 +307,7 @@ skip_restore:
3076: or k0, k2 ! Set the IMASK-bits 3076: or k0, k2 ! Set the IMASK-bits
308 ldc k2, ssr 308 ldc k2, ssr
309 ! 309 !
310#if defined(CONFIG_KGDB_NMI) 310#if defined(CONFIG_KGDB)
311 ! Clear in_nmi 311 ! Clear in_nmi
312 mov.l 6f, k0 312 mov.l 6f, k0
313 mov #0, k1 313 mov #0, k1
@@ -320,7 +320,7 @@ skip_restore:
320 320
321 .align 2 321 .align 2
3225: .long 0x00001000 ! DSP 3225: .long 0x00001000 ! DSP
323#ifdef CONFIG_KGDB_NMI 323#ifdef CONFIG_KGDB
3246: .long in_nmi 3246: .long in_nmi
325#endif 325#endif
3267: .long 0x30000000 3267: .long 0x30000000
@@ -376,9 +376,9 @@ tlb_miss:
376! 376!
377 .balign 512,0,512 377 .balign 512,0,512
378interrupt: 378interrupt:
379 mov.l 2f, k2
380 mov.l 3f, k3 379 mov.l 3f, k3
381#if defined(CONFIG_KGDB_NMI) 380#if defined(CONFIG_KGDB)
381 mov.l 2f, k2
382 ! Debounce (filter nested NMI) 382 ! Debounce (filter nested NMI)
383 mov.l @k2, k0 383 mov.l @k2, k0
384 mov.l 5f, k1 384 mov.l 5f, k1
@@ -390,16 +390,16 @@ interrupt:
390 rte 390 rte
391 nop 391 nop
392 .align 2 392 .align 2
3932: .long INTEVT
3935: .long NMI_VEC 3945: .long NMI_VEC
3946: .long in_nmi 3956: .long in_nmi
3950: 3960:
396#endif /* defined(CONFIG_KGDB_NMI) */ 397#endif /* defined(CONFIG_KGDB) */
397 bra handle_exception 398 bra handle_exception
398 mov #-1, k2 ! interrupt exception marker 399 mov #-1, k2 ! interrupt exception marker
399 400
400 .align 2 401 .align 2
4011: .long EXPEVT 4021: .long EXPEVT
4022: .long INTEVT
4033: .long ret_from_irq 4033: .long ret_from_irq
4044: .long ret_from_exception 4044: .long ret_from_exception
405 405
diff --git a/arch/sh/kernel/cpu/sh3/ex.S b/arch/sh/kernel/cpu/sh3/ex.S
index dac429726899..e5a0de39a2db 100644
--- a/arch/sh/kernel/cpu/sh3/ex.S
+++ b/arch/sh/kernel/cpu/sh3/ex.S
@@ -26,7 +26,7 @@
26#define fpu_error_trap_handler exception_error 26#define fpu_error_trap_handler exception_error
27#endif 27#endif
28 28
29#if !defined(CONFIG_KGDB_NMI) 29#if !defined(CONFIG_KGDB)
30#define kgdb_handle_exception exception_error 30#define kgdb_handle_exception exception_error
31#endif 31#endif
32 32
diff --git a/arch/sh/kernel/cpu/sh4/softfloat.c b/arch/sh/kernel/cpu/sh4/softfloat.c
index 2b747f3b02bd..42edf2e54e85 100644
--- a/arch/sh/kernel/cpu/sh4/softfloat.c
+++ b/arch/sh/kernel/cpu/sh4/softfloat.c
@@ -37,6 +37,7 @@
37 */ 37 */
38#include <linux/kernel.h> 38#include <linux/kernel.h>
39#include <cpu/fpu.h> 39#include <cpu/fpu.h>
40#include <asm/div64.h>
40 41
41#define LIT64( a ) a##LL 42#define LIT64( a ) a##LL
42 43
@@ -67,16 +68,16 @@ typedef unsigned long long float64;
67extern void float_raise(unsigned int flags); /* in fpu.c */ 68extern void float_raise(unsigned int flags); /* in fpu.c */
68extern int float_rounding_mode(void); /* in fpu.c */ 69extern int float_rounding_mode(void); /* in fpu.c */
69 70
70inline bits64 extractFloat64Frac(float64 a); 71bits64 extractFloat64Frac(float64 a);
71inline flag extractFloat64Sign(float64 a); 72flag extractFloat64Sign(float64 a);
72inline int16 extractFloat64Exp(float64 a); 73int16 extractFloat64Exp(float64 a);
73inline int16 extractFloat32Exp(float32 a); 74int16 extractFloat32Exp(float32 a);
74inline flag extractFloat32Sign(float32 a); 75flag extractFloat32Sign(float32 a);
75inline bits32 extractFloat32Frac(float32 a); 76bits32 extractFloat32Frac(float32 a);
76inline float64 packFloat64(flag zSign, int16 zExp, bits64 zSig); 77float64 packFloat64(flag zSign, int16 zExp, bits64 zSig);
77inline void shift64RightJamming(bits64 a, int16 count, bits64 * zPtr); 78void shift64RightJamming(bits64 a, int16 count, bits64 * zPtr);
78inline float32 packFloat32(flag zSign, int16 zExp, bits32 zSig); 79float32 packFloat32(flag zSign, int16 zExp, bits32 zSig);
79inline void shift32RightJamming(bits32 a, int16 count, bits32 * zPtr); 80void shift32RightJamming(bits32 a, int16 count, bits32 * zPtr);
80float64 float64_sub(float64 a, float64 b); 81float64 float64_sub(float64 a, float64 b);
81float32 float32_sub(float32 a, float32 b); 82float32 float32_sub(float32 a, float32 b);
82float32 float32_add(float32 a, float32 b); 83float32 float32_add(float32 a, float32 b);
@@ -86,11 +87,11 @@ float32 float32_div(float32 a, float32 b);
86float32 float32_mul(float32 a, float32 b); 87float32 float32_mul(float32 a, float32 b);
87float64 float64_mul(float64 a, float64 b); 88float64 float64_mul(float64 a, float64 b);
88float32 float64_to_float32(float64 a); 89float32 float64_to_float32(float64 a);
89inline void add128(bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 * z0Ptr, 90void add128(bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 * z0Ptr,
90 bits64 * z1Ptr); 91 bits64 * z1Ptr);
91inline void sub128(bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 * z0Ptr, 92void sub128(bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 * z0Ptr,
92 bits64 * z1Ptr); 93 bits64 * z1Ptr);
93inline void mul64To128(bits64 a, bits64 b, bits64 * z0Ptr, bits64 * z1Ptr); 94void mul64To128(bits64 a, bits64 b, bits64 * z0Ptr, bits64 * z1Ptr);
94 95
95static int8 countLeadingZeros32(bits32 a); 96static int8 countLeadingZeros32(bits32 a);
96static int8 countLeadingZeros64(bits64 a); 97static int8 countLeadingZeros64(bits64 a);
@@ -110,42 +111,42 @@ static bits64 estimateDiv128To64(bits64 a0, bits64 a1, bits64 b);
110static void normalizeFloat32Subnormal(bits32 aSig, int16 * zExpPtr, 111static void normalizeFloat32Subnormal(bits32 aSig, int16 * zExpPtr,
111 bits32 * zSigPtr); 112 bits32 * zSigPtr);
112 113
113inline bits64 extractFloat64Frac(float64 a) 114bits64 extractFloat64Frac(float64 a)
114{ 115{
115 return a & LIT64(0x000FFFFFFFFFFFFF); 116 return a & LIT64(0x000FFFFFFFFFFFFF);
116} 117}
117 118
118inline flag extractFloat64Sign(float64 a) 119flag extractFloat64Sign(float64 a)
119{ 120{
120 return a >> 63; 121 return a >> 63;
121} 122}
122 123
123inline int16 extractFloat64Exp(float64 a) 124int16 extractFloat64Exp(float64 a)
124{ 125{
125 return (a >> 52) & 0x7FF; 126 return (a >> 52) & 0x7FF;
126} 127}
127 128
128inline int16 extractFloat32Exp(float32 a) 129int16 extractFloat32Exp(float32 a)
129{ 130{
130 return (a >> 23) & 0xFF; 131 return (a >> 23) & 0xFF;
131} 132}
132 133
133inline flag extractFloat32Sign(float32 a) 134flag extractFloat32Sign(float32 a)
134{ 135{
135 return a >> 31; 136 return a >> 31;
136} 137}
137 138
138inline bits32 extractFloat32Frac(float32 a) 139bits32 extractFloat32Frac(float32 a)
139{ 140{
140 return a & 0x007FFFFF; 141 return a & 0x007FFFFF;
141} 142}
142 143
143inline float64 packFloat64(flag zSign, int16 zExp, bits64 zSig) 144float64 packFloat64(flag zSign, int16 zExp, bits64 zSig)
144{ 145{
145 return (((bits64) zSign) << 63) + (((bits64) zExp) << 52) + zSig; 146 return (((bits64) zSign) << 63) + (((bits64) zExp) << 52) + zSig;
146} 147}
147 148
148inline void shift64RightJamming(bits64 a, int16 count, bits64 * zPtr) 149void shift64RightJamming(bits64 a, int16 count, bits64 * zPtr)
149{ 150{
150 bits64 z; 151 bits64 z;
151 152
@@ -338,12 +339,12 @@ static float64 addFloat64Sigs(float64 a, float64 b, flag zSign)
338 339
339} 340}
340 341
341inline float32 packFloat32(flag zSign, int16 zExp, bits32 zSig) 342float32 packFloat32(flag zSign, int16 zExp, bits32 zSig)
342{ 343{
343 return (((bits32) zSign) << 31) + (((bits32) zExp) << 23) + zSig; 344 return (((bits32) zSign) << 31) + (((bits32) zExp) << 23) + zSig;
344} 345}
345 346
346inline void shift32RightJamming(bits32 a, int16 count, bits32 * zPtr) 347void shift32RightJamming(bits32 a, int16 count, bits32 * zPtr)
347{ 348{
348 bits32 z; 349 bits32 z;
349 if (count == 0) { 350 if (count == 0) {
@@ -634,7 +635,7 @@ normalizeFloat64Subnormal(bits64 aSig, int16 * zExpPtr, bits64 * zSigPtr)
634 *zExpPtr = 1 - shiftCount; 635 *zExpPtr = 1 - shiftCount;
635} 636}
636 637
637inline void add128(bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 * z0Ptr, 638void add128(bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 * z0Ptr,
638 bits64 * z1Ptr) 639 bits64 * z1Ptr)
639{ 640{
640 bits64 z1; 641 bits64 z1;
@@ -644,7 +645,7 @@ inline void add128(bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 * z0Ptr,
644 *z0Ptr = a0 + b0 + (z1 < a1); 645 *z0Ptr = a0 + b0 + (z1 < a1);
645} 646}
646 647
647inline void 648void
648sub128(bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 * z0Ptr, 649sub128(bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 * z0Ptr,
649 bits64 * z1Ptr) 650 bits64 * z1Ptr)
650{ 651{
@@ -656,11 +657,14 @@ static bits64 estimateDiv128To64(bits64 a0, bits64 a1, bits64 b)
656{ 657{
657 bits64 b0, b1; 658 bits64 b0, b1;
658 bits64 rem0, rem1, term0, term1; 659 bits64 rem0, rem1, term0, term1;
659 bits64 z; 660 bits64 z, tmp;
660 if (b <= a0) 661 if (b <= a0)
661 return LIT64(0xFFFFFFFFFFFFFFFF); 662 return LIT64(0xFFFFFFFFFFFFFFFF);
662 b0 = b >> 32; 663 b0 = b >> 32;
663 z = (b0 << 32 <= a0) ? LIT64(0xFFFFFFFF00000000) : (a0 / b0) << 32; 664 tmp = a0;
665 do_div(tmp, b0);
666
667 z = (b0 << 32 <= a0) ? LIT64(0xFFFFFFFF00000000) : tmp << 32;
664 mul64To128(b, z, &term0, &term1); 668 mul64To128(b, z, &term0, &term1);
665 sub128(a0, a1, term0, term1, &rem0, &rem1); 669 sub128(a0, a1, term0, term1, &rem0, &rem1);
666 while (((sbits64) rem0) < 0) { 670 while (((sbits64) rem0) < 0) {
@@ -669,11 +673,13 @@ static bits64 estimateDiv128To64(bits64 a0, bits64 a1, bits64 b)
669 add128(rem0, rem1, b0, b1, &rem0, &rem1); 673 add128(rem0, rem1, b0, b1, &rem0, &rem1);
670 } 674 }
671 rem0 = (rem0 << 32) | (rem1 >> 32); 675 rem0 = (rem0 << 32) | (rem1 >> 32);
672 z |= (b0 << 32 <= rem0) ? 0xFFFFFFFF : rem0 / b0; 676 tmp = rem0;
677 do_div(tmp, b0);
678 z |= (b0 << 32 <= rem0) ? 0xFFFFFFFF : tmp;
673 return z; 679 return z;
674} 680}
675 681
676inline void mul64To128(bits64 a, bits64 b, bits64 * z0Ptr, bits64 * z1Ptr) 682void mul64To128(bits64 a, bits64 b, bits64 * z0Ptr, bits64 * z1Ptr)
677{ 683{
678 bits32 aHigh, aLow, bHigh, bLow; 684 bits32 aHigh, aLow, bHigh, bLow;
679 bits64 z0, zMiddleA, zMiddleB, z1; 685 bits64 z0, zMiddleA, zMiddleB, z1;
@@ -769,7 +775,8 @@ float32 float32_div(float32 a, float32 b)
769{ 775{
770 flag aSign, bSign, zSign; 776 flag aSign, bSign, zSign;
771 int16 aExp, bExp, zExp; 777 int16 aExp, bExp, zExp;
772 bits32 aSig, bSig, zSig; 778 bits32 aSig, bSig;
779 uint64_t zSig;
773 780
774 aSig = extractFloat32Frac(a); 781 aSig = extractFloat32Frac(a);
775 aExp = extractFloat32Exp(a); 782 aExp = extractFloat32Exp(a);
@@ -804,11 +811,13 @@ float32 float32_div(float32 a, float32 b)
804 aSig >>= 1; 811 aSig >>= 1;
805 ++zExp; 812 ++zExp;
806 } 813 }
807 zSig = (((bits64) aSig) << 32) / bSig; 814 zSig = (((bits64) aSig) << 32);
815 do_div(zSig, bSig);
816
808 if ((zSig & 0x3F) == 0) { 817 if ((zSig & 0x3F) == 0) {
809 zSig |= (((bits64) bSig) * zSig != ((bits64) aSig) << 32); 818 zSig |= (((bits64) bSig) * zSig != ((bits64) aSig) << 32);
810 } 819 }
811 return roundAndPackFloat32(zSign, zExp, zSig); 820 return roundAndPackFloat32(zSign, zExp, (bits32)zSig);
812 821
813} 822}
814 823
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
index db913855c2fd..0e174af21874 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
@@ -229,7 +229,7 @@ struct frqcr_context sh7722_get_clk_context(const char *name)
229} 229}
230 230
231/** 231/**
232 * sh7722_find_divisors - find divisor for setting rate 232 * sh7722_find_div_index - find divisor for setting rate
233 * 233 *
234 * All sh7722 clocks use the same set of multipliers/divisors. This function 234 * All sh7722 clocks use the same set of multipliers/divisors. This function
235 * chooses correct divisor to set the rate of clock with parent clock that 235 * chooses correct divisor to set the rate of clock with parent clock that
@@ -238,7 +238,7 @@ struct frqcr_context sh7722_get_clk_context(const char *name)
238 * @parent_rate: rate of parent clock 238 * @parent_rate: rate of parent clock
239 * @rate: requested rate to be set 239 * @rate: requested rate to be set
240 */ 240 */
241static int sh7722_find_divisors(unsigned long parent_rate, unsigned rate) 241static int sh7722_find_div_index(unsigned long parent_rate, unsigned rate)
242{ 242{
243 unsigned div2 = parent_rate * 2 / rate; 243 unsigned div2 = parent_rate * 2 / rate;
244 int index; 244 int index;
@@ -247,12 +247,12 @@ static int sh7722_find_divisors(unsigned long parent_rate, unsigned rate)
247 return -EINVAL; 247 return -EINVAL;
248 248
249 for (index = 1; index < ARRAY_SIZE(divisors2); index++) { 249 for (index = 1; index < ARRAY_SIZE(divisors2); index++) {
250 if (div2 > divisors2[index] && div2 <= divisors2[index]) 250 if (div2 > divisors2[index - 1] && div2 <= divisors2[index])
251 break; 251 break;
252 } 252 }
253 if (index >= ARRAY_SIZE(divisors2)) 253 if (index >= ARRAY_SIZE(divisors2))
254 index = ARRAY_SIZE(divisors2) - 1; 254 index = ARRAY_SIZE(divisors2) - 1;
255 return divisors2[index]; 255 return index;
256} 256}
257 257
258static void sh7722_frqcr_recalc(struct clk *clk) 258static void sh7722_frqcr_recalc(struct clk *clk)
@@ -279,12 +279,12 @@ static int sh7722_frqcr_set_rate(struct clk *clk, unsigned long rate,
279 return -EINVAL; 279 return -EINVAL;
280 280
281 /* look for multiplier/divisor pair */ 281 /* look for multiplier/divisor pair */
282 div = sh7722_find_divisors(parent_rate, rate); 282 div = sh7722_find_div_index(parent_rate, rate);
283 if (div<0) 283 if (div<0)
284 return div; 284 return div;
285 285
286 /* calculate new value of clock rate */ 286 /* calculate new value of clock rate */
287 clk->rate = parent_rate * 2 / div; 287 clk->rate = parent_rate * 2 / divisors2[div];
288 frqcr = ctrl_inl(FRQCR); 288 frqcr = ctrl_inl(FRQCR);
289 289
290 /* FIXME: adjust as algo_id specifies */ 290 /* FIXME: adjust as algo_id specifies */
@@ -353,7 +353,7 @@ static int sh7722_frqcr_set_rate(struct clk *clk, unsigned long rate,
353 int part_div; 353 int part_div;
354 354
355 if (likely(!err)) { 355 if (likely(!err)) {
356 part_div = sh7722_find_divisors(parent_rate, 356 part_div = sh7722_find_div_index(parent_rate,
357 rate); 357 rate);
358 if (part_div > 0) { 358 if (part_div > 0) {
359 part_ctx = sh7722_get_clk_context( 359 part_ctx = sh7722_get_clk_context(
@@ -394,12 +394,12 @@ static long sh7722_frqcr_round_rate(struct clk *clk, unsigned long rate)
394 int div; 394 int div;
395 395
396 /* look for multiplier/divisor pair */ 396 /* look for multiplier/divisor pair */
397 div = sh7722_find_divisors(parent_rate, rate); 397 div = sh7722_find_div_index(parent_rate, rate);
398 if (div < 0) 398 if (div < 0)
399 return clk->rate; 399 return clk->rate;
400 400
401 /* calculate new value of clock rate */ 401 /* calculate new value of clock rate */
402 return parent_rate * 2 / div; 402 return parent_rate * 2 / divisors2[div];
403} 403}
404 404
405static struct clk_ops sh7722_frqcr_clk_ops = { 405static struct clk_ops sh7722_frqcr_clk_ops = {
@@ -421,7 +421,7 @@ static int sh7722_siu_set_rate(struct clk *clk, unsigned long rate, int algo_id)
421 int div; 421 int div;
422 422
423 r = ctrl_inl(clk->arch_flags); 423 r = ctrl_inl(clk->arch_flags);
424 div = sh7722_find_divisors(clk->parent->rate, rate); 424 div = sh7722_find_div_index(clk->parent->rate, rate);
425 if (div < 0) 425 if (div < 0)
426 return div; 426 return div;
427 r = (r & ~0xF) | div; 427 r = (r & ~0xF) | div;
@@ -516,16 +516,19 @@ static struct clk_ops sh7722_video_clk_ops = {
516static struct clk sh7722_umem_clock = { 516static struct clk sh7722_umem_clock = {
517 .name = "umem_clk", 517 .name = "umem_clk",
518 .ops = &sh7722_frqcr_clk_ops, 518 .ops = &sh7722_frqcr_clk_ops,
519 .flags = CLK_RATE_PROPAGATES,
519}; 520};
520 521
521static struct clk sh7722_sh_clock = { 522static struct clk sh7722_sh_clock = {
522 .name = "sh_clk", 523 .name = "sh_clk",
523 .ops = &sh7722_frqcr_clk_ops, 524 .ops = &sh7722_frqcr_clk_ops,
525 .flags = CLK_RATE_PROPAGATES,
524}; 526};
525 527
526static struct clk sh7722_peripheral_clock = { 528static struct clk sh7722_peripheral_clock = {
527 .name = "peripheral_clk", 529 .name = "peripheral_clk",
528 .ops = &sh7722_frqcr_clk_ops, 530 .ops = &sh7722_frqcr_clk_ops,
531 .flags = CLK_RATE_PROPAGATES,
529}; 532};
530 533
531static struct clk sh7722_sdram_clock = { 534static struct clk sh7722_sdram_clock = {
@@ -533,6 +536,11 @@ static struct clk sh7722_sdram_clock = {
533 .ops = &sh7722_frqcr_clk_ops, 536 .ops = &sh7722_frqcr_clk_ops,
534}; 537};
535 538
539static struct clk sh7722_r_clock = {
540 .name = "r_clk",
541 .rate = 32768,
542 .flags = CLK_RATE_PROPAGATES,
543};
536 544
537#ifndef CONFIG_CPU_SUBTYPE_SH7343 545#ifndef CONFIG_CPU_SUBTYPE_SH7343
538 546
@@ -567,12 +575,30 @@ static struct clk sh7722_video_clock = {
567 .ops = &sh7722_video_clk_ops, 575 .ops = &sh7722_video_clk_ops,
568}; 576};
569 577
570static int sh7722_mstpcr_start_stop(struct clk *clk, unsigned long reg, 578#define MSTPCR_ARCH_FLAGS(reg, bit) (((reg) << 8) | (bit))
571 int enable) 579#define MSTPCR_ARCH_FLAGS_REG(value) ((value) >> 8)
580#define MSTPCR_ARCH_FLAGS_BIT(value) ((value) & 0xff)
581
582static int sh7722_mstpcr_start_stop(struct clk *clk, int enable)
572{ 583{
573 unsigned long bit = clk->arch_flags; 584 unsigned long bit = MSTPCR_ARCH_FLAGS_BIT(clk->arch_flags);
585 unsigned long reg;
574 unsigned long r; 586 unsigned long r;
575 587
588 switch(MSTPCR_ARCH_FLAGS_REG(clk->arch_flags)) {
589 case 0:
590 reg = MSTPCR0;
591 break;
592 case 1:
593 reg = MSTPCR1;
594 break;
595 case 2:
596 reg = MSTPCR2;
597 break;
598 default:
599 return -EINVAL;
600 }
601
576 r = ctrl_inl(reg); 602 r = ctrl_inl(reg);
577 603
578 if (enable) 604 if (enable)
@@ -584,96 +610,175 @@ static int sh7722_mstpcr_start_stop(struct clk *clk, unsigned long reg,
584 return 0; 610 return 0;
585} 611}
586 612
587static void sh7722_mstpcr0_enable(struct clk *clk) 613static void sh7722_mstpcr_enable(struct clk *clk)
588{
589 sh7722_mstpcr_start_stop(clk, MSTPCR0, 1);
590}
591
592static void sh7722_mstpcr0_disable(struct clk *clk)
593{
594 sh7722_mstpcr_start_stop(clk, MSTPCR0, 0);
595}
596
597static void sh7722_mstpcr1_enable(struct clk *clk)
598{
599 sh7722_mstpcr_start_stop(clk, MSTPCR1, 1);
600}
601
602static void sh7722_mstpcr1_disable(struct clk *clk)
603{ 614{
604 sh7722_mstpcr_start_stop(clk, MSTPCR1, 0); 615 sh7722_mstpcr_start_stop(clk, 1);
605} 616}
606 617
607static void sh7722_mstpcr2_enable(struct clk *clk) 618static void sh7722_mstpcr_disable(struct clk *clk)
608{ 619{
609 sh7722_mstpcr_start_stop(clk, MSTPCR2, 1); 620 sh7722_mstpcr_start_stop(clk, 0);
610} 621}
611 622
612static void sh7722_mstpcr2_disable(struct clk *clk) 623static void sh7722_mstpcr_recalc(struct clk *clk)
613{ 624{
614 sh7722_mstpcr_start_stop(clk, MSTPCR2, 0); 625 if (clk->parent)
626 clk->rate = clk->parent->rate;
615} 627}
616 628
617static struct clk_ops sh7722_mstpcr0_clk_ops = { 629static struct clk_ops sh7722_mstpcr_clk_ops = {
618 .enable = sh7722_mstpcr0_enable, 630 .enable = sh7722_mstpcr_enable,
619 .disable = sh7722_mstpcr0_disable, 631 .disable = sh7722_mstpcr_disable,
620}; 632 .recalc = sh7722_mstpcr_recalc,
621
622static struct clk_ops sh7722_mstpcr1_clk_ops = {
623 .enable = sh7722_mstpcr1_enable,
624 .disable = sh7722_mstpcr1_disable,
625}; 633};
626 634
627static struct clk_ops sh7722_mstpcr2_clk_ops = { 635#define MSTPCR(_name, _parent, regnr, bitnr) \
628 .enable = sh7722_mstpcr2_enable, 636{ \
629 .disable = sh7722_mstpcr2_disable, 637 .name = _name, \
630}; 638 .arch_flags = MSTPCR_ARCH_FLAGS(regnr, bitnr), \
631 639 .ops = (void *)_parent, \
632#define DECLARE_MSTPCRN(regnr, bitnr, bitstr) \
633{ \
634 .name = "mstp" __stringify(regnr) bitstr, \
635 .arch_flags = bitnr, \
636 .ops = &sh7722_mstpcr ## regnr ## _clk_ops, \
637} 640}
638 641
639#define DECLARE_MSTPCR(regnr) \ 642static struct clk sh7722_mstpcr_clocks[] = {
640 DECLARE_MSTPCRN(regnr, 31, "31"), \ 643#if defined(CONFIG_CPU_SUBTYPE_SH7722)
641 DECLARE_MSTPCRN(regnr, 30, "30"), \ 644 MSTPCR("uram0", "umem_clk", 0, 28),
642 DECLARE_MSTPCRN(regnr, 29, "29"), \ 645 MSTPCR("xymem0", "bus_clk", 0, 26),
643 DECLARE_MSTPCRN(regnr, 28, "28"), \ 646 MSTPCR("tmu0", "peripheral_clk", 0, 15),
644 DECLARE_MSTPCRN(regnr, 27, "27"), \ 647 MSTPCR("cmt0", "r_clk", 0, 14),
645 DECLARE_MSTPCRN(regnr, 26, "26"), \ 648 MSTPCR("rwdt0", "r_clk", 0, 13),
646 DECLARE_MSTPCRN(regnr, 25, "25"), \ 649 MSTPCR("flctl0", "peripheral_clk", 0, 10),
647 DECLARE_MSTPCRN(regnr, 24, "24"), \ 650 MSTPCR("scif0", "peripheral_clk", 0, 7),
648 DECLARE_MSTPCRN(regnr, 23, "23"), \ 651 MSTPCR("scif1", "peripheral_clk", 0, 6),
649 DECLARE_MSTPCRN(regnr, 22, "22"), \ 652 MSTPCR("scif2", "peripheral_clk", 0, 5),
650 DECLARE_MSTPCRN(regnr, 21, "21"), \ 653 MSTPCR("i2c0", "peripheral_clk", 1, 9),
651 DECLARE_MSTPCRN(regnr, 20, "20"), \ 654 MSTPCR("rtc0", "r_clk", 1, 8),
652 DECLARE_MSTPCRN(regnr, 19, "19"), \ 655 MSTPCR("sdhi0", "peripheral_clk", 2, 18),
653 DECLARE_MSTPCRN(regnr, 18, "18"), \ 656 MSTPCR("keysc0", "r_clk", 2, 14),
654 DECLARE_MSTPCRN(regnr, 17, "17"), \ 657 MSTPCR("usbf0", "peripheral_clk", 2, 11),
655 DECLARE_MSTPCRN(regnr, 16, "16"), \ 658 MSTPCR("2dg0", "bus_clk", 2, 9),
656 DECLARE_MSTPCRN(regnr, 15, "15"), \ 659 MSTPCR("siu0", "bus_clk", 2, 8),
657 DECLARE_MSTPCRN(regnr, 14, "14"), \ 660 MSTPCR("vou0", "bus_clk", 2, 5),
658 DECLARE_MSTPCRN(regnr, 13, "13"), \ 661 MSTPCR("jpu0", "bus_clk", 2, 6),
659 DECLARE_MSTPCRN(regnr, 12, "12"), \ 662 MSTPCR("beu0", "bus_clk", 2, 4),
660 DECLARE_MSTPCRN(regnr, 11, "11"), \ 663 MSTPCR("ceu0", "bus_clk", 2, 3),
661 DECLARE_MSTPCRN(regnr, 10, "10"), \ 664 MSTPCR("veu0", "bus_clk", 2, 2),
662 DECLARE_MSTPCRN(regnr, 9, "09"), \ 665 MSTPCR("vpu0", "bus_clk", 2, 1),
663 DECLARE_MSTPCRN(regnr, 8, "08"), \ 666 MSTPCR("lcdc0", "bus_clk", 2, 0),
664 DECLARE_MSTPCRN(regnr, 7, "07"), \ 667#endif
665 DECLARE_MSTPCRN(regnr, 6, "06"), \ 668#if defined(CONFIG_CPU_SUBTYPE_SH7723)
666 DECLARE_MSTPCRN(regnr, 5, "05"), \ 669 /* See page 60 of Datasheet V1.0: Overview -> Block Diagram */
667 DECLARE_MSTPCRN(regnr, 4, "04"), \ 670 MSTPCR("tlb0", "cpu_clk", 0, 31),
668 DECLARE_MSTPCRN(regnr, 3, "03"), \ 671 MSTPCR("ic0", "cpu_clk", 0, 30),
669 DECLARE_MSTPCRN(regnr, 2, "02"), \ 672 MSTPCR("oc0", "cpu_clk", 0, 29),
670 DECLARE_MSTPCRN(regnr, 1, "01"), \ 673 MSTPCR("l2c0", "sh_clk", 0, 28),
671 DECLARE_MSTPCRN(regnr, 0, "00") 674 MSTPCR("ilmem0", "cpu_clk", 0, 27),
672 675 MSTPCR("fpu0", "cpu_clk", 0, 24),
673static struct clk sh7722_mstpcr[] = { 676 MSTPCR("intc0", "cpu_clk", 0, 22),
674 DECLARE_MSTPCR(0), 677 MSTPCR("dmac0", "bus_clk", 0, 21),
675 DECLARE_MSTPCR(1), 678 MSTPCR("sh0", "sh_clk", 0, 20),
676 DECLARE_MSTPCR(2), 679 MSTPCR("hudi0", "peripheral_clk", 0, 19),
680 MSTPCR("ubc0", "cpu_clk", 0, 17),
681 MSTPCR("tmu0", "peripheral_clk", 0, 15),
682 MSTPCR("cmt0", "r_clk", 0, 14),
683 MSTPCR("rwdt0", "r_clk", 0, 13),
684 MSTPCR("dmac1", "bus_clk", 0, 12),
685 MSTPCR("tmu1", "peripheral_clk", 0, 11),
686 MSTPCR("flctl0", "peripheral_clk", 0, 10),
687 MSTPCR("scif0", "peripheral_clk", 0, 9),
688 MSTPCR("scif1", "peripheral_clk", 0, 8),
689 MSTPCR("scif2", "peripheral_clk", 0, 7),
690 MSTPCR("scif3", "bus_clk", 0, 6),
691 MSTPCR("scif4", "bus_clk", 0, 5),
692 MSTPCR("scif5", "bus_clk", 0, 4),
693 MSTPCR("msiof0", "bus_clk", 0, 2),
694 MSTPCR("msiof1", "bus_clk", 0, 1),
695 MSTPCR("meram0", "sh_clk", 0, 0),
696 MSTPCR("i2c0", "peripheral_clk", 1, 9),
697 MSTPCR("rtc0", "r_clk", 1, 8),
698 MSTPCR("atapi0", "sh_clk", 2, 28),
699 MSTPCR("adc0", "peripheral_clk", 2, 28),
700 MSTPCR("tpu0", "bus_clk", 2, 25),
701 MSTPCR("irda0", "peripheral_clk", 2, 24),
702 MSTPCR("tsif0", "bus_clk", 2, 22),
703 MSTPCR("icb0", "bus_clk", 2, 21),
704 MSTPCR("sdhi0", "bus_clk", 2, 18),
705 MSTPCR("sdhi1", "bus_clk", 2, 17),
706 MSTPCR("keysc0", "r_clk", 2, 14),
707 MSTPCR("usb0", "bus_clk", 2, 11),
708 MSTPCR("2dg0", "bus_clk", 2, 10),
709 MSTPCR("siu0", "bus_clk", 2, 8),
710 MSTPCR("veu1", "bus_clk", 2, 6),
711 MSTPCR("vou0", "bus_clk", 2, 5),
712 MSTPCR("beu0", "bus_clk", 2, 4),
713 MSTPCR("ceu0", "bus_clk", 2, 3),
714 MSTPCR("veu0", "bus_clk", 2, 2),
715 MSTPCR("vpu0", "bus_clk", 2, 1),
716 MSTPCR("lcdc0", "bus_clk", 2, 0),
717#endif
718#if defined(CONFIG_CPU_SUBTYPE_SH7343)
719 MSTPCR("uram0", "umem_clk", 0, 28),
720 MSTPCR("xymem0", "bus_clk", 0, 26),
721 MSTPCR("tmu0", "peripheral_clk", 0, 15),
722 MSTPCR("cmt0", "r_clk", 0, 14),
723 MSTPCR("rwdt0", "r_clk", 0, 13),
724 MSTPCR("scif0", "peripheral_clk", 0, 7),
725 MSTPCR("scif1", "peripheral_clk", 0, 6),
726 MSTPCR("scif2", "peripheral_clk", 0, 5),
727 MSTPCR("scif3", "peripheral_clk", 0, 4),
728 MSTPCR("i2c0", "peripheral_clk", 1, 9),
729 MSTPCR("i2c1", "peripheral_clk", 1, 8),
730 MSTPCR("sdhi0", "peripheral_clk", 2, 18),
731 MSTPCR("keysc0", "r_clk", 2, 14),
732 MSTPCR("usbf0", "peripheral_clk", 2, 11),
733 MSTPCR("siu0", "bus_clk", 2, 8),
734 MSTPCR("jpu0", "bus_clk", 2, 6),
735 MSTPCR("vou0", "bus_clk", 2, 5),
736 MSTPCR("beu0", "bus_clk", 2, 4),
737 MSTPCR("ceu0", "bus_clk", 2, 3),
738 MSTPCR("veu0", "bus_clk", 2, 2),
739 MSTPCR("vpu0", "bus_clk", 2, 1),
740 MSTPCR("lcdc0", "bus_clk", 2, 0),
741#endif
742#if defined(CONFIG_CPU_SUBTYPE_SH7366)
743 /* See page 52 of Datasheet V0.40: Overview -> Block Diagram */
744 MSTPCR("tlb0", "cpu_clk", 0, 31),
745 MSTPCR("ic0", "cpu_clk", 0, 30),
746 MSTPCR("oc0", "cpu_clk", 0, 29),
747 MSTPCR("rsmem0", "sh_clk", 0, 28),
748 MSTPCR("xymem0", "cpu_clk", 0, 26),
749 MSTPCR("intc30", "peripheral_clk", 0, 23),
750 MSTPCR("intc0", "peripheral_clk", 0, 22),
751 MSTPCR("dmac0", "bus_clk", 0, 21),
752 MSTPCR("sh0", "sh_clk", 0, 20),
753 MSTPCR("hudi0", "peripheral_clk", 0, 19),
754 MSTPCR("ubc0", "cpu_clk", 0, 17),
755 MSTPCR("tmu0", "peripheral_clk", 0, 15),
756 MSTPCR("cmt0", "r_clk", 0, 14),
757 MSTPCR("rwdt0", "r_clk", 0, 13),
758 MSTPCR("flctl0", "peripheral_clk", 0, 10),
759 MSTPCR("scif0", "peripheral_clk", 0, 7),
760 MSTPCR("scif1", "bus_clk", 0, 6),
761 MSTPCR("scif2", "bus_clk", 0, 5),
762 MSTPCR("msiof0", "peripheral_clk", 0, 2),
763 MSTPCR("sbr0", "peripheral_clk", 0, 1),
764 MSTPCR("i2c0", "peripheral_clk", 1, 9),
765 MSTPCR("icb0", "bus_clk", 2, 27),
766 MSTPCR("meram0", "sh_clk", 2, 26),
767 MSTPCR("dacc0", "peripheral_clk", 2, 24),
768 MSTPCR("dacy0", "peripheral_clk", 2, 23),
769 MSTPCR("tsif0", "bus_clk", 2, 22),
770 MSTPCR("sdhi0", "bus_clk", 2, 18),
771 MSTPCR("mmcif0", "bus_clk", 2, 17),
772 MSTPCR("usb0", "bus_clk", 2, 11),
773 MSTPCR("siu0", "bus_clk", 2, 8),
774 MSTPCR("veu1", "bus_clk", 2, 7),
775 MSTPCR("vou0", "bus_clk", 2, 5),
776 MSTPCR("beu0", "bus_clk", 2, 4),
777 MSTPCR("ceu0", "bus_clk", 2, 3),
778 MSTPCR("veu0", "bus_clk", 2, 2),
779 MSTPCR("vpu0", "bus_clk", 2, 1),
780 MSTPCR("lcdc0", "bus_clk", 2, 0),
781#endif
677}; 782};
678 783
679static struct clk *sh7722_clocks[] = { 784static struct clk *sh7722_clocks[] = {
@@ -710,21 +815,30 @@ arch_init_clk_ops(struct clk_ops **ops, int type)
710 815
711int __init arch_clk_init(void) 816int __init arch_clk_init(void)
712{ 817{
713 struct clk *master; 818 struct clk *clk;
714 int i; 819 int i;
715 820
716 master = clk_get(NULL, "master_clk"); 821 clk = clk_get(NULL, "master_clk");
717 for (i = 0; i < ARRAY_SIZE(sh7722_clocks); i++) { 822 for (i = 0; i < ARRAY_SIZE(sh7722_clocks); i++) {
718 pr_debug( "Registering clock '%s'\n", sh7722_clocks[i]->name); 823 pr_debug( "Registering clock '%s'\n", sh7722_clocks[i]->name);
719 sh7722_clocks[i]->parent = master; 824 sh7722_clocks[i]->parent = clk;
720 clk_register(sh7722_clocks[i]); 825 clk_register(sh7722_clocks[i]);
721 } 826 }
722 clk_put(master); 827 clk_put(clk);
723 828
724 for (i = 0; i < ARRAY_SIZE(sh7722_mstpcr); i++) { 829 clk_register(&sh7722_r_clock);
725 pr_debug( "Registering mstpcr '%s'\n", sh7722_mstpcr[i].name); 830
726 clk_register(&sh7722_mstpcr[i]); 831 for (i = 0; i < ARRAY_SIZE(sh7722_mstpcr_clocks); i++) {
832 pr_debug( "Registering mstpcr clock '%s'\n",
833 sh7722_mstpcr_clocks[i].name);
834 clk = clk_get(NULL, (void *) sh7722_mstpcr_clocks[i].ops);
835 sh7722_mstpcr_clocks[i].parent = clk;
836 sh7722_mstpcr_clocks[i].ops = &sh7722_mstpcr_clk_ops;
837 clk_register(&sh7722_mstpcr_clocks[i]);
838 clk_put(clk);
727 } 839 }
728 840
841 clk_recalc_rate(&sh7722_r_clock); /* make sure rate gets propagated */
842
729 return 0; 843 return 0;
730} 844}
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c
index 78881b4214da..0623e377f488 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c
@@ -30,6 +30,7 @@ static struct resource iic0_resources[] = {
30 30
31static struct platform_device iic0_device = { 31static struct platform_device iic0_device = {
32 .name = "i2c-sh_mobile", 32 .name = "i2c-sh_mobile",
33 .id = 0, /* "i2c0" clock */
33 .num_resources = ARRAY_SIZE(iic0_resources), 34 .num_resources = ARRAY_SIZE(iic0_resources),
34 .resource = iic0_resources, 35 .resource = iic0_resources,
35}; 36};
@@ -50,6 +51,7 @@ static struct resource iic1_resources[] = {
50 51
51static struct platform_device iic1_device = { 52static struct platform_device iic1_device = {
52 .name = "i2c-sh_mobile", 53 .name = "i2c-sh_mobile",
54 .id = 1, /* "i2c1" clock */
53 .num_resources = ARRAY_SIZE(iic1_resources), 55 .num_resources = ARRAY_SIZE(iic1_resources),
54 .resource = iic1_resources, 56 .resource = iic1_resources,
55}; 57};
@@ -115,7 +117,22 @@ static struct plat_sci_port sci_platform_data[] = {
115 .mapbase = 0xffe00000, 117 .mapbase = 0xffe00000,
116 .flags = UPF_BOOT_AUTOCONF, 118 .flags = UPF_BOOT_AUTOCONF,
117 .type = PORT_SCIF, 119 .type = PORT_SCIF,
118 .irqs = { 80, 81, 83, 82 }, 120 .irqs = { 80, 80, 80, 80 },
121 }, {
122 .mapbase = 0xffe10000,
123 .flags = UPF_BOOT_AUTOCONF,
124 .type = PORT_SCIF,
125 .irqs = { 81, 81, 81, 81 },
126 }, {
127 .mapbase = 0xffe20000,
128 .flags = UPF_BOOT_AUTOCONF,
129 .type = PORT_SCIF,
130 .irqs = { 82, 82, 82, 82 },
131 }, {
132 .mapbase = 0xffe30000,
133 .flags = UPF_BOOT_AUTOCONF,
134 .type = PORT_SCIF,
135 .irqs = { 83, 83, 83, 83 },
119 }, { 136 }, {
120 .flags = 0, 137 .flags = 0,
121 } 138 }
@@ -139,18 +156,10 @@ static struct platform_device *sh7343_devices[] __initdata = {
139 156
140static int __init sh7343_devices_setup(void) 157static int __init sh7343_devices_setup(void)
141{ 158{
142 clk_always_enable("mstp031"); /* TLB */ 159 clk_always_enable("uram0"); /* URAM */
143 clk_always_enable("mstp030"); /* IC */ 160 clk_always_enable("xymem0"); /* XYMEM */
144 clk_always_enable("mstp029"); /* OC */ 161 clk_always_enable("veu0"); /* VEU */
145 clk_always_enable("mstp028"); /* URAM */ 162 clk_always_enable("vpu0"); /* VPU */
146 clk_always_enable("mstp026"); /* XYMEM */
147 clk_always_enable("mstp023"); /* INTC3 */
148 clk_always_enable("mstp022"); /* INTC */
149 clk_always_enable("mstp020"); /* SuperHyway */
150 clk_always_enable("mstp109"); /* I2C0 */
151 clk_always_enable("mstp108"); /* I2C1 */
152 clk_always_enable("mstp202"); /* VEU */
153 clk_always_enable("mstp201"); /* VPU */
154 163
155 platform_resource_setup_memory(&vpu_device, "vpu", 1 << 20); 164 platform_resource_setup_memory(&vpu_device, "vpu", 1 << 20);
156 platform_resource_setup_memory(&veu_device, "veu", 2 << 20); 165 platform_resource_setup_memory(&veu_device, "veu", 2 << 20);
@@ -171,7 +180,7 @@ enum {
171 MMC_ERR, MMC_TRAN, MMC_FSTAT, MMC_FRDY, 180 MMC_ERR, MMC_TRAN, MMC_FSTAT, MMC_FRDY,
172 DMAC4, DMAC5, DMAC_DADERR, 181 DMAC4, DMAC5, DMAC_DADERR,
173 KEYSC, 182 KEYSC,
174 SCIF, SCIF1, SCIF2, SCIF3, SCIF4, 183 SCIF, SCIF1, SCIF2, SCIF3,
175 SIOF0, SIOF1, SIO, 184 SIOF0, SIOF1, SIO,
176 FLCTL_FLSTEI, FLCTL_FLENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I, 185 FLCTL_FLSTEI, FLCTL_FLENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I,
177 I2C0_ALI, I2C0_TACKI, I2C0_WAITI, I2C0_DTEI, 186 I2C0_ALI, I2C0_TACKI, I2C0_WAITI, I2C0_DTEI,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
index e17db39b97aa..839ae97a7fd2 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
@@ -32,6 +32,7 @@ static struct resource iic_resources[] = {
32 32
33static struct platform_device iic_device = { 33static struct platform_device iic_device = {
34 .name = "i2c-sh_mobile", 34 .name = "i2c-sh_mobile",
35 .id = 0, /* "i2c0" clock */
35 .num_resources = ARRAY_SIZE(iic_resources), 36 .num_resources = ARRAY_SIZE(iic_resources),
36 .resource = iic_resources, 37 .resource = iic_resources,
37}; 38};
@@ -176,19 +177,11 @@ static struct platform_device *sh7366_devices[] __initdata = {
176 177
177static int __init sh7366_devices_setup(void) 178static int __init sh7366_devices_setup(void)
178{ 179{
179 clk_always_enable("mstp031"); /* TLB */ 180 clk_always_enable("rsmem0"); /* RSMEM */
180 clk_always_enable("mstp030"); /* IC */ 181 clk_always_enable("xymem0"); /* XYMEM */
181 clk_always_enable("mstp029"); /* OC */ 182 clk_always_enable("veu1"); /* VEU-2 */
182 clk_always_enable("mstp028"); /* RSMEM */ 183 clk_always_enable("veu0"); /* VEU-1 */
183 clk_always_enable("mstp026"); /* XYMEM */ 184 clk_always_enable("vpu0"); /* VPU */
184 clk_always_enable("mstp023"); /* INTC3 */
185 clk_always_enable("mstp022"); /* INTC */
186 clk_always_enable("mstp020"); /* SuperHyway */
187 clk_always_enable("mstp109"); /* I2C */
188 clk_always_enable("mstp211"); /* USB */
189 clk_always_enable("mstp207"); /* VEU-2 */
190 clk_always_enable("mstp202"); /* VEU-1 */
191 clk_always_enable("mstp201"); /* VPU */
192 185
193 platform_resource_setup_memory(&vpu_device, "vpu", 2 << 20); 186 platform_resource_setup_memory(&vpu_device, "vpu", 2 << 20);
194 platform_resource_setup_memory(&veu0_device, "veu0", 2 << 20); 187 platform_resource_setup_memory(&veu0_device, "veu0", 2 << 20);
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
index ef77ee1d9f53..50cf6838ec41 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
@@ -62,7 +62,7 @@ static struct resource usbf_resources[] = {
62 62
63static struct platform_device usbf_device = { 63static struct platform_device usbf_device = {
64 .name = "m66592_udc", 64 .name = "m66592_udc",
65 .id = -1, 65 .id = 0, /* "usbf0" clock */
66 .dev = { 66 .dev = {
67 .dma_mask = NULL, 67 .dma_mask = NULL,
68 .coherent_dma_mask = 0xffffffff, 68 .coherent_dma_mask = 0xffffffff,
@@ -87,6 +87,7 @@ static struct resource iic_resources[] = {
87 87
88static struct platform_device iic_device = { 88static struct platform_device iic_device = {
89 .name = "i2c-sh_mobile", 89 .name = "i2c-sh_mobile",
90 .id = 0, /* "i2c0" clock */
90 .num_resources = ARRAY_SIZE(iic_resources), 91 .num_resources = ARRAY_SIZE(iic_resources),
91 .resource = iic_resources, 92 .resource = iic_resources,
92}; 93};
@@ -147,6 +148,34 @@ static struct platform_device veu_device = {
147 .num_resources = ARRAY_SIZE(veu_resources), 148 .num_resources = ARRAY_SIZE(veu_resources),
148}; 149};
149 150
151static struct uio_info jpu_platform_data = {
152 .name = "JPU",
153 .version = "0",
154 .irq = 27,
155};
156
157static struct resource jpu_resources[] = {
158 [0] = {
159 .name = "JPU",
160 .start = 0xfea00000,
161 .end = 0xfea102d0,
162 .flags = IORESOURCE_MEM,
163 },
164 [1] = {
165 /* place holder for contiguous memory */
166 },
167};
168
169static struct platform_device jpu_device = {
170 .name = "uio_pdrv_genirq",
171 .id = 2,
172 .dev = {
173 .platform_data = &jpu_platform_data,
174 },
175 .resource = jpu_resources,
176 .num_resources = ARRAY_SIZE(jpu_resources),
177};
178
150static struct plat_sci_port sci_platform_data[] = { 179static struct plat_sci_port sci_platform_data[] = {
151 { 180 {
152 .mapbase = 0xffe00000, 181 .mapbase = 0xffe00000,
@@ -186,24 +215,21 @@ static struct platform_device *sh7722_devices[] __initdata = {
186 &sci_device, 215 &sci_device,
187 &vpu_device, 216 &vpu_device,
188 &veu_device, 217 &veu_device,
218 &jpu_device,
189}; 219};
190 220
191static int __init sh7722_devices_setup(void) 221static int __init sh7722_devices_setup(void)
192{ 222{
193 clk_always_enable("mstp031"); /* TLB */ 223 clk_always_enable("uram0"); /* URAM */
194 clk_always_enable("mstp030"); /* IC */ 224 clk_always_enable("xymem0"); /* XYMEM */
195 clk_always_enable("mstp029"); /* OC */ 225 clk_always_enable("rtc0"); /* RTC */
196 clk_always_enable("mstp028"); /* URAM */ 226 clk_always_enable("veu0"); /* VEU */
197 clk_always_enable("mstp026"); /* XYMEM */ 227 clk_always_enable("vpu0"); /* VPU */
198 clk_always_enable("mstp022"); /* INTC */ 228 clk_always_enable("jpu0"); /* JPU */
199 clk_always_enable("mstp020"); /* SuperHyway */
200 clk_always_enable("mstp109"); /* I2C */
201 clk_always_enable("mstp211"); /* USB */
202 clk_always_enable("mstp202"); /* VEU */
203 clk_always_enable("mstp201"); /* VPU */
204 229
205 platform_resource_setup_memory(&vpu_device, "vpu", 1 << 20); 230 platform_resource_setup_memory(&vpu_device, "vpu", 1 << 20);
206 platform_resource_setup_memory(&veu_device, "veu", 2 << 20); 231 platform_resource_setup_memory(&veu_device, "veu", 2 << 20);
232 platform_resource_setup_memory(&jpu_device, "jpu", 2 << 20);
207 233
208 return platform_add_devices(sh7722_devices, 234 return platform_add_devices(sh7722_devices,
209 ARRAY_SIZE(sh7722_devices)); 235 ARRAY_SIZE(sh7722_devices));
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
index 6d9e6972cfc9..849770d780ae 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
@@ -215,6 +215,7 @@ static struct resource iic_resources[] = {
215 215
216static struct platform_device iic_device = { 216static struct platform_device iic_device = {
217 .name = "i2c-sh_mobile", 217 .name = "i2c-sh_mobile",
218 .id = 0, /* "i2c0" clock */
218 .num_resources = ARRAY_SIZE(iic_resources), 219 .num_resources = ARRAY_SIZE(iic_resources),
219 .resource = iic_resources, 220 .resource = iic_resources,
220}; 221};
@@ -231,19 +232,11 @@ static struct platform_device *sh7723_devices[] __initdata = {
231 232
232static int __init sh7723_devices_setup(void) 233static int __init sh7723_devices_setup(void)
233{ 234{
234 clk_always_enable("mstp031"); /* TLB */ 235 clk_always_enable("meram0"); /* MERAM */
235 clk_always_enable("mstp030"); /* IC */ 236 clk_always_enable("rtc0"); /* RTC */
236 clk_always_enable("mstp029"); /* OC */ 237 clk_always_enable("veu1"); /* VEU2H1 */
237 clk_always_enable("mstp024"); /* FPU */ 238 clk_always_enable("veu0"); /* VEU2H0 */
238 clk_always_enable("mstp022"); /* INTC */ 239 clk_always_enable("vpu0"); /* VPU */
239 clk_always_enable("mstp020"); /* SuperHyway */
240 clk_always_enable("mstp000"); /* MERAM */
241 clk_always_enable("mstp109"); /* I2C */
242 clk_always_enable("mstp108"); /* RTC */
243 clk_always_enable("mstp211"); /* USB */
244 clk_always_enable("mstp206"); /* VEU2H1 */
245 clk_always_enable("mstp202"); /* VEU2H0 */
246 clk_always_enable("mstp201"); /* VPU */
247 240
248 platform_resource_setup_memory(&vpu_device, "vpu", 2 << 20); 241 platform_resource_setup_memory(&vpu_device, "vpu", 2 << 20);
249 platform_resource_setup_memory(&veu0_device, "veu0", 2 << 20); 242 platform_resource_setup_memory(&veu0_device, "veu0", 2 << 20);
diff --git a/arch/sh/kernel/debugtraps.S b/arch/sh/kernel/debugtraps.S
index 13b66746410a..591741383ee6 100644
--- a/arch/sh/kernel/debugtraps.S
+++ b/arch/sh/kernel/debugtraps.S
@@ -3,7 +3,7 @@
3 * 3 *
4 * Debug trap jump tables for SuperH 4 * Debug trap jump tables for SuperH
5 * 5 *
6 * Copyright (C) 2006 Paul Mundt 6 * Copyright (C) 2006 - 2008 Paul Mundt
7 * 7 *
8 * This file is subject to the terms and conditions of the GNU General Public 8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive 9 * License. See the file "COPYING" in the main directory of this archive
@@ -12,12 +12,13 @@
12#include <linux/sys.h> 12#include <linux/sys.h>
13#include <linux/linkage.h> 13#include <linux/linkage.h>
14 14
15#if !defined(CONFIG_SH_KGDB) 15#if !defined(CONFIG_KGDB)
16#define kgdb_handle_exception debug_trap_handler 16#define breakpoint_trap_handler debug_trap_handler
17#define singlestep_trap_handler debug_trap_handler
17#endif 18#endif
18 19
19#if !defined(CONFIG_SH_STANDARD_BIOS) 20#if !defined(CONFIG_SH_STANDARD_BIOS)
20#define sh_bios_handler debug_trap_handler 21#define sh_bios_handler debug_trap_handler
21#endif 22#endif
22 23
23 .data 24 .data
@@ -35,7 +36,7 @@ ENTRY(debug_trap_table)
35 .long debug_trap_handler /* 0x39 */ 36 .long debug_trap_handler /* 0x39 */
36 .long debug_trap_handler /* 0x3a */ 37 .long debug_trap_handler /* 0x3a */
37 .long debug_trap_handler /* 0x3b */ 38 .long debug_trap_handler /* 0x3b */
38 .long kgdb_handle_exception /* 0x3c */ 39 .long breakpoint_trap_handler /* 0x3c */
39 .long debug_trap_handler /* 0x3d */ 40 .long singlestep_trap_handler /* 0x3d */
40 .long bug_trap_handler /* 0x3e */ 41 .long bug_trap_handler /* 0x3e */
41 .long sh_bios_handler /* 0x3f */ 42 .long sh_bios_handler /* 0x3f */
diff --git a/arch/sh/kernel/disassemble.c b/arch/sh/kernel/disassemble.c
new file mode 100644
index 000000000000..64d5d8dded7c
--- /dev/null
+++ b/arch/sh/kernel/disassemble.c
@@ -0,0 +1,573 @@
1/*
2 * Disassemble SuperH instructions.
3 *
4 * Copyright (C) 1999 kaz Kojima
5 * Copyright (C) 2008 Paul Mundt
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details.
10 */
11#include <linux/kernel.h>
12#include <linux/string.h>
13#include <linux/uaccess.h>
14
15/*
16 * Format of an instruction in memory.
17 */
18typedef enum {
19 HEX_0, HEX_1, HEX_2, HEX_3, HEX_4, HEX_5, HEX_6, HEX_7,
20 HEX_8, HEX_9, HEX_A, HEX_B, HEX_C, HEX_D, HEX_E, HEX_F,
21 REG_N, REG_M, REG_NM, REG_B,
22 BRANCH_12, BRANCH_8,
23 DISP_8, DISP_4,
24 IMM_4, IMM_4BY2, IMM_4BY4, PCRELIMM_8BY2, PCRELIMM_8BY4,
25 IMM_8, IMM_8BY2, IMM_8BY4,
26} sh_nibble_type;
27
28typedef enum {
29 A_END, A_BDISP12, A_BDISP8,
30 A_DEC_M, A_DEC_N,
31 A_DISP_GBR, A_DISP_PC, A_DISP_REG_M, A_DISP_REG_N,
32 A_GBR,
33 A_IMM,
34 A_INC_M, A_INC_N,
35 A_IND_M, A_IND_N, A_IND_R0_REG_M, A_IND_R0_REG_N,
36 A_MACH, A_MACL,
37 A_PR, A_R0, A_R0_GBR, A_REG_M, A_REG_N, A_REG_B,
38 A_SR, A_VBR, A_SSR, A_SPC, A_SGR, A_DBR,
39 F_REG_N, F_REG_M, D_REG_N, D_REG_M,
40 X_REG_N, /* Only used for argument parsing */
41 X_REG_M, /* Only used for argument parsing */
42 DX_REG_N, DX_REG_M, V_REG_N, V_REG_M,
43 FD_REG_N,
44 XMTRX_M4,
45 F_FR0,
46 FPUL_N, FPUL_M, FPSCR_N, FPSCR_M,
47} sh_arg_type;
48
49static struct sh_opcode_info {
50 char *name;
51 sh_arg_type arg[7];
52 sh_nibble_type nibbles[4];
53} sh_table[] = {
54 {"add",{A_IMM,A_REG_N},{HEX_7,REG_N,IMM_8}},
55 {"add",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_C}},
56 {"addc",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_E}},
57 {"addv",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_F}},
58 {"and",{A_IMM,A_R0},{HEX_C,HEX_9,IMM_8}},
59 {"and",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_9}},
60 {"and.b",{A_IMM,A_R0_GBR},{HEX_C,HEX_D,IMM_8}},
61 {"bra",{A_BDISP12},{HEX_A,BRANCH_12}},
62 {"bsr",{A_BDISP12},{HEX_B,BRANCH_12}},
63 {"bt",{A_BDISP8},{HEX_8,HEX_9,BRANCH_8}},
64 {"bf",{A_BDISP8},{HEX_8,HEX_B,BRANCH_8}},
65 {"bt.s",{A_BDISP8},{HEX_8,HEX_D,BRANCH_8}},
66 {"bt/s",{A_BDISP8},{HEX_8,HEX_D,BRANCH_8}},
67 {"bf.s",{A_BDISP8},{HEX_8,HEX_F,BRANCH_8}},
68 {"bf/s",{A_BDISP8},{HEX_8,HEX_F,BRANCH_8}},
69 {"clrmac",{0},{HEX_0,HEX_0,HEX_2,HEX_8}},
70 {"clrs",{0},{HEX_0,HEX_0,HEX_4,HEX_8}},
71 {"clrt",{0},{HEX_0,HEX_0,HEX_0,HEX_8}},
72 {"cmp/eq",{A_IMM,A_R0},{HEX_8,HEX_8,IMM_8}},
73 {"cmp/eq",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_0}},
74 {"cmp/ge",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_3}},
75 {"cmp/gt",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_7}},
76 {"cmp/hi",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_6}},
77 {"cmp/hs",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_2}},
78 {"cmp/pl",{A_REG_N},{HEX_4,REG_N,HEX_1,HEX_5}},
79 {"cmp/pz",{A_REG_N},{HEX_4,REG_N,HEX_1,HEX_1}},
80 {"cmp/str",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_C}},
81 {"div0s",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_7}},
82 {"div0u",{0},{HEX_0,HEX_0,HEX_1,HEX_9}},
83 {"div1",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_4}},
84 {"exts.b",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_E}},
85 {"exts.w",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_F}},
86 {"extu.b",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_C}},
87 {"extu.w",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_D}},
88 {"jmp",{A_IND_N},{HEX_4,REG_N,HEX_2,HEX_B}},
89 {"jsr",{A_IND_N},{HEX_4,REG_N,HEX_0,HEX_B}},
90 {"ldc",{A_REG_N,A_SR},{HEX_4,REG_N,HEX_0,HEX_E}},
91 {"ldc",{A_REG_N,A_GBR},{HEX_4,REG_N,HEX_1,HEX_E}},
92 {"ldc",{A_REG_N,A_VBR},{HEX_4,REG_N,HEX_2,HEX_E}},
93 {"ldc",{A_REG_N,A_SSR},{HEX_4,REG_N,HEX_3,HEX_E}},
94 {"ldc",{A_REG_N,A_SPC},{HEX_4,REG_N,HEX_4,HEX_E}},
95 {"ldc",{A_REG_N,A_DBR},{HEX_4,REG_N,HEX_7,HEX_E}},
96 {"ldc",{A_REG_N,A_REG_B},{HEX_4,REG_N,REG_B,HEX_E}},
97 {"ldc.l",{A_INC_N,A_SR},{HEX_4,REG_N,HEX_0,HEX_7}},
98 {"ldc.l",{A_INC_N,A_GBR},{HEX_4,REG_N,HEX_1,HEX_7}},
99 {"ldc.l",{A_INC_N,A_VBR},{HEX_4,REG_N,HEX_2,HEX_7}},
100 {"ldc.l",{A_INC_N,A_SSR},{HEX_4,REG_N,HEX_3,HEX_7}},
101 {"ldc.l",{A_INC_N,A_SPC},{HEX_4,REG_N,HEX_4,HEX_7}},
102 {"ldc.l",{A_INC_N,A_DBR},{HEX_4,REG_N,HEX_7,HEX_7}},
103 {"ldc.l",{A_INC_N,A_REG_B},{HEX_4,REG_N,REG_B,HEX_7}},
104 {"lds",{A_REG_N,A_MACH},{HEX_4,REG_N,HEX_0,HEX_A}},
105 {"lds",{A_REG_N,A_MACL},{HEX_4,REG_N,HEX_1,HEX_A}},
106 {"lds",{A_REG_N,A_PR},{HEX_4,REG_N,HEX_2,HEX_A}},
107 {"lds",{A_REG_M,FPUL_N},{HEX_4,REG_M,HEX_5,HEX_A}},
108 {"lds",{A_REG_M,FPSCR_N},{HEX_4,REG_M,HEX_6,HEX_A}},
109 {"lds.l",{A_INC_N,A_MACH},{HEX_4,REG_N,HEX_0,HEX_6}},
110 {"lds.l",{A_INC_N,A_MACL},{HEX_4,REG_N,HEX_1,HEX_6}},
111 {"lds.l",{A_INC_N,A_PR},{HEX_4,REG_N,HEX_2,HEX_6}},
112 {"lds.l",{A_INC_M,FPUL_N},{HEX_4,REG_M,HEX_5,HEX_6}},
113 {"lds.l",{A_INC_M,FPSCR_N},{HEX_4,REG_M,HEX_6,HEX_6}},
114 {"ldtlb",{0},{HEX_0,HEX_0,HEX_3,HEX_8}},
115 {"mac.w",{A_INC_M,A_INC_N},{HEX_4,REG_N,REG_M,HEX_F}},
116 {"mov",{A_IMM,A_REG_N},{HEX_E,REG_N,IMM_8}},
117 {"mov",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_3}},
118 {"mov.b",{ A_REG_M,A_IND_R0_REG_N},{HEX_0,REG_N,REG_M,HEX_4}},
119 {"mov.b",{ A_REG_M,A_DEC_N},{HEX_2,REG_N,REG_M,HEX_4}},
120 {"mov.b",{ A_REG_M,A_IND_N},{HEX_2,REG_N,REG_M,HEX_0}},
121 {"mov.b",{A_DISP_REG_M,A_R0},{HEX_8,HEX_4,REG_M,IMM_4}},
122 {"mov.b",{A_DISP_GBR,A_R0},{HEX_C,HEX_4,IMM_8}},
123 {"mov.b",{A_IND_R0_REG_M,A_REG_N},{HEX_0,REG_N,REG_M,HEX_C}},
124 {"mov.b",{A_INC_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_4}},
125 {"mov.b",{A_IND_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_0}},
126 {"mov.b",{A_R0,A_DISP_REG_M},{HEX_8,HEX_0,REG_M,IMM_4}},
127 {"mov.b",{A_R0,A_DISP_GBR},{HEX_C,HEX_0,IMM_8}},
128 {"mov.l",{ A_REG_M,A_DISP_REG_N},{HEX_1,REG_N,REG_M,IMM_4BY4}},
129 {"mov.l",{ A_REG_M,A_IND_R0_REG_N},{HEX_0,REG_N,REG_M,HEX_6}},
130 {"mov.l",{ A_REG_M,A_DEC_N},{HEX_2,REG_N,REG_M,HEX_6}},
131 {"mov.l",{ A_REG_M,A_IND_N},{HEX_2,REG_N,REG_M,HEX_2}},
132 {"mov.l",{A_DISP_REG_M,A_REG_N},{HEX_5,REG_N,REG_M,IMM_4BY4}},
133 {"mov.l",{A_DISP_GBR,A_R0},{HEX_C,HEX_6,IMM_8BY4}},
134 {"mov.l",{A_DISP_PC,A_REG_N},{HEX_D,REG_N,PCRELIMM_8BY4}},
135 {"mov.l",{A_IND_R0_REG_M,A_REG_N},{HEX_0,REG_N,REG_M,HEX_E}},
136 {"mov.l",{A_INC_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_6}},
137 {"mov.l",{A_IND_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_2}},
138 {"mov.l",{A_R0,A_DISP_GBR},{HEX_C,HEX_2,IMM_8BY4}},
139 {"mov.w",{ A_REG_M,A_IND_R0_REG_N},{HEX_0,REG_N,REG_M,HEX_5}},
140 {"mov.w",{ A_REG_M,A_DEC_N},{HEX_2,REG_N,REG_M,HEX_5}},
141 {"mov.w",{ A_REG_M,A_IND_N},{HEX_2,REG_N,REG_M,HEX_1}},
142 {"mov.w",{A_DISP_REG_M,A_R0},{HEX_8,HEX_5,REG_M,IMM_4BY2}},
143 {"mov.w",{A_DISP_GBR,A_R0},{HEX_C,HEX_5,IMM_8BY2}},
144 {"mov.w",{A_DISP_PC,A_REG_N},{HEX_9,REG_N,PCRELIMM_8BY2}},
145 {"mov.w",{A_IND_R0_REG_M,A_REG_N},{HEX_0,REG_N,REG_M,HEX_D}},
146 {"mov.w",{A_INC_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_5}},
147 {"mov.w",{A_IND_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_1}},
148 {"mov.w",{A_R0,A_DISP_REG_M},{HEX_8,HEX_1,REG_M,IMM_4BY2}},
149 {"mov.w",{A_R0,A_DISP_GBR},{HEX_C,HEX_1,IMM_8BY2}},
150 {"mova",{A_DISP_PC,A_R0},{HEX_C,HEX_7,PCRELIMM_8BY4}},
151 {"movca.l",{A_R0,A_IND_N},{HEX_0,REG_N,HEX_C,HEX_3}},
152 {"movt",{A_REG_N},{HEX_0,REG_N,HEX_2,HEX_9}},
153 {"muls",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_F}},
154 {"mul.l",{ A_REG_M,A_REG_N},{HEX_0,REG_N,REG_M,HEX_7}},
155 {"mulu",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_E}},
156 {"neg",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_B}},
157 {"negc",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_A}},
158 {"nop",{0},{HEX_0,HEX_0,HEX_0,HEX_9}},
159 {"not",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_7}},
160 {"ocbi",{A_IND_N},{HEX_0,REG_N,HEX_9,HEX_3}},
161 {"ocbp",{A_IND_N},{HEX_0,REG_N,HEX_A,HEX_3}},
162 {"ocbwb",{A_IND_N},{HEX_0,REG_N,HEX_B,HEX_3}},
163 {"or",{A_IMM,A_R0},{HEX_C,HEX_B,IMM_8}},
164 {"or",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_B}},
165 {"or.b",{A_IMM,A_R0_GBR},{HEX_C,HEX_F,IMM_8}},
166 {"pref",{A_IND_N},{HEX_0,REG_N,HEX_8,HEX_3}},
167 {"rotcl",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_4}},
168 {"rotcr",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_5}},
169 {"rotl",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_4}},
170 {"rotr",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_5}},
171 {"rte",{0},{HEX_0,HEX_0,HEX_2,HEX_B}},
172 {"rts",{0},{HEX_0,HEX_0,HEX_0,HEX_B}},
173 {"sets",{0},{HEX_0,HEX_0,HEX_5,HEX_8}},
174 {"sett",{0},{HEX_0,HEX_0,HEX_1,HEX_8}},
175 {"shad",{ A_REG_M,A_REG_N},{HEX_4,REG_N,REG_M,HEX_C}},
176 {"shld",{ A_REG_M,A_REG_N},{HEX_4,REG_N,REG_M,HEX_D}},
177 {"shal",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_0}},
178 {"shar",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_1}},
179 {"shll",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_0}},
180 {"shll16",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_8}},
181 {"shll2",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_8}},
182 {"shll8",{A_REG_N},{HEX_4,REG_N,HEX_1,HEX_8}},
183 {"shlr",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_1}},
184 {"shlr16",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_9}},
185 {"shlr2",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_9}},
186 {"shlr8",{A_REG_N},{HEX_4,REG_N,HEX_1,HEX_9}},
187 {"sleep",{0},{HEX_0,HEX_0,HEX_1,HEX_B}},
188 {"stc",{A_SR,A_REG_N},{HEX_0,REG_N,HEX_0,HEX_2}},
189 {"stc",{A_GBR,A_REG_N},{HEX_0,REG_N,HEX_1,HEX_2}},
190 {"stc",{A_VBR,A_REG_N},{HEX_0,REG_N,HEX_2,HEX_2}},
191 {"stc",{A_SSR,A_REG_N},{HEX_0,REG_N,HEX_3,HEX_2}},
192 {"stc",{A_SPC,A_REG_N},{HEX_0,REG_N,HEX_4,HEX_2}},
193 {"stc",{A_SGR,A_REG_N},{HEX_0,REG_N,HEX_6,HEX_2}},
194 {"stc",{A_DBR,A_REG_N},{HEX_0,REG_N,HEX_7,HEX_2}},
195 {"stc",{A_REG_B,A_REG_N},{HEX_0,REG_N,REG_B,HEX_2}},
196 {"stc.l",{A_SR,A_DEC_N},{HEX_4,REG_N,HEX_0,HEX_3}},
197 {"stc.l",{A_GBR,A_DEC_N},{HEX_4,REG_N,HEX_1,HEX_3}},
198 {"stc.l",{A_VBR,A_DEC_N},{HEX_4,REG_N,HEX_2,HEX_3}},
199 {"stc.l",{A_SSR,A_DEC_N},{HEX_4,REG_N,HEX_3,HEX_3}},
200 {"stc.l",{A_SPC,A_DEC_N},{HEX_4,REG_N,HEX_4,HEX_3}},
201 {"stc.l",{A_SGR,A_DEC_N},{HEX_4,REG_N,HEX_6,HEX_3}},
202 {"stc.l",{A_DBR,A_DEC_N},{HEX_4,REG_N,HEX_7,HEX_3}},
203 {"stc.l",{A_REG_B,A_DEC_N},{HEX_4,REG_N,REG_B,HEX_3}},
204 {"sts",{A_MACH,A_REG_N},{HEX_0,REG_N,HEX_0,HEX_A}},
205 {"sts",{A_MACL,A_REG_N},{HEX_0,REG_N,HEX_1,HEX_A}},
206 {"sts",{A_PR,A_REG_N},{HEX_0,REG_N,HEX_2,HEX_A}},
207 {"sts",{FPUL_M,A_REG_N},{HEX_0,REG_N,HEX_5,HEX_A}},
208 {"sts",{FPSCR_M,A_REG_N},{HEX_0,REG_N,HEX_6,HEX_A}},
209 {"sts.l",{A_MACH,A_DEC_N},{HEX_4,REG_N,HEX_0,HEX_2}},
210 {"sts.l",{A_MACL,A_DEC_N},{HEX_4,REG_N,HEX_1,HEX_2}},
211 {"sts.l",{A_PR,A_DEC_N},{HEX_4,REG_N,HEX_2,HEX_2}},
212 {"sts.l",{FPUL_M,A_DEC_N},{HEX_4,REG_N,HEX_5,HEX_2}},
213 {"sts.l",{FPSCR_M,A_DEC_N},{HEX_4,REG_N,HEX_6,HEX_2}},
214 {"sub",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_8}},
215 {"subc",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_A}},
216 {"subv",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_B}},
217 {"swap.b",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_8}},
218 {"swap.w",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_9}},
219 {"tas.b",{A_IND_N},{HEX_4,REG_N,HEX_1,HEX_B}},
220 {"trapa",{A_IMM},{HEX_C,HEX_3,IMM_8}},
221 {"tst",{A_IMM,A_R0},{HEX_C,HEX_8,IMM_8}},
222 {"tst",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_8}},
223 {"tst.b",{A_IMM,A_R0_GBR},{HEX_C,HEX_C,IMM_8}},
224 {"xor",{A_IMM,A_R0},{HEX_C,HEX_A,IMM_8}},
225 {"xor",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_A}},
226 {"xor.b",{A_IMM,A_R0_GBR},{HEX_C,HEX_E,IMM_8}},
227 {"xtrct",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_D}},
228 {"mul.l",{ A_REG_M,A_REG_N},{HEX_0,REG_N,REG_M,HEX_7}},
229 {"dt",{A_REG_N},{HEX_4,REG_N,HEX_1,HEX_0}},
230 {"dmuls.l",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_D}},
231 {"dmulu.l",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_5}},
232 {"mac.l",{A_INC_M,A_INC_N},{HEX_0,REG_N,REG_M,HEX_F}},
233 {"braf",{A_REG_N},{HEX_0,REG_N,HEX_2,HEX_3}},
234 {"bsrf",{A_REG_N},{HEX_0,REG_N,HEX_0,HEX_3}},
235 {"fabs",{FD_REG_N},{HEX_F,REG_N,HEX_5,HEX_D}},
236 {"fadd",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_0}},
237 {"fadd",{D_REG_M,D_REG_N},{HEX_F,REG_N,REG_M,HEX_0}},
238 {"fcmp/eq",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_4}},
239 {"fcmp/eq",{D_REG_M,D_REG_N},{HEX_F,REG_N,REG_M,HEX_4}},
240 {"fcmp/gt",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_5}},
241 {"fcmp/gt",{D_REG_M,D_REG_N},{HEX_F,REG_N,REG_M,HEX_5}},
242 {"fcnvds",{D_REG_N,FPUL_M},{HEX_F,REG_N,HEX_B,HEX_D}},
243 {"fcnvsd",{FPUL_M,D_REG_N},{HEX_F,REG_N,HEX_A,HEX_D}},
244 {"fdiv",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_3}},
245 {"fdiv",{D_REG_M,D_REG_N},{HEX_F,REG_N,REG_M,HEX_3}},
246 {"fipr",{V_REG_M,V_REG_N},{HEX_F,REG_NM,HEX_E,HEX_D}},
247 {"fldi0",{F_REG_N},{HEX_F,REG_N,HEX_8,HEX_D}},
248 {"fldi1",{F_REG_N},{HEX_F,REG_N,HEX_9,HEX_D}},
249 {"flds",{F_REG_N,FPUL_M},{HEX_F,REG_N,HEX_1,HEX_D}},
250 {"float",{FPUL_M,FD_REG_N},{HEX_F,REG_N,HEX_2,HEX_D}},
251 {"fmac",{F_FR0,F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_E}},
252 {"fmov",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_C}},
253 {"fmov",{DX_REG_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_C}},
254 {"fmov",{A_IND_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_8}},
255 {"fmov",{A_IND_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_8}},
256 {"fmov",{F_REG_M,A_IND_N},{HEX_F,REG_N,REG_M,HEX_A}},
257 {"fmov",{DX_REG_M,A_IND_N},{HEX_F,REG_N,REG_M,HEX_A}},
258 {"fmov",{A_INC_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_9}},
259 {"fmov",{A_INC_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_9}},
260 {"fmov",{F_REG_M,A_DEC_N},{HEX_F,REG_N,REG_M,HEX_B}},
261 {"fmov",{DX_REG_M,A_DEC_N},{HEX_F,REG_N,REG_M,HEX_B}},
262 {"fmov",{A_IND_R0_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_6}},
263 {"fmov",{A_IND_R0_REG_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_6}},
264 {"fmov",{F_REG_M,A_IND_R0_REG_N},{HEX_F,REG_N,REG_M,HEX_7}},
265 {"fmov",{DX_REG_M,A_IND_R0_REG_N},{HEX_F,REG_N,REG_M,HEX_7}},
266 {"fmov.d",{A_IND_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_8}},
267 {"fmov.d",{DX_REG_M,A_IND_N},{HEX_F,REG_N,REG_M,HEX_A}},
268 {"fmov.d",{A_INC_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_9}},
269 {"fmov.d",{DX_REG_M,A_DEC_N},{HEX_F,REG_N,REG_M,HEX_B}},
270 {"fmov.d",{A_IND_R0_REG_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_6}},
271 {"fmov.d",{DX_REG_M,A_IND_R0_REG_N},{HEX_F,REG_N,REG_M,HEX_7}},
272 {"fmov.s",{A_IND_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_8}},
273 {"fmov.s",{F_REG_M,A_IND_N},{HEX_F,REG_N,REG_M,HEX_A}},
274 {"fmov.s",{A_INC_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_9}},
275 {"fmov.s",{F_REG_M,A_DEC_N},{HEX_F,REG_N,REG_M,HEX_B}},
276 {"fmov.s",{A_IND_R0_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_6}},
277 {"fmov.s",{F_REG_M,A_IND_R0_REG_N},{HEX_F,REG_N,REG_M,HEX_7}},
278 {"fmul",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_2}},
279 {"fmul",{D_REG_M,D_REG_N},{HEX_F,REG_N,REG_M,HEX_2}},
280 {"fneg",{FD_REG_N},{HEX_F,REG_N,HEX_4,HEX_D}},
281 {"frchg",{0},{HEX_F,HEX_B,HEX_F,HEX_D}},
282 {"fschg",{0},{HEX_F,HEX_3,HEX_F,HEX_D}},
283 {"fsqrt",{FD_REG_N},{HEX_F,REG_N,HEX_6,HEX_D}},
284 {"fsts",{FPUL_M,F_REG_N},{HEX_F,REG_N,HEX_0,HEX_D}},
285 {"fsub",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_1}},
286 {"fsub",{D_REG_M,D_REG_N},{HEX_F,REG_N,REG_M,HEX_1}},
287 {"ftrc",{FD_REG_N,FPUL_M},{HEX_F,REG_N,HEX_3,HEX_D}},
288 {"ftrv",{XMTRX_M4,V_REG_N},{HEX_F,REG_NM,HEX_F,HEX_D}},
289 { 0 },
290};
291
292static void print_sh_insn(u32 memaddr, u16 insn)
293{
294 int relmask = ~0;
295 int nibs[4] = { (insn >> 12) & 0xf, (insn >> 8) & 0xf, (insn >> 4) & 0xf, insn & 0xf};
296 int lastsp;
297 struct sh_opcode_info *op = sh_table;
298
299 for (; op->name; op++) {
300 int n;
301 int imm = 0;
302 int rn = 0;
303 int rm = 0;
304 int rb = 0;
305 int disp_pc;
306 int disp_pc_addr = 0;
307
308 for (n = 0; n < 4; n++) {
309 int i = op->nibbles[n];
310
311 if (i < 16) {
312 if (nibs[n] == i)
313 continue;
314 goto fail;
315 }
316 switch (i) {
317 case BRANCH_8:
318 imm = (nibs[2] << 4) | (nibs[3]);
319 if (imm & 0x80)
320 imm |= ~0xff;
321 imm = ((char)imm) * 2 + 4 ;
322 goto ok;
323 case BRANCH_12:
324 imm = ((nibs[1]) << 8) | (nibs[2] << 4) | (nibs[3]);
325 if (imm & 0x800)
326 imm |= ~0xfff;
327 imm = imm * 2 + 4;
328 goto ok;
329 case IMM_4:
330 imm = nibs[3];
331 goto ok;
332 case IMM_4BY2:
333 imm = nibs[3] <<1;
334 goto ok;
335 case IMM_4BY4:
336 imm = nibs[3] <<2;
337 goto ok;
338 case IMM_8:
339 imm = (nibs[2] << 4) | nibs[3];
340 goto ok;
341 case PCRELIMM_8BY2:
342 imm = ((nibs[2] << 4) | nibs[3]) <<1;
343 relmask = ~1;
344 goto ok;
345 case PCRELIMM_8BY4:
346 imm = ((nibs[2] << 4) | nibs[3]) <<2;
347 relmask = ~3;
348 goto ok;
349 case IMM_8BY2:
350 imm = ((nibs[2] << 4) | nibs[3]) <<1;
351 goto ok;
352 case IMM_8BY4:
353 imm = ((nibs[2] << 4) | nibs[3]) <<2;
354 goto ok;
355 case DISP_8:
356 imm = (nibs[2] << 4) | (nibs[3]);
357 goto ok;
358 case DISP_4:
359 imm = nibs[3];
360 goto ok;
361 case REG_N:
362 rn = nibs[n];
363 break;
364 case REG_M:
365 rm = nibs[n];
366 break;
367 case REG_NM:
368 rn = (nibs[n] & 0xc) >> 2;
369 rm = (nibs[n] & 0x3);
370 break;
371 case REG_B:
372 rb = nibs[n] & 0x07;
373 break;
374 default:
375 return;
376 }
377 }
378
379 ok:
380 printk("%-8s ", op->name);
381 lastsp = (op->arg[0] == A_END);
382 disp_pc = 0;
383 for (n = 0; n < 6 && op->arg[n] != A_END; n++) {
384 if (n && op->arg[1] != A_END)
385 printk(", ");
386 switch (op->arg[n]) {
387 case A_IMM:
388 printk("#%d", (char)(imm));
389 break;
390 case A_R0:
391 printk("r0");
392 break;
393 case A_REG_N:
394 printk("r%d", rn);
395 break;
396 case A_INC_N:
397 printk("@r%d+", rn);
398 break;
399 case A_DEC_N:
400 printk("@-r%d", rn);
401 break;
402 case A_IND_N:
403 printk("@r%d", rn);
404 break;
405 case A_DISP_REG_N:
406 printk("@(%d,r%d)", imm, rn);
407 break;
408 case A_REG_M:
409 printk("r%d", rm);
410 break;
411 case A_INC_M:
412 printk("@r%d+", rm);
413 break;
414 case A_DEC_M:
415 printk("@-r%d", rm);
416 break;
417 case A_IND_M:
418 printk("@r%d", rm);
419 break;
420 case A_DISP_REG_M:
421 printk("@(%d,r%d)", imm, rm);
422 break;
423 case A_REG_B:
424 printk("r%d_bank", rb);
425 break;
426 case A_DISP_PC:
427 disp_pc = 1;
428 disp_pc_addr = imm + 4 + (memaddr & relmask);
429 printk("%08x <%pS>", disp_pc_addr,
430 (void *)disp_pc_addr);
431 break;
432 case A_IND_R0_REG_N:
433 printk("@(r0,r%d)", rn);
434 break;
435 case A_IND_R0_REG_M:
436 printk("@(r0,r%d)", rm);
437 break;
438 case A_DISP_GBR:
439 printk("@(%d,gbr)",imm);
440 break;
441 case A_R0_GBR:
442 printk("@(r0,gbr)");
443 break;
444 case A_BDISP12:
445 case A_BDISP8:
446 printk("%08x", imm + memaddr);
447 break;
448 case A_SR:
449 printk("sr");
450 break;
451 case A_GBR:
452 printk("gbr");
453 break;
454 case A_VBR:
455 printk("vbr");
456 break;
457 case A_SSR:
458 printk("ssr");
459 break;
460 case A_SPC:
461 printk("spc");
462 break;
463 case A_MACH:
464 printk("mach");
465 break;
466 case A_MACL:
467 printk("macl");
468 break;
469 case A_PR:
470 printk("pr");
471 break;
472 case A_SGR:
473 printk("sgr");
474 break;
475 case A_DBR:
476 printk("dbr");
477 break;
478 case FD_REG_N:
479 if (0)
480 goto d_reg_n;
481 case F_REG_N:
482 printk("fr%d", rn);
483 break;
484 case F_REG_M:
485 printk("fr%d", rm);
486 break;
487 case DX_REG_N:
488 if (rn & 1) {
489 printk("xd%d", rn & ~1);
490 break;
491 }
492 d_reg_n:
493 case D_REG_N:
494 printk("dr%d", rn);
495 break;
496 case DX_REG_M:
497 if (rm & 1) {
498 printk("xd%d", rm & ~1);
499 break;
500 }
501 case D_REG_M:
502 printk("dr%d", rm);
503 break;
504 case FPSCR_M:
505 case FPSCR_N:
506 printk("fpscr");
507 break;
508 case FPUL_M:
509 case FPUL_N:
510 printk("fpul");
511 break;
512 case F_FR0:
513 printk("fr0");
514 break;
515 case V_REG_N:
516 printk("fv%d", rn*4);
517 break;
518 case V_REG_M:
519 printk("fv%d", rm*4);
520 break;
521 case XMTRX_M4:
522 printk("xmtrx");
523 break;
524 default:
525 return;
526 }
527 }
528
529 if (disp_pc && strcmp(op->name, "mova") != 0) {
530 u32 val;
531
532 if (relmask == ~1)
533 __get_user(val, (u16 *)disp_pc_addr);
534 else
535 __get_user(val, (u32 *)disp_pc_addr);
536
537 printk(" ! %08x <%pS>", val, (void *)val);
538 }
539
540 return;
541 fail:
542 ;
543
544 }
545
546 printk(".word 0x%x%x%x%x", nibs[0], nibs[1], nibs[2], nibs[3]);
547}
548
549void show_code(struct pt_regs *regs)
550{
551 unsigned short *pc = (unsigned short *)regs->pc;
552 long i;
553
554 if (regs->pc & 0x1)
555 return;
556
557 printk("Code:\n");
558
559 for (i = -3 ; i < 6 ; i++) {
560 unsigned short insn;
561
562 if (__get_user(insn, pc + i)) {
563 printk(" (Bad address in pc)\n");
564 break;
565 }
566
567 printk("%s%08lx: ", (i ? " ": "->"), (unsigned long)(pc + i));
568 print_sh_insn((unsigned long)(pc + i), insn);
569 printk("\n");
570 }
571
572 printk("\n");
573}
diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S
index 5b7efc4016fa..d62359cfbbe2 100644
--- a/arch/sh/kernel/entry-common.S
+++ b/arch/sh/kernel/entry-common.S
@@ -308,15 +308,19 @@ ENTRY(system_call)
308 mov.l 1f, r9 308 mov.l 1f, r9
309 mov.l @r9, r8 ! Read from TRA (Trap Address) Register 309 mov.l @r9, r8 ! Read from TRA (Trap Address) Register
310#endif 310#endif
311
312 mov #OFF_TRA, r10
313 add r15, r10
314 mov.l r8, @r10 ! set TRA value to tra
315
311 /* 316 /*
312 * Check the trap type 317 * Check the trap type
313 */ 318 */
314 mov #((0x20 << 2) - 1), r9 319 mov #((0x20 << 2) - 1), r9
315 cmp/hi r9, r8 320 cmp/hi r9, r8
316 bt/s debug_trap ! it's a debug trap.. 321 bt/s debug_trap ! it's a debug trap..
317 mov #OFF_TRA, r9 322 nop
318 add r15, r9 323
319 mov.l r8, @r9 ! set TRA value to tra
320#ifdef CONFIG_TRACE_IRQFLAGS 324#ifdef CONFIG_TRACE_IRQFLAGS
321 mov.l 5f, r10 325 mov.l 5f, r10
322 jsr @r10 326 jsr @r10
@@ -371,47 +375,3 @@ syscall_exit:
371#endif 375#endif
3727: .long do_syscall_trace_enter 3767: .long do_syscall_trace_enter
3738: .long do_syscall_trace_leave 3778: .long do_syscall_trace_leave
374
375#ifdef CONFIG_FUNCTION_TRACER
376 .align 2
377 .globl _mcount
378 .type _mcount,@function
379 .globl mcount
380 .type mcount,@function
381_mcount:
382mcount:
383 mov.l r4, @-r15
384 mov.l r5, @-r15
385 mov.l r6, @-r15
386 mov.l r7, @-r15
387 sts.l pr, @-r15
388
389 mov.l @(20,r15),r4
390 sts pr, r5
391
392 mov.l 1f, r6
393 mov.l ftrace_stub, r7
394 cmp/eq r6, r7
395 bt skip_trace
396
397 mov.l @r6, r6
398 jsr @r6
399 nop
400
401skip_trace:
402
403 lds.l @r15+, pr
404 mov.l @r15+, r7
405 mov.l @r15+, r6
406 mov.l @r15+, r5
407 rts
408 mov.l @r15+, r4
409
410 .align 2
4111: .long ftrace_trace_function
412
413 .globl ftrace_stub
414ftrace_stub:
415 rts
416 nop
417#endif /* CONFIG_FUNCTION_TRACER */
diff --git a/arch/sh/kernel/ftrace.c b/arch/sh/kernel/ftrace.c
new file mode 100644
index 000000000000..4c3247477aa3
--- /dev/null
+++ b/arch/sh/kernel/ftrace.c
@@ -0,0 +1,133 @@
1/*
2 * Copyright (C) 2008 Matt Fleming <mjf@gentoo.org>
3 * Copyright (C) 2008 Paul Mundt <lethal@linux-sh.org>
4 *
5 * Code for replacing ftrace calls with jumps.
6 *
7 * Copyright (C) 2007-2008 Steven Rostedt <srostedt@redhat.com>
8 *
9 * Thanks goes to Ingo Molnar, for suggesting the idea.
10 * Mathieu Desnoyers, for suggesting postponing the modifications.
11 * Arjan van de Ven, for keeping me straight, and explaining to me
12 * the dangers of modifying code on the run.
13 */
14#include <linux/uaccess.h>
15#include <linux/ftrace.h>
16#include <linux/string.h>
17#include <linux/init.h>
18#include <linux/io.h>
19#include <asm/ftrace.h>
20#include <asm/cacheflush.h>
21
22static unsigned char ftrace_nop[] = {
23 0x09, 0x00, /* nop */
24 0x09, 0x00, /* nop */
25};
26
27static unsigned char ftrace_replaced_code[MCOUNT_INSN_SIZE];
28
29unsigned char *ftrace_nop_replace(void)
30{
31 return ftrace_nop;
32}
33
34static int is_sh_nop(unsigned char *ip)
35{
36 return strncmp(ip, ftrace_nop, sizeof(ftrace_nop));
37}
38
39unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr)
40{
41 /* Place the address in the memory table. */
42 if (addr == CALLER_ADDR)
43 __raw_writel(addr + MCOUNT_INSN_OFFSET, ftrace_replaced_code);
44 else
45 __raw_writel(addr, ftrace_replaced_code);
46
47 /*
48 * No locking needed, this must be called via kstop_machine
49 * which in essence is like running on a uniprocessor machine.
50 */
51 return ftrace_replaced_code;
52}
53
54int ftrace_modify_code(unsigned long ip, unsigned char *old_code,
55 unsigned char *new_code)
56{
57 unsigned char replaced[MCOUNT_INSN_SIZE];
58
59 /*
60 * Note: Due to modules and __init, code can
61 * disappear and change, we need to protect against faulting
62 * as well as code changing. We do this by using the
63 * probe_kernel_* functions.
64 *
65 * No real locking needed, this code is run through
66 * kstop_machine, or before SMP starts.
67 */
68
69 /*
70 * If we're trying to nop out a call to a function, we instead
71 * place a call to the address after the memory table.
72 */
73 if (is_sh_nop(new_code) == 0)
74 __raw_writel(ip + MCOUNT_INSN_SIZE, (unsigned long)new_code);
75
76 /* read the text we want to modify */
77 if (probe_kernel_read(replaced, (void *)ip, MCOUNT_INSN_SIZE))
78 return -EFAULT;
79
80 /* Make sure it is what we expect it to be */
81 if (memcmp(replaced, old_code, MCOUNT_INSN_SIZE) != 0)
82 return -EINVAL;
83
84 /* replace the text with the new text */
85 if (probe_kernel_write((void *)ip, new_code, MCOUNT_INSN_SIZE))
86 return -EPERM;
87
88 flush_icache_range(ip, ip + MCOUNT_INSN_SIZE);
89
90 return 0;
91}
92
93int ftrace_update_ftrace_func(ftrace_func_t func)
94{
95 unsigned long ip = (unsigned long)(&ftrace_call);
96 unsigned char old[MCOUNT_INSN_SIZE], *new;
97
98 memcpy(old, (unsigned char *)(ip + MCOUNT_INSN_OFFSET), MCOUNT_INSN_SIZE);
99 new = ftrace_call_replace(ip, (unsigned long)func);
100
101 return ftrace_modify_code(ip + MCOUNT_INSN_OFFSET, old, new);
102}
103
104int ftrace_make_nop(struct module *mod,
105 struct dyn_ftrace *rec, unsigned long addr)
106{
107 unsigned char *new, *old;
108 unsigned long ip = rec->ip;
109
110 old = ftrace_call_replace(ip, addr);
111 new = ftrace_nop_replace();
112
113 return ftrace_modify_code(rec->ip, old, new);
114}
115
116int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
117{
118 unsigned char *new, *old;
119 unsigned long ip = rec->ip;
120
121 old = ftrace_nop_replace();
122 new = ftrace_call_replace(ip, addr);
123
124 return ftrace_modify_code(rec->ip, old, new);
125}
126
127int __init ftrace_dyn_arch_init(void *data)
128{
129 /* The return code is retured via data */
130 __raw_writel(0, (unsigned long)data);
131
132 return 0;
133}
diff --git a/arch/sh/kernel/head_32.S b/arch/sh/kernel/head_32.S
index ae0a382a82eb..788605ff7088 100644
--- a/arch/sh/kernel/head_32.S
+++ b/arch/sh/kernel/head_32.S
@@ -80,8 +80,14 @@ ENTRY(_stext)
80 mov.l 7f, r0 80 mov.l 7f, r0
81 ldc r0, r7_bank ! ... and initial thread_info 81 ldc r0, r7_bank ! ... and initial thread_info
82#endif 82#endif
83 83
84 ! Clear BSS area 84#ifndef CONFIG_SH_NO_BSS_INIT
85 /*
86 * Don't clear BSS if running on slow platforms such as an RTL simulation,
87 * remote memory via SHdebug link, etc. For these the memory can be guaranteed
88 * to be all zero on boot anyway.
89 */
90 ! Clear BSS area
85#ifdef CONFIG_SMP 91#ifdef CONFIG_SMP
86 mov.l 3f, r0 92 mov.l 3f, r0
87 cmp/eq #0, r0 ! skip clear if set to zero 93 cmp/eq #0, r0 ! skip clear if set to zero
@@ -97,6 +103,8 @@ ENTRY(_stext)
97 mov.l r0,@-r2 103 mov.l r0,@-r2
98 104
9910: 10510:
106#endif
107
100 ! Additional CPU initialization 108 ! Additional CPU initialization
101 mov.l 6f, r0 109 mov.l 6f, r0
102 jsr @r0 110 jsr @r0
diff --git a/arch/sh/kernel/idle.c b/arch/sh/kernel/idle.c
new file mode 100644
index 000000000000..fe59ccfc1152
--- /dev/null
+++ b/arch/sh/kernel/idle.c
@@ -0,0 +1,81 @@
1/*
2 * The idle loop for all SuperH platforms.
3 *
4 * Copyright (C) 2002 - 2008 Paul Mundt
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10#include <linux/module.h>
11#include <linux/init.h>
12#include <linux/mm.h>
13#include <linux/pm.h>
14#include <linux/tick.h>
15#include <linux/preempt.h>
16#include <linux/thread_info.h>
17#include <linux/irqflags.h>
18#include <asm/pgalloc.h>
19#include <asm/system.h>
20#include <asm/atomic.h>
21
22static int hlt_counter;
23void (*pm_idle)(void);
24void (*pm_power_off)(void);
25EXPORT_SYMBOL(pm_power_off);
26
27static int __init nohlt_setup(char *__unused)
28{
29 hlt_counter = 1;
30 return 1;
31}
32__setup("nohlt", nohlt_setup);
33
34static int __init hlt_setup(char *__unused)
35{
36 hlt_counter = 0;
37 return 1;
38}
39__setup("hlt", hlt_setup);
40
41static void default_idle(void)
42{
43 if (!hlt_counter) {
44 clear_thread_flag(TIF_POLLING_NRFLAG);
45 smp_mb__after_clear_bit();
46 set_bl_bit();
47 stop_critical_timings();
48
49 while (!need_resched())
50 cpu_sleep();
51
52 start_critical_timings();
53 clear_bl_bit();
54 set_thread_flag(TIF_POLLING_NRFLAG);
55 } else
56 while (!need_resched())
57 cpu_relax();
58}
59
60void cpu_idle(void)
61{
62 set_thread_flag(TIF_POLLING_NRFLAG);
63
64 /* endless idle loop with no priority at all */
65 while (1) {
66 void (*idle)(void) = pm_idle;
67
68 if (!idle)
69 idle = default_idle;
70
71 tick_nohz_stop_sched_tick(1);
72 while (!need_resched())
73 idle();
74 tick_nohz_restart_sched_tick();
75
76 preempt_enable_no_resched();
77 schedule();
78 preempt_disable();
79 check_pgt_cache();
80 }
81}
diff --git a/arch/sh/kernel/kgdb.c b/arch/sh/kernel/kgdb.c
new file mode 100644
index 000000000000..7c747e7d71b8
--- /dev/null
+++ b/arch/sh/kernel/kgdb.c
@@ -0,0 +1,285 @@
1/*
2 * SuperH KGDB support
3 *
4 * Copyright (C) 2008 Paul Mundt
5 *
6 * Single stepping taken from the old stub by Henry Bell and Jeremy Siegel.
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 */
12#include <linux/kgdb.h>
13#include <linux/kdebug.h>
14#include <linux/irq.h>
15#include <linux/io.h>
16#include <asm/cacheflush.h>
17
18char in_nmi = 0; /* Set during NMI to prevent re-entry */
19
20/* Macros for single step instruction identification */
21#define OPCODE_BT(op) (((op) & 0xff00) == 0x8900)
22#define OPCODE_BF(op) (((op) & 0xff00) == 0x8b00)
23#define OPCODE_BTF_DISP(op) (((op) & 0x80) ? (((op) | 0xffffff80) << 1) : \
24 (((op) & 0x7f ) << 1))
25#define OPCODE_BFS(op) (((op) & 0xff00) == 0x8f00)
26#define OPCODE_BTS(op) (((op) & 0xff00) == 0x8d00)
27#define OPCODE_BRA(op) (((op) & 0xf000) == 0xa000)
28#define OPCODE_BRA_DISP(op) (((op) & 0x800) ? (((op) | 0xfffff800) << 1) : \
29 (((op) & 0x7ff) << 1))
30#define OPCODE_BRAF(op) (((op) & 0xf0ff) == 0x0023)
31#define OPCODE_BRAF_REG(op) (((op) & 0x0f00) >> 8)
32#define OPCODE_BSR(op) (((op) & 0xf000) == 0xb000)
33#define OPCODE_BSR_DISP(op) (((op) & 0x800) ? (((op) | 0xfffff800) << 1) : \
34 (((op) & 0x7ff) << 1))
35#define OPCODE_BSRF(op) (((op) & 0xf0ff) == 0x0003)
36#define OPCODE_BSRF_REG(op) (((op) >> 8) & 0xf)
37#define OPCODE_JMP(op) (((op) & 0xf0ff) == 0x402b)
38#define OPCODE_JMP_REG(op) (((op) >> 8) & 0xf)
39#define OPCODE_JSR(op) (((op) & 0xf0ff) == 0x400b)
40#define OPCODE_JSR_REG(op) (((op) >> 8) & 0xf)
41#define OPCODE_RTS(op) ((op) == 0xb)
42#define OPCODE_RTE(op) ((op) == 0x2b)
43
44#define SR_T_BIT_MASK 0x1
45#define STEP_OPCODE 0xc33d
46
47/* Calculate the new address for after a step */
48static short *get_step_address(struct pt_regs *linux_regs)
49{
50 opcode_t op = __raw_readw(linux_regs->pc);
51 long addr;
52
53 /* BT */
54 if (OPCODE_BT(op)) {
55 if (linux_regs->sr & SR_T_BIT_MASK)
56 addr = linux_regs->pc + 4 + OPCODE_BTF_DISP(op);
57 else
58 addr = linux_regs->pc + 2;
59 }
60
61 /* BTS */
62 else if (OPCODE_BTS(op)) {
63 if (linux_regs->sr & SR_T_BIT_MASK)
64 addr = linux_regs->pc + 4 + OPCODE_BTF_DISP(op);
65 else
66 addr = linux_regs->pc + 4; /* Not in delay slot */
67 }
68
69 /* BF */
70 else if (OPCODE_BF(op)) {
71 if (!(linux_regs->sr & SR_T_BIT_MASK))
72 addr = linux_regs->pc + 4 + OPCODE_BTF_DISP(op);
73 else
74 addr = linux_regs->pc + 2;
75 }
76
77 /* BFS */
78 else if (OPCODE_BFS(op)) {
79 if (!(linux_regs->sr & SR_T_BIT_MASK))
80 addr = linux_regs->pc + 4 + OPCODE_BTF_DISP(op);
81 else
82 addr = linux_regs->pc + 4; /* Not in delay slot */
83 }
84
85 /* BRA */
86 else if (OPCODE_BRA(op))
87 addr = linux_regs->pc + 4 + OPCODE_BRA_DISP(op);
88
89 /* BRAF */
90 else if (OPCODE_BRAF(op))
91 addr = linux_regs->pc + 4
92 + linux_regs->regs[OPCODE_BRAF_REG(op)];
93
94 /* BSR */
95 else if (OPCODE_BSR(op))
96 addr = linux_regs->pc + 4 + OPCODE_BSR_DISP(op);
97
98 /* BSRF */
99 else if (OPCODE_BSRF(op))
100 addr = linux_regs->pc + 4
101 + linux_regs->regs[OPCODE_BSRF_REG(op)];
102
103 /* JMP */
104 else if (OPCODE_JMP(op))
105 addr = linux_regs->regs[OPCODE_JMP_REG(op)];
106
107 /* JSR */
108 else if (OPCODE_JSR(op))
109 addr = linux_regs->regs[OPCODE_JSR_REG(op)];
110
111 /* RTS */
112 else if (OPCODE_RTS(op))
113 addr = linux_regs->pr;
114
115 /* RTE */
116 else if (OPCODE_RTE(op))
117 addr = linux_regs->regs[15];
118
119 /* Other */
120 else
121 addr = linux_regs->pc + instruction_size(op);
122
123 flush_icache_range(addr, addr + instruction_size(op));
124 return (short *)addr;
125}
126
127/*
128 * Replace the instruction immediately after the current instruction
129 * (i.e. next in the expected flow of control) with a trap instruction,
130 * so that returning will cause only a single instruction to be executed.
131 * Note that this model is slightly broken for instructions with delay
132 * slots (e.g. B[TF]S, BSR, BRA etc), where both the branch and the
133 * instruction in the delay slot will be executed.
134 */
135
136static unsigned long stepped_address;
137static opcode_t stepped_opcode;
138
139static void do_single_step(struct pt_regs *linux_regs)
140{
141 /* Determine where the target instruction will send us to */
142 unsigned short *addr = get_step_address(linux_regs);
143
144 stepped_address = (int)addr;
145
146 /* Replace it */
147 stepped_opcode = __raw_readw((long)addr);
148 *addr = STEP_OPCODE;
149
150 /* Flush and return */
151 flush_icache_range((long)addr, (long)addr +
152 instruction_size(stepped_opcode));
153}
154
155/* Undo a single step */
156static void undo_single_step(struct pt_regs *linux_regs)
157{
158 /* If we have stepped, put back the old instruction */
159 /* Use stepped_address in case we stopped elsewhere */
160 if (stepped_opcode != 0) {
161 __raw_writew(stepped_opcode, stepped_address);
162 flush_icache_range(stepped_address, stepped_address + 2);
163 }
164
165 stepped_opcode = 0;
166}
167
168void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
169{
170 int i;
171
172 for (i = 0; i < 16; i++)
173 gdb_regs[GDB_R0 + i] = regs->regs[i];
174
175 gdb_regs[GDB_PC] = regs->pc;
176 gdb_regs[GDB_PR] = regs->pr;
177 gdb_regs[GDB_SR] = regs->sr;
178 gdb_regs[GDB_GBR] = regs->gbr;
179 gdb_regs[GDB_MACH] = regs->mach;
180 gdb_regs[GDB_MACL] = regs->macl;
181
182 __asm__ __volatile__ ("stc vbr, %0" : "=r" (gdb_regs[GDB_VBR]));
183}
184
185void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
186{
187 int i;
188
189 for (i = 0; i < 16; i++)
190 regs->regs[GDB_R0 + i] = gdb_regs[GDB_R0 + i];
191
192 regs->pc = gdb_regs[GDB_PC];
193 regs->pr = gdb_regs[GDB_PR];
194 regs->sr = gdb_regs[GDB_SR];
195 regs->gbr = gdb_regs[GDB_GBR];
196 regs->mach = gdb_regs[GDB_MACH];
197 regs->macl = gdb_regs[GDB_MACL];
198
199 __asm__ __volatile__ ("ldc %0, vbr" : : "r" (gdb_regs[GDB_VBR]));
200}
201
202void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
203{
204 gdb_regs[GDB_R15] = p->thread.sp;
205 gdb_regs[GDB_PC] = p->thread.pc;
206}
207
208int kgdb_arch_handle_exception(int e_vector, int signo, int err_code,
209 char *remcomInBuffer, char *remcomOutBuffer,
210 struct pt_regs *linux_regs)
211{
212 unsigned long addr;
213 char *ptr;
214
215 /* Undo any stepping we may have done */
216 undo_single_step(linux_regs);
217
218 switch (remcomInBuffer[0]) {
219 case 'c':
220 case 's':
221 /* try to read optional parameter, pc unchanged if no parm */
222 ptr = &remcomInBuffer[1];
223 if (kgdb_hex2long(&ptr, &addr))
224 linux_regs->pc = addr;
225 case 'D':
226 case 'k':
227 atomic_set(&kgdb_cpu_doing_single_step, -1);
228
229 if (remcomInBuffer[0] == 's') {
230 do_single_step(linux_regs);
231 kgdb_single_step = 1;
232
233 atomic_set(&kgdb_cpu_doing_single_step,
234 raw_smp_processor_id());
235 }
236
237 return 0;
238 }
239
240 /* this means that we do not want to exit from the handler: */
241 return -1;
242}
243
244/*
245 * The primary entry points for the kgdb debug trap table entries.
246 */
247BUILD_TRAP_HANDLER(singlestep)
248{
249 unsigned long flags;
250 TRAP_HANDLER_DECL;
251
252 local_irq_save(flags);
253 regs->pc -= instruction_size(__raw_readw(regs->pc - 4));
254 kgdb_handle_exception(vec >> 2, SIGTRAP, 0, regs);
255 local_irq_restore(flags);
256}
257
258
259BUILD_TRAP_HANDLER(breakpoint)
260{
261 unsigned long flags;
262 TRAP_HANDLER_DECL;
263
264 local_irq_save(flags);
265 kgdb_handle_exception(vec >> 2, SIGTRAP, 0, regs);
266 local_irq_restore(flags);
267}
268
269int kgdb_arch_init(void)
270{
271 return 0;
272}
273
274void kgdb_arch_exit(void)
275{
276}
277
278struct kgdb_arch arch_kgdb_ops = {
279 /* Breakpoint instruction: trapa #0x3c */
280#ifdef CONFIG_CPU_LITTLE_ENDIAN
281 .gdb_bpt_instr = { 0x3c, 0xc3 },
282#else
283 .gdb_bpt_instr = { 0xc3, 0x3c },
284#endif
285};
diff --git a/arch/sh/kernel/kgdb_jmp.S b/arch/sh/kernel/kgdb_jmp.S
deleted file mode 100644
index 339bb1d7ff0b..000000000000
--- a/arch/sh/kernel/kgdb_jmp.S
+++ /dev/null
@@ -1,33 +0,0 @@
1#include <linux/linkage.h>
2
3ENTRY(setjmp)
4 add #(9*4), r4
5 sts.l pr, @-r4
6 mov.l r15, @-r4
7 mov.l r14, @-r4
8 mov.l r13, @-r4
9 mov.l r12, @-r4
10 mov.l r11, @-r4
11 mov.l r10, @-r4
12 mov.l r9, @-r4
13 mov.l r8, @-r4
14 rts
15 mov #0, r0
16
17ENTRY(longjmp)
18 mov.l @r4+, r8
19 mov.l @r4+, r9
20 mov.l @r4+, r10
21 mov.l @r4+, r11
22 mov.l @r4+, r12
23 mov.l @r4+, r13
24 mov.l @r4+, r14
25 mov.l @r4+, r15
26 lds.l @r4+, pr
27 mov r5, r0
28 tst r0, r0
29 bf 1f
30 mov #1, r0 ! in case val==0
311: rts
32 nop
33
diff --git a/arch/sh/kernel/kgdb_stub.c b/arch/sh/kernel/kgdb_stub.c
deleted file mode 100644
index bf8ac4c71640..000000000000
--- a/arch/sh/kernel/kgdb_stub.c
+++ /dev/null
@@ -1,1052 +0,0 @@
1/*
2 * May be copied or modified under the terms of the GNU General Public
3 * License. See linux/COPYING for more information.
4 *
5 * Contains extracts from code by Glenn Engel, Jim Kingdon,
6 * David Grothe <dave@gcom.com>, Tigran Aivazian <tigran@sco.com>,
7 * Amit S. Kale <akale@veritas.com>, William Gatliff <bgat@open-widgets.com>,
8 * Ben Lee, Steve Chamberlain and Benoit Miller <fulg@iname.com>.
9 *
10 * This version by Henry Bell <henry.bell@st.com>
11 * Minor modifications by Jeremy Siegel <jsiegel@mvista.com>
12 *
13 * Contains low-level support for remote debug using GDB.
14 *
15 * To enable debugger support, two things need to happen. A call to
16 * set_debug_traps() is necessary in order to allow any breakpoints
17 * or error conditions to be properly intercepted and reported to gdb.
18 * A breakpoint also needs to be generated to begin communication. This
19 * is most easily accomplished by a call to breakpoint() which does
20 * a trapa if the initialisation phase has been successfully completed.
21 *
22 * In this case, set_debug_traps() is not used to "take over" exceptions;
23 * other kernel code is modified instead to enter the kgdb functions here
24 * when appropriate (see entry.S for breakpoint traps and NMI interrupts,
25 * see traps.c for kernel error exceptions).
26 *
27 * The following gdb commands are supported:
28 *
29 * Command Function Return value
30 *
31 * g return the value of the CPU registers hex data or ENN
32 * G set the value of the CPU registers OK or ENN
33 *
34 * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN
35 * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN
36 * XAA..AA,LLLL: Same, but data is binary (not hex) OK or ENN
37 *
38 * c Resume at current address SNN ( signal NN)
39 * cAA..AA Continue at address AA..AA SNN
40 * CNN; Resume at current address with signal SNN
41 * CNN;AA..AA Resume at address AA..AA with signal SNN
42 *
43 * s Step one instruction SNN
44 * sAA..AA Step one instruction from AA..AA SNN
45 * SNN; Step one instruction with signal SNN
46 * SNNAA..AA Step one instruction from AA..AA w/NN SNN
47 *
48 * k kill (Detach GDB)
49 *
50 * d Toggle debug flag
51 * D Detach GDB
52 *
53 * Hct Set thread t for operations, OK or ENN
54 * c = 'c' (step, cont), c = 'g' (other
55 * operations)
56 *
57 * qC Query current thread ID QCpid
58 * qfThreadInfo Get list of current threads (first) m<id>
59 * qsThreadInfo " " " " " (subsequent)
60 * qOffsets Get section offsets Text=x;Data=y;Bss=z
61 *
62 * TXX Find if thread XX is alive OK or ENN
63 * ? What was the last sigval ? SNN (signal NN)
64 * O Output to GDB console
65 *
66 * Remote communication protocol.
67 *
68 * A debug packet whose contents are <data> is encapsulated for
69 * transmission in the form:
70 *
71 * $ <data> # CSUM1 CSUM2
72 *
73 * <data> must be ASCII alphanumeric and cannot include characters
74 * '$' or '#'. If <data> starts with two characters followed by
75 * ':', then the existing stubs interpret this as a sequence number.
76 *
77 * CSUM1 and CSUM2 are ascii hex representation of an 8-bit
78 * checksum of <data>, the most significant nibble is sent first.
79 * the hex digits 0-9,a-f are used.
80 *
81 * Receiver responds with:
82 *
83 * + - if CSUM is correct and ready for next packet
84 * - - if CSUM is incorrect
85 *
86 * Responses can be run-length encoded to save space. A '*' means that
87 * the next character is an ASCII encoding giving a repeat count which
88 * stands for that many repetitions of the character preceding the '*'.
89 * The encoding is n+29, yielding a printable character where n >=3
90 * (which is where RLE starts to win). Don't use an n > 126.
91 *
92 * So "0* " means the same as "0000".
93 */
94
95#include <linux/string.h>
96#include <linux/kernel.h>
97#include <linux/sched.h>
98#include <linux/smp.h>
99#include <linux/spinlock.h>
100#include <linux/delay.h>
101#include <linux/linkage.h>
102#include <linux/init.h>
103#include <linux/console.h>
104#include <linux/sysrq.h>
105#include <linux/module.h>
106#include <asm/system.h>
107#include <asm/cacheflush.h>
108#include <asm/current.h>
109#include <asm/signal.h>
110#include <asm/pgtable.h>
111#include <asm/ptrace.h>
112#include <asm/kgdb.h>
113#include <asm/io.h>
114
115/* Function pointers for linkage */
116kgdb_debug_hook_t *kgdb_debug_hook;
117kgdb_bus_error_hook_t *kgdb_bus_err_hook;
118
119int (*kgdb_getchar)(void);
120EXPORT_SYMBOL_GPL(kgdb_getchar);
121void (*kgdb_putchar)(int);
122EXPORT_SYMBOL_GPL(kgdb_putchar);
123
124static void put_debug_char(int c)
125{
126 if (!kgdb_putchar)
127 return;
128 (*kgdb_putchar)(c);
129}
130static int get_debug_char(void)
131{
132 if (!kgdb_getchar)
133 return -1;
134 return (*kgdb_getchar)();
135}
136
137/* Num chars in in/out bound buffers, register packets need NUMREGBYTES * 2 */
138#define BUFMAX 1024
139#define NUMREGBYTES (MAXREG*4)
140#define OUTBUFMAX (NUMREGBYTES*2+512)
141
142enum {
143 R0 = 0, R1, R2, R3, R4, R5, R6, R7,
144 R8, R9, R10, R11, R12, R13, R14, R15,
145 PC, PR, GBR, VBR, MACH, MACL, SR,
146 /* */
147 MAXREG
148};
149
150static unsigned int registers[MAXREG];
151struct kgdb_regs trap_registers;
152
153char kgdb_in_gdb_mode;
154char in_nmi; /* Set during NMI to prevent reentry */
155int kgdb_nofault; /* Boolean to ignore bus errs (i.e. in GDB) */
156
157/* Default values for SCI (can override via kernel args in setup.c) */
158#ifndef CONFIG_KGDB_DEFPORT
159#define CONFIG_KGDB_DEFPORT 1
160#endif
161
162#ifndef CONFIG_KGDB_DEFBAUD
163#define CONFIG_KGDB_DEFBAUD 115200
164#endif
165
166#if defined(CONFIG_KGDB_DEFPARITY_E)
167#define CONFIG_KGDB_DEFPARITY 'E'
168#elif defined(CONFIG_KGDB_DEFPARITY_O)
169#define CONFIG_KGDB_DEFPARITY 'O'
170#else /* CONFIG_KGDB_DEFPARITY_N */
171#define CONFIG_KGDB_DEFPARITY 'N'
172#endif
173
174#ifdef CONFIG_KGDB_DEFBITS_7
175#define CONFIG_KGDB_DEFBITS '7'
176#else /* CONFIG_KGDB_DEFBITS_8 */
177#define CONFIG_KGDB_DEFBITS '8'
178#endif
179
180/* SCI/UART settings, used in kgdb_console_setup() */
181int kgdb_portnum = CONFIG_KGDB_DEFPORT;
182EXPORT_SYMBOL_GPL(kgdb_portnum);
183int kgdb_baud = CONFIG_KGDB_DEFBAUD;
184EXPORT_SYMBOL_GPL(kgdb_baud);
185char kgdb_parity = CONFIG_KGDB_DEFPARITY;
186EXPORT_SYMBOL_GPL(kgdb_parity);
187char kgdb_bits = CONFIG_KGDB_DEFBITS;
188EXPORT_SYMBOL_GPL(kgdb_bits);
189
190/* Jump buffer for setjmp/longjmp */
191static jmp_buf rem_com_env;
192
193/* TRA differs sh3/4 */
194#if defined(CONFIG_CPU_SH3)
195#define TRA 0xffffffd0
196#elif defined(CONFIG_CPU_SH4)
197#define TRA 0xff000020
198#endif
199
200/* Macros for single step instruction identification */
201#define OPCODE_BT(op) (((op) & 0xff00) == 0x8900)
202#define OPCODE_BF(op) (((op) & 0xff00) == 0x8b00)
203#define OPCODE_BTF_DISP(op) (((op) & 0x80) ? (((op) | 0xffffff80) << 1) : \
204 (((op) & 0x7f ) << 1))
205#define OPCODE_BFS(op) (((op) & 0xff00) == 0x8f00)
206#define OPCODE_BTS(op) (((op) & 0xff00) == 0x8d00)
207#define OPCODE_BRA(op) (((op) & 0xf000) == 0xa000)
208#define OPCODE_BRA_DISP(op) (((op) & 0x800) ? (((op) | 0xfffff800) << 1) : \
209 (((op) & 0x7ff) << 1))
210#define OPCODE_BRAF(op) (((op) & 0xf0ff) == 0x0023)
211#define OPCODE_BRAF_REG(op) (((op) & 0x0f00) >> 8)
212#define OPCODE_BSR(op) (((op) & 0xf000) == 0xb000)
213#define OPCODE_BSR_DISP(op) (((op) & 0x800) ? (((op) | 0xfffff800) << 1) : \
214 (((op) & 0x7ff) << 1))
215#define OPCODE_BSRF(op) (((op) & 0xf0ff) == 0x0003)
216#define OPCODE_BSRF_REG(op) (((op) >> 8) & 0xf)
217#define OPCODE_JMP(op) (((op) & 0xf0ff) == 0x402b)
218#define OPCODE_JMP_REG(op) (((op) >> 8) & 0xf)
219#define OPCODE_JSR(op) (((op) & 0xf0ff) == 0x400b)
220#define OPCODE_JSR_REG(op) (((op) >> 8) & 0xf)
221#define OPCODE_RTS(op) ((op) == 0xb)
222#define OPCODE_RTE(op) ((op) == 0x2b)
223
224#define SR_T_BIT_MASK 0x1
225#define STEP_OPCODE 0xc320
226#define BIOS_CALL_TRAP 0x3f
227
228/* Exception codes as per SH-4 core manual */
229#define ADDRESS_ERROR_LOAD_VEC 7
230#define ADDRESS_ERROR_STORE_VEC 8
231#define TRAP_VEC 11
232#define INVALID_INSN_VEC 12
233#define INVALID_SLOT_VEC 13
234#define NMI_VEC 14
235#define USER_BREAK_VEC 15
236#define SERIAL_BREAK_VEC 58
237
238/* Misc static */
239static int stepped_address;
240static short stepped_opcode;
241static char in_buffer[BUFMAX];
242static char out_buffer[OUTBUFMAX];
243
244static void kgdb_to_gdb(const char *s);
245
246/* Convert ch to hex */
247static int hex(const char ch)
248{
249 if ((ch >= 'a') && (ch <= 'f'))
250 return (ch - 'a' + 10);
251 if ((ch >= '0') && (ch <= '9'))
252 return (ch - '0');
253 if ((ch >= 'A') && (ch <= 'F'))
254 return (ch - 'A' + 10);
255 return (-1);
256}
257
258/* Convert the memory pointed to by mem into hex, placing result in buf.
259 Returns a pointer to the last char put in buf (null) */
260static char *mem_to_hex(const char *mem, char *buf, const int count)
261{
262 int i;
263 int ch;
264 unsigned short s_val;
265 unsigned long l_val;
266
267 /* Check for 16 or 32 */
268 if (count == 2 && ((long) mem & 1) == 0) {
269 s_val = *(unsigned short *) mem;
270 mem = (char *) &s_val;
271 } else if (count == 4 && ((long) mem & 3) == 0) {
272 l_val = *(unsigned long *) mem;
273 mem = (char *) &l_val;
274 }
275 for (i = 0; i < count; i++) {
276 ch = *mem++;
277 buf = pack_hex_byte(buf, ch);
278 }
279 *buf = 0;
280 return (buf);
281}
282
283/* Convert the hex array pointed to by buf into binary, to be placed in mem.
284 Return a pointer to the character after the last byte written */
285static char *hex_to_mem(const char *buf, char *mem, const int count)
286{
287 int i;
288 unsigned char ch;
289
290 for (i = 0; i < count; i++) {
291 ch = hex(*buf++) << 4;
292 ch = ch + hex(*buf++);
293 *mem++ = ch;
294 }
295 return (mem);
296}
297
298/* While finding valid hex chars, convert to an integer, then return it */
299static int hex_to_int(char **ptr, int *int_value)
300{
301 int num_chars = 0;
302 int hex_value;
303
304 *int_value = 0;
305
306 while (**ptr) {
307 hex_value = hex(**ptr);
308 if (hex_value >= 0) {
309 *int_value = (*int_value << 4) | hex_value;
310 num_chars++;
311 } else
312 break;
313 (*ptr)++;
314 }
315 return num_chars;
316}
317
318/* Copy the binary array pointed to by buf into mem. Fix $, #,
319 and 0x7d escaped with 0x7d. Return a pointer to the character
320 after the last byte written. */
321static char *ebin_to_mem(const char *buf, char *mem, int count)
322{
323 for (; count > 0; count--, buf++) {
324 if (*buf == 0x7d)
325 *mem++ = *(++buf) ^ 0x20;
326 else
327 *mem++ = *buf;
328 }
329 return mem;
330}
331
332/* Scan for the start char '$', read the packet and check the checksum */
333static void get_packet(char *buffer, int buflen)
334{
335 unsigned char checksum;
336 unsigned char xmitcsum;
337 int i;
338 int count;
339 char ch;
340
341 do {
342 /* Ignore everything until the start character */
343 while ((ch = get_debug_char()) != '$');
344
345 checksum = 0;
346 xmitcsum = -1;
347 count = 0;
348
349 /* Now, read until a # or end of buffer is found */
350 while (count < (buflen - 1)) {
351 ch = get_debug_char();
352
353 if (ch == '#')
354 break;
355
356 checksum = checksum + ch;
357 buffer[count] = ch;
358 count = count + 1;
359 }
360
361 buffer[count] = 0;
362
363 /* Continue to read checksum following # */
364 if (ch == '#') {
365 xmitcsum = hex(get_debug_char()) << 4;
366 xmitcsum += hex(get_debug_char());
367
368 /* Checksum */
369 if (checksum != xmitcsum)
370 put_debug_char('-'); /* Failed checksum */
371 else {
372 /* Ack successful transfer */
373 put_debug_char('+');
374
375 /* If a sequence char is present, reply
376 the sequence ID */
377 if (buffer[2] == ':') {
378 put_debug_char(buffer[0]);
379 put_debug_char(buffer[1]);
380
381 /* Remove sequence chars from buffer */
382 count = strlen(buffer);
383 for (i = 3; i <= count; i++)
384 buffer[i - 3] = buffer[i];
385 }
386 }
387 }
388 }
389 while (checksum != xmitcsum); /* Keep trying while we fail */
390}
391
392/* Send the packet in the buffer with run-length encoding */
393static void put_packet(char *buffer)
394{
395 int checksum;
396 char *src;
397 int runlen;
398 int encode;
399
400 do {
401 src = buffer;
402 put_debug_char('$');
403 checksum = 0;
404
405 /* Continue while we still have chars left */
406 while (*src) {
407 /* Check for runs up to 99 chars long */
408 for (runlen = 1; runlen < 99; runlen++) {
409 if (src[0] != src[runlen])
410 break;
411 }
412
413 if (runlen > 3) {
414 /* Got a useful amount, send encoding */
415 encode = runlen + ' ' - 4;
416 put_debug_char(*src); checksum += *src;
417 put_debug_char('*'); checksum += '*';
418 put_debug_char(encode); checksum += encode;
419 src += runlen;
420 } else {
421 /* Otherwise just send the current char */
422 put_debug_char(*src); checksum += *src;
423 src += 1;
424 }
425 }
426
427 /* '#' Separator, put high and low components of checksum */
428 put_debug_char('#');
429 put_debug_char(hex_asc_hi(checksum));
430 put_debug_char(hex_asc_lo(checksum));
431 }
432 while ((get_debug_char()) != '+'); /* While no ack */
433}
434
435/* A bus error has occurred - perform a longjmp to return execution and
436 allow handling of the error */
437static void kgdb_handle_bus_error(void)
438{
439 longjmp(rem_com_env, 1);
440}
441
442/* Translate SH-3/4 exception numbers to unix-like signal values */
443static int compute_signal(const int excep_code)
444{
445 int sigval;
446
447 switch (excep_code) {
448
449 case INVALID_INSN_VEC:
450 case INVALID_SLOT_VEC:
451 sigval = SIGILL;
452 break;
453 case ADDRESS_ERROR_LOAD_VEC:
454 case ADDRESS_ERROR_STORE_VEC:
455 sigval = SIGSEGV;
456 break;
457
458 case SERIAL_BREAK_VEC:
459 case NMI_VEC:
460 sigval = SIGINT;
461 break;
462
463 case USER_BREAK_VEC:
464 case TRAP_VEC:
465 sigval = SIGTRAP;
466 break;
467
468 default:
469 sigval = SIGBUS; /* "software generated" */
470 break;
471 }
472
473 return (sigval);
474}
475
476/* Make a local copy of the registers passed into the handler (bletch) */
477static void kgdb_regs_to_gdb_regs(const struct kgdb_regs *regs,
478 int *gdb_regs)
479{
480 gdb_regs[R0] = regs->regs[R0];
481 gdb_regs[R1] = regs->regs[R1];
482 gdb_regs[R2] = regs->regs[R2];
483 gdb_regs[R3] = regs->regs[R3];
484 gdb_regs[R4] = regs->regs[R4];
485 gdb_regs[R5] = regs->regs[R5];
486 gdb_regs[R6] = regs->regs[R6];
487 gdb_regs[R7] = regs->regs[R7];
488 gdb_regs[R8] = regs->regs[R8];
489 gdb_regs[R9] = regs->regs[R9];
490 gdb_regs[R10] = regs->regs[R10];
491 gdb_regs[R11] = regs->regs[R11];
492 gdb_regs[R12] = regs->regs[R12];
493 gdb_regs[R13] = regs->regs[R13];
494 gdb_regs[R14] = regs->regs[R14];
495 gdb_regs[R15] = regs->regs[R15];
496 gdb_regs[PC] = regs->pc;
497 gdb_regs[PR] = regs->pr;
498 gdb_regs[GBR] = regs->gbr;
499 gdb_regs[MACH] = regs->mach;
500 gdb_regs[MACL] = regs->macl;
501 gdb_regs[SR] = regs->sr;
502 gdb_regs[VBR] = regs->vbr;
503}
504
505/* Copy local gdb registers back to kgdb regs, for later copy to kernel */
506static void gdb_regs_to_kgdb_regs(const int *gdb_regs,
507 struct kgdb_regs *regs)
508{
509 regs->regs[R0] = gdb_regs[R0];
510 regs->regs[R1] = gdb_regs[R1];
511 regs->regs[R2] = gdb_regs[R2];
512 regs->regs[R3] = gdb_regs[R3];
513 regs->regs[R4] = gdb_regs[R4];
514 regs->regs[R5] = gdb_regs[R5];
515 regs->regs[R6] = gdb_regs[R6];
516 regs->regs[R7] = gdb_regs[R7];
517 regs->regs[R8] = gdb_regs[R8];
518 regs->regs[R9] = gdb_regs[R9];
519 regs->regs[R10] = gdb_regs[R10];
520 regs->regs[R11] = gdb_regs[R11];
521 regs->regs[R12] = gdb_regs[R12];
522 regs->regs[R13] = gdb_regs[R13];
523 regs->regs[R14] = gdb_regs[R14];
524 regs->regs[R15] = gdb_regs[R15];
525 regs->pc = gdb_regs[PC];
526 regs->pr = gdb_regs[PR];
527 regs->gbr = gdb_regs[GBR];
528 regs->mach = gdb_regs[MACH];
529 regs->macl = gdb_regs[MACL];
530 regs->sr = gdb_regs[SR];
531 regs->vbr = gdb_regs[VBR];
532}
533
534/* Calculate the new address for after a step */
535static short *get_step_address(void)
536{
537 short op = *(short *) trap_registers.pc;
538 long addr;
539
540 /* BT */
541 if (OPCODE_BT(op)) {
542 if (trap_registers.sr & SR_T_BIT_MASK)
543 addr = trap_registers.pc + 4 + OPCODE_BTF_DISP(op);
544 else
545 addr = trap_registers.pc + 2;
546 }
547
548 /* BTS */
549 else if (OPCODE_BTS(op)) {
550 if (trap_registers.sr & SR_T_BIT_MASK)
551 addr = trap_registers.pc + 4 + OPCODE_BTF_DISP(op);
552 else
553 addr = trap_registers.pc + 4; /* Not in delay slot */
554 }
555
556 /* BF */
557 else if (OPCODE_BF(op)) {
558 if (!(trap_registers.sr & SR_T_BIT_MASK))
559 addr = trap_registers.pc + 4 + OPCODE_BTF_DISP(op);
560 else
561 addr = trap_registers.pc + 2;
562 }
563
564 /* BFS */
565 else if (OPCODE_BFS(op)) {
566 if (!(trap_registers.sr & SR_T_BIT_MASK))
567 addr = trap_registers.pc + 4 + OPCODE_BTF_DISP(op);
568 else
569 addr = trap_registers.pc + 4; /* Not in delay slot */
570 }
571
572 /* BRA */
573 else if (OPCODE_BRA(op))
574 addr = trap_registers.pc + 4 + OPCODE_BRA_DISP(op);
575
576 /* BRAF */
577 else if (OPCODE_BRAF(op))
578 addr = trap_registers.pc + 4
579 + trap_registers.regs[OPCODE_BRAF_REG(op)];
580
581 /* BSR */
582 else if (OPCODE_BSR(op))
583 addr = trap_registers.pc + 4 + OPCODE_BSR_DISP(op);
584
585 /* BSRF */
586 else if (OPCODE_BSRF(op))
587 addr = trap_registers.pc + 4
588 + trap_registers.regs[OPCODE_BSRF_REG(op)];
589
590 /* JMP */
591 else if (OPCODE_JMP(op))
592 addr = trap_registers.regs[OPCODE_JMP_REG(op)];
593
594 /* JSR */
595 else if (OPCODE_JSR(op))
596 addr = trap_registers.regs[OPCODE_JSR_REG(op)];
597
598 /* RTS */
599 else if (OPCODE_RTS(op))
600 addr = trap_registers.pr;
601
602 /* RTE */
603 else if (OPCODE_RTE(op))
604 addr = trap_registers.regs[15];
605
606 /* Other */
607 else
608 addr = trap_registers.pc + 2;
609
610 flush_icache_range(addr, addr + 2);
611 return (short *) addr;
612}
613
614/* Set up a single-step. Replace the instruction immediately after the
615 current instruction (i.e. next in the expected flow of control) with a
616 trap instruction, so that returning will cause only a single instruction
617 to be executed. Note that this model is slightly broken for instructions
618 with delay slots (e.g. B[TF]S, BSR, BRA etc), where both the branch
619 and the instruction in the delay slot will be executed. */
620static void do_single_step(void)
621{
622 unsigned short *addr = 0;
623
624 /* Determine where the target instruction will send us to */
625 addr = get_step_address();
626 stepped_address = (int)addr;
627
628 /* Replace it */
629 stepped_opcode = *(short *)addr;
630 *addr = STEP_OPCODE;
631
632 /* Flush and return */
633 flush_icache_range((long) addr, (long) addr + 2);
634}
635
636/* Undo a single step */
637static void undo_single_step(void)
638{
639 /* If we have stepped, put back the old instruction */
640 /* Use stepped_address in case we stopped elsewhere */
641 if (stepped_opcode != 0) {
642 *(short*)stepped_address = stepped_opcode;
643 flush_icache_range(stepped_address, stepped_address + 2);
644 }
645 stepped_opcode = 0;
646}
647
648/* Send a signal message */
649static void send_signal_msg(const int signum)
650{
651 out_buffer[0] = 'S';
652 out_buffer[1] = hex_asc_hi(signum);
653 out_buffer[2] = hex_asc_lo(signum);
654 out_buffer[3] = 0;
655 put_packet(out_buffer);
656}
657
658/* Reply that all was well */
659static void send_ok_msg(void)
660{
661 strcpy(out_buffer, "OK");
662 put_packet(out_buffer);
663}
664
665/* Reply that an error occurred */
666static void send_err_msg(void)
667{
668 strcpy(out_buffer, "E01");
669 put_packet(out_buffer);
670}
671
672/* Empty message indicates unrecognised command */
673static void send_empty_msg(void)
674{
675 put_packet("");
676}
677
678/* Read memory due to 'm' message */
679static void read_mem_msg(void)
680{
681 char *ptr;
682 int addr;
683 int length;
684
685 /* Jmp, disable bus error handler */
686 if (setjmp(rem_com_env) == 0) {
687
688 kgdb_nofault = 1;
689
690 /* Walk through, have m<addr>,<length> */
691 ptr = &in_buffer[1];
692 if (hex_to_int(&ptr, &addr) && (*ptr++ == ','))
693 if (hex_to_int(&ptr, &length)) {
694 ptr = 0;
695 if (length * 2 > OUTBUFMAX)
696 length = OUTBUFMAX / 2;
697 mem_to_hex((char *) addr, out_buffer, length);
698 }
699 if (ptr)
700 send_err_msg();
701 else
702 put_packet(out_buffer);
703 } else
704 send_err_msg();
705
706 /* Restore bus error handler */
707 kgdb_nofault = 0;
708}
709
710/* Write memory due to 'M' or 'X' message */
711static void write_mem_msg(int binary)
712{
713 char *ptr;
714 int addr;
715 int length;
716
717 if (setjmp(rem_com_env) == 0) {
718
719 kgdb_nofault = 1;
720
721 /* Walk through, have M<addr>,<length>:<data> */
722 ptr = &in_buffer[1];
723 if (hex_to_int(&ptr, &addr) && (*ptr++ == ','))
724 if (hex_to_int(&ptr, &length) && (*ptr++ == ':')) {
725 if (binary)
726 ebin_to_mem(ptr, (char*)addr, length);
727 else
728 hex_to_mem(ptr, (char*)addr, length);
729 flush_icache_range(addr, addr + length);
730 ptr = 0;
731 send_ok_msg();
732 }
733 if (ptr)
734 send_err_msg();
735 } else
736 send_err_msg();
737
738 /* Restore bus error handler */
739 kgdb_nofault = 0;
740}
741
742/* Continue message */
743static void continue_msg(void)
744{
745 /* Try to read optional parameter, PC unchanged if none */
746 char *ptr = &in_buffer[1];
747 int addr;
748
749 if (hex_to_int(&ptr, &addr))
750 trap_registers.pc = addr;
751}
752
753/* Continue message with signal */
754static void continue_with_sig_msg(void)
755{
756 int signal;
757 char *ptr = &in_buffer[1];
758 int addr;
759
760 /* Report limitation */
761 kgdb_to_gdb("Cannot force signal in kgdb, continuing anyway.\n");
762
763 /* Signal */
764 hex_to_int(&ptr, &signal);
765 if (*ptr == ';')
766 ptr++;
767
768 /* Optional address */
769 if (hex_to_int(&ptr, &addr))
770 trap_registers.pc = addr;
771}
772
773/* Step message */
774static void step_msg(void)
775{
776 continue_msg();
777 do_single_step();
778}
779
780/* Step message with signal */
781static void step_with_sig_msg(void)
782{
783 continue_with_sig_msg();
784 do_single_step();
785}
786
787/* Send register contents */
788static void send_regs_msg(void)
789{
790 kgdb_regs_to_gdb_regs(&trap_registers, registers);
791 mem_to_hex((char *) registers, out_buffer, NUMREGBYTES);
792 put_packet(out_buffer);
793}
794
795/* Set register contents - currently can't set other thread's registers */
796static void set_regs_msg(void)
797{
798 kgdb_regs_to_gdb_regs(&trap_registers, registers);
799 hex_to_mem(&in_buffer[1], (char *) registers, NUMREGBYTES);
800 gdb_regs_to_kgdb_regs(registers, &trap_registers);
801 send_ok_msg();
802}
803
804#ifdef CONFIG_SH_KGDB_CONSOLE
805/*
806 * Bring up the ports..
807 */
808static int __init kgdb_serial_setup(void)
809{
810 struct console dummy;
811 return kgdb_console_setup(&dummy, 0);
812}
813#else
814#define kgdb_serial_setup() 0
815#endif
816
817/* The command loop, read and act on requests */
818static void kgdb_command_loop(const int excep_code, const int trapa_value)
819{
820 int sigval;
821
822 /* Enter GDB mode (e.g. after detach) */
823 if (!kgdb_in_gdb_mode) {
824 /* Do serial setup, notify user, issue preemptive ack */
825 printk(KERN_NOTICE "KGDB: Waiting for GDB\n");
826 kgdb_in_gdb_mode = 1;
827 put_debug_char('+');
828 }
829
830 /* Reply to host that an exception has occurred */
831 sigval = compute_signal(excep_code);
832 send_signal_msg(sigval);
833
834 /* TRAP_VEC exception indicates a software trap inserted in place of
835 code by GDB so back up PC by one instruction, as this instruction
836 will later be replaced by its original one. Do NOT do this for
837 trap 0xff, since that indicates a compiled-in breakpoint which
838 will not be replaced (and we would retake the trap forever) */
839 if ((excep_code == TRAP_VEC) && (trapa_value != (0x3c << 2)))
840 trap_registers.pc -= 2;
841
842 /* Undo any stepping we may have done */
843 undo_single_step();
844
845 while (1) {
846 out_buffer[0] = 0;
847 get_packet(in_buffer, BUFMAX);
848
849 /* Examine first char of buffer to see what we need to do */
850 switch (in_buffer[0]) {
851 case '?': /* Send which signal we've received */
852 send_signal_msg(sigval);
853 break;
854
855 case 'g': /* Return the values of the CPU registers */
856 send_regs_msg();
857 break;
858
859 case 'G': /* Set the value of the CPU registers */
860 set_regs_msg();
861 break;
862
863 case 'm': /* Read LLLL bytes address AA..AA */
864 read_mem_msg();
865 break;
866
867 case 'M': /* Write LLLL bytes address AA..AA, ret OK */
868 write_mem_msg(0); /* 0 = data in hex */
869 break;
870
871 case 'X': /* Write LLLL bytes esc bin address AA..AA */
872 if (kgdb_bits == '8')
873 write_mem_msg(1); /* 1 = data in binary */
874 else
875 send_empty_msg();
876 break;
877
878 case 'C': /* Continue, signum included, we ignore it */
879 continue_with_sig_msg();
880 return;
881
882 case 'c': /* Continue at address AA..AA (optional) */
883 continue_msg();
884 return;
885
886 case 'S': /* Step, signum included, we ignore it */
887 step_with_sig_msg();
888 return;
889
890 case 's': /* Step one instruction from AA..AA */
891 step_msg();
892 return;
893
894 case 'k': /* 'Kill the program' with a kernel ? */
895 break;
896
897 case 'D': /* Detach from program, send reply OK */
898 kgdb_in_gdb_mode = 0;
899 send_ok_msg();
900 get_debug_char();
901 return;
902
903 default:
904 send_empty_msg();
905 break;
906 }
907 }
908}
909
910/* There has been an exception, most likely a breakpoint. */
911static void handle_exception(struct pt_regs *regs)
912{
913 int excep_code, vbr_val;
914 int count;
915 int trapa_value = ctrl_inl(TRA);
916
917 /* Copy kernel regs (from stack) */
918 for (count = 0; count < 16; count++)
919 trap_registers.regs[count] = regs->regs[count];
920 trap_registers.pc = regs->pc;
921 trap_registers.pr = regs->pr;
922 trap_registers.sr = regs->sr;
923 trap_registers.gbr = regs->gbr;
924 trap_registers.mach = regs->mach;
925 trap_registers.macl = regs->macl;
926
927 asm("stc vbr, %0":"=r"(vbr_val));
928 trap_registers.vbr = vbr_val;
929
930 /* Get excode for command loop call, user access */
931 asm("stc r2_bank, %0":"=r"(excep_code));
932
933 /* Act on the exception */
934 kgdb_command_loop(excep_code, trapa_value);
935
936 /* Copy back the (maybe modified) registers */
937 for (count = 0; count < 16; count++)
938 regs->regs[count] = trap_registers.regs[count];
939 regs->pc = trap_registers.pc;
940 regs->pr = trap_registers.pr;
941 regs->sr = trap_registers.sr;
942 regs->gbr = trap_registers.gbr;
943 regs->mach = trap_registers.mach;
944 regs->macl = trap_registers.macl;
945
946 vbr_val = trap_registers.vbr;
947 asm("ldc %0, vbr": :"r"(vbr_val));
948}
949
950asmlinkage void kgdb_handle_exception(unsigned long r4, unsigned long r5,
951 unsigned long r6, unsigned long r7,
952 struct pt_regs __regs)
953{
954 struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
955 handle_exception(regs);
956}
957
958/* Initialise the KGDB data structures and serial configuration */
959int __init kgdb_init(void)
960{
961 in_nmi = 0;
962 kgdb_nofault = 0;
963 stepped_opcode = 0;
964 kgdb_in_gdb_mode = 0;
965
966 if (kgdb_serial_setup() != 0) {
967 printk(KERN_NOTICE "KGDB: serial setup error\n");
968 return -1;
969 }
970
971 /* Init ptr to exception handler */
972 kgdb_debug_hook = handle_exception;
973 kgdb_bus_err_hook = kgdb_handle_bus_error;
974
975 /* Enter kgdb now if requested, or just report init done */
976 printk(KERN_NOTICE "KGDB: stub is initialized.\n");
977
978 return 0;
979}
980
981/* Make function available for "user messages"; console will use it too. */
982
983char gdbmsgbuf[BUFMAX];
984#define MAXOUT ((BUFMAX-2)/2)
985
986static void kgdb_msg_write(const char *s, unsigned count)
987{
988 int i;
989 int wcount;
990 char *bufptr;
991
992 /* 'O'utput */
993 gdbmsgbuf[0] = 'O';
994
995 /* Fill and send buffers... */
996 while (count > 0) {
997 bufptr = gdbmsgbuf + 1;
998
999 /* Calculate how many this time */
1000 wcount = (count > MAXOUT) ? MAXOUT : count;
1001
1002 /* Pack in hex chars */
1003 for (i = 0; i < wcount; i++)
1004 bufptr = pack_hex_byte(bufptr, s[i]);
1005 *bufptr = '\0';
1006
1007 /* Move up */
1008 s += wcount;
1009 count -= wcount;
1010
1011 /* Write packet */
1012 put_packet(gdbmsgbuf);
1013 }
1014}
1015
1016static void kgdb_to_gdb(const char *s)
1017{
1018 kgdb_msg_write(s, strlen(s));
1019}
1020
1021#ifdef CONFIG_SH_KGDB_CONSOLE
1022void kgdb_console_write(struct console *co, const char *s, unsigned count)
1023{
1024 /* Bail if we're not talking to GDB */
1025 if (!kgdb_in_gdb_mode)
1026 return;
1027
1028 kgdb_msg_write(s, count);
1029}
1030#endif
1031
1032#ifdef CONFIG_KGDB_SYSRQ
1033static void sysrq_handle_gdb(int key, struct tty_struct *tty)
1034{
1035 printk("Entering GDB stub\n");
1036 breakpoint();
1037}
1038
1039static struct sysrq_key_op sysrq_gdb_op = {
1040 .handler = sysrq_handle_gdb,
1041 .help_msg = "Gdb",
1042 .action_msg = "GDB",
1043};
1044
1045static int gdb_register_sysrq(void)
1046{
1047 printk("Registering GDB sysrq handler\n");
1048 register_sysrq_key('g', &sysrq_gdb_op);
1049 return 0;
1050}
1051module_init(gdb_register_sysrq);
1052#endif
diff --git a/arch/sh/kernel/pm.c b/arch/sh/kernel/pm.c
deleted file mode 100644
index 10ab62c9aede..000000000000
--- a/arch/sh/kernel/pm.c
+++ /dev/null
@@ -1,88 +0,0 @@
1/*
2 * Generic Power Management Routine
3 *
4 * Copyright (c) 2006 Andriy Skulysh <askulsyh@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License.
8 */
9#include <linux/suspend.h>
10#include <linux/delay.h>
11#include <linux/gfp.h>
12#include <asm/freq.h>
13#include <asm/io.h>
14#include <asm/watchdog.h>
15#include <asm/pm.h>
16
17#define INTR_OFFSET 0x600
18
19#define STBCR 0xffffff82
20#define STBCR2 0xffffff88
21
22#define STBCR_STBY 0x80
23#define STBCR_MSTP2 0x04
24
25#define MCR 0xffffff68
26#define RTCNT 0xffffff70
27
28#define MCR_RMODE 2
29#define MCR_RFSH 4
30
31void pm_enter(void)
32{
33 u8 stbcr, csr;
34 u16 frqcr, mcr;
35 u32 vbr_new, vbr_old;
36
37 set_bl_bit();
38
39 /* set wdt */
40 csr = sh_wdt_read_csr();
41 csr &= ~WTCSR_TME;
42 csr |= WTCSR_CKS_4096;
43 sh_wdt_write_csr(csr);
44 csr = sh_wdt_read_csr();
45 sh_wdt_write_cnt(0);
46
47 /* disable PLL1 */
48 frqcr = ctrl_inw(FRQCR);
49 frqcr &= ~(FRQCR_PLLEN | FRQCR_PSTBY);
50 ctrl_outw(frqcr, FRQCR);
51
52 /* enable standby */
53 stbcr = ctrl_inb(STBCR);
54 ctrl_outb(stbcr | STBCR_STBY | STBCR_MSTP2, STBCR);
55
56 /* set self-refresh */
57 mcr = ctrl_inw(MCR);
58 ctrl_outw(mcr & ~MCR_RFSH, MCR);
59
60 /* set interrupt handler */
61 asm volatile("stc vbr, %0" : "=r" (vbr_old));
62 vbr_new = get_zeroed_page(GFP_ATOMIC);
63 udelay(50);
64 memcpy((void*)(vbr_new + INTR_OFFSET),
65 &wakeup_start, &wakeup_end - &wakeup_start);
66 asm volatile("ldc %0, vbr" : : "r" (vbr_new));
67
68 ctrl_outw(0, RTCNT);
69 ctrl_outw(mcr | MCR_RFSH | MCR_RMODE, MCR);
70
71 cpu_sleep();
72
73 asm volatile("ldc %0, vbr" : : "r" (vbr_old));
74
75 free_page(vbr_new);
76
77 /* enable PLL1 */
78 frqcr = ctrl_inw(FRQCR);
79 frqcr |= FRQCR_PSTBY;
80 ctrl_outw(frqcr, FRQCR);
81 udelay(50);
82 frqcr |= FRQCR_PLLEN;
83 ctrl_outw(frqcr, FRQCR);
84
85 ctrl_outb(stbcr, STBCR);
86
87 clear_bl_bit();
88}
diff --git a/arch/sh/kernel/process_32.c b/arch/sh/kernel/process_32.c
index b965f0282c7d..ddafbbbab2ab 100644
--- a/arch/sh/kernel/process_32.c
+++ b/arch/sh/kernel/process_32.c
@@ -32,65 +32,8 @@
32#include <asm/fpu.h> 32#include <asm/fpu.h>
33#include <asm/syscalls.h> 33#include <asm/syscalls.h>
34 34
35static int hlt_counter;
36int ubc_usercnt = 0; 35int ubc_usercnt = 0;
37 36
38void (*pm_idle)(void);
39void (*pm_power_off)(void);
40EXPORT_SYMBOL(pm_power_off);
41
42static int __init nohlt_setup(char *__unused)
43{
44 hlt_counter = 1;
45 return 1;
46}
47__setup("nohlt", nohlt_setup);
48
49static int __init hlt_setup(char *__unused)
50{
51 hlt_counter = 0;
52 return 1;
53}
54__setup("hlt", hlt_setup);
55
56static void default_idle(void)
57{
58 if (!hlt_counter) {
59 clear_thread_flag(TIF_POLLING_NRFLAG);
60 smp_mb__after_clear_bit();
61 set_bl_bit();
62 while (!need_resched())
63 cpu_sleep();
64 clear_bl_bit();
65 set_thread_flag(TIF_POLLING_NRFLAG);
66 } else
67 while (!need_resched())
68 cpu_relax();
69}
70
71void cpu_idle(void)
72{
73 set_thread_flag(TIF_POLLING_NRFLAG);
74
75 /* endless idle loop with no priority at all */
76 while (1) {
77 void (*idle)(void) = pm_idle;
78
79 if (!idle)
80 idle = default_idle;
81
82 tick_nohz_stop_sched_tick(1);
83 while (!need_resched())
84 idle();
85 tick_nohz_restart_sched_tick();
86
87 preempt_enable_no_resched();
88 schedule();
89 preempt_disable();
90 check_pgt_cache();
91 }
92}
93
94void machine_restart(char * __unused) 37void machine_restart(char * __unused)
95{ 38{
96 /* SR.BL=1 and invoke address error to let CPU reset (manual reset) */ 39 /* SR.BL=1 and invoke address error to let CPU reset (manual reset) */
@@ -115,8 +58,8 @@ void machine_power_off(void)
115void show_regs(struct pt_regs * regs) 58void show_regs(struct pt_regs * regs)
116{ 59{
117 printk("\n"); 60 printk("\n");
118 printk("Pid : %d, Comm: %20s\n", task_pid_nr(current), current->comm); 61 printk("Pid : %d, Comm: \t\t%s\n", task_pid_nr(current), current->comm);
119 printk("CPU : %d %s (%s %.*s)\n", 62 printk("CPU : %d \t\t%s (%s %.*s)\n\n",
120 smp_processor_id(), print_tainted(), init_utsname()->release, 63 smp_processor_id(), print_tainted(), init_utsname()->release,
121 (int)strcspn(init_utsname()->version, " "), 64 (int)strcspn(init_utsname()->version, " "),
122 init_utsname()->version); 65 init_utsname()->version);
@@ -148,26 +91,16 @@ void show_regs(struct pt_regs * regs)
148 regs->mach, regs->macl, regs->gbr, regs->pr); 91 regs->mach, regs->macl, regs->gbr, regs->pr);
149 92
150 show_trace(NULL, (unsigned long *)regs->regs[15], regs); 93 show_trace(NULL, (unsigned long *)regs->regs[15], regs);
94 show_code(regs);
151} 95}
152 96
153/* 97/*
154 * Create a kernel thread 98 * Create a kernel thread
155 */ 99 */
156 100ATTRIB_NORET void kernel_thread_helper(void *arg, int (*fn)(void *))
157/* 101{
158 * This is the mechanism for creating a new kernel thread. 102 do_exit(fn(arg));
159 * 103}
160 */
161extern void kernel_thread_helper(void);
162__asm__(".align 5\n"
163 "kernel_thread_helper:\n\t"
164 "jsr @r5\n\t"
165 " nop\n\t"
166 "mov.l 1f, r1\n\t"
167 "jsr @r1\n\t"
168 " mov r0, r4\n\t"
169 ".align 2\n\t"
170 "1:.long do_exit");
171 104
172/* Don't use this in BL=1(cli). Or else, CPU resets! */ 105/* Don't use this in BL=1(cli). Or else, CPU resets! */
173int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) 106int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
diff --git a/arch/sh/kernel/process_64.c b/arch/sh/kernel/process_64.c
index b7aa09235b51..a7e5f2e74bac 100644
--- a/arch/sh/kernel/process_64.c
+++ b/arch/sh/kernel/process_64.c
@@ -23,7 +23,6 @@
23#include <linux/reboot.h> 23#include <linux/reboot.h>
24#include <linux/init.h> 24#include <linux/init.h>
25#include <linux/module.h> 25#include <linux/module.h>
26#include <linux/proc_fs.h>
27#include <linux/io.h> 26#include <linux/io.h>
28#include <asm/syscalls.h> 27#include <asm/syscalls.h>
29#include <asm/uaccess.h> 28#include <asm/uaccess.h>
@@ -33,56 +32,6 @@
33 32
34struct task_struct *last_task_used_math = NULL; 33struct task_struct *last_task_used_math = NULL;
35 34
36static int hlt_counter = 1;
37
38#define HARD_IDLE_TIMEOUT (HZ / 3)
39
40static int __init nohlt_setup(char *__unused)
41{
42 hlt_counter = 1;
43 return 1;
44}
45
46static int __init hlt_setup(char *__unused)
47{
48 hlt_counter = 0;
49 return 1;
50}
51
52__setup("nohlt", nohlt_setup);
53__setup("hlt", hlt_setup);
54
55static inline void hlt(void)
56{
57 __asm__ __volatile__ ("sleep" : : : "memory");
58}
59
60/*
61 * The idle loop on a uniprocessor SH..
62 */
63void cpu_idle(void)
64{
65 /* endless idle loop with no priority at all */
66 while (1) {
67 if (hlt_counter) {
68 while (!need_resched())
69 cpu_relax();
70 } else {
71 local_irq_disable();
72 while (!need_resched()) {
73 local_irq_enable();
74 hlt();
75 local_irq_disable();
76 }
77 local_irq_enable();
78 }
79 preempt_enable_no_resched();
80 schedule();
81 preempt_disable();
82 }
83
84}
85
86void machine_restart(char * __unused) 35void machine_restart(char * __unused)
87{ 36{
88 extern void phys_stext(void); 37 extern void phys_stext(void);
@@ -97,13 +46,6 @@ void machine_halt(void)
97 46
98void machine_power_off(void) 47void machine_power_off(void)
99{ 48{
100#if 0
101 /* Disable watchdog timer */
102 ctrl_outl(0xa5000000, WTCSR);
103 /* Configure deep standby on sleep */
104 ctrl_outl(0x03, STBCR);
105#endif
106
107 __asm__ __volatile__ ( 49 __asm__ __volatile__ (
108 "sleep\n\t" 50 "sleep\n\t"
109 "synci\n\t" 51 "synci\n\t"
@@ -113,9 +55,6 @@ void machine_power_off(void)
113 panic("Unexpected wakeup!\n"); 55 panic("Unexpected wakeup!\n");
114} 56}
115 57
116void (*pm_power_off)(void) = machine_power_off;
117EXPORT_SYMBOL(pm_power_off);
118
119void show_regs(struct pt_regs * regs) 58void show_regs(struct pt_regs * regs)
120{ 59{
121 unsigned long long ah, al, bh, bl, ch, cl; 60 unsigned long long ah, al, bh, bl, ch, cl;
@@ -365,18 +304,6 @@ void show_regs(struct pt_regs * regs)
365 } 304 }
366} 305}
367 306
368struct task_struct * alloc_task_struct(void)
369{
370 /* Get task descriptor pages */
371 return (struct task_struct *)
372 __get_free_pages(GFP_KERNEL, get_order(THREAD_SIZE));
373}
374
375void free_task_struct(struct task_struct *p)
376{
377 free_pages((unsigned long) p, get_order(THREAD_SIZE));
378}
379
380/* 307/*
381 * Create a kernel thread 308 * Create a kernel thread
382 */ 309 */
@@ -662,41 +589,3 @@ unsigned long get_wchan(struct task_struct *p)
662#endif 589#endif
663 return pc; 590 return pc;
664} 591}
665
666/* Provide a /proc/asids file that lists out the
667 ASIDs currently associated with the processes. (If the DM.PC register is
668 examined through the debug link, this shows ASID + PC. To make use of this,
669 the PID->ASID relationship needs to be known. This is primarily for
670 debugging.)
671 */
672
673#if defined(CONFIG_SH64_PROC_ASIDS)
674static int
675asids_proc_info(char *buf, char **start, off_t fpos, int length, int *eof, void *data)
676{
677 int len=0;
678 struct task_struct *p;
679 read_lock(&tasklist_lock);
680 for_each_process(p) {
681 int pid = p->pid;
682
683 if (!pid)
684 continue;
685 if (p->mm)
686 len += sprintf(buf+len, "%5d : %02lx\n", pid,
687 asid_cache(smp_processor_id()));
688 else
689 len += sprintf(buf+len, "%5d : (none)\n", pid);
690 }
691 read_unlock(&tasklist_lock);
692 *eof = 1;
693 return len;
694}
695
696static int __init register_proc_asids(void)
697{
698 create_proc_read_entry("asids", 0, NULL, asids_proc_info, NULL);
699 return 0;
700}
701__initcall(register_proc_asids);
702#endif
diff --git a/arch/sh/kernel/ptrace_64.c b/arch/sh/kernel/ptrace_64.c
index e15b099c1f06..695097438f02 100644
--- a/arch/sh/kernel/ptrace_64.c
+++ b/arch/sh/kernel/ptrace_64.c
@@ -2,7 +2,7 @@
2 * arch/sh/kernel/ptrace_64.c 2 * arch/sh/kernel/ptrace_64.c
3 * 3 *
4 * Copyright (C) 2000, 2001 Paolo Alberelli 4 * Copyright (C) 2000, 2001 Paolo Alberelli
5 * Copyright (C) 2003 - 2007 Paul Mundt 5 * Copyright (C) 2003 - 2008 Paul Mundt
6 * 6 *
7 * Started from SH3/4 version: 7 * Started from SH3/4 version:
8 * SuperH version: Copyright (C) 1999, 2000 Kaz Kojima & Niibe Yutaka 8 * SuperH version: Copyright (C) 1999, 2000 Kaz Kojima & Niibe Yutaka
@@ -29,6 +29,8 @@
29#include <linux/audit.h> 29#include <linux/audit.h>
30#include <linux/seccomp.h> 30#include <linux/seccomp.h>
31#include <linux/tracehook.h> 31#include <linux/tracehook.h>
32#include <linux/elf.h>
33#include <linux/regset.h>
32#include <asm/io.h> 34#include <asm/io.h>
33#include <asm/uaccess.h> 35#include <asm/uaccess.h>
34#include <asm/pgtable.h> 36#include <asm/pgtable.h>
@@ -137,6 +139,165 @@ void user_disable_single_step(struct task_struct *child)
137 regs->sr &= ~SR_SSTEP; 139 regs->sr &= ~SR_SSTEP;
138} 140}
139 141
142static int genregs_get(struct task_struct *target,
143 const struct user_regset *regset,
144 unsigned int pos, unsigned int count,
145 void *kbuf, void __user *ubuf)
146{
147 const struct pt_regs *regs = task_pt_regs(target);
148 int ret;
149
150 /* PC, SR, SYSCALL */
151 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
152 &regs->pc,
153 0, 3 * sizeof(unsigned long long));
154
155 /* R1 -> R63 */
156 if (!ret)
157 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
158 regs->regs,
159 offsetof(struct pt_regs, regs[0]),
160 63 * sizeof(unsigned long long));
161 /* TR0 -> TR7 */
162 if (!ret)
163 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
164 regs->tregs,
165 offsetof(struct pt_regs, tregs[0]),
166 8 * sizeof(unsigned long long));
167
168 if (!ret)
169 ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
170 sizeof(struct pt_regs), -1);
171
172 return ret;
173}
174
175static int genregs_set(struct task_struct *target,
176 const struct user_regset *regset,
177 unsigned int pos, unsigned int count,
178 const void *kbuf, const void __user *ubuf)
179{
180 struct pt_regs *regs = task_pt_regs(target);
181 int ret;
182
183 /* PC, SR, SYSCALL */
184 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
185 &regs->pc,
186 0, 3 * sizeof(unsigned long long));
187
188 /* R1 -> R63 */
189 if (!ret && count > 0)
190 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
191 regs->regs,
192 offsetof(struct pt_regs, regs[0]),
193 63 * sizeof(unsigned long long));
194
195 /* TR0 -> TR7 */
196 if (!ret && count > 0)
197 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
198 regs->tregs,
199 offsetof(struct pt_regs, tregs[0]),
200 8 * sizeof(unsigned long long));
201
202 if (!ret)
203 ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
204 sizeof(struct pt_regs), -1);
205
206 return ret;
207}
208
209#ifdef CONFIG_SH_FPU
210int fpregs_get(struct task_struct *target,
211 const struct user_regset *regset,
212 unsigned int pos, unsigned int count,
213 void *kbuf, void __user *ubuf)
214{
215 int ret;
216
217 ret = init_fpu(target);
218 if (ret)
219 return ret;
220
221 return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
222 &target->thread.fpu.hard, 0, -1);
223}
224
225static int fpregs_set(struct task_struct *target,
226 const struct user_regset *regset,
227 unsigned int pos, unsigned int count,
228 const void *kbuf, const void __user *ubuf)
229{
230 int ret;
231
232 ret = init_fpu(target);
233 if (ret)
234 return ret;
235
236 set_stopped_child_used_math(target);
237
238 return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
239 &target->thread.fpu.hard, 0, -1);
240}
241
242static int fpregs_active(struct task_struct *target,
243 const struct user_regset *regset)
244{
245 return tsk_used_math(target) ? regset->n : 0;
246}
247#endif
248
249/*
250 * These are our native regset flavours.
251 */
252enum sh_regset {
253 REGSET_GENERAL,
254#ifdef CONFIG_SH_FPU
255 REGSET_FPU,
256#endif
257};
258
259static const struct user_regset sh_regsets[] = {
260 /*
261 * Format is:
262 * PC, SR, SYSCALL,
263 * R1 --> R63,
264 * TR0 --> TR7,
265 */
266 [REGSET_GENERAL] = {
267 .core_note_type = NT_PRSTATUS,
268 .n = ELF_NGREG,
269 .size = sizeof(long long),
270 .align = sizeof(long long),
271 .get = genregs_get,
272 .set = genregs_set,
273 },
274
275#ifdef CONFIG_SH_FPU
276 [REGSET_FPU] = {
277 .core_note_type = NT_PRFPREG,
278 .n = sizeof(struct user_fpu_struct) /
279 sizeof(long long),
280 .size = sizeof(long long),
281 .align = sizeof(long long),
282 .get = fpregs_get,
283 .set = fpregs_set,
284 .active = fpregs_active,
285 },
286#endif
287};
288
289static const struct user_regset_view user_sh64_native_view = {
290 .name = "sh64",
291 .e_machine = EM_SH,
292 .regsets = sh_regsets,
293 .n = ARRAY_SIZE(sh_regsets),
294};
295
296const struct user_regset_view *task_user_regset_view(struct task_struct *task)
297{
298 return &user_sh64_native_view;
299}
300
140long arch_ptrace(struct task_struct *child, long request, long addr, long data) 301long arch_ptrace(struct task_struct *child, long request, long addr, long data)
141{ 302{
142 int ret; 303 int ret;
@@ -195,10 +356,33 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
195 } 356 }
196 break; 357 break;
197 358
359 case PTRACE_GETREGS:
360 return copy_regset_to_user(child, &user_sh64_native_view,
361 REGSET_GENERAL,
362 0, sizeof(struct pt_regs),
363 (void __user *)data);
364 case PTRACE_SETREGS:
365 return copy_regset_from_user(child, &user_sh64_native_view,
366 REGSET_GENERAL,
367 0, sizeof(struct pt_regs),
368 (const void __user *)data);
369#ifdef CONFIG_SH_FPU
370 case PTRACE_GETFPREGS:
371 return copy_regset_to_user(child, &user_sh64_native_view,
372 REGSET_FPU,
373 0, sizeof(struct user_fpu_struct),
374 (void __user *)data);
375 case PTRACE_SETFPREGS:
376 return copy_regset_from_user(child, &user_sh64_native_view,
377 REGSET_FPU,
378 0, sizeof(struct user_fpu_struct),
379 (const void __user *)data);
380#endif
198 default: 381 default:
199 ret = ptrace_request(child, request, addr, data); 382 ret = ptrace_request(child, request, addr, data);
200 break; 383 break;
201 } 384 }
385
202 return ret; 386 return ret;
203} 387}
204 388
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index e7152cc6930e..534247508572 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -417,6 +417,7 @@ void __init setup_arch(char **cmdline_p)
417} 417}
418 418
419static const char *cpu_name[] = { 419static const char *cpu_name[] = {
420 [CPU_SH7201] = "SH7201",
420 [CPU_SH7203] = "SH7203", [CPU_SH7263] = "SH7263", 421 [CPU_SH7203] = "SH7203", [CPU_SH7263] = "SH7263",
421 [CPU_SH7206] = "SH7206", [CPU_SH7619] = "SH7619", 422 [CPU_SH7206] = "SH7206", [CPU_SH7619] = "SH7619",
422 [CPU_SH7705] = "SH7705", [CPU_SH7706] = "SH7706", 423 [CPU_SH7705] = "SH7705", [CPU_SH7706] = "SH7706",
diff --git a/arch/sh/kernel/sh_bios.c b/arch/sh/kernel/sh_bios.c
index d1bcac4fa269..c852f7805728 100644
--- a/arch/sh/kernel/sh_bios.c
+++ b/arch/sh/kernel/sh_bios.c
@@ -8,69 +8,50 @@
8#include <linux/module.h> 8#include <linux/module.h>
9#include <asm/sh_bios.h> 9#include <asm/sh_bios.h>
10 10
11#define BIOS_CALL_CONSOLE_WRITE 0 11#define BIOS_CALL_CONSOLE_WRITE 0
12#define BIOS_CALL_READ_BLOCK 1
13#define BIOS_CALL_ETH_NODE_ADDR 10 12#define BIOS_CALL_ETH_NODE_ADDR 10
14#define BIOS_CALL_SHUTDOWN 11 13#define BIOS_CALL_SHUTDOWN 11
15#define BIOS_CALL_CHAR_OUT 0x1f /* TODO: hack */ 14#define BIOS_CALL_CHAR_OUT 0x1f /* TODO: hack */
16#define BIOS_CALL_GDB_GET_MODE_PTR 0xfe 15#define BIOS_CALL_GDB_DETACH 0xff
17#define BIOS_CALL_GDB_DETACH 0xff
18 16
19static __inline__ long sh_bios_call(long func, long arg0, long arg1, long arg2, long arg3) 17static inline long sh_bios_call(long func, long arg0, long arg1, long arg2,
18 long arg3)
20{ 19{
21 register long r0 __asm__("r0") = func; 20 register long r0 __asm__("r0") = func;
22 register long r4 __asm__("r4") = arg0; 21 register long r4 __asm__("r4") = arg0;
23 register long r5 __asm__("r5") = arg1; 22 register long r5 __asm__("r5") = arg1;
24 register long r6 __asm__("r6") = arg2; 23 register long r6 __asm__("r6") = arg2;
25 register long r7 __asm__("r7") = arg3; 24 register long r7 __asm__("r7") = arg3;
26 __asm__ __volatile__("trapa #0x3f" 25
27 : "=z" (r0) 26 __asm__ __volatile__("trapa #0x3f":"=z"(r0)
28 : "0" (r0), "r" (r4), "r" (r5), "r" (r6), "r" (r7) 27 :"0"(r0), "r"(r4), "r"(r5), "r"(r6), "r"(r7)
29 : "memory"); 28 :"memory");
30 return r0; 29 return r0;
31} 30}
32 31
33
34void sh_bios_console_write(const char *buf, unsigned int len) 32void sh_bios_console_write(const char *buf, unsigned int len)
35{ 33{
36 sh_bios_call(BIOS_CALL_CONSOLE_WRITE, (long)buf, (long)len, 0, 0); 34 sh_bios_call(BIOS_CALL_CONSOLE_WRITE, (long)buf, (long)len, 0, 0);
37} 35}
38 36
39
40void sh_bios_char_out(char ch) 37void sh_bios_char_out(char ch)
41{ 38{
42 sh_bios_call(BIOS_CALL_CHAR_OUT, ch, 0, 0, 0); 39 sh_bios_call(BIOS_CALL_CHAR_OUT, ch, 0, 0, 0);
43}
44
45
46int sh_bios_in_gdb_mode(void)
47{
48 static char queried = 0;
49 static char *gdb_mode_p = 0;
50
51 if (!queried)
52 {
53 /* Query the gdb stub for address of its gdb mode variable */
54 long r = sh_bios_call(BIOS_CALL_GDB_GET_MODE_PTR, 0, 0, 0, 0);
55 if (r != ~0) /* BIOS returns -1 for unknown function */
56 gdb_mode_p = (char *)r;
57 queried = 1;
58 }
59 return (gdb_mode_p != 0 ? *gdb_mode_p : 0);
60} 40}
61 41
62void sh_bios_gdb_detach(void) 42void sh_bios_gdb_detach(void)
63{ 43{
64 sh_bios_call(BIOS_CALL_GDB_DETACH, 0, 0, 0, 0); 44 sh_bios_call(BIOS_CALL_GDB_DETACH, 0, 0, 0, 0);
65} 45}
66EXPORT_SYMBOL(sh_bios_gdb_detach); 46EXPORT_SYMBOL_GPL(sh_bios_gdb_detach);
67 47
68void sh_bios_get_node_addr (unsigned char *node_addr) 48void sh_bios_get_node_addr(unsigned char *node_addr)
69{ 49{
70 sh_bios_call(BIOS_CALL_ETH_NODE_ADDR, 0, (long)node_addr, 0, 0); 50 sh_bios_call(BIOS_CALL_ETH_NODE_ADDR, 0, (long)node_addr, 0, 0);
71} 51}
52EXPORT_SYMBOL_GPL(sh_bios_get_node_addr);
72 53
73void sh_bios_shutdown(unsigned int how) 54void sh_bios_shutdown(unsigned int how)
74{ 55{
75 sh_bios_call(BIOS_CALL_SHUTDOWN, how, 0, 0, 0); 56 sh_bios_call(BIOS_CALL_SHUTDOWN, how, 0, 0, 0);
76} 57}
diff --git a/arch/sh/kernel/sh_ksyms_32.c b/arch/sh/kernel/sh_ksyms_32.c
index 92ae5e6c099e..528de2955c81 100644
--- a/arch/sh/kernel/sh_ksyms_32.c
+++ b/arch/sh/kernel/sh_ksyms_32.c
@@ -52,16 +52,12 @@ EXPORT_SYMBOL(__const_udelay);
52 52
53#define DECLARE_EXPORT(name) \ 53#define DECLARE_EXPORT(name) \
54 extern void name(void);EXPORT_SYMBOL(name) 54 extern void name(void);EXPORT_SYMBOL(name)
55#define MAYBE_DECLARE_EXPORT(name) \
56 extern void name(void) __weak;EXPORT_SYMBOL(name)
57 55
58/* These symbols are generated by the compiler itself */
59DECLARE_EXPORT(__udivsi3); 56DECLARE_EXPORT(__udivsi3);
60DECLARE_EXPORT(__sdivsi3); 57DECLARE_EXPORT(__sdivsi3);
58DECLARE_EXPORT(__lshrsi3);
61DECLARE_EXPORT(__ashrsi3); 59DECLARE_EXPORT(__ashrsi3);
62DECLARE_EXPORT(__ashlsi3); 60DECLARE_EXPORT(__ashlsi3);
63DECLARE_EXPORT(__ashrdi3);
64DECLARE_EXPORT(__ashldi3);
65DECLARE_EXPORT(__ashiftrt_r4_6); 61DECLARE_EXPORT(__ashiftrt_r4_6);
66DECLARE_EXPORT(__ashiftrt_r4_7); 62DECLARE_EXPORT(__ashiftrt_r4_7);
67DECLARE_EXPORT(__ashiftrt_r4_8); 63DECLARE_EXPORT(__ashiftrt_r4_8);
@@ -79,8 +75,7 @@ DECLARE_EXPORT(__ashiftrt_r4_23);
79DECLARE_EXPORT(__ashiftrt_r4_24); 75DECLARE_EXPORT(__ashiftrt_r4_24);
80DECLARE_EXPORT(__ashiftrt_r4_27); 76DECLARE_EXPORT(__ashiftrt_r4_27);
81DECLARE_EXPORT(__ashiftrt_r4_30); 77DECLARE_EXPORT(__ashiftrt_r4_30);
82DECLARE_EXPORT(__lshrsi3); 78DECLARE_EXPORT(__movstr);
83DECLARE_EXPORT(__lshrdi3);
84DECLARE_EXPORT(__movstrSI8); 79DECLARE_EXPORT(__movstrSI8);
85DECLARE_EXPORT(__movstrSI12); 80DECLARE_EXPORT(__movstrSI12);
86DECLARE_EXPORT(__movstrSI16); 81DECLARE_EXPORT(__movstrSI16);
@@ -95,31 +90,17 @@ DECLARE_EXPORT(__movstrSI48);
95DECLARE_EXPORT(__movstrSI52); 90DECLARE_EXPORT(__movstrSI52);
96DECLARE_EXPORT(__movstrSI56); 91DECLARE_EXPORT(__movstrSI56);
97DECLARE_EXPORT(__movstrSI60); 92DECLARE_EXPORT(__movstrSI60);
98#if __GNUC__ == 4 93DECLARE_EXPORT(__movstr_i4_even);
99DECLARE_EXPORT(__movmem); 94DECLARE_EXPORT(__movstr_i4_odd);
100#else 95DECLARE_EXPORT(__movstrSI12_i4);
101DECLARE_EXPORT(__movstr);
102#endif
103
104#if __GNUC__ == 4
105DECLARE_EXPORT(__movmem_i4_even); 96DECLARE_EXPORT(__movmem_i4_even);
106DECLARE_EXPORT(__movmem_i4_odd); 97DECLARE_EXPORT(__movmem_i4_odd);
107DECLARE_EXPORT(__movmemSI12_i4); 98DECLARE_EXPORT(__movmemSI12_i4);
108
109#if (__GNUC_MINOR__ >= 2 || defined(__GNUC_STM_RELEASE__))
110/*
111 * GCC >= 4.2 emits these for division, as do GCC 4.1.x versions of the ST
112 * compiler which include backported patches.
113 */
114DECLARE_EXPORT(__udiv_qrnnd_16); 99DECLARE_EXPORT(__udiv_qrnnd_16);
115MAYBE_DECLARE_EXPORT(__sdivsi3_i4i); 100DECLARE_EXPORT(__sdivsi3_i4);
116MAYBE_DECLARE_EXPORT(__udivsi3_i4i); 101DECLARE_EXPORT(__udivsi3_i4);
117#endif 102DECLARE_EXPORT(__sdivsi3_i4i);
118#else /* GCC 3.x */ 103DECLARE_EXPORT(__udivsi3_i4i);
119DECLARE_EXPORT(__movstr_i4_even);
120DECLARE_EXPORT(__movstr_i4_odd);
121DECLARE_EXPORT(__movstrSI12_i4);
122#endif /* __GNUC__ == 4 */
123 104
124#if !defined(CONFIG_CACHE_OFF) && (defined(CONFIG_CPU_SH4) || \ 105#if !defined(CONFIG_CACHE_OFF) && (defined(CONFIG_CPU_SH4) || \
125 defined(CONFIG_SH7705_CACHE_32KB)) 106 defined(CONFIG_SH7705_CACHE_32KB))
diff --git a/arch/sh/kernel/sh_ksyms_64.c b/arch/sh/kernel/sh_ksyms_64.c
index 9324d32adacc..0d74d6b8774e 100644
--- a/arch/sh/kernel/sh_ksyms_64.c
+++ b/arch/sh/kernel/sh_ksyms_64.c
@@ -65,15 +65,16 @@ EXPORT_SYMBOL(copy_page);
65EXPORT_SYMBOL(__copy_user); 65EXPORT_SYMBOL(__copy_user);
66EXPORT_SYMBOL(empty_zero_page); 66EXPORT_SYMBOL(empty_zero_page);
67EXPORT_SYMBOL(memcpy); 67EXPORT_SYMBOL(memcpy);
68EXPORT_SYMBOL(memset);
68EXPORT_SYMBOL(__udelay); 69EXPORT_SYMBOL(__udelay);
69EXPORT_SYMBOL(__ndelay); 70EXPORT_SYMBOL(__ndelay);
70EXPORT_SYMBOL(__const_udelay); 71EXPORT_SYMBOL(__const_udelay);
72EXPORT_SYMBOL(strlen);
73EXPORT_SYMBOL(strcpy);
71 74
72/* Ugh. These come in from libgcc.a at link time. */ 75/* Ugh. These come in from libgcc.a at link time. */
73#define DECLARE_EXPORT(name) extern void name(void);EXPORT_SYMBOL(name) 76#define DECLARE_EXPORT(name) extern void name(void);EXPORT_SYMBOL(name)
74 77
75DECLARE_EXPORT(__sdivsi3); 78DECLARE_EXPORT(__sdivsi3);
76DECLARE_EXPORT(__sdivsi3_2);
77DECLARE_EXPORT(__muldi3);
78DECLARE_EXPORT(__udivsi3); 79DECLARE_EXPORT(__udivsi3);
79DECLARE_EXPORT(__div_table); 80DECLARE_EXPORT(__div_table);
diff --git a/arch/sh/kernel/signal_32.c b/arch/sh/kernel/signal_32.c
index 69d09c0b3498..77c21bde376a 100644
--- a/arch/sh/kernel/signal_32.c
+++ b/arch/sh/kernel/signal_32.c
@@ -533,7 +533,6 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
533{ 533{
534 int ret; 534 int ret;
535 535
536
537 /* Set up the stack frame */ 536 /* Set up the stack frame */
538 if (ka->sa.sa_flags & SA_SIGINFO) 537 if (ka->sa.sa_flags & SA_SIGINFO)
539 ret = setup_rt_frame(sig, ka, info, oldset, regs); 538 ret = setup_rt_frame(sig, ka, info, oldset, regs);
diff --git a/arch/sh/kernel/signal_64.c b/arch/sh/kernel/signal_64.c
index ce3e851dffcb..b22fdfaaa191 100644
--- a/arch/sh/kernel/signal_64.c
+++ b/arch/sh/kernel/signal_64.c
@@ -2,7 +2,7 @@
2 * arch/sh/kernel/signal_64.c 2 * arch/sh/kernel/signal_64.c
3 * 3 *
4 * Copyright (C) 2000, 2001 Paolo Alberelli 4 * Copyright (C) 2000, 2001 Paolo Alberelli
5 * Copyright (C) 2003 Paul Mundt 5 * Copyright (C) 2003 - 2008 Paul Mundt
6 * Copyright (C) 2004 Richard Curnow 6 * Copyright (C) 2004 Richard Curnow
7 * 7 *
8 * This file is subject to the terms and conditions of the GNU General Public 8 * This file is subject to the terms and conditions of the GNU General Public
@@ -43,10 +43,38 @@
43 43
44#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 44#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
45 45
46static void 46static int
47handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, 47handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
48 sigset_t *oldset, struct pt_regs * regs); 48 sigset_t *oldset, struct pt_regs * regs);
49 49
50static inline void
51handle_syscall_restart(struct pt_regs *regs, struct sigaction *sa)
52{
53 /* If we're not from a syscall, bail out */
54 if (regs->syscall_nr < 0)
55 return;
56
57 /* check for system call restart.. */
58 switch (regs->regs[REG_RET]) {
59 case -ERESTART_RESTARTBLOCK:
60 case -ERESTARTNOHAND:
61 no_system_call_restart:
62 regs->regs[REG_RET] = -EINTR;
63 regs->sr |= 1;
64 break;
65
66 case -ERESTARTSYS:
67 if (!(sa->sa_flags & SA_RESTART))
68 goto no_system_call_restart;
69 /* fallthrough */
70 case -ERESTARTNOINTR:
71 /* Decode syscall # */
72 regs->regs[REG_RET] = regs->syscall_nr;
73 regs->pc -= 4;
74 break;
75 }
76}
77
50/* 78/*
51 * Note that 'init' is a special process: it doesn't get signals it doesn't 79 * Note that 'init' is a special process: it doesn't get signals it doesn't
52 * want to handle. Thus you cannot kill init even with a SIGKILL even by 80 * want to handle. Thus you cannot kill init even with a SIGKILL even by
@@ -80,21 +108,23 @@ static int do_signal(struct pt_regs *regs, sigset_t *oldset)
80 oldset = &current->blocked; 108 oldset = &current->blocked;
81 109
82 signr = get_signal_to_deliver(&info, &ka, regs, 0); 110 signr = get_signal_to_deliver(&info, &ka, regs, 0);
83
84 if (signr > 0) { 111 if (signr > 0) {
85 /* Whee! Actually deliver the signal. */ 112 if (regs->sr & 1)
86 handle_signal(signr, &info, &ka, oldset, regs); 113 handle_syscall_restart(regs, &ka.sa);
87 114
88 /* 115 /* Whee! Actually deliver the signal. */
89 * If a signal was successfully delivered, the saved sigmask 116 if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
90 * is in its frame, and we can clear the TIF_RESTORE_SIGMASK 117 /*
91 * flag. 118 * If a signal was successfully delivered, the
92 */ 119 * saved sigmask is in its frame, and we can
93 if (test_thread_flag(TIF_RESTORE_SIGMASK)) 120 * clear the TIF_RESTORE_SIGMASK flag.
94 clear_thread_flag(TIF_RESTORE_SIGMASK); 121 */
95 122 if (test_thread_flag(TIF_RESTORE_SIGMASK))
96 tracehook_signal_handler(signr, &info, &ka, regs, 0); 123 clear_thread_flag(TIF_RESTORE_SIGMASK);
97 return 1; 124
125 tracehook_signal_handler(signr, &info, &ka, regs, 0);
126 return 1;
127 }
98 } 128 }
99 129
100no_signal: 130no_signal:
@@ -129,7 +159,6 @@ no_signal:
129/* 159/*
130 * Atomically swap in the new signal mask, and wait for a signal. 160 * Atomically swap in the new signal mask, and wait for a signal.
131 */ 161 */
132
133asmlinkage int 162asmlinkage int
134sys_sigsuspend(old_sigset_t mask, 163sys_sigsuspend(old_sigset_t mask,
135 unsigned long r3, unsigned long r4, unsigned long r5, 164 unsigned long r3, unsigned long r4, unsigned long r5,
@@ -235,20 +264,16 @@ sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
235 return do_sigaltstack(uss, uoss, REF_REG_SP); 264 return do_sigaltstack(uss, uoss, REF_REG_SP);
236} 265}
237 266
238
239/* 267/*
240 * Do a signal return; undo the signal stack. 268 * Do a signal return; undo the signal stack.
241 */ 269 */
242 270struct sigframe {
243struct sigframe
244{
245 struct sigcontext sc; 271 struct sigcontext sc;
246 unsigned long extramask[_NSIG_WORDS-1]; 272 unsigned long extramask[_NSIG_WORDS-1];
247 long long retcode[2]; 273 long long retcode[2];
248}; 274};
249 275
250struct rt_sigframe 276struct rt_sigframe {
251{
252 struct siginfo __user *pinfo; 277 struct siginfo __user *pinfo;
253 void *puc; 278 void *puc;
254 struct siginfo info; 279 struct siginfo info;
@@ -450,7 +475,6 @@ badframe:
450/* 475/*
451 * Set up a signal frame. 476 * Set up a signal frame.
452 */ 477 */
453
454static int 478static int
455setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, 479setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
456 unsigned long mask) 480 unsigned long mask)
@@ -504,8 +528,8 @@ get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
504void sa_default_restorer(void); /* See comments below */ 528void sa_default_restorer(void); /* See comments below */
505void sa_default_rt_restorer(void); /* See comments below */ 529void sa_default_rt_restorer(void); /* See comments below */
506 530
507static void setup_frame(int sig, struct k_sigaction *ka, 531static int setup_frame(int sig, struct k_sigaction *ka,
508 sigset_t *set, struct pt_regs *regs) 532 sigset_t *set, struct pt_regs *regs)
509{ 533{
510 struct sigframe __user *frame; 534 struct sigframe __user *frame;
511 int err = 0; 535 int err = 0;
@@ -596,23 +620,21 @@ static void setup_frame(int sig, struct k_sigaction *ka,
596 620
597 set_fs(USER_DS); 621 set_fs(USER_DS);
598 622
599#if DEBUG_SIG
600 /* Broken %016Lx */ 623 /* Broken %016Lx */
601 printk("SIG deliver (#%d,%s:%d): sp=%p pc=%08Lx%08Lx link=%08Lx%08Lx\n", 624 pr_debug("SIG deliver (#%d,%s:%d): sp=%p pc=%08Lx%08Lx link=%08Lx%08Lx\n",
602 signal, 625 signal, current->comm, current->pid, frame,
603 current->comm, current->pid, frame, 626 regs->pc >> 32, regs->pc & 0xffffffff,
604 regs->pc >> 32, regs->pc & 0xffffffff, 627 DEREF_REG_PR >> 32, DEREF_REG_PR & 0xffffffff);
605 DEREF_REG_PR >> 32, DEREF_REG_PR & 0xffffffff);
606#endif
607 628
608 return; 629 return 0;
609 630
610give_sigsegv: 631give_sigsegv:
611 force_sigsegv(sig, current); 632 force_sigsegv(sig, current);
633 return -EFAULT;
612} 634}
613 635
614static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 636static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
615 sigset_t *set, struct pt_regs *regs) 637 sigset_t *set, struct pt_regs *regs)
616{ 638{
617 struct rt_sigframe __user *frame; 639 struct rt_sigframe __user *frame;
618 int err = 0; 640 int err = 0;
@@ -702,62 +724,46 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
702 724
703 set_fs(USER_DS); 725 set_fs(USER_DS);
704 726
705#if DEBUG_SIG 727 pr_debug("SIG deliver (#%d,%s:%d): sp=%p pc=%08Lx%08Lx link=%08Lx%08Lx\n",
706 /* Broken %016Lx */ 728 signal, current->comm, current->pid, frame,
707 printk("SIG deliver (#%d,%s:%d): sp=%p pc=%08Lx%08Lx link=%08Lx%08Lx\n", 729 regs->pc >> 32, regs->pc & 0xffffffff,
708 signal, 730 DEREF_REG_PR >> 32, DEREF_REG_PR & 0xffffffff);
709 current->comm, current->pid, frame,
710 regs->pc >> 32, regs->pc & 0xffffffff,
711 DEREF_REG_PR >> 32, DEREF_REG_PR & 0xffffffff);
712#endif
713 731
714 return; 732 return 0;
715 733
716give_sigsegv: 734give_sigsegv:
717 force_sigsegv(sig, current); 735 force_sigsegv(sig, current);
736 return -EFAULT;
718} 737}
719 738
720/* 739/*
721 * OK, we're invoking a handler 740 * OK, we're invoking a handler
722 */ 741 */
723 742static int
724static void
725handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, 743handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
726 sigset_t *oldset, struct pt_regs * regs) 744 sigset_t *oldset, struct pt_regs * regs)
727{ 745{
728 /* Are we from a system call? */ 746 int ret;
729 if (regs->syscall_nr >= 0) {
730 /* If so, check system call restarting.. */
731 switch (regs->regs[REG_RET]) {
732 case -ERESTART_RESTARTBLOCK:
733 case -ERESTARTNOHAND:
734 no_system_call_restart:
735 regs->regs[REG_RET] = -EINTR;
736 break;
737
738 case -ERESTARTSYS:
739 if (!(ka->sa.sa_flags & SA_RESTART))
740 goto no_system_call_restart;
741 /* fallthrough */
742 case -ERESTARTNOINTR:
743 /* Decode syscall # */
744 regs->regs[REG_RET] = regs->syscall_nr;
745 regs->pc -= 4;
746 }
747 }
748 747
749 /* Set up the stack frame */ 748 /* Set up the stack frame */
750 if (ka->sa.sa_flags & SA_SIGINFO) 749 if (ka->sa.sa_flags & SA_SIGINFO)
751 setup_rt_frame(sig, ka, info, oldset, regs); 750 ret = setup_rt_frame(sig, ka, info, oldset, regs);
752 else 751 else
753 setup_frame(sig, ka, oldset, regs); 752 ret = setup_frame(sig, ka, oldset, regs);
753
754 if (ka->sa.sa_flags & SA_ONESHOT)
755 ka->sa.sa_handler = SIG_DFL;
756
757 if (ret == 0) {
758 spin_lock_irq(&current->sighand->siglock);
759 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
760 if (!(ka->sa.sa_flags & SA_NODEFER))
761 sigaddset(&current->blocked,sig);
762 recalc_sigpending();
763 spin_unlock_irq(&current->sighand->siglock);
764 }
754 765
755 spin_lock_irq(&current->sighand->siglock); 766 return ret;
756 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
757 if (!(ka->sa.sa_flags & SA_NODEFER))
758 sigaddset(&current->blocked,sig);
759 recalc_sigpending();
760 spin_unlock_irq(&current->sighand->siglock);
761} 767}
762 768
763asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags) 769asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags)
diff --git a/arch/sh/kernel/sys_sh.c b/arch/sh/kernel/sys_sh.c
index 38f098c9c72d..58dfc02c7af1 100644
--- a/arch/sh/kernel/sys_sh.c
+++ b/arch/sh/kernel/sys_sh.c
@@ -22,102 +22,10 @@
22#include <linux/module.h> 22#include <linux/module.h>
23#include <linux/fs.h> 23#include <linux/fs.h>
24#include <linux/ipc.h> 24#include <linux/ipc.h>
25#include <asm/cacheflush.h>
26#include <asm/syscalls.h> 25#include <asm/syscalls.h>
27#include <asm/uaccess.h> 26#include <asm/uaccess.h>
28#include <asm/unistd.h> 27#include <asm/unistd.h>
29 28
30unsigned long shm_align_mask = PAGE_SIZE - 1; /* Sane caches */
31EXPORT_SYMBOL(shm_align_mask);
32
33#ifdef CONFIG_MMU
34/*
35 * To avoid cache aliases, we map the shared page with same color.
36 */
37#define COLOUR_ALIGN(addr, pgoff) \
38 ((((addr) + shm_align_mask) & ~shm_align_mask) + \
39 (((pgoff) << PAGE_SHIFT) & shm_align_mask))
40
41unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
42 unsigned long len, unsigned long pgoff, unsigned long flags)
43{
44 struct mm_struct *mm = current->mm;
45 struct vm_area_struct *vma;
46 unsigned long start_addr;
47 int do_colour_align;
48
49 if (flags & MAP_FIXED) {
50 /* We do not accept a shared mapping if it would violate
51 * cache aliasing constraints.
52 */
53 if ((flags & MAP_SHARED) && (addr & shm_align_mask))
54 return -EINVAL;
55 return addr;
56 }
57
58 if (unlikely(len > TASK_SIZE))
59 return -ENOMEM;
60
61 do_colour_align = 0;
62 if (filp || (flags & MAP_SHARED))
63 do_colour_align = 1;
64
65 if (addr) {
66 if (do_colour_align)
67 addr = COLOUR_ALIGN(addr, pgoff);
68 else
69 addr = PAGE_ALIGN(addr);
70
71 vma = find_vma(mm, addr);
72 if (TASK_SIZE - len >= addr &&
73 (!vma || addr + len <= vma->vm_start))
74 return addr;
75 }
76
77 if (len > mm->cached_hole_size) {
78 start_addr = addr = mm->free_area_cache;
79 } else {
80 mm->cached_hole_size = 0;
81 start_addr = addr = TASK_UNMAPPED_BASE;
82 }
83
84full_search:
85 if (do_colour_align)
86 addr = COLOUR_ALIGN(addr, pgoff);
87 else
88 addr = PAGE_ALIGN(mm->free_area_cache);
89
90 for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
91 /* At this point: (!vma || addr < vma->vm_end). */
92 if (unlikely(TASK_SIZE - len < addr)) {
93 /*
94 * Start a new search - just in case we missed
95 * some holes.
96 */
97 if (start_addr != TASK_UNMAPPED_BASE) {
98 start_addr = addr = TASK_UNMAPPED_BASE;
99 mm->cached_hole_size = 0;
100 goto full_search;
101 }
102 return -ENOMEM;
103 }
104 if (likely(!vma || addr + len <= vma->vm_start)) {
105 /*
106 * Remember the place where we stopped the search:
107 */
108 mm->free_area_cache = addr + len;
109 return addr;
110 }
111 if (addr + mm->cached_hole_size < vma->vm_start)
112 mm->cached_hole_size = vma->vm_start - addr;
113
114 addr = vma->vm_end;
115 if (do_colour_align)
116 addr = COLOUR_ALIGN(addr, pgoff);
117 }
118}
119#endif /* CONFIG_MMU */
120
121static inline long 29static inline long
122do_mmap2(unsigned long addr, unsigned long len, unsigned long prot, 30do_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
123 unsigned long flags, int fd, unsigned long pgoff) 31 unsigned long flags, int fd, unsigned long pgoff)
diff --git a/arch/sh/kernel/time_32.c b/arch/sh/kernel/time_32.c
index 23ca711c27d2..8457f83242c5 100644
--- a/arch/sh/kernel/time_32.c
+++ b/arch/sh/kernel/time_32.c
@@ -125,11 +125,6 @@ void handle_timer_tick(void)
125 if (current->pid) 125 if (current->pid)
126 profile_tick(CPU_PROFILING); 126 profile_tick(CPU_PROFILING);
127 127
128#ifdef CONFIG_HEARTBEAT
129 if (sh_mv.mv_heartbeat != NULL)
130 sh_mv.mv_heartbeat();
131#endif
132
133 /* 128 /*
134 * Here we are in the timer irq handler. We just have irqs locally 129 * Here we are in the timer irq handler. We just have irqs locally
135 * disabled but we don't know if the timer_bh is running on the other 130 * disabled but we don't know if the timer_bh is running on the other
@@ -277,11 +272,4 @@ void __init time_init(void)
277 ((sh_hpt_frequency + 500) / 1000) / 1000, 272 ((sh_hpt_frequency + 500) / 1000) / 1000,
278 ((sh_hpt_frequency + 500) / 1000) % 1000); 273 ((sh_hpt_frequency + 500) / 1000) % 1000);
279 274
280#if defined(CONFIG_SH_KGDB)
281 /*
282 * Set up kgdb as requested. We do it here because the serial
283 * init uses the timer vars we just set up for figuring baud.
284 */
285 kgdb_init();
286#endif
287} 275}
diff --git a/arch/sh/kernel/time_64.c b/arch/sh/kernel/time_64.c
index bbb2af1004d9..59d2a03e8b3c 100644
--- a/arch/sh/kernel/time_64.c
+++ b/arch/sh/kernel/time_64.c
@@ -240,11 +240,6 @@ static inline void do_timer_interrupt(void)
240 240
241 do_timer(1); 241 do_timer(1);
242 242
243#ifdef CONFIG_HEARTBEAT
244 if (sh_mv.mv_heartbeat != NULL)
245 sh_mv.mv_heartbeat();
246#endif
247
248 /* 243 /*
249 * If we have an externally synchronized Linux clock, then update 244 * If we have an externally synchronized Linux clock, then update
250 * RTC clock accordingly every ~11 minutes. Set_rtc_mmss() has to be 245 * RTC clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
diff --git a/arch/sh/kernel/timers/timer-mtu2.c b/arch/sh/kernel/timers/timer-mtu2.c
index fe453c01f9c9..c3d237e1d566 100644
--- a/arch/sh/kernel/timers/timer-mtu2.c
+++ b/arch/sh/kernel/timers/timer-mtu2.c
@@ -34,7 +34,12 @@
34#define MTU2_TIER_1 0xfffe4384 34#define MTU2_TIER_1 0xfffe4384
35#define MTU2_TSR_1 0xfffe4385 35#define MTU2_TSR_1 0xfffe4385
36#define MTU2_TCNT_1 0xfffe4386 /* 16-bit counter */ 36#define MTU2_TCNT_1 0xfffe4386 /* 16-bit counter */
37
38#if defined(CONFIG_CPU_SUBTYPE_SH7201)
39#define MTU2_TGRA_1 0xfffe4388
40#else
37#define MTU2_TGRA_1 0xfffe438a 41#define MTU2_TGRA_1 0xfffe438a
42#endif
38 43
39#define STBCR3 0xfffe0408 44#define STBCR3 0xfffe0408
40 45
diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c
index 1e5c74efbacc..88807a2aacc3 100644
--- a/arch/sh/kernel/traps_32.c
+++ b/arch/sh/kernel/traps_32.c
@@ -28,17 +28,6 @@
28#include <asm/fpu.h> 28#include <asm/fpu.h>
29#include <asm/kprobes.h> 29#include <asm/kprobes.h>
30 30
31#ifdef CONFIG_SH_KGDB
32#include <asm/kgdb.h>
33#define CHK_REMOTE_DEBUG(regs) \
34{ \
35 if (kgdb_debug_hook && !user_mode(regs))\
36 (*kgdb_debug_hook)(regs); \
37}
38#else
39#define CHK_REMOTE_DEBUG(regs)
40#endif
41
42#ifdef CONFIG_CPU_SH2 31#ifdef CONFIG_CPU_SH2
43# define TRAP_RESERVED_INST 4 32# define TRAP_RESERVED_INST 4
44# define TRAP_ILLEGAL_SLOT_INST 6 33# define TRAP_ILLEGAL_SLOT_INST 6
@@ -94,7 +83,6 @@ void die(const char * str, struct pt_regs * regs, long err)
94 83
95 printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter); 84 printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
96 85
97 CHK_REMOTE_DEBUG(regs);
98 print_modules(); 86 print_modules();
99 show_regs(regs); 87 show_regs(regs);
100 88
@@ -683,13 +671,12 @@ asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5,
683 error_code = lookup_exception_vector(); 671 error_code = lookup_exception_vector();
684 672
685 local_irq_enable(); 673 local_irq_enable();
686 CHK_REMOTE_DEBUG(regs);
687 force_sig(SIGILL, tsk); 674 force_sig(SIGILL, tsk);
688 die_if_no_fixup("reserved instruction", regs, error_code); 675 die_if_no_fixup("reserved instruction", regs, error_code);
689} 676}
690 677
691#ifdef CONFIG_SH_FPU_EMU 678#ifdef CONFIG_SH_FPU_EMU
692static int emulate_branch(unsigned short inst, struct pt_regs* regs) 679static int emulate_branch(unsigned short inst, struct pt_regs *regs)
693{ 680{
694 /* 681 /*
695 * bfs: 8fxx: PC+=d*2+4; 682 * bfs: 8fxx: PC+=d*2+4;
@@ -702,27 +689,32 @@ static int emulate_branch(unsigned short inst, struct pt_regs* regs)
702 * jsr: 4x0b: PC=Rn after PR=PC+4; 689 * jsr: 4x0b: PC=Rn after PR=PC+4;
703 * rts: 000b: PC=PR; 690 * rts: 000b: PC=PR;
704 */ 691 */
705 if ((inst & 0xfd00) == 0x8d00) { 692 if (((inst & 0xf000) == 0xb000) || /* bsr */
693 ((inst & 0xf0ff) == 0x0003) || /* bsrf */
694 ((inst & 0xf0ff) == 0x400b)) /* jsr */
695 regs->pr = regs->pc + 4;
696
697 if ((inst & 0xfd00) == 0x8d00) { /* bfs, bts */
706 regs->pc += SH_PC_8BIT_OFFSET(inst); 698 regs->pc += SH_PC_8BIT_OFFSET(inst);
707 return 0; 699 return 0;
708 } 700 }
709 701
710 if ((inst & 0xe000) == 0xa000) { 702 if ((inst & 0xe000) == 0xa000) { /* bra, bsr */
711 regs->pc += SH_PC_12BIT_OFFSET(inst); 703 regs->pc += SH_PC_12BIT_OFFSET(inst);
712 return 0; 704 return 0;
713 } 705 }
714 706
715 if ((inst & 0xf0df) == 0x0003) { 707 if ((inst & 0xf0df) == 0x0003) { /* braf, bsrf */
716 regs->pc += regs->regs[(inst & 0x0f00) >> 8] + 4; 708 regs->pc += regs->regs[(inst & 0x0f00) >> 8] + 4;
717 return 0; 709 return 0;
718 } 710 }
719 711
720 if ((inst & 0xf0df) == 0x400b) { 712 if ((inst & 0xf0df) == 0x400b) { /* jmp, jsr */
721 regs->pc = regs->regs[(inst & 0x0f00) >> 8]; 713 regs->pc = regs->regs[(inst & 0x0f00) >> 8];
722 return 0; 714 return 0;
723 } 715 }
724 716
725 if ((inst & 0xffff) == 0x000b) { 717 if ((inst & 0xffff) == 0x000b) { /* rts */
726 regs->pc = regs->pr; 718 regs->pc = regs->pr;
727 return 0; 719 return 0;
728 } 720 }
@@ -756,7 +748,6 @@ asmlinkage void do_illegal_slot_inst(unsigned long r4, unsigned long r5,
756 inst = lookup_exception_vector(); 748 inst = lookup_exception_vector();
757 749
758 local_irq_enable(); 750 local_irq_enable();
759 CHK_REMOTE_DEBUG(regs);
760 force_sig(SIGILL, tsk); 751 force_sig(SIGILL, tsk);
761 die_if_no_fixup("illegal slot instruction", regs, inst); 752 die_if_no_fixup("illegal slot instruction", regs, inst);
762} 753}
@@ -868,10 +859,7 @@ void show_trace(struct task_struct *tsk, unsigned long *sp,
868 if (regs && user_mode(regs)) 859 if (regs && user_mode(regs))
869 return; 860 return;
870 861
871 printk("\nCall trace: "); 862 printk("\nCall trace:\n");
872#ifdef CONFIG_KALLSYMS
873 printk("\n");
874#endif
875 863
876 while (!kstack_end(sp)) { 864 while (!kstack_end(sp)) {
877 addr = *sp++; 865 addr = *sp++;
diff --git a/arch/sh/lib/Makefile b/arch/sh/lib/Makefile
index 8596cc78e18d..aaea580b65bb 100644
--- a/arch/sh/lib/Makefile
+++ b/arch/sh/lib/Makefile
@@ -5,12 +5,26 @@
5lib-y = delay.o memset.o memmove.o memchr.o \ 5lib-y = delay.o memset.o memmove.o memchr.o \
6 checksum.o strlen.o div64.o div64-generic.o 6 checksum.o strlen.o div64.o div64-generic.o
7 7
8# Extracted from libgcc
9lib-y += movmem.o ashldi3.o ashrdi3.o lshrdi3.o \
10 ashlsi3.o ashrsi3.o ashiftrt.o lshrsi3.o \
11 udiv_qrnnd.o
12
13udivsi3-y := udivsi3_i4i-Os.o
14
15ifneq ($(CONFIG_CC_OPTIMIZE_FOR_SIZE),y)
16udivsi3-$(CONFIG_CPU_SH3) := udivsi3_i4i.o
17udivsi3-$(CONFIG_CPU_SH4) := udivsi3_i4i.o
18endif
19udivsi3-y += udivsi3.o
20
8obj-y += io.o 21obj-y += io.o
9 22
10memcpy-y := memcpy.o 23memcpy-y := memcpy.o
11memcpy-$(CONFIG_CPU_SH4) := memcpy-sh4.o 24memcpy-$(CONFIG_CPU_SH4) := memcpy-sh4.o
12 25
13lib-$(CONFIG_MMU) += copy_page.o clear_page.o 26lib-$(CONFIG_MMU) += copy_page.o clear_page.o
14lib-y += $(memcpy-y) 27lib-$(CONFIG_FUNCTION_TRACER) += mcount.o
28lib-y += $(memcpy-y) $(udivsi3-y)
15 29
16EXTRA_CFLAGS += -Werror 30EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/lib/ashiftrt.S b/arch/sh/lib/ashiftrt.S
new file mode 100644
index 000000000000..45ce86558f46
--- /dev/null
+++ b/arch/sh/lib/ashiftrt.S
@@ -0,0 +1,149 @@
1/* Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
2 2004, 2005, 2006
3 Free Software Foundation, Inc.
4
5This file is free software; you can redistribute it and/or modify it
6under the terms of the GNU General Public License as published by the
7Free Software Foundation; either version 2, or (at your option) any
8later version.
9
10In addition to the permissions in the GNU General Public License, the
11Free Software Foundation gives you unlimited permission to link the
12compiled version of this file into combinations with other programs,
13and to distribute those combinations without any restriction coming
14from the use of this file. (The General Public License restrictions
15do apply in other respects; for example, they cover modification of
16the file, and distribution when not linked into a combine
17executable.)
18
19This file is distributed in the hope that it will be useful, but
20WITHOUT ANY WARRANTY; without even the implied warranty of
21MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22General Public License for more details.
23
24You should have received a copy of the GNU General Public License
25along with this program; see the file COPYING. If not, write to
26the Free Software Foundation, 51 Franklin Street, Fifth Floor,
27Boston, MA 02110-1301, USA. */
28
29!! libgcc routines for the Renesas / SuperH SH CPUs.
30!! Contributed by Steve Chamberlain.
31!! sac@cygnus.com
32
33!! ashiftrt_r4_x, ___ashrsi3, ___ashlsi3, ___lshrsi3 routines
34!! recoded in assembly by Toshiyasu Morita
35!! tm@netcom.com
36
37/* SH2 optimizations for ___ashrsi3, ___ashlsi3, ___lshrsi3 and
38 ELF local label prefixes by J"orn Rennecke
39 amylaar@cygnus.com */
40
41 .global __ashiftrt_r4_0
42 .global __ashiftrt_r4_1
43 .global __ashiftrt_r4_2
44 .global __ashiftrt_r4_3
45 .global __ashiftrt_r4_4
46 .global __ashiftrt_r4_5
47 .global __ashiftrt_r4_6
48 .global __ashiftrt_r4_7
49 .global __ashiftrt_r4_8
50 .global __ashiftrt_r4_9
51 .global __ashiftrt_r4_10
52 .global __ashiftrt_r4_11
53 .global __ashiftrt_r4_12
54 .global __ashiftrt_r4_13
55 .global __ashiftrt_r4_14
56 .global __ashiftrt_r4_15
57 .global __ashiftrt_r4_16
58 .global __ashiftrt_r4_17
59 .global __ashiftrt_r4_18
60 .global __ashiftrt_r4_19
61 .global __ashiftrt_r4_20
62 .global __ashiftrt_r4_21
63 .global __ashiftrt_r4_22
64 .global __ashiftrt_r4_23
65 .global __ashiftrt_r4_24
66 .global __ashiftrt_r4_25
67 .global __ashiftrt_r4_26
68 .global __ashiftrt_r4_27
69 .global __ashiftrt_r4_28
70 .global __ashiftrt_r4_29
71 .global __ashiftrt_r4_30
72 .global __ashiftrt_r4_31
73 .global __ashiftrt_r4_32
74
75 .align 1
76__ashiftrt_r4_32:
77__ashiftrt_r4_31:
78 rotcl r4
79 rts
80 subc r4,r4
81__ashiftrt_r4_30:
82 shar r4
83__ashiftrt_r4_29:
84 shar r4
85__ashiftrt_r4_28:
86 shar r4
87__ashiftrt_r4_27:
88 shar r4
89__ashiftrt_r4_26:
90 shar r4
91__ashiftrt_r4_25:
92 shar r4
93__ashiftrt_r4_24:
94 shlr16 r4
95 shlr8 r4
96 rts
97 exts.b r4,r4
98__ashiftrt_r4_23:
99 shar r4
100__ashiftrt_r4_22:
101 shar r4
102__ashiftrt_r4_21:
103 shar r4
104__ashiftrt_r4_20:
105 shar r4
106__ashiftrt_r4_19:
107 shar r4
108__ashiftrt_r4_18:
109 shar r4
110__ashiftrt_r4_17:
111 shar r4
112__ashiftrt_r4_16:
113 shlr16 r4
114 rts
115 exts.w r4,r4
116__ashiftrt_r4_15:
117 shar r4
118__ashiftrt_r4_14:
119 shar r4
120__ashiftrt_r4_13:
121 shar r4
122__ashiftrt_r4_12:
123 shar r4
124__ashiftrt_r4_11:
125 shar r4
126__ashiftrt_r4_10:
127 shar r4
128__ashiftrt_r4_9:
129 shar r4
130__ashiftrt_r4_8:
131 shar r4
132__ashiftrt_r4_7:
133 shar r4
134__ashiftrt_r4_6:
135 shar r4
136__ashiftrt_r4_5:
137 shar r4
138__ashiftrt_r4_4:
139 shar r4
140__ashiftrt_r4_3:
141 shar r4
142__ashiftrt_r4_2:
143 shar r4
144__ashiftrt_r4_1:
145 rts
146 shar r4
147__ashiftrt_r4_0:
148 rts
149 nop
diff --git a/arch/sh/lib/ashldi3.c b/arch/sh/lib/ashldi3.c
new file mode 100644
index 000000000000..beb80f316095
--- /dev/null
+++ b/arch/sh/lib/ashldi3.c
@@ -0,0 +1,29 @@
1#include <linux/module.h>
2
3#include "libgcc.h"
4
5long long __ashldi3(long long u, word_type b)
6{
7 DWunion uu, w;
8 word_type bm;
9
10 if (b == 0)
11 return u;
12
13 uu.ll = u;
14 bm = 32 - b;
15
16 if (bm <= 0) {
17 w.s.low = 0;
18 w.s.high = (unsigned int) uu.s.low << -bm;
19 } else {
20 const unsigned int carries = (unsigned int) uu.s.low >> bm;
21
22 w.s.low = (unsigned int) uu.s.low << b;
23 w.s.high = ((unsigned int) uu.s.high << b) | carries;
24 }
25
26 return w.ll;
27}
28
29EXPORT_SYMBOL(__ashldi3);
diff --git a/arch/sh/lib/ashlsi3.S b/arch/sh/lib/ashlsi3.S
new file mode 100644
index 000000000000..bd47e9b403a5
--- /dev/null
+++ b/arch/sh/lib/ashlsi3.S
@@ -0,0 +1,193 @@
1/* Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
2 2004, 2005, 2006
3 Free Software Foundation, Inc.
4
5This file is free software; you can redistribute it and/or modify it
6under the terms of the GNU General Public License as published by the
7Free Software Foundation; either version 2, or (at your option) any
8later version.
9
10In addition to the permissions in the GNU General Public License, the
11Free Software Foundation gives you unlimited permission to link the
12compiled version of this file into combinations with other programs,
13and to distribute those combinations without any restriction coming
14from the use of this file. (The General Public License restrictions
15do apply in other respects; for example, they cover modification of
16the file, and distribution when not linked into a combine
17executable.)
18
19This file is distributed in the hope that it will be useful, but
20WITHOUT ANY WARRANTY; without even the implied warranty of
21MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22General Public License for more details.
23
24You should have received a copy of the GNU General Public License
25along with this program; see the file COPYING. If not, write to
26the Free Software Foundation, 51 Franklin Street, Fifth Floor,
27Boston, MA 02110-1301, USA. */
28
29!! libgcc routines for the Renesas / SuperH SH CPUs.
30!! Contributed by Steve Chamberlain.
31!! sac@cygnus.com
32
33!! ashiftrt_r4_x, ___ashrsi3, ___ashlsi3, ___lshrsi3 routines
34!! recoded in assembly by Toshiyasu Morita
35!! tm@netcom.com
36
37/* SH2 optimizations for ___ashrsi3, ___ashlsi3, ___lshrsi3 and
38 ELF local label prefixes by J"orn Rennecke
39 amylaar@cygnus.com */
40
41!
42! __ashlsi3
43!
44! Entry:
45!
46! r4: Value to shift
47! r5: Shifts
48!
49! Exit:
50!
51! r0: Result
52!
53! Destroys:
54!
55! (none)
56!
57 .global __ashlsi3
58
59 .align 2
60__ashlsi3:
61 mov #31,r0
62 and r0,r5
63 mova ashlsi3_table,r0
64 mov.b @(r0,r5),r5
65#ifdef __sh1__
66 add r5,r0
67 jmp @r0
68#else
69 braf r5
70#endif
71 mov r4,r0
72
73 .align 2
74ashlsi3_table:
75 .byte ashlsi3_0-ashlsi3_table
76 .byte ashlsi3_1-ashlsi3_table
77 .byte ashlsi3_2-ashlsi3_table
78 .byte ashlsi3_3-ashlsi3_table
79 .byte ashlsi3_4-ashlsi3_table
80 .byte ashlsi3_5-ashlsi3_table
81 .byte ashlsi3_6-ashlsi3_table
82 .byte ashlsi3_7-ashlsi3_table
83 .byte ashlsi3_8-ashlsi3_table
84 .byte ashlsi3_9-ashlsi3_table
85 .byte ashlsi3_10-ashlsi3_table
86 .byte ashlsi3_11-ashlsi3_table
87 .byte ashlsi3_12-ashlsi3_table
88 .byte ashlsi3_13-ashlsi3_table
89 .byte ashlsi3_14-ashlsi3_table
90 .byte ashlsi3_15-ashlsi3_table
91 .byte ashlsi3_16-ashlsi3_table
92 .byte ashlsi3_17-ashlsi3_table
93 .byte ashlsi3_18-ashlsi3_table
94 .byte ashlsi3_19-ashlsi3_table
95 .byte ashlsi3_20-ashlsi3_table
96 .byte ashlsi3_21-ashlsi3_table
97 .byte ashlsi3_22-ashlsi3_table
98 .byte ashlsi3_23-ashlsi3_table
99 .byte ashlsi3_24-ashlsi3_table
100 .byte ashlsi3_25-ashlsi3_table
101 .byte ashlsi3_26-ashlsi3_table
102 .byte ashlsi3_27-ashlsi3_table
103 .byte ashlsi3_28-ashlsi3_table
104 .byte ashlsi3_29-ashlsi3_table
105 .byte ashlsi3_30-ashlsi3_table
106 .byte ashlsi3_31-ashlsi3_table
107
108ashlsi3_6:
109 shll2 r0
110ashlsi3_4:
111 shll2 r0
112ashlsi3_2:
113 rts
114 shll2 r0
115
116ashlsi3_7:
117 shll2 r0
118ashlsi3_5:
119 shll2 r0
120ashlsi3_3:
121 shll2 r0
122ashlsi3_1:
123 rts
124 shll r0
125
126ashlsi3_14:
127 shll2 r0
128ashlsi3_12:
129 shll2 r0
130ashlsi3_10:
131 shll2 r0
132ashlsi3_8:
133 rts
134 shll8 r0
135
136ashlsi3_15:
137 shll2 r0
138ashlsi3_13:
139 shll2 r0
140ashlsi3_11:
141 shll2 r0
142ashlsi3_9:
143 shll8 r0
144 rts
145 shll r0
146
147ashlsi3_22:
148 shll2 r0
149ashlsi3_20:
150 shll2 r0
151ashlsi3_18:
152 shll2 r0
153ashlsi3_16:
154 rts
155 shll16 r0
156
157ashlsi3_23:
158 shll2 r0
159ashlsi3_21:
160 shll2 r0
161ashlsi3_19:
162 shll2 r0
163ashlsi3_17:
164 shll16 r0
165 rts
166 shll r0
167
168ashlsi3_30:
169 shll2 r0
170ashlsi3_28:
171 shll2 r0
172ashlsi3_26:
173 shll2 r0
174ashlsi3_24:
175 shll16 r0
176 rts
177 shll8 r0
178
179ashlsi3_31:
180 shll2 r0
181ashlsi3_29:
182 shll2 r0
183ashlsi3_27:
184 shll2 r0
185ashlsi3_25:
186 shll16 r0
187 shll8 r0
188 rts
189 shll r0
190
191ashlsi3_0:
192 rts
193 nop
diff --git a/arch/sh/lib/ashrdi3.c b/arch/sh/lib/ashrdi3.c
new file mode 100644
index 000000000000..c884a912b660
--- /dev/null
+++ b/arch/sh/lib/ashrdi3.c
@@ -0,0 +1,31 @@
1#include <linux/module.h>
2
3#include "libgcc.h"
4
5long long __ashrdi3(long long u, word_type b)
6{
7 DWunion uu, w;
8 word_type bm;
9
10 if (b == 0)
11 return u;
12
13 uu.ll = u;
14 bm = 32 - b;
15
16 if (bm <= 0) {
17 /* w.s.high = 1..1 or 0..0 */
18 w.s.high =
19 uu.s.high >> 31;
20 w.s.low = uu.s.high >> -bm;
21 } else {
22 const unsigned int carries = (unsigned int) uu.s.high << bm;
23
24 w.s.high = uu.s.high >> b;
25 w.s.low = ((unsigned int) uu.s.low >> b) | carries;
26 }
27
28 return w.ll;
29}
30
31EXPORT_SYMBOL(__ashrdi3);
diff --git a/arch/sh/lib/ashrsi3.S b/arch/sh/lib/ashrsi3.S
new file mode 100644
index 000000000000..6f3cf46b77c2
--- /dev/null
+++ b/arch/sh/lib/ashrsi3.S
@@ -0,0 +1,185 @@
1/* Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
2 2004, 2005, 2006
3 Free Software Foundation, Inc.
4
5This file is free software; you can redistribute it and/or modify it
6under the terms of the GNU General Public License as published by the
7Free Software Foundation; either version 2, or (at your option) any
8later version.
9
10In addition to the permissions in the GNU General Public License, the
11Free Software Foundation gives you unlimited permission to link the
12compiled version of this file into combinations with other programs,
13and to distribute those combinations without any restriction coming
14from the use of this file. (The General Public License restrictions
15do apply in other respects; for example, they cover modification of
16the file, and distribution when not linked into a combine
17executable.)
18
19This file is distributed in the hope that it will be useful, but
20WITHOUT ANY WARRANTY; without even the implied warranty of
21MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22General Public License for more details.
23
24You should have received a copy of the GNU General Public License
25along with this program; see the file COPYING. If not, write to
26the Free Software Foundation, 51 Franklin Street, Fifth Floor,
27Boston, MA 02110-1301, USA. */
28
29!! libgcc routines for the Renesas / SuperH SH CPUs.
30!! Contributed by Steve Chamberlain.
31!! sac@cygnus.com
32
33!! ashiftrt_r4_x, ___ashrsi3, ___ashlsi3, ___lshrsi3 routines
34!! recoded in assembly by Toshiyasu Morita
35!! tm@netcom.com
36
37/* SH2 optimizations for ___ashrsi3, ___ashlsi3, ___lshrsi3 and
38 ELF local label prefixes by J"orn Rennecke
39 amylaar@cygnus.com */
40
41!
42! __ashrsi3
43!
44! Entry:
45!
46! r4: Value to shift
47! r5: Shifts
48!
49! Exit:
50!
51! r0: Result
52!
53! Destroys:
54!
55! (none)
56!
57
58 .global __ashrsi3
59
60 .align 2
61__ashrsi3:
62 mov #31,r0
63 and r0,r5
64 mova ashrsi3_table,r0
65 mov.b @(r0,r5),r5
66#ifdef __sh1__
67 add r5,r0
68 jmp @r0
69#else
70 braf r5
71#endif
72 mov r4,r0
73
74 .align 2
75ashrsi3_table:
76 .byte ashrsi3_0-ashrsi3_table
77 .byte ashrsi3_1-ashrsi3_table
78 .byte ashrsi3_2-ashrsi3_table
79 .byte ashrsi3_3-ashrsi3_table
80 .byte ashrsi3_4-ashrsi3_table
81 .byte ashrsi3_5-ashrsi3_table
82 .byte ashrsi3_6-ashrsi3_table
83 .byte ashrsi3_7-ashrsi3_table
84 .byte ashrsi3_8-ashrsi3_table
85 .byte ashrsi3_9-ashrsi3_table
86 .byte ashrsi3_10-ashrsi3_table
87 .byte ashrsi3_11-ashrsi3_table
88 .byte ashrsi3_12-ashrsi3_table
89 .byte ashrsi3_13-ashrsi3_table
90 .byte ashrsi3_14-ashrsi3_table
91 .byte ashrsi3_15-ashrsi3_table
92 .byte ashrsi3_16-ashrsi3_table
93 .byte ashrsi3_17-ashrsi3_table
94 .byte ashrsi3_18-ashrsi3_table
95 .byte ashrsi3_19-ashrsi3_table
96 .byte ashrsi3_20-ashrsi3_table
97 .byte ashrsi3_21-ashrsi3_table
98 .byte ashrsi3_22-ashrsi3_table
99 .byte ashrsi3_23-ashrsi3_table
100 .byte ashrsi3_24-ashrsi3_table
101 .byte ashrsi3_25-ashrsi3_table
102 .byte ashrsi3_26-ashrsi3_table
103 .byte ashrsi3_27-ashrsi3_table
104 .byte ashrsi3_28-ashrsi3_table
105 .byte ashrsi3_29-ashrsi3_table
106 .byte ashrsi3_30-ashrsi3_table
107 .byte ashrsi3_31-ashrsi3_table
108
109ashrsi3_31:
110 rotcl r0
111 rts
112 subc r0,r0
113
114ashrsi3_30:
115 shar r0
116ashrsi3_29:
117 shar r0
118ashrsi3_28:
119 shar r0
120ashrsi3_27:
121 shar r0
122ashrsi3_26:
123 shar r0
124ashrsi3_25:
125 shar r0
126ashrsi3_24:
127 shlr16 r0
128 shlr8 r0
129 rts
130 exts.b r0,r0
131
132ashrsi3_23:
133 shar r0
134ashrsi3_22:
135 shar r0
136ashrsi3_21:
137 shar r0
138ashrsi3_20:
139 shar r0
140ashrsi3_19:
141 shar r0
142ashrsi3_18:
143 shar r0
144ashrsi3_17:
145 shar r0
146ashrsi3_16:
147 shlr16 r0
148 rts
149 exts.w r0,r0
150
151ashrsi3_15:
152 shar r0
153ashrsi3_14:
154 shar r0
155ashrsi3_13:
156 shar r0
157ashrsi3_12:
158 shar r0
159ashrsi3_11:
160 shar r0
161ashrsi3_10:
162 shar r0
163ashrsi3_9:
164 shar r0
165ashrsi3_8:
166 shar r0
167ashrsi3_7:
168 shar r0
169ashrsi3_6:
170 shar r0
171ashrsi3_5:
172 shar r0
173ashrsi3_4:
174 shar r0
175ashrsi3_3:
176 shar r0
177ashrsi3_2:
178 shar r0
179ashrsi3_1:
180 rts
181 shar r0
182
183ashrsi3_0:
184 rts
185 nop
diff --git a/arch/sh/lib/libgcc.h b/arch/sh/lib/libgcc.h
new file mode 100644
index 000000000000..3f19d1c5d942
--- /dev/null
+++ b/arch/sh/lib/libgcc.h
@@ -0,0 +1,26 @@
1#ifndef __ASM_LIBGCC_H
2#define __ASM_LIBGCC_H
3
4#include <asm/byteorder.h>
5
6typedef int word_type __attribute__ ((mode (__word__)));
7
8#ifdef __BIG_ENDIAN
9struct DWstruct {
10 int high, low;
11};
12#elif defined(__LITTLE_ENDIAN)
13struct DWstruct {
14 int low, high;
15};
16#else
17#error I feel sick.
18#endif
19
20typedef union
21{
22 struct DWstruct s;
23 long long ll;
24} DWunion;
25
26#endif /* __ASM_LIBGCC_H */
diff --git a/arch/sh/lib/lshrdi3.c b/arch/sh/lib/lshrdi3.c
new file mode 100644
index 000000000000..dcf8d6810b7c
--- /dev/null
+++ b/arch/sh/lib/lshrdi3.c
@@ -0,0 +1,29 @@
1#include <linux/module.h>
2
3#include "libgcc.h"
4
5long long __lshrdi3(long long u, word_type b)
6{
7 DWunion uu, w;
8 word_type bm;
9
10 if (b == 0)
11 return u;
12
13 uu.ll = u;
14 bm = 32 - b;
15
16 if (bm <= 0) {
17 w.s.high = 0;
18 w.s.low = (unsigned int) uu.s.high >> -bm;
19 } else {
20 const unsigned int carries = (unsigned int) uu.s.high << bm;
21
22 w.s.high = (unsigned int) uu.s.high >> b;
23 w.s.low = ((unsigned int) uu.s.low >> b) | carries;
24 }
25
26 return w.ll;
27}
28
29EXPORT_SYMBOL(__lshrdi3);
diff --git a/arch/sh/lib/lshrsi3.S b/arch/sh/lib/lshrsi3.S
new file mode 100644
index 000000000000..1e7aaa557130
--- /dev/null
+++ b/arch/sh/lib/lshrsi3.S
@@ -0,0 +1,193 @@
1/* Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
2 2004, 2005, 2006
3 Free Software Foundation, Inc.
4
5This file is free software; you can redistribute it and/or modify it
6under the terms of the GNU General Public License as published by the
7Free Software Foundation; either version 2, or (at your option) any
8later version.
9
10In addition to the permissions in the GNU General Public License, the
11Free Software Foundation gives you unlimited permission to link the
12compiled version of this file into combinations with other programs,
13and to distribute those combinations without any restriction coming
14from the use of this file. (The General Public License restrictions
15do apply in other respects; for example, they cover modification of
16the file, and distribution when not linked into a combine
17executable.)
18
19This file is distributed in the hope that it will be useful, but
20WITHOUT ANY WARRANTY; without even the implied warranty of
21MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22General Public License for more details.
23
24You should have received a copy of the GNU General Public License
25along with this program; see the file COPYING. If not, write to
26the Free Software Foundation, 51 Franklin Street, Fifth Floor,
27Boston, MA 02110-1301, USA. */
28
29!! libgcc routines for the Renesas / SuperH SH CPUs.
30!! Contributed by Steve Chamberlain.
31!! sac@cygnus.com
32
33!! ashiftrt_r4_x, ___ashrsi3, ___ashlsi3, ___lshrsi3 routines
34!! recoded in assembly by Toshiyasu Morita
35!! tm@netcom.com
36
37/* SH2 optimizations for ___ashrsi3, ___ashlsi3, ___lshrsi3 and
38 ELF local label prefixes by J"orn Rennecke
39 amylaar@cygnus.com */
40
41!
42! __lshrsi3
43!
44! Entry:
45!
46! r4: Value to shift
47! r5: Shifts
48!
49! Exit:
50!
51! r0: Result
52!
53! Destroys:
54!
55! (none)
56!
57 .global __lshrsi3
58
59 .align 2
60__lshrsi3:
61 mov #31,r0
62 and r0,r5
63 mova lshrsi3_table,r0
64 mov.b @(r0,r5),r5
65#ifdef __sh1__
66 add r5,r0
67 jmp @r0
68#else
69 braf r5
70#endif
71 mov r4,r0
72
73 .align 2
74lshrsi3_table:
75 .byte lshrsi3_0-lshrsi3_table
76 .byte lshrsi3_1-lshrsi3_table
77 .byte lshrsi3_2-lshrsi3_table
78 .byte lshrsi3_3-lshrsi3_table
79 .byte lshrsi3_4-lshrsi3_table
80 .byte lshrsi3_5-lshrsi3_table
81 .byte lshrsi3_6-lshrsi3_table
82 .byte lshrsi3_7-lshrsi3_table
83 .byte lshrsi3_8-lshrsi3_table
84 .byte lshrsi3_9-lshrsi3_table
85 .byte lshrsi3_10-lshrsi3_table
86 .byte lshrsi3_11-lshrsi3_table
87 .byte lshrsi3_12-lshrsi3_table
88 .byte lshrsi3_13-lshrsi3_table
89 .byte lshrsi3_14-lshrsi3_table
90 .byte lshrsi3_15-lshrsi3_table
91 .byte lshrsi3_16-lshrsi3_table
92 .byte lshrsi3_17-lshrsi3_table
93 .byte lshrsi3_18-lshrsi3_table
94 .byte lshrsi3_19-lshrsi3_table
95 .byte lshrsi3_20-lshrsi3_table
96 .byte lshrsi3_21-lshrsi3_table
97 .byte lshrsi3_22-lshrsi3_table
98 .byte lshrsi3_23-lshrsi3_table
99 .byte lshrsi3_24-lshrsi3_table
100 .byte lshrsi3_25-lshrsi3_table
101 .byte lshrsi3_26-lshrsi3_table
102 .byte lshrsi3_27-lshrsi3_table
103 .byte lshrsi3_28-lshrsi3_table
104 .byte lshrsi3_29-lshrsi3_table
105 .byte lshrsi3_30-lshrsi3_table
106 .byte lshrsi3_31-lshrsi3_table
107
108lshrsi3_6:
109 shlr2 r0
110lshrsi3_4:
111 shlr2 r0
112lshrsi3_2:
113 rts
114 shlr2 r0
115
116lshrsi3_7:
117 shlr2 r0
118lshrsi3_5:
119 shlr2 r0
120lshrsi3_3:
121 shlr2 r0
122lshrsi3_1:
123 rts
124 shlr r0
125
126lshrsi3_14:
127 shlr2 r0
128lshrsi3_12:
129 shlr2 r0
130lshrsi3_10:
131 shlr2 r0
132lshrsi3_8:
133 rts
134 shlr8 r0
135
136lshrsi3_15:
137 shlr2 r0
138lshrsi3_13:
139 shlr2 r0
140lshrsi3_11:
141 shlr2 r0
142lshrsi3_9:
143 shlr8 r0
144 rts
145 shlr r0
146
147lshrsi3_22:
148 shlr2 r0
149lshrsi3_20:
150 shlr2 r0
151lshrsi3_18:
152 shlr2 r0
153lshrsi3_16:
154 rts
155 shlr16 r0
156
157lshrsi3_23:
158 shlr2 r0
159lshrsi3_21:
160 shlr2 r0
161lshrsi3_19:
162 shlr2 r0
163lshrsi3_17:
164 shlr16 r0
165 rts
166 shlr r0
167
168lshrsi3_30:
169 shlr2 r0
170lshrsi3_28:
171 shlr2 r0
172lshrsi3_26:
173 shlr2 r0
174lshrsi3_24:
175 shlr16 r0
176 rts
177 shlr8 r0
178
179lshrsi3_31:
180 shlr2 r0
181lshrsi3_29:
182 shlr2 r0
183lshrsi3_27:
184 shlr2 r0
185lshrsi3_25:
186 shlr16 r0
187 shlr8 r0
188 rts
189 shlr r0
190
191lshrsi3_0:
192 rts
193 nop
diff --git a/arch/sh/lib/mcount.S b/arch/sh/lib/mcount.S
new file mode 100644
index 000000000000..110fbfe1831f
--- /dev/null
+++ b/arch/sh/lib/mcount.S
@@ -0,0 +1,90 @@
1/*
2 * arch/sh/lib/mcount.S
3 *
4 * Copyright (C) 2008 Paul Mundt
5 * Copyright (C) 2008 Matt Fleming
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details.
10 */
11#include <asm/ftrace.h>
12
13#define MCOUNT_ENTER() \
14 mov.l r4, @-r15; \
15 mov.l r5, @-r15; \
16 mov.l r6, @-r15; \
17 mov.l r7, @-r15; \
18 sts.l pr, @-r15; \
19 \
20 mov.l @(20,r15),r4; \
21 sts pr, r5
22
23#define MCOUNT_LEAVE() \
24 lds.l @r15+, pr; \
25 mov.l @r15+, r7; \
26 mov.l @r15+, r6; \
27 mov.l @r15+, r5; \
28 rts; \
29 mov.l @r15+, r4
30
31 .align 2
32 .globl _mcount
33 .type _mcount,@function
34 .globl mcount
35 .type mcount,@function
36_mcount:
37mcount:
38 MCOUNT_ENTER()
39
40#ifdef CONFIG_DYNAMIC_FTRACE
41 .globl mcount_call
42mcount_call:
43 mov.l .Lftrace_stub, r6
44#else
45 mov.l .Lftrace_trace_function, r6
46 mov.l ftrace_stub, r7
47 cmp/eq r6, r7
48 bt skip_trace
49 mov.l @r6, r6
50#endif
51
52 jsr @r6
53 nop
54
55skip_trace:
56 MCOUNT_LEAVE()
57
58 .align 2
59.Lftrace_trace_function:
60 .long ftrace_trace_function
61
62#ifdef CONFIG_DYNAMIC_FTRACE
63 .globl ftrace_caller
64ftrace_caller:
65 MCOUNT_ENTER()
66
67 .globl ftrace_call
68ftrace_call:
69 mov.l .Lftrace_stub, r6
70 jsr @r6
71 nop
72
73 MCOUNT_LEAVE()
74#endif /* CONFIG_DYNAMIC_FTRACE */
75
76/*
77 * NOTE: From here on the locations of the .Lftrace_stub label and
78 * ftrace_stub itself are fixed. Adding additional data here will skew
79 * the displacement for the memory table and break the block replacement.
80 * Place new labels either after the ftrace_stub body, or before
81 * ftrace_caller. You have been warned.
82 */
83 .align 2
84.Lftrace_stub:
85 .long ftrace_stub
86
87 .globl ftrace_stub
88ftrace_stub:
89 rts
90 nop
diff --git a/arch/sh/lib/movmem.S b/arch/sh/lib/movmem.S
new file mode 100644
index 000000000000..62075f6bc67c
--- /dev/null
+++ b/arch/sh/lib/movmem.S
@@ -0,0 +1,238 @@
1/* Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
2 2004, 2005, 2006
3 Free Software Foundation, Inc.
4
5This file is free software; you can redistribute it and/or modify it
6under the terms of the GNU General Public License as published by the
7Free Software Foundation; either version 2, or (at your option) any
8later version.
9
10In addition to the permissions in the GNU General Public License, the
11Free Software Foundation gives you unlimited permission to link the
12compiled version of this file into combinations with other programs,
13and to distribute those combinations without any restriction coming
14from the use of this file. (The General Public License restrictions
15do apply in other respects; for example, they cover modification of
16the file, and distribution when not linked into a combine
17executable.)
18
19This file is distributed in the hope that it will be useful, but
20WITHOUT ANY WARRANTY; without even the implied warranty of
21MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22General Public License for more details.
23
24You should have received a copy of the GNU General Public License
25along with this program; see the file COPYING. If not, write to
26the Free Software Foundation, 51 Franklin Street, Fifth Floor,
27Boston, MA 02110-1301, USA. */
28
29!! libgcc routines for the Renesas / SuperH SH CPUs.
30!! Contributed by Steve Chamberlain.
31!! sac@cygnus.com
32
33!! ashiftrt_r4_x, ___ashrsi3, ___ashlsi3, ___lshrsi3 routines
34!! recoded in assembly by Toshiyasu Morita
35!! tm@netcom.com
36
37/* SH2 optimizations for ___ashrsi3, ___ashlsi3, ___lshrsi3 and
38 ELF local label prefixes by J"orn Rennecke
39 amylaar@cygnus.com */
40
41 .text
42 .balign 4
43 .global __movmem
44 .global __movstr
45 .set __movstr, __movmem
46 /* This would be a lot simpler if r6 contained the byte count
47 minus 64, and we wouldn't be called here for a byte count of 64. */
48__movmem:
49 sts.l pr,@-r15
50 shll2 r6
51 bsr __movmemSI52+2
52 mov.l @(48,r5),r0
53 .balign 4
54movmem_loop: /* Reached with rts */
55 mov.l @(60,r5),r0
56 add #-64,r6
57 mov.l r0,@(60,r4)
58 tst r6,r6
59 mov.l @(56,r5),r0
60 bt movmem_done
61 mov.l r0,@(56,r4)
62 cmp/pl r6
63 mov.l @(52,r5),r0
64 add #64,r5
65 mov.l r0,@(52,r4)
66 add #64,r4
67 bt __movmemSI52
68! done all the large groups, do the remainder
69! jump to movmem+
70 mova __movmemSI4+4,r0
71 add r6,r0
72 jmp @r0
73movmem_done: ! share slot insn, works out aligned.
74 lds.l @r15+,pr
75 mov.l r0,@(56,r4)
76 mov.l @(52,r5),r0
77 rts
78 mov.l r0,@(52,r4)
79 .balign 4
80
81 .global __movmemSI64
82 .global __movstrSI64
83 .set __movstrSI64, __movmemSI64
84__movmemSI64:
85 mov.l @(60,r5),r0
86 mov.l r0,@(60,r4)
87 .global __movmemSI60
88 .global __movstrSI60
89 .set __movstrSI60, __movmemSI60
90__movmemSI60:
91 mov.l @(56,r5),r0
92 mov.l r0,@(56,r4)
93 .global __movmemSI56
94 .global __movstrSI56
95 .set __movstrSI56, __movmemSI56
96__movmemSI56:
97 mov.l @(52,r5),r0
98 mov.l r0,@(52,r4)
99 .global __movmemSI52
100 .global __movstrSI52
101 .set __movstrSI52, __movmemSI52
102__movmemSI52:
103 mov.l @(48,r5),r0
104 mov.l r0,@(48,r4)
105 .global __movmemSI48
106 .global __movstrSI48
107 .set __movstrSI48, __movmemSI48
108__movmemSI48:
109 mov.l @(44,r5),r0
110 mov.l r0,@(44,r4)
111 .global __movmemSI44
112 .global __movstrSI44
113 .set __movstrSI44, __movmemSI44
114__movmemSI44:
115 mov.l @(40,r5),r0
116 mov.l r0,@(40,r4)
117 .global __movmemSI40
118 .global __movstrSI40
119 .set __movstrSI40, __movmemSI40
120__movmemSI40:
121 mov.l @(36,r5),r0
122 mov.l r0,@(36,r4)
123 .global __movmemSI36
124 .global __movstrSI36
125 .set __movstrSI36, __movmemSI36
126__movmemSI36:
127 mov.l @(32,r5),r0
128 mov.l r0,@(32,r4)
129 .global __movmemSI32
130 .global __movstrSI32
131 .set __movstrSI32, __movmemSI32
132__movmemSI32:
133 mov.l @(28,r5),r0
134 mov.l r0,@(28,r4)
135 .global __movmemSI28
136 .global __movstrSI28
137 .set __movstrSI28, __movmemSI28
138__movmemSI28:
139 mov.l @(24,r5),r0
140 mov.l r0,@(24,r4)
141 .global __movmemSI24
142 .global __movstrSI24
143 .set __movstrSI24, __movmemSI24
144__movmemSI24:
145 mov.l @(20,r5),r0
146 mov.l r0,@(20,r4)
147 .global __movmemSI20
148 .global __movstrSI20
149 .set __movstrSI20, __movmemSI20
150__movmemSI20:
151 mov.l @(16,r5),r0
152 mov.l r0,@(16,r4)
153 .global __movmemSI16
154 .global __movstrSI16
155 .set __movstrSI16, __movmemSI16
156__movmemSI16:
157 mov.l @(12,r5),r0
158 mov.l r0,@(12,r4)
159 .global __movmemSI12
160 .global __movstrSI12
161 .set __movstrSI12, __movmemSI12
162__movmemSI12:
163 mov.l @(8,r5),r0
164 mov.l r0,@(8,r4)
165 .global __movmemSI8
166 .global __movstrSI8
167 .set __movstrSI8, __movmemSI8
168__movmemSI8:
169 mov.l @(4,r5),r0
170 mov.l r0,@(4,r4)
171 .global __movmemSI4
172 .global __movstrSI4
173 .set __movstrSI4, __movmemSI4
174__movmemSI4:
175 mov.l @(0,r5),r0
176 rts
177 mov.l r0,@(0,r4)
178
179 .global __movmem_i4_even
180 .global __movstr_i4_even
181 .set __movstr_i4_even, __movmem_i4_even
182
183 .global __movmem_i4_odd
184 .global __movstr_i4_odd
185 .set __movstr_i4_odd, __movmem_i4_odd
186
187 .global __movmemSI12_i4
188 .global __movstrSI12_i4
189 .set __movstrSI12_i4, __movmemSI12_i4
190
191 .p2align 5
192L_movmem_2mod4_end:
193 mov.l r0,@(16,r4)
194 rts
195 mov.l r1,@(20,r4)
196
197 .p2align 2
198
199__movmem_i4_even:
200 mov.l @r5+,r0
201 bra L_movmem_start_even
202 mov.l @r5+,r1
203
204__movmem_i4_odd:
205 mov.l @r5+,r1
206 add #-4,r4
207 mov.l @r5+,r2
208 mov.l @r5+,r3
209 mov.l r1,@(4,r4)
210 mov.l r2,@(8,r4)
211
212L_movmem_loop:
213 mov.l r3,@(12,r4)
214 dt r6
215 mov.l @r5+,r0
216 bt/s L_movmem_2mod4_end
217 mov.l @r5+,r1
218 add #16,r4
219L_movmem_start_even:
220 mov.l @r5+,r2
221 mov.l @r5+,r3
222 mov.l r0,@r4
223 dt r6
224 mov.l r1,@(4,r4)
225 bf/s L_movmem_loop
226 mov.l r2,@(8,r4)
227 rts
228 mov.l r3,@(12,r4)
229
230 .p2align 4
231__movmemSI12_i4:
232 mov.l @r5,r0
233 mov.l @(4,r5),r1
234 mov.l @(8,r5),r2
235 mov.l r0,@r4
236 mov.l r1,@(4,r4)
237 rts
238 mov.l r2,@(8,r4)
diff --git a/arch/sh/lib/udiv_qrnnd.S b/arch/sh/lib/udiv_qrnnd.S
new file mode 100644
index 000000000000..32b9a36de943
--- /dev/null
+++ b/arch/sh/lib/udiv_qrnnd.S
@@ -0,0 +1,81 @@
1/* Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
2 2004, 2005, 2006
3 Free Software Foundation, Inc.
4
5This file is free software; you can redistribute it and/or modify it
6under the terms of the GNU General Public License as published by the
7Free Software Foundation; either version 2, or (at your option) any
8later version.
9
10In addition to the permissions in the GNU General Public License, the
11Free Software Foundation gives you unlimited permission to link the
12compiled version of this file into combinations with other programs,
13and to distribute those combinations without any restriction coming
14from the use of this file. (The General Public License restrictions
15do apply in other respects; for example, they cover modification of
16the file, and distribution when not linked into a combine
17executable.)
18
19This file is distributed in the hope that it will be useful, but
20WITHOUT ANY WARRANTY; without even the implied warranty of
21MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22General Public License for more details.
23
24You should have received a copy of the GNU General Public License
25along with this program; see the file COPYING. If not, write to
26the Free Software Foundation, 51 Franklin Street, Fifth Floor,
27Boston, MA 02110-1301, USA. */
28
29!! libgcc routines for the Renesas / SuperH SH CPUs.
30!! Contributed by Steve Chamberlain.
31!! sac@cygnus.com
32
33!! ashiftrt_r4_x, ___ashrsi3, ___ashlsi3, ___lshrsi3 routines
34!! recoded in assembly by Toshiyasu Morita
35!! tm@netcom.com
36
37/* SH2 optimizations for ___ashrsi3, ___ashlsi3, ___lshrsi3 and
38 ELF local label prefixes by J"orn Rennecke
39 amylaar@cygnus.com */
40
41 /* r0: rn r1: qn */ /* r0: n1 r4: n0 r5: d r6: d1 */ /* r2: __m */
42 /* n1 < d, but n1 might be larger than d1. */
43 .global __udiv_qrnnd_16
44 .balign 8
45__udiv_qrnnd_16:
46 div0u
47 cmp/hi r6,r0
48 bt .Lots
49 .rept 16
50 div1 r6,r0
51 .endr
52 extu.w r0,r1
53 bt 0f
54 add r6,r0
550: rotcl r1
56 mulu.w r1,r5
57 xtrct r4,r0
58 swap.w r0,r0
59 sts macl,r2
60 cmp/hs r2,r0
61 sub r2,r0
62 bt 0f
63 addc r5,r0
64 add #-1,r1
65 bt 0f
661: add #-1,r1
67 rts
68 add r5,r0
69 .balign 8
70.Lots:
71 sub r5,r0
72 swap.w r4,r1
73 xtrct r0,r1
74 clrt
75 mov r1,r0
76 addc r5,r0
77 mov #-1,r1
78 bf/s 1b
79 shlr16 r1
800: rts
81 nop
diff --git a/arch/sh/lib/udivsi3.S b/arch/sh/lib/udivsi3.S
new file mode 100644
index 000000000000..72157ab5c314
--- /dev/null
+++ b/arch/sh/lib/udivsi3.S
@@ -0,0 +1,87 @@
1/* Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
2 2004, 2005
3 Free Software Foundation, Inc.
4
5This file is free software; you can redistribute it and/or modify it
6under the terms of the GNU General Public License as published by the
7Free Software Foundation; either version 2, or (at your option) any
8later version.
9
10In addition to the permissions in the GNU General Public License, the
11Free Software Foundation gives you unlimited permission to link the
12compiled version of this file into combinations with other programs,
13and to distribute those combinations without any restriction coming
14from the use of this file. (The General Public License restrictions
15do apply in other respects; for example, they cover modification of
16the file, and distribution when not linked into a combine
17executable.)
18
19This file is distributed in the hope that it will be useful, but
20WITHOUT ANY WARRANTY; without even the implied warranty of
21MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22General Public License for more details.
23
24You should have received a copy of the GNU General Public License
25along with this program; see the file COPYING. If not, write to
26the Free Software Foundation, 51 Franklin Street, Fifth Floor,
27Boston, MA 02110-1301, USA. */
28
29!! libgcc routines for the Renesas / SuperH SH CPUs.
30!! Contributed by Steve Chamberlain.
31!! sac@cygnus.com
32
33 .balign 4
34 .global __udivsi3
35 .type __udivsi3, @function
36div8:
37 div1 r5,r4
38div7:
39 div1 r5,r4; div1 r5,r4; div1 r5,r4
40 div1 r5,r4; div1 r5,r4; div1 r5,r4; rts; div1 r5,r4
41
42divx4:
43 div1 r5,r4; rotcl r0
44 div1 r5,r4; rotcl r0
45 div1 r5,r4; rotcl r0
46 rts; div1 r5,r4
47
48__udivsi3:
49 sts.l pr,@-r15
50 extu.w r5,r0
51 cmp/eq r5,r0
52 bf/s large_divisor
53 div0u
54 swap.w r4,r0
55 shlr16 r4
56 bsr div8
57 shll16 r5
58 bsr div7
59 div1 r5,r4
60 xtrct r4,r0
61 xtrct r0,r4
62 bsr div8
63 swap.w r4,r4
64 bsr div7
65 div1 r5,r4
66 lds.l @r15+,pr
67 xtrct r4,r0
68 swap.w r0,r0
69 rotcl r0
70 rts
71 shlr16 r5
72
73large_divisor:
74 mov #0,r0
75 xtrct r4,r0
76 xtrct r0,r4
77 bsr divx4
78 rotcl r0
79 bsr divx4
80 rotcl r0
81 bsr divx4
82 rotcl r0
83 bsr divx4
84 rotcl r0
85 lds.l @r15+,pr
86 rts
87 rotcl r0
diff --git a/arch/sh/lib/udivsi3_i4i-Os.S b/arch/sh/lib/udivsi3_i4i-Os.S
new file mode 100644
index 000000000000..4835553e1ea9
--- /dev/null
+++ b/arch/sh/lib/udivsi3_i4i-Os.S
@@ -0,0 +1,149 @@
1/* Copyright (C) 2006 Free Software Foundation, Inc.
2
3This file is free software; you can redistribute it and/or modify it
4under the terms of the GNU General Public License as published by the
5Free Software Foundation; either version 2, or (at your option) any
6later version.
7
8In addition to the permissions in the GNU General Public License, the
9Free Software Foundation gives you unlimited permission to link the
10compiled version of this file into combinations with other programs,
11and to distribute those combinations without any restriction coming
12from the use of this file. (The General Public License restrictions
13do apply in other respects; for example, they cover modification of
14the file, and distribution when not linked into a combine
15executable.)
16
17This file is distributed in the hope that it will be useful, but
18WITHOUT ANY WARRANTY; without even the implied warranty of
19MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20General Public License for more details.
21
22You should have received a copy of the GNU General Public License
23along with this program; see the file COPYING. If not, write to
24the Free Software Foundation, 51 Franklin Street, Fifth Floor,
25Boston, MA 02110-1301, USA. */
26
27/* Moderately Space-optimized libgcc routines for the Renesas SH /
28 STMicroelectronics ST40 CPUs.
29 Contributed by J"orn Rennecke joern.rennecke@st.com. */
30
31/* Size: 186 bytes jointly for udivsi3_i4i and sdivsi3_i4i
32 sh4-200 run times:
33 udiv small divisor: 55 cycles
34 udiv large divisor: 52 cycles
35 sdiv small divisor, positive result: 59 cycles
36 sdiv large divisor, positive result: 56 cycles
37 sdiv small divisor, negative result: 65 cycles (*)
38 sdiv large divisor, negative result: 62 cycles (*)
39 (*): r2 is restored in the rts delay slot and has a lingering latency
40 of two more cycles. */
41 .balign 4
42 .global __udivsi3_i4i
43 .global __udivsi3_i4
44 .set __udivsi3_i4, __udivsi3_i4i
45 .type __udivsi3_i4i, @function
46 .type __sdivsi3_i4i, @function
47__udivsi3_i4i:
48 sts pr,r1
49 mov.l r4,@-r15
50 extu.w r5,r0
51 cmp/eq r5,r0
52 swap.w r4,r0
53 shlr16 r4
54 bf/s large_divisor
55 div0u
56 mov.l r5,@-r15
57 shll16 r5
58sdiv_small_divisor:
59 div1 r5,r4
60 bsr div6
61 div1 r5,r4
62 div1 r5,r4
63 bsr div6
64 div1 r5,r4
65 xtrct r4,r0
66 xtrct r0,r4
67 bsr div7
68 swap.w r4,r4
69 div1 r5,r4
70 bsr div7
71 div1 r5,r4
72 xtrct r4,r0
73 mov.l @r15+,r5
74 swap.w r0,r0
75 mov.l @r15+,r4
76 jmp @r1
77 rotcl r0
78div7:
79 div1 r5,r4
80div6:
81 div1 r5,r4; div1 r5,r4; div1 r5,r4
82 div1 r5,r4; div1 r5,r4; rts; div1 r5,r4
83
84divx3:
85 rotcl r0
86 div1 r5,r4
87 rotcl r0
88 div1 r5,r4
89 rotcl r0
90 rts
91 div1 r5,r4
92
93large_divisor:
94 mov.l r5,@-r15
95sdiv_large_divisor:
96 xor r4,r0
97 .rept 4
98 rotcl r0
99 bsr divx3
100 div1 r5,r4
101 .endr
102 mov.l @r15+,r5
103 mov.l @r15+,r4
104 jmp @r1
105 rotcl r0
106
107 .global __sdivsi3_i4i
108 .global __sdivsi3_i4
109 .global __sdivsi3
110 .set __sdivsi3_i4, __sdivsi3_i4i
111 .set __sdivsi3, __sdivsi3_i4i
112__sdivsi3_i4i:
113 mov.l r4,@-r15
114 cmp/pz r5
115 mov.l r5,@-r15
116 bt/s pos_divisor
117 cmp/pz r4
118 neg r5,r5
119 extu.w r5,r0
120 bt/s neg_result
121 cmp/eq r5,r0
122 neg r4,r4
123pos_result:
124 swap.w r4,r0
125 bra sdiv_check_divisor
126 sts pr,r1
127pos_divisor:
128 extu.w r5,r0
129 bt/s pos_result
130 cmp/eq r5,r0
131 neg r4,r4
132neg_result:
133 mova negate_result,r0
134 ;
135 mov r0,r1
136 swap.w r4,r0
137 lds r2,macl
138 sts pr,r2
139sdiv_check_divisor:
140 shlr16 r4
141 bf/s sdiv_large_divisor
142 div0u
143 bra sdiv_small_divisor
144 shll16 r5
145 .balign 4
146negate_result:
147 neg r0,r0
148 jmp @r2
149 sts macl,r2
diff --git a/arch/sh/lib/udivsi3_i4i.S b/arch/sh/lib/udivsi3_i4i.S
new file mode 100644
index 000000000000..f1a79d9c5015
--- /dev/null
+++ b/arch/sh/lib/udivsi3_i4i.S
@@ -0,0 +1,666 @@
1/* Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
2 2004, 2005, 2006
3 Free Software Foundation, Inc.
4
5This file is free software; you can redistribute it and/or modify it
6under the terms of the GNU General Public License as published by the
7Free Software Foundation; either version 2, or (at your option) any
8later version.
9
10In addition to the permissions in the GNU General Public License, the
11Free Software Foundation gives you unlimited permission to link the
12compiled version of this file into combinations with other programs,
13and to distribute those combinations without any restriction coming
14from the use of this file. (The General Public License restrictions
15do apply in other respects; for example, they cover modification of
16the file, and distribution when not linked into a combine
17executable.)
18
19This file is distributed in the hope that it will be useful, but
20WITHOUT ANY WARRANTY; without even the implied warranty of
21MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22General Public License for more details.
23
24You should have received a copy of the GNU General Public License
25along with this program; see the file COPYING. If not, write to
26the Free Software Foundation, 51 Franklin Street, Fifth Floor,
27Boston, MA 02110-1301, USA. */
28
29!! libgcc routines for the Renesas / SuperH SH CPUs.
30!! Contributed by Steve Chamberlain.
31!! sac@cygnus.com
32
33!! ashiftrt_r4_x, ___ashrsi3, ___ashlsi3, ___lshrsi3 routines
34!! recoded in assembly by Toshiyasu Morita
35!! tm@netcom.com
36
37/* SH2 optimizations for ___ashrsi3, ___ashlsi3, ___lshrsi3 and
38 ELF local label prefixes by J"orn Rennecke
39 amylaar@cygnus.com */
40
41/* This code used shld, thus is not suitable for SH1 / SH2. */
42
43/* Signed / unsigned division without use of FPU, optimized for SH4.
44 Uses a lookup table for divisors in the range -128 .. +128, and
45 div1 with case distinction for larger divisors in three more ranges.
46 The code is lumped together with the table to allow the use of mova. */
47#ifdef CONFIG_CPU_LITTLE_ENDIAN
48#define L_LSB 0
49#define L_LSWMSB 1
50#define L_MSWLSB 2
51#else
52#define L_LSB 3
53#define L_LSWMSB 2
54#define L_MSWLSB 1
55#endif
56
57 .balign 4
58 .global __udivsi3_i4i
59 .global __udivsi3_i4
60 .set __udivsi3_i4, __udivsi3_i4i
61 .type __udivsi3_i4i, @function
62__udivsi3_i4i:
63 mov.w c128_w, r1
64 div0u
65 mov r4,r0
66 shlr8 r0
67 cmp/hi r1,r5
68 extu.w r5,r1
69 bf udiv_le128
70 cmp/eq r5,r1
71 bf udiv_ge64k
72 shlr r0
73 mov r5,r1
74 shll16 r5
75 mov.l r4,@-r15
76 div1 r5,r0
77 mov.l r1,@-r15
78 div1 r5,r0
79 div1 r5,r0
80 bra udiv_25
81 div1 r5,r0
82
83div_le128:
84 mova div_table_ix,r0
85 bra div_le128_2
86 mov.b @(r0,r5),r1
87udiv_le128:
88 mov.l r4,@-r15
89 mova div_table_ix,r0
90 mov.b @(r0,r5),r1
91 mov.l r5,@-r15
92div_le128_2:
93 mova div_table_inv,r0
94 mov.l @(r0,r1),r1
95 mov r5,r0
96 tst #0xfe,r0
97 mova div_table_clz,r0
98 dmulu.l r1,r4
99 mov.b @(r0,r5),r1
100 bt/s div_by_1
101 mov r4,r0
102 mov.l @r15+,r5
103 sts mach,r0
104 /* clrt */
105 addc r4,r0
106 mov.l @r15+,r4
107 rotcr r0
108 rts
109 shld r1,r0
110
111div_by_1_neg:
112 neg r4,r0
113div_by_1:
114 mov.l @r15+,r5
115 rts
116 mov.l @r15+,r4
117
118div_ge64k:
119 bt/s div_r8
120 div0u
121 shll8 r5
122 bra div_ge64k_2
123 div1 r5,r0
124udiv_ge64k:
125 cmp/hi r0,r5
126 mov r5,r1
127 bt udiv_r8
128 shll8 r5
129 mov.l r4,@-r15
130 div1 r5,r0
131 mov.l r1,@-r15
132div_ge64k_2:
133 div1 r5,r0
134 mov.l zero_l,r1
135 .rept 4
136 div1 r5,r0
137 .endr
138 mov.l r1,@-r15
139 div1 r5,r0
140 mov.w m256_w,r1
141 div1 r5,r0
142 mov.b r0,@(L_LSWMSB,r15)
143 xor r4,r0
144 and r1,r0
145 bra div_ge64k_end
146 xor r4,r0
147
148div_r8:
149 shll16 r4
150 bra div_r8_2
151 shll8 r4
152udiv_r8:
153 mov.l r4,@-r15
154 shll16 r4
155 clrt
156 shll8 r4
157 mov.l r5,@-r15
158div_r8_2:
159 rotcl r4
160 mov r0,r1
161 div1 r5,r1
162 mov r4,r0
163 rotcl r0
164 mov r5,r4
165 div1 r5,r1
166 .rept 5
167 rotcl r0; div1 r5,r1
168 .endr
169 rotcl r0
170 mov.l @r15+,r5
171 div1 r4,r1
172 mov.l @r15+,r4
173 rts
174 rotcl r0
175
176 .global __sdivsi3_i4i
177 .global __sdivsi3_i4
178 .global __sdivsi3
179 .set __sdivsi3_i4, __sdivsi3_i4i
180 .set __sdivsi3, __sdivsi3_i4i
181 .type __sdivsi3_i4i, @function
182 /* This is link-compatible with a __sdivsi3 call,
183 but we effectively clobber only r1. */
184__sdivsi3_i4i:
185 mov.l r4,@-r15
186 cmp/pz r5
187 mov.w c128_w, r1
188 bt/s pos_divisor
189 cmp/pz r4
190 mov.l r5,@-r15
191 neg r5,r5
192 bt/s neg_result
193 cmp/hi r1,r5
194 neg r4,r4
195pos_result:
196 extu.w r5,r0
197 bf div_le128
198 cmp/eq r5,r0
199 mov r4,r0
200 shlr8 r0
201 bf/s div_ge64k
202 cmp/hi r0,r5
203 div0u
204 shll16 r5
205 div1 r5,r0
206 div1 r5,r0
207 div1 r5,r0
208udiv_25:
209 mov.l zero_l,r1
210 div1 r5,r0
211 div1 r5,r0
212 mov.l r1,@-r15
213 .rept 3
214 div1 r5,r0
215 .endr
216 mov.b r0,@(L_MSWLSB,r15)
217 xtrct r4,r0
218 swap.w r0,r0
219 .rept 8
220 div1 r5,r0
221 .endr
222 mov.b r0,@(L_LSWMSB,r15)
223div_ge64k_end:
224 .rept 8
225 div1 r5,r0
226 .endr
227 mov.l @r15+,r4 ! zero-extension and swap using LS unit.
228 extu.b r0,r0
229 mov.l @r15+,r5
230 or r4,r0
231 mov.l @r15+,r4
232 rts
233 rotcl r0
234
235div_le128_neg:
236 tst #0xfe,r0
237 mova div_table_ix,r0
238 mov.b @(r0,r5),r1
239 mova div_table_inv,r0
240 bt/s div_by_1_neg
241 mov.l @(r0,r1),r1
242 mova div_table_clz,r0
243 dmulu.l r1,r4
244 mov.b @(r0,r5),r1
245 mov.l @r15+,r5
246 sts mach,r0
247 /* clrt */
248 addc r4,r0
249 mov.l @r15+,r4
250 rotcr r0
251 shld r1,r0
252 rts
253 neg r0,r0
254
255pos_divisor:
256 mov.l r5,@-r15
257 bt/s pos_result
258 cmp/hi r1,r5
259 neg r4,r4
260neg_result:
261 extu.w r5,r0
262 bf div_le128_neg
263 cmp/eq r5,r0
264 mov r4,r0
265 shlr8 r0
266 bf/s div_ge64k_neg
267 cmp/hi r0,r5
268 div0u
269 mov.l zero_l,r1
270 shll16 r5
271 div1 r5,r0
272 mov.l r1,@-r15
273 .rept 7
274 div1 r5,r0
275 .endr
276 mov.b r0,@(L_MSWLSB,r15)
277 xtrct r4,r0
278 swap.w r0,r0
279 .rept 8
280 div1 r5,r0
281 .endr
282 mov.b r0,@(L_LSWMSB,r15)
283div_ge64k_neg_end:
284 .rept 8
285 div1 r5,r0
286 .endr
287 mov.l @r15+,r4 ! zero-extension and swap using LS unit.
288 extu.b r0,r1
289 mov.l @r15+,r5
290 or r4,r1
291div_r8_neg_end:
292 mov.l @r15+,r4
293 rotcl r1
294 rts
295 neg r1,r0
296
297div_ge64k_neg:
298 bt/s div_r8_neg
299 div0u
300 shll8 r5
301 mov.l zero_l,r1
302 .rept 6
303 div1 r5,r0
304 .endr
305 mov.l r1,@-r15
306 div1 r5,r0
307 mov.w m256_w,r1
308 div1 r5,r0
309 mov.b r0,@(L_LSWMSB,r15)
310 xor r4,r0
311 and r1,r0
312 bra div_ge64k_neg_end
313 xor r4,r0
314
315c128_w:
316 .word 128
317
318div_r8_neg:
319 clrt
320 shll16 r4
321 mov r4,r1
322 shll8 r1
323 mov r5,r4
324 .rept 7
325 rotcl r1; div1 r5,r0
326 .endr
327 mov.l @r15+,r5
328 rotcl r1
329 bra div_r8_neg_end
330 div1 r4,r0
331
332m256_w:
333 .word 0xff00
334/* This table has been generated by divtab-sh4.c. */
335 .balign 4
336div_table_clz:
337 .byte 0
338 .byte 1
339 .byte 0
340 .byte -1
341 .byte -1
342 .byte -2
343 .byte -2
344 .byte -2
345 .byte -2
346 .byte -3
347 .byte -3
348 .byte -3
349 .byte -3
350 .byte -3
351 .byte -3
352 .byte -3
353 .byte -3
354 .byte -4
355 .byte -4
356 .byte -4
357 .byte -4
358 .byte -4
359 .byte -4
360 .byte -4
361 .byte -4
362 .byte -4
363 .byte -4
364 .byte -4
365 .byte -4
366 .byte -4
367 .byte -4
368 .byte -4
369 .byte -4
370 .byte -5
371 .byte -5
372 .byte -5
373 .byte -5
374 .byte -5
375 .byte -5
376 .byte -5
377 .byte -5
378 .byte -5
379 .byte -5
380 .byte -5
381 .byte -5
382 .byte -5
383 .byte -5
384 .byte -5
385 .byte -5
386 .byte -5
387 .byte -5
388 .byte -5
389 .byte -5
390 .byte -5
391 .byte -5
392 .byte -5
393 .byte -5
394 .byte -5
395 .byte -5
396 .byte -5
397 .byte -5
398 .byte -5
399 .byte -5
400 .byte -5
401 .byte -5
402 .byte -6
403 .byte -6
404 .byte -6
405 .byte -6
406 .byte -6
407 .byte -6
408 .byte -6
409 .byte -6
410 .byte -6
411 .byte -6
412 .byte -6
413 .byte -6
414 .byte -6
415 .byte -6
416 .byte -6
417 .byte -6
418 .byte -6
419 .byte -6
420 .byte -6
421 .byte -6
422 .byte -6
423 .byte -6
424 .byte -6
425 .byte -6
426 .byte -6
427 .byte -6
428 .byte -6
429 .byte -6
430 .byte -6
431 .byte -6
432 .byte -6
433 .byte -6
434 .byte -6
435 .byte -6
436 .byte -6
437 .byte -6
438 .byte -6
439 .byte -6
440 .byte -6
441 .byte -6
442 .byte -6
443 .byte -6
444 .byte -6
445 .byte -6
446 .byte -6
447 .byte -6
448 .byte -6
449 .byte -6
450 .byte -6
451 .byte -6
452 .byte -6
453 .byte -6
454 .byte -6
455 .byte -6
456 .byte -6
457 .byte -6
458 .byte -6
459 .byte -6
460 .byte -6
461 .byte -6
462 .byte -6
463 .byte -6
464 .byte -6
465/* Lookup table translating positive divisor to index into table of
466 normalized inverse. N.B. the '0' entry is also the last entry of the
467 previous table, and causes an unaligned access for division by zero. */
468div_table_ix:
469 .byte -6
470 .byte -128
471 .byte -128
472 .byte 0
473 .byte -128
474 .byte -64
475 .byte 0
476 .byte 64
477 .byte -128
478 .byte -96
479 .byte -64
480 .byte -32
481 .byte 0
482 .byte 32
483 .byte 64
484 .byte 96
485 .byte -128
486 .byte -112
487 .byte -96
488 .byte -80
489 .byte -64
490 .byte -48
491 .byte -32
492 .byte -16
493 .byte 0
494 .byte 16
495 .byte 32
496 .byte 48
497 .byte 64
498 .byte 80
499 .byte 96
500 .byte 112
501 .byte -128
502 .byte -120
503 .byte -112
504 .byte -104
505 .byte -96
506 .byte -88
507 .byte -80
508 .byte -72
509 .byte -64
510 .byte -56
511 .byte -48
512 .byte -40
513 .byte -32
514 .byte -24
515 .byte -16
516 .byte -8
517 .byte 0
518 .byte 8
519 .byte 16
520 .byte 24
521 .byte 32
522 .byte 40
523 .byte 48
524 .byte 56
525 .byte 64
526 .byte 72
527 .byte 80
528 .byte 88
529 .byte 96
530 .byte 104
531 .byte 112
532 .byte 120
533 .byte -128
534 .byte -124
535 .byte -120
536 .byte -116
537 .byte -112
538 .byte -108
539 .byte -104
540 .byte -100
541 .byte -96
542 .byte -92
543 .byte -88
544 .byte -84
545 .byte -80
546 .byte -76
547 .byte -72
548 .byte -68
549 .byte -64
550 .byte -60
551 .byte -56
552 .byte -52
553 .byte -48
554 .byte -44
555 .byte -40
556 .byte -36
557 .byte -32
558 .byte -28
559 .byte -24
560 .byte -20
561 .byte -16
562 .byte -12
563 .byte -8
564 .byte -4
565 .byte 0
566 .byte 4
567 .byte 8
568 .byte 12
569 .byte 16
570 .byte 20
571 .byte 24
572 .byte 28
573 .byte 32
574 .byte 36
575 .byte 40
576 .byte 44
577 .byte 48
578 .byte 52
579 .byte 56
580 .byte 60
581 .byte 64
582 .byte 68
583 .byte 72
584 .byte 76
585 .byte 80
586 .byte 84
587 .byte 88
588 .byte 92
589 .byte 96
590 .byte 100
591 .byte 104
592 .byte 108
593 .byte 112
594 .byte 116
595 .byte 120
596 .byte 124
597 .byte -128
598/* 1/64 .. 1/127, normalized. There is an implicit leading 1 in bit 32. */
599 .balign 4
600zero_l:
601 .long 0x0
602 .long 0xF81F81F9
603 .long 0xF07C1F08
604 .long 0xE9131AC0
605 .long 0xE1E1E1E2
606 .long 0xDAE6076C
607 .long 0xD41D41D5
608 .long 0xCD856891
609 .long 0xC71C71C8
610 .long 0xC0E07039
611 .long 0xBACF914D
612 .long 0xB4E81B4F
613 .long 0xAF286BCB
614 .long 0xA98EF607
615 .long 0xA41A41A5
616 .long 0x9EC8E952
617 .long 0x9999999A
618 .long 0x948B0FCE
619 .long 0x8F9C18FA
620 .long 0x8ACB90F7
621 .long 0x86186187
622 .long 0x81818182
623 .long 0x7D05F418
624 .long 0x78A4C818
625 .long 0x745D1746
626 .long 0x702E05C1
627 .long 0x6C16C16D
628 .long 0x68168169
629 .long 0x642C8591
630 .long 0x60581606
631 .long 0x5C9882BA
632 .long 0x58ED2309
633div_table_inv:
634 .long 0x55555556
635 .long 0x51D07EAF
636 .long 0x4E5E0A73
637 .long 0x4AFD6A06
638 .long 0x47AE147B
639 .long 0x446F8657
640 .long 0x41414142
641 .long 0x3E22CBCF
642 .long 0x3B13B13C
643 .long 0x38138139
644 .long 0x3521CFB3
645 .long 0x323E34A3
646 .long 0x2F684BDB
647 .long 0x2C9FB4D9
648 .long 0x29E4129F
649 .long 0x27350B89
650 .long 0x24924925
651 .long 0x21FB7813
652 .long 0x1F7047DD
653 .long 0x1CF06ADB
654 .long 0x1A7B9612
655 .long 0x18118119
656 .long 0x15B1E5F8
657 .long 0x135C8114
658 .long 0x11111112
659 .long 0xECF56BF
660 .long 0xC9714FC
661 .long 0xA6810A7
662 .long 0x8421085
663 .long 0x624DD30
664 .long 0x4104105
665 .long 0x2040811
666 /* maximum error: 0.987342 scaled: 0.921875*/
diff --git a/arch/sh/lib64/Makefile b/arch/sh/lib64/Makefile
index 9950966923a0..4bacb9e83478 100644
--- a/arch/sh/lib64/Makefile
+++ b/arch/sh/lib64/Makefile
@@ -2,7 +2,7 @@
2# Makefile for the SH-5 specific library files.. 2# Makefile for the SH-5 specific library files..
3# 3#
4# Copyright (C) 2000, 2001 Paolo Alberelli 4# Copyright (C) 2000, 2001 Paolo Alberelli
5# Copyright (C) 2003 Paul Mundt 5# Copyright (C) 2003 - 2008 Paul Mundt
6# 6#
7# This file is subject to the terms and conditions of the GNU General Public 7# This file is subject to the terms and conditions of the GNU General Public
8# License. See the file "COPYING" in the main directory of this archive 8# License. See the file "COPYING" in the main directory of this archive
@@ -10,6 +10,8 @@
10# 10#
11 11
12# Panic should really be compiled as PIC 12# Panic should really be compiled as PIC
13lib-y := udelay.o c-checksum.o dbg.o panic.o memcpy.o copy_user_memcpy.o \ 13lib-y := udelay.o c-checksum.o dbg.o panic.o memcpy.o memset.o \
14 copy_page.o clear_page.o 14 copy_user_memcpy.o copy_page.o clear_page.o strcpy.o strlen.o
15 15
16# Extracted from libgcc
17lib-y += udivsi3.o udivdi3.o sdivsi3.o
diff --git a/arch/sh/lib64/c-checksum.c b/arch/sh/lib64/c-checksum.c
index 5c284e0cff9c..73c0877e3a29 100644
--- a/arch/sh/lib64/c-checksum.c
+++ b/arch/sh/lib64/c-checksum.c
@@ -35,7 +35,7 @@ static inline unsigned short foldto16(unsigned long x)
35 35
36static inline unsigned short myfoldto16(unsigned long long x) 36static inline unsigned short myfoldto16(unsigned long long x)
37{ 37{
38 /* Fold down to 32-bits so we don't loose in the typedef-less 38 /* Fold down to 32-bits so we don't lose in the typedef-less
39 network stack. */ 39 network stack. */
40 /* 64 to 33 */ 40 /* 64 to 33 */
41 x = (x & 0xffffffff) + (x >> 32); 41 x = (x & 0xffffffff) + (x >> 32);
@@ -199,7 +199,7 @@ __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
199 result = (__force u64) saddr + (__force u64) daddr + 199 result = (__force u64) saddr + (__force u64) daddr +
200 (__force u64) sum + ((len + proto) << 8); 200 (__force u64) sum + ((len + proto) << 8);
201 201
202 /* Fold down to 32-bits so we don't loose in the typedef-less 202 /* Fold down to 32-bits so we don't lose in the typedef-less
203 network stack. */ 203 network stack. */
204 /* 64 to 33 */ 204 /* 64 to 33 */
205 result = (result & 0xffffffff) + (result >> 32); 205 result = (result & 0xffffffff) + (result >> 32);
diff --git a/arch/sh/lib64/memcpy.S b/arch/sh/lib64/memcpy.S
new file mode 100644
index 000000000000..dd300c372ce1
--- /dev/null
+++ b/arch/sh/lib64/memcpy.S
@@ -0,0 +1,201 @@
1/* Cloned and hacked for uClibc by Paul Mundt, December 2003 */
2/* Modified by SuperH, Inc. September 2003 */
3!
4! Fast SH memcpy
5!
6! by Toshiyasu Morita (tm@netcom.com)
7! hacked by J"orn Rernnecke (joern.rennecke@superh.com) ("o for o-umlaut)
8! SH5 code Copyright 2002 SuperH Ltd.
9!
10! Entry: ARG0: destination pointer
11! ARG1: source pointer
12! ARG2: byte count
13!
14! Exit: RESULT: destination pointer
15! any other registers in the range r0-r7: trashed
16!
17! Notes: Usually one wants to do small reads and write a longword, but
18! unfortunately it is difficult in some cases to concatanate bytes
19! into a longword on the SH, so this does a longword read and small
20! writes.
21!
22! This implementation makes two assumptions about how it is called:
23!
24! 1.: If the byte count is nonzero, the address of the last byte to be
25! copied is unsigned greater than the address of the first byte to
26! be copied. This could be easily swapped for a signed comparison,
27! but the algorithm used needs some comparison.
28!
29! 2.: When there are two or three bytes in the last word of an 11-or-more
30! bytes memory chunk to b copied, the rest of the word can be read
31! without side effects.
32! This could be easily changed by increasing the minumum size of
33! a fast memcpy and the amount subtracted from r7 before L_2l_loop be 2,
34! however, this would cost a few extra cyles on average.
35! For SHmedia, the assumption is that any quadword can be read in its
36! enirety if at least one byte is included in the copy.
37!
38
39 .section .text..SHmedia32,"ax"
40 .globl memcpy
41 .type memcpy, @function
42 .align 5
43
44memcpy:
45
46#define LDUAQ(P,O,D0,D1) ldlo.q P,O,D0; ldhi.q P,O+7,D1
47#define STUAQ(P,O,D0,D1) stlo.q P,O,D0; sthi.q P,O+7,D1
48#define LDUAL(P,O,D0,D1) ldlo.l P,O,D0; ldhi.l P,O+3,D1
49#define STUAL(P,O,D0,D1) stlo.l P,O,D0; sthi.l P,O+3,D1
50
51 ld.b r3,0,r63
52 pta/l Large,tr0
53 movi 25,r0
54 bgeu/u r4,r0,tr0
55 nsb r4,r0
56 shlli r0,5,r0
57 movi (L1-L0+63*32 + 1) & 0xffff,r1
58 sub r1, r0, r0
59L0: ptrel r0,tr0
60 add r2,r4,r5
61 ptabs r18,tr1
62 add r3,r4,r6
63 blink tr0,r63
64
65/* Rearranged to make cut2 safe */
66 .balign 8
67L4_7: /* 4..7 byte memcpy cntd. */
68 stlo.l r2, 0, r0
69 or r6, r7, r6
70 sthi.l r5, -1, r6
71 stlo.l r5, -4, r6
72 blink tr1,r63
73
74 .balign 8
75L1: /* 0 byte memcpy */
76 nop
77 blink tr1,r63
78 nop
79 nop
80 nop
81 nop
82
83L2_3: /* 2 or 3 byte memcpy cntd. */
84 st.b r5,-1,r6
85 blink tr1,r63
86
87 /* 1 byte memcpy */
88 ld.b r3,0,r0
89 st.b r2,0,r0
90 blink tr1,r63
91
92L8_15: /* 8..15 byte memcpy cntd. */
93 stlo.q r2, 0, r0
94 or r6, r7, r6
95 sthi.q r5, -1, r6
96 stlo.q r5, -8, r6
97 blink tr1,r63
98
99 /* 2 or 3 byte memcpy */
100 ld.b r3,0,r0
101 ld.b r2,0,r63
102 ld.b r3,1,r1
103 st.b r2,0,r0
104 pta/l L2_3,tr0
105 ld.b r6,-1,r6
106 st.b r2,1,r1
107 blink tr0, r63
108
109 /* 4 .. 7 byte memcpy */
110 LDUAL (r3, 0, r0, r1)
111 pta L4_7, tr0
112 ldlo.l r6, -4, r7
113 or r0, r1, r0
114 sthi.l r2, 3, r0
115 ldhi.l r6, -1, r6
116 blink tr0, r63
117
118 /* 8 .. 15 byte memcpy */
119 LDUAQ (r3, 0, r0, r1)
120 pta L8_15, tr0
121 ldlo.q r6, -8, r7
122 or r0, r1, r0
123 sthi.q r2, 7, r0
124 ldhi.q r6, -1, r6
125 blink tr0, r63
126
127 /* 16 .. 24 byte memcpy */
128 LDUAQ (r3, 0, r0, r1)
129 LDUAQ (r3, 8, r8, r9)
130 or r0, r1, r0
131 sthi.q r2, 7, r0
132 or r8, r9, r8
133 sthi.q r2, 15, r8
134 ldlo.q r6, -8, r7
135 ldhi.q r6, -1, r6
136 stlo.q r2, 8, r8
137 stlo.q r2, 0, r0
138 or r6, r7, r6
139 sthi.q r5, -1, r6
140 stlo.q r5, -8, r6
141 blink tr1,r63
142
143Large:
144 ld.b r2, 0, r63
145 pta/l Loop_ua, tr1
146 ori r3, -8, r7
147 sub r2, r7, r22
148 sub r3, r2, r6
149 add r2, r4, r5
150 ldlo.q r3, 0, r0
151 addi r5, -16, r5
152 movi 64+8, r27 // could subtract r7 from that.
153 stlo.q r2, 0, r0
154 sthi.q r2, 7, r0
155 ldx.q r22, r6, r0
156 bgtu/l r27, r4, tr1
157
158 addi r5, -48, r27
159 pta/l Loop_line, tr0
160 addi r6, 64, r36
161 addi r6, -24, r19
162 addi r6, -16, r20
163 addi r6, -8, r21
164
165Loop_line:
166 ldx.q r22, r36, r63
167 alloco r22, 32
168 addi r22, 32, r22
169 ldx.q r22, r19, r23
170 sthi.q r22, -25, r0
171 ldx.q r22, r20, r24
172 ldx.q r22, r21, r25
173 stlo.q r22, -32, r0
174 ldx.q r22, r6, r0
175 sthi.q r22, -17, r23
176 sthi.q r22, -9, r24
177 sthi.q r22, -1, r25
178 stlo.q r22, -24, r23
179 stlo.q r22, -16, r24
180 stlo.q r22, -8, r25
181 bgeu r27, r22, tr0
182
183Loop_ua:
184 addi r22, 8, r22
185 sthi.q r22, -1, r0
186 stlo.q r22, -8, r0
187 ldx.q r22, r6, r0
188 bgtu/l r5, r22, tr1
189
190 add r3, r4, r7
191 ldlo.q r7, -8, r1
192 sthi.q r22, 7, r0
193 ldhi.q r7, -1, r7
194 ptabs r18,tr1
195 stlo.q r22, 0, r0
196 or r1, r7, r1
197 sthi.q r5, 15, r1
198 stlo.q r5, 8, r1
199 blink tr1, r63
200
201 .size memcpy,.-memcpy
diff --git a/arch/sh/lib64/memcpy.c b/arch/sh/lib64/memcpy.c
deleted file mode 100644
index fba436a92bfa..000000000000
--- a/arch/sh/lib64/memcpy.c
+++ /dev/null
@@ -1,81 +0,0 @@
1/*
2 * Copyright (C) 2002 Mark Debbage (Mark.Debbage@superh.com)
3 *
4 * May be copied or modified under the terms of the GNU General Public
5 * License. See linux/COPYING for more information.
6 *
7 */
8
9#include <linux/types.h>
10#include <asm/string.h>
11
12// This is a simplistic optimization of memcpy to increase the
13// granularity of access beyond one byte using aligned
14// loads and stores. This is not an optimal implementation
15// for SH-5 (especially with regard to prefetching and the cache),
16// and a better version should be provided later ...
17
18void *memcpy(void *dest, const void *src, size_t count)
19{
20 char *d = (char *) dest, *s = (char *) src;
21
22 if (count >= 32) {
23 int i = 8 - (((unsigned long) d) & 0x7);
24
25 if (i != 8)
26 while (i-- && count--) {
27 *d++ = *s++;
28 }
29
30 if (((((unsigned long) d) & 0x7) == 0) &&
31 ((((unsigned long) s) & 0x7) == 0)) {
32 while (count >= 32) {
33 unsigned long long t1, t2, t3, t4;
34 t1 = *(unsigned long long *) (s);
35 t2 = *(unsigned long long *) (s + 8);
36 t3 = *(unsigned long long *) (s + 16);
37 t4 = *(unsigned long long *) (s + 24);
38 *(unsigned long long *) (d) = t1;
39 *(unsigned long long *) (d + 8) = t2;
40 *(unsigned long long *) (d + 16) = t3;
41 *(unsigned long long *) (d + 24) = t4;
42 d += 32;
43 s += 32;
44 count -= 32;
45 }
46 while (count >= 8) {
47 *(unsigned long long *) d =
48 *(unsigned long long *) s;
49 d += 8;
50 s += 8;
51 count -= 8;
52 }
53 }
54
55 if (((((unsigned long) d) & 0x3) == 0) &&
56 ((((unsigned long) s) & 0x3) == 0)) {
57 while (count >= 4) {
58 *(unsigned long *) d = *(unsigned long *) s;
59 d += 4;
60 s += 4;
61 count -= 4;
62 }
63 }
64
65 if (((((unsigned long) d) & 0x1) == 0) &&
66 ((((unsigned long) s) & 0x1) == 0)) {
67 while (count >= 2) {
68 *(unsigned short *) d = *(unsigned short *) s;
69 d += 2;
70 s += 2;
71 count -= 2;
72 }
73 }
74 }
75
76 while (count--) {
77 *d++ = *s++;
78 }
79
80 return d;
81}
diff --git a/arch/sh/lib64/memset.S b/arch/sh/lib64/memset.S
new file mode 100644
index 000000000000..2d37b0488552
--- /dev/null
+++ b/arch/sh/lib64/memset.S
@@ -0,0 +1,91 @@
1/* Cloned and hacked for uClibc by Paul Mundt, December 2003 */
2/* Modified by SuperH, Inc. September 2003 */
3!
4! Fast SH memset
5!
6! by Toshiyasu Morita (tm@netcom.com)
7!
8! SH5 code by J"orn Rennecke (joern.rennecke@superh.com)
9! Copyright 2002 SuperH Ltd.
10!
11
12#if __BYTE_ORDER == __LITTLE_ENDIAN
13#define SHHI shlld
14#define SHLO shlrd
15#else
16#define SHHI shlrd
17#define SHLO shlld
18#endif
19
20 .section .text..SHmedia32,"ax"
21 .globl memset
22 .type memset, @function
23
24 .align 5
25
26memset:
27 pta/l multiquad, tr0
28 andi r2, 7, r22
29 ptabs r18, tr2
30 mshflo.b r3,r3,r3
31 add r4, r22, r23
32 mperm.w r3, r63, r3 // Fill pattern now in every byte of r3
33
34 movi 8, r9
35 bgtu/u r23, r9, tr0 // multiquad
36
37 beqi/u r4, 0, tr2 // Return with size 0 - ensures no mem accesses
38 ldlo.q r2, 0, r7
39 shlli r4, 2, r4
40 movi -1, r8
41 SHHI r8, r4, r8
42 SHHI r8, r4, r8
43 mcmv r7, r8, r3
44 stlo.q r2, 0, r3
45 blink tr2, r63
46
47multiquad:
48 pta/l lastquad, tr0
49 stlo.q r2, 0, r3
50 shlri r23, 3, r24
51 add r2, r4, r5
52 beqi/u r24, 1, tr0 // lastquad
53 pta/l loop, tr1
54 sub r2, r22, r25
55 andi r5, -8, r20 // calculate end address and
56 addi r20, -7*8, r8 // loop end address; This might overflow, so we need
57 // to use a different test before we start the loop
58 bge/u r24, r9, tr1 // loop
59 st.q r25, 8, r3
60 st.q r20, -8, r3
61 shlri r24, 1, r24
62 beqi/u r24, 1, tr0 // lastquad
63 st.q r25, 16, r3
64 st.q r20, -16, r3
65 beqi/u r24, 2, tr0 // lastquad
66 st.q r25, 24, r3
67 st.q r20, -24, r3
68lastquad:
69 sthi.q r5, -1, r3
70 blink tr2,r63
71
72loop:
73!!! alloco r25, 32 // QQQ comment out for short-term fix to SHUK #3895.
74 // QQQ commenting out is locically correct, but sub-optimal
75 // QQQ Sean McGoogan - 4th April 2003.
76 st.q r25, 8, r3
77 st.q r25, 16, r3
78 st.q r25, 24, r3
79 st.q r25, 32, r3
80 addi r25, 32, r25
81 bgeu/l r8, r25, tr1 // loop
82
83 st.q r20, -40, r3
84 st.q r20, -32, r3
85 st.q r20, -24, r3
86 st.q r20, -16, r3
87 st.q r20, -8, r3
88 sthi.q r5, -1, r3
89 blink tr2,r63
90
91 .size memset,.-memset
diff --git a/arch/sh/lib64/sdivsi3.S b/arch/sh/lib64/sdivsi3.S
new file mode 100644
index 000000000000..6a800c6a4904
--- /dev/null
+++ b/arch/sh/lib64/sdivsi3.S
@@ -0,0 +1,131 @@
1 .global __sdivsi3
2 .section .text..SHmedia32,"ax"
3 .align 2
4
5 /* inputs: r4,r5 */
6 /* clobbered: r1,r18,r19,r20,r21,r25,tr0 */
7 /* result in r0 */
8__sdivsi3:
9 ptb __div_table,tr0
10
11 nsb r5, r1
12 shlld r5, r1, r25 /* normalize; [-2 ..1, 1..2) in s2.62 */
13 shari r25, 58, r21 /* extract 5(6) bit index (s2.4 with hole -1..1) */
14 /* bubble */
15 gettr tr0,r20
16 ldx.ub r20, r21, r19 /* u0.8 */
17 shari r25, 32, r25 /* normalize to s2.30 */
18 shlli r21, 1, r21
19 muls.l r25, r19, r19 /* s2.38 */
20 ldx.w r20, r21, r21 /* s2.14 */
21 ptabs r18, tr0
22 shari r19, 24, r19 /* truncate to s2.14 */
23 sub r21, r19, r19 /* some 11 bit inverse in s1.14 */
24 muls.l r19, r19, r21 /* u0.28 */
25 sub r63, r1, r1
26 addi r1, 92, r1
27 muls.l r25, r21, r18 /* s2.58 */
28 shlli r19, 45, r19 /* multiply by two and convert to s2.58 */
29 /* bubble */
30 sub r19, r18, r18
31 shari r18, 28, r18 /* some 22 bit inverse in s1.30 */
32 muls.l r18, r25, r0 /* s2.60 */
33 muls.l r18, r4, r25 /* s32.30 */
34 /* bubble */
35 shari r0, 16, r19 /* s-16.44 */
36 muls.l r19, r18, r19 /* s-16.74 */
37 shari r25, 63, r0
38 shari r4, 14, r18 /* s19.-14 */
39 shari r19, 30, r19 /* s-16.44 */
40 muls.l r19, r18, r19 /* s15.30 */
41 xor r21, r0, r21 /* You could also use the constant 1 << 27. */
42 add r21, r25, r21
43 sub r21, r19, r21
44 shard r21, r1, r21
45 sub r21, r0, r0
46 blink tr0, r63
47
48/* This table has been generated by divtab.c .
49Defects for bias -330:
50 Max defect: 6.081536e-07 at -1.000000e+00
51 Min defect: 2.849516e-08 at 1.030651e+00
52 Max 2nd step defect: 9.606539e-12 at -1.000000e+00
53 Min 2nd step defect: 0.000000e+00 at 0.000000e+00
54 Defect at 1: 1.238659e-07
55 Defect at -2: 1.061708e-07 */
56
57 .balign 2
58 .type __div_table,@object
59 .size __div_table,128
60/* negative division constants */
61 .word -16638
62 .word -17135
63 .word -17737
64 .word -18433
65 .word -19103
66 .word -19751
67 .word -20583
68 .word -21383
69 .word -22343
70 .word -23353
71 .word -24407
72 .word -25582
73 .word -26863
74 .word -28382
75 .word -29965
76 .word -31800
77/* negative division factors */
78 .byte 66
79 .byte 70
80 .byte 75
81 .byte 81
82 .byte 87
83 .byte 93
84 .byte 101
85 .byte 109
86 .byte 119
87 .byte 130
88 .byte 142
89 .byte 156
90 .byte 172
91 .byte 192
92 .byte 214
93 .byte 241
94 .skip 16
95 .global __div_table
96__div_table:
97 .skip 16
98/* positive division factors */
99 .byte 241
100 .byte 214
101 .byte 192
102 .byte 172
103 .byte 156
104 .byte 142
105 .byte 130
106 .byte 119
107 .byte 109
108 .byte 101
109 .byte 93
110 .byte 87
111 .byte 81
112 .byte 75
113 .byte 70
114 .byte 66
115/* positive division constants */
116 .word 31801
117 .word 29966
118 .word 28383
119 .word 26864
120 .word 25583
121 .word 24408
122 .word 23354
123 .word 22344
124 .word 21384
125 .word 20584
126 .word 19752
127 .word 19104
128 .word 18434
129 .word 17738
130 .word 17136
131 .word 16639
diff --git a/arch/sh/lib64/strcpy.S b/arch/sh/lib64/strcpy.S
new file mode 100644
index 000000000000..ea7c9c533eea
--- /dev/null
+++ b/arch/sh/lib64/strcpy.S
@@ -0,0 +1,97 @@
1/* Cloned and hacked for uClibc by Paul Mundt, December 2003 */
2/* Modified by SuperH, Inc. September 2003 */
3! Entry: arg0: destination
4! arg1: source
5! Exit: result: destination
6!
7! SH5 code Copyright 2002 SuperH Ltd.
8
9#if __BYTE_ORDER == __LITTLE_ENDIAN
10#define SHHI shlld
11#define SHLO shlrd
12#else
13#define SHHI shlrd
14#define SHLO shlld
15#endif
16
17 .section .text..SHmedia32,"ax"
18 .globl strcpy
19 .type strcpy, @function
20 .align 5
21
22strcpy:
23
24 pta/l shortstring,tr1
25 ldlo.q r3,0,r4
26 ptabs r18,tr4
27 shlli r3,3,r7
28 addi r2, 8, r0
29 mcmpeq.b r4,r63,r6
30 SHHI r6,r7,r6
31 bnei/u r6,0,tr1 // shortstring
32 pta/l no_lddst, tr2
33 ori r3,-8,r23
34 sub r2, r23, r0
35 sub r3, r2, r21
36 addi r21, 8, r20
37 ldx.q r0, r21, r5
38 pta/l loop, tr0
39 ori r2,-8,r22
40 mcmpeq.b r5, r63, r6
41 bgt/u r22, r23, tr2 // no_lddst
42
43 // r22 < r23 : Need to do a load from the destination.
44 // r22 == r23 : Doesn't actually need to load from destination,
45 // but still can be handled here.
46 ldlo.q r2, 0, r9
47 movi -1, r8
48 SHLO r8, r7, r8
49 mcmv r4, r8, r9
50 stlo.q r2, 0, r9
51 beqi/l r6, 0, tr0 // loop
52
53 add r5, r63, r4
54 addi r0, 8, r0
55 blink tr1, r63 // shortstring
56no_lddst:
57 // r22 > r23: note that for r22 == r23 the sthi.q would clobber
58 // bytes before the destination region.
59 stlo.q r2, 0, r4
60 SHHI r4, r7, r4
61 sthi.q r0, -1, r4
62 beqi/l r6, 0, tr0 // loop
63
64 add r5, r63, r4
65 addi r0, 8, r0
66shortstring:
67#if __BYTE_ORDER != __LITTLE_ENDIAN
68 pta/l shortstring2,tr1
69 byterev r4,r4
70#endif
71shortstring2:
72 st.b r0,-8,r4
73 andi r4,0xff,r5
74 shlri r4,8,r4
75 addi r0,1,r0
76 bnei/l r5,0,tr1
77 blink tr4,r63 // return
78
79 .balign 8
80loop:
81 stlo.q r0, 0, r5
82 ldx.q r0, r20, r4
83 addi r0, 16, r0
84 sthi.q r0, -9, r5
85 mcmpeq.b r4, r63, r6
86 bnei/u r6, 0, tr1 // shortstring
87 ldx.q r0, r21, r5
88 stlo.q r0, -8, r4
89 sthi.q r0, -1, r4
90 mcmpeq.b r5, r63, r6
91 beqi/l r6, 0, tr0 // loop
92
93 add r5, r63, r4
94 addi r0, 8, r0
95 blink tr1, r63 // shortstring
96
97 .size strcpy,.-strcpy
diff --git a/arch/sh/lib64/strlen.S b/arch/sh/lib64/strlen.S
new file mode 100644
index 000000000000..cbc0d912e5f3
--- /dev/null
+++ b/arch/sh/lib64/strlen.S
@@ -0,0 +1,33 @@
1/*
2 * Simplistic strlen() implementation for SHmedia.
3 *
4 * Copyright (C) 2003 Paul Mundt <lethal@linux-sh.org>
5 */
6
7 .section .text..SHmedia32,"ax"
8 .globl strlen
9 .type strlen,@function
10
11 .balign 16
12strlen:
13 ptabs r18, tr4
14
15 /*
16 * Note: We could easily deal with the NULL case here with a simple
17 * sanity check, though it seems that the behavior we want is to fault
18 * in the event that r2 == NULL, so we don't bother.
19 */
20/* beqi r2, 0, tr4 */ ! Sanity check
21
22 movi -1, r0
23 pta/l loop, tr0
24loop:
25 ld.b r2, 0, r1
26 addi r2, 1, r2
27 addi r0, 1, r0
28 bnei/l r1, 0, tr0
29
30 or r0, r63, r2
31 blink tr4, r63
32
33 .size strlen,.-strlen
diff --git a/arch/sh/lib64/udivdi3.S b/arch/sh/lib64/udivdi3.S
new file mode 100644
index 000000000000..6895c0225b85
--- /dev/null
+++ b/arch/sh/lib64/udivdi3.S
@@ -0,0 +1,120 @@
1 .section .text..SHmedia32,"ax"
2 .align 2
3 .global __udivdi3
4__udivdi3:
5 shlri r3,1,r4
6 nsb r4,r22
7 shlld r3,r22,r6
8 shlri r6,49,r5
9 movi 0xffffffffffffbaf1,r21 /* .l shift count 17. */
10 sub r21,r5,r1
11 mmulfx.w r1,r1,r4
12 mshflo.w r1,r63,r1
13 sub r63,r22,r20 // r63 == 64 % 64
14 mmulfx.w r5,r4,r4
15 pta large_divisor,tr0
16 addi r20,32,r9
17 msub.w r1,r4,r1
18 madd.w r1,r1,r1
19 mmulfx.w r1,r1,r4
20 shlri r6,32,r7
21 bgt/u r9,r63,tr0 // large_divisor
22 mmulfx.w r5,r4,r4
23 shlri r2,32+14,r19
24 addi r22,-31,r0
25 msub.w r1,r4,r1
26
27 mulu.l r1,r7,r4
28 addi r1,-3,r5
29 mulu.l r5,r19,r5
30 sub r63,r4,r4 // Negate to make sure r1 ends up <= 1/r2
31 shlri r4,2,r4 /* chop off leading %0000000000000000 001.00000000000 - or, as
32 the case may be, %0000000000000000 000.11111111111, still */
33 muls.l r1,r4,r4 /* leaving at least one sign bit. */
34 mulu.l r5,r3,r8
35 mshalds.l r1,r21,r1
36 shari r4,26,r4
37 shlld r8,r0,r8
38 add r1,r4,r1 // 31 bit unsigned reciprocal now in r1 (msb equiv. 0.5)
39 sub r2,r8,r2
40 /* Can do second step of 64 : 32 div now, using r1 and the rest in r2. */
41
42 shlri r2,22,r21
43 mulu.l r21,r1,r21
44 shlld r5,r0,r8
45 addi r20,30-22,r0
46 shlrd r21,r0,r21
47 mulu.l r21,r3,r5
48 add r8,r21,r8
49 mcmpgt.l r21,r63,r21 // See Note 1
50 addi r20,30,r0
51 mshfhi.l r63,r21,r21
52 sub r2,r5,r2
53 andc r2,r21,r2
54
55 /* small divisor: need a third divide step */
56 mulu.l r2,r1,r7
57 ptabs r18,tr0
58 addi r2,1,r2
59 shlrd r7,r0,r7
60 mulu.l r7,r3,r5
61 add r8,r7,r8
62 sub r2,r3,r2
63 cmpgt r2,r5,r5
64 add r8,r5,r2
65 /* could test r3 here to check for divide by zero. */
66 blink tr0,r63
67
68large_divisor:
69 mmulfx.w r5,r4,r4
70 shlrd r2,r9,r25
71 shlri r25,32,r8
72 msub.w r1,r4,r1
73
74 mulu.l r1,r7,r4
75 addi r1,-3,r5
76 mulu.l r5,r8,r5
77 sub r63,r4,r4 // Negate to make sure r1 ends up <= 1/r2
78 shlri r4,2,r4 /* chop off leading %0000000000000000 001.00000000000 - or, as
79 the case may be, %0000000000000000 000.11111111111, still */
80 muls.l r1,r4,r4 /* leaving at least one sign bit. */
81 shlri r5,14-1,r8
82 mulu.l r8,r7,r5
83 mshalds.l r1,r21,r1
84 shari r4,26,r4
85 add r1,r4,r1 // 31 bit unsigned reciprocal now in r1 (msb equiv. 0.5)
86 sub r25,r5,r25
87 /* Can do second step of 64 : 32 div now, using r1 and the rest in r25. */
88
89 shlri r25,22,r21
90 mulu.l r21,r1,r21
91 pta no_lo_adj,tr0
92 addi r22,32,r0
93 shlri r21,40,r21
94 mulu.l r21,r7,r5
95 add r8,r21,r8
96 shlld r2,r0,r2
97 sub r25,r5,r25
98 bgtu/u r7,r25,tr0 // no_lo_adj
99 addi r8,1,r8
100 sub r25,r7,r25
101no_lo_adj:
102 mextr4 r2,r25,r2
103
104 /* large_divisor: only needs a few adjustments. */
105 mulu.l r8,r6,r5
106 ptabs r18,tr0
107 /* bubble */
108 cmpgtu r5,r2,r5
109 sub r8,r5,r2
110 blink tr0,r63
111
112/* Note 1: To shift the result of the second divide stage so that the result
113 always fits into 32 bits, yet we still reduce the rest sufficiently
114 would require a lot of instructions to do the shifts just right. Using
115 the full 64 bit shift result to multiply with the divisor would require
116 four extra instructions for the upper 32 bits (shift / mulu / shift / sub).
117 Fortunately, if the upper 32 bits of the shift result are nonzero, we
118 know that the rest after taking this partial result into account will
119 fit into 32 bits. So we just clear the upper 32 bits of the rest if the
120 upper 32 bits of the partial result are nonzero. */
diff --git a/arch/sh/lib64/udivsi3.S b/arch/sh/lib64/udivsi3.S
new file mode 100644
index 000000000000..e68120e4b847
--- /dev/null
+++ b/arch/sh/lib64/udivsi3.S
@@ -0,0 +1,59 @@
1 .global __udivsi3
2 .section .text..SHmedia32,"ax"
3 .align 2
4
5/*
6 inputs: r4,r5
7 clobbered: r18,r19,r20,r21,r22,r25,tr0
8 result in r0.
9 */
10__udivsi3:
11 addz.l r5,r63,r22
12 nsb r22,r0
13 shlld r22,r0,r25
14 shlri r25,48,r25
15 movi 0xffffffffffffbb0c,r20 /* shift count eqiv 76 */
16 sub r20,r25,r21
17 mmulfx.w r21,r21,r19
18 mshflo.w r21,r63,r21
19 ptabs r18,tr0
20 mmulfx.w r25,r19,r19
21 sub r20,r0,r0
22 /* bubble */
23 msub.w r21,r19,r19
24
25 /*
26 * It would be nice for scheduling to do this add to r21 before
27 * the msub.w, but we need a different value for r19 to keep
28 * errors under control.
29 */
30 addi r19,-2,r21
31 mulu.l r4,r21,r18
32 mmulfx.w r19,r19,r19
33 shlli r21,15,r21
34 shlrd r18,r0,r18
35 mulu.l r18,r22,r20
36 mmacnfx.wl r25,r19,r21
37 /* bubble */
38 sub r4,r20,r25
39
40 mulu.l r25,r21,r19
41 addi r0,14,r0
42 /* bubble */
43 shlrd r19,r0,r19
44 mulu.l r19,r22,r20
45 add r18,r19,r18
46 /* bubble */
47 sub.l r25,r20,r25
48
49 mulu.l r25,r21,r19
50 addz.l r25,r63,r25
51 sub r25,r22,r25
52 shlrd r19,r0,r19
53 mulu.l r19,r22,r20
54 addi r25,1,r25
55 add r18,r19,r18
56
57 cmpgt r25,r20,r25
58 add.l r18,r25,r0
59 blink tr0,r63
diff --git a/arch/sh/mm/Makefile_32 b/arch/sh/mm/Makefile_32
index f066e76da204..cb2f3f299591 100644
--- a/arch/sh/mm/Makefile_32
+++ b/arch/sh/mm/Makefile_32
@@ -18,6 +18,7 @@ mmu-y := tlb-nommu.o pg-nommu.o
18mmu-$(CONFIG_MMU) := fault_32.o tlbflush_32.o ioremap_32.o 18mmu-$(CONFIG_MMU) := fault_32.o tlbflush_32.o ioremap_32.o
19 19
20obj-y += $(mmu-y) 20obj-y += $(mmu-y)
21obj-$(CONFIG_DEBUG_FS) += asids-debugfs.o
21 22
22ifdef CONFIG_DEBUG_FS 23ifdef CONFIG_DEBUG_FS
23obj-$(CONFIG_CPU_SH4) += cache-debugfs.o 24obj-$(CONFIG_CPU_SH4) += cache-debugfs.o
diff --git a/arch/sh/mm/Makefile_64 b/arch/sh/mm/Makefile_64
index 9481d0f54efd..2863ffb7006d 100644
--- a/arch/sh/mm/Makefile_64
+++ b/arch/sh/mm/Makefile_64
@@ -13,6 +13,7 @@ obj-y += cache-sh5.o
13endif 13endif
14 14
15obj-y += $(mmu-y) 15obj-y += $(mmu-y)
16obj-$(CONFIG_DEBUG_FS) += asids-debugfs.o
16 17
17obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o 18obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
18obj-$(CONFIG_NUMA) += numa.o 19obj-$(CONFIG_NUMA) += numa.o
diff --git a/arch/sh/mm/asids-debugfs.c b/arch/sh/mm/asids-debugfs.c
new file mode 100644
index 000000000000..8e912a15e94f
--- /dev/null
+++ b/arch/sh/mm/asids-debugfs.c
@@ -0,0 +1,79 @@
1/*
2 * debugfs ops for process ASIDs
3 *
4 * Copyright (C) 2000, 2001 Paolo Alberelli
5 * Copyright (C) 2003 - 2008 Paul Mundt
6 * Copyright (C) 2003, 2004 Richard Curnow
7 *
8 * Provides a debugfs file that lists out the ASIDs currently associated
9 * with the processes.
10 *
11 * In the SH-5 case, if the DM.PC register is examined through the debug
12 * link, this shows ASID + PC. To make use of this, the PID->ASID
13 * relationship needs to be known. This is primarily for debugging.
14 *
15 * This file is subject to the terms and conditions of the GNU General Public
16 * License. See the file "COPYING" in the main directory of this archive
17 * for more details.
18 */
19#include <linux/init.h>
20#include <linux/module.h>
21#include <linux/debugfs.h>
22#include <linux/seq_file.h>
23#include <linux/spinlock.h>
24#include <asm/processor.h>
25#include <asm/mmu_context.h>
26
27static int asids_seq_show(struct seq_file *file, void *iter)
28{
29 struct task_struct *p;
30
31 read_lock(&tasklist_lock);
32
33 for_each_process(p) {
34 int pid = p->pid;
35
36 if (unlikely(!pid))
37 continue;
38
39 if (p->mm)
40 seq_printf(file, "%5d : %02lx\n", pid,
41 cpu_asid(smp_processor_id(), p->mm));
42 else
43 seq_printf(file, "%5d : (none)\n", pid);
44 }
45
46 read_unlock(&tasklist_lock);
47
48 return 0;
49}
50
51static int asids_debugfs_open(struct inode *inode, struct file *file)
52{
53 return single_open(file, asids_seq_show, inode->i_private);
54}
55
56static const struct file_operations asids_debugfs_fops = {
57 .owner = THIS_MODULE,
58 .open = asids_debugfs_open,
59 .read = seq_read,
60 .llseek = seq_lseek,
61 .release = single_release,
62};
63
64static int __init asids_debugfs_init(void)
65{
66 struct dentry *asids_dentry;
67
68 asids_dentry = debugfs_create_file("asids", S_IRUSR, sh_debugfs_root,
69 NULL, &asids_debugfs_fops);
70 if (!asids_dentry)
71 return -ENOMEM;
72 if (IS_ERR(asids_dentry))
73 return PTR_ERR(asids_dentry);
74
75 return 0;
76}
77module_init(asids_debugfs_init);
78
79MODULE_LICENSE("GPL v2");
diff --git a/arch/sh/mm/consistent.c b/arch/sh/mm/consistent.c
index 9f8ea3ada4db..edcd5fbf9651 100644
--- a/arch/sh/mm/consistent.c
+++ b/arch/sh/mm/consistent.c
@@ -42,6 +42,8 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
42 return NULL; 42 return NULL;
43 } 43 }
44 44
45 split_page(pfn_to_page(virt_to_phys(ret) >> PAGE_SHIFT), order);
46
45 *dma_handle = virt_to_phys(ret); 47 *dma_handle = virt_to_phys(ret);
46 return ret_nocache; 48 return ret_nocache;
47} 49}
@@ -51,10 +53,13 @@ void dma_free_coherent(struct device *dev, size_t size,
51 void *vaddr, dma_addr_t dma_handle) 53 void *vaddr, dma_addr_t dma_handle)
52{ 54{
53 int order = get_order(size); 55 int order = get_order(size);
56 unsigned long pfn = dma_handle >> PAGE_SHIFT;
57 int k;
54 58
55 if (!dma_release_from_coherent(dev, order, vaddr)) { 59 if (!dma_release_from_coherent(dev, order, vaddr)) {
56 WARN_ON(irqs_disabled()); /* for portability */ 60 WARN_ON(irqs_disabled()); /* for portability */
57 free_pages((unsigned long)phys_to_virt(dma_handle), order); 61 for (k = 0; k < (1 << order); k++)
62 __free_pages(pfn_to_page(pfn + k), 0);
58 iounmap(vaddr); 63 iounmap(vaddr);
59 } 64 }
60} 65}
diff --git a/arch/sh/mm/fault_32.c b/arch/sh/mm/fault_32.c
index 898d477e47c1..31a33ebdef6f 100644
--- a/arch/sh/mm/fault_32.c
+++ b/arch/sh/mm/fault_32.c
@@ -20,7 +20,6 @@
20#include <asm/system.h> 20#include <asm/system.h>
21#include <asm/mmu_context.h> 21#include <asm/mmu_context.h>
22#include <asm/tlbflush.h> 22#include <asm/tlbflush.h>
23#include <asm/kgdb.h>
24 23
25/* 24/*
26 * This routine handles page faults. It determines the address, 25 * This routine handles page faults. It determines the address,
@@ -265,17 +264,6 @@ static inline int notify_page_fault(struct pt_regs *regs, int trap)
265 return ret; 264 return ret;
266} 265}
267 266
268#ifdef CONFIG_SH_STORE_QUEUES
269/*
270 * This is a special case for the SH-4 store queues, as pages for this
271 * space still need to be faulted in before it's possible to flush the
272 * store queue cache for writeout to the remapped region.
273 */
274#define P3_ADDR_MAX (P4SEG_STORE_QUE + 0x04000000)
275#else
276#define P3_ADDR_MAX P4SEG
277#endif
278
279/* 267/*
280 * Called with interrupts disabled. 268 * Called with interrupts disabled.
281 */ 269 */
@@ -293,11 +281,6 @@ asmlinkage int __kprobes __do_page_fault(struct pt_regs *regs,
293 if (notify_page_fault(regs, lookup_exception_vector())) 281 if (notify_page_fault(regs, lookup_exception_vector()))
294 goto out; 282 goto out;
295 283
296#ifdef CONFIG_SH_KGDB
297 if (kgdb_nofault && kgdb_bus_err_hook)
298 kgdb_bus_err_hook();
299#endif
300
301 ret = 1; 284 ret = 1;
302 285
303 /* 286 /*
diff --git a/arch/sh/mm/ioremap_32.c b/arch/sh/mm/ioremap_32.c
index 882a32ebc6b7..32946fba123e 100644
--- a/arch/sh/mm/ioremap_32.c
+++ b/arch/sh/mm/ioremap_32.c
@@ -116,9 +116,10 @@ EXPORT_SYMBOL(__ioremap);
116void __iounmap(void __iomem *addr) 116void __iounmap(void __iomem *addr)
117{ 117{
118 unsigned long vaddr = (unsigned long __force)addr; 118 unsigned long vaddr = (unsigned long __force)addr;
119 unsigned long seg = PXSEG(vaddr);
119 struct vm_struct *p; 120 struct vm_struct *p;
120 121
121 if (PXSEG(vaddr) < P3SEG || is_pci_memaddr(vaddr)) 122 if (seg < P3SEG || seg >= P3_ADDR_MAX || is_pci_memaddr(vaddr))
122 return; 123 return;
123 124
124#ifdef CONFIG_32BIT 125#ifdef CONFIG_32BIT
diff --git a/arch/sh/mm/mmap.c b/arch/sh/mm/mmap.c
index 8837d511710a..931f4d003fa0 100644
--- a/arch/sh/mm/mmap.c
+++ b/arch/sh/mm/mmap.c
@@ -9,7 +9,101 @@
9 */ 9 */
10#include <linux/io.h> 10#include <linux/io.h>
11#include <linux/mm.h> 11#include <linux/mm.h>
12#include <linux/mman.h>
13#include <linux/module.h>
12#include <asm/page.h> 14#include <asm/page.h>
15#include <asm/processor.h>
16
17#ifdef CONFIG_MMU
18unsigned long shm_align_mask = PAGE_SIZE - 1; /* Sane caches */
19EXPORT_SYMBOL(shm_align_mask);
20
21/*
22 * To avoid cache aliases, we map the shared page with same color.
23 */
24#define COLOUR_ALIGN(addr, pgoff) \
25 ((((addr) + shm_align_mask) & ~shm_align_mask) + \
26 (((pgoff) << PAGE_SHIFT) & shm_align_mask))
27
28unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
29 unsigned long len, unsigned long pgoff, unsigned long flags)
30{
31 struct mm_struct *mm = current->mm;
32 struct vm_area_struct *vma;
33 unsigned long start_addr;
34 int do_colour_align;
35
36 if (flags & MAP_FIXED) {
37 /* We do not accept a shared mapping if it would violate
38 * cache aliasing constraints.
39 */
40 if ((flags & MAP_SHARED) && (addr & shm_align_mask))
41 return -EINVAL;
42 return addr;
43 }
44
45 if (unlikely(len > TASK_SIZE))
46 return -ENOMEM;
47
48 do_colour_align = 0;
49 if (filp || (flags & MAP_SHARED))
50 do_colour_align = 1;
51
52 if (addr) {
53 if (do_colour_align)
54 addr = COLOUR_ALIGN(addr, pgoff);
55 else
56 addr = PAGE_ALIGN(addr);
57
58 vma = find_vma(mm, addr);
59 if (TASK_SIZE - len >= addr &&
60 (!vma || addr + len <= vma->vm_start))
61 return addr;
62 }
63
64 if (len > mm->cached_hole_size) {
65 start_addr = addr = mm->free_area_cache;
66 } else {
67 mm->cached_hole_size = 0;
68 start_addr = addr = TASK_UNMAPPED_BASE;
69 }
70
71full_search:
72 if (do_colour_align)
73 addr = COLOUR_ALIGN(addr, pgoff);
74 else
75 addr = PAGE_ALIGN(mm->free_area_cache);
76
77 for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
78 /* At this point: (!vma || addr < vma->vm_end). */
79 if (unlikely(TASK_SIZE - len < addr)) {
80 /*
81 * Start a new search - just in case we missed
82 * some holes.
83 */
84 if (start_addr != TASK_UNMAPPED_BASE) {
85 start_addr = addr = TASK_UNMAPPED_BASE;
86 mm->cached_hole_size = 0;
87 goto full_search;
88 }
89 return -ENOMEM;
90 }
91 if (likely(!vma || addr + len <= vma->vm_start)) {
92 /*
93 * Remember the place where we stopped the search:
94 */
95 mm->free_area_cache = addr + len;
96 return addr;
97 }
98 if (addr + mm->cached_hole_size < vma->vm_start)
99 mm->cached_hole_size = vma->vm_start - addr;
100
101 addr = vma->vm_end;
102 if (do_colour_align)
103 addr = COLOUR_ALIGN(addr, pgoff);
104 }
105}
106#endif /* CONFIG_MMU */
13 107
14/* 108/*
15 * You really shouldn't be using read() or write() on /dev/mem. This 109 * You really shouldn't be using read() or write() on /dev/mem. This
diff --git a/arch/sh/oprofile/Makefile b/arch/sh/oprofile/Makefile
index 2efc2e79fd29..8e6eec91c14c 100644
--- a/arch/sh/oprofile/Makefile
+++ b/arch/sh/oprofile/Makefile
@@ -6,13 +6,8 @@ DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
6 oprofilefs.o oprofile_stats.o \ 6 oprofilefs.o oprofile_stats.o \
7 timer_int.o ) 7 timer_int.o )
8 8
9profdrvr-y := op_model_null.o 9oprofile-y := $(DRIVER_OBJS) common.o backtrace.o
10 10
11# SH7750-style performance counters exist across 7750/7750S and 7091. 11oprofile-$(CONFIG_CPU_SUBTYPE_SH7750S) += op_model_sh7750.o
12profdrvr-$(CONFIG_CPU_SUBTYPE_SH7750S) := op_model_sh7750.o 12oprofile-$(CONFIG_CPU_SUBTYPE_SH7750) += op_model_sh7750.o
13profdrvr-$(CONFIG_CPU_SUBTYPE_SH7750) := op_model_sh7750.o 13oprofile-$(CONFIG_CPU_SUBTYPE_SH7091) += op_model_sh7750.o
14profdrvr-$(CONFIG_CPU_SUBTYPE_SH7091) := op_model_sh7750.o
15
16oprofile-y := $(DRIVER_OBJS) $(profdrvr-y)
17
18EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/oprofile/backtrace.c b/arch/sh/oprofile/backtrace.c
new file mode 100644
index 000000000000..9499a2914f89
--- /dev/null
+++ b/arch/sh/oprofile/backtrace.c
@@ -0,0 +1,114 @@
1/*
2 * SH specific backtracing code for oprofile
3 *
4 * Copyright 2007 STMicroelectronics Ltd.
5 *
6 * Author: Dave Peverley <dpeverley@mpc-data.co.uk>
7 *
8 * Based on ARM oprofile backtrace code by Richard Purdie and in turn, i386
9 * oprofile backtrace code by John Levon, David Smith
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 version 2 as
13 * published by the Free Software Foundation.
14 *
15 */
16#include <linux/oprofile.h>
17#include <linux/sched.h>
18#include <linux/kallsyms.h>
19#include <linux/mm.h>
20#include <asm/ptrace.h>
21#include <asm/uaccess.h>
22#include <asm/sections.h>
23
24/* Limit to stop backtracing too far. */
25static int backtrace_limit = 20;
26
27static unsigned long *
28user_backtrace(unsigned long *stackaddr, struct pt_regs *regs)
29{
30 unsigned long buf_stack;
31
32 /* Also check accessibility of address */
33 if (!access_ok(VERIFY_READ, stackaddr, sizeof(unsigned long)))
34 return NULL;
35
36 if (__copy_from_user_inatomic(&buf_stack, stackaddr, sizeof(unsigned long)))
37 return NULL;
38
39 /* Quick paranoia check */
40 if (buf_stack & 3)
41 return NULL;
42
43 oprofile_add_trace(buf_stack);
44
45 stackaddr++;
46
47 return stackaddr;
48}
49
50/*
51 * | | /\ Higher addresses
52 * | |
53 * --------------- stack base (address of current_thread_info)
54 * | thread info |
55 * . .
56 * | stack |
57 * --------------- saved regs->regs[15] value if valid
58 * . .
59 * --------------- struct pt_regs stored on stack (struct pt_regs *)
60 * | |
61 * . .
62 * | |
63 * --------------- ???
64 * | |
65 * | | \/ Lower addresses
66 *
67 * Thus, &pt_regs <-> stack base restricts the valid(ish) fp values
68 */
69static int valid_kernel_stack(unsigned long *stackaddr, struct pt_regs *regs)
70{
71 unsigned long stack = (unsigned long)regs;
72 unsigned long stack_base = (stack & ~(THREAD_SIZE - 1)) + THREAD_SIZE;
73
74 return ((unsigned long)stackaddr > stack) && ((unsigned long)stackaddr < stack_base);
75}
76
77static unsigned long *
78kernel_backtrace(unsigned long *stackaddr, struct pt_regs *regs)
79{
80 unsigned long addr;
81
82 /*
83 * If not a valid kernel address, keep going till we find one
84 * or the SP stops being a valid address.
85 */
86 do {
87 addr = *stackaddr++;
88 oprofile_add_trace(addr);
89 } while (valid_kernel_stack(stackaddr, regs));
90
91 return stackaddr;
92}
93
94void sh_backtrace(struct pt_regs * const regs, unsigned int depth)
95{
96 unsigned long *stackaddr;
97
98 /*
99 * Paranoia - clip max depth as we could get lost in the weeds.
100 */
101 if (depth > backtrace_limit)
102 depth = backtrace_limit;
103
104 stackaddr = (unsigned long *)regs->regs[15];
105 if (!user_mode(regs)) {
106 while (depth-- && valid_kernel_stack(stackaddr, regs))
107 stackaddr = kernel_backtrace(stackaddr, regs);
108
109 return;
110 }
111
112 while (depth-- && (stackaddr != NULL))
113 stackaddr = user_backtrace(stackaddr, regs);
114}
diff --git a/arch/sh/oprofile/common.c b/arch/sh/oprofile/common.c
new file mode 100644
index 000000000000..1d97d64cb95f
--- /dev/null
+++ b/arch/sh/oprofile/common.c
@@ -0,0 +1,150 @@
1/*
2 * arch/sh/oprofile/init.c
3 *
4 * Copyright (C) 2003 - 2008 Paul Mundt
5 *
6 * Based on arch/mips/oprofile/common.c:
7 *
8 * Copyright (C) 2004, 2005 Ralf Baechle
9 * Copyright (C) 2005 MIPS Technologies, Inc.
10 *
11 * This file is subject to the terms and conditions of the GNU General Public
12 * License. See the file "COPYING" in the main directory of this archive
13 * for more details.
14 */
15#include <linux/kernel.h>
16#include <linux/oprofile.h>
17#include <linux/init.h>
18#include <linux/errno.h>
19#include <linux/smp.h>
20#include <asm/processor.h>
21#include "op_impl.h"
22
23extern struct op_sh_model op_model_sh7750_ops __weak;
24extern struct op_sh_model op_model_sh4a_ops __weak;
25
26static struct op_sh_model *model;
27
28static struct op_counter_config ctr[20];
29
30extern void sh_backtrace(struct pt_regs * const regs, unsigned int depth);
31
32static int op_sh_setup(void)
33{
34 /* Pre-compute the values to stuff in the hardware registers. */
35 model->reg_setup(ctr);
36
37 /* Configure the registers on all cpus. */
38 on_each_cpu(model->cpu_setup, NULL, 1);
39
40 return 0;
41}
42
43static int op_sh_create_files(struct super_block *sb, struct dentry *root)
44{
45 int i, ret = 0;
46
47 for (i = 0; i < model->num_counters; i++) {
48 struct dentry *dir;
49 char buf[4];
50
51 snprintf(buf, sizeof(buf), "%d", i);
52 dir = oprofilefs_mkdir(sb, root, buf);
53
54 ret |= oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled);
55 ret |= oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event);
56 ret |= oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel);
57 ret |= oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user);
58
59 if (model->create_files)
60 ret |= model->create_files(sb, dir);
61 else
62 ret |= oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count);
63
64 /* Dummy entries */
65 ret |= oprofilefs_create_ulong(sb, dir, "unit_mask", &ctr[i].unit_mask);
66 }
67
68 return ret;
69}
70
71static int op_sh_start(void)
72{
73 /* Enable performance monitoring for all counters. */
74 on_each_cpu(model->cpu_start, NULL, 1);
75
76 return 0;
77}
78
79static void op_sh_stop(void)
80{
81 /* Disable performance monitoring for all counters. */
82 on_each_cpu(model->cpu_stop, NULL, 1);
83}
84
85int __init oprofile_arch_init(struct oprofile_operations *ops)
86{
87 struct op_sh_model *lmodel = NULL;
88 int ret;
89
90 /*
91 * Always assign the backtrace op. If the counter initialization
92 * fails, we fall back to the timer which will still make use of
93 * this.
94 */
95 ops->backtrace = sh_backtrace;
96
97 switch (current_cpu_data.type) {
98 /* SH-4 types */
99 case CPU_SH7750:
100 case CPU_SH7750S:
101 lmodel = &op_model_sh7750_ops;
102 break;
103
104 /* SH-4A types */
105 case CPU_SH7763:
106 case CPU_SH7770:
107 case CPU_SH7780:
108 case CPU_SH7781:
109 case CPU_SH7785:
110 case CPU_SH7723:
111 case CPU_SHX3:
112 lmodel = &op_model_sh4a_ops;
113 break;
114
115 /* SH4AL-DSP types */
116 case CPU_SH7343:
117 case CPU_SH7722:
118 case CPU_SH7366:
119 lmodel = &op_model_sh4a_ops;
120 break;
121 }
122
123 if (!lmodel)
124 return -ENODEV;
125 if (!(current_cpu_data.flags & CPU_HAS_PERF_COUNTER))
126 return -ENODEV;
127
128 ret = lmodel->init();
129 if (unlikely(ret != 0))
130 return ret;
131
132 model = lmodel;
133
134 ops->setup = op_sh_setup;
135 ops->create_files = op_sh_create_files;
136 ops->start = op_sh_start;
137 ops->stop = op_sh_stop;
138 ops->cpu_type = lmodel->cpu_type;
139
140 printk(KERN_INFO "oprofile: using %s performance monitoring.\n",
141 lmodel->cpu_type);
142
143 return 0;
144}
145
146void oprofile_arch_exit(void)
147{
148 if (model && model->exit)
149 model->exit();
150}
diff --git a/arch/sh/oprofile/op_impl.h b/arch/sh/oprofile/op_impl.h
new file mode 100644
index 000000000000..4d509975eba6
--- /dev/null
+++ b/arch/sh/oprofile/op_impl.h
@@ -0,0 +1,33 @@
1#ifndef __OP_IMPL_H
2#define __OP_IMPL_H
3
4/* Per-counter configuration as set via oprofilefs. */
5struct op_counter_config {
6 unsigned long enabled;
7 unsigned long event;
8
9 unsigned long long count;
10
11 /* Dummy values for userspace tool compliance */
12 unsigned long kernel;
13 unsigned long user;
14 unsigned long unit_mask;
15};
16
17/* Per-architecture configury and hooks. */
18struct op_sh_model {
19 void (*reg_setup)(struct op_counter_config *);
20 int (*create_files)(struct super_block *sb, struct dentry *dir);
21 void (*cpu_setup)(void *dummy);
22 int (*init)(void);
23 void (*exit)(void);
24 void (*cpu_start)(void *args);
25 void (*cpu_stop)(void *args);
26 char *cpu_type;
27 unsigned char num_counters;
28};
29
30/* arch/sh/oprofile/common.c */
31extern void sh_backtrace(struct pt_regs * const regs, unsigned int depth);
32
33#endif /* __OP_IMPL_H */
diff --git a/arch/sh/oprofile/op_model_null.c b/arch/sh/oprofile/op_model_null.c
deleted file mode 100644
index a845b088edb4..000000000000
--- a/arch/sh/oprofile/op_model_null.c
+++ /dev/null
@@ -1,23 +0,0 @@
1/*
2 * arch/sh/oprofile/op_model_null.c
3 *
4 * Copyright (C) 2003 Paul Mundt
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10#include <linux/kernel.h>
11#include <linux/oprofile.h>
12#include <linux/init.h>
13#include <linux/errno.h>
14
15int __init oprofile_arch_init(struct oprofile_operations *ops)
16{
17 return -ENODEV;
18}
19
20void oprofile_arch_exit(void)
21{
22}
23
diff --git a/arch/sh/oprofile/op_model_sh7750.c b/arch/sh/oprofile/op_model_sh7750.c
index 008b3b03750a..c892c7c30c2f 100644
--- a/arch/sh/oprofile/op_model_sh7750.c
+++ b/arch/sh/oprofile/op_model_sh7750.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * OProfile support for SH7750/SH7750S Performance Counters 4 * OProfile support for SH7750/SH7750S Performance Counters
5 * 5 *
6 * Copyright (C) 2003, 2004 Paul Mundt 6 * Copyright (C) 2003 - 2008 Paul Mundt
7 * 7 *
8 * This file is subject to the terms and conditions of the GNU General Public 8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive 9 * License. See the file "COPYING" in the main directory of this archive
@@ -15,19 +15,16 @@
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/errno.h> 16#include <linux/errno.h>
17#include <linux/interrupt.h> 17#include <linux/interrupt.h>
18#include <linux/io.h>
18#include <linux/fs.h> 19#include <linux/fs.h>
19#include <asm/uaccess.h> 20#include "op_impl.h"
20#include <asm/io.h>
21 21
22#define PM_CR_BASE 0xff000084 /* 16-bit */ 22#define PM_CR_BASE 0xff000084 /* 16-bit */
23#define PM_CTR_BASE 0xff100004 /* 32-bit */ 23#define PM_CTR_BASE 0xff100004 /* 32-bit */
24 24
25#define PMCR1 (PM_CR_BASE + 0x00) 25#define PMCR(n) (PM_CR_BASE + ((n) * 0x04))
26#define PMCR2 (PM_CR_BASE + 0x04) 26#define PMCTRH(n) (PM_CTR_BASE + 0x00 + ((n) * 0x08))
27#define PMCTR1H (PM_CTR_BASE + 0x00) 27#define PMCTRL(n) (PM_CTR_BASE + 0x04 + ((n) * 0x08))
28#define PMCTR1L (PM_CTR_BASE + 0x04)
29#define PMCTR2H (PM_CTR_BASE + 0x08)
30#define PMCTR2L (PM_CTR_BASE + 0x0c)
31 28
32#define PMCR_PMM_MASK 0x0000003f 29#define PMCR_PMM_MASK 0x0000003f
33 30
@@ -36,25 +33,15 @@
36#define PMCR_PMST 0x00004000 33#define PMCR_PMST 0x00004000
37#define PMCR_PMEN 0x00008000 34#define PMCR_PMEN 0x00008000
38 35
39#define PMCR_ENABLE (PMCR_PMST | PMCR_PMEN) 36struct op_sh_model op_model_sh7750_ops;
40 37
41/*
42 * SH7750/SH7750S have 2 perf counters
43 */
44#define NR_CNTRS 2 38#define NR_CNTRS 2
45 39
46struct op_counter_config { 40static struct sh7750_ppc_register_config {
47 unsigned long enabled; 41 unsigned int ctrl;
48 unsigned long event; 42 unsigned long cnt_hi;
49 unsigned long count; 43 unsigned long cnt_lo;
50 44} regcache[NR_CNTRS];
51 /* Dummy values for userspace tool compliance */
52 unsigned long kernel;
53 unsigned long user;
54 unsigned long unit_mask;
55};
56
57static struct op_counter_config ctr[NR_CNTRS];
58 45
59/* 46/*
60 * There are a number of events supported by each counter (33 in total). 47 * There are a number of events supported by each counter (33 in total).
@@ -116,12 +103,8 @@ static int sh7750_timer_notify(struct pt_regs *regs)
116 103
117static u64 sh7750_read_counter(int counter) 104static u64 sh7750_read_counter(int counter)
118{ 105{
119 u32 hi, lo; 106 return (u64)((u64)(__raw_readl(PMCTRH(counter)) & 0xffff) << 32) |
120 107 __raw_readl(PMCTRL(counter));
121 hi = (counter == 0) ? ctrl_inl(PMCTR1H) : ctrl_inl(PMCTR2H);
122 lo = (counter == 0) ? ctrl_inl(PMCTR1L) : ctrl_inl(PMCTR2L);
123
124 return (u64)((u64)(hi & 0xffff) << 32) | lo;
125} 108}
126 109
127/* 110/*
@@ -170,11 +153,7 @@ static ssize_t sh7750_write_count(struct file *file, const char __user *buf,
170 */ 153 */
171 WARN_ON(val != 0); 154 WARN_ON(val != 0);
172 155
173 if (counter == 0) { 156 __raw_writew(__raw_readw(PMCR(counter)) | PMCR_PMCLR, PMCR(counter));
174 ctrl_outw(ctrl_inw(PMCR1) | PMCR_PMCLR, PMCR1);
175 } else {
176 ctrl_outw(ctrl_inw(PMCR2) | PMCR_PMCLR, PMCR2);
177 }
178 157
179 return count; 158 return count;
180} 159}
@@ -184,88 +163,93 @@ static const struct file_operations count_fops = {
184 .write = sh7750_write_count, 163 .write = sh7750_write_count,
185}; 164};
186 165
187static int sh7750_perf_counter_create_files(struct super_block *sb, struct dentry *root) 166static int sh7750_ppc_create_files(struct super_block *sb, struct dentry *dir)
188{ 167{
189 int i; 168 return oprofilefs_create_file(sb, dir, "count", &count_fops);
169}
190 170
191 for (i = 0; i < NR_CNTRS; i++) { 171static void sh7750_ppc_reg_setup(struct op_counter_config *ctr)
192 struct dentry *dir; 172{
193 char buf[4]; 173 unsigned int counters = op_model_sh7750_ops.num_counters;
174 int i;
194 175
195 snprintf(buf, sizeof(buf), "%d", i); 176 for (i = 0; i < counters; i++) {
196 dir = oprofilefs_mkdir(sb, root, buf); 177 regcache[i].ctrl = 0;
178 regcache[i].cnt_hi = 0;
179 regcache[i].cnt_lo = 0;
197 180
198 oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled); 181 if (!ctr[i].enabled)
199 oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event); 182 continue;
200 oprofilefs_create_file(sb, dir, "count", &count_fops);
201 183
202 /* Dummy entries */ 184 regcache[i].ctrl |= ctr[i].event | PMCR_PMEN | PMCR_PMST;
203 oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel); 185 regcache[i].cnt_hi = (unsigned long)((ctr->count >> 32) & 0xffff);
204 oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user); 186 regcache[i].cnt_lo = (unsigned long)(ctr->count & 0xffffffff);
205 oprofilefs_create_ulong(sb, dir, "unit_mask", &ctr[i].unit_mask);
206 } 187 }
207
208 return 0;
209} 188}
210 189
211static int sh7750_perf_counter_start(void) 190static void sh7750_ppc_cpu_setup(void *args)
212{ 191{
213 u16 pmcr; 192 unsigned int counters = op_model_sh7750_ops.num_counters;
214 193 int i;
215 /* Enable counter 1 */
216 if (ctr[0].enabled) {
217 pmcr = ctrl_inw(PMCR1);
218 WARN_ON(pmcr & PMCR_PMEN);
219
220 pmcr &= ~PMCR_PMM_MASK;
221 pmcr |= ctr[0].event;
222 ctrl_outw(pmcr | PMCR_ENABLE, PMCR1);
223 }
224
225 /* Enable counter 2 */
226 if (ctr[1].enabled) {
227 pmcr = ctrl_inw(PMCR2);
228 WARN_ON(pmcr & PMCR_PMEN);
229 194
230 pmcr &= ~PMCR_PMM_MASK; 195 for (i = 0; i < counters; i++) {
231 pmcr |= ctr[1].event; 196 __raw_writew(0, PMCR(i));
232 ctrl_outw(pmcr | PMCR_ENABLE, PMCR2); 197 __raw_writel(regcache[i].cnt_hi, PMCTRH(i));
198 __raw_writel(regcache[i].cnt_lo, PMCTRL(i));
233 } 199 }
234
235 return register_timer_hook(sh7750_timer_notify);
236} 200}
237 201
238static void sh7750_perf_counter_stop(void) 202static void sh7750_ppc_cpu_start(void *args)
239{ 203{
240 ctrl_outw(ctrl_inw(PMCR1) & ~PMCR_PMEN, PMCR1); 204 unsigned int counters = op_model_sh7750_ops.num_counters;
241 ctrl_outw(ctrl_inw(PMCR2) & ~PMCR_PMEN, PMCR2); 205 int i;
242 206
243 unregister_timer_hook(sh7750_timer_notify); 207 for (i = 0; i < counters; i++)
208 __raw_writew(regcache[i].ctrl, PMCR(i));
244} 209}
245 210
246static struct oprofile_operations sh7750_perf_counter_ops = { 211static void sh7750_ppc_cpu_stop(void *args)
247 .create_files = sh7750_perf_counter_create_files,
248 .start = sh7750_perf_counter_start,
249 .stop = sh7750_perf_counter_stop,
250};
251
252int __init oprofile_arch_init(struct oprofile_operations *ops)
253{ 212{
254 if (!(current_cpu_data.flags & CPU_HAS_PERF_COUNTER)) 213 unsigned int counters = op_model_sh7750_ops.num_counters;
255 return -ENODEV; 214 int i;
256 215
257 ops = &sh7750_perf_counter_ops; 216 /* Disable the counters */
258 ops->cpu_type = "sh/sh7750"; 217 for (i = 0; i < counters; i++)
218 __raw_writew(__raw_readw(PMCR(i)) & ~PMCR_PMEN, PMCR(i));
219}
259 220
260 printk(KERN_INFO "oprofile: using SH-4 performance monitoring.\n"); 221static inline void sh7750_ppc_reset(void)
222{
223 unsigned int counters = op_model_sh7750_ops.num_counters;
224 int i;
261 225
262 /* Clear the counters */ 226 /* Clear the counters */
263 ctrl_outw(ctrl_inw(PMCR1) | PMCR_PMCLR, PMCR1); 227 for (i = 0; i < counters; i++)
264 ctrl_outw(ctrl_inw(PMCR2) | PMCR_PMCLR, PMCR2); 228 __raw_writew(__raw_readw(PMCR(i)) | PMCR_PMCLR, PMCR(i));
229}
265 230
266 return 0; 231static int sh7750_ppc_init(void)
232{
233 sh7750_ppc_reset();
234
235 return register_timer_hook(sh7750_timer_notify);
267} 236}
268 237
269void oprofile_arch_exit(void) 238static void sh7750_ppc_exit(void)
270{ 239{
240 unregister_timer_hook(sh7750_timer_notify);
241
242 sh7750_ppc_reset();
271} 243}
244
245struct op_sh_model op_model_sh7750_ops = {
246 .cpu_type = "sh/sh7750",
247 .num_counters = NR_CNTRS,
248 .reg_setup = sh7750_ppc_reg_setup,
249 .cpu_setup = sh7750_ppc_cpu_setup,
250 .cpu_start = sh7750_ppc_cpu_start,
251 .cpu_stop = sh7750_ppc_cpu_stop,
252 .init = sh7750_ppc_init,
253 .exit = sh7750_ppc_exit,
254 .create_files = sh7750_ppc_create_files,
255};
diff --git a/arch/sh/tools/mach-types b/arch/sh/tools/mach-types
index d0c2928d1066..284b7e867496 100644
--- a/arch/sh/tools/mach-types
+++ b/arch/sh/tools/mach-types
@@ -8,6 +8,7 @@
8SE SH_SOLUTION_ENGINE 8SE SH_SOLUTION_ENGINE
9HIGHLANDER SH_HIGHLANDER 9HIGHLANDER SH_HIGHLANDER
10RTS7751R2D SH_RTS7751R2D 10RTS7751R2D SH_RTS7751R2D
11RSK SH_RSK
11 12
12# 13#
13# List of companion chips / MFDs. 14# List of companion chips / MFDs.
@@ -46,6 +47,7 @@ R2D_1 RTS7751R2D_1
46CAYMAN SH_CAYMAN 47CAYMAN SH_CAYMAN
47SDK7780 SH_SDK7780 48SDK7780 SH_SDK7780
48MIGOR SH_MIGOR 49MIGOR SH_MIGOR
50RSK7201 SH_RSK7201
49RSK7203 SH_RSK7203 51RSK7203 SH_RSK7203
50AP325RXA SH_AP325RXA 52AP325RXA SH_AP325RXA
51SH7763RDP SH_SH7763RDP 53SH7763RDP SH_SH7763RDP
diff --git a/arch/x86/crypto/crc32c-intel.c b/arch/x86/crypto/crc32c-intel.c
index 070afc5b6c94..b9d00261703c 100644
--- a/arch/x86/crypto/crc32c-intel.c
+++ b/arch/x86/crypto/crc32c-intel.c
@@ -6,13 +6,22 @@
6 * Intel(R) 64 and IA-32 Architectures Software Developer's Manual 6 * Intel(R) 64 and IA-32 Architectures Software Developer's Manual
7 * Volume 2A: Instruction Set Reference, A-M 7 * Volume 2A: Instruction Set Reference, A-M
8 * 8 *
9 * Copyright (c) 2008 Austin Zhang <austin_zhang@linux.intel.com> 9 * Copyright (C) 2008 Intel Corporation
10 * Copyright (c) 2008 Kent Liu <kent.liu@intel.com> 10 * Authors: Austin Zhang <austin_zhang@linux.intel.com>
11 * Kent Liu <kent.liu@intel.com>
11 * 12 *
12 * This program is free software; you can redistribute it and/or modify it 13 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the Free 14 * under the terms and conditions of the GNU General Public License,
14 * Software Foundation; either version 2 of the License, or (at your option) 15 * version 2, as published by the Free Software Foundation.
15 * any later version. 16 *
17 * This program is distributed in the hope it will be useful, but WITHOUT
18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
20 * more details.
21 *
22 * You should have received a copy of the GNU General Public License along with
23 * this program; if not, write to the Free Software Foundation, Inc.,
24 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
16 * 25 *
17 */ 26 */
18#include <linux/init.h> 27#include <linux/init.h>
@@ -75,99 +84,92 @@ static u32 __pure crc32c_intel_le_hw(u32 crc, unsigned char const *p, size_t len
75 * If your algorithm starts with ~0, then XOR with ~0 before you set 84 * If your algorithm starts with ~0, then XOR with ~0 before you set
76 * the seed. 85 * the seed.
77 */ 86 */
78static int crc32c_intel_setkey(struct crypto_ahash *hash, const u8 *key, 87static int crc32c_intel_setkey(struct crypto_shash *hash, const u8 *key,
79 unsigned int keylen) 88 unsigned int keylen)
80{ 89{
81 u32 *mctx = crypto_ahash_ctx(hash); 90 u32 *mctx = crypto_shash_ctx(hash);
82 91
83 if (keylen != sizeof(u32)) { 92 if (keylen != sizeof(u32)) {
84 crypto_ahash_set_flags(hash, CRYPTO_TFM_RES_BAD_KEY_LEN); 93 crypto_shash_set_flags(hash, CRYPTO_TFM_RES_BAD_KEY_LEN);
85 return -EINVAL; 94 return -EINVAL;
86 } 95 }
87 *mctx = le32_to_cpup((__le32 *)key); 96 *mctx = le32_to_cpup((__le32 *)key);
88 return 0; 97 return 0;
89} 98}
90 99
91static int crc32c_intel_init(struct ahash_request *req) 100static int crc32c_intel_init(struct shash_desc *desc)
92{ 101{
93 u32 *mctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req)); 102 u32 *mctx = crypto_shash_ctx(desc->tfm);
94 u32 *crcp = ahash_request_ctx(req); 103 u32 *crcp = shash_desc_ctx(desc);
95 104
96 *crcp = *mctx; 105 *crcp = *mctx;
97 106
98 return 0; 107 return 0;
99} 108}
100 109
101static int crc32c_intel_update(struct ahash_request *req) 110static int crc32c_intel_update(struct shash_desc *desc, const u8 *data,
111 unsigned int len)
102{ 112{
103 struct crypto_hash_walk walk; 113 u32 *crcp = shash_desc_ctx(desc);
104 u32 *crcp = ahash_request_ctx(req);
105 u32 crc = *crcp;
106 int nbytes;
107
108 for (nbytes = crypto_hash_walk_first(req, &walk); nbytes;
109 nbytes = crypto_hash_walk_done(&walk, 0))
110 crc = crc32c_intel_le_hw(crc, walk.data, nbytes);
111 114
112 *crcp = crc; 115 *crcp = crc32c_intel_le_hw(*crcp, data, len);
113 return 0; 116 return 0;
114} 117}
115 118
116static int crc32c_intel_final(struct ahash_request *req) 119static int __crc32c_intel_finup(u32 *crcp, const u8 *data, unsigned int len,
120 u8 *out)
117{ 121{
118 u32 *crcp = ahash_request_ctx(req); 122 *(__le32 *)out = ~cpu_to_le32(crc32c_intel_le_hw(*crcp, data, len));
119
120 *(__le32 *)req->result = ~cpu_to_le32p(crcp);
121 return 0; 123 return 0;
122} 124}
123 125
124static int crc32c_intel_digest(struct ahash_request *req) 126static int crc32c_intel_finup(struct shash_desc *desc, const u8 *data,
127 unsigned int len, u8 *out)
125{ 128{
126 struct crypto_hash_walk walk; 129 return __crc32c_intel_finup(shash_desc_ctx(desc), data, len, out);
127 u32 *mctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req)); 130}
128 u32 crc = *mctx;
129 int nbytes;
130 131
131 for (nbytes = crypto_hash_walk_first(req, &walk); nbytes; 132static int crc32c_intel_final(struct shash_desc *desc, u8 *out)
132 nbytes = crypto_hash_walk_done(&walk, 0)) 133{
133 crc = crc32c_intel_le_hw(crc, walk.data, nbytes); 134 u32 *crcp = shash_desc_ctx(desc);
134 135
135 *(__le32 *)req->result = ~cpu_to_le32(crc); 136 *(__le32 *)out = ~cpu_to_le32p(crcp);
136 return 0; 137 return 0;
137} 138}
138 139
140static int crc32c_intel_digest(struct shash_desc *desc, const u8 *data,
141 unsigned int len, u8 *out)
142{
143 return __crc32c_intel_finup(crypto_shash_ctx(desc->tfm), data, len,
144 out);
145}
146
139static int crc32c_intel_cra_init(struct crypto_tfm *tfm) 147static int crc32c_intel_cra_init(struct crypto_tfm *tfm)
140{ 148{
141 u32 *key = crypto_tfm_ctx(tfm); 149 u32 *key = crypto_tfm_ctx(tfm);
142 150
143 *key = ~0; 151 *key = ~0;
144 152
145 tfm->crt_ahash.reqsize = sizeof(u32);
146
147 return 0; 153 return 0;
148} 154}
149 155
150static struct crypto_alg alg = { 156static struct shash_alg alg = {
151 .cra_name = "crc32c", 157 .setkey = crc32c_intel_setkey,
152 .cra_driver_name = "crc32c-intel", 158 .init = crc32c_intel_init,
153 .cra_priority = 200, 159 .update = crc32c_intel_update,
154 .cra_flags = CRYPTO_ALG_TYPE_AHASH, 160 .final = crc32c_intel_final,
155 .cra_blocksize = CHKSUM_BLOCK_SIZE, 161 .finup = crc32c_intel_finup,
156 .cra_alignmask = 3, 162 .digest = crc32c_intel_digest,
157 .cra_ctxsize = sizeof(u32), 163 .descsize = sizeof(u32),
158 .cra_module = THIS_MODULE, 164 .digestsize = CHKSUM_DIGEST_SIZE,
159 .cra_list = LIST_HEAD_INIT(alg.cra_list), 165 .base = {
160 .cra_init = crc32c_intel_cra_init, 166 .cra_name = "crc32c",
161 .cra_type = &crypto_ahash_type, 167 .cra_driver_name = "crc32c-intel",
162 .cra_u = { 168 .cra_priority = 200,
163 .ahash = { 169 .cra_blocksize = CHKSUM_BLOCK_SIZE,
164 .digestsize = CHKSUM_DIGEST_SIZE, 170 .cra_ctxsize = sizeof(u32),
165 .setkey = crc32c_intel_setkey, 171 .cra_module = THIS_MODULE,
166 .init = crc32c_intel_init, 172 .cra_init = crc32c_intel_cra_init,
167 .update = crc32c_intel_update,
168 .final = crc32c_intel_final,
169 .digest = crc32c_intel_digest,
170 }
171 } 173 }
172}; 174};
173 175
@@ -175,14 +177,14 @@ static struct crypto_alg alg = {
175static int __init crc32c_intel_mod_init(void) 177static int __init crc32c_intel_mod_init(void)
176{ 178{
177 if (cpu_has_xmm4_2) 179 if (cpu_has_xmm4_2)
178 return crypto_register_alg(&alg); 180 return crypto_register_shash(&alg);
179 else 181 else
180 return -ENODEV; 182 return -ENODEV;
181} 183}
182 184
183static void __exit crc32c_intel_mod_fini(void) 185static void __exit crc32c_intel_mod_fini(void)
184{ 186{
185 crypto_unregister_alg(&alg); 187 crypto_unregister_shash(&alg);
186} 188}
187 189
188module_init(crc32c_intel_mod_init); 190module_init(crc32c_intel_mod_init);
@@ -194,4 +196,3 @@ MODULE_LICENSE("GPL");
194 196
195MODULE_ALIAS("crc32c"); 197MODULE_ALIAS("crc32c");
196MODULE_ALIAS("crc32c-intel"); 198MODULE_ALIAS("crc32c-intel");
197
diff --git a/crypto/Kconfig b/crypto/Kconfig
index dc20a34ba5ef..8dde4fcf99c9 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -102,6 +102,7 @@ config CRYPTO_NULL
102 tristate "Null algorithms" 102 tristate "Null algorithms"
103 select CRYPTO_ALGAPI 103 select CRYPTO_ALGAPI
104 select CRYPTO_BLKCIPHER 104 select CRYPTO_BLKCIPHER
105 select CRYPTO_HASH
105 help 106 help
106 These are 'Null' algorithms, used by IPsec, which do nothing. 107 These are 'Null' algorithms, used by IPsec, which do nothing.
107 108
@@ -256,12 +257,10 @@ comment "Digest"
256config CRYPTO_CRC32C 257config CRYPTO_CRC32C
257 tristate "CRC32c CRC algorithm" 258 tristate "CRC32c CRC algorithm"
258 select CRYPTO_HASH 259 select CRYPTO_HASH
259 select LIBCRC32C
260 help 260 help
261 Castagnoli, et al Cyclic Redundancy-Check Algorithm. Used 261 Castagnoli, et al Cyclic Redundancy-Check Algorithm. Used
262 by iSCSI for header and data digests and by others. 262 by iSCSI for header and data digests and by others.
263 See Castagnoli93. This implementation uses lib/libcrc32c. 263 See Castagnoli93. Module will be crc32c.
264 Module will be crc32c.
265 264
266config CRYPTO_CRC32C_INTEL 265config CRYPTO_CRC32C_INTEL
267 tristate "CRC32c INTEL hardware acceleration" 266 tristate "CRC32c INTEL hardware acceleration"
@@ -277,19 +276,19 @@ config CRYPTO_CRC32C_INTEL
277 276
278config CRYPTO_MD4 277config CRYPTO_MD4
279 tristate "MD4 digest algorithm" 278 tristate "MD4 digest algorithm"
280 select CRYPTO_ALGAPI 279 select CRYPTO_HASH
281 help 280 help
282 MD4 message digest algorithm (RFC1320). 281 MD4 message digest algorithm (RFC1320).
283 282
284config CRYPTO_MD5 283config CRYPTO_MD5
285 tristate "MD5 digest algorithm" 284 tristate "MD5 digest algorithm"
286 select CRYPTO_ALGAPI 285 select CRYPTO_HASH
287 help 286 help
288 MD5 message digest algorithm (RFC1321). 287 MD5 message digest algorithm (RFC1321).
289 288
290config CRYPTO_MICHAEL_MIC 289config CRYPTO_MICHAEL_MIC
291 tristate "Michael MIC keyed digest algorithm" 290 tristate "Michael MIC keyed digest algorithm"
292 select CRYPTO_ALGAPI 291 select CRYPTO_HASH
293 help 292 help
294 Michael MIC is used for message integrity protection in TKIP 293 Michael MIC is used for message integrity protection in TKIP
295 (IEEE 802.11i). This algorithm is required for TKIP, but it 294 (IEEE 802.11i). This algorithm is required for TKIP, but it
@@ -298,7 +297,7 @@ config CRYPTO_MICHAEL_MIC
298 297
299config CRYPTO_RMD128 298config CRYPTO_RMD128
300 tristate "RIPEMD-128 digest algorithm" 299 tristate "RIPEMD-128 digest algorithm"
301 select CRYPTO_ALGAPI 300 select CRYPTO_HASH
302 help 301 help
303 RIPEMD-128 (ISO/IEC 10118-3:2004). 302 RIPEMD-128 (ISO/IEC 10118-3:2004).
304 303
@@ -311,7 +310,7 @@ config CRYPTO_RMD128
311 310
312config CRYPTO_RMD160 311config CRYPTO_RMD160
313 tristate "RIPEMD-160 digest algorithm" 312 tristate "RIPEMD-160 digest algorithm"
314 select CRYPTO_ALGAPI 313 select CRYPTO_HASH
315 help 314 help
316 RIPEMD-160 (ISO/IEC 10118-3:2004). 315 RIPEMD-160 (ISO/IEC 10118-3:2004).
317 316
@@ -328,7 +327,7 @@ config CRYPTO_RMD160
328 327
329config CRYPTO_RMD256 328config CRYPTO_RMD256
330 tristate "RIPEMD-256 digest algorithm" 329 tristate "RIPEMD-256 digest algorithm"
331 select CRYPTO_ALGAPI 330 select CRYPTO_HASH
332 help 331 help
333 RIPEMD-256 is an optional extension of RIPEMD-128 with a 332 RIPEMD-256 is an optional extension of RIPEMD-128 with a
334 256 bit hash. It is intended for applications that require 333 256 bit hash. It is intended for applications that require
@@ -340,7 +339,7 @@ config CRYPTO_RMD256
340 339
341config CRYPTO_RMD320 340config CRYPTO_RMD320
342 tristate "RIPEMD-320 digest algorithm" 341 tristate "RIPEMD-320 digest algorithm"
343 select CRYPTO_ALGAPI 342 select CRYPTO_HASH
344 help 343 help
345 RIPEMD-320 is an optional extension of RIPEMD-160 with a 344 RIPEMD-320 is an optional extension of RIPEMD-160 with a
346 320 bit hash. It is intended for applications that require 345 320 bit hash. It is intended for applications that require
@@ -352,13 +351,13 @@ config CRYPTO_RMD320
352 351
353config CRYPTO_SHA1 352config CRYPTO_SHA1
354 tristate "SHA1 digest algorithm" 353 tristate "SHA1 digest algorithm"
355 select CRYPTO_ALGAPI 354 select CRYPTO_HASH
356 help 355 help
357 SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2). 356 SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2).
358 357
359config CRYPTO_SHA256 358config CRYPTO_SHA256
360 tristate "SHA224 and SHA256 digest algorithm" 359 tristate "SHA224 and SHA256 digest algorithm"
361 select CRYPTO_ALGAPI 360 select CRYPTO_HASH
362 help 361 help
363 SHA256 secure hash standard (DFIPS 180-2). 362 SHA256 secure hash standard (DFIPS 180-2).
364 363
@@ -370,7 +369,7 @@ config CRYPTO_SHA256
370 369
371config CRYPTO_SHA512 370config CRYPTO_SHA512
372 tristate "SHA384 and SHA512 digest algorithms" 371 tristate "SHA384 and SHA512 digest algorithms"
373 select CRYPTO_ALGAPI 372 select CRYPTO_HASH
374 help 373 help
375 SHA512 secure hash standard (DFIPS 180-2). 374 SHA512 secure hash standard (DFIPS 180-2).
376 375
@@ -382,7 +381,7 @@ config CRYPTO_SHA512
382 381
383config CRYPTO_TGR192 382config CRYPTO_TGR192
384 tristate "Tiger digest algorithms" 383 tristate "Tiger digest algorithms"
385 select CRYPTO_ALGAPI 384 select CRYPTO_HASH
386 help 385 help
387 Tiger hash algorithm 192, 160 and 128-bit hashes 386 Tiger hash algorithm 192, 160 and 128-bit hashes
388 387
@@ -395,7 +394,7 @@ config CRYPTO_TGR192
395 394
396config CRYPTO_WP512 395config CRYPTO_WP512
397 tristate "Whirlpool digest algorithms" 396 tristate "Whirlpool digest algorithms"
398 select CRYPTO_ALGAPI 397 select CRYPTO_HASH
399 help 398 help
400 Whirlpool hash algorithm 512, 384 and 256-bit hashes 399 Whirlpool hash algorithm 512, 384 and 256-bit hashes
401 400
diff --git a/crypto/Makefile b/crypto/Makefile
index cd4a4ed078ff..46b08bf2035f 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_CRYPTO_SEQIV) += seqiv.o
22 22
23crypto_hash-objs := hash.o 23crypto_hash-objs := hash.o
24crypto_hash-objs += ahash.o 24crypto_hash-objs += ahash.o
25crypto_hash-objs += shash.o
25obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o 26obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
26 27
27cryptomgr-objs := algboss.o testmgr.o 28cryptomgr-objs := algboss.o testmgr.o
diff --git a/crypto/aes_generic.c b/crypto/aes_generic.c
index 136dc98d8a03..b8b66ec3883b 100644
--- a/crypto/aes_generic.c
+++ b/crypto/aes_generic.c
@@ -60,102 +60,1068 @@ static inline u8 byte(const u32 x, const unsigned n)
60 return x >> (n << 3); 60 return x >> (n << 3);
61} 61}
62 62
63static u8 pow_tab[256] __initdata; 63static const u32 rco_tab[10] = { 1, 2, 4, 8, 16, 32, 64, 128, 27, 54 };
64static u8 log_tab[256] __initdata; 64
65static u8 sbx_tab[256] __initdata; 65const u32 crypto_ft_tab[4][256] = {
66static u8 isb_tab[256] __initdata; 66 {
67static u32 rco_tab[10]; 67 0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6,
68 68 0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591,
69u32 crypto_ft_tab[4][256]; 69 0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56,
70u32 crypto_fl_tab[4][256]; 70 0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec,
71u32 crypto_it_tab[4][256]; 71 0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa,
72u32 crypto_il_tab[4][256]; 72 0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb,
73 73 0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45,
74EXPORT_SYMBOL_GPL(crypto_ft_tab); 74 0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b,
75EXPORT_SYMBOL_GPL(crypto_fl_tab); 75 0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c,
76EXPORT_SYMBOL_GPL(crypto_it_tab); 76 0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83,
77EXPORT_SYMBOL_GPL(crypto_il_tab); 77 0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9,
78 78 0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a,
79static inline u8 __init f_mult(u8 a, u8 b) 79 0x0c040408, 0x52c7c795, 0x65232346, 0x5ec3c39d,
80{ 80 0x28181830, 0xa1969637, 0x0f05050a, 0xb59a9a2f,
81 u8 aa = log_tab[a], cc = aa + log_tab[b]; 81 0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df,
82 82 0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea,
83 return pow_tab[cc + (cc < aa ? 1 : 0)]; 83 0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34,
84} 84 0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b,
85 85 0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d,
86#define ff_mult(a, b) (a && b ? f_mult(a, b) : 0) 86 0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413,
87 87 0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1,
88static void __init gen_tabs(void) 88 0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6,
89{ 89 0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972,
90 u32 i, t; 90 0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85,
91 u8 p, q; 91 0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed,
92 92 0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511,
93 /* 93 0xcf45458a, 0x10f9f9e9, 0x06020204, 0x817f7ffe,
94 * log and power tables for GF(2**8) finite field with 94 0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b,
95 * 0x011b as modular polynomial - the simplest primitive 95 0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05,
96 * root is 0x03, used here to generate the tables 96 0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1,
97 */ 97 0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142,
98 98 0x30101020, 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf,
99 for (i = 0, p = 1; i < 256; ++i) { 99 0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3,
100 pow_tab[i] = (u8) p; 100 0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e,
101 log_tab[p] = (u8) i; 101 0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a,
102 102 0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6,
103 p ^= (p << 1) ^ (p & 0x80 ? 0x01b : 0); 103 0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3,
104 0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b,
105 0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428,
106 0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad,
107 0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14,
108 0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8,
109 0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4,
110 0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2,
111 0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda,
112 0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949,
113 0xb46c6cd8, 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf,
114 0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810,
115 0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c,
116 0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697,
117 0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e,
118 0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f,
119 0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc,
120 0xd8484890, 0x05030306, 0x01f6f6f7, 0x120e0e1c,
121 0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969,
122 0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27,
123 0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122,
124 0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433,
125 0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9,
126 0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5,
127 0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a,
128 0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0,
129 0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e,
130 0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c,
131 }, {
132 0x6363c6a5, 0x7c7cf884, 0x7777ee99, 0x7b7bf68d,
133 0xf2f2ff0d, 0x6b6bd6bd, 0x6f6fdeb1, 0xc5c59154,
134 0x30306050, 0x01010203, 0x6767cea9, 0x2b2b567d,
135 0xfefee719, 0xd7d7b562, 0xabab4de6, 0x7676ec9a,
136 0xcaca8f45, 0x82821f9d, 0xc9c98940, 0x7d7dfa87,
137 0xfafaef15, 0x5959b2eb, 0x47478ec9, 0xf0f0fb0b,
138 0xadad41ec, 0xd4d4b367, 0xa2a25ffd, 0xafaf45ea,
139 0x9c9c23bf, 0xa4a453f7, 0x7272e496, 0xc0c09b5b,
140 0xb7b775c2, 0xfdfde11c, 0x93933dae, 0x26264c6a,
141 0x36366c5a, 0x3f3f7e41, 0xf7f7f502, 0xcccc834f,
142 0x3434685c, 0xa5a551f4, 0xe5e5d134, 0xf1f1f908,
143 0x7171e293, 0xd8d8ab73, 0x31316253, 0x15152a3f,
144 0x0404080c, 0xc7c79552, 0x23234665, 0xc3c39d5e,
145 0x18183028, 0x969637a1, 0x05050a0f, 0x9a9a2fb5,
146 0x07070e09, 0x12122436, 0x80801b9b, 0xe2e2df3d,
147 0xebebcd26, 0x27274e69, 0xb2b27fcd, 0x7575ea9f,
148 0x0909121b, 0x83831d9e, 0x2c2c5874, 0x1a1a342e,
149 0x1b1b362d, 0x6e6edcb2, 0x5a5ab4ee, 0xa0a05bfb,
150 0x5252a4f6, 0x3b3b764d, 0xd6d6b761, 0xb3b37dce,
151 0x2929527b, 0xe3e3dd3e, 0x2f2f5e71, 0x84841397,
152 0x5353a6f5, 0xd1d1b968, 0x00000000, 0xededc12c,
153 0x20204060, 0xfcfce31f, 0xb1b179c8, 0x5b5bb6ed,
154 0x6a6ad4be, 0xcbcb8d46, 0xbebe67d9, 0x3939724b,
155 0x4a4a94de, 0x4c4c98d4, 0x5858b0e8, 0xcfcf854a,
156 0xd0d0bb6b, 0xefefc52a, 0xaaaa4fe5, 0xfbfbed16,
157 0x434386c5, 0x4d4d9ad7, 0x33336655, 0x85851194,
158 0x45458acf, 0xf9f9e910, 0x02020406, 0x7f7ffe81,
159 0x5050a0f0, 0x3c3c7844, 0x9f9f25ba, 0xa8a84be3,
160 0x5151a2f3, 0xa3a35dfe, 0x404080c0, 0x8f8f058a,
161 0x92923fad, 0x9d9d21bc, 0x38387048, 0xf5f5f104,
162 0xbcbc63df, 0xb6b677c1, 0xdadaaf75, 0x21214263,
163 0x10102030, 0xffffe51a, 0xf3f3fd0e, 0xd2d2bf6d,
164 0xcdcd814c, 0x0c0c1814, 0x13132635, 0xececc32f,
165 0x5f5fbee1, 0x979735a2, 0x444488cc, 0x17172e39,
166 0xc4c49357, 0xa7a755f2, 0x7e7efc82, 0x3d3d7a47,
167 0x6464c8ac, 0x5d5dbae7, 0x1919322b, 0x7373e695,
168 0x6060c0a0, 0x81811998, 0x4f4f9ed1, 0xdcdca37f,
169 0x22224466, 0x2a2a547e, 0x90903bab, 0x88880b83,
170 0x46468cca, 0xeeeec729, 0xb8b86bd3, 0x1414283c,
171 0xdedea779, 0x5e5ebce2, 0x0b0b161d, 0xdbdbad76,
172 0xe0e0db3b, 0x32326456, 0x3a3a744e, 0x0a0a141e,
173 0x494992db, 0x06060c0a, 0x2424486c, 0x5c5cb8e4,
174 0xc2c29f5d, 0xd3d3bd6e, 0xacac43ef, 0x6262c4a6,
175 0x919139a8, 0x959531a4, 0xe4e4d337, 0x7979f28b,
176 0xe7e7d532, 0xc8c88b43, 0x37376e59, 0x6d6ddab7,
177 0x8d8d018c, 0xd5d5b164, 0x4e4e9cd2, 0xa9a949e0,
178 0x6c6cd8b4, 0x5656acfa, 0xf4f4f307, 0xeaeacf25,
179 0x6565caaf, 0x7a7af48e, 0xaeae47e9, 0x08081018,
180 0xbaba6fd5, 0x7878f088, 0x25254a6f, 0x2e2e5c72,
181 0x1c1c3824, 0xa6a657f1, 0xb4b473c7, 0xc6c69751,
182 0xe8e8cb23, 0xdddda17c, 0x7474e89c, 0x1f1f3e21,
183 0x4b4b96dd, 0xbdbd61dc, 0x8b8b0d86, 0x8a8a0f85,
184 0x7070e090, 0x3e3e7c42, 0xb5b571c4, 0x6666ccaa,
185 0x484890d8, 0x03030605, 0xf6f6f701, 0x0e0e1c12,
186 0x6161c2a3, 0x35356a5f, 0x5757aef9, 0xb9b969d0,
187 0x86861791, 0xc1c19958, 0x1d1d3a27, 0x9e9e27b9,
188 0xe1e1d938, 0xf8f8eb13, 0x98982bb3, 0x11112233,
189 0x6969d2bb, 0xd9d9a970, 0x8e8e0789, 0x949433a7,
190 0x9b9b2db6, 0x1e1e3c22, 0x87871592, 0xe9e9c920,
191 0xcece8749, 0x5555aaff, 0x28285078, 0xdfdfa57a,
192 0x8c8c038f, 0xa1a159f8, 0x89890980, 0x0d0d1a17,
193 0xbfbf65da, 0xe6e6d731, 0x424284c6, 0x6868d0b8,
194 0x414182c3, 0x999929b0, 0x2d2d5a77, 0x0f0f1e11,
195 0xb0b07bcb, 0x5454a8fc, 0xbbbb6dd6, 0x16162c3a,
196 }, {
197 0x63c6a563, 0x7cf8847c, 0x77ee9977, 0x7bf68d7b,
198 0xf2ff0df2, 0x6bd6bd6b, 0x6fdeb16f, 0xc59154c5,
199 0x30605030, 0x01020301, 0x67cea967, 0x2b567d2b,
200 0xfee719fe, 0xd7b562d7, 0xab4de6ab, 0x76ec9a76,
201 0xca8f45ca, 0x821f9d82, 0xc98940c9, 0x7dfa877d,
202 0xfaef15fa, 0x59b2eb59, 0x478ec947, 0xf0fb0bf0,
203 0xad41ecad, 0xd4b367d4, 0xa25ffda2, 0xaf45eaaf,
204 0x9c23bf9c, 0xa453f7a4, 0x72e49672, 0xc09b5bc0,
205 0xb775c2b7, 0xfde11cfd, 0x933dae93, 0x264c6a26,
206 0x366c5a36, 0x3f7e413f, 0xf7f502f7, 0xcc834fcc,
207 0x34685c34, 0xa551f4a5, 0xe5d134e5, 0xf1f908f1,
208 0x71e29371, 0xd8ab73d8, 0x31625331, 0x152a3f15,
209 0x04080c04, 0xc79552c7, 0x23466523, 0xc39d5ec3,
210 0x18302818, 0x9637a196, 0x050a0f05, 0x9a2fb59a,
211 0x070e0907, 0x12243612, 0x801b9b80, 0xe2df3de2,
212 0xebcd26eb, 0x274e6927, 0xb27fcdb2, 0x75ea9f75,
213 0x09121b09, 0x831d9e83, 0x2c58742c, 0x1a342e1a,
214 0x1b362d1b, 0x6edcb26e, 0x5ab4ee5a, 0xa05bfba0,
215 0x52a4f652, 0x3b764d3b, 0xd6b761d6, 0xb37dceb3,
216 0x29527b29, 0xe3dd3ee3, 0x2f5e712f, 0x84139784,
217 0x53a6f553, 0xd1b968d1, 0x00000000, 0xedc12ced,
218 0x20406020, 0xfce31ffc, 0xb179c8b1, 0x5bb6ed5b,
219 0x6ad4be6a, 0xcb8d46cb, 0xbe67d9be, 0x39724b39,
220 0x4a94de4a, 0x4c98d44c, 0x58b0e858, 0xcf854acf,
221 0xd0bb6bd0, 0xefc52aef, 0xaa4fe5aa, 0xfbed16fb,
222 0x4386c543, 0x4d9ad74d, 0x33665533, 0x85119485,
223 0x458acf45, 0xf9e910f9, 0x02040602, 0x7ffe817f,
224 0x50a0f050, 0x3c78443c, 0x9f25ba9f, 0xa84be3a8,
225 0x51a2f351, 0xa35dfea3, 0x4080c040, 0x8f058a8f,
226 0x923fad92, 0x9d21bc9d, 0x38704838, 0xf5f104f5,
227 0xbc63dfbc, 0xb677c1b6, 0xdaaf75da, 0x21426321,
228 0x10203010, 0xffe51aff, 0xf3fd0ef3, 0xd2bf6dd2,
229 0xcd814ccd, 0x0c18140c, 0x13263513, 0xecc32fec,
230 0x5fbee15f, 0x9735a297, 0x4488cc44, 0x172e3917,
231 0xc49357c4, 0xa755f2a7, 0x7efc827e, 0x3d7a473d,
232 0x64c8ac64, 0x5dbae75d, 0x19322b19, 0x73e69573,
233 0x60c0a060, 0x81199881, 0x4f9ed14f, 0xdca37fdc,
234 0x22446622, 0x2a547e2a, 0x903bab90, 0x880b8388,
235 0x468cca46, 0xeec729ee, 0xb86bd3b8, 0x14283c14,
236 0xdea779de, 0x5ebce25e, 0x0b161d0b, 0xdbad76db,
237 0xe0db3be0, 0x32645632, 0x3a744e3a, 0x0a141e0a,
238 0x4992db49, 0x060c0a06, 0x24486c24, 0x5cb8e45c,
239 0xc29f5dc2, 0xd3bd6ed3, 0xac43efac, 0x62c4a662,
240 0x9139a891, 0x9531a495, 0xe4d337e4, 0x79f28b79,
241 0xe7d532e7, 0xc88b43c8, 0x376e5937, 0x6ddab76d,
242 0x8d018c8d, 0xd5b164d5, 0x4e9cd24e, 0xa949e0a9,
243 0x6cd8b46c, 0x56acfa56, 0xf4f307f4, 0xeacf25ea,
244 0x65caaf65, 0x7af48e7a, 0xae47e9ae, 0x08101808,
245 0xba6fd5ba, 0x78f08878, 0x254a6f25, 0x2e5c722e,
246 0x1c38241c, 0xa657f1a6, 0xb473c7b4, 0xc69751c6,
247 0xe8cb23e8, 0xdda17cdd, 0x74e89c74, 0x1f3e211f,
248 0x4b96dd4b, 0xbd61dcbd, 0x8b0d868b, 0x8a0f858a,
249 0x70e09070, 0x3e7c423e, 0xb571c4b5, 0x66ccaa66,
250 0x4890d848, 0x03060503, 0xf6f701f6, 0x0e1c120e,
251 0x61c2a361, 0x356a5f35, 0x57aef957, 0xb969d0b9,
252 0x86179186, 0xc19958c1, 0x1d3a271d, 0x9e27b99e,
253 0xe1d938e1, 0xf8eb13f8, 0x982bb398, 0x11223311,
254 0x69d2bb69, 0xd9a970d9, 0x8e07898e, 0x9433a794,
255 0x9b2db69b, 0x1e3c221e, 0x87159287, 0xe9c920e9,
256 0xce8749ce, 0x55aaff55, 0x28507828, 0xdfa57adf,
257 0x8c038f8c, 0xa159f8a1, 0x89098089, 0x0d1a170d,
258 0xbf65dabf, 0xe6d731e6, 0x4284c642, 0x68d0b868,
259 0x4182c341, 0x9929b099, 0x2d5a772d, 0x0f1e110f,
260 0xb07bcbb0, 0x54a8fc54, 0xbb6dd6bb, 0x162c3a16,
261 }, {
262 0xc6a56363, 0xf8847c7c, 0xee997777, 0xf68d7b7b,
263 0xff0df2f2, 0xd6bd6b6b, 0xdeb16f6f, 0x9154c5c5,
264 0x60503030, 0x02030101, 0xcea96767, 0x567d2b2b,
265 0xe719fefe, 0xb562d7d7, 0x4de6abab, 0xec9a7676,
266 0x8f45caca, 0x1f9d8282, 0x8940c9c9, 0xfa877d7d,
267 0xef15fafa, 0xb2eb5959, 0x8ec94747, 0xfb0bf0f0,
268 0x41ecadad, 0xb367d4d4, 0x5ffda2a2, 0x45eaafaf,
269 0x23bf9c9c, 0x53f7a4a4, 0xe4967272, 0x9b5bc0c0,
270 0x75c2b7b7, 0xe11cfdfd, 0x3dae9393, 0x4c6a2626,
271 0x6c5a3636, 0x7e413f3f, 0xf502f7f7, 0x834fcccc,
272 0x685c3434, 0x51f4a5a5, 0xd134e5e5, 0xf908f1f1,
273 0xe2937171, 0xab73d8d8, 0x62533131, 0x2a3f1515,
274 0x080c0404, 0x9552c7c7, 0x46652323, 0x9d5ec3c3,
275 0x30281818, 0x37a19696, 0x0a0f0505, 0x2fb59a9a,
276 0x0e090707, 0x24361212, 0x1b9b8080, 0xdf3de2e2,
277 0xcd26ebeb, 0x4e692727, 0x7fcdb2b2, 0xea9f7575,
278 0x121b0909, 0x1d9e8383, 0x58742c2c, 0x342e1a1a,
279 0x362d1b1b, 0xdcb26e6e, 0xb4ee5a5a, 0x5bfba0a0,
280 0xa4f65252, 0x764d3b3b, 0xb761d6d6, 0x7dceb3b3,
281 0x527b2929, 0xdd3ee3e3, 0x5e712f2f, 0x13978484,
282 0xa6f55353, 0xb968d1d1, 0x00000000, 0xc12ceded,
283 0x40602020, 0xe31ffcfc, 0x79c8b1b1, 0xb6ed5b5b,
284 0xd4be6a6a, 0x8d46cbcb, 0x67d9bebe, 0x724b3939,
285 0x94de4a4a, 0x98d44c4c, 0xb0e85858, 0x854acfcf,
286 0xbb6bd0d0, 0xc52aefef, 0x4fe5aaaa, 0xed16fbfb,
287 0x86c54343, 0x9ad74d4d, 0x66553333, 0x11948585,
288 0x8acf4545, 0xe910f9f9, 0x04060202, 0xfe817f7f,
289 0xa0f05050, 0x78443c3c, 0x25ba9f9f, 0x4be3a8a8,
290 0xa2f35151, 0x5dfea3a3, 0x80c04040, 0x058a8f8f,
291 0x3fad9292, 0x21bc9d9d, 0x70483838, 0xf104f5f5,
292 0x63dfbcbc, 0x77c1b6b6, 0xaf75dada, 0x42632121,
293 0x20301010, 0xe51affff, 0xfd0ef3f3, 0xbf6dd2d2,
294 0x814ccdcd, 0x18140c0c, 0x26351313, 0xc32fecec,
295 0xbee15f5f, 0x35a29797, 0x88cc4444, 0x2e391717,
296 0x9357c4c4, 0x55f2a7a7, 0xfc827e7e, 0x7a473d3d,
297 0xc8ac6464, 0xbae75d5d, 0x322b1919, 0xe6957373,
298 0xc0a06060, 0x19988181, 0x9ed14f4f, 0xa37fdcdc,
299 0x44662222, 0x547e2a2a, 0x3bab9090, 0x0b838888,
300 0x8cca4646, 0xc729eeee, 0x6bd3b8b8, 0x283c1414,
301 0xa779dede, 0xbce25e5e, 0x161d0b0b, 0xad76dbdb,
302 0xdb3be0e0, 0x64563232, 0x744e3a3a, 0x141e0a0a,
303 0x92db4949, 0x0c0a0606, 0x486c2424, 0xb8e45c5c,
304 0x9f5dc2c2, 0xbd6ed3d3, 0x43efacac, 0xc4a66262,
305 0x39a89191, 0x31a49595, 0xd337e4e4, 0xf28b7979,
306 0xd532e7e7, 0x8b43c8c8, 0x6e593737, 0xdab76d6d,
307 0x018c8d8d, 0xb164d5d5, 0x9cd24e4e, 0x49e0a9a9,
308 0xd8b46c6c, 0xacfa5656, 0xf307f4f4, 0xcf25eaea,
309 0xcaaf6565, 0xf48e7a7a, 0x47e9aeae, 0x10180808,
310 0x6fd5baba, 0xf0887878, 0x4a6f2525, 0x5c722e2e,
311 0x38241c1c, 0x57f1a6a6, 0x73c7b4b4, 0x9751c6c6,
312 0xcb23e8e8, 0xa17cdddd, 0xe89c7474, 0x3e211f1f,
313 0x96dd4b4b, 0x61dcbdbd, 0x0d868b8b, 0x0f858a8a,
314 0xe0907070, 0x7c423e3e, 0x71c4b5b5, 0xccaa6666,
315 0x90d84848, 0x06050303, 0xf701f6f6, 0x1c120e0e,
316 0xc2a36161, 0x6a5f3535, 0xaef95757, 0x69d0b9b9,
317 0x17918686, 0x9958c1c1, 0x3a271d1d, 0x27b99e9e,
318 0xd938e1e1, 0xeb13f8f8, 0x2bb39898, 0x22331111,
319 0xd2bb6969, 0xa970d9d9, 0x07898e8e, 0x33a79494,
320 0x2db69b9b, 0x3c221e1e, 0x15928787, 0xc920e9e9,
321 0x8749cece, 0xaaff5555, 0x50782828, 0xa57adfdf,
322 0x038f8c8c, 0x59f8a1a1, 0x09808989, 0x1a170d0d,
323 0x65dabfbf, 0xd731e6e6, 0x84c64242, 0xd0b86868,
324 0x82c34141, 0x29b09999, 0x5a772d2d, 0x1e110f0f,
325 0x7bcbb0b0, 0xa8fc5454, 0x6dd6bbbb, 0x2c3a1616,
104 } 326 }
327};
105 328
106 log_tab[1] = 0; 329const u32 crypto_fl_tab[4][256] = {
107 330 {
108 for (i = 0, p = 1; i < 10; ++i) { 331 0x00000063, 0x0000007c, 0x00000077, 0x0000007b,
109 rco_tab[i] = p; 332 0x000000f2, 0x0000006b, 0x0000006f, 0x000000c5,
110 333 0x00000030, 0x00000001, 0x00000067, 0x0000002b,
111 p = (p << 1) ^ (p & 0x80 ? 0x01b : 0); 334 0x000000fe, 0x000000d7, 0x000000ab, 0x00000076,
335 0x000000ca, 0x00000082, 0x000000c9, 0x0000007d,
336 0x000000fa, 0x00000059, 0x00000047, 0x000000f0,
337 0x000000ad, 0x000000d4, 0x000000a2, 0x000000af,
338 0x0000009c, 0x000000a4, 0x00000072, 0x000000c0,
339 0x000000b7, 0x000000fd, 0x00000093, 0x00000026,
340 0x00000036, 0x0000003f, 0x000000f7, 0x000000cc,
341 0x00000034, 0x000000a5, 0x000000e5, 0x000000f1,
342 0x00000071, 0x000000d8, 0x00000031, 0x00000015,
343 0x00000004, 0x000000c7, 0x00000023, 0x000000c3,
344 0x00000018, 0x00000096, 0x00000005, 0x0000009a,
345 0x00000007, 0x00000012, 0x00000080, 0x000000e2,
346 0x000000eb, 0x00000027, 0x000000b2, 0x00000075,
347 0x00000009, 0x00000083, 0x0000002c, 0x0000001a,
348 0x0000001b, 0x0000006e, 0x0000005a, 0x000000a0,
349 0x00000052, 0x0000003b, 0x000000d6, 0x000000b3,
350 0x00000029, 0x000000e3, 0x0000002f, 0x00000084,
351 0x00000053, 0x000000d1, 0x00000000, 0x000000ed,
352 0x00000020, 0x000000fc, 0x000000b1, 0x0000005b,
353 0x0000006a, 0x000000cb, 0x000000be, 0x00000039,
354 0x0000004a, 0x0000004c, 0x00000058, 0x000000cf,
355 0x000000d0, 0x000000ef, 0x000000aa, 0x000000fb,
356 0x00000043, 0x0000004d, 0x00000033, 0x00000085,
357 0x00000045, 0x000000f9, 0x00000002, 0x0000007f,
358 0x00000050, 0x0000003c, 0x0000009f, 0x000000a8,
359 0x00000051, 0x000000a3, 0x00000040, 0x0000008f,
360 0x00000092, 0x0000009d, 0x00000038, 0x000000f5,
361 0x000000bc, 0x000000b6, 0x000000da, 0x00000021,
362 0x00000010, 0x000000ff, 0x000000f3, 0x000000d2,
363 0x000000cd, 0x0000000c, 0x00000013, 0x000000ec,
364 0x0000005f, 0x00000097, 0x00000044, 0x00000017,
365 0x000000c4, 0x000000a7, 0x0000007e, 0x0000003d,
366 0x00000064, 0x0000005d, 0x00000019, 0x00000073,
367 0x00000060, 0x00000081, 0x0000004f, 0x000000dc,
368 0x00000022, 0x0000002a, 0x00000090, 0x00000088,
369 0x00000046, 0x000000ee, 0x000000b8, 0x00000014,
370 0x000000de, 0x0000005e, 0x0000000b, 0x000000db,
371 0x000000e0, 0x00000032, 0x0000003a, 0x0000000a,
372 0x00000049, 0x00000006, 0x00000024, 0x0000005c,
373 0x000000c2, 0x000000d3, 0x000000ac, 0x00000062,
374 0x00000091, 0x00000095, 0x000000e4, 0x00000079,
375 0x000000e7, 0x000000c8, 0x00000037, 0x0000006d,
376 0x0000008d, 0x000000d5, 0x0000004e, 0x000000a9,
377 0x0000006c, 0x00000056, 0x000000f4, 0x000000ea,
378 0x00000065, 0x0000007a, 0x000000ae, 0x00000008,
379 0x000000ba, 0x00000078, 0x00000025, 0x0000002e,
380 0x0000001c, 0x000000a6, 0x000000b4, 0x000000c6,
381 0x000000e8, 0x000000dd, 0x00000074, 0x0000001f,
382 0x0000004b, 0x000000bd, 0x0000008b, 0x0000008a,
383 0x00000070, 0x0000003e, 0x000000b5, 0x00000066,
384 0x00000048, 0x00000003, 0x000000f6, 0x0000000e,
385 0x00000061, 0x00000035, 0x00000057, 0x000000b9,
386 0x00000086, 0x000000c1, 0x0000001d, 0x0000009e,
387 0x000000e1, 0x000000f8, 0x00000098, 0x00000011,
388 0x00000069, 0x000000d9, 0x0000008e, 0x00000094,
389 0x0000009b, 0x0000001e, 0x00000087, 0x000000e9,
390 0x000000ce, 0x00000055, 0x00000028, 0x000000df,
391 0x0000008c, 0x000000a1, 0x00000089, 0x0000000d,
392 0x000000bf, 0x000000e6, 0x00000042, 0x00000068,
393 0x00000041, 0x00000099, 0x0000002d, 0x0000000f,
394 0x000000b0, 0x00000054, 0x000000bb, 0x00000016,
395 }, {
396 0x00006300, 0x00007c00, 0x00007700, 0x00007b00,
397 0x0000f200, 0x00006b00, 0x00006f00, 0x0000c500,
398 0x00003000, 0x00000100, 0x00006700, 0x00002b00,
399 0x0000fe00, 0x0000d700, 0x0000ab00, 0x00007600,
400 0x0000ca00, 0x00008200, 0x0000c900, 0x00007d00,
401 0x0000fa00, 0x00005900, 0x00004700, 0x0000f000,
402 0x0000ad00, 0x0000d400, 0x0000a200, 0x0000af00,
403 0x00009c00, 0x0000a400, 0x00007200, 0x0000c000,
404 0x0000b700, 0x0000fd00, 0x00009300, 0x00002600,
405 0x00003600, 0x00003f00, 0x0000f700, 0x0000cc00,
406 0x00003400, 0x0000a500, 0x0000e500, 0x0000f100,
407 0x00007100, 0x0000d800, 0x00003100, 0x00001500,
408 0x00000400, 0x0000c700, 0x00002300, 0x0000c300,
409 0x00001800, 0x00009600, 0x00000500, 0x00009a00,
410 0x00000700, 0x00001200, 0x00008000, 0x0000e200,
411 0x0000eb00, 0x00002700, 0x0000b200, 0x00007500,
412 0x00000900, 0x00008300, 0x00002c00, 0x00001a00,
413 0x00001b00, 0x00006e00, 0x00005a00, 0x0000a000,
414 0x00005200, 0x00003b00, 0x0000d600, 0x0000b300,
415 0x00002900, 0x0000e300, 0x00002f00, 0x00008400,
416 0x00005300, 0x0000d100, 0x00000000, 0x0000ed00,
417 0x00002000, 0x0000fc00, 0x0000b100, 0x00005b00,
418 0x00006a00, 0x0000cb00, 0x0000be00, 0x00003900,
419 0x00004a00, 0x00004c00, 0x00005800, 0x0000cf00,
420 0x0000d000, 0x0000ef00, 0x0000aa00, 0x0000fb00,
421 0x00004300, 0x00004d00, 0x00003300, 0x00008500,
422 0x00004500, 0x0000f900, 0x00000200, 0x00007f00,
423 0x00005000, 0x00003c00, 0x00009f00, 0x0000a800,
424 0x00005100, 0x0000a300, 0x00004000, 0x00008f00,
425 0x00009200, 0x00009d00, 0x00003800, 0x0000f500,
426 0x0000bc00, 0x0000b600, 0x0000da00, 0x00002100,
427 0x00001000, 0x0000ff00, 0x0000f300, 0x0000d200,
428 0x0000cd00, 0x00000c00, 0x00001300, 0x0000ec00,
429 0x00005f00, 0x00009700, 0x00004400, 0x00001700,
430 0x0000c400, 0x0000a700, 0x00007e00, 0x00003d00,
431 0x00006400, 0x00005d00, 0x00001900, 0x00007300,
432 0x00006000, 0x00008100, 0x00004f00, 0x0000dc00,
433 0x00002200, 0x00002a00, 0x00009000, 0x00008800,
434 0x00004600, 0x0000ee00, 0x0000b800, 0x00001400,
435 0x0000de00, 0x00005e00, 0x00000b00, 0x0000db00,
436 0x0000e000, 0x00003200, 0x00003a00, 0x00000a00,
437 0x00004900, 0x00000600, 0x00002400, 0x00005c00,
438 0x0000c200, 0x0000d300, 0x0000ac00, 0x00006200,
439 0x00009100, 0x00009500, 0x0000e400, 0x00007900,
440 0x0000e700, 0x0000c800, 0x00003700, 0x00006d00,
441 0x00008d00, 0x0000d500, 0x00004e00, 0x0000a900,
442 0x00006c00, 0x00005600, 0x0000f400, 0x0000ea00,
443 0x00006500, 0x00007a00, 0x0000ae00, 0x00000800,
444 0x0000ba00, 0x00007800, 0x00002500, 0x00002e00,
445 0x00001c00, 0x0000a600, 0x0000b400, 0x0000c600,
446 0x0000e800, 0x0000dd00, 0x00007400, 0x00001f00,
447 0x00004b00, 0x0000bd00, 0x00008b00, 0x00008a00,
448 0x00007000, 0x00003e00, 0x0000b500, 0x00006600,
449 0x00004800, 0x00000300, 0x0000f600, 0x00000e00,
450 0x00006100, 0x00003500, 0x00005700, 0x0000b900,
451 0x00008600, 0x0000c100, 0x00001d00, 0x00009e00,
452 0x0000e100, 0x0000f800, 0x00009800, 0x00001100,
453 0x00006900, 0x0000d900, 0x00008e00, 0x00009400,
454 0x00009b00, 0x00001e00, 0x00008700, 0x0000e900,
455 0x0000ce00, 0x00005500, 0x00002800, 0x0000df00,
456 0x00008c00, 0x0000a100, 0x00008900, 0x00000d00,
457 0x0000bf00, 0x0000e600, 0x00004200, 0x00006800,
458 0x00004100, 0x00009900, 0x00002d00, 0x00000f00,
459 0x0000b000, 0x00005400, 0x0000bb00, 0x00001600,
460 }, {
461 0x00630000, 0x007c0000, 0x00770000, 0x007b0000,
462 0x00f20000, 0x006b0000, 0x006f0000, 0x00c50000,
463 0x00300000, 0x00010000, 0x00670000, 0x002b0000,
464 0x00fe0000, 0x00d70000, 0x00ab0000, 0x00760000,
465 0x00ca0000, 0x00820000, 0x00c90000, 0x007d0000,
466 0x00fa0000, 0x00590000, 0x00470000, 0x00f00000,
467 0x00ad0000, 0x00d40000, 0x00a20000, 0x00af0000,
468 0x009c0000, 0x00a40000, 0x00720000, 0x00c00000,
469 0x00b70000, 0x00fd0000, 0x00930000, 0x00260000,
470 0x00360000, 0x003f0000, 0x00f70000, 0x00cc0000,
471 0x00340000, 0x00a50000, 0x00e50000, 0x00f10000,
472 0x00710000, 0x00d80000, 0x00310000, 0x00150000,
473 0x00040000, 0x00c70000, 0x00230000, 0x00c30000,
474 0x00180000, 0x00960000, 0x00050000, 0x009a0000,
475 0x00070000, 0x00120000, 0x00800000, 0x00e20000,
476 0x00eb0000, 0x00270000, 0x00b20000, 0x00750000,
477 0x00090000, 0x00830000, 0x002c0000, 0x001a0000,
478 0x001b0000, 0x006e0000, 0x005a0000, 0x00a00000,
479 0x00520000, 0x003b0000, 0x00d60000, 0x00b30000,
480 0x00290000, 0x00e30000, 0x002f0000, 0x00840000,
481 0x00530000, 0x00d10000, 0x00000000, 0x00ed0000,
482 0x00200000, 0x00fc0000, 0x00b10000, 0x005b0000,
483 0x006a0000, 0x00cb0000, 0x00be0000, 0x00390000,
484 0x004a0000, 0x004c0000, 0x00580000, 0x00cf0000,
485 0x00d00000, 0x00ef0000, 0x00aa0000, 0x00fb0000,
486 0x00430000, 0x004d0000, 0x00330000, 0x00850000,
487 0x00450000, 0x00f90000, 0x00020000, 0x007f0000,
488 0x00500000, 0x003c0000, 0x009f0000, 0x00a80000,
489 0x00510000, 0x00a30000, 0x00400000, 0x008f0000,
490 0x00920000, 0x009d0000, 0x00380000, 0x00f50000,
491 0x00bc0000, 0x00b60000, 0x00da0000, 0x00210000,
492 0x00100000, 0x00ff0000, 0x00f30000, 0x00d20000,
493 0x00cd0000, 0x000c0000, 0x00130000, 0x00ec0000,
494 0x005f0000, 0x00970000, 0x00440000, 0x00170000,
495 0x00c40000, 0x00a70000, 0x007e0000, 0x003d0000,
496 0x00640000, 0x005d0000, 0x00190000, 0x00730000,
497 0x00600000, 0x00810000, 0x004f0000, 0x00dc0000,
498 0x00220000, 0x002a0000, 0x00900000, 0x00880000,
499 0x00460000, 0x00ee0000, 0x00b80000, 0x00140000,
500 0x00de0000, 0x005e0000, 0x000b0000, 0x00db0000,
501 0x00e00000, 0x00320000, 0x003a0000, 0x000a0000,
502 0x00490000, 0x00060000, 0x00240000, 0x005c0000,
503 0x00c20000, 0x00d30000, 0x00ac0000, 0x00620000,
504 0x00910000, 0x00950000, 0x00e40000, 0x00790000,
505 0x00e70000, 0x00c80000, 0x00370000, 0x006d0000,
506 0x008d0000, 0x00d50000, 0x004e0000, 0x00a90000,
507 0x006c0000, 0x00560000, 0x00f40000, 0x00ea0000,
508 0x00650000, 0x007a0000, 0x00ae0000, 0x00080000,
509 0x00ba0000, 0x00780000, 0x00250000, 0x002e0000,
510 0x001c0000, 0x00a60000, 0x00b40000, 0x00c60000,
511 0x00e80000, 0x00dd0000, 0x00740000, 0x001f0000,
512 0x004b0000, 0x00bd0000, 0x008b0000, 0x008a0000,
513 0x00700000, 0x003e0000, 0x00b50000, 0x00660000,
514 0x00480000, 0x00030000, 0x00f60000, 0x000e0000,
515 0x00610000, 0x00350000, 0x00570000, 0x00b90000,
516 0x00860000, 0x00c10000, 0x001d0000, 0x009e0000,
517 0x00e10000, 0x00f80000, 0x00980000, 0x00110000,
518 0x00690000, 0x00d90000, 0x008e0000, 0x00940000,
519 0x009b0000, 0x001e0000, 0x00870000, 0x00e90000,
520 0x00ce0000, 0x00550000, 0x00280000, 0x00df0000,
521 0x008c0000, 0x00a10000, 0x00890000, 0x000d0000,
522 0x00bf0000, 0x00e60000, 0x00420000, 0x00680000,
523 0x00410000, 0x00990000, 0x002d0000, 0x000f0000,
524 0x00b00000, 0x00540000, 0x00bb0000, 0x00160000,
525 }, {
526 0x63000000, 0x7c000000, 0x77000000, 0x7b000000,
527 0xf2000000, 0x6b000000, 0x6f000000, 0xc5000000,
528 0x30000000, 0x01000000, 0x67000000, 0x2b000000,
529 0xfe000000, 0xd7000000, 0xab000000, 0x76000000,
530 0xca000000, 0x82000000, 0xc9000000, 0x7d000000,
531 0xfa000000, 0x59000000, 0x47000000, 0xf0000000,
532 0xad000000, 0xd4000000, 0xa2000000, 0xaf000000,
533 0x9c000000, 0xa4000000, 0x72000000, 0xc0000000,
534 0xb7000000, 0xfd000000, 0x93000000, 0x26000000,
535 0x36000000, 0x3f000000, 0xf7000000, 0xcc000000,
536 0x34000000, 0xa5000000, 0xe5000000, 0xf1000000,
537 0x71000000, 0xd8000000, 0x31000000, 0x15000000,
538 0x04000000, 0xc7000000, 0x23000000, 0xc3000000,
539 0x18000000, 0x96000000, 0x05000000, 0x9a000000,
540 0x07000000, 0x12000000, 0x80000000, 0xe2000000,
541 0xeb000000, 0x27000000, 0xb2000000, 0x75000000,
542 0x09000000, 0x83000000, 0x2c000000, 0x1a000000,
543 0x1b000000, 0x6e000000, 0x5a000000, 0xa0000000,
544 0x52000000, 0x3b000000, 0xd6000000, 0xb3000000,
545 0x29000000, 0xe3000000, 0x2f000000, 0x84000000,
546 0x53000000, 0xd1000000, 0x00000000, 0xed000000,
547 0x20000000, 0xfc000000, 0xb1000000, 0x5b000000,
548 0x6a000000, 0xcb000000, 0xbe000000, 0x39000000,
549 0x4a000000, 0x4c000000, 0x58000000, 0xcf000000,
550 0xd0000000, 0xef000000, 0xaa000000, 0xfb000000,
551 0x43000000, 0x4d000000, 0x33000000, 0x85000000,
552 0x45000000, 0xf9000000, 0x02000000, 0x7f000000,
553 0x50000000, 0x3c000000, 0x9f000000, 0xa8000000,
554 0x51000000, 0xa3000000, 0x40000000, 0x8f000000,
555 0x92000000, 0x9d000000, 0x38000000, 0xf5000000,
556 0xbc000000, 0xb6000000, 0xda000000, 0x21000000,
557 0x10000000, 0xff000000, 0xf3000000, 0xd2000000,
558 0xcd000000, 0x0c000000, 0x13000000, 0xec000000,
559 0x5f000000, 0x97000000, 0x44000000, 0x17000000,
560 0xc4000000, 0xa7000000, 0x7e000000, 0x3d000000,
561 0x64000000, 0x5d000000, 0x19000000, 0x73000000,
562 0x60000000, 0x81000000, 0x4f000000, 0xdc000000,
563 0x22000000, 0x2a000000, 0x90000000, 0x88000000,
564 0x46000000, 0xee000000, 0xb8000000, 0x14000000,
565 0xde000000, 0x5e000000, 0x0b000000, 0xdb000000,
566 0xe0000000, 0x32000000, 0x3a000000, 0x0a000000,
567 0x49000000, 0x06000000, 0x24000000, 0x5c000000,
568 0xc2000000, 0xd3000000, 0xac000000, 0x62000000,
569 0x91000000, 0x95000000, 0xe4000000, 0x79000000,
570 0xe7000000, 0xc8000000, 0x37000000, 0x6d000000,
571 0x8d000000, 0xd5000000, 0x4e000000, 0xa9000000,
572 0x6c000000, 0x56000000, 0xf4000000, 0xea000000,
573 0x65000000, 0x7a000000, 0xae000000, 0x08000000,
574 0xba000000, 0x78000000, 0x25000000, 0x2e000000,
575 0x1c000000, 0xa6000000, 0xb4000000, 0xc6000000,
576 0xe8000000, 0xdd000000, 0x74000000, 0x1f000000,
577 0x4b000000, 0xbd000000, 0x8b000000, 0x8a000000,
578 0x70000000, 0x3e000000, 0xb5000000, 0x66000000,
579 0x48000000, 0x03000000, 0xf6000000, 0x0e000000,
580 0x61000000, 0x35000000, 0x57000000, 0xb9000000,
581 0x86000000, 0xc1000000, 0x1d000000, 0x9e000000,
582 0xe1000000, 0xf8000000, 0x98000000, 0x11000000,
583 0x69000000, 0xd9000000, 0x8e000000, 0x94000000,
584 0x9b000000, 0x1e000000, 0x87000000, 0xe9000000,
585 0xce000000, 0x55000000, 0x28000000, 0xdf000000,
586 0x8c000000, 0xa1000000, 0x89000000, 0x0d000000,
587 0xbf000000, 0xe6000000, 0x42000000, 0x68000000,
588 0x41000000, 0x99000000, 0x2d000000, 0x0f000000,
589 0xb0000000, 0x54000000, 0xbb000000, 0x16000000,
112 } 590 }
591};
113 592
114 for (i = 0; i < 256; ++i) { 593const u32 crypto_it_tab[4][256] = {
115 p = (i ? pow_tab[255 - log_tab[i]] : 0); 594 {
116 q = ((p >> 7) | (p << 1)) ^ ((p >> 6) | (p << 2)); 595 0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a,
117 p ^= 0x63 ^ q ^ ((q >> 6) | (q << 2)); 596 0xcb6bab3b, 0xf1459d1f, 0xab58faac, 0x9303e34b,
118 sbx_tab[i] = p; 597 0x55fa3020, 0xf66d76ad, 0x9176cc88, 0x254c02f5,
119 isb_tab[p] = (u8) i; 598 0xfcd7e54f, 0xd7cb2ac5, 0x80443526, 0x8fa362b5,
599 0x495ab1de, 0x671bba25, 0x980eea45, 0xe1c0fe5d,
600 0x02752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b,
601 0xe75f8f03, 0x959c9215, 0xeb7a6dbf, 0xda595295,
602 0x2d83bed4, 0xd3217458, 0x2969e049, 0x44c8c98e,
603 0x6a89c275, 0x78798ef4, 0x6b3e5899, 0xdd71b927,
604 0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d,
605 0x184adf63, 0x82311ae5, 0x60335197, 0x457f5362,
606 0xe07764b1, 0x84ae6bbb, 0x1ca081fe, 0x942b08f9,
607 0x58684870, 0x19fd458f, 0x876cde94, 0xb7f87b52,
608 0x23d373ab, 0xe2024b72, 0x578f1fe3, 0x2aab5566,
609 0x0728ebb2, 0x03c2b52f, 0x9a7bc586, 0xa50837d3,
610 0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed,
611 0x2b1ccf8a, 0x92b479a7, 0xf0f207f3, 0xa1e2694e,
612 0xcdf4da65, 0xd5be0506, 0x1f6234d1, 0x8afea6c4,
613 0x9d532e34, 0xa055f3a2, 0x32e18a05, 0x75ebf6a4,
614 0x39ec830b, 0xaaef6040, 0x069f715e, 0x51106ebd,
615 0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d,
616 0xb58d5491, 0x055dc471, 0x6fd40604, 0xff155060,
617 0x24fb9819, 0x97e9bdd6, 0xcc434089, 0x779ed967,
618 0xbd42e8b0, 0x888b8907, 0x385b19e7, 0xdbeec879,
619 0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x00000000,
620 0x83868009, 0x48ed2b32, 0xac70111e, 0x4e725a6c,
621 0xfbff0efd, 0x5638850f, 0x1ed5ae3d, 0x27392d36,
622 0x64d90f0a, 0x21a65c68, 0xd1545b9b, 0x3a2e3624,
623 0xb1670a0c, 0x0fe75793, 0xd296eeb4, 0x9e919b1b,
624 0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c,
625 0x0aba93e2, 0xe52aa0c0, 0x43e0223c, 0x1d171b12,
626 0x0b0d090e, 0xadc78bf2, 0xb9a8b62d, 0xc8a91e14,
627 0x8519f157, 0x4c0775af, 0xbbdd99ee, 0xfd607fa3,
628 0x9f2601f7, 0xbcf5725c, 0xc53b6644, 0x347efb5b,
629 0x7629438b, 0xdcc623cb, 0x68fcedb6, 0x63f1e4b8,
630 0xcadc31d7, 0x10856342, 0x40229713, 0x2011c684,
631 0x7d244a85, 0xf83dbbd2, 0x1132f9ae, 0x6da129c7,
632 0x4b2f9e1d, 0xf330b2dc, 0xec52860d, 0xd0e3c177,
633 0x6c16b32b, 0x99b970a9, 0xfa489411, 0x2264e947,
634 0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56, 0xef903322,
635 0xc74e4987, 0xc1d138d9, 0xfea2ca8c, 0x360bd498,
636 0xcf81f5a6, 0x28de7aa5, 0x268eb7da, 0xa4bfad3f,
637 0xe49d3a2c, 0x0d927850, 0x9bcc5f6a, 0x62467e54,
638 0xc2138df6, 0xe8b8d890, 0x5ef7392e, 0xf5afc382,
639 0xbe805d9f, 0x7c93d069, 0xa92dd56f, 0xb31225cf,
640 0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb,
641 0x097826cd, 0xf418596e, 0x01b79aec, 0xa89a4f83,
642 0x656e95e6, 0x7ee6ffaa, 0x08cfbc21, 0xe6e815ef,
643 0xd99be7ba, 0xce366f4a, 0xd4099fea, 0xd67cb029,
644 0xafb2a431, 0x31233f2a, 0x3094a5c6, 0xc066a235,
645 0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733,
646 0x4a9804f1, 0xf7daec41, 0x0e50cd7f, 0x2ff69117,
647 0x8dd64d76, 0x4db0ef43, 0x544daacc, 0xdf0496e4,
648 0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1, 0x7f516546,
649 0x04ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb,
650 0x5a1d67b3, 0x52d2db92, 0x335610e9, 0x1347d66d,
651 0x8c61d79a, 0x7a0ca137, 0x8e14f859, 0x893c13eb,
652 0xee27a9ce, 0x35c961b7, 0xede51ce1, 0x3cb1477a,
653 0x59dfd29c, 0x3f73f255, 0x79ce1418, 0xbf37c773,
654 0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478,
655 0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2,
656 0x72c31d16, 0x0c25e2bc, 0x8b493c28, 0x41950dff,
657 0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664,
658 0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0,
659 }, {
660 0xa7f45150, 0x65417e53, 0xa4171ac3, 0x5e273a96,
661 0x6bab3bcb, 0x459d1ff1, 0x58faacab, 0x03e34b93,
662 0xfa302055, 0x6d76adf6, 0x76cc8891, 0x4c02f525,
663 0xd7e54ffc, 0xcb2ac5d7, 0x44352680, 0xa362b58f,
664 0x5ab1de49, 0x1bba2567, 0x0eea4598, 0xc0fe5de1,
665 0x752fc302, 0xf04c8112, 0x97468da3, 0xf9d36bc6,
666 0x5f8f03e7, 0x9c921595, 0x7a6dbfeb, 0x595295da,
667 0x83bed42d, 0x217458d3, 0x69e04929, 0xc8c98e44,
668 0x89c2756a, 0x798ef478, 0x3e58996b, 0x71b927dd,
669 0x4fe1beb6, 0xad88f017, 0xac20c966, 0x3ace7db4,
670 0x4adf6318, 0x311ae582, 0x33519760, 0x7f536245,
671 0x7764b1e0, 0xae6bbb84, 0xa081fe1c, 0x2b08f994,
672 0x68487058, 0xfd458f19, 0x6cde9487, 0xf87b52b7,
673 0xd373ab23, 0x024b72e2, 0x8f1fe357, 0xab55662a,
674 0x28ebb207, 0xc2b52f03, 0x7bc5869a, 0x0837d3a5,
675 0x872830f2, 0xa5bf23b2, 0x6a0302ba, 0x8216ed5c,
676 0x1ccf8a2b, 0xb479a792, 0xf207f3f0, 0xe2694ea1,
677 0xf4da65cd, 0xbe0506d5, 0x6234d11f, 0xfea6c48a,
678 0x532e349d, 0x55f3a2a0, 0xe18a0532, 0xebf6a475,
679 0xec830b39, 0xef6040aa, 0x9f715e06, 0x106ebd51,
680 0x8a213ef9, 0x06dd963d, 0x053eddae, 0xbde64d46,
681 0x8d5491b5, 0x5dc47105, 0xd406046f, 0x155060ff,
682 0xfb981924, 0xe9bdd697, 0x434089cc, 0x9ed96777,
683 0x42e8b0bd, 0x8b890788, 0x5b19e738, 0xeec879db,
684 0x0a7ca147, 0x0f427ce9, 0x1e84f8c9, 0x00000000,
685 0x86800983, 0xed2b3248, 0x70111eac, 0x725a6c4e,
686 0xff0efdfb, 0x38850f56, 0xd5ae3d1e, 0x392d3627,
687 0xd90f0a64, 0xa65c6821, 0x545b9bd1, 0x2e36243a,
688 0x670a0cb1, 0xe757930f, 0x96eeb4d2, 0x919b1b9e,
689 0xc5c0804f, 0x20dc61a2, 0x4b775a69, 0x1a121c16,
690 0xba93e20a, 0x2aa0c0e5, 0xe0223c43, 0x171b121d,
691 0x0d090e0b, 0xc78bf2ad, 0xa8b62db9, 0xa91e14c8,
692 0x19f15785, 0x0775af4c, 0xdd99eebb, 0x607fa3fd,
693 0x2601f79f, 0xf5725cbc, 0x3b6644c5, 0x7efb5b34,
694 0x29438b76, 0xc623cbdc, 0xfcedb668, 0xf1e4b863,
695 0xdc31d7ca, 0x85634210, 0x22971340, 0x11c68420,
696 0x244a857d, 0x3dbbd2f8, 0x32f9ae11, 0xa129c76d,
697 0x2f9e1d4b, 0x30b2dcf3, 0x52860dec, 0xe3c177d0,
698 0x16b32b6c, 0xb970a999, 0x489411fa, 0x64e94722,
699 0x8cfca8c4, 0x3ff0a01a, 0x2c7d56d8, 0x903322ef,
700 0x4e4987c7, 0xd138d9c1, 0xa2ca8cfe, 0x0bd49836,
701 0x81f5a6cf, 0xde7aa528, 0x8eb7da26, 0xbfad3fa4,
702 0x9d3a2ce4, 0x9278500d, 0xcc5f6a9b, 0x467e5462,
703 0x138df6c2, 0xb8d890e8, 0xf7392e5e, 0xafc382f5,
704 0x805d9fbe, 0x93d0697c, 0x2dd56fa9, 0x1225cfb3,
705 0x99acc83b, 0x7d1810a7, 0x639ce86e, 0xbb3bdb7b,
706 0x7826cd09, 0x18596ef4, 0xb79aec01, 0x9a4f83a8,
707 0x6e95e665, 0xe6ffaa7e, 0xcfbc2108, 0xe815efe6,
708 0x9be7bad9, 0x366f4ace, 0x099fead4, 0x7cb029d6,
709 0xb2a431af, 0x233f2a31, 0x94a5c630, 0x66a235c0,
710 0xbc4e7437, 0xca82fca6, 0xd090e0b0, 0xd8a73315,
711 0x9804f14a, 0xdaec41f7, 0x50cd7f0e, 0xf691172f,
712 0xd64d768d, 0xb0ef434d, 0x4daacc54, 0x0496e4df,
713 0xb5d19ee3, 0x886a4c1b, 0x1f2cc1b8, 0x5165467f,
714 0xea5e9d04, 0x358c015d, 0x7487fa73, 0x410bfb2e,
715 0x1d67b35a, 0xd2db9252, 0x5610e933, 0x47d66d13,
716 0x61d79a8c, 0x0ca1377a, 0x14f8598e, 0x3c13eb89,
717 0x27a9ceee, 0xc961b735, 0xe51ce1ed, 0xb1477a3c,
718 0xdfd29c59, 0x73f2553f, 0xce141879, 0x37c773bf,
719 0xcdf753ea, 0xaafd5f5b, 0x6f3ddf14, 0xdb447886,
720 0xf3afca81, 0xc468b93e, 0x3424382c, 0x40a3c25f,
721 0xc31d1672, 0x25e2bc0c, 0x493c288b, 0x950dff41,
722 0x01a83971, 0xb30c08de, 0xe4b4d89c, 0xc1566490,
723 0x84cb7b61, 0xb632d570, 0x5c6c4874, 0x57b8d042,
724 }, {
725 0xf45150a7, 0x417e5365, 0x171ac3a4, 0x273a965e,
726 0xab3bcb6b, 0x9d1ff145, 0xfaacab58, 0xe34b9303,
727 0x302055fa, 0x76adf66d, 0xcc889176, 0x02f5254c,
728 0xe54ffcd7, 0x2ac5d7cb, 0x35268044, 0x62b58fa3,
729 0xb1de495a, 0xba25671b, 0xea45980e, 0xfe5de1c0,
730 0x2fc30275, 0x4c8112f0, 0x468da397, 0xd36bc6f9,
731 0x8f03e75f, 0x9215959c, 0x6dbfeb7a, 0x5295da59,
732 0xbed42d83, 0x7458d321, 0xe0492969, 0xc98e44c8,
733 0xc2756a89, 0x8ef47879, 0x58996b3e, 0xb927dd71,
734 0xe1beb64f, 0x88f017ad, 0x20c966ac, 0xce7db43a,
735 0xdf63184a, 0x1ae58231, 0x51976033, 0x5362457f,
736 0x64b1e077, 0x6bbb84ae, 0x81fe1ca0, 0x08f9942b,
737 0x48705868, 0x458f19fd, 0xde94876c, 0x7b52b7f8,
738 0x73ab23d3, 0x4b72e202, 0x1fe3578f, 0x55662aab,
739 0xebb20728, 0xb52f03c2, 0xc5869a7b, 0x37d3a508,
740 0x2830f287, 0xbf23b2a5, 0x0302ba6a, 0x16ed5c82,
741 0xcf8a2b1c, 0x79a792b4, 0x07f3f0f2, 0x694ea1e2,
742 0xda65cdf4, 0x0506d5be, 0x34d11f62, 0xa6c48afe,
743 0x2e349d53, 0xf3a2a055, 0x8a0532e1, 0xf6a475eb,
744 0x830b39ec, 0x6040aaef, 0x715e069f, 0x6ebd5110,
745 0x213ef98a, 0xdd963d06, 0x3eddae05, 0xe64d46bd,
746 0x5491b58d, 0xc471055d, 0x06046fd4, 0x5060ff15,
747 0x981924fb, 0xbdd697e9, 0x4089cc43, 0xd967779e,
748 0xe8b0bd42, 0x8907888b, 0x19e7385b, 0xc879dbee,
749 0x7ca1470a, 0x427ce90f, 0x84f8c91e, 0x00000000,
750 0x80098386, 0x2b3248ed, 0x111eac70, 0x5a6c4e72,
751 0x0efdfbff, 0x850f5638, 0xae3d1ed5, 0x2d362739,
752 0x0f0a64d9, 0x5c6821a6, 0x5b9bd154, 0x36243a2e,
753 0x0a0cb167, 0x57930fe7, 0xeeb4d296, 0x9b1b9e91,
754 0xc0804fc5, 0xdc61a220, 0x775a694b, 0x121c161a,
755 0x93e20aba, 0xa0c0e52a, 0x223c43e0, 0x1b121d17,
756 0x090e0b0d, 0x8bf2adc7, 0xb62db9a8, 0x1e14c8a9,
757 0xf1578519, 0x75af4c07, 0x99eebbdd, 0x7fa3fd60,
758 0x01f79f26, 0x725cbcf5, 0x6644c53b, 0xfb5b347e,
759 0x438b7629, 0x23cbdcc6, 0xedb668fc, 0xe4b863f1,
760 0x31d7cadc, 0x63421085, 0x97134022, 0xc6842011,
761 0x4a857d24, 0xbbd2f83d, 0xf9ae1132, 0x29c76da1,
762 0x9e1d4b2f, 0xb2dcf330, 0x860dec52, 0xc177d0e3,
763 0xb32b6c16, 0x70a999b9, 0x9411fa48, 0xe9472264,
764 0xfca8c48c, 0xf0a01a3f, 0x7d56d82c, 0x3322ef90,
765 0x4987c74e, 0x38d9c1d1, 0xca8cfea2, 0xd498360b,
766 0xf5a6cf81, 0x7aa528de, 0xb7da268e, 0xad3fa4bf,
767 0x3a2ce49d, 0x78500d92, 0x5f6a9bcc, 0x7e546246,
768 0x8df6c213, 0xd890e8b8, 0x392e5ef7, 0xc382f5af,
769 0x5d9fbe80, 0xd0697c93, 0xd56fa92d, 0x25cfb312,
770 0xacc83b99, 0x1810a77d, 0x9ce86e63, 0x3bdb7bbb,
771 0x26cd0978, 0x596ef418, 0x9aec01b7, 0x4f83a89a,
772 0x95e6656e, 0xffaa7ee6, 0xbc2108cf, 0x15efe6e8,
773 0xe7bad99b, 0x6f4ace36, 0x9fead409, 0xb029d67c,
774 0xa431afb2, 0x3f2a3123, 0xa5c63094, 0xa235c066,
775 0x4e7437bc, 0x82fca6ca, 0x90e0b0d0, 0xa73315d8,
776 0x04f14a98, 0xec41f7da, 0xcd7f0e50, 0x91172ff6,
777 0x4d768dd6, 0xef434db0, 0xaacc544d, 0x96e4df04,
778 0xd19ee3b5, 0x6a4c1b88, 0x2cc1b81f, 0x65467f51,
779 0x5e9d04ea, 0x8c015d35, 0x87fa7374, 0x0bfb2e41,
780 0x67b35a1d, 0xdb9252d2, 0x10e93356, 0xd66d1347,
781 0xd79a8c61, 0xa1377a0c, 0xf8598e14, 0x13eb893c,
782 0xa9ceee27, 0x61b735c9, 0x1ce1ede5, 0x477a3cb1,
783 0xd29c59df, 0xf2553f73, 0x141879ce, 0xc773bf37,
784 0xf753eacd, 0xfd5f5baa, 0x3ddf146f, 0x447886db,
785 0xafca81f3, 0x68b93ec4, 0x24382c34, 0xa3c25f40,
786 0x1d1672c3, 0xe2bc0c25, 0x3c288b49, 0x0dff4195,
787 0xa8397101, 0x0c08deb3, 0xb4d89ce4, 0x566490c1,
788 0xcb7b6184, 0x32d570b6, 0x6c48745c, 0xb8d04257,
789 }, {
790 0x5150a7f4, 0x7e536541, 0x1ac3a417, 0x3a965e27,
791 0x3bcb6bab, 0x1ff1459d, 0xacab58fa, 0x4b9303e3,
792 0x2055fa30, 0xadf66d76, 0x889176cc, 0xf5254c02,
793 0x4ffcd7e5, 0xc5d7cb2a, 0x26804435, 0xb58fa362,
794 0xde495ab1, 0x25671bba, 0x45980eea, 0x5de1c0fe,
795 0xc302752f, 0x8112f04c, 0x8da39746, 0x6bc6f9d3,
796 0x03e75f8f, 0x15959c92, 0xbfeb7a6d, 0x95da5952,
797 0xd42d83be, 0x58d32174, 0x492969e0, 0x8e44c8c9,
798 0x756a89c2, 0xf478798e, 0x996b3e58, 0x27dd71b9,
799 0xbeb64fe1, 0xf017ad88, 0xc966ac20, 0x7db43ace,
800 0x63184adf, 0xe582311a, 0x97603351, 0x62457f53,
801 0xb1e07764, 0xbb84ae6b, 0xfe1ca081, 0xf9942b08,
802 0x70586848, 0x8f19fd45, 0x94876cde, 0x52b7f87b,
803 0xab23d373, 0x72e2024b, 0xe3578f1f, 0x662aab55,
804 0xb20728eb, 0x2f03c2b5, 0x869a7bc5, 0xd3a50837,
805 0x30f28728, 0x23b2a5bf, 0x02ba6a03, 0xed5c8216,
806 0x8a2b1ccf, 0xa792b479, 0xf3f0f207, 0x4ea1e269,
807 0x65cdf4da, 0x06d5be05, 0xd11f6234, 0xc48afea6,
808 0x349d532e, 0xa2a055f3, 0x0532e18a, 0xa475ebf6,
809 0x0b39ec83, 0x40aaef60, 0x5e069f71, 0xbd51106e,
810 0x3ef98a21, 0x963d06dd, 0xddae053e, 0x4d46bde6,
811 0x91b58d54, 0x71055dc4, 0x046fd406, 0x60ff1550,
812 0x1924fb98, 0xd697e9bd, 0x89cc4340, 0x67779ed9,
813 0xb0bd42e8, 0x07888b89, 0xe7385b19, 0x79dbeec8,
814 0xa1470a7c, 0x7ce90f42, 0xf8c91e84, 0x00000000,
815 0x09838680, 0x3248ed2b, 0x1eac7011, 0x6c4e725a,
816 0xfdfbff0e, 0x0f563885, 0x3d1ed5ae, 0x3627392d,
817 0x0a64d90f, 0x6821a65c, 0x9bd1545b, 0x243a2e36,
818 0x0cb1670a, 0x930fe757, 0xb4d296ee, 0x1b9e919b,
819 0x804fc5c0, 0x61a220dc, 0x5a694b77, 0x1c161a12,
820 0xe20aba93, 0xc0e52aa0, 0x3c43e022, 0x121d171b,
821 0x0e0b0d09, 0xf2adc78b, 0x2db9a8b6, 0x14c8a91e,
822 0x578519f1, 0xaf4c0775, 0xeebbdd99, 0xa3fd607f,
823 0xf79f2601, 0x5cbcf572, 0x44c53b66, 0x5b347efb,
824 0x8b762943, 0xcbdcc623, 0xb668fced, 0xb863f1e4,
825 0xd7cadc31, 0x42108563, 0x13402297, 0x842011c6,
826 0x857d244a, 0xd2f83dbb, 0xae1132f9, 0xc76da129,
827 0x1d4b2f9e, 0xdcf330b2, 0x0dec5286, 0x77d0e3c1,
828 0x2b6c16b3, 0xa999b970, 0x11fa4894, 0x472264e9,
829 0xa8c48cfc, 0xa01a3ff0, 0x56d82c7d, 0x22ef9033,
830 0x87c74e49, 0xd9c1d138, 0x8cfea2ca, 0x98360bd4,
831 0xa6cf81f5, 0xa528de7a, 0xda268eb7, 0x3fa4bfad,
832 0x2ce49d3a, 0x500d9278, 0x6a9bcc5f, 0x5462467e,
833 0xf6c2138d, 0x90e8b8d8, 0x2e5ef739, 0x82f5afc3,
834 0x9fbe805d, 0x697c93d0, 0x6fa92dd5, 0xcfb31225,
835 0xc83b99ac, 0x10a77d18, 0xe86e639c, 0xdb7bbb3b,
836 0xcd097826, 0x6ef41859, 0xec01b79a, 0x83a89a4f,
837 0xe6656e95, 0xaa7ee6ff, 0x2108cfbc, 0xefe6e815,
838 0xbad99be7, 0x4ace366f, 0xead4099f, 0x29d67cb0,
839 0x31afb2a4, 0x2a31233f, 0xc63094a5, 0x35c066a2,
840 0x7437bc4e, 0xfca6ca82, 0xe0b0d090, 0x3315d8a7,
841 0xf14a9804, 0x41f7daec, 0x7f0e50cd, 0x172ff691,
842 0x768dd64d, 0x434db0ef, 0xcc544daa, 0xe4df0496,
843 0x9ee3b5d1, 0x4c1b886a, 0xc1b81f2c, 0x467f5165,
844 0x9d04ea5e, 0x015d358c, 0xfa737487, 0xfb2e410b,
845 0xb35a1d67, 0x9252d2db, 0xe9335610, 0x6d1347d6,
846 0x9a8c61d7, 0x377a0ca1, 0x598e14f8, 0xeb893c13,
847 0xceee27a9, 0xb735c961, 0xe1ede51c, 0x7a3cb147,
848 0x9c59dfd2, 0x553f73f2, 0x1879ce14, 0x73bf37c7,
849 0x53eacdf7, 0x5f5baafd, 0xdf146f3d, 0x7886db44,
850 0xca81f3af, 0xb93ec468, 0x382c3424, 0xc25f40a3,
851 0x1672c31d, 0xbc0c25e2, 0x288b493c, 0xff41950d,
852 0x397101a8, 0x08deb30c, 0xd89ce4b4, 0x6490c156,
853 0x7b6184cb, 0xd570b632, 0x48745c6c, 0xd04257b8,
120 } 854 }
855};
121 856
122 for (i = 0; i < 256; ++i) { 857const u32 crypto_il_tab[4][256] = {
123 p = sbx_tab[i]; 858 {
124 859 0x00000052, 0x00000009, 0x0000006a, 0x000000d5,
125 t = p; 860 0x00000030, 0x00000036, 0x000000a5, 0x00000038,
126 crypto_fl_tab[0][i] = t; 861 0x000000bf, 0x00000040, 0x000000a3, 0x0000009e,
127 crypto_fl_tab[1][i] = rol32(t, 8); 862 0x00000081, 0x000000f3, 0x000000d7, 0x000000fb,
128 crypto_fl_tab[2][i] = rol32(t, 16); 863 0x0000007c, 0x000000e3, 0x00000039, 0x00000082,
129 crypto_fl_tab[3][i] = rol32(t, 24); 864 0x0000009b, 0x0000002f, 0x000000ff, 0x00000087,
130 865 0x00000034, 0x0000008e, 0x00000043, 0x00000044,
131 t = ((u32) ff_mult(2, p)) | 866 0x000000c4, 0x000000de, 0x000000e9, 0x000000cb,
132 ((u32) p << 8) | 867 0x00000054, 0x0000007b, 0x00000094, 0x00000032,
133 ((u32) p << 16) | ((u32) ff_mult(3, p) << 24); 868 0x000000a6, 0x000000c2, 0x00000023, 0x0000003d,
134 869 0x000000ee, 0x0000004c, 0x00000095, 0x0000000b,
135 crypto_ft_tab[0][i] = t; 870 0x00000042, 0x000000fa, 0x000000c3, 0x0000004e,
136 crypto_ft_tab[1][i] = rol32(t, 8); 871 0x00000008, 0x0000002e, 0x000000a1, 0x00000066,
137 crypto_ft_tab[2][i] = rol32(t, 16); 872 0x00000028, 0x000000d9, 0x00000024, 0x000000b2,
138 crypto_ft_tab[3][i] = rol32(t, 24); 873 0x00000076, 0x0000005b, 0x000000a2, 0x00000049,
139 874 0x0000006d, 0x0000008b, 0x000000d1, 0x00000025,
140 p = isb_tab[i]; 875 0x00000072, 0x000000f8, 0x000000f6, 0x00000064,
141 876 0x00000086, 0x00000068, 0x00000098, 0x00000016,
142 t = p; 877 0x000000d4, 0x000000a4, 0x0000005c, 0x000000cc,
143 crypto_il_tab[0][i] = t; 878 0x0000005d, 0x00000065, 0x000000b6, 0x00000092,
144 crypto_il_tab[1][i] = rol32(t, 8); 879 0x0000006c, 0x00000070, 0x00000048, 0x00000050,
145 crypto_il_tab[2][i] = rol32(t, 16); 880 0x000000fd, 0x000000ed, 0x000000b9, 0x000000da,
146 crypto_il_tab[3][i] = rol32(t, 24); 881 0x0000005e, 0x00000015, 0x00000046, 0x00000057,
147 882 0x000000a7, 0x0000008d, 0x0000009d, 0x00000084,
148 t = ((u32) ff_mult(14, p)) | 883 0x00000090, 0x000000d8, 0x000000ab, 0x00000000,
149 ((u32) ff_mult(9, p) << 8) | 884 0x0000008c, 0x000000bc, 0x000000d3, 0x0000000a,
150 ((u32) ff_mult(13, p) << 16) | 885 0x000000f7, 0x000000e4, 0x00000058, 0x00000005,
151 ((u32) ff_mult(11, p) << 24); 886 0x000000b8, 0x000000b3, 0x00000045, 0x00000006,
152 887 0x000000d0, 0x0000002c, 0x0000001e, 0x0000008f,
153 crypto_it_tab[0][i] = t; 888 0x000000ca, 0x0000003f, 0x0000000f, 0x00000002,
154 crypto_it_tab[1][i] = rol32(t, 8); 889 0x000000c1, 0x000000af, 0x000000bd, 0x00000003,
155 crypto_it_tab[2][i] = rol32(t, 16); 890 0x00000001, 0x00000013, 0x0000008a, 0x0000006b,
156 crypto_it_tab[3][i] = rol32(t, 24); 891 0x0000003a, 0x00000091, 0x00000011, 0x00000041,
892 0x0000004f, 0x00000067, 0x000000dc, 0x000000ea,
893 0x00000097, 0x000000f2, 0x000000cf, 0x000000ce,
894 0x000000f0, 0x000000b4, 0x000000e6, 0x00000073,
895 0x00000096, 0x000000ac, 0x00000074, 0x00000022,
896 0x000000e7, 0x000000ad, 0x00000035, 0x00000085,
897 0x000000e2, 0x000000f9, 0x00000037, 0x000000e8,
898 0x0000001c, 0x00000075, 0x000000df, 0x0000006e,
899 0x00000047, 0x000000f1, 0x0000001a, 0x00000071,
900 0x0000001d, 0x00000029, 0x000000c5, 0x00000089,
901 0x0000006f, 0x000000b7, 0x00000062, 0x0000000e,
902 0x000000aa, 0x00000018, 0x000000be, 0x0000001b,
903 0x000000fc, 0x00000056, 0x0000003e, 0x0000004b,
904 0x000000c6, 0x000000d2, 0x00000079, 0x00000020,
905 0x0000009a, 0x000000db, 0x000000c0, 0x000000fe,
906 0x00000078, 0x000000cd, 0x0000005a, 0x000000f4,
907 0x0000001f, 0x000000dd, 0x000000a8, 0x00000033,
908 0x00000088, 0x00000007, 0x000000c7, 0x00000031,
909 0x000000b1, 0x00000012, 0x00000010, 0x00000059,
910 0x00000027, 0x00000080, 0x000000ec, 0x0000005f,
911 0x00000060, 0x00000051, 0x0000007f, 0x000000a9,
912 0x00000019, 0x000000b5, 0x0000004a, 0x0000000d,
913 0x0000002d, 0x000000e5, 0x0000007a, 0x0000009f,
914 0x00000093, 0x000000c9, 0x0000009c, 0x000000ef,
915 0x000000a0, 0x000000e0, 0x0000003b, 0x0000004d,
916 0x000000ae, 0x0000002a, 0x000000f5, 0x000000b0,
917 0x000000c8, 0x000000eb, 0x000000bb, 0x0000003c,
918 0x00000083, 0x00000053, 0x00000099, 0x00000061,
919 0x00000017, 0x0000002b, 0x00000004, 0x0000007e,
920 0x000000ba, 0x00000077, 0x000000d6, 0x00000026,
921 0x000000e1, 0x00000069, 0x00000014, 0x00000063,
922 0x00000055, 0x00000021, 0x0000000c, 0x0000007d,
923 }, {
924 0x00005200, 0x00000900, 0x00006a00, 0x0000d500,
925 0x00003000, 0x00003600, 0x0000a500, 0x00003800,
926 0x0000bf00, 0x00004000, 0x0000a300, 0x00009e00,
927 0x00008100, 0x0000f300, 0x0000d700, 0x0000fb00,
928 0x00007c00, 0x0000e300, 0x00003900, 0x00008200,
929 0x00009b00, 0x00002f00, 0x0000ff00, 0x00008700,
930 0x00003400, 0x00008e00, 0x00004300, 0x00004400,
931 0x0000c400, 0x0000de00, 0x0000e900, 0x0000cb00,
932 0x00005400, 0x00007b00, 0x00009400, 0x00003200,
933 0x0000a600, 0x0000c200, 0x00002300, 0x00003d00,
934 0x0000ee00, 0x00004c00, 0x00009500, 0x00000b00,
935 0x00004200, 0x0000fa00, 0x0000c300, 0x00004e00,
936 0x00000800, 0x00002e00, 0x0000a100, 0x00006600,
937 0x00002800, 0x0000d900, 0x00002400, 0x0000b200,
938 0x00007600, 0x00005b00, 0x0000a200, 0x00004900,
939 0x00006d00, 0x00008b00, 0x0000d100, 0x00002500,
940 0x00007200, 0x0000f800, 0x0000f600, 0x00006400,
941 0x00008600, 0x00006800, 0x00009800, 0x00001600,
942 0x0000d400, 0x0000a400, 0x00005c00, 0x0000cc00,
943 0x00005d00, 0x00006500, 0x0000b600, 0x00009200,
944 0x00006c00, 0x00007000, 0x00004800, 0x00005000,
945 0x0000fd00, 0x0000ed00, 0x0000b900, 0x0000da00,
946 0x00005e00, 0x00001500, 0x00004600, 0x00005700,
947 0x0000a700, 0x00008d00, 0x00009d00, 0x00008400,
948 0x00009000, 0x0000d800, 0x0000ab00, 0x00000000,
949 0x00008c00, 0x0000bc00, 0x0000d300, 0x00000a00,
950 0x0000f700, 0x0000e400, 0x00005800, 0x00000500,
951 0x0000b800, 0x0000b300, 0x00004500, 0x00000600,
952 0x0000d000, 0x00002c00, 0x00001e00, 0x00008f00,
953 0x0000ca00, 0x00003f00, 0x00000f00, 0x00000200,
954 0x0000c100, 0x0000af00, 0x0000bd00, 0x00000300,
955 0x00000100, 0x00001300, 0x00008a00, 0x00006b00,
956 0x00003a00, 0x00009100, 0x00001100, 0x00004100,
957 0x00004f00, 0x00006700, 0x0000dc00, 0x0000ea00,
958 0x00009700, 0x0000f200, 0x0000cf00, 0x0000ce00,
959 0x0000f000, 0x0000b400, 0x0000e600, 0x00007300,
960 0x00009600, 0x0000ac00, 0x00007400, 0x00002200,
961 0x0000e700, 0x0000ad00, 0x00003500, 0x00008500,
962 0x0000e200, 0x0000f900, 0x00003700, 0x0000e800,
963 0x00001c00, 0x00007500, 0x0000df00, 0x00006e00,
964 0x00004700, 0x0000f100, 0x00001a00, 0x00007100,
965 0x00001d00, 0x00002900, 0x0000c500, 0x00008900,
966 0x00006f00, 0x0000b700, 0x00006200, 0x00000e00,
967 0x0000aa00, 0x00001800, 0x0000be00, 0x00001b00,
968 0x0000fc00, 0x00005600, 0x00003e00, 0x00004b00,
969 0x0000c600, 0x0000d200, 0x00007900, 0x00002000,
970 0x00009a00, 0x0000db00, 0x0000c000, 0x0000fe00,
971 0x00007800, 0x0000cd00, 0x00005a00, 0x0000f400,
972 0x00001f00, 0x0000dd00, 0x0000a800, 0x00003300,
973 0x00008800, 0x00000700, 0x0000c700, 0x00003100,
974 0x0000b100, 0x00001200, 0x00001000, 0x00005900,
975 0x00002700, 0x00008000, 0x0000ec00, 0x00005f00,
976 0x00006000, 0x00005100, 0x00007f00, 0x0000a900,
977 0x00001900, 0x0000b500, 0x00004a00, 0x00000d00,
978 0x00002d00, 0x0000e500, 0x00007a00, 0x00009f00,
979 0x00009300, 0x0000c900, 0x00009c00, 0x0000ef00,
980 0x0000a000, 0x0000e000, 0x00003b00, 0x00004d00,
981 0x0000ae00, 0x00002a00, 0x0000f500, 0x0000b000,
982 0x0000c800, 0x0000eb00, 0x0000bb00, 0x00003c00,
983 0x00008300, 0x00005300, 0x00009900, 0x00006100,
984 0x00001700, 0x00002b00, 0x00000400, 0x00007e00,
985 0x0000ba00, 0x00007700, 0x0000d600, 0x00002600,
986 0x0000e100, 0x00006900, 0x00001400, 0x00006300,
987 0x00005500, 0x00002100, 0x00000c00, 0x00007d00,
988 }, {
989 0x00520000, 0x00090000, 0x006a0000, 0x00d50000,
990 0x00300000, 0x00360000, 0x00a50000, 0x00380000,
991 0x00bf0000, 0x00400000, 0x00a30000, 0x009e0000,
992 0x00810000, 0x00f30000, 0x00d70000, 0x00fb0000,
993 0x007c0000, 0x00e30000, 0x00390000, 0x00820000,
994 0x009b0000, 0x002f0000, 0x00ff0000, 0x00870000,
995 0x00340000, 0x008e0000, 0x00430000, 0x00440000,
996 0x00c40000, 0x00de0000, 0x00e90000, 0x00cb0000,
997 0x00540000, 0x007b0000, 0x00940000, 0x00320000,
998 0x00a60000, 0x00c20000, 0x00230000, 0x003d0000,
999 0x00ee0000, 0x004c0000, 0x00950000, 0x000b0000,
1000 0x00420000, 0x00fa0000, 0x00c30000, 0x004e0000,
1001 0x00080000, 0x002e0000, 0x00a10000, 0x00660000,
1002 0x00280000, 0x00d90000, 0x00240000, 0x00b20000,
1003 0x00760000, 0x005b0000, 0x00a20000, 0x00490000,
1004 0x006d0000, 0x008b0000, 0x00d10000, 0x00250000,
1005 0x00720000, 0x00f80000, 0x00f60000, 0x00640000,
1006 0x00860000, 0x00680000, 0x00980000, 0x00160000,
1007 0x00d40000, 0x00a40000, 0x005c0000, 0x00cc0000,
1008 0x005d0000, 0x00650000, 0x00b60000, 0x00920000,
1009 0x006c0000, 0x00700000, 0x00480000, 0x00500000,
1010 0x00fd0000, 0x00ed0000, 0x00b90000, 0x00da0000,
1011 0x005e0000, 0x00150000, 0x00460000, 0x00570000,
1012 0x00a70000, 0x008d0000, 0x009d0000, 0x00840000,
1013 0x00900000, 0x00d80000, 0x00ab0000, 0x00000000,
1014 0x008c0000, 0x00bc0000, 0x00d30000, 0x000a0000,
1015 0x00f70000, 0x00e40000, 0x00580000, 0x00050000,
1016 0x00b80000, 0x00b30000, 0x00450000, 0x00060000,
1017 0x00d00000, 0x002c0000, 0x001e0000, 0x008f0000,
1018 0x00ca0000, 0x003f0000, 0x000f0000, 0x00020000,
1019 0x00c10000, 0x00af0000, 0x00bd0000, 0x00030000,
1020 0x00010000, 0x00130000, 0x008a0000, 0x006b0000,
1021 0x003a0000, 0x00910000, 0x00110000, 0x00410000,
1022 0x004f0000, 0x00670000, 0x00dc0000, 0x00ea0000,
1023 0x00970000, 0x00f20000, 0x00cf0000, 0x00ce0000,
1024 0x00f00000, 0x00b40000, 0x00e60000, 0x00730000,
1025 0x00960000, 0x00ac0000, 0x00740000, 0x00220000,
1026 0x00e70000, 0x00ad0000, 0x00350000, 0x00850000,
1027 0x00e20000, 0x00f90000, 0x00370000, 0x00e80000,
1028 0x001c0000, 0x00750000, 0x00df0000, 0x006e0000,
1029 0x00470000, 0x00f10000, 0x001a0000, 0x00710000,
1030 0x001d0000, 0x00290000, 0x00c50000, 0x00890000,
1031 0x006f0000, 0x00b70000, 0x00620000, 0x000e0000,
1032 0x00aa0000, 0x00180000, 0x00be0000, 0x001b0000,
1033 0x00fc0000, 0x00560000, 0x003e0000, 0x004b0000,
1034 0x00c60000, 0x00d20000, 0x00790000, 0x00200000,
1035 0x009a0000, 0x00db0000, 0x00c00000, 0x00fe0000,
1036 0x00780000, 0x00cd0000, 0x005a0000, 0x00f40000,
1037 0x001f0000, 0x00dd0000, 0x00a80000, 0x00330000,
1038 0x00880000, 0x00070000, 0x00c70000, 0x00310000,
1039 0x00b10000, 0x00120000, 0x00100000, 0x00590000,
1040 0x00270000, 0x00800000, 0x00ec0000, 0x005f0000,
1041 0x00600000, 0x00510000, 0x007f0000, 0x00a90000,
1042 0x00190000, 0x00b50000, 0x004a0000, 0x000d0000,
1043 0x002d0000, 0x00e50000, 0x007a0000, 0x009f0000,
1044 0x00930000, 0x00c90000, 0x009c0000, 0x00ef0000,
1045 0x00a00000, 0x00e00000, 0x003b0000, 0x004d0000,
1046 0x00ae0000, 0x002a0000, 0x00f50000, 0x00b00000,
1047 0x00c80000, 0x00eb0000, 0x00bb0000, 0x003c0000,
1048 0x00830000, 0x00530000, 0x00990000, 0x00610000,
1049 0x00170000, 0x002b0000, 0x00040000, 0x007e0000,
1050 0x00ba0000, 0x00770000, 0x00d60000, 0x00260000,
1051 0x00e10000, 0x00690000, 0x00140000, 0x00630000,
1052 0x00550000, 0x00210000, 0x000c0000, 0x007d0000,
1053 }, {
1054 0x52000000, 0x09000000, 0x6a000000, 0xd5000000,
1055 0x30000000, 0x36000000, 0xa5000000, 0x38000000,
1056 0xbf000000, 0x40000000, 0xa3000000, 0x9e000000,
1057 0x81000000, 0xf3000000, 0xd7000000, 0xfb000000,
1058 0x7c000000, 0xe3000000, 0x39000000, 0x82000000,
1059 0x9b000000, 0x2f000000, 0xff000000, 0x87000000,
1060 0x34000000, 0x8e000000, 0x43000000, 0x44000000,
1061 0xc4000000, 0xde000000, 0xe9000000, 0xcb000000,
1062 0x54000000, 0x7b000000, 0x94000000, 0x32000000,
1063 0xa6000000, 0xc2000000, 0x23000000, 0x3d000000,
1064 0xee000000, 0x4c000000, 0x95000000, 0x0b000000,
1065 0x42000000, 0xfa000000, 0xc3000000, 0x4e000000,
1066 0x08000000, 0x2e000000, 0xa1000000, 0x66000000,
1067 0x28000000, 0xd9000000, 0x24000000, 0xb2000000,
1068 0x76000000, 0x5b000000, 0xa2000000, 0x49000000,
1069 0x6d000000, 0x8b000000, 0xd1000000, 0x25000000,
1070 0x72000000, 0xf8000000, 0xf6000000, 0x64000000,
1071 0x86000000, 0x68000000, 0x98000000, 0x16000000,
1072 0xd4000000, 0xa4000000, 0x5c000000, 0xcc000000,
1073 0x5d000000, 0x65000000, 0xb6000000, 0x92000000,
1074 0x6c000000, 0x70000000, 0x48000000, 0x50000000,
1075 0xfd000000, 0xed000000, 0xb9000000, 0xda000000,
1076 0x5e000000, 0x15000000, 0x46000000, 0x57000000,
1077 0xa7000000, 0x8d000000, 0x9d000000, 0x84000000,
1078 0x90000000, 0xd8000000, 0xab000000, 0x00000000,
1079 0x8c000000, 0xbc000000, 0xd3000000, 0x0a000000,
1080 0xf7000000, 0xe4000000, 0x58000000, 0x05000000,
1081 0xb8000000, 0xb3000000, 0x45000000, 0x06000000,
1082 0xd0000000, 0x2c000000, 0x1e000000, 0x8f000000,
1083 0xca000000, 0x3f000000, 0x0f000000, 0x02000000,
1084 0xc1000000, 0xaf000000, 0xbd000000, 0x03000000,
1085 0x01000000, 0x13000000, 0x8a000000, 0x6b000000,
1086 0x3a000000, 0x91000000, 0x11000000, 0x41000000,
1087 0x4f000000, 0x67000000, 0xdc000000, 0xea000000,
1088 0x97000000, 0xf2000000, 0xcf000000, 0xce000000,
1089 0xf0000000, 0xb4000000, 0xe6000000, 0x73000000,
1090 0x96000000, 0xac000000, 0x74000000, 0x22000000,
1091 0xe7000000, 0xad000000, 0x35000000, 0x85000000,
1092 0xe2000000, 0xf9000000, 0x37000000, 0xe8000000,
1093 0x1c000000, 0x75000000, 0xdf000000, 0x6e000000,
1094 0x47000000, 0xf1000000, 0x1a000000, 0x71000000,
1095 0x1d000000, 0x29000000, 0xc5000000, 0x89000000,
1096 0x6f000000, 0xb7000000, 0x62000000, 0x0e000000,
1097 0xaa000000, 0x18000000, 0xbe000000, 0x1b000000,
1098 0xfc000000, 0x56000000, 0x3e000000, 0x4b000000,
1099 0xc6000000, 0xd2000000, 0x79000000, 0x20000000,
1100 0x9a000000, 0xdb000000, 0xc0000000, 0xfe000000,
1101 0x78000000, 0xcd000000, 0x5a000000, 0xf4000000,
1102 0x1f000000, 0xdd000000, 0xa8000000, 0x33000000,
1103 0x88000000, 0x07000000, 0xc7000000, 0x31000000,
1104 0xb1000000, 0x12000000, 0x10000000, 0x59000000,
1105 0x27000000, 0x80000000, 0xec000000, 0x5f000000,
1106 0x60000000, 0x51000000, 0x7f000000, 0xa9000000,
1107 0x19000000, 0xb5000000, 0x4a000000, 0x0d000000,
1108 0x2d000000, 0xe5000000, 0x7a000000, 0x9f000000,
1109 0x93000000, 0xc9000000, 0x9c000000, 0xef000000,
1110 0xa0000000, 0xe0000000, 0x3b000000, 0x4d000000,
1111 0xae000000, 0x2a000000, 0xf5000000, 0xb0000000,
1112 0xc8000000, 0xeb000000, 0xbb000000, 0x3c000000,
1113 0x83000000, 0x53000000, 0x99000000, 0x61000000,
1114 0x17000000, 0x2b000000, 0x04000000, 0x7e000000,
1115 0xba000000, 0x77000000, 0xd6000000, 0x26000000,
1116 0xe1000000, 0x69000000, 0x14000000, 0x63000000,
1117 0x55000000, 0x21000000, 0x0c000000, 0x7d000000,
157 } 1118 }
158} 1119};
1120
1121EXPORT_SYMBOL_GPL(crypto_ft_tab);
1122EXPORT_SYMBOL_GPL(crypto_fl_tab);
1123EXPORT_SYMBOL_GPL(crypto_it_tab);
1124EXPORT_SYMBOL_GPL(crypto_il_tab);
159 1125
160/* initialise the key schedule from the user supplied key */ 1126/* initialise the key schedule from the user supplied key */
161 1127
@@ -491,7 +1457,6 @@ static struct crypto_alg aes_alg = {
491 1457
492static int __init aes_init(void) 1458static int __init aes_init(void)
493{ 1459{
494 gen_tabs();
495 return crypto_register_alg(&aes_alg); 1460 return crypto_register_alg(&aes_alg);
496} 1461}
497 1462
diff --git a/crypto/ahash.c b/crypto/ahash.c
index 27128f2c687a..ba5292d69ebd 100644
--- a/crypto/ahash.c
+++ b/crypto/ahash.c
@@ -112,6 +112,22 @@ int crypto_hash_walk_first(struct ahash_request *req,
112} 112}
113EXPORT_SYMBOL_GPL(crypto_hash_walk_first); 113EXPORT_SYMBOL_GPL(crypto_hash_walk_first);
114 114
115int crypto_hash_walk_first_compat(struct hash_desc *hdesc,
116 struct crypto_hash_walk *walk,
117 struct scatterlist *sg, unsigned int len)
118{
119 walk->total = len;
120
121 if (!walk->total)
122 return 0;
123
124 walk->alignmask = crypto_hash_alignmask(hdesc->tfm);
125 walk->sg = sg;
126 walk->flags = hdesc->flags;
127
128 return hash_walk_new_entry(walk);
129}
130
115static int ahash_setkey_unaligned(struct crypto_ahash *tfm, const u8 *key, 131static int ahash_setkey_unaligned(struct crypto_ahash *tfm, const u8 *key,
116 unsigned int keylen) 132 unsigned int keylen)
117{ 133{
@@ -146,6 +162,26 @@ static int ahash_setkey(struct crypto_ahash *tfm, const u8 *key,
146 return ahash->setkey(tfm, key, keylen); 162 return ahash->setkey(tfm, key, keylen);
147} 163}
148 164
165static int ahash_nosetkey(struct crypto_ahash *tfm, const u8 *key,
166 unsigned int keylen)
167{
168 return -ENOSYS;
169}
170
171int crypto_ahash_import(struct ahash_request *req, const u8 *in)
172{
173 struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
174 struct ahash_alg *alg = crypto_ahash_alg(tfm);
175
176 memcpy(ahash_request_ctx(req), in, crypto_ahash_reqsize(tfm));
177
178 if (alg->reinit)
179 alg->reinit(req);
180
181 return 0;
182}
183EXPORT_SYMBOL_GPL(crypto_ahash_import);
184
149static unsigned int crypto_ahash_ctxsize(struct crypto_alg *alg, u32 type, 185static unsigned int crypto_ahash_ctxsize(struct crypto_alg *alg, u32 type,
150 u32 mask) 186 u32 mask)
151{ 187{
@@ -164,7 +200,7 @@ static int crypto_init_ahash_ops(struct crypto_tfm *tfm, u32 type, u32 mask)
164 crt->update = alg->update; 200 crt->update = alg->update;
165 crt->final = alg->final; 201 crt->final = alg->final;
166 crt->digest = alg->digest; 202 crt->digest = alg->digest;
167 crt->setkey = ahash_setkey; 203 crt->setkey = alg->setkey ? ahash_setkey : ahash_nosetkey;
168 crt->digestsize = alg->digestsize; 204 crt->digestsize = alg->digestsize;
169 205
170 return 0; 206 return 0;
diff --git a/crypto/ansi_cprng.c b/crypto/ansi_cprng.c
index 72db0fd763cc..0fac8ffc2fb7 100644
--- a/crypto/ansi_cprng.c
+++ b/crypto/ansi_cprng.c
@@ -161,7 +161,7 @@ static int _get_more_prng_bytes(struct prng_context *ctx)
161 /* 161 /*
162 * Now update our DT value 162 * Now update our DT value
163 */ 163 */
164 for (i = 0; i < DEFAULT_BLK_SZ; i++) { 164 for (i = DEFAULT_BLK_SZ - 1; i >= 0; i--) {
165 ctx->DT[i] += 1; 165 ctx->DT[i] += 1;
166 if (ctx->DT[i] != 0) 166 if (ctx->DT[i] != 0)
167 break; 167 break;
@@ -223,9 +223,10 @@ remainder:
223 } 223 }
224 224
225 /* 225 /*
226 * Copy up to the next whole block size 226 * Copy any data less than an entire block
227 */ 227 */
228 if (byte_count < DEFAULT_BLK_SZ) { 228 if (byte_count < DEFAULT_BLK_SZ) {
229empty_rbuf:
229 for (; ctx->rand_data_valid < DEFAULT_BLK_SZ; 230 for (; ctx->rand_data_valid < DEFAULT_BLK_SZ;
230 ctx->rand_data_valid++) { 231 ctx->rand_data_valid++) {
231 *ptr = ctx->rand_data[ctx->rand_data_valid]; 232 *ptr = ctx->rand_data[ctx->rand_data_valid];
@@ -240,18 +241,22 @@ remainder:
240 * Now copy whole blocks 241 * Now copy whole blocks
241 */ 242 */
242 for (; byte_count >= DEFAULT_BLK_SZ; byte_count -= DEFAULT_BLK_SZ) { 243 for (; byte_count >= DEFAULT_BLK_SZ; byte_count -= DEFAULT_BLK_SZ) {
243 if (_get_more_prng_bytes(ctx) < 0) { 244 if (ctx->rand_data_valid == DEFAULT_BLK_SZ) {
244 memset(buf, 0, nbytes); 245 if (_get_more_prng_bytes(ctx) < 0) {
245 err = -EINVAL; 246 memset(buf, 0, nbytes);
246 goto done; 247 err = -EINVAL;
248 goto done;
249 }
247 } 250 }
251 if (ctx->rand_data_valid > 0)
252 goto empty_rbuf;
248 memcpy(ptr, ctx->rand_data, DEFAULT_BLK_SZ); 253 memcpy(ptr, ctx->rand_data, DEFAULT_BLK_SZ);
249 ctx->rand_data_valid += DEFAULT_BLK_SZ; 254 ctx->rand_data_valid += DEFAULT_BLK_SZ;
250 ptr += DEFAULT_BLK_SZ; 255 ptr += DEFAULT_BLK_SZ;
251 } 256 }
252 257
253 /* 258 /*
254 * Now copy any extra partial data 259 * Now go back and get any remaining partial block
255 */ 260 */
256 if (byte_count) 261 if (byte_count)
257 goto remainder; 262 goto remainder;
@@ -349,15 +354,25 @@ static int cprng_get_random(struct crypto_rng *tfm, u8 *rdata,
349 return get_prng_bytes(rdata, dlen, prng); 354 return get_prng_bytes(rdata, dlen, prng);
350} 355}
351 356
357/*
358 * This is the cprng_registered reset method the seed value is
359 * interpreted as the tuple { V KEY DT}
360 * V and KEY are required during reset, and DT is optional, detected
361 * as being present by testing the length of the seed
362 */
352static int cprng_reset(struct crypto_rng *tfm, u8 *seed, unsigned int slen) 363static int cprng_reset(struct crypto_rng *tfm, u8 *seed, unsigned int slen)
353{ 364{
354 struct prng_context *prng = crypto_rng_ctx(tfm); 365 struct prng_context *prng = crypto_rng_ctx(tfm);
355 u8 *key = seed + DEFAULT_PRNG_KSZ; 366 u8 *key = seed + DEFAULT_BLK_SZ;
367 u8 *dt = NULL;
356 368
357 if (slen < DEFAULT_PRNG_KSZ + DEFAULT_BLK_SZ) 369 if (slen < DEFAULT_PRNG_KSZ + DEFAULT_BLK_SZ)
358 return -EINVAL; 370 return -EINVAL;
359 371
360 reset_prng_context(prng, key, DEFAULT_PRNG_KSZ, seed, NULL); 372 if (slen >= (2 * DEFAULT_BLK_SZ + DEFAULT_PRNG_KSZ))
373 dt = key + DEFAULT_PRNG_KSZ;
374
375 reset_prng_context(prng, key, DEFAULT_PRNG_KSZ, seed, dt);
361 376
362 if (prng->flags & PRNG_NEED_RESET) 377 if (prng->flags & PRNG_NEED_RESET)
363 return -EINVAL; 378 return -EINVAL;
@@ -379,7 +394,7 @@ static struct crypto_alg rng_alg = {
379 .rng = { 394 .rng = {
380 .rng_make_random = cprng_get_random, 395 .rng_make_random = cprng_get_random,
381 .rng_reset = cprng_reset, 396 .rng_reset = cprng_reset,
382 .seedsize = DEFAULT_PRNG_KSZ + DEFAULT_BLK_SZ, 397 .seedsize = DEFAULT_PRNG_KSZ + 2*DEFAULT_BLK_SZ,
383 } 398 }
384 } 399 }
385}; 400};
diff --git a/crypto/api.c b/crypto/api.c
index 0444d242e985..9975a7bd246c 100644
--- a/crypto/api.c
+++ b/crypto/api.c
@@ -300,8 +300,8 @@ static void crypto_exit_ops(struct crypto_tfm *tfm)
300 const struct crypto_type *type = tfm->__crt_alg->cra_type; 300 const struct crypto_type *type = tfm->__crt_alg->cra_type;
301 301
302 if (type) { 302 if (type) {
303 if (type->exit) 303 if (tfm->exit)
304 type->exit(tfm); 304 tfm->exit(tfm);
305 return; 305 return;
306 } 306 }
307 307
@@ -379,17 +379,16 @@ struct crypto_tfm *__crypto_alloc_tfm(struct crypto_alg *alg, u32 type,
379 if (err) 379 if (err)
380 goto out_free_tfm; 380 goto out_free_tfm;
381 381
382 if (alg->cra_init && (err = alg->cra_init(tfm))) { 382 if (!tfm->exit && alg->cra_init && (err = alg->cra_init(tfm)))
383 if (err == -EAGAIN)
384 crypto_shoot_alg(alg);
385 goto cra_init_failed; 383 goto cra_init_failed;
386 }
387 384
388 goto out; 385 goto out;
389 386
390cra_init_failed: 387cra_init_failed:
391 crypto_exit_ops(tfm); 388 crypto_exit_ops(tfm);
392out_free_tfm: 389out_free_tfm:
390 if (err == -EAGAIN)
391 crypto_shoot_alg(alg);
393 kfree(tfm); 392 kfree(tfm);
394out_err: 393out_err:
395 tfm = ERR_PTR(err); 394 tfm = ERR_PTR(err);
@@ -404,6 +403,9 @@ EXPORT_SYMBOL_GPL(__crypto_alloc_tfm);
404 * @type: Type of algorithm 403 * @type: Type of algorithm
405 * @mask: Mask for type comparison 404 * @mask: Mask for type comparison
406 * 405 *
406 * This function should not be used by new algorithm types.
407 * Plesae use crypto_alloc_tfm instead.
408 *
407 * crypto_alloc_base() will first attempt to locate an already loaded 409 * crypto_alloc_base() will first attempt to locate an already loaded
408 * algorithm. If that fails and the kernel supports dynamically loadable 410 * algorithm. If that fails and the kernel supports dynamically loadable
409 * modules, it will then attempt to load a module of the same name or 411 * modules, it will then attempt to load a module of the same name or
@@ -450,6 +452,111 @@ err:
450 return ERR_PTR(err); 452 return ERR_PTR(err);
451} 453}
452EXPORT_SYMBOL_GPL(crypto_alloc_base); 454EXPORT_SYMBOL_GPL(crypto_alloc_base);
455
456struct crypto_tfm *crypto_create_tfm(struct crypto_alg *alg,
457 const struct crypto_type *frontend)
458{
459 char *mem;
460 struct crypto_tfm *tfm = NULL;
461 unsigned int tfmsize;
462 unsigned int total;
463 int err = -ENOMEM;
464
465 tfmsize = frontend->tfmsize;
466 total = tfmsize + sizeof(*tfm) + frontend->extsize(alg, frontend);
467
468 mem = kzalloc(total, GFP_KERNEL);
469 if (mem == NULL)
470 goto out_err;
471
472 tfm = (struct crypto_tfm *)(mem + tfmsize);
473 tfm->__crt_alg = alg;
474
475 err = frontend->init_tfm(tfm, frontend);
476 if (err)
477 goto out_free_tfm;
478
479 if (!tfm->exit && alg->cra_init && (err = alg->cra_init(tfm)))
480 goto cra_init_failed;
481
482 goto out;
483
484cra_init_failed:
485 crypto_exit_ops(tfm);
486out_free_tfm:
487 if (err == -EAGAIN)
488 crypto_shoot_alg(alg);
489 kfree(mem);
490out_err:
491 tfm = ERR_PTR(err);
492out:
493 return tfm;
494}
495EXPORT_SYMBOL_GPL(crypto_create_tfm);
496
497/*
498 * crypto_alloc_tfm - Locate algorithm and allocate transform
499 * @alg_name: Name of algorithm
500 * @frontend: Frontend algorithm type
501 * @type: Type of algorithm
502 * @mask: Mask for type comparison
503 *
504 * crypto_alloc_tfm() will first attempt to locate an already loaded
505 * algorithm. If that fails and the kernel supports dynamically loadable
506 * modules, it will then attempt to load a module of the same name or
507 * alias. If that fails it will send a query to any loaded crypto manager
508 * to construct an algorithm on the fly. A refcount is grabbed on the
509 * algorithm which is then associated with the new transform.
510 *
511 * The returned transform is of a non-determinate type. Most people
512 * should use one of the more specific allocation functions such as
513 * crypto_alloc_blkcipher.
514 *
515 * In case of error the return value is an error pointer.
516 */
517struct crypto_tfm *crypto_alloc_tfm(const char *alg_name,
518 const struct crypto_type *frontend,
519 u32 type, u32 mask)
520{
521 struct crypto_alg *(*lookup)(const char *name, u32 type, u32 mask);
522 struct crypto_tfm *tfm;
523 int err;
524
525 type &= frontend->maskclear;
526 mask &= frontend->maskclear;
527 type |= frontend->type;
528 mask |= frontend->maskset;
529
530 lookup = frontend->lookup ?: crypto_alg_mod_lookup;
531
532 for (;;) {
533 struct crypto_alg *alg;
534
535 alg = lookup(alg_name, type, mask);
536 if (IS_ERR(alg)) {
537 err = PTR_ERR(alg);
538 goto err;
539 }
540
541 tfm = crypto_create_tfm(alg, frontend);
542 if (!IS_ERR(tfm))
543 return tfm;
544
545 crypto_mod_put(alg);
546 err = PTR_ERR(tfm);
547
548err:
549 if (err != -EAGAIN)
550 break;
551 if (signal_pending(current)) {
552 err = -EINTR;
553 break;
554 }
555 }
556
557 return ERR_PTR(err);
558}
559EXPORT_SYMBOL_GPL(crypto_alloc_tfm);
453 560
454/* 561/*
455 * crypto_free_tfm - Free crypto transform 562 * crypto_free_tfm - Free crypto transform
@@ -469,7 +576,7 @@ void crypto_free_tfm(struct crypto_tfm *tfm)
469 alg = tfm->__crt_alg; 576 alg = tfm->__crt_alg;
470 size = sizeof(*tfm) + alg->cra_ctxsize; 577 size = sizeof(*tfm) + alg->cra_ctxsize;
471 578
472 if (alg->cra_exit) 579 if (!tfm->exit && alg->cra_exit)
473 alg->cra_exit(tfm); 580 alg->cra_exit(tfm);
474 crypto_exit_ops(tfm); 581 crypto_exit_ops(tfm);
475 crypto_mod_put(alg); 582 crypto_mod_put(alg);
diff --git a/crypto/authenc.c b/crypto/authenc.c
index fd9f06c63d76..40b6e9ec9e3a 100644
--- a/crypto/authenc.c
+++ b/crypto/authenc.c
@@ -11,6 +11,7 @@
11 */ 11 */
12 12
13#include <crypto/aead.h> 13#include <crypto/aead.h>
14#include <crypto/internal/hash.h>
14#include <crypto/internal/skcipher.h> 15#include <crypto/internal/skcipher.h>
15#include <crypto/authenc.h> 16#include <crypto/authenc.h>
16#include <crypto/scatterwalk.h> 17#include <crypto/scatterwalk.h>
@@ -431,6 +432,8 @@ static struct crypto_instance *crypto_authenc_alloc(struct rtattr **tb)
431 inst->alg.cra_aead.ivsize = enc->cra_ablkcipher.ivsize; 432 inst->alg.cra_aead.ivsize = enc->cra_ablkcipher.ivsize;
432 inst->alg.cra_aead.maxauthsize = auth->cra_type == &crypto_hash_type ? 433 inst->alg.cra_aead.maxauthsize = auth->cra_type == &crypto_hash_type ?
433 auth->cra_hash.digestsize : 434 auth->cra_hash.digestsize :
435 auth->cra_type ?
436 __crypto_shash_alg(auth)->digestsize :
434 auth->cra_digest.dia_digestsize; 437 auth->cra_digest.dia_digestsize;
435 438
436 inst->alg.cra_ctxsize = sizeof(struct crypto_authenc_ctx); 439 inst->alg.cra_ctxsize = sizeof(struct crypto_authenc_ctx);
diff --git a/crypto/camellia.c b/crypto/camellia.c
index 493fee7e0a8b..964635d163f4 100644
--- a/crypto/camellia.c
+++ b/crypto/camellia.c
@@ -35,6 +35,8 @@
35#include <linux/init.h> 35#include <linux/init.h>
36#include <linux/kernel.h> 36#include <linux/kernel.h>
37#include <linux/module.h> 37#include <linux/module.h>
38#include <linux/bitops.h>
39#include <asm/unaligned.h>
38 40
39static const u32 camellia_sp1110[256] = { 41static const u32 camellia_sp1110[256] = {
40 0x70707000,0x82828200,0x2c2c2c00,0xececec00, 42 0x70707000,0x82828200,0x2c2c2c00,0xececec00,
@@ -335,20 +337,6 @@ static const u32 camellia_sp4404[256] = {
335/* 337/*
336 * macros 338 * macros
337 */ 339 */
338#define GETU32(v, pt) \
339 do { \
340 /* latest breed of gcc is clever enough to use move */ \
341 memcpy(&(v), (pt), 4); \
342 (v) = be32_to_cpu(v); \
343 } while(0)
344
345/* rotation right shift 1byte */
346#define ROR8(x) (((x) >> 8) + ((x) << 24))
347/* rotation left shift 1bit */
348#define ROL1(x) (((x) << 1) + ((x) >> 31))
349/* rotation left shift 1byte */
350#define ROL8(x) (((x) << 8) + ((x) >> 24))
351
352#define ROLDQ(ll, lr, rl, rr, w0, w1, bits) \ 340#define ROLDQ(ll, lr, rl, rr, w0, w1, bits) \
353 do { \ 341 do { \
354 w0 = ll; \ 342 w0 = ll; \
@@ -383,7 +371,7 @@ static const u32 camellia_sp4404[256] = {
383 ^ camellia_sp3033[(u8)(il >> 8)] \ 371 ^ camellia_sp3033[(u8)(il >> 8)] \
384 ^ camellia_sp4404[(u8)(il )]; \ 372 ^ camellia_sp4404[(u8)(il )]; \
385 yl ^= yr; \ 373 yl ^= yr; \
386 yr = ROR8(yr); \ 374 yr = ror32(yr, 8); \
387 yr ^= yl; \ 375 yr ^= yl; \
388 } while(0) 376 } while(0)
389 377
@@ -405,7 +393,7 @@ static void camellia_setup_tail(u32 *subkey, u32 *subL, u32 *subR, int max)
405 subL[7] ^= subL[1]; subR[7] ^= subR[1]; 393 subL[7] ^= subL[1]; subR[7] ^= subR[1];
406 subL[1] ^= subR[1] & ~subR[9]; 394 subL[1] ^= subR[1] & ~subR[9];
407 dw = subL[1] & subL[9], 395 dw = subL[1] & subL[9],
408 subR[1] ^= ROL1(dw); /* modified for FLinv(kl2) */ 396 subR[1] ^= rol32(dw, 1); /* modified for FLinv(kl2) */
409 /* round 8 */ 397 /* round 8 */
410 subL[11] ^= subL[1]; subR[11] ^= subR[1]; 398 subL[11] ^= subL[1]; subR[11] ^= subR[1];
411 /* round 10 */ 399 /* round 10 */
@@ -414,7 +402,7 @@ static void camellia_setup_tail(u32 *subkey, u32 *subL, u32 *subR, int max)
414 subL[15] ^= subL[1]; subR[15] ^= subR[1]; 402 subL[15] ^= subL[1]; subR[15] ^= subR[1];
415 subL[1] ^= subR[1] & ~subR[17]; 403 subL[1] ^= subR[1] & ~subR[17];
416 dw = subL[1] & subL[17], 404 dw = subL[1] & subL[17],
417 subR[1] ^= ROL1(dw); /* modified for FLinv(kl4) */ 405 subR[1] ^= rol32(dw, 1); /* modified for FLinv(kl4) */
418 /* round 14 */ 406 /* round 14 */
419 subL[19] ^= subL[1]; subR[19] ^= subR[1]; 407 subL[19] ^= subL[1]; subR[19] ^= subR[1];
420 /* round 16 */ 408 /* round 16 */
@@ -430,7 +418,7 @@ static void camellia_setup_tail(u32 *subkey, u32 *subL, u32 *subR, int max)
430 } else { 418 } else {
431 subL[1] ^= subR[1] & ~subR[25]; 419 subL[1] ^= subR[1] & ~subR[25];
432 dw = subL[1] & subL[25], 420 dw = subL[1] & subL[25],
433 subR[1] ^= ROL1(dw); /* modified for FLinv(kl6) */ 421 subR[1] ^= rol32(dw, 1); /* modified for FLinv(kl6) */
434 /* round 20 */ 422 /* round 20 */
435 subL[27] ^= subL[1]; subR[27] ^= subR[1]; 423 subL[27] ^= subL[1]; subR[27] ^= subR[1];
436 /* round 22 */ 424 /* round 22 */
@@ -450,7 +438,7 @@ static void camellia_setup_tail(u32 *subkey, u32 *subL, u32 *subR, int max)
450 subL[26] ^= kw4l; subR[26] ^= kw4r; 438 subL[26] ^= kw4l; subR[26] ^= kw4r;
451 kw4l ^= kw4r & ~subR[24]; 439 kw4l ^= kw4r & ~subR[24];
452 dw = kw4l & subL[24], 440 dw = kw4l & subL[24],
453 kw4r ^= ROL1(dw); /* modified for FL(kl5) */ 441 kw4r ^= rol32(dw, 1); /* modified for FL(kl5) */
454 } 442 }
455 /* round 17 */ 443 /* round 17 */
456 subL[22] ^= kw4l; subR[22] ^= kw4r; 444 subL[22] ^= kw4l; subR[22] ^= kw4r;
@@ -460,7 +448,7 @@ static void camellia_setup_tail(u32 *subkey, u32 *subL, u32 *subR, int max)
460 subL[18] ^= kw4l; subR[18] ^= kw4r; 448 subL[18] ^= kw4l; subR[18] ^= kw4r;
461 kw4l ^= kw4r & ~subR[16]; 449 kw4l ^= kw4r & ~subR[16];
462 dw = kw4l & subL[16], 450 dw = kw4l & subL[16],
463 kw4r ^= ROL1(dw); /* modified for FL(kl3) */ 451 kw4r ^= rol32(dw, 1); /* modified for FL(kl3) */
464 /* round 11 */ 452 /* round 11 */
465 subL[14] ^= kw4l; subR[14] ^= kw4r; 453 subL[14] ^= kw4l; subR[14] ^= kw4r;
466 /* round 9 */ 454 /* round 9 */
@@ -469,7 +457,7 @@ static void camellia_setup_tail(u32 *subkey, u32 *subL, u32 *subR, int max)
469 subL[10] ^= kw4l; subR[10] ^= kw4r; 457 subL[10] ^= kw4l; subR[10] ^= kw4r;
470 kw4l ^= kw4r & ~subR[8]; 458 kw4l ^= kw4r & ~subR[8];
471 dw = kw4l & subL[8], 459 dw = kw4l & subL[8],
472 kw4r ^= ROL1(dw); /* modified for FL(kl1) */ 460 kw4r ^= rol32(dw, 1); /* modified for FL(kl1) */
473 /* round 5 */ 461 /* round 5 */
474 subL[6] ^= kw4l; subR[6] ^= kw4r; 462 subL[6] ^= kw4l; subR[6] ^= kw4r;
475 /* round 3 */ 463 /* round 3 */
@@ -494,7 +482,7 @@ static void camellia_setup_tail(u32 *subkey, u32 *subL, u32 *subR, int max)
494 SUBKEY_R(6) = subR[5] ^ subR[7]; 482 SUBKEY_R(6) = subR[5] ^ subR[7];
495 tl = subL[10] ^ (subR[10] & ~subR[8]); 483 tl = subL[10] ^ (subR[10] & ~subR[8]);
496 dw = tl & subL[8], /* FL(kl1) */ 484 dw = tl & subL[8], /* FL(kl1) */
497 tr = subR[10] ^ ROL1(dw); 485 tr = subR[10] ^ rol32(dw, 1);
498 SUBKEY_L(7) = subL[6] ^ tl; /* round 6 */ 486 SUBKEY_L(7) = subL[6] ^ tl; /* round 6 */
499 SUBKEY_R(7) = subR[6] ^ tr; 487 SUBKEY_R(7) = subR[6] ^ tr;
500 SUBKEY_L(8) = subL[8]; /* FL(kl1) */ 488 SUBKEY_L(8) = subL[8]; /* FL(kl1) */
@@ -503,7 +491,7 @@ static void camellia_setup_tail(u32 *subkey, u32 *subL, u32 *subR, int max)
503 SUBKEY_R(9) = subR[9]; 491 SUBKEY_R(9) = subR[9];
504 tl = subL[7] ^ (subR[7] & ~subR[9]); 492 tl = subL[7] ^ (subR[7] & ~subR[9]);
505 dw = tl & subL[9], /* FLinv(kl2) */ 493 dw = tl & subL[9], /* FLinv(kl2) */
506 tr = subR[7] ^ ROL1(dw); 494 tr = subR[7] ^ rol32(dw, 1);
507 SUBKEY_L(10) = tl ^ subL[11]; /* round 7 */ 495 SUBKEY_L(10) = tl ^ subL[11]; /* round 7 */
508 SUBKEY_R(10) = tr ^ subR[11]; 496 SUBKEY_R(10) = tr ^ subR[11];
509 SUBKEY_L(11) = subL[10] ^ subL[12]; /* round 8 */ 497 SUBKEY_L(11) = subL[10] ^ subL[12]; /* round 8 */
@@ -516,7 +504,7 @@ static void camellia_setup_tail(u32 *subkey, u32 *subL, u32 *subR, int max)
516 SUBKEY_R(14) = subR[13] ^ subR[15]; 504 SUBKEY_R(14) = subR[13] ^ subR[15];
517 tl = subL[18] ^ (subR[18] & ~subR[16]); 505 tl = subL[18] ^ (subR[18] & ~subR[16]);
518 dw = tl & subL[16], /* FL(kl3) */ 506 dw = tl & subL[16], /* FL(kl3) */
519 tr = subR[18] ^ ROL1(dw); 507 tr = subR[18] ^ rol32(dw, 1);
520 SUBKEY_L(15) = subL[14] ^ tl; /* round 12 */ 508 SUBKEY_L(15) = subL[14] ^ tl; /* round 12 */
521 SUBKEY_R(15) = subR[14] ^ tr; 509 SUBKEY_R(15) = subR[14] ^ tr;
522 SUBKEY_L(16) = subL[16]; /* FL(kl3) */ 510 SUBKEY_L(16) = subL[16]; /* FL(kl3) */
@@ -525,7 +513,7 @@ static void camellia_setup_tail(u32 *subkey, u32 *subL, u32 *subR, int max)
525 SUBKEY_R(17) = subR[17]; 513 SUBKEY_R(17) = subR[17];
526 tl = subL[15] ^ (subR[15] & ~subR[17]); 514 tl = subL[15] ^ (subR[15] & ~subR[17]);
527 dw = tl & subL[17], /* FLinv(kl4) */ 515 dw = tl & subL[17], /* FLinv(kl4) */
528 tr = subR[15] ^ ROL1(dw); 516 tr = subR[15] ^ rol32(dw, 1);
529 SUBKEY_L(18) = tl ^ subL[19]; /* round 13 */ 517 SUBKEY_L(18) = tl ^ subL[19]; /* round 13 */
530 SUBKEY_R(18) = tr ^ subR[19]; 518 SUBKEY_R(18) = tr ^ subR[19];
531 SUBKEY_L(19) = subL[18] ^ subL[20]; /* round 14 */ 519 SUBKEY_L(19) = subL[18] ^ subL[20]; /* round 14 */
@@ -544,7 +532,7 @@ static void camellia_setup_tail(u32 *subkey, u32 *subL, u32 *subR, int max)
544 } else { 532 } else {
545 tl = subL[26] ^ (subR[26] & ~subR[24]); 533 tl = subL[26] ^ (subR[26] & ~subR[24]);
546 dw = tl & subL[24], /* FL(kl5) */ 534 dw = tl & subL[24], /* FL(kl5) */
547 tr = subR[26] ^ ROL1(dw); 535 tr = subR[26] ^ rol32(dw, 1);
548 SUBKEY_L(23) = subL[22] ^ tl; /* round 18 */ 536 SUBKEY_L(23) = subL[22] ^ tl; /* round 18 */
549 SUBKEY_R(23) = subR[22] ^ tr; 537 SUBKEY_R(23) = subR[22] ^ tr;
550 SUBKEY_L(24) = subL[24]; /* FL(kl5) */ 538 SUBKEY_L(24) = subL[24]; /* FL(kl5) */
@@ -553,7 +541,7 @@ static void camellia_setup_tail(u32 *subkey, u32 *subL, u32 *subR, int max)
553 SUBKEY_R(25) = subR[25]; 541 SUBKEY_R(25) = subR[25];
554 tl = subL[23] ^ (subR[23] & ~subR[25]); 542 tl = subL[23] ^ (subR[23] & ~subR[25]);
555 dw = tl & subL[25], /* FLinv(kl6) */ 543 dw = tl & subL[25], /* FLinv(kl6) */
556 tr = subR[23] ^ ROL1(dw); 544 tr = subR[23] ^ rol32(dw, 1);
557 SUBKEY_L(26) = tl ^ subL[27]; /* round 19 */ 545 SUBKEY_L(26) = tl ^ subL[27]; /* round 19 */
558 SUBKEY_R(26) = tr ^ subR[27]; 546 SUBKEY_R(26) = tr ^ subR[27];
559 SUBKEY_L(27) = subL[26] ^ subL[28]; /* round 20 */ 547 SUBKEY_L(27) = subL[26] ^ subL[28]; /* round 20 */
@@ -573,17 +561,17 @@ static void camellia_setup_tail(u32 *subkey, u32 *subL, u32 *subR, int max)
573 /* apply the inverse of the last half of P-function */ 561 /* apply the inverse of the last half of P-function */
574 i = 2; 562 i = 2;
575 do { 563 do {
576 dw = SUBKEY_L(i + 0) ^ SUBKEY_R(i + 0); dw = ROL8(dw);/* round 1 */ 564 dw = SUBKEY_L(i + 0) ^ SUBKEY_R(i + 0); dw = rol32(dw, 8);/* round 1 */
577 SUBKEY_R(i + 0) = SUBKEY_L(i + 0) ^ dw; SUBKEY_L(i + 0) = dw; 565 SUBKEY_R(i + 0) = SUBKEY_L(i + 0) ^ dw; SUBKEY_L(i + 0) = dw;
578 dw = SUBKEY_L(i + 1) ^ SUBKEY_R(i + 1); dw = ROL8(dw);/* round 2 */ 566 dw = SUBKEY_L(i + 1) ^ SUBKEY_R(i + 1); dw = rol32(dw, 8);/* round 2 */
579 SUBKEY_R(i + 1) = SUBKEY_L(i + 1) ^ dw; SUBKEY_L(i + 1) = dw; 567 SUBKEY_R(i + 1) = SUBKEY_L(i + 1) ^ dw; SUBKEY_L(i + 1) = dw;
580 dw = SUBKEY_L(i + 2) ^ SUBKEY_R(i + 2); dw = ROL8(dw);/* round 3 */ 568 dw = SUBKEY_L(i + 2) ^ SUBKEY_R(i + 2); dw = rol32(dw, 8);/* round 3 */
581 SUBKEY_R(i + 2) = SUBKEY_L(i + 2) ^ dw; SUBKEY_L(i + 2) = dw; 569 SUBKEY_R(i + 2) = SUBKEY_L(i + 2) ^ dw; SUBKEY_L(i + 2) = dw;
582 dw = SUBKEY_L(i + 3) ^ SUBKEY_R(i + 3); dw = ROL8(dw);/* round 4 */ 570 dw = SUBKEY_L(i + 3) ^ SUBKEY_R(i + 3); dw = rol32(dw, 8);/* round 4 */
583 SUBKEY_R(i + 3) = SUBKEY_L(i + 3) ^ dw; SUBKEY_L(i + 3) = dw; 571 SUBKEY_R(i + 3) = SUBKEY_L(i + 3) ^ dw; SUBKEY_L(i + 3) = dw;
584 dw = SUBKEY_L(i + 4) ^ SUBKEY_R(i + 4); dw = ROL8(dw);/* round 5 */ 572 dw = SUBKEY_L(i + 4) ^ SUBKEY_R(i + 4); dw = rol32(dw, 8);/* round 5 */
585 SUBKEY_R(i + 4) = SUBKEY_L(i + 4) ^ dw; SUBKEY_L(i + 4) = dw; 573 SUBKEY_R(i + 4) = SUBKEY_L(i + 4) ^ dw; SUBKEY_L(i + 4) = dw;
586 dw = SUBKEY_L(i + 5) ^ SUBKEY_R(i + 5); dw = ROL8(dw);/* round 6 */ 574 dw = SUBKEY_L(i + 5) ^ SUBKEY_R(i + 5); dw = rol32(dw, 8);/* round 6 */
587 SUBKEY_R(i + 5) = SUBKEY_L(i + 5) ^ dw; SUBKEY_L(i + 5) = dw; 575 SUBKEY_R(i + 5) = SUBKEY_L(i + 5) ^ dw; SUBKEY_L(i + 5) = dw;
588 i += 8; 576 i += 8;
589 } while (i < max); 577 } while (i < max);
@@ -599,10 +587,10 @@ static void camellia_setup128(const unsigned char *key, u32 *subkey)
599 /** 587 /**
600 * k == kll || klr || krl || krr (|| is concatenation) 588 * k == kll || klr || krl || krr (|| is concatenation)
601 */ 589 */
602 GETU32(kll, key ); 590 kll = get_unaligned_be32(key);
603 GETU32(klr, key + 4); 591 klr = get_unaligned_be32(key + 4);
604 GETU32(krl, key + 8); 592 krl = get_unaligned_be32(key + 8);
605 GETU32(krr, key + 12); 593 krr = get_unaligned_be32(key + 12);
606 594
607 /* generate KL dependent subkeys */ 595 /* generate KL dependent subkeys */
608 /* kw1 */ 596 /* kw1 */
@@ -707,14 +695,14 @@ static void camellia_setup256(const unsigned char *key, u32 *subkey)
707 * key = (kll || klr || krl || krr || krll || krlr || krrl || krrr) 695 * key = (kll || klr || krl || krr || krll || krlr || krrl || krrr)
708 * (|| is concatenation) 696 * (|| is concatenation)
709 */ 697 */
710 GETU32(kll, key ); 698 kll = get_unaligned_be32(key);
711 GETU32(klr, key + 4); 699 klr = get_unaligned_be32(key + 4);
712 GETU32(krl, key + 8); 700 krl = get_unaligned_be32(key + 8);
713 GETU32(krr, key + 12); 701 krr = get_unaligned_be32(key + 12);
714 GETU32(krll, key + 16); 702 krll = get_unaligned_be32(key + 16);
715 GETU32(krlr, key + 20); 703 krlr = get_unaligned_be32(key + 20);
716 GETU32(krrl, key + 24); 704 krrl = get_unaligned_be32(key + 24);
717 GETU32(krrr, key + 28); 705 krrr = get_unaligned_be32(key + 28);
718 706
719 /* generate KL dependent subkeys */ 707 /* generate KL dependent subkeys */
720 /* kw1 */ 708 /* kw1 */
@@ -870,13 +858,13 @@ static void camellia_setup192(const unsigned char *key, u32 *subkey)
870 t0 &= ll; \ 858 t0 &= ll; \
871 t2 |= rr; \ 859 t2 |= rr; \
872 rl ^= t2; \ 860 rl ^= t2; \
873 lr ^= ROL1(t0); \ 861 lr ^= rol32(t0, 1); \
874 t3 = krl; \ 862 t3 = krl; \
875 t1 = klr; \ 863 t1 = klr; \
876 t3 &= rl; \ 864 t3 &= rl; \
877 t1 |= lr; \ 865 t1 |= lr; \
878 ll ^= t1; \ 866 ll ^= t1; \
879 rr ^= ROL1(t3); \ 867 rr ^= rol32(t3, 1); \
880 } while(0) 868 } while(0)
881 869
882#define CAMELLIA_ROUNDSM(xl, xr, kl, kr, yl, yr, il, ir) \ 870#define CAMELLIA_ROUNDSM(xl, xr, kl, kr, yl, yr, il, ir) \
@@ -892,7 +880,7 @@ static void camellia_setup192(const unsigned char *key, u32 *subkey)
892 il ^= kl; \ 880 il ^= kl; \
893 ir ^= il ^ kr; \ 881 ir ^= il ^ kr; \
894 yl ^= ir; \ 882 yl ^= ir; \
895 yr ^= ROR8(il) ^ ir; \ 883 yr ^= ror32(il, 8) ^ ir; \
896 } while(0) 884 } while(0)
897 885
898/* max = 24: 128bit encrypt, max = 32: 256bit encrypt */ 886/* max = 24: 128bit encrypt, max = 32: 256bit encrypt */
diff --git a/crypto/crc32c.c b/crypto/crc32c.c
index a882d9e4e63e..973bc2cfab2e 100644
--- a/crypto/crc32c.c
+++ b/crypto/crc32c.c
@@ -3,8 +3,29 @@
3 * 3 *
4 * CRC32C chksum 4 * CRC32C chksum
5 * 5 *
6 * This module file is a wrapper to invoke the lib/crc32c routines. 6 *@Article{castagnoli-crc,
7 * author = { Guy Castagnoli and Stefan Braeuer and Martin Herrman},
8 * title = {{Optimization of Cyclic Redundancy-Check Codes with 24
9 * and 32 Parity Bits}},
10 * journal = IEEE Transactions on Communication,
11 * year = {1993},
12 * volume = {41},
13 * number = {6},
14 * pages = {},
15 * month = {June},
16 *}
17 * Used by the iSCSI driver, possibly others, and derived from the
18 * the iscsi-crc.c module of the linux-iscsi driver at
19 * http://linux-iscsi.sourceforge.net.
7 * 20 *
21 * Following the example of lib/crc32, this function is intended to be
22 * flexible and useful for all users. Modules that currently have their
23 * own crc32c, but hopefully may be able to use this one are:
24 * net/sctp (please add all your doco to here if you change to
25 * use this one!)
26 * <endoflist>
27 *
28 * Copyright (c) 2004 Cisco Systems, Inc.
8 * Copyright (c) 2008 Herbert Xu <herbert@gondor.apana.org.au> 29 * Copyright (c) 2008 Herbert Xu <herbert@gondor.apana.org.au>
9 * 30 *
10 * This program is free software; you can redistribute it and/or modify it 31 * This program is free software; you can redistribute it and/or modify it
@@ -18,208 +39,217 @@
18#include <linux/init.h> 39#include <linux/init.h>
19#include <linux/module.h> 40#include <linux/module.h>
20#include <linux/string.h> 41#include <linux/string.h>
21#include <linux/crc32c.h>
22#include <linux/kernel.h> 42#include <linux/kernel.h>
23 43
24#define CHKSUM_BLOCK_SIZE 1 44#define CHKSUM_BLOCK_SIZE 1
25#define CHKSUM_DIGEST_SIZE 4 45#define CHKSUM_DIGEST_SIZE 4
26 46
27struct chksum_ctx { 47struct chksum_ctx {
28 u32 crc;
29 u32 key; 48 u32 key;
30}; 49};
31 50
51struct chksum_desc_ctx {
52 u32 crc;
53};
54
32/* 55/*
33 * Steps through buffer one byte at at time, calculates reflected 56 * This is the CRC-32C table
34 * crc using table. 57 * Generated with:
58 * width = 32 bits
59 * poly = 0x1EDC6F41
60 * reflect input bytes = true
61 * reflect output bytes = true
35 */ 62 */
36 63
37static void chksum_init(struct crypto_tfm *tfm) 64static const u32 crc32c_table[256] = {
38{ 65 0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L,
39 struct chksum_ctx *mctx = crypto_tfm_ctx(tfm); 66 0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL,
40 67 0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL,
41 mctx->crc = mctx->key; 68 0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L,
42} 69 0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL,
70 0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L,
71 0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L,
72 0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL,
73 0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL,
74 0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L,
75 0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L,
76 0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL,
77 0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L,
78 0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL,
79 0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL,
80 0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L,
81 0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L,
82 0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L,
83 0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L,
84 0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L,
85 0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L,
86 0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L,
87 0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L,
88 0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L,
89 0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L,
90 0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L,
91 0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L,
92 0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L,
93 0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L,
94 0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L,
95 0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L,
96 0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L,
97 0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL,
98 0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L,
99 0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L,
100 0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL,
101 0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L,
102 0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL,
103 0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL,
104 0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L,
105 0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L,
106 0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL,
107 0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL,
108 0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L,
109 0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL,
110 0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L,
111 0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L,
112 0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL,
113 0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L,
114 0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL,
115 0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL,
116 0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L,
117 0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL,
118 0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L,
119 0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L,
120 0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL,
121 0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL,
122 0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L,
123 0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L,
124 0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL,
125 0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L,
126 0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL,
127 0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL,
128 0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L
129};
43 130
44/* 131/*
45 * Setting the seed allows arbitrary accumulators and flexible XOR policy 132 * Steps through buffer one byte at at time, calculates reflected
46 * If your algorithm starts with ~0, then XOR with ~0 before you set 133 * crc using table.
47 * the seed.
48 */ 134 */
49static int chksum_setkey(struct crypto_tfm *tfm, const u8 *key,
50 unsigned int keylen)
51{
52 struct chksum_ctx *mctx = crypto_tfm_ctx(tfm);
53 135
54 if (keylen != sizeof(mctx->crc)) { 136static u32 crc32c(u32 crc, const u8 *data, unsigned int length)
55 tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
56 return -EINVAL;
57 }
58 mctx->key = le32_to_cpu(*(__le32 *)key);
59 return 0;
60}
61
62static void chksum_update(struct crypto_tfm *tfm, const u8 *data,
63 unsigned int length)
64{ 137{
65 struct chksum_ctx *mctx = crypto_tfm_ctx(tfm); 138 while (length--)
139 crc = crc32c_table[(crc ^ *data++) & 0xFFL] ^ (crc >> 8);
66 140
67 mctx->crc = crc32c(mctx->crc, data, length); 141 return crc;
68} 142}
69 143
70static void chksum_final(struct crypto_tfm *tfm, u8 *out) 144/*
71{ 145 * Steps through buffer one byte at at time, calculates reflected
72 struct chksum_ctx *mctx = crypto_tfm_ctx(tfm); 146 * crc using table.
73 147 */
74 *(__le32 *)out = ~cpu_to_le32(mctx->crc);
75}
76 148
77static int crc32c_cra_init_old(struct crypto_tfm *tfm) 149static int chksum_init(struct shash_desc *desc)
78{ 150{
79 struct chksum_ctx *mctx = crypto_tfm_ctx(tfm); 151 struct chksum_ctx *mctx = crypto_shash_ctx(desc->tfm);
152 struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
153
154 ctx->crc = mctx->key;
80 155
81 mctx->key = ~0;
82 return 0; 156 return 0;
83} 157}
84 158
85static struct crypto_alg old_alg = {
86 .cra_name = "crc32c",
87 .cra_flags = CRYPTO_ALG_TYPE_DIGEST,
88 .cra_blocksize = CHKSUM_BLOCK_SIZE,
89 .cra_ctxsize = sizeof(struct chksum_ctx),
90 .cra_module = THIS_MODULE,
91 .cra_list = LIST_HEAD_INIT(old_alg.cra_list),
92 .cra_init = crc32c_cra_init_old,
93 .cra_u = {
94 .digest = {
95 .dia_digestsize= CHKSUM_DIGEST_SIZE,
96 .dia_setkey = chksum_setkey,
97 .dia_init = chksum_init,
98 .dia_update = chksum_update,
99 .dia_final = chksum_final
100 }
101 }
102};
103
104/* 159/*
105 * Setting the seed allows arbitrary accumulators and flexible XOR policy 160 * Setting the seed allows arbitrary accumulators and flexible XOR policy
106 * If your algorithm starts with ~0, then XOR with ~0 before you set 161 * If your algorithm starts with ~0, then XOR with ~0 before you set
107 * the seed. 162 * the seed.
108 */ 163 */
109static int crc32c_setkey(struct crypto_ahash *hash, const u8 *key, 164static int chksum_setkey(struct crypto_shash *tfm, const u8 *key,
110 unsigned int keylen) 165 unsigned int keylen)
111{ 166{
112 u32 *mctx = crypto_ahash_ctx(hash); 167 struct chksum_ctx *mctx = crypto_shash_ctx(tfm);
113 168
114 if (keylen != sizeof(u32)) { 169 if (keylen != sizeof(mctx->key)) {
115 crypto_ahash_set_flags(hash, CRYPTO_TFM_RES_BAD_KEY_LEN); 170 crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
116 return -EINVAL; 171 return -EINVAL;
117 } 172 }
118 *mctx = le32_to_cpup((__le32 *)key); 173 mctx->key = le32_to_cpu(*(__le32 *)key);
119 return 0; 174 return 0;
120} 175}
121 176
122static int crc32c_init(struct ahash_request *req) 177static int chksum_update(struct shash_desc *desc, const u8 *data,
178 unsigned int length)
123{ 179{
124 u32 *mctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req)); 180 struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
125 u32 *crcp = ahash_request_ctx(req);
126 181
127 *crcp = *mctx; 182 ctx->crc = crc32c(ctx->crc, data, length);
128 return 0; 183 return 0;
129} 184}
130 185
131static int crc32c_update(struct ahash_request *req) 186static int chksum_final(struct shash_desc *desc, u8 *out)
132{ 187{
133 struct crypto_hash_walk walk; 188 struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
134 u32 *crcp = ahash_request_ctx(req);
135 u32 crc = *crcp;
136 int nbytes;
137
138 for (nbytes = crypto_hash_walk_first(req, &walk); nbytes;
139 nbytes = crypto_hash_walk_done(&walk, 0))
140 crc = crc32c(crc, walk.data, nbytes);
141 189
142 *crcp = crc; 190 *(__le32 *)out = ~cpu_to_le32p(&ctx->crc);
143 return 0; 191 return 0;
144} 192}
145 193
146static int crc32c_final(struct ahash_request *req) 194static int __chksum_finup(u32 *crcp, const u8 *data, unsigned int len, u8 *out)
147{ 195{
148 u32 *crcp = ahash_request_ctx(req); 196 *(__le32 *)out = ~cpu_to_le32(crc32c(*crcp, data, len));
149
150 *(__le32 *)req->result = ~cpu_to_le32p(crcp);
151 return 0; 197 return 0;
152} 198}
153 199
154static int crc32c_digest(struct ahash_request *req) 200static int chksum_finup(struct shash_desc *desc, const u8 *data,
201 unsigned int len, u8 *out)
155{ 202{
156 struct crypto_hash_walk walk; 203 struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
157 u32 *mctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req));
158 u32 crc = *mctx;
159 int nbytes;
160 204
161 for (nbytes = crypto_hash_walk_first(req, &walk); nbytes; 205 return __chksum_finup(&ctx->crc, data, len, out);
162 nbytes = crypto_hash_walk_done(&walk, 0))
163 crc = crc32c(crc, walk.data, nbytes);
164
165 *(__le32 *)req->result = ~cpu_to_le32(crc);
166 return 0;
167} 206}
168 207
169static int crc32c_cra_init(struct crypto_tfm *tfm) 208static int chksum_digest(struct shash_desc *desc, const u8 *data,
209 unsigned int length, u8 *out)
170{ 210{
171 u32 *key = crypto_tfm_ctx(tfm); 211 struct chksum_ctx *mctx = crypto_shash_ctx(desc->tfm);
172 212
173 *key = ~0; 213 return __chksum_finup(&mctx->key, data, length, out);
214}
174 215
175 tfm->crt_ahash.reqsize = sizeof(u32); 216static int crc32c_cra_init(struct crypto_tfm *tfm)
217{
218 struct chksum_ctx *mctx = crypto_tfm_ctx(tfm);
176 219
220 mctx->key = ~0;
177 return 0; 221 return 0;
178} 222}
179 223
180static struct crypto_alg alg = { 224static struct shash_alg alg = {
181 .cra_name = "crc32c", 225 .digestsize = CHKSUM_DIGEST_SIZE,
182 .cra_driver_name = "crc32c-generic", 226 .setkey = chksum_setkey,
183 .cra_priority = 100, 227 .init = chksum_init,
184 .cra_flags = CRYPTO_ALG_TYPE_AHASH, 228 .update = chksum_update,
185 .cra_blocksize = CHKSUM_BLOCK_SIZE, 229 .final = chksum_final,
186 .cra_alignmask = 3, 230 .finup = chksum_finup,
187 .cra_ctxsize = sizeof(u32), 231 .digest = chksum_digest,
188 .cra_module = THIS_MODULE, 232 .descsize = sizeof(struct chksum_desc_ctx),
189 .cra_list = LIST_HEAD_INIT(alg.cra_list), 233 .base = {
190 .cra_init = crc32c_cra_init, 234 .cra_name = "crc32c",
191 .cra_type = &crypto_ahash_type, 235 .cra_driver_name = "crc32c-generic",
192 .cra_u = { 236 .cra_priority = 100,
193 .ahash = { 237 .cra_blocksize = CHKSUM_BLOCK_SIZE,
194 .digestsize = CHKSUM_DIGEST_SIZE, 238 .cra_alignmask = 3,
195 .setkey = crc32c_setkey, 239 .cra_ctxsize = sizeof(struct chksum_ctx),
196 .init = crc32c_init, 240 .cra_module = THIS_MODULE,
197 .update = crc32c_update, 241 .cra_init = crc32c_cra_init,
198 .final = crc32c_final,
199 .digest = crc32c_digest,
200 }
201 } 242 }
202}; 243};
203 244
204static int __init crc32c_mod_init(void) 245static int __init crc32c_mod_init(void)
205{ 246{
206 int err; 247 return crypto_register_shash(&alg);
207
208 err = crypto_register_alg(&old_alg);
209 if (err)
210 return err;
211
212 err = crypto_register_alg(&alg);
213 if (err)
214 crypto_unregister_alg(&old_alg);
215
216 return err;
217} 248}
218 249
219static void __exit crc32c_mod_fini(void) 250static void __exit crc32c_mod_fini(void)
220{ 251{
221 crypto_unregister_alg(&alg); 252 crypto_unregister_shash(&alg);
222 crypto_unregister_alg(&old_alg);
223} 253}
224 254
225module_init(crc32c_mod_init); 255module_init(crc32c_mod_init);
diff --git a/crypto/crypto_null.c b/crypto/crypto_null.c
index 1f7d53013a22..cb71c9122bc0 100644
--- a/crypto/crypto_null.c
+++ b/crypto/crypto_null.c
@@ -17,6 +17,7 @@
17 * 17 *
18 */ 18 */
19 19
20#include <crypto/internal/hash.h>
20#include <crypto/internal/skcipher.h> 21#include <crypto/internal/skcipher.h>
21#include <linux/init.h> 22#include <linux/init.h>
22#include <linux/module.h> 23#include <linux/module.h>
@@ -38,15 +39,31 @@ static int null_compress(struct crypto_tfm *tfm, const u8 *src,
38 return 0; 39 return 0;
39} 40}
40 41
41static void null_init(struct crypto_tfm *tfm) 42static int null_init(struct shash_desc *desc)
42{ } 43{
44 return 0;
45}
43 46
44static void null_update(struct crypto_tfm *tfm, const u8 *data, 47static int null_update(struct shash_desc *desc, const u8 *data,
45 unsigned int len) 48 unsigned int len)
46{ } 49{
50 return 0;
51}
47 52
48static void null_final(struct crypto_tfm *tfm, u8 *out) 53static int null_final(struct shash_desc *desc, u8 *out)
49{ } 54{
55 return 0;
56}
57
58static int null_digest(struct shash_desc *desc, const u8 *data,
59 unsigned int len, u8 *out)
60{
61 return 0;
62}
63
64static int null_hash_setkey(struct crypto_shash *tfm, const u8 *key,
65 unsigned int keylen)
66{ return 0; }
50 67
51static int null_setkey(struct crypto_tfm *tfm, const u8 *key, 68static int null_setkey(struct crypto_tfm *tfm, const u8 *key,
52 unsigned int keylen) 69 unsigned int keylen)
@@ -89,19 +106,20 @@ static struct crypto_alg compress_null = {
89 .coa_decompress = null_compress } } 106 .coa_decompress = null_compress } }
90}; 107};
91 108
92static struct crypto_alg digest_null = { 109static struct shash_alg digest_null = {
93 .cra_name = "digest_null", 110 .digestsize = NULL_DIGEST_SIZE,
94 .cra_flags = CRYPTO_ALG_TYPE_DIGEST, 111 .setkey = null_hash_setkey,
95 .cra_blocksize = NULL_BLOCK_SIZE, 112 .init = null_init,
96 .cra_ctxsize = 0, 113 .update = null_update,
97 .cra_module = THIS_MODULE, 114 .finup = null_digest,
98 .cra_list = LIST_HEAD_INIT(digest_null.cra_list), 115 .digest = null_digest,
99 .cra_u = { .digest = { 116 .final = null_final,
100 .dia_digestsize = NULL_DIGEST_SIZE, 117 .base = {
101 .dia_setkey = null_setkey, 118 .cra_name = "digest_null",
102 .dia_init = null_init, 119 .cra_flags = CRYPTO_ALG_TYPE_SHASH,
103 .dia_update = null_update, 120 .cra_blocksize = NULL_BLOCK_SIZE,
104 .dia_final = null_final } } 121 .cra_module = THIS_MODULE,
122 }
105}; 123};
106 124
107static struct crypto_alg cipher_null = { 125static struct crypto_alg cipher_null = {
@@ -154,7 +172,7 @@ static int __init crypto_null_mod_init(void)
154 if (ret < 0) 172 if (ret < 0)
155 goto out_unregister_cipher; 173 goto out_unregister_cipher;
156 174
157 ret = crypto_register_alg(&digest_null); 175 ret = crypto_register_shash(&digest_null);
158 if (ret < 0) 176 if (ret < 0)
159 goto out_unregister_skcipher; 177 goto out_unregister_skcipher;
160 178
@@ -166,7 +184,7 @@ out:
166 return ret; 184 return ret;
167 185
168out_unregister_digest: 186out_unregister_digest:
169 crypto_unregister_alg(&digest_null); 187 crypto_unregister_shash(&digest_null);
170out_unregister_skcipher: 188out_unregister_skcipher:
171 crypto_unregister_alg(&skcipher_null); 189 crypto_unregister_alg(&skcipher_null);
172out_unregister_cipher: 190out_unregister_cipher:
@@ -177,7 +195,7 @@ out_unregister_cipher:
177static void __exit crypto_null_mod_fini(void) 195static void __exit crypto_null_mod_fini(void)
178{ 196{
179 crypto_unregister_alg(&compress_null); 197 crypto_unregister_alg(&compress_null);
180 crypto_unregister_alg(&digest_null); 198 crypto_unregister_shash(&digest_null);
181 crypto_unregister_alg(&skcipher_null); 199 crypto_unregister_alg(&skcipher_null);
182 crypto_unregister_alg(&cipher_null); 200 crypto_unregister_alg(&cipher_null);
183} 201}
diff --git a/crypto/des_generic.c b/crypto/des_generic.c
index 5d0e4580f998..5bd3ee345a64 100644
--- a/crypto/des_generic.c
+++ b/crypto/des_generic.c
@@ -868,9 +868,10 @@ static int des3_ede_setkey(struct crypto_tfm *tfm, const u8 *key,
868 u32 *flags = &tfm->crt_flags; 868 u32 *flags = &tfm->crt_flags;
869 869
870 if (unlikely(!((K[0] ^ K[2]) | (K[1] ^ K[3])) || 870 if (unlikely(!((K[0] ^ K[2]) | (K[1] ^ K[3])) ||
871 !((K[2] ^ K[4]) | (K[3] ^ K[5])))) 871 !((K[2] ^ K[4]) | (K[3] ^ K[5]))) &&
872 (*flags & CRYPTO_TFM_REQ_WEAK_KEY))
872 { 873 {
873 *flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED; 874 *flags |= CRYPTO_TFM_RES_WEAK_KEY;
874 return -EINVAL; 875 return -EINVAL;
875 } 876 }
876 877
diff --git a/crypto/fcrypt.c b/crypto/fcrypt.c
index 1302f4cae337..b82d61f4e26c 100644
--- a/crypto/fcrypt.c
+++ b/crypto/fcrypt.c
@@ -73,7 +73,7 @@ do { \
73 * /afs/transarc.com/public/afsps/afs.rel31b.export-src/rxkad/sboxes.h 73 * /afs/transarc.com/public/afsps/afs.rel31b.export-src/rxkad/sboxes.h
74 */ 74 */
75#undef Z 75#undef Z
76#define Z(x) __constant_cpu_to_be32(x << 3) 76#define Z(x) cpu_to_be32(x << 3)
77static const __be32 sbox0[256] = { 77static const __be32 sbox0[256] = {
78 Z(0xea), Z(0x7f), Z(0xb2), Z(0x64), Z(0x9d), Z(0xb0), Z(0xd9), Z(0x11), 78 Z(0xea), Z(0x7f), Z(0xb2), Z(0x64), Z(0x9d), Z(0xb0), Z(0xd9), Z(0x11),
79 Z(0xcd), Z(0x86), Z(0x86), Z(0x91), Z(0x0a), Z(0xb2), Z(0x93), Z(0x06), 79 Z(0xcd), Z(0x86), Z(0x86), Z(0x91), Z(0x0a), Z(0xb2), Z(0x93), Z(0x06),
@@ -110,7 +110,7 @@ static const __be32 sbox0[256] = {
110}; 110};
111 111
112#undef Z 112#undef Z
113#define Z(x) __constant_cpu_to_be32((x << 27) | (x >> 5)) 113#define Z(x) cpu_to_be32((x << 27) | (x >> 5))
114static const __be32 sbox1[256] = { 114static const __be32 sbox1[256] = {
115 Z(0x77), Z(0x14), Z(0xa6), Z(0xfe), Z(0xb2), Z(0x5e), Z(0x8c), Z(0x3e), 115 Z(0x77), Z(0x14), Z(0xa6), Z(0xfe), Z(0xb2), Z(0x5e), Z(0x8c), Z(0x3e),
116 Z(0x67), Z(0x6c), Z(0xa1), Z(0x0d), Z(0xc2), Z(0xa2), Z(0xc1), Z(0x85), 116 Z(0x67), Z(0x6c), Z(0xa1), Z(0x0d), Z(0xc2), Z(0xa2), Z(0xc1), Z(0x85),
@@ -147,7 +147,7 @@ static const __be32 sbox1[256] = {
147}; 147};
148 148
149#undef Z 149#undef Z
150#define Z(x) __constant_cpu_to_be32(x << 11) 150#define Z(x) cpu_to_be32(x << 11)
151static const __be32 sbox2[256] = { 151static const __be32 sbox2[256] = {
152 Z(0xf0), Z(0x37), Z(0x24), Z(0x53), Z(0x2a), Z(0x03), Z(0x83), Z(0x86), 152 Z(0xf0), Z(0x37), Z(0x24), Z(0x53), Z(0x2a), Z(0x03), Z(0x83), Z(0x86),
153 Z(0xd1), Z(0xec), Z(0x50), Z(0xf0), Z(0x42), Z(0x78), Z(0x2f), Z(0x6d), 153 Z(0xd1), Z(0xec), Z(0x50), Z(0xf0), Z(0x42), Z(0x78), Z(0x2f), Z(0x6d),
@@ -184,7 +184,7 @@ static const __be32 sbox2[256] = {
184}; 184};
185 185
186#undef Z 186#undef Z
187#define Z(x) __constant_cpu_to_be32(x << 19) 187#define Z(x) cpu_to_be32(x << 19)
188static const __be32 sbox3[256] = { 188static const __be32 sbox3[256] = {
189 Z(0xa9), Z(0x2a), Z(0x48), Z(0x51), Z(0x84), Z(0x7e), Z(0x49), Z(0xe2), 189 Z(0xa9), Z(0x2a), Z(0x48), Z(0x51), Z(0x84), Z(0x7e), Z(0x49), Z(0xe2),
190 Z(0xb5), Z(0xb7), Z(0x42), Z(0x33), Z(0x7d), Z(0x5d), Z(0xa6), Z(0x12), 190 Z(0xb5), Z(0xb7), Z(0x42), Z(0x33), Z(0x7d), Z(0x5d), Z(0xa6), Z(0x12),
diff --git a/crypto/hmac.c b/crypto/hmac.c
index 7ff2d6a8c7d0..0ad39c374963 100644
--- a/crypto/hmac.c
+++ b/crypto/hmac.c
@@ -16,7 +16,7 @@
16 * 16 *
17 */ 17 */
18 18
19#include <crypto/algapi.h> 19#include <crypto/internal/hash.h>
20#include <crypto/scatterwalk.h> 20#include <crypto/scatterwalk.h>
21#include <linux/err.h> 21#include <linux/err.h>
22#include <linux/init.h> 22#include <linux/init.h>
@@ -238,9 +238,11 @@ static struct crypto_instance *hmac_alloc(struct rtattr **tb)
238 return ERR_CAST(alg); 238 return ERR_CAST(alg);
239 239
240 inst = ERR_PTR(-EINVAL); 240 inst = ERR_PTR(-EINVAL);
241 ds = (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) == 241 ds = alg->cra_type == &crypto_hash_type ?
242 CRYPTO_ALG_TYPE_HASH ? alg->cra_hash.digestsize : 242 alg->cra_hash.digestsize :
243 alg->cra_digest.dia_digestsize; 243 alg->cra_type ?
244 __crypto_shash_alg(alg)->digestsize :
245 alg->cra_digest.dia_digestsize;
244 if (ds > alg->cra_blocksize) 246 if (ds > alg->cra_blocksize)
245 goto out_put_alg; 247 goto out_put_alg;
246 248
diff --git a/crypto/internal.h b/crypto/internal.h
index 8ef72d76092e..3c19a27a7563 100644
--- a/crypto/internal.h
+++ b/crypto/internal.h
@@ -109,6 +109,8 @@ void crypto_alg_tested(const char *name, int err);
109void crypto_shoot_alg(struct crypto_alg *alg); 109void crypto_shoot_alg(struct crypto_alg *alg);
110struct crypto_tfm *__crypto_alloc_tfm(struct crypto_alg *alg, u32 type, 110struct crypto_tfm *__crypto_alloc_tfm(struct crypto_alg *alg, u32 type,
111 u32 mask); 111 u32 mask);
112struct crypto_tfm *crypto_create_tfm(struct crypto_alg *alg,
113 const struct crypto_type *frontend);
112 114
113int crypto_register_instance(struct crypto_template *tmpl, 115int crypto_register_instance(struct crypto_template *tmpl,
114 struct crypto_instance *inst); 116 struct crypto_instance *inst);
diff --git a/crypto/md4.c b/crypto/md4.c
index 3c19aa0750fd..7fca1f59a4f5 100644
--- a/crypto/md4.c
+++ b/crypto/md4.c
@@ -20,8 +20,8 @@
20 * (at your option) any later version. 20 * (at your option) any later version.
21 * 21 *
22 */ 22 */
23#include <crypto/internal/hash.h>
23#include <linux/init.h> 24#include <linux/init.h>
24#include <linux/crypto.h>
25#include <linux/kernel.h> 25#include <linux/kernel.h>
26#include <linux/string.h> 26#include <linux/string.h>
27#include <linux/types.h> 27#include <linux/types.h>
@@ -58,7 +58,7 @@ static inline u32 H(u32 x, u32 y, u32 z)
58{ 58{
59 return x ^ y ^ z; 59 return x ^ y ^ z;
60} 60}
61 61
62#define ROUND1(a,b,c,d,k,s) (a = lshift(a + F(b,c,d) + k, s)) 62#define ROUND1(a,b,c,d,k,s) (a = lshift(a + F(b,c,d) + k, s))
63#define ROUND2(a,b,c,d,k,s) (a = lshift(a + G(b,c,d) + k + (u32)0x5A827999,s)) 63#define ROUND2(a,b,c,d,k,s) (a = lshift(a + G(b,c,d) + k + (u32)0x5A827999,s))
64#define ROUND3(a,b,c,d,k,s) (a = lshift(a + H(b,c,d) + k + (u32)0x6ED9EBA1,s)) 64#define ROUND3(a,b,c,d,k,s) (a = lshift(a + H(b,c,d) + k + (u32)0x6ED9EBA1,s))
@@ -148,24 +148,26 @@ static void md4_transform(u32 *hash, u32 const *in)
148 148
149static inline void md4_transform_helper(struct md4_ctx *ctx) 149static inline void md4_transform_helper(struct md4_ctx *ctx)
150{ 150{
151 le32_to_cpu_array(ctx->block, sizeof(ctx->block) / sizeof(u32)); 151 le32_to_cpu_array(ctx->block, ARRAY_SIZE(ctx->block));
152 md4_transform(ctx->hash, ctx->block); 152 md4_transform(ctx->hash, ctx->block);
153} 153}
154 154
155static void md4_init(struct crypto_tfm *tfm) 155static int md4_init(struct shash_desc *desc)
156{ 156{
157 struct md4_ctx *mctx = crypto_tfm_ctx(tfm); 157 struct md4_ctx *mctx = shash_desc_ctx(desc);
158 158
159 mctx->hash[0] = 0x67452301; 159 mctx->hash[0] = 0x67452301;
160 mctx->hash[1] = 0xefcdab89; 160 mctx->hash[1] = 0xefcdab89;
161 mctx->hash[2] = 0x98badcfe; 161 mctx->hash[2] = 0x98badcfe;
162 mctx->hash[3] = 0x10325476; 162 mctx->hash[3] = 0x10325476;
163 mctx->byte_count = 0; 163 mctx->byte_count = 0;
164
165 return 0;
164} 166}
165 167
166static void md4_update(struct crypto_tfm *tfm, const u8 *data, unsigned int len) 168static int md4_update(struct shash_desc *desc, const u8 *data, unsigned int len)
167{ 169{
168 struct md4_ctx *mctx = crypto_tfm_ctx(tfm); 170 struct md4_ctx *mctx = shash_desc_ctx(desc);
169 const u32 avail = sizeof(mctx->block) - (mctx->byte_count & 0x3f); 171 const u32 avail = sizeof(mctx->block) - (mctx->byte_count & 0x3f);
170 172
171 mctx->byte_count += len; 173 mctx->byte_count += len;
@@ -173,7 +175,7 @@ static void md4_update(struct crypto_tfm *tfm, const u8 *data, unsigned int len)
173 if (avail > len) { 175 if (avail > len) {
174 memcpy((char *)mctx->block + (sizeof(mctx->block) - avail), 176 memcpy((char *)mctx->block + (sizeof(mctx->block) - avail),
175 data, len); 177 data, len);
176 return; 178 return 0;
177 } 179 }
178 180
179 memcpy((char *)mctx->block + (sizeof(mctx->block) - avail), 181 memcpy((char *)mctx->block + (sizeof(mctx->block) - avail),
@@ -191,11 +193,13 @@ static void md4_update(struct crypto_tfm *tfm, const u8 *data, unsigned int len)
191 } 193 }
192 194
193 memcpy(mctx->block, data, len); 195 memcpy(mctx->block, data, len);
196
197 return 0;
194} 198}
195 199
196static void md4_final(struct crypto_tfm *tfm, u8 *out) 200static int md4_final(struct shash_desc *desc, u8 *out)
197{ 201{
198 struct md4_ctx *mctx = crypto_tfm_ctx(tfm); 202 struct md4_ctx *mctx = shash_desc_ctx(desc);
199 const unsigned int offset = mctx->byte_count & 0x3f; 203 const unsigned int offset = mctx->byte_count & 0x3f;
200 char *p = (char *)mctx->block + offset; 204 char *p = (char *)mctx->block + offset;
201 int padding = 56 - (offset + 1); 205 int padding = 56 - (offset + 1);
@@ -214,33 +218,35 @@ static void md4_final(struct crypto_tfm *tfm, u8 *out)
214 le32_to_cpu_array(mctx->block, (sizeof(mctx->block) - 218 le32_to_cpu_array(mctx->block, (sizeof(mctx->block) -
215 sizeof(u64)) / sizeof(u32)); 219 sizeof(u64)) / sizeof(u32));
216 md4_transform(mctx->hash, mctx->block); 220 md4_transform(mctx->hash, mctx->block);
217 cpu_to_le32_array(mctx->hash, sizeof(mctx->hash) / sizeof(u32)); 221 cpu_to_le32_array(mctx->hash, ARRAY_SIZE(mctx->hash));
218 memcpy(out, mctx->hash, sizeof(mctx->hash)); 222 memcpy(out, mctx->hash, sizeof(mctx->hash));
219 memset(mctx, 0, sizeof(*mctx)); 223 memset(mctx, 0, sizeof(*mctx));
224
225 return 0;
220} 226}
221 227
222static struct crypto_alg alg = { 228static struct shash_alg alg = {
223 .cra_name = "md4", 229 .digestsize = MD4_DIGEST_SIZE,
224 .cra_flags = CRYPTO_ALG_TYPE_DIGEST, 230 .init = md4_init,
225 .cra_blocksize = MD4_HMAC_BLOCK_SIZE, 231 .update = md4_update,
226 .cra_ctxsize = sizeof(struct md4_ctx), 232 .final = md4_final,
227 .cra_module = THIS_MODULE, 233 .descsize = sizeof(struct md4_ctx),
228 .cra_list = LIST_HEAD_INIT(alg.cra_list), 234 .base = {
229 .cra_u = { .digest = { 235 .cra_name = "md4",
230 .dia_digestsize = MD4_DIGEST_SIZE, 236 .cra_flags = CRYPTO_ALG_TYPE_SHASH,
231 .dia_init = md4_init, 237 .cra_blocksize = MD4_HMAC_BLOCK_SIZE,
232 .dia_update = md4_update, 238 .cra_module = THIS_MODULE,
233 .dia_final = md4_final } } 239 }
234}; 240};
235 241
236static int __init md4_mod_init(void) 242static int __init md4_mod_init(void)
237{ 243{
238 return crypto_register_alg(&alg); 244 return crypto_register_shash(&alg);
239} 245}
240 246
241static void __exit md4_mod_fini(void) 247static void __exit md4_mod_fini(void)
242{ 248{
243 crypto_unregister_alg(&alg); 249 crypto_unregister_shash(&alg);
244} 250}
245 251
246module_init(md4_mod_init); 252module_init(md4_mod_init);
diff --git a/crypto/md5.c b/crypto/md5.c
index 39268f3d2f1d..83eb52961750 100644
--- a/crypto/md5.c
+++ b/crypto/md5.c
@@ -15,10 +15,10 @@
15 * any later version. 15 * any later version.
16 * 16 *
17 */ 17 */
18#include <crypto/internal/hash.h>
18#include <linux/init.h> 19#include <linux/init.h>
19#include <linux/module.h> 20#include <linux/module.h>
20#include <linux/string.h> 21#include <linux/string.h>
21#include <linux/crypto.h>
22#include <linux/types.h> 22#include <linux/types.h>
23#include <asm/byteorder.h> 23#include <asm/byteorder.h>
24 24
@@ -147,20 +147,22 @@ static inline void md5_transform_helper(struct md5_ctx *ctx)
147 md5_transform(ctx->hash, ctx->block); 147 md5_transform(ctx->hash, ctx->block);
148} 148}
149 149
150static void md5_init(struct crypto_tfm *tfm) 150static int md5_init(struct shash_desc *desc)
151{ 151{
152 struct md5_ctx *mctx = crypto_tfm_ctx(tfm); 152 struct md5_ctx *mctx = shash_desc_ctx(desc);
153 153
154 mctx->hash[0] = 0x67452301; 154 mctx->hash[0] = 0x67452301;
155 mctx->hash[1] = 0xefcdab89; 155 mctx->hash[1] = 0xefcdab89;
156 mctx->hash[2] = 0x98badcfe; 156 mctx->hash[2] = 0x98badcfe;
157 mctx->hash[3] = 0x10325476; 157 mctx->hash[3] = 0x10325476;
158 mctx->byte_count = 0; 158 mctx->byte_count = 0;
159
160 return 0;
159} 161}
160 162
161static void md5_update(struct crypto_tfm *tfm, const u8 *data, unsigned int len) 163static int md5_update(struct shash_desc *desc, const u8 *data, unsigned int len)
162{ 164{
163 struct md5_ctx *mctx = crypto_tfm_ctx(tfm); 165 struct md5_ctx *mctx = shash_desc_ctx(desc);
164 const u32 avail = sizeof(mctx->block) - (mctx->byte_count & 0x3f); 166 const u32 avail = sizeof(mctx->block) - (mctx->byte_count & 0x3f);
165 167
166 mctx->byte_count += len; 168 mctx->byte_count += len;
@@ -168,7 +170,7 @@ static void md5_update(struct crypto_tfm *tfm, const u8 *data, unsigned int len)
168 if (avail > len) { 170 if (avail > len) {
169 memcpy((char *)mctx->block + (sizeof(mctx->block) - avail), 171 memcpy((char *)mctx->block + (sizeof(mctx->block) - avail),
170 data, len); 172 data, len);
171 return; 173 return 0;
172 } 174 }
173 175
174 memcpy((char *)mctx->block + (sizeof(mctx->block) - avail), 176 memcpy((char *)mctx->block + (sizeof(mctx->block) - avail),
@@ -186,11 +188,13 @@ static void md5_update(struct crypto_tfm *tfm, const u8 *data, unsigned int len)
186 } 188 }
187 189
188 memcpy(mctx->block, data, len); 190 memcpy(mctx->block, data, len);
191
192 return 0;
189} 193}
190 194
191static void md5_final(struct crypto_tfm *tfm, u8 *out) 195static int md5_final(struct shash_desc *desc, u8 *out)
192{ 196{
193 struct md5_ctx *mctx = crypto_tfm_ctx(tfm); 197 struct md5_ctx *mctx = shash_desc_ctx(desc);
194 const unsigned int offset = mctx->byte_count & 0x3f; 198 const unsigned int offset = mctx->byte_count & 0x3f;
195 char *p = (char *)mctx->block + offset; 199 char *p = (char *)mctx->block + offset;
196 int padding = 56 - (offset + 1); 200 int padding = 56 - (offset + 1);
@@ -212,30 +216,32 @@ static void md5_final(struct crypto_tfm *tfm, u8 *out)
212 cpu_to_le32_array(mctx->hash, sizeof(mctx->hash) / sizeof(u32)); 216 cpu_to_le32_array(mctx->hash, sizeof(mctx->hash) / sizeof(u32));
213 memcpy(out, mctx->hash, sizeof(mctx->hash)); 217 memcpy(out, mctx->hash, sizeof(mctx->hash));
214 memset(mctx, 0, sizeof(*mctx)); 218 memset(mctx, 0, sizeof(*mctx));
219
220 return 0;
215} 221}
216 222
217static struct crypto_alg alg = { 223static struct shash_alg alg = {
218 .cra_name = "md5", 224 .digestsize = MD5_DIGEST_SIZE,
219 .cra_flags = CRYPTO_ALG_TYPE_DIGEST, 225 .init = md5_init,
220 .cra_blocksize = MD5_HMAC_BLOCK_SIZE, 226 .update = md5_update,
221 .cra_ctxsize = sizeof(struct md5_ctx), 227 .final = md5_final,
222 .cra_module = THIS_MODULE, 228 .descsize = sizeof(struct md5_ctx),
223 .cra_list = LIST_HEAD_INIT(alg.cra_list), 229 .base = {
224 .cra_u = { .digest = { 230 .cra_name = "md5",
225 .dia_digestsize = MD5_DIGEST_SIZE, 231 .cra_flags = CRYPTO_ALG_TYPE_SHASH,
226 .dia_init = md5_init, 232 .cra_blocksize = MD5_HMAC_BLOCK_SIZE,
227 .dia_update = md5_update, 233 .cra_module = THIS_MODULE,
228 .dia_final = md5_final } } 234 }
229}; 235};
230 236
231static int __init md5_mod_init(void) 237static int __init md5_mod_init(void)
232{ 238{
233 return crypto_register_alg(&alg); 239 return crypto_register_shash(&alg);
234} 240}
235 241
236static void __exit md5_mod_fini(void) 242static void __exit md5_mod_fini(void)
237{ 243{
238 crypto_unregister_alg(&alg); 244 crypto_unregister_shash(&alg);
239} 245}
240 246
241module_init(md5_mod_init); 247module_init(md5_mod_init);
diff --git a/crypto/michael_mic.c b/crypto/michael_mic.c
index 9e917b8011b1..079b761bc70d 100644
--- a/crypto/michael_mic.c
+++ b/crypto/michael_mic.c
@@ -9,23 +9,25 @@
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 12#include <crypto/internal/hash.h>
13#include <asm/byteorder.h> 13#include <asm/byteorder.h>
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/string.h> 16#include <linux/string.h>
17#include <linux/crypto.h>
18#include <linux/types.h> 17#include <linux/types.h>
19 18
20 19
21struct michael_mic_ctx { 20struct michael_mic_ctx {
21 u32 l, r;
22};
23
24struct michael_mic_desc_ctx {
22 u8 pending[4]; 25 u8 pending[4];
23 size_t pending_len; 26 size_t pending_len;
24 27
25 u32 l, r; 28 u32 l, r;
26}; 29};
27 30
28
29static inline u32 xswap(u32 val) 31static inline u32 xswap(u32 val)
30{ 32{
31 return ((val & 0x00ff00ff) << 8) | ((val & 0xff00ff00) >> 8); 33 return ((val & 0x00ff00ff) << 8) | ((val & 0xff00ff00) >> 8);
@@ -45,17 +47,22 @@ do { \
45} while (0) 47} while (0)
46 48
47 49
48static void michael_init(struct crypto_tfm *tfm) 50static int michael_init(struct shash_desc *desc)
49{ 51{
50 struct michael_mic_ctx *mctx = crypto_tfm_ctx(tfm); 52 struct michael_mic_desc_ctx *mctx = shash_desc_ctx(desc);
53 struct michael_mic_ctx *ctx = crypto_shash_ctx(desc->tfm);
51 mctx->pending_len = 0; 54 mctx->pending_len = 0;
55 mctx->l = ctx->l;
56 mctx->r = ctx->r;
57
58 return 0;
52} 59}
53 60
54 61
55static void michael_update(struct crypto_tfm *tfm, const u8 *data, 62static int michael_update(struct shash_desc *desc, const u8 *data,
56 unsigned int len) 63 unsigned int len)
57{ 64{
58 struct michael_mic_ctx *mctx = crypto_tfm_ctx(tfm); 65 struct michael_mic_desc_ctx *mctx = shash_desc_ctx(desc);
59 const __le32 *src; 66 const __le32 *src;
60 67
61 if (mctx->pending_len) { 68 if (mctx->pending_len) {
@@ -68,7 +75,7 @@ static void michael_update(struct crypto_tfm *tfm, const u8 *data,
68 len -= flen; 75 len -= flen;
69 76
70 if (mctx->pending_len < 4) 77 if (mctx->pending_len < 4)
71 return; 78 return 0;
72 79
73 src = (const __le32 *)mctx->pending; 80 src = (const __le32 *)mctx->pending;
74 mctx->l ^= le32_to_cpup(src); 81 mctx->l ^= le32_to_cpup(src);
@@ -88,12 +95,14 @@ static void michael_update(struct crypto_tfm *tfm, const u8 *data,
88 mctx->pending_len = len; 95 mctx->pending_len = len;
89 memcpy(mctx->pending, src, len); 96 memcpy(mctx->pending, src, len);
90 } 97 }
98
99 return 0;
91} 100}
92 101
93 102
94static void michael_final(struct crypto_tfm *tfm, u8 *out) 103static int michael_final(struct shash_desc *desc, u8 *out)
95{ 104{
96 struct michael_mic_ctx *mctx = crypto_tfm_ctx(tfm); 105 struct michael_mic_desc_ctx *mctx = shash_desc_ctx(desc);
97 u8 *data = mctx->pending; 106 u8 *data = mctx->pending;
98 __le32 *dst = (__le32 *)out; 107 __le32 *dst = (__le32 *)out;
99 108
@@ -119,17 +128,20 @@ static void michael_final(struct crypto_tfm *tfm, u8 *out)
119 128
120 dst[0] = cpu_to_le32(mctx->l); 129 dst[0] = cpu_to_le32(mctx->l);
121 dst[1] = cpu_to_le32(mctx->r); 130 dst[1] = cpu_to_le32(mctx->r);
131
132 return 0;
122} 133}
123 134
124 135
125static int michael_setkey(struct crypto_tfm *tfm, const u8 *key, 136static int michael_setkey(struct crypto_shash *tfm, const u8 *key,
126 unsigned int keylen) 137 unsigned int keylen)
127{ 138{
128 struct michael_mic_ctx *mctx = crypto_tfm_ctx(tfm); 139 struct michael_mic_ctx *mctx = crypto_shash_ctx(tfm);
140
129 const __le32 *data = (const __le32 *)key; 141 const __le32 *data = (const __le32 *)key;
130 142
131 if (keylen != 8) { 143 if (keylen != 8) {
132 tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; 144 crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
133 return -EINVAL; 145 return -EINVAL;
134 } 146 }
135 147
@@ -138,33 +150,31 @@ static int michael_setkey(struct crypto_tfm *tfm, const u8 *key,
138 return 0; 150 return 0;
139} 151}
140 152
141 153static struct shash_alg alg = {
142static struct crypto_alg michael_mic_alg = { 154 .digestsize = 8,
143 .cra_name = "michael_mic", 155 .setkey = michael_setkey,
144 .cra_flags = CRYPTO_ALG_TYPE_DIGEST, 156 .init = michael_init,
145 .cra_blocksize = 8, 157 .update = michael_update,
146 .cra_ctxsize = sizeof(struct michael_mic_ctx), 158 .final = michael_final,
147 .cra_module = THIS_MODULE, 159 .descsize = sizeof(struct michael_mic_desc_ctx),
148 .cra_alignmask = 3, 160 .base = {
149 .cra_list = LIST_HEAD_INIT(michael_mic_alg.cra_list), 161 .cra_name = "michael_mic",
150 .cra_u = { .digest = { 162 .cra_blocksize = 8,
151 .dia_digestsize = 8, 163 .cra_alignmask = 3,
152 .dia_init = michael_init, 164 .cra_ctxsize = sizeof(struct michael_mic_ctx),
153 .dia_update = michael_update, 165 .cra_module = THIS_MODULE,
154 .dia_final = michael_final, 166 }
155 .dia_setkey = michael_setkey } }
156}; 167};
157 168
158
159static int __init michael_mic_init(void) 169static int __init michael_mic_init(void)
160{ 170{
161 return crypto_register_alg(&michael_mic_alg); 171 return crypto_register_shash(&alg);
162} 172}
163 173
164 174
165static void __exit michael_mic_exit(void) 175static void __exit michael_mic_exit(void)
166{ 176{
167 crypto_unregister_alg(&michael_mic_alg); 177 crypto_unregister_shash(&alg);
168} 178}
169 179
170 180
diff --git a/crypto/proc.c b/crypto/proc.c
index 37a13d05636d..5dc07e442fca 100644
--- a/crypto/proc.c
+++ b/crypto/proc.c
@@ -94,6 +94,17 @@ static int c_show(struct seq_file *m, void *p)
94 seq_printf(m, "selftest : %s\n", 94 seq_printf(m, "selftest : %s\n",
95 (alg->cra_flags & CRYPTO_ALG_TESTED) ? 95 (alg->cra_flags & CRYPTO_ALG_TESTED) ?
96 "passed" : "unknown"); 96 "passed" : "unknown");
97
98 if (alg->cra_flags & CRYPTO_ALG_LARVAL) {
99 seq_printf(m, "type : larval\n");
100 seq_printf(m, "flags : 0x%x\n", alg->cra_flags);
101 goto out;
102 }
103
104 if (alg->cra_type && alg->cra_type->show) {
105 alg->cra_type->show(m, alg);
106 goto out;
107 }
97 108
98 switch (alg->cra_flags & (CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_LARVAL)) { 109 switch (alg->cra_flags & (CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_LARVAL)) {
99 case CRYPTO_ALG_TYPE_CIPHER: 110 case CRYPTO_ALG_TYPE_CIPHER:
@@ -115,16 +126,11 @@ static int c_show(struct seq_file *m, void *p)
115 seq_printf(m, "type : compression\n"); 126 seq_printf(m, "type : compression\n");
116 break; 127 break;
117 default: 128 default:
118 if (alg->cra_flags & CRYPTO_ALG_LARVAL) { 129 seq_printf(m, "type : unknown\n");
119 seq_printf(m, "type : larval\n");
120 seq_printf(m, "flags : 0x%x\n", alg->cra_flags);
121 } else if (alg->cra_type && alg->cra_type->show)
122 alg->cra_type->show(m, alg);
123 else
124 seq_printf(m, "type : unknown\n");
125 break; 130 break;
126 } 131 }
127 132
133out:
128 seq_putc(m, '\n'); 134 seq_putc(m, '\n');
129 return 0; 135 return 0;
130} 136}
diff --git a/crypto/rmd128.c b/crypto/rmd128.c
index 5de6fa2a76fb..1ceb6735aa53 100644
--- a/crypto/rmd128.c
+++ b/crypto/rmd128.c
@@ -13,11 +13,10 @@
13 * any later version. 13 * any later version.
14 * 14 *
15 */ 15 */
16#include <crypto/internal/hash.h>
16#include <linux/init.h> 17#include <linux/init.h>
17#include <linux/module.h> 18#include <linux/module.h>
18#include <linux/mm.h> 19#include <linux/mm.h>
19#include <linux/crypto.h>
20#include <linux/cryptohash.h>
21#include <linux/types.h> 20#include <linux/types.h>
22#include <asm/byteorder.h> 21#include <asm/byteorder.h>
23 22
@@ -218,9 +217,9 @@ static void rmd128_transform(u32 *state, const __le32 *in)
218 return; 217 return;
219} 218}
220 219
221static void rmd128_init(struct crypto_tfm *tfm) 220static int rmd128_init(struct shash_desc *desc)
222{ 221{
223 struct rmd128_ctx *rctx = crypto_tfm_ctx(tfm); 222 struct rmd128_ctx *rctx = shash_desc_ctx(desc);
224 223
225 rctx->byte_count = 0; 224 rctx->byte_count = 0;
226 225
@@ -230,12 +229,14 @@ static void rmd128_init(struct crypto_tfm *tfm)
230 rctx->state[3] = RMD_H3; 229 rctx->state[3] = RMD_H3;
231 230
232 memset(rctx->buffer, 0, sizeof(rctx->buffer)); 231 memset(rctx->buffer, 0, sizeof(rctx->buffer));
232
233 return 0;
233} 234}
234 235
235static void rmd128_update(struct crypto_tfm *tfm, const u8 *data, 236static int rmd128_update(struct shash_desc *desc, const u8 *data,
236 unsigned int len) 237 unsigned int len)
237{ 238{
238 struct rmd128_ctx *rctx = crypto_tfm_ctx(tfm); 239 struct rmd128_ctx *rctx = shash_desc_ctx(desc);
239 const u32 avail = sizeof(rctx->buffer) - (rctx->byte_count & 0x3f); 240 const u32 avail = sizeof(rctx->buffer) - (rctx->byte_count & 0x3f);
240 241
241 rctx->byte_count += len; 242 rctx->byte_count += len;
@@ -244,7 +245,7 @@ static void rmd128_update(struct crypto_tfm *tfm, const u8 *data,
244 if (avail > len) { 245 if (avail > len) {
245 memcpy((char *)rctx->buffer + (sizeof(rctx->buffer) - avail), 246 memcpy((char *)rctx->buffer + (sizeof(rctx->buffer) - avail),
246 data, len); 247 data, len);
247 return; 248 goto out;
248 } 249 }
249 250
250 memcpy((char *)rctx->buffer + (sizeof(rctx->buffer) - avail), 251 memcpy((char *)rctx->buffer + (sizeof(rctx->buffer) - avail),
@@ -262,12 +263,15 @@ static void rmd128_update(struct crypto_tfm *tfm, const u8 *data,
262 } 263 }
263 264
264 memcpy(rctx->buffer, data, len); 265 memcpy(rctx->buffer, data, len);
266
267out:
268 return 0;
265} 269}
266 270
267/* Add padding and return the message digest. */ 271/* Add padding and return the message digest. */
268static void rmd128_final(struct crypto_tfm *tfm, u8 *out) 272static int rmd128_final(struct shash_desc *desc, u8 *out)
269{ 273{
270 struct rmd128_ctx *rctx = crypto_tfm_ctx(tfm); 274 struct rmd128_ctx *rctx = shash_desc_ctx(desc);
271 u32 i, index, padlen; 275 u32 i, index, padlen;
272 __le64 bits; 276 __le64 bits;
273 __le32 *dst = (__le32 *)out; 277 __le32 *dst = (__le32 *)out;
@@ -278,10 +282,10 @@ static void rmd128_final(struct crypto_tfm *tfm, u8 *out)
278 /* Pad out to 56 mod 64 */ 282 /* Pad out to 56 mod 64 */
279 index = rctx->byte_count & 0x3f; 283 index = rctx->byte_count & 0x3f;
280 padlen = (index < 56) ? (56 - index) : ((64+56) - index); 284 padlen = (index < 56) ? (56 - index) : ((64+56) - index);
281 rmd128_update(tfm, padding, padlen); 285 rmd128_update(desc, padding, padlen);
282 286
283 /* Append length */ 287 /* Append length */
284 rmd128_update(tfm, (const u8 *)&bits, sizeof(bits)); 288 rmd128_update(desc, (const u8 *)&bits, sizeof(bits));
285 289
286 /* Store state in digest */ 290 /* Store state in digest */
287 for (i = 0; i < 4; i++) 291 for (i = 0; i < 4; i++)
@@ -289,31 +293,32 @@ static void rmd128_final(struct crypto_tfm *tfm, u8 *out)
289 293
290 /* Wipe context */ 294 /* Wipe context */
291 memset(rctx, 0, sizeof(*rctx)); 295 memset(rctx, 0, sizeof(*rctx));
296
297 return 0;
292} 298}
293 299
294static struct crypto_alg alg = { 300static struct shash_alg alg = {
295 .cra_name = "rmd128", 301 .digestsize = RMD128_DIGEST_SIZE,
296 .cra_driver_name = "rmd128", 302 .init = rmd128_init,
297 .cra_flags = CRYPTO_ALG_TYPE_DIGEST, 303 .update = rmd128_update,
298 .cra_blocksize = RMD128_BLOCK_SIZE, 304 .final = rmd128_final,
299 .cra_ctxsize = sizeof(struct rmd128_ctx), 305 .descsize = sizeof(struct rmd128_ctx),
300 .cra_module = THIS_MODULE, 306 .base = {
301 .cra_list = LIST_HEAD_INIT(alg.cra_list), 307 .cra_name = "rmd128",
302 .cra_u = { .digest = { 308 .cra_flags = CRYPTO_ALG_TYPE_SHASH,
303 .dia_digestsize = RMD128_DIGEST_SIZE, 309 .cra_blocksize = RMD128_BLOCK_SIZE,
304 .dia_init = rmd128_init, 310 .cra_module = THIS_MODULE,
305 .dia_update = rmd128_update, 311 }
306 .dia_final = rmd128_final } }
307}; 312};
308 313
309static int __init rmd128_mod_init(void) 314static int __init rmd128_mod_init(void)
310{ 315{
311 return crypto_register_alg(&alg); 316 return crypto_register_shash(&alg);
312} 317}
313 318
314static void __exit rmd128_mod_fini(void) 319static void __exit rmd128_mod_fini(void)
315{ 320{
316 crypto_unregister_alg(&alg); 321 crypto_unregister_shash(&alg);
317} 322}
318 323
319module_init(rmd128_mod_init); 324module_init(rmd128_mod_init);
@@ -321,5 +326,3 @@ module_exit(rmd128_mod_fini);
321 326
322MODULE_LICENSE("GPL"); 327MODULE_LICENSE("GPL");
323MODULE_DESCRIPTION("RIPEMD-128 Message Digest"); 328MODULE_DESCRIPTION("RIPEMD-128 Message Digest");
324
325MODULE_ALIAS("rmd128");
diff --git a/crypto/rmd160.c b/crypto/rmd160.c
index f001ec775e1f..472261fc913f 100644
--- a/crypto/rmd160.c
+++ b/crypto/rmd160.c
@@ -13,11 +13,10 @@
13 * any later version. 13 * any later version.
14 * 14 *
15 */ 15 */
16#include <crypto/internal/hash.h>
16#include <linux/init.h> 17#include <linux/init.h>
17#include <linux/module.h> 18#include <linux/module.h>
18#include <linux/mm.h> 19#include <linux/mm.h>
19#include <linux/crypto.h>
20#include <linux/cryptohash.h>
21#include <linux/types.h> 20#include <linux/types.h>
22#include <asm/byteorder.h> 21#include <asm/byteorder.h>
23 22
@@ -261,9 +260,9 @@ static void rmd160_transform(u32 *state, const __le32 *in)
261 return; 260 return;
262} 261}
263 262
264static void rmd160_init(struct crypto_tfm *tfm) 263static int rmd160_init(struct shash_desc *desc)
265{ 264{
266 struct rmd160_ctx *rctx = crypto_tfm_ctx(tfm); 265 struct rmd160_ctx *rctx = shash_desc_ctx(desc);
267 266
268 rctx->byte_count = 0; 267 rctx->byte_count = 0;
269 268
@@ -274,12 +273,14 @@ static void rmd160_init(struct crypto_tfm *tfm)
274 rctx->state[4] = RMD_H4; 273 rctx->state[4] = RMD_H4;
275 274
276 memset(rctx->buffer, 0, sizeof(rctx->buffer)); 275 memset(rctx->buffer, 0, sizeof(rctx->buffer));
276
277 return 0;
277} 278}
278 279
279static void rmd160_update(struct crypto_tfm *tfm, const u8 *data, 280static int rmd160_update(struct shash_desc *desc, const u8 *data,
280 unsigned int len) 281 unsigned int len)
281{ 282{
282 struct rmd160_ctx *rctx = crypto_tfm_ctx(tfm); 283 struct rmd160_ctx *rctx = shash_desc_ctx(desc);
283 const u32 avail = sizeof(rctx->buffer) - (rctx->byte_count & 0x3f); 284 const u32 avail = sizeof(rctx->buffer) - (rctx->byte_count & 0x3f);
284 285
285 rctx->byte_count += len; 286 rctx->byte_count += len;
@@ -288,7 +289,7 @@ static void rmd160_update(struct crypto_tfm *tfm, const u8 *data,
288 if (avail > len) { 289 if (avail > len) {
289 memcpy((char *)rctx->buffer + (sizeof(rctx->buffer) - avail), 290 memcpy((char *)rctx->buffer + (sizeof(rctx->buffer) - avail),
290 data, len); 291 data, len);
291 return; 292 goto out;
292 } 293 }
293 294
294 memcpy((char *)rctx->buffer + (sizeof(rctx->buffer) - avail), 295 memcpy((char *)rctx->buffer + (sizeof(rctx->buffer) - avail),
@@ -306,12 +307,15 @@ static void rmd160_update(struct crypto_tfm *tfm, const u8 *data,
306 } 307 }
307 308
308 memcpy(rctx->buffer, data, len); 309 memcpy(rctx->buffer, data, len);
310
311out:
312 return 0;
309} 313}
310 314
311/* Add padding and return the message digest. */ 315/* Add padding and return the message digest. */
312static void rmd160_final(struct crypto_tfm *tfm, u8 *out) 316static int rmd160_final(struct shash_desc *desc, u8 *out)
313{ 317{
314 struct rmd160_ctx *rctx = crypto_tfm_ctx(tfm); 318 struct rmd160_ctx *rctx = shash_desc_ctx(desc);
315 u32 i, index, padlen; 319 u32 i, index, padlen;
316 __le64 bits; 320 __le64 bits;
317 __le32 *dst = (__le32 *)out; 321 __le32 *dst = (__le32 *)out;
@@ -322,10 +326,10 @@ static void rmd160_final(struct crypto_tfm *tfm, u8 *out)
322 /* Pad out to 56 mod 64 */ 326 /* Pad out to 56 mod 64 */
323 index = rctx->byte_count & 0x3f; 327 index = rctx->byte_count & 0x3f;
324 padlen = (index < 56) ? (56 - index) : ((64+56) - index); 328 padlen = (index < 56) ? (56 - index) : ((64+56) - index);
325 rmd160_update(tfm, padding, padlen); 329 rmd160_update(desc, padding, padlen);
326 330
327 /* Append length */ 331 /* Append length */
328 rmd160_update(tfm, (const u8 *)&bits, sizeof(bits)); 332 rmd160_update(desc, (const u8 *)&bits, sizeof(bits));
329 333
330 /* Store state in digest */ 334 /* Store state in digest */
331 for (i = 0; i < 5; i++) 335 for (i = 0; i < 5; i++)
@@ -333,31 +337,32 @@ static void rmd160_final(struct crypto_tfm *tfm, u8 *out)
333 337
334 /* Wipe context */ 338 /* Wipe context */
335 memset(rctx, 0, sizeof(*rctx)); 339 memset(rctx, 0, sizeof(*rctx));
340
341 return 0;
336} 342}
337 343
338static struct crypto_alg alg = { 344static struct shash_alg alg = {
339 .cra_name = "rmd160", 345 .digestsize = RMD160_DIGEST_SIZE,
340 .cra_driver_name = "rmd160", 346 .init = rmd160_init,
341 .cra_flags = CRYPTO_ALG_TYPE_DIGEST, 347 .update = rmd160_update,
342 .cra_blocksize = RMD160_BLOCK_SIZE, 348 .final = rmd160_final,
343 .cra_ctxsize = sizeof(struct rmd160_ctx), 349 .descsize = sizeof(struct rmd160_ctx),
344 .cra_module = THIS_MODULE, 350 .base = {
345 .cra_list = LIST_HEAD_INIT(alg.cra_list), 351 .cra_name = "rmd160",
346 .cra_u = { .digest = { 352 .cra_flags = CRYPTO_ALG_TYPE_SHASH,
347 .dia_digestsize = RMD160_DIGEST_SIZE, 353 .cra_blocksize = RMD160_BLOCK_SIZE,
348 .dia_init = rmd160_init, 354 .cra_module = THIS_MODULE,
349 .dia_update = rmd160_update, 355 }
350 .dia_final = rmd160_final } }
351}; 356};
352 357
353static int __init rmd160_mod_init(void) 358static int __init rmd160_mod_init(void)
354{ 359{
355 return crypto_register_alg(&alg); 360 return crypto_register_shash(&alg);
356} 361}
357 362
358static void __exit rmd160_mod_fini(void) 363static void __exit rmd160_mod_fini(void)
359{ 364{
360 crypto_unregister_alg(&alg); 365 crypto_unregister_shash(&alg);
361} 366}
362 367
363module_init(rmd160_mod_init); 368module_init(rmd160_mod_init);
@@ -365,5 +370,3 @@ module_exit(rmd160_mod_fini);
365 370
366MODULE_LICENSE("GPL"); 371MODULE_LICENSE("GPL");
367MODULE_DESCRIPTION("RIPEMD-160 Message Digest"); 372MODULE_DESCRIPTION("RIPEMD-160 Message Digest");
368
369MODULE_ALIAS("rmd160");
diff --git a/crypto/rmd256.c b/crypto/rmd256.c
index e3de5b4cb47f..72eafa8d2e7b 100644
--- a/crypto/rmd256.c
+++ b/crypto/rmd256.c
@@ -13,11 +13,10 @@
13 * any later version. 13 * any later version.
14 * 14 *
15 */ 15 */
16#include <crypto/internal/hash.h>
16#include <linux/init.h> 17#include <linux/init.h>
17#include <linux/module.h> 18#include <linux/module.h>
18#include <linux/mm.h> 19#include <linux/mm.h>
19#include <linux/crypto.h>
20#include <linux/cryptohash.h>
21#include <linux/types.h> 20#include <linux/types.h>
22#include <asm/byteorder.h> 21#include <asm/byteorder.h>
23 22
@@ -233,9 +232,9 @@ static void rmd256_transform(u32 *state, const __le32 *in)
233 return; 232 return;
234} 233}
235 234
236static void rmd256_init(struct crypto_tfm *tfm) 235static int rmd256_init(struct shash_desc *desc)
237{ 236{
238 struct rmd256_ctx *rctx = crypto_tfm_ctx(tfm); 237 struct rmd256_ctx *rctx = shash_desc_ctx(desc);
239 238
240 rctx->byte_count = 0; 239 rctx->byte_count = 0;
241 240
@@ -249,12 +248,14 @@ static void rmd256_init(struct crypto_tfm *tfm)
249 rctx->state[7] = RMD_H8; 248 rctx->state[7] = RMD_H8;
250 249
251 memset(rctx->buffer, 0, sizeof(rctx->buffer)); 250 memset(rctx->buffer, 0, sizeof(rctx->buffer));
251
252 return 0;
252} 253}
253 254
254static void rmd256_update(struct crypto_tfm *tfm, const u8 *data, 255static int rmd256_update(struct shash_desc *desc, const u8 *data,
255 unsigned int len) 256 unsigned int len)
256{ 257{
257 struct rmd256_ctx *rctx = crypto_tfm_ctx(tfm); 258 struct rmd256_ctx *rctx = shash_desc_ctx(desc);
258 const u32 avail = sizeof(rctx->buffer) - (rctx->byte_count & 0x3f); 259 const u32 avail = sizeof(rctx->buffer) - (rctx->byte_count & 0x3f);
259 260
260 rctx->byte_count += len; 261 rctx->byte_count += len;
@@ -263,7 +264,7 @@ static void rmd256_update(struct crypto_tfm *tfm, const u8 *data,
263 if (avail > len) { 264 if (avail > len) {
264 memcpy((char *)rctx->buffer + (sizeof(rctx->buffer) - avail), 265 memcpy((char *)rctx->buffer + (sizeof(rctx->buffer) - avail),
265 data, len); 266 data, len);
266 return; 267 goto out;
267 } 268 }
268 269
269 memcpy((char *)rctx->buffer + (sizeof(rctx->buffer) - avail), 270 memcpy((char *)rctx->buffer + (sizeof(rctx->buffer) - avail),
@@ -281,12 +282,15 @@ static void rmd256_update(struct crypto_tfm *tfm, const u8 *data,
281 } 282 }
282 283
283 memcpy(rctx->buffer, data, len); 284 memcpy(rctx->buffer, data, len);
285
286out:
287 return 0;
284} 288}
285 289
286/* Add padding and return the message digest. */ 290/* Add padding and return the message digest. */
287static void rmd256_final(struct crypto_tfm *tfm, u8 *out) 291static int rmd256_final(struct shash_desc *desc, u8 *out)
288{ 292{
289 struct rmd256_ctx *rctx = crypto_tfm_ctx(tfm); 293 struct rmd256_ctx *rctx = shash_desc_ctx(desc);
290 u32 i, index, padlen; 294 u32 i, index, padlen;
291 __le64 bits; 295 __le64 bits;
292 __le32 *dst = (__le32 *)out; 296 __le32 *dst = (__le32 *)out;
@@ -297,10 +301,10 @@ static void rmd256_final(struct crypto_tfm *tfm, u8 *out)
297 /* Pad out to 56 mod 64 */ 301 /* Pad out to 56 mod 64 */
298 index = rctx->byte_count & 0x3f; 302 index = rctx->byte_count & 0x3f;
299 padlen = (index < 56) ? (56 - index) : ((64+56) - index); 303 padlen = (index < 56) ? (56 - index) : ((64+56) - index);
300 rmd256_update(tfm, padding, padlen); 304 rmd256_update(desc, padding, padlen);
301 305
302 /* Append length */ 306 /* Append length */
303 rmd256_update(tfm, (const u8 *)&bits, sizeof(bits)); 307 rmd256_update(desc, (const u8 *)&bits, sizeof(bits));
304 308
305 /* Store state in digest */ 309 /* Store state in digest */
306 for (i = 0; i < 8; i++) 310 for (i = 0; i < 8; i++)
@@ -308,31 +312,32 @@ static void rmd256_final(struct crypto_tfm *tfm, u8 *out)
308 312
309 /* Wipe context */ 313 /* Wipe context */
310 memset(rctx, 0, sizeof(*rctx)); 314 memset(rctx, 0, sizeof(*rctx));
315
316 return 0;
311} 317}
312 318
313static struct crypto_alg alg = { 319static struct shash_alg alg = {
314 .cra_name = "rmd256", 320 .digestsize = RMD256_DIGEST_SIZE,
315 .cra_driver_name = "rmd256", 321 .init = rmd256_init,
316 .cra_flags = CRYPTO_ALG_TYPE_DIGEST, 322 .update = rmd256_update,
317 .cra_blocksize = RMD256_BLOCK_SIZE, 323 .final = rmd256_final,
318 .cra_ctxsize = sizeof(struct rmd256_ctx), 324 .descsize = sizeof(struct rmd256_ctx),
319 .cra_module = THIS_MODULE, 325 .base = {
320 .cra_list = LIST_HEAD_INIT(alg.cra_list), 326 .cra_name = "rmd256",
321 .cra_u = { .digest = { 327 .cra_flags = CRYPTO_ALG_TYPE_SHASH,
322 .dia_digestsize = RMD256_DIGEST_SIZE, 328 .cra_blocksize = RMD256_BLOCK_SIZE,
323 .dia_init = rmd256_init, 329 .cra_module = THIS_MODULE,
324 .dia_update = rmd256_update, 330 }
325 .dia_final = rmd256_final } }
326}; 331};
327 332
328static int __init rmd256_mod_init(void) 333static int __init rmd256_mod_init(void)
329{ 334{
330 return crypto_register_alg(&alg); 335 return crypto_register_shash(&alg);
331} 336}
332 337
333static void __exit rmd256_mod_fini(void) 338static void __exit rmd256_mod_fini(void)
334{ 339{
335 crypto_unregister_alg(&alg); 340 crypto_unregister_shash(&alg);
336} 341}
337 342
338module_init(rmd256_mod_init); 343module_init(rmd256_mod_init);
@@ -340,5 +345,3 @@ module_exit(rmd256_mod_fini);
340 345
341MODULE_LICENSE("GPL"); 346MODULE_LICENSE("GPL");
342MODULE_DESCRIPTION("RIPEMD-256 Message Digest"); 347MODULE_DESCRIPTION("RIPEMD-256 Message Digest");
343
344MODULE_ALIAS("rmd256");
diff --git a/crypto/rmd320.c b/crypto/rmd320.c
index b143d66e42c8..86becaba2f05 100644
--- a/crypto/rmd320.c
+++ b/crypto/rmd320.c
@@ -13,11 +13,10 @@
13 * any later version. 13 * any later version.
14 * 14 *
15 */ 15 */
16#include <crypto/internal/hash.h>
16#include <linux/init.h> 17#include <linux/init.h>
17#include <linux/module.h> 18#include <linux/module.h>
18#include <linux/mm.h> 19#include <linux/mm.h>
19#include <linux/crypto.h>
20#include <linux/cryptohash.h>
21#include <linux/types.h> 20#include <linux/types.h>
22#include <asm/byteorder.h> 21#include <asm/byteorder.h>
23 22
@@ -280,9 +279,9 @@ static void rmd320_transform(u32 *state, const __le32 *in)
280 return; 279 return;
281} 280}
282 281
283static void rmd320_init(struct crypto_tfm *tfm) 282static int rmd320_init(struct shash_desc *desc)
284{ 283{
285 struct rmd320_ctx *rctx = crypto_tfm_ctx(tfm); 284 struct rmd320_ctx *rctx = shash_desc_ctx(desc);
286 285
287 rctx->byte_count = 0; 286 rctx->byte_count = 0;
288 287
@@ -298,12 +297,14 @@ static void rmd320_init(struct crypto_tfm *tfm)
298 rctx->state[9] = RMD_H9; 297 rctx->state[9] = RMD_H9;
299 298
300 memset(rctx->buffer, 0, sizeof(rctx->buffer)); 299 memset(rctx->buffer, 0, sizeof(rctx->buffer));
300
301 return 0;
301} 302}
302 303
303static void rmd320_update(struct crypto_tfm *tfm, const u8 *data, 304static int rmd320_update(struct shash_desc *desc, const u8 *data,
304 unsigned int len) 305 unsigned int len)
305{ 306{
306 struct rmd320_ctx *rctx = crypto_tfm_ctx(tfm); 307 struct rmd320_ctx *rctx = shash_desc_ctx(desc);
307 const u32 avail = sizeof(rctx->buffer) - (rctx->byte_count & 0x3f); 308 const u32 avail = sizeof(rctx->buffer) - (rctx->byte_count & 0x3f);
308 309
309 rctx->byte_count += len; 310 rctx->byte_count += len;
@@ -312,7 +313,7 @@ static void rmd320_update(struct crypto_tfm *tfm, const u8 *data,
312 if (avail > len) { 313 if (avail > len) {
313 memcpy((char *)rctx->buffer + (sizeof(rctx->buffer) - avail), 314 memcpy((char *)rctx->buffer + (sizeof(rctx->buffer) - avail),
314 data, len); 315 data, len);
315 return; 316 goto out;
316 } 317 }
317 318
318 memcpy((char *)rctx->buffer + (sizeof(rctx->buffer) - avail), 319 memcpy((char *)rctx->buffer + (sizeof(rctx->buffer) - avail),
@@ -330,12 +331,15 @@ static void rmd320_update(struct crypto_tfm *tfm, const u8 *data,
330 } 331 }
331 332
332 memcpy(rctx->buffer, data, len); 333 memcpy(rctx->buffer, data, len);
334
335out:
336 return 0;
333} 337}
334 338
335/* Add padding and return the message digest. */ 339/* Add padding and return the message digest. */
336static void rmd320_final(struct crypto_tfm *tfm, u8 *out) 340static int rmd320_final(struct shash_desc *desc, u8 *out)
337{ 341{
338 struct rmd320_ctx *rctx = crypto_tfm_ctx(tfm); 342 struct rmd320_ctx *rctx = shash_desc_ctx(desc);
339 u32 i, index, padlen; 343 u32 i, index, padlen;
340 __le64 bits; 344 __le64 bits;
341 __le32 *dst = (__le32 *)out; 345 __le32 *dst = (__le32 *)out;
@@ -346,10 +350,10 @@ static void rmd320_final(struct crypto_tfm *tfm, u8 *out)
346 /* Pad out to 56 mod 64 */ 350 /* Pad out to 56 mod 64 */
347 index = rctx->byte_count & 0x3f; 351 index = rctx->byte_count & 0x3f;
348 padlen = (index < 56) ? (56 - index) : ((64+56) - index); 352 padlen = (index < 56) ? (56 - index) : ((64+56) - index);
349 rmd320_update(tfm, padding, padlen); 353 rmd320_update(desc, padding, padlen);
350 354
351 /* Append length */ 355 /* Append length */
352 rmd320_update(tfm, (const u8 *)&bits, sizeof(bits)); 356 rmd320_update(desc, (const u8 *)&bits, sizeof(bits));
353 357
354 /* Store state in digest */ 358 /* Store state in digest */
355 for (i = 0; i < 10; i++) 359 for (i = 0; i < 10; i++)
@@ -357,31 +361,32 @@ static void rmd320_final(struct crypto_tfm *tfm, u8 *out)
357 361
358 /* Wipe context */ 362 /* Wipe context */
359 memset(rctx, 0, sizeof(*rctx)); 363 memset(rctx, 0, sizeof(*rctx));
364
365 return 0;
360} 366}
361 367
362static struct crypto_alg alg = { 368static struct shash_alg alg = {
363 .cra_name = "rmd320", 369 .digestsize = RMD320_DIGEST_SIZE,
364 .cra_driver_name = "rmd320", 370 .init = rmd320_init,
365 .cra_flags = CRYPTO_ALG_TYPE_DIGEST, 371 .update = rmd320_update,
366 .cra_blocksize = RMD320_BLOCK_SIZE, 372 .final = rmd320_final,
367 .cra_ctxsize = sizeof(struct rmd320_ctx), 373 .descsize = sizeof(struct rmd320_ctx),
368 .cra_module = THIS_MODULE, 374 .base = {
369 .cra_list = LIST_HEAD_INIT(alg.cra_list), 375 .cra_name = "rmd320",
370 .cra_u = { .digest = { 376 .cra_flags = CRYPTO_ALG_TYPE_SHASH,
371 .dia_digestsize = RMD320_DIGEST_SIZE, 377 .cra_blocksize = RMD320_BLOCK_SIZE,
372 .dia_init = rmd320_init, 378 .cra_module = THIS_MODULE,
373 .dia_update = rmd320_update, 379 }
374 .dia_final = rmd320_final } }
375}; 380};
376 381
377static int __init rmd320_mod_init(void) 382static int __init rmd320_mod_init(void)
378{ 383{
379 return crypto_register_alg(&alg); 384 return crypto_register_shash(&alg);
380} 385}
381 386
382static void __exit rmd320_mod_fini(void) 387static void __exit rmd320_mod_fini(void)
383{ 388{
384 crypto_unregister_alg(&alg); 389 crypto_unregister_shash(&alg);
385} 390}
386 391
387module_init(rmd320_mod_init); 392module_init(rmd320_mod_init);
@@ -389,5 +394,3 @@ module_exit(rmd320_mod_fini);
389 394
390MODULE_LICENSE("GPL"); 395MODULE_LICENSE("GPL");
391MODULE_DESCRIPTION("RIPEMD-320 Message Digest"); 396MODULE_DESCRIPTION("RIPEMD-320 Message Digest");
392
393MODULE_ALIAS("rmd320");
diff --git a/crypto/salsa20_generic.c b/crypto/salsa20_generic.c
index b07d55981741..eac10c11685c 100644
--- a/crypto/salsa20_generic.c
+++ b/crypto/salsa20_generic.c
@@ -24,6 +24,7 @@
24#include <linux/errno.h> 24#include <linux/errno.h>
25#include <linux/crypto.h> 25#include <linux/crypto.h>
26#include <linux/types.h> 26#include <linux/types.h>
27#include <linux/bitops.h>
27#include <crypto/algapi.h> 28#include <crypto/algapi.h>
28#include <asm/byteorder.h> 29#include <asm/byteorder.h>
29 30
@@ -42,10 +43,6 @@ D. J. Bernstein
42Public domain. 43Public domain.
43*/ 44*/
44 45
45#define ROTATE(v,n) (((v) << (n)) | ((v) >> (32 - (n))))
46#define XOR(v,w) ((v) ^ (w))
47#define PLUS(v,w) (((v) + (w)))
48#define PLUSONE(v) (PLUS((v),1))
49#define U32TO8_LITTLE(p, v) \ 46#define U32TO8_LITTLE(p, v) \
50 { (p)[0] = (v >> 0) & 0xff; (p)[1] = (v >> 8) & 0xff; \ 47 { (p)[0] = (v >> 0) & 0xff; (p)[1] = (v >> 8) & 0xff; \
51 (p)[2] = (v >> 16) & 0xff; (p)[3] = (v >> 24) & 0xff; } 48 (p)[2] = (v >> 16) & 0xff; (p)[3] = (v >> 24) & 0xff; }
@@ -65,41 +62,41 @@ static void salsa20_wordtobyte(u8 output[64], const u32 input[16])
65 62
66 memcpy(x, input, sizeof(x)); 63 memcpy(x, input, sizeof(x));
67 for (i = 20; i > 0; i -= 2) { 64 for (i = 20; i > 0; i -= 2) {
68 x[ 4] = XOR(x[ 4],ROTATE(PLUS(x[ 0],x[12]), 7)); 65 x[ 4] ^= rol32((x[ 0] + x[12]), 7);
69 x[ 8] = XOR(x[ 8],ROTATE(PLUS(x[ 4],x[ 0]), 9)); 66 x[ 8] ^= rol32((x[ 4] + x[ 0]), 9);
70 x[12] = XOR(x[12],ROTATE(PLUS(x[ 8],x[ 4]),13)); 67 x[12] ^= rol32((x[ 8] + x[ 4]), 13);
71 x[ 0] = XOR(x[ 0],ROTATE(PLUS(x[12],x[ 8]),18)); 68 x[ 0] ^= rol32((x[12] + x[ 8]), 18);
72 x[ 9] = XOR(x[ 9],ROTATE(PLUS(x[ 5],x[ 1]), 7)); 69 x[ 9] ^= rol32((x[ 5] + x[ 1]), 7);
73 x[13] = XOR(x[13],ROTATE(PLUS(x[ 9],x[ 5]), 9)); 70 x[13] ^= rol32((x[ 9] + x[ 5]), 9);
74 x[ 1] = XOR(x[ 1],ROTATE(PLUS(x[13],x[ 9]),13)); 71 x[ 1] ^= rol32((x[13] + x[ 9]), 13);
75 x[ 5] = XOR(x[ 5],ROTATE(PLUS(x[ 1],x[13]),18)); 72 x[ 5] ^= rol32((x[ 1] + x[13]), 18);
76 x[14] = XOR(x[14],ROTATE(PLUS(x[10],x[ 6]), 7)); 73 x[14] ^= rol32((x[10] + x[ 6]), 7);
77 x[ 2] = XOR(x[ 2],ROTATE(PLUS(x[14],x[10]), 9)); 74 x[ 2] ^= rol32((x[14] + x[10]), 9);
78 x[ 6] = XOR(x[ 6],ROTATE(PLUS(x[ 2],x[14]),13)); 75 x[ 6] ^= rol32((x[ 2] + x[14]), 13);
79 x[10] = XOR(x[10],ROTATE(PLUS(x[ 6],x[ 2]),18)); 76 x[10] ^= rol32((x[ 6] + x[ 2]), 18);
80 x[ 3] = XOR(x[ 3],ROTATE(PLUS(x[15],x[11]), 7)); 77 x[ 3] ^= rol32((x[15] + x[11]), 7);
81 x[ 7] = XOR(x[ 7],ROTATE(PLUS(x[ 3],x[15]), 9)); 78 x[ 7] ^= rol32((x[ 3] + x[15]), 9);
82 x[11] = XOR(x[11],ROTATE(PLUS(x[ 7],x[ 3]),13)); 79 x[11] ^= rol32((x[ 7] + x[ 3]), 13);
83 x[15] = XOR(x[15],ROTATE(PLUS(x[11],x[ 7]),18)); 80 x[15] ^= rol32((x[11] + x[ 7]), 18);
84 x[ 1] = XOR(x[ 1],ROTATE(PLUS(x[ 0],x[ 3]), 7)); 81 x[ 1] ^= rol32((x[ 0] + x[ 3]), 7);
85 x[ 2] = XOR(x[ 2],ROTATE(PLUS(x[ 1],x[ 0]), 9)); 82 x[ 2] ^= rol32((x[ 1] + x[ 0]), 9);
86 x[ 3] = XOR(x[ 3],ROTATE(PLUS(x[ 2],x[ 1]),13)); 83 x[ 3] ^= rol32((x[ 2] + x[ 1]), 13);
87 x[ 0] = XOR(x[ 0],ROTATE(PLUS(x[ 3],x[ 2]),18)); 84 x[ 0] ^= rol32((x[ 3] + x[ 2]), 18);
88 x[ 6] = XOR(x[ 6],ROTATE(PLUS(x[ 5],x[ 4]), 7)); 85 x[ 6] ^= rol32((x[ 5] + x[ 4]), 7);
89 x[ 7] = XOR(x[ 7],ROTATE(PLUS(x[ 6],x[ 5]), 9)); 86 x[ 7] ^= rol32((x[ 6] + x[ 5]), 9);
90 x[ 4] = XOR(x[ 4],ROTATE(PLUS(x[ 7],x[ 6]),13)); 87 x[ 4] ^= rol32((x[ 7] + x[ 6]), 13);
91 x[ 5] = XOR(x[ 5],ROTATE(PLUS(x[ 4],x[ 7]),18)); 88 x[ 5] ^= rol32((x[ 4] + x[ 7]), 18);
92 x[11] = XOR(x[11],ROTATE(PLUS(x[10],x[ 9]), 7)); 89 x[11] ^= rol32((x[10] + x[ 9]), 7);
93 x[ 8] = XOR(x[ 8],ROTATE(PLUS(x[11],x[10]), 9)); 90 x[ 8] ^= rol32((x[11] + x[10]), 9);
94 x[ 9] = XOR(x[ 9],ROTATE(PLUS(x[ 8],x[11]),13)); 91 x[ 9] ^= rol32((x[ 8] + x[11]), 13);
95 x[10] = XOR(x[10],ROTATE(PLUS(x[ 9],x[ 8]),18)); 92 x[10] ^= rol32((x[ 9] + x[ 8]), 18);
96 x[12] = XOR(x[12],ROTATE(PLUS(x[15],x[14]), 7)); 93 x[12] ^= rol32((x[15] + x[14]), 7);
97 x[13] = XOR(x[13],ROTATE(PLUS(x[12],x[15]), 9)); 94 x[13] ^= rol32((x[12] + x[15]), 9);
98 x[14] = XOR(x[14],ROTATE(PLUS(x[13],x[12]),13)); 95 x[14] ^= rol32((x[13] + x[12]), 13);
99 x[15] = XOR(x[15],ROTATE(PLUS(x[14],x[13]),18)); 96 x[15] ^= rol32((x[14] + x[13]), 18);
100 } 97 }
101 for (i = 0; i < 16; ++i) 98 for (i = 0; i < 16; ++i)
102 x[i] = PLUS(x[i],input[i]); 99 x[i] += input[i];
103 for (i = 0; i < 16; ++i) 100 for (i = 0; i < 16; ++i)
104 U32TO8_LITTLE(output + 4 * i,x[i]); 101 U32TO8_LITTLE(output + 4 * i,x[i]);
105} 102}
@@ -150,9 +147,9 @@ static void salsa20_encrypt_bytes(struct salsa20_ctx *ctx, u8 *dst,
150 while (bytes) { 147 while (bytes) {
151 salsa20_wordtobyte(buf, ctx->input); 148 salsa20_wordtobyte(buf, ctx->input);
152 149
153 ctx->input[8] = PLUSONE(ctx->input[8]); 150 ctx->input[8]++;
154 if (!ctx->input[8]) 151 if (!ctx->input[8])
155 ctx->input[9] = PLUSONE(ctx->input[9]); 152 ctx->input[9]++;
156 153
157 if (bytes <= 64) { 154 if (bytes <= 64) {
158 crypto_xor(dst, buf, bytes); 155 crypto_xor(dst, buf, bytes);
diff --git a/crypto/sha1_generic.c b/crypto/sha1_generic.c
index c7c6899e1fca..9efef20454cb 100644
--- a/crypto/sha1_generic.c
+++ b/crypto/sha1_generic.c
@@ -16,10 +16,10 @@
16 * any later version. 16 * any later version.
17 * 17 *
18 */ 18 */
19#include <crypto/internal/hash.h>
19#include <linux/init.h> 20#include <linux/init.h>
20#include <linux/module.h> 21#include <linux/module.h>
21#include <linux/mm.h> 22#include <linux/mm.h>
22#include <linux/crypto.h>
23#include <linux/cryptohash.h> 23#include <linux/cryptohash.h>
24#include <linux/types.h> 24#include <linux/types.h>
25#include <crypto/sha.h> 25#include <crypto/sha.h>
@@ -31,9 +31,10 @@ struct sha1_ctx {
31 u8 buffer[64]; 31 u8 buffer[64];
32}; 32};
33 33
34static void sha1_init(struct crypto_tfm *tfm) 34static int sha1_init(struct shash_desc *desc)
35{ 35{
36 struct sha1_ctx *sctx = crypto_tfm_ctx(tfm); 36 struct sha1_ctx *sctx = shash_desc_ctx(desc);
37
37 static const struct sha1_ctx initstate = { 38 static const struct sha1_ctx initstate = {
38 0, 39 0,
39 { SHA1_H0, SHA1_H1, SHA1_H2, SHA1_H3, SHA1_H4 }, 40 { SHA1_H0, SHA1_H1, SHA1_H2, SHA1_H3, SHA1_H4 },
@@ -41,12 +42,14 @@ static void sha1_init(struct crypto_tfm *tfm)
41 }; 42 };
42 43
43 *sctx = initstate; 44 *sctx = initstate;
45
46 return 0;
44} 47}
45 48
46static void sha1_update(struct crypto_tfm *tfm, const u8 *data, 49static int sha1_update(struct shash_desc *desc, const u8 *data,
47 unsigned int len) 50 unsigned int len)
48{ 51{
49 struct sha1_ctx *sctx = crypto_tfm_ctx(tfm); 52 struct sha1_ctx *sctx = shash_desc_ctx(desc);
50 unsigned int partial, done; 53 unsigned int partial, done;
51 const u8 *src; 54 const u8 *src;
52 55
@@ -74,13 +77,15 @@ static void sha1_update(struct crypto_tfm *tfm, const u8 *data,
74 partial = 0; 77 partial = 0;
75 } 78 }
76 memcpy(sctx->buffer + partial, src, len - done); 79 memcpy(sctx->buffer + partial, src, len - done);
80
81 return 0;
77} 82}
78 83
79 84
80/* Add padding and return the message digest. */ 85/* Add padding and return the message digest. */
81static void sha1_final(struct crypto_tfm *tfm, u8 *out) 86static int sha1_final(struct shash_desc *desc, u8 *out)
82{ 87{
83 struct sha1_ctx *sctx = crypto_tfm_ctx(tfm); 88 struct sha1_ctx *sctx = shash_desc_ctx(desc);
84 __be32 *dst = (__be32 *)out; 89 __be32 *dst = (__be32 *)out;
85 u32 i, index, padlen; 90 u32 i, index, padlen;
86 __be64 bits; 91 __be64 bits;
@@ -91,10 +96,10 @@ static void sha1_final(struct crypto_tfm *tfm, u8 *out)
91 /* Pad out to 56 mod 64 */ 96 /* Pad out to 56 mod 64 */
92 index = sctx->count & 0x3f; 97 index = sctx->count & 0x3f;
93 padlen = (index < 56) ? (56 - index) : ((64+56) - index); 98 padlen = (index < 56) ? (56 - index) : ((64+56) - index);
94 sha1_update(tfm, padding, padlen); 99 sha1_update(desc, padding, padlen);
95 100
96 /* Append length */ 101 /* Append length */
97 sha1_update(tfm, (const u8 *)&bits, sizeof(bits)); 102 sha1_update(desc, (const u8 *)&bits, sizeof(bits));
98 103
99 /* Store state in digest */ 104 /* Store state in digest */
100 for (i = 0; i < 5; i++) 105 for (i = 0; i < 5; i++)
@@ -102,32 +107,33 @@ static void sha1_final(struct crypto_tfm *tfm, u8 *out)
102 107
103 /* Wipe context */ 108 /* Wipe context */
104 memset(sctx, 0, sizeof *sctx); 109 memset(sctx, 0, sizeof *sctx);
110
111 return 0;
105} 112}
106 113
107static struct crypto_alg alg = { 114static struct shash_alg alg = {
108 .cra_name = "sha1", 115 .digestsize = SHA1_DIGEST_SIZE,
109 .cra_driver_name= "sha1-generic", 116 .init = sha1_init,
110 .cra_flags = CRYPTO_ALG_TYPE_DIGEST, 117 .update = sha1_update,
111 .cra_blocksize = SHA1_BLOCK_SIZE, 118 .final = sha1_final,
112 .cra_ctxsize = sizeof(struct sha1_ctx), 119 .descsize = sizeof(struct sha1_ctx),
113 .cra_module = THIS_MODULE, 120 .base = {
114 .cra_alignmask = 3, 121 .cra_name = "sha1",
115 .cra_list = LIST_HEAD_INIT(alg.cra_list), 122 .cra_driver_name= "sha1-generic",
116 .cra_u = { .digest = { 123 .cra_flags = CRYPTO_ALG_TYPE_SHASH,
117 .dia_digestsize = SHA1_DIGEST_SIZE, 124 .cra_blocksize = SHA1_BLOCK_SIZE,
118 .dia_init = sha1_init, 125 .cra_module = THIS_MODULE,
119 .dia_update = sha1_update, 126 }
120 .dia_final = sha1_final } }
121}; 127};
122 128
123static int __init sha1_generic_mod_init(void) 129static int __init sha1_generic_mod_init(void)
124{ 130{
125 return crypto_register_alg(&alg); 131 return crypto_register_shash(&alg);
126} 132}
127 133
128static void __exit sha1_generic_mod_fini(void) 134static void __exit sha1_generic_mod_fini(void)
129{ 135{
130 crypto_unregister_alg(&alg); 136 crypto_unregister_shash(&alg);
131} 137}
132 138
133module_init(sha1_generic_mod_init); 139module_init(sha1_generic_mod_init);
diff --git a/crypto/sha256_generic.c b/crypto/sha256_generic.c
index 5a8dd47558e5..caa3542e6ce8 100644
--- a/crypto/sha256_generic.c
+++ b/crypto/sha256_generic.c
@@ -17,10 +17,10 @@
17 * any later version. 17 * any later version.
18 * 18 *
19 */ 19 */
20#include <crypto/internal/hash.h>
20#include <linux/init.h> 21#include <linux/init.h>
21#include <linux/module.h> 22#include <linux/module.h>
22#include <linux/mm.h> 23#include <linux/mm.h>
23#include <linux/crypto.h>
24#include <linux/types.h> 24#include <linux/types.h>
25#include <crypto/sha.h> 25#include <crypto/sha.h>
26#include <asm/byteorder.h> 26#include <asm/byteorder.h>
@@ -69,7 +69,7 @@ static void sha256_transform(u32 *state, const u8 *input)
69 /* now blend */ 69 /* now blend */
70 for (i = 16; i < 64; i++) 70 for (i = 16; i < 64; i++)
71 BLEND_OP(i, W); 71 BLEND_OP(i, W);
72 72
73 /* load the state into our registers */ 73 /* load the state into our registers */
74 a=state[0]; b=state[1]; c=state[2]; d=state[3]; 74 a=state[0]; b=state[1]; c=state[2]; d=state[3];
75 e=state[4]; f=state[5]; g=state[6]; h=state[7]; 75 e=state[4]; f=state[5]; g=state[6]; h=state[7];
@@ -220,9 +220,9 @@ static void sha256_transform(u32 *state, const u8 *input)
220} 220}
221 221
222 222
223static void sha224_init(struct crypto_tfm *tfm) 223static int sha224_init(struct shash_desc *desc)
224{ 224{
225 struct sha256_ctx *sctx = crypto_tfm_ctx(tfm); 225 struct sha256_ctx *sctx = shash_desc_ctx(desc);
226 sctx->state[0] = SHA224_H0; 226 sctx->state[0] = SHA224_H0;
227 sctx->state[1] = SHA224_H1; 227 sctx->state[1] = SHA224_H1;
228 sctx->state[2] = SHA224_H2; 228 sctx->state[2] = SHA224_H2;
@@ -233,11 +233,13 @@ static void sha224_init(struct crypto_tfm *tfm)
233 sctx->state[7] = SHA224_H7; 233 sctx->state[7] = SHA224_H7;
234 sctx->count[0] = 0; 234 sctx->count[0] = 0;
235 sctx->count[1] = 0; 235 sctx->count[1] = 0;
236
237 return 0;
236} 238}
237 239
238static void sha256_init(struct crypto_tfm *tfm) 240static int sha256_init(struct shash_desc *desc)
239{ 241{
240 struct sha256_ctx *sctx = crypto_tfm_ctx(tfm); 242 struct sha256_ctx *sctx = shash_desc_ctx(desc);
241 sctx->state[0] = SHA256_H0; 243 sctx->state[0] = SHA256_H0;
242 sctx->state[1] = SHA256_H1; 244 sctx->state[1] = SHA256_H1;
243 sctx->state[2] = SHA256_H2; 245 sctx->state[2] = SHA256_H2;
@@ -247,12 +249,14 @@ static void sha256_init(struct crypto_tfm *tfm)
247 sctx->state[6] = SHA256_H6; 249 sctx->state[6] = SHA256_H6;
248 sctx->state[7] = SHA256_H7; 250 sctx->state[7] = SHA256_H7;
249 sctx->count[0] = sctx->count[1] = 0; 251 sctx->count[0] = sctx->count[1] = 0;
252
253 return 0;
250} 254}
251 255
252static void sha256_update(struct crypto_tfm *tfm, const u8 *data, 256static int sha256_update(struct shash_desc *desc, const u8 *data,
253 unsigned int len) 257 unsigned int len)
254{ 258{
255 struct sha256_ctx *sctx = crypto_tfm_ctx(tfm); 259 struct sha256_ctx *sctx = shash_desc_ctx(desc);
256 unsigned int i, index, part_len; 260 unsigned int i, index, part_len;
257 261
258 /* Compute number of bytes mod 128 */ 262 /* Compute number of bytes mod 128 */
@@ -277,14 +281,16 @@ static void sha256_update(struct crypto_tfm *tfm, const u8 *data,
277 } else { 281 } else {
278 i = 0; 282 i = 0;
279 } 283 }
280 284
281 /* Buffer remaining input */ 285 /* Buffer remaining input */
282 memcpy(&sctx->buf[index], &data[i], len-i); 286 memcpy(&sctx->buf[index], &data[i], len-i);
287
288 return 0;
283} 289}
284 290
285static void sha256_final(struct crypto_tfm *tfm, u8 *out) 291static int sha256_final(struct shash_desc *desc, u8 *out)
286{ 292{
287 struct sha256_ctx *sctx = crypto_tfm_ctx(tfm); 293 struct sha256_ctx *sctx = shash_desc_ctx(desc);
288 __be32 *dst = (__be32 *)out; 294 __be32 *dst = (__be32 *)out;
289 __be32 bits[2]; 295 __be32 bits[2];
290 unsigned int index, pad_len; 296 unsigned int index, pad_len;
@@ -298,10 +304,10 @@ static void sha256_final(struct crypto_tfm *tfm, u8 *out)
298 /* Pad out to 56 mod 64. */ 304 /* Pad out to 56 mod 64. */
299 index = (sctx->count[0] >> 3) & 0x3f; 305 index = (sctx->count[0] >> 3) & 0x3f;
300 pad_len = (index < 56) ? (56 - index) : ((64+56) - index); 306 pad_len = (index < 56) ? (56 - index) : ((64+56) - index);
301 sha256_update(tfm, padding, pad_len); 307 sha256_update(desc, padding, pad_len);
302 308
303 /* Append length (before padding) */ 309 /* Append length (before padding) */
304 sha256_update(tfm, (const u8 *)bits, sizeof(bits)); 310 sha256_update(desc, (const u8 *)bits, sizeof(bits));
305 311
306 /* Store state in digest */ 312 /* Store state in digest */
307 for (i = 0; i < 8; i++) 313 for (i = 0; i < 8; i++)
@@ -309,71 +315,73 @@ static void sha256_final(struct crypto_tfm *tfm, u8 *out)
309 315
310 /* Zeroize sensitive information. */ 316 /* Zeroize sensitive information. */
311 memset(sctx, 0, sizeof(*sctx)); 317 memset(sctx, 0, sizeof(*sctx));
318
319 return 0;
312} 320}
313 321
314static void sha224_final(struct crypto_tfm *tfm, u8 *hash) 322static int sha224_final(struct shash_desc *desc, u8 *hash)
315{ 323{
316 u8 D[SHA256_DIGEST_SIZE]; 324 u8 D[SHA256_DIGEST_SIZE];
317 325
318 sha256_final(tfm, D); 326 sha256_final(desc, D);
319 327
320 memcpy(hash, D, SHA224_DIGEST_SIZE); 328 memcpy(hash, D, SHA224_DIGEST_SIZE);
321 memset(D, 0, SHA256_DIGEST_SIZE); 329 memset(D, 0, SHA256_DIGEST_SIZE);
330
331 return 0;
322} 332}
323 333
324static struct crypto_alg sha256 = { 334static struct shash_alg sha256 = {
325 .cra_name = "sha256", 335 .digestsize = SHA256_DIGEST_SIZE,
326 .cra_driver_name= "sha256-generic", 336 .init = sha256_init,
327 .cra_flags = CRYPTO_ALG_TYPE_DIGEST, 337 .update = sha256_update,
328 .cra_blocksize = SHA256_BLOCK_SIZE, 338 .final = sha256_final,
329 .cra_ctxsize = sizeof(struct sha256_ctx), 339 .descsize = sizeof(struct sha256_ctx),
330 .cra_module = THIS_MODULE, 340 .base = {
331 .cra_alignmask = 3, 341 .cra_name = "sha256",
332 .cra_list = LIST_HEAD_INIT(sha256.cra_list), 342 .cra_driver_name= "sha256-generic",
333 .cra_u = { .digest = { 343 .cra_flags = CRYPTO_ALG_TYPE_SHASH,
334 .dia_digestsize = SHA256_DIGEST_SIZE, 344 .cra_blocksize = SHA256_BLOCK_SIZE,
335 .dia_init = sha256_init, 345 .cra_module = THIS_MODULE,
336 .dia_update = sha256_update, 346 }
337 .dia_final = sha256_final } }
338}; 347};
339 348
340static struct crypto_alg sha224 = { 349static struct shash_alg sha224 = {
341 .cra_name = "sha224", 350 .digestsize = SHA224_DIGEST_SIZE,
342 .cra_driver_name = "sha224-generic", 351 .init = sha224_init,
343 .cra_flags = CRYPTO_ALG_TYPE_DIGEST, 352 .update = sha256_update,
344 .cra_blocksize = SHA224_BLOCK_SIZE, 353 .final = sha224_final,
345 .cra_ctxsize = sizeof(struct sha256_ctx), 354 .descsize = sizeof(struct sha256_ctx),
346 .cra_module = THIS_MODULE, 355 .base = {
347 .cra_alignmask = 3, 356 .cra_name = "sha224",
348 .cra_list = LIST_HEAD_INIT(sha224.cra_list), 357 .cra_driver_name= "sha224-generic",
349 .cra_u = { .digest = { 358 .cra_flags = CRYPTO_ALG_TYPE_SHASH,
350 .dia_digestsize = SHA224_DIGEST_SIZE, 359 .cra_blocksize = SHA224_BLOCK_SIZE,
351 .dia_init = sha224_init, 360 .cra_module = THIS_MODULE,
352 .dia_update = sha256_update, 361 }
353 .dia_final = sha224_final } }
354}; 362};
355 363
356static int __init sha256_generic_mod_init(void) 364static int __init sha256_generic_mod_init(void)
357{ 365{
358 int ret = 0; 366 int ret = 0;
359 367
360 ret = crypto_register_alg(&sha224); 368 ret = crypto_register_shash(&sha224);
361 369
362 if (ret < 0) 370 if (ret < 0)
363 return ret; 371 return ret;
364 372
365 ret = crypto_register_alg(&sha256); 373 ret = crypto_register_shash(&sha256);
366 374
367 if (ret < 0) 375 if (ret < 0)
368 crypto_unregister_alg(&sha224); 376 crypto_unregister_shash(&sha224);
369 377
370 return ret; 378 return ret;
371} 379}
372 380
373static void __exit sha256_generic_mod_fini(void) 381static void __exit sha256_generic_mod_fini(void)
374{ 382{
375 crypto_unregister_alg(&sha224); 383 crypto_unregister_shash(&sha224);
376 crypto_unregister_alg(&sha256); 384 crypto_unregister_shash(&sha256);
377} 385}
378 386
379module_init(sha256_generic_mod_init); 387module_init(sha256_generic_mod_init);
diff --git a/crypto/sha512_generic.c b/crypto/sha512_generic.c
index bc3686138aeb..3bea38d12242 100644
--- a/crypto/sha512_generic.c
+++ b/crypto/sha512_generic.c
@@ -10,7 +10,7 @@
10 * later version. 10 * later version.
11 * 11 *
12 */ 12 */
13 13#include <crypto/internal/hash.h>
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/mm.h> 16#include <linux/mm.h>
@@ -18,16 +18,17 @@
18#include <linux/crypto.h> 18#include <linux/crypto.h>
19#include <linux/types.h> 19#include <linux/types.h>
20#include <crypto/sha.h> 20#include <crypto/sha.h>
21 21#include <linux/percpu.h>
22#include <asm/byteorder.h> 22#include <asm/byteorder.h>
23 23
24struct sha512_ctx { 24struct sha512_ctx {
25 u64 state[8]; 25 u64 state[8];
26 u32 count[4]; 26 u32 count[4];
27 u8 buf[128]; 27 u8 buf[128];
28 u64 W[80];
29}; 28};
30 29
30static DEFINE_PER_CPU(u64[80], msg_schedule);
31
31static inline u64 Ch(u64 x, u64 y, u64 z) 32static inline u64 Ch(u64 x, u64 y, u64 z)
32{ 33{
33 return z ^ (x & (y ^ z)); 34 return z ^ (x & (y ^ z));
@@ -89,11 +90,12 @@ static inline void BLEND_OP(int I, u64 *W)
89} 90}
90 91
91static void 92static void
92sha512_transform(u64 *state, u64 *W, const u8 *input) 93sha512_transform(u64 *state, const u8 *input)
93{ 94{
94 u64 a, b, c, d, e, f, g, h, t1, t2; 95 u64 a, b, c, d, e, f, g, h, t1, t2;
95 96
96 int i; 97 int i;
98 u64 *W = get_cpu_var(msg_schedule);
97 99
98 /* load the input */ 100 /* load the input */
99 for (i = 0; i < 16; i++) 101 for (i = 0; i < 16; i++)
@@ -132,12 +134,14 @@ sha512_transform(u64 *state, u64 *W, const u8 *input)
132 134
133 /* erase our data */ 135 /* erase our data */
134 a = b = c = d = e = f = g = h = t1 = t2 = 0; 136 a = b = c = d = e = f = g = h = t1 = t2 = 0;
137 memset(W, 0, sizeof(__get_cpu_var(msg_schedule)));
138 put_cpu_var(msg_schedule);
135} 139}
136 140
137static void 141static int
138sha512_init(struct crypto_tfm *tfm) 142sha512_init(struct shash_desc *desc)
139{ 143{
140 struct sha512_ctx *sctx = crypto_tfm_ctx(tfm); 144 struct sha512_ctx *sctx = shash_desc_ctx(desc);
141 sctx->state[0] = SHA512_H0; 145 sctx->state[0] = SHA512_H0;
142 sctx->state[1] = SHA512_H1; 146 sctx->state[1] = SHA512_H1;
143 sctx->state[2] = SHA512_H2; 147 sctx->state[2] = SHA512_H2;
@@ -147,12 +151,14 @@ sha512_init(struct crypto_tfm *tfm)
147 sctx->state[6] = SHA512_H6; 151 sctx->state[6] = SHA512_H6;
148 sctx->state[7] = SHA512_H7; 152 sctx->state[7] = SHA512_H7;
149 sctx->count[0] = sctx->count[1] = sctx->count[2] = sctx->count[3] = 0; 153 sctx->count[0] = sctx->count[1] = sctx->count[2] = sctx->count[3] = 0;
154
155 return 0;
150} 156}
151 157
152static void 158static int
153sha384_init(struct crypto_tfm *tfm) 159sha384_init(struct shash_desc *desc)
154{ 160{
155 struct sha512_ctx *sctx = crypto_tfm_ctx(tfm); 161 struct sha512_ctx *sctx = shash_desc_ctx(desc);
156 sctx->state[0] = SHA384_H0; 162 sctx->state[0] = SHA384_H0;
157 sctx->state[1] = SHA384_H1; 163 sctx->state[1] = SHA384_H1;
158 sctx->state[2] = SHA384_H2; 164 sctx->state[2] = SHA384_H2;
@@ -162,12 +168,14 @@ sha384_init(struct crypto_tfm *tfm)
162 sctx->state[6] = SHA384_H6; 168 sctx->state[6] = SHA384_H6;
163 sctx->state[7] = SHA384_H7; 169 sctx->state[7] = SHA384_H7;
164 sctx->count[0] = sctx->count[1] = sctx->count[2] = sctx->count[3] = 0; 170 sctx->count[0] = sctx->count[1] = sctx->count[2] = sctx->count[3] = 0;
171
172 return 0;
165} 173}
166 174
167static void 175static int
168sha512_update(struct crypto_tfm *tfm, const u8 *data, unsigned int len) 176sha512_update(struct shash_desc *desc, const u8 *data, unsigned int len)
169{ 177{
170 struct sha512_ctx *sctx = crypto_tfm_ctx(tfm); 178 struct sha512_ctx *sctx = shash_desc_ctx(desc);
171 179
172 unsigned int i, index, part_len; 180 unsigned int i, index, part_len;
173 181
@@ -187,10 +195,10 @@ sha512_update(struct crypto_tfm *tfm, const u8 *data, unsigned int len)
187 /* Transform as many times as possible. */ 195 /* Transform as many times as possible. */
188 if (len >= part_len) { 196 if (len >= part_len) {
189 memcpy(&sctx->buf[index], data, part_len); 197 memcpy(&sctx->buf[index], data, part_len);
190 sha512_transform(sctx->state, sctx->W, sctx->buf); 198 sha512_transform(sctx->state, sctx->buf);
191 199
192 for (i = part_len; i + 127 < len; i+=128) 200 for (i = part_len; i + 127 < len; i+=128)
193 sha512_transform(sctx->state, sctx->W, &data[i]); 201 sha512_transform(sctx->state, &data[i]);
194 202
195 index = 0; 203 index = 0;
196 } else { 204 } else {
@@ -200,14 +208,13 @@ sha512_update(struct crypto_tfm *tfm, const u8 *data, unsigned int len)
200 /* Buffer remaining input */ 208 /* Buffer remaining input */
201 memcpy(&sctx->buf[index], &data[i], len - i); 209 memcpy(&sctx->buf[index], &data[i], len - i);
202 210
203 /* erase our data */ 211 return 0;
204 memset(sctx->W, 0, sizeof(sctx->W));
205} 212}
206 213
207static void 214static int
208sha512_final(struct crypto_tfm *tfm, u8 *hash) 215sha512_final(struct shash_desc *desc, u8 *hash)
209{ 216{
210 struct sha512_ctx *sctx = crypto_tfm_ctx(tfm); 217 struct sha512_ctx *sctx = shash_desc_ctx(desc);
211 static u8 padding[128] = { 0x80, }; 218 static u8 padding[128] = { 0x80, };
212 __be64 *dst = (__be64 *)hash; 219 __be64 *dst = (__be64 *)hash;
213 __be32 bits[4]; 220 __be32 bits[4];
@@ -223,10 +230,10 @@ sha512_final(struct crypto_tfm *tfm, u8 *hash)
223 /* Pad out to 112 mod 128. */ 230 /* Pad out to 112 mod 128. */
224 index = (sctx->count[0] >> 3) & 0x7f; 231 index = (sctx->count[0] >> 3) & 0x7f;
225 pad_len = (index < 112) ? (112 - index) : ((128+112) - index); 232 pad_len = (index < 112) ? (112 - index) : ((128+112) - index);
226 sha512_update(tfm, padding, pad_len); 233 sha512_update(desc, padding, pad_len);
227 234
228 /* Append length (before padding) */ 235 /* Append length (before padding) */
229 sha512_update(tfm, (const u8 *)bits, sizeof(bits)); 236 sha512_update(desc, (const u8 *)bits, sizeof(bits));
230 237
231 /* Store state in digest */ 238 /* Store state in digest */
232 for (i = 0; i < 8; i++) 239 for (i = 0; i < 8; i++)
@@ -234,66 +241,66 @@ sha512_final(struct crypto_tfm *tfm, u8 *hash)
234 241
235 /* Zeroize sensitive information. */ 242 /* Zeroize sensitive information. */
236 memset(sctx, 0, sizeof(struct sha512_ctx)); 243 memset(sctx, 0, sizeof(struct sha512_ctx));
244
245 return 0;
237} 246}
238 247
239static void sha384_final(struct crypto_tfm *tfm, u8 *hash) 248static int sha384_final(struct shash_desc *desc, u8 *hash)
240{ 249{
241 u8 D[64]; 250 u8 D[64];
251
252 sha512_final(desc, D);
242 253
243 sha512_final(tfm, D); 254 memcpy(hash, D, 48);
255 memset(D, 0, 64);
244 256
245 memcpy(hash, D, 48); 257 return 0;
246 memset(D, 0, 64);
247} 258}
248 259
249static struct crypto_alg sha512 = { 260static struct shash_alg sha512 = {
250 .cra_name = "sha512", 261 .digestsize = SHA512_DIGEST_SIZE,
251 .cra_flags = CRYPTO_ALG_TYPE_DIGEST, 262 .init = sha512_init,
252 .cra_blocksize = SHA512_BLOCK_SIZE, 263 .update = sha512_update,
253 .cra_ctxsize = sizeof(struct sha512_ctx), 264 .final = sha512_final,
254 .cra_module = THIS_MODULE, 265 .descsize = sizeof(struct sha512_ctx),
255 .cra_alignmask = 3, 266 .base = {
256 .cra_list = LIST_HEAD_INIT(sha512.cra_list), 267 .cra_name = "sha512",
257 .cra_u = { .digest = { 268 .cra_flags = CRYPTO_ALG_TYPE_SHASH,
258 .dia_digestsize = SHA512_DIGEST_SIZE, 269 .cra_blocksize = SHA512_BLOCK_SIZE,
259 .dia_init = sha512_init, 270 .cra_module = THIS_MODULE,
260 .dia_update = sha512_update, 271 }
261 .dia_final = sha512_final }
262 }
263}; 272};
264 273
265static struct crypto_alg sha384 = { 274static struct shash_alg sha384 = {
266 .cra_name = "sha384", 275 .digestsize = SHA384_DIGEST_SIZE,
267 .cra_flags = CRYPTO_ALG_TYPE_DIGEST, 276 .init = sha384_init,
268 .cra_blocksize = SHA384_BLOCK_SIZE, 277 .update = sha512_update,
269 .cra_ctxsize = sizeof(struct sha512_ctx), 278 .final = sha384_final,
270 .cra_alignmask = 3, 279 .descsize = sizeof(struct sha512_ctx),
271 .cra_module = THIS_MODULE, 280 .base = {
272 .cra_list = LIST_HEAD_INIT(sha384.cra_list), 281 .cra_name = "sha384",
273 .cra_u = { .digest = { 282 .cra_flags = CRYPTO_ALG_TYPE_SHASH,
274 .dia_digestsize = SHA384_DIGEST_SIZE, 283 .cra_blocksize = SHA384_BLOCK_SIZE,
275 .dia_init = sha384_init, 284 .cra_module = THIS_MODULE,
276 .dia_update = sha512_update, 285 }
277 .dia_final = sha384_final }
278 }
279}; 286};
280 287
281static int __init sha512_generic_mod_init(void) 288static int __init sha512_generic_mod_init(void)
282{ 289{
283 int ret = 0; 290 int ret = 0;
284 291
285 if ((ret = crypto_register_alg(&sha384)) < 0) 292 if ((ret = crypto_register_shash(&sha384)) < 0)
286 goto out; 293 goto out;
287 if ((ret = crypto_register_alg(&sha512)) < 0) 294 if ((ret = crypto_register_shash(&sha512)) < 0)
288 crypto_unregister_alg(&sha384); 295 crypto_unregister_shash(&sha384);
289out: 296out:
290 return ret; 297 return ret;
291} 298}
292 299
293static void __exit sha512_generic_mod_fini(void) 300static void __exit sha512_generic_mod_fini(void)
294{ 301{
295 crypto_unregister_alg(&sha384); 302 crypto_unregister_shash(&sha384);
296 crypto_unregister_alg(&sha512); 303 crypto_unregister_shash(&sha512);
297} 304}
298 305
299module_init(sha512_generic_mod_init); 306module_init(sha512_generic_mod_init);
diff --git a/crypto/shash.c b/crypto/shash.c
new file mode 100644
index 000000000000..c9df367332ff
--- /dev/null
+++ b/crypto/shash.c
@@ -0,0 +1,508 @@
1/*
2 * Synchronous Cryptographic Hash operations.
3 *
4 * Copyright (c) 2008 Herbert Xu <herbert@gondor.apana.org.au>
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 Free
8 * Software Foundation; either version 2 of the License, or (at your option)
9 * any later version.
10 *
11 */
12
13#include <crypto/scatterwalk.h>
14#include <crypto/internal/hash.h>
15#include <linux/err.h>
16#include <linux/kernel.h>
17#include <linux/module.h>
18#include <linux/slab.h>
19#include <linux/seq_file.h>
20
21static const struct crypto_type crypto_shash_type;
22
23static inline struct crypto_shash *__crypto_shash_cast(struct crypto_tfm *tfm)
24{
25 return container_of(tfm, struct crypto_shash, base);
26}
27
28#include "internal.h"
29
30static int shash_setkey_unaligned(struct crypto_shash *tfm, const u8 *key,
31 unsigned int keylen)
32{
33 struct shash_alg *shash = crypto_shash_alg(tfm);
34 unsigned long alignmask = crypto_shash_alignmask(tfm);
35 unsigned long absize;
36 u8 *buffer, *alignbuffer;
37 int err;
38
39 absize = keylen + (alignmask & ~(CRYPTO_MINALIGN - 1));
40 buffer = kmalloc(absize, GFP_KERNEL);
41 if (!buffer)
42 return -ENOMEM;
43
44 alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
45 memcpy(alignbuffer, key, keylen);
46 err = shash->setkey(tfm, alignbuffer, keylen);
47 memset(alignbuffer, 0, keylen);
48 kfree(buffer);
49 return err;
50}
51
52int crypto_shash_setkey(struct crypto_shash *tfm, const u8 *key,
53 unsigned int keylen)
54{
55 struct shash_alg *shash = crypto_shash_alg(tfm);
56 unsigned long alignmask = crypto_shash_alignmask(tfm);
57
58 if (!shash->setkey)
59 return -ENOSYS;
60
61 if ((unsigned long)key & alignmask)
62 return shash_setkey_unaligned(tfm, key, keylen);
63
64 return shash->setkey(tfm, key, keylen);
65}
66EXPORT_SYMBOL_GPL(crypto_shash_setkey);
67
68static inline unsigned int shash_align_buffer_size(unsigned len,
69 unsigned long mask)
70{
71 return len + (mask & ~(__alignof__(u8 __attribute__ ((aligned))) - 1));
72}
73
74static int shash_update_unaligned(struct shash_desc *desc, const u8 *data,
75 unsigned int len)
76{
77 struct crypto_shash *tfm = desc->tfm;
78 struct shash_alg *shash = crypto_shash_alg(tfm);
79 unsigned long alignmask = crypto_shash_alignmask(tfm);
80 unsigned int unaligned_len = alignmask + 1 -
81 ((unsigned long)data & alignmask);
82 u8 buf[shash_align_buffer_size(unaligned_len, alignmask)]
83 __attribute__ ((aligned));
84
85 memcpy(buf, data, unaligned_len);
86
87 return shash->update(desc, buf, unaligned_len) ?:
88 shash->update(desc, data + unaligned_len, len - unaligned_len);
89}
90
91int crypto_shash_update(struct shash_desc *desc, const u8 *data,
92 unsigned int len)
93{
94 struct crypto_shash *tfm = desc->tfm;
95 struct shash_alg *shash = crypto_shash_alg(tfm);
96 unsigned long alignmask = crypto_shash_alignmask(tfm);
97
98 if ((unsigned long)data & alignmask)
99 return shash_update_unaligned(desc, data, len);
100
101 return shash->update(desc, data, len);
102}
103EXPORT_SYMBOL_GPL(crypto_shash_update);
104
105static int shash_final_unaligned(struct shash_desc *desc, u8 *out)
106{
107 struct crypto_shash *tfm = desc->tfm;
108 unsigned long alignmask = crypto_shash_alignmask(tfm);
109 struct shash_alg *shash = crypto_shash_alg(tfm);
110 unsigned int ds = crypto_shash_digestsize(tfm);
111 u8 buf[shash_align_buffer_size(ds, alignmask)]
112 __attribute__ ((aligned));
113 int err;
114
115 err = shash->final(desc, buf);
116 memcpy(out, buf, ds);
117 return err;
118}
119
120int crypto_shash_final(struct shash_desc *desc, u8 *out)
121{
122 struct crypto_shash *tfm = desc->tfm;
123 struct shash_alg *shash = crypto_shash_alg(tfm);
124 unsigned long alignmask = crypto_shash_alignmask(tfm);
125
126 if ((unsigned long)out & alignmask)
127 return shash_final_unaligned(desc, out);
128
129 return shash->final(desc, out);
130}
131EXPORT_SYMBOL_GPL(crypto_shash_final);
132
133static int shash_finup_unaligned(struct shash_desc *desc, const u8 *data,
134 unsigned int len, u8 *out)
135{
136 return crypto_shash_update(desc, data, len) ?:
137 crypto_shash_final(desc, out);
138}
139
140int crypto_shash_finup(struct shash_desc *desc, const u8 *data,
141 unsigned int len, u8 *out)
142{
143 struct crypto_shash *tfm = desc->tfm;
144 struct shash_alg *shash = crypto_shash_alg(tfm);
145 unsigned long alignmask = crypto_shash_alignmask(tfm);
146
147 if (((unsigned long)data | (unsigned long)out) & alignmask ||
148 !shash->finup)
149 return shash_finup_unaligned(desc, data, len, out);
150
151 return shash->finup(desc, data, len, out);
152}
153EXPORT_SYMBOL_GPL(crypto_shash_finup);
154
155static int shash_digest_unaligned(struct shash_desc *desc, const u8 *data,
156 unsigned int len, u8 *out)
157{
158 return crypto_shash_init(desc) ?:
159 crypto_shash_update(desc, data, len) ?:
160 crypto_shash_final(desc, out);
161}
162
163int crypto_shash_digest(struct shash_desc *desc, const u8 *data,
164 unsigned int len, u8 *out)
165{
166 struct crypto_shash *tfm = desc->tfm;
167 struct shash_alg *shash = crypto_shash_alg(tfm);
168 unsigned long alignmask = crypto_shash_alignmask(tfm);
169
170 if (((unsigned long)data | (unsigned long)out) & alignmask ||
171 !shash->digest)
172 return shash_digest_unaligned(desc, data, len, out);
173
174 return shash->digest(desc, data, len, out);
175}
176EXPORT_SYMBOL_GPL(crypto_shash_digest);
177
178int crypto_shash_import(struct shash_desc *desc, const u8 *in)
179{
180 struct crypto_shash *tfm = desc->tfm;
181 struct shash_alg *alg = crypto_shash_alg(tfm);
182
183 memcpy(shash_desc_ctx(desc), in, crypto_shash_descsize(tfm));
184
185 if (alg->reinit)
186 alg->reinit(desc);
187
188 return 0;
189}
190EXPORT_SYMBOL_GPL(crypto_shash_import);
191
192static int shash_async_setkey(struct crypto_ahash *tfm, const u8 *key,
193 unsigned int keylen)
194{
195 struct crypto_shash **ctx = crypto_ahash_ctx(tfm);
196
197 return crypto_shash_setkey(*ctx, key, keylen);
198}
199
200static int shash_async_init(struct ahash_request *req)
201{
202 struct crypto_shash **ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req));
203 struct shash_desc *desc = ahash_request_ctx(req);
204
205 desc->tfm = *ctx;
206 desc->flags = req->base.flags;
207
208 return crypto_shash_init(desc);
209}
210
211static int shash_async_update(struct ahash_request *req)
212{
213 struct shash_desc *desc = ahash_request_ctx(req);
214 struct crypto_hash_walk walk;
215 int nbytes;
216
217 for (nbytes = crypto_hash_walk_first(req, &walk); nbytes > 0;
218 nbytes = crypto_hash_walk_done(&walk, nbytes))
219 nbytes = crypto_shash_update(desc, walk.data, nbytes);
220
221 return nbytes;
222}
223
224static int shash_async_final(struct ahash_request *req)
225{
226 return crypto_shash_final(ahash_request_ctx(req), req->result);
227}
228
229static int shash_async_digest(struct ahash_request *req)
230{
231 struct scatterlist *sg = req->src;
232 unsigned int offset = sg->offset;
233 unsigned int nbytes = req->nbytes;
234 int err;
235
236 if (nbytes < min(sg->length, ((unsigned int)(PAGE_SIZE)) - offset)) {
237 struct crypto_shash **ctx =
238 crypto_ahash_ctx(crypto_ahash_reqtfm(req));
239 struct shash_desc *desc = ahash_request_ctx(req);
240 void *data;
241
242 desc->tfm = *ctx;
243 desc->flags = req->base.flags;
244
245 data = crypto_kmap(sg_page(sg), 0);
246 err = crypto_shash_digest(desc, data + offset, nbytes,
247 req->result);
248 crypto_kunmap(data, 0);
249 crypto_yield(desc->flags);
250 goto out;
251 }
252
253 err = shash_async_init(req);
254 if (err)
255 goto out;
256
257 err = shash_async_update(req);
258 if (err)
259 goto out;
260
261 err = shash_async_final(req);
262
263out:
264 return err;
265}
266
267static void crypto_exit_shash_ops_async(struct crypto_tfm *tfm)
268{
269 struct crypto_shash **ctx = crypto_tfm_ctx(tfm);
270
271 crypto_free_shash(*ctx);
272}
273
274static int crypto_init_shash_ops_async(struct crypto_tfm *tfm)
275{
276 struct crypto_alg *calg = tfm->__crt_alg;
277 struct shash_alg *alg = __crypto_shash_alg(calg);
278 struct ahash_tfm *crt = &tfm->crt_ahash;
279 struct crypto_shash **ctx = crypto_tfm_ctx(tfm);
280 struct crypto_shash *shash;
281
282 if (!crypto_mod_get(calg))
283 return -EAGAIN;
284
285 shash = __crypto_shash_cast(crypto_create_tfm(
286 calg, &crypto_shash_type));
287 if (IS_ERR(shash)) {
288 crypto_mod_put(calg);
289 return PTR_ERR(shash);
290 }
291
292 *ctx = shash;
293 tfm->exit = crypto_exit_shash_ops_async;
294
295 crt->init = shash_async_init;
296 crt->update = shash_async_update;
297 crt->final = shash_async_final;
298 crt->digest = shash_async_digest;
299 crt->setkey = shash_async_setkey;
300
301 crt->digestsize = alg->digestsize;
302 crt->reqsize = sizeof(struct shash_desc) + crypto_shash_descsize(shash);
303
304 return 0;
305}
306
307static int shash_compat_setkey(struct crypto_hash *tfm, const u8 *key,
308 unsigned int keylen)
309{
310 struct shash_desc *desc = crypto_hash_ctx(tfm);
311
312 return crypto_shash_setkey(desc->tfm, key, keylen);
313}
314
315static int shash_compat_init(struct hash_desc *hdesc)
316{
317 struct shash_desc *desc = crypto_hash_ctx(hdesc->tfm);
318
319 desc->flags = hdesc->flags;
320
321 return crypto_shash_init(desc);
322}
323
324static int shash_compat_update(struct hash_desc *hdesc, struct scatterlist *sg,
325 unsigned int len)
326{
327 struct shash_desc *desc = crypto_hash_ctx(hdesc->tfm);
328 struct crypto_hash_walk walk;
329 int nbytes;
330
331 for (nbytes = crypto_hash_walk_first_compat(hdesc, &walk, sg, len);
332 nbytes > 0; nbytes = crypto_hash_walk_done(&walk, nbytes))
333 nbytes = crypto_shash_update(desc, walk.data, nbytes);
334
335 return nbytes;
336}
337
338static int shash_compat_final(struct hash_desc *hdesc, u8 *out)
339{
340 return crypto_shash_final(crypto_hash_ctx(hdesc->tfm), out);
341}
342
343static int shash_compat_digest(struct hash_desc *hdesc, struct scatterlist *sg,
344 unsigned int nbytes, u8 *out)
345{
346 unsigned int offset = sg->offset;
347 int err;
348
349 if (nbytes < min(sg->length, ((unsigned int)(PAGE_SIZE)) - offset)) {
350 struct shash_desc *desc = crypto_hash_ctx(hdesc->tfm);
351 void *data;
352
353 desc->flags = hdesc->flags;
354
355 data = crypto_kmap(sg_page(sg), 0);
356 err = crypto_shash_digest(desc, data + offset, nbytes, out);
357 crypto_kunmap(data, 0);
358 crypto_yield(desc->flags);
359 goto out;
360 }
361
362 err = shash_compat_init(hdesc);
363 if (err)
364 goto out;
365
366 err = shash_compat_update(hdesc, sg, nbytes);
367 if (err)
368 goto out;
369
370 err = shash_compat_final(hdesc, out);
371
372out:
373 return err;
374}
375
376static void crypto_exit_shash_ops_compat(struct crypto_tfm *tfm)
377{
378 struct shash_desc *desc= crypto_tfm_ctx(tfm);
379
380 crypto_free_shash(desc->tfm);
381}
382
383static int crypto_init_shash_ops_compat(struct crypto_tfm *tfm)
384{
385 struct hash_tfm *crt = &tfm->crt_hash;
386 struct crypto_alg *calg = tfm->__crt_alg;
387 struct shash_alg *alg = __crypto_shash_alg(calg);
388 struct shash_desc *desc = crypto_tfm_ctx(tfm);
389 struct crypto_shash *shash;
390
391 shash = __crypto_shash_cast(crypto_create_tfm(
392 calg, &crypto_shash_type));
393 if (IS_ERR(shash))
394 return PTR_ERR(shash);
395
396 desc->tfm = shash;
397 tfm->exit = crypto_exit_shash_ops_compat;
398
399 crt->init = shash_compat_init;
400 crt->update = shash_compat_update;
401 crt->final = shash_compat_final;
402 crt->digest = shash_compat_digest;
403 crt->setkey = shash_compat_setkey;
404
405 crt->digestsize = alg->digestsize;
406
407 return 0;
408}
409
410static int crypto_init_shash_ops(struct crypto_tfm *tfm, u32 type, u32 mask)
411{
412 switch (mask & CRYPTO_ALG_TYPE_MASK) {
413 case CRYPTO_ALG_TYPE_HASH_MASK:
414 return crypto_init_shash_ops_compat(tfm);
415 case CRYPTO_ALG_TYPE_AHASH_MASK:
416 return crypto_init_shash_ops_async(tfm);
417 }
418
419 return -EINVAL;
420}
421
422static unsigned int crypto_shash_ctxsize(struct crypto_alg *alg, u32 type,
423 u32 mask)
424{
425 struct shash_alg *salg = __crypto_shash_alg(alg);
426
427 switch (mask & CRYPTO_ALG_TYPE_MASK) {
428 case CRYPTO_ALG_TYPE_HASH_MASK:
429 return sizeof(struct shash_desc) + salg->descsize;
430 case CRYPTO_ALG_TYPE_AHASH_MASK:
431 return sizeof(struct crypto_shash *);
432 }
433
434 return 0;
435}
436
437static int crypto_shash_init_tfm(struct crypto_tfm *tfm,
438 const struct crypto_type *frontend)
439{
440 if (frontend->type != CRYPTO_ALG_TYPE_SHASH)
441 return -EINVAL;
442 return 0;
443}
444
445static unsigned int crypto_shash_extsize(struct crypto_alg *alg,
446 const struct crypto_type *frontend)
447{
448 return alg->cra_ctxsize;
449}
450
451static void crypto_shash_show(struct seq_file *m, struct crypto_alg *alg)
452 __attribute__ ((unused));
453static void crypto_shash_show(struct seq_file *m, struct crypto_alg *alg)
454{
455 struct shash_alg *salg = __crypto_shash_alg(alg);
456
457 seq_printf(m, "type : shash\n");
458 seq_printf(m, "blocksize : %u\n", alg->cra_blocksize);
459 seq_printf(m, "digestsize : %u\n", salg->digestsize);
460 seq_printf(m, "descsize : %u\n", salg->descsize);
461}
462
463static const struct crypto_type crypto_shash_type = {
464 .ctxsize = crypto_shash_ctxsize,
465 .extsize = crypto_shash_extsize,
466 .init = crypto_init_shash_ops,
467 .init_tfm = crypto_shash_init_tfm,
468#ifdef CONFIG_PROC_FS
469 .show = crypto_shash_show,
470#endif
471 .maskclear = ~CRYPTO_ALG_TYPE_MASK,
472 .maskset = CRYPTO_ALG_TYPE_MASK,
473 .type = CRYPTO_ALG_TYPE_SHASH,
474 .tfmsize = offsetof(struct crypto_shash, base),
475};
476
477struct crypto_shash *crypto_alloc_shash(const char *alg_name, u32 type,
478 u32 mask)
479{
480 return __crypto_shash_cast(
481 crypto_alloc_tfm(alg_name, &crypto_shash_type, type, mask));
482}
483EXPORT_SYMBOL_GPL(crypto_alloc_shash);
484
485int crypto_register_shash(struct shash_alg *alg)
486{
487 struct crypto_alg *base = &alg->base;
488
489 if (alg->digestsize > PAGE_SIZE / 8 ||
490 alg->descsize > PAGE_SIZE / 8)
491 return -EINVAL;
492
493 base->cra_type = &crypto_shash_type;
494 base->cra_flags &= ~CRYPTO_ALG_TYPE_MASK;
495 base->cra_flags |= CRYPTO_ALG_TYPE_SHASH;
496
497 return crypto_register_alg(base);
498}
499EXPORT_SYMBOL_GPL(crypto_register_shash);
500
501int crypto_unregister_shash(struct shash_alg *alg)
502{
503 return crypto_unregister_alg(&alg->base);
504}
505EXPORT_SYMBOL_GPL(crypto_unregister_shash);
506
507MODULE_LICENSE("GPL");
508MODULE_DESCRIPTION("Synchronous cryptographic hash type");
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index b828c6cf1b1d..a75f11ffb957 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -843,6 +843,14 @@ static int test_comp(struct crypto_comp *tfm, struct comp_testvec *ctemplate,
843 goto out; 843 goto out;
844 } 844 }
845 845
846 if (dlen != ctemplate[i].outlen) {
847 printk(KERN_ERR "alg: comp: Compression test %d "
848 "failed for %s: output len = %d\n", i + 1, algo,
849 dlen);
850 ret = -EINVAL;
851 goto out;
852 }
853
846 if (memcmp(result, ctemplate[i].output, dlen)) { 854 if (memcmp(result, ctemplate[i].output, dlen)) {
847 printk(KERN_ERR "alg: comp: Compression test %d " 855 printk(KERN_ERR "alg: comp: Compression test %d "
848 "failed for %s\n", i + 1, algo); 856 "failed for %s\n", i + 1, algo);
@@ -853,7 +861,7 @@ static int test_comp(struct crypto_comp *tfm, struct comp_testvec *ctemplate,
853 } 861 }
854 862
855 for (i = 0; i < dtcount; i++) { 863 for (i = 0; i < dtcount; i++) {
856 int ilen, ret, dlen = COMP_BUF_SIZE; 864 int ilen, dlen = COMP_BUF_SIZE;
857 865
858 memset(result, 0, sizeof (result)); 866 memset(result, 0, sizeof (result));
859 867
@@ -867,6 +875,14 @@ static int test_comp(struct crypto_comp *tfm, struct comp_testvec *ctemplate,
867 goto out; 875 goto out;
868 } 876 }
869 877
878 if (dlen != dtemplate[i].outlen) {
879 printk(KERN_ERR "alg: comp: Decompression test %d "
880 "failed for %s: output len = %d\n", i + 1, algo,
881 dlen);
882 ret = -EINVAL;
883 goto out;
884 }
885
870 if (memcmp(result, dtemplate[i].output, dlen)) { 886 if (memcmp(result, dtemplate[i].output, dlen)) {
871 printk(KERN_ERR "alg: comp: Decompression test %d " 887 printk(KERN_ERR "alg: comp: Decompression test %d "
872 "failed for %s\n", i + 1, algo); 888 "failed for %s\n", i + 1, algo);
@@ -1010,6 +1026,55 @@ static int alg_test_hash(const struct alg_test_desc *desc, const char *driver,
1010 return err; 1026 return err;
1011} 1027}
1012 1028
1029static int alg_test_crc32c(const struct alg_test_desc *desc,
1030 const char *driver, u32 type, u32 mask)
1031{
1032 struct crypto_shash *tfm;
1033 u32 val;
1034 int err;
1035
1036 err = alg_test_hash(desc, driver, type, mask);
1037 if (err)
1038 goto out;
1039
1040 tfm = crypto_alloc_shash(driver, type, mask);
1041 if (IS_ERR(tfm)) {
1042 printk(KERN_ERR "alg: crc32c: Failed to load transform for %s: "
1043 "%ld\n", driver, PTR_ERR(tfm));
1044 err = PTR_ERR(tfm);
1045 goto out;
1046 }
1047
1048 do {
1049 struct {
1050 struct shash_desc shash;
1051 char ctx[crypto_shash_descsize(tfm)];
1052 } sdesc;
1053
1054 sdesc.shash.tfm = tfm;
1055 sdesc.shash.flags = 0;
1056
1057 *(u32 *)sdesc.ctx = le32_to_cpu(420553207);
1058 err = crypto_shash_final(&sdesc.shash, (u8 *)&val);
1059 if (err) {
1060 printk(KERN_ERR "alg: crc32c: Operation failed for "
1061 "%s: %d\n", driver, err);
1062 break;
1063 }
1064
1065 if (val != ~420553207) {
1066 printk(KERN_ERR "alg: crc32c: Test failed for %s: "
1067 "%d\n", driver, val);
1068 err = -EINVAL;
1069 }
1070 } while (0);
1071
1072 crypto_free_shash(tfm);
1073
1074out:
1075 return err;
1076}
1077
1013/* Please keep this list sorted by algorithm name. */ 1078/* Please keep this list sorted by algorithm name. */
1014static const struct alg_test_desc alg_test_descs[] = { 1079static const struct alg_test_desc alg_test_descs[] = {
1015 { 1080 {
@@ -1134,7 +1199,7 @@ static const struct alg_test_desc alg_test_descs[] = {
1134 } 1199 }
1135 }, { 1200 }, {
1136 .alg = "crc32c", 1201 .alg = "crc32c",
1137 .test = alg_test_hash, 1202 .test = alg_test_crc32c,
1138 .suite = { 1203 .suite = {
1139 .hash = { 1204 .hash = {
1140 .vecs = crc32c_tv_template, 1205 .vecs = crc32c_tv_template,
@@ -1801,6 +1866,7 @@ static int alg_find_test(const char *alg)
1801int alg_test(const char *driver, const char *alg, u32 type, u32 mask) 1866int alg_test(const char *driver, const char *alg, u32 type, u32 mask)
1802{ 1867{
1803 int i; 1868 int i;
1869 int rc;
1804 1870
1805 if ((type & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_CIPHER) { 1871 if ((type & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_CIPHER) {
1806 char nalg[CRYPTO_MAX_ALG_NAME]; 1872 char nalg[CRYPTO_MAX_ALG_NAME];
@@ -1820,8 +1886,12 @@ int alg_test(const char *driver, const char *alg, u32 type, u32 mask)
1820 if (i < 0) 1886 if (i < 0)
1821 goto notest; 1887 goto notest;
1822 1888
1823 return alg_test_descs[i].test(alg_test_descs + i, driver, 1889 rc = alg_test_descs[i].test(alg_test_descs + i, driver,
1824 type, mask); 1890 type, mask);
1891 if (fips_enabled && rc)
1892 panic("%s: %s alg self test failed in fips mode!\n", driver, alg);
1893
1894 return rc;
1825 1895
1826notest: 1896notest:
1827 printk(KERN_INFO "alg: No test for %s (%s)\n", alg, driver); 1897 printk(KERN_INFO "alg: No test for %s (%s)\n", alg, driver);
diff --git a/crypto/testmgr.h b/crypto/testmgr.h
index dee94d9ecfba..132953e144d3 100644
--- a/crypto/testmgr.h
+++ b/crypto/testmgr.h
@@ -8349,7 +8349,7 @@ struct comp_testvec {
8349 8349
8350/* 8350/*
8351 * Deflate test vectors (null-terminated strings). 8351 * Deflate test vectors (null-terminated strings).
8352 * Params: winbits=11, Z_DEFAULT_COMPRESSION, MAX_MEM_LEVEL. 8352 * Params: winbits=-11, Z_DEFAULT_COMPRESSION, MAX_MEM_LEVEL.
8353 */ 8353 */
8354#define DEFLATE_COMP_TEST_VECTORS 2 8354#define DEFLATE_COMP_TEST_VECTORS 2
8355#define DEFLATE_DECOMP_TEST_VECTORS 2 8355#define DEFLATE_DECOMP_TEST_VECTORS 2
diff --git a/crypto/tgr192.c b/crypto/tgr192.c
index a92414f24beb..cbca4f208c9f 100644
--- a/crypto/tgr192.c
+++ b/crypto/tgr192.c
@@ -21,11 +21,11 @@
21 * (at your option) any later version. 21 * (at your option) any later version.
22 * 22 *
23 */ 23 */
24#include <crypto/internal/hash.h>
24#include <linux/init.h> 25#include <linux/init.h>
25#include <linux/module.h> 26#include <linux/module.h>
26#include <linux/mm.h> 27#include <linux/mm.h>
27#include <asm/byteorder.h> 28#include <asm/byteorder.h>
28#include <linux/crypto.h>
29#include <linux/types.h> 29#include <linux/types.h>
30 30
31#define TGR192_DIGEST_SIZE 24 31#define TGR192_DIGEST_SIZE 24
@@ -495,24 +495,26 @@ static void tgr192_transform(struct tgr192_ctx *tctx, const u8 * data)
495 tctx->c = c; 495 tctx->c = c;
496} 496}
497 497
498static void tgr192_init(struct crypto_tfm *tfm) 498static int tgr192_init(struct shash_desc *desc)
499{ 499{
500 struct tgr192_ctx *tctx = crypto_tfm_ctx(tfm); 500 struct tgr192_ctx *tctx = shash_desc_ctx(desc);
501 501
502 tctx->a = 0x0123456789abcdefULL; 502 tctx->a = 0x0123456789abcdefULL;
503 tctx->b = 0xfedcba9876543210ULL; 503 tctx->b = 0xfedcba9876543210ULL;
504 tctx->c = 0xf096a5b4c3b2e187ULL; 504 tctx->c = 0xf096a5b4c3b2e187ULL;
505 tctx->nblocks = 0; 505 tctx->nblocks = 0;
506 tctx->count = 0; 506 tctx->count = 0;
507
508 return 0;
507} 509}
508 510
509 511
510/* Update the message digest with the contents 512/* Update the message digest with the contents
511 * of INBUF with length INLEN. */ 513 * of INBUF with length INLEN. */
512static void tgr192_update(struct crypto_tfm *tfm, const u8 *inbuf, 514static int tgr192_update(struct shash_desc *desc, const u8 *inbuf,
513 unsigned int len) 515 unsigned int len)
514{ 516{
515 struct tgr192_ctx *tctx = crypto_tfm_ctx(tfm); 517 struct tgr192_ctx *tctx = shash_desc_ctx(desc);
516 518
517 if (tctx->count == 64) { /* flush the buffer */ 519 if (tctx->count == 64) { /* flush the buffer */
518 tgr192_transform(tctx, tctx->hash); 520 tgr192_transform(tctx, tctx->hash);
@@ -520,15 +522,15 @@ static void tgr192_update(struct crypto_tfm *tfm, const u8 *inbuf,
520 tctx->nblocks++; 522 tctx->nblocks++;
521 } 523 }
522 if (!inbuf) { 524 if (!inbuf) {
523 return; 525 return 0;
524 } 526 }
525 if (tctx->count) { 527 if (tctx->count) {
526 for (; len && tctx->count < 64; len--) { 528 for (; len && tctx->count < 64; len--) {
527 tctx->hash[tctx->count++] = *inbuf++; 529 tctx->hash[tctx->count++] = *inbuf++;
528 } 530 }
529 tgr192_update(tfm, NULL, 0); 531 tgr192_update(desc, NULL, 0);
530 if (!len) { 532 if (!len) {
531 return; 533 return 0;
532 } 534 }
533 535
534 } 536 }
@@ -543,20 +545,22 @@ static void tgr192_update(struct crypto_tfm *tfm, const u8 *inbuf,
543 for (; len && tctx->count < 64; len--) { 545 for (; len && tctx->count < 64; len--) {
544 tctx->hash[tctx->count++] = *inbuf++; 546 tctx->hash[tctx->count++] = *inbuf++;
545 } 547 }
548
549 return 0;
546} 550}
547 551
548 552
549 553
550/* The routine terminates the computation */ 554/* The routine terminates the computation */
551static void tgr192_final(struct crypto_tfm *tfm, u8 * out) 555static int tgr192_final(struct shash_desc *desc, u8 * out)
552{ 556{
553 struct tgr192_ctx *tctx = crypto_tfm_ctx(tfm); 557 struct tgr192_ctx *tctx = shash_desc_ctx(desc);
554 __be64 *dst = (__be64 *)out; 558 __be64 *dst = (__be64 *)out;
555 __be64 *be64p; 559 __be64 *be64p;
556 __le32 *le32p; 560 __le32 *le32p;
557 u32 t, msb, lsb; 561 u32 t, msb, lsb;
558 562
559 tgr192_update(tfm, NULL, 0); /* flush */ ; 563 tgr192_update(desc, NULL, 0); /* flush */ ;
560 564
561 msb = 0; 565 msb = 0;
562 t = tctx->nblocks; 566 t = tctx->nblocks;
@@ -584,7 +588,7 @@ static void tgr192_final(struct crypto_tfm *tfm, u8 * out)
584 while (tctx->count < 64) { 588 while (tctx->count < 64) {
585 tctx->hash[tctx->count++] = 0; 589 tctx->hash[tctx->count++] = 0;
586 } 590 }
587 tgr192_update(tfm, NULL, 0); /* flush */ ; 591 tgr192_update(desc, NULL, 0); /* flush */ ;
588 memset(tctx->hash, 0, 56); /* fill next block with zeroes */ 592 memset(tctx->hash, 0, 56); /* fill next block with zeroes */
589 } 593 }
590 /* append the 64 bit count */ 594 /* append the 64 bit count */
@@ -598,91 +602,94 @@ static void tgr192_final(struct crypto_tfm *tfm, u8 * out)
598 dst[0] = be64p[0] = cpu_to_be64(tctx->a); 602 dst[0] = be64p[0] = cpu_to_be64(tctx->a);
599 dst[1] = be64p[1] = cpu_to_be64(tctx->b); 603 dst[1] = be64p[1] = cpu_to_be64(tctx->b);
600 dst[2] = be64p[2] = cpu_to_be64(tctx->c); 604 dst[2] = be64p[2] = cpu_to_be64(tctx->c);
605
606 return 0;
601} 607}
602 608
603static void tgr160_final(struct crypto_tfm *tfm, u8 * out) 609static int tgr160_final(struct shash_desc *desc, u8 * out)
604{ 610{
605 u8 D[64]; 611 u8 D[64];
606 612
607 tgr192_final(tfm, D); 613 tgr192_final(desc, D);
608 memcpy(out, D, TGR160_DIGEST_SIZE); 614 memcpy(out, D, TGR160_DIGEST_SIZE);
609 memset(D, 0, TGR192_DIGEST_SIZE); 615 memset(D, 0, TGR192_DIGEST_SIZE);
616
617 return 0;
610} 618}
611 619
612static void tgr128_final(struct crypto_tfm *tfm, u8 * out) 620static int tgr128_final(struct shash_desc *desc, u8 * out)
613{ 621{
614 u8 D[64]; 622 u8 D[64];
615 623
616 tgr192_final(tfm, D); 624 tgr192_final(desc, D);
617 memcpy(out, D, TGR128_DIGEST_SIZE); 625 memcpy(out, D, TGR128_DIGEST_SIZE);
618 memset(D, 0, TGR192_DIGEST_SIZE); 626 memset(D, 0, TGR192_DIGEST_SIZE);
627
628 return 0;
619} 629}
620 630
621static struct crypto_alg tgr192 = { 631static struct shash_alg tgr192 = {
622 .cra_name = "tgr192", 632 .digestsize = TGR192_DIGEST_SIZE,
623 .cra_flags = CRYPTO_ALG_TYPE_DIGEST, 633 .init = tgr192_init,
624 .cra_blocksize = TGR192_BLOCK_SIZE, 634 .update = tgr192_update,
625 .cra_ctxsize = sizeof(struct tgr192_ctx), 635 .final = tgr192_final,
626 .cra_module = THIS_MODULE, 636 .descsize = sizeof(struct tgr192_ctx),
627 .cra_alignmask = 7, 637 .base = {
628 .cra_list = LIST_HEAD_INIT(tgr192.cra_list), 638 .cra_name = "tgr192",
629 .cra_u = {.digest = { 639 .cra_flags = CRYPTO_ALG_TYPE_SHASH,
630 .dia_digestsize = TGR192_DIGEST_SIZE, 640 .cra_blocksize = TGR192_BLOCK_SIZE,
631 .dia_init = tgr192_init, 641 .cra_module = THIS_MODULE,
632 .dia_update = tgr192_update, 642 }
633 .dia_final = tgr192_final}}
634}; 643};
635 644
636static struct crypto_alg tgr160 = { 645static struct shash_alg tgr160 = {
637 .cra_name = "tgr160", 646 .digestsize = TGR160_DIGEST_SIZE,
638 .cra_flags = CRYPTO_ALG_TYPE_DIGEST, 647 .init = tgr192_init,
639 .cra_blocksize = TGR192_BLOCK_SIZE, 648 .update = tgr192_update,
640 .cra_ctxsize = sizeof(struct tgr192_ctx), 649 .final = tgr160_final,
641 .cra_module = THIS_MODULE, 650 .descsize = sizeof(struct tgr192_ctx),
642 .cra_alignmask = 7, 651 .base = {
643 .cra_list = LIST_HEAD_INIT(tgr160.cra_list), 652 .cra_name = "tgr160",
644 .cra_u = {.digest = { 653 .cra_flags = CRYPTO_ALG_TYPE_SHASH,
645 .dia_digestsize = TGR160_DIGEST_SIZE, 654 .cra_blocksize = TGR192_BLOCK_SIZE,
646 .dia_init = tgr192_init, 655 .cra_module = THIS_MODULE,
647 .dia_update = tgr192_update, 656 }
648 .dia_final = tgr160_final}}
649}; 657};
650 658
651static struct crypto_alg tgr128 = { 659static struct shash_alg tgr128 = {
652 .cra_name = "tgr128", 660 .digestsize = TGR128_DIGEST_SIZE,
653 .cra_flags = CRYPTO_ALG_TYPE_DIGEST, 661 .init = tgr192_init,
654 .cra_blocksize = TGR192_BLOCK_SIZE, 662 .update = tgr192_update,
655 .cra_ctxsize = sizeof(struct tgr192_ctx), 663 .final = tgr128_final,
656 .cra_module = THIS_MODULE, 664 .descsize = sizeof(struct tgr192_ctx),
657 .cra_alignmask = 7, 665 .base = {
658 .cra_list = LIST_HEAD_INIT(tgr128.cra_list), 666 .cra_name = "tgr128",
659 .cra_u = {.digest = { 667 .cra_flags = CRYPTO_ALG_TYPE_SHASH,
660 .dia_digestsize = TGR128_DIGEST_SIZE, 668 .cra_blocksize = TGR192_BLOCK_SIZE,
661 .dia_init = tgr192_init, 669 .cra_module = THIS_MODULE,
662 .dia_update = tgr192_update, 670 }
663 .dia_final = tgr128_final}}
664}; 671};
665 672
666static int __init tgr192_mod_init(void) 673static int __init tgr192_mod_init(void)
667{ 674{
668 int ret = 0; 675 int ret = 0;
669 676
670 ret = crypto_register_alg(&tgr192); 677 ret = crypto_register_shash(&tgr192);
671 678
672 if (ret < 0) { 679 if (ret < 0) {
673 goto out; 680 goto out;
674 } 681 }
675 682
676 ret = crypto_register_alg(&tgr160); 683 ret = crypto_register_shash(&tgr160);
677 if (ret < 0) { 684 if (ret < 0) {
678 crypto_unregister_alg(&tgr192); 685 crypto_unregister_shash(&tgr192);
679 goto out; 686 goto out;
680 } 687 }
681 688
682 ret = crypto_register_alg(&tgr128); 689 ret = crypto_register_shash(&tgr128);
683 if (ret < 0) { 690 if (ret < 0) {
684 crypto_unregister_alg(&tgr192); 691 crypto_unregister_shash(&tgr192);
685 crypto_unregister_alg(&tgr160); 692 crypto_unregister_shash(&tgr160);
686 } 693 }
687 out: 694 out:
688 return ret; 695 return ret;
@@ -690,9 +697,9 @@ static int __init tgr192_mod_init(void)
690 697
691static void __exit tgr192_mod_fini(void) 698static void __exit tgr192_mod_fini(void)
692{ 699{
693 crypto_unregister_alg(&tgr192); 700 crypto_unregister_shash(&tgr192);
694 crypto_unregister_alg(&tgr160); 701 crypto_unregister_shash(&tgr160);
695 crypto_unregister_alg(&tgr128); 702 crypto_unregister_shash(&tgr128);
696} 703}
697 704
698MODULE_ALIAS("tgr160"); 705MODULE_ALIAS("tgr160");
diff --git a/crypto/wp512.c b/crypto/wp512.c
index bff28560d66d..723427273687 100644
--- a/crypto/wp512.c
+++ b/crypto/wp512.c
@@ -19,11 +19,11 @@
19 * (at your option) any later version. 19 * (at your option) any later version.
20 * 20 *
21 */ 21 */
22#include <crypto/internal/hash.h>
22#include <linux/init.h> 23#include <linux/init.h>
23#include <linux/module.h> 24#include <linux/module.h>
24#include <linux/mm.h> 25#include <linux/mm.h>
25#include <asm/byteorder.h> 26#include <asm/byteorder.h>
26#include <linux/crypto.h>
27#include <linux/types.h> 27#include <linux/types.h>
28 28
29#define WP512_DIGEST_SIZE 64 29#define WP512_DIGEST_SIZE 64
@@ -980,8 +980,8 @@ static void wp512_process_buffer(struct wp512_ctx *wctx) {
980 980
981} 981}
982 982
983static void wp512_init(struct crypto_tfm *tfm) { 983static int wp512_init(struct shash_desc *desc) {
984 struct wp512_ctx *wctx = crypto_tfm_ctx(tfm); 984 struct wp512_ctx *wctx = shash_desc_ctx(desc);
985 int i; 985 int i;
986 986
987 memset(wctx->bitLength, 0, 32); 987 memset(wctx->bitLength, 0, 32);
@@ -990,12 +990,14 @@ static void wp512_init(struct crypto_tfm *tfm) {
990 for (i = 0; i < 8; i++) { 990 for (i = 0; i < 8; i++) {
991 wctx->hash[i] = 0L; 991 wctx->hash[i] = 0L;
992 } 992 }
993
994 return 0;
993} 995}
994 996
995static void wp512_update(struct crypto_tfm *tfm, const u8 *source, 997static int wp512_update(struct shash_desc *desc, const u8 *source,
996 unsigned int len) 998 unsigned int len)
997{ 999{
998 struct wp512_ctx *wctx = crypto_tfm_ctx(tfm); 1000 struct wp512_ctx *wctx = shash_desc_ctx(desc);
999 int sourcePos = 0; 1001 int sourcePos = 0;
1000 unsigned int bits_len = len * 8; // convert to number of bits 1002 unsigned int bits_len = len * 8; // convert to number of bits
1001 int sourceGap = (8 - ((int)bits_len & 7)) & 7; 1003 int sourceGap = (8 - ((int)bits_len & 7)) & 7;
@@ -1051,11 +1053,12 @@ static void wp512_update(struct crypto_tfm *tfm, const u8 *source,
1051 wctx->bufferBits = bufferBits; 1053 wctx->bufferBits = bufferBits;
1052 wctx->bufferPos = bufferPos; 1054 wctx->bufferPos = bufferPos;
1053 1055
1056 return 0;
1054} 1057}
1055 1058
1056static void wp512_final(struct crypto_tfm *tfm, u8 *out) 1059static int wp512_final(struct shash_desc *desc, u8 *out)
1057{ 1060{
1058 struct wp512_ctx *wctx = crypto_tfm_ctx(tfm); 1061 struct wp512_ctx *wctx = shash_desc_ctx(desc);
1059 int i; 1062 int i;
1060 u8 *buffer = wctx->buffer; 1063 u8 *buffer = wctx->buffer;
1061 u8 *bitLength = wctx->bitLength; 1064 u8 *bitLength = wctx->bitLength;
@@ -1084,89 +1087,95 @@ static void wp512_final(struct crypto_tfm *tfm, u8 *out)
1084 digest[i] = cpu_to_be64(wctx->hash[i]); 1087 digest[i] = cpu_to_be64(wctx->hash[i]);
1085 wctx->bufferBits = bufferBits; 1088 wctx->bufferBits = bufferBits;
1086 wctx->bufferPos = bufferPos; 1089 wctx->bufferPos = bufferPos;
1090
1091 return 0;
1087} 1092}
1088 1093
1089static void wp384_final(struct crypto_tfm *tfm, u8 *out) 1094static int wp384_final(struct shash_desc *desc, u8 *out)
1090{ 1095{
1091 u8 D[64]; 1096 u8 D[64];
1092 1097
1093 wp512_final(tfm, D); 1098 wp512_final(desc, D);
1094 memcpy (out, D, WP384_DIGEST_SIZE); 1099 memcpy (out, D, WP384_DIGEST_SIZE);
1095 memset (D, 0, WP512_DIGEST_SIZE); 1100 memset (D, 0, WP512_DIGEST_SIZE);
1101
1102 return 0;
1096} 1103}
1097 1104
1098static void wp256_final(struct crypto_tfm *tfm, u8 *out) 1105static int wp256_final(struct shash_desc *desc, u8 *out)
1099{ 1106{
1100 u8 D[64]; 1107 u8 D[64];
1101 1108
1102 wp512_final(tfm, D); 1109 wp512_final(desc, D);
1103 memcpy (out, D, WP256_DIGEST_SIZE); 1110 memcpy (out, D, WP256_DIGEST_SIZE);
1104 memset (D, 0, WP512_DIGEST_SIZE); 1111 memset (D, 0, WP512_DIGEST_SIZE);
1112
1113 return 0;
1105} 1114}
1106 1115
1107static struct crypto_alg wp512 = { 1116static struct shash_alg wp512 = {
1108 .cra_name = "wp512", 1117 .digestsize = WP512_DIGEST_SIZE,
1109 .cra_flags = CRYPTO_ALG_TYPE_DIGEST, 1118 .init = wp512_init,
1110 .cra_blocksize = WP512_BLOCK_SIZE, 1119 .update = wp512_update,
1111 .cra_ctxsize = sizeof(struct wp512_ctx), 1120 .final = wp512_final,
1112 .cra_module = THIS_MODULE, 1121 .descsize = sizeof(struct wp512_ctx),
1113 .cra_list = LIST_HEAD_INIT(wp512.cra_list), 1122 .base = {
1114 .cra_u = { .digest = { 1123 .cra_name = "wp512",
1115 .dia_digestsize = WP512_DIGEST_SIZE, 1124 .cra_flags = CRYPTO_ALG_TYPE_SHASH,
1116 .dia_init = wp512_init, 1125 .cra_blocksize = WP512_BLOCK_SIZE,
1117 .dia_update = wp512_update, 1126 .cra_module = THIS_MODULE,
1118 .dia_final = wp512_final } } 1127 }
1119}; 1128};
1120 1129
1121static struct crypto_alg wp384 = { 1130static struct shash_alg wp384 = {
1122 .cra_name = "wp384", 1131 .digestsize = WP384_DIGEST_SIZE,
1123 .cra_flags = CRYPTO_ALG_TYPE_DIGEST, 1132 .init = wp512_init,
1124 .cra_blocksize = WP512_BLOCK_SIZE, 1133 .update = wp512_update,
1125 .cra_ctxsize = sizeof(struct wp512_ctx), 1134 .final = wp384_final,
1126 .cra_module = THIS_MODULE, 1135 .descsize = sizeof(struct wp512_ctx),
1127 .cra_list = LIST_HEAD_INIT(wp384.cra_list), 1136 .base = {
1128 .cra_u = { .digest = { 1137 .cra_name = "wp384",
1129 .dia_digestsize = WP384_DIGEST_SIZE, 1138 .cra_flags = CRYPTO_ALG_TYPE_SHASH,
1130 .dia_init = wp512_init, 1139 .cra_blocksize = WP512_BLOCK_SIZE,
1131 .dia_update = wp512_update, 1140 .cra_module = THIS_MODULE,
1132 .dia_final = wp384_final } } 1141 }
1133}; 1142};
1134 1143
1135static struct crypto_alg wp256 = { 1144static struct shash_alg wp256 = {
1136 .cra_name = "wp256", 1145 .digestsize = WP256_DIGEST_SIZE,
1137 .cra_flags = CRYPTO_ALG_TYPE_DIGEST, 1146 .init = wp512_init,
1138 .cra_blocksize = WP512_BLOCK_SIZE, 1147 .update = wp512_update,
1139 .cra_ctxsize = sizeof(struct wp512_ctx), 1148 .final = wp256_final,
1140 .cra_module = THIS_MODULE, 1149 .descsize = sizeof(struct wp512_ctx),
1141 .cra_list = LIST_HEAD_INIT(wp256.cra_list), 1150 .base = {
1142 .cra_u = { .digest = { 1151 .cra_name = "wp256",
1143 .dia_digestsize = WP256_DIGEST_SIZE, 1152 .cra_flags = CRYPTO_ALG_TYPE_SHASH,
1144 .dia_init = wp512_init, 1153 .cra_blocksize = WP512_BLOCK_SIZE,
1145 .dia_update = wp512_update, 1154 .cra_module = THIS_MODULE,
1146 .dia_final = wp256_final } } 1155 }
1147}; 1156};
1148 1157
1149static int __init wp512_mod_init(void) 1158static int __init wp512_mod_init(void)
1150{ 1159{
1151 int ret = 0; 1160 int ret = 0;
1152 1161
1153 ret = crypto_register_alg(&wp512); 1162 ret = crypto_register_shash(&wp512);
1154 1163
1155 if (ret < 0) 1164 if (ret < 0)
1156 goto out; 1165 goto out;
1157 1166
1158 ret = crypto_register_alg(&wp384); 1167 ret = crypto_register_shash(&wp384);
1159 if (ret < 0) 1168 if (ret < 0)
1160 { 1169 {
1161 crypto_unregister_alg(&wp512); 1170 crypto_unregister_shash(&wp512);
1162 goto out; 1171 goto out;
1163 } 1172 }
1164 1173
1165 ret = crypto_register_alg(&wp256); 1174 ret = crypto_register_shash(&wp256);
1166 if (ret < 0) 1175 if (ret < 0)
1167 { 1176 {
1168 crypto_unregister_alg(&wp512); 1177 crypto_unregister_shash(&wp512);
1169 crypto_unregister_alg(&wp384); 1178 crypto_unregister_shash(&wp384);
1170 } 1179 }
1171out: 1180out:
1172 return ret; 1181 return ret;
@@ -1174,9 +1183,9 @@ out:
1174 1183
1175static void __exit wp512_mod_fini(void) 1184static void __exit wp512_mod_fini(void)
1176{ 1185{
1177 crypto_unregister_alg(&wp512); 1186 crypto_unregister_shash(&wp512);
1178 crypto_unregister_alg(&wp384); 1187 crypto_unregister_shash(&wp384);
1179 crypto_unregister_alg(&wp256); 1188 crypto_unregister_shash(&wp256);
1180} 1189}
1181 1190
1182MODULE_ALIAS("wp384"); 1191MODULE_ALIAS("wp384");
diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c
index 4d22b21bd3e3..0c79fe7f1567 100644
--- a/drivers/crypto/hifn_795x.c
+++ b/drivers/crypto/hifn_795x.c
@@ -38,9 +38,6 @@
38 38
39#include <asm/kmap_types.h> 39#include <asm/kmap_types.h>
40 40
41#undef dprintk
42
43#define HIFN_TEST
44//#define HIFN_DEBUG 41//#define HIFN_DEBUG
45 42
46#ifdef HIFN_DEBUG 43#ifdef HIFN_DEBUG
@@ -363,14 +360,14 @@ static atomic_t hifn_dev_number;
363#define HIFN_NAMESIZE 32 360#define HIFN_NAMESIZE 32
364#define HIFN_MAX_RESULT_ORDER 5 361#define HIFN_MAX_RESULT_ORDER 5
365 362
366#define HIFN_D_CMD_RSIZE 24*4 363#define HIFN_D_CMD_RSIZE 24*1
367#define HIFN_D_SRC_RSIZE 80*4 364#define HIFN_D_SRC_RSIZE 80*1
368#define HIFN_D_DST_RSIZE 80*4 365#define HIFN_D_DST_RSIZE 80*1
369#define HIFN_D_RES_RSIZE 24*4 366#define HIFN_D_RES_RSIZE 24*1
370 367
371#define HIFN_D_DST_DALIGN 4 368#define HIFN_D_DST_DALIGN 4
372 369
373#define HIFN_QUEUE_LENGTH HIFN_D_CMD_RSIZE-1 370#define HIFN_QUEUE_LENGTH (HIFN_D_CMD_RSIZE - 1)
374 371
375#define AES_MIN_KEY_SIZE 16 372#define AES_MIN_KEY_SIZE 16
376#define AES_MAX_KEY_SIZE 32 373#define AES_MAX_KEY_SIZE 32
@@ -406,8 +403,6 @@ struct hifn_dma {
406 u8 command_bufs[HIFN_D_CMD_RSIZE][HIFN_MAX_COMMAND]; 403 u8 command_bufs[HIFN_D_CMD_RSIZE][HIFN_MAX_COMMAND];
407 u8 result_bufs[HIFN_D_CMD_RSIZE][HIFN_MAX_RESULT]; 404 u8 result_bufs[HIFN_D_CMD_RSIZE][HIFN_MAX_RESULT];
408 405
409 u64 test_src, test_dst;
410
411 /* 406 /*
412 * Our current positions for insertion and removal from the descriptor 407 * Our current positions for insertion and removal from the descriptor
413 * rings. 408 * rings.
@@ -434,9 +429,6 @@ struct hifn_device
434 struct pci_dev *pdev; 429 struct pci_dev *pdev;
435 void __iomem *bar[3]; 430 void __iomem *bar[3];
436 431
437 unsigned long result_mem;
438 dma_addr_t dst;
439
440 void *desc_virt; 432 void *desc_virt;
441 dma_addr_t desc_dma; 433 dma_addr_t desc_dma;
442 434
@@ -446,8 +438,6 @@ struct hifn_device
446 438
447 spinlock_t lock; 439 spinlock_t lock;
448 440
449 void *priv;
450
451 u32 flags; 441 u32 flags;
452 int active, started; 442 int active, started;
453 struct delayed_work work; 443 struct delayed_work work;
@@ -657,12 +647,17 @@ struct ablkcipher_walk
657 647
658struct hifn_context 648struct hifn_context
659{ 649{
660 u8 key[HIFN_MAX_CRYPT_KEY_LENGTH], *iv; 650 u8 key[HIFN_MAX_CRYPT_KEY_LENGTH];
661 struct hifn_device *dev; 651 struct hifn_device *dev;
662 unsigned int keysize, ivsize; 652 unsigned int keysize;
653};
654
655struct hifn_request_context
656{
657 u8 *iv;
658 unsigned int ivsize;
663 u8 op, type, mode, unused; 659 u8 op, type, mode, unused;
664 struct ablkcipher_walk walk; 660 struct ablkcipher_walk walk;
665 atomic_t sg_num;
666}; 661};
667 662
668#define crypto_alg_to_hifn(a) container_of(a, struct hifn_crypto_alg, alg) 663#define crypto_alg_to_hifn(a) container_of(a, struct hifn_crypto_alg, alg)
@@ -1168,7 +1163,8 @@ static int hifn_setup_crypto_command(struct hifn_device *dev,
1168} 1163}
1169 1164
1170static int hifn_setup_cmd_desc(struct hifn_device *dev, 1165static int hifn_setup_cmd_desc(struct hifn_device *dev,
1171 struct hifn_context *ctx, void *priv, unsigned int nbytes) 1166 struct hifn_context *ctx, struct hifn_request_context *rctx,
1167 void *priv, unsigned int nbytes)
1172{ 1168{
1173 struct hifn_dma *dma = (struct hifn_dma *)dev->desc_virt; 1169 struct hifn_dma *dma = (struct hifn_dma *)dev->desc_virt;
1174 int cmd_len, sa_idx; 1170 int cmd_len, sa_idx;
@@ -1179,7 +1175,7 @@ static int hifn_setup_cmd_desc(struct hifn_device *dev,
1179 buf_pos = buf = dma->command_bufs[dma->cmdi]; 1175 buf_pos = buf = dma->command_bufs[dma->cmdi];
1180 1176
1181 mask = 0; 1177 mask = 0;
1182 switch (ctx->op) { 1178 switch (rctx->op) {
1183 case ACRYPTO_OP_DECRYPT: 1179 case ACRYPTO_OP_DECRYPT:
1184 mask = HIFN_BASE_CMD_CRYPT | HIFN_BASE_CMD_DECODE; 1180 mask = HIFN_BASE_CMD_CRYPT | HIFN_BASE_CMD_DECODE;
1185 break; 1181 break;
@@ -1196,15 +1192,15 @@ static int hifn_setup_cmd_desc(struct hifn_device *dev,
1196 buf_pos += hifn_setup_base_command(dev, buf_pos, nbytes, 1192 buf_pos += hifn_setup_base_command(dev, buf_pos, nbytes,
1197 nbytes, mask, dev->snum); 1193 nbytes, mask, dev->snum);
1198 1194
1199 if (ctx->op == ACRYPTO_OP_ENCRYPT || ctx->op == ACRYPTO_OP_DECRYPT) { 1195 if (rctx->op == ACRYPTO_OP_ENCRYPT || rctx->op == ACRYPTO_OP_DECRYPT) {
1200 u16 md = 0; 1196 u16 md = 0;
1201 1197
1202 if (ctx->keysize) 1198 if (ctx->keysize)
1203 md |= HIFN_CRYPT_CMD_NEW_KEY; 1199 md |= HIFN_CRYPT_CMD_NEW_KEY;
1204 if (ctx->iv && ctx->mode != ACRYPTO_MODE_ECB) 1200 if (rctx->iv && rctx->mode != ACRYPTO_MODE_ECB)
1205 md |= HIFN_CRYPT_CMD_NEW_IV; 1201 md |= HIFN_CRYPT_CMD_NEW_IV;
1206 1202
1207 switch (ctx->mode) { 1203 switch (rctx->mode) {
1208 case ACRYPTO_MODE_ECB: 1204 case ACRYPTO_MODE_ECB:
1209 md |= HIFN_CRYPT_CMD_MODE_ECB; 1205 md |= HIFN_CRYPT_CMD_MODE_ECB;
1210 break; 1206 break;
@@ -1221,7 +1217,7 @@ static int hifn_setup_cmd_desc(struct hifn_device *dev,
1221 goto err_out; 1217 goto err_out;
1222 } 1218 }
1223 1219
1224 switch (ctx->type) { 1220 switch (rctx->type) {
1225 case ACRYPTO_TYPE_AES_128: 1221 case ACRYPTO_TYPE_AES_128:
1226 if (ctx->keysize != 16) 1222 if (ctx->keysize != 16)
1227 goto err_out; 1223 goto err_out;
@@ -1256,17 +1252,18 @@ static int hifn_setup_cmd_desc(struct hifn_device *dev,
1256 1252
1257 buf_pos += hifn_setup_crypto_command(dev, buf_pos, 1253 buf_pos += hifn_setup_crypto_command(dev, buf_pos,
1258 nbytes, nbytes, ctx->key, ctx->keysize, 1254 nbytes, nbytes, ctx->key, ctx->keysize,
1259 ctx->iv, ctx->ivsize, md); 1255 rctx->iv, rctx->ivsize, md);
1260 } 1256 }
1261 1257
1262 dev->sa[sa_idx] = priv; 1258 dev->sa[sa_idx] = priv;
1259 dev->started++;
1263 1260
1264 cmd_len = buf_pos - buf; 1261 cmd_len = buf_pos - buf;
1265 dma->cmdr[dma->cmdi].l = __cpu_to_le32(cmd_len | HIFN_D_VALID | 1262 dma->cmdr[dma->cmdi].l = __cpu_to_le32(cmd_len | HIFN_D_VALID |
1266 HIFN_D_LAST | HIFN_D_MASKDONEIRQ); 1263 HIFN_D_LAST | HIFN_D_MASKDONEIRQ);
1267 1264
1268 if (++dma->cmdi == HIFN_D_CMD_RSIZE) { 1265 if (++dma->cmdi == HIFN_D_CMD_RSIZE) {
1269 dma->cmdr[dma->cmdi].l = __cpu_to_le32(HIFN_MAX_COMMAND | 1266 dma->cmdr[dma->cmdi].l = __cpu_to_le32(
1270 HIFN_D_VALID | HIFN_D_LAST | 1267 HIFN_D_VALID | HIFN_D_LAST |
1271 HIFN_D_MASKDONEIRQ | HIFN_D_JUMP); 1268 HIFN_D_MASKDONEIRQ | HIFN_D_JUMP);
1272 dma->cmdi = 0; 1269 dma->cmdi = 0;
@@ -1284,7 +1281,7 @@ err_out:
1284} 1281}
1285 1282
1286static int hifn_setup_src_desc(struct hifn_device *dev, struct page *page, 1283static int hifn_setup_src_desc(struct hifn_device *dev, struct page *page,
1287 unsigned int offset, unsigned int size) 1284 unsigned int offset, unsigned int size, int last)
1288{ 1285{
1289 struct hifn_dma *dma = (struct hifn_dma *)dev->desc_virt; 1286 struct hifn_dma *dma = (struct hifn_dma *)dev->desc_virt;
1290 int idx; 1287 int idx;
@@ -1296,12 +1293,12 @@ static int hifn_setup_src_desc(struct hifn_device *dev, struct page *page,
1296 1293
1297 dma->srcr[idx].p = __cpu_to_le32(addr); 1294 dma->srcr[idx].p = __cpu_to_le32(addr);
1298 dma->srcr[idx].l = __cpu_to_le32(size | HIFN_D_VALID | 1295 dma->srcr[idx].l = __cpu_to_le32(size | HIFN_D_VALID |
1299 HIFN_D_MASKDONEIRQ | HIFN_D_LAST); 1296 HIFN_D_MASKDONEIRQ | (last ? HIFN_D_LAST : 0));
1300 1297
1301 if (++idx == HIFN_D_SRC_RSIZE) { 1298 if (++idx == HIFN_D_SRC_RSIZE) {
1302 dma->srcr[idx].l = __cpu_to_le32(HIFN_D_VALID | 1299 dma->srcr[idx].l = __cpu_to_le32(HIFN_D_VALID |
1303 HIFN_D_JUMP | 1300 HIFN_D_JUMP | HIFN_D_MASKDONEIRQ |
1304 HIFN_D_MASKDONEIRQ | HIFN_D_LAST); 1301 (last ? HIFN_D_LAST : 0));
1305 idx = 0; 1302 idx = 0;
1306 } 1303 }
1307 1304
@@ -1342,7 +1339,7 @@ static void hifn_setup_res_desc(struct hifn_device *dev)
1342} 1339}
1343 1340
1344static void hifn_setup_dst_desc(struct hifn_device *dev, struct page *page, 1341static void hifn_setup_dst_desc(struct hifn_device *dev, struct page *page,
1345 unsigned offset, unsigned size) 1342 unsigned offset, unsigned size, int last)
1346{ 1343{
1347 struct hifn_dma *dma = (struct hifn_dma *)dev->desc_virt; 1344 struct hifn_dma *dma = (struct hifn_dma *)dev->desc_virt;
1348 int idx; 1345 int idx;
@@ -1353,12 +1350,12 @@ static void hifn_setup_dst_desc(struct hifn_device *dev, struct page *page,
1353 idx = dma->dsti; 1350 idx = dma->dsti;
1354 dma->dstr[idx].p = __cpu_to_le32(addr); 1351 dma->dstr[idx].p = __cpu_to_le32(addr);
1355 dma->dstr[idx].l = __cpu_to_le32(size | HIFN_D_VALID | 1352 dma->dstr[idx].l = __cpu_to_le32(size | HIFN_D_VALID |
1356 HIFN_D_MASKDONEIRQ | HIFN_D_LAST); 1353 HIFN_D_MASKDONEIRQ | (last ? HIFN_D_LAST : 0));
1357 1354
1358 if (++idx == HIFN_D_DST_RSIZE) { 1355 if (++idx == HIFN_D_DST_RSIZE) {
1359 dma->dstr[idx].l = __cpu_to_le32(HIFN_D_VALID | 1356 dma->dstr[idx].l = __cpu_to_le32(HIFN_D_VALID |
1360 HIFN_D_JUMP | HIFN_D_MASKDONEIRQ | 1357 HIFN_D_JUMP | HIFN_D_MASKDONEIRQ |
1361 HIFN_D_LAST); 1358 (last ? HIFN_D_LAST : 0));
1362 idx = 0; 1359 idx = 0;
1363 } 1360 }
1364 dma->dsti = idx; 1361 dma->dsti = idx;
@@ -1370,16 +1367,52 @@ static void hifn_setup_dst_desc(struct hifn_device *dev, struct page *page,
1370 } 1367 }
1371} 1368}
1372 1369
1373static int hifn_setup_dma(struct hifn_device *dev, struct page *spage, unsigned int soff, 1370static int hifn_setup_dma(struct hifn_device *dev,
1374 struct page *dpage, unsigned int doff, unsigned int nbytes, void *priv, 1371 struct hifn_context *ctx, struct hifn_request_context *rctx,
1375 struct hifn_context *ctx) 1372 struct scatterlist *src, struct scatterlist *dst,
1373 unsigned int nbytes, void *priv)
1376{ 1374{
1377 dprintk("%s: spage: %p, soffset: %u, dpage: %p, doffset: %u, nbytes: %u, priv: %p, ctx: %p.\n", 1375 struct scatterlist *t;
1378 dev->name, spage, soff, dpage, doff, nbytes, priv, ctx); 1376 struct page *spage, *dpage;
1377 unsigned int soff, doff;
1378 unsigned int n, len;
1379 1379
1380 hifn_setup_src_desc(dev, spage, soff, nbytes); 1380 n = nbytes;
1381 hifn_setup_cmd_desc(dev, ctx, priv, nbytes); 1381 while (n) {
1382 hifn_setup_dst_desc(dev, dpage, doff, nbytes); 1382 spage = sg_page(src);
1383 soff = src->offset;
1384 len = min(src->length, n);
1385
1386 hifn_setup_src_desc(dev, spage, soff, len, n - len == 0);
1387
1388 src++;
1389 n -= len;
1390 }
1391
1392 t = &rctx->walk.cache[0];
1393 n = nbytes;
1394 while (n) {
1395 if (t->length && rctx->walk.flags & ASYNC_FLAGS_MISALIGNED) {
1396 BUG_ON(!sg_page(t));
1397 dpage = sg_page(t);
1398 doff = 0;
1399 len = t->length;
1400 } else {
1401 BUG_ON(!sg_page(dst));
1402 dpage = sg_page(dst);
1403 doff = dst->offset;
1404 len = dst->length;
1405 }
1406 len = min(len, n);
1407
1408 hifn_setup_dst_desc(dev, dpage, doff, len, n - len == 0);
1409
1410 dst++;
1411 t++;
1412 n -= len;
1413 }
1414
1415 hifn_setup_cmd_desc(dev, ctx, rctx, priv, nbytes);
1383 hifn_setup_res_desc(dev); 1416 hifn_setup_res_desc(dev);
1384 return 0; 1417 return 0;
1385} 1418}
@@ -1424,32 +1457,26 @@ static void ablkcipher_walk_exit(struct ablkcipher_walk *w)
1424 w->num = 0; 1457 w->num = 0;
1425} 1458}
1426 1459
1427static int ablkcipher_add(void *daddr, unsigned int *drestp, struct scatterlist *src, 1460static int ablkcipher_add(unsigned int *drestp, struct scatterlist *dst,
1428 unsigned int size, unsigned int *nbytesp) 1461 unsigned int size, unsigned int *nbytesp)
1429{ 1462{
1430 unsigned int copy, drest = *drestp, nbytes = *nbytesp; 1463 unsigned int copy, drest = *drestp, nbytes = *nbytesp;
1431 int idx = 0; 1464 int idx = 0;
1432 void *saddr;
1433 1465
1434 if (drest < size || size > nbytes) 1466 if (drest < size || size > nbytes)
1435 return -EINVAL; 1467 return -EINVAL;
1436 1468
1437 while (size) { 1469 while (size) {
1438 copy = min(drest, min(size, src->length)); 1470 copy = min(drest, min(size, dst->length));
1439
1440 saddr = kmap_atomic(sg_page(src), KM_SOFTIRQ1);
1441 memcpy(daddr, saddr + src->offset, copy);
1442 kunmap_atomic(saddr, KM_SOFTIRQ1);
1443 1471
1444 size -= copy; 1472 size -= copy;
1445 drest -= copy; 1473 drest -= copy;
1446 nbytes -= copy; 1474 nbytes -= copy;
1447 daddr += copy;
1448 1475
1449 dprintk("%s: copy: %u, size: %u, drest: %u, nbytes: %u.\n", 1476 dprintk("%s: copy: %u, size: %u, drest: %u, nbytes: %u.\n",
1450 __func__, copy, size, drest, nbytes); 1477 __func__, copy, size, drest, nbytes);
1451 1478
1452 src++; 1479 dst++;
1453 idx++; 1480 idx++;
1454 } 1481 }
1455 1482
@@ -1462,8 +1489,7 @@ static int ablkcipher_add(void *daddr, unsigned int *drestp, struct scatterlist
1462static int ablkcipher_walk(struct ablkcipher_request *req, 1489static int ablkcipher_walk(struct ablkcipher_request *req,
1463 struct ablkcipher_walk *w) 1490 struct ablkcipher_walk *w)
1464{ 1491{
1465 struct scatterlist *src, *dst, *t; 1492 struct scatterlist *dst, *t;
1466 void *daddr;
1467 unsigned int nbytes = req->nbytes, offset, copy, diff; 1493 unsigned int nbytes = req->nbytes, offset, copy, diff;
1468 int idx, tidx, err; 1494 int idx, tidx, err;
1469 1495
@@ -1473,26 +1499,22 @@ static int ablkcipher_walk(struct ablkcipher_request *req,
1473 if (idx >= w->num && (w->flags & ASYNC_FLAGS_MISALIGNED)) 1499 if (idx >= w->num && (w->flags & ASYNC_FLAGS_MISALIGNED))
1474 return -EINVAL; 1500 return -EINVAL;
1475 1501
1476 src = &req->src[idx];
1477 dst = &req->dst[idx]; 1502 dst = &req->dst[idx];
1478 1503
1479 dprintk("\n%s: slen: %u, dlen: %u, soff: %u, doff: %u, offset: %u, " 1504 dprintk("\n%s: dlen: %u, doff: %u, offset: %u, nbytes: %u.\n",
1480 "nbytes: %u.\n", 1505 __func__, dst->length, dst->offset, offset, nbytes);
1481 __func__, src->length, dst->length, src->offset,
1482 dst->offset, offset, nbytes);
1483 1506
1484 if (!IS_ALIGNED(dst->offset, HIFN_D_DST_DALIGN) || 1507 if (!IS_ALIGNED(dst->offset, HIFN_D_DST_DALIGN) ||
1485 !IS_ALIGNED(dst->length, HIFN_D_DST_DALIGN) || 1508 !IS_ALIGNED(dst->length, HIFN_D_DST_DALIGN) ||
1486 offset) { 1509 offset) {
1487 unsigned slen = min(src->length - offset, nbytes); 1510 unsigned slen = min(dst->length - offset, nbytes);
1488 unsigned dlen = PAGE_SIZE; 1511 unsigned dlen = PAGE_SIZE;
1489 1512
1490 t = &w->cache[idx]; 1513 t = &w->cache[idx];
1491 1514
1492 daddr = kmap_atomic(sg_page(t), KM_SOFTIRQ0); 1515 err = ablkcipher_add(&dlen, dst, slen, &nbytes);
1493 err = ablkcipher_add(daddr, &dlen, src, slen, &nbytes);
1494 if (err < 0) 1516 if (err < 0)
1495 goto err_out_unmap; 1517 return err;
1496 1518
1497 idx += err; 1519 idx += err;
1498 1520
@@ -1528,21 +1550,19 @@ static int ablkcipher_walk(struct ablkcipher_request *req,
1528 } else { 1550 } else {
1529 copy += diff + nbytes; 1551 copy += diff + nbytes;
1530 1552
1531 src = &req->src[idx]; 1553 dst = &req->dst[idx];
1532 1554
1533 err = ablkcipher_add(daddr + slen, &dlen, src, nbytes, &nbytes); 1555 err = ablkcipher_add(&dlen, dst, nbytes, &nbytes);
1534 if (err < 0) 1556 if (err < 0)
1535 goto err_out_unmap; 1557 return err;
1536 1558
1537 idx += err; 1559 idx += err;
1538 } 1560 }
1539 1561
1540 t->length = copy; 1562 t->length = copy;
1541 t->offset = offset; 1563 t->offset = offset;
1542
1543 kunmap_atomic(daddr, KM_SOFTIRQ0);
1544 } else { 1564 } else {
1545 nbytes -= min(src->length, nbytes); 1565 nbytes -= min(dst->length, nbytes);
1546 idx++; 1566 idx++;
1547 } 1567 }
1548 1568
@@ -1550,26 +1570,22 @@ static int ablkcipher_walk(struct ablkcipher_request *req,
1550 } 1570 }
1551 1571
1552 return tidx; 1572 return tidx;
1553
1554err_out_unmap:
1555 kunmap_atomic(daddr, KM_SOFTIRQ0);
1556 return err;
1557} 1573}
1558 1574
1559static int hifn_setup_session(struct ablkcipher_request *req) 1575static int hifn_setup_session(struct ablkcipher_request *req)
1560{ 1576{
1561 struct hifn_context *ctx = crypto_tfm_ctx(req->base.tfm); 1577 struct hifn_context *ctx = crypto_tfm_ctx(req->base.tfm);
1578 struct hifn_request_context *rctx = ablkcipher_request_ctx(req);
1562 struct hifn_device *dev = ctx->dev; 1579 struct hifn_device *dev = ctx->dev;
1563 struct page *spage, *dpage; 1580 unsigned long dlen, flags;
1564 unsigned long soff, doff, dlen, flags; 1581 unsigned int nbytes = req->nbytes, idx = 0;
1565 unsigned int nbytes = req->nbytes, idx = 0, len;
1566 int err = -EINVAL, sg_num; 1582 int err = -EINVAL, sg_num;
1567 struct scatterlist *src, *dst, *t; 1583 struct scatterlist *dst;
1568 1584
1569 if (ctx->iv && !ctx->ivsize && ctx->mode != ACRYPTO_MODE_ECB) 1585 if (rctx->iv && !rctx->ivsize && rctx->mode != ACRYPTO_MODE_ECB)
1570 goto err_out_exit; 1586 goto err_out_exit;
1571 1587
1572 ctx->walk.flags = 0; 1588 rctx->walk.flags = 0;
1573 1589
1574 while (nbytes) { 1590 while (nbytes) {
1575 dst = &req->dst[idx]; 1591 dst = &req->dst[idx];
@@ -1577,27 +1593,23 @@ static int hifn_setup_session(struct ablkcipher_request *req)
1577 1593
1578 if (!IS_ALIGNED(dst->offset, HIFN_D_DST_DALIGN) || 1594 if (!IS_ALIGNED(dst->offset, HIFN_D_DST_DALIGN) ||
1579 !IS_ALIGNED(dlen, HIFN_D_DST_DALIGN)) 1595 !IS_ALIGNED(dlen, HIFN_D_DST_DALIGN))
1580 ctx->walk.flags |= ASYNC_FLAGS_MISALIGNED; 1596 rctx->walk.flags |= ASYNC_FLAGS_MISALIGNED;
1581 1597
1582 nbytes -= dlen; 1598 nbytes -= dlen;
1583 idx++; 1599 idx++;
1584 } 1600 }
1585 1601
1586 if (ctx->walk.flags & ASYNC_FLAGS_MISALIGNED) { 1602 if (rctx->walk.flags & ASYNC_FLAGS_MISALIGNED) {
1587 err = ablkcipher_walk_init(&ctx->walk, idx, GFP_ATOMIC); 1603 err = ablkcipher_walk_init(&rctx->walk, idx, GFP_ATOMIC);
1588 if (err < 0) 1604 if (err < 0)
1589 return err; 1605 return err;
1590 } 1606 }
1591 1607
1592 nbytes = req->nbytes; 1608 sg_num = ablkcipher_walk(req, &rctx->walk);
1593 idx = 0;
1594
1595 sg_num = ablkcipher_walk(req, &ctx->walk);
1596 if (sg_num < 0) { 1609 if (sg_num < 0) {
1597 err = sg_num; 1610 err = sg_num;
1598 goto err_out_exit; 1611 goto err_out_exit;
1599 } 1612 }
1600 atomic_set(&ctx->sg_num, sg_num);
1601 1613
1602 spin_lock_irqsave(&dev->lock, flags); 1614 spin_lock_irqsave(&dev->lock, flags);
1603 if (dev->started + sg_num > HIFN_QUEUE_LENGTH) { 1615 if (dev->started + sg_num > HIFN_QUEUE_LENGTH) {
@@ -1605,37 +1617,11 @@ static int hifn_setup_session(struct ablkcipher_request *req)
1605 goto err_out; 1617 goto err_out;
1606 } 1618 }
1607 1619
1608 dev->snum++; 1620 err = hifn_setup_dma(dev, ctx, rctx, req->src, req->dst, req->nbytes, req);
1609 dev->started += sg_num; 1621 if (err)
1610 1622 goto err_out;
1611 while (nbytes) {
1612 src = &req->src[idx];
1613 dst = &req->dst[idx];
1614 t = &ctx->walk.cache[idx];
1615
1616 if (t->length) {
1617 spage = dpage = sg_page(t);
1618 soff = doff = 0;
1619 len = t->length;
1620 } else {
1621 spage = sg_page(src);
1622 soff = src->offset;
1623
1624 dpage = sg_page(dst);
1625 doff = dst->offset;
1626
1627 len = dst->length;
1628 }
1629
1630 idx++;
1631
1632 err = hifn_setup_dma(dev, spage, soff, dpage, doff, nbytes,
1633 req, ctx);
1634 if (err)
1635 goto err_out;
1636 1623
1637 nbytes -= min(len, nbytes); 1624 dev->snum++;
1638 }
1639 1625
1640 dev->active = HIFN_DEFAULT_ACTIVE_NUM; 1626 dev->active = HIFN_DEFAULT_ACTIVE_NUM;
1641 spin_unlock_irqrestore(&dev->lock, flags); 1627 spin_unlock_irqrestore(&dev->lock, flags);
@@ -1645,12 +1631,13 @@ static int hifn_setup_session(struct ablkcipher_request *req)
1645err_out: 1631err_out:
1646 spin_unlock_irqrestore(&dev->lock, flags); 1632 spin_unlock_irqrestore(&dev->lock, flags);
1647err_out_exit: 1633err_out_exit:
1648 if (err) 1634 if (err) {
1649 dprintk("%s: iv: %p [%d], key: %p [%d], mode: %u, op: %u, " 1635 printk("%s: iv: %p [%d], key: %p [%d], mode: %u, op: %u, "
1650 "type: %u, err: %d.\n", 1636 "type: %u, err: %d.\n",
1651 dev->name, ctx->iv, ctx->ivsize, 1637 dev->name, rctx->iv, rctx->ivsize,
1652 ctx->key, ctx->keysize, 1638 ctx->key, ctx->keysize,
1653 ctx->mode, ctx->op, ctx->type, err); 1639 rctx->mode, rctx->op, rctx->type, err);
1640 }
1654 1641
1655 return err; 1642 return err;
1656} 1643}
@@ -1660,31 +1647,33 @@ static int hifn_test(struct hifn_device *dev, int encdec, u8 snum)
1660 int n, err; 1647 int n, err;
1661 u8 src[16]; 1648 u8 src[16];
1662 struct hifn_context ctx; 1649 struct hifn_context ctx;
1650 struct hifn_request_context rctx;
1663 u8 fips_aes_ecb_from_zero[16] = { 1651 u8 fips_aes_ecb_from_zero[16] = {
1664 0x66, 0xE9, 0x4B, 0xD4, 1652 0x66, 0xE9, 0x4B, 0xD4,
1665 0xEF, 0x8A, 0x2C, 0x3B, 1653 0xEF, 0x8A, 0x2C, 0x3B,
1666 0x88, 0x4C, 0xFA, 0x59, 1654 0x88, 0x4C, 0xFA, 0x59,
1667 0xCA, 0x34, 0x2B, 0x2E}; 1655 0xCA, 0x34, 0x2B, 0x2E};
1656 struct scatterlist sg;
1668 1657
1669 memset(src, 0, sizeof(src)); 1658 memset(src, 0, sizeof(src));
1670 memset(ctx.key, 0, sizeof(ctx.key)); 1659 memset(ctx.key, 0, sizeof(ctx.key));
1671 1660
1672 ctx.dev = dev; 1661 ctx.dev = dev;
1673 ctx.keysize = 16; 1662 ctx.keysize = 16;
1674 ctx.ivsize = 0; 1663 rctx.ivsize = 0;
1675 ctx.iv = NULL; 1664 rctx.iv = NULL;
1676 ctx.op = (encdec)?ACRYPTO_OP_ENCRYPT:ACRYPTO_OP_DECRYPT; 1665 rctx.op = (encdec)?ACRYPTO_OP_ENCRYPT:ACRYPTO_OP_DECRYPT;
1677 ctx.mode = ACRYPTO_MODE_ECB; 1666 rctx.mode = ACRYPTO_MODE_ECB;
1678 ctx.type = ACRYPTO_TYPE_AES_128; 1667 rctx.type = ACRYPTO_TYPE_AES_128;
1679 atomic_set(&ctx.sg_num, 1); 1668 rctx.walk.cache[0].length = 0;
1680 1669
1681 err = hifn_setup_dma(dev, 1670 sg_init_one(&sg, &src, sizeof(src));
1682 virt_to_page(src), offset_in_page(src), 1671
1683 virt_to_page(src), offset_in_page(src), 1672 err = hifn_setup_dma(dev, &ctx, &rctx, &sg, &sg, sizeof(src), NULL);
1684 sizeof(src), NULL, &ctx);
1685 if (err) 1673 if (err)
1686 goto err_out; 1674 goto err_out;
1687 1675
1676 dev->started = 0;
1688 msleep(200); 1677 msleep(200);
1689 1678
1690 dprintk("%s: decoded: ", dev->name); 1679 dprintk("%s: decoded: ", dev->name);
@@ -1711,6 +1700,7 @@ static int hifn_start_device(struct hifn_device *dev)
1711{ 1700{
1712 int err; 1701 int err;
1713 1702
1703 dev->started = dev->active = 0;
1714 hifn_reset_dma(dev, 1); 1704 hifn_reset_dma(dev, 1);
1715 1705
1716 err = hifn_enable_crypto(dev); 1706 err = hifn_enable_crypto(dev);
@@ -1764,90 +1754,65 @@ static int ablkcipher_get(void *saddr, unsigned int *srestp, unsigned int offset
1764 return idx; 1754 return idx;
1765} 1755}
1766 1756
1767static void hifn_process_ready(struct ablkcipher_request *req, int error) 1757static inline void hifn_complete_sa(struct hifn_device *dev, int i)
1768{ 1758{
1769 struct hifn_context *ctx = crypto_tfm_ctx(req->base.tfm); 1759 unsigned long flags;
1770 struct hifn_device *dev;
1771
1772 dprintk("%s: req: %p, ctx: %p.\n", __func__, req, ctx);
1773 1760
1774 dev = ctx->dev; 1761 spin_lock_irqsave(&dev->lock, flags);
1775 dprintk("%s: req: %p, started: %d, sg_num: %d.\n", 1762 dev->sa[i] = NULL;
1776 __func__, req, dev->started, atomic_read(&ctx->sg_num)); 1763 dev->started--;
1764 if (dev->started < 0)
1765 printk("%s: started: %d.\n", __func__, dev->started);
1766 spin_unlock_irqrestore(&dev->lock, flags);
1767 BUG_ON(dev->started < 0);
1768}
1777 1769
1778 if (--dev->started < 0) 1770static void hifn_process_ready(struct ablkcipher_request *req, int error)
1779 BUG(); 1771{
1772 struct hifn_request_context *rctx = ablkcipher_request_ctx(req);
1780 1773
1781 if (atomic_dec_and_test(&ctx->sg_num)) { 1774 if (rctx->walk.flags & ASYNC_FLAGS_MISALIGNED) {
1782 unsigned int nbytes = req->nbytes; 1775 unsigned int nbytes = req->nbytes;
1783 int idx = 0, err; 1776 int idx = 0, err;
1784 struct scatterlist *dst, *t; 1777 struct scatterlist *dst, *t;
1785 void *saddr; 1778 void *saddr;
1786 1779
1787 if (ctx->walk.flags & ASYNC_FLAGS_MISALIGNED) { 1780 while (nbytes) {
1788 while (nbytes) { 1781 t = &rctx->walk.cache[idx];
1789 t = &ctx->walk.cache[idx]; 1782 dst = &req->dst[idx];
1790 dst = &req->dst[idx];
1791
1792 dprintk("\n%s: sg_page(t): %p, t->length: %u, "
1793 "sg_page(dst): %p, dst->length: %u, "
1794 "nbytes: %u.\n",
1795 __func__, sg_page(t), t->length,
1796 sg_page(dst), dst->length, nbytes);
1797 1783
1798 if (!t->length) { 1784 dprintk("\n%s: sg_page(t): %p, t->length: %u, "
1799 nbytes -= min(dst->length, nbytes); 1785 "sg_page(dst): %p, dst->length: %u, "
1800 idx++; 1786 "nbytes: %u.\n",
1801 continue; 1787 __func__, sg_page(t), t->length,
1802 } 1788 sg_page(dst), dst->length, nbytes);
1803 1789
1804 saddr = kmap_atomic(sg_page(t), KM_IRQ1); 1790 if (!t->length) {
1791 nbytes -= min(dst->length, nbytes);
1792 idx++;
1793 continue;
1794 }
1805 1795
1806 err = ablkcipher_get(saddr, &t->length, t->offset, 1796 saddr = kmap_atomic(sg_page(t), KM_SOFTIRQ0);
1807 dst, nbytes, &nbytes);
1808 if (err < 0) {
1809 kunmap_atomic(saddr, KM_IRQ1);
1810 break;
1811 }
1812 1797
1813 idx += err; 1798 err = ablkcipher_get(saddr, &t->length, t->offset,
1814 kunmap_atomic(saddr, KM_IRQ1); 1799 dst, nbytes, &nbytes);
1800 if (err < 0) {
1801 kunmap_atomic(saddr, KM_SOFTIRQ0);
1802 break;
1815 } 1803 }
1816 1804
1817 ablkcipher_walk_exit(&ctx->walk); 1805 idx += err;
1806 kunmap_atomic(saddr, KM_SOFTIRQ0);
1818 } 1807 }
1819 1808
1820 req->base.complete(&req->base, error); 1809 ablkcipher_walk_exit(&rctx->walk);
1821 } 1810 }
1822}
1823 1811
1824static void hifn_check_for_completion(struct hifn_device *dev, int error) 1812 req->base.complete(&req->base, error);
1825{
1826 int i;
1827 struct hifn_dma *dma = (struct hifn_dma *)dev->desc_virt;
1828
1829 for (i=0; i<HIFN_D_RES_RSIZE; ++i) {
1830 struct hifn_desc *d = &dma->resr[i];
1831
1832 if (!(d->l & __cpu_to_le32(HIFN_D_VALID)) && dev->sa[i]) {
1833 dev->success++;
1834 dev->reset = 0;
1835 hifn_process_ready(dev->sa[i], error);
1836 dev->sa[i] = NULL;
1837 }
1838
1839 if (d->l & __cpu_to_le32(HIFN_D_DESTOVER | HIFN_D_OVER))
1840 if (printk_ratelimit())
1841 printk("%s: overflow detected [d: %u, o: %u] "
1842 "at %d resr: l: %08x, p: %08x.\n",
1843 dev->name,
1844 !!(d->l & __cpu_to_le32(HIFN_D_DESTOVER)),
1845 !!(d->l & __cpu_to_le32(HIFN_D_OVER)),
1846 i, d->l, d->p);
1847 }
1848} 1813}
1849 1814
1850static void hifn_clear_rings(struct hifn_device *dev) 1815static void hifn_clear_rings(struct hifn_device *dev, int error)
1851{ 1816{
1852 struct hifn_dma *dma = (struct hifn_dma *)dev->desc_virt; 1817 struct hifn_dma *dma = (struct hifn_dma *)dev->desc_virt;
1853 int i, u; 1818 int i, u;
@@ -1864,21 +1829,26 @@ static void hifn_clear_rings(struct hifn_device *dev)
1864 if (dma->resr[i].l & __cpu_to_le32(HIFN_D_VALID)) 1829 if (dma->resr[i].l & __cpu_to_le32(HIFN_D_VALID))
1865 break; 1830 break;
1866 1831
1867 if (i != HIFN_D_RES_RSIZE) 1832 if (dev->sa[i]) {
1868 u--; 1833 dev->success++;
1834 dev->reset = 0;
1835 hifn_process_ready(dev->sa[i], error);
1836 hifn_complete_sa(dev, i);
1837 }
1869 1838
1870 if (++i == (HIFN_D_RES_RSIZE + 1)) 1839 if (++i == HIFN_D_RES_RSIZE)
1871 i = 0; 1840 i = 0;
1841 u--;
1872 } 1842 }
1873 dma->resk = i; dma->resu = u; 1843 dma->resk = i; dma->resu = u;
1874 1844
1875 i = dma->srck; u = dma->srcu; 1845 i = dma->srck; u = dma->srcu;
1876 while (u != 0) { 1846 while (u != 0) {
1877 if (i == HIFN_D_SRC_RSIZE)
1878 i = 0;
1879 if (dma->srcr[i].l & __cpu_to_le32(HIFN_D_VALID)) 1847 if (dma->srcr[i].l & __cpu_to_le32(HIFN_D_VALID))
1880 break; 1848 break;
1881 i++, u--; 1849 if (++i == HIFN_D_SRC_RSIZE)
1850 i = 0;
1851 u--;
1882 } 1852 }
1883 dma->srck = i; dma->srcu = u; 1853 dma->srck = i; dma->srcu = u;
1884 1854
@@ -1886,20 +1856,19 @@ static void hifn_clear_rings(struct hifn_device *dev)
1886 while (u != 0) { 1856 while (u != 0) {
1887 if (dma->cmdr[i].l & __cpu_to_le32(HIFN_D_VALID)) 1857 if (dma->cmdr[i].l & __cpu_to_le32(HIFN_D_VALID))
1888 break; 1858 break;
1889 if (i != HIFN_D_CMD_RSIZE) 1859 if (++i == HIFN_D_CMD_RSIZE)
1890 u--;
1891 if (++i == (HIFN_D_CMD_RSIZE + 1))
1892 i = 0; 1860 i = 0;
1861 u--;
1893 } 1862 }
1894 dma->cmdk = i; dma->cmdu = u; 1863 dma->cmdk = i; dma->cmdu = u;
1895 1864
1896 i = dma->dstk; u = dma->dstu; 1865 i = dma->dstk; u = dma->dstu;
1897 while (u != 0) { 1866 while (u != 0) {
1898 if (i == HIFN_D_DST_RSIZE)
1899 i = 0;
1900 if (dma->dstr[i].l & __cpu_to_le32(HIFN_D_VALID)) 1867 if (dma->dstr[i].l & __cpu_to_le32(HIFN_D_VALID))
1901 break; 1868 break;
1902 i++, u--; 1869 if (++i == HIFN_D_DST_RSIZE)
1870 i = 0;
1871 u--;
1903 } 1872 }
1904 dma->dstk = i; dma->dstu = u; 1873 dma->dstk = i; dma->dstu = u;
1905 1874
@@ -1944,30 +1913,39 @@ static void hifn_work(struct work_struct *work)
1944 } else 1913 } else
1945 dev->active--; 1914 dev->active--;
1946 1915
1947 if (dev->prev_success == dev->success && dev->started) 1916 if ((dev->prev_success == dev->success) && dev->started)
1948 reset = 1; 1917 reset = 1;
1949 dev->prev_success = dev->success; 1918 dev->prev_success = dev->success;
1950 spin_unlock_irqrestore(&dev->lock, flags); 1919 spin_unlock_irqrestore(&dev->lock, flags);
1951 1920
1952 if (reset) { 1921 if (reset) {
1953 dprintk("%s: r: %08x, active: %d, started: %d, "
1954 "success: %lu: reset: %d.\n",
1955 dev->name, r, dev->active, dev->started,
1956 dev->success, reset);
1957
1958 if (++dev->reset >= 5) { 1922 if (++dev->reset >= 5) {
1959 dprintk("%s: really hard reset.\n", dev->name); 1923 int i;
1924 struct hifn_dma *dma = (struct hifn_dma *)dev->desc_virt;
1925
1926 printk("%s: r: %08x, active: %d, started: %d, "
1927 "success: %lu: qlen: %u/%u, reset: %d.\n",
1928 dev->name, r, dev->active, dev->started,
1929 dev->success, dev->queue.qlen, dev->queue.max_qlen,
1930 reset);
1931
1932 printk("%s: res: ", __func__);
1933 for (i=0; i<HIFN_D_RES_RSIZE; ++i) {
1934 printk("%x.%p ", dma->resr[i].l, dev->sa[i]);
1935 if (dev->sa[i]) {
1936 hifn_process_ready(dev->sa[i], -ENODEV);
1937 hifn_complete_sa(dev, i);
1938 }
1939 }
1940 printk("\n");
1941
1960 hifn_reset_dma(dev, 1); 1942 hifn_reset_dma(dev, 1);
1961 hifn_stop_device(dev); 1943 hifn_stop_device(dev);
1962 hifn_start_device(dev); 1944 hifn_start_device(dev);
1963 dev->reset = 0; 1945 dev->reset = 0;
1964 } 1946 }
1965 1947
1966 spin_lock_irqsave(&dev->lock, flags); 1948 tasklet_schedule(&dev->tasklet);
1967 hifn_check_for_completion(dev, -EBUSY);
1968 hifn_clear_rings(dev);
1969 dev->started = 0;
1970 spin_unlock_irqrestore(&dev->lock, flags);
1971 } 1949 }
1972 1950
1973 schedule_delayed_work(&dev->work, HZ); 1951 schedule_delayed_work(&dev->work, HZ);
@@ -1984,8 +1962,8 @@ static irqreturn_t hifn_interrupt(int irq, void *data)
1984 dprintk("%s: 1 dmacsr: %08x, dmareg: %08x, res: %08x [%d], " 1962 dprintk("%s: 1 dmacsr: %08x, dmareg: %08x, res: %08x [%d], "
1985 "i: %d.%d.%d.%d, u: %d.%d.%d.%d.\n", 1963 "i: %d.%d.%d.%d, u: %d.%d.%d.%d.\n",
1986 dev->name, dmacsr, dev->dmareg, dmacsr & dev->dmareg, dma->cmdi, 1964 dev->name, dmacsr, dev->dmareg, dmacsr & dev->dmareg, dma->cmdi,
1987 dma->cmdu, dma->srcu, dma->dstu, dma->resu, 1965 dma->cmdi, dma->srci, dma->dsti, dma->resi,
1988 dma->cmdi, dma->srci, dma->dsti, dma->resi); 1966 dma->cmdu, dma->srcu, dma->dstu, dma->resu);
1989 1967
1990 if ((dmacsr & dev->dmareg) == 0) 1968 if ((dmacsr & dev->dmareg) == 0)
1991 return IRQ_NONE; 1969 return IRQ_NONE;
@@ -2002,11 +1980,10 @@ static irqreturn_t hifn_interrupt(int irq, void *data)
2002 if (restart) { 1980 if (restart) {
2003 u32 puisr = hifn_read_0(dev, HIFN_0_PUISR); 1981 u32 puisr = hifn_read_0(dev, HIFN_0_PUISR);
2004 1982
2005 if (printk_ratelimit()) 1983 printk(KERN_WARNING "%s: overflow: r: %d, d: %d, puisr: %08x, d: %u.\n",
2006 printk("%s: overflow: r: %d, d: %d, puisr: %08x, d: %u.\n", 1984 dev->name, !!(dmacsr & HIFN_DMACSR_R_OVER),
2007 dev->name, !!(dmacsr & HIFN_DMACSR_R_OVER), 1985 !!(dmacsr & HIFN_DMACSR_D_OVER),
2008 !!(dmacsr & HIFN_DMACSR_D_OVER), 1986 puisr, !!(puisr & HIFN_PUISR_DSTOVER));
2009 puisr, !!(puisr & HIFN_PUISR_DSTOVER));
2010 if (!!(puisr & HIFN_PUISR_DSTOVER)) 1987 if (!!(puisr & HIFN_PUISR_DSTOVER))
2011 hifn_write_0(dev, HIFN_0_PUISR, HIFN_PUISR_DSTOVER); 1988 hifn_write_0(dev, HIFN_0_PUISR, HIFN_PUISR_DSTOVER);
2012 hifn_write_1(dev, HIFN_1_DMA_CSR, dmacsr & (HIFN_DMACSR_R_OVER | 1989 hifn_write_1(dev, HIFN_1_DMA_CSR, dmacsr & (HIFN_DMACSR_R_OVER |
@@ -2016,12 +1993,11 @@ static irqreturn_t hifn_interrupt(int irq, void *data)
2016 restart = dmacsr & (HIFN_DMACSR_C_ABORT | HIFN_DMACSR_S_ABORT | 1993 restart = dmacsr & (HIFN_DMACSR_C_ABORT | HIFN_DMACSR_S_ABORT |
2017 HIFN_DMACSR_D_ABORT | HIFN_DMACSR_R_ABORT); 1994 HIFN_DMACSR_D_ABORT | HIFN_DMACSR_R_ABORT);
2018 if (restart) { 1995 if (restart) {
2019 if (printk_ratelimit()) 1996 printk(KERN_WARNING "%s: abort: c: %d, s: %d, d: %d, r: %d.\n",
2020 printk("%s: abort: c: %d, s: %d, d: %d, r: %d.\n", 1997 dev->name, !!(dmacsr & HIFN_DMACSR_C_ABORT),
2021 dev->name, !!(dmacsr & HIFN_DMACSR_C_ABORT), 1998 !!(dmacsr & HIFN_DMACSR_S_ABORT),
2022 !!(dmacsr & HIFN_DMACSR_S_ABORT), 1999 !!(dmacsr & HIFN_DMACSR_D_ABORT),
2023 !!(dmacsr & HIFN_DMACSR_D_ABORT), 2000 !!(dmacsr & HIFN_DMACSR_R_ABORT));
2024 !!(dmacsr & HIFN_DMACSR_R_ABORT));
2025 hifn_reset_dma(dev, 1); 2001 hifn_reset_dma(dev, 1);
2026 hifn_init_dma(dev); 2002 hifn_init_dma(dev);
2027 hifn_init_registers(dev); 2003 hifn_init_registers(dev);
@@ -2034,7 +2010,6 @@ static irqreturn_t hifn_interrupt(int irq, void *data)
2034 } 2010 }
2035 2011
2036 tasklet_schedule(&dev->tasklet); 2012 tasklet_schedule(&dev->tasklet);
2037 hifn_clear_rings(dev);
2038 2013
2039 return IRQ_HANDLED; 2014 return IRQ_HANDLED;
2040} 2015}
@@ -2048,21 +2023,25 @@ static void hifn_flush(struct hifn_device *dev)
2048 struct hifn_dma *dma = (struct hifn_dma *)dev->desc_virt; 2023 struct hifn_dma *dma = (struct hifn_dma *)dev->desc_virt;
2049 int i; 2024 int i;
2050 2025
2051 spin_lock_irqsave(&dev->lock, flags);
2052 for (i=0; i<HIFN_D_RES_RSIZE; ++i) { 2026 for (i=0; i<HIFN_D_RES_RSIZE; ++i) {
2053 struct hifn_desc *d = &dma->resr[i]; 2027 struct hifn_desc *d = &dma->resr[i];
2054 2028
2055 if (dev->sa[i]) { 2029 if (dev->sa[i]) {
2056 hifn_process_ready(dev->sa[i], 2030 hifn_process_ready(dev->sa[i],
2057 (d->l & __cpu_to_le32(HIFN_D_VALID))?-ENODEV:0); 2031 (d->l & __cpu_to_le32(HIFN_D_VALID))?-ENODEV:0);
2032 hifn_complete_sa(dev, i);
2058 } 2033 }
2059 } 2034 }
2060 2035
2036 spin_lock_irqsave(&dev->lock, flags);
2061 while ((async_req = crypto_dequeue_request(&dev->queue))) { 2037 while ((async_req = crypto_dequeue_request(&dev->queue))) {
2062 ctx = crypto_tfm_ctx(async_req->tfm); 2038 ctx = crypto_tfm_ctx(async_req->tfm);
2063 req = container_of(async_req, struct ablkcipher_request, base); 2039 req = container_of(async_req, struct ablkcipher_request, base);
2040 spin_unlock_irqrestore(&dev->lock, flags);
2064 2041
2065 hifn_process_ready(req, -ENODEV); 2042 hifn_process_ready(req, -ENODEV);
2043
2044 spin_lock_irqsave(&dev->lock, flags);
2066 } 2045 }
2067 spin_unlock_irqrestore(&dev->lock, flags); 2046 spin_unlock_irqrestore(&dev->lock, flags);
2068} 2047}
@@ -2121,6 +2100,7 @@ static int hifn_setup_crypto_req(struct ablkcipher_request *req, u8 op,
2121 u8 type, u8 mode) 2100 u8 type, u8 mode)
2122{ 2101{
2123 struct hifn_context *ctx = crypto_tfm_ctx(req->base.tfm); 2102 struct hifn_context *ctx = crypto_tfm_ctx(req->base.tfm);
2103 struct hifn_request_context *rctx = ablkcipher_request_ctx(req);
2124 unsigned ivsize; 2104 unsigned ivsize;
2125 2105
2126 ivsize = crypto_ablkcipher_ivsize(crypto_ablkcipher_reqtfm(req)); 2106 ivsize = crypto_ablkcipher_ivsize(crypto_ablkcipher_reqtfm(req));
@@ -2141,11 +2121,11 @@ static int hifn_setup_crypto_req(struct ablkcipher_request *req, u8 op,
2141 type = ACRYPTO_TYPE_AES_256; 2121 type = ACRYPTO_TYPE_AES_256;
2142 } 2122 }
2143 2123
2144 ctx->op = op; 2124 rctx->op = op;
2145 ctx->mode = mode; 2125 rctx->mode = mode;
2146 ctx->type = type; 2126 rctx->type = type;
2147 ctx->iv = req->info; 2127 rctx->iv = req->info;
2148 ctx->ivsize = ivsize; 2128 rctx->ivsize = ivsize;
2149 2129
2150 /* 2130 /*
2151 * HEAVY TODO: needs to kick Herbert XU to write documentation. 2131 * HEAVY TODO: needs to kick Herbert XU to write documentation.
@@ -2158,7 +2138,7 @@ static int hifn_setup_crypto_req(struct ablkcipher_request *req, u8 op,
2158 2138
2159static int hifn_process_queue(struct hifn_device *dev) 2139static int hifn_process_queue(struct hifn_device *dev)
2160{ 2140{
2161 struct crypto_async_request *async_req; 2141 struct crypto_async_request *async_req, *backlog;
2162 struct hifn_context *ctx; 2142 struct hifn_context *ctx;
2163 struct ablkcipher_request *req; 2143 struct ablkcipher_request *req;
2164 unsigned long flags; 2144 unsigned long flags;
@@ -2166,12 +2146,16 @@ static int hifn_process_queue(struct hifn_device *dev)
2166 2146
2167 while (dev->started < HIFN_QUEUE_LENGTH) { 2147 while (dev->started < HIFN_QUEUE_LENGTH) {
2168 spin_lock_irqsave(&dev->lock, flags); 2148 spin_lock_irqsave(&dev->lock, flags);
2149 backlog = crypto_get_backlog(&dev->queue);
2169 async_req = crypto_dequeue_request(&dev->queue); 2150 async_req = crypto_dequeue_request(&dev->queue);
2170 spin_unlock_irqrestore(&dev->lock, flags); 2151 spin_unlock_irqrestore(&dev->lock, flags);
2171 2152
2172 if (!async_req) 2153 if (!async_req)
2173 break; 2154 break;
2174 2155
2156 if (backlog)
2157 backlog->complete(backlog, -EINPROGRESS);
2158
2175 ctx = crypto_tfm_ctx(async_req->tfm); 2159 ctx = crypto_tfm_ctx(async_req->tfm);
2176 req = container_of(async_req, struct ablkcipher_request, base); 2160 req = container_of(async_req, struct ablkcipher_request, base);
2177 2161
@@ -2496,7 +2480,7 @@ static int hifn_cra_init(struct crypto_tfm *tfm)
2496 struct hifn_context *ctx = crypto_tfm_ctx(tfm); 2480 struct hifn_context *ctx = crypto_tfm_ctx(tfm);
2497 2481
2498 ctx->dev = ha->dev; 2482 ctx->dev = ha->dev;
2499 2483 tfm->crt_ablkcipher.reqsize = sizeof(struct hifn_request_context);
2500 return 0; 2484 return 0;
2501} 2485}
2502 2486
@@ -2574,7 +2558,10 @@ static void hifn_tasklet_callback(unsigned long data)
2574 * (like dev->success), but they are used in process 2558 * (like dev->success), but they are used in process
2575 * context or update is atomic (like setting dev->sa[i] to NULL). 2559 * context or update is atomic (like setting dev->sa[i] to NULL).
2576 */ 2560 */
2577 hifn_check_for_completion(dev, 0); 2561 hifn_clear_rings(dev, 0);
2562
2563 if (dev->started < HIFN_QUEUE_LENGTH && dev->queue.qlen)
2564 hifn_process_queue(dev);
2578} 2565}
2579 2566
2580static int hifn_probe(struct pci_dev *pdev, const struct pci_device_id *id) 2567static int hifn_probe(struct pci_dev *pdev, const struct pci_device_id *id)
@@ -2631,22 +2618,11 @@ static int hifn_probe(struct pci_dev *pdev, const struct pci_device_id *id)
2631 goto err_out_unmap_bars; 2618 goto err_out_unmap_bars;
2632 } 2619 }
2633 2620
2634 dev->result_mem = __get_free_pages(GFP_KERNEL, HIFN_MAX_RESULT_ORDER);
2635 if (!dev->result_mem) {
2636 dprintk("Failed to allocate %d pages for result_mem.\n",
2637 HIFN_MAX_RESULT_ORDER);
2638 goto err_out_unmap_bars;
2639 }
2640 memset((void *)dev->result_mem, 0, PAGE_SIZE*(1<<HIFN_MAX_RESULT_ORDER));
2641
2642 dev->dst = pci_map_single(pdev, (void *)dev->result_mem,
2643 PAGE_SIZE << HIFN_MAX_RESULT_ORDER, PCI_DMA_FROMDEVICE);
2644
2645 dev->desc_virt = pci_alloc_consistent(pdev, sizeof(struct hifn_dma), 2621 dev->desc_virt = pci_alloc_consistent(pdev, sizeof(struct hifn_dma),
2646 &dev->desc_dma); 2622 &dev->desc_dma);
2647 if (!dev->desc_virt) { 2623 if (!dev->desc_virt) {
2648 dprintk("Failed to allocate descriptor rings.\n"); 2624 dprintk("Failed to allocate descriptor rings.\n");
2649 goto err_out_free_result_pages; 2625 goto err_out_unmap_bars;
2650 } 2626 }
2651 memset(dev->desc_virt, 0, sizeof(struct hifn_dma)); 2627 memset(dev->desc_virt, 0, sizeof(struct hifn_dma));
2652 2628
@@ -2706,11 +2682,6 @@ err_out_free_desc:
2706 pci_free_consistent(pdev, sizeof(struct hifn_dma), 2682 pci_free_consistent(pdev, sizeof(struct hifn_dma),
2707 dev->desc_virt, dev->desc_dma); 2683 dev->desc_virt, dev->desc_dma);
2708 2684
2709err_out_free_result_pages:
2710 pci_unmap_single(pdev, dev->dst, PAGE_SIZE << HIFN_MAX_RESULT_ORDER,
2711 PCI_DMA_FROMDEVICE);
2712 free_pages(dev->result_mem, HIFN_MAX_RESULT_ORDER);
2713
2714err_out_unmap_bars: 2685err_out_unmap_bars:
2715 for (i=0; i<3; ++i) 2686 for (i=0; i<3; ++i)
2716 if (dev->bar[i]) 2687 if (dev->bar[i])
@@ -2748,10 +2719,6 @@ static void hifn_remove(struct pci_dev *pdev)
2748 2719
2749 pci_free_consistent(pdev, sizeof(struct hifn_dma), 2720 pci_free_consistent(pdev, sizeof(struct hifn_dma),
2750 dev->desc_virt, dev->desc_dma); 2721 dev->desc_virt, dev->desc_dma);
2751 pci_unmap_single(pdev, dev->dst,
2752 PAGE_SIZE << HIFN_MAX_RESULT_ORDER,
2753 PCI_DMA_FROMDEVICE);
2754 free_pages(dev->result_mem, HIFN_MAX_RESULT_ORDER);
2755 for (i=0; i<3; ++i) 2722 for (i=0; i<3; ++i)
2756 if (dev->bar[i]) 2723 if (dev->bar[i])
2757 iounmap(dev->bar[i]); 2724 iounmap(dev->bar[i]);
@@ -2782,6 +2749,11 @@ static int __devinit hifn_init(void)
2782 unsigned int freq; 2749 unsigned int freq;
2783 int err; 2750 int err;
2784 2751
2752 if (sizeof(dma_addr_t) > 4) {
2753 printk(KERN_INFO "HIFN supports only 32-bit addresses.\n");
2754 return -EINVAL;
2755 }
2756
2785 if (strncmp(hifn_pll_ref, "ext", 3) && 2757 if (strncmp(hifn_pll_ref, "ext", 3) &&
2786 strncmp(hifn_pll_ref, "pci", 3)) { 2758 strncmp(hifn_pll_ref, "pci", 3)) {
2787 printk(KERN_ERR "hifn795x: invalid hifn_pll_ref clock, " 2759 printk(KERN_ERR "hifn795x: invalid hifn_pll_ref clock, "
diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c
index bf2917d197a0..856b3cc25583 100644
--- a/drivers/crypto/padlock-aes.c
+++ b/drivers/crypto/padlock-aes.c
@@ -15,6 +15,8 @@
15#include <linux/errno.h> 15#include <linux/errno.h>
16#include <linux/interrupt.h> 16#include <linux/interrupt.h>
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/percpu.h>
19#include <linux/smp.h>
18#include <asm/byteorder.h> 20#include <asm/byteorder.h>
19#include <asm/i387.h> 21#include <asm/i387.h>
20#include "padlock.h" 22#include "padlock.h"
@@ -49,6 +51,8 @@ struct aes_ctx {
49 u32 *D; 51 u32 *D;
50}; 52};
51 53
54static DEFINE_PER_CPU(struct cword *, last_cword);
55
52/* Tells whether the ACE is capable to generate 56/* Tells whether the ACE is capable to generate
53 the extended key for a given key_len. */ 57 the extended key for a given key_len. */
54static inline int 58static inline int
@@ -89,6 +93,7 @@ static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
89 const __le32 *key = (const __le32 *)in_key; 93 const __le32 *key = (const __le32 *)in_key;
90 u32 *flags = &tfm->crt_flags; 94 u32 *flags = &tfm->crt_flags;
91 struct crypto_aes_ctx gen_aes; 95 struct crypto_aes_ctx gen_aes;
96 int cpu;
92 97
93 if (key_len % 8) { 98 if (key_len % 8) {
94 *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; 99 *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
@@ -118,7 +123,7 @@ static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
118 123
119 /* Don't generate extended keys if the hardware can do it. */ 124 /* Don't generate extended keys if the hardware can do it. */
120 if (aes_hw_extkey_available(key_len)) 125 if (aes_hw_extkey_available(key_len))
121 return 0; 126 goto ok;
122 127
123 ctx->D = ctx->d_data; 128 ctx->D = ctx->d_data;
124 ctx->cword.encrypt.keygen = 1; 129 ctx->cword.encrypt.keygen = 1;
@@ -131,15 +136,30 @@ static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
131 136
132 memcpy(ctx->E, gen_aes.key_enc, AES_MAX_KEYLENGTH); 137 memcpy(ctx->E, gen_aes.key_enc, AES_MAX_KEYLENGTH);
133 memcpy(ctx->D, gen_aes.key_dec, AES_MAX_KEYLENGTH); 138 memcpy(ctx->D, gen_aes.key_dec, AES_MAX_KEYLENGTH);
139
140ok:
141 for_each_online_cpu(cpu)
142 if (&ctx->cword.encrypt == per_cpu(last_cword, cpu) ||
143 &ctx->cword.decrypt == per_cpu(last_cword, cpu))
144 per_cpu(last_cword, cpu) = NULL;
145
134 return 0; 146 return 0;
135} 147}
136 148
137/* ====== Encryption/decryption routines ====== */ 149/* ====== Encryption/decryption routines ====== */
138 150
139/* These are the real call to PadLock. */ 151/* These are the real call to PadLock. */
140static inline void padlock_reset_key(void) 152static inline void padlock_reset_key(struct cword *cword)
153{
154 int cpu = raw_smp_processor_id();
155
156 if (cword != per_cpu(last_cword, cpu))
157 asm volatile ("pushfl; popfl");
158}
159
160static inline void padlock_store_cword(struct cword *cword)
141{ 161{
142 asm volatile ("pushfl; popfl"); 162 per_cpu(last_cword, raw_smp_processor_id()) = cword;
143} 163}
144 164
145/* 165/*
@@ -149,7 +169,7 @@ static inline void padlock_reset_key(void)
149 */ 169 */
150 170
151static inline void padlock_xcrypt(const u8 *input, u8 *output, void *key, 171static inline void padlock_xcrypt(const u8 *input, u8 *output, void *key,
152 void *control_word) 172 struct cword *control_word)
153{ 173{
154 asm volatile (".byte 0xf3,0x0f,0xa7,0xc8" /* rep xcryptecb */ 174 asm volatile (".byte 0xf3,0x0f,0xa7,0xc8" /* rep xcryptecb */
155 : "+S"(input), "+D"(output) 175 : "+S"(input), "+D"(output)
@@ -213,22 +233,24 @@ static void aes_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
213{ 233{
214 struct aes_ctx *ctx = aes_ctx(tfm); 234 struct aes_ctx *ctx = aes_ctx(tfm);
215 int ts_state; 235 int ts_state;
216 padlock_reset_key();
217 236
237 padlock_reset_key(&ctx->cword.encrypt);
218 ts_state = irq_ts_save(); 238 ts_state = irq_ts_save();
219 aes_crypt(in, out, ctx->E, &ctx->cword.encrypt); 239 aes_crypt(in, out, ctx->E, &ctx->cword.encrypt);
220 irq_ts_restore(ts_state); 240 irq_ts_restore(ts_state);
241 padlock_store_cword(&ctx->cword.encrypt);
221} 242}
222 243
223static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) 244static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
224{ 245{
225 struct aes_ctx *ctx = aes_ctx(tfm); 246 struct aes_ctx *ctx = aes_ctx(tfm);
226 int ts_state; 247 int ts_state;
227 padlock_reset_key();
228 248
249 padlock_reset_key(&ctx->cword.encrypt);
229 ts_state = irq_ts_save(); 250 ts_state = irq_ts_save();
230 aes_crypt(in, out, ctx->D, &ctx->cword.decrypt); 251 aes_crypt(in, out, ctx->D, &ctx->cword.decrypt);
231 irq_ts_restore(ts_state); 252 irq_ts_restore(ts_state);
253 padlock_store_cword(&ctx->cword.encrypt);
232} 254}
233 255
234static struct crypto_alg aes_alg = { 256static struct crypto_alg aes_alg = {
@@ -261,7 +283,7 @@ static int ecb_aes_encrypt(struct blkcipher_desc *desc,
261 int err; 283 int err;
262 int ts_state; 284 int ts_state;
263 285
264 padlock_reset_key(); 286 padlock_reset_key(&ctx->cword.encrypt);
265 287
266 blkcipher_walk_init(&walk, dst, src, nbytes); 288 blkcipher_walk_init(&walk, dst, src, nbytes);
267 err = blkcipher_walk_virt(desc, &walk); 289 err = blkcipher_walk_virt(desc, &walk);
@@ -276,6 +298,8 @@ static int ecb_aes_encrypt(struct blkcipher_desc *desc,
276 } 298 }
277 irq_ts_restore(ts_state); 299 irq_ts_restore(ts_state);
278 300
301 padlock_store_cword(&ctx->cword.encrypt);
302
279 return err; 303 return err;
280} 304}
281 305
@@ -288,7 +312,7 @@ static int ecb_aes_decrypt(struct blkcipher_desc *desc,
288 int err; 312 int err;
289 int ts_state; 313 int ts_state;
290 314
291 padlock_reset_key(); 315 padlock_reset_key(&ctx->cword.decrypt);
292 316
293 blkcipher_walk_init(&walk, dst, src, nbytes); 317 blkcipher_walk_init(&walk, dst, src, nbytes);
294 err = blkcipher_walk_virt(desc, &walk); 318 err = blkcipher_walk_virt(desc, &walk);
@@ -302,6 +326,9 @@ static int ecb_aes_decrypt(struct blkcipher_desc *desc,
302 err = blkcipher_walk_done(desc, &walk, nbytes); 326 err = blkcipher_walk_done(desc, &walk, nbytes);
303 } 327 }
304 irq_ts_restore(ts_state); 328 irq_ts_restore(ts_state);
329
330 padlock_store_cword(&ctx->cword.encrypt);
331
305 return err; 332 return err;
306} 333}
307 334
@@ -336,7 +363,7 @@ static int cbc_aes_encrypt(struct blkcipher_desc *desc,
336 int err; 363 int err;
337 int ts_state; 364 int ts_state;
338 365
339 padlock_reset_key(); 366 padlock_reset_key(&ctx->cword.encrypt);
340 367
341 blkcipher_walk_init(&walk, dst, src, nbytes); 368 blkcipher_walk_init(&walk, dst, src, nbytes);
342 err = blkcipher_walk_virt(desc, &walk); 369 err = blkcipher_walk_virt(desc, &walk);
@@ -353,6 +380,8 @@ static int cbc_aes_encrypt(struct blkcipher_desc *desc,
353 } 380 }
354 irq_ts_restore(ts_state); 381 irq_ts_restore(ts_state);
355 382
383 padlock_store_cword(&ctx->cword.decrypt);
384
356 return err; 385 return err;
357} 386}
358 387
@@ -365,7 +394,7 @@ static int cbc_aes_decrypt(struct blkcipher_desc *desc,
365 int err; 394 int err;
366 int ts_state; 395 int ts_state;
367 396
368 padlock_reset_key(); 397 padlock_reset_key(&ctx->cword.encrypt);
369 398
370 blkcipher_walk_init(&walk, dst, src, nbytes); 399 blkcipher_walk_init(&walk, dst, src, nbytes);
371 err = blkcipher_walk_virt(desc, &walk); 400 err = blkcipher_walk_virt(desc, &walk);
@@ -380,6 +409,9 @@ static int cbc_aes_decrypt(struct blkcipher_desc *desc,
380 } 409 }
381 410
382 irq_ts_restore(ts_state); 411 irq_ts_restore(ts_state);
412
413 padlock_store_cword(&ctx->cword.encrypt);
414
383 return err; 415 return err;
384} 416}
385 417
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 24607669a52b..a3918c16b3db 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -127,7 +127,6 @@ struct talitos_private {
127 127
128 /* request callback tasklet */ 128 /* request callback tasklet */
129 struct tasklet_struct done_task; 129 struct tasklet_struct done_task;
130 struct tasklet_struct error_task;
131 130
132 /* list of registered algorithms */ 131 /* list of registered algorithms */
133 struct list_head alg_list; 132 struct list_head alg_list;
@@ -138,6 +137,7 @@ struct talitos_private {
138 137
139/* .features flag */ 138/* .features flag */
140#define TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT 0x00000001 139#define TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT 0x00000001
140#define TALITOS_FTR_HW_AUTH_CHECK 0x00000002
141 141
142/* 142/*
143 * map virtual single (contiguous) pointer to h/w descriptor pointer 143 * map virtual single (contiguous) pointer to h/w descriptor pointer
@@ -184,6 +184,11 @@ static int reset_channel(struct device *dev, int ch)
184 setbits32(priv->reg + TALITOS_CCCR_LO(ch), TALITOS_CCCR_LO_CDWE | 184 setbits32(priv->reg + TALITOS_CCCR_LO(ch), TALITOS_CCCR_LO_CDWE |
185 TALITOS_CCCR_LO_CDIE); 185 TALITOS_CCCR_LO_CDIE);
186 186
187 /* and ICCR writeback, if available */
188 if (priv->features & TALITOS_FTR_HW_AUTH_CHECK)
189 setbits32(priv->reg + TALITOS_CCCR_LO(ch),
190 TALITOS_CCCR_LO_IWSE);
191
187 return 0; 192 return 0;
188} 193}
189 194
@@ -239,6 +244,11 @@ static int init_device(struct device *dev)
239 setbits32(priv->reg + TALITOS_IMR, TALITOS_IMR_INIT); 244 setbits32(priv->reg + TALITOS_IMR, TALITOS_IMR_INIT);
240 setbits32(priv->reg + TALITOS_IMR_LO, TALITOS_IMR_LO_INIT); 245 setbits32(priv->reg + TALITOS_IMR_LO, TALITOS_IMR_LO_INIT);
241 246
247 /* disable integrity check error interrupts (use writeback instead) */
248 if (priv->features & TALITOS_FTR_HW_AUTH_CHECK)
249 setbits32(priv->reg + TALITOS_MDEUICR_LO,
250 TALITOS_MDEUICR_LO_ICE);
251
242 return 0; 252 return 0;
243} 253}
244 254
@@ -370,6 +380,12 @@ static void talitos_done(unsigned long data)
370 380
371 for (ch = 0; ch < priv->num_channels; ch++) 381 for (ch = 0; ch < priv->num_channels; ch++)
372 flush_channel(dev, ch, 0, 0); 382 flush_channel(dev, ch, 0, 0);
383
384 /* At this point, all completed channels have been processed.
385 * Unmask done interrupts for channels completed later on.
386 */
387 setbits32(priv->reg + TALITOS_IMR, TALITOS_IMR_INIT);
388 setbits32(priv->reg + TALITOS_IMR_LO, TALITOS_IMR_LO_INIT);
373} 389}
374 390
375/* 391/*
@@ -469,16 +485,13 @@ static void report_eu_error(struct device *dev, int ch, struct talitos_desc *des
469/* 485/*
470 * recover from error interrupts 486 * recover from error interrupts
471 */ 487 */
472static void talitos_error(unsigned long data) 488static void talitos_error(unsigned long data, u32 isr, u32 isr_lo)
473{ 489{
474 struct device *dev = (struct device *)data; 490 struct device *dev = (struct device *)data;
475 struct talitos_private *priv = dev_get_drvdata(dev); 491 struct talitos_private *priv = dev_get_drvdata(dev);
476 unsigned int timeout = TALITOS_TIMEOUT; 492 unsigned int timeout = TALITOS_TIMEOUT;
477 int ch, error, reset_dev = 0, reset_ch = 0; 493 int ch, error, reset_dev = 0, reset_ch = 0;
478 u32 isr, isr_lo, v, v_lo; 494 u32 v, v_lo;
479
480 isr = in_be32(priv->reg + TALITOS_ISR);
481 isr_lo = in_be32(priv->reg + TALITOS_ISR_LO);
482 495
483 for (ch = 0; ch < priv->num_channels; ch++) { 496 for (ch = 0; ch < priv->num_channels; ch++) {
484 /* skip channels without errors */ 497 /* skip channels without errors */
@@ -560,16 +573,19 @@ static irqreturn_t talitos_interrupt(int irq, void *data)
560 573
561 isr = in_be32(priv->reg + TALITOS_ISR); 574 isr = in_be32(priv->reg + TALITOS_ISR);
562 isr_lo = in_be32(priv->reg + TALITOS_ISR_LO); 575 isr_lo = in_be32(priv->reg + TALITOS_ISR_LO);
563 576 /* Acknowledge interrupt */
564 /* ack */
565 out_be32(priv->reg + TALITOS_ICR, isr); 577 out_be32(priv->reg + TALITOS_ICR, isr);
566 out_be32(priv->reg + TALITOS_ICR_LO, isr_lo); 578 out_be32(priv->reg + TALITOS_ICR_LO, isr_lo);
567 579
568 if (unlikely((isr & ~TALITOS_ISR_CHDONE) || isr_lo)) 580 if (unlikely((isr & ~TALITOS_ISR_CHDONE) || isr_lo))
569 talitos_error((unsigned long)data); 581 talitos_error((unsigned long)data, isr, isr_lo);
570 else 582 else
571 if (likely(isr & TALITOS_ISR_CHDONE)) 583 if (likely(isr & TALITOS_ISR_CHDONE)) {
584 /* mask further done interrupts. */
585 clrbits32(priv->reg + TALITOS_IMR, TALITOS_IMR_DONE);
586 /* done_task will unmask done interrupts at exit */
572 tasklet_schedule(&priv->done_task); 587 tasklet_schedule(&priv->done_task);
588 }
573 589
574 return (isr || isr_lo) ? IRQ_HANDLED : IRQ_NONE; 590 return (isr || isr_lo) ? IRQ_HANDLED : IRQ_NONE;
575} 591}
@@ -802,7 +818,7 @@ static void ipsec_esp_encrypt_done(struct device *dev,
802 aead_request_complete(areq, err); 818 aead_request_complete(areq, err);
803} 819}
804 820
805static void ipsec_esp_decrypt_done(struct device *dev, 821static void ipsec_esp_decrypt_swauth_done(struct device *dev,
806 struct talitos_desc *desc, void *context, 822 struct talitos_desc *desc, void *context,
807 int err) 823 int err)
808{ 824{
@@ -834,6 +850,27 @@ static void ipsec_esp_decrypt_done(struct device *dev,
834 aead_request_complete(req, err); 850 aead_request_complete(req, err);
835} 851}
836 852
853static void ipsec_esp_decrypt_hwauth_done(struct device *dev,
854 struct talitos_desc *desc, void *context,
855 int err)
856{
857 struct aead_request *req = context;
858 struct ipsec_esp_edesc *edesc =
859 container_of(desc, struct ipsec_esp_edesc, desc);
860
861 ipsec_esp_unmap(dev, edesc, req);
862
863 /* check ICV auth status */
864 if (!err)
865 if ((desc->hdr_lo & DESC_HDR_LO_ICCR1_MASK) !=
866 DESC_HDR_LO_ICCR1_PASS)
867 err = -EBADMSG;
868
869 kfree(edesc);
870
871 aead_request_complete(req, err);
872}
873
837/* 874/*
838 * convert scatterlist to SEC h/w link table format 875 * convert scatterlist to SEC h/w link table format
839 * stop at cryptlen bytes 876 * stop at cryptlen bytes
@@ -887,6 +924,7 @@ static int ipsec_esp(struct ipsec_esp_edesc *edesc, struct aead_request *areq,
887 unsigned int authsize = ctx->authsize; 924 unsigned int authsize = ctx->authsize;
888 unsigned int ivsize; 925 unsigned int ivsize;
889 int sg_count, ret; 926 int sg_count, ret;
927 int sg_link_tbl_len;
890 928
891 /* hmac key */ 929 /* hmac key */
892 map_single_talitos_ptr(dev, &desc->ptr[0], ctx->authkeylen, &ctx->key, 930 map_single_talitos_ptr(dev, &desc->ptr[0], ctx->authkeylen, &ctx->key,
@@ -924,33 +962,19 @@ static int ipsec_esp(struct ipsec_esp_edesc *edesc, struct aead_request *areq,
924 if (sg_count == 1) { 962 if (sg_count == 1) {
925 desc->ptr[4].ptr = cpu_to_be32(sg_dma_address(areq->src)); 963 desc->ptr[4].ptr = cpu_to_be32(sg_dma_address(areq->src));
926 } else { 964 } else {
927 sg_count = sg_to_link_tbl(areq->src, sg_count, cryptlen, 965 sg_link_tbl_len = cryptlen;
966
967 if ((edesc->desc.hdr & DESC_HDR_MODE1_MDEU_CICV) &&
968 (edesc->desc.hdr & DESC_HDR_MODE0_ENCRYPT) == 0) {
969 sg_link_tbl_len = cryptlen + authsize;
970 }
971 sg_count = sg_to_link_tbl(areq->src, sg_count, sg_link_tbl_len,
928 &edesc->link_tbl[0]); 972 &edesc->link_tbl[0]);
929 if (sg_count > 1) { 973 if (sg_count > 1) {
930 struct talitos_ptr *link_tbl_ptr =
931 &edesc->link_tbl[sg_count-1];
932 struct scatterlist *sg;
933 struct talitos_private *priv = dev_get_drvdata(dev);
934
935 desc->ptr[4].j_extent |= DESC_PTR_LNKTBL_JUMP; 974 desc->ptr[4].j_extent |= DESC_PTR_LNKTBL_JUMP;
936 desc->ptr[4].ptr = cpu_to_be32(edesc->dma_link_tbl); 975 desc->ptr[4].ptr = cpu_to_be32(edesc->dma_link_tbl);
937 dma_sync_single_for_device(ctx->dev, edesc->dma_link_tbl, 976 dma_sync_single_for_device(ctx->dev, edesc->dma_link_tbl,
938 edesc->dma_len, DMA_BIDIRECTIONAL); 977 edesc->dma_len, DMA_BIDIRECTIONAL);
939 /* If necessary for this SEC revision,
940 * add a link table entry for ICV.
941 */
942 if ((priv->features &
943 TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT) &&
944 (edesc->desc.hdr & DESC_HDR_MODE0_ENCRYPT) == 0) {
945 link_tbl_ptr->j_extent = 0;
946 link_tbl_ptr++;
947 link_tbl_ptr->j_extent = DESC_PTR_LNKTBL_RETURN;
948 link_tbl_ptr->len = cpu_to_be16(authsize);
949 sg = sg_last(areq->src, edesc->src_nents ? : 1);
950 link_tbl_ptr->ptr = cpu_to_be32(
951 (char *)sg_dma_address(sg)
952 + sg->length - authsize);
953 }
954 } else { 978 } else {
955 /* Only one segment now, so no link tbl needed */ 979 /* Only one segment now, so no link tbl needed */
956 desc->ptr[4].ptr = cpu_to_be32(sg_dma_address(areq->src)); 980 desc->ptr[4].ptr = cpu_to_be32(sg_dma_address(areq->src));
@@ -975,13 +999,9 @@ static int ipsec_esp(struct ipsec_esp_edesc *edesc, struct aead_request *areq,
975 desc->ptr[5].ptr = cpu_to_be32((struct talitos_ptr *) 999 desc->ptr[5].ptr = cpu_to_be32((struct talitos_ptr *)
976 edesc->dma_link_tbl + 1000 edesc->dma_link_tbl +
977 edesc->src_nents + 1); 1001 edesc->src_nents + 1);
978 if (areq->src == areq->dst) { 1002 sg_count = sg_to_link_tbl(areq->dst, sg_count, cryptlen,
979 memcpy(link_tbl_ptr, &edesc->link_tbl[0], 1003 link_tbl_ptr);
980 edesc->src_nents * sizeof(struct talitos_ptr)); 1004
981 } else {
982 sg_count = sg_to_link_tbl(areq->dst, sg_count, cryptlen,
983 link_tbl_ptr);
984 }
985 /* Add an entry to the link table for ICV data */ 1005 /* Add an entry to the link table for ICV data */
986 link_tbl_ptr += sg_count - 1; 1006 link_tbl_ptr += sg_count - 1;
987 link_tbl_ptr->j_extent = 0; 1007 link_tbl_ptr->j_extent = 0;
@@ -1106,11 +1126,14 @@ static int aead_authenc_encrypt(struct aead_request *req)
1106 return ipsec_esp(edesc, req, NULL, 0, ipsec_esp_encrypt_done); 1126 return ipsec_esp(edesc, req, NULL, 0, ipsec_esp_encrypt_done);
1107} 1127}
1108 1128
1129
1130
1109static int aead_authenc_decrypt(struct aead_request *req) 1131static int aead_authenc_decrypt(struct aead_request *req)
1110{ 1132{
1111 struct crypto_aead *authenc = crypto_aead_reqtfm(req); 1133 struct crypto_aead *authenc = crypto_aead_reqtfm(req);
1112 struct talitos_ctx *ctx = crypto_aead_ctx(authenc); 1134 struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
1113 unsigned int authsize = ctx->authsize; 1135 unsigned int authsize = ctx->authsize;
1136 struct talitos_private *priv = dev_get_drvdata(ctx->dev);
1114 struct ipsec_esp_edesc *edesc; 1137 struct ipsec_esp_edesc *edesc;
1115 struct scatterlist *sg; 1138 struct scatterlist *sg;
1116 void *icvdata; 1139 void *icvdata;
@@ -1122,22 +1145,39 @@ static int aead_authenc_decrypt(struct aead_request *req)
1122 if (IS_ERR(edesc)) 1145 if (IS_ERR(edesc))
1123 return PTR_ERR(edesc); 1146 return PTR_ERR(edesc);
1124 1147
1125 /* stash incoming ICV for later cmp with ICV generated by the h/w */ 1148 if ((priv->features & TALITOS_FTR_HW_AUTH_CHECK) &&
1126 if (edesc->dma_len) 1149 (((!edesc->src_nents && !edesc->dst_nents) ||
1127 icvdata = &edesc->link_tbl[edesc->src_nents + 1150 priv->features & TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT))) {
1128 edesc->dst_nents + 2]; 1151
1129 else 1152 /* decrypt and check the ICV */
1130 icvdata = &edesc->link_tbl[0]; 1153 edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND |
1154 DESC_HDR_MODE1_MDEU_CICV;
1155
1156 /* reset integrity check result bits */
1157 edesc->desc.hdr_lo = 0;
1158
1159 return ipsec_esp(edesc, req, NULL, 0, ipsec_esp_decrypt_hwauth_done);
1160
1161 } else {
1162
1163 /* Have to check the ICV with software */
1131 1164
1132 sg = sg_last(req->src, edesc->src_nents ? : 1); 1165 edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND;
1166
1167 /* stash incoming ICV for later cmp with ICV generated by the h/w */
1168 if (edesc->dma_len)
1169 icvdata = &edesc->link_tbl[edesc->src_nents +
1170 edesc->dst_nents + 2];
1171 else
1172 icvdata = &edesc->link_tbl[0];
1133 1173
1134 memcpy(icvdata, (char *)sg_virt(sg) + sg->length - ctx->authsize, 1174 sg = sg_last(req->src, edesc->src_nents ? : 1);
1135 ctx->authsize);
1136 1175
1137 /* decrypt */ 1176 memcpy(icvdata, (char *)sg_virt(sg) + sg->length - ctx->authsize,
1138 edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND; 1177 ctx->authsize);
1139 1178
1140 return ipsec_esp(edesc, req, NULL, 0, ipsec_esp_decrypt_done); 1179 return ipsec_esp(edesc, req, NULL, 0, ipsec_esp_decrypt_swauth_done);
1180 }
1141} 1181}
1142 1182
1143static int aead_authenc_givencrypt( 1183static int aead_authenc_givencrypt(
@@ -1391,7 +1431,6 @@ static int talitos_remove(struct of_device *ofdev)
1391 } 1431 }
1392 1432
1393 tasklet_kill(&priv->done_task); 1433 tasklet_kill(&priv->done_task);
1394 tasklet_kill(&priv->error_task);
1395 1434
1396 iounmap(priv->reg); 1435 iounmap(priv->reg);
1397 1436
@@ -1451,10 +1490,9 @@ static int talitos_probe(struct of_device *ofdev,
1451 1490
1452 priv->ofdev = ofdev; 1491 priv->ofdev = ofdev;
1453 1492
1454 INIT_LIST_HEAD(&priv->alg_list);
1455
1456 tasklet_init(&priv->done_task, talitos_done, (unsigned long)dev); 1493 tasklet_init(&priv->done_task, talitos_done, (unsigned long)dev);
1457 tasklet_init(&priv->error_task, talitos_error, (unsigned long)dev); 1494
1495 INIT_LIST_HEAD(&priv->alg_list);
1458 1496
1459 priv->irq = irq_of_parse_and_map(np, 0); 1497 priv->irq = irq_of_parse_and_map(np, 0);
1460 1498
@@ -1508,6 +1546,9 @@ static int talitos_probe(struct of_device *ofdev,
1508 if (of_device_is_compatible(np, "fsl,sec3.0")) 1546 if (of_device_is_compatible(np, "fsl,sec3.0"))
1509 priv->features |= TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT; 1547 priv->features |= TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT;
1510 1548
1549 if (of_device_is_compatible(np, "fsl,sec2.1"))
1550 priv->features |= TALITOS_FTR_HW_AUTH_CHECK;
1551
1511 priv->head_lock = kmalloc(sizeof(spinlock_t) * priv->num_channels, 1552 priv->head_lock = kmalloc(sizeof(spinlock_t) * priv->num_channels,
1512 GFP_KERNEL); 1553 GFP_KERNEL);
1513 priv->tail_lock = kmalloc(sizeof(spinlock_t) * priv->num_channels, 1554 priv->tail_lock = kmalloc(sizeof(spinlock_t) * priv->num_channels,
@@ -1551,7 +1592,7 @@ static int talitos_probe(struct of_device *ofdev,
1551 goto err_out; 1592 goto err_out;
1552 } 1593 }
1553 for (i = 0; i < priv->num_channels; i++) 1594 for (i = 0; i < priv->num_channels; i++)
1554 atomic_set(&priv->submit_count[i], -priv->chfifo_len); 1595 atomic_set(&priv->submit_count[i], -(priv->chfifo_len - 1));
1555 1596
1556 priv->head = kzalloc(sizeof(int) * priv->num_channels, GFP_KERNEL); 1597 priv->head = kzalloc(sizeof(int) * priv->num_channels, GFP_KERNEL);
1557 priv->tail = kzalloc(sizeof(int) * priv->num_channels, GFP_KERNEL); 1598 priv->tail = kzalloc(sizeof(int) * priv->num_channels, GFP_KERNEL);
diff --git a/drivers/crypto/talitos.h b/drivers/crypto/talitos.h
index c48a405abf70..575981f0cfda 100644
--- a/drivers/crypto/talitos.h
+++ b/drivers/crypto/talitos.h
@@ -37,7 +37,8 @@
37#define TALITOS_MCR_LO 0x1038 37#define TALITOS_MCR_LO 0x1038
38#define TALITOS_MCR_SWR 0x1 /* s/w reset */ 38#define TALITOS_MCR_SWR 0x1 /* s/w reset */
39#define TALITOS_IMR 0x1008 /* interrupt mask register */ 39#define TALITOS_IMR 0x1008 /* interrupt mask register */
40#define TALITOS_IMR_INIT 0x10fff /* enable channel IRQs */ 40#define TALITOS_IMR_INIT 0x100ff /* enable channel IRQs */
41#define TALITOS_IMR_DONE 0x00055 /* done IRQs */
41#define TALITOS_IMR_LO 0x100C 42#define TALITOS_IMR_LO 0x100C
42#define TALITOS_IMR_LO_INIT 0x20000 /* allow RNGU error IRQs */ 43#define TALITOS_IMR_LO_INIT 0x20000 /* allow RNGU error IRQs */
43#define TALITOS_ISR 0x1010 /* interrupt status register */ 44#define TALITOS_ISR 0x1010 /* interrupt status register */
@@ -55,6 +56,7 @@
55#define TALITOS_CCCR_CONT 0x2 /* channel continue */ 56#define TALITOS_CCCR_CONT 0x2 /* channel continue */
56#define TALITOS_CCCR_RESET 0x1 /* channel reset */ 57#define TALITOS_CCCR_RESET 0x1 /* channel reset */
57#define TALITOS_CCCR_LO(ch) (ch * TALITOS_CH_STRIDE + 0x110c) 58#define TALITOS_CCCR_LO(ch) (ch * TALITOS_CH_STRIDE + 0x110c)
59#define TALITOS_CCCR_LO_IWSE 0x80 /* chan. ICCR writeback enab. */
58#define TALITOS_CCCR_LO_CDWE 0x10 /* chan. done writeback enab. */ 60#define TALITOS_CCCR_LO_CDWE 0x10 /* chan. done writeback enab. */
59#define TALITOS_CCCR_LO_NT 0x4 /* notification type */ 61#define TALITOS_CCCR_LO_NT 0x4 /* notification type */
60#define TALITOS_CCCR_LO_CDIE 0x2 /* channel done IRQ enable */ 62#define TALITOS_CCCR_LO_CDIE 0x2 /* channel done IRQ enable */
@@ -102,6 +104,9 @@
102#define TALITOS_AESUISR_LO 0x4034 104#define TALITOS_AESUISR_LO 0x4034
103#define TALITOS_MDEUISR 0x6030 /* message digest unit */ 105#define TALITOS_MDEUISR 0x6030 /* message digest unit */
104#define TALITOS_MDEUISR_LO 0x6034 106#define TALITOS_MDEUISR_LO 0x6034
107#define TALITOS_MDEUICR 0x6038 /* interrupt control */
108#define TALITOS_MDEUICR_LO 0x603c
109#define TALITOS_MDEUICR_LO_ICE 0x4000 /* integrity check IRQ enable */
105#define TALITOS_AFEUISR 0x8030 /* arc4 unit */ 110#define TALITOS_AFEUISR 0x8030 /* arc4 unit */
106#define TALITOS_AFEUISR_LO 0x8034 111#define TALITOS_AFEUISR_LO 0x8034
107#define TALITOS_RNGUISR 0xa030 /* random number unit */ 112#define TALITOS_RNGUISR 0xa030 /* random number unit */
@@ -129,31 +134,34 @@
129 */ 134 */
130 135
131/* written back when done */ 136/* written back when done */
132#define DESC_HDR_DONE __constant_cpu_to_be32(0xff000000) 137#define DESC_HDR_DONE cpu_to_be32(0xff000000)
138#define DESC_HDR_LO_ICCR1_MASK cpu_to_be32(0x00180000)
139#define DESC_HDR_LO_ICCR1_PASS cpu_to_be32(0x00080000)
140#define DESC_HDR_LO_ICCR1_FAIL cpu_to_be32(0x00100000)
133 141
134/* primary execution unit select */ 142/* primary execution unit select */
135#define DESC_HDR_SEL0_MASK __constant_cpu_to_be32(0xf0000000) 143#define DESC_HDR_SEL0_MASK cpu_to_be32(0xf0000000)
136#define DESC_HDR_SEL0_AFEU __constant_cpu_to_be32(0x10000000) 144#define DESC_HDR_SEL0_AFEU cpu_to_be32(0x10000000)
137#define DESC_HDR_SEL0_DEU __constant_cpu_to_be32(0x20000000) 145#define DESC_HDR_SEL0_DEU cpu_to_be32(0x20000000)
138#define DESC_HDR_SEL0_MDEUA __constant_cpu_to_be32(0x30000000) 146#define DESC_HDR_SEL0_MDEUA cpu_to_be32(0x30000000)
139#define DESC_HDR_SEL0_MDEUB __constant_cpu_to_be32(0xb0000000) 147#define DESC_HDR_SEL0_MDEUB cpu_to_be32(0xb0000000)
140#define DESC_HDR_SEL0_RNG __constant_cpu_to_be32(0x40000000) 148#define DESC_HDR_SEL0_RNG cpu_to_be32(0x40000000)
141#define DESC_HDR_SEL0_PKEU __constant_cpu_to_be32(0x50000000) 149#define DESC_HDR_SEL0_PKEU cpu_to_be32(0x50000000)
142#define DESC_HDR_SEL0_AESU __constant_cpu_to_be32(0x60000000) 150#define DESC_HDR_SEL0_AESU cpu_to_be32(0x60000000)
143#define DESC_HDR_SEL0_KEU __constant_cpu_to_be32(0x70000000) 151#define DESC_HDR_SEL0_KEU cpu_to_be32(0x70000000)
144#define DESC_HDR_SEL0_CRCU __constant_cpu_to_be32(0x80000000) 152#define DESC_HDR_SEL0_CRCU cpu_to_be32(0x80000000)
145 153
146/* primary execution unit mode (MODE0) and derivatives */ 154/* primary execution unit mode (MODE0) and derivatives */
147#define DESC_HDR_MODE0_ENCRYPT __constant_cpu_to_be32(0x00100000) 155#define DESC_HDR_MODE0_ENCRYPT cpu_to_be32(0x00100000)
148#define DESC_HDR_MODE0_AESU_CBC __constant_cpu_to_be32(0x00200000) 156#define DESC_HDR_MODE0_AESU_CBC cpu_to_be32(0x00200000)
149#define DESC_HDR_MODE0_DEU_CBC __constant_cpu_to_be32(0x00400000) 157#define DESC_HDR_MODE0_DEU_CBC cpu_to_be32(0x00400000)
150#define DESC_HDR_MODE0_DEU_3DES __constant_cpu_to_be32(0x00200000) 158#define DESC_HDR_MODE0_DEU_3DES cpu_to_be32(0x00200000)
151#define DESC_HDR_MODE0_MDEU_INIT __constant_cpu_to_be32(0x01000000) 159#define DESC_HDR_MODE0_MDEU_INIT cpu_to_be32(0x01000000)
152#define DESC_HDR_MODE0_MDEU_HMAC __constant_cpu_to_be32(0x00800000) 160#define DESC_HDR_MODE0_MDEU_HMAC cpu_to_be32(0x00800000)
153#define DESC_HDR_MODE0_MDEU_PAD __constant_cpu_to_be32(0x00400000) 161#define DESC_HDR_MODE0_MDEU_PAD cpu_to_be32(0x00400000)
154#define DESC_HDR_MODE0_MDEU_MD5 __constant_cpu_to_be32(0x00200000) 162#define DESC_HDR_MODE0_MDEU_MD5 cpu_to_be32(0x00200000)
155#define DESC_HDR_MODE0_MDEU_SHA256 __constant_cpu_to_be32(0x00100000) 163#define DESC_HDR_MODE0_MDEU_SHA256 cpu_to_be32(0x00100000)
156#define DESC_HDR_MODE0_MDEU_SHA1 __constant_cpu_to_be32(0x00000000) 164#define DESC_HDR_MODE0_MDEU_SHA1 cpu_to_be32(0x00000000)
157#define DESC_HDR_MODE0_MDEU_MD5_HMAC (DESC_HDR_MODE0_MDEU_MD5 | \ 165#define DESC_HDR_MODE0_MDEU_MD5_HMAC (DESC_HDR_MODE0_MDEU_MD5 | \
158 DESC_HDR_MODE0_MDEU_HMAC) 166 DESC_HDR_MODE0_MDEU_HMAC)
159#define DESC_HDR_MODE0_MDEU_SHA256_HMAC (DESC_HDR_MODE0_MDEU_SHA256 | \ 167#define DESC_HDR_MODE0_MDEU_SHA256_HMAC (DESC_HDR_MODE0_MDEU_SHA256 | \
@@ -162,18 +170,19 @@
162 DESC_HDR_MODE0_MDEU_HMAC) 170 DESC_HDR_MODE0_MDEU_HMAC)
163 171
164/* secondary execution unit select (SEL1) */ 172/* secondary execution unit select (SEL1) */
165#define DESC_HDR_SEL1_MASK __constant_cpu_to_be32(0x000f0000) 173#define DESC_HDR_SEL1_MASK cpu_to_be32(0x000f0000)
166#define DESC_HDR_SEL1_MDEUA __constant_cpu_to_be32(0x00030000) 174#define DESC_HDR_SEL1_MDEUA cpu_to_be32(0x00030000)
167#define DESC_HDR_SEL1_MDEUB __constant_cpu_to_be32(0x000b0000) 175#define DESC_HDR_SEL1_MDEUB cpu_to_be32(0x000b0000)
168#define DESC_HDR_SEL1_CRCU __constant_cpu_to_be32(0x00080000) 176#define DESC_HDR_SEL1_CRCU cpu_to_be32(0x00080000)
169 177
170/* secondary execution unit mode (MODE1) and derivatives */ 178/* secondary execution unit mode (MODE1) and derivatives */
171#define DESC_HDR_MODE1_MDEU_INIT __constant_cpu_to_be32(0x00001000) 179#define DESC_HDR_MODE1_MDEU_CICV cpu_to_be32(0x00004000)
172#define DESC_HDR_MODE1_MDEU_HMAC __constant_cpu_to_be32(0x00000800) 180#define DESC_HDR_MODE1_MDEU_INIT cpu_to_be32(0x00001000)
173#define DESC_HDR_MODE1_MDEU_PAD __constant_cpu_to_be32(0x00000400) 181#define DESC_HDR_MODE1_MDEU_HMAC cpu_to_be32(0x00000800)
174#define DESC_HDR_MODE1_MDEU_MD5 __constant_cpu_to_be32(0x00000200) 182#define DESC_HDR_MODE1_MDEU_PAD cpu_to_be32(0x00000400)
175#define DESC_HDR_MODE1_MDEU_SHA256 __constant_cpu_to_be32(0x00000100) 183#define DESC_HDR_MODE1_MDEU_MD5 cpu_to_be32(0x00000200)
176#define DESC_HDR_MODE1_MDEU_SHA1 __constant_cpu_to_be32(0x00000000) 184#define DESC_HDR_MODE1_MDEU_SHA256 cpu_to_be32(0x00000100)
185#define DESC_HDR_MODE1_MDEU_SHA1 cpu_to_be32(0x00000000)
177#define DESC_HDR_MODE1_MDEU_MD5_HMAC (DESC_HDR_MODE1_MDEU_MD5 | \ 186#define DESC_HDR_MODE1_MDEU_MD5_HMAC (DESC_HDR_MODE1_MDEU_MD5 | \
178 DESC_HDR_MODE1_MDEU_HMAC) 187 DESC_HDR_MODE1_MDEU_HMAC)
179#define DESC_HDR_MODE1_MDEU_SHA256_HMAC (DESC_HDR_MODE1_MDEU_SHA256 | \ 188#define DESC_HDR_MODE1_MDEU_SHA256_HMAC (DESC_HDR_MODE1_MDEU_SHA256 | \
@@ -182,16 +191,16 @@
182 DESC_HDR_MODE1_MDEU_HMAC) 191 DESC_HDR_MODE1_MDEU_HMAC)
183 192
184/* direction of overall data flow (DIR) */ 193/* direction of overall data flow (DIR) */
185#define DESC_HDR_DIR_INBOUND __constant_cpu_to_be32(0x00000002) 194#define DESC_HDR_DIR_INBOUND cpu_to_be32(0x00000002)
186 195
187/* request done notification (DN) */ 196/* request done notification (DN) */
188#define DESC_HDR_DONE_NOTIFY __constant_cpu_to_be32(0x00000001) 197#define DESC_HDR_DONE_NOTIFY cpu_to_be32(0x00000001)
189 198
190/* descriptor types */ 199/* descriptor types */
191#define DESC_HDR_TYPE_AESU_CTR_NONSNOOP __constant_cpu_to_be32(0 << 3) 200#define DESC_HDR_TYPE_AESU_CTR_NONSNOOP cpu_to_be32(0 << 3)
192#define DESC_HDR_TYPE_IPSEC_ESP __constant_cpu_to_be32(1 << 3) 201#define DESC_HDR_TYPE_IPSEC_ESP cpu_to_be32(1 << 3)
193#define DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU __constant_cpu_to_be32(2 << 3) 202#define DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU cpu_to_be32(2 << 3)
194#define DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU __constant_cpu_to_be32(4 << 3) 203#define DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU cpu_to_be32(4 << 3)
195 204
196/* link table extent field bits */ 205/* link table extent field bits */
197#define DESC_PTR_LNKTBL_JUMP 0x80 206#define DESC_PTR_LNKTBL_JUMP 0x80
diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c
index 3384a717fec0..6c3d60b939bf 100644
--- a/drivers/i2c/busses/i2c-sh_mobile.c
+++ b/drivers/i2c/busses/i2c-sh_mobile.c
@@ -160,9 +160,39 @@ struct sh_mobile_i2c_data {
160 160
161static void activate_ch(struct sh_mobile_i2c_data *pd) 161static void activate_ch(struct sh_mobile_i2c_data *pd)
162{ 162{
163 unsigned long i2c_clk;
164 u_int32_t num;
165 u_int32_t denom;
166 u_int32_t tmp;
167
163 /* Make sure the clock is enabled */ 168 /* Make sure the clock is enabled */
164 clk_enable(pd->clk); 169 clk_enable(pd->clk);
165 170
171 /* Get clock rate after clock is enabled */
172 i2c_clk = clk_get_rate(pd->clk);
173
174 /* Calculate the value for iccl. From the data sheet:
175 * iccl = (p clock / transfer rate) * (L / (L + H))
176 * where L and H are the SCL low/high ratio (5/4 in this case).
177 * We also round off the result.
178 */
179 num = i2c_clk * 5;
180 denom = NORMAL_SPEED * 9;
181 tmp = num * 10 / denom;
182 if (tmp % 10 >= 5)
183 pd->iccl = (u_int8_t)((num/denom) + 1);
184 else
185 pd->iccl = (u_int8_t)(num/denom);
186
187 /* Calculate the value for icch. From the data sheet:
188 icch = (p clock / transfer rate) * (H / (L + H)) */
189 num = i2c_clk * 4;
190 tmp = num * 10 / denom;
191 if (tmp % 10 >= 5)
192 pd->icch = (u_int8_t)((num/denom) + 1);
193 else
194 pd->icch = (u_int8_t)(num/denom);
195
166 /* Enable channel and configure rx ack */ 196 /* Enable channel and configure rx ack */
167 iowrite8(ioread8(ICCR(pd)) | ICCR_ICE, ICCR(pd)); 197 iowrite8(ioread8(ICCR(pd)) | ICCR_ICE, ICCR(pd));
168 198
@@ -459,40 +489,6 @@ static struct i2c_algorithm sh_mobile_i2c_algorithm = {
459 .master_xfer = sh_mobile_i2c_xfer, 489 .master_xfer = sh_mobile_i2c_xfer,
460}; 490};
461 491
462static void sh_mobile_i2c_setup_channel(struct platform_device *dev)
463{
464 struct sh_mobile_i2c_data *pd = platform_get_drvdata(dev);
465 unsigned long peripheral_clk = clk_get_rate(pd->clk);
466 u_int32_t num;
467 u_int32_t denom;
468 u_int32_t tmp;
469
470 spin_lock_init(&pd->lock);
471 init_waitqueue_head(&pd->wait);
472
473 /* Calculate the value for iccl. From the data sheet:
474 * iccl = (p clock / transfer rate) * (L / (L + H))
475 * where L and H are the SCL low/high ratio (5/4 in this case).
476 * We also round off the result.
477 */
478 num = peripheral_clk * 5;
479 denom = NORMAL_SPEED * 9;
480 tmp = num * 10 / denom;
481 if (tmp % 10 >= 5)
482 pd->iccl = (u_int8_t)((num/denom) + 1);
483 else
484 pd->iccl = (u_int8_t)(num/denom);
485
486 /* Calculate the value for icch. From the data sheet:
487 icch = (p clock / transfer rate) * (H / (L + H)) */
488 num = peripheral_clk * 4;
489 tmp = num * 10 / denom;
490 if (tmp % 10 >= 5)
491 pd->icch = (u_int8_t)((num/denom) + 1);
492 else
493 pd->icch = (u_int8_t)(num/denom);
494}
495
496static int sh_mobile_i2c_hook_irqs(struct platform_device *dev, int hook) 492static int sh_mobile_i2c_hook_irqs(struct platform_device *dev, int hook)
497{ 493{
498 struct resource *res; 494 struct resource *res;
@@ -533,6 +529,7 @@ static int sh_mobile_i2c_probe(struct platform_device *dev)
533 struct sh_mobile_i2c_data *pd; 529 struct sh_mobile_i2c_data *pd;
534 struct i2c_adapter *adap; 530 struct i2c_adapter *adap;
535 struct resource *res; 531 struct resource *res;
532 char clk_name[8];
536 int size; 533 int size;
537 int ret; 534 int ret;
538 535
@@ -542,9 +539,10 @@ static int sh_mobile_i2c_probe(struct platform_device *dev)
542 return -ENOMEM; 539 return -ENOMEM;
543 } 540 }
544 541
545 pd->clk = clk_get(&dev->dev, "peripheral_clk"); 542 snprintf(clk_name, sizeof(clk_name), "i2c%d", dev->id);
543 pd->clk = clk_get(&dev->dev, clk_name);
546 if (IS_ERR(pd->clk)) { 544 if (IS_ERR(pd->clk)) {
547 dev_err(&dev->dev, "cannot get peripheral clock\n"); 545 dev_err(&dev->dev, "cannot get clock \"%s\"\n", clk_name);
548 ret = PTR_ERR(pd->clk); 546 ret = PTR_ERR(pd->clk);
549 goto err; 547 goto err;
550 } 548 }
@@ -586,7 +584,8 @@ static int sh_mobile_i2c_probe(struct platform_device *dev)
586 584
587 strlcpy(adap->name, dev->name, sizeof(adap->name)); 585 strlcpy(adap->name, dev->name, sizeof(adap->name));
588 586
589 sh_mobile_i2c_setup_channel(dev); 587 spin_lock_init(&pd->lock);
588 init_waitqueue_head(&pd->wait);
590 589
591 ret = i2c_add_numbered_adapter(adap); 590 ret = i2c_add_numbered_adapter(adap);
592 if (ret < 0) { 591 if (ret < 0) {
diff --git a/drivers/input/keyboard/sh_keysc.c b/drivers/input/keyboard/sh_keysc.c
index c600ab7f93e8..5c8a1bcf7ca7 100644
--- a/drivers/input/keyboard/sh_keysc.c
+++ b/drivers/input/keyboard/sh_keysc.c
@@ -18,6 +18,7 @@
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/platform_device.h> 19#include <linux/platform_device.h>
20#include <linux/input.h> 20#include <linux/input.h>
21#include <linux/clk.h>
21#include <linux/io.h> 22#include <linux/io.h>
22#include <asm/sh_keysc.h> 23#include <asm/sh_keysc.h>
23 24
@@ -39,6 +40,7 @@ static const struct {
39 40
40struct sh_keysc_priv { 41struct sh_keysc_priv {
41 void __iomem *iomem_base; 42 void __iomem *iomem_base;
43 struct clk *clk;
42 unsigned long last_keys; 44 unsigned long last_keys;
43 struct input_dev *input; 45 struct input_dev *input;
44 struct sh_keysc_info pdata; 46 struct sh_keysc_info pdata;
@@ -125,6 +127,7 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev)
125 struct sh_keysc_info *pdata; 127 struct sh_keysc_info *pdata;
126 struct resource *res; 128 struct resource *res;
127 struct input_dev *input; 129 struct input_dev *input;
130 char clk_name[8];
128 int i, k; 131 int i, k;
129 int irq, error; 132 int irq, error;
130 133
@@ -165,11 +168,19 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev)
165 goto err1; 168 goto err1;
166 } 169 }
167 170
171 snprintf(clk_name, sizeof(clk_name), "keysc%d", pdev->id);
172 priv->clk = clk_get(&pdev->dev, clk_name);
173 if (IS_ERR(priv->clk)) {
174 dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
175 error = PTR_ERR(priv->clk);
176 goto err2;
177 }
178
168 priv->input = input_allocate_device(); 179 priv->input = input_allocate_device();
169 if (!priv->input) { 180 if (!priv->input) {
170 dev_err(&pdev->dev, "failed to allocate input device\n"); 181 dev_err(&pdev->dev, "failed to allocate input device\n");
171 error = -ENOMEM; 182 error = -ENOMEM;
172 goto err2; 183 goto err3;
173 } 184 }
174 185
175 input = priv->input; 186 input = priv->input;
@@ -187,7 +198,7 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev)
187 error = request_irq(irq, sh_keysc_isr, 0, pdev->name, pdev); 198 error = request_irq(irq, sh_keysc_isr, 0, pdev->name, pdev);
188 if (error) { 199 if (error) {
189 dev_err(&pdev->dev, "failed to request IRQ\n"); 200 dev_err(&pdev->dev, "failed to request IRQ\n");
190 goto err3; 201 goto err4;
191 } 202 }
192 203
193 for (i = 0; i < SH_KEYSC_MAXKEYS; i++) { 204 for (i = 0; i < SH_KEYSC_MAXKEYS; i++) {
@@ -199,18 +210,22 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev)
199 error = input_register_device(input); 210 error = input_register_device(input);
200 if (error) { 211 if (error) {
201 dev_err(&pdev->dev, "failed to register input device\n"); 212 dev_err(&pdev->dev, "failed to register input device\n");
202 goto err4; 213 goto err5;
203 } 214 }
204 215
216 clk_enable(priv->clk);
217
205 iowrite16((sh_keysc_mode[pdata->mode].kymd << 8) | 218 iowrite16((sh_keysc_mode[pdata->mode].kymd << 8) |
206 pdata->scan_timing, priv->iomem_base + KYCR1_OFFS); 219 pdata->scan_timing, priv->iomem_base + KYCR1_OFFS);
207 iowrite16(0, priv->iomem_base + KYOUTDR_OFFS); 220 iowrite16(0, priv->iomem_base + KYOUTDR_OFFS);
208 iowrite16(KYCR2_IRQ_LEVEL, priv->iomem_base + KYCR2_OFFS); 221 iowrite16(KYCR2_IRQ_LEVEL, priv->iomem_base + KYCR2_OFFS);
209 return 0; 222 return 0;
210 err4: 223 err5:
211 free_irq(irq, pdev); 224 free_irq(irq, pdev);
212 err3: 225 err4:
213 input_free_device(input); 226 input_free_device(input);
227 err3:
228 clk_put(priv->clk);
214 err2: 229 err2:
215 iounmap(priv->iomem_base); 230 iounmap(priv->iomem_base);
216 err1: 231 err1:
@@ -230,6 +245,9 @@ static int __devexit sh_keysc_remove(struct platform_device *pdev)
230 free_irq(platform_get_irq(pdev, 0), pdev); 245 free_irq(platform_get_irq(pdev, 0), pdev);
231 iounmap(priv->iomem_base); 246 iounmap(priv->iomem_base);
232 247
248 clk_disable(priv->clk);
249 clk_put(priv->clk);
250
233 platform_set_drvdata(pdev, NULL); 251 platform_set_drvdata(pdev, NULL);
234 kfree(priv); 252 kfree(priv);
235 return 0; 253 return 0;
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 47102c2c8250..057fd7e160c4 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -759,7 +759,7 @@ config VIDEO_PXA27x
759 759
760config VIDEO_SH_MOBILE_CEU 760config VIDEO_SH_MOBILE_CEU
761 tristate "SuperH Mobile CEU Interface driver" 761 tristate "SuperH Mobile CEU Interface driver"
762 depends on VIDEO_DEV && SOC_CAMERA && HAS_DMA 762 depends on VIDEO_DEV && SOC_CAMERA && HAS_DMA && HAVE_CLK
763 select VIDEOBUF_DMA_CONTIG 763 select VIDEOBUF_DMA_CONTIG
764 ---help--- 764 ---help---
765 This is a v4l2 driver for the SuperH Mobile CEU Interface 765 This is a v4l2 driver for the SuperH Mobile CEU Interface
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index 2407607f2eff..536b1a9b310c 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -31,6 +31,7 @@
31#include <linux/platform_device.h> 31#include <linux/platform_device.h>
32#include <linux/mutex.h> 32#include <linux/mutex.h>
33#include <linux/videodev2.h> 33#include <linux/videodev2.h>
34#include <linux/clk.h>
34 35
35#include <media/v4l2-common.h> 36#include <media/v4l2-common.h>
36#include <media/v4l2-dev.h> 37#include <media/v4l2-dev.h>
@@ -89,6 +90,7 @@ struct sh_mobile_ceu_dev {
89 90
90 unsigned int irq; 91 unsigned int irq;
91 void __iomem *base; 92 void __iomem *base;
93 struct clk *clk;
92 unsigned long video_limit; 94 unsigned long video_limit;
93 95
94 /* lock used to protect videobuf */ 96 /* lock used to protect videobuf */
@@ -309,6 +311,8 @@ static int sh_mobile_ceu_add_device(struct soc_camera_device *icd)
309 if (ret) 311 if (ret)
310 goto err; 312 goto err;
311 313
314 clk_enable(pcdev->clk);
315
312 ceu_write(pcdev, CAPSR, 1 << 16); /* reset */ 316 ceu_write(pcdev, CAPSR, 1 << 16); /* reset */
313 while (ceu_read(pcdev, CSTSR) & 1) 317 while (ceu_read(pcdev, CSTSR) & 1)
314 msleep(1); 318 msleep(1);
@@ -342,6 +346,8 @@ static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd)
342 } 346 }
343 spin_unlock_irqrestore(&pcdev->lock, flags); 347 spin_unlock_irqrestore(&pcdev->lock, flags);
344 348
349 clk_disable(pcdev->clk);
350
345 icd->ops->release(icd); 351 icd->ops->release(icd);
346 352
347 dev_info(&icd->dev, 353 dev_info(&icd->dev,
@@ -550,6 +556,7 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev)
550 struct sh_mobile_ceu_dev *pcdev; 556 struct sh_mobile_ceu_dev *pcdev;
551 struct resource *res; 557 struct resource *res;
552 void __iomem *base; 558 void __iomem *base;
559 char clk_name[8];
553 unsigned int irq; 560 unsigned int irq;
554 int err = 0; 561 int err = 0;
555 562
@@ -615,6 +622,14 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev)
615 goto exit_release_mem; 622 goto exit_release_mem;
616 } 623 }
617 624
625 snprintf(clk_name, sizeof(clk_name), "ceu%d", pdev->id);
626 pcdev->clk = clk_get(&pdev->dev, clk_name);
627 if (IS_ERR(pcdev->clk)) {
628 dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
629 err = PTR_ERR(pcdev->clk);
630 goto exit_free_irq;
631 }
632
618 pcdev->ici.priv = pcdev; 633 pcdev->ici.priv = pcdev;
619 pcdev->ici.dev.parent = &pdev->dev; 634 pcdev->ici.dev.parent = &pdev->dev;
620 pcdev->ici.nr = pdev->id; 635 pcdev->ici.nr = pdev->id;
@@ -623,10 +638,12 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev)
623 638
624 err = soc_camera_host_register(&pcdev->ici); 639 err = soc_camera_host_register(&pcdev->ici);
625 if (err) 640 if (err)
626 goto exit_free_irq; 641 goto exit_free_clk;
627 642
628 return 0; 643 return 0;
629 644
645exit_free_clk:
646 clk_put(pcdev->clk);
630exit_free_irq: 647exit_free_irq:
631 free_irq(pcdev->irq, pcdev); 648 free_irq(pcdev->irq, pcdev);
632exit_release_mem: 649exit_release_mem:
@@ -645,6 +662,7 @@ static int sh_mobile_ceu_remove(struct platform_device *pdev)
645 struct sh_mobile_ceu_dev *pcdev = platform_get_drvdata(pdev); 662 struct sh_mobile_ceu_dev *pcdev = platform_get_drvdata(pdev);
646 663
647 soc_camera_host_unregister(&pcdev->ici); 664 soc_camera_host_unregister(&pcdev->ici);
665 clk_put(pcdev->clk);
648 free_irq(pcdev->irq, pcdev); 666 free_irq(pcdev->irq, pcdev);
649 if (platform_get_resource(pdev, IORESOURCE_MEM, 1)) 667 if (platform_get_resource(pdev, IORESOURCE_MEM, 1))
650 dma_release_declared_memory(&pdev->dev); 668 dma_release_declared_memory(&pdev->dev);
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c
index 165fc010978c..557b54ab2f25 100644
--- a/drivers/serial/sh-sci.c
+++ b/drivers/serial/sh-sci.c
@@ -51,7 +51,6 @@
51#ifdef CONFIG_SUPERH 51#ifdef CONFIG_SUPERH
52#include <asm/clock.h> 52#include <asm/clock.h>
53#include <asm/sh_bios.h> 53#include <asm/sh_bios.h>
54#include <asm/kgdb.h>
55#endif 54#endif
56 55
57#include "sh-sci.h" 56#include "sh-sci.h"
@@ -65,10 +64,6 @@ struct sci_port {
65 /* Port IRQs: ERI, RXI, TXI, BRI (optional) */ 64 /* Port IRQs: ERI, RXI, TXI, BRI (optional) */
66 unsigned int irqs[SCIx_NR_IRQS]; 65 unsigned int irqs[SCIx_NR_IRQS];
67 66
68 /* Port pin configuration */
69 void (*init_pins)(struct uart_port *port,
70 unsigned int cflag);
71
72 /* Port enable callback */ 67 /* Port enable callback */
73 void (*enable)(struct uart_port *port); 68 void (*enable)(struct uart_port *port);
74 69
@@ -85,10 +80,6 @@ struct sci_port {
85#endif 80#endif
86}; 81};
87 82
88#ifdef CONFIG_SH_KGDB
89static struct sci_port *kgdb_sci_port;
90#endif
91
92#ifdef CONFIG_SERIAL_SH_SCI_CONSOLE 83#ifdef CONFIG_SERIAL_SH_SCI_CONSOLE
93static struct sci_port *serial_console_port; 84static struct sci_port *serial_console_port;
94#endif 85#endif
@@ -101,21 +92,26 @@ static void sci_stop_tx(struct uart_port *port);
101static struct sci_port sci_ports[SCI_NPORTS]; 92static struct sci_port sci_ports[SCI_NPORTS];
102static struct uart_driver sci_uart_driver; 93static struct uart_driver sci_uart_driver;
103 94
104#if defined(CONFIG_SERIAL_SH_SCI_CONSOLE) && \ 95static inline struct sci_port *
105 defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB) 96to_sci_port(struct uart_port *uart)
97{
98 return container_of(uart, struct sci_port, port);
99}
100
101#if defined(CONFIG_CONSOLE_POLL) || defined(CONFIG_SERIAL_SH_SCI_CONSOLE)
102
103#ifdef CONFIG_CONSOLE_POLL
106static inline void handle_error(struct uart_port *port) 104static inline void handle_error(struct uart_port *port)
107{ 105{
108 /* Clear error flags */ 106 /* Clear error flags */
109 sci_out(port, SCxSR, SCxSR_ERROR_CLEAR(port)); 107 sci_out(port, SCxSR, SCxSR_ERROR_CLEAR(port));
110} 108}
111 109
112static int get_char(struct uart_port *port) 110static int sci_poll_get_char(struct uart_port *port)
113{ 111{
114 unsigned long flags;
115 unsigned short status; 112 unsigned short status;
116 int c; 113 int c;
117 114
118 spin_lock_irqsave(&port->lock, flags);
119 do { 115 do {
120 status = sci_in(port, SCxSR); 116 status = sci_in(port, SCxSR);
121 if (status & SCxSR_ERRORS(port)) { 117 if (status & SCxSR_ERRORS(port)) {
@@ -123,23 +119,21 @@ static int get_char(struct uart_port *port)
123 continue; 119 continue;
124 } 120 }
125 } while (!(status & SCxSR_RDxF(port))); 121 } while (!(status & SCxSR_RDxF(port)));
122
126 c = sci_in(port, SCxRDR); 123 c = sci_in(port, SCxRDR);
127 sci_in(port, SCxSR); /* Dummy read */ 124
125 /* Dummy read */
126 sci_in(port, SCxSR);
128 sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port)); 127 sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
129 spin_unlock_irqrestore(&port->lock, flags);
130 128
131 return c; 129 return c;
132} 130}
133#endif /* CONFIG_SH_STANDARD_BIOS || CONFIG_SH_KGDB */ 131#endif
134 132
135#if defined(CONFIG_SERIAL_SH_SCI_CONSOLE) || defined(CONFIG_SH_KGDB) 133static void sci_poll_put_char(struct uart_port *port, unsigned char c)
136static void put_char(struct uart_port *port, char c)
137{ 134{
138 unsigned long flags;
139 unsigned short status; 135 unsigned short status;
140 136
141 spin_lock_irqsave(&port->lock, flags);
142
143 do { 137 do {
144 status = sci_in(port, SCxSR); 138 status = sci_in(port, SCxSR);
145 } while (!(status & SCxSR_TDxE(port))); 139 } while (!(status & SCxSR_TDxE(port)));
@@ -147,96 +141,22 @@ static void put_char(struct uart_port *port, char c)
147 sci_in(port, SCxSR); /* Dummy read */ 141 sci_in(port, SCxSR); /* Dummy read */
148 sci_out(port, SCxSR, SCxSR_TDxE_CLEAR(port)); 142 sci_out(port, SCxSR, SCxSR_TDxE_CLEAR(port));
149 sci_out(port, SCxTDR, c); 143 sci_out(port, SCxTDR, c);
150
151 spin_unlock_irqrestore(&port->lock, flags);
152} 144}
153#endif 145#endif /* CONFIG_CONSOLE_POLL || CONFIG_SERIAL_SH_SCI_CONSOLE */
154
155#ifdef CONFIG_SERIAL_SH_SCI_CONSOLE
156static void put_string(struct sci_port *sci_port, const char *buffer, int count)
157{
158 struct uart_port *port = &sci_port->port;
159 const unsigned char *p = buffer;
160 int i;
161
162#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB)
163 int checksum;
164 int usegdb=0;
165
166#ifdef CONFIG_SH_STANDARD_BIOS
167 /* This call only does a trap the first time it is
168 * called, and so is safe to do here unconditionally
169 */
170 usegdb |= sh_bios_in_gdb_mode();
171#endif
172#ifdef CONFIG_SH_KGDB
173 usegdb |= (kgdb_in_gdb_mode && (sci_port == kgdb_sci_port));
174#endif
175
176 if (usegdb) {
177 /* $<packet info>#<checksum>. */
178 do {
179 unsigned char c;
180 put_char(port, '$');
181 put_char(port, 'O'); /* 'O'utput to console */
182 checksum = 'O';
183
184 for (i=0; i<count; i++) { /* Don't use run length encoding */
185 int h, l;
186
187 c = *p++;
188 h = hex_asc_hi(c);
189 l = hex_asc_lo(c);
190 put_char(port, h);
191 put_char(port, l);
192 checksum += h + l;
193 }
194 put_char(port, '#');
195 put_char(port, hex_asc_hi(checksum));
196 put_char(port, hex_asc_lo(checksum));
197 } while (get_char(port) != '+');
198 } else
199#endif /* CONFIG_SH_STANDARD_BIOS || CONFIG_SH_KGDB */
200 for (i=0; i<count; i++) {
201 if (*p == 10)
202 put_char(port, '\r');
203 put_char(port, *p++);
204 }
205}
206#endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */
207
208#ifdef CONFIG_SH_KGDB
209static int kgdb_sci_getchar(void)
210{
211 int c;
212
213 /* Keep trying to read a character, this could be neater */
214 while ((c = get_char(&kgdb_sci_port->port)) < 0)
215 cpu_relax();
216
217 return c;
218}
219
220static inline void kgdb_sci_putchar(int c)
221{
222 put_char(&kgdb_sci_port->port, c);
223}
224#endif /* CONFIG_SH_KGDB */
225 146
226#if defined(__H8300S__) 147#if defined(__H8300S__)
227enum { sci_disable, sci_enable }; 148enum { sci_disable, sci_enable };
228 149
229static void h8300_sci_config(struct uart_port* port, unsigned int ctrl) 150static void h8300_sci_config(struct uart_port *port, unsigned int ctrl)
230{ 151{
231 volatile unsigned char *mstpcrl=(volatile unsigned char *)MSTPCRL; 152 volatile unsigned char *mstpcrl = (volatile unsigned char *)MSTPCRL;
232 int ch = (port->mapbase - SMR0) >> 3; 153 int ch = (port->mapbase - SMR0) >> 3;
233 unsigned char mask = 1 << (ch+1); 154 unsigned char mask = 1 << (ch+1);
234 155
235 if (ctrl == sci_disable) { 156 if (ctrl == sci_disable)
236 *mstpcrl |= mask; 157 *mstpcrl |= mask;
237 } else { 158 else
238 *mstpcrl &= ~mask; 159 *mstpcrl &= ~mask;
239 }
240} 160}
241 161
242static inline void h8300_sci_enable(struct uart_port *port) 162static inline void h8300_sci_enable(struct uart_port *port)
@@ -251,7 +171,7 @@ static inline void h8300_sci_disable(struct uart_port *port)
251#endif 171#endif
252 172
253#if defined(__H8300H__) || defined(__H8300S__) 173#if defined(__H8300H__) || defined(__H8300S__)
254static void sci_init_pins_sci(struct uart_port* port, unsigned int cflag) 174static void sci_init_pins(struct uart_port *port, unsigned int cflag)
255{ 175{
256 int ch = (port->mapbase - SMR0) >> 3; 176 int ch = (port->mapbase - SMR0) >> 3;
257 177
@@ -266,141 +186,99 @@ static void sci_init_pins_sci(struct uart_port* port, unsigned int cflag)
266 /* tx mark output*/ 186 /* tx mark output*/
267 H8300_SCI_DR(ch) |= h8300_sci_pins[ch].tx; 187 H8300_SCI_DR(ch) |= h8300_sci_pins[ch].tx;
268} 188}
269#else 189#elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712)
270#define sci_init_pins_sci NULL 190static inline void sci_init_pins(struct uart_port *port, unsigned int cflag)
271#endif
272
273#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709)
274static void sci_init_pins_irda(struct uart_port *port, unsigned int cflag)
275{ 191{
276 unsigned int fcr_val = 0; 192 if (port->mapbase == 0xA4400000) {
277 193 __raw_writew(__raw_readw(PACR) & 0xffc0, PACR);
278 if (cflag & CRTSCTS) 194 __raw_writew(__raw_readw(PBCR) & 0x0fff, PBCR);
279 fcr_val |= SCFCR_MCE; 195 } else if (port->mapbase == 0xA4410000)
280 196 __raw_writew(__raw_readw(PBCR) & 0xf003, PBCR);
281 sci_out(port, SCFCR, fcr_val);
282}
283#else
284#define sci_init_pins_irda NULL
285#endif
286
287#if defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712)
288static void sci_init_pins_scif(struct uart_port* port, unsigned int cflag)
289{
290 unsigned int fcr_val = 0;
291
292 set_sh771x_scif_pfc(port);
293 if (cflag & CRTSCTS) {
294 fcr_val |= SCFCR_MCE;
295 }
296 sci_out(port, SCFCR, fcr_val);
297} 197}
298#elif defined(CONFIG_CPU_SUBTYPE_SH7720) || defined(CONFIG_CPU_SUBTYPE_SH7721) 198#elif defined(CONFIG_CPU_SUBTYPE_SH7720) || defined(CONFIG_CPU_SUBTYPE_SH7721)
299static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) 199static inline void sci_init_pins(struct uart_port *port, unsigned int cflag)
300{ 200{
301 unsigned int fcr_val = 0;
302 unsigned short data; 201 unsigned short data;
303 202
304 if (cflag & CRTSCTS) { 203 if (cflag & CRTSCTS) {
305 /* enable RTS/CTS */ 204 /* enable RTS/CTS */
306 if (port->mapbase == 0xa4430000) { /* SCIF0 */ 205 if (port->mapbase == 0xa4430000) { /* SCIF0 */
307 /* Clear PTCR bit 9-2; enable all scif pins but sck */ 206 /* Clear PTCR bit 9-2; enable all scif pins but sck */
308 data = ctrl_inw(PORT_PTCR); 207 data = __raw_readw(PORT_PTCR);
309 ctrl_outw((data & 0xfc03), PORT_PTCR); 208 __raw_writew((data & 0xfc03), PORT_PTCR);
310 } else if (port->mapbase == 0xa4438000) { /* SCIF1 */ 209 } else if (port->mapbase == 0xa4438000) { /* SCIF1 */
311 /* Clear PVCR bit 9-2 */ 210 /* Clear PVCR bit 9-2 */
312 data = ctrl_inw(PORT_PVCR); 211 data = __raw_readw(PORT_PVCR);
313 ctrl_outw((data & 0xfc03), PORT_PVCR); 212 __raw_writew((data & 0xfc03), PORT_PVCR);
314 } 213 }
315 fcr_val |= SCFCR_MCE;
316 } else { 214 } else {
317 if (port->mapbase == 0xa4430000) { /* SCIF0 */ 215 if (port->mapbase == 0xa4430000) { /* SCIF0 */
318 /* Clear PTCR bit 5-2; enable only tx and rx */ 216 /* Clear PTCR bit 5-2; enable only tx and rx */
319 data = ctrl_inw(PORT_PTCR); 217 data = __raw_readw(PORT_PTCR);
320 ctrl_outw((data & 0xffc3), PORT_PTCR); 218 __raw_writew((data & 0xffc3), PORT_PTCR);
321 } else if (port->mapbase == 0xa4438000) { /* SCIF1 */ 219 } else if (port->mapbase == 0xa4438000) { /* SCIF1 */
322 /* Clear PVCR bit 5-2 */ 220 /* Clear PVCR bit 5-2 */
323 data = ctrl_inw(PORT_PVCR); 221 data = __raw_readw(PORT_PVCR);
324 ctrl_outw((data & 0xffc3), PORT_PVCR); 222 __raw_writew((data & 0xffc3), PORT_PVCR);
325 } 223 }
326 } 224 }
327 sci_out(port, SCFCR, fcr_val);
328} 225}
329#elif defined(CONFIG_CPU_SH3) 226#elif defined(CONFIG_CPU_SH3)
330/* For SH7705, SH7706, SH7707, SH7709, SH7709A, SH7729 */ 227/* For SH7705, SH7706, SH7707, SH7709, SH7709A, SH7729 */
331static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) 228static inline void sci_init_pins(struct uart_port *port, unsigned int cflag)
332{ 229{
333 unsigned int fcr_val = 0;
334 unsigned short data; 230 unsigned short data;
335 231
336 /* We need to set SCPCR to enable RTS/CTS */ 232 /* We need to set SCPCR to enable RTS/CTS */
337 data = ctrl_inw(SCPCR); 233 data = __raw_readw(SCPCR);
338 /* Clear out SCP7MD1,0, SCP6MD1,0, SCP4MD1,0*/ 234 /* Clear out SCP7MD1,0, SCP6MD1,0, SCP4MD1,0*/
339 ctrl_outw(data & 0x0fcf, SCPCR); 235 __raw_writew(data & 0x0fcf, SCPCR);
340 236
341 if (cflag & CRTSCTS) 237 if (!(cflag & CRTSCTS)) {
342 fcr_val |= SCFCR_MCE;
343 else {
344 /* We need to set SCPCR to enable RTS/CTS */ 238 /* We need to set SCPCR to enable RTS/CTS */
345 data = ctrl_inw(SCPCR); 239 data = __raw_readw(SCPCR);
346 /* Clear out SCP7MD1,0, SCP4MD1,0, 240 /* Clear out SCP7MD1,0, SCP4MD1,0,
347 Set SCP6MD1,0 = {01} (output) */ 241 Set SCP6MD1,0 = {01} (output) */
348 ctrl_outw((data & 0x0fcf) | 0x1000, SCPCR); 242 __raw_writew((data & 0x0fcf) | 0x1000, SCPCR);
349 243
350 data = ctrl_inb(SCPDR); 244 data = ctrl_inb(SCPDR);
351 /* Set /RTS2 (bit6) = 0 */ 245 /* Set /RTS2 (bit6) = 0 */
352 ctrl_outb(data & 0xbf, SCPDR); 246 ctrl_outb(data & 0xbf, SCPDR);
353 } 247 }
354
355 sci_out(port, SCFCR, fcr_val);
356} 248}
357#elif defined(CONFIG_CPU_SUBTYPE_SH7722) 249#elif defined(CONFIG_CPU_SUBTYPE_SH7722)
358static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) 250static inline void sci_init_pins(struct uart_port *port, unsigned int cflag)
359{ 251{
360 unsigned int fcr_val = 0;
361 unsigned short data; 252 unsigned short data;
362 253
363 if (port->mapbase == 0xffe00000) { 254 if (port->mapbase == 0xffe00000) {
364 data = ctrl_inw(PSCR); 255 data = __raw_readw(PSCR);
365 data &= ~0x03cf; 256 data &= ~0x03cf;
366 if (cflag & CRTSCTS) 257 if (!(cflag & CRTSCTS))
367 fcr_val |= SCFCR_MCE;
368 else
369 data |= 0x0340; 258 data |= 0x0340;
370 259
371 ctrl_outw(data, PSCR); 260 __raw_writew(data, PSCR);
372 } 261 }
373 /* SCIF1 and SCIF2 should be setup by board code */
374
375 sci_out(port, SCFCR, fcr_val);
376}
377#elif defined(CONFIG_CPU_SUBTYPE_SH7723)
378static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag)
379{
380 /* Nothing to do here.. */
381 sci_out(port, SCFCR, 0);
382} 262}
383#else
384/* For SH7750 */
385static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag)
386{
387 unsigned int fcr_val = 0;
388
389 if (cflag & CRTSCTS) {
390 fcr_val |= SCFCR_MCE;
391 } else {
392#if defined(CONFIG_CPU_SUBTYPE_SH7343) || defined(CONFIG_CPU_SUBTYPE_SH7366)
393 /* Nothing */
394#elif defined(CONFIG_CPU_SUBTYPE_SH7763) || \ 263#elif defined(CONFIG_CPU_SUBTYPE_SH7763) || \
395 defined(CONFIG_CPU_SUBTYPE_SH7780) || \ 264 defined(CONFIG_CPU_SUBTYPE_SH7780) || \
396 defined(CONFIG_CPU_SUBTYPE_SH7785) || \ 265 defined(CONFIG_CPU_SUBTYPE_SH7785) || \
397 defined(CONFIG_CPU_SUBTYPE_SHX3) 266 defined(CONFIG_CPU_SUBTYPE_SHX3)
398 ctrl_outw(0x0080, SCSPTR0); /* Set RTS = 1 */ 267static inline void sci_init_pins(struct uart_port *port, unsigned int cflag)
268{
269 if (!(cflag & CRTSCTS))
270 __raw_writew(0x0080, SCSPTR0); /* Set RTS = 1 */
271}
272#elif defined(CONFIG_CPU_SH4) && !defined(CONFIG_CPU_SH4A)
273static inline void sci_init_pins(struct uart_port *port, unsigned int cflag)
274{
275 if (!(cflag & CRTSCTS))
276 __raw_writew(0x0080, SCSPTR2); /* Set RTS = 1 */
277}
399#else 278#else
400 ctrl_outw(0x0080, SCSPTR2); /* Set RTS = 1 */ 279static inline void sci_init_pins(struct uart_port *port, unsigned int cflag)
401#endif 280{
402 } 281 /* Nothing to do */
403 sci_out(port, SCFCR, fcr_val);
404} 282}
405#endif 283#endif
406 284
@@ -419,18 +297,26 @@ static inline int scif_rxroom(struct uart_port *port)
419#elif defined(CONFIG_CPU_SUBTYPE_SH7763) 297#elif defined(CONFIG_CPU_SUBTYPE_SH7763)
420static inline int scif_txroom(struct uart_port *port) 298static inline int scif_txroom(struct uart_port *port)
421{ 299{
422 if((port->mapbase == 0xffe00000) || (port->mapbase == 0xffe08000)) /* SCIF0/1*/ 300 if ((port->mapbase == 0xffe00000) ||
301 (port->mapbase == 0xffe08000)) {
302 /* SCIF0/1*/
423 return SCIF_TXROOM_MAX - (sci_in(port, SCTFDR) & 0xff); 303 return SCIF_TXROOM_MAX - (sci_in(port, SCTFDR) & 0xff);
424 else /* SCIF2 */ 304 } else {
305 /* SCIF2 */
425 return SCIF2_TXROOM_MAX - (sci_in(port, SCFDR) >> 8); 306 return SCIF2_TXROOM_MAX - (sci_in(port, SCFDR) >> 8);
307 }
426} 308}
427 309
428static inline int scif_rxroom(struct uart_port *port) 310static inline int scif_rxroom(struct uart_port *port)
429{ 311{
430 if((port->mapbase == 0xffe00000) || (port->mapbase == 0xffe08000)) /* SCIF0/1*/ 312 if ((port->mapbase == 0xffe00000) ||
313 (port->mapbase == 0xffe08000)) {
314 /* SCIF0/1*/
431 return sci_in(port, SCRFDR) & 0xff; 315 return sci_in(port, SCRFDR) & 0xff;
432 else /* SCIF2 */ 316 } else {
317 /* SCIF2 */
433 return sci_in(port, SCFDR) & SCIF2_RFDC_MASK; 318 return sci_in(port, SCFDR) & SCIF2_RFDC_MASK;
319 }
434} 320}
435#else 321#else
436static inline int scif_txroom(struct uart_port *port) 322static inline int scif_txroom(struct uart_port *port)
@@ -446,12 +332,12 @@ static inline int scif_rxroom(struct uart_port *port)
446 332
447static inline int sci_txroom(struct uart_port *port) 333static inline int sci_txroom(struct uart_port *port)
448{ 334{
449 return ((sci_in(port, SCxSR) & SCI_TDRE) != 0); 335 return (sci_in(port, SCxSR) & SCI_TDRE) != 0;
450} 336}
451 337
452static inline int sci_rxroom(struct uart_port *port) 338static inline int sci_rxroom(struct uart_port *port)
453{ 339{
454 return ((sci_in(port, SCxSR) & SCxSR_RDxF(port)) != 0); 340 return (sci_in(port, SCxSR) & SCxSR_RDxF(port)) != 0;
455} 341}
456 342
457/* ********************************************************************** * 343/* ********************************************************************** *
@@ -469,11 +355,10 @@ static void sci_transmit_chars(struct uart_port *port)
469 status = sci_in(port, SCxSR); 355 status = sci_in(port, SCxSR);
470 if (!(status & SCxSR_TDxE(port))) { 356 if (!(status & SCxSR_TDxE(port))) {
471 ctrl = sci_in(port, SCSCR); 357 ctrl = sci_in(port, SCSCR);
472 if (uart_circ_empty(xmit)) { 358 if (uart_circ_empty(xmit))
473 ctrl &= ~SCI_CTRL_FLAGS_TIE; 359 ctrl &= ~SCI_CTRL_FLAGS_TIE;
474 } else { 360 else
475 ctrl |= SCI_CTRL_FLAGS_TIE; 361 ctrl |= SCI_CTRL_FLAGS_TIE;
476 }
477 sci_out(port, SCSCR, ctrl); 362 sci_out(port, SCSCR, ctrl);
478 return; 363 return;
479 } 364 }
@@ -521,11 +406,11 @@ static void sci_transmit_chars(struct uart_port *port)
521} 406}
522 407
523/* On SH3, SCIF may read end-of-break as a space->mark char */ 408/* On SH3, SCIF may read end-of-break as a space->mark char */
524#define STEPFN(c) ({int __c=(c); (((__c-1)|(__c)) == -1); }) 409#define STEPFN(c) ({int __c = (c); (((__c-1)|(__c)) == -1); })
525 410
526static inline void sci_receive_chars(struct uart_port *port) 411static inline void sci_receive_chars(struct uart_port *port)
527{ 412{
528 struct sci_port *sci_port = (struct sci_port *)port; 413 struct sci_port *sci_port = to_sci_port(port);
529 struct tty_struct *tty = port->info->port.tty; 414 struct tty_struct *tty = port->info->port.tty;
530 int i, count, copied = 0; 415 int i, count, copied = 0;
531 unsigned short status; 416 unsigned short status;
@@ -550,13 +435,13 @@ static inline void sci_receive_chars(struct uart_port *port)
550 435
551 if (port->type == PORT_SCI) { 436 if (port->type == PORT_SCI) {
552 char c = sci_in(port, SCxRDR); 437 char c = sci_in(port, SCxRDR);
553 if (uart_handle_sysrq_char(port, c) || sci_port->break_flag) 438 if (uart_handle_sysrq_char(port, c) ||
439 sci_port->break_flag)
554 count = 0; 440 count = 0;
555 else { 441 else
556 tty_insert_flip_char(tty, c, TTY_NORMAL); 442 tty_insert_flip_char(tty, c, TTY_NORMAL);
557 }
558 } else { 443 } else {
559 for (i=0; i<count; i++) { 444 for (i = 0; i < count; i++) {
560 char c = sci_in(port, SCxRDR); 445 char c = sci_in(port, SCxRDR);
561 status = sci_in(port, SCxSR); 446 status = sci_in(port, SCxSR);
562#if defined(CONFIG_CPU_SH3) 447#if defined(CONFIG_CPU_SH3)
@@ -569,7 +454,7 @@ static inline void sci_receive_chars(struct uart_port *port)
569 } 454 }
570 455
571 /* Nonzero => end-of-break */ 456 /* Nonzero => end-of-break */
572 pr_debug("scif: debounce<%02x>\n", c); 457 dev_dbg(port->dev, "debounce<%02x>\n", c);
573 sci_port->break_flag = 0; 458 sci_port->break_flag = 0;
574 459
575 if (STEPFN(c)) { 460 if (STEPFN(c)) {
@@ -586,12 +471,13 @@ static inline void sci_receive_chars(struct uart_port *port)
586 /* Store data and status */ 471 /* Store data and status */
587 if (status&SCxSR_FER(port)) { 472 if (status&SCxSR_FER(port)) {
588 flag = TTY_FRAME; 473 flag = TTY_FRAME;
589 pr_debug("sci: frame error\n"); 474 dev_notice(port->dev, "frame error\n");
590 } else if (status&SCxSR_PER(port)) { 475 } else if (status&SCxSR_PER(port)) {
591 flag = TTY_PARITY; 476 flag = TTY_PARITY;
592 pr_debug("sci: parity error\n"); 477 dev_notice(port->dev, "parity error\n");
593 } else 478 } else
594 flag = TTY_NORMAL; 479 flag = TTY_NORMAL;
480
595 tty_insert_flip_char(tty, c, flag); 481 tty_insert_flip_char(tty, c, flag);
596 } 482 }
597 } 483 }
@@ -651,13 +537,14 @@ static inline int sci_handle_errors(struct uart_port *port)
651 /* overrun error */ 537 /* overrun error */
652 if (tty_insert_flip_char(tty, 0, TTY_OVERRUN)) 538 if (tty_insert_flip_char(tty, 0, TTY_OVERRUN))
653 copied++; 539 copied++;
654 pr_debug("sci: overrun error\n"); 540
541 dev_notice(port->dev, "overrun error");
655 } 542 }
656 543
657 if (status & SCxSR_FER(port)) { 544 if (status & SCxSR_FER(port)) {
658 if (sci_rxd_in(port) == 0) { 545 if (sci_rxd_in(port) == 0) {
659 /* Notify of BREAK */ 546 /* Notify of BREAK */
660 struct sci_port *sci_port = (struct sci_port *)port; 547 struct sci_port *sci_port = to_sci_port(port);
661 548
662 if (!sci_port->break_flag) { 549 if (!sci_port->break_flag) {
663 sci_port->break_flag = 1; 550 sci_port->break_flag = 1;
@@ -666,15 +553,19 @@ static inline int sci_handle_errors(struct uart_port *port)
666 /* Do sysrq handling. */ 553 /* Do sysrq handling. */
667 if (uart_handle_break(port)) 554 if (uart_handle_break(port))
668 return 0; 555 return 0;
669 pr_debug("sci: BREAK detected\n"); 556
557 dev_dbg(port->dev, "BREAK detected\n");
558
670 if (tty_insert_flip_char(tty, 0, TTY_BREAK)) 559 if (tty_insert_flip_char(tty, 0, TTY_BREAK))
671 copied++; 560 copied++;
672 } 561 }
562
673 } else { 563 } else {
674 /* frame error */ 564 /* frame error */
675 if (tty_insert_flip_char(tty, 0, TTY_FRAME)) 565 if (tty_insert_flip_char(tty, 0, TTY_FRAME))
676 copied++; 566 copied++;
677 pr_debug("sci: frame error\n"); 567
568 dev_notice(port->dev, "frame error\n");
678 } 569 }
679 } 570 }
680 571
@@ -682,7 +573,8 @@ static inline int sci_handle_errors(struct uart_port *port)
682 /* parity error */ 573 /* parity error */
683 if (tty_insert_flip_char(tty, 0, TTY_PARITY)) 574 if (tty_insert_flip_char(tty, 0, TTY_PARITY))
684 copied++; 575 copied++;
685 pr_debug("sci: parity error\n"); 576
577 dev_notice(port->dev, "parity error");
686 } 578 }
687 579
688 if (copied) 580 if (copied)
@@ -691,6 +583,27 @@ static inline int sci_handle_errors(struct uart_port *port)
691 return copied; 583 return copied;
692} 584}
693 585
586static inline int sci_handle_fifo_overrun(struct uart_port *port)
587{
588 struct tty_struct *tty = port->info->port.tty;
589 int copied = 0;
590
591 if (port->type != PORT_SCIF)
592 return 0;
593
594 if ((sci_in(port, SCLSR) & SCIF_ORER) != 0) {
595 sci_out(port, SCLSR, 0);
596
597 tty_insert_flip_char(tty, 0, TTY_OVERRUN);
598 tty_flip_buffer_push(tty);
599
600 dev_notice(port->dev, "overrun error\n");
601 copied++;
602 }
603
604 return copied;
605}
606
694static inline int sci_handle_breaks(struct uart_port *port) 607static inline int sci_handle_breaks(struct uart_port *port)
695{ 608{
696 int copied = 0; 609 int copied = 0;
@@ -709,23 +622,15 @@ static inline int sci_handle_breaks(struct uart_port *port)
709 /* Notify of BREAK */ 622 /* Notify of BREAK */
710 if (tty_insert_flip_char(tty, 0, TTY_BREAK)) 623 if (tty_insert_flip_char(tty, 0, TTY_BREAK))
711 copied++; 624 copied++;
712 pr_debug("sci: BREAK detected\n");
713 }
714 625
715#if defined(SCIF_ORER) 626 dev_dbg(port->dev, "BREAK detected\n");
716 /* XXX: Handle SCIF overrun error */
717 if (port->type != PORT_SCI && (sci_in(port, SCLSR) & SCIF_ORER) != 0) {
718 sci_out(port, SCLSR, 0);
719 if (tty_insert_flip_char(tty, 0, TTY_OVERRUN)) {
720 copied++;
721 pr_debug("sci: overrun error\n");
722 }
723 } 627 }
724#endif
725 628
726 if (copied) 629 if (copied)
727 tty_flip_buffer_push(tty); 630 tty_flip_buffer_push(tty);
728 631
632 copied += sci_handle_fifo_overrun(port);
633
729 return copied; 634 return copied;
730} 635}
731 636
@@ -763,16 +668,7 @@ static irqreturn_t sci_er_interrupt(int irq, void *ptr)
763 sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port)); 668 sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
764 } 669 }
765 } else { 670 } else {
766#if defined(SCIF_ORER) 671 sci_handle_fifo_overrun(port);
767 if((sci_in(port, SCLSR) & SCIF_ORER) != 0) {
768 struct tty_struct *tty = port->info->port.tty;
769
770 sci_out(port, SCLSR, 0);
771 tty_insert_flip_char(tty, 0, TTY_OVERRUN);
772 tty_flip_buffer_push(tty);
773 pr_debug("scif: overrun error\n");
774 }
775#endif
776 sci_rx_interrupt(irq, ptr); 672 sci_rx_interrupt(irq, ptr);
777 } 673 }
778 674
@@ -801,8 +697,8 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr)
801 struct uart_port *port = ptr; 697 struct uart_port *port = ptr;
802 irqreturn_t ret = IRQ_NONE; 698 irqreturn_t ret = IRQ_NONE;
803 699
804 ssr_status = sci_in(port,SCxSR); 700 ssr_status = sci_in(port, SCxSR);
805 scr_status = sci_in(port,SCSCR); 701 scr_status = sci_in(port, SCSCR);
806 702
807 /* Tx Interrupt */ 703 /* Tx Interrupt */
808 if ((ssr_status & 0x0020) && (scr_status & SCI_CTRL_FLAGS_TIE)) 704 if ((ssr_status & 0x0020) && (scr_status & SCI_CTRL_FLAGS_TIE))
@@ -820,7 +716,7 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr)
820 return ret; 716 return ret;
821} 717}
822 718
823#if defined(CONFIG_CPU_FREQ) && defined(CONFIG_HAVE_CLK) 719#ifdef CONFIG_HAVE_CLK
824/* 720/*
825 * Here we define a transistion notifier so that we can update all of our 721 * Here we define a transistion notifier so that we can update all of our
826 * ports' baud rate when the peripheral clock changes. 722 * ports' baud rate when the peripheral clock changes.
@@ -828,41 +724,20 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr)
828static int sci_notifier(struct notifier_block *self, 724static int sci_notifier(struct notifier_block *self,
829 unsigned long phase, void *p) 725 unsigned long phase, void *p)
830{ 726{
831 struct cpufreq_freqs *freqs = p;
832 int i; 727 int i;
833 728
834 if ((phase == CPUFREQ_POSTCHANGE) || 729 if ((phase == CPUFREQ_POSTCHANGE) ||
835 (phase == CPUFREQ_RESUMECHANGE)){ 730 (phase == CPUFREQ_RESUMECHANGE))
836 for (i = 0; i < SCI_NPORTS; i++) { 731 for (i = 0; i < SCI_NPORTS; i++) {
837 struct uart_port *port = &sci_ports[i].port; 732 struct sci_port *s = &sci_ports[i];
838 struct clk *clk; 733 s->port.uartclk = clk_get_rate(s->clk);
839
840 /*
841 * Update the uartclk per-port if frequency has
842 * changed, since it will no longer necessarily be
843 * consistent with the old frequency.
844 *
845 * Really we want to be able to do something like
846 * uart_change_speed() or something along those lines
847 * here to implicitly reset the per-port baud rate..
848 *
849 * Clean this up later..
850 */
851 clk = clk_get(NULL, "module_clk");
852 port->uartclk = clk_get_rate(clk);
853 clk_put(clk);
854 } 734 }
855 735
856 printk(KERN_INFO "%s: got a postchange notification "
857 "for cpu %d (old %d, new %d)\n",
858 __func__, freqs->cpu, freqs->old, freqs->new);
859 }
860
861 return NOTIFY_OK; 736 return NOTIFY_OK;
862} 737}
863 738
864static struct notifier_block sci_nb = { &sci_notifier, NULL, 0 }; 739static struct notifier_block sci_nb = { &sci_notifier, NULL, 0 };
865#endif /* CONFIG_CPU_FREQ && CONFIG_HAVE_CLK */ 740#endif
866 741
867static int sci_request_irq(struct sci_port *port) 742static int sci_request_irq(struct sci_port *port)
868{ 743{
@@ -875,23 +750,22 @@ static int sci_request_irq(struct sci_port *port)
875 "SCI Transmit Data Empty", "SCI Break" }; 750 "SCI Transmit Data Empty", "SCI Break" };
876 751
877 if (port->irqs[0] == port->irqs[1]) { 752 if (port->irqs[0] == port->irqs[1]) {
878 if (!port->irqs[0]) { 753 if (unlikely(!port->irqs[0]))
879 printk(KERN_ERR "sci: Cannot allocate irq.(IRQ=0)\n");
880 return -ENODEV; 754 return -ENODEV;
881 }
882 755
883 if (request_irq(port->irqs[0], sci_mpxed_interrupt, 756 if (request_irq(port->irqs[0], sci_mpxed_interrupt,
884 IRQF_DISABLED, "sci", port)) { 757 IRQF_DISABLED, "sci", port)) {
885 printk(KERN_ERR "sci: Cannot allocate irq.\n"); 758 dev_err(port->port.dev, "Can't allocate IRQ\n");
886 return -ENODEV; 759 return -ENODEV;
887 } 760 }
888 } else { 761 } else {
889 for (i = 0; i < ARRAY_SIZE(handlers); i++) { 762 for (i = 0; i < ARRAY_SIZE(handlers); i++) {
890 if (!port->irqs[i]) 763 if (unlikely(!port->irqs[i]))
891 continue; 764 continue;
765
892 if (request_irq(port->irqs[i], handlers[i], 766 if (request_irq(port->irqs[i], handlers[i],
893 IRQF_DISABLED, desc[i], port)) { 767 IRQF_DISABLED, desc[i], port)) {
894 printk(KERN_ERR "sci: Cannot allocate irq.\n"); 768 dev_err(port->port.dev, "Can't allocate IRQ\n");
895 return -ENODEV; 769 return -ENODEV;
896 } 770 }
897 } 771 }
@@ -904,12 +778,9 @@ static void sci_free_irq(struct sci_port *port)
904{ 778{
905 int i; 779 int i;
906 780
907 if (port->irqs[0] == port->irqs[1]) { 781 if (port->irqs[0] == port->irqs[1])
908 if (!port->irqs[0]) 782 free_irq(port->irqs[0], port);
909 printk("sci: sci_free_irq error\n"); 783 else {
910 else
911 free_irq(port->irqs[0], port);
912 } else {
913 for (i = 0; i < ARRAY_SIZE(port->irqs); i++) { 784 for (i = 0; i < ARRAY_SIZE(port->irqs); i++) {
914 if (!port->irqs[i]) 785 if (!port->irqs[i])
915 continue; 786 continue;
@@ -1028,7 +899,6 @@ static void sci_shutdown(struct uart_port *port)
1028static void sci_set_termios(struct uart_port *port, struct ktermios *termios, 899static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
1029 struct ktermios *old) 900 struct ktermios *old)
1030{ 901{
1031 struct sci_port *s = &sci_ports[port->line];
1032 unsigned int status, baud, smr_val; 902 unsigned int status, baud, smr_val;
1033 int t = -1; 903 int t = -1;
1034 904
@@ -1060,32 +930,36 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
1060 sci_out(port, SCSMR, smr_val); 930 sci_out(port, SCSMR, smr_val);
1061 931
1062 if (t > 0) { 932 if (t > 0) {
1063 if(t >= 256) { 933 if (t >= 256) {
1064 sci_out(port, SCSMR, (sci_in(port, SCSMR) & ~3) | 1); 934 sci_out(port, SCSMR, (sci_in(port, SCSMR) & ~3) | 1);
1065 t >>= 2; 935 t >>= 2;
1066 } else { 936 } else
1067 sci_out(port, SCSMR, sci_in(port, SCSMR) & ~3); 937 sci_out(port, SCSMR, sci_in(port, SCSMR) & ~3);
1068 } 938
1069 sci_out(port, SCBRR, t); 939 sci_out(port, SCBRR, t);
1070 udelay((1000000+(baud-1)) / baud); /* Wait one bit interval */ 940 udelay((1000000+(baud-1)) / baud); /* Wait one bit interval */
1071 } 941 }
1072 942
1073 if (likely(s->init_pins)) 943 sci_init_pins(port, termios->c_cflag);
1074 s->init_pins(port, termios->c_cflag); 944 sci_out(port, SCFCR, (termios->c_cflag & CRTSCTS) ? SCFCR_MCE : 0);
1075 945
1076 sci_out(port, SCSCR, SCSCR_INIT(port)); 946 sci_out(port, SCSCR, SCSCR_INIT(port));
1077 947
1078 if ((termios->c_cflag & CREAD) != 0) 948 if ((termios->c_cflag & CREAD) != 0)
1079 sci_start_rx(port,0); 949 sci_start_rx(port, 0);
1080} 950}
1081 951
1082static const char *sci_type(struct uart_port *port) 952static const char *sci_type(struct uart_port *port)
1083{ 953{
1084 switch (port->type) { 954 switch (port->type) {
1085 case PORT_SCI: return "sci"; 955 case PORT_IRDA:
1086 case PORT_SCIF: return "scif"; 956 return "irda";
1087 case PORT_IRDA: return "irda"; 957 case PORT_SCI:
1088 case PORT_SCIFA: return "scifa"; 958 return "sci";
959 case PORT_SCIF:
960 return "scif";
961 case PORT_SCIFA:
962 return "scifa";
1089 } 963 }
1090 964
1091 return NULL; 965 return NULL;
@@ -1108,19 +982,6 @@ static void sci_config_port(struct uart_port *port, int flags)
1108 982
1109 port->type = s->type; 983 port->type = s->type;
1110 984
1111 switch (port->type) {
1112 case PORT_SCI:
1113 s->init_pins = sci_init_pins_sci;
1114 break;
1115 case PORT_SCIF:
1116 case PORT_SCIFA:
1117 s->init_pins = sci_init_pins_scif;
1118 break;
1119 case PORT_IRDA:
1120 s->init_pins = sci_init_pins_irda;
1121 break;
1122 }
1123
1124 if (port->flags & UPF_IOREMAP && !port->membase) { 985 if (port->flags & UPF_IOREMAP && !port->membase) {
1125#if defined(CONFIG_SUPERH64) 986#if defined(CONFIG_SUPERH64)
1126 port->mapbase = onchip_remap(SCIF_ADDR_SH5, 1024, "SCIF"); 987 port->mapbase = onchip_remap(SCIF_ADDR_SH5, 1024, "SCIF");
@@ -1129,7 +990,7 @@ static void sci_config_port(struct uart_port *port, int flags)
1129 port->membase = ioremap_nocache(port->mapbase, 0x40); 990 port->membase = ioremap_nocache(port->mapbase, 0x40);
1130#endif 991#endif
1131 992
1132 printk(KERN_ERR "sci: can't remap port#%d\n", port->line); 993 dev_err(port->dev, "can't remap port#%d\n", port->line);
1133 } 994 }
1134} 995}
1135 996
@@ -1163,6 +1024,10 @@ static struct uart_ops sci_uart_ops = {
1163 .request_port = sci_request_port, 1024 .request_port = sci_request_port,
1164 .config_port = sci_config_port, 1025 .config_port = sci_config_port,
1165 .verify_port = sci_verify_port, 1026 .verify_port = sci_verify_port,
1027#ifdef CONFIG_CONSOLE_POLL
1028 .poll_get_char = sci_poll_get_char,
1029 .poll_put_char = sci_poll_put_char,
1030#endif
1166}; 1031};
1167 1032
1168static void __init sci_init_ports(void) 1033static void __init sci_init_ports(void)
@@ -1229,7 +1094,15 @@ int __init early_sci_setup(struct uart_port *port)
1229static void serial_console_write(struct console *co, const char *s, 1094static void serial_console_write(struct console *co, const char *s,
1230 unsigned count) 1095 unsigned count)
1231{ 1096{
1232 put_string(serial_console_port, s, count); 1097 struct uart_port *port = &serial_console_port->port;
1098 int i;
1099
1100 for (i = 0; i < count; i++) {
1101 if (*s == 10)
1102 sci_poll_put_char(port, '\r');
1103
1104 sci_poll_put_char(port, *s++);
1105 }
1233} 1106}
1234 1107
1235static int __init serial_console_setup(struct console *co, char *options) 1108static int __init serial_console_setup(struct console *co, char *options)
@@ -1307,89 +1180,8 @@ static int __init sci_console_init(void)
1307console_initcall(sci_console_init); 1180console_initcall(sci_console_init);
1308#endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */ 1181#endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */
1309 1182
1310#ifdef CONFIG_SH_KGDB_CONSOLE 1183#if defined(CONFIG_SERIAL_SH_SCI_CONSOLE)
1311/* 1184#define SCI_CONSOLE (&serial_console)
1312 * FIXME: Most of this can go away.. at the moment, we rely on
1313 * arch/sh/kernel/setup.c to do the command line parsing for kgdb, though
1314 * most of that can easily be done here instead.
1315 *
1316 * For the time being, just accept the values that were parsed earlier..
1317 */
1318static void __init kgdb_console_get_options(struct uart_port *port, int *baud,
1319 int *parity, int *bits)
1320{
1321 *baud = kgdb_baud;
1322 *parity = tolower(kgdb_parity);
1323 *bits = kgdb_bits - '0';
1324}
1325
1326/*
1327 * The naming here is somewhat misleading, since kgdb_console_setup() takes
1328 * care of the early-on initialization for kgdb, regardless of whether we
1329 * actually use kgdb as a console or not.
1330 *
1331 * On the plus side, this lets us kill off the old kgdb_sci_setup() nonsense.
1332 */
1333int __init kgdb_console_setup(struct console *co, char *options)
1334{
1335 struct uart_port *port = &sci_ports[kgdb_portnum].port;
1336 int baud = 38400;
1337 int bits = 8;
1338 int parity = 'n';
1339 int flow = 'n';
1340
1341 if (co->index != kgdb_portnum)
1342 co->index = kgdb_portnum;
1343
1344 kgdb_sci_port = &sci_ports[co->index];
1345 port = &kgdb_sci_port->port;
1346
1347 /*
1348 * Also need to check port->type, we don't actually have any
1349 * UPIO_PORT ports, but uart_report_port() handily misreports
1350 * it anyways if we don't have a port available by the time this is
1351 * called.
1352 */
1353 if (!port->type)
1354 return -ENODEV;
1355 if (!port->membase || !port->mapbase)
1356 return -ENODEV;
1357
1358 if (options)
1359 uart_parse_options(options, &baud, &parity, &bits, &flow);
1360 else
1361 kgdb_console_get_options(port, &baud, &parity, &bits);
1362
1363 kgdb_getchar = kgdb_sci_getchar;
1364 kgdb_putchar = kgdb_sci_putchar;
1365
1366 return uart_set_options(port, co, baud, parity, bits, flow);
1367}
1368
1369static struct console kgdb_console = {
1370 .name = "ttySC",
1371 .device = uart_console_device,
1372 .write = kgdb_console_write,
1373 .setup = kgdb_console_setup,
1374 .flags = CON_PRINTBUFFER,
1375 .index = -1,
1376 .data = &sci_uart_driver,
1377};
1378
1379/* Register the KGDB console so we get messages (d'oh!) */
1380static int __init kgdb_console_init(void)
1381{
1382 sci_init_ports();
1383 register_console(&kgdb_console);
1384 return 0;
1385}
1386console_initcall(kgdb_console_init);
1387#endif /* CONFIG_SH_KGDB_CONSOLE */
1388
1389#if defined(CONFIG_SH_KGDB_CONSOLE)
1390#define SCI_CONSOLE &kgdb_console
1391#elif defined(CONFIG_SERIAL_SH_SCI_CONSOLE)
1392#define SCI_CONSOLE &serial_console
1393#else 1185#else
1394#define SCI_CONSOLE 0 1186#define SCI_CONSOLE 0
1395#endif 1187#endif
@@ -1463,15 +1255,8 @@ static int __devinit sci_probe(struct platform_device *dev)
1463 uart_add_one_port(&sci_uart_driver, &sciport->port); 1255 uart_add_one_port(&sci_uart_driver, &sciport->port);
1464 } 1256 }
1465 1257
1466#if defined(CONFIG_SH_KGDB) && !defined(CONFIG_SH_KGDB_CONSOLE) 1258#ifdef CONFIG_HAVE_CLK
1467 kgdb_sci_port = &sci_ports[kgdb_portnum];
1468 kgdb_getchar = kgdb_sci_getchar;
1469 kgdb_putchar = kgdb_sci_putchar;
1470#endif
1471
1472#if defined(CONFIG_CPU_FREQ) && defined(CONFIG_HAVE_CLK)
1473 cpufreq_register_notifier(&sci_nb, CPUFREQ_TRANSITION_NOTIFIER); 1259 cpufreq_register_notifier(&sci_nb, CPUFREQ_TRANSITION_NOTIFIER);
1474 dev_info(&dev->dev, "CPU frequency notifier registered\n");
1475#endif 1260#endif
1476 1261
1477#ifdef CONFIG_SH_STANDARD_BIOS 1262#ifdef CONFIG_SH_STANDARD_BIOS
@@ -1491,6 +1276,10 @@ static int __devexit sci_remove(struct platform_device *dev)
1491{ 1276{
1492 int i; 1277 int i;
1493 1278
1279#ifdef CONFIG_HAVE_CLK
1280 cpufreq_unregister_notifier(&sci_nb, CPUFREQ_TRANSITION_NOTIFIER);
1281#endif
1282
1494 for (i = 0; i < SCI_NPORTS; i++) 1283 for (i = 0; i < SCI_NPORTS; i++)
1495 uart_remove_one_port(&sci_uart_driver, &sci_ports[i].port); 1284 uart_remove_one_port(&sci_uart_driver, &sci_ports[i].port);
1496 1285
diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h
index 9f33b064172e..38c600c0dbbf 100644
--- a/drivers/serial/sh-sci.h
+++ b/drivers/serial/sh-sci.h
@@ -133,13 +133,20 @@
133# define SCSPTR5 0xffef0024 /* 16 bit SCIF */ 133# define SCSPTR5 0xffef0024 /* 16 bit SCIF */
134# define SCIF_OPER 0x0001 /* Overrun error bit */ 134# define SCIF_OPER 0x0001 /* Overrun error bit */
135# define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ 135# define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
136#elif defined(CONFIG_CPU_SUBTYPE_SH7203) || \ 136#elif defined(CONFIG_CPU_SUBTYPE_SH7201) || \
137 defined(CONFIG_CPU_SUBTYPE_SH7203) || \
137 defined(CONFIG_CPU_SUBTYPE_SH7206) || \ 138 defined(CONFIG_CPU_SUBTYPE_SH7206) || \
138 defined(CONFIG_CPU_SUBTYPE_SH7263) 139 defined(CONFIG_CPU_SUBTYPE_SH7263)
139# define SCSPTR0 0xfffe8020 /* 16 bit SCIF */ 140# define SCSPTR0 0xfffe8020 /* 16 bit SCIF */
140# define SCSPTR1 0xfffe8820 /* 16 bit SCIF */ 141# define SCSPTR1 0xfffe8820 /* 16 bit SCIF */
141# define SCSPTR2 0xfffe9020 /* 16 bit SCIF */ 142# define SCSPTR2 0xfffe9020 /* 16 bit SCIF */
142# define SCSPTR3 0xfffe9820 /* 16 bit SCIF */ 143# define SCSPTR3 0xfffe9820 /* 16 bit SCIF */
144# if defined(CONFIG_CPU_SUBTYPE_SH7201)
145# define SCSPTR4 0xfffeA020 /* 16 bit SCIF */
146# define SCSPTR5 0xfffeA820 /* 16 bit SCIF */
147# define SCSPTR6 0xfffeB020 /* 16 bit SCIF */
148# define SCSPTR7 0xfffeB820 /* 16 bit SCIF */
149# endif
143# define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ 150# define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
144#elif defined(CONFIG_CPU_SUBTYPE_SH7619) 151#elif defined(CONFIG_CPU_SUBTYPE_SH7619)
145# define SCSPTR0 0xf8400020 /* 16 bit SCIF */ 152# define SCSPTR0 0xf8400020 /* 16 bit SCIF */
@@ -225,6 +232,10 @@
225# define SCIF_TXROOM_MAX 16 232# define SCIF_TXROOM_MAX 16
226#endif 233#endif
227 234
235#ifndef SCIF_ORER
236#define SCIF_ORER 0x0000
237#endif
238
228#define SCxSR_TEND(port) (((port)->type == PORT_SCI) ? SCI_TEND : SCIF_TEND) 239#define SCxSR_TEND(port) (((port)->type == PORT_SCI) ? SCI_TEND : SCIF_TEND)
229#define SCxSR_ERRORS(port) (((port)->type == PORT_SCI) ? SCI_ERRORS : SCIF_ERRORS) 240#define SCxSR_ERRORS(port) (((port)->type == PORT_SCI) ? SCI_ERRORS : SCIF_ERRORS)
230#define SCxSR_RDxF(port) (((port)->type == PORT_SCI) ? SCI_RDRF : SCIF_RDF) 241#define SCxSR_RDxF(port) (((port)->type == PORT_SCI) ? SCI_RDRF : SCIF_RDF)
@@ -232,12 +243,7 @@
232#define SCxSR_FER(port) (((port)->type == PORT_SCI) ? SCI_FER : SCIF_FER) 243#define SCxSR_FER(port) (((port)->type == PORT_SCI) ? SCI_FER : SCIF_FER)
233#define SCxSR_PER(port) (((port)->type == PORT_SCI) ? SCI_PER : SCIF_PER) 244#define SCxSR_PER(port) (((port)->type == PORT_SCI) ? SCI_PER : SCIF_PER)
234#define SCxSR_BRK(port) (((port)->type == PORT_SCI) ? 0x00 : SCIF_BRK) 245#define SCxSR_BRK(port) (((port)->type == PORT_SCI) ? 0x00 : SCIF_BRK)
235 246#define SCxSR_ORER(port) (((port)->type == PORT_SCI) ? SCI_ORER : SCIF_ORER)
236#if defined(CONFIG_CPU_SUBTYPE_SH7705)
237# define SCxSR_ORER(port) (((port)->type == PORT_SCI) ? SCI_ORER : SCIF_ORER)
238#else
239# define SCxSR_ORER(port) (((port)->type == PORT_SCI) ? SCI_ORER : 0x0000)
240#endif
241 247
242#if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ 248#if defined(CONFIG_CPU_SUBTYPE_SH7705) || \
243 defined(CONFIG_CPU_SUBTYPE_SH7720) || \ 249 defined(CONFIG_CPU_SUBTYPE_SH7720) || \
@@ -501,18 +507,6 @@ static inline int sci_rxd_in(struct uart_port *port)
501{ 507{
502 return sci_in(port,SCxSR)&0x0010 ? 1 : 0; 508 return sci_in(port,SCxSR)&0x0010 ? 1 : 0;
503} 509}
504static inline void set_sh771x_scif_pfc(struct uart_port *port)
505{
506 if (port->mapbase == 0xA4400000){
507 ctrl_outw(ctrl_inw(PACR)&0xffc0,PACR);
508 ctrl_outw(ctrl_inw(PBCR)&0x0fff,PBCR);
509 return;
510 }
511 if (port->mapbase == 0xA4410000){
512 ctrl_outw(ctrl_inw(PBCR)&0xf003,PBCR);
513 return;
514 }
515}
516#elif defined(CONFIG_CPU_SUBTYPE_SH7720) || \ 510#elif defined(CONFIG_CPU_SUBTYPE_SH7720) || \
517 defined(CONFIG_CPU_SUBTYPE_SH7721) 511 defined(CONFIG_CPU_SUBTYPE_SH7721)
518static inline int sci_rxd_in(struct uart_port *port) 512static inline int sci_rxd_in(struct uart_port *port)
@@ -664,7 +658,8 @@ static inline int sci_rxd_in(struct uart_port *port)
664 return ctrl_inw(SCSPTR5) & 0x0001 ? 1 : 0; /* SCIF */ 658 return ctrl_inw(SCSPTR5) & 0x0001 ? 1 : 0; /* SCIF */
665 return 1; 659 return 1;
666} 660}
667#elif defined(CONFIG_CPU_SUBTYPE_SH7203) || \ 661#elif defined(CONFIG_CPU_SUBTYPE_SH7201) || \
662 defined(CONFIG_CPU_SUBTYPE_SH7203) || \
668 defined(CONFIG_CPU_SUBTYPE_SH7206) || \ 663 defined(CONFIG_CPU_SUBTYPE_SH7206) || \
669 defined(CONFIG_CPU_SUBTYPE_SH7263) 664 defined(CONFIG_CPU_SUBTYPE_SH7263)
670static inline int sci_rxd_in(struct uart_port *port) 665static inline int sci_rxd_in(struct uart_port *port)
@@ -677,6 +672,16 @@ static inline int sci_rxd_in(struct uart_port *port)
677 return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ 672 return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */
678 if (port->mapbase == 0xfffe9800) 673 if (port->mapbase == 0xfffe9800)
679 return ctrl_inw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */ 674 return ctrl_inw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */
675#if defined(CONFIG_CPU_SUBTYPE_SH7201)
676 if (port->mapbase == 0xfffeA000)
677 return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */
678 if (port->mapbase == 0xfffeA800)
679 return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */
680 if (port->mapbase == 0xfffeB000)
681 return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */
682 if (port->mapbase == 0xfffeB800)
683 return ctrl_inw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */
684#endif
680 return 1; 685 return 1;
681} 686}
682#elif defined(CONFIG_CPU_SUBTYPE_SH7619) 687#elif defined(CONFIG_CPU_SUBTYPE_SH7619)
diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c
index 77b44fb48f0a..3a8879ec2061 100644
--- a/drivers/usb/gadget/m66592-udc.c
+++ b/drivers/usb/gadget/m66592-udc.c
@@ -623,7 +623,6 @@ static void start_ep0(struct m66592_ep *ep, struct m66592_request *req)
623#if defined(CONFIG_SUPERH_BUILT_IN_M66592) 623#if defined(CONFIG_SUPERH_BUILT_IN_M66592)
624static void init_controller(struct m66592 *m66592) 624static void init_controller(struct m66592 *m66592)
625{ 625{
626 usbf_start_clock();
627 m66592_bset(m66592, M66592_HSE, M66592_SYSCFG); /* High spd */ 626 m66592_bset(m66592, M66592_HSE, M66592_SYSCFG); /* High spd */
628 m66592_bclr(m66592, M66592_USBE, M66592_SYSCFG); 627 m66592_bclr(m66592, M66592_USBE, M66592_SYSCFG);
629 m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG); 628 m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG);
@@ -671,9 +670,7 @@ static void init_controller(struct m66592 *m66592)
671 670
672static void disable_controller(struct m66592 *m66592) 671static void disable_controller(struct m66592 *m66592)
673{ 672{
674#if defined(CONFIG_SUPERH_BUILT_IN_M66592) 673#if !defined(CONFIG_SUPERH_BUILT_IN_M66592)
675 usbf_stop_clock();
676#else
677 m66592_bclr(m66592, M66592_SCKE, M66592_SYSCFG); 674 m66592_bclr(m66592, M66592_SCKE, M66592_SYSCFG);
678 udelay(1); 675 udelay(1);
679 m66592_bclr(m66592, M66592_PLLC, M66592_SYSCFG); 676 m66592_bclr(m66592, M66592_PLLC, M66592_SYSCFG);
@@ -686,9 +683,7 @@ static void disable_controller(struct m66592 *m66592)
686 683
687static void m66592_start_xclock(struct m66592 *m66592) 684static void m66592_start_xclock(struct m66592 *m66592)
688{ 685{
689#if defined(CONFIG_SUPERH_BUILT_IN_M66592) 686#if !defined(CONFIG_SUPERH_BUILT_IN_M66592)
690 usbf_start_clock();
691#else
692 u16 tmp; 687 u16 tmp;
693 688
694 tmp = m66592_read(m66592, M66592_SYSCFG); 689 tmp = m66592_read(m66592, M66592_SYSCFG);
@@ -1539,7 +1534,10 @@ static int __exit m66592_remove(struct platform_device *pdev)
1539 iounmap(m66592->reg); 1534 iounmap(m66592->reg);
1540 free_irq(platform_get_irq(pdev, 0), m66592); 1535 free_irq(platform_get_irq(pdev, 0), m66592);
1541 m66592_free_request(&m66592->ep[0].ep, m66592->ep0_req); 1536 m66592_free_request(&m66592->ep[0].ep, m66592->ep0_req);
1542 usbf_stop_clock(); 1537#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK)
1538 clk_disable(m66592->clk);
1539 clk_put(m66592->clk);
1540#endif
1543 kfree(m66592); 1541 kfree(m66592);
1544 return 0; 1542 return 0;
1545} 1543}
@@ -1556,6 +1554,9 @@ static int __init m66592_probe(struct platform_device *pdev)
1556 int irq; 1554 int irq;
1557 void __iomem *reg = NULL; 1555 void __iomem *reg = NULL;
1558 struct m66592 *m66592 = NULL; 1556 struct m66592 *m66592 = NULL;
1557#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK)
1558 char clk_name[8];
1559#endif
1559 int ret = 0; 1560 int ret = 0;
1560 int i; 1561 int i;
1561 1562
@@ -1614,6 +1615,16 @@ static int __init m66592_probe(struct platform_device *pdev)
1614 goto clean_up; 1615 goto clean_up;
1615 } 1616 }
1616 1617
1618#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK)
1619 snprintf(clk_name, sizeof(clk_name), "usbf%d", pdev->id);
1620 m66592->clk = clk_get(&pdev->dev, clk_name);
1621 if (IS_ERR(m66592->clk)) {
1622 dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
1623 ret = PTR_ERR(m66592->clk);
1624 goto clean_up2;
1625 }
1626 clk_enable(m66592->clk);
1627#endif
1617 INIT_LIST_HEAD(&m66592->gadget.ep_list); 1628 INIT_LIST_HEAD(&m66592->gadget.ep_list);
1618 m66592->gadget.ep0 = &m66592->ep[0].ep; 1629 m66592->gadget.ep0 = &m66592->ep[0].ep;
1619 INIT_LIST_HEAD(&m66592->gadget.ep0->ep_list); 1630 INIT_LIST_HEAD(&m66592->gadget.ep0->ep_list);
@@ -1645,7 +1656,7 @@ static int __init m66592_probe(struct platform_device *pdev)
1645 1656
1646 m66592->ep0_req = m66592_alloc_request(&m66592->ep[0].ep, GFP_KERNEL); 1657 m66592->ep0_req = m66592_alloc_request(&m66592->ep[0].ep, GFP_KERNEL);
1647 if (m66592->ep0_req == NULL) 1658 if (m66592->ep0_req == NULL)
1648 goto clean_up2; 1659 goto clean_up3;
1649 m66592->ep0_req->complete = nop_completion; 1660 m66592->ep0_req->complete = nop_completion;
1650 1661
1651 init_controller(m66592); 1662 init_controller(m66592);
@@ -1653,7 +1664,12 @@ static int __init m66592_probe(struct platform_device *pdev)
1653 dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION); 1664 dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION);
1654 return 0; 1665 return 0;
1655 1666
1667clean_up3:
1668#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK)
1669 clk_disable(m66592->clk);
1670 clk_put(m66592->clk);
1656clean_up2: 1671clean_up2:
1672#endif
1657 free_irq(irq, m66592); 1673 free_irq(irq, m66592);
1658clean_up: 1674clean_up:
1659 if (m66592) { 1675 if (m66592) {
diff --git a/drivers/usb/gadget/m66592-udc.h b/drivers/usb/gadget/m66592-udc.h
index f118f00f1466..286ce07e7960 100644
--- a/drivers/usb/gadget/m66592-udc.h
+++ b/drivers/usb/gadget/m66592-udc.h
@@ -23,6 +23,10 @@
23#ifndef __M66592_UDC_H__ 23#ifndef __M66592_UDC_H__
24#define __M66592_UDC_H__ 24#define __M66592_UDC_H__
25 25
26#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK)
27#include <linux/clk.h>
28#endif
29
26#define M66592_SYSCFG 0x00 30#define M66592_SYSCFG 0x00
27#define M66592_XTAL 0xC000 /* b15-14: Crystal selection */ 31#define M66592_XTAL 0xC000 /* b15-14: Crystal selection */
28#define M66592_XTAL48 0x8000 /* 48MHz */ 32#define M66592_XTAL48 0x8000 /* 48MHz */
@@ -476,6 +480,9 @@ struct m66592_ep {
476struct m66592 { 480struct m66592 {
477 spinlock_t lock; 481 spinlock_t lock;
478 void __iomem *reg; 482 void __iomem *reg;
483#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK)
484 struct clk *clk;
485#endif
479 486
480 struct usb_gadget gadget; 487 struct usb_gadget gadget;
481 struct usb_gadget_driver *driver; 488 struct usb_gadget_driver *driver;
@@ -604,26 +611,6 @@ static inline void m66592_mdfy(struct m66592 *m66592, u16 val, u16 pat,
604#define m66592_bset(m66592, val, offset) \ 611#define m66592_bset(m66592, val, offset) \
605 m66592_mdfy(m66592, val, 0, offset) 612 m66592_mdfy(m66592, val, 0, offset)
606 613
607#if defined(CONFIG_SUPERH_BUILT_IN_M66592)
608#include <asm/io.h>
609#define MSTPCR2 0xA4150038 /* for SH7722 */
610#define MSTPCR2_USB 0x00000800
611
612static inline void usbf_start_clock(void)
613{
614 ctrl_outl(ctrl_inl(MSTPCR2) & ~MSTPCR2_USB, MSTPCR2);
615}
616
617static inline void usbf_stop_clock(void)
618{
619 ctrl_outl(ctrl_inl(MSTPCR2) | MSTPCR2_USB, MSTPCR2);
620}
621
622#else
623#define usbf_start_clock(x)
624#define usbf_stop_clock(x)
625#endif /* if defined(CONFIG_SUPERH_BUILT_IN_M66592) */
626
627#endif /* ifndef __M66592_UDC_H__ */ 614#endif /* ifndef __M66592_UDC_H__ */
628 615
629 616
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c
index 2376f24f3c83..c21f14e0666a 100644
--- a/drivers/usb/host/r8a66597-hcd.c
+++ b/drivers/usb/host/r8a66597-hcd.c
@@ -114,6 +114,9 @@ static int r8a66597_clock_enable(struct r8a66597 *r8a66597)
114 int i = 0; 114 int i = 0;
115 115
116#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) 116#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
117#if defined(CONFIG_HAVE_CLK)
118 clk_enable(r8a66597->clk);
119#endif
117 do { 120 do {
118 r8a66597_write(r8a66597, SCKE, SYSCFG0); 121 r8a66597_write(r8a66597, SCKE, SYSCFG0);
119 tmp = r8a66597_read(r8a66597, SYSCFG0); 122 tmp = r8a66597_read(r8a66597, SYSCFG0);
@@ -154,7 +157,11 @@ static void r8a66597_clock_disable(struct r8a66597 *r8a66597)
154{ 157{
155 r8a66597_bclr(r8a66597, SCKE, SYSCFG0); 158 r8a66597_bclr(r8a66597, SCKE, SYSCFG0);
156 udelay(1); 159 udelay(1);
157#if !defined(CONFIG_SUPERH_ON_CHIP_R8A66597) 160#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
161#if defined(CONFIG_HAVE_CLK)
162 clk_disable(r8a66597->clk);
163#endif
164#else
158 r8a66597_bclr(r8a66597, PLLC, SYSCFG0); 165 r8a66597_bclr(r8a66597, PLLC, SYSCFG0);
159 r8a66597_bclr(r8a66597, XCKE, SYSCFG0); 166 r8a66597_bclr(r8a66597, XCKE, SYSCFG0);
160 r8a66597_bclr(r8a66597, USBE, SYSCFG0); 167 r8a66597_bclr(r8a66597, USBE, SYSCFG0);
@@ -2261,6 +2268,9 @@ static int __init_or_module r8a66597_remove(struct platform_device *pdev)
2261 del_timer_sync(&r8a66597->rh_timer); 2268 del_timer_sync(&r8a66597->rh_timer);
2262 usb_remove_hcd(hcd); 2269 usb_remove_hcd(hcd);
2263 iounmap((void *)r8a66597->reg); 2270 iounmap((void *)r8a66597->reg);
2271#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK)
2272 clk_put(r8a66597->clk);
2273#endif
2264 usb_put_hcd(hcd); 2274 usb_put_hcd(hcd);
2265 return 0; 2275 return 0;
2266} 2276}
@@ -2268,6 +2278,9 @@ static int __init_or_module r8a66597_remove(struct platform_device *pdev)
2268#define resource_len(r) (((r)->end - (r)->start) + 1) 2278#define resource_len(r) (((r)->end - (r)->start) + 1)
2269static int __init r8a66597_probe(struct platform_device *pdev) 2279static int __init r8a66597_probe(struct platform_device *pdev)
2270{ 2280{
2281#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK)
2282 char clk_name[8];
2283#endif
2271 struct resource *res = NULL, *ires; 2284 struct resource *res = NULL, *ires;
2272 int irq = -1; 2285 int irq = -1;
2273 void __iomem *reg = NULL; 2286 void __iomem *reg = NULL;
@@ -2320,6 +2333,16 @@ static int __init r8a66597_probe(struct platform_device *pdev)
2320 memset(r8a66597, 0, sizeof(struct r8a66597)); 2333 memset(r8a66597, 0, sizeof(struct r8a66597));
2321 dev_set_drvdata(&pdev->dev, r8a66597); 2334 dev_set_drvdata(&pdev->dev, r8a66597);
2322 2335
2336#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK)
2337 snprintf(clk_name, sizeof(clk_name), "usb%d", pdev->id);
2338 r8a66597->clk = clk_get(&pdev->dev, clk_name);
2339 if (IS_ERR(r8a66597->clk)) {
2340 dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
2341 ret = PTR_ERR(r8a66597->clk);
2342 goto clean_up2;
2343 }
2344#endif
2345
2323 spin_lock_init(&r8a66597->lock); 2346 spin_lock_init(&r8a66597->lock);
2324 init_timer(&r8a66597->rh_timer); 2347 init_timer(&r8a66597->rh_timer);
2325 r8a66597->rh_timer.function = r8a66597_timer; 2348 r8a66597->rh_timer.function = r8a66597_timer;
@@ -2365,11 +2388,18 @@ static int __init r8a66597_probe(struct platform_device *pdev)
2365 ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | irq_trigger); 2388 ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | irq_trigger);
2366 if (ret != 0) { 2389 if (ret != 0) {
2367 dev_err(&pdev->dev, "Failed to add hcd\n"); 2390 dev_err(&pdev->dev, "Failed to add hcd\n");
2368 goto clean_up; 2391 goto clean_up3;
2369 } 2392 }
2370 2393
2371 return 0; 2394 return 0;
2372 2395
2396clean_up3:
2397#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK)
2398 clk_put(r8a66597->clk);
2399clean_up2:
2400#endif
2401 usb_put_hcd(hcd);
2402
2373clean_up: 2403clean_up:
2374 if (reg) 2404 if (reg)
2375 iounmap(reg); 2405 iounmap(reg);
diff --git a/drivers/usb/host/r8a66597.h b/drivers/usb/host/r8a66597.h
index 84ee01417315..ecacde4d69b0 100644
--- a/drivers/usb/host/r8a66597.h
+++ b/drivers/usb/host/r8a66597.h
@@ -26,6 +26,10 @@
26#ifndef __R8A66597_H__ 26#ifndef __R8A66597_H__
27#define __R8A66597_H__ 27#define __R8A66597_H__
28 28
29#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK)
30#include <linux/clk.h>
31#endif
32
29#define SYSCFG0 0x00 33#define SYSCFG0 0x00
30#define SYSCFG1 0x02 34#define SYSCFG1 0x02
31#define SYSSTS0 0x04 35#define SYSSTS0 0x04
@@ -481,7 +485,9 @@ struct r8a66597_root_hub {
481struct r8a66597 { 485struct r8a66597 {
482 spinlock_t lock; 486 spinlock_t lock;
483 unsigned long reg; 487 unsigned long reg;
484 488#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK)
489 struct clk *clk;
490#endif
485 struct r8a66597_device device0; 491 struct r8a66597_device device0;
486 struct r8a66597_root_hub root_hub[R8A66597_MAX_ROOT_HUB]; 492 struct r8a66597_root_hub root_hub[R8A66597_MAX_ROOT_HUB];
487 struct list_head pipe_queue[R8A66597_MAX_NUM_PIPE]; 493 struct list_head pipe_queue[R8A66597_MAX_NUM_PIPE];
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 3f3ce13fef43..d0c821992a99 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -1889,10 +1889,11 @@ config FB_W100
1889config FB_SH_MOBILE_LCDC 1889config FB_SH_MOBILE_LCDC
1890 tristate "SuperH Mobile LCDC framebuffer support" 1890 tristate "SuperH Mobile LCDC framebuffer support"
1891 depends on FB && SUPERH 1891 depends on FB && SUPERH
1892 select FB_CFB_FILLRECT 1892 select FB_SYS_FILLRECT
1893 select FB_CFB_COPYAREA 1893 select FB_SYS_COPYAREA
1894 select FB_CFB_IMAGEBLIT 1894 select FB_SYS_IMAGEBLIT
1895 default m 1895 select FB_SYS_FOPS
1896 select FB_DEFERRED_IO
1896 ---help--- 1897 ---help---
1897 Frame buffer driver for the on-chip SH-Mobile LCD controller. 1898 Frame buffer driver for the on-chip SH-Mobile LCD controller.
1898 1899
@@ -2021,17 +2022,19 @@ config FB_COBALT
2021 depends on FB && MIPS_COBALT 2022 depends on FB && MIPS_COBALT
2022 2023
2023config FB_SH7760 2024config FB_SH7760
2024 bool "SH7760/SH7763 LCDC support" 2025 bool "SH7760/SH7763/SH7720/SH7721 LCDC support"
2025 depends on FB && (CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7763) 2026 depends on FB && (CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7763 \
2026 select FB_CFB_FILLRECT 2027 || CPU_SUBTYPE_SH7720 || CPU_SUBTYPE_SH7721)
2027 select FB_CFB_COPYAREA 2028 select FB_CFB_FILLRECT
2028 select FB_CFB_IMAGEBLIT 2029 select FB_CFB_COPYAREA
2029 help 2030 select FB_CFB_IMAGEBLIT
2030 Support for the SH7760/SH7763 integrated (D)STN/TFT LCD Controller. 2031 ---help---
2031 Supports display resolutions up to 1024x1024 pixel, grayscale and 2032 Support for the SH7760/SH7763/SH7720/SH7721 integrated
2032 color operation, with depths ranging from 1 bpp to 8 bpp monochrome 2033 (D)STN/TFT LCD Controller.
2033 and 8, 15 or 16 bpp color; 90 degrees clockwise display rotation for 2034 Supports display resolutions up to 1024x1024 pixel, grayscale and
2034 panels <= 320 pixel horizontal resolution. 2035 color operation, with depths ranging from 1 bpp to 8 bpp monochrome
2036 and 8, 15 or 16 bpp color; 90 degrees clockwise display rotation for
2037 panels <= 320 pixel horizontal resolution.
2035 2038
2036config FB_VIRTUAL 2039config FB_VIRTUAL
2037 tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)" 2040 tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)"
diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c
index 4835bdc4e9f1..082026546aee 100644
--- a/drivers/video/fb_defio.c
+++ b/drivers/video/fb_defio.c
@@ -24,6 +24,19 @@
24#include <linux/rmap.h> 24#include <linux/rmap.h>
25#include <linux/pagemap.h> 25#include <linux/pagemap.h>
26 26
27struct page *fb_deferred_io_page(struct fb_info *info, unsigned long offs)
28{
29 void *screen_base = (void __force *) info->screen_base;
30 struct page *page;
31
32 if (is_vmalloc_addr(screen_base + offs))
33 page = vmalloc_to_page(screen_base + offs);
34 else
35 page = pfn_to_page((info->fix.smem_start + offs) >> PAGE_SHIFT);
36
37 return page;
38}
39
27/* this is to find and return the vmalloc-ed fb pages */ 40/* this is to find and return the vmalloc-ed fb pages */
28static int fb_deferred_io_fault(struct vm_area_struct *vma, 41static int fb_deferred_io_fault(struct vm_area_struct *vma,
29 struct vm_fault *vmf) 42 struct vm_fault *vmf)
@@ -31,14 +44,12 @@ static int fb_deferred_io_fault(struct vm_area_struct *vma,
31 unsigned long offset; 44 unsigned long offset;
32 struct page *page; 45 struct page *page;
33 struct fb_info *info = vma->vm_private_data; 46 struct fb_info *info = vma->vm_private_data;
34 /* info->screen_base is virtual memory */
35 void *screen_base = (void __force *) info->screen_base;
36 47
37 offset = vmf->pgoff << PAGE_SHIFT; 48 offset = vmf->pgoff << PAGE_SHIFT;
38 if (offset >= info->fix.smem_len) 49 if (offset >= info->fix.smem_len)
39 return VM_FAULT_SIGBUS; 50 return VM_FAULT_SIGBUS;
40 51
41 page = vmalloc_to_page(screen_base + offset); 52 page = fb_deferred_io_page(info, offset);
42 if (!page) 53 if (!page)
43 return VM_FAULT_SIGBUS; 54 return VM_FAULT_SIGBUS;
44 55
@@ -60,6 +71,10 @@ int fb_deferred_io_fsync(struct file *file, struct dentry *dentry, int datasync)
60{ 71{
61 struct fb_info *info = file->private_data; 72 struct fb_info *info = file->private_data;
62 73
74 /* Skip if deferred io is complied-in but disabled on this fbdev */
75 if (!info->fbdefio)
76 return 0;
77
63 /* Kill off the delayed work */ 78 /* Kill off the delayed work */
64 cancel_rearming_delayed_work(&info->deferred_work); 79 cancel_rearming_delayed_work(&info->deferred_work);
65 80
@@ -184,7 +199,6 @@ EXPORT_SYMBOL_GPL(fb_deferred_io_open);
184 199
185void fb_deferred_io_cleanup(struct fb_info *info) 200void fb_deferred_io_cleanup(struct fb_info *info)
186{ 201{
187 void *screen_base = (void __force *) info->screen_base;
188 struct fb_deferred_io *fbdefio = info->fbdefio; 202 struct fb_deferred_io *fbdefio = info->fbdefio;
189 struct page *page; 203 struct page *page;
190 int i; 204 int i;
@@ -195,9 +209,12 @@ void fb_deferred_io_cleanup(struct fb_info *info)
195 209
196 /* clear out the mapping that we setup */ 210 /* clear out the mapping that we setup */
197 for (i = 0 ; i < info->fix.smem_len; i += PAGE_SIZE) { 211 for (i = 0 ; i < info->fix.smem_len; i += PAGE_SIZE) {
198 page = vmalloc_to_page(screen_base + i); 212 page = fb_deferred_io_page(info, i);
199 page->mapping = NULL; 213 page->mapping = NULL;
200 } 214 }
215
216 info->fbops->fb_mmap = NULL;
217 mutex_destroy(&fbdefio->lock);
201} 218}
202EXPORT_SYMBOL_GPL(fb_deferred_io_cleanup); 219EXPORT_SYMBOL_GPL(fb_deferred_io_cleanup);
203 220
diff --git a/drivers/video/sh7760fb.c b/drivers/video/sh7760fb.c
index 8d0212da4514..653bdfee3057 100644
--- a/drivers/video/sh7760fb.c
+++ b/drivers/video/sh7760fb.c
@@ -13,6 +13,8 @@
13 * 13 *
14 * Thanks to Siegfried Schaefer <s.schaefer at schaefer-edv.de> 14 * Thanks to Siegfried Schaefer <s.schaefer at schaefer-edv.de>
15 * for his original source and testing! 15 * for his original source and testing!
16 *
17 * sh7760_setcolreg get from drivers/video/sh_mobile_lcdcfb.c
16 */ 18 */
17 19
18#include <linux/completion.h> 20#include <linux/completion.h>
@@ -53,29 +55,6 @@ static irqreturn_t sh7760fb_irq(int irq, void *data)
53 return IRQ_HANDLED; 55 return IRQ_HANDLED;
54} 56}
55 57
56static void sh7760fb_wait_vsync(struct fb_info *info)
57{
58 struct sh7760fb_par *par = info->par;
59
60 if (par->pd->novsync)
61 return;
62
63 iowrite16(ioread16(par->base + LDINTR) & ~VINT_CHECK,
64 par->base + LDINTR);
65
66 if (par->irq < 0) {
67 /* poll for vert. retrace: status bit is sticky */
68 while (!(ioread16(par->base + LDINTR) & VINT_CHECK))
69 cpu_relax();
70 } else {
71 /* a "wait_for_irq_event(par->irq)" would be extremely nice */
72 init_completion(&par->vsync);
73 enable_irq(par->irq);
74 wait_for_completion(&par->vsync);
75 disable_irq_nosync(par->irq);
76 }
77}
78
79/* wait_for_lps - wait until power supply has reached a certain state. */ 58/* wait_for_lps - wait until power supply has reached a certain state. */
80static int wait_for_lps(struct sh7760fb_par *par, int val) 59static int wait_for_lps(struct sh7760fb_par *par, int val)
81{ 60{
@@ -117,55 +96,28 @@ static int sh7760fb_blank(int blank, struct fb_info *info)
117 return wait_for_lps(par, lps); 96 return wait_for_lps(par, lps);
118} 97}
119 98
120/* set color registers */ 99static int sh7760_setcolreg (u_int regno,
121static int sh7760fb_setcmap(struct fb_cmap *cmap, struct fb_info *info) 100 u_int red, u_int green, u_int blue,
101 u_int transp, struct fb_info *info)
122{ 102{
123 struct sh7760fb_par *par = info->par; 103 u32 *palette = info->pseudo_palette;
124 u32 s = cmap->start;
125 u32 l = cmap->len;
126 u16 *r = cmap->red;
127 u16 *g = cmap->green;
128 u16 *b = cmap->blue;
129 u32 col, tmo;
130 int ret;
131 104
132 ret = 0; 105 if (regno >= 16)
106 return -EINVAL;
133 107
134 sh7760fb_wait_vsync(info); 108 /* only FB_VISUAL_TRUECOLOR supported */
135 109
136 /* request palette access */ 110 red >>= 16 - info->var.red.length;
137 iowrite16(LDPALCR_PALEN, par->base + LDPALCR); 111 green >>= 16 - info->var.green.length;
112 blue >>= 16 - info->var.blue.length;
113 transp >>= 16 - info->var.transp.length;
138 114
139 /* poll for access grant */ 115 palette[regno] = (red << info->var.red.offset) |
140 tmo = 100; 116 (green << info->var.green.offset) |
141 while (!(ioread16(par->base + LDPALCR) & LDPALCR_PALS) && (--tmo)) 117 (blue << info->var.blue.offset) |
142 cpu_relax(); 118 (transp << info->var.transp.offset);
143 119
144 if (!tmo) { 120 return 0;
145 ret = 1;
146 dev_dbg(info->dev, "no palette access!\n");
147 goto out;
148 }
149
150 while (l && (s < 256)) {
151 col = ((*r) & 0xff) << 16;
152 col |= ((*g) & 0xff) << 8;
153 col |= ((*b) & 0xff);
154 col &= SH7760FB_PALETTE_MASK;
155 iowrite32(col, par->base + LDPR(s));
156
157 if (s < 16)
158 ((u32 *) (info->pseudo_palette))[s] = s;
159
160 s++;
161 l--;
162 r++;
163 g++;
164 b++;
165 }
166out:
167 iowrite16(0, par->base + LDPALCR);
168 return ret;
169} 121}
170 122
171static void encode_fix(struct fb_fix_screeninfo *fix, struct fb_info *info, 123static void encode_fix(struct fb_fix_screeninfo *fix, struct fb_info *info,
@@ -406,7 +358,7 @@ static struct fb_ops sh7760fb_ops = {
406 .owner = THIS_MODULE, 358 .owner = THIS_MODULE,
407 .fb_blank = sh7760fb_blank, 359 .fb_blank = sh7760fb_blank,
408 .fb_check_var = sh7760fb_check_var, 360 .fb_check_var = sh7760fb_check_var,
409 .fb_setcmap = sh7760fb_setcmap, 361 .fb_setcolreg = sh7760_setcolreg,
410 .fb_set_par = sh7760fb_set_par, 362 .fb_set_par = sh7760fb_set_par,
411 .fb_fillrect = cfb_fillrect, 363 .fb_fillrect = cfb_fillrect,
412 .fb_copyarea = cfb_copyarea, 364 .fb_copyarea = cfb_copyarea,
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index efff672fd7b8..0e2b8fd24df1 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -16,7 +16,9 @@
16#include <linux/clk.h> 16#include <linux/clk.h>
17#include <linux/platform_device.h> 17#include <linux/platform_device.h>
18#include <linux/dma-mapping.h> 18#include <linux/dma-mapping.h>
19#include <linux/interrupt.h>
19#include <video/sh_mobile_lcdc.h> 20#include <video/sh_mobile_lcdc.h>
21#include <asm/atomic.h>
20 22
21#define PALETTE_NR 16 23#define PALETTE_NR 16
22 24
@@ -30,11 +32,15 @@ struct sh_mobile_lcdc_chan {
30 u32 pseudo_palette[PALETTE_NR]; 32 u32 pseudo_palette[PALETTE_NR];
31 struct fb_info info; 33 struct fb_info info;
32 dma_addr_t dma_handle; 34 dma_addr_t dma_handle;
35 struct fb_deferred_io defio;
33}; 36};
34 37
35struct sh_mobile_lcdc_priv { 38struct sh_mobile_lcdc_priv {
36 void __iomem *base; 39 void __iomem *base;
40 int irq;
37#ifdef CONFIG_HAVE_CLK 41#ifdef CONFIG_HAVE_CLK
42 atomic_t clk_usecnt;
43 struct clk *dot_clk;
38 struct clk *clk; 44 struct clk *clk;
39#endif 45#endif
40 unsigned long lddckr; 46 unsigned long lddckr;
@@ -56,7 +62,7 @@ struct sh_mobile_lcdc_priv {
56 62
57/* per-channel registers */ 63/* per-channel registers */
58enum { LDDCKPAT1R, LDDCKPAT2R, LDMT1R, LDMT2R, LDMT3R, LDDFR, LDSM1R, 64enum { LDDCKPAT1R, LDDCKPAT2R, LDMT1R, LDMT2R, LDMT3R, LDDFR, LDSM1R,
59 LDSA1R, LDMLSR, LDHCNR, LDHSYNR, LDVLNR, LDVSYNR, LDPMR }; 65 LDSM2R, LDSA1R, LDMLSR, LDHCNR, LDHSYNR, LDVLNR, LDVSYNR, LDPMR };
60 66
61static unsigned long lcdc_offs_mainlcd[] = { 67static unsigned long lcdc_offs_mainlcd[] = {
62 [LDDCKPAT1R] = 0x400, 68 [LDDCKPAT1R] = 0x400,
@@ -66,6 +72,7 @@ static unsigned long lcdc_offs_mainlcd[] = {
66 [LDMT3R] = 0x420, 72 [LDMT3R] = 0x420,
67 [LDDFR] = 0x424, 73 [LDDFR] = 0x424,
68 [LDSM1R] = 0x428, 74 [LDSM1R] = 0x428,
75 [LDSM2R] = 0x42c,
69 [LDSA1R] = 0x430, 76 [LDSA1R] = 0x430,
70 [LDMLSR] = 0x438, 77 [LDMLSR] = 0x438,
71 [LDHCNR] = 0x448, 78 [LDHCNR] = 0x448,
@@ -83,6 +90,7 @@ static unsigned long lcdc_offs_sublcd[] = {
83 [LDMT3R] = 0x608, 90 [LDMT3R] = 0x608,
84 [LDDFR] = 0x60c, 91 [LDDFR] = 0x60c,
85 [LDSM1R] = 0x610, 92 [LDSM1R] = 0x610,
93 [LDSM2R] = 0x614,
86 [LDSA1R] = 0x618, 94 [LDSA1R] = 0x618,
87 [LDMLSR] = 0x620, 95 [LDMLSR] = 0x620,
88 [LDHCNR] = 0x624, 96 [LDHCNR] = 0x624,
@@ -96,6 +104,8 @@ static unsigned long lcdc_offs_sublcd[] = {
96#define LCDC_RESET 0x00000100 104#define LCDC_RESET 0x00000100
97#define DISPLAY_BEU 0x00000008 105#define DISPLAY_BEU 0x00000008
98#define LCDC_ENABLE 0x00000001 106#define LCDC_ENABLE 0x00000001
107#define LDINTR_FE 0x00000400
108#define LDINTR_FS 0x00000004
99 109
100static void lcdc_write_chan(struct sh_mobile_lcdc_chan *chan, 110static void lcdc_write_chan(struct sh_mobile_lcdc_chan *chan,
101 int reg_nr, unsigned long data) 111 int reg_nr, unsigned long data)
@@ -170,6 +180,65 @@ struct sh_mobile_lcdc_sys_bus_ops sh_mobile_lcdc_sys_bus_ops = {
170 lcdc_sys_read_data, 180 lcdc_sys_read_data,
171}; 181};
172 182
183#ifdef CONFIG_HAVE_CLK
184static void sh_mobile_lcdc_clk_on(struct sh_mobile_lcdc_priv *priv)
185{
186 if (atomic_inc_and_test(&priv->clk_usecnt)) {
187 clk_enable(priv->clk);
188 if (priv->dot_clk)
189 clk_enable(priv->dot_clk);
190 }
191}
192
193static void sh_mobile_lcdc_clk_off(struct sh_mobile_lcdc_priv *priv)
194{
195 if (atomic_sub_return(1, &priv->clk_usecnt) == -1) {
196 if (priv->dot_clk)
197 clk_disable(priv->dot_clk);
198 clk_disable(priv->clk);
199 }
200}
201#else
202static void sh_mobile_lcdc_clk_on(struct sh_mobile_lcdc_priv *priv) {}
203static void sh_mobile_lcdc_clk_off(struct sh_mobile_lcdc_priv *priv) {}
204#endif
205
206static void sh_mobile_lcdc_deferred_io(struct fb_info *info,
207 struct list_head *pagelist)
208{
209 struct sh_mobile_lcdc_chan *ch = info->par;
210
211 /* enable clocks before accessing hardware */
212 sh_mobile_lcdc_clk_on(ch->lcdc);
213
214 /* trigger panel update */
215 lcdc_write_chan(ch, LDSM2R, 1);
216}
217
218static void sh_mobile_lcdc_deferred_io_touch(struct fb_info *info)
219{
220 struct fb_deferred_io *fbdefio = info->fbdefio;
221
222 if (fbdefio)
223 schedule_delayed_work(&info->deferred_work, fbdefio->delay);
224}
225
226static irqreturn_t sh_mobile_lcdc_irq(int irq, void *data)
227{
228 struct sh_mobile_lcdc_priv *priv = data;
229 unsigned long tmp;
230
231 /* acknowledge interrupt */
232 tmp = lcdc_read(priv, _LDINTR);
233 tmp &= 0xffffff00; /* mask in high 24 bits */
234 tmp |= 0x000000ff ^ LDINTR_FS; /* status in low 8 */
235 lcdc_write(priv, _LDINTR, tmp);
236
237 /* disable clocks */
238 sh_mobile_lcdc_clk_off(priv);
239 return IRQ_HANDLED;
240}
241
173static void sh_mobile_lcdc_start_stop(struct sh_mobile_lcdc_priv *priv, 242static void sh_mobile_lcdc_start_stop(struct sh_mobile_lcdc_priv *priv,
174 int start) 243 int start)
175{ 244{
@@ -207,6 +276,11 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
207 int k, m; 276 int k, m;
208 int ret = 0; 277 int ret = 0;
209 278
279 /* enable clocks before accessing the hardware */
280 for (k = 0; k < ARRAY_SIZE(priv->ch); k++)
281 if (priv->ch[k].enabled)
282 sh_mobile_lcdc_clk_on(priv);
283
210 /* reset */ 284 /* reset */
211 lcdc_write(priv, _LDCNT2R, lcdc_read(priv, _LDCNT2R) | LCDC_RESET); 285 lcdc_write(priv, _LDCNT2R, lcdc_read(priv, _LDCNT2R) | LCDC_RESET);
212 lcdc_wait_bit(priv, _LDCNT2R, LCDC_RESET, 0); 286 lcdc_wait_bit(priv, _LDCNT2R, LCDC_RESET, 0);
@@ -249,7 +323,7 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
249 lcdc_write(priv, _LDDCKSTPR, 0); 323 lcdc_write(priv, _LDDCKSTPR, 0);
250 lcdc_wait_bit(priv, _LDDCKSTPR, ~0, 0); 324 lcdc_wait_bit(priv, _LDDCKSTPR, ~0, 0);
251 325
252 /* interrupts are disabled */ 326 /* interrupts are disabled to begin with */
253 lcdc_write(priv, _LDINTR, 0); 327 lcdc_write(priv, _LDINTR, 0);
254 328
255 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { 329 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
@@ -310,9 +384,6 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
310 return ret; 384 return ret;
311 } 385 }
312 386
313 /* --- display_lcdc_data() --- */
314 lcdc_write(priv, _LDINTR, 0x00000f00);
315
316 /* word and long word swap */ 387 /* word and long word swap */
317 lcdc_write(priv, _LDDDSR, lcdc_read(priv, _LDDDSR) | 6); 388 lcdc_write(priv, _LDDDSR, lcdc_read(priv, _LDDDSR) | 6);
318 389
@@ -334,8 +405,24 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
334 /* set line size */ 405 /* set line size */
335 lcdc_write_chan(ch, LDMLSR, ch->info.fix.line_length); 406 lcdc_write_chan(ch, LDMLSR, ch->info.fix.line_length);
336 407
337 /* continuous read mode */ 408 /* setup deferred io if SYS bus */
338 lcdc_write_chan(ch, LDSM1R, 0); 409 tmp = ch->cfg.sys_bus_cfg.deferred_io_msec;
410 if (ch->ldmt1r_value & (1 << 12) && tmp) {
411 ch->defio.deferred_io = sh_mobile_lcdc_deferred_io;
412 ch->defio.delay = msecs_to_jiffies(tmp);
413 ch->info.fbdefio = &ch->defio;
414 fb_deferred_io_init(&ch->info);
415
416 /* one-shot mode */
417 lcdc_write_chan(ch, LDSM1R, 1);
418
419 /* enable "Frame End Interrupt Enable" bit */
420 lcdc_write(priv, _LDINTR, LDINTR_FE);
421
422 } else {
423 /* continuous read mode */
424 lcdc_write_chan(ch, LDSM1R, 0);
425 }
339 } 426 }
340 427
341 /* display output */ 428 /* display output */
@@ -359,6 +446,7 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv)
359{ 446{
360 struct sh_mobile_lcdc_chan *ch; 447 struct sh_mobile_lcdc_chan *ch;
361 struct sh_mobile_lcdc_board_cfg *board_cfg; 448 struct sh_mobile_lcdc_board_cfg *board_cfg;
449 unsigned long tmp;
362 int k; 450 int k;
363 451
364 /* tell the board code to disable the panel */ 452 /* tell the board code to disable the panel */
@@ -367,10 +455,22 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv)
367 board_cfg = &ch->cfg.board_cfg; 455 board_cfg = &ch->cfg.board_cfg;
368 if (board_cfg->display_off) 456 if (board_cfg->display_off)
369 board_cfg->display_off(board_cfg->board_data); 457 board_cfg->display_off(board_cfg->board_data);
458
459 /* cleanup deferred io if SYS bus */
460 tmp = ch->cfg.sys_bus_cfg.deferred_io_msec;
461 if (ch->ldmt1r_value & (1 << 12) && tmp) {
462 fb_deferred_io_cleanup(&ch->info);
463 ch->info.fbdefio = NULL;
464 }
370 } 465 }
371 466
372 /* stop the lcdc */ 467 /* stop the lcdc */
373 sh_mobile_lcdc_start_stop(priv, 0); 468 sh_mobile_lcdc_start_stop(priv, 0);
469
470 /* stop clocks */
471 for (k = 0; k < ARRAY_SIZE(priv->ch); k++)
472 if (priv->ch[k].enabled)
473 sh_mobile_lcdc_clk_off(priv);
374} 474}
375 475
376static int sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan *ch) 476static int sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan *ch)
@@ -413,9 +513,13 @@ static int sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan *ch)
413 return -EINVAL; 513 return -EINVAL;
414} 514}
415 515
416static int sh_mobile_lcdc_setup_clocks(struct device *dev, int clock_source, 516static int sh_mobile_lcdc_setup_clocks(struct platform_device *pdev,
517 int clock_source,
417 struct sh_mobile_lcdc_priv *priv) 518 struct sh_mobile_lcdc_priv *priv)
418{ 519{
520#ifdef CONFIG_HAVE_CLK
521 char clk_name[8];
522#endif
419 char *str; 523 char *str;
420 int icksel; 524 int icksel;
421 525
@@ -430,14 +534,21 @@ static int sh_mobile_lcdc_setup_clocks(struct device *dev, int clock_source,
430 priv->lddckr = icksel << 16; 534 priv->lddckr = icksel << 16;
431 535
432#ifdef CONFIG_HAVE_CLK 536#ifdef CONFIG_HAVE_CLK
537 atomic_set(&priv->clk_usecnt, -1);
538 snprintf(clk_name, sizeof(clk_name), "lcdc%d", pdev->id);
539 priv->clk = clk_get(&pdev->dev, clk_name);
540 if (IS_ERR(priv->clk)) {
541 dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
542 return PTR_ERR(priv->clk);
543 }
544
433 if (str) { 545 if (str) {
434 priv->clk = clk_get(dev, str); 546 priv->dot_clk = clk_get(&pdev->dev, str);
435 if (IS_ERR(priv->clk)) { 547 if (IS_ERR(priv->dot_clk)) {
436 dev_err(dev, "cannot get clock %s\n", str); 548 dev_err(&pdev->dev, "cannot get dot clock %s\n", str);
437 return PTR_ERR(priv->clk); 549 clk_put(priv->clk);
550 return PTR_ERR(priv->dot_clk);
438 } 551 }
439
440 clk_enable(priv->clk);
441 } 552 }
442#endif 553#endif
443 554
@@ -475,11 +586,34 @@ static struct fb_fix_screeninfo sh_mobile_lcdc_fix = {
475 .accel = FB_ACCEL_NONE, 586 .accel = FB_ACCEL_NONE,
476}; 587};
477 588
589static void sh_mobile_lcdc_fillrect(struct fb_info *info,
590 const struct fb_fillrect *rect)
591{
592 sys_fillrect(info, rect);
593 sh_mobile_lcdc_deferred_io_touch(info);
594}
595
596static void sh_mobile_lcdc_copyarea(struct fb_info *info,
597 const struct fb_copyarea *area)
598{
599 sys_copyarea(info, area);
600 sh_mobile_lcdc_deferred_io_touch(info);
601}
602
603static void sh_mobile_lcdc_imageblit(struct fb_info *info,
604 const struct fb_image *image)
605{
606 sys_imageblit(info, image);
607 sh_mobile_lcdc_deferred_io_touch(info);
608}
609
478static struct fb_ops sh_mobile_lcdc_ops = { 610static struct fb_ops sh_mobile_lcdc_ops = {
479 .fb_setcolreg = sh_mobile_lcdc_setcolreg, 611 .fb_setcolreg = sh_mobile_lcdc_setcolreg,
480 .fb_fillrect = cfb_fillrect, 612 .fb_read = fb_sys_read,
481 .fb_copyarea = cfb_copyarea, 613 .fb_write = fb_sys_write,
482 .fb_imageblit = cfb_imageblit, 614 .fb_fillrect = sh_mobile_lcdc_fillrect,
615 .fb_copyarea = sh_mobile_lcdc_copyarea,
616 .fb_imageblit = sh_mobile_lcdc_imageblit,
483}; 617};
484 618
485static int sh_mobile_lcdc_set_bpp(struct fb_var_screeninfo *var, int bpp) 619static int sh_mobile_lcdc_set_bpp(struct fb_var_screeninfo *var, int bpp)
@@ -540,8 +674,9 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev)
540 } 674 }
541 675
542 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 676 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
543 if (res == NULL) { 677 i = platform_get_irq(pdev, 0);
544 dev_err(&pdev->dev, "cannot find IO resource\n"); 678 if (!res || i < 0) {
679 dev_err(&pdev->dev, "cannot get platform resources\n");
545 error = -ENOENT; 680 error = -ENOENT;
546 goto err0; 681 goto err0;
547 } 682 }
@@ -553,6 +688,14 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev)
553 goto err0; 688 goto err0;
554 } 689 }
555 690
691 error = request_irq(i, sh_mobile_lcdc_irq, IRQF_DISABLED,
692 pdev->dev.bus_id, priv);
693 if (error) {
694 dev_err(&pdev->dev, "unable to request irq\n");
695 goto err1;
696 }
697
698 priv->irq = i;
556 platform_set_drvdata(pdev, priv); 699 platform_set_drvdata(pdev, priv);
557 pdata = pdev->dev.platform_data; 700 pdata = pdev->dev.platform_data;
558 701
@@ -587,8 +730,7 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev)
587 goto err1; 730 goto err1;
588 } 731 }
589 732
590 error = sh_mobile_lcdc_setup_clocks(&pdev->dev, 733 error = sh_mobile_lcdc_setup_clocks(pdev, pdata->clock_source, priv);
591 pdata->clock_source, priv);
592 if (error) { 734 if (error) {
593 dev_err(&pdev->dev, "unable to setup clocks\n"); 735 dev_err(&pdev->dev, "unable to setup clocks\n");
594 goto err1; 736 goto err1;
@@ -637,6 +779,7 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev)
637 info->fix.smem_start = priv->ch[i].dma_handle; 779 info->fix.smem_start = priv->ch[i].dma_handle;
638 info->screen_base = buf; 780 info->screen_base = buf;
639 info->device = &pdev->dev; 781 info->device = &pdev->dev;
782 info->par = &priv->ch[i];
640 } 783 }
641 784
642 if (error) 785 if (error)
@@ -664,6 +807,10 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev)
664 (int) priv->ch[i].cfg.lcd_cfg.xres, 807 (int) priv->ch[i].cfg.lcd_cfg.xres,
665 (int) priv->ch[i].cfg.lcd_cfg.yres, 808 (int) priv->ch[i].cfg.lcd_cfg.yres,
666 priv->ch[i].cfg.bpp); 809 priv->ch[i].cfg.bpp);
810
811 /* deferred io mode: disable clock to save power */
812 if (info->fbdefio)
813 sh_mobile_lcdc_clk_off(priv);
667 } 814 }
668 815
669 return 0; 816 return 0;
@@ -697,15 +844,16 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev)
697 } 844 }
698 845
699#ifdef CONFIG_HAVE_CLK 846#ifdef CONFIG_HAVE_CLK
700 if (priv->clk) { 847 if (priv->dot_clk)
701 clk_disable(priv->clk); 848 clk_put(priv->dot_clk);
702 clk_put(priv->clk); 849 clk_put(priv->clk);
703 }
704#endif 850#endif
705 851
706 if (priv->base) 852 if (priv->base)
707 iounmap(priv->base); 853 iounmap(priv->base);
708 854
855 if (priv->irq)
856 free_irq(priv->irq, priv);
709 kfree(priv); 857 kfree(priv);
710 return 0; 858 return 0;
711} 859}
diff --git a/include/crypto/aes.h b/include/crypto/aes.h
index 40008d67ee3d..656a4c66a568 100644
--- a/include/crypto/aes.h
+++ b/include/crypto/aes.h
@@ -23,10 +23,10 @@ struct crypto_aes_ctx {
23 u32 key_dec[AES_MAX_KEYLENGTH_U32]; 23 u32 key_dec[AES_MAX_KEYLENGTH_U32];
24}; 24};
25 25
26extern u32 crypto_ft_tab[4][256]; 26extern const u32 crypto_ft_tab[4][256];
27extern u32 crypto_fl_tab[4][256]; 27extern const u32 crypto_fl_tab[4][256];
28extern u32 crypto_it_tab[4][256]; 28extern const u32 crypto_it_tab[4][256];
29extern u32 crypto_il_tab[4][256]; 29extern const u32 crypto_il_tab[4][256];
30 30
31int crypto_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, 31int crypto_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
32 unsigned int key_len); 32 unsigned int key_len);
diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h
index 60d06e784be3..010545436efa 100644
--- a/include/crypto/algapi.h
+++ b/include/crypto/algapi.h
@@ -22,9 +22,18 @@ struct seq_file;
22 22
23struct crypto_type { 23struct crypto_type {
24 unsigned int (*ctxsize)(struct crypto_alg *alg, u32 type, u32 mask); 24 unsigned int (*ctxsize)(struct crypto_alg *alg, u32 type, u32 mask);
25 unsigned int (*extsize)(struct crypto_alg *alg,
26 const struct crypto_type *frontend);
25 int (*init)(struct crypto_tfm *tfm, u32 type, u32 mask); 27 int (*init)(struct crypto_tfm *tfm, u32 type, u32 mask);
26 void (*exit)(struct crypto_tfm *tfm); 28 int (*init_tfm)(struct crypto_tfm *tfm,
29 const struct crypto_type *frontend);
27 void (*show)(struct seq_file *m, struct crypto_alg *alg); 30 void (*show)(struct seq_file *m, struct crypto_alg *alg);
31 struct crypto_alg *(*lookup)(const char *name, u32 type, u32 mask);
32
33 unsigned int type;
34 unsigned int maskclear;
35 unsigned int maskset;
36 unsigned int tfmsize;
28}; 37};
29 38
30struct crypto_instance { 39struct crypto_instance {
@@ -239,6 +248,11 @@ static inline struct crypto_hash *crypto_spawn_hash(struct crypto_spawn *spawn)
239 return __crypto_hash_cast(crypto_spawn_tfm(spawn, type, mask)); 248 return __crypto_hash_cast(crypto_spawn_tfm(spawn, type, mask));
240} 249}
241 250
251static inline void *crypto_hash_ctx(struct crypto_hash *tfm)
252{
253 return crypto_tfm_ctx(&tfm->base);
254}
255
242static inline void *crypto_hash_ctx_aligned(struct crypto_hash *tfm) 256static inline void *crypto_hash_ctx_aligned(struct crypto_hash *tfm)
243{ 257{
244 return crypto_tfm_ctx_aligned(&tfm->base); 258 return crypto_tfm_ctx_aligned(&tfm->base);
diff --git a/include/crypto/hash.h b/include/crypto/hash.h
index ee48ef8fb2ea..cd16d6e668ce 100644
--- a/include/crypto/hash.h
+++ b/include/crypto/hash.h
@@ -15,10 +15,40 @@
15 15
16#include <linux/crypto.h> 16#include <linux/crypto.h>
17 17
18struct shash_desc {
19 struct crypto_shash *tfm;
20 u32 flags;
21
22 void *__ctx[] CRYPTO_MINALIGN_ATTR;
23};
24
25struct shash_alg {
26 int (*init)(struct shash_desc *desc);
27 int (*reinit)(struct shash_desc *desc);
28 int (*update)(struct shash_desc *desc, const u8 *data,
29 unsigned int len);
30 int (*final)(struct shash_desc *desc, u8 *out);
31 int (*finup)(struct shash_desc *desc, const u8 *data,
32 unsigned int len, u8 *out);
33 int (*digest)(struct shash_desc *desc, const u8 *data,
34 unsigned int len, u8 *out);
35 int (*setkey)(struct crypto_shash *tfm, const u8 *key,
36 unsigned int keylen);
37
38 unsigned int descsize;
39 unsigned int digestsize;
40
41 struct crypto_alg base;
42};
43
18struct crypto_ahash { 44struct crypto_ahash {
19 struct crypto_tfm base; 45 struct crypto_tfm base;
20}; 46};
21 47
48struct crypto_shash {
49 struct crypto_tfm base;
50};
51
22static inline struct crypto_ahash *__crypto_ahash_cast(struct crypto_tfm *tfm) 52static inline struct crypto_ahash *__crypto_ahash_cast(struct crypto_tfm *tfm)
23{ 53{
24 return (struct crypto_ahash *)tfm; 54 return (struct crypto_ahash *)tfm;
@@ -87,6 +117,11 @@ static inline unsigned int crypto_ahash_reqsize(struct crypto_ahash *tfm)
87 return crypto_ahash_crt(tfm)->reqsize; 117 return crypto_ahash_crt(tfm)->reqsize;
88} 118}
89 119
120static inline void *ahash_request_ctx(struct ahash_request *req)
121{
122 return req->__ctx;
123}
124
90static inline int crypto_ahash_setkey(struct crypto_ahash *tfm, 125static inline int crypto_ahash_setkey(struct crypto_ahash *tfm,
91 const u8 *key, unsigned int keylen) 126 const u8 *key, unsigned int keylen)
92{ 127{
@@ -101,6 +136,14 @@ static inline int crypto_ahash_digest(struct ahash_request *req)
101 return crt->digest(req); 136 return crt->digest(req);
102} 137}
103 138
139static inline void crypto_ahash_export(struct ahash_request *req, u8 *out)
140{
141 memcpy(out, ahash_request_ctx(req),
142 crypto_ahash_reqsize(crypto_ahash_reqtfm(req)));
143}
144
145int crypto_ahash_import(struct ahash_request *req, const u8 *in);
146
104static inline int crypto_ahash_init(struct ahash_request *req) 147static inline int crypto_ahash_init(struct ahash_request *req)
105{ 148{
106 struct ahash_tfm *crt = crypto_ahash_crt(crypto_ahash_reqtfm(req)); 149 struct ahash_tfm *crt = crypto_ahash_crt(crypto_ahash_reqtfm(req));
@@ -169,4 +212,86 @@ static inline void ahash_request_set_crypt(struct ahash_request *req,
169 req->result = result; 212 req->result = result;
170} 213}
171 214
215struct crypto_shash *crypto_alloc_shash(const char *alg_name, u32 type,
216 u32 mask);
217
218static inline struct crypto_tfm *crypto_shash_tfm(struct crypto_shash *tfm)
219{
220 return &tfm->base;
221}
222
223static inline void crypto_free_shash(struct crypto_shash *tfm)
224{
225 crypto_free_tfm(crypto_shash_tfm(tfm));
226}
227
228static inline unsigned int crypto_shash_alignmask(
229 struct crypto_shash *tfm)
230{
231 return crypto_tfm_alg_alignmask(crypto_shash_tfm(tfm));
232}
233
234static inline struct shash_alg *__crypto_shash_alg(struct crypto_alg *alg)
235{
236 return container_of(alg, struct shash_alg, base);
237}
238
239static inline struct shash_alg *crypto_shash_alg(struct crypto_shash *tfm)
240{
241 return __crypto_shash_alg(crypto_shash_tfm(tfm)->__crt_alg);
242}
243
244static inline unsigned int crypto_shash_digestsize(struct crypto_shash *tfm)
245{
246 return crypto_shash_alg(tfm)->digestsize;
247}
248
249static inline u32 crypto_shash_get_flags(struct crypto_shash *tfm)
250{
251 return crypto_tfm_get_flags(crypto_shash_tfm(tfm));
252}
253
254static inline void crypto_shash_set_flags(struct crypto_shash *tfm, u32 flags)
255{
256 crypto_tfm_set_flags(crypto_shash_tfm(tfm), flags);
257}
258
259static inline void crypto_shash_clear_flags(struct crypto_shash *tfm, u32 flags)
260{
261 crypto_tfm_clear_flags(crypto_shash_tfm(tfm), flags);
262}
263
264static inline unsigned int crypto_shash_descsize(struct crypto_shash *tfm)
265{
266 return crypto_shash_alg(tfm)->descsize;
267}
268
269static inline void *shash_desc_ctx(struct shash_desc *desc)
270{
271 return desc->__ctx;
272}
273
274int crypto_shash_setkey(struct crypto_shash *tfm, const u8 *key,
275 unsigned int keylen);
276int crypto_shash_digest(struct shash_desc *desc, const u8 *data,
277 unsigned int len, u8 *out);
278
279static inline void crypto_shash_export(struct shash_desc *desc, u8 *out)
280{
281 memcpy(out, shash_desc_ctx(desc), crypto_shash_descsize(desc->tfm));
282}
283
284int crypto_shash_import(struct shash_desc *desc, const u8 *in);
285
286static inline int crypto_shash_init(struct shash_desc *desc)
287{
288 return crypto_shash_alg(desc->tfm)->init(desc);
289}
290
291int crypto_shash_update(struct shash_desc *desc, const u8 *data,
292 unsigned int len);
293int crypto_shash_final(struct shash_desc *desc, u8 *out);
294int crypto_shash_finup(struct shash_desc *desc, const u8 *data,
295 unsigned int len, u8 *out);
296
172#endif /* _CRYPTO_HASH_H */ 297#endif /* _CRYPTO_HASH_H */
diff --git a/include/crypto/internal/hash.h b/include/crypto/internal/hash.h
index 917ae57bad4a..82b70564bcab 100644
--- a/include/crypto/internal/hash.h
+++ b/include/crypto/internal/hash.h
@@ -39,6 +39,12 @@ extern const struct crypto_type crypto_ahash_type;
39int crypto_hash_walk_done(struct crypto_hash_walk *walk, int err); 39int crypto_hash_walk_done(struct crypto_hash_walk *walk, int err);
40int crypto_hash_walk_first(struct ahash_request *req, 40int crypto_hash_walk_first(struct ahash_request *req,
41 struct crypto_hash_walk *walk); 41 struct crypto_hash_walk *walk);
42int crypto_hash_walk_first_compat(struct hash_desc *hdesc,
43 struct crypto_hash_walk *walk,
44 struct scatterlist *sg, unsigned int len);
45
46int crypto_register_shash(struct shash_alg *alg);
47int crypto_unregister_shash(struct shash_alg *alg);
42 48
43static inline void *crypto_ahash_ctx(struct crypto_ahash *tfm) 49static inline void *crypto_ahash_ctx(struct crypto_ahash *tfm)
44{ 50{
@@ -63,16 +69,16 @@ static inline struct ahash_request *ahash_dequeue_request(
63 return ahash_request_cast(crypto_dequeue_request(queue)); 69 return ahash_request_cast(crypto_dequeue_request(queue));
64} 70}
65 71
66static inline void *ahash_request_ctx(struct ahash_request *req)
67{
68 return req->__ctx;
69}
70
71static inline int ahash_tfm_in_queue(struct crypto_queue *queue, 72static inline int ahash_tfm_in_queue(struct crypto_queue *queue,
72 struct crypto_ahash *tfm) 73 struct crypto_ahash *tfm)
73{ 74{
74 return crypto_tfm_in_queue(queue, crypto_ahash_tfm(tfm)); 75 return crypto_tfm_in_queue(queue, crypto_ahash_tfm(tfm));
75} 76}
76 77
78static inline void *crypto_shash_ctx(struct crypto_shash *tfm)
79{
80 return crypto_tfm_ctx(&tfm->base);
81}
82
77#endif /* _CRYPTO_INTERNAL_HASH_H */ 83#endif /* _CRYPTO_INTERNAL_HASH_H */
78 84
diff --git a/include/linux/crc32c.h b/include/linux/crc32c.h
index 508f512e5a2f..bd8b44d96bdc 100644
--- a/include/linux/crc32c.h
+++ b/include/linux/crc32c.h
@@ -3,9 +3,9 @@
3 3
4#include <linux/types.h> 4#include <linux/types.h>
5 5
6extern u32 crc32c_le(u32 crc, unsigned char const *address, size_t length); 6extern u32 crc32c(u32 crc, const void *address, unsigned int length);
7extern u32 crc32c_be(u32 crc, unsigned char const *address, size_t length);
8 7
9#define crc32c(seed, data, length) crc32c_le(seed, (unsigned char const *)data, length) 8/* This macro exists for backwards-compatibility. */
9#define crc32c_le crc32c
10 10
11#endif /* _LINUX_CRC32C_H */ 11#endif /* _LINUX_CRC32C_H */
diff --git a/include/linux/crypto.h b/include/linux/crypto.h
index 3d2317e4af2e..3bacd71509fb 100644
--- a/include/linux/crypto.h
+++ b/include/linux/crypto.h
@@ -36,7 +36,8 @@
36#define CRYPTO_ALG_TYPE_ABLKCIPHER 0x00000005 36#define CRYPTO_ALG_TYPE_ABLKCIPHER 0x00000005
37#define CRYPTO_ALG_TYPE_GIVCIPHER 0x00000006 37#define CRYPTO_ALG_TYPE_GIVCIPHER 0x00000006
38#define CRYPTO_ALG_TYPE_DIGEST 0x00000008 38#define CRYPTO_ALG_TYPE_DIGEST 0x00000008
39#define CRYPTO_ALG_TYPE_HASH 0x00000009 39#define CRYPTO_ALG_TYPE_HASH 0x00000008
40#define CRYPTO_ALG_TYPE_SHASH 0x00000009
40#define CRYPTO_ALG_TYPE_AHASH 0x0000000a 41#define CRYPTO_ALG_TYPE_AHASH 0x0000000a
41#define CRYPTO_ALG_TYPE_RNG 0x0000000c 42#define CRYPTO_ALG_TYPE_RNG 0x0000000c
42 43
@@ -220,6 +221,7 @@ struct ablkcipher_alg {
220 221
221struct ahash_alg { 222struct ahash_alg {
222 int (*init)(struct ahash_request *req); 223 int (*init)(struct ahash_request *req);
224 int (*reinit)(struct ahash_request *req);
223 int (*update)(struct ahash_request *req); 225 int (*update)(struct ahash_request *req);
224 int (*final)(struct ahash_request *req); 226 int (*final)(struct ahash_request *req);
225 int (*digest)(struct ahash_request *req); 227 int (*digest)(struct ahash_request *req);
@@ -480,6 +482,8 @@ struct crypto_tfm {
480 struct compress_tfm compress; 482 struct compress_tfm compress;
481 struct rng_tfm rng; 483 struct rng_tfm rng;
482 } crt_u; 484 } crt_u;
485
486 void (*exit)(struct crypto_tfm *tfm);
483 487
484 struct crypto_alg *__crt_alg; 488 struct crypto_alg *__crt_alg;
485 489
@@ -544,7 +548,9 @@ struct crypto_attr_u32 {
544 * Transform user interface. 548 * Transform user interface.
545 */ 549 */
546 550
547struct crypto_tfm *crypto_alloc_tfm(const char *alg_name, u32 tfm_flags); 551struct crypto_tfm *crypto_alloc_tfm(const char *alg_name,
552 const struct crypto_type *frontend,
553 u32 type, u32 mask);
548struct crypto_tfm *crypto_alloc_base(const char *alg_name, u32 type, u32 mask); 554struct crypto_tfm *crypto_alloc_base(const char *alg_name, u32 type, u32 mask);
549void crypto_free_tfm(struct crypto_tfm *tfm); 555void crypto_free_tfm(struct crypto_tfm *tfm);
550 556
diff --git a/include/linux/fb.h b/include/linux/fb.h
index 75a81eaf3430..1ee63df5be92 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -888,7 +888,7 @@ struct fb_info {
888#define fb_writeq sbus_writeq 888#define fb_writeq sbus_writeq
889#define fb_memset sbus_memset_io 889#define fb_memset sbus_memset_io
890 890
891#elif defined(__i386__) || defined(__alpha__) || defined(__x86_64__) || defined(__hppa__) || (defined(__sh__) && !defined(__SH5__)) || defined(__powerpc__) || defined(__avr32__) 891#elif defined(__i386__) || defined(__alpha__) || defined(__x86_64__) || defined(__hppa__) || defined(__sh__) || defined(__powerpc__) || defined(__avr32__)
892 892
893#define fb_readb __raw_readb 893#define fb_readb __raw_readb
894#define fb_readw __raw_readw 894#define fb_readw __raw_readw
diff --git a/include/linux/input.h b/include/linux/input.h
index 5341e8251f8c..9a6355f74db2 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -659,6 +659,8 @@ struct input_absinfo {
659#define SW_RADIO SW_RFKILL_ALL /* deprecated */ 659#define SW_RADIO SW_RFKILL_ALL /* deprecated */
660#define SW_MICROPHONE_INSERT 0x04 /* set = inserted */ 660#define SW_MICROPHONE_INSERT 0x04 /* set = inserted */
661#define SW_DOCK 0x05 /* set = plugged into dock */ 661#define SW_DOCK 0x05 /* set = plugged into dock */
662#define SW_LINEOUT_INSERT 0x06 /* set = inserted */
663#define SW_JACK_PHYSICAL_INSERT 0x07 /* set = mechanical switch set */
662#define SW_MAX 0x0f 664#define SW_MAX 0x0f
663#define SW_CNT (SW_MAX+1) 665#define SW_CNT (SW_MAX+1)
664 666
diff --git a/include/linux/mfd/wm8350/audio.h b/include/linux/mfd/wm8350/audio.h
index 217bb22ebb8e..af95a1d2f3a1 100644
--- a/include/linux/mfd/wm8350/audio.h
+++ b/include/linux/mfd/wm8350/audio.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * audio.h -- Audio Driver for Wolfson WM8350 PMIC 2 * audio.h -- Audio Driver for Wolfson WM8350 PMIC
3 * 3 *
4 * Copyright 2007 Wolfson Microelectronics PLC 4 * Copyright 2007, 2008 Wolfson Microelectronics PLC
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify it 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 7 * under the terms of the GNU General Public License as published by the
@@ -70,9 +70,9 @@
70#define WM8350_CODEC_ISEL_0_5 3 /* x0.5 */ 70#define WM8350_CODEC_ISEL_0_5 3 /* x0.5 */
71 71
72#define WM8350_VMID_OFF 0 72#define WM8350_VMID_OFF 0
73#define WM8350_VMID_500K 1 73#define WM8350_VMID_300K 1
74#define WM8350_VMID_100K 2 74#define WM8350_VMID_50K 2
75#define WM8350_VMID_10K 3 75#define WM8350_VMID_5K 3
76 76
77/* 77/*
78 * R40 (0x28) - Clock Control 1 78 * R40 (0x28) - Clock Control 1
@@ -591,8 +591,38 @@
591#define WM8350_IRQ_CODEC_MICSCD 41 591#define WM8350_IRQ_CODEC_MICSCD 41
592#define WM8350_IRQ_CODEC_MICD 42 592#define WM8350_IRQ_CODEC_MICD 42
593 593
594/*
595 * WM8350 Platform data.
596 *
597 * This must be initialised per platform for best audio performance.
598 * Please see WM8350 datasheet for information.
599 */
600struct wm8350_audio_platform_data {
601 int vmid_discharge_msecs; /* VMID --> OFF discharge time */
602 int drain_msecs; /* OFF drain time */
603 int cap_discharge_msecs; /* Cap ON (from OFF) discharge time */
604 int vmid_charge_msecs; /* vmid power up time */
605 u32 vmid_s_curve:2; /* vmid enable s curve speed */
606 u32 dis_out4:2; /* out4 discharge speed */
607 u32 dis_out3:2; /* out3 discharge speed */
608 u32 dis_out2:2; /* out2 discharge speed */
609 u32 dis_out1:2; /* out1 discharge speed */
610 u32 vroi_out4:1; /* out4 tie off */
611 u32 vroi_out3:1; /* out3 tie off */
612 u32 vroi_out2:1; /* out2 tie off */
613 u32 vroi_out1:1; /* out1 tie off */
614 u32 vroi_enable:1; /* enable tie off */
615 u32 codec_current_on:2; /* current level ON */
616 u32 codec_current_standby:2; /* current level STANDBY */
617 u32 codec_current_charge:2; /* codec current @ vmid charge */
618};
619
620struct snd_soc_codec;
621
594struct wm8350_codec { 622struct wm8350_codec {
595 struct platform_device *pdev; 623 struct platform_device *pdev;
624 struct snd_soc_codec *codec;
625 struct wm8350_audio_platform_data *platform_data;
596}; 626};
597 627
598#endif 628#endif
diff --git a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h
index 9c309daf492b..251fc1cd5002 100644
--- a/include/sound/ac97_codec.h
+++ b/include/sound/ac97_codec.h
@@ -281,10 +281,12 @@
281/* specific - Analog Devices */ 281/* specific - Analog Devices */
282#define AC97_AD_TEST 0x5a /* test register */ 282#define AC97_AD_TEST 0x5a /* test register */
283#define AC97_AD_TEST2 0x5c /* undocumented test register 2 */ 283#define AC97_AD_TEST2 0x5c /* undocumented test register 2 */
284#define AC97_AD_HPFD_SHIFT 12 /* High Pass Filter Disable */
284#define AC97_AD_CODEC_CFG 0x70 /* codec configuration */ 285#define AC97_AD_CODEC_CFG 0x70 /* codec configuration */
285#define AC97_AD_JACK_SPDIF 0x72 /* Jack Sense & S/PDIF */ 286#define AC97_AD_JACK_SPDIF 0x72 /* Jack Sense & S/PDIF */
286#define AC97_AD_SERIAL_CFG 0x74 /* Serial Configuration */ 287#define AC97_AD_SERIAL_CFG 0x74 /* Serial Configuration */
287#define AC97_AD_MISC 0x76 /* Misc Control Bits */ 288#define AC97_AD_MISC 0x76 /* Misc Control Bits */
289#define AC97_AD_VREFD_SHIFT 2 /* V_REFOUT Disable (AD1888) */
288 290
289/* specific - Cirrus Logic */ 291/* specific - Cirrus Logic */
290#define AC97_CSR_ACMODE 0x5e /* AC Mode Register */ 292#define AC97_CSR_ACMODE 0x5e /* AC Mode Register */
diff --git a/include/sound/asound.h b/include/sound/asound.h
index 2c4dc908a54a..1c02ed1d7c4a 100644
--- a/include/sound/asound.h
+++ b/include/sound/asound.h
@@ -575,6 +575,7 @@ enum {
575#define SNDRV_TIMER_GLOBAL_SYSTEM 0 575#define SNDRV_TIMER_GLOBAL_SYSTEM 0
576#define SNDRV_TIMER_GLOBAL_RTC 1 576#define SNDRV_TIMER_GLOBAL_RTC 1
577#define SNDRV_TIMER_GLOBAL_HPET 2 577#define SNDRV_TIMER_GLOBAL_HPET 2
578#define SNDRV_TIMER_GLOBAL_HRTIMER 3
578 579
579/* info flags */ 580/* info flags */
580#define SNDRV_TIMER_FLG_SLAVE (1<<0) /* cannot be controlled */ 581#define SNDRV_TIMER_FLG_SLAVE (1<<0) /* cannot be controlled */
diff --git a/include/sound/core.h b/include/sound/core.h
index 1508c4ec1ba9..f632484bc743 100644
--- a/include/sound/core.h
+++ b/include/sound/core.h
@@ -353,7 +353,7 @@ void snd_verbose_printd(const char *file, int line, const char *format, ...)
353 * snd_printk - printk wrapper 353 * snd_printk - printk wrapper
354 * @fmt: format string 354 * @fmt: format string
355 * 355 *
356 * Works like print() but prints the file and the line of the caller 356 * Works like printk() but prints the file and the line of the caller
357 * when configured with CONFIG_SND_VERBOSE_PRINTK. 357 * when configured with CONFIG_SND_VERBOSE_PRINTK.
358 */ 358 */
359#define snd_printk(fmt, args...) \ 359#define snd_printk(fmt, args...) \
@@ -380,18 +380,40 @@ void snd_verbose_printd(const char *file, int line, const char *format, ...)
380 printk(fmt ,##args) 380 printk(fmt ,##args)
381#endif 381#endif
382 382
383/**
384 * snd_BUG - give a BUG warning message and stack trace
385 *
386 * Calls WARN() if CONFIG_SND_DEBUG is set.
387 * Ignored when CONFIG_SND_DEBUG is not set.
388 */
383#define snd_BUG() WARN(1, "BUG?\n") 389#define snd_BUG() WARN(1, "BUG?\n")
390
391/**
392 * snd_BUG_ON - debugging check macro
393 * @cond: condition to evaluate
394 *
395 * When CONFIG_SND_DEBUG is set, this macro evaluates the given condition,
396 * and call WARN() and returns the value if it's non-zero.
397 *
398 * When CONFIG_SND_DEBUG is not set, this just returns zero, and the given
399 * condition is ignored.
400 *
401 * NOTE: the argument won't be evaluated at all when CONFIG_SND_DEBUG=n.
402 * Thus, don't put any statement that influences on the code behavior,
403 * such as pre/post increment, to the argument of this macro.
404 * If you want to evaluate and give a warning, use standard WARN_ON().
405 */
384#define snd_BUG_ON(cond) WARN((cond), "BUG? (%s)\n", __stringify(cond)) 406#define snd_BUG_ON(cond) WARN((cond), "BUG? (%s)\n", __stringify(cond))
385 407
386#else /* !CONFIG_SND_DEBUG */ 408#else /* !CONFIG_SND_DEBUG */
387 409
388#define snd_printd(fmt, args...) do { } while (0) 410#define snd_printd(fmt, args...) do { } while (0)
389#define snd_BUG() do { } while (0) 411#define snd_BUG() do { } while (0)
390static inline int __snd_bug_on(void) 412static inline int __snd_bug_on(int cond)
391{ 413{
392 return 0; 414 return 0;
393} 415}
394#define snd_BUG_ON(cond) __snd_bug_on() /* always false */ 416#define snd_BUG_ON(cond) __snd_bug_on(0 && (cond)) /* always false */
395 417
396#endif /* CONFIG_SND_DEBUG */ 418#endif /* CONFIG_SND_DEBUG */
397 419
diff --git a/include/sound/info.h b/include/sound/info.h
index 8ae72e74f898..7c2ee1a21b00 100644
--- a/include/sound/info.h
+++ b/include/sound/info.h
@@ -40,30 +40,34 @@ struct snd_info_buffer {
40struct snd_info_entry; 40struct snd_info_entry;
41 41
42struct snd_info_entry_text { 42struct snd_info_entry_text {
43 void (*read) (struct snd_info_entry *entry, struct snd_info_buffer *buffer); 43 void (*read)(struct snd_info_entry *entry,
44 void (*write) (struct snd_info_entry *entry, struct snd_info_buffer *buffer); 44 struct snd_info_buffer *buffer);
45 void (*write)(struct snd_info_entry *entry,
46 struct snd_info_buffer *buffer);
45}; 47};
46 48
47struct snd_info_entry_ops { 49struct snd_info_entry_ops {
48 int (*open) (struct snd_info_entry *entry, 50 int (*open)(struct snd_info_entry *entry,
49 unsigned short mode, void **file_private_data); 51 unsigned short mode, void **file_private_data);
50 int (*release) (struct snd_info_entry * entry, 52 int (*release)(struct snd_info_entry *entry,
51 unsigned short mode, void *file_private_data); 53 unsigned short mode, void *file_private_data);
52 long (*read) (struct snd_info_entry *entry, void *file_private_data, 54 long (*read)(struct snd_info_entry *entry, void *file_private_data,
53 struct file * file, char __user *buf, 55 struct file *file, char __user *buf,
56 unsigned long count, unsigned long pos);
57 long (*write)(struct snd_info_entry *entry, void *file_private_data,
58 struct file *file, const char __user *buf,
54 unsigned long count, unsigned long pos); 59 unsigned long count, unsigned long pos);
55 long (*write) (struct snd_info_entry *entry, void *file_private_data, 60 long long (*llseek)(struct snd_info_entry *entry,
56 struct file * file, const char __user *buf, 61 void *file_private_data, struct file *file,
57 unsigned long count, unsigned long pos); 62 long long offset, int orig);
58 long long (*llseek) (struct snd_info_entry *entry, void *file_private_data, 63 unsigned int(*poll)(struct snd_info_entry *entry,
59 struct file * file, long long offset, int orig); 64 void *file_private_data, struct file *file,
60 unsigned int (*poll) (struct snd_info_entry *entry, void *file_private_data, 65 poll_table *wait);
61 struct file * file, poll_table * wait); 66 int (*ioctl)(struct snd_info_entry *entry, void *file_private_data,
62 int (*ioctl) (struct snd_info_entry *entry, void *file_private_data, 67 struct file *file, unsigned int cmd, unsigned long arg);
63 struct file * file, unsigned int cmd, unsigned long arg); 68 int (*mmap)(struct snd_info_entry *entry, void *file_private_data,
64 int (*mmap) (struct snd_info_entry *entry, void *file_private_data, 69 struct inode *inode, struct file *file,
65 struct inode * inode, struct file * file, 70 struct vm_area_struct *vma);
66 struct vm_area_struct * vma);
67}; 71};
68 72
69struct snd_info_entry { 73struct snd_info_entry {
@@ -106,34 +110,37 @@ void snd_card_info_read_oss(struct snd_info_buffer *buffer);
106static inline void snd_card_info_read_oss(struct snd_info_buffer *buffer) {} 110static inline void snd_card_info_read_oss(struct snd_info_buffer *buffer) {}
107#endif 111#endif
108 112
109int snd_iprintf(struct snd_info_buffer * buffer, char *fmt,...) __attribute__ ((format (printf, 2, 3))); 113int snd_iprintf(struct snd_info_buffer *buffer, char *fmt, ...) \
114 __attribute__ ((format (printf, 2, 3)));
110int snd_info_init(void); 115int snd_info_init(void);
111int snd_info_done(void); 116int snd_info_done(void);
112 117
113int snd_info_get_line(struct snd_info_buffer * buffer, char *line, int len); 118int snd_info_get_line(struct snd_info_buffer *buffer, char *line, int len);
114char *snd_info_get_str(char *dest, char *src, int len); 119char *snd_info_get_str(char *dest, char *src, int len);
115struct snd_info_entry *snd_info_create_module_entry(struct module * module, 120struct snd_info_entry *snd_info_create_module_entry(struct module *module,
116 const char *name, 121 const char *name,
117 struct snd_info_entry * parent); 122 struct snd_info_entry *parent);
118struct snd_info_entry *snd_info_create_card_entry(struct snd_card * card, 123struct snd_info_entry *snd_info_create_card_entry(struct snd_card *card,
119 const char *name, 124 const char *name,
120 struct snd_info_entry * parent); 125 struct snd_info_entry *parent);
121void snd_info_free_entry(struct snd_info_entry * entry); 126void snd_info_free_entry(struct snd_info_entry *entry);
122int snd_info_store_text(struct snd_info_entry * entry); 127int snd_info_store_text(struct snd_info_entry *entry);
123int snd_info_restore_text(struct snd_info_entry * entry); 128int snd_info_restore_text(struct snd_info_entry *entry);
124 129
125int snd_info_card_create(struct snd_card * card); 130int snd_info_card_create(struct snd_card *card);
126int snd_info_card_register(struct snd_card * card); 131int snd_info_card_register(struct snd_card *card);
127int snd_info_card_free(struct snd_card * card); 132int snd_info_card_free(struct snd_card *card);
128void snd_info_card_disconnect(struct snd_card * card); 133void snd_info_card_disconnect(struct snd_card *card);
129int snd_info_register(struct snd_info_entry * entry); 134void snd_info_card_id_change(struct snd_card *card);
135int snd_info_register(struct snd_info_entry *entry);
130 136
131/* for card drivers */ 137/* for card drivers */
132int snd_card_proc_new(struct snd_card *card, const char *name, struct snd_info_entry **entryp); 138int snd_card_proc_new(struct snd_card *card, const char *name,
139 struct snd_info_entry **entryp);
133 140
134static inline void snd_info_set_text_ops(struct snd_info_entry *entry, 141static inline void snd_info_set_text_ops(struct snd_info_entry *entry,
135 void *private_data, 142 void *private_data,
136 void (*read)(struct snd_info_entry *, struct snd_info_buffer *)) 143 void (*read)(struct snd_info_entry *, struct snd_info_buffer *))
137{ 144{
138 entry->private_data = private_data; 145 entry->private_data = private_data;
139 entry->c.text.read = read; 146 entry->c.text.read = read;
@@ -146,21 +153,22 @@ int snd_info_check_reserved_words(const char *str);
146#define snd_seq_root NULL 153#define snd_seq_root NULL
147#define snd_oss_root NULL 154#define snd_oss_root NULL
148 155
149static inline int snd_iprintf(struct snd_info_buffer * buffer, char *fmt,...) { return 0; } 156static inline int snd_iprintf(struct snd_info_buffer *buffer, char *fmt, ...) { return 0; }
150static inline int snd_info_init(void) { return 0; } 157static inline int snd_info_init(void) { return 0; }
151static inline int snd_info_done(void) { return 0; } 158static inline int snd_info_done(void) { return 0; }
152 159
153static inline int snd_info_get_line(struct snd_info_buffer * buffer, char *line, int len) { return 0; } 160static inline int snd_info_get_line(struct snd_info_buffer *buffer, char *line, int len) { return 0; }
154static inline char *snd_info_get_str(char *dest, char *src, int len) { return NULL; } 161static inline char *snd_info_get_str(char *dest, char *src, int len) { return NULL; }
155static inline struct snd_info_entry *snd_info_create_module_entry(struct module * module, const char *name, struct snd_info_entry * parent) { return NULL; } 162static inline struct snd_info_entry *snd_info_create_module_entry(struct module *module, const char *name, struct snd_info_entry *parent) { return NULL; }
156static inline struct snd_info_entry *snd_info_create_card_entry(struct snd_card * card, const char *name, struct snd_info_entry * parent) { return NULL; } 163static inline struct snd_info_entry *snd_info_create_card_entry(struct snd_card *card, const char *name, struct snd_info_entry *parent) { return NULL; }
157static inline void snd_info_free_entry(struct snd_info_entry * entry) { ; } 164static inline void snd_info_free_entry(struct snd_info_entry *entry) { ; }
158 165
159static inline int snd_info_card_create(struct snd_card * card) { return 0; } 166static inline int snd_info_card_create(struct snd_card *card) { return 0; }
160static inline int snd_info_card_register(struct snd_card * card) { return 0; } 167static inline int snd_info_card_register(struct snd_card *card) { return 0; }
161static inline int snd_info_card_free(struct snd_card * card) { return 0; } 168static inline int snd_info_card_free(struct snd_card *card) { return 0; }
162static inline void snd_info_card_disconnect(struct snd_card * card) { } 169static inline void snd_info_card_disconnect(struct snd_card *card) { }
163static inline int snd_info_register(struct snd_info_entry * entry) { return 0; } 170static inline void snd_info_card_id_change(struct snd_card *card) { }
171static inline int snd_info_register(struct snd_info_entry *entry) { return 0; }
164 172
165static inline int snd_card_proc_new(struct snd_card *card, const char *name, 173static inline int snd_card_proc_new(struct snd_card *card, const char *name,
166 struct snd_info_entry **entryp) { return -EINVAL; } 174 struct snd_info_entry **entryp) { return -EINVAL; }
diff --git a/include/sound/jack.h b/include/sound/jack.h
index b1b2b8b59adb..2e0315cdd0d6 100644
--- a/include/sound/jack.h
+++ b/include/sound/jack.h
@@ -35,6 +35,8 @@ enum snd_jack_types {
35 SND_JACK_HEADPHONE = 0x0001, 35 SND_JACK_HEADPHONE = 0x0001,
36 SND_JACK_MICROPHONE = 0x0002, 36 SND_JACK_MICROPHONE = 0x0002,
37 SND_JACK_HEADSET = SND_JACK_HEADPHONE | SND_JACK_MICROPHONE, 37 SND_JACK_HEADSET = SND_JACK_HEADPHONE | SND_JACK_MICROPHONE,
38 SND_JACK_LINEOUT = 0x0004,
39 SND_JACK_MECHANICAL = 0x0008, /* If detected separately */
38}; 40};
39 41
40struct snd_jack { 42struct snd_jack {
diff --git a/include/sound/l3.h b/include/sound/l3.h
new file mode 100644
index 000000000000..423a08f0f1b0
--- /dev/null
+++ b/include/sound/l3.h
@@ -0,0 +1,18 @@
1#ifndef _L3_H_
2#define _L3_H_ 1
3
4struct l3_pins {
5 void (*setdat)(int);
6 void (*setclk)(int);
7 void (*setmode)(int);
8 int data_hold;
9 int data_setup;
10 int clock_high;
11 int mode_hold;
12 int mode;
13 int mode_setup;
14};
15
16int l3_write(struct l3_pins *adap, u8 addr, u8 *data, int len);
17
18#endif
diff --git a/include/sound/s3c24xx_uda134x.h b/include/sound/s3c24xx_uda134x.h
new file mode 100644
index 000000000000..33df4cb909d3
--- /dev/null
+++ b/include/sound/s3c24xx_uda134x.h
@@ -0,0 +1,14 @@
1#ifndef _S3C24XX_UDA134X_H_
2#define _S3C24XX_UDA134X_H_ 1
3
4#include <sound/uda134x.h>
5
6struct s3c24xx_uda134x_platform_data {
7 int l3_clk;
8 int l3_mode;
9 int l3_data;
10 void (*power) (int);
11 int model;
12};
13
14#endif
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
new file mode 100644
index 000000000000..24247f763608
--- /dev/null
+++ b/include/sound/soc-dai.h
@@ -0,0 +1,231 @@
1/*
2 * linux/sound/soc-dai.h -- ALSA SoC Layer
3 *
4 * Copyright: 2005-2008 Wolfson Microelectronics. PLC.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * Digital Audio Interface (DAI) API.
11 */
12
13#ifndef __LINUX_SND_SOC_DAI_H
14#define __LINUX_SND_SOC_DAI_H
15
16
17#include <linux/list.h>
18
19struct snd_pcm_substream;
20
21/*
22 * DAI hardware audio formats.
23 *
24 * Describes the physical PCM data formating and clocking. Add new formats
25 * to the end.
26 */
27#define SND_SOC_DAIFMT_I2S 0 /* I2S mode */
28#define SND_SOC_DAIFMT_RIGHT_J 1 /* Right Justified mode */
29#define SND_SOC_DAIFMT_LEFT_J 2 /* Left Justified mode */
30#define SND_SOC_DAIFMT_DSP_A 3 /* L data msb after FRM LRC */
31#define SND_SOC_DAIFMT_DSP_B 4 /* L data msb during FRM LRC */
32#define SND_SOC_DAIFMT_AC97 5 /* AC97 */
33
34/* left and right justified also known as MSB and LSB respectively */
35#define SND_SOC_DAIFMT_MSB SND_SOC_DAIFMT_LEFT_J
36#define SND_SOC_DAIFMT_LSB SND_SOC_DAIFMT_RIGHT_J
37
38/*
39 * DAI Clock gating.
40 *
41 * DAI bit clocks can be be gated (disabled) when not the DAI is not
42 * sending or receiving PCM data in a frame. This can be used to save power.
43 */
44#define SND_SOC_DAIFMT_CONT (0 << 4) /* continuous clock */
45#define SND_SOC_DAIFMT_GATED (1 << 4) /* clock is gated */
46
47/*
48 * DAI Left/Right Clocks.
49 *
50 * Specifies whether the DAI can support different samples for similtanious
51 * playback and capture. This usually requires a seperate physical frame
52 * clock for playback and capture.
53 */
54#define SND_SOC_DAIFMT_SYNC (0 << 5) /* Tx FRM = Rx FRM */
55#define SND_SOC_DAIFMT_ASYNC (1 << 5) /* Tx FRM ~ Rx FRM */
56
57/*
58 * TDM
59 *
60 * Time Division Multiplexing. Allows PCM data to be multplexed with other
61 * data on the DAI.
62 */
63#define SND_SOC_DAIFMT_TDM (1 << 6)
64
65/*
66 * DAI hardware signal inversions.
67 *
68 * Specifies whether the DAI can also support inverted clocks for the specified
69 * format.
70 */
71#define SND_SOC_DAIFMT_NB_NF (0 << 8) /* normal bit clock + frame */
72#define SND_SOC_DAIFMT_NB_IF (1 << 8) /* normal bclk + inv frm */
73#define SND_SOC_DAIFMT_IB_NF (2 << 8) /* invert bclk + nor frm */
74#define SND_SOC_DAIFMT_IB_IF (3 << 8) /* invert bclk + frm */
75
76/*
77 * DAI hardware clock masters.
78 *
79 * This is wrt the codec, the inverse is true for the interface
80 * i.e. if the codec is clk and frm master then the interface is
81 * clk and frame slave.
82 */
83#define SND_SOC_DAIFMT_CBM_CFM (0 << 12) /* codec clk & frm master */
84#define SND_SOC_DAIFMT_CBS_CFM (1 << 12) /* codec clk slave & frm master */
85#define SND_SOC_DAIFMT_CBM_CFS (2 << 12) /* codec clk master & frame slave */
86#define SND_SOC_DAIFMT_CBS_CFS (3 << 12) /* codec clk & frm slave */
87
88#define SND_SOC_DAIFMT_FORMAT_MASK 0x000f
89#define SND_SOC_DAIFMT_CLOCK_MASK 0x00f0
90#define SND_SOC_DAIFMT_INV_MASK 0x0f00
91#define SND_SOC_DAIFMT_MASTER_MASK 0xf000
92
93/*
94 * Master Clock Directions
95 */
96#define SND_SOC_CLOCK_IN 0
97#define SND_SOC_CLOCK_OUT 1
98
99struct snd_soc_dai_ops;
100struct snd_soc_dai;
101struct snd_ac97_bus_ops;
102
103/* Digital Audio Interface registration */
104int snd_soc_register_dai(struct snd_soc_dai *dai);
105void snd_soc_unregister_dai(struct snd_soc_dai *dai);
106int snd_soc_register_dais(struct snd_soc_dai *dai, size_t count);
107void snd_soc_unregister_dais(struct snd_soc_dai *dai, size_t count);
108
109/* Digital Audio Interface clocking API.*/
110int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
111 unsigned int freq, int dir);
112
113int snd_soc_dai_set_clkdiv(struct snd_soc_dai *dai,
114 int div_id, int div);
115
116int snd_soc_dai_set_pll(struct snd_soc_dai *dai,
117 int pll_id, unsigned int freq_in, unsigned int freq_out);
118
119/* Digital Audio interface formatting */
120int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt);
121
122int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
123 unsigned int mask, int slots);
124
125int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate);
126
127/* Digital Audio Interface mute */
128int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute);
129
130/*
131 * Digital Audio Interface.
132 *
133 * Describes the Digital Audio Interface in terms of it's ALSA, DAI and AC97
134 * operations an capabilities. Codec and platfom drivers will register a this
135 * structure for every DAI they have.
136 *
137 * This structure covers the clocking, formating and ALSA operations for each
138 * interface a
139 */
140struct snd_soc_dai_ops {
141 /*
142 * DAI clocking configuration, all optional.
143 * Called by soc_card drivers, normally in their hw_params.
144 */
145 int (*set_sysclk)(struct snd_soc_dai *dai,
146 int clk_id, unsigned int freq, int dir);
147 int (*set_pll)(struct snd_soc_dai *dai,
148 int pll_id, unsigned int freq_in, unsigned int freq_out);
149 int (*set_clkdiv)(struct snd_soc_dai *dai, int div_id, int div);
150
151 /*
152 * DAI format configuration
153 * Called by soc_card drivers, normally in their hw_params.
154 */
155 int (*set_fmt)(struct snd_soc_dai *dai, unsigned int fmt);
156 int (*set_tdm_slot)(struct snd_soc_dai *dai,
157 unsigned int mask, int slots);
158 int (*set_tristate)(struct snd_soc_dai *dai, int tristate);
159
160 /*
161 * DAI digital mute - optional.
162 * Called by soc-core to minimise any pops.
163 */
164 int (*digital_mute)(struct snd_soc_dai *dai, int mute);
165
166 /*
167 * ALSA PCM audio operations - all optional.
168 * Called by soc-core during audio PCM operations.
169 */
170 int (*startup)(struct snd_pcm_substream *,
171 struct snd_soc_dai *);
172 void (*shutdown)(struct snd_pcm_substream *,
173 struct snd_soc_dai *);
174 int (*hw_params)(struct snd_pcm_substream *,
175 struct snd_pcm_hw_params *, struct snd_soc_dai *);
176 int (*hw_free)(struct snd_pcm_substream *,
177 struct snd_soc_dai *);
178 int (*prepare)(struct snd_pcm_substream *,
179 struct snd_soc_dai *);
180 int (*trigger)(struct snd_pcm_substream *, int,
181 struct snd_soc_dai *);
182};
183
184/*
185 * Digital Audio Interface runtime data.
186 *
187 * Holds runtime data for a DAI.
188 */
189struct snd_soc_dai {
190 /* DAI description */
191 char *name;
192 unsigned int id;
193 int ac97_control;
194
195 struct device *dev;
196
197 /* DAI callbacks */
198 int (*probe)(struct platform_device *pdev,
199 struct snd_soc_dai *dai);
200 void (*remove)(struct platform_device *pdev,
201 struct snd_soc_dai *dai);
202 int (*suspend)(struct snd_soc_dai *dai);
203 int (*resume)(struct snd_soc_dai *dai);
204
205 /* ops */
206 struct snd_soc_dai_ops ops;
207
208 /* DAI capabilities */
209 struct snd_soc_pcm_stream capture;
210 struct snd_soc_pcm_stream playback;
211
212 /* DAI runtime info */
213 struct snd_pcm_runtime *runtime;
214 struct snd_soc_codec *codec;
215 unsigned int active;
216 unsigned char pop_wait:1;
217 void *dma_data;
218
219 /* DAI private data */
220 void *private_data;
221
222 /* parent codec/platform */
223 union {
224 struct snd_soc_codec *codec;
225 struct snd_soc_platform *platform;
226 };
227
228 struct list_head list;
229};
230
231#endif
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index ca699a3017f3..7ee2f70ca42e 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -221,8 +221,6 @@ int snd_soc_dapm_new_controls(struct snd_soc_codec *codec,
221 int num); 221 int num);
222 222
223/* dapm path setup */ 223/* dapm path setup */
224int __deprecated snd_soc_dapm_connect_input(struct snd_soc_codec *codec,
225 const char *sink_name, const char *control_name, const char *src_name);
226int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec); 224int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec);
227void snd_soc_dapm_free(struct snd_soc_device *socdev); 225void snd_soc_dapm_free(struct snd_soc_device *socdev);
228int snd_soc_dapm_add_routes(struct snd_soc_codec *codec, 226int snd_soc_dapm_add_routes(struct snd_soc_codec *codec,
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 5e0189876afd..f86e455d3828 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -21,8 +21,6 @@
21#include <sound/control.h> 21#include <sound/control.h>
22#include <sound/ac97_codec.h> 22#include <sound/ac97_codec.h>
23 23
24#define SND_SOC_VERSION "0.13.2"
25
26/* 24/*
27 * Convenience kcontrol builders 25 * Convenience kcontrol builders
28 */ 26 */
@@ -145,105 +143,31 @@ enum snd_soc_bias_level {
145 SND_SOC_BIAS_OFF, 143 SND_SOC_BIAS_OFF,
146}; 144};
147 145
148/*
149 * Digital Audio Interface (DAI) types
150 */
151#define SND_SOC_DAI_AC97 0x1
152#define SND_SOC_DAI_I2S 0x2
153#define SND_SOC_DAI_PCM 0x4
154#define SND_SOC_DAI_AC97_BUS 0x8 /* for custom i.e. non ac97_codec.c */
155
156/*
157 * DAI hardware audio formats
158 */
159#define SND_SOC_DAIFMT_I2S 0 /* I2S mode */
160#define SND_SOC_DAIFMT_RIGHT_J 1 /* Right justified mode */
161#define SND_SOC_DAIFMT_LEFT_J 2 /* Left Justified mode */
162#define SND_SOC_DAIFMT_DSP_A 3 /* L data msb after FRM or LRC */
163#define SND_SOC_DAIFMT_DSP_B 4 /* L data msb during FRM or LRC */
164#define SND_SOC_DAIFMT_AC97 5 /* AC97 */
165
166#define SND_SOC_DAIFMT_MSB SND_SOC_DAIFMT_LEFT_J
167#define SND_SOC_DAIFMT_LSB SND_SOC_DAIFMT_RIGHT_J
168
169/*
170 * DAI Gating
171 */
172#define SND_SOC_DAIFMT_CONT (0 << 4) /* continuous clock */
173#define SND_SOC_DAIFMT_GATED (1 << 4) /* clock is gated when not Tx/Rx */
174
175/*
176 * DAI Sync
177 * Synchronous LR (Left Right) clocks and Frame signals.
178 */
179#define SND_SOC_DAIFMT_SYNC (0 << 5) /* Tx FRM = Rx FRM */
180#define SND_SOC_DAIFMT_ASYNC (1 << 5) /* Tx FRM ~ Rx FRM */
181
182/*
183 * TDM
184 */
185#define SND_SOC_DAIFMT_TDM (1 << 6)
186
187/*
188 * DAI hardware signal inversions
189 */
190#define SND_SOC_DAIFMT_NB_NF (0 << 8) /* normal bclk + frm */
191#define SND_SOC_DAIFMT_NB_IF (1 << 8) /* normal bclk + inv frm */
192#define SND_SOC_DAIFMT_IB_NF (2 << 8) /* invert bclk + nor frm */
193#define SND_SOC_DAIFMT_IB_IF (3 << 8) /* invert bclk + frm */
194
195/*
196 * DAI hardware clock masters
197 * This is wrt the codec, the inverse is true for the interface
198 * i.e. if the codec is clk and frm master then the interface is
199 * clk and frame slave.
200 */
201#define SND_SOC_DAIFMT_CBM_CFM (0 << 12) /* codec clk & frm master */
202#define SND_SOC_DAIFMT_CBS_CFM (1 << 12) /* codec clk slave & frm master */
203#define SND_SOC_DAIFMT_CBM_CFS (2 << 12) /* codec clk master & frame slave */
204#define SND_SOC_DAIFMT_CBS_CFS (3 << 12) /* codec clk & frm slave */
205
206#define SND_SOC_DAIFMT_FORMAT_MASK 0x000f
207#define SND_SOC_DAIFMT_CLOCK_MASK 0x00f0
208#define SND_SOC_DAIFMT_INV_MASK 0x0f00
209#define SND_SOC_DAIFMT_MASTER_MASK 0xf000
210
211
212/*
213 * Master Clock Directions
214 */
215#define SND_SOC_CLOCK_IN 0
216#define SND_SOC_CLOCK_OUT 1
217
218/*
219 * AC97 codec ID's bitmask
220 */
221#define SND_SOC_DAI_AC97_ID0 (1 << 0)
222#define SND_SOC_DAI_AC97_ID1 (1 << 1)
223#define SND_SOC_DAI_AC97_ID2 (1 << 2)
224#define SND_SOC_DAI_AC97_ID3 (1 << 3)
225
226struct snd_soc_device; 146struct snd_soc_device;
227struct snd_soc_pcm_stream; 147struct snd_soc_pcm_stream;
228struct snd_soc_ops; 148struct snd_soc_ops;
229struct snd_soc_dai_mode; 149struct snd_soc_dai_mode;
230struct snd_soc_pcm_runtime; 150struct snd_soc_pcm_runtime;
231struct snd_soc_dai; 151struct snd_soc_dai;
152struct snd_soc_platform;
232struct snd_soc_codec; 153struct snd_soc_codec;
233struct snd_soc_machine_config;
234struct soc_enum; 154struct soc_enum;
235struct snd_soc_ac97_ops; 155struct snd_soc_ac97_ops;
236struct snd_soc_clock_info;
237 156
238typedef int (*hw_write_t)(void *,const char* ,int); 157typedef int (*hw_write_t)(void *,const char* ,int);
239typedef int (*hw_read_t)(void *,char* ,int); 158typedef int (*hw_read_t)(void *,char* ,int);
240 159
241extern struct snd_ac97_bus_ops soc_ac97_ops; 160extern struct snd_ac97_bus_ops soc_ac97_ops;
242 161
162int snd_soc_register_platform(struct snd_soc_platform *platform);
163void snd_soc_unregister_platform(struct snd_soc_platform *platform);
164int snd_soc_register_codec(struct snd_soc_codec *codec);
165void snd_soc_unregister_codec(struct snd_soc_codec *codec);
166
243/* pcm <-> DAI connect */ 167/* pcm <-> DAI connect */
244void snd_soc_free_pcms(struct snd_soc_device *socdev); 168void snd_soc_free_pcms(struct snd_soc_device *socdev);
245int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid); 169int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid);
246int snd_soc_register_card(struct snd_soc_device *socdev); 170int snd_soc_init_card(struct snd_soc_device *socdev);
247 171
248/* set runtime hw params */ 172/* set runtime hw params */
249int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream, 173int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream,
@@ -263,27 +187,6 @@ int snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
263 struct snd_ac97_bus_ops *ops, int num); 187 struct snd_ac97_bus_ops *ops, int num);
264void snd_soc_free_ac97_codec(struct snd_soc_codec *codec); 188void snd_soc_free_ac97_codec(struct snd_soc_codec *codec);
265 189
266/* Digital Audio Interface clocking API.*/
267int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
268 unsigned int freq, int dir);
269
270int snd_soc_dai_set_clkdiv(struct snd_soc_dai *dai,
271 int div_id, int div);
272
273int snd_soc_dai_set_pll(struct snd_soc_dai *dai,
274 int pll_id, unsigned int freq_in, unsigned int freq_out);
275
276/* Digital Audio interface formatting */
277int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt);
278
279int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
280 unsigned int mask, int slots);
281
282int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate);
283
284/* Digital Audio Interface mute */
285int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute);
286
287/* 190/*
288 *Controls 191 *Controls
289 */ 192 */
@@ -341,66 +244,14 @@ struct snd_soc_ops {
341 int (*trigger)(struct snd_pcm_substream *, int); 244 int (*trigger)(struct snd_pcm_substream *, int);
342}; 245};
343 246
344/* ASoC DAI ops */
345struct snd_soc_dai_ops {
346 /* DAI clocking configuration */
347 int (*set_sysclk)(struct snd_soc_dai *dai,
348 int clk_id, unsigned int freq, int dir);
349 int (*set_pll)(struct snd_soc_dai *dai,
350 int pll_id, unsigned int freq_in, unsigned int freq_out);
351 int (*set_clkdiv)(struct snd_soc_dai *dai, int div_id, int div);
352
353 /* DAI format configuration */
354 int (*set_fmt)(struct snd_soc_dai *dai, unsigned int fmt);
355 int (*set_tdm_slot)(struct snd_soc_dai *dai,
356 unsigned int mask, int slots);
357 int (*set_tristate)(struct snd_soc_dai *dai, int tristate);
358
359 /* digital mute */
360 int (*digital_mute)(struct snd_soc_dai *dai, int mute);
361};
362
363/* SoC DAI (Digital Audio Interface) */
364struct snd_soc_dai {
365 /* DAI description */
366 char *name;
367 unsigned int id;
368 unsigned char type;
369
370 /* DAI callbacks */
371 int (*probe)(struct platform_device *pdev,
372 struct snd_soc_dai *dai);
373 void (*remove)(struct platform_device *pdev,
374 struct snd_soc_dai *dai);
375 int (*suspend)(struct platform_device *pdev,
376 struct snd_soc_dai *dai);
377 int (*resume)(struct platform_device *pdev,
378 struct snd_soc_dai *dai);
379
380 /* ops */
381 struct snd_soc_ops ops;
382 struct snd_soc_dai_ops dai_ops;
383
384 /* DAI capabilities */
385 struct snd_soc_pcm_stream capture;
386 struct snd_soc_pcm_stream playback;
387
388 /* DAI runtime info */
389 struct snd_pcm_runtime *runtime;
390 struct snd_soc_codec *codec;
391 unsigned int active;
392 unsigned char pop_wait:1;
393 void *dma_data;
394
395 /* DAI private data */
396 void *private_data;
397};
398
399/* SoC Audio Codec */ 247/* SoC Audio Codec */
400struct snd_soc_codec { 248struct snd_soc_codec {
401 char *name; 249 char *name;
402 struct module *owner; 250 struct module *owner;
403 struct mutex mutex; 251 struct mutex mutex;
252 struct device *dev;
253
254 struct list_head list;
404 255
405 /* callbacks */ 256 /* callbacks */
406 int (*set_bias_level)(struct snd_soc_codec *, 257 int (*set_bias_level)(struct snd_soc_codec *,
@@ -426,6 +277,7 @@ struct snd_soc_codec {
426 short reg_cache_step; 277 short reg_cache_step;
427 278
428 /* dapm */ 279 /* dapm */
280 u32 pop_time;
429 struct list_head dapm_widgets; 281 struct list_head dapm_widgets;
430 struct list_head dapm_paths; 282 struct list_head dapm_paths;
431 enum snd_soc_bias_level bias_level; 283 enum snd_soc_bias_level bias_level;
@@ -435,6 +287,11 @@ struct snd_soc_codec {
435 /* codec DAI's */ 287 /* codec DAI's */
436 struct snd_soc_dai *dai; 288 struct snd_soc_dai *dai;
437 unsigned int num_dai; 289 unsigned int num_dai;
290
291#ifdef CONFIG_DEBUG_FS
292 struct dentry *debugfs_reg;
293 struct dentry *debugfs_pop_time;
294#endif
438}; 295};
439 296
440/* codec device */ 297/* codec device */
@@ -448,13 +305,12 @@ struct snd_soc_codec_device {
448/* SoC platform interface */ 305/* SoC platform interface */
449struct snd_soc_platform { 306struct snd_soc_platform {
450 char *name; 307 char *name;
308 struct list_head list;
451 309
452 int (*probe)(struct platform_device *pdev); 310 int (*probe)(struct platform_device *pdev);
453 int (*remove)(struct platform_device *pdev); 311 int (*remove)(struct platform_device *pdev);
454 int (*suspend)(struct platform_device *pdev, 312 int (*suspend)(struct snd_soc_dai *dai);
455 struct snd_soc_dai *dai); 313 int (*resume)(struct snd_soc_dai *dai);
456 int (*resume)(struct platform_device *pdev,
457 struct snd_soc_dai *dai);
458 314
459 /* pcm creation and destruction */ 315 /* pcm creation and destruction */
460 int (*pcm_new)(struct snd_card *, struct snd_soc_dai *, 316 int (*pcm_new)(struct snd_card *, struct snd_soc_dai *,
@@ -484,9 +340,14 @@ struct snd_soc_dai_link {
484 struct snd_pcm *pcm; 340 struct snd_pcm *pcm;
485}; 341};
486 342
487/* SoC machine */ 343/* SoC card */
488struct snd_soc_machine { 344struct snd_soc_card {
489 char *name; 345 char *name;
346 struct device *dev;
347
348 struct list_head list;
349
350 int instantiated;
490 351
491 int (*probe)(struct platform_device *pdev); 352 int (*probe)(struct platform_device *pdev);
492 int (*remove)(struct platform_device *pdev); 353 int (*remove)(struct platform_device *pdev);
@@ -499,23 +360,26 @@ struct snd_soc_machine {
499 int (*resume_post)(struct platform_device *pdev); 360 int (*resume_post)(struct platform_device *pdev);
500 361
501 /* callbacks */ 362 /* callbacks */
502 int (*set_bias_level)(struct snd_soc_machine *, 363 int (*set_bias_level)(struct snd_soc_card *,
503 enum snd_soc_bias_level level); 364 enum snd_soc_bias_level level);
504 365
505 /* CPU <--> Codec DAI links */ 366 /* CPU <--> Codec DAI links */
506 struct snd_soc_dai_link *dai_link; 367 struct snd_soc_dai_link *dai_link;
507 int num_links; 368 int num_links;
369
370 struct snd_soc_device *socdev;
371
372 struct snd_soc_platform *platform;
373 struct delayed_work delayed_work;
374 struct work_struct deferred_resume_work;
508}; 375};
509 376
510/* SoC Device - the audio subsystem */ 377/* SoC Device - the audio subsystem */
511struct snd_soc_device { 378struct snd_soc_device {
512 struct device *dev; 379 struct device *dev;
513 struct snd_soc_machine *machine; 380 struct snd_soc_card *card;
514 struct snd_soc_platform *platform;
515 struct snd_soc_codec *codec; 381 struct snd_soc_codec *codec;
516 struct snd_soc_codec_device *codec_dev; 382 struct snd_soc_codec_device *codec_dev;
517 struct delayed_work delayed_work;
518 struct work_struct deferred_resume_work;
519 void *codec_data; 383 void *codec_data;
520}; 384};
521 385
@@ -542,4 +406,6 @@ struct soc_enum {
542 void *dapm; 406 void *dapm;
543}; 407};
544 408
409#include <sound/soc-dai.h>
410
545#endif 411#endif
diff --git a/include/sound/uda134x.h b/include/sound/uda134x.h
new file mode 100644
index 000000000000..475ef8bb7dcd
--- /dev/null
+++ b/include/sound/uda134x.h
@@ -0,0 +1,26 @@
1/*
2 * uda134x.h -- UDA134x ALSA SoC Codec driver
3 *
4 * Copyright 2007 Dension Audio Systems Ltd.
5 * Author: Zoltan Devai
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 _UDA134X_H
13#define _UDA134X_H
14
15#include <sound/l3.h>
16
17struct uda134x_platform_data {
18 struct l3_pins l3;
19 void (*power) (int);
20 int model;
21#define UDA134X_UDA1340 1
22#define UDA134X_UDA1341 2
23#define UDA134X_UDA1344 3
24};
25
26#endif /* _UDA134X_H */
diff --git a/include/sound/version.h b/include/sound/version.h
index 4aafeda88634..2b48237e23bf 100644
--- a/include/sound/version.h
+++ b/include/sound/version.h
@@ -1,3 +1,3 @@
1/* include/version.h */ 1/* include/version.h */
2#define CONFIG_SND_VERSION "1.0.18rc3" 2#define CONFIG_SND_VERSION "1.0.18a"
3#define CONFIG_SND_DATE "" 3#define CONFIG_SND_DATE ""
diff --git a/include/video/sh_mobile_lcdc.h b/include/video/sh_mobile_lcdc.h
index 1a4bc6ada606..25144ab22b95 100644
--- a/include/video/sh_mobile_lcdc.h
+++ b/include/video/sh_mobile_lcdc.h
@@ -37,6 +37,7 @@ enum { LCDC_CLK_BUS, LCDC_CLK_PERIPHERAL, LCDC_CLK_EXTERNAL };
37struct sh_mobile_lcdc_sys_bus_cfg { 37struct sh_mobile_lcdc_sys_bus_cfg {
38 unsigned long ldmt2r; 38 unsigned long ldmt2r;
39 unsigned long ldmt3r; 39 unsigned long ldmt3r;
40 unsigned long deferred_io_msec;
40}; 41};
41 42
42struct sh_mobile_lcdc_sys_bus_ops { 43struct sh_mobile_lcdc_sys_bus_ops {
diff --git a/lib/Kconfig b/lib/Kconfig
index 85cf7ea978aa..fd4118e097f0 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -64,6 +64,8 @@ config CRC7
64 64
65config LIBCRC32C 65config LIBCRC32C
66 tristate "CRC32c (Castagnoli, et al) Cyclic Redundancy-Check" 66 tristate "CRC32c (Castagnoli, et al) Cyclic Redundancy-Check"
67 select CRYPTO
68 select CRYPTO_CRC32C
67 help 69 help
68 This option is provided for the case where no in-kernel-tree 70 This option is provided for the case where no in-kernel-tree
69 modules require CRC32c functions, but a module built outside the 71 modules require CRC32c functions, but a module built outside the
diff --git a/lib/libcrc32c.c b/lib/libcrc32c.c
index b5c3287d8ea4..244f5480c898 100644
--- a/lib/libcrc32c.c
+++ b/lib/libcrc32c.c
@@ -30,168 +30,52 @@
30 * any later version. 30 * any later version.
31 * 31 *
32 */ 32 */
33#include <linux/crc32c.h>
34#include <linux/compiler.h>
35#include <linux/module.h>
36
37MODULE_AUTHOR("Clay Haapala <chaapala@cisco.com>");
38MODULE_DESCRIPTION("CRC32c (Castagnoli) calculations");
39MODULE_LICENSE("GPL");
40 33
41#define CRC32C_POLY_BE 0x1EDC6F41 34#include <crypto/hash.h>
42#define CRC32C_POLY_LE 0x82F63B78 35#include <linux/err.h>
36#include <linux/init.h>
37#include <linux/kernel.h>
38#include <linux/module.h>
43 39
44#ifndef CRC_LE_BITS 40static struct crypto_shash *tfm;
45# define CRC_LE_BITS 8
46#endif
47 41
42u32 crc32c(u32 crc, const void *address, unsigned int length)
43{
44 struct {
45 struct shash_desc shash;
46 char ctx[crypto_shash_descsize(tfm)];
47 } desc;
48 int err;
48 49
49/* 50 desc.shash.tfm = tfm;
50 * Haven't generated a big-endian table yet, but the bit-wise version 51 desc.shash.flags = 0;
51 * should at least work. 52 *(u32 *)desc.ctx = crc;
52 */
53#if defined CRC_BE_BITS && CRC_BE_BITS != 1
54#undef CRC_BE_BITS
55#endif
56#ifndef CRC_BE_BITS
57# define CRC_BE_BITS 1
58#endif
59 53
60EXPORT_SYMBOL(crc32c_le); 54 err = crypto_shash_update(&desc.shash, address, length);
55 BUG_ON(err);
61 56
62#if CRC_LE_BITS == 1 57 return *(u32 *)desc.ctx;
63/*
64 * Compute things bit-wise, as done in crc32.c. We could share the tight
65 * loop below with crc32 and vary the POLY if we don't find value in terms
66 * of space and maintainability in keeping the two modules separate.
67 */
68u32 __pure
69crc32c_le(u32 crc, unsigned char const *p, size_t len)
70{
71 int i;
72 while (len--) {
73 crc ^= *p++;
74 for (i = 0; i < 8; i++)
75 crc = (crc >> 1) ^ ((crc & 1) ? CRC32C_POLY_LE : 0);
76 }
77 return crc;
78} 58}
79#else
80
81/*
82 * This is the CRC-32C table
83 * Generated with:
84 * width = 32 bits
85 * poly = 0x1EDC6F41
86 * reflect input bytes = true
87 * reflect output bytes = true
88 */
89
90static const u32 crc32c_table[256] = {
91 0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L,
92 0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL,
93 0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL,
94 0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L,
95 0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL,
96 0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L,
97 0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L,
98 0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL,
99 0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL,
100 0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L,
101 0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L,
102 0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL,
103 0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L,
104 0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL,
105 0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL,
106 0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L,
107 0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L,
108 0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L,
109 0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L,
110 0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L,
111 0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L,
112 0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L,
113 0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L,
114 0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L,
115 0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L,
116 0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L,
117 0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L,
118 0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L,
119 0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L,
120 0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L,
121 0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L,
122 0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L,
123 0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL,
124 0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L,
125 0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L,
126 0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL,
127 0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L,
128 0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL,
129 0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL,
130 0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L,
131 0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L,
132 0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL,
133 0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL,
134 0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L,
135 0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL,
136 0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L,
137 0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L,
138 0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL,
139 0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L,
140 0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL,
141 0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL,
142 0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L,
143 0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL,
144 0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L,
145 0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L,
146 0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL,
147 0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL,
148 0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L,
149 0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L,
150 0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL,
151 0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L,
152 0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL,
153 0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL,
154 0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L
155};
156 59
157/* 60EXPORT_SYMBOL(crc32c);
158 * Steps through buffer one byte at at time, calculates reflected
159 * crc using table.
160 */
161 61
162u32 __pure 62static int __init libcrc32c_mod_init(void)
163crc32c_le(u32 crc, unsigned char const *data, size_t length)
164{ 63{
165 while (length--) 64 tfm = crypto_alloc_shash("crc32c", 0, 0);
166 crc = 65 if (IS_ERR(tfm))
167 crc32c_table[(crc ^ *data++) & 0xFFL] ^ (crc >> 8); 66 return PTR_ERR(tfm);
168 67
169 return crc; 68 return 0;
170} 69}
171 70
172#endif /* CRC_LE_BITS == 8 */ 71static void __exit libcrc32c_mod_fini(void)
173
174EXPORT_SYMBOL(crc32c_be);
175
176#if CRC_BE_BITS == 1
177u32 __pure
178crc32c_be(u32 crc, unsigned char const *p, size_t len)
179{ 72{
180 int i; 73 crypto_free_shash(tfm);
181 while (len--) {
182 crc ^= *p++ << 24;
183 for (i = 0; i < 8; i++)
184 crc =
185 (crc << 1) ^ ((crc & 0x80000000) ? CRC32C_POLY_BE :
186 0);
187 }
188 return crc;
189} 74}
190#endif
191 75
192/* 76module_init(libcrc32c_mod_init);
193 * Unit test 77module_exit(libcrc32c_mod_fini);
194 * 78
195 * A small unit test suite is implemented as part of the crypto suite. 79MODULE_AUTHOR("Clay Haapala <chaapala@cisco.com>");
196 * Select CRYPTO_CRC32C and use the tcrypt module to run the tests. 80MODULE_DESCRIPTION("CRC32c (Castagnoli) calculations");
197 */ 81MODULE_LICENSE("GPL");
diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl
index 6b9fe3eb8360..c67cec8e90f4 100755
--- a/scripts/recordmcount.pl
+++ b/scripts/recordmcount.pl
@@ -167,6 +167,17 @@ if ($arch eq "x86_64") {
167 $objcopy .= " -O elf32-i386"; 167 $objcopy .= " -O elf32-i386";
168 $cc .= " -m32"; 168 $cc .= " -m32";
169 169
170} elsif ($arch eq "sh") {
171 $section_regex = "Disassembly of section\\s+(\\S+):";
172 $function_regex = "^([0-9a-fA-F]+)\\s+<(.*?)>:";
173 $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\smcount\$";
174 $type = ".long";
175
176 # force flags for this arch
177 $ld .= " -m shlelf_linux";
178 $objcopy .= " -O elf32-sh-linux";
179 $cc .= " -m32";
180
170} else { 181} else {
171 die "Arch $arch is not supported with CONFIG_FTRACE_MCOUNT_RECORD"; 182 die "Arch $arch is not supported with CONFIG_FTRACE_MCOUNT_RECORD";
172} 183}
diff --git a/sound/ac97_bus.c b/sound/ac97_bus.c
index 7fa37e15f196..a351dd0a09c7 100644
--- a/sound/ac97_bus.c
+++ b/sound/ac97_bus.c
@@ -15,6 +15,7 @@
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/device.h> 16#include <linux/device.h>
17#include <linux/string.h> 17#include <linux/string.h>
18#include <sound/ac97_codec.h>
18 19
19/* 20/*
20 * Let drivers decide whether they want to support given codec from their 21 * Let drivers decide whether they want to support given codec from their
diff --git a/sound/aoa/codecs/Makefile b/sound/aoa/codecs/Makefile
index 31cbe68fd42f..c3ee77fc4b2d 100644
--- a/sound/aoa/codecs/Makefile
+++ b/sound/aoa/codecs/Makefile
@@ -1,3 +1,7 @@
1snd-aoa-codec-onyx-objs := onyx.o
2snd-aoa-codec-tas-objs := tas.o
3snd-aoa-codec-toonie-objs := toonie.o
4
1obj-$(CONFIG_SND_AOA_ONYX) += snd-aoa-codec-onyx.o 5obj-$(CONFIG_SND_AOA_ONYX) += snd-aoa-codec-onyx.o
2obj-$(CONFIG_SND_AOA_TAS) += snd-aoa-codec-tas.o 6obj-$(CONFIG_SND_AOA_TAS) += snd-aoa-codec-tas.o
3obj-$(CONFIG_SND_AOA_TOONIE) += snd-aoa-codec-toonie.o 7obj-$(CONFIG_SND_AOA_TOONIE) += snd-aoa-codec-toonie.o
diff --git a/sound/aoa/codecs/snd-aoa-codec-onyx.c b/sound/aoa/codecs/onyx.c
index 6a3837d480e5..15500b9d2da0 100644
--- a/sound/aoa/codecs/snd-aoa-codec-onyx.c
+++ b/sound/aoa/codecs/onyx.c
@@ -37,7 +37,7 @@ MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
37MODULE_LICENSE("GPL"); 37MODULE_LICENSE("GPL");
38MODULE_DESCRIPTION("pcm3052 (onyx) codec driver for snd-aoa"); 38MODULE_DESCRIPTION("pcm3052 (onyx) codec driver for snd-aoa");
39 39
40#include "snd-aoa-codec-onyx.h" 40#include "onyx.h"
41#include "../aoa.h" 41#include "../aoa.h"
42#include "../soundbus/soundbus.h" 42#include "../soundbus/soundbus.h"
43 43
@@ -292,7 +292,7 @@ static int onyx_snd_capture_source_put(struct snd_kcontrol *kcontrol,
292static struct snd_kcontrol_new capture_source_control = { 292static struct snd_kcontrol_new capture_source_control = {
293 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 293 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
294 /* If we name this 'Input Source', it properly shows up in 294 /* If we name this 'Input Source', it properly shows up in
295 * alsamixer as a selection, * but it's shown under the 295 * alsamixer as a selection, * but it's shown under the
296 * 'Playback' category. 296 * 'Playback' category.
297 * If I name it 'Capture Source', it shows up in strange 297 * If I name it 'Capture Source', it shows up in strange
298 * ways (two bools of which one can be selected at a 298 * ways (two bools of which one can be selected at a
@@ -477,7 +477,7 @@ static int onyx_spdif_mask_get(struct snd_kcontrol *kcontrol,
477 477
478 ucontrol->value.iec958.status[3] = 0x3f; 478 ucontrol->value.iec958.status[3] = 0x3f;
479 ucontrol->value.iec958.status[4] = 0x0f; 479 ucontrol->value.iec958.status[4] = 0x0f;
480 480
481 return 0; 481 return 0;
482} 482}
483 483
@@ -682,7 +682,7 @@ static int onyx_usable(struct codec_info_item *cii,
682 onyx_read_register(onyx, ONYX_REG_DIG_INFO4, &v); 682 onyx_read_register(onyx, ONYX_REG_DIG_INFO4, &v);
683 spdif_enabled = !!(v & ONYX_SPDIF_ENABLE); 683 spdif_enabled = !!(v & ONYX_SPDIF_ENABLE);
684 onyx_read_register(onyx, ONYX_REG_DAC_CONTROL, &v); 684 onyx_read_register(onyx, ONYX_REG_DAC_CONTROL, &v);
685 analog_enabled = 685 analog_enabled =
686 (v & (ONYX_MUTE_RIGHT|ONYX_MUTE_LEFT)) 686 (v & (ONYX_MUTE_RIGHT|ONYX_MUTE_LEFT))
687 != (ONYX_MUTE_RIGHT|ONYX_MUTE_LEFT); 687 != (ONYX_MUTE_RIGHT|ONYX_MUTE_LEFT);
688 mutex_unlock(&onyx->mutex); 688 mutex_unlock(&onyx->mutex);
@@ -882,7 +882,7 @@ static int onyx_init_codec(struct aoa_codec *codec)
882 msleep(1); 882 msleep(1);
883 onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 0); 883 onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 0);
884 msleep(1); 884 msleep(1);
885 885
886 if (onyx_register_init(onyx)) { 886 if (onyx_register_init(onyx)) {
887 printk(KERN_ERR PFX "failed to initialise onyx registers\n"); 887 printk(KERN_ERR PFX "failed to initialise onyx registers\n");
888 return -ENODEV; 888 return -ENODEV;
@@ -1069,7 +1069,7 @@ static int onyx_i2c_attach(struct i2c_adapter *adapter)
1069 1069
1070 /* if that didn't work, try desperate mode for older 1070 /* if that didn't work, try desperate mode for older
1071 * machines that have stuff missing from the device tree */ 1071 * machines that have stuff missing from the device tree */
1072 1072
1073 if (!of_device_is_compatible(busnode, "k2-i2c")) 1073 if (!of_device_is_compatible(busnode, "k2-i2c"))
1074 return -ENODEV; 1074 return -ENODEV;
1075 1075
diff --git a/sound/aoa/codecs/snd-aoa-codec-onyx.h b/sound/aoa/codecs/onyx.h
index ffd20254ff76..ffd20254ff76 100644
--- a/sound/aoa/codecs/snd-aoa-codec-onyx.h
+++ b/sound/aoa/codecs/onyx.h
diff --git a/sound/aoa/codecs/snd-aoa-codec-tas-basstreble.h b/sound/aoa/codecs/tas-basstreble.h
index 69b61136fd54..69b61136fd54 100644
--- a/sound/aoa/codecs/snd-aoa-codec-tas-basstreble.h
+++ b/sound/aoa/codecs/tas-basstreble.h
diff --git a/sound/aoa/codecs/snd-aoa-codec-tas-gain-table.h b/sound/aoa/codecs/tas-gain-table.h
index 4cfa6757715e..4cfa6757715e 100644
--- a/sound/aoa/codecs/snd-aoa-codec-tas-gain-table.h
+++ b/sound/aoa/codecs/tas-gain-table.h
diff --git a/sound/aoa/codecs/snd-aoa-codec-tas.c b/sound/aoa/codecs/tas.c
index 6c515b2b8bbd..008e0f85097d 100644
--- a/sound/aoa/codecs/snd-aoa-codec-tas.c
+++ b/sound/aoa/codecs/tas.c
@@ -71,9 +71,9 @@ MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
71MODULE_LICENSE("GPL"); 71MODULE_LICENSE("GPL");
72MODULE_DESCRIPTION("tas codec driver for snd-aoa"); 72MODULE_DESCRIPTION("tas codec driver for snd-aoa");
73 73
74#include "snd-aoa-codec-tas.h" 74#include "tas.h"
75#include "snd-aoa-codec-tas-gain-table.h" 75#include "tas-gain-table.h"
76#include "snd-aoa-codec-tas-basstreble.h" 76#include "tas-basstreble.h"
77#include "../aoa.h" 77#include "../aoa.h"
78#include "../soundbus/soundbus.h" 78#include "../soundbus/soundbus.h"
79 79
@@ -880,7 +880,7 @@ static void tas_exit_codec(struct aoa_codec *codec)
880 return; 880 return;
881 tas->codec.soundbus_dev->detach_codec(tas->codec.soundbus_dev, tas); 881 tas->codec.soundbus_dev->detach_codec(tas->codec.soundbus_dev, tas);
882} 882}
883 883
884 884
885static struct i2c_driver tas_driver; 885static struct i2c_driver tas_driver;
886 886
diff --git a/sound/aoa/codecs/snd-aoa-codec-tas.h b/sound/aoa/codecs/tas.h
index ae177e3466e6..ae177e3466e6 100644
--- a/sound/aoa/codecs/snd-aoa-codec-tas.h
+++ b/sound/aoa/codecs/tas.h
diff --git a/sound/aoa/codecs/snd-aoa-codec-toonie.c b/sound/aoa/codecs/toonie.c
index 3c7d1d8a9a6f..f13827e17562 100644
--- a/sound/aoa/codecs/snd-aoa-codec-toonie.c
+++ b/sound/aoa/codecs/toonie.c
@@ -131,7 +131,7 @@ static int __init toonie_init(void)
131 toonie->codec.owner = THIS_MODULE; 131 toonie->codec.owner = THIS_MODULE;
132 toonie->codec.init = toonie_init_codec; 132 toonie->codec.init = toonie_init_codec;
133 toonie->codec.exit = toonie_exit_codec; 133 toonie->codec.exit = toonie_exit_codec;
134 134
135 if (aoa_codec_register(&toonie->codec)) { 135 if (aoa_codec_register(&toonie->codec)) {
136 kfree(toonie); 136 kfree(toonie);
137 return -EINVAL; 137 return -EINVAL;
diff --git a/sound/aoa/core/Makefile b/sound/aoa/core/Makefile
index 62dc7287f663..a1596e88c718 100644
--- a/sound/aoa/core/Makefile
+++ b/sound/aoa/core/Makefile
@@ -1,5 +1,5 @@
1obj-$(CONFIG_SND_AOA) += snd-aoa.o 1obj-$(CONFIG_SND_AOA) += snd-aoa.o
2snd-aoa-objs := snd-aoa-core.o \ 2snd-aoa-objs := core.o \
3 snd-aoa-alsa.o \ 3 alsa.o \
4 snd-aoa-gpio-pmf.o \ 4 gpio-pmf.o \
5 snd-aoa-gpio-feature.o 5 gpio-feature.o
diff --git a/sound/aoa/core/snd-aoa-alsa.c b/sound/aoa/core/alsa.c
index 17fe689ed287..617850463582 100644
--- a/sound/aoa/core/snd-aoa-alsa.c
+++ b/sound/aoa/core/alsa.c
@@ -6,7 +6,7 @@
6 * GPL v2, can be found in COPYING. 6 * GPL v2, can be found in COPYING.
7 */ 7 */
8#include <linux/module.h> 8#include <linux/module.h>
9#include "snd-aoa-alsa.h" 9#include "alsa.h"
10 10
11static int index = -1; 11static int index = -1;
12module_param(index, int, 0444); 12module_param(index, int, 0444);
@@ -64,7 +64,7 @@ int aoa_snd_device_new(snd_device_type_t type,
64{ 64{
65 struct snd_card *card = aoa_get_card(); 65 struct snd_card *card = aoa_get_card();
66 int err; 66 int err;
67 67
68 if (!card) return -ENOMEM; 68 if (!card) return -ENOMEM;
69 69
70 err = snd_device_new(card, type, device_data, ops); 70 err = snd_device_new(card, type, device_data, ops);
diff --git a/sound/aoa/core/snd-aoa-alsa.h b/sound/aoa/core/alsa.h
index 9669e4489cab..9669e4489cab 100644
--- a/sound/aoa/core/snd-aoa-alsa.h
+++ b/sound/aoa/core/alsa.h
diff --git a/sound/aoa/core/snd-aoa-core.c b/sound/aoa/core/core.c
index 19fdae400687..10bec6c61382 100644
--- a/sound/aoa/core/snd-aoa-core.c
+++ b/sound/aoa/core/core.c
@@ -10,7 +10,7 @@
10#include <linux/module.h> 10#include <linux/module.h>
11#include <linux/list.h> 11#include <linux/list.h>
12#include "../aoa.h" 12#include "../aoa.h"
13#include "snd-aoa-alsa.h" 13#include "alsa.h"
14 14
15MODULE_DESCRIPTION("Apple Onboard Audio Sound Driver"); 15MODULE_DESCRIPTION("Apple Onboard Audio Sound Driver");
16MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>"); 16MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
diff --git a/sound/aoa/core/snd-aoa-gpio-feature.c b/sound/aoa/core/gpio-feature.c
index 805dcbff2257..c93ad5dec66b 100644
--- a/sound/aoa/core/snd-aoa-gpio-feature.c
+++ b/sound/aoa/core/gpio-feature.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL v2, can be found in COPYING. 6 * GPL v2, can be found in COPYING.
7 * 7 *
8 * This file contains the GPIO control routines for 8 * This file contains the GPIO control routines for
9 * direct (through feature calls) access to the GPIO 9 * direct (through feature calls) access to the GPIO
10 * registers. 10 * registers.
11 */ 11 */
diff --git a/sound/aoa/core/snd-aoa-gpio-pmf.c b/sound/aoa/core/gpio-pmf.c
index 5ca2220eac7d..5ca2220eac7d 100644
--- a/sound/aoa/core/snd-aoa-gpio-pmf.c
+++ b/sound/aoa/core/gpio-pmf.c
diff --git a/sound/aoa/fabrics/Makefile b/sound/aoa/fabrics/Makefile
index 55fc5e7e52cf..da37c10eca51 100644
--- a/sound/aoa/fabrics/Makefile
+++ b/sound/aoa/fabrics/Makefile
@@ -1 +1,3 @@
1snd-aoa-fabric-layout-objs += layout.o
2
1obj-$(CONFIG_SND_AOA_FABRIC_LAYOUT) += snd-aoa-fabric-layout.o 3obj-$(CONFIG_SND_AOA_FABRIC_LAYOUT) += snd-aoa-fabric-layout.o
diff --git a/sound/aoa/fabrics/snd-aoa-fabric-layout.c b/sound/aoa/fabrics/layout.c
index dea7abb082cd..ad60f5d10e82 100644
--- a/sound/aoa/fabrics/snd-aoa-fabric-layout.c
+++ b/sound/aoa/fabrics/layout.c
@@ -66,7 +66,7 @@ struct layout {
66 unsigned int layout_id; 66 unsigned int layout_id;
67 struct codec_connect_info codecs[MAX_CODECS_PER_BUS]; 67 struct codec_connect_info codecs[MAX_CODECS_PER_BUS];
68 int flags; 68 int flags;
69 69
70 /* if busname is not assigned, we use 'Master' below, 70 /* if busname is not assigned, we use 'Master' below,
71 * so that our layout table doesn't need to be filled 71 * so that our layout table doesn't need to be filled
72 * too much. 72 * too much.
diff --git a/sound/aoa/soundbus/i2sbus/Makefile b/sound/aoa/soundbus/i2sbus/Makefile
index e57a5cf65655..1b949b2a4028 100644
--- a/sound/aoa/soundbus/i2sbus/Makefile
+++ b/sound/aoa/soundbus/i2sbus/Makefile
@@ -1,2 +1,2 @@
1obj-$(CONFIG_SND_AOA_SOUNDBUS_I2S) += snd-aoa-i2sbus.o 1obj-$(CONFIG_SND_AOA_SOUNDBUS_I2S) += snd-aoa-i2sbus.o
2snd-aoa-i2sbus-objs := i2sbus-core.o i2sbus-pcm.o i2sbus-control.o 2snd-aoa-i2sbus-objs := core.o pcm.o control.o
diff --git a/sound/aoa/soundbus/i2sbus/i2sbus-control.c b/sound/aoa/soundbus/i2sbus/control.c
index 87beb4ad4d63..87beb4ad4d63 100644
--- a/sound/aoa/soundbus/i2sbus/i2sbus-control.c
+++ b/sound/aoa/soundbus/i2sbus/control.c
diff --git a/sound/aoa/soundbus/i2sbus/i2sbus-core.c b/sound/aoa/soundbus/i2sbus/core.c
index b4590df07466..be468edf3ecb 100644
--- a/sound/aoa/soundbus/i2sbus/i2sbus-core.c
+++ b/sound/aoa/soundbus/i2sbus/core.c
@@ -64,7 +64,7 @@ static void free_dbdma_descriptor_ring(struct i2sbus_dev *i2sdev,
64 struct dbdma_command_mem *r) 64 struct dbdma_command_mem *r)
65{ 65{
66 if (!r->space) return; 66 if (!r->space) return;
67 67
68 dma_free_coherent(&macio_get_pci_dev(i2sdev->macio)->dev, 68 dma_free_coherent(&macio_get_pci_dev(i2sdev->macio)->dev,
69 r->size, r->space, r->bus_addr); 69 r->size, r->space, r->bus_addr);
70} 70}
@@ -247,7 +247,7 @@ static int i2sbus_add_dev(struct macio_dev *macio,
247 * but request_resource doesn't know about parents and 247 * but request_resource doesn't know about parents and
248 * contained resources... 248 * contained resources...
249 */ 249 */
250 dev->allocated_resource[i] = 250 dev->allocated_resource[i] =
251 request_mem_region(dev->resources[i].start, 251 request_mem_region(dev->resources[i].start,
252 dev->resources[i].end - 252 dev->resources[i].end -
253 dev->resources[i].start + 1, 253 dev->resources[i].start + 1,
diff --git a/sound/aoa/soundbus/i2sbus/i2sbus.h b/sound/aoa/soundbus/i2sbus/i2sbus.h
index ff29654782c9..befefd99e271 100644
--- a/sound/aoa/soundbus/i2sbus/i2sbus.h
+++ b/sound/aoa/soundbus/i2sbus/i2sbus.h
@@ -18,7 +18,7 @@
18#include <asm/pmac_feature.h> 18#include <asm/pmac_feature.h>
19#include <asm/dbdma.h> 19#include <asm/dbdma.h>
20 20
21#include "i2sbus-interface.h" 21#include "interface.h"
22#include "../soundbus.h" 22#include "../soundbus.h"
23 23
24struct i2sbus_control { 24struct i2sbus_control {
diff --git a/sound/aoa/soundbus/i2sbus/i2sbus-interface.h b/sound/aoa/soundbus/i2sbus/interface.h
index c6b5f5452d20..c6b5f5452d20 100644
--- a/sound/aoa/soundbus/i2sbus/i2sbus-interface.h
+++ b/sound/aoa/soundbus/i2sbus/interface.h
diff --git a/sound/aoa/soundbus/i2sbus/i2sbus-pcm.c b/sound/aoa/soundbus/i2sbus/pcm.c
index 59bacd365733..59bacd365733 100644
--- a/sound/aoa/soundbus/i2sbus/i2sbus-pcm.c
+++ b/sound/aoa/soundbus/i2sbus/pcm.c
diff --git a/sound/core/Kconfig b/sound/core/Kconfig
index 66348c92f88d..7bbdda041a99 100644
--- a/sound/core/Kconfig
+++ b/sound/core/Kconfig
@@ -95,6 +95,26 @@ config SND_SEQUENCER_OSS
95 this will be compiled as a module. The module will be called 95 this will be compiled as a module. The module will be called
96 snd-seq-oss. 96 snd-seq-oss.
97 97
98config SND_HRTIMER
99 tristate "HR-timer backend support"
100 depends on HIGH_RES_TIMERS
101 select SND_TIMER
102 help
103 Say Y here to enable HR-timer backend for ALSA timer. ALSA uses
104 the hrtimer as a precise timing source. The ALSA sequencer code
105 also can use this timing source.
106
107 To compile this driver as a module, choose M here: the module
108 will be called snd-hrtimer.
109
110config SND_SEQ_HRTIMER_DEFAULT
111 bool "Use HR-timer as default sequencer timer"
112 depends on SND_HRTIMER && SND_SEQUENCER
113 default y
114 help
115 Say Y here to use the HR-timer backend as the default sequencer
116 timer.
117
98config SND_RTCTIMER 118config SND_RTCTIMER
99 tristate "RTC Timer support" 119 tristate "RTC Timer support"
100 depends on RTC 120 depends on RTC
@@ -114,6 +134,7 @@ config SND_RTCTIMER
114config SND_SEQ_RTCTIMER_DEFAULT 134config SND_SEQ_RTCTIMER_DEFAULT
115 bool "Use RTC as default sequencer timer" 135 bool "Use RTC as default sequencer timer"
116 depends on SND_RTCTIMER && SND_SEQUENCER 136 depends on SND_RTCTIMER && SND_SEQUENCER
137 depends on !SND_SEQ_HRTIMER_DEFAULT
117 default y 138 default y
118 help 139 help
119 Say Y here to use the RTC timer as the default sequencer 140 Say Y here to use the RTC timer as the default sequencer
diff --git a/sound/core/Makefile b/sound/core/Makefile
index d57125a5687d..4229052e7b91 100644
--- a/sound/core/Makefile
+++ b/sound/core/Makefile
@@ -17,12 +17,14 @@ snd-page-alloc-$(CONFIG_HAS_DMA) += sgbuf.o
17 17
18snd-rawmidi-objs := rawmidi.o 18snd-rawmidi-objs := rawmidi.o
19snd-timer-objs := timer.o 19snd-timer-objs := timer.o
20snd-hrtimer-objs := hrtimer.o
20snd-rtctimer-objs := rtctimer.o 21snd-rtctimer-objs := rtctimer.o
21snd-hwdep-objs := hwdep.o 22snd-hwdep-objs := hwdep.o
22 23
23obj-$(CONFIG_SND) += snd.o 24obj-$(CONFIG_SND) += snd.o
24obj-$(CONFIG_SND_HWDEP) += snd-hwdep.o 25obj-$(CONFIG_SND_HWDEP) += snd-hwdep.o
25obj-$(CONFIG_SND_TIMER) += snd-timer.o 26obj-$(CONFIG_SND_TIMER) += snd-timer.o
27obj-$(CONFIG_SND_HRTIMER) += snd-hrtimer.o
26obj-$(CONFIG_SND_RTCTIMER) += snd-rtctimer.o 28obj-$(CONFIG_SND_RTCTIMER) += snd-rtctimer.o
27obj-$(CONFIG_SND_PCM) += snd-pcm.o snd-page-alloc.o 29obj-$(CONFIG_SND_PCM) += snd-pcm.o snd-page-alloc.o
28obj-$(CONFIG_SND_RAWMIDI) += snd-rawmidi.o 30obj-$(CONFIG_SND_RAWMIDI) += snd-rawmidi.o
diff --git a/sound/core/device.c b/sound/core/device.c
index c58d8227254c..a67dfac08c03 100644
--- a/sound/core/device.c
+++ b/sound/core/device.c
@@ -98,7 +98,7 @@ int snd_device_free(struct snd_card *card, void *device_data)
98 kfree(dev); 98 kfree(dev);
99 return 0; 99 return 0;
100 } 100 }
101 snd_printd("device free %p (from %p), not found\n", device_data, 101 snd_printd("device free %p (from %pF), not found\n", device_data,
102 __builtin_return_address(0)); 102 __builtin_return_address(0));
103 return -ENXIO; 103 return -ENXIO;
104} 104}
@@ -135,7 +135,7 @@ int snd_device_disconnect(struct snd_card *card, void *device_data)
135 } 135 }
136 return 0; 136 return 0;
137 } 137 }
138 snd_printd("device disconnect %p (from %p), not found\n", device_data, 138 snd_printd("device disconnect %p (from %pF), not found\n", device_data,
139 __builtin_return_address(0)); 139 __builtin_return_address(0));
140 return -ENXIO; 140 return -ENXIO;
141} 141}
diff --git a/sound/core/hrtimer.c b/sound/core/hrtimer.c
new file mode 100644
index 000000000000..c1d285921f80
--- /dev/null
+++ b/sound/core/hrtimer.c
@@ -0,0 +1,155 @@
1/*
2 * ALSA timer back-end using hrtimer
3 * Copyright (C) 2008 Takashi Iwai
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 */
20
21#include <linux/init.h>
22#include <linux/module.h>
23#include <linux/moduleparam.h>
24#include <linux/hrtimer.h>
25#include <sound/core.h>
26#include <sound/timer.h>
27
28MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
29MODULE_DESCRIPTION("ALSA hrtimer backend");
30MODULE_LICENSE("GPL");
31
32MODULE_ALIAS("snd-timer-" __stringify(SNDRV_TIMER_GLOBAL_HRTIMER));
33
34#define NANO_SEC 1000000000UL /* 10^9 in sec */
35static unsigned int resolution;
36
37struct snd_hrtimer {
38 struct snd_timer *timer;
39 struct hrtimer hrt;
40};
41
42static enum hrtimer_restart snd_hrtimer_callback(struct hrtimer *hrt)
43{
44 struct snd_hrtimer *stime = container_of(hrt, struct snd_hrtimer, hrt);
45 struct snd_timer *t = stime->timer;
46 hrtimer_forward_now(hrt, ns_to_ktime(t->sticks * resolution));
47 snd_timer_interrupt(stime->timer, t->sticks);
48 return HRTIMER_RESTART;
49}
50
51static int snd_hrtimer_open(struct snd_timer *t)
52{
53 struct snd_hrtimer *stime;
54
55 stime = kmalloc(sizeof(*stime), GFP_KERNEL);
56 if (!stime)
57 return -ENOMEM;
58 hrtimer_init(&stime->hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
59 stime->timer = t;
60 stime->hrt.cb_mode = HRTIMER_CB_IRQSAFE_UNLOCKED;
61 stime->hrt.function = snd_hrtimer_callback;
62 t->private_data = stime;
63 return 0;
64}
65
66static int snd_hrtimer_close(struct snd_timer *t)
67{
68 struct snd_hrtimer *stime = t->private_data;
69
70 if (stime) {
71 hrtimer_cancel(&stime->hrt);
72 kfree(stime);
73 t->private_data = NULL;
74 }
75 return 0;
76}
77
78static int snd_hrtimer_start(struct snd_timer *t)
79{
80 struct snd_hrtimer *stime = t->private_data;
81
82 hrtimer_start(&stime->hrt, ns_to_ktime(t->sticks * resolution),
83 HRTIMER_MODE_REL);
84 return 0;
85}
86
87static int snd_hrtimer_stop(struct snd_timer *t)
88{
89 struct snd_hrtimer *stime = t->private_data;
90
91 hrtimer_cancel(&stime->hrt);
92 return 0;
93}
94
95static struct snd_timer_hardware hrtimer_hw = {
96 .flags = SNDRV_TIMER_HW_AUTO,
97 .open = snd_hrtimer_open,
98 .close = snd_hrtimer_close,
99 .start = snd_hrtimer_start,
100 .stop = snd_hrtimer_stop,
101};
102
103/*
104 * entry functions
105 */
106
107static struct snd_timer *mytimer;
108
109static int __init snd_hrtimer_init(void)
110{
111 struct snd_timer *timer;
112 struct timespec tp;
113 int err;
114
115 hrtimer_get_res(CLOCK_MONOTONIC, &tp);
116 if (tp.tv_sec > 0 || !tp.tv_nsec) {
117 snd_printk(KERN_ERR
118 "snd-hrtimer: Invalid resolution %u.%09u",
119 (unsigned)tp.tv_sec, (unsigned)tp.tv_nsec);
120 return -EINVAL;
121 }
122 resolution = tp.tv_nsec;
123
124 /* Create a new timer and set up the fields */
125 err = snd_timer_global_new("hrtimer", SNDRV_TIMER_GLOBAL_HRTIMER,
126 &timer);
127 if (err < 0)
128 return err;
129
130 timer->module = THIS_MODULE;
131 strcpy(timer->name, "HR timer");
132 timer->hw = hrtimer_hw;
133 timer->hw.resolution = resolution;
134 timer->hw.ticks = NANO_SEC / resolution;
135
136 err = snd_timer_global_register(timer);
137 if (err < 0) {
138 snd_timer_global_free(timer);
139 return err;
140 }
141 mytimer = timer; /* remember this */
142
143 return 0;
144}
145
146static void __exit snd_hrtimer_exit(void)
147{
148 if (mytimer) {
149 snd_timer_global_free(mytimer);
150 mytimer = NULL;
151 }
152}
153
154module_init(snd_hrtimer_init);
155module_exit(snd_hrtimer_exit);
diff --git a/sound/core/info.c b/sound/core/info.c
index 527b207462b0..70fa87189f36 100644
--- a/sound/core/info.c
+++ b/sound/core/info.c
@@ -653,6 +653,23 @@ int snd_info_card_register(struct snd_card *card)
653} 653}
654 654
655/* 655/*
656 * called on card->id change
657 */
658void snd_info_card_id_change(struct snd_card *card)
659{
660 mutex_lock(&info_mutex);
661 if (card->proc_root_link) {
662 snd_remove_proc_entry(snd_proc_root, card->proc_root_link);
663 card->proc_root_link = NULL;
664 }
665 if (strcmp(card->id, card->proc_root->name))
666 card->proc_root_link = proc_symlink(card->id,
667 snd_proc_root,
668 card->proc_root->name);
669 mutex_unlock(&info_mutex);
670}
671
672/*
656 * de-register the card proc file 673 * de-register the card proc file
657 * called from init.c 674 * called from init.c
658 */ 675 */
diff --git a/sound/core/init.c b/sound/core/init.c
index b47ff8b44be8..0d5520c415d3 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -533,6 +533,65 @@ static void choose_default_id(struct snd_card *card)
533 } 533 }
534} 534}
535 535
536#ifndef CONFIG_SYSFS_DEPRECATED
537static ssize_t
538card_id_show_attr(struct device *dev,
539 struct device_attribute *attr, char *buf)
540{
541 struct snd_card *card = dev_get_drvdata(dev);
542 return snprintf(buf, PAGE_SIZE, "%s\n", card ? card->id : "(null)");
543}
544
545static ssize_t
546card_id_store_attr(struct device *dev, struct device_attribute *attr,
547 const char *buf, size_t count)
548{
549 struct snd_card *card = dev_get_drvdata(dev);
550 char buf1[sizeof(card->id)];
551 size_t copy = count > sizeof(card->id) - 1 ?
552 sizeof(card->id) - 1 : count;
553 size_t idx;
554 int c;
555
556 for (idx = 0; idx < copy; idx++) {
557 c = buf[idx];
558 if (!isalnum(c) && c != '_' && c != '-')
559 return -EINVAL;
560 }
561 memcpy(buf1, buf, copy);
562 buf1[copy] = '\0';
563 mutex_lock(&snd_card_mutex);
564 if (!snd_info_check_reserved_words(buf1)) {
565 __exist:
566 mutex_unlock(&snd_card_mutex);
567 return -EEXIST;
568 }
569 for (idx = 0; idx < snd_ecards_limit; idx++) {
570 if (snd_cards[idx] && !strcmp(snd_cards[idx]->id, buf1))
571 goto __exist;
572 }
573 strcpy(card->id, buf1);
574 snd_info_card_id_change(card);
575 mutex_unlock(&snd_card_mutex);
576
577 return count;
578}
579
580static struct device_attribute card_id_attrs =
581 __ATTR(id, S_IRUGO | S_IWUSR, card_id_show_attr, card_id_store_attr);
582
583static ssize_t
584card_number_show_attr(struct device *dev,
585 struct device_attribute *attr, char *buf)
586{
587 struct snd_card *card = dev_get_drvdata(dev);
588 return snprintf(buf, PAGE_SIZE, "%i\n", card ? card->number : -1);
589}
590
591static struct device_attribute card_number_attrs =
592 __ATTR(number, S_IRUGO, card_number_show_attr, NULL);
593#endif /* CONFIG_SYSFS_DEPRECATED */
594
536/** 595/**
537 * snd_card_register - register the soundcard 596 * snd_card_register - register the soundcard
538 * @card: soundcard structure 597 * @card: soundcard structure
@@ -553,7 +612,7 @@ int snd_card_register(struct snd_card *card)
553#ifndef CONFIG_SYSFS_DEPRECATED 612#ifndef CONFIG_SYSFS_DEPRECATED
554 if (!card->card_dev) { 613 if (!card->card_dev) {
555 card->card_dev = device_create(sound_class, card->dev, 614 card->card_dev = device_create(sound_class, card->dev,
556 MKDEV(0, 0), NULL, 615 MKDEV(0, 0), card,
557 "card%i", card->number); 616 "card%i", card->number);
558 if (IS_ERR(card->card_dev)) 617 if (IS_ERR(card->card_dev))
559 card->card_dev = NULL; 618 card->card_dev = NULL;
@@ -576,6 +635,16 @@ int snd_card_register(struct snd_card *card)
576 if (snd_mixer_oss_notify_callback) 635 if (snd_mixer_oss_notify_callback)
577 snd_mixer_oss_notify_callback(card, SND_MIXER_OSS_NOTIFY_REGISTER); 636 snd_mixer_oss_notify_callback(card, SND_MIXER_OSS_NOTIFY_REGISTER);
578#endif 637#endif
638#ifndef CONFIG_SYSFS_DEPRECATED
639 if (card->card_dev) {
640 err = device_create_file(card->card_dev, &card_id_attrs);
641 if (err < 0)
642 return err;
643 err = device_create_file(card->card_dev, &card_number_attrs);
644 if (err < 0)
645 return err;
646 }
647#endif
579 return 0; 648 return 0;
580} 649}
581 650
diff --git a/sound/core/jack.c b/sound/core/jack.c
index bd2d9e6b55e9..dd4a12dc09aa 100644
--- a/sound/core/jack.c
+++ b/sound/core/jack.c
@@ -34,6 +34,7 @@ static int snd_jack_dev_free(struct snd_device *device)
34 else 34 else
35 input_free_device(jack->input_dev); 35 input_free_device(jack->input_dev);
36 36
37 kfree(jack->id);
37 kfree(jack); 38 kfree(jack);
38 39
39 return 0; 40 return 0;
@@ -87,7 +88,7 @@ int snd_jack_new(struct snd_card *card, const char *id, int type,
87 if (jack == NULL) 88 if (jack == NULL)
88 return -ENOMEM; 89 return -ENOMEM;
89 90
90 jack->id = id; 91 jack->id = kstrdup(id, GFP_KERNEL);
91 92
92 jack->input_dev = input_allocate_device(); 93 jack->input_dev = input_allocate_device();
93 if (jack->input_dev == NULL) { 94 if (jack->input_dev == NULL) {
@@ -102,9 +103,15 @@ int snd_jack_new(struct snd_card *card, const char *id, int type,
102 if (type & SND_JACK_HEADPHONE) 103 if (type & SND_JACK_HEADPHONE)
103 input_set_capability(jack->input_dev, EV_SW, 104 input_set_capability(jack->input_dev, EV_SW,
104 SW_HEADPHONE_INSERT); 105 SW_HEADPHONE_INSERT);
106 if (type & SND_JACK_LINEOUT)
107 input_set_capability(jack->input_dev, EV_SW,
108 SW_LINEOUT_INSERT);
105 if (type & SND_JACK_MICROPHONE) 109 if (type & SND_JACK_MICROPHONE)
106 input_set_capability(jack->input_dev, EV_SW, 110 input_set_capability(jack->input_dev, EV_SW,
107 SW_MICROPHONE_INSERT); 111 SW_MICROPHONE_INSERT);
112 if (type & SND_JACK_MECHANICAL)
113 input_set_capability(jack->input_dev, EV_SW,
114 SW_JACK_PHYSICAL_INSERT);
108 115
109 err = snd_device_new(card, SNDRV_DEV_JACK, jack, &ops); 116 err = snd_device_new(card, SNDRV_DEV_JACK, jack, &ops);
110 if (err < 0) 117 if (err < 0)
@@ -153,9 +160,15 @@ void snd_jack_report(struct snd_jack *jack, int status)
153 if (jack->type & SND_JACK_HEADPHONE) 160 if (jack->type & SND_JACK_HEADPHONE)
154 input_report_switch(jack->input_dev, SW_HEADPHONE_INSERT, 161 input_report_switch(jack->input_dev, SW_HEADPHONE_INSERT,
155 status & SND_JACK_HEADPHONE); 162 status & SND_JACK_HEADPHONE);
163 if (jack->type & SND_JACK_LINEOUT)
164 input_report_switch(jack->input_dev, SW_LINEOUT_INSERT,
165 status & SND_JACK_LINEOUT);
156 if (jack->type & SND_JACK_MICROPHONE) 166 if (jack->type & SND_JACK_MICROPHONE)
157 input_report_switch(jack->input_dev, SW_MICROPHONE_INSERT, 167 input_report_switch(jack->input_dev, SW_MICROPHONE_INSERT,
158 status & SND_JACK_MICROPHONE); 168 status & SND_JACK_MICROPHONE);
169 if (jack->type & SND_JACK_MECHANICAL)
170 input_report_switch(jack->input_dev, SW_JACK_PHYSICAL_INSERT,
171 status & SND_JACK_MECHANICAL);
159 172
160 input_sync(jack->input_dev); 173 input_sync(jack->input_dev);
161} 174}
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index 39672f68ce5d..002777ba336a 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -151,7 +151,7 @@ static inline void snd_rawmidi_output_trigger(struct snd_rawmidi_substream *subs
151 if (!substream->opened) 151 if (!substream->opened)
152 return; 152 return;
153 if (up) { 153 if (up) {
154 tasklet_hi_schedule(&substream->runtime->tasklet); 154 tasklet_schedule(&substream->runtime->tasklet);
155 } else { 155 } else {
156 tasklet_kill(&substream->runtime->tasklet); 156 tasklet_kill(&substream->runtime->tasklet);
157 substream->ops->trigger(substream, 0); 157 substream->ops->trigger(substream, 0);
@@ -908,7 +908,7 @@ int snd_rawmidi_receive(struct snd_rawmidi_substream *substream,
908 } 908 }
909 if (result > 0) { 909 if (result > 0) {
910 if (runtime->event) 910 if (runtime->event)
911 tasklet_hi_schedule(&runtime->tasklet); 911 tasklet_schedule(&runtime->tasklet);
912 else if (snd_rawmidi_ready(substream)) 912 else if (snd_rawmidi_ready(substream))
913 wake_up(&runtime->sleep); 913 wake_up(&runtime->sleep);
914 } 914 }
diff --git a/sound/core/rtctimer.c b/sound/core/rtctimer.c
index 51e64e30dd3b..0851cd13e303 100644
--- a/sound/core/rtctimer.c
+++ b/sound/core/rtctimer.c
@@ -118,7 +118,7 @@ static void rtctimer_tasklet(unsigned long data)
118 */ 118 */
119static void rtctimer_interrupt(void *private_data) 119static void rtctimer_interrupt(void *private_data)
120{ 120{
121 tasklet_hi_schedule(private_data); 121 tasklet_schedule(private_data);
122} 122}
123 123
124 124
diff --git a/sound/core/seq/seq.c b/sound/core/seq/seq.c
index ee0f8405ab35..bf09a5ad1865 100644
--- a/sound/core/seq/seq.c
+++ b/sound/core/seq/seq.c
@@ -43,7 +43,9 @@ int seq_default_timer_class = SNDRV_TIMER_CLASS_GLOBAL;
43int seq_default_timer_sclass = SNDRV_TIMER_SCLASS_NONE; 43int seq_default_timer_sclass = SNDRV_TIMER_SCLASS_NONE;
44int seq_default_timer_card = -1; 44int seq_default_timer_card = -1;
45int seq_default_timer_device = 45int seq_default_timer_device =
46#ifdef CONFIG_SND_SEQ_RTCTIMER_DEFAULT 46#ifdef CONFIG_SND_SEQ_HRTIMER_DEFAULT
47 SNDRV_TIMER_GLOBAL_HRTIMER
48#elif defined(CONFIG_SND_SEQ_RTCTIMER_DEFAULT)
47 SNDRV_TIMER_GLOBAL_RTC 49 SNDRV_TIMER_GLOBAL_RTC
48#else 50#else
49 SNDRV_TIMER_GLOBAL_SYSTEM 51 SNDRV_TIMER_GLOBAL_SYSTEM
diff --git a/sound/core/timer.c b/sound/core/timer.c
index c584408c9f17..796532081e81 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -743,7 +743,7 @@ void snd_timer_interrupt(struct snd_timer * timer, unsigned long ticks_left)
743 spin_unlock_irqrestore(&timer->lock, flags); 743 spin_unlock_irqrestore(&timer->lock, flags);
744 744
745 if (use_tasklet) 745 if (use_tasklet)
746 tasklet_hi_schedule(&timer->task_queue); 746 tasklet_schedule(&timer->task_queue);
747} 747}
748 748
749/* 749/*
diff --git a/sound/drivers/Kconfig b/sound/drivers/Kconfig
index 255fd18b9aec..0bcf14640fde 100644
--- a/sound/drivers/Kconfig
+++ b/sound/drivers/Kconfig
@@ -163,7 +163,7 @@ config SND_ML403_AC97CR
163 163
164config SND_AC97_POWER_SAVE 164config SND_AC97_POWER_SAVE
165 bool "AC97 Power-Saving Mode" 165 bool "AC97 Power-Saving Mode"
166 depends on SND_AC97_CODEC && EXPERIMENTAL 166 depends on SND_AC97_CODEC
167 default n 167 default n
168 help 168 help
169 Say Y here to enable the aggressive power-saving support of 169 Say Y here to enable the aggressive power-saving support of
diff --git a/sound/drivers/pcsp/pcsp.c b/sound/drivers/pcsp/pcsp.c
index 1899cf0685bc..2a02f704f366 100644
--- a/sound/drivers/pcsp/pcsp.c
+++ b/sound/drivers/pcsp/pcsp.c
@@ -96,7 +96,7 @@ static int __devinit snd_card_pcsp_probe(int devnum, struct device *dev)
96 return -EINVAL; 96 return -EINVAL;
97 97
98 hrtimer_init(&pcsp_chip.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); 98 hrtimer_init(&pcsp_chip.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
99 pcsp_chip.timer.cb_mode = HRTIMER_CB_SOFTIRQ; 99 pcsp_chip.timer.cb_mode = HRTIMER_CB_IRQSAFE_UNLOCKED;
100 pcsp_chip.timer.function = pcsp_do_timer; 100 pcsp_chip.timer.function = pcsp_do_timer;
101 101
102 card = snd_card_new(index, id, THIS_MODULE, 0); 102 card = snd_card_new(index, id, THIS_MODULE, 0);
@@ -188,10 +188,8 @@ static int __devexit pcsp_remove(struct platform_device *dev)
188 188
189static void pcsp_stop_beep(struct snd_pcsp *chip) 189static void pcsp_stop_beep(struct snd_pcsp *chip)
190{ 190{
191 spin_lock_irq(&chip->substream_lock); 191 pcsp_sync_stop(chip);
192 if (!chip->playback_substream) 192 pcspkr_stop_sound();
193 pcspkr_stop_sound();
194 spin_unlock_irq(&chip->substream_lock);
195} 193}
196 194
197#ifdef CONFIG_PM 195#ifdef CONFIG_PM
diff --git a/sound/drivers/pcsp/pcsp.h b/sound/drivers/pcsp/pcsp.h
index 1d661f795e8c..cdef2664218f 100644
--- a/sound/drivers/pcsp/pcsp.h
+++ b/sound/drivers/pcsp/pcsp.h
@@ -62,6 +62,8 @@ struct snd_pcsp {
62 unsigned short port, irq, dma; 62 unsigned short port, irq, dma;
63 spinlock_t substream_lock; 63 spinlock_t substream_lock;
64 struct snd_pcm_substream *playback_substream; 64 struct snd_pcm_substream *playback_substream;
65 unsigned int fmt_size;
66 unsigned int is_signed;
65 size_t playback_ptr; 67 size_t playback_ptr;
66 size_t period_ptr; 68 size_t period_ptr;
67 atomic_t timer_active; 69 atomic_t timer_active;
@@ -77,6 +79,7 @@ struct snd_pcsp {
77extern struct snd_pcsp pcsp_chip; 79extern struct snd_pcsp pcsp_chip;
78 80
79extern enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle); 81extern enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle);
82extern void pcsp_sync_stop(struct snd_pcsp *chip);
80 83
81extern int snd_pcsp_new_pcm(struct snd_pcsp *chip); 84extern int snd_pcsp_new_pcm(struct snd_pcsp *chip);
82extern int snd_pcsp_new_mixer(struct snd_pcsp *chip); 85extern int snd_pcsp_new_mixer(struct snd_pcsp *chip);
diff --git a/sound/drivers/pcsp/pcsp_lib.c b/sound/drivers/pcsp/pcsp_lib.c
index 1f42e4063118..84cc2658c05b 100644
--- a/sound/drivers/pcsp/pcsp_lib.c
+++ b/sound/drivers/pcsp/pcsp_lib.c
@@ -8,6 +8,7 @@
8 8
9#include <linux/module.h> 9#include <linux/module.h>
10#include <linux/moduleparam.h> 10#include <linux/moduleparam.h>
11#include <linux/interrupt.h>
11#include <sound/pcm.h> 12#include <sound/pcm.h>
12#include <asm/io.h> 13#include <asm/io.h>
13#include "pcsp.h" 14#include "pcsp.h"
@@ -19,61 +20,57 @@ MODULE_PARM_DESC(nforce_wa, "Apply NForce chipset workaround "
19 20
20#define DMIX_WANTS_S16 1 21#define DMIX_WANTS_S16 1
21 22
22enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle) 23/*
24 * Call snd_pcm_period_elapsed in a tasklet
25 * This avoids spinlock messes and long-running irq contexts
26 */
27static void pcsp_call_pcm_elapsed(unsigned long priv)
28{
29 if (atomic_read(&pcsp_chip.timer_active)) {
30 struct snd_pcm_substream *substream;
31 substream = pcsp_chip.playback_substream;
32 if (substream)
33 snd_pcm_period_elapsed(substream);
34 }
35}
36
37static DECLARE_TASKLET(pcsp_pcm_tasklet, pcsp_call_pcm_elapsed, 0);
38
39/* write the port and returns the next expire time in ns;
40 * called at the trigger-start and in hrtimer callback
41 */
42static unsigned long pcsp_timer_update(struct hrtimer *handle)
23{ 43{
24 unsigned char timer_cnt, val; 44 unsigned char timer_cnt, val;
25 int fmt_size, periods_elapsed;
26 u64 ns; 45 u64 ns;
27 size_t period_bytes, buffer_bytes;
28 struct snd_pcm_substream *substream; 46 struct snd_pcm_substream *substream;
29 struct snd_pcm_runtime *runtime; 47 struct snd_pcm_runtime *runtime;
30 struct snd_pcsp *chip = container_of(handle, struct snd_pcsp, timer); 48 struct snd_pcsp *chip = container_of(handle, struct snd_pcsp, timer);
49 unsigned long flags;
31 50
32 if (chip->thalf) { 51 if (chip->thalf) {
33 outb(chip->val61, 0x61); 52 outb(chip->val61, 0x61);
34 chip->thalf = 0; 53 chip->thalf = 0;
35 if (!atomic_read(&chip->timer_active)) 54 if (!atomic_read(&chip->timer_active))
36 return HRTIMER_NORESTART; 55 return 0;
37 hrtimer_forward(&chip->timer, hrtimer_get_expires(&chip->timer), 56 return chip->ns_rem;
38 ktime_set(0, chip->ns_rem));
39 return HRTIMER_RESTART;
40 } 57 }
41 58
42 spin_lock_irq(&chip->substream_lock);
43 /* Takashi Iwai says regarding this extra lock:
44
45 If the irq handler handles some data on the DMA buffer, it should
46 do snd_pcm_stream_lock().
47 That protects basically against all races among PCM callbacks, yes.
48 However, there are two remaining issues:
49 1. The substream pointer you try to lock isn't protected _before_
50 this lock yet.
51 2. snd_pcm_period_elapsed() itself acquires the lock.
52 The requirement of another lock is because of 1. When you get
53 chip->playback_substream, it's not protected.
54 Keeping this lock while snd_pcm_period_elapsed() assures the substream
55 is still protected (at least, not released). And the other status is
56 handled properly inside snd_pcm_stream_lock() in
57 snd_pcm_period_elapsed().
58
59 */
60 if (!chip->playback_substream)
61 goto exit_nr_unlock1;
62 substream = chip->playback_substream;
63 snd_pcm_stream_lock(substream);
64 if (!atomic_read(&chip->timer_active)) 59 if (!atomic_read(&chip->timer_active))
65 goto exit_nr_unlock2; 60 return 0;
61 substream = chip->playback_substream;
62 if (!substream)
63 return 0;
66 64
67 runtime = substream->runtime; 65 runtime = substream->runtime;
68 fmt_size = snd_pcm_format_physical_width(runtime->format) >> 3;
69 /* assume it is mono! */ 66 /* assume it is mono! */
70 val = runtime->dma_area[chip->playback_ptr + fmt_size - 1]; 67 val = runtime->dma_area[chip->playback_ptr + chip->fmt_size - 1];
71 if (snd_pcm_format_signed(runtime->format)) 68 if (chip->is_signed)
72 val ^= 0x80; 69 val ^= 0x80;
73 timer_cnt = val * CUR_DIV() / 256; 70 timer_cnt = val * CUR_DIV() / 256;
74 71
75 if (timer_cnt && chip->enable) { 72 if (timer_cnt && chip->enable) {
76 spin_lock(&i8253_lock); 73 spin_lock_irqsave(&i8253_lock, flags);
77 if (!nforce_wa) { 74 if (!nforce_wa) {
78 outb_p(chip->val61, 0x61); 75 outb_p(chip->val61, 0x61);
79 outb_p(timer_cnt, 0x42); 76 outb_p(timer_cnt, 0x42);
@@ -82,12 +79,39 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle)
82 outb(chip->val61 ^ 2, 0x61); 79 outb(chip->val61 ^ 2, 0x61);
83 chip->thalf = 1; 80 chip->thalf = 1;
84 } 81 }
85 spin_unlock(&i8253_lock); 82 spin_unlock_irqrestore(&i8253_lock, flags);
86 } 83 }
87 84
85 chip->ns_rem = PCSP_PERIOD_NS();
86 ns = (chip->thalf ? PCSP_CALC_NS(timer_cnt) : chip->ns_rem);
87 chip->ns_rem -= ns;
88 return ns;
89}
90
91enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle)
92{
93 struct snd_pcsp *chip = container_of(handle, struct snd_pcsp, timer);
94 struct snd_pcm_substream *substream;
95 int periods_elapsed, pointer_update;
96 size_t period_bytes, buffer_bytes;
97 unsigned long ns;
98 unsigned long flags;
99
100 pointer_update = !chip->thalf;
101 ns = pcsp_timer_update(handle);
102 if (!ns)
103 return HRTIMER_NORESTART;
104
105 /* update the playback position */
106 substream = chip->playback_substream;
107 if (!substream)
108 return HRTIMER_NORESTART;
109
88 period_bytes = snd_pcm_lib_period_bytes(substream); 110 period_bytes = snd_pcm_lib_period_bytes(substream);
89 buffer_bytes = snd_pcm_lib_buffer_bytes(substream); 111 buffer_bytes = snd_pcm_lib_buffer_bytes(substream);
90 chip->playback_ptr += PCSP_INDEX_INC() * fmt_size; 112
113 spin_lock_irqsave(&chip->substream_lock, flags);
114 chip->playback_ptr += PCSP_INDEX_INC() * chip->fmt_size;
91 periods_elapsed = chip->playback_ptr - chip->period_ptr; 115 periods_elapsed = chip->playback_ptr - chip->period_ptr;
92 if (periods_elapsed < 0) { 116 if (periods_elapsed < 0) {
93#if PCSP_DEBUG 117#if PCSP_DEBUG
@@ -102,41 +126,30 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle)
102 * or ALSA will BUG on us. */ 126 * or ALSA will BUG on us. */
103 chip->playback_ptr %= buffer_bytes; 127 chip->playback_ptr %= buffer_bytes;
104 128
105 snd_pcm_stream_unlock(substream);
106
107 if (periods_elapsed) { 129 if (periods_elapsed) {
108 snd_pcm_period_elapsed(substream);
109 chip->period_ptr += periods_elapsed * period_bytes; 130 chip->period_ptr += periods_elapsed * period_bytes;
110 chip->period_ptr %= buffer_bytes; 131 chip->period_ptr %= buffer_bytes;
111 } 132 }
133 spin_unlock_irqrestore(&chip->substream_lock, flags);
112 134
113 spin_unlock_irq(&chip->substream_lock); 135 if (periods_elapsed)
136 tasklet_schedule(&pcsp_pcm_tasklet);
114 137
115 if (!atomic_read(&chip->timer_active)) 138 hrtimer_forward(handle, hrtimer_get_expires(handle), ns_to_ktime(ns));
116 return HRTIMER_NORESTART;
117 139
118 chip->ns_rem = PCSP_PERIOD_NS();
119 ns = (chip->thalf ? PCSP_CALC_NS(timer_cnt) : chip->ns_rem);
120 chip->ns_rem -= ns;
121 hrtimer_forward(&chip->timer, hrtimer_get_expires(&chip->timer),
122 ktime_set(0, ns));
123 return HRTIMER_RESTART; 140 return HRTIMER_RESTART;
124
125exit_nr_unlock2:
126 snd_pcm_stream_unlock(substream);
127exit_nr_unlock1:
128 spin_unlock_irq(&chip->substream_lock);
129 return HRTIMER_NORESTART;
130} 141}
131 142
132static void pcsp_start_playing(struct snd_pcsp *chip) 143static int pcsp_start_playing(struct snd_pcsp *chip)
133{ 144{
145 unsigned long ns;
146
134#if PCSP_DEBUG 147#if PCSP_DEBUG
135 printk(KERN_INFO "PCSP: start_playing called\n"); 148 printk(KERN_INFO "PCSP: start_playing called\n");
136#endif 149#endif
137 if (atomic_read(&chip->timer_active)) { 150 if (atomic_read(&chip->timer_active)) {
138 printk(KERN_ERR "PCSP: Timer already active\n"); 151 printk(KERN_ERR "PCSP: Timer already active\n");
139 return; 152 return -EIO;
140 } 153 }
141 154
142 spin_lock(&i8253_lock); 155 spin_lock(&i8253_lock);
@@ -146,7 +159,12 @@ static void pcsp_start_playing(struct snd_pcsp *chip)
146 atomic_set(&chip->timer_active, 1); 159 atomic_set(&chip->timer_active, 1);
147 chip->thalf = 0; 160 chip->thalf = 0;
148 161
149 hrtimer_start(&pcsp_chip.timer, ktime_set(0, 0), HRTIMER_MODE_REL); 162 ns = pcsp_timer_update(&pcsp_chip.timer);
163 if (!ns)
164 return -EIO;
165
166 hrtimer_start(&pcsp_chip.timer, ktime_set(0, ns), HRTIMER_MODE_REL);
167 return 0;
150} 168}
151 169
152static void pcsp_stop_playing(struct snd_pcsp *chip) 170static void pcsp_stop_playing(struct snd_pcsp *chip)
@@ -165,26 +183,35 @@ static void pcsp_stop_playing(struct snd_pcsp *chip)
165 spin_unlock(&i8253_lock); 183 spin_unlock(&i8253_lock);
166} 184}
167 185
186/*
187 * Force to stop and sync the stream
188 */
189void pcsp_sync_stop(struct snd_pcsp *chip)
190{
191 local_irq_disable();
192 pcsp_stop_playing(chip);
193 local_irq_enable();
194 hrtimer_cancel(&chip->timer);
195 tasklet_kill(&pcsp_pcm_tasklet);
196}
197
168static int snd_pcsp_playback_close(struct snd_pcm_substream *substream) 198static int snd_pcsp_playback_close(struct snd_pcm_substream *substream)
169{ 199{
170 struct snd_pcsp *chip = snd_pcm_substream_chip(substream); 200 struct snd_pcsp *chip = snd_pcm_substream_chip(substream);
171#if PCSP_DEBUG 201#if PCSP_DEBUG
172 printk(KERN_INFO "PCSP: close called\n"); 202 printk(KERN_INFO "PCSP: close called\n");
173#endif 203#endif
174 if (atomic_read(&chip->timer_active)) { 204 pcsp_sync_stop(chip);
175 printk(KERN_ERR "PCSP: timer still active\n");
176 pcsp_stop_playing(chip);
177 }
178 spin_lock_irq(&chip->substream_lock);
179 chip->playback_substream = NULL; 205 chip->playback_substream = NULL;
180 spin_unlock_irq(&chip->substream_lock);
181 return 0; 206 return 0;
182} 207}
183 208
184static int snd_pcsp_playback_hw_params(struct snd_pcm_substream *substream, 209static int snd_pcsp_playback_hw_params(struct snd_pcm_substream *substream,
185 struct snd_pcm_hw_params *hw_params) 210 struct snd_pcm_hw_params *hw_params)
186{ 211{
212 struct snd_pcsp *chip = snd_pcm_substream_chip(substream);
187 int err; 213 int err;
214 pcsp_sync_stop(chip);
188 err = snd_pcm_lib_malloc_pages(substream, 215 err = snd_pcm_lib_malloc_pages(substream,
189 params_buffer_bytes(hw_params)); 216 params_buffer_bytes(hw_params));
190 if (err < 0) 217 if (err < 0)
@@ -194,9 +221,11 @@ static int snd_pcsp_playback_hw_params(struct snd_pcm_substream *substream,
194 221
195static int snd_pcsp_playback_hw_free(struct snd_pcm_substream *substream) 222static int snd_pcsp_playback_hw_free(struct snd_pcm_substream *substream)
196{ 223{
224 struct snd_pcsp *chip = snd_pcm_substream_chip(substream);
197#if PCSP_DEBUG 225#if PCSP_DEBUG
198 printk(KERN_INFO "PCSP: hw_free called\n"); 226 printk(KERN_INFO "PCSP: hw_free called\n");
199#endif 227#endif
228 pcsp_sync_stop(chip);
200 return snd_pcm_lib_free_pages(substream); 229 return snd_pcm_lib_free_pages(substream);
201} 230}
202 231
@@ -212,8 +241,12 @@ static int snd_pcsp_playback_prepare(struct snd_pcm_substream *substream)
212 snd_pcm_lib_period_bytes(substream), 241 snd_pcm_lib_period_bytes(substream),
213 substream->runtime->periods); 242 substream->runtime->periods);
214#endif 243#endif
244 pcsp_sync_stop(chip);
215 chip->playback_ptr = 0; 245 chip->playback_ptr = 0;
216 chip->period_ptr = 0; 246 chip->period_ptr = 0;
247 chip->fmt_size =
248 snd_pcm_format_physical_width(substream->runtime->format) >> 3;
249 chip->is_signed = snd_pcm_format_signed(substream->runtime->format);
217 return 0; 250 return 0;
218} 251}
219 252
@@ -226,8 +259,7 @@ static int snd_pcsp_trigger(struct snd_pcm_substream *substream, int cmd)
226 switch (cmd) { 259 switch (cmd) {
227 case SNDRV_PCM_TRIGGER_START: 260 case SNDRV_PCM_TRIGGER_START:
228 case SNDRV_PCM_TRIGGER_RESUME: 261 case SNDRV_PCM_TRIGGER_RESUME:
229 pcsp_start_playing(chip); 262 return pcsp_start_playing(chip);
230 break;
231 case SNDRV_PCM_TRIGGER_STOP: 263 case SNDRV_PCM_TRIGGER_STOP:
232 case SNDRV_PCM_TRIGGER_SUSPEND: 264 case SNDRV_PCM_TRIGGER_SUSPEND:
233 pcsp_stop_playing(chip); 265 pcsp_stop_playing(chip);
@@ -242,7 +274,11 @@ static snd_pcm_uframes_t snd_pcsp_playback_pointer(struct snd_pcm_substream
242 *substream) 274 *substream)
243{ 275{
244 struct snd_pcsp *chip = snd_pcm_substream_chip(substream); 276 struct snd_pcsp *chip = snd_pcm_substream_chip(substream);
245 return bytes_to_frames(substream->runtime, chip->playback_ptr); 277 unsigned int pos;
278 spin_lock(&chip->substream_lock);
279 pos = chip->playback_ptr;
280 spin_unlock(&chip->substream_lock);
281 return bytes_to_frames(substream->runtime, pos);
246} 282}
247 283
248static struct snd_pcm_hardware snd_pcsp_playback = { 284static struct snd_pcm_hardware snd_pcsp_playback = {
@@ -279,9 +315,7 @@ static int snd_pcsp_playback_open(struct snd_pcm_substream *substream)
279 return -EBUSY; 315 return -EBUSY;
280 } 316 }
281 runtime->hw = snd_pcsp_playback; 317 runtime->hw = snd_pcsp_playback;
282 spin_lock_irq(&chip->substream_lock);
283 chip->playback_substream = substream; 318 chip->playback_substream = substream;
284 spin_unlock_irq(&chip->substream_lock);
285 return 0; 319 return 0;
286} 320}
287 321
diff --git a/sound/drivers/vx/vx_core.c b/sound/drivers/vx/vx_core.c
index 473b07f6ae85..14e3354be43a 100644
--- a/sound/drivers/vx/vx_core.c
+++ b/sound/drivers/vx/vx_core.c
@@ -548,7 +548,7 @@ irqreturn_t snd_vx_irq_handler(int irq, void *dev)
548 (chip->chip_status & VX_STAT_IS_STALE)) 548 (chip->chip_status & VX_STAT_IS_STALE))
549 return IRQ_NONE; 549 return IRQ_NONE;
550 if (! vx_test_and_ack(chip)) 550 if (! vx_test_and_ack(chip))
551 tasklet_hi_schedule(&chip->tq); 551 tasklet_schedule(&chip->tq);
552 return IRQ_HANDLED; 552 return IRQ_HANDLED;
553} 553}
554 554
diff --git a/sound/drivers/vx/vx_pcm.c b/sound/drivers/vx/vx_pcm.c
index 27de574c08f7..6644d0034fba 100644
--- a/sound/drivers/vx/vx_pcm.c
+++ b/sound/drivers/vx/vx_pcm.c
@@ -823,7 +823,7 @@ static int vx_pcm_trigger(struct snd_pcm_substream *subs, int cmd)
823 * we trigger the pipe using tasklet, so that the interrupts are 823 * we trigger the pipe using tasklet, so that the interrupts are
824 * issued surely after the trigger is completed. 824 * issued surely after the trigger is completed.
825 */ 825 */
826 tasklet_hi_schedule(&pipe->start_tq); 826 tasklet_schedule(&pipe->start_tq);
827 chip->pcm_running++; 827 chip->pcm_running++;
828 pipe->running = 1; 828 pipe->running = 1;
829 break; 829 break;
diff --git a/sound/isa/sb/sb8.c b/sound/isa/sb/sb8.c
index 667eccc676a4..ea06877be4b1 100644
--- a/sound/isa/sb/sb8.c
+++ b/sound/isa/sb/sb8.c
@@ -140,8 +140,10 @@ static int __devinit snd_sb8_probe(struct device *pdev, unsigned int dev)
140 break; 140 break;
141 } 141 }
142 } 142 }
143 if (i >= ARRAY_SIZE(possible_ports)) 143 if (i >= ARRAY_SIZE(possible_ports)) {
144 err = -EINVAL;
144 goto _err; 145 goto _err;
146 }
145 } 147 }
146 acard->chip = chip; 148 acard->chip = chip;
147 149
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index 7003711f4fcc..6e3a1848447c 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -208,7 +208,8 @@ config SND_OXYGEN
208 * AuzenTech X-Meridian 208 * AuzenTech X-Meridian
209 * Bgears b-Enspirer 209 * Bgears b-Enspirer
210 * Club3D Theatron DTS 210 * Club3D Theatron DTS
211 * HT-Omega Claro 211 * HT-Omega Claro (plus)
212 * HT-Omega Claro halo (XT)
212 * Razer Barracuda AC-1 213 * Razer Barracuda AC-1
213 * Sondigo Inferno 214 * Sondigo Inferno
214 215
@@ -497,129 +498,7 @@ config SND_FM801_TEA575X
497 depends on SND_FM801_TEA575X_BOOL 498 depends on SND_FM801_TEA575X_BOOL
498 default SND_FM801 499 default SND_FM801
499 500
500config SND_HDA_INTEL 501source "sound/pci/hda/Kconfig"
501 tristate "Intel HD Audio"
502 select SND_PCM
503 select SND_VMASTER
504 help
505 Say Y here to include support for Intel "High Definition
506 Audio" (Azalia) motherboard devices.
507
508 To compile this driver as a module, choose M here: the module
509 will be called snd-hda-intel.
510
511config SND_HDA_HWDEP
512 bool "Build hwdep interface for HD-audio driver"
513 depends on SND_HDA_INTEL
514 select SND_HWDEP
515 help
516 Say Y here to build a hwdep interface for HD-audio driver.
517 This interface can be used for out-of-band communication
518 with codecs for debugging purposes.
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
528config SND_HDA_CODEC_REALTEK
529 bool "Build Realtek HD-audio codec support"
530 depends on SND_HDA_INTEL
531 default y
532 help
533 Say Y here to include Realtek HD-audio codec support in
534 snd-hda-intel driver, such as ALC880.
535
536config SND_HDA_CODEC_ANALOG
537 bool "Build Analog Device HD-audio codec support"
538 depends on SND_HDA_INTEL
539 default y
540 help
541 Say Y here to include Analog Device HD-audio codec support in
542 snd-hda-intel driver, such as AD1986A.
543
544config SND_HDA_CODEC_SIGMATEL
545 bool "Build IDT/Sigmatel HD-audio codec support"
546 depends on SND_HDA_INTEL
547 default y
548 help
549 Say Y here to include IDT (Sigmatel) HD-audio codec support in
550 snd-hda-intel driver, such as STAC9200.
551
552config SND_HDA_CODEC_VIA
553 bool "Build VIA HD-audio codec support"
554 depends on SND_HDA_INTEL
555 default y
556 help
557 Say Y here to include VIA HD-audio codec support in
558 snd-hda-intel driver, such as VT1708.
559
560config SND_HDA_CODEC_ATIHDMI
561 bool "Build ATI HDMI HD-audio codec support"
562 depends on SND_HDA_INTEL
563 default y
564 help
565 Say Y here to include ATI HDMI HD-audio codec support in
566 snd-hda-intel driver, such as ATI RS600 HDMI.
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
576config SND_HDA_CODEC_CONEXANT
577 bool "Build Conexant HD-audio codec support"
578 depends on SND_HDA_INTEL
579 default y
580 help
581 Say Y here to include Conexant HD-audio codec support in
582 snd-hda-intel driver, such as CX20549.
583
584config SND_HDA_CODEC_CMEDIA
585 bool "Build C-Media HD-audio codec support"
586 depends on SND_HDA_INTEL
587 default y
588 help
589 Say Y here to include C-Media HD-audio codec support in
590 snd-hda-intel driver, such as CMI9880.
591
592config SND_HDA_CODEC_SI3054
593 bool "Build Silicon Labs 3054 HD-modem codec support"
594 depends on SND_HDA_INTEL
595 default y
596 help
597 Say Y here to include Silicon Labs 3054 HD-modem codec
598 (and compatibles) support in snd-hda-intel driver.
599
600config SND_HDA_GENERIC
601 bool "Enable generic HD-audio codec parser"
602 depends on SND_HDA_INTEL
603 default y
604 help
605 Say Y here to enable the generic HD-audio codec parser
606 in snd-hda-intel driver.
607
608config SND_HDA_POWER_SAVE
609 bool "Aggressive power-saving on HD-audio"
610 depends on SND_HDA_INTEL && EXPERIMENTAL
611 help
612 Say Y here to enable more aggressive power-saving mode on
613 HD-audio driver. The power-saving timeout can be configured
614 via power_save option or over sysfs on-the-fly.
615
616config SND_HDA_POWER_SAVE_DEFAULT
617 int "Default time-out for HD-audio power-save mode"
618 depends on SND_HDA_POWER_SAVE
619 default 0
620 help
621 The default time-out value in seconds for HD-audio automatic
622 power-save mode. 0 means to disable the power-save mode.
623 502
624config SND_HDSP 503config SND_HDSP
625 tristate "RME Hammerfall DSP Audio" 504 tristate "RME Hammerfall DSP Audio"
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
index bd510eceff1f..e2b843b4f9d0 100644
--- a/sound/pci/ac97/ac97_codec.c
+++ b/sound/pci/ac97/ac97_codec.c
@@ -175,7 +175,7 @@ static const struct ac97_codec_id snd_ac97_codec_ids[] = {
175{ 0x574d4C04, 0xffffffff, "WM9704M,WM9704Q", patch_wolfson04, NULL}, 175{ 0x574d4C04, 0xffffffff, "WM9704M,WM9704Q", patch_wolfson04, NULL},
176{ 0x574d4C05, 0xffffffff, "WM9705,WM9710", patch_wolfson05, NULL}, 176{ 0x574d4C05, 0xffffffff, "WM9705,WM9710", patch_wolfson05, NULL},
177{ 0x574d4C09, 0xffffffff, "WM9709", NULL, NULL}, 177{ 0x574d4C09, 0xffffffff, "WM9709", NULL, NULL},
178{ 0x574d4C12, 0xffffffff, "WM9711,WM9712", patch_wolfson11, NULL}, 178{ 0x574d4C12, 0xffffffff, "WM9711,WM9712,WM9715", patch_wolfson11, NULL},
179{ 0x574d4c13, 0xffffffff, "WM9713,WM9714", patch_wolfson13, NULL, AC97_DEFAULT_POWER_OFF}, 179{ 0x574d4c13, 0xffffffff, "WM9713,WM9714", patch_wolfson13, NULL, AC97_DEFAULT_POWER_OFF},
180{ 0x594d4800, 0xffffffff, "YMF743", patch_yamaha_ymf743, NULL }, 180{ 0x594d4800, 0xffffffff, "YMF743", patch_yamaha_ymf743, NULL },
181{ 0x594d4802, 0xffffffff, "YMF752", NULL, NULL }, 181{ 0x594d4802, 0xffffffff, "YMF752", NULL, NULL },
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index 6e831aff1bd0..81bc93e5f1e3 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -2054,8 +2054,9 @@ static const struct snd_kcontrol_new snd_ac97_ad1888_controls[] = {
2054 .get = snd_ac97_ad1888_lohpsel_get, 2054 .get = snd_ac97_ad1888_lohpsel_get,
2055 .put = snd_ac97_ad1888_lohpsel_put 2055 .put = snd_ac97_ad1888_lohpsel_put
2056 }, 2056 },
2057 AC97_SINGLE("V_REFOUT Enable", AC97_AD_MISC, 2, 1, 1), 2057 AC97_SINGLE("V_REFOUT Enable", AC97_AD_MISC, AC97_AD_VREFD_SHIFT, 1, 1),
2058 AC97_SINGLE("High Pass Filter Enable", AC97_AD_TEST2, 12, 1, 1), 2058 AC97_SINGLE("High Pass Filter Enable", AC97_AD_TEST2,
2059 AC97_AD_HPFD_SHIFT, 1, 1),
2059 AC97_SINGLE("Spread Front to Surround and Center/LFE", AC97_AD_MISC, 7, 1, 0), 2060 AC97_SINGLE("Spread Front to Surround and Center/LFE", AC97_AD_MISC, 7, 1, 0),
2060 { 2061 {
2061 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2062 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -2832,6 +2833,8 @@ static int patch_alc655(struct snd_ac97 * ac97)
2832 val &= ~(1 << 1); /* Pin 47 is EAPD (for internal speaker) */ 2833 val &= ~(1 << 1); /* Pin 47 is EAPD (for internal speaker) */
2833 else 2834 else
2834 val |= (1 << 1); /* Pin 47 is spdif input pin */ 2835 val |= (1 << 1); /* Pin 47 is spdif input pin */
2836 /* this seems missing on some hardwares */
2837 ac97->ext_id |= AC97_EI_SPDIF;
2835 } 2838 }
2836 val &= ~(1 << 12); /* vref enable */ 2839 val &= ~(1 << 12); /* vref enable */
2837 snd_ac97_write_cache(ac97, 0x7a, val); 2840 snd_ac97_write_cache(ac97, 0x7a, val);
diff --git a/sound/pci/ca0106/ca0106.h b/sound/pci/ca0106/ca0106.h
index 74175fc80c7f..14b8d9a91aae 100644
--- a/sound/pci/ca0106/ca0106.h
+++ b/sound/pci/ca0106/ca0106.h
@@ -664,10 +664,14 @@ struct snd_ca0106_pcm {
664struct snd_ca0106_details { 664struct snd_ca0106_details {
665 u32 serial; 665 u32 serial;
666 char * name; 666 char * name;
667 int ac97; 667 int ac97; /* ac97 = 0 -> Select MIC, Line in, TAD in, AUX in.
668 int gpio_type; 668 ac97 = 1 -> Default to AC97 in. */
669 int i2c_adc; 669 int gpio_type; /* gpio_type = 1 -> shared mic-in/line-in
670 int spi_dac; 670 gpio_type = 2 -> shared side-out/line-in. */
671 int i2c_adc; /* with i2c_adc=1, the driver adds some capture volume
672 controls, phone, mic, line-in and aux. */
673 int spi_dac; /* spi_dac=1 adds the mute switch for each analog
674 output, front, rear, etc. */
671}; 675};
672 676
673// definition of the chip-specific record 677// definition of the chip-specific record
@@ -686,11 +690,12 @@ struct snd_ca0106 {
686 spinlock_t emu_lock; 690 spinlock_t emu_lock;
687 691
688 struct snd_ac97 *ac97; 692 struct snd_ac97 *ac97;
689 struct snd_pcm *pcm; 693 struct snd_pcm *pcm[4];
690 694
691 struct snd_ca0106_channel playback_channels[4]; 695 struct snd_ca0106_channel playback_channels[4];
692 struct snd_ca0106_channel capture_channels[4]; 696 struct snd_ca0106_channel capture_channels[4];
693 u32 spdif_bits[4]; /* s/pdif out setup */ 697 u32 spdif_bits[4]; /* s/pdif out default setup */
698 u32 spdif_str_bits[4]; /* s/pdif out per-stream setup */
694 int spdif_enable; 699 int spdif_enable;
695 int capture_source; 700 int capture_source;
696 int i2c_capture_source; 701 int i2c_capture_source;
@@ -703,6 +708,11 @@ struct snd_ca0106 {
703 struct snd_ca_midi midi2; 708 struct snd_ca_midi midi2;
704 709
705 u16 spi_dac_reg[16]; 710 u16 spi_dac_reg[16];
711
712#ifdef CONFIG_PM
713#define NUM_SAVED_VOLUMES 9
714 unsigned int saved_vol[NUM_SAVED_VOLUMES];
715#endif
706}; 716};
707 717
708int snd_ca0106_mixer(struct snd_ca0106 *emu); 718int snd_ca0106_mixer(struct snd_ca0106 *emu);
@@ -721,3 +731,11 @@ int snd_ca0106_i2c_write(struct snd_ca0106 *emu, u32 reg, u32 value);
721 731
722int snd_ca0106_spi_write(struct snd_ca0106 * emu, 732int snd_ca0106_spi_write(struct snd_ca0106 * emu,
723 unsigned int data); 733 unsigned int data);
734
735#ifdef CONFIG_PM
736void snd_ca0106_mixer_suspend(struct snd_ca0106 *chip);
737void snd_ca0106_mixer_resume(struct snd_ca0106 *chip);
738#else
739#define snd_ca0106_mixer_suspend(chip) do { } while (0)
740#define snd_ca0106_mixer_resume(chip) do { } while (0)
741#endif
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index 88fbf285d2b7..0e62205d4081 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 = 1 } ,
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".
@@ -305,9 +305,15 @@ static struct snd_pcm_hardware snd_ca0106_capture_hw = {
305 SNDRV_PCM_INFO_BLOCK_TRANSFER | 305 SNDRV_PCM_INFO_BLOCK_TRANSFER |
306 SNDRV_PCM_INFO_MMAP_VALID), 306 SNDRV_PCM_INFO_MMAP_VALID),
307 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE, 307 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
308#if 0 /* FIXME: looks like 44.1kHz capture causes noisy output on 48kHz */
308 .rates = (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | 309 .rates = (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
309 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000), 310 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000),
310 .rate_min = 44100, 311 .rate_min = 44100,
312#else
313 .rates = (SNDRV_PCM_RATE_48000 |
314 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000),
315 .rate_min = 48000,
316#endif /* FIXME */
311 .rate_max = 192000, 317 .rate_max = 192000,
312 .channels_min = 2, 318 .channels_min = 2,
313 .channels_max = 2, 319 .channels_max = 2,
@@ -479,6 +485,15 @@ static const int spi_dacd_bit[] = {
479 [PCM_UNKNOWN_CHANNEL] = SPI_DACD1_BIT, 485 [PCM_UNKNOWN_CHANNEL] = SPI_DACD1_BIT,
480}; 486};
481 487
488static void restore_spdif_bits(struct snd_ca0106 *chip, int idx)
489{
490 if (chip->spdif_str_bits[idx] != chip->spdif_bits[idx]) {
491 chip->spdif_str_bits[idx] = chip->spdif_bits[idx];
492 snd_ca0106_ptr_write(chip, SPCS0 + idx, 0,
493 chip->spdif_str_bits[idx]);
494 }
495}
496
482/* open_playback callback */ 497/* open_playback callback */
483static int snd_ca0106_pcm_open_playback_channel(struct snd_pcm_substream *substream, 498static int snd_ca0106_pcm_open_playback_channel(struct snd_pcm_substream *substream,
484 int channel_id) 499 int channel_id)
@@ -524,6 +539,9 @@ static int snd_ca0106_pcm_open_playback_channel(struct snd_pcm_substream *substr
524 if (err < 0) 539 if (err < 0)
525 return err; 540 return err;
526 } 541 }
542
543 restore_spdif_bits(chip, channel_id);
544
527 return 0; 545 return 0;
528} 546}
529 547
@@ -535,6 +553,8 @@ static int snd_ca0106_pcm_close_playback(struct snd_pcm_substream *substream)
535 struct snd_ca0106_pcm *epcm = runtime->private_data; 553 struct snd_ca0106_pcm *epcm = runtime->private_data;
536 chip->playback_channels[epcm->channel_id].use = 0; 554 chip->playback_channels[epcm->channel_id].use = 0;
537 555
556 restore_spdif_bits(chip, epcm->channel_id);
557
538 if (chip->details->spi_dac && epcm->channel_id != PCM_FRONT_CHANNEL) { 558 if (chip->details->spi_dac && epcm->channel_id != PCM_FRONT_CHANNEL) {
539 const int reg = spi_dacd_reg[epcm->channel_id]; 559 const int reg = spi_dacd_reg[epcm->channel_id];
540 560
@@ -847,15 +867,18 @@ static int snd_ca0106_pcm_trigger_playback(struct snd_pcm_substream *substream,
847 struct snd_pcm_substream *s; 867 struct snd_pcm_substream *s;
848 u32 basic = 0; 868 u32 basic = 0;
849 u32 extended = 0; 869 u32 extended = 0;
850 int running=0; 870 u32 bits;
871 int running = 0;
851 872
852 switch (cmd) { 873 switch (cmd) {
853 case SNDRV_PCM_TRIGGER_START: 874 case SNDRV_PCM_TRIGGER_START:
854 running=1; 875 case SNDRV_PCM_TRIGGER_RESUME:
876 running = 1;
855 break; 877 break;
856 case SNDRV_PCM_TRIGGER_STOP: 878 case SNDRV_PCM_TRIGGER_STOP:
879 case SNDRV_PCM_TRIGGER_SUSPEND:
857 default: 880 default:
858 running=0; 881 running = 0;
859 break; 882 break;
860 } 883 }
861 snd_pcm_group_for_each_entry(s, substream) { 884 snd_pcm_group_for_each_entry(s, substream) {
@@ -865,22 +888,32 @@ static int snd_ca0106_pcm_trigger_playback(struct snd_pcm_substream *substream,
865 runtime = s->runtime; 888 runtime = s->runtime;
866 epcm = runtime->private_data; 889 epcm = runtime->private_data;
867 channel = epcm->channel_id; 890 channel = epcm->channel_id;
868 //snd_printk("channel=%d\n",channel); 891 /* snd_printk("channel=%d\n",channel); */
869 epcm->running = running; 892 epcm->running = running;
870 basic |= (0x1<<channel); 893 basic |= (0x1 << channel);
871 extended |= (0x10<<channel); 894 extended |= (0x10 << channel);
872 snd_pcm_trigger_done(s, substream); 895 snd_pcm_trigger_done(s, substream);
873 } 896 }
874 //snd_printk("basic=0x%x, extended=0x%x\n",basic, extended); 897 /* snd_printk("basic=0x%x, extended=0x%x\n",basic, extended); */
875 898
876 switch (cmd) { 899 switch (cmd) {
877 case SNDRV_PCM_TRIGGER_START: 900 case SNDRV_PCM_TRIGGER_START:
878 snd_ca0106_ptr_write(emu, EXTENDED_INT_MASK, 0, snd_ca0106_ptr_read(emu, EXTENDED_INT_MASK, 0) | (extended)); 901 case SNDRV_PCM_TRIGGER_RESUME:
879 snd_ca0106_ptr_write(emu, BASIC_INTERRUPT, 0, snd_ca0106_ptr_read(emu, BASIC_INTERRUPT, 0)|(basic)); 902 bits = snd_ca0106_ptr_read(emu, EXTENDED_INT_MASK, 0);
903 bits |= extended;
904 snd_ca0106_ptr_write(emu, EXTENDED_INT_MASK, 0, bits);
905 bits = snd_ca0106_ptr_read(emu, BASIC_INTERRUPT, 0);
906 bits |= basic;
907 snd_ca0106_ptr_write(emu, BASIC_INTERRUPT, 0, bits);
880 break; 908 break;
881 case SNDRV_PCM_TRIGGER_STOP: 909 case SNDRV_PCM_TRIGGER_STOP:
882 snd_ca0106_ptr_write(emu, BASIC_INTERRUPT, 0, snd_ca0106_ptr_read(emu, BASIC_INTERRUPT, 0) & ~(basic)); 910 case SNDRV_PCM_TRIGGER_SUSPEND:
883 snd_ca0106_ptr_write(emu, EXTENDED_INT_MASK, 0, snd_ca0106_ptr_read(emu, EXTENDED_INT_MASK, 0) & ~(extended)); 911 bits = snd_ca0106_ptr_read(emu, BASIC_INTERRUPT, 0);
912 bits &= ~basic;
913 snd_ca0106_ptr_write(emu, BASIC_INTERRUPT, 0, bits);
914 bits = snd_ca0106_ptr_read(emu, EXTENDED_INT_MASK, 0);
915 bits &= ~extended;
916 snd_ca0106_ptr_write(emu, EXTENDED_INT_MASK, 0, bits);
884 break; 917 break;
885 default: 918 default:
886 result = -EINVAL; 919 result = -EINVAL;
@@ -1103,21 +1136,13 @@ static int snd_ca0106_ac97(struct snd_ca0106 *chip)
1103 return snd_ac97_mixer(pbus, &ac97, &chip->ac97); 1136 return snd_ac97_mixer(pbus, &ac97, &chip->ac97);
1104} 1137}
1105 1138
1139static void ca0106_stop_chip(struct snd_ca0106 *chip);
1140
1106static int snd_ca0106_free(struct snd_ca0106 *chip) 1141static int snd_ca0106_free(struct snd_ca0106 *chip)
1107{ 1142{
1108 if (chip->res_port != NULL) { /* avoid access to already used hardware */ 1143 if (chip->res_port != NULL) {
1109 // disable interrupts 1144 /* avoid access to already used hardware */
1110 snd_ca0106_ptr_write(chip, BASIC_INTERRUPT, 0, 0); 1145 ca0106_stop_chip(chip);
1111 outl(0, chip->port + INTE);
1112 snd_ca0106_ptr_write(chip, EXTENDED_INT_MASK, 0, 0);
1113 udelay(1000);
1114 // disable audio
1115 //outl(HCFG_LOCKSOUNDCACHE, chip->port + HCFG);
1116 outl(0, chip->port + HCFG);
1117 /* FIXME: We need to stop and DMA transfers here.
1118 * But as I am not sure how yet, we cannot from the dma pages.
1119 * So we can fix: snd-malloc: Memory leak? pages not freed = 8
1120 */
1121 } 1146 }
1122 if (chip->irq >= 0) 1147 if (chip->irq >= 0)
1123 free_irq(chip->irq, chip); 1148 free_irq(chip->irq, chip);
@@ -1203,15 +1228,14 @@ static irqreturn_t snd_ca0106_interrupt(int irq, void *dev_id)
1203 return IRQ_HANDLED; 1228 return IRQ_HANDLED;
1204} 1229}
1205 1230
1206static int __devinit snd_ca0106_pcm(struct snd_ca0106 *emu, int device, struct snd_pcm **rpcm) 1231static int __devinit snd_ca0106_pcm(struct snd_ca0106 *emu, int device)
1207{ 1232{
1208 struct snd_pcm *pcm; 1233 struct snd_pcm *pcm;
1209 struct snd_pcm_substream *substream; 1234 struct snd_pcm_substream *substream;
1210 int err; 1235 int err;
1211 1236
1212 if (rpcm) 1237 err = snd_pcm_new(emu->card, "ca0106", device, 1, 1, &pcm);
1213 *rpcm = NULL; 1238 if (err < 0)
1214 if ((err = snd_pcm_new(emu->card, "ca0106", device, 1, 1, &pcm)) < 0)
1215 return err; 1239 return err;
1216 1240
1217 pcm->private_data = emu; 1241 pcm->private_data = emu;
@@ -1238,7 +1262,6 @@ static int __devinit snd_ca0106_pcm(struct snd_ca0106 *emu, int device, struct s
1238 pcm->info_flags = 0; 1262 pcm->info_flags = 0;
1239 pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX; 1263 pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
1240 strcpy(pcm->name, "CA0106"); 1264 strcpy(pcm->name, "CA0106");
1241 emu->pcm = pcm;
1242 1265
1243 for(substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; 1266 for(substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
1244 substream; 1267 substream;
@@ -1260,8 +1283,7 @@ static int __devinit snd_ca0106_pcm(struct snd_ca0106 *emu, int device, struct s
1260 return err; 1283 return err;
1261 } 1284 }
1262 1285
1263 if (rpcm) 1286 emu->pcm[device] = pcm;
1264 *rpcm = pcm;
1265 1287
1266 return 0; 1288 return 0;
1267} 1289}
@@ -1301,89 +1323,10 @@ static unsigned int i2c_adc_init[][2] = {
1301 { 0x15, ADC_MUX_LINEIN }, /* ADC Mixer control */ 1323 { 0x15, ADC_MUX_LINEIN }, /* ADC Mixer control */
1302}; 1324};
1303 1325
1304static int __devinit snd_ca0106_create(int dev, struct snd_card *card, 1326static void ca0106_init_chip(struct snd_ca0106 *chip, int resume)
1305 struct pci_dev *pci,
1306 struct snd_ca0106 **rchip)
1307{ 1327{
1308 struct snd_ca0106 *chip;
1309 struct snd_ca0106_details *c;
1310 int err;
1311 int ch; 1328 int ch;
1312 static struct snd_device_ops ops = { 1329 unsigned int def_bits;
1313 .dev_free = snd_ca0106_dev_free,
1314 };
1315
1316 *rchip = NULL;
1317
1318 if ((err = pci_enable_device(pci)) < 0)
1319 return err;
1320 if (pci_set_dma_mask(pci, DMA_32BIT_MASK) < 0 ||
1321 pci_set_consistent_dma_mask(pci, DMA_32BIT_MASK) < 0) {
1322 printk(KERN_ERR "error to set 32bit mask DMA\n");
1323 pci_disable_device(pci);
1324 return -ENXIO;
1325 }
1326
1327 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
1328 if (chip == NULL) {
1329 pci_disable_device(pci);
1330 return -ENOMEM;
1331 }
1332
1333 chip->card = card;
1334 chip->pci = pci;
1335 chip->irq = -1;
1336
1337 spin_lock_init(&chip->emu_lock);
1338
1339 chip->port = pci_resource_start(pci, 0);
1340 if ((chip->res_port = request_region(chip->port, 0x20,
1341 "snd_ca0106")) == NULL) {
1342 snd_ca0106_free(chip);
1343 printk(KERN_ERR "cannot allocate the port\n");
1344 return -EBUSY;
1345 }
1346
1347 if (request_irq(pci->irq, snd_ca0106_interrupt,
1348 IRQF_SHARED, "snd_ca0106", chip)) {
1349 snd_ca0106_free(chip);
1350 printk(KERN_ERR "cannot grab irq\n");
1351 return -EBUSY;
1352 }
1353 chip->irq = pci->irq;
1354
1355 /* This stores the periods table. */
1356 if(snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), 1024, &chip->buffer) < 0) {
1357 snd_ca0106_free(chip);
1358 return -ENOMEM;
1359 }
1360
1361 pci_set_master(pci);
1362 /* read serial */
1363 pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &chip->serial);
1364 pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &chip->model);
1365#if 1
1366 printk(KERN_INFO "snd-ca0106: Model %04x Rev %08x Serial %08x\n", chip->model,
1367 pci->revision, chip->serial);
1368#endif
1369 strcpy(card->driver, "CA0106");
1370 strcpy(card->shortname, "CA0106");
1371
1372 for (c = ca0106_chip_details; c->serial; c++) {
1373 if (subsystem[dev]) {
1374 if (c->serial == subsystem[dev])
1375 break;
1376 } else if (c->serial == chip->serial)
1377 break;
1378 }
1379 chip->details = c;
1380 if (subsystem[dev]) {
1381 printk(KERN_INFO "snd-ca0106: Sound card name=%s, subsystem=0x%x. Forced to subsystem=0x%x\n",
1382 c->name, chip->serial, subsystem[dev]);
1383 }
1384
1385 sprintf(card->longname, "%s at 0x%lx irq %i",
1386 c->name, chip->port, chip->irq);
1387 1330
1388 outl(0, chip->port + INTE); 1331 outl(0, chip->port + INTE);
1389 1332
@@ -1401,31 +1344,22 @@ static int __devinit snd_ca0106_create(int dev, struct snd_card *card,
1401 * AN = 0 (Audio data) 1344 * AN = 0 (Audio data)
1402 * P = 0 (Consumer) 1345 * P = 0 (Consumer)
1403 */ 1346 */
1404 snd_ca0106_ptr_write(chip, SPCS0, 0, 1347 def_bits =
1405 chip->spdif_bits[0] = 1348 SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
1406 SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 | 1349 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
1407 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC | 1350 SPCS_GENERATIONSTATUS | 0x00001200 |
1408 SPCS_GENERATIONSTATUS | 0x00001200 | 1351 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT;
1409 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT); 1352 if (!resume) {
1353 chip->spdif_str_bits[0] = chip->spdif_bits[0] = def_bits;
1354 chip->spdif_str_bits[1] = chip->spdif_bits[1] = def_bits;
1355 chip->spdif_str_bits[2] = chip->spdif_bits[2] = def_bits;
1356 chip->spdif_str_bits[3] = chip->spdif_bits[3] = def_bits;
1357 }
1410 /* Only SPCS1 has been tested */ 1358 /* Only SPCS1 has been tested */
1411 snd_ca0106_ptr_write(chip, SPCS1, 0, 1359 snd_ca0106_ptr_write(chip, SPCS1, 0, chip->spdif_str_bits[1]);
1412 chip->spdif_bits[1] = 1360 snd_ca0106_ptr_write(chip, SPCS0, 0, chip->spdif_str_bits[0]);
1413 SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 | 1361 snd_ca0106_ptr_write(chip, SPCS2, 0, chip->spdif_str_bits[2]);
1414 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC | 1362 snd_ca0106_ptr_write(chip, SPCS3, 0, chip->spdif_str_bits[3]);
1415 SPCS_GENERATIONSTATUS | 0x00001200 |
1416 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
1417 snd_ca0106_ptr_write(chip, SPCS2, 0,
1418 chip->spdif_bits[2] =
1419 SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
1420 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
1421 SPCS_GENERATIONSTATUS | 0x00001200 |
1422 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
1423 snd_ca0106_ptr_write(chip, SPCS3, 0,
1424 chip->spdif_bits[3] =
1425 SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
1426 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
1427 SPCS_GENERATIONSTATUS | 0x00001200 |
1428 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
1429 1363
1430 snd_ca0106_ptr_write(chip, PLAYBACK_MUTE, 0, 0x00fc0000); 1364 snd_ca0106_ptr_write(chip, PLAYBACK_MUTE, 0, 0x00fc0000);
1431 snd_ca0106_ptr_write(chip, CAPTURE_MUTE, 0, 0x00fc0000); 1365 snd_ca0106_ptr_write(chip, CAPTURE_MUTE, 0, 0x00fc0000);
@@ -1433,92 +1367,124 @@ static int __devinit snd_ca0106_create(int dev, struct snd_card *card,
1433 /* Write 0x8000 to AC97_REC_GAIN to mute it. */ 1367 /* Write 0x8000 to AC97_REC_GAIN to mute it. */
1434 outb(AC97_REC_GAIN, chip->port + AC97ADDRESS); 1368 outb(AC97_REC_GAIN, chip->port + AC97ADDRESS);
1435 outw(0x8000, chip->port + AC97DATA); 1369 outw(0x8000, chip->port + AC97DATA);
1436#if 0 1370#if 0 /* FIXME: what are these? */
1437 snd_ca0106_ptr_write(chip, SPCS0, 0, 0x2108006); 1371 snd_ca0106_ptr_write(chip, SPCS0, 0, 0x2108006);
1438 snd_ca0106_ptr_write(chip, 0x42, 0, 0x2108006); 1372 snd_ca0106_ptr_write(chip, 0x42, 0, 0x2108006);
1439 snd_ca0106_ptr_write(chip, 0x43, 0, 0x2108006); 1373 snd_ca0106_ptr_write(chip, 0x43, 0, 0x2108006);
1440 snd_ca0106_ptr_write(chip, 0x44, 0, 0x2108006); 1374 snd_ca0106_ptr_write(chip, 0x44, 0, 0x2108006);
1441#endif 1375#endif
1442 1376
1443 //snd_ca0106_ptr_write(chip, SPDIF_SELECT2, 0, 0xf0f003f); /* OSS drivers set this. */ 1377 /* OSS drivers set this. */
1378 /* snd_ca0106_ptr_write(chip, SPDIF_SELECT2, 0, 0xf0f003f); */
1379
1444 /* Analog or Digital output */ 1380 /* Analog or Digital output */
1445 snd_ca0106_ptr_write(chip, SPDIF_SELECT1, 0, 0xf); 1381 snd_ca0106_ptr_write(chip, SPDIF_SELECT1, 0, 0xf);
1446 snd_ca0106_ptr_write(chip, SPDIF_SELECT2, 0, 0x000f0000); /* 0x0b000000 for digital, 0x000b0000 for analog, from win2000 drivers. Use 0x000f0000 for surround71 */ 1382 /* 0x0b000000 for digital, 0x000b0000 for analog, from win2000 drivers.
1383 * Use 0x000f0000 for surround71
1384 */
1385 snd_ca0106_ptr_write(chip, SPDIF_SELECT2, 0, 0x000f0000);
1386
1447 chip->spdif_enable = 0; /* Set digital SPDIF output off */ 1387 chip->spdif_enable = 0; /* Set digital SPDIF output off */
1448 //snd_ca0106_ptr_write(chip, 0x45, 0, 0); /* Analogue out */ 1388 /*snd_ca0106_ptr_write(chip, 0x45, 0, 0);*/ /* Analogue out */
1449 //snd_ca0106_ptr_write(chip, 0x45, 0, 0xf00); /* Digital out */ 1389 /*snd_ca0106_ptr_write(chip, 0x45, 0, 0xf00);*/ /* Digital out */
1390
1391 /* goes to 0x40c80000 when doing SPDIF IN/OUT */
1392 snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 0, 0x40c81000);
1393 /* (Mute) CAPTURE feedback into PLAYBACK volume.
1394 * Only lower 16 bits matter.
1395 */
1396 snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 1, 0xffffffff);
1397 /* SPDIF IN Volume */
1398 snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 2, 0x30300000);
1399 /* SPDIF IN Volume, 0x70 = (vol & 0x3f) | 0x40 */
1400 snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 3, 0x00700000);
1450 1401
1451 snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 0, 0x40c81000); /* goes to 0x40c80000 when doing SPDIF IN/OUT */
1452 snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 1, 0xffffffff); /* (Mute) CAPTURE feedback into PLAYBACK volume. Only lower 16 bits matter. */
1453 snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 2, 0x30300000); /* SPDIF IN Volume */
1454 snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 3, 0x00700000); /* SPDIF IN Volume, 0x70 = (vol & 0x3f) | 0x40 */
1455 snd_ca0106_ptr_write(chip, PLAYBACK_ROUTING1, 0, 0x32765410); 1402 snd_ca0106_ptr_write(chip, PLAYBACK_ROUTING1, 0, 0x32765410);
1456 snd_ca0106_ptr_write(chip, PLAYBACK_ROUTING2, 0, 0x76767676); 1403 snd_ca0106_ptr_write(chip, PLAYBACK_ROUTING2, 0, 0x76767676);
1457 snd_ca0106_ptr_write(chip, CAPTURE_ROUTING1, 0, 0x32765410); 1404 snd_ca0106_ptr_write(chip, CAPTURE_ROUTING1, 0, 0x32765410);
1458 snd_ca0106_ptr_write(chip, CAPTURE_ROUTING2, 0, 0x76767676); 1405 snd_ca0106_ptr_write(chip, CAPTURE_ROUTING2, 0, 0x76767676);
1459 for(ch = 0; ch < 4; ch++) { 1406
1460 snd_ca0106_ptr_write(chip, CAPTURE_VOLUME1, ch, 0x30303030); /* Only high 16 bits matter */ 1407 for (ch = 0; ch < 4; ch++) {
1408 /* Only high 16 bits matter */
1409 snd_ca0106_ptr_write(chip, CAPTURE_VOLUME1, ch, 0x30303030);
1461 snd_ca0106_ptr_write(chip, CAPTURE_VOLUME2, ch, 0x30303030); 1410 snd_ca0106_ptr_write(chip, CAPTURE_VOLUME2, ch, 0x30303030);
1462 //snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME1, ch, 0x40404040); /* Mute */ 1411#if 0 /* Mute */
1463 //snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME2, ch, 0x40404040); /* Mute */ 1412 snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME1, ch, 0x40404040);
1464 snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME1, ch, 0xffffffff); /* Mute */ 1413 snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME2, ch, 0x40404040);
1465 snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME2, ch, 0xffffffff); /* Mute */ 1414 snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME1, ch, 0xffffffff);
1415 snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME2, ch, 0xffffffff);
1416#endif
1466 } 1417 }
1467 if (chip->details->i2c_adc == 1) { 1418 if (chip->details->i2c_adc == 1) {
1468 /* Select MIC, Line in, TAD in, AUX in */ 1419 /* Select MIC, Line in, TAD in, AUX in */
1469 snd_ca0106_ptr_write(chip, CAPTURE_SOURCE, 0x0, 0x333300e4); 1420 snd_ca0106_ptr_write(chip, CAPTURE_SOURCE, 0x0, 0x333300e4);
1470 /* Default to CAPTURE_SOURCE to i2s in */ 1421 /* Default to CAPTURE_SOURCE to i2s in */
1471 chip->capture_source = 3; 1422 if (!resume)
1423 chip->capture_source = 3;
1472 } else if (chip->details->ac97 == 1) { 1424 } else if (chip->details->ac97 == 1) {
1473 /* Default to AC97 in */ 1425 /* Default to AC97 in */
1474 snd_ca0106_ptr_write(chip, CAPTURE_SOURCE, 0x0, 0x444400e4); 1426 snd_ca0106_ptr_write(chip, CAPTURE_SOURCE, 0x0, 0x444400e4);
1475 /* Default to CAPTURE_SOURCE to AC97 in */ 1427 /* Default to CAPTURE_SOURCE to AC97 in */
1476 chip->capture_source = 4; 1428 if (!resume)
1429 chip->capture_source = 4;
1477 } else { 1430 } else {
1478 /* Select MIC, Line in, TAD in, AUX in */ 1431 /* Select MIC, Line in, TAD in, AUX in */
1479 snd_ca0106_ptr_write(chip, CAPTURE_SOURCE, 0x0, 0x333300e4); 1432 snd_ca0106_ptr_write(chip, CAPTURE_SOURCE, 0x0, 0x333300e4);
1480 /* Default to Set CAPTURE_SOURCE to i2s in */ 1433 /* Default to Set CAPTURE_SOURCE to i2s in */
1481 chip->capture_source = 3; 1434 if (!resume)
1435 chip->capture_source = 3;
1482 } 1436 }
1483 1437
1484 if (chip->details->gpio_type == 2) { /* The SB0438 use GPIO differently. */ 1438 if (chip->details->gpio_type == 2) {
1485 /* FIXME: Still need to find out what the other GPIO bits do. E.g. For digital spdif out. */ 1439 /* The SB0438 use GPIO differently. */
1440 /* FIXME: Still need to find out what the other GPIO bits do.
1441 * E.g. For digital spdif out.
1442 */
1486 outl(0x0, chip->port+GPIO); 1443 outl(0x0, chip->port+GPIO);
1487 //outl(0x00f0e000, chip->port+GPIO); /* Analog */ 1444 /* outl(0x00f0e000, chip->port+GPIO); */ /* Analog */
1488 outl(0x005f5301, chip->port+GPIO); /* Analog */ 1445 outl(0x005f5301, chip->port+GPIO); /* Analog */
1489 } else if (chip->details->gpio_type == 1) { /* The SB0410 and SB0413 use GPIO differently. */ 1446 } else if (chip->details->gpio_type == 1) {
1490 /* FIXME: Still need to find out what the other GPIO bits do. E.g. For digital spdif out. */ 1447 /* The SB0410 and SB0413 use GPIO differently. */
1448 /* FIXME: Still need to find out what the other GPIO bits do.
1449 * E.g. For digital spdif out.
1450 */
1491 outl(0x0, chip->port+GPIO); 1451 outl(0x0, chip->port+GPIO);
1492 //outl(0x00f0e000, chip->port+GPIO); /* Analog */ 1452 /* outl(0x00f0e000, chip->port+GPIO); */ /* Analog */
1493 outl(0x005f5301, chip->port+GPIO); /* Analog */ 1453 outl(0x005f5301, chip->port+GPIO); /* Analog */
1494 } else { 1454 } else {
1495 outl(0x0, chip->port+GPIO); 1455 outl(0x0, chip->port+GPIO);
1496 outl(0x005f03a3, chip->port+GPIO); /* Analog */ 1456 outl(0x005f03a3, chip->port+GPIO); /* Analog */
1497 //outl(0x005f02a2, chip->port+GPIO); /* SPDIF */ 1457 /* outl(0x005f02a2, chip->port+GPIO); */ /* SPDIF */
1498 } 1458 }
1499 snd_ca0106_intr_enable(chip, 0x105); /* Win2000 uses 0x1e0 */ 1459 snd_ca0106_intr_enable(chip, 0x105); /* Win2000 uses 0x1e0 */
1500 1460
1501 //outl(HCFG_LOCKSOUNDCACHE|HCFG_AUDIOENABLE, chip->port+HCFG); 1461 /* outl(HCFG_LOCKSOUNDCACHE|HCFG_AUDIOENABLE, chip->port+HCFG); */
1502 //outl(0x00001409, chip->port+HCFG); /* 0x1000 causes AC3 to fails. Maybe it effects 24 bit output. */ 1462 /* 0x1000 causes AC3 to fails. Maybe it effects 24 bit output. */
1503 //outl(0x00000009, chip->port+HCFG); 1463 /* outl(0x00001409, chip->port+HCFG); */
1504 outl(HCFG_AC97 | HCFG_AUDIOENABLE, chip->port+HCFG); /* AC97 2.0, Enable outputs. */ 1464 /* outl(0x00000009, chip->port+HCFG); */
1465 /* AC97 2.0, Enable outputs. */
1466 outl(HCFG_AC97 | HCFG_AUDIOENABLE, chip->port+HCFG);
1505 1467
1506 if (chip->details->i2c_adc == 1) { /* The SB0410 and SB0413 use I2C to control ADC. */ 1468 if (chip->details->i2c_adc == 1) {
1469 /* The SB0410 and SB0413 use I2C to control ADC. */
1507 int size, n; 1470 int size, n;
1508 1471
1509 size = ARRAY_SIZE(i2c_adc_init); 1472 size = ARRAY_SIZE(i2c_adc_init);
1510 //snd_printk("I2C:array size=0x%x\n", size); 1473 /* snd_printk("I2C:array size=0x%x\n", size); */
1511 for (n=0; n < size; n++) { 1474 for (n = 0; n < size; n++)
1512 snd_ca0106_i2c_write(chip, i2c_adc_init[n][0], i2c_adc_init[n][1]); 1475 snd_ca0106_i2c_write(chip, i2c_adc_init[n][0],
1513 } 1476 i2c_adc_init[n][1]);
1514 for (n=0; n < 4; n++) { 1477 for (n = 0; n < 4; n++) {
1515 chip->i2c_capture_volume[n][0]= 0xcf; 1478 chip->i2c_capture_volume[n][0] = 0xcf;
1516 chip->i2c_capture_volume[n][1]= 0xcf; 1479 chip->i2c_capture_volume[n][1] = 0xcf;
1517 } 1480 }
1518 chip->i2c_capture_source=2; /* Line in */ 1481 chip->i2c_capture_source = 2; /* Line in */
1519 //snd_ca0106_i2c_write(chip, ADC_MUX, ADC_MUX_LINEIN); /* Enable Line-in capture. MIC in currently untested. */ 1482 /* Enable Line-in capture. MIC in currently untested. */
1483 /* snd_ca0106_i2c_write(chip, ADC_MUX, ADC_MUX_LINEIN); */
1520 } 1484 }
1521 if (chip->details->spi_dac == 1) { /* The SB0570 use SPI to control DAC. */ 1485
1486 if (chip->details->spi_dac == 1) {
1487 /* The SB0570 use SPI to control DAC. */
1522 int size, n; 1488 int size, n;
1523 1489
1524 size = ARRAY_SIZE(spi_dac_init); 1490 size = ARRAY_SIZE(spi_dac_init);
@@ -1530,9 +1496,112 @@ static int __devinit snd_ca0106_create(int dev, struct snd_card *card,
1530 chip->spi_dac_reg[reg] = spi_dac_init[n]; 1496 chip->spi_dac_reg[reg] = spi_dac_init[n];
1531 } 1497 }
1532 } 1498 }
1499}
1533 1500
1534 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, 1501static void ca0106_stop_chip(struct snd_ca0106 *chip)
1535 chip, &ops)) < 0) { 1502{
1503 /* disable interrupts */
1504 snd_ca0106_ptr_write(chip, BASIC_INTERRUPT, 0, 0);
1505 outl(0, chip->port + INTE);
1506 snd_ca0106_ptr_write(chip, EXTENDED_INT_MASK, 0, 0);
1507 udelay(1000);
1508 /* disable audio */
1509 /* outl(HCFG_LOCKSOUNDCACHE, chip->port + HCFG); */
1510 outl(0, chip->port + HCFG);
1511 /* FIXME: We need to stop and DMA transfers here.
1512 * But as I am not sure how yet, we cannot from the dma pages.
1513 * So we can fix: snd-malloc: Memory leak? pages not freed = 8
1514 */
1515}
1516
1517static int __devinit snd_ca0106_create(int dev, struct snd_card *card,
1518 struct pci_dev *pci,
1519 struct snd_ca0106 **rchip)
1520{
1521 struct snd_ca0106 *chip;
1522 struct snd_ca0106_details *c;
1523 int err;
1524 static struct snd_device_ops ops = {
1525 .dev_free = snd_ca0106_dev_free,
1526 };
1527
1528 *rchip = NULL;
1529
1530 err = pci_enable_device(pci);
1531 if (err < 0)
1532 return err;
1533 if (pci_set_dma_mask(pci, DMA_32BIT_MASK) < 0 ||
1534 pci_set_consistent_dma_mask(pci, DMA_32BIT_MASK) < 0) {
1535 printk(KERN_ERR "error to set 32bit mask DMA\n");
1536 pci_disable_device(pci);
1537 return -ENXIO;
1538 }
1539
1540 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
1541 if (chip == NULL) {
1542 pci_disable_device(pci);
1543 return -ENOMEM;
1544 }
1545
1546 chip->card = card;
1547 chip->pci = pci;
1548 chip->irq = -1;
1549
1550 spin_lock_init(&chip->emu_lock);
1551
1552 chip->port = pci_resource_start(pci, 0);
1553 chip->res_port = request_region(chip->port, 0x20, "snd_ca0106");
1554 if (!chip->res_port) {
1555 snd_ca0106_free(chip);
1556 printk(KERN_ERR "cannot allocate the port\n");
1557 return -EBUSY;
1558 }
1559
1560 if (request_irq(pci->irq, snd_ca0106_interrupt,
1561 IRQF_SHARED, "snd_ca0106", chip)) {
1562 snd_ca0106_free(chip);
1563 printk(KERN_ERR "cannot grab irq\n");
1564 return -EBUSY;
1565 }
1566 chip->irq = pci->irq;
1567
1568 /* This stores the periods table. */
1569 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
1570 1024, &chip->buffer) < 0) {
1571 snd_ca0106_free(chip);
1572 return -ENOMEM;
1573 }
1574
1575 pci_set_master(pci);
1576 /* read serial */
1577 pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &chip->serial);
1578 pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &chip->model);
1579 printk(KERN_INFO "snd-ca0106: Model %04x Rev %08x Serial %08x\n",
1580 chip->model, pci->revision, chip->serial);
1581 strcpy(card->driver, "CA0106");
1582 strcpy(card->shortname, "CA0106");
1583
1584 for (c = ca0106_chip_details; c->serial; c++) {
1585 if (subsystem[dev]) {
1586 if (c->serial == subsystem[dev])
1587 break;
1588 } else if (c->serial == chip->serial)
1589 break;
1590 }
1591 chip->details = c;
1592 if (subsystem[dev]) {
1593 printk(KERN_INFO "snd-ca0106: Sound card name=%s, "
1594 "subsystem=0x%x. Forced to subsystem=0x%x\n",
1595 c->name, chip->serial, subsystem[dev]);
1596 }
1597
1598 sprintf(card->longname, "%s at 0x%lx irq %i",
1599 c->name, chip->port, chip->irq);
1600
1601 ca0106_init_chip(chip, 0);
1602
1603 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
1604 if (err < 0) {
1536 snd_ca0106_free(chip); 1605 snd_ca0106_free(chip);
1537 return err; 1606 return err;
1538 } 1607 }
@@ -1629,7 +1698,7 @@ static int __devinit snd_ca0106_probe(struct pci_dev *pci,
1629 static int dev; 1698 static int dev;
1630 struct snd_card *card; 1699 struct snd_card *card;
1631 struct snd_ca0106 *chip; 1700 struct snd_ca0106 *chip;
1632 int err; 1701 int i, err;
1633 1702
1634 if (dev >= SNDRV_CARDS) 1703 if (dev >= SNDRV_CARDS)
1635 return -ENODEV; 1704 return -ENODEV;
@@ -1642,44 +1711,31 @@ static int __devinit snd_ca0106_probe(struct pci_dev *pci,
1642 if (card == NULL) 1711 if (card == NULL)
1643 return -ENOMEM; 1712 return -ENOMEM;
1644 1713
1645 if ((err = snd_ca0106_create(dev, card, pci, &chip)) < 0) { 1714 err = snd_ca0106_create(dev, card, pci, &chip);
1646 snd_card_free(card); 1715 if (err < 0)
1647 return err; 1716 goto error;
1648 } 1717 card->private_data = chip;
1649 1718
1650 if ((err = snd_ca0106_pcm(chip, 0, NULL)) < 0) { 1719 for (i = 0; i < 4; i++) {
1651 snd_card_free(card); 1720 err = snd_ca0106_pcm(chip, i);
1652 return err; 1721 if (err < 0)
1653 } 1722 goto error;
1654 if ((err = snd_ca0106_pcm(chip, 1, NULL)) < 0) {
1655 snd_card_free(card);
1656 return err;
1657 }
1658 if ((err = snd_ca0106_pcm(chip, 2, NULL)) < 0) {
1659 snd_card_free(card);
1660 return err;
1661 }
1662 if ((err = snd_ca0106_pcm(chip, 3, NULL)) < 0) {
1663 snd_card_free(card);
1664 return err;
1665 }
1666 if (chip->details->ac97 == 1) { /* The SB0410 and SB0413 do not have an AC97 chip. */
1667 if ((err = snd_ca0106_ac97(chip)) < 0) {
1668 snd_card_free(card);
1669 return err;
1670 }
1671 } 1723 }
1672 if ((err = snd_ca0106_mixer(chip)) < 0) { 1724
1673 snd_card_free(card); 1725 if (chip->details->ac97 == 1) {
1674 return err; 1726 /* The SB0410 and SB0413 do not have an AC97 chip. */
1727 err = snd_ca0106_ac97(chip);
1728 if (err < 0)
1729 goto error;
1675 } 1730 }
1731 err = snd_ca0106_mixer(chip);
1732 if (err < 0)
1733 goto error;
1676 1734
1677 snd_printdd("ca0106: probe for MIDI channel A ..."); 1735 snd_printdd("ca0106: probe for MIDI channel A ...");
1678 if ((err = snd_ca0106_midi(chip,CA0106_MIDI_CHAN_A)) < 0) { 1736 err = snd_ca0106_midi(chip, CA0106_MIDI_CHAN_A);
1679 snd_card_free(card); 1737 if (err < 0)
1680 snd_printdd(" failed, err=0x%x\n",err); 1738 goto error;
1681 return err;
1682 }
1683 snd_printdd(" done.\n"); 1739 snd_printdd(" done.\n");
1684 1740
1685#ifdef CONFIG_PROC_FS 1741#ifdef CONFIG_PROC_FS
@@ -1688,14 +1744,17 @@ static int __devinit snd_ca0106_probe(struct pci_dev *pci,
1688 1744
1689 snd_card_set_dev(card, &pci->dev); 1745 snd_card_set_dev(card, &pci->dev);
1690 1746
1691 if ((err = snd_card_register(card)) < 0) { 1747 err = snd_card_register(card);
1692 snd_card_free(card); 1748 if (err < 0)
1693 return err; 1749 goto error;
1694 }
1695 1750
1696 pci_set_drvdata(pci, card); 1751 pci_set_drvdata(pci, card);
1697 dev++; 1752 dev++;
1698 return 0; 1753 return 0;
1754
1755 error:
1756 snd_card_free(card);
1757 return err;
1699} 1758}
1700 1759
1701static void __devexit snd_ca0106_remove(struct pci_dev *pci) 1760static void __devexit snd_ca0106_remove(struct pci_dev *pci)
@@ -1704,6 +1763,59 @@ static void __devexit snd_ca0106_remove(struct pci_dev *pci)
1704 pci_set_drvdata(pci, NULL); 1763 pci_set_drvdata(pci, NULL);
1705} 1764}
1706 1765
1766#ifdef CONFIG_PM
1767static int snd_ca0106_suspend(struct pci_dev *pci, pm_message_t state)
1768{
1769 struct snd_card *card = pci_get_drvdata(pci);
1770 struct snd_ca0106 *chip = card->private_data;
1771 int i;
1772
1773 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
1774 for (i = 0; i < 4; i++)
1775 snd_pcm_suspend_all(chip->pcm[i]);
1776 if (chip->details->ac97)
1777 snd_ac97_suspend(chip->ac97);
1778 snd_ca0106_mixer_suspend(chip);
1779
1780 ca0106_stop_chip(chip);
1781
1782 pci_disable_device(pci);
1783 pci_save_state(pci);
1784 pci_set_power_state(pci, pci_choose_state(pci, state));
1785 return 0;
1786}
1787
1788static int snd_ca0106_resume(struct pci_dev *pci)
1789{
1790 struct snd_card *card = pci_get_drvdata(pci);
1791 struct snd_ca0106 *chip = card->private_data;
1792 int i;
1793
1794 pci_set_power_state(pci, PCI_D0);
1795 pci_restore_state(pci);
1796
1797 if (pci_enable_device(pci) < 0) {
1798 snd_card_disconnect(card);
1799 return -EIO;
1800 }
1801
1802 pci_set_master(pci);
1803
1804 ca0106_init_chip(chip, 1);
1805
1806 if (chip->details->ac97)
1807 snd_ac97_resume(chip->ac97);
1808 snd_ca0106_mixer_resume(chip);
1809 if (chip->details->spi_dac) {
1810 for (i = 0; i < ARRAY_SIZE(chip->spi_dac_reg); i++)
1811 snd_ca0106_spi_write(chip, chip->spi_dac_reg[i]);
1812 }
1813
1814 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
1815 return 0;
1816}
1817#endif
1818
1707// PCI IDs 1819// PCI IDs
1708static struct pci_device_id snd_ca0106_ids[] = { 1820static struct pci_device_id snd_ca0106_ids[] = {
1709 { 0x1102, 0x0007, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* Audigy LS or Live 24bit */ 1821 { 0x1102, 0x0007, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* Audigy LS or Live 24bit */
@@ -1717,6 +1829,10 @@ static struct pci_driver driver = {
1717 .id_table = snd_ca0106_ids, 1829 .id_table = snd_ca0106_ids,
1718 .probe = snd_ca0106_probe, 1830 .probe = snd_ca0106_probe,
1719 .remove = __devexit_p(snd_ca0106_remove), 1831 .remove = __devexit_p(snd_ca0106_remove),
1832#ifdef CONFIG_PM
1833 .suspend = snd_ca0106_suspend,
1834 .resume = snd_ca0106_resume,
1835#endif
1720}; 1836};
1721 1837
1722// initialization of the module 1838// initialization of the module
diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c
index 3025ed1b6e1e..ad2888705d2a 100644
--- a/sound/pci/ca0106/ca0106_mixer.c
+++ b/sound/pci/ca0106/ca0106_mixer.c
@@ -75,6 +75,84 @@
75 75
76#include "ca0106.h" 76#include "ca0106.h"
77 77
78static void ca0106_spdif_enable(struct snd_ca0106 *emu)
79{
80 unsigned int val;
81
82 if (emu->spdif_enable) {
83 /* Digital */
84 snd_ca0106_ptr_write(emu, SPDIF_SELECT1, 0, 0xf);
85 snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x0b000000);
86 val = snd_ca0106_ptr_read(emu, CAPTURE_CONTROL, 0) & ~0x1000;
87 snd_ca0106_ptr_write(emu, CAPTURE_CONTROL, 0, val);
88 val = inl(emu->port + GPIO) & ~0x101;
89 outl(val, emu->port + GPIO);
90
91 } else {
92 /* Analog */
93 snd_ca0106_ptr_write(emu, SPDIF_SELECT1, 0, 0xf);
94 snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x000f0000);
95 val = snd_ca0106_ptr_read(emu, CAPTURE_CONTROL, 0) | 0x1000;
96 snd_ca0106_ptr_write(emu, CAPTURE_CONTROL, 0, val);
97 val = inl(emu->port + GPIO) | 0x101;
98 outl(val, emu->port + GPIO);
99 }
100}
101
102static void ca0106_set_capture_source(struct snd_ca0106 *emu)
103{
104 unsigned int val = emu->capture_source;
105 unsigned int source, mask;
106 source = (val << 28) | (val << 24) | (val << 20) | (val << 16);
107 mask = snd_ca0106_ptr_read(emu, CAPTURE_SOURCE, 0) & 0xffff;
108 snd_ca0106_ptr_write(emu, CAPTURE_SOURCE, 0, source | mask);
109}
110
111static void ca0106_set_i2c_capture_source(struct snd_ca0106 *emu,
112 unsigned int val, int force)
113{
114 unsigned int ngain, ogain;
115 u32 source;
116
117 snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */
118 ngain = emu->i2c_capture_volume[val][0]; /* Left */
119 ogain = emu->i2c_capture_volume[emu->i2c_capture_source][0]; /* Left */
120 if (force || ngain != ogain)
121 snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCL, ngain & 0xff);
122 ngain = emu->i2c_capture_volume[val][1]; /* Right */
123 ogain = emu->i2c_capture_volume[emu->i2c_capture_source][1]; /* Right */
124 if (force || ngain != ogain)
125 snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCR, ngain & 0xff);
126 source = 1 << val;
127 snd_ca0106_i2c_write(emu, ADC_MUX, source); /* Set source */
128 emu->i2c_capture_source = val;
129}
130
131static void ca0106_set_capture_mic_line_in(struct snd_ca0106 *emu)
132{
133 u32 tmp;
134
135 if (emu->capture_mic_line_in) {
136 /* snd_ca0106_i2c_write(emu, ADC_MUX, 0); */ /* Mute input */
137 tmp = inl(emu->port+GPIO) & ~0x400;
138 tmp = tmp | 0x400;
139 outl(tmp, emu->port+GPIO);
140 /* snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_MIC); */
141 } else {
142 /* snd_ca0106_i2c_write(emu, ADC_MUX, 0); */ /* Mute input */
143 tmp = inl(emu->port+GPIO) & ~0x400;
144 outl(tmp, emu->port+GPIO);
145 /* snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_LINEIN); */
146 }
147}
148
149static void ca0106_set_spdif_bits(struct snd_ca0106 *emu, int idx)
150{
151 snd_ca0106_ptr_write(emu, SPCS0 + idx, 0, emu->spdif_str_bits[idx]);
152}
153
154/*
155 */
78static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale1, -5175, 25, 1); 156static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale1, -5175, 25, 1);
79static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale2, -10350, 50, 1); 157static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale2, -10350, 50, 1);
80 158
@@ -95,30 +173,12 @@ static int snd_ca0106_shared_spdif_put(struct snd_kcontrol *kcontrol,
95 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol); 173 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
96 unsigned int val; 174 unsigned int val;
97 int change = 0; 175 int change = 0;
98 u32 mask;
99 176
100 val = !!ucontrol->value.integer.value[0]; 177 val = !!ucontrol->value.integer.value[0];
101 change = (emu->spdif_enable != val); 178 change = (emu->spdif_enable != val);
102 if (change) { 179 if (change) {
103 emu->spdif_enable = val; 180 emu->spdif_enable = val;
104 if (val) { 181 ca0106_spdif_enable(emu);
105 /* Digital */
106 snd_ca0106_ptr_write(emu, SPDIF_SELECT1, 0, 0xf);
107 snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x0b000000);
108 snd_ca0106_ptr_write(emu, CAPTURE_CONTROL, 0,
109 snd_ca0106_ptr_read(emu, CAPTURE_CONTROL, 0) & ~0x1000);
110 mask = inl(emu->port + GPIO) & ~0x101;
111 outl(mask, emu->port + GPIO);
112
113 } else {
114 /* Analog */
115 snd_ca0106_ptr_write(emu, SPDIF_SELECT1, 0, 0xf);
116 snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x000f0000);
117 snd_ca0106_ptr_write(emu, CAPTURE_CONTROL, 0,
118 snd_ca0106_ptr_read(emu, CAPTURE_CONTROL, 0) | 0x1000);
119 mask = inl(emu->port + GPIO) | 0x101;
120 outl(mask, emu->port + GPIO);
121 }
122 } 182 }
123 return change; 183 return change;
124} 184}
@@ -154,8 +214,6 @@ static int snd_ca0106_capture_source_put(struct snd_kcontrol *kcontrol,
154 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol); 214 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
155 unsigned int val; 215 unsigned int val;
156 int change = 0; 216 int change = 0;
157 u32 mask;
158 u32 source;
159 217
160 val = ucontrol->value.enumerated.item[0] ; 218 val = ucontrol->value.enumerated.item[0] ;
161 if (val >= 6) 219 if (val >= 6)
@@ -163,9 +221,7 @@ static int snd_ca0106_capture_source_put(struct snd_kcontrol *kcontrol,
163 change = (emu->capture_source != val); 221 change = (emu->capture_source != val);
164 if (change) { 222 if (change) {
165 emu->capture_source = val; 223 emu->capture_source = val;
166 source = (val << 28) | (val << 24) | (val << 20) | (val << 16); 224 ca0106_set_capture_source(emu);
167 mask = snd_ca0106_ptr_read(emu, CAPTURE_SOURCE, 0) & 0xffff;
168 snd_ca0106_ptr_write(emu, CAPTURE_SOURCE, 0, source | mask);
169 } 225 }
170 return change; 226 return change;
171} 227}
@@ -200,9 +256,7 @@ static int snd_ca0106_i2c_capture_source_put(struct snd_kcontrol *kcontrol,
200{ 256{
201 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol); 257 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
202 unsigned int source_id; 258 unsigned int source_id;
203 unsigned int ngain, ogain;
204 int change = 0; 259 int change = 0;
205 u32 source;
206 /* If the capture source has changed, 260 /* If the capture source has changed,
207 * update the capture volume from the cached value 261 * update the capture volume from the cached value
208 * for the particular source. 262 * for the particular source.
@@ -212,18 +266,7 @@ static int snd_ca0106_i2c_capture_source_put(struct snd_kcontrol *kcontrol,
212 return -EINVAL; 266 return -EINVAL;
213 change = (emu->i2c_capture_source != source_id); 267 change = (emu->i2c_capture_source != source_id);
214 if (change) { 268 if (change) {
215 snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */ 269 ca0106_set_i2c_capture_source(emu, source_id, 0);
216 ngain = emu->i2c_capture_volume[source_id][0]; /* Left */
217 ogain = emu->i2c_capture_volume[emu->i2c_capture_source][0]; /* Left */
218 if (ngain != ogain)
219 snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCL, ((ngain) & 0xff));
220 ngain = emu->i2c_capture_volume[source_id][1]; /* Left */
221 ogain = emu->i2c_capture_volume[emu->i2c_capture_source][1]; /* Left */
222 if (ngain != ogain)
223 snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCR, ((ngain) & 0xff));
224 source = 1 << source_id;
225 snd_ca0106_i2c_write(emu, ADC_MUX, source); /* Set source */
226 emu->i2c_capture_source = source_id;
227 } 270 }
228 return change; 271 return change;
229} 272}
@@ -271,7 +314,6 @@ static int snd_ca0106_capture_mic_line_in_put(struct snd_kcontrol *kcontrol,
271 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol); 314 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
272 unsigned int val; 315 unsigned int val;
273 int change = 0; 316 int change = 0;
274 u32 tmp;
275 317
276 val = ucontrol->value.enumerated.item[0] ; 318 val = ucontrol->value.enumerated.item[0] ;
277 if (val > 1) 319 if (val > 1)
@@ -279,18 +321,7 @@ static int snd_ca0106_capture_mic_line_in_put(struct snd_kcontrol *kcontrol,
279 change = (emu->capture_mic_line_in != val); 321 change = (emu->capture_mic_line_in != val);
280 if (change) { 322 if (change) {
281 emu->capture_mic_line_in = val; 323 emu->capture_mic_line_in = val;
282 if (val) { 324 ca0106_set_capture_mic_line_in(emu);
283 //snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */
284 tmp = inl(emu->port+GPIO) & ~0x400;
285 tmp = tmp | 0x400;
286 outl(tmp, emu->port+GPIO);
287 //snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_MIC);
288 } else {
289 //snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */
290 tmp = inl(emu->port+GPIO) & ~0x400;
291 outl(tmp, emu->port+GPIO);
292 //snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_LINEIN);
293 }
294 } 325 }
295 return change; 326 return change;
296} 327}
@@ -322,16 +353,33 @@ static int snd_ca0106_spdif_info(struct snd_kcontrol *kcontrol,
322 return 0; 353 return 0;
323} 354}
324 355
325static int snd_ca0106_spdif_get(struct snd_kcontrol *kcontrol, 356static void decode_spdif_bits(unsigned char *status, unsigned int bits)
357{
358 status[0] = (bits >> 0) & 0xff;
359 status[1] = (bits >> 8) & 0xff;
360 status[2] = (bits >> 16) & 0xff;
361 status[3] = (bits >> 24) & 0xff;
362}
363
364static int snd_ca0106_spdif_get_default(struct snd_kcontrol *kcontrol,
326 struct snd_ctl_elem_value *ucontrol) 365 struct snd_ctl_elem_value *ucontrol)
327{ 366{
328 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol); 367 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
329 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 368 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
330 369
331 ucontrol->value.iec958.status[0] = (emu->spdif_bits[idx] >> 0) & 0xff; 370 decode_spdif_bits(ucontrol->value.iec958.status,
332 ucontrol->value.iec958.status[1] = (emu->spdif_bits[idx] >> 8) & 0xff; 371 emu->spdif_bits[idx]);
333 ucontrol->value.iec958.status[2] = (emu->spdif_bits[idx] >> 16) & 0xff; 372 return 0;
334 ucontrol->value.iec958.status[3] = (emu->spdif_bits[idx] >> 24) & 0xff; 373}
374
375static int snd_ca0106_spdif_get_stream(struct snd_kcontrol *kcontrol,
376 struct snd_ctl_elem_value *ucontrol)
377{
378 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
379 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
380
381 decode_spdif_bits(ucontrol->value.iec958.status,
382 emu->spdif_str_bits[idx]);
335 return 0; 383 return 0;
336} 384}
337 385
@@ -345,24 +393,48 @@ static int snd_ca0106_spdif_get_mask(struct snd_kcontrol *kcontrol,
345 return 0; 393 return 0;
346} 394}
347 395
348static int snd_ca0106_spdif_put(struct snd_kcontrol *kcontrol, 396static unsigned int encode_spdif_bits(unsigned char *status)
397{
398 return ((unsigned int)status[0] << 0) |
399 ((unsigned int)status[1] << 8) |
400 ((unsigned int)status[2] << 16) |
401 ((unsigned int)status[3] << 24);
402}
403
404static int snd_ca0106_spdif_put_default(struct snd_kcontrol *kcontrol,
349 struct snd_ctl_elem_value *ucontrol) 405 struct snd_ctl_elem_value *ucontrol)
350{ 406{
351 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol); 407 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
352 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 408 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
353 int change;
354 unsigned int val; 409 unsigned int val;
355 410
356 val = (ucontrol->value.iec958.status[0] << 0) | 411 val = encode_spdif_bits(ucontrol->value.iec958.status);
357 (ucontrol->value.iec958.status[1] << 8) | 412 if (val != emu->spdif_bits[idx]) {
358 (ucontrol->value.iec958.status[2] << 16) |
359 (ucontrol->value.iec958.status[3] << 24);
360 change = val != emu->spdif_bits[idx];
361 if (change) {
362 snd_ca0106_ptr_write(emu, SPCS0 + idx, 0, val);
363 emu->spdif_bits[idx] = val; 413 emu->spdif_bits[idx] = val;
414 /* FIXME: this isn't safe, but needed to keep the compatibility
415 * with older alsa-lib config
416 */
417 emu->spdif_str_bits[idx] = val;
418 ca0106_set_spdif_bits(emu, idx);
419 return 1;
364 } 420 }
365 return change; 421 return 0;
422}
423
424static int snd_ca0106_spdif_put_stream(struct snd_kcontrol *kcontrol,
425 struct snd_ctl_elem_value *ucontrol)
426{
427 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
428 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
429 unsigned int val;
430
431 val = encode_spdif_bits(ucontrol->value.iec958.status);
432 if (val != emu->spdif_str_bits[idx]) {
433 emu->spdif_str_bits[idx] = val;
434 ca0106_set_spdif_bits(emu, idx);
435 return 1;
436 }
437 return 0;
366} 438}
367 439
368static int snd_ca0106_volume_info(struct snd_kcontrol *kcontrol, 440static int snd_ca0106_volume_info(struct snd_kcontrol *kcontrol,
@@ -573,8 +645,16 @@ static struct snd_kcontrol_new snd_ca0106_volume_ctls[] __devinitdata = {
573 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), 645 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
574 .count = 4, 646 .count = 4,
575 .info = snd_ca0106_spdif_info, 647 .info = snd_ca0106_spdif_info,
576 .get = snd_ca0106_spdif_get, 648 .get = snd_ca0106_spdif_get_default,
577 .put = snd_ca0106_spdif_put 649 .put = snd_ca0106_spdif_put_default
650 },
651 {
652 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
653 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
654 .count = 4,
655 .info = snd_ca0106_spdif_info,
656 .get = snd_ca0106_spdif_get_stream,
657 .put = snd_ca0106_spdif_put_stream
578 }, 658 },
579}; 659};
580 660
@@ -773,3 +853,50 @@ int __devinit snd_ca0106_mixer(struct snd_ca0106 *emu)
773 return 0; 853 return 0;
774} 854}
775 855
856#ifdef CONFIG_PM
857struct ca0106_vol_tbl {
858 unsigned int channel_id;
859 unsigned int reg;
860};
861
862static struct ca0106_vol_tbl saved_volumes[NUM_SAVED_VOLUMES] = {
863 { CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME2 },
864 { CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME2 },
865 { CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME2 },
866 { CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME2 },
867 { CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME1 },
868 { CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME1 },
869 { CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME1 },
870 { CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME1 },
871 { 1, CAPTURE_CONTROL },
872};
873
874void snd_ca0106_mixer_suspend(struct snd_ca0106 *chip)
875{
876 int i;
877
878 /* save volumes */
879 for (i = 0; i < NUM_SAVED_VOLUMES; i++)
880 chip->saved_vol[i] =
881 snd_ca0106_ptr_read(chip, saved_volumes[i].reg,
882 saved_volumes[i].channel_id);
883}
884
885void snd_ca0106_mixer_resume(struct snd_ca0106 *chip)
886{
887 int i;
888
889 for (i = 0; i < NUM_SAVED_VOLUMES; i++)
890 snd_ca0106_ptr_write(chip, saved_volumes[i].reg,
891 saved_volumes[i].channel_id,
892 chip->saved_vol[i]);
893
894 ca0106_spdif_enable(chip);
895 ca0106_set_capture_source(chip);
896 ca0106_set_i2c_capture_source(chip, chip->i2c_capture_source, 1);
897 for (i = 0; i < 4; i++)
898 ca0106_set_spdif_bits(chip, i);
899 if (chip->details->i2c_adc)
900 ca0106_set_capture_mic_line_in(chip);
901}
902#endif /* CONFIG_PM */
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
index fb6dc3980257..8ab07aa63652 100644
--- a/sound/pci/cs46xx/cs46xx_lib.c
+++ b/sound/pci/cs46xx/cs46xx_lib.c
@@ -3640,7 +3640,10 @@ int snd_cs46xx_resume(struct pci_dev *pci)
3640{ 3640{
3641 struct snd_card *card = pci_get_drvdata(pci); 3641 struct snd_card *card = pci_get_drvdata(pci);
3642 struct snd_cs46xx *chip = card->private_data; 3642 struct snd_cs46xx *chip = card->private_data;
3643 int i, amp_saved; 3643 int amp_saved;
3644#ifdef CONFIG_SND_CS46XX_NEW_DSP
3645 int i;
3646#endif
3644 3647
3645 pci_set_power_state(pci, PCI_D0); 3648 pci_set_power_state(pci, PCI_D0);
3646 pci_restore_state(pci); 3649 pci_restore_state(pci);
diff --git a/sound/pci/cs5535audio/Makefile b/sound/pci/cs5535audio/Makefile
index bb3d57e6a3cb..fda7a94c992f 100644
--- a/sound/pci/cs5535audio/Makefile
+++ b/sound/pci/cs5535audio/Makefile
@@ -4,6 +4,9 @@
4 4
5snd-cs5535audio-y := cs5535audio.o cs5535audio_pcm.o 5snd-cs5535audio-y := cs5535audio.o cs5535audio_pcm.o
6snd-cs5535audio-$(CONFIG_PM) += cs5535audio_pm.o 6snd-cs5535audio-$(CONFIG_PM) += cs5535audio_pm.o
7ifdef CONFIG_MGEODE_LX
8snd-cs5535audio-$(CONFIG_OLPC) += cs5535audio_olpc.o
9endif
7 10
8# Toplevel Module Dependency 11# Toplevel Module Dependency
9obj-$(CONFIG_SND_CS5535AUDIO) += snd-cs5535audio.o 12obj-$(CONFIG_SND_CS5535AUDIO) += snd-cs5535audio.o
diff --git a/sound/pci/cs5535audio/cs5535audio.c b/sound/pci/cs5535audio/cs5535audio.c
index 1d8b16052535..826e6dec2e97 100644
--- a/sound/pci/cs5535audio/cs5535audio.c
+++ b/sound/pci/cs5535audio/cs5535audio.c
@@ -159,10 +159,14 @@ static int __devinit snd_cs5535audio_mixer(struct cs5535audio *cs5535au)
159 return err; 159 return err;
160 160
161 memset(&ac97, 0, sizeof(ac97)); 161 memset(&ac97, 0, sizeof(ac97));
162 ac97.scaps = AC97_SCAP_AUDIO|AC97_SCAP_SKIP_MODEM; 162 ac97.scaps = AC97_SCAP_AUDIO | AC97_SCAP_SKIP_MODEM
163 | AC97_SCAP_POWER_SAVE;
163 ac97.private_data = cs5535au; 164 ac97.private_data = cs5535au;
164 ac97.pci = cs5535au->pci; 165 ac97.pci = cs5535au->pci;
165 166
167 /* set any OLPC-specific scaps */
168 olpc_prequirks(card, &ac97);
169
166 if ((err = snd_ac97_mixer(pbus, &ac97, &cs5535au->ac97)) < 0) { 170 if ((err = snd_ac97_mixer(pbus, &ac97, &cs5535au->ac97)) < 0) {
167 snd_printk(KERN_ERR "mixer failed\n"); 171 snd_printk(KERN_ERR "mixer failed\n");
168 return err; 172 return err;
@@ -170,6 +174,12 @@ static int __devinit snd_cs5535audio_mixer(struct cs5535audio *cs5535au)
170 174
171 snd_ac97_tune_hardware(cs5535au->ac97, ac97_quirks, ac97_quirk); 175 snd_ac97_tune_hardware(cs5535au->ac97, ac97_quirks, ac97_quirk);
172 176
177 err = olpc_quirks(card, cs5535au->ac97);
178 if (err < 0) {
179 snd_printk(KERN_ERR "olpc quirks failed\n");
180 return err;
181 }
182
173 return 0; 183 return 0;
174} 184}
175 185
diff --git a/sound/pci/cs5535audio/cs5535audio.h b/sound/pci/cs5535audio/cs5535audio.h
index 66bae7664193..7a298ac662e3 100644
--- a/sound/pci/cs5535audio/cs5535audio.h
+++ b/sound/pci/cs5535audio/cs5535audio.h
@@ -78,6 +78,7 @@ struct cs5535audio_dma {
78 unsigned int buf_addr, buf_bytes; 78 unsigned int buf_addr, buf_bytes;
79 unsigned int period_bytes, periods; 79 unsigned int period_bytes, periods;
80 u32 saved_prd; 80 u32 saved_prd;
81 int pcm_open_flag;
81}; 82};
82 83
83struct cs5535audio { 84struct cs5535audio {
@@ -93,8 +94,46 @@ struct cs5535audio {
93 struct cs5535audio_dma dmas[NUM_CS5535AUDIO_DMAS]; 94 struct cs5535audio_dma dmas[NUM_CS5535AUDIO_DMAS];
94}; 95};
95 96
97#ifdef CONFIG_PM
96int snd_cs5535audio_suspend(struct pci_dev *pci, pm_message_t state); 98int snd_cs5535audio_suspend(struct pci_dev *pci, pm_message_t state);
97int snd_cs5535audio_resume(struct pci_dev *pci); 99int snd_cs5535audio_resume(struct pci_dev *pci);
100#endif
101
102#if defined(CONFIG_OLPC) && defined(CONFIG_MGEODE_LX)
103void __devinit olpc_prequirks(struct snd_card *card,
104 struct snd_ac97_template *ac97);
105int __devinit olpc_quirks(struct snd_card *card, struct snd_ac97 *ac97);
106void olpc_analog_input(struct snd_ac97 *ac97, int on);
107void olpc_mic_bias(struct snd_ac97 *ac97, int on);
108
109static inline void olpc_capture_open(struct snd_ac97 *ac97)
110{
111 /* default to Analog Input off */
112 olpc_analog_input(ac97, 0);
113 /* enable MIC Bias for recording */
114 olpc_mic_bias(ac97, 1);
115}
116
117static inline void olpc_capture_close(struct snd_ac97 *ac97)
118{
119 /* disable Analog Input */
120 olpc_analog_input(ac97, 0);
121 /* disable the MIC Bias (so the recording LED turns off) */
122 olpc_mic_bias(ac97, 0);
123}
124#else
125static inline void olpc_prequirks(struct snd_card *card,
126 struct snd_ac97_template *ac97) { }
127static inline int olpc_quirks(struct snd_card *card, struct snd_ac97 *ac97)
128{
129 return 0;
130}
131static inline void olpc_analog_input(struct snd_ac97 *ac97, int on) { }
132static inline void olpc_mic_bias(struct snd_ac97 *ac97, int on) { }
133static inline void olpc_capture_open(struct snd_ac97 *ac97) { }
134static inline void olpc_capture_close(struct snd_ac97 *ac97) { }
135#endif
136
98int __devinit snd_cs5535audio_pcm(struct cs5535audio *cs5535audio); 137int __devinit snd_cs5535audio_pcm(struct cs5535audio *cs5535audio);
99 138
100#endif /* __SOUND_CS5535AUDIO_H */ 139#endif /* __SOUND_CS5535AUDIO_H */
diff --git a/sound/pci/cs5535audio/cs5535audio_olpc.c b/sound/pci/cs5535audio/cs5535audio_olpc.c
new file mode 100644
index 000000000000..5c6814335cd7
--- /dev/null
+++ b/sound/pci/cs5535audio/cs5535audio_olpc.c
@@ -0,0 +1,179 @@
1/*
2 * OLPC XO-1 additional sound features
3 *
4 * Copyright © 2006 Jaya Kumar <jayakumar.lkml@gmail.com>
5 * Copyright © 2007-2008 Andres Salomon <dilinger@debian.org>
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 as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12#include <sound/core.h>
13#include <sound/info.h>
14#include <sound/control.h>
15#include <sound/ac97_codec.h>
16
17#include <asm/olpc.h>
18#include "cs5535audio.h"
19
20/*
21 * OLPC has an additional feature on top of the regular AD1888 codec features.
22 * It has an Analog Input mode that is switched into (after disabling the
23 * High Pass Filter) via GPIO. It is supported on B2 and later models.
24 */
25void olpc_analog_input(struct snd_ac97 *ac97, int on)
26{
27 int err;
28
29 if (!machine_is_olpc())
30 return;
31
32 /* update the High Pass Filter (via AC97_AD_TEST2) */
33 err = snd_ac97_update_bits(ac97, AC97_AD_TEST2,
34 1 << AC97_AD_HPFD_SHIFT, on << AC97_AD_HPFD_SHIFT);
35 if (err < 0) {
36 snd_printk(KERN_ERR "setting High Pass Filter - %d\n", err);
37 return;
38 }
39
40 /* set Analog Input through GPIO */
41 if (on)
42 geode_gpio_set(OLPC_GPIO_MIC_AC, GPIO_OUTPUT_VAL);
43 else
44 geode_gpio_clear(OLPC_GPIO_MIC_AC, GPIO_OUTPUT_VAL);
45}
46
47/*
48 * OLPC XO-1's V_REFOUT is a mic bias enable.
49 */
50void olpc_mic_bias(struct snd_ac97 *ac97, int on)
51{
52 int err;
53
54 if (!machine_is_olpc())
55 return;
56
57 on = on ? 0 : 1;
58 err = snd_ac97_update_bits(ac97, AC97_AD_MISC,
59 1 << AC97_AD_VREFD_SHIFT, on << AC97_AD_VREFD_SHIFT);
60 if (err < 0)
61 snd_printk(KERN_ERR "setting MIC Bias - %d\n", err);
62}
63
64static int olpc_dc_info(struct snd_kcontrol *kctl,
65 struct snd_ctl_elem_info *uinfo)
66{
67 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
68 uinfo->count = 1;
69 uinfo->value.integer.min = 0;
70 uinfo->value.integer.max = 1;
71 return 0;
72}
73
74static int olpc_dc_get(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *v)
75{
76 v->value.integer.value[0] = geode_gpio_isset(OLPC_GPIO_MIC_AC,
77 GPIO_OUTPUT_VAL);
78 return 0;
79}
80
81static int olpc_dc_put(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *v)
82{
83 struct cs5535audio *cs5535au = snd_kcontrol_chip(kctl);
84
85 olpc_analog_input(cs5535au->ac97, v->value.integer.value[0]);
86 return 1;
87}
88
89static int olpc_mic_info(struct snd_kcontrol *kctl,
90 struct snd_ctl_elem_info *uinfo)
91{
92 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
93 uinfo->count = 1;
94 uinfo->value.integer.min = 0;
95 uinfo->value.integer.max = 1;
96 return 0;
97}
98
99static int olpc_mic_get(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *v)
100{
101 struct cs5535audio *cs5535au = snd_kcontrol_chip(kctl);
102 struct snd_ac97 *ac97 = cs5535au->ac97;
103 int i;
104
105 i = (snd_ac97_read(ac97, AC97_AD_MISC) >> AC97_AD_VREFD_SHIFT) & 0x1;
106 v->value.integer.value[0] = i ? 0 : 1;
107 return 0;
108}
109
110static int olpc_mic_put(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *v)
111{
112 struct cs5535audio *cs5535au = snd_kcontrol_chip(kctl);
113
114 olpc_mic_bias(cs5535au->ac97, v->value.integer.value[0]);
115 return 1;
116}
117
118static struct snd_kcontrol_new olpc_cs5535audio_ctls[] __devinitdata = {
119{
120 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
121 .name = "DC Mode Enable",
122 .info = olpc_dc_info,
123 .get = olpc_dc_get,
124 .put = olpc_dc_put,
125 .private_value = 0,
126},
127{
128 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
129 .name = "MIC Bias Enable",
130 .info = olpc_mic_info,
131 .get = olpc_mic_get,
132 .put = olpc_mic_put,
133 .private_value = 0,
134},
135};
136
137void __devinit olpc_prequirks(struct snd_card *card,
138 struct snd_ac97_template *ac97)
139{
140 if (!machine_is_olpc())
141 return;
142
143 /* invert EAPD if on an OLPC B3 or higher */
144 if (olpc_board_at_least(olpc_board_pre(0xb3)))
145 ac97->scaps |= AC97_SCAP_INV_EAPD;
146}
147
148int __devinit olpc_quirks(struct snd_card *card, struct snd_ac97 *ac97)
149{
150 struct snd_ctl_elem_id elem;
151 int i, err;
152
153 if (!machine_is_olpc())
154 return 0;
155
156 /* drop the original AD1888 HPF control */
157 memset(&elem, 0, sizeof(elem));
158 elem.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
159 strncpy(elem.name, "High Pass Filter Enable", sizeof(elem.name));
160 snd_ctl_remove_id(card, &elem);
161
162 /* drop the original V_REFOUT control */
163 memset(&elem, 0, sizeof(elem));
164 elem.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
165 strncpy(elem.name, "V_REFOUT Enable", sizeof(elem.name));
166 snd_ctl_remove_id(card, &elem);
167
168 /* add the OLPC-specific controls */
169 for (i = 0; i < ARRAY_SIZE(olpc_cs5535audio_ctls); i++) {
170 err = snd_ctl_add(card, snd_ctl_new1(&olpc_cs5535audio_ctls[i],
171 ac97->private_data));
172 if (err < 0)
173 return err;
174 }
175
176 /* turn off the mic by default */
177 olpc_mic_bias(ac97, 0);
178 return 0;
179}
diff --git a/sound/pci/cs5535audio/cs5535audio_pcm.c b/sound/pci/cs5535audio/cs5535audio_pcm.c
index cdcda87116c3..0f48a871f17b 100644
--- a/sound/pci/cs5535audio/cs5535audio_pcm.c
+++ b/sound/pci/cs5535audio/cs5535audio_pcm.c
@@ -260,6 +260,9 @@ static int snd_cs5535audio_hw_params(struct snd_pcm_substream *substream,
260 err = cs5535audio_build_dma_packets(cs5535au, dma, substream, 260 err = cs5535audio_build_dma_packets(cs5535au, dma, substream,
261 params_periods(hw_params), 261 params_periods(hw_params),
262 params_period_bytes(hw_params)); 262 params_period_bytes(hw_params));
263 if (!err)
264 dma->pcm_open_flag = 1;
265
263 return err; 266 return err;
264} 267}
265 268
@@ -268,6 +271,15 @@ static int snd_cs5535audio_hw_free(struct snd_pcm_substream *substream)
268 struct cs5535audio *cs5535au = snd_pcm_substream_chip(substream); 271 struct cs5535audio *cs5535au = snd_pcm_substream_chip(substream);
269 struct cs5535audio_dma *dma = substream->runtime->private_data; 272 struct cs5535audio_dma *dma = substream->runtime->private_data;
270 273
274 if (dma->pcm_open_flag) {
275 if (substream == cs5535au->playback_substream)
276 snd_ac97_update_power(cs5535au->ac97,
277 AC97_PCM_FRONT_DAC_RATE, 0);
278 else
279 snd_ac97_update_power(cs5535au->ac97,
280 AC97_PCM_LR_ADC_RATE, 0);
281 dma->pcm_open_flag = 0;
282 }
271 cs5535audio_clear_dma_packets(cs5535au, dma, substream); 283 cs5535audio_clear_dma_packets(cs5535au, dma, substream);
272 return snd_pcm_lib_free_pages(substream); 284 return snd_pcm_lib_free_pages(substream);
273} 285}
@@ -351,11 +363,14 @@ static int snd_cs5535audio_capture_open(struct snd_pcm_substream *substream)
351 if ((err = snd_pcm_hw_constraint_integer(runtime, 363 if ((err = snd_pcm_hw_constraint_integer(runtime,
352 SNDRV_PCM_HW_PARAM_PERIODS)) < 0) 364 SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
353 return err; 365 return err;
366 olpc_capture_open(cs5535au->ac97);
354 return 0; 367 return 0;
355} 368}
356 369
357static int snd_cs5535audio_capture_close(struct snd_pcm_substream *substream) 370static int snd_cs5535audio_capture_close(struct snd_pcm_substream *substream)
358{ 371{
372 struct cs5535audio *cs5535au = snd_pcm_substream_chip(substream);
373 olpc_capture_close(cs5535au->ac97);
359 return 0; 374 return 0;
360} 375}
361 376
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
index de5ee8f097f6..7958006a1d66 100644
--- a/sound/pci/emu10k1/emu10k1_main.c
+++ b/sound/pci/emu10k1/emu10k1_main.c
@@ -69,7 +69,7 @@ MODULE_FIRMWARE(EMU1010_NOTEBOOK_FILENAME);
69 * EMU10K1 init / done 69 * EMU10K1 init / done
70 *************************************************************************/ 70 *************************************************************************/
71 71
72void snd_emu10k1_voice_init(struct snd_emu10k1 * emu, int ch) 72void snd_emu10k1_voice_init(struct snd_emu10k1 *emu, int ch)
73{ 73{
74 snd_emu10k1_ptr_write(emu, DCYSUSV, ch, 0); 74 snd_emu10k1_ptr_write(emu, DCYSUSV, ch, 0);
75 snd_emu10k1_ptr_write(emu, IP, ch, 0); 75 snd_emu10k1_ptr_write(emu, IP, ch, 0);
@@ -151,9 +151,9 @@ static unsigned int i2c_adc_init[][2] = {
151 { 0x12, 0x32 }, /* ALC Control 3 */ 151 { 0x12, 0x32 }, /* ALC Control 3 */
152 { 0x13, 0x00 }, /* Noise gate control */ 152 { 0x13, 0x00 }, /* Noise gate control */
153 { 0x14, 0xa6 }, /* Limiter control */ 153 { 0x14, 0xa6 }, /* Limiter control */
154 { 0x15, ADC_MUX_2 }, /* ADC Mixer control. Mic for Audigy 2 ZS Notebook */ 154 { 0x15, ADC_MUX_2 }, /* ADC Mixer control. Mic for A2ZS Notebook */
155}; 155};
156 156
157static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume) 157static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
158{ 158{
159 unsigned int silent_page; 159 unsigned int silent_page;
@@ -161,8 +161,8 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
161 u32 tmp; 161 u32 tmp;
162 162
163 /* disable audio and lock cache */ 163 /* disable audio and lock cache */
164 outl(HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK | HCFG_MUTEBUTTONENABLE, 164 outl(HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK |
165 emu->port + HCFG); 165 HCFG_MUTEBUTTONENABLE, emu->port + HCFG);
166 166
167 /* reset recording buffers */ 167 /* reset recording buffers */
168 snd_emu10k1_ptr_write(emu, MICBS, 0, ADCBS_BUFSIZE_NONE); 168 snd_emu10k1_ptr_write(emu, MICBS, 0, ADCBS_BUFSIZE_NONE);
@@ -179,7 +179,7 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
179 snd_emu10k1_ptr_write(emu, SOLEL, 0, 0); 179 snd_emu10k1_ptr_write(emu, SOLEL, 0, 0);
180 snd_emu10k1_ptr_write(emu, SOLEH, 0, 0); 180 snd_emu10k1_ptr_write(emu, SOLEH, 0, 0);
181 181
182 if (emu->audigy){ 182 if (emu->audigy) {
183 /* set SPDIF bypass mode */ 183 /* set SPDIF bypass mode */
184 snd_emu10k1_ptr_write(emu, SPBYPASS, 0, SPBYPASS_FORMAT); 184 snd_emu10k1_ptr_write(emu, SPBYPASS, 0, SPBYPASS_FORMAT);
185 /* enable rear left + rear right AC97 slots */ 185 /* enable rear left + rear right AC97 slots */
@@ -197,12 +197,12 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
197 197
198 if (emu->card_capabilities->ca0151_chip) { /* audigy2 */ 198 if (emu->card_capabilities->ca0151_chip) { /* audigy2 */
199 /* Hacks for Alice3 to work independent of haP16V driver */ 199 /* Hacks for Alice3 to work independent of haP16V driver */
200 //Setup SRCMulti_I2S SamplingRate 200 /* Setup SRCMulti_I2S SamplingRate */
201 tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0); 201 tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);
202 tmp &= 0xfffff1ff; 202 tmp &= 0xfffff1ff;
203 tmp |= (0x2<<9); 203 tmp |= (0x2<<9);
204 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, 0, tmp); 204 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, 0, tmp);
205 205
206 /* Setup SRCSel (Enable Spdif,I2S SRCMulti) */ 206 /* Setup SRCSel (Enable Spdif,I2S SRCMulti) */
207 snd_emu10k1_ptr20_write(emu, SRCSel, 0, 0x14); 207 snd_emu10k1_ptr20_write(emu, SRCSel, 0, 0x14);
208 /* Setup SRCMulti Input Audio Enable */ 208 /* Setup SRCMulti Input Audio Enable */
@@ -217,7 +217,7 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
217 if (emu->card_capabilities->ca0108_chip) { /* audigy2 Value */ 217 if (emu->card_capabilities->ca0108_chip) { /* audigy2 Value */
218 /* Hacks for Alice3 to work independent of haP16V driver */ 218 /* Hacks for Alice3 to work independent of haP16V driver */
219 snd_printk(KERN_INFO "Audigy2 value: Special config.\n"); 219 snd_printk(KERN_INFO "Audigy2 value: Special config.\n");
220 //Setup SRCMulti_I2S SamplingRate 220 /* Setup SRCMulti_I2S SamplingRate */
221 tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0); 221 tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);
222 tmp &= 0xfffff1ff; 222 tmp &= 0xfffff1ff;
223 tmp |= (0x2<<9); 223 tmp |= (0x2<<9);
@@ -270,13 +270,13 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
270 size = ARRAY_SIZE(i2c_adc_init); 270 size = ARRAY_SIZE(i2c_adc_init);
271 for (n = 0; n < size; n++) 271 for (n = 0; n < size; n++)
272 snd_emu10k1_i2c_write(emu, i2c_adc_init[n][0], i2c_adc_init[n][1]); 272 snd_emu10k1_i2c_write(emu, i2c_adc_init[n][0], i2c_adc_init[n][1]);
273 for (n=0; n < 4; n++) { 273 for (n = 0; n < 4; n++) {
274 emu->i2c_capture_volume[n][0]= 0xcf; 274 emu->i2c_capture_volume[n][0] = 0xcf;
275 emu->i2c_capture_volume[n][1]= 0xcf; 275 emu->i2c_capture_volume[n][1] = 0xcf;
276 } 276 }
277 } 277 }
278 278
279 279
280 snd_emu10k1_ptr_write(emu, PTB, 0, emu->ptb_pages.addr); 280 snd_emu10k1_ptr_write(emu, PTB, 0, emu->ptb_pages.addr);
281 snd_emu10k1_ptr_write(emu, TCB, 0, 0); /* taken from original driver */ 281 snd_emu10k1_ptr_write(emu, TCB, 0, 0); /* taken from original driver */
282 snd_emu10k1_ptr_write(emu, TCBS, 0, 4); /* taken from original driver */ 282 snd_emu10k1_ptr_write(emu, TCBS, 0, 4); /* taken from original driver */
@@ -313,7 +313,7 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
313 (emu->model == 0x21 && emu->revision < 6)) 313 (emu->model == 0x21 && emu->revision < 6))
314 outl(HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE, emu->port + HCFG); 314 outl(HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE, emu->port + HCFG);
315 else 315 else
316 // With on-chip joystick 316 /* With on-chip joystick */
317 outl(HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG); 317 outl(HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG);
318 318
319 if (enable_ir) { /* enable IR for SB Live */ 319 if (enable_ir) { /* enable IR for SB Live */
@@ -335,9 +335,9 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
335 outl(reg | HCFG_GPOUT1 | HCFG_GPOUT2, emu->port + HCFG); 335 outl(reg | HCFG_GPOUT1 | HCFG_GPOUT2, emu->port + HCFG);
336 udelay(100); 336 udelay(100);
337 outl(reg, emu->port + HCFG); 337 outl(reg, emu->port + HCFG);
338 } 338 }
339 } 339 }
340 340
341 if (emu->card_capabilities->emu_model) { 341 if (emu->card_capabilities->emu_model) {
342 ; /* Disable all access to A_IOCFG for the emu1010 */ 342 ; /* Disable all access to A_IOCFG for the emu1010 */
343 } else if (emu->card_capabilities->i2c_adc) { 343 } else if (emu->card_capabilities->i2c_adc) {
@@ -364,7 +364,7 @@ static void snd_emu10k1_audio_enable(struct snd_emu10k1 *emu)
364 ; /* Disable A_IOCFG for Audigy 2 ZS Notebook */ 364 ; /* Disable A_IOCFG for Audigy 2 ZS Notebook */
365 } else if (emu->audigy) { 365 } else if (emu->audigy) {
366 outl(inl(emu->port + A_IOCFG) & ~0x44, emu->port + A_IOCFG); 366 outl(inl(emu->port + A_IOCFG) & ~0x44, emu->port + A_IOCFG);
367 367
368 if (emu->card_capabilities->ca0151_chip) { /* audigy2 */ 368 if (emu->card_capabilities->ca0151_chip) { /* audigy2 */
369 /* Unmute Analog now. Set GPO6 to 1 for Apollo. 369 /* Unmute Analog now. Set GPO6 to 1 for Apollo.
370 * This has to be done after init ALice3 I2SOut beyond 48KHz. 370 * This has to be done after init ALice3 I2SOut beyond 48KHz.
@@ -378,12 +378,12 @@ static void snd_emu10k1_audio_enable(struct snd_emu10k1 *emu)
378 outl(inl(emu->port + A_IOCFG) | 0x0080, emu->port + A_IOCFG); 378 outl(inl(emu->port + A_IOCFG) | 0x0080, emu->port + A_IOCFG);
379 } 379 }
380 } 380 }
381 381
382#if 0 382#if 0
383 { 383 {
384 unsigned int tmp; 384 unsigned int tmp;
385 /* FIXME: the following routine disables LiveDrive-II !! */ 385 /* FIXME: the following routine disables LiveDrive-II !! */
386 // TOSLink detection 386 /* TOSLink detection */
387 emu->tos_link = 0; 387 emu->tos_link = 0;
388 tmp = inl(emu->port + HCFG); 388 tmp = inl(emu->port + HCFG);
389 if (tmp & (HCFG_GPINPUT0 | HCFG_GPINPUT1)) { 389 if (tmp & (HCFG_GPINPUT0 | HCFG_GPINPUT1)) {
@@ -400,7 +400,7 @@ static void snd_emu10k1_audio_enable(struct snd_emu10k1 *emu)
400 snd_emu10k1_intr_enable(emu, INTE_PCIERRORENABLE); 400 snd_emu10k1_intr_enable(emu, INTE_PCIERRORENABLE);
401} 401}
402 402
403int snd_emu10k1_done(struct snd_emu10k1 * emu) 403int snd_emu10k1_done(struct snd_emu10k1 *emu)
404{ 404{
405 int ch; 405 int ch;
406 406
@@ -495,7 +495,7 @@ int snd_emu10k1_done(struct snd_emu10k1 * emu)
495 495
496#define EC_LAST_PROMFILE_ADDR 0x2f 496#define EC_LAST_PROMFILE_ADDR 0x2f
497 497
498#define EC_SERIALNUM_ADDR 0x30 /* First word of serial number. The 498#define EC_SERIALNUM_ADDR 0x30 /* First word of serial number. The
499 * can be up to 30 characters in length 499 * can be up to 30 characters in length
500 * and is stored as a NULL-terminated 500 * and is stored as a NULL-terminated
501 * ASCII string. Any unused bytes must be 501 * ASCII string. Any unused bytes must be
@@ -503,8 +503,8 @@ int snd_emu10k1_done(struct snd_emu10k1 * emu)
503#define EC_CHECKSUM_ADDR 0x3f /* Location at which checksum is stored */ 503#define EC_CHECKSUM_ADDR 0x3f /* Location at which checksum is stored */
504 504
505 505
506/* Most of this stuff is pretty self-evident. According to the hardware 506/* Most of this stuff is pretty self-evident. According to the hardware
507 * dudes, we need to leave the ADCCAL bit low in order to avoid a DC 507 * dudes, we need to leave the ADCCAL bit low in order to avoid a DC
508 * offset problem. Weird. 508 * offset problem. Weird.
509 */ 509 */
510#define EC_RAW_RUN_MODE (EC_DACMUTEN | EC_ADCRSTN | EC_TRIM_MUTEN | \ 510#define EC_RAW_RUN_MODE (EC_DACMUTEN | EC_ADCRSTN | EC_TRIM_MUTEN | \
@@ -523,7 +523,7 @@ int snd_emu10k1_done(struct snd_emu10k1 * emu)
523 * register. 523 * register.
524 */ 524 */
525 525
526static void snd_emu10k1_ecard_write(struct snd_emu10k1 * emu, unsigned int value) 526static void snd_emu10k1_ecard_write(struct snd_emu10k1 *emu, unsigned int value)
527{ 527{
528 unsigned short count; 528 unsigned short count;
529 unsigned int data; 529 unsigned int data;
@@ -561,7 +561,7 @@ static void snd_emu10k1_ecard_write(struct snd_emu10k1 * emu, unsigned int value
561 * channel. 561 * channel.
562 */ 562 */
563 563
564static void snd_emu10k1_ecard_setadcgain(struct snd_emu10k1 * emu, 564static void snd_emu10k1_ecard_setadcgain(struct snd_emu10k1 *emu,
565 unsigned short gain) 565 unsigned short gain)
566{ 566{
567 unsigned int bit; 567 unsigned int bit;
@@ -574,7 +574,7 @@ static void snd_emu10k1_ecard_setadcgain(struct snd_emu10k1 * emu,
574 574
575 for (bit = (1 << 15); bit; bit >>= 1) { 575 for (bit = (1 << 15); bit; bit >>= 1) {
576 unsigned int value; 576 unsigned int value;
577 577
578 value = emu->ecard_ctrl & ~(EC_TRIM_CSN | EC_TRIM_SDATA); 578 value = emu->ecard_ctrl & ~(EC_TRIM_CSN | EC_TRIM_SDATA);
579 579
580 if (gain & bit) 580 if (gain & bit)
@@ -589,7 +589,7 @@ static void snd_emu10k1_ecard_setadcgain(struct snd_emu10k1 * emu,
589 snd_emu10k1_ecard_write(emu, emu->ecard_ctrl); 589 snd_emu10k1_ecard_write(emu, emu->ecard_ctrl);
590} 590}
591 591
592static int snd_emu10k1_ecard_init(struct snd_emu10k1 * emu) 592static int snd_emu10k1_ecard_init(struct snd_emu10k1 *emu)
593{ 593{
594 unsigned int hc_value; 594 unsigned int hc_value;
595 595
@@ -598,7 +598,7 @@ static int snd_emu10k1_ecard_init(struct snd_emu10k1 * emu)
598 EC_SPDIF0_SELECT(EC_DEFAULT_SPDIF0_SEL) | 598 EC_SPDIF0_SELECT(EC_DEFAULT_SPDIF0_SEL) |
599 EC_SPDIF1_SELECT(EC_DEFAULT_SPDIF1_SEL); 599 EC_SPDIF1_SELECT(EC_DEFAULT_SPDIF1_SEL);
600 600
601 /* Step 0: Set the codec type in the hardware control register 601 /* Step 0: Set the codec type in the hardware control register
602 * and enable audio output */ 602 * and enable audio output */
603 hc_value = inl(emu->port + HCFG); 603 hc_value = inl(emu->port + HCFG);
604 outl(hc_value | HCFG_AUDIOENABLE | HCFG_CODECFORMAT_I2S, emu->port + HCFG); 604 outl(hc_value | HCFG_AUDIOENABLE | HCFG_CODECFORMAT_I2S, emu->port + HCFG);
@@ -629,7 +629,7 @@ static int snd_emu10k1_ecard_init(struct snd_emu10k1 * emu)
629 return 0; 629 return 0;
630} 630}
631 631
632static int snd_emu10k1_cardbus_init(struct snd_emu10k1 * emu) 632static int snd_emu10k1_cardbus_init(struct snd_emu10k1 *emu)
633{ 633{
634 unsigned long special_port; 634 unsigned long special_port;
635 unsigned int value; 635 unsigned int value;
@@ -656,7 +656,7 @@ static int snd_emu10k1_cardbus_init(struct snd_emu10k1 * emu)
656 return 0; 656 return 0;
657} 657}
658 658
659static int snd_emu1010_load_firmware(struct snd_emu10k1 * emu, const char * filename) 659static int snd_emu1010_load_firmware(struct snd_emu10k1 *emu, const char *filename)
660{ 660{
661 int err; 661 int err;
662 int n, i; 662 int n, i;
@@ -666,11 +666,12 @@ static int snd_emu1010_load_firmware(struct snd_emu10k1 * emu, const char * file
666 unsigned long flags; 666 unsigned long flags;
667 const struct firmware *fw_entry; 667 const struct firmware *fw_entry;
668 668
669 if ((err = request_firmware(&fw_entry, filename, &emu->pci->dev)) != 0) { 669 err = request_firmware(&fw_entry, filename, &emu->pci->dev);
670 snd_printk(KERN_ERR "firmware: %s not found. Err=%d\n",filename, err); 670 if (err != 0) {
671 snd_printk(KERN_ERR "firmware: %s not found. Err = %d\n", filename, err);
671 return err; 672 return err;
672 } 673 }
673 snd_printk(KERN_INFO "firmware size=0x%zx\n", fw_entry->size); 674 snd_printk(KERN_INFO "firmware size = 0x%zx\n", fw_entry->size);
674 675
675 /* The FPGA is a Xilinx Spartan IIE XC2S50E */ 676 /* The FPGA is a Xilinx Spartan IIE XC2S50E */
676 /* GPIO7 -> FPGA PGMN 677 /* GPIO7 -> FPGA PGMN
@@ -685,13 +686,13 @@ static int snd_emu1010_load_firmware(struct snd_emu10k1 * emu, const char * file
685 outl(0x80, emu->port + A_IOCFG); /* Leave bit 7 set during netlist setup. */ 686 outl(0x80, emu->port + A_IOCFG); /* Leave bit 7 set during netlist setup. */
686 write_post = inl(emu->port + A_IOCFG); 687 write_post = inl(emu->port + A_IOCFG);
687 udelay(100); /* Allow FPGA memory to clean */ 688 udelay(100); /* Allow FPGA memory to clean */
688 for(n = 0; n < fw_entry->size; n++) { 689 for (n = 0; n < fw_entry->size; n++) {
689 value=fw_entry->data[n]; 690 value = fw_entry->data[n];
690 for(i = 0; i < 8; i++) { 691 for (i = 0; i < 8; i++) {
691 reg = 0x80; 692 reg = 0x80;
692 if (value & 0x1) 693 if (value & 0x1)
693 reg = reg | 0x20; 694 reg = reg | 0x20;
694 value = value >> 1; 695 value = value >> 1;
695 outl(reg, emu->port + A_IOCFG); 696 outl(reg, emu->port + A_IOCFG);
696 write_post = inl(emu->port + A_IOCFG); 697 write_post = inl(emu->port + A_IOCFG);
697 outl(reg | 0x40, emu->port + A_IOCFG); 698 outl(reg | 0x40, emu->port + A_IOCFG);
@@ -703,14 +704,14 @@ static int snd_emu1010_load_firmware(struct snd_emu10k1 * emu, const char * file
703 write_post = inl(emu->port + A_IOCFG); 704 write_post = inl(emu->port + A_IOCFG);
704 spin_unlock_irqrestore(&emu->emu_lock, flags); 705 spin_unlock_irqrestore(&emu->emu_lock, flags);
705 706
706 release_firmware(fw_entry); 707 release_firmware(fw_entry);
707 return 0; 708 return 0;
708} 709}
709 710
710static int emu1010_firmware_thread(void *data) 711static int emu1010_firmware_thread(void *data)
711{ 712{
712 struct snd_emu10k1 * emu = data; 713 struct snd_emu10k1 *emu = data;
713 int tmp,tmp2; 714 int tmp, tmp2;
714 int reg; 715 int reg;
715 int err; 716 int err;
716 717
@@ -719,50 +720,50 @@ static int emu1010_firmware_thread(void *data)
719 msleep_interruptible(1000); 720 msleep_interruptible(1000);
720 if (kthread_should_stop()) 721 if (kthread_should_stop())
721 break; 722 break;
722 snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &tmp ); /* IRQ Status */ 723 snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &tmp); /* IRQ Status */
723 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg ); /* OPTIONS: Which cards are attached to the EMU */ 724 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg); /* OPTIONS: Which cards are attached to the EMU */
724 if (reg & EMU_HANA_OPTION_DOCK_OFFLINE) { 725 if (reg & EMU_HANA_OPTION_DOCK_OFFLINE) {
725 /* Audio Dock attached */ 726 /* Audio Dock attached */
726 /* Return to Audio Dock programming mode */ 727 /* Return to Audio Dock programming mode */
727 snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware\n"); 728 snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware\n");
728 snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, EMU_HANA_FPGA_CONFIG_AUDIODOCK ); 729 snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, EMU_HANA_FPGA_CONFIG_AUDIODOCK);
729 if (emu->card_capabilities->emu_model == 730 if (emu->card_capabilities->emu_model ==
730 EMU_MODEL_EMU1010) { 731 EMU_MODEL_EMU1010) {
731 if ((err = snd_emu1010_load_firmware(emu, DOCK_FILENAME)) != 0) { 732 err = snd_emu1010_load_firmware(emu, DOCK_FILENAME);
733 if (err != 0)
732 continue; 734 continue;
733 }
734 } else if (emu->card_capabilities->emu_model == 735 } else if (emu->card_capabilities->emu_model ==
735 EMU_MODEL_EMU1010B) { 736 EMU_MODEL_EMU1010B) {
736 if ((err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME)) != 0) { 737 err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME);
738 if (err != 0)
737 continue; 739 continue;
738 }
739 } else if (emu->card_capabilities->emu_model == 740 } else if (emu->card_capabilities->emu_model ==
740 EMU_MODEL_EMU1616) { 741 EMU_MODEL_EMU1616) {
741 if ((err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME)) != 0) { 742 err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME);
743 if (err != 0)
742 continue; 744 continue;
743 }
744 } 745 }
745 746
746 snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0 ); 747 snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0);
747 snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &reg ); 748 snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &reg);
748 snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_IRQ_STATUS=0x%x\n",reg); 749 snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_IRQ_STATUS = 0x%x\n", reg);
749 /* ID, should read & 0x7f = 0x55 when FPGA programmed. */ 750 /* ID, should read & 0x7f = 0x55 when FPGA programmed. */
750 snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg ); 751 snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg);
751 snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_ID=0x%x\n",reg); 752 snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_ID = 0x%x\n", reg);
752 if ((reg & 0x1f) != 0x15) { 753 if ((reg & 0x1f) != 0x15) {
753 /* FPGA failed to be programmed */ 754 /* FPGA failed to be programmed */
754 snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware file failed, reg=0x%x\n", reg); 755 snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware file failed, reg = 0x%x\n", reg);
755 continue; 756 continue;
756 } 757 }
757 snd_printk(KERN_INFO "emu1010: Audio Dock Firmware loaded\n"); 758 snd_printk(KERN_INFO "emu1010: Audio Dock Firmware loaded\n");
758 snd_emu1010_fpga_read(emu, EMU_DOCK_MAJOR_REV, &tmp ); 759 snd_emu1010_fpga_read(emu, EMU_DOCK_MAJOR_REV, &tmp);
759 snd_emu1010_fpga_read(emu, EMU_DOCK_MINOR_REV, &tmp2 ); 760 snd_emu1010_fpga_read(emu, EMU_DOCK_MINOR_REV, &tmp2);
760 snd_printk("Audio Dock ver:%d.%d\n",tmp ,tmp2); 761 snd_printk("Audio Dock ver:%d.%d\n", tmp, tmp2);
761 /* Sync clocking between 1010 and Dock */ 762 /* Sync clocking between 1010 and Dock */
762 /* Allow DLL to settle */ 763 /* Allow DLL to settle */
763 msleep(10); 764 msleep(10);
764 /* Unmute all. Default is muted after a firmware load */ 765 /* Unmute all. Default is muted after a firmware load */
765 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE ); 766 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE);
766 } 767 }
767 } 768 }
768 snd_printk(KERN_INFO "emu1010: firmware thread stopping\n"); 769 snd_printk(KERN_INFO "emu1010: firmware thread stopping\n");
@@ -800,10 +801,10 @@ static int emu1010_firmware_thread(void *data)
800 * 16 x 16-bit playback - snd_emu10k1_fx8010_playback_ops 801 * 16 x 16-bit playback - snd_emu10k1_fx8010_playback_ops
801 * 16 x 32-bit capture - snd_emu10k1_capture_efx_ops 802 * 16 x 32-bit capture - snd_emu10k1_capture_efx_ops
802 */ 803 */
803static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu) 804static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu)
804{ 805{
805 unsigned int i; 806 unsigned int i;
806 int tmp,tmp2; 807 int tmp, tmp2;
807 int reg; 808 int reg;
808 int err; 809 int err;
809 const char *filename = NULL; 810 const char *filename = NULL;
@@ -818,7 +819,7 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
818 * Lock Tank Memory Cache, 819 * Lock Tank Memory Cache,
819 * Mute all codecs. 820 * Mute all codecs.
820 */ 821 */
821 outl(0x0005a004, emu->port + HCFG); 822 outl(0x0005a004, emu->port + HCFG);
822 /* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave, 823 /* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave,
823 * Mute all codecs. 824 * Mute all codecs.
824 */ 825 */
@@ -829,25 +830,25 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
829 outl(0x0005a000, emu->port + HCFG); 830 outl(0x0005a000, emu->port + HCFG);
830 831
831 /* Disable 48Volt power to Audio Dock */ 832 /* Disable 48Volt power to Audio Dock */
832 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, 0 ); 833 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, 0);
833 834
834 /* ID, should read & 0x7f = 0x55. (Bit 7 is the IRQ bit) */ 835 /* ID, should read & 0x7f = 0x55. (Bit 7 is the IRQ bit) */
835 snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg ); 836 snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg);
836 snd_printdd("reg1=0x%x\n",reg); 837 snd_printdd("reg1 = 0x%x\n", reg);
837 if ((reg & 0x3f) == 0x15) { 838 if ((reg & 0x3f) == 0x15) {
838 /* FPGA netlist already present so clear it */ 839 /* FPGA netlist already present so clear it */
839 /* Return to programming mode */ 840 /* Return to programming mode */
840 841
841 snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0x02 ); 842 snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0x02);
842 } 843 }
843 snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg ); 844 snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg);
844 snd_printdd("reg2=0x%x\n",reg); 845 snd_printdd("reg2 = 0x%x\n", reg);
845 if ((reg & 0x3f) == 0x15) { 846 if ((reg & 0x3f) == 0x15) {
846 /* FPGA failed to return to programming mode */ 847 /* FPGA failed to return to programming mode */
847 snd_printk(KERN_INFO "emu1010: FPGA failed to return to programming mode\n"); 848 snd_printk(KERN_INFO "emu1010: FPGA failed to return to programming mode\n");
848 return -ENODEV; 849 return -ENODEV;
849 } 850 }
850 snd_printk(KERN_INFO "emu1010: EMU_HANA_ID=0x%x\n",reg); 851 snd_printk(KERN_INFO "emu1010: EMU_HANA_ID = 0x%x\n", reg);
851 switch (emu->card_capabilities->emu_model) { 852 switch (emu->card_capabilities->emu_model) {
852 case EMU_MODEL_EMU1010: 853 case EMU_MODEL_EMU1010:
853 filename = HANA_FILENAME; 854 filename = HANA_FILENAME;
@@ -876,25 +877,25 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
876 } 877 }
877 878
878 /* ID, should read & 0x7f = 0x55 when FPGA programmed. */ 879 /* ID, should read & 0x7f = 0x55 when FPGA programmed. */
879 snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg ); 880 snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg);
880 if ((reg & 0x3f) != 0x15) { 881 if ((reg & 0x3f) != 0x15) {
881 /* FPGA failed to be programmed */ 882 /* FPGA failed to be programmed */
882 snd_printk(KERN_INFO "emu1010: Loading Hana Firmware file failed, reg=0x%x\n", reg); 883 snd_printk(KERN_INFO "emu1010: Loading Hana Firmware file failed, reg = 0x%x\n", reg);
883 return -ENODEV; 884 return -ENODEV;
884 } 885 }
885 886
886 snd_printk(KERN_INFO "emu1010: Hana Firmware loaded\n"); 887 snd_printk(KERN_INFO "emu1010: Hana Firmware loaded\n");
887 snd_emu1010_fpga_read(emu, EMU_HANA_MAJOR_REV, &tmp ); 888 snd_emu1010_fpga_read(emu, EMU_HANA_MAJOR_REV, &tmp);
888 snd_emu1010_fpga_read(emu, EMU_HANA_MINOR_REV, &tmp2 ); 889 snd_emu1010_fpga_read(emu, EMU_HANA_MINOR_REV, &tmp2);
889 snd_printk("Hana ver:%d.%d\n",tmp ,tmp2); 890 snd_printk("emu1010: Hana version: %d.%d\n", tmp, tmp2);
890 /* Enable 48Volt power to Audio Dock */ 891 /* Enable 48Volt power to Audio Dock */
891 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, EMU_HANA_DOCK_PWR_ON ); 892 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, EMU_HANA_DOCK_PWR_ON);
892 893
893 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg ); 894 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg);
894 snd_printk(KERN_INFO "emu1010: Card options=0x%x\n",reg); 895 snd_printk(KERN_INFO "emu1010: Card options = 0x%x\n", reg);
895 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg ); 896 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg);
896 snd_printk(KERN_INFO "emu1010: Card options=0x%x\n",reg); 897 snd_printk(KERN_INFO "emu1010: Card options = 0x%x\n", reg);
897 snd_emu1010_fpga_read(emu, EMU_HANA_OPTICAL_TYPE, &tmp ); 898 snd_emu1010_fpga_read(emu, EMU_HANA_OPTICAL_TYPE, &tmp);
898 /* Optical -> ADAT I/O */ 899 /* Optical -> ADAT I/O */
899 /* 0 : SPDIF 900 /* 0 : SPDIF
900 * 1 : ADAT 901 * 1 : ADAT
@@ -904,41 +905,42 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
904 tmp = 0; 905 tmp = 0;
905 tmp = (emu->emu1010.optical_in ? EMU_HANA_OPTICAL_IN_ADAT : 0) | 906 tmp = (emu->emu1010.optical_in ? EMU_HANA_OPTICAL_IN_ADAT : 0) |
906 (emu->emu1010.optical_out ? EMU_HANA_OPTICAL_OUT_ADAT : 0); 907 (emu->emu1010.optical_out ? EMU_HANA_OPTICAL_OUT_ADAT : 0);
907 snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, tmp ); 908 snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, tmp);
908 snd_emu1010_fpga_read(emu, EMU_HANA_ADC_PADS, &tmp ); 909 snd_emu1010_fpga_read(emu, EMU_HANA_ADC_PADS, &tmp);
909 /* Set no attenuation on Audio Dock pads. */ 910 /* Set no attenuation on Audio Dock pads. */
910 snd_emu1010_fpga_write(emu, EMU_HANA_ADC_PADS, 0x00 ); 911 snd_emu1010_fpga_write(emu, EMU_HANA_ADC_PADS, 0x00);
911 emu->emu1010.adc_pads = 0x00; 912 emu->emu1010.adc_pads = 0x00;
912 snd_emu1010_fpga_read(emu, EMU_HANA_DOCK_MISC, &tmp ); 913 snd_emu1010_fpga_read(emu, EMU_HANA_DOCK_MISC, &tmp);
913 /* Unmute Audio dock DACs, Headphone source DAC-4. */ 914 /* Unmute Audio dock DACs, Headphone source DAC-4. */
914 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_MISC, 0x30 ); 915 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_MISC, 0x30);
915 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, 0x12 ); 916 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, 0x12);
916 snd_emu1010_fpga_read(emu, EMU_HANA_DAC_PADS, &tmp ); 917 snd_emu1010_fpga_read(emu, EMU_HANA_DAC_PADS, &tmp);
917 /* DAC PADs. */ 918 /* DAC PADs. */
918 snd_emu1010_fpga_write(emu, EMU_HANA_DAC_PADS, 0x0f ); 919 snd_emu1010_fpga_write(emu, EMU_HANA_DAC_PADS, 0x0f);
919 emu->emu1010.dac_pads = 0x0f; 920 emu->emu1010.dac_pads = 0x0f;
920 snd_emu1010_fpga_read(emu, EMU_HANA_DOCK_MISC, &tmp ); 921 snd_emu1010_fpga_read(emu, EMU_HANA_DOCK_MISC, &tmp);
921 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_MISC, 0x30 ); 922 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_MISC, 0x30);
922 snd_emu1010_fpga_read(emu, EMU_HANA_SPDIF_MODE, &tmp ); 923 snd_emu1010_fpga_read(emu, EMU_HANA_SPDIF_MODE, &tmp);
923 /* SPDIF Format. Set Consumer mode, 24bit, copy enable */ 924 /* SPDIF Format. Set Consumer mode, 24bit, copy enable */
924 snd_emu1010_fpga_write(emu, EMU_HANA_SPDIF_MODE, 0x10 ); 925 snd_emu1010_fpga_write(emu, EMU_HANA_SPDIF_MODE, 0x10);
925 /* MIDI routing */ 926 /* MIDI routing */
926 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_IN, 0x19 ); 927 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_IN, 0x19);
927 /* Unknown. */ 928 /* Unknown. */
928 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_OUT, 0x0c ); 929 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_OUT, 0x0c);
929 /* snd_emu1010_fpga_write(emu, 0x09, 0x0f ); // IRQ Enable: All on */ 930 /* IRQ Enable: Alll on */
931 /* snd_emu1010_fpga_write(emu, 0x09, 0x0f ); */
930 /* IRQ Enable: All off */ 932 /* IRQ Enable: All off */
931 snd_emu1010_fpga_write(emu, EMU_HANA_IRQ_ENABLE, 0x00 ); 933 snd_emu1010_fpga_write(emu, EMU_HANA_IRQ_ENABLE, 0x00);
932 934
933 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg ); 935 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg);
934 snd_printk(KERN_INFO "emu1010: Card options3=0x%x\n",reg); 936 snd_printk(KERN_INFO "emu1010: Card options3 = 0x%x\n", reg);
935 /* Default WCLK set to 48kHz. */ 937 /* Default WCLK set to 48kHz. */
936 snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, 0x00 ); 938 snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, 0x00);
937 /* Word Clock source, Internal 48kHz x1 */ 939 /* Word Clock source, Internal 48kHz x1 */
938 snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K ); 940 snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K);
939 //snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K | EMU_HANA_WCLOCK_4X ); 941 /* snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K | EMU_HANA_WCLOCK_4X); */
940 /* Audio Dock LEDs. */ 942 /* Audio Dock LEDs. */
941 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, 0x12 ); 943 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, 0x12);
942 944
943#if 0 945#if 0
944 /* For 96kHz */ 946 /* For 96kHz */
@@ -992,7 +994,7 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
992 * Defaults only, users will set their own values anyways, let's 994 * Defaults only, users will set their own values anyways, let's
993 * just copy/paste. 995 * just copy/paste.
994 */ 996 */
995 997
996 snd_emu1010_fpga_link_dst_src_write(emu, 998 snd_emu1010_fpga_link_dst_src_write(emu,
997 EMU_DST_ALICE2_EMU32_8, EMU_SRC_DOCK_MIC_A1); 999 EMU_DST_ALICE2_EMU32_8, EMU_SRC_DOCK_MIC_A1);
998 snd_emu1010_fpga_link_dst_src_write(emu, 1000 snd_emu1010_fpga_link_dst_src_write(emu,
@@ -1037,19 +1039,19 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
1037 snd_emu1010_fpga_link_dst_src_write(emu, 1039 snd_emu1010_fpga_link_dst_src_write(emu,
1038 EMU_DST_ALICE2_EMU32_F, EMU_SRC_HAMOA_ADC_LEFT2); 1040 EMU_DST_ALICE2_EMU32_F, EMU_SRC_HAMOA_ADC_LEFT2);
1039#endif 1041#endif
1040 for (i = 0;i < 0x20; i++ ) { 1042 for (i = 0; i < 0x20; i++) {
1041 /* AudioDock Elink <- Silence */ 1043 /* AudioDock Elink <- Silence */
1042 snd_emu1010_fpga_link_dst_src_write(emu, 0x0100+i, EMU_SRC_SILENCE); 1044 snd_emu1010_fpga_link_dst_src_write(emu, 0x0100 + i, EMU_SRC_SILENCE);
1043 } 1045 }
1044 for (i = 0;i < 4; i++) { 1046 for (i = 0; i < 4; i++) {
1045 /* Hana SPDIF Out <- Silence */ 1047 /* Hana SPDIF Out <- Silence */
1046 snd_emu1010_fpga_link_dst_src_write(emu, 0x0200+i, EMU_SRC_SILENCE); 1048 snd_emu1010_fpga_link_dst_src_write(emu, 0x0200 + i, EMU_SRC_SILENCE);
1047 } 1049 }
1048 for (i = 0;i < 7; i++) { 1050 for (i = 0; i < 7; i++) {
1049 /* Hamoa DAC <- Silence */ 1051 /* Hamoa DAC <- Silence */
1050 snd_emu1010_fpga_link_dst_src_write(emu, 0x0300+i, EMU_SRC_SILENCE); 1052 snd_emu1010_fpga_link_dst_src_write(emu, 0x0300 + i, EMU_SRC_SILENCE);
1051 } 1053 }
1052 for (i = 0;i < 7; i++) { 1054 for (i = 0; i < 7; i++) {
1053 /* Hana ADAT Out <- Silence */ 1055 /* Hana ADAT Out <- Silence */
1054 snd_emu1010_fpga_link_dst_src_write(emu, EMU_DST_HANA_ADAT + i, EMU_SRC_SILENCE); 1056 snd_emu1010_fpga_link_dst_src_write(emu, EMU_DST_HANA_ADAT + i, EMU_SRC_SILENCE);
1055 } 1057 }
@@ -1065,30 +1067,30 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
1065 EMU_DST_ALICE_I2S2_LEFT, EMU_SRC_DOCK_ADC3_LEFT1); 1067 EMU_DST_ALICE_I2S2_LEFT, EMU_SRC_DOCK_ADC3_LEFT1);
1066 snd_emu1010_fpga_link_dst_src_write(emu, 1068 snd_emu1010_fpga_link_dst_src_write(emu,
1067 EMU_DST_ALICE_I2S2_RIGHT, EMU_SRC_DOCK_ADC3_RIGHT1); 1069 EMU_DST_ALICE_I2S2_RIGHT, EMU_SRC_DOCK_ADC3_RIGHT1);
1068 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x01 ); // Unmute all 1070 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x01); /* Unmute all */
1071
1072 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &tmp);
1069 1073
1070 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &tmp );
1071
1072 /* AC97 1.03, Any 32Meg of 2Gig address, Auto-Mute, EMU32 Slave, 1074 /* AC97 1.03, Any 32Meg of 2Gig address, Auto-Mute, EMU32 Slave,
1073 * Lock Sound Memory Cache, Lock Tank Memory Cache, 1075 * Lock Sound Memory Cache, Lock Tank Memory Cache,
1074 * Mute all codecs. 1076 * Mute all codecs.
1075 */ 1077 */
1076 outl(0x0000a000, emu->port + HCFG); 1078 outl(0x0000a000, emu->port + HCFG);
1077 /* AC97 1.03, Any 32Meg of 2Gig address, Auto-Mute, EMU32 Slave, 1079 /* AC97 1.03, Any 32Meg of 2Gig address, Auto-Mute, EMU32 Slave,
1078 * Lock Sound Memory Cache, Lock Tank Memory Cache, 1080 * Lock Sound Memory Cache, Lock Tank Memory Cache,
1079 * Un-Mute all codecs. 1081 * Un-Mute all codecs.
1080 */ 1082 */
1081 outl(0x0000a001, emu->port + HCFG); 1083 outl(0x0000a001, emu->port + HCFG);
1082 1084
1083 /* Initial boot complete. Now patches */ 1085 /* Initial boot complete. Now patches */
1084 1086
1085 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &tmp ); 1087 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &tmp);
1086 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_IN, 0x19 ); /* MIDI Route */ 1088 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_IN, 0x19); /* MIDI Route */
1087 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_OUT, 0x0c ); /* Unknown */ 1089 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_OUT, 0x0c); /* Unknown */
1088 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_IN, 0x19 ); /* MIDI Route */ 1090 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_IN, 0x19); /* MIDI Route */
1089 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_OUT, 0x0c ); /* Unknown */ 1091 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_OUT, 0x0c); /* Unknown */
1090 snd_emu1010_fpga_read(emu, EMU_HANA_SPDIF_MODE, &tmp ); 1092 snd_emu1010_fpga_read(emu, EMU_HANA_SPDIF_MODE, &tmp);
1091 snd_emu1010_fpga_write(emu, EMU_HANA_SPDIF_MODE, 0x10 ); /* SPDIF Format spdif (or 0x11 for aes/ebu) */ 1093 snd_emu1010_fpga_write(emu, EMU_HANA_SPDIF_MODE, 0x10); /* SPDIF Format spdif (or 0x11 for aes/ebu) */
1092 1094
1093 /* Start Micro/Audio Dock firmware loader thread */ 1095 /* Start Micro/Audio Dock firmware loader thread */
1094 if (!emu->emu1010.firmware_thread) { 1096 if (!emu->emu1010.firmware_thread) {
@@ -1218,20 +1220,20 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
1218 emu->emu1010.output_source[23] = 28; 1220 emu->emu1010.output_source[23] = 28;
1219 } 1221 }
1220 /* TEMP: Select SPDIF in/out */ 1222 /* TEMP: Select SPDIF in/out */
1221 //snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, 0x0); /* Output spdif */ 1223 /* snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, 0x0); */ /* Output spdif */
1222 1224
1223 /* TEMP: Select 48kHz SPDIF out */ 1225 /* TEMP: Select 48kHz SPDIF out */
1224 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x0); /* Mute all */ 1226 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x0); /* Mute all */
1225 snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, 0x0); /* Default fallback clock 48kHz */ 1227 snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, 0x0); /* Default fallback clock 48kHz */
1226 /* Word Clock source, Internal 48kHz x1 */ 1228 /* Word Clock source, Internal 48kHz x1 */
1227 snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K ); 1229 snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K);
1228 //snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K | EMU_HANA_WCLOCK_4X ); 1230 /* snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K | EMU_HANA_WCLOCK_4X); */
1229 emu->emu1010.internal_clock = 1; /* 48000 */ 1231 emu->emu1010.internal_clock = 1; /* 48000 */
1230 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, 0x12);/* Set LEDs on Audio Dock */ 1232 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, 0x12); /* Set LEDs on Audio Dock */
1231 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x1); /* Unmute all */ 1233 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x1); /* Unmute all */
1232 //snd_emu1010_fpga_write(emu, 0x7, 0x0); /* Mute all */ 1234 /* snd_emu1010_fpga_write(emu, 0x7, 0x0); */ /* Mute all */
1233 //snd_emu1010_fpga_write(emu, 0x7, 0x1); /* Unmute all */ 1235 /* snd_emu1010_fpga_write(emu, 0x7, 0x1); */ /* Unmute all */
1234 //snd_emu1010_fpga_write(emu, 0xe, 0x12); /* Set LEDs on Audio Dock */ 1236 /* snd_emu1010_fpga_write(emu, 0xe, 0x12); */ /* Set LEDs on Audio Dock */
1235 1237
1236 return 0; 1238 return 0;
1237} 1239}
@@ -1247,13 +1249,13 @@ static void free_pm_buffer(struct snd_emu10k1 *emu);
1247static int snd_emu10k1_free(struct snd_emu10k1 *emu) 1249static int snd_emu10k1_free(struct snd_emu10k1 *emu)
1248{ 1250{
1249 if (emu->port) { /* avoid access to already used hardware */ 1251 if (emu->port) { /* avoid access to already used hardware */
1250 snd_emu10k1_fx8010_tram_setup(emu, 0); 1252 snd_emu10k1_fx8010_tram_setup(emu, 0);
1251 snd_emu10k1_done(emu); 1253 snd_emu10k1_done(emu);
1252 snd_emu10k1_free_efx(emu); 1254 snd_emu10k1_free_efx(emu);
1253 } 1255 }
1254 if (emu->card_capabilities->emu_model == EMU_MODEL_EMU1010) { 1256 if (emu->card_capabilities->emu_model == EMU_MODEL_EMU1010) {
1255 /* Disable 48Volt power to Audio Dock */ 1257 /* Disable 48Volt power to Audio Dock */
1256 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, 0 ); 1258 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, 0);
1257 } 1259 }
1258 if (emu->emu1010.firmware_thread) 1260 if (emu->emu1010.firmware_thread)
1259 kthread_stop(emu->emu1010.firmware_thread); 1261 kthread_stop(emu->emu1010.firmware_thread);
@@ -1278,7 +1280,7 @@ static int snd_emu10k1_free(struct snd_emu10k1 *emu)
1278#endif 1280#endif
1279 if (emu->port) 1281 if (emu->port)
1280 pci_release_regions(emu->pci); 1282 pci_release_regions(emu->pci);
1281 if (emu->card_capabilities->ca0151_chip) /* P16V */ 1283 if (emu->card_capabilities->ca0151_chip) /* P16V */
1282 snd_p16v_free(emu); 1284 snd_p16v_free(emu);
1283 pci_disable_device(emu->pci); 1285 pci_disable_device(emu->pci);
1284 kfree(emu); 1286 kfree(emu);
@@ -1292,21 +1294,6 @@ static int snd_emu10k1_dev_free(struct snd_device *device)
1292} 1294}
1293 1295
1294static struct snd_emu_chip_details emu_chip_details[] = { 1296static struct snd_emu_chip_details emu_chip_details[] = {
1295 /* Audigy 2 Value AC3 out does not work yet. Need to find out how to turn off interpolators.*/
1296 /* Tested by James@superbug.co.uk 3rd July 2005 */
1297 /* DSP: CA0108-IAT
1298 * DAC: CS4382-KQ
1299 * ADC: Philips 1361T
1300 * AC97: STAC9750
1301 * CA0151: None
1302 */
1303 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x10011102,
1304 .driver = "Audigy2", .name = "Audigy 2 Value [SB0400]",
1305 .id = "Audigy2",
1306 .emu10k2_chip = 1,
1307 .ca0108_chip = 1,
1308 .spk71 = 1,
1309 .ac97_chip = 1} ,
1310 /* Audigy4 (Not PRO) SB0610 */ 1297 /* Audigy4 (Not PRO) SB0610 */
1311 /* Tested by James@superbug.co.uk 4th April 2006 */ 1298 /* Tested by James@superbug.co.uk 4th April 2006 */
1312 /* A_IOCFG bits 1299 /* A_IOCFG bits
@@ -1346,20 +1333,37 @@ static struct snd_emu_chip_details emu_chip_details[] = {
1346 * CA0151: None 1333 * CA0151: None
1347 */ 1334 */
1348 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x10211102, 1335 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x10211102,
1349 .driver = "Audigy2", .name = "Audigy 4 [SB0610]", 1336 .driver = "Audigy2", .name = "SB Audigy 4 [SB0610]",
1350 .id = "Audigy2", 1337 .id = "Audigy2",
1351 .emu10k2_chip = 1, 1338 .emu10k2_chip = 1,
1352 .ca0108_chip = 1, 1339 .ca0108_chip = 1,
1353 .spk71 = 1, 1340 .spk71 = 1,
1354 .adc_1361t = 1, /* 24 bit capture instead of 16bit */ 1341 .adc_1361t = 1, /* 24 bit capture instead of 16bit */
1355 .ac97_chip = 1} , 1342 .ac97_chip = 1} ,
1343 /* Audigy 2 Value AC3 out does not work yet.
1344 * Need to find out how to turn off interpolators.
1345 */
1346 /* Tested by James@superbug.co.uk 3rd July 2005 */
1347 /* DSP: CA0108-IAT
1348 * DAC: CS4382-KQ
1349 * ADC: Philips 1361T
1350 * AC97: STAC9750
1351 * CA0151: None
1352 */
1353 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x10011102,
1354 .driver = "Audigy2", .name = "SB Audigy 2 Value [SB0400]",
1355 .id = "Audigy2",
1356 .emu10k2_chip = 1,
1357 .ca0108_chip = 1,
1358 .spk71 = 1,
1359 .ac97_chip = 1} ,
1356 /* Audigy 2 ZS Notebook Cardbus card.*/ 1360 /* Audigy 2 ZS Notebook Cardbus card.*/
1357 /* Tested by James@superbug.co.uk 6th November 2006 */ 1361 /* Tested by James@superbug.co.uk 6th November 2006 */
1358 /* Audio output 7.1/Headphones working. 1362 /* Audio output 7.1/Headphones working.
1359 * Digital output working. (AC3 not checked, only PCM) 1363 * Digital output working. (AC3 not checked, only PCM)
1360 * Audio Mic/Line inputs working. 1364 * Audio Mic/Line inputs working.
1361 * Digital input not tested. 1365 * Digital input not tested.
1362 */ 1366 */
1363 /* DSP: Tina2 1367 /* DSP: Tina2
1364 * DAC: Wolfson WM8768/WM8568 1368 * DAC: Wolfson WM8768/WM8568
1365 * ADC: Wolfson WM8775 1369 * ADC: Wolfson WM8775
@@ -1386,7 +1390,7 @@ static struct snd_emu_chip_details emu_chip_details[] = {
1386 * 1390 *
1387 */ 1391 */
1388 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x20011102, 1392 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x20011102,
1389 .driver = "Audigy2", .name = "Audigy 2 ZS Notebook [SB0530]", 1393 .driver = "Audigy2", .name = "SB Audigy 2 ZS Notebook [SB0530]",
1390 .id = "Audigy2", 1394 .id = "Audigy2",
1391 .emu10k2_chip = 1, 1395 .emu10k2_chip = 1,
1392 .ca0108_chip = 1, 1396 .ca0108_chip = 1,
@@ -1396,7 +1400,7 @@ static struct snd_emu_chip_details emu_chip_details[] = {
1396 .spk71 = 1} , 1400 .spk71 = 1} ,
1397 /* Tested by James@superbug.co.uk 4th Nov 2007. */ 1401 /* Tested by James@superbug.co.uk 4th Nov 2007. */
1398 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x42011102, 1402 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x42011102,
1399 .driver = "Audigy2", .name = "E-mu 1010 Notebook [MAEM8950]", 1403 .driver = "Audigy2", .name = "E-mu 1010 Notebook [MAEM8950]",
1400 .id = "EMU1010", 1404 .id = "EMU1010",
1401 .emu10k2_chip = 1, 1405 .emu10k2_chip = 1,
1402 .ca0108_chip = 1, 1406 .ca0108_chip = 1,
@@ -1404,47 +1408,49 @@ static struct snd_emu_chip_details emu_chip_details[] = {
1404 .spk71 = 1 , 1408 .spk71 = 1 ,
1405 .emu_model = EMU_MODEL_EMU1616}, 1409 .emu_model = EMU_MODEL_EMU1616},
1406 /* Tested by James@superbug.co.uk 4th Nov 2007. */ 1410 /* Tested by James@superbug.co.uk 4th Nov 2007. */
1411 /* This is MAEM8960, 0202 is MAEM 8980 */
1407 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x40041102, 1412 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x40041102,
1408 .driver = "Audigy2", .name = "E-mu 1010b PCI [MAEM????]", 1413 .driver = "Audigy2", .name = "E-mu 1010b PCI [MAEM8960]",
1409 .id = "EMU1010", 1414 .id = "EMU1010",
1410 .emu10k2_chip = 1, 1415 .emu10k2_chip = 1,
1411 .ca0108_chip = 1, 1416 .ca0108_chip = 1,
1412 .spk71 = 1, 1417 .spk71 = 1,
1413 .emu_model = EMU_MODEL_EMU1010B}, 1418 .emu_model = EMU_MODEL_EMU1010B}, /* EMU 1010 new revision */
1414 /* Tested by James@superbug.co.uk 8th July 2005. */ 1419 /* Tested by James@superbug.co.uk 8th July 2005. */
1420 /* This is MAEM8810, 0202 is MAEM8820 */
1415 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x40011102, 1421 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x40011102,
1416 .driver = "Audigy2", .name = "E-mu 1010 [4001]", 1422 .driver = "Audigy2", .name = "E-mu 1010 [MAEM8810]",
1417 .id = "EMU1010", 1423 .id = "EMU1010",
1418 .emu10k2_chip = 1, 1424 .emu10k2_chip = 1,
1419 .ca0102_chip = 1, 1425 .ca0102_chip = 1,
1420 .spk71 = 1, 1426 .spk71 = 1,
1421 .emu_model = EMU_MODEL_EMU1010}, /* Emu 1010 */ 1427 .emu_model = EMU_MODEL_EMU1010}, /* EMU 1010 old revision */
1422 /* EMU0404b */ 1428 /* EMU0404b */
1423 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x40021102, 1429 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x40021102,
1424 .driver = "Audigy2", .name = "E-mu 0404b [4002]", 1430 .driver = "Audigy2", .name = "E-mu 0404b PCI [MAEM8852]",
1425 .id = "EMU0404", 1431 .id = "EMU0404",
1426 .emu10k2_chip = 1, 1432 .emu10k2_chip = 1,
1427 .ca0108_chip = 1, 1433 .ca0108_chip = 1,
1428 .spk71 = 1, 1434 .spk71 = 1,
1429 .emu_model = EMU_MODEL_EMU0404}, /* EMU 0404 */ 1435 .emu_model = EMU_MODEL_EMU0404}, /* EMU 0404 new revision */
1430 /* Tested by James@superbug.co.uk 20-3-2007. */ 1436 /* Tested by James@superbug.co.uk 20-3-2007. */
1431 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x40021102, 1437 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x40021102,
1432 .driver = "Audigy2", .name = "E-mu 0404 [4002]", 1438 .driver = "Audigy2", .name = "E-mu 0404 [MAEM8850]",
1433 .id = "EMU0404", 1439 .id = "EMU0404",
1434 .emu10k2_chip = 1, 1440 .emu10k2_chip = 1,
1435 .ca0102_chip = 1, 1441 .ca0102_chip = 1,
1436 .spk71 = 1, 1442 .spk71 = 1,
1437 .emu_model = EMU_MODEL_EMU0404}, /* EMU 0404 */ 1443 .emu_model = EMU_MODEL_EMU0404}, /* EMU 0404 */
1438 /* Audigy4 (Not PRO) SB0610 */ 1444 /* Note that all E-mu cards require kernel 2.6 or newer. */
1439 {.vendor = 0x1102, .device = 0x0008, 1445 {.vendor = 0x1102, .device = 0x0008,
1440 .driver = "Audigy2", .name = "Audigy 2 Value [Unknown]", 1446 .driver = "Audigy2", .name = "SB Audigy 2 Value [Unknown]",
1441 .id = "Audigy2", 1447 .id = "Audigy2",
1442 .emu10k2_chip = 1, 1448 .emu10k2_chip = 1,
1443 .ca0108_chip = 1, 1449 .ca0108_chip = 1,
1444 .ac97_chip = 1} , 1450 .ac97_chip = 1} ,
1445 /* Tested by James@superbug.co.uk 3rd July 2005 */ 1451 /* Tested by James@superbug.co.uk 3rd July 2005 */
1446 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20071102, 1452 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20071102,
1447 .driver = "Audigy2", .name = "Audigy 4 PRO [SB0380]", 1453 .driver = "Audigy2", .name = "SB Audigy 4 PRO [SB0380]",
1448 .id = "Audigy2", 1454 .id = "Audigy2",
1449 .emu10k2_chip = 1, 1455 .emu10k2_chip = 1,
1450 .ca0102_chip = 1, 1456 .ca0102_chip = 1,
@@ -1457,7 +1463,7 @@ static struct snd_emu_chip_details emu_chip_details[] = {
1457 * Just like 0x20021102 1463 * Just like 0x20021102
1458 */ 1464 */
1459 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20061102, 1465 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20061102,
1460 .driver = "Audigy2", .name = "Audigy 2 [SB0350b]", 1466 .driver = "Audigy2", .name = "SB Audigy 2 [SB0350b]",
1461 .id = "Audigy2", 1467 .id = "Audigy2",
1462 .emu10k2_chip = 1, 1468 .emu10k2_chip = 1,
1463 .ca0102_chip = 1, 1469 .ca0102_chip = 1,
@@ -1467,7 +1473,7 @@ static struct snd_emu_chip_details emu_chip_details[] = {
1467 .invert_shared_spdif = 1, /* digital/analog switch swapped */ 1473 .invert_shared_spdif = 1, /* digital/analog switch swapped */
1468 .ac97_chip = 1} , 1474 .ac97_chip = 1} ,
1469 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20021102, 1475 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20021102,
1470 .driver = "Audigy2", .name = "Audigy 2 ZS [SB0350]", 1476 .driver = "Audigy2", .name = "SB Audigy 2 ZS [SB0350]",
1471 .id = "Audigy2", 1477 .id = "Audigy2",
1472 .emu10k2_chip = 1, 1478 .emu10k2_chip = 1,
1473 .ca0102_chip = 1, 1479 .ca0102_chip = 1,
@@ -1477,7 +1483,7 @@ static struct snd_emu_chip_details emu_chip_details[] = {
1477 .invert_shared_spdif = 1, /* digital/analog switch swapped */ 1483 .invert_shared_spdif = 1, /* digital/analog switch swapped */
1478 .ac97_chip = 1} , 1484 .ac97_chip = 1} ,
1479 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20011102, 1485 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20011102,
1480 .driver = "Audigy2", .name = "Audigy 2 ZS [2001]", 1486 .driver = "Audigy2", .name = "SB Audigy 2 ZS [SB0360]",
1481 .id = "Audigy2", 1487 .id = "Audigy2",
1482 .emu10k2_chip = 1, 1488 .emu10k2_chip = 1,
1483 .ca0102_chip = 1, 1489 .ca0102_chip = 1,
@@ -1495,7 +1501,7 @@ static struct snd_emu_chip_details emu_chip_details[] = {
1495 * CA0151: Yes 1501 * CA0151: Yes
1496 */ 1502 */
1497 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10071102, 1503 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10071102,
1498 .driver = "Audigy2", .name = "Audigy 2 [SB0240]", 1504 .driver = "Audigy2", .name = "SB Audigy 2 [SB0240]",
1499 .id = "Audigy2", 1505 .id = "Audigy2",
1500 .emu10k2_chip = 1, 1506 .emu10k2_chip = 1,
1501 .ca0102_chip = 1, 1507 .ca0102_chip = 1,
@@ -1505,7 +1511,7 @@ static struct snd_emu_chip_details emu_chip_details[] = {
1505 .adc_1361t = 1, /* 24 bit capture instead of 16bit */ 1511 .adc_1361t = 1, /* 24 bit capture instead of 16bit */
1506 .ac97_chip = 1} , 1512 .ac97_chip = 1} ,
1507 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10051102, 1513 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10051102,
1508 .driver = "Audigy2", .name = "Audigy 2 EX [1005]", 1514 .driver = "Audigy2", .name = "SB Audigy 2 Platinum EX [SB0280]",
1509 .id = "Audigy2", 1515 .id = "Audigy2",
1510 .emu10k2_chip = 1, 1516 .emu10k2_chip = 1,
1511 .ca0102_chip = 1, 1517 .ca0102_chip = 1,
@@ -1515,7 +1521,7 @@ static struct snd_emu_chip_details emu_chip_details[] = {
1515 /* Dell OEM/Creative Labs Audigy 2 ZS */ 1521 /* Dell OEM/Creative Labs Audigy 2 ZS */
1516 /* See ALSA bug#1365 */ 1522 /* See ALSA bug#1365 */
1517 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10031102, 1523 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10031102,
1518 .driver = "Audigy2", .name = "Audigy 2 ZS [SB0353]", 1524 .driver = "Audigy2", .name = "SB Audigy 2 ZS [SB0353]",
1519 .id = "Audigy2", 1525 .id = "Audigy2",
1520 .emu10k2_chip = 1, 1526 .emu10k2_chip = 1,
1521 .ca0102_chip = 1, 1527 .ca0102_chip = 1,
@@ -1524,7 +1530,7 @@ static struct snd_emu_chip_details emu_chip_details[] = {
1524 .spdif_bug = 1, 1530 .spdif_bug = 1,
1525 .ac97_chip = 1} , 1531 .ac97_chip = 1} ,
1526 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10021102, 1532 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10021102,
1527 .driver = "Audigy2", .name = "Audigy 2 Platinum [SB0240P]", 1533 .driver = "Audigy2", .name = "SB Audigy 2 Platinum [SB0240P]",
1528 .id = "Audigy2", 1534 .id = "Audigy2",
1529 .emu10k2_chip = 1, 1535 .emu10k2_chip = 1,
1530 .ca0102_chip = 1, 1536 .ca0102_chip = 1,
@@ -1535,7 +1541,7 @@ static struct snd_emu_chip_details emu_chip_details[] = {
1535 .adc_1361t = 1, /* 24 bit capture instead of 16bit. Fixes ALSA bug#324 */ 1541 .adc_1361t = 1, /* 24 bit capture instead of 16bit. Fixes ALSA bug#324 */
1536 .ac97_chip = 1} , 1542 .ac97_chip = 1} ,
1537 {.vendor = 0x1102, .device = 0x0004, .revision = 0x04, 1543 {.vendor = 0x1102, .device = 0x0004, .revision = 0x04,
1538 .driver = "Audigy2", .name = "Audigy 2 [Unknown]", 1544 .driver = "Audigy2", .name = "SB Audigy 2 [Unknown]",
1539 .id = "Audigy2", 1545 .id = "Audigy2",
1540 .emu10k2_chip = 1, 1546 .emu10k2_chip = 1,
1541 .ca0102_chip = 1, 1547 .ca0102_chip = 1,
@@ -1543,78 +1549,79 @@ static struct snd_emu_chip_details emu_chip_details[] = {
1543 .spdif_bug = 1, 1549 .spdif_bug = 1,
1544 .ac97_chip = 1} , 1550 .ac97_chip = 1} ,
1545 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00531102, 1551 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00531102,
1546 .driver = "Audigy", .name = "Audigy 1 [SB0090]", 1552 .driver = "Audigy", .name = "SB Audigy 1 [SB0092]",
1547 .id = "Audigy", 1553 .id = "Audigy",
1548 .emu10k2_chip = 1, 1554 .emu10k2_chip = 1,
1549 .ca0102_chip = 1, 1555 .ca0102_chip = 1,
1550 .ac97_chip = 1} , 1556 .ac97_chip = 1} ,
1551 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00521102, 1557 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00521102,
1552 .driver = "Audigy", .name = "Audigy 1 ES [SB0160]", 1558 .driver = "Audigy", .name = "SB Audigy 1 ES [SB0160]",
1553 .id = "Audigy", 1559 .id = "Audigy",
1554 .emu10k2_chip = 1, 1560 .emu10k2_chip = 1,
1555 .ca0102_chip = 1, 1561 .ca0102_chip = 1,
1556 .spdif_bug = 1, 1562 .spdif_bug = 1,
1557 .ac97_chip = 1} , 1563 .ac97_chip = 1} ,
1558 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00511102, 1564 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00511102,
1559 .driver = "Audigy", .name = "Audigy 1 [SB0090]", 1565 .driver = "Audigy", .name = "SB Audigy 1 [SB0090]",
1560 .id = "Audigy", 1566 .id = "Audigy",
1561 .emu10k2_chip = 1, 1567 .emu10k2_chip = 1,
1562 .ca0102_chip = 1, 1568 .ca0102_chip = 1,
1563 .ac97_chip = 1} , 1569 .ac97_chip = 1} ,
1564 {.vendor = 0x1102, .device = 0x0004, 1570 {.vendor = 0x1102, .device = 0x0004,
1565 .driver = "Audigy", .name = "Audigy 1 [Unknown]", 1571 .driver = "Audigy", .name = "Audigy 1 [Unknown]",
1566 .id = "Audigy", 1572 .id = "Audigy",
1567 .emu10k2_chip = 1, 1573 .emu10k2_chip = 1,
1568 .ca0102_chip = 1, 1574 .ca0102_chip = 1,
1569 .ac97_chip = 1} , 1575 .ac97_chip = 1} ,
1570 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x806B1102, 1576 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x100a1102,
1571 .driver = "EMU10K1", .name = "SBLive! [SB0105]", 1577 .driver = "EMU10K1", .name = "SB Live! 5.1 [SB0220]",
1578 .id = "Live",
1579 .emu10k1_chip = 1,
1580 .ac97_chip = 1,
1581 .sblive51 = 1} ,
1582 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x806b1102,
1583 .driver = "EMU10K1", .name = "SB Live! [SB0105]",
1572 .id = "Live", 1584 .id = "Live",
1573 .emu10k1_chip = 1, 1585 .emu10k1_chip = 1,
1574 .ac97_chip = 1, 1586 .ac97_chip = 1,
1575 .sblive51 = 1} , 1587 .sblive51 = 1} ,
1576 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x806A1102, 1588 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x806a1102,
1577 .driver = "EMU10K1", .name = "SBLive! Value [SB0103]", 1589 .driver = "EMU10K1", .name = "SB Live! Value [SB0103]",
1578 .id = "Live", 1590 .id = "Live",
1579 .emu10k1_chip = 1, 1591 .emu10k1_chip = 1,
1580 .ac97_chip = 1, 1592 .ac97_chip = 1,
1581 .sblive51 = 1} , 1593 .sblive51 = 1} ,
1582 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80691102, 1594 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80691102,
1583 .driver = "EMU10K1", .name = "SBLive! Value [SB0101]", 1595 .driver = "EMU10K1", .name = "SB Live! Value [SB0101]",
1584 .id = "Live", 1596 .id = "Live",
1585 .emu10k1_chip = 1, 1597 .emu10k1_chip = 1,
1586 .ac97_chip = 1, 1598 .ac97_chip = 1,
1587 .sblive51 = 1} , 1599 .sblive51 = 1} ,
1588 /* Tested by ALSA bug#1680 26th December 2005 */ 1600 /* Tested by ALSA bug#1680 26th December 2005 */
1589 /* note: It really has SB0220 written on the card. */ 1601 /* note: It really has SB0220 written on the card, */
1602 /* but it's SB0228 according to kx.inf */
1590 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80661102, 1603 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80661102,
1591 .driver = "EMU10K1", .name = "SB Live 5.1 Dell OEM [SB0220]", 1604 .driver = "EMU10K1", .name = "SB Live! 5.1 Dell OEM [SB0228]",
1592 .id = "Live", 1605 .id = "Live",
1593 .emu10k1_chip = 1, 1606 .emu10k1_chip = 1,
1594 .ac97_chip = 1, 1607 .ac97_chip = 1,
1595 .sblive51 = 1} , 1608 .sblive51 = 1} ,
1596 /* Tested by Thomas Zehetbauer 27th Aug 2005 */ 1609 /* Tested by Thomas Zehetbauer 27th Aug 2005 */
1597 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80651102, 1610 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80651102,
1598 .driver = "EMU10K1", .name = "SB Live 5.1 [SB0220]", 1611 .driver = "EMU10K1", .name = "SB Live! 5.1 [SB0220]",
1599 .id = "Live",
1600 .emu10k1_chip = 1,
1601 .ac97_chip = 1,
1602 .sblive51 = 1} ,
1603 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x100a1102,
1604 .driver = "EMU10K1", .name = "SB Live 5.1 [SB0220]",
1605 .id = "Live", 1612 .id = "Live",
1606 .emu10k1_chip = 1, 1613 .emu10k1_chip = 1,
1607 .ac97_chip = 1, 1614 .ac97_chip = 1,
1608 .sblive51 = 1} , 1615 .sblive51 = 1} ,
1609 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80641102, 1616 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80641102,
1610 .driver = "EMU10K1", .name = "SB Live 5.1", 1617 .driver = "EMU10K1", .name = "SB Live! 5.1",
1611 .id = "Live", 1618 .id = "Live",
1612 .emu10k1_chip = 1, 1619 .emu10k1_chip = 1,
1613 .ac97_chip = 1, 1620 .ac97_chip = 1,
1614 .sblive51 = 1} , 1621 .sblive51 = 1} ,
1615 /* Tested by alsa bugtrack user "hus" bug #1297 12th Aug 2005 */ 1622 /* Tested by alsa bugtrack user "hus" bug #1297 12th Aug 2005 */
1616 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80611102, 1623 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80611102,
1617 .driver = "EMU10K1", .name = "SBLive 5.1 [SB0060]", 1624 .driver = "EMU10K1", .name = "SB Live! 5.1 [SB0060]",
1618 .id = "Live", 1625 .id = "Live",
1619 .emu10k1_chip = 1, 1626 .emu10k1_chip = 1,
1620 .ac97_chip = 2, /* ac97 is optional; both SBLive 5.1 and platinum 1627 .ac97_chip = 2, /* ac97 is optional; both SBLive 5.1 and platinum
@@ -1622,78 +1629,78 @@ static struct snd_emu_chip_details emu_chip_details[] = {
1622 */ 1629 */
1623 .sblive51 = 1} , 1630 .sblive51 = 1} ,
1624 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80511102, 1631 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80511102,
1625 .driver = "EMU10K1", .name = "SBLive! Value [CT4850]", 1632 .driver = "EMU10K1", .name = "SB Live! Value [CT4850]",
1626 .id = "Live", 1633 .id = "Live",
1627 .emu10k1_chip = 1, 1634 .emu10k1_chip = 1,
1628 .ac97_chip = 1, 1635 .ac97_chip = 1,
1629 .sblive51 = 1} , 1636 .sblive51 = 1} ,
1630 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80401102, 1637 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80401102,
1631 .driver = "EMU10K1", .name = "SBLive! Platinum [CT4760P]", 1638 .driver = "EMU10K1", .name = "SB Live! Platinum [CT4760P]",
1632 .id = "Live", 1639 .id = "Live",
1633 .emu10k1_chip = 1, 1640 .emu10k1_chip = 1,
1634 .ac97_chip = 1} , 1641 .ac97_chip = 1} ,
1635 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80321102, 1642 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80321102,
1636 .driver = "EMU10K1", .name = "SBLive! Value [CT4871]", 1643 .driver = "EMU10K1", .name = "SB Live! Value [CT4871]",
1637 .id = "Live", 1644 .id = "Live",
1638 .emu10k1_chip = 1, 1645 .emu10k1_chip = 1,
1639 .ac97_chip = 1, 1646 .ac97_chip = 1,
1640 .sblive51 = 1} , 1647 .sblive51 = 1} ,
1641 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80311102, 1648 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80311102,
1642 .driver = "EMU10K1", .name = "SBLive! Value [CT4831]", 1649 .driver = "EMU10K1", .name = "SB Live! Value [CT4831]",
1643 .id = "Live", 1650 .id = "Live",
1644 .emu10k1_chip = 1, 1651 .emu10k1_chip = 1,
1645 .ac97_chip = 1, 1652 .ac97_chip = 1,
1646 .sblive51 = 1} , 1653 .sblive51 = 1} ,
1647 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80281102, 1654 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80281102,
1648 .driver = "EMU10K1", .name = "SBLive! Value [CT4870]", 1655 .driver = "EMU10K1", .name = "SB Live! Value [CT4870]",
1649 .id = "Live", 1656 .id = "Live",
1650 .emu10k1_chip = 1, 1657 .emu10k1_chip = 1,
1651 .ac97_chip = 1, 1658 .ac97_chip = 1,
1652 .sblive51 = 1} , 1659 .sblive51 = 1} ,
1653 /* Tested by James@superbug.co.uk 3rd July 2005 */ 1660 /* Tested by James@superbug.co.uk 3rd July 2005 */
1654 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80271102, 1661 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80271102,
1655 .driver = "EMU10K1", .name = "SBLive! Value [CT4832]", 1662 .driver = "EMU10K1", .name = "SB Live! Value [CT4832]",
1656 .id = "Live", 1663 .id = "Live",
1657 .emu10k1_chip = 1, 1664 .emu10k1_chip = 1,
1658 .ac97_chip = 1, 1665 .ac97_chip = 1,
1659 .sblive51 = 1} , 1666 .sblive51 = 1} ,
1660 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80261102, 1667 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80261102,
1661 .driver = "EMU10K1", .name = "SBLive! Value [CT4830]", 1668 .driver = "EMU10K1", .name = "SB Live! Value [CT4830]",
1662 .id = "Live", 1669 .id = "Live",
1663 .emu10k1_chip = 1, 1670 .emu10k1_chip = 1,
1664 .ac97_chip = 1, 1671 .ac97_chip = 1,
1665 .sblive51 = 1} , 1672 .sblive51 = 1} ,
1666 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80231102, 1673 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80231102,
1667 .driver = "EMU10K1", .name = "SB PCI512 [CT4790]", 1674 .driver = "EMU10K1", .name = "SB PCI512 [CT4790]",
1668 .id = "Live", 1675 .id = "Live",
1669 .emu10k1_chip = 1, 1676 .emu10k1_chip = 1,
1670 .ac97_chip = 1, 1677 .ac97_chip = 1,
1671 .sblive51 = 1} , 1678 .sblive51 = 1} ,
1672 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80221102, 1679 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80221102,
1673 .driver = "EMU10K1", .name = "SBLive! Value [CT4780]", 1680 .driver = "EMU10K1", .name = "SB Live! Value [CT4780]",
1674 .id = "Live", 1681 .id = "Live",
1675 .emu10k1_chip = 1, 1682 .emu10k1_chip = 1,
1676 .ac97_chip = 1, 1683 .ac97_chip = 1,
1677 .sblive51 = 1} , 1684 .sblive51 = 1} ,
1678 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x40011102, 1685 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x40011102,
1679 .driver = "EMU10K1", .name = "E-mu APS [4001]", 1686 .driver = "EMU10K1", .name = "E-mu APS [PC545]",
1680 .id = "APS", 1687 .id = "APS",
1681 .emu10k1_chip = 1, 1688 .emu10k1_chip = 1,
1682 .ecard = 1} , 1689 .ecard = 1} ,
1683 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x00211102, 1690 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x00211102,
1684 .driver = "EMU10K1", .name = "SBLive! [CT4620]", 1691 .driver = "EMU10K1", .name = "SB Live! [CT4620]",
1685 .id = "Live", 1692 .id = "Live",
1686 .emu10k1_chip = 1, 1693 .emu10k1_chip = 1,
1687 .ac97_chip = 1, 1694 .ac97_chip = 1,
1688 .sblive51 = 1} , 1695 .sblive51 = 1} ,
1689 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x00201102, 1696 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x00201102,
1690 .driver = "EMU10K1", .name = "SBLive! Value [CT4670]", 1697 .driver = "EMU10K1", .name = "SB Live! Value [CT4670]",
1691 .id = "Live", 1698 .id = "Live",
1692 .emu10k1_chip = 1, 1699 .emu10k1_chip = 1,
1693 .ac97_chip = 1, 1700 .ac97_chip = 1,
1694 .sblive51 = 1} , 1701 .sblive51 = 1} ,
1695 {.vendor = 0x1102, .device = 0x0002, 1702 {.vendor = 0x1102, .device = 0x0002,
1696 .driver = "EMU10K1", .name = "SB Live [Unknown]", 1703 .driver = "EMU10K1", .name = "SB Live! [Unknown]",
1697 .id = "Live", 1704 .id = "Live",
1698 .emu10k1_chip = 1, 1705 .emu10k1_chip = 1,
1699 .ac97_chip = 1, 1706 .ac97_chip = 1,
@@ -1702,13 +1709,13 @@ static struct snd_emu_chip_details emu_chip_details[] = {
1702}; 1709};
1703 1710
1704int __devinit snd_emu10k1_create(struct snd_card *card, 1711int __devinit snd_emu10k1_create(struct snd_card *card,
1705 struct pci_dev * pci, 1712 struct pci_dev *pci,
1706 unsigned short extin_mask, 1713 unsigned short extin_mask,
1707 unsigned short extout_mask, 1714 unsigned short extout_mask,
1708 long max_cache_bytes, 1715 long max_cache_bytes,
1709 int enable_ir, 1716 int enable_ir,
1710 uint subsystem, 1717 uint subsystem,
1711 struct snd_emu10k1 ** remu) 1718 struct snd_emu10k1 **remu)
1712{ 1719{
1713 struct snd_emu10k1 *emu; 1720 struct snd_emu10k1 *emu;
1714 int idx, err; 1721 int idx, err;
@@ -1718,11 +1725,12 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
1718 static struct snd_device_ops ops = { 1725 static struct snd_device_ops ops = {
1719 .dev_free = snd_emu10k1_dev_free, 1726 .dev_free = snd_emu10k1_dev_free,
1720 }; 1727 };
1721 1728
1722 *remu = NULL; 1729 *remu = NULL;
1723 1730
1724 /* enable PCI device */ 1731 /* enable PCI device */
1725 if ((err = pci_enable_device(pci)) < 0) 1732 err = pci_enable_device(pci);
1733 if (err < 0)
1726 return err; 1734 return err;
1727 1735
1728 emu = kzalloc(sizeof(*emu), GFP_KERNEL); 1736 emu = kzalloc(sizeof(*emu), GFP_KERNEL);
@@ -1749,16 +1757,17 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
1749 emu->revision = pci->revision; 1757 emu->revision = pci->revision;
1750 pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &emu->serial); 1758 pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &emu->serial);
1751 pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &emu->model); 1759 pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &emu->model);
1752 snd_printdd("vendor=0x%x, device=0x%x, subsystem_vendor_id=0x%x, subsystem_id=0x%x\n",pci->vendor, pci->device, emu->serial, emu->model); 1760 snd_printdd("vendor = 0x%x, device = 0x%x, subsystem_vendor_id = 0x%x, subsystem_id = 0x%x\n", pci->vendor, pci->device, emu->serial, emu->model);
1753 1761
1754 for (c = emu_chip_details; c->vendor; c++) { 1762 for (c = emu_chip_details; c->vendor; c++) {
1755 if (c->vendor == pci->vendor && c->device == pci->device) { 1763 if (c->vendor == pci->vendor && c->device == pci->device) {
1756 if (subsystem) { 1764 if (subsystem) {
1757 if (c->subsystem && (c->subsystem == subsystem) ) { 1765 if (c->subsystem && (c->subsystem == subsystem))
1758 break; 1766 break;
1759 } else continue; 1767 else
1768 continue;
1760 } else { 1769 } else {
1761 if (c->subsystem && (c->subsystem != emu->serial) ) 1770 if (c->subsystem && (c->subsystem != emu->serial))
1762 continue; 1771 continue;
1763 if (c->revision && c->revision != emu->revision) 1772 if (c->revision && c->revision != emu->revision)
1764 continue; 1773 continue;
@@ -1774,14 +1783,18 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
1774 } 1783 }
1775 emu->card_capabilities = c; 1784 emu->card_capabilities = c;
1776 if (c->subsystem && !subsystem) 1785 if (c->subsystem && !subsystem)
1777 snd_printdd("Sound card name=%s\n", c->name); 1786 snd_printdd("Sound card name = %s\n", c->name);
1778 else if (subsystem) 1787 else if (subsystem)
1779 snd_printdd("Sound card name=%s, vendor=0x%x, device=0x%x, subsystem=0x%x. Forced to subsytem=0x%x\n", 1788 snd_printdd("Sound card name = %s, "
1780 c->name, pci->vendor, pci->device, emu->serial, c->subsystem); 1789 "vendor = 0x%x, device = 0x%x, subsystem = 0x%x. "
1781 else 1790 "Forced to subsytem = 0x%x\n", c->name,
1782 snd_printdd("Sound card name=%s, vendor=0x%x, device=0x%x, subsystem=0x%x.\n", 1791 pci->vendor, pci->device, emu->serial, c->subsystem);
1783 c->name, pci->vendor, pci->device, emu->serial); 1792 else
1784 1793 snd_printdd("Sound card name = %s, "
1794 "vendor = 0x%x, device = 0x%x, subsystem = 0x%x.\n",
1795 c->name, pci->vendor, pci->device,
1796 emu->serial);
1797
1785 if (!*card->id && c->id) { 1798 if (!*card->id && c->id) {
1786 int i, n = 0; 1799 int i, n = 0;
1787 strlcpy(card->id, c->id, sizeof(card->id)); 1800 strlcpy(card->id, c->id, sizeof(card->id));
@@ -1815,7 +1828,8 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
1815 else 1828 else
1816 emu->gpr_base = FXGPREGBASE; 1829 emu->gpr_base = FXGPREGBASE;
1817 1830
1818 if ((err = pci_request_regions(pci, "EMU10K1")) < 0) { 1831 err = pci_request_regions(pci, "EMU10K1");
1832 if (err < 0) {
1819 kfree(emu); 1833 kfree(emu);
1820 pci_disable_device(pci); 1834 pci_disable_device(pci);
1821 return err; 1835 return err;
@@ -1862,21 +1876,25 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
1862 emu->enable_ir = enable_ir; 1876 emu->enable_ir = enable_ir;
1863 1877
1864 if (emu->card_capabilities->ca_cardbus_chip) { 1878 if (emu->card_capabilities->ca_cardbus_chip) {
1865 if ((err = snd_emu10k1_cardbus_init(emu)) < 0) 1879 err = snd_emu10k1_cardbus_init(emu);
1880 if (err < 0)
1866 goto error; 1881 goto error;
1867 } 1882 }
1868 if (emu->card_capabilities->ecard) { 1883 if (emu->card_capabilities->ecard) {
1869 if ((err = snd_emu10k1_ecard_init(emu)) < 0) 1884 err = snd_emu10k1_ecard_init(emu);
1885 if (err < 0)
1870 goto error; 1886 goto error;
1871 } else if (emu->card_capabilities->emu_model) { 1887 } else if (emu->card_capabilities->emu_model) {
1872 if ((err = snd_emu10k1_emu1010_init(emu)) < 0) { 1888 err = snd_emu10k1_emu1010_init(emu);
1873 snd_emu10k1_free(emu); 1889 if (err < 0) {
1874 return err; 1890 snd_emu10k1_free(emu);
1875 } 1891 return err;
1892 }
1876 } else { 1893 } else {
1877 /* 5.1: Enable the additional AC97 Slots. If the emu10k1 version 1894 /* 5.1: Enable the additional AC97 Slots. If the emu10k1 version
1878 does not support this, it shouldn't do any harm */ 1895 does not support this, it shouldn't do any harm */
1879 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE); 1896 snd_emu10k1_ptr_write(emu, AC97SLOT, 0,
1897 AC97SLOT_CNTR|AC97SLOT_LFE);
1880 } 1898 }
1881 1899
1882 /* initialize TRAM setup */ 1900 /* initialize TRAM setup */
@@ -1916,7 +1934,7 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
1916 snd_emu10k1_synth_alloc(emu, 4096); 1934 snd_emu10k1_synth_alloc(emu, 4096);
1917 if (emu->reserved_page) 1935 if (emu->reserved_page)
1918 emu->reserved_page->map_locked = 1; 1936 emu->reserved_page->map_locked = 1;
1919 1937
1920 /* Clear silent pages and set up pointers */ 1938 /* Clear silent pages and set up pointers */
1921 memset(emu->silent_page.area, 0, PAGE_SIZE); 1939 memset(emu->silent_page.area, 0, PAGE_SIZE);
1922 silent_page = emu->silent_page.addr << 1; 1940 silent_page = emu->silent_page.addr << 1;
@@ -1929,19 +1947,23 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
1929 emu->voices[idx].number = idx; 1947 emu->voices[idx].number = idx;
1930 } 1948 }
1931 1949
1932 if ((err = snd_emu10k1_init(emu, enable_ir, 0)) < 0) 1950 err = snd_emu10k1_init(emu, enable_ir, 0);
1951 if (err < 0)
1933 goto error; 1952 goto error;
1934#ifdef CONFIG_PM 1953#ifdef CONFIG_PM
1935 if ((err = alloc_pm_buffer(emu)) < 0) 1954 err = alloc_pm_buffer(emu);
1955 if (err < 0)
1936 goto error; 1956 goto error;
1937#endif 1957#endif
1938 1958
1939 /* Initialize the effect engine */ 1959 /* Initialize the effect engine */
1940 if ((err = snd_emu10k1_init_efx(emu)) < 0) 1960 err = snd_emu10k1_init_efx(emu);
1961 if (err < 0)
1941 goto error; 1962 goto error;
1942 snd_emu10k1_audio_enable(emu); 1963 snd_emu10k1_audio_enable(emu);
1943 1964
1944 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, emu, &ops)) < 0) 1965 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, emu, &ops);
1966 if (err < 0)
1945 goto error; 1967 goto error;
1946 1968
1947#ifdef CONFIG_PROC_FS 1969#ifdef CONFIG_PROC_FS
@@ -1981,7 +2003,7 @@ static int __devinit alloc_pm_buffer(struct snd_emu10k1 *emu)
1981 if (emu->audigy) 2003 if (emu->audigy)
1982 size += ARRAY_SIZE(saved_regs_audigy); 2004 size += ARRAY_SIZE(saved_regs_audigy);
1983 emu->saved_ptr = vmalloc(4 * NUM_G * size); 2005 emu->saved_ptr = vmalloc(4 * NUM_G * size);
1984 if (! emu->saved_ptr) 2006 if (!emu->saved_ptr)
1985 return -ENOMEM; 2007 return -ENOMEM;
1986 if (snd_emu10k1_efx_alloc_pm_buffer(emu) < 0) 2008 if (snd_emu10k1_efx_alloc_pm_buffer(emu) < 0)
1987 return -ENOMEM; 2009 return -ENOMEM;
@@ -2026,7 +2048,7 @@ void snd_emu10k1_resume_init(struct snd_emu10k1 *emu)
2026 if (emu->card_capabilities->ecard) 2048 if (emu->card_capabilities->ecard)
2027 snd_emu10k1_ecard_init(emu); 2049 snd_emu10k1_ecard_init(emu);
2028 else if (emu->card_capabilities->emu_model) 2050 else if (emu->card_capabilities->emu_model)
2029 snd_emu10k1_emu1010_init(emu); 2051 snd_emu10k1_emu1010_init(emu);
2030 else 2052 else
2031 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE); 2053 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE);
2032 snd_emu10k1_init(emu, emu->enable_ir, 1); 2054 snd_emu10k1_init(emu, emu->enable_ir, 1);
diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c
index f34bbfb705f5..b0fb6c917c38 100644
--- a/sound/pci/emu10k1/emumixer.c
+++ b/sound/pci/emu10k1/emumixer.c
@@ -1639,6 +1639,45 @@ static struct snd_kcontrol_new snd_audigy_shared_spdif __devinitdata =
1639 .put = snd_emu10k1_shared_spdif_put 1639 .put = snd_emu10k1_shared_spdif_put
1640}; 1640};
1641 1641
1642/* workaround for too low volume on Audigy due to 16bit/24bit conversion */
1643
1644#define snd_audigy_capture_boost_info snd_ctl_boolean_mono_info
1645
1646static int snd_audigy_capture_boost_get(struct snd_kcontrol *kcontrol,
1647 struct snd_ctl_elem_value *ucontrol)
1648{
1649 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
1650 unsigned int val;
1651
1652 /* FIXME: better to use a cached version */
1653 val = snd_ac97_read(emu->ac97, AC97_REC_GAIN);
1654 ucontrol->value.integer.value[0] = !!val;
1655 return 0;
1656}
1657
1658static int snd_audigy_capture_boost_put(struct snd_kcontrol *kcontrol,
1659 struct snd_ctl_elem_value *ucontrol)
1660{
1661 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
1662 unsigned int val;
1663
1664 if (ucontrol->value.integer.value[0])
1665 val = 0x0f0f;
1666 else
1667 val = 0;
1668 return snd_ac97_update(emu->ac97, AC97_REC_GAIN, val);
1669}
1670
1671static struct snd_kcontrol_new snd_audigy_capture_boost __devinitdata =
1672{
1673 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1674 .name = "Analog Capture Boost",
1675 .info = snd_audigy_capture_boost_info,
1676 .get = snd_audigy_capture_boost_get,
1677 .put = snd_audigy_capture_boost_put
1678};
1679
1680
1642/* 1681/*
1643 */ 1682 */
1644static void snd_emu10k1_mixer_free_ac97(struct snd_ac97 *ac97) 1683static void snd_emu10k1_mixer_free_ac97(struct snd_ac97 *ac97)
@@ -2087,5 +2126,12 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu,
2087 } 2126 }
2088 } 2127 }
2089 2128
2129 if (emu->card_capabilities->ac97_chip && emu->audigy) {
2130 err = snd_ctl_add(card, snd_ctl_new1(&snd_audigy_capture_boost,
2131 emu));
2132 if (err < 0)
2133 return err;
2134 }
2135
2090 return 0; 2136 return 0;
2091} 2137}
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index 20ee7599600b..e9c3794bbcb8 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -1953,7 +1953,7 @@ static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id)
1953 outw(inw(chip->io_port + 4) & 1, chip->io_port + 4); 1953 outw(inw(chip->io_port + 4) & 1, chip->io_port + 4);
1954 1954
1955 if (event & ESM_HWVOL_IRQ) 1955 if (event & ESM_HWVOL_IRQ)
1956 tasklet_hi_schedule(&chip->hwvol_tq); /* we'll do this later */ 1956 tasklet_schedule(&chip->hwvol_tq); /* we'll do this later */
1957 1957
1958 /* else ack 'em all, i imagine */ 1958 /* else ack 'em all, i imagine */
1959 outb(0xFF, chip->io_port + 0x1A); 1959 outb(0xFF, chip->io_port + 0x1A);
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig
new file mode 100644
index 000000000000..eb2a19b894a0
--- /dev/null
+++ b/sound/pci/hda/Kconfig
@@ -0,0 +1,188 @@
1menuconfig SND_HDA_INTEL
2 tristate "Intel HD Audio"
3 select SND_PCM
4 select SND_VMASTER
5 select SND_JACK if INPUT=y || INPUT=SND
6 help
7 Say Y here to include support for Intel "High Definition
8 Audio" (Azalia) and its compatible devices.
9
10 This option enables the HD-audio controller. Don't forget
11 to choose the appropriate codec options below.
12
13 To compile this driver as a module, choose M here: the module
14 will be called snd-hda-intel.
15
16if SND_HDA_INTEL
17
18config SND_HDA_HWDEP
19 bool "Build hwdep interface for HD-audio driver"
20 select SND_HWDEP
21 help
22 Say Y here to build a hwdep interface for HD-audio driver.
23 This interface can be used for out-of-band communication
24 with codecs for debugging purposes.
25
26config SND_HDA_RECONFIG
27 bool "Allow dynamic codec reconfiguration (EXPERIMENTAL)"
28 depends on SND_HDA_HWDEP && EXPERIMENTAL
29 help
30 Say Y here to enable the HD-audio codec re-configuration feature.
31 This adds the sysfs interfaces to allow user to clear the whole
32 codec configuration, change the codec setup, add extra verbs,
33 and re-configure the codec dynamically.
34
35config SND_HDA_INPUT_BEEP
36 bool "Support digital beep via input layer"
37 depends on INPUT=y || INPUT=SND_HDA_INTEL
38 help
39 Say Y here to build a digital beep interface for HD-audio
40 driver. This interface is used to generate digital beeps.
41
42config SND_HDA_CODEC_REALTEK
43 bool "Build Realtek HD-audio codec support"
44 default y
45 help
46 Say Y here to include Realtek HD-audio codec support in
47 snd-hda-intel driver, such as ALC880.
48
49 When the HD-audio driver is built as a module, the codec
50 support code is also built as another module,
51 snd-hda-codec-realtek.
52 This module is automatically loaded at probing.
53
54config SND_HDA_CODEC_ANALOG
55 bool "Build Analog Device HD-audio codec support"
56 default y
57 help
58 Say Y here to include Analog Device HD-audio codec support in
59 snd-hda-intel driver, such as AD1986A.
60
61 When the HD-audio driver is built as a module, the codec
62 support code is also built as another module,
63 snd-hda-codec-analog.
64 This module is automatically loaded at probing.
65
66config SND_HDA_CODEC_SIGMATEL
67 bool "Build IDT/Sigmatel HD-audio codec support"
68 default y
69 help
70 Say Y here to include IDT (Sigmatel) HD-audio codec support in
71 snd-hda-intel driver, such as STAC9200.
72
73 When the HD-audio driver is built as a module, the codec
74 support code is also built as another module,
75 snd-hda-codec-idt.
76 This module is automatically loaded at probing.
77
78config SND_HDA_CODEC_VIA
79 bool "Build VIA HD-audio codec support"
80 default y
81 help
82 Say Y here to include VIA HD-audio codec support in
83 snd-hda-intel driver, such as VT1708.
84
85 When the HD-audio driver is built as a module, the codec
86 support code is also built as another module,
87 snd-hda-codec-via.
88 This module is automatically loaded at probing.
89
90config SND_HDA_CODEC_ATIHDMI
91 bool "Build ATI HDMI HD-audio codec support"
92 default y
93 help
94 Say Y here to include ATI HDMI HD-audio codec support in
95 snd-hda-intel driver, such as ATI RS600 HDMI.
96
97 When the HD-audio driver is built as a module, the codec
98 support code is also built as another module,
99 snd-hda-codec-atihdmi.
100 This module is automatically loaded at probing.
101
102config SND_HDA_CODEC_NVHDMI
103 bool "Build NVIDIA HDMI HD-audio codec support"
104 default y
105 help
106 Say Y here to include NVIDIA HDMI HD-audio codec support in
107 snd-hda-intel driver, such as NVIDIA MCP78 HDMI.
108
109 When the HD-audio driver is built as a module, the codec
110 support code is also built as another module,
111 snd-hda-codec-nvhdmi.
112 This module is automatically loaded at probing.
113
114config SND_HDA_CODEC_INTELHDMI
115 bool "Build INTEL HDMI HD-audio codec support"
116 default y
117 help
118 Say Y here to include INTEL HDMI HD-audio codec support in
119 snd-hda-intel driver, such as Eaglelake integrated HDMI.
120
121 When the HD-audio driver is built as a module, the codec
122 support code is also built as another module,
123 snd-hda-codec-intelhdmi.
124 This module is automatically loaded at probing.
125
126config SND_HDA_ELD
127 def_bool y
128 depends on SND_HDA_CODEC_INTELHDMI
129
130config SND_HDA_CODEC_CONEXANT
131 bool "Build Conexant HD-audio codec support"
132 default y
133 help
134 Say Y here to include Conexant HD-audio codec support in
135 snd-hda-intel driver, such as CX20549.
136
137 When the HD-audio driver is built as a module, the codec
138 support code is also built as another module,
139 snd-hda-codec-conexant.
140 This module is automatically loaded at probing.
141
142config SND_HDA_CODEC_CMEDIA
143 bool "Build C-Media HD-audio codec support"
144 default y
145 help
146 Say Y here to include C-Media HD-audio codec support in
147 snd-hda-intel driver, such as CMI9880.
148
149 When the HD-audio driver is built as a module, the codec
150 support code is also built as another module,
151 snd-hda-codec-cmedia.
152 This module is automatically loaded at probing.
153
154config SND_HDA_CODEC_SI3054
155 bool "Build Silicon Labs 3054 HD-modem codec support"
156 default y
157 help
158 Say Y here to include Silicon Labs 3054 HD-modem codec
159 (and compatibles) support in snd-hda-intel driver.
160
161 When the HD-audio driver is built as a module, the codec
162 support code is also built as another module,
163 snd-hda-codec-si3054.
164 This module is automatically loaded at probing.
165
166config SND_HDA_GENERIC
167 bool "Enable generic HD-audio codec parser"
168 default y
169 help
170 Say Y here to enable the generic HD-audio codec parser
171 in snd-hda-intel driver.
172
173config SND_HDA_POWER_SAVE
174 bool "Aggressive power-saving on HD-audio"
175 help
176 Say Y here to enable more aggressive power-saving mode on
177 HD-audio driver. The power-saving timeout can be configured
178 via power_save option or over sysfs on-the-fly.
179
180config SND_HDA_POWER_SAVE_DEFAULT
181 int "Default time-out for HD-audio power-save mode"
182 depends on SND_HDA_POWER_SAVE
183 default 0
184 help
185 The default time-out value in seconds for HD-audio automatic
186 power-save mode. 0 means to disable the power-save mode.
187
188endif
diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile
index 1980c6d207e7..50f9d0967251 100644
--- a/sound/pci/hda/Makefile
+++ b/sound/pci/hda/Makefile
@@ -1,20 +1,59 @@
1snd-hda-intel-y := hda_intel.o 1snd-hda-intel-objs := hda_intel.o
2# since snd-hda-intel is the only driver using hda-codec,
3# merge it into a single module although it was originally
4# designed to be individual modules
5snd-hda-intel-y += hda_codec.o
6snd-hda-intel-$(CONFIG_PROC_FS) += hda_proc.o
7snd-hda-intel-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o
8snd-hda-intel-$(CONFIG_SND_HDA_INPUT_BEEP) += hda_beep.o
9snd-hda-intel-$(CONFIG_SND_HDA_GENERIC) += hda_generic.o
10snd-hda-intel-$(CONFIG_SND_HDA_CODEC_REALTEK) += patch_realtek.o
11snd-hda-intel-$(CONFIG_SND_HDA_CODEC_CMEDIA) += patch_cmedia.o
12snd-hda-intel-$(CONFIG_SND_HDA_CODEC_ANALOG) += patch_analog.o
13snd-hda-intel-$(CONFIG_SND_HDA_CODEC_SIGMATEL) += patch_sigmatel.o
14snd-hda-intel-$(CONFIG_SND_HDA_CODEC_SI3054) += patch_si3054.o
15snd-hda-intel-$(CONFIG_SND_HDA_CODEC_ATIHDMI) += patch_atihdmi.o
16snd-hda-intel-$(CONFIG_SND_HDA_CODEC_CONEXANT) += patch_conexant.o
17snd-hda-intel-$(CONFIG_SND_HDA_CODEC_VIA) += patch_via.o
18snd-hda-intel-$(CONFIG_SND_HDA_CODEC_NVHDMI) += patch_nvhdmi.o
19 2
3snd-hda-codec-y := hda_codec.o
4snd-hda-codec-$(CONFIG_SND_HDA_GENERIC) += hda_generic.o
5snd-hda-codec-$(CONFIG_PROC_FS) += hda_proc.o
6# snd-hda-codec-$(CONFIG_SND_HDA_ELD) += hda_eld.o
7snd-hda-codec-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o
8snd-hda-codec-$(CONFIG_SND_HDA_INPUT_BEEP) += hda_beep.o
9
10snd-hda-codec-realtek-objs := patch_realtek.o
11snd-hda-codec-cmedia-objs := patch_cmedia.o
12snd-hda-codec-analog-objs := patch_analog.o
13snd-hda-codec-idt-objs := patch_sigmatel.o
14snd-hda-codec-si3054-objs := patch_si3054.o
15snd-hda-codec-atihdmi-objs := patch_atihdmi.o
16snd-hda-codec-conexant-objs := patch_conexant.o
17snd-hda-codec-via-objs := patch_via.o
18snd-hda-codec-nvhdmi-objs := patch_nvhdmi.o
19snd-hda-codec-intelhdmi-objs := patch_intelhdmi.o hda_eld.o
20
21# common driver
22obj-$(CONFIG_SND_HDA_INTEL) := snd-hda-codec.o
23
24# codec drivers (note: CONFIG_SND_HDA_CODEC_XXX are booleans)
25ifdef CONFIG_SND_HDA_CODEC_REALTEK
26obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-realtek.o
27endif
28ifdef CONFIG_SND_HDA_CODEC_CMEDIA
29obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-cmedia.o
30endif
31ifdef CONFIG_SND_HDA_CODEC_ANALOG
32obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-analog.o
33endif
34ifdef CONFIG_SND_HDA_CODEC_SIGMATEL
35obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-idt.o
36endif
37ifdef CONFIG_SND_HDA_CODEC_SI3054
38obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-si3054.o
39endif
40ifdef CONFIG_SND_HDA_CODEC_ATIHDMI
41obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-atihdmi.o
42endif
43ifdef CONFIG_SND_HDA_CODEC_CONEXANT
44obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-conexant.o
45endif
46ifdef CONFIG_SND_HDA_CODEC_VIA
47obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-via.o
48endif
49ifdef CONFIG_SND_HDA_CODEC_NVHDMI
50obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-nvhdmi.o
51endif
52ifdef CONFIG_SND_HDA_CODEC_INTELHDMI
53obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-intelhdmi.o
54endif
55
56# this must be the last entry after codec drivers;
57# otherwise the codec patches won't be hooked before the PCI probe
58# when built in kernel
20obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-intel.o 59obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-intel.o
diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c
index 3ecd7e797dee..e00421c0d8ba 100644
--- a/sound/pci/hda/hda_beep.c
+++ b/sound/pci/hda/hda_beep.c
@@ -128,6 +128,7 @@ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid)
128 INIT_WORK(&beep->beep_work, &snd_hda_generate_beep); 128 INIT_WORK(&beep->beep_work, &snd_hda_generate_beep);
129 return 0; 129 return 0;
130} 130}
131EXPORT_SYMBOL_HDA(snd_hda_attach_beep_device);
131 132
132void snd_hda_detach_beep_device(struct hda_codec *codec) 133void snd_hda_detach_beep_device(struct hda_codec *codec)
133{ 134{
@@ -140,3 +141,4 @@ void snd_hda_detach_beep_device(struct hda_codec *codec)
140 kfree(beep); 141 kfree(beep);
141 } 142 }
142} 143}
144EXPORT_SYMBOL_HDA(snd_hda_detach_beep_device);
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index eb9164176dab..e16cf63821ae 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -31,15 +31,6 @@
31#include <sound/initval.h> 31#include <sound/initval.h>
32#include "hda_local.h" 32#include "hda_local.h"
33#include <sound/hda_hwdep.h> 33#include <sound/hda_hwdep.h>
34#include "hda_patch.h" /* codec presets */
35
36#ifdef CONFIG_SND_HDA_POWER_SAVE
37/* define this option here to hide as static */
38static int power_save = CONFIG_SND_HDA_POWER_SAVE_DEFAULT;
39module_param(power_save, int, 0644);
40MODULE_PARM_DESC(power_save, "Automatic power-saving timeout "
41 "(in second, 0 = disable).");
42#endif
43 34
44/* 35/*
45 * vendor / preset table 36 * vendor / preset table
@@ -55,6 +46,7 @@ static struct hda_vendor_id hda_vendor_ids[] = {
55 { 0x1002, "ATI" }, 46 { 0x1002, "ATI" },
56 { 0x1057, "Motorola" }, 47 { 0x1057, "Motorola" },
57 { 0x1095, "Silicon Image" }, 48 { 0x1095, "Silicon Image" },
49 { 0x10de, "Nvidia" },
58 { 0x10ec, "Realtek" }, 50 { 0x10ec, "Realtek" },
59 { 0x1106, "VIA" }, 51 { 0x1106, "VIA" },
60 { 0x111d, "IDT" }, 52 { 0x111d, "IDT" },
@@ -66,40 +58,31 @@ static struct hda_vendor_id hda_vendor_ids[] = {
66 { 0x1854, "LG" }, 58 { 0x1854, "LG" },
67 { 0x1aec, "Wolfson Microelectronics" }, 59 { 0x1aec, "Wolfson Microelectronics" },
68 { 0x434d, "C-Media" }, 60 { 0x434d, "C-Media" },
61 { 0x8086, "Intel" },
69 { 0x8384, "SigmaTel" }, 62 { 0x8384, "SigmaTel" },
70 {} /* terminator */ 63 {} /* terminator */
71}; 64};
72 65
73static const struct hda_codec_preset *hda_preset_tables[] = { 66static DEFINE_MUTEX(preset_mutex);
74#ifdef CONFIG_SND_HDA_CODEC_REALTEK 67static LIST_HEAD(hda_preset_tables);
75 snd_hda_preset_realtek, 68
76#endif 69int snd_hda_add_codec_preset(struct hda_codec_preset_list *preset)
77#ifdef CONFIG_SND_HDA_CODEC_CMEDIA 70{
78 snd_hda_preset_cmedia, 71 mutex_lock(&preset_mutex);
79#endif 72 list_add_tail(&preset->list, &hda_preset_tables);
80#ifdef CONFIG_SND_HDA_CODEC_ANALOG 73 mutex_unlock(&preset_mutex);
81 snd_hda_preset_analog, 74 return 0;
82#endif 75}
83#ifdef CONFIG_SND_HDA_CODEC_SIGMATEL 76EXPORT_SYMBOL_HDA(snd_hda_add_codec_preset);
84 snd_hda_preset_sigmatel, 77
85#endif 78int snd_hda_delete_codec_preset(struct hda_codec_preset_list *preset)
86#ifdef CONFIG_SND_HDA_CODEC_SI3054 79{
87 snd_hda_preset_si3054, 80 mutex_lock(&preset_mutex);
88#endif 81 list_del(&preset->list);
89#ifdef CONFIG_SND_HDA_CODEC_ATIHDMI 82 mutex_unlock(&preset_mutex);
90 snd_hda_preset_atihdmi, 83 return 0;
91#endif 84}
92#ifdef CONFIG_SND_HDA_CODEC_CONEXANT 85EXPORT_SYMBOL_HDA(snd_hda_delete_codec_preset);
93 snd_hda_preset_conexant,
94#endif
95#ifdef CONFIG_SND_HDA_CODEC_VIA
96 snd_hda_preset_via,
97#endif
98#ifdef CONFIG_SND_HDA_CODEC_NVHDMI
99 snd_hda_preset_nvhdmi,
100#endif
101 NULL
102};
103 86
104#ifdef CONFIG_SND_HDA_POWER_SAVE 87#ifdef CONFIG_SND_HDA_POWER_SAVE
105static void hda_power_work(struct work_struct *work); 88static void hda_power_work(struct work_struct *work);
@@ -108,6 +91,72 @@ static void hda_keep_power_on(struct hda_codec *codec);
108static inline void hda_keep_power_on(struct hda_codec *codec) {} 91static inline void hda_keep_power_on(struct hda_codec *codec) {}
109#endif 92#endif
110 93
94const char *snd_hda_get_jack_location(u32 cfg)
95{
96 static char *bases[7] = {
97 "N/A", "Rear", "Front", "Left", "Right", "Top", "Bottom",
98 };
99 static unsigned char specials_idx[] = {
100 0x07, 0x08,
101 0x17, 0x18, 0x19,
102 0x37, 0x38
103 };
104 static char *specials[] = {
105 "Rear Panel", "Drive Bar",
106 "Riser", "HDMI", "ATAPI",
107 "Mobile-In", "Mobile-Out"
108 };
109 int i;
110 cfg = (cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT;
111 if ((cfg & 0x0f) < 7)
112 return bases[cfg & 0x0f];
113 for (i = 0; i < ARRAY_SIZE(specials_idx); i++) {
114 if (cfg == specials_idx[i])
115 return specials[i];
116 }
117 return "UNKNOWN";
118}
119EXPORT_SYMBOL_HDA(snd_hda_get_jack_location);
120
121const char *snd_hda_get_jack_connectivity(u32 cfg)
122{
123 static char *jack_locations[4] = { "Ext", "Int", "Sep", "Oth" };
124
125 return jack_locations[(cfg >> (AC_DEFCFG_LOCATION_SHIFT + 4)) & 3];
126}
127EXPORT_SYMBOL_HDA(snd_hda_get_jack_connectivity);
128
129const char *snd_hda_get_jack_type(u32 cfg)
130{
131 static char *jack_types[16] = {
132 "Line Out", "Speaker", "HP Out", "CD",
133 "SPDIF Out", "Digital Out", "Modem Line", "Modem Hand",
134 "Line In", "Aux", "Mic", "Telephony",
135 "SPDIF In", "Digitial In", "Reserved", "Other"
136 };
137
138 return jack_types[(cfg & AC_DEFCFG_DEVICE)
139 >> AC_DEFCFG_DEVICE_SHIFT];
140}
141EXPORT_SYMBOL_HDA(snd_hda_get_jack_type);
142
143/*
144 * Compose a 32bit command word to be sent to the HD-audio controller
145 */
146static inline unsigned int
147make_codec_cmd(struct hda_codec *codec, hda_nid_t nid, int direct,
148 unsigned int verb, unsigned int parm)
149{
150 u32 val;
151
152 val = (u32)(codec->addr & 0x0f) << 28;
153 val |= (u32)direct << 27;
154 val |= (u32)nid << 20;
155 val |= verb << 8;
156 val |= parm;
157 return val;
158}
159
111/** 160/**
112 * snd_hda_codec_read - send a command and get the response 161 * snd_hda_codec_read - send a command and get the response
113 * @codec: the HDA codec 162 * @codec: the HDA codec
@@ -124,17 +173,21 @@ unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid,
124 int direct, 173 int direct,
125 unsigned int verb, unsigned int parm) 174 unsigned int verb, unsigned int parm)
126{ 175{
176 struct hda_bus *bus = codec->bus;
127 unsigned int res; 177 unsigned int res;
178
179 res = make_codec_cmd(codec, nid, direct, verb, parm);
128 snd_hda_power_up(codec); 180 snd_hda_power_up(codec);
129 mutex_lock(&codec->bus->cmd_mutex); 181 mutex_lock(&bus->cmd_mutex);
130 if (!codec->bus->ops.command(codec, nid, direct, verb, parm)) 182 if (!bus->ops.command(bus, res))
131 res = codec->bus->ops.get_response(codec); 183 res = bus->ops.get_response(bus);
132 else 184 else
133 res = (unsigned int)-1; 185 res = (unsigned int)-1;
134 mutex_unlock(&codec->bus->cmd_mutex); 186 mutex_unlock(&bus->cmd_mutex);
135 snd_hda_power_down(codec); 187 snd_hda_power_down(codec);
136 return res; 188 return res;
137} 189}
190EXPORT_SYMBOL_HDA(snd_hda_codec_read);
138 191
139/** 192/**
140 * snd_hda_codec_write - send a single command without waiting for response 193 * snd_hda_codec_write - send a single command without waiting for response
@@ -151,14 +204,19 @@ unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid,
151int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct, 204int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct,
152 unsigned int verb, unsigned int parm) 205 unsigned int verb, unsigned int parm)
153{ 206{
207 struct hda_bus *bus = codec->bus;
208 unsigned int res;
154 int err; 209 int err;
210
211 res = make_codec_cmd(codec, nid, direct, verb, parm);
155 snd_hda_power_up(codec); 212 snd_hda_power_up(codec);
156 mutex_lock(&codec->bus->cmd_mutex); 213 mutex_lock(&bus->cmd_mutex);
157 err = codec->bus->ops.command(codec, nid, direct, verb, parm); 214 err = bus->ops.command(bus, res);
158 mutex_unlock(&codec->bus->cmd_mutex); 215 mutex_unlock(&bus->cmd_mutex);
159 snd_hda_power_down(codec); 216 snd_hda_power_down(codec);
160 return err; 217 return err;
161} 218}
219EXPORT_SYMBOL_HDA(snd_hda_codec_write);
162 220
163/** 221/**
164 * snd_hda_sequence_write - sequence writes 222 * snd_hda_sequence_write - sequence writes
@@ -173,6 +231,7 @@ void snd_hda_sequence_write(struct hda_codec *codec, const struct hda_verb *seq)
173 for (; seq->nid; seq++) 231 for (; seq->nid; seq++)
174 snd_hda_codec_write(codec, seq->nid, 0, seq->verb, seq->param); 232 snd_hda_codec_write(codec, seq->nid, 0, seq->verb, seq->param);
175} 233}
234EXPORT_SYMBOL_HDA(snd_hda_sequence_write);
176 235
177/** 236/**
178 * snd_hda_get_sub_nodes - get the range of sub nodes 237 * snd_hda_get_sub_nodes - get the range of sub nodes
@@ -194,6 +253,7 @@ int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid,
194 *start_id = (parm >> 16) & 0x7fff; 253 *start_id = (parm >> 16) & 0x7fff;
195 return (int)(parm & 0x7fff); 254 return (int)(parm & 0x7fff);
196} 255}
256EXPORT_SYMBOL_HDA(snd_hda_get_sub_nodes);
197 257
198/** 258/**
199 * snd_hda_get_connections - get connection list 259 * snd_hda_get_connections - get connection list
@@ -282,6 +342,7 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
282 } 342 }
283 return conns; 343 return conns;
284} 344}
345EXPORT_SYMBOL_HDA(snd_hda_get_connections);
285 346
286 347
287/** 348/**
@@ -316,6 +377,7 @@ int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex)
316 377
317 return 0; 378 return 0;
318} 379}
380EXPORT_SYMBOL_HDA(snd_hda_queue_unsol_event);
319 381
320/* 382/*
321 * process queued unsolicited events 383 * process queued unsolicited events
@@ -345,7 +407,7 @@ static void process_unsol_events(struct work_struct *work)
345/* 407/*
346 * initialize unsolicited queue 408 * initialize unsolicited queue
347 */ 409 */
348static int __devinit init_unsol_queue(struct hda_bus *bus) 410static int init_unsol_queue(struct hda_bus *bus)
349{ 411{
350 struct hda_bus_unsolicited *unsol; 412 struct hda_bus_unsolicited *unsol;
351 413
@@ -391,9 +453,24 @@ static int snd_hda_bus_free(struct hda_bus *bus)
391static int snd_hda_bus_dev_free(struct snd_device *device) 453static int snd_hda_bus_dev_free(struct snd_device *device)
392{ 454{
393 struct hda_bus *bus = device->device_data; 455 struct hda_bus *bus = device->device_data;
456 bus->shutdown = 1;
394 return snd_hda_bus_free(bus); 457 return snd_hda_bus_free(bus);
395} 458}
396 459
460#ifdef CONFIG_SND_HDA_HWDEP
461static int snd_hda_bus_dev_register(struct snd_device *device)
462{
463 struct hda_bus *bus = device->device_data;
464 struct hda_codec *codec;
465 list_for_each_entry(codec, &bus->codec_list, list) {
466 snd_hda_hwdep_add_sysfs(codec);
467 }
468 return 0;
469}
470#else
471#define snd_hda_bus_dev_register NULL
472#endif
473
397/** 474/**
398 * snd_hda_bus_new - create a HDA bus 475 * snd_hda_bus_new - create a HDA bus
399 * @card: the card entry 476 * @card: the card entry
@@ -402,13 +479,14 @@ static int snd_hda_bus_dev_free(struct snd_device *device)
402 * 479 *
403 * Returns 0 if successful, or a negative error code. 480 * Returns 0 if successful, or a negative error code.
404 */ 481 */
405int __devinit snd_hda_bus_new(struct snd_card *card, 482int /*__devinit*/ snd_hda_bus_new(struct snd_card *card,
406 const struct hda_bus_template *temp, 483 const struct hda_bus_template *temp,
407 struct hda_bus **busp) 484 struct hda_bus **busp)
408{ 485{
409 struct hda_bus *bus; 486 struct hda_bus *bus;
410 int err; 487 int err;
411 static struct snd_device_ops dev_ops = { 488 static struct snd_device_ops dev_ops = {
489 .dev_register = snd_hda_bus_dev_register,
412 .dev_free = snd_hda_bus_dev_free, 490 .dev_free = snd_hda_bus_dev_free,
413 }; 491 };
414 492
@@ -430,6 +508,7 @@ int __devinit snd_hda_bus_new(struct snd_card *card,
430 bus->private_data = temp->private_data; 508 bus->private_data = temp->private_data;
431 bus->pci = temp->pci; 509 bus->pci = temp->pci;
432 bus->modelname = temp->modelname; 510 bus->modelname = temp->modelname;
511 bus->power_save = temp->power_save;
433 bus->ops = temp->ops; 512 bus->ops = temp->ops;
434 513
435 mutex_init(&bus->cmd_mutex); 514 mutex_init(&bus->cmd_mutex);
@@ -444,27 +523,42 @@ int __devinit snd_hda_bus_new(struct snd_card *card,
444 *busp = bus; 523 *busp = bus;
445 return 0; 524 return 0;
446} 525}
526EXPORT_SYMBOL_HDA(snd_hda_bus_new);
447 527
448#ifdef CONFIG_SND_HDA_GENERIC 528#ifdef CONFIG_SND_HDA_GENERIC
449#define is_generic_config(codec) \ 529#define is_generic_config(codec) \
450 (codec->bus->modelname && !strcmp(codec->bus->modelname, "generic")) 530 (codec->modelname && !strcmp(codec->modelname, "generic"))
451#else 531#else
452#define is_generic_config(codec) 0 532#define is_generic_config(codec) 0
453#endif 533#endif
454 534
535#ifdef MODULE
536#define HDA_MODREQ_MAX_COUNT 2 /* two request_modules()'s */
537#else
538#define HDA_MODREQ_MAX_COUNT 0 /* all presets are statically linked */
539#endif
540
455/* 541/*
456 * find a matching codec preset 542 * find a matching codec preset
457 */ 543 */
458static const struct hda_codec_preset __devinit * 544static const struct hda_codec_preset *
459find_codec_preset(struct hda_codec *codec) 545find_codec_preset(struct hda_codec *codec)
460{ 546{
461 const struct hda_codec_preset **tbl, *preset; 547 struct hda_codec_preset_list *tbl;
548 const struct hda_codec_preset *preset;
549 int mod_requested = 0;
462 550
463 if (is_generic_config(codec)) 551 if (is_generic_config(codec))
464 return NULL; /* use the generic parser */ 552 return NULL; /* use the generic parser */
465 553
466 for (tbl = hda_preset_tables; *tbl; tbl++) { 554 again:
467 for (preset = *tbl; preset->id; preset++) { 555 mutex_lock(&preset_mutex);
556 list_for_each_entry(tbl, &hda_preset_tables, list) {
557 if (!try_module_get(tbl->owner)) {
558 snd_printk(KERN_ERR "hda_codec: cannot module_get\n");
559 continue;
560 }
561 for (preset = tbl->preset; preset->id; preset++) {
468 u32 mask = preset->mask; 562 u32 mask = preset->mask;
469 if (preset->afg && preset->afg != codec->afg) 563 if (preset->afg && preset->afg != codec->afg)
470 continue; 564 continue;
@@ -474,23 +568,40 @@ find_codec_preset(struct hda_codec *codec)
474 mask = ~0; 568 mask = ~0;
475 if (preset->id == (codec->vendor_id & mask) && 569 if (preset->id == (codec->vendor_id & mask) &&
476 (!preset->rev || 570 (!preset->rev ||
477 preset->rev == codec->revision_id)) 571 preset->rev == codec->revision_id)) {
572 mutex_unlock(&preset_mutex);
573 codec->owner = tbl->owner;
478 return preset; 574 return preset;
575 }
479 } 576 }
577 module_put(tbl->owner);
578 }
579 mutex_unlock(&preset_mutex);
580
581 if (mod_requested < HDA_MODREQ_MAX_COUNT) {
582 char name[32];
583 if (!mod_requested)
584 snprintf(name, sizeof(name), "snd-hda-codec-id:%08x",
585 codec->vendor_id);
586 else
587 snprintf(name, sizeof(name), "snd-hda-codec-id:%04x*",
588 (codec->vendor_id >> 16) & 0xffff);
589 request_module(name);
590 mod_requested++;
591 goto again;
480 } 592 }
481 return NULL; 593 return NULL;
482} 594}
483 595
484/* 596/*
485 * snd_hda_get_codec_name - store the codec name 597 * get_codec_name - store the codec name
486 */ 598 */
487void snd_hda_get_codec_name(struct hda_codec *codec, 599static int get_codec_name(struct hda_codec *codec)
488 char *name, int namelen)
489{ 600{
490 const struct hda_vendor_id *c; 601 const struct hda_vendor_id *c;
491 const char *vendor = NULL; 602 const char *vendor = NULL;
492 u16 vendor_id = codec->vendor_id >> 16; 603 u16 vendor_id = codec->vendor_id >> 16;
493 char tmp[16]; 604 char tmp[16], name[32];
494 605
495 for (c = hda_vendor_ids; c->id; c++) { 606 for (c = hda_vendor_ids; c->id; c++) {
496 if (c->id == vendor_id) { 607 if (c->id == vendor_id) {
@@ -503,16 +614,21 @@ void snd_hda_get_codec_name(struct hda_codec *codec,
503 vendor = tmp; 614 vendor = tmp;
504 } 615 }
505 if (codec->preset && codec->preset->name) 616 if (codec->preset && codec->preset->name)
506 snprintf(name, namelen, "%s %s", vendor, codec->preset->name); 617 snprintf(name, sizeof(name), "%s %s", vendor,
618 codec->preset->name);
507 else 619 else
508 snprintf(name, namelen, "%s ID %x", vendor, 620 snprintf(name, sizeof(name), "%s ID %x", vendor,
509 codec->vendor_id & 0xffff); 621 codec->vendor_id & 0xffff);
622 codec->name = kstrdup(name, GFP_KERNEL);
623 if (!codec->name)
624 return -ENOMEM;
625 return 0;
510} 626}
511 627
512/* 628/*
513 * look for an AFG and MFG nodes 629 * look for an AFG and MFG nodes
514 */ 630 */
515static void __devinit setup_fg_nodes(struct hda_codec *codec) 631static void /*__devinit*/ setup_fg_nodes(struct hda_codec *codec)
516{ 632{
517 int i, total_nodes; 633 int i, total_nodes;
518 hda_nid_t nid; 634 hda_nid_t nid;
@@ -571,11 +687,15 @@ static void snd_hda_codec_free(struct hda_codec *codec)
571 flush_scheduled_work(); 687 flush_scheduled_work();
572#endif 688#endif
573 list_del(&codec->list); 689 list_del(&codec->list);
690 snd_array_free(&codec->mixers);
574 codec->bus->caddr_tbl[codec->addr] = NULL; 691 codec->bus->caddr_tbl[codec->addr] = NULL;
575 if (codec->patch_ops.free) 692 if (codec->patch_ops.free)
576 codec->patch_ops.free(codec); 693 codec->patch_ops.free(codec);
694 module_put(codec->owner);
577 free_hda_cache(&codec->amp_cache); 695 free_hda_cache(&codec->amp_cache);
578 free_hda_cache(&codec->cmd_cache); 696 free_hda_cache(&codec->cmd_cache);
697 kfree(codec->name);
698 kfree(codec->modelname);
579 kfree(codec->wcaps); 699 kfree(codec->wcaps);
580 kfree(codec); 700 kfree(codec);
581} 701}
@@ -588,8 +708,8 @@ static void snd_hda_codec_free(struct hda_codec *codec)
588 * 708 *
589 * Returns 0 if successful, or a negative error code. 709 * Returns 0 if successful, or a negative error code.
590 */ 710 */
591int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, 711int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
592 struct hda_codec **codecp) 712 int do_init, struct hda_codec **codecp)
593{ 713{
594 struct hda_codec *codec; 714 struct hda_codec *codec;
595 char component[31]; 715 char component[31];
@@ -617,6 +737,14 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
617 mutex_init(&codec->spdif_mutex); 737 mutex_init(&codec->spdif_mutex);
618 init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info)); 738 init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info));
619 init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head)); 739 init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head));
740 snd_array_init(&codec->mixers, sizeof(struct snd_kcontrol *), 32);
741 if (codec->bus->modelname) {
742 codec->modelname = kstrdup(codec->bus->modelname, GFP_KERNEL);
743 if (!codec->modelname) {
744 snd_hda_codec_free(codec);
745 return -ENODEV;
746 }
747 }
620 748
621#ifdef CONFIG_SND_HDA_POWER_SAVE 749#ifdef CONFIG_SND_HDA_POWER_SAVE
622 INIT_DELAYED_WORK(&codec->power_work, hda_power_work); 750 INIT_DELAYED_WORK(&codec->power_work, hda_power_work);
@@ -662,12 +790,44 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
662 snd_hda_codec_read(codec, nid, 0, 790 snd_hda_codec_read(codec, nid, 0,
663 AC_VERB_GET_SUBSYSTEM_ID, 0); 791 AC_VERB_GET_SUBSYSTEM_ID, 0);
664 } 792 }
793 if (bus->modelname)
794 codec->modelname = kstrdup(bus->modelname, GFP_KERNEL);
795
796 if (do_init) {
797 err = snd_hda_codec_configure(codec);
798 if (err < 0) {
799 snd_hda_codec_free(codec);
800 return err;
801 }
802 }
803 snd_hda_codec_proc_new(codec);
804
805 snd_hda_create_hwdep(codec);
806
807 sprintf(component, "HDA:%08x,%08x,%08x", codec->vendor_id,
808 codec->subsystem_id, codec->revision_id);
809 snd_component_add(codec->bus->card, component);
810
811 if (codecp)
812 *codecp = codec;
813 return 0;
814}
815EXPORT_SYMBOL_HDA(snd_hda_codec_new);
816
817int snd_hda_codec_configure(struct hda_codec *codec)
818{
819 int err;
665 820
666 codec->preset = find_codec_preset(codec); 821 codec->preset = find_codec_preset(codec);
822 if (!codec->name) {
823 err = get_codec_name(codec);
824 if (err < 0)
825 return err;
826 }
667 /* audio codec should override the mixer name */ 827 /* audio codec should override the mixer name */
668 if (codec->afg || !*bus->card->mixername) 828 if (codec->afg || !*codec->bus->card->mixername)
669 snd_hda_get_codec_name(codec, bus->card->mixername, 829 strlcpy(codec->bus->card->mixername, codec->name,
670 sizeof(bus->card->mixername)); 830 sizeof(codec->bus->card->mixername));
671 831
672 if (is_generic_config(codec)) { 832 if (is_generic_config(codec)) {
673 err = snd_hda_parse_generic_codec(codec); 833 err = snd_hda_parse_generic_codec(codec);
@@ -684,25 +844,9 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
684 printk(KERN_ERR "hda-codec: No codec parser is available\n"); 844 printk(KERN_ERR "hda-codec: No codec parser is available\n");
685 845
686 patched: 846 patched:
687 if (err < 0) { 847 if (!err && codec->patch_ops.unsol_event)
688 snd_hda_codec_free(codec); 848 err = init_unsol_queue(codec->bus);
689 return err; 849 return err;
690 }
691
692 if (codec->patch_ops.unsol_event)
693 init_unsol_queue(bus);
694
695 snd_hda_codec_proc_new(codec);
696#ifdef CONFIG_SND_HDA_HWDEP
697 snd_hda_create_hwdep(codec);
698#endif
699
700 sprintf(component, "HDA:%08x,%08x,%08x", codec->vendor_id, codec->subsystem_id, codec->revision_id);
701 snd_component_add(codec->bus->card, component);
702
703 if (codecp)
704 *codecp = codec;
705 return 0;
706} 850}
707 851
708/** 852/**
@@ -728,6 +872,7 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
728 msleep(1); 872 msleep(1);
729 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, format); 873 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, format);
730} 874}
875EXPORT_SYMBOL_HDA(snd_hda_codec_setup_stream);
731 876
732void snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid) 877void snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid)
733{ 878{
@@ -741,6 +886,7 @@ void snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid)
741 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, 0); 886 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, 0);
742#endif 887#endif
743} 888}
889EXPORT_SYMBOL_HDA(snd_hda_codec_cleanup_stream);
744 890
745/* 891/*
746 * amp access functions 892 * amp access functions
@@ -752,17 +898,17 @@ void snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid)
752#define INFO_AMP_VOL(ch) (1 << (1 + (ch))) 898#define INFO_AMP_VOL(ch) (1 << (1 + (ch)))
753 899
754/* initialize the hash table */ 900/* initialize the hash table */
755static void __devinit init_hda_cache(struct hda_cache_rec *cache, 901static void /*__devinit*/ init_hda_cache(struct hda_cache_rec *cache,
756 unsigned int record_size) 902 unsigned int record_size)
757{ 903{
758 memset(cache, 0, sizeof(*cache)); 904 memset(cache, 0, sizeof(*cache));
759 memset(cache->hash, 0xff, sizeof(cache->hash)); 905 memset(cache->hash, 0xff, sizeof(cache->hash));
760 cache->record_size = record_size; 906 snd_array_init(&cache->buf, record_size, 64);
761} 907}
762 908
763static void free_hda_cache(struct hda_cache_rec *cache) 909static void free_hda_cache(struct hda_cache_rec *cache)
764{ 910{
765 kfree(cache->buffer); 911 snd_array_free(&cache->buf);
766} 912}
767 913
768/* query the hash. allocate an entry if not found. */ 914/* query the hash. allocate an entry if not found. */
@@ -774,35 +920,17 @@ static struct hda_cache_head *get_alloc_hash(struct hda_cache_rec *cache,
774 struct hda_cache_head *info; 920 struct hda_cache_head *info;
775 921
776 while (cur != 0xffff) { 922 while (cur != 0xffff) {
777 info = (struct hda_cache_head *)(cache->buffer + 923 info = snd_array_elem(&cache->buf, cur);
778 cur * cache->record_size);
779 if (info->key == key) 924 if (info->key == key)
780 return info; 925 return info;
781 cur = info->next; 926 cur = info->next;
782 } 927 }
783 928
784 /* add a new hash entry */ 929 /* add a new hash entry */
785 if (cache->num_entries >= cache->size) { 930 info = snd_array_new(&cache->buf);
786 /* reallocate the array */ 931 if (!info)
787 unsigned int new_size = cache->size + 64; 932 return NULL;
788 void *new_buffer; 933 cur = snd_array_index(&cache->buf, info);
789 new_buffer = kcalloc(new_size, cache->record_size, GFP_KERNEL);
790 if (!new_buffer) {
791 snd_printk(KERN_ERR "hda_codec: "
792 "can't malloc amp_info\n");
793 return NULL;
794 }
795 if (cache->buffer) {
796 memcpy(new_buffer, cache->buffer,
797 cache->size * cache->record_size);
798 kfree(cache->buffer);
799 }
800 cache->size = new_size;
801 cache->buffer = new_buffer;
802 }
803 cur = cache->num_entries++;
804 info = (struct hda_cache_head *)(cache->buffer +
805 cur * cache->record_size);
806 info->key = key; 934 info->key = key;
807 info->val = 0; 935 info->val = 0;
808 info->next = cache->hash[idx]; 936 info->next = cache->hash[idx];
@@ -840,6 +968,7 @@ u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction)
840 } 968 }
841 return info->amp_caps; 969 return info->amp_caps;
842} 970}
971EXPORT_SYMBOL_HDA(query_amp_caps);
843 972
844int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, 973int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
845 unsigned int caps) 974 unsigned int caps)
@@ -853,6 +982,7 @@ int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
853 info->head.val |= INFO_AMP_CAPS; 982 info->head.val |= INFO_AMP_CAPS;
854 return 0; 983 return 0;
855} 984}
985EXPORT_SYMBOL_HDA(snd_hda_override_amp_caps);
856 986
857/* 987/*
858 * read the current volume to info 988 * read the current volume to info
@@ -906,6 +1036,7 @@ int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch,
906 return 0; 1036 return 0;
907 return get_vol_mute(codec, info, nid, ch, direction, index); 1037 return get_vol_mute(codec, info, nid, ch, direction, index);
908} 1038}
1039EXPORT_SYMBOL_HDA(snd_hda_codec_amp_read);
909 1040
910/* 1041/*
911 * update the AMP value, mask = bit mask to set, val = the value 1042 * update the AMP value, mask = bit mask to set, val = the value
@@ -925,6 +1056,7 @@ int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch,
925 put_vol_mute(codec, info, nid, ch, direction, idx, val); 1056 put_vol_mute(codec, info, nid, ch, direction, idx, val);
926 return 1; 1057 return 1;
927} 1058}
1059EXPORT_SYMBOL_HDA(snd_hda_codec_amp_update);
928 1060
929/* 1061/*
930 * update the AMP stereo with the same mask and value 1062 * update the AMP stereo with the same mask and value
@@ -938,15 +1070,16 @@ int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid,
938 idx, mask, val); 1070 idx, mask, val);
939 return ret; 1071 return ret;
940} 1072}
1073EXPORT_SYMBOL_HDA(snd_hda_codec_amp_stereo);
941 1074
942#ifdef SND_HDA_NEEDS_RESUME 1075#ifdef SND_HDA_NEEDS_RESUME
943/* resume the all amp commands from the cache */ 1076/* resume the all amp commands from the cache */
944void snd_hda_codec_resume_amp(struct hda_codec *codec) 1077void snd_hda_codec_resume_amp(struct hda_codec *codec)
945{ 1078{
946 struct hda_amp_info *buffer = codec->amp_cache.buffer; 1079 struct hda_amp_info *buffer = codec->amp_cache.buf.list;
947 int i; 1080 int i;
948 1081
949 for (i = 0; i < codec->amp_cache.size; i++, buffer++) { 1082 for (i = 0; i < codec->amp_cache.buf.used; i++, buffer++) {
950 u32 key = buffer->head.key; 1083 u32 key = buffer->head.key;
951 hda_nid_t nid; 1084 hda_nid_t nid;
952 unsigned int idx, dir, ch; 1085 unsigned int idx, dir, ch;
@@ -963,6 +1096,7 @@ void snd_hda_codec_resume_amp(struct hda_codec *codec)
963 } 1096 }
964 } 1097 }
965} 1098}
1099EXPORT_SYMBOL_HDA(snd_hda_codec_resume_amp);
966#endif /* SND_HDA_NEEDS_RESUME */ 1100#endif /* SND_HDA_NEEDS_RESUME */
967 1101
968/* volume */ 1102/* volume */
@@ -990,6 +1124,7 @@ int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol,
990 uinfo->value.integer.max = caps; 1124 uinfo->value.integer.max = caps;
991 return 0; 1125 return 0;
992} 1126}
1127EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_volume_info);
993 1128
994int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol, 1129int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol,
995 struct snd_ctl_elem_value *ucontrol) 1130 struct snd_ctl_elem_value *ucontrol)
@@ -1009,6 +1144,7 @@ int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol,
1009 & HDA_AMP_VOLMASK; 1144 & HDA_AMP_VOLMASK;
1010 return 0; 1145 return 0;
1011} 1146}
1147EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_volume_get);
1012 1148
1013int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol, 1149int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol,
1014 struct snd_ctl_elem_value *ucontrol) 1150 struct snd_ctl_elem_value *ucontrol)
@@ -1033,6 +1169,7 @@ int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol,
1033 snd_hda_power_down(codec); 1169 snd_hda_power_down(codec);
1034 return change; 1170 return change;
1035} 1171}
1172EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_volume_put);
1036 1173
1037int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag, 1174int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1038 unsigned int size, unsigned int __user *_tlv) 1175 unsigned int size, unsigned int __user *_tlv)
@@ -1059,6 +1196,7 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1059 return -EFAULT; 1196 return -EFAULT;
1060 return 0; 1197 return 0;
1061} 1198}
1199EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_tlv);
1062 1200
1063/* 1201/*
1064 * set (static) TLV for virtual master volume; recalculated as max 0dB 1202 * set (static) TLV for virtual master volume; recalculated as max 0dB
@@ -1078,6 +1216,7 @@ void snd_hda_set_vmaster_tlv(struct hda_codec *codec, hda_nid_t nid, int dir,
1078 tlv[2] = -nums * step; 1216 tlv[2] = -nums * step;
1079 tlv[3] = step; 1217 tlv[3] = step;
1080} 1218}
1219EXPORT_SYMBOL_HDA(snd_hda_set_vmaster_tlv);
1081 1220
1082/* find a mixer control element with the given name */ 1221/* find a mixer control element with the given name */
1083static struct snd_kcontrol * 1222static struct snd_kcontrol *
@@ -1097,6 +1236,69 @@ struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec,
1097{ 1236{
1098 return _snd_hda_find_mixer_ctl(codec, name, 0); 1237 return _snd_hda_find_mixer_ctl(codec, name, 0);
1099} 1238}
1239EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl);
1240
1241/* Add a control element and assign to the codec */
1242int snd_hda_ctl_add(struct hda_codec *codec, struct snd_kcontrol *kctl)
1243{
1244 int err;
1245 struct snd_kcontrol **knewp;
1246
1247 err = snd_ctl_add(codec->bus->card, kctl);
1248 if (err < 0)
1249 return err;
1250 knewp = snd_array_new(&codec->mixers);
1251 if (!knewp)
1252 return -ENOMEM;
1253 *knewp = kctl;
1254 return 0;
1255}
1256EXPORT_SYMBOL_HDA(snd_hda_ctl_add);
1257
1258#ifdef CONFIG_SND_HDA_RECONFIG
1259/* Clear all controls assigned to the given codec */
1260void snd_hda_ctls_clear(struct hda_codec *codec)
1261{
1262 int i;
1263 struct snd_kcontrol **kctls = codec->mixers.list;
1264 for (i = 0; i < codec->mixers.used; i++)
1265 snd_ctl_remove(codec->bus->card, kctls[i]);
1266 snd_array_free(&codec->mixers);
1267}
1268
1269void snd_hda_codec_reset(struct hda_codec *codec)
1270{
1271 int i;
1272
1273#ifdef CONFIG_SND_HDA_POWER_SAVE
1274 cancel_delayed_work(&codec->power_work);
1275 flush_scheduled_work();
1276#endif
1277 snd_hda_ctls_clear(codec);
1278 /* relase PCMs */
1279 for (i = 0; i < codec->num_pcms; i++) {
1280 if (codec->pcm_info[i].pcm) {
1281 snd_device_free(codec->bus->card,
1282 codec->pcm_info[i].pcm);
1283 clear_bit(codec->pcm_info[i].device,
1284 codec->bus->pcm_dev_bits);
1285 }
1286 }
1287 if (codec->patch_ops.free)
1288 codec->patch_ops.free(codec);
1289 codec->proc_widget_hook = NULL;
1290 codec->spec = NULL;
1291 free_hda_cache(&codec->amp_cache);
1292 free_hda_cache(&codec->cmd_cache);
1293 init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info));
1294 init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head));
1295 codec->num_pcms = 0;
1296 codec->pcm_info = NULL;
1297 codec->preset = NULL;
1298 module_put(codec->owner);
1299 codec->owner = NULL;
1300}
1301#endif /* CONFIG_SND_HDA_RECONFIG */
1100 1302
1101/* create a virtual master control and add slaves */ 1303/* create a virtual master control and add slaves */
1102int snd_hda_add_vmaster(struct hda_codec *codec, char *name, 1304int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
@@ -1115,7 +1317,7 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
1115 kctl = snd_ctl_make_virtual_master(name, tlv); 1317 kctl = snd_ctl_make_virtual_master(name, tlv);
1116 if (!kctl) 1318 if (!kctl)
1117 return -ENOMEM; 1319 return -ENOMEM;
1118 err = snd_ctl_add(codec->bus->card, kctl); 1320 err = snd_hda_ctl_add(codec, kctl);
1119 if (err < 0) 1321 if (err < 0)
1120 return err; 1322 return err;
1121 1323
@@ -1133,6 +1335,7 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
1133 } 1335 }
1134 return 0; 1336 return 0;
1135} 1337}
1338EXPORT_SYMBOL_HDA(snd_hda_add_vmaster);
1136 1339
1137/* switch */ 1340/* switch */
1138int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, 1341int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol,
@@ -1146,6 +1349,7 @@ int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol,
1146 uinfo->value.integer.max = 1; 1349 uinfo->value.integer.max = 1;
1147 return 0; 1350 return 0;
1148} 1351}
1352EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_info);
1149 1353
1150int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, 1354int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol,
1151 struct snd_ctl_elem_value *ucontrol) 1355 struct snd_ctl_elem_value *ucontrol)
@@ -1165,6 +1369,7 @@ int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol,
1165 HDA_AMP_MUTE) ? 0 : 1; 1369 HDA_AMP_MUTE) ? 0 : 1;
1166 return 0; 1370 return 0;
1167} 1371}
1372EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_get);
1168 1373
1169int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, 1374int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol,
1170 struct snd_ctl_elem_value *ucontrol) 1375 struct snd_ctl_elem_value *ucontrol)
@@ -1195,6 +1400,7 @@ int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol,
1195 snd_hda_power_down(codec); 1400 snd_hda_power_down(codec);
1196 return change; 1401 return change;
1197} 1402}
1403EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put);
1198 1404
1199/* 1405/*
1200 * bound volume controls 1406 * bound volume controls
@@ -1220,6 +1426,7 @@ int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol,
1220 mutex_unlock(&codec->spdif_mutex); 1426 mutex_unlock(&codec->spdif_mutex);
1221 return err; 1427 return err;
1222} 1428}
1429EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_switch_get);
1223 1430
1224int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, 1431int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol,
1225 struct snd_ctl_elem_value *ucontrol) 1432 struct snd_ctl_elem_value *ucontrol)
@@ -1243,6 +1450,7 @@ int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol,
1243 mutex_unlock(&codec->spdif_mutex); 1450 mutex_unlock(&codec->spdif_mutex);
1244 return err < 0 ? err : change; 1451 return err < 0 ? err : change;
1245} 1452}
1453EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_switch_put);
1246 1454
1247/* 1455/*
1248 * generic bound volume/swtich controls 1456 * generic bound volume/swtich controls
@@ -1262,6 +1470,7 @@ int snd_hda_mixer_bind_ctls_info(struct snd_kcontrol *kcontrol,
1262 mutex_unlock(&codec->spdif_mutex); 1470 mutex_unlock(&codec->spdif_mutex);
1263 return err; 1471 return err;
1264} 1472}
1473EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_ctls_info);
1265 1474
1266int snd_hda_mixer_bind_ctls_get(struct snd_kcontrol *kcontrol, 1475int snd_hda_mixer_bind_ctls_get(struct snd_kcontrol *kcontrol,
1267 struct snd_ctl_elem_value *ucontrol) 1476 struct snd_ctl_elem_value *ucontrol)
@@ -1278,6 +1487,7 @@ int snd_hda_mixer_bind_ctls_get(struct snd_kcontrol *kcontrol,
1278 mutex_unlock(&codec->spdif_mutex); 1487 mutex_unlock(&codec->spdif_mutex);
1279 return err; 1488 return err;
1280} 1489}
1490EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_ctls_get);
1281 1491
1282int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol, 1492int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol,
1283 struct snd_ctl_elem_value *ucontrol) 1493 struct snd_ctl_elem_value *ucontrol)
@@ -1300,6 +1510,7 @@ int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol,
1300 mutex_unlock(&codec->spdif_mutex); 1510 mutex_unlock(&codec->spdif_mutex);
1301 return err < 0 ? err : change; 1511 return err < 0 ? err : change;
1302} 1512}
1513EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_ctls_put);
1303 1514
1304int snd_hda_mixer_bind_tlv(struct snd_kcontrol *kcontrol, int op_flag, 1515int snd_hda_mixer_bind_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1305 unsigned int size, unsigned int __user *tlv) 1516 unsigned int size, unsigned int __user *tlv)
@@ -1316,6 +1527,7 @@ int snd_hda_mixer_bind_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1316 mutex_unlock(&codec->spdif_mutex); 1527 mutex_unlock(&codec->spdif_mutex);
1317 return err; 1528 return err;
1318} 1529}
1530EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_tlv);
1319 1531
1320struct hda_ctl_ops snd_hda_bind_vol = { 1532struct hda_ctl_ops snd_hda_bind_vol = {
1321 .info = snd_hda_mixer_amp_volume_info, 1533 .info = snd_hda_mixer_amp_volume_info,
@@ -1323,6 +1535,7 @@ struct hda_ctl_ops snd_hda_bind_vol = {
1323 .put = snd_hda_mixer_amp_volume_put, 1535 .put = snd_hda_mixer_amp_volume_put,
1324 .tlv = snd_hda_mixer_amp_tlv 1536 .tlv = snd_hda_mixer_amp_tlv
1325}; 1537};
1538EXPORT_SYMBOL_HDA(snd_hda_bind_vol);
1326 1539
1327struct hda_ctl_ops snd_hda_bind_sw = { 1540struct hda_ctl_ops snd_hda_bind_sw = {
1328 .info = snd_hda_mixer_amp_switch_info, 1541 .info = snd_hda_mixer_amp_switch_info,
@@ -1330,6 +1543,7 @@ struct hda_ctl_ops snd_hda_bind_sw = {
1330 .put = snd_hda_mixer_amp_switch_put, 1543 .put = snd_hda_mixer_amp_switch_put,
1331 .tlv = snd_hda_mixer_amp_tlv 1544 .tlv = snd_hda_mixer_amp_tlv
1332}; 1545};
1546EXPORT_SYMBOL_HDA(snd_hda_bind_sw);
1333 1547
1334/* 1548/*
1335 * SPDIF out controls 1549 * SPDIF out controls
@@ -1577,9 +1791,11 @@ int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid)
1577 } 1791 }
1578 for (dig_mix = dig_mixes; dig_mix->name; dig_mix++) { 1792 for (dig_mix = dig_mixes; dig_mix->name; dig_mix++) {
1579 kctl = snd_ctl_new1(dig_mix, codec); 1793 kctl = snd_ctl_new1(dig_mix, codec);
1794 if (!kctl)
1795 return -ENOMEM;
1580 kctl->id.index = idx; 1796 kctl->id.index = idx;
1581 kctl->private_value = nid; 1797 kctl->private_value = nid;
1582 err = snd_ctl_add(codec->bus->card, kctl); 1798 err = snd_hda_ctl_add(codec, kctl);
1583 if (err < 0) 1799 if (err < 0)
1584 return err; 1800 return err;
1585 } 1801 }
@@ -1589,6 +1805,7 @@ int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid)
1589 codec->spdif_status = convert_to_spdif_status(codec->spdif_ctls); 1805 codec->spdif_status = convert_to_spdif_status(codec->spdif_ctls);
1590 return 0; 1806 return 0;
1591} 1807}
1808EXPORT_SYMBOL_HDA(snd_hda_create_spdif_out_ctls);
1592 1809
1593/* 1810/*
1594 * SPDIF sharing with analog output 1811 * SPDIF sharing with analog output
@@ -1623,9 +1840,10 @@ int snd_hda_create_spdif_share_sw(struct hda_codec *codec,
1623 if (!mout->dig_out_nid) 1840 if (!mout->dig_out_nid)
1624 return 0; 1841 return 0;
1625 /* ATTENTION: here mout is passed as private_data, instead of codec */ 1842 /* ATTENTION: here mout is passed as private_data, instead of codec */
1626 return snd_ctl_add(codec->bus->card, 1843 return snd_hda_ctl_add(codec,
1627 snd_ctl_new1(&spdif_share_sw, mout)); 1844 snd_ctl_new1(&spdif_share_sw, mout));
1628} 1845}
1846EXPORT_SYMBOL_HDA(snd_hda_create_spdif_share_sw);
1629 1847
1630/* 1848/*
1631 * SPDIF input 1849 * SPDIF input
@@ -1725,7 +1943,7 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid)
1725 for (dig_mix = dig_in_ctls; dig_mix->name; dig_mix++) { 1943 for (dig_mix = dig_in_ctls; dig_mix->name; dig_mix++) {
1726 kctl = snd_ctl_new1(dig_mix, codec); 1944 kctl = snd_ctl_new1(dig_mix, codec);
1727 kctl->private_value = nid; 1945 kctl->private_value = nid;
1728 err = snd_ctl_add(codec->bus->card, kctl); 1946 err = snd_hda_ctl_add(codec, kctl);
1729 if (err < 0) 1947 if (err < 0)
1730 return err; 1948 return err;
1731 } 1949 }
@@ -1735,6 +1953,7 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid)
1735 AC_DIG1_ENABLE; 1953 AC_DIG1_ENABLE;
1736 return 0; 1954 return 0;
1737} 1955}
1956EXPORT_SYMBOL_HDA(snd_hda_create_spdif_in_ctls);
1738 1957
1739#ifdef SND_HDA_NEEDS_RESUME 1958#ifdef SND_HDA_NEEDS_RESUME
1740/* 1959/*
@@ -1761,10 +1980,14 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid)
1761int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid, 1980int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid,
1762 int direct, unsigned int verb, unsigned int parm) 1981 int direct, unsigned int verb, unsigned int parm)
1763{ 1982{
1983 struct hda_bus *bus = codec->bus;
1984 unsigned int res;
1764 int err; 1985 int err;
1986
1987 res = make_codec_cmd(codec, nid, direct, verb, parm);
1765 snd_hda_power_up(codec); 1988 snd_hda_power_up(codec);
1766 mutex_lock(&codec->bus->cmd_mutex); 1989 mutex_lock(&bus->cmd_mutex);
1767 err = codec->bus->ops.command(codec, nid, direct, verb, parm); 1990 err = bus->ops.command(bus, res);
1768 if (!err) { 1991 if (!err) {
1769 struct hda_cache_head *c; 1992 struct hda_cache_head *c;
1770 u32 key = build_cmd_cache_key(nid, verb); 1993 u32 key = build_cmd_cache_key(nid, verb);
@@ -1772,18 +1995,19 @@ int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid,
1772 if (c) 1995 if (c)
1773 c->val = parm; 1996 c->val = parm;
1774 } 1997 }
1775 mutex_unlock(&codec->bus->cmd_mutex); 1998 mutex_unlock(&bus->cmd_mutex);
1776 snd_hda_power_down(codec); 1999 snd_hda_power_down(codec);
1777 return err; 2000 return err;
1778} 2001}
2002EXPORT_SYMBOL_HDA(snd_hda_codec_write_cache);
1779 2003
1780/* resume the all commands from the cache */ 2004/* resume the all commands from the cache */
1781void snd_hda_codec_resume_cache(struct hda_codec *codec) 2005void snd_hda_codec_resume_cache(struct hda_codec *codec)
1782{ 2006{
1783 struct hda_cache_head *buffer = codec->cmd_cache.buffer; 2007 struct hda_cache_head *buffer = codec->cmd_cache.buf.list;
1784 int i; 2008 int i;
1785 2009
1786 for (i = 0; i < codec->cmd_cache.size; i++, buffer++) { 2010 for (i = 0; i < codec->cmd_cache.buf.used; i++, buffer++) {
1787 u32 key = buffer->key; 2011 u32 key = buffer->key;
1788 if (!key) 2012 if (!key)
1789 continue; 2013 continue;
@@ -1791,6 +2015,7 @@ void snd_hda_codec_resume_cache(struct hda_codec *codec)
1791 get_cmd_cache_cmd(key), buffer->val); 2015 get_cmd_cache_cmd(key), buffer->val);
1792 } 2016 }
1793} 2017}
2018EXPORT_SYMBOL_HDA(snd_hda_codec_resume_cache);
1794 2019
1795/** 2020/**
1796 * snd_hda_sequence_write_cache - sequence writes with caching 2021 * snd_hda_sequence_write_cache - sequence writes with caching
@@ -1808,6 +2033,7 @@ void snd_hda_sequence_write_cache(struct hda_codec *codec,
1808 snd_hda_codec_write_cache(codec, seq->nid, 0, seq->verb, 2033 snd_hda_codec_write_cache(codec, seq->nid, 0, seq->verb,
1809 seq->param); 2034 seq->param);
1810} 2035}
2036EXPORT_SYMBOL_HDA(snd_hda_sequence_write_cache);
1811#endif /* SND_HDA_NEEDS_RESUME */ 2037#endif /* SND_HDA_NEEDS_RESUME */
1812 2038
1813/* 2039/*
@@ -1868,6 +2094,17 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
1868 } 2094 }
1869} 2095}
1870 2096
2097#ifdef CONFIG_SND_HDA_HWDEP
2098/* execute additional init verbs */
2099static void hda_exec_init_verbs(struct hda_codec *codec)
2100{
2101 if (codec->init_verbs.list)
2102 snd_hda_sequence_write(codec, codec->init_verbs.list);
2103}
2104#else
2105static inline void hda_exec_init_verbs(struct hda_codec *codec) {}
2106#endif
2107
1871#ifdef SND_HDA_NEEDS_RESUME 2108#ifdef SND_HDA_NEEDS_RESUME
1872/* 2109/*
1873 * call suspend and power-down; used both from PM and power-save 2110 * call suspend and power-down; used both from PM and power-save
@@ -1894,6 +2131,7 @@ static void hda_call_codec_resume(struct hda_codec *codec)
1894 hda_set_power_state(codec, 2131 hda_set_power_state(codec,
1895 codec->afg ? codec->afg : codec->mfg, 2132 codec->afg ? codec->afg : codec->mfg,
1896 AC_PWRST_D0); 2133 AC_PWRST_D0);
2134 hda_exec_init_verbs(codec);
1897 if (codec->patch_ops.resume) 2135 if (codec->patch_ops.resume)
1898 codec->patch_ops.resume(codec); 2136 codec->patch_ops.resume(codec);
1899 else { 2137 else {
@@ -1914,28 +2152,37 @@ static void hda_call_codec_resume(struct hda_codec *codec)
1914 * 2152 *
1915 * Returns 0 if successful, otherwise a negative error code. 2153 * Returns 0 if successful, otherwise a negative error code.
1916 */ 2154 */
1917int __devinit snd_hda_build_controls(struct hda_bus *bus) 2155int /*__devinit*/ snd_hda_build_controls(struct hda_bus *bus)
1918{ 2156{
1919 struct hda_codec *codec; 2157 struct hda_codec *codec;
1920 2158
1921 list_for_each_entry(codec, &bus->codec_list, list) { 2159 list_for_each_entry(codec, &bus->codec_list, list) {
1922 int err = 0; 2160 int err = snd_hda_codec_build_controls(codec);
1923 /* fake as if already powered-on */
1924 hda_keep_power_on(codec);
1925 /* then fire up */
1926 hda_set_power_state(codec,
1927 codec->afg ? codec->afg : codec->mfg,
1928 AC_PWRST_D0);
1929 /* continue to initialize... */
1930 if (codec->patch_ops.init)
1931 err = codec->patch_ops.init(codec);
1932 if (!err && codec->patch_ops.build_controls)
1933 err = codec->patch_ops.build_controls(codec);
1934 snd_hda_power_down(codec);
1935 if (err < 0) 2161 if (err < 0)
1936 return err; 2162 return err;
1937 } 2163 }
2164 return 0;
2165}
2166EXPORT_SYMBOL_HDA(snd_hda_build_controls);
1938 2167
2168int snd_hda_codec_build_controls(struct hda_codec *codec)
2169{
2170 int err = 0;
2171 /* fake as if already powered-on */
2172 hda_keep_power_on(codec);
2173 /* then fire up */
2174 hda_set_power_state(codec,
2175 codec->afg ? codec->afg : codec->mfg,
2176 AC_PWRST_D0);
2177 hda_exec_init_verbs(codec);
2178 /* continue to initialize... */
2179 if (codec->patch_ops.init)
2180 err = codec->patch_ops.init(codec);
2181 if (!err && codec->patch_ops.build_controls)
2182 err = codec->patch_ops.build_controls(codec);
2183 snd_hda_power_down(codec);
2184 if (err < 0)
2185 return err;
1939 return 0; 2186 return 0;
1940} 2187}
1941 2188
@@ -2028,6 +2275,7 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate,
2028 2275
2029 return val; 2276 return val;
2030} 2277}
2278EXPORT_SYMBOL_HDA(snd_hda_calc_stream_format);
2031 2279
2032/** 2280/**
2033 * snd_hda_query_supported_pcm - query the supported PCM rates and formats 2281 * snd_hda_query_supported_pcm - query the supported PCM rates and formats
@@ -2042,7 +2290,7 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate,
2042 * 2290 *
2043 * Returns 0 if successful, otherwise a negative error code. 2291 * Returns 0 if successful, otherwise a negative error code.
2044 */ 2292 */
2045int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, 2293static int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
2046 u32 *ratesp, u64 *formatsp, unsigned int *bpsp) 2294 u32 *ratesp, u64 *formatsp, unsigned int *bpsp)
2047{ 2295{
2048 int i; 2296 int i;
@@ -2207,6 +2455,7 @@ int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid,
2207 2455
2208 return 1; 2456 return 1;
2209} 2457}
2458EXPORT_SYMBOL_HDA(snd_hda_is_supported_format);
2210 2459
2211/* 2460/*
2212 * PCM stuff 2461 * PCM stuff
@@ -2236,8 +2485,8 @@ static int hda_pcm_default_cleanup(struct hda_pcm_stream *hinfo,
2236 return 0; 2485 return 0;
2237} 2486}
2238 2487
2239static int __devinit set_pcm_default_values(struct hda_codec *codec, 2488static int set_pcm_default_values(struct hda_codec *codec,
2240 struct hda_pcm_stream *info) 2489 struct hda_pcm_stream *info)
2241{ 2490{
2242 /* query support PCM information from the given NID */ 2491 /* query support PCM information from the given NID */
2243 if (info->nid && (!info->rates || !info->formats)) { 2492 if (info->nid && (!info->rates || !info->formats)) {
@@ -2263,6 +2512,110 @@ static int __devinit set_pcm_default_values(struct hda_codec *codec,
2263 return 0; 2512 return 0;
2264} 2513}
2265 2514
2515/*
2516 * get the empty PCM device number to assign
2517 */
2518static int get_empty_pcm_device(struct hda_bus *bus, int type)
2519{
2520 static const char *dev_name[HDA_PCM_NTYPES] = {
2521 "Audio", "SPDIF", "HDMI", "Modem"
2522 };
2523 /* starting device index for each PCM type */
2524 static int dev_idx[HDA_PCM_NTYPES] = {
2525 [HDA_PCM_TYPE_AUDIO] = 0,
2526 [HDA_PCM_TYPE_SPDIF] = 1,
2527 [HDA_PCM_TYPE_HDMI] = 3,
2528 [HDA_PCM_TYPE_MODEM] = 6
2529 };
2530 /* normal audio device indices; not linear to keep compatibility */
2531 static int audio_idx[4] = { 0, 2, 4, 5 };
2532 int i, dev;
2533
2534 switch (type) {
2535 case HDA_PCM_TYPE_AUDIO:
2536 for (i = 0; i < ARRAY_SIZE(audio_idx); i++) {
2537 dev = audio_idx[i];
2538 if (!test_bit(dev, bus->pcm_dev_bits))
2539 break;
2540 }
2541 if (i >= ARRAY_SIZE(audio_idx)) {
2542 snd_printk(KERN_WARNING "Too many audio devices\n");
2543 return -EAGAIN;
2544 }
2545 break;
2546 case HDA_PCM_TYPE_SPDIF:
2547 case HDA_PCM_TYPE_HDMI:
2548 case HDA_PCM_TYPE_MODEM:
2549 dev = dev_idx[type];
2550 if (test_bit(dev, bus->pcm_dev_bits)) {
2551 snd_printk(KERN_WARNING "%s already defined\n",
2552 dev_name[type]);
2553 return -EAGAIN;
2554 }
2555 break;
2556 default:
2557 snd_printk(KERN_WARNING "Invalid PCM type %d\n", type);
2558 return -EINVAL;
2559 }
2560 set_bit(dev, bus->pcm_dev_bits);
2561 return dev;
2562}
2563
2564/*
2565 * attach a new PCM stream
2566 */
2567static int snd_hda_attach_pcm(struct hda_codec *codec, struct hda_pcm *pcm)
2568{
2569 struct hda_bus *bus = codec->bus;
2570 struct hda_pcm_stream *info;
2571 int stream, err;
2572
2573 if (snd_BUG_ON(!pcm->name))
2574 return -EINVAL;
2575 for (stream = 0; stream < 2; stream++) {
2576 info = &pcm->stream[stream];
2577 if (info->substreams) {
2578 err = set_pcm_default_values(codec, info);
2579 if (err < 0)
2580 return err;
2581 }
2582 }
2583 return bus->ops.attach_pcm(bus, codec, pcm);
2584}
2585
2586/* assign all PCMs of the given codec */
2587int snd_hda_codec_build_pcms(struct hda_codec *codec)
2588{
2589 unsigned int pcm;
2590 int err;
2591
2592 if (!codec->num_pcms) {
2593 if (!codec->patch_ops.build_pcms)
2594 return 0;
2595 err = codec->patch_ops.build_pcms(codec);
2596 if (err < 0)
2597 return err;
2598 }
2599 for (pcm = 0; pcm < codec->num_pcms; pcm++) {
2600 struct hda_pcm *cpcm = &codec->pcm_info[pcm];
2601 int dev;
2602
2603 if (!cpcm->stream[0].substreams && !cpcm->stream[1].substreams)
2604 return 0; /* no substreams assigned */
2605
2606 if (!cpcm->pcm) {
2607 dev = get_empty_pcm_device(codec->bus, cpcm->pcm_type);
2608 if (dev < 0)
2609 return 0;
2610 cpcm->device = dev;
2611 err = snd_hda_attach_pcm(codec, cpcm);
2612 if (err < 0)
2613 return err;
2614 }
2615 }
2616 return 0;
2617}
2618
2266/** 2619/**
2267 * snd_hda_build_pcms - build PCM information 2620 * snd_hda_build_pcms - build PCM information
2268 * @bus: the BUS 2621 * @bus: the BUS
@@ -2294,27 +2647,13 @@ int __devinit snd_hda_build_pcms(struct hda_bus *bus)
2294 struct hda_codec *codec; 2647 struct hda_codec *codec;
2295 2648
2296 list_for_each_entry(codec, &bus->codec_list, list) { 2649 list_for_each_entry(codec, &bus->codec_list, list) {
2297 unsigned int pcm, s; 2650 int err = snd_hda_codec_build_pcms(codec);
2298 int err;
2299 if (!codec->patch_ops.build_pcms)
2300 continue;
2301 err = codec->patch_ops.build_pcms(codec);
2302 if (err < 0) 2651 if (err < 0)
2303 return err; 2652 return err;
2304 for (pcm = 0; pcm < codec->num_pcms; pcm++) {
2305 for (s = 0; s < 2; s++) {
2306 struct hda_pcm_stream *info;
2307 info = &codec->pcm_info[pcm].stream[s];
2308 if (!info->substreams)
2309 continue;
2310 err = set_pcm_default_values(codec, info);
2311 if (err < 0)
2312 return err;
2313 }
2314 }
2315 } 2653 }
2316 return 0; 2654 return 0;
2317} 2655}
2656EXPORT_SYMBOL_HDA(snd_hda_build_pcms);
2318 2657
2319/** 2658/**
2320 * snd_hda_check_board_config - compare the current codec with the config table 2659 * snd_hda_check_board_config - compare the current codec with the config table
@@ -2333,11 +2672,11 @@ int snd_hda_check_board_config(struct hda_codec *codec,
2333 int num_configs, const char **models, 2672 int num_configs, const char **models,
2334 const struct snd_pci_quirk *tbl) 2673 const struct snd_pci_quirk *tbl)
2335{ 2674{
2336 if (codec->bus->modelname && models) { 2675 if (codec->modelname && models) {
2337 int i; 2676 int i;
2338 for (i = 0; i < num_configs; i++) { 2677 for (i = 0; i < num_configs; i++) {
2339 if (models[i] && 2678 if (models[i] &&
2340 !strcmp(codec->bus->modelname, models[i])) { 2679 !strcmp(codec->modelname, models[i])) {
2341 snd_printd(KERN_INFO "hda_codec: model '%s' is " 2680 snd_printd(KERN_INFO "hda_codec: model '%s' is "
2342 "selected\n", models[i]); 2681 "selected\n", models[i]);
2343 return i; 2682 return i;
@@ -2370,6 +2709,7 @@ int snd_hda_check_board_config(struct hda_codec *codec,
2370 } 2709 }
2371 return -1; 2710 return -1;
2372} 2711}
2712EXPORT_SYMBOL_HDA(snd_hda_check_board_config);
2373 2713
2374/** 2714/**
2375 * snd_hda_add_new_ctls - create controls from the array 2715 * snd_hda_add_new_ctls - create controls from the array
@@ -2390,7 +2730,7 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)
2390 kctl = snd_ctl_new1(knew, codec); 2730 kctl = snd_ctl_new1(knew, codec);
2391 if (!kctl) 2731 if (!kctl)
2392 return -ENOMEM; 2732 return -ENOMEM;
2393 err = snd_ctl_add(codec->bus->card, kctl); 2733 err = snd_hda_ctl_add(codec, kctl);
2394 if (err < 0) { 2734 if (err < 0) {
2395 if (!codec->addr) 2735 if (!codec->addr)
2396 return err; 2736 return err;
@@ -2398,13 +2738,14 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)
2398 if (!kctl) 2738 if (!kctl)
2399 return -ENOMEM; 2739 return -ENOMEM;
2400 kctl->id.device = codec->addr; 2740 kctl->id.device = codec->addr;
2401 err = snd_ctl_add(codec->bus->card, kctl); 2741 err = snd_hda_ctl_add(codec, kctl);
2402 if (err < 0) 2742 if (err < 0)
2403 return err; 2743 return err;
2404 } 2744 }
2405 } 2745 }
2406 return 0; 2746 return 0;
2407} 2747}
2748EXPORT_SYMBOL_HDA(snd_hda_add_new_ctls);
2408 2749
2409#ifdef CONFIG_SND_HDA_POWER_SAVE 2750#ifdef CONFIG_SND_HDA_POWER_SAVE
2410static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, 2751static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
@@ -2414,6 +2755,7 @@ static void hda_power_work(struct work_struct *work)
2414{ 2755{
2415 struct hda_codec *codec = 2756 struct hda_codec *codec =
2416 container_of(work, struct hda_codec, power_work.work); 2757 container_of(work, struct hda_codec, power_work.work);
2758 struct hda_bus *bus = codec->bus;
2417 2759
2418 if (!codec->power_on || codec->power_count) { 2760 if (!codec->power_on || codec->power_count) {
2419 codec->power_transition = 0; 2761 codec->power_transition = 0;
@@ -2421,8 +2763,8 @@ static void hda_power_work(struct work_struct *work)
2421 } 2763 }
2422 2764
2423 hda_call_codec_suspend(codec); 2765 hda_call_codec_suspend(codec);
2424 if (codec->bus->ops.pm_notify) 2766 if (bus->ops.pm_notify)
2425 codec->bus->ops.pm_notify(codec); 2767 bus->ops.pm_notify(bus);
2426} 2768}
2427 2769
2428static void hda_keep_power_on(struct hda_codec *codec) 2770static void hda_keep_power_on(struct hda_codec *codec)
@@ -2433,29 +2775,39 @@ static void hda_keep_power_on(struct hda_codec *codec)
2433 2775
2434void snd_hda_power_up(struct hda_codec *codec) 2776void snd_hda_power_up(struct hda_codec *codec)
2435{ 2777{
2778 struct hda_bus *bus = codec->bus;
2779
2436 codec->power_count++; 2780 codec->power_count++;
2437 if (codec->power_on || codec->power_transition) 2781 if (codec->power_on || codec->power_transition)
2438 return; 2782 return;
2439 2783
2440 codec->power_on = 1; 2784 codec->power_on = 1;
2441 if (codec->bus->ops.pm_notify) 2785 if (bus->ops.pm_notify)
2442 codec->bus->ops.pm_notify(codec); 2786 bus->ops.pm_notify(bus);
2443 hda_call_codec_resume(codec); 2787 hda_call_codec_resume(codec);
2444 cancel_delayed_work(&codec->power_work); 2788 cancel_delayed_work(&codec->power_work);
2445 codec->power_transition = 0; 2789 codec->power_transition = 0;
2446} 2790}
2791EXPORT_SYMBOL_HDA(snd_hda_power_up);
2792
2793#define power_save(codec) \
2794 ((codec)->bus->power_save ? *(codec)->bus->power_save : 0)
2795
2796#define power_save(codec) \
2797 ((codec)->bus->power_save ? *(codec)->bus->power_save : 0)
2447 2798
2448void snd_hda_power_down(struct hda_codec *codec) 2799void snd_hda_power_down(struct hda_codec *codec)
2449{ 2800{
2450 --codec->power_count; 2801 --codec->power_count;
2451 if (!codec->power_on || codec->power_count || codec->power_transition) 2802 if (!codec->power_on || codec->power_count || codec->power_transition)
2452 return; 2803 return;
2453 if (power_save) { 2804 if (power_save(codec)) {
2454 codec->power_transition = 1; /* avoid reentrance */ 2805 codec->power_transition = 1; /* avoid reentrance */
2455 schedule_delayed_work(&codec->power_work, 2806 schedule_delayed_work(&codec->power_work,
2456 msecs_to_jiffies(power_save * 1000)); 2807 msecs_to_jiffies(power_save(codec) * 1000));
2457 } 2808 }
2458} 2809}
2810EXPORT_SYMBOL_HDA(snd_hda_power_down);
2459 2811
2460int snd_hda_check_amp_list_power(struct hda_codec *codec, 2812int snd_hda_check_amp_list_power(struct hda_codec *codec,
2461 struct hda_loopback_check *check, 2813 struct hda_loopback_check *check,
@@ -2492,6 +2844,7 @@ int snd_hda_check_amp_list_power(struct hda_codec *codec,
2492 } 2844 }
2493 return 0; 2845 return 0;
2494} 2846}
2847EXPORT_SYMBOL_HDA(snd_hda_check_amp_list_power);
2495#endif 2848#endif
2496 2849
2497/* 2850/*
@@ -2511,6 +2864,7 @@ int snd_hda_ch_mode_info(struct hda_codec *codec,
2511 chmode[uinfo->value.enumerated.item].channels); 2864 chmode[uinfo->value.enumerated.item].channels);
2512 return 0; 2865 return 0;
2513} 2866}
2867EXPORT_SYMBOL_HDA(snd_hda_ch_mode_info);
2514 2868
2515int snd_hda_ch_mode_get(struct hda_codec *codec, 2869int snd_hda_ch_mode_get(struct hda_codec *codec,
2516 struct snd_ctl_elem_value *ucontrol, 2870 struct snd_ctl_elem_value *ucontrol,
@@ -2528,6 +2882,7 @@ int snd_hda_ch_mode_get(struct hda_codec *codec,
2528 } 2882 }
2529 return 0; 2883 return 0;
2530} 2884}
2885EXPORT_SYMBOL_HDA(snd_hda_ch_mode_get);
2531 2886
2532int snd_hda_ch_mode_put(struct hda_codec *codec, 2887int snd_hda_ch_mode_put(struct hda_codec *codec,
2533 struct snd_ctl_elem_value *ucontrol, 2888 struct snd_ctl_elem_value *ucontrol,
@@ -2548,6 +2903,7 @@ int snd_hda_ch_mode_put(struct hda_codec *codec,
2548 snd_hda_sequence_write_cache(codec, chmode[mode].sequence); 2903 snd_hda_sequence_write_cache(codec, chmode[mode].sequence);
2549 return 1; 2904 return 1;
2550} 2905}
2906EXPORT_SYMBOL_HDA(snd_hda_ch_mode_put);
2551 2907
2552/* 2908/*
2553 * input MUX helper 2909 * input MUX helper
@@ -2568,6 +2924,7 @@ int snd_hda_input_mux_info(const struct hda_input_mux *imux,
2568 strcpy(uinfo->value.enumerated.name, imux->items[index].label); 2924 strcpy(uinfo->value.enumerated.name, imux->items[index].label);
2569 return 0; 2925 return 0;
2570} 2926}
2927EXPORT_SYMBOL_HDA(snd_hda_input_mux_info);
2571 2928
2572int snd_hda_input_mux_put(struct hda_codec *codec, 2929int snd_hda_input_mux_put(struct hda_codec *codec,
2573 const struct hda_input_mux *imux, 2930 const struct hda_input_mux *imux,
@@ -2589,6 +2946,7 @@ int snd_hda_input_mux_put(struct hda_codec *codec,
2589 *cur_val = idx; 2946 *cur_val = idx;
2590 return 1; 2947 return 1;
2591} 2948}
2949EXPORT_SYMBOL_HDA(snd_hda_input_mux_put);
2592 2950
2593 2951
2594/* 2952/*
@@ -2641,6 +2999,7 @@ int snd_hda_multi_out_dig_open(struct hda_codec *codec,
2641 mutex_unlock(&codec->spdif_mutex); 2999 mutex_unlock(&codec->spdif_mutex);
2642 return 0; 3000 return 0;
2643} 3001}
3002EXPORT_SYMBOL_HDA(snd_hda_multi_out_dig_open);
2644 3003
2645int snd_hda_multi_out_dig_prepare(struct hda_codec *codec, 3004int snd_hda_multi_out_dig_prepare(struct hda_codec *codec,
2646 struct hda_multi_out *mout, 3005 struct hda_multi_out *mout,
@@ -2653,6 +3012,7 @@ int snd_hda_multi_out_dig_prepare(struct hda_codec *codec,
2653 mutex_unlock(&codec->spdif_mutex); 3012 mutex_unlock(&codec->spdif_mutex);
2654 return 0; 3013 return 0;
2655} 3014}
3015EXPORT_SYMBOL_HDA(snd_hda_multi_out_dig_prepare);
2656 3016
2657/* 3017/*
2658 * release the digital out 3018 * release the digital out
@@ -2665,6 +3025,7 @@ int snd_hda_multi_out_dig_close(struct hda_codec *codec,
2665 mutex_unlock(&codec->spdif_mutex); 3025 mutex_unlock(&codec->spdif_mutex);
2666 return 0; 3026 return 0;
2667} 3027}
3028EXPORT_SYMBOL_HDA(snd_hda_multi_out_dig_close);
2668 3029
2669/* 3030/*
2670 * set up more restrictions for analog out 3031 * set up more restrictions for analog out
@@ -2704,6 +3065,7 @@ int snd_hda_multi_out_analog_open(struct hda_codec *codec,
2704 return snd_pcm_hw_constraint_step(substream->runtime, 0, 3065 return snd_pcm_hw_constraint_step(substream->runtime, 0,
2705 SNDRV_PCM_HW_PARAM_CHANNELS, 2); 3066 SNDRV_PCM_HW_PARAM_CHANNELS, 2);
2706} 3067}
3068EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_open);
2707 3069
2708/* 3070/*
2709 * set up the i/o for analog out 3071 * set up the i/o for analog out
@@ -2762,6 +3124,7 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec,
2762 } 3124 }
2763 return 0; 3125 return 0;
2764} 3126}
3127EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_prepare);
2765 3128
2766/* 3129/*
2767 * clean up the setting for analog out 3130 * clean up the setting for analog out
@@ -2788,6 +3151,7 @@ int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec,
2788 mutex_unlock(&codec->spdif_mutex); 3151 mutex_unlock(&codec->spdif_mutex);
2789 return 0; 3152 return 0;
2790} 3153}
3154EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_cleanup);
2791 3155
2792/* 3156/*
2793 * Helper for automatic pin configuration 3157 * Helper for automatic pin configuration
@@ -3073,11 +3437,13 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
3073 3437
3074 return 0; 3438 return 0;
3075} 3439}
3440EXPORT_SYMBOL_HDA(snd_hda_parse_pin_def_config);
3076 3441
3077/* labels for input pins */ 3442/* labels for input pins */
3078const char *auto_pin_cfg_labels[AUTO_PIN_LAST] = { 3443const char *auto_pin_cfg_labels[AUTO_PIN_LAST] = {
3079 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux" 3444 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux"
3080}; 3445};
3446EXPORT_SYMBOL_HDA(auto_pin_cfg_labels);
3081 3447
3082 3448
3083#ifdef CONFIG_PM 3449#ifdef CONFIG_PM
@@ -3105,11 +3471,11 @@ int snd_hda_suspend(struct hda_bus *bus, pm_message_t state)
3105 } 3471 }
3106 return 0; 3472 return 0;
3107} 3473}
3474EXPORT_SYMBOL_HDA(snd_hda_suspend);
3108 3475
3109/** 3476/**
3110 * snd_hda_resume - resume the codecs 3477 * snd_hda_resume - resume the codecs
3111 * @bus: the HDA bus 3478 * @bus: the HDA bus
3112 * @state: resume state
3113 * 3479 *
3114 * Returns 0 if successful. 3480 * Returns 0 if successful.
3115 * 3481 *
@@ -3126,16 +3492,79 @@ int snd_hda_resume(struct hda_bus *bus)
3126 } 3492 }
3127 return 0; 3493 return 0;
3128} 3494}
3129#ifdef CONFIG_SND_HDA_POWER_SAVE 3495EXPORT_SYMBOL_HDA(snd_hda_resume);
3130int snd_hda_codecs_inuse(struct hda_bus *bus) 3496#endif /* CONFIG_PM */
3131{
3132 struct hda_codec *codec;
3133 3497
3134 list_for_each_entry(codec, &bus->codec_list, list) { 3498/*
3135 if (snd_hda_codec_needs_resume(codec)) 3499 * generic arrays
3136 return 1; 3500 */
3501
3502/* get a new element from the given array
3503 * if it exceeds the pre-allocated array size, re-allocate the array
3504 */
3505void *snd_array_new(struct snd_array *array)
3506{
3507 if (array->used >= array->alloced) {
3508 int num = array->alloced + array->alloc_align;
3509 void *nlist;
3510 if (snd_BUG_ON(num >= 4096))
3511 return NULL;
3512 nlist = kcalloc(num + 1, array->elem_size, GFP_KERNEL);
3513 if (!nlist)
3514 return NULL;
3515 if (array->list) {
3516 memcpy(nlist, array->list,
3517 array->elem_size * array->alloced);
3518 kfree(array->list);
3519 }
3520 array->list = nlist;
3521 array->alloced = num;
3137 } 3522 }
3138 return 0; 3523 return snd_array_elem(array, array->used++);
3139} 3524}
3140#endif 3525EXPORT_SYMBOL_HDA(snd_array_new);
3141#endif 3526
3527/* free the given array elements */
3528void snd_array_free(struct snd_array *array)
3529{
3530 kfree(array->list);
3531 array->used = 0;
3532 array->alloced = 0;
3533 array->list = NULL;
3534}
3535EXPORT_SYMBOL_HDA(snd_array_free);
3536
3537/*
3538 * used by hda_proc.c and hda_eld.c
3539 */
3540void snd_print_pcm_rates(int pcm, char *buf, int buflen)
3541{
3542 static unsigned int rates[] = {
3543 8000, 11025, 16000, 22050, 32000, 44100, 48000, 88200,
3544 96000, 176400, 192000, 384000
3545 };
3546 int i, j;
3547
3548 for (i = 0, j = 0; i < ARRAY_SIZE(rates); i++)
3549 if (pcm & (1 << i))
3550 j += snprintf(buf + j, buflen - j, " %d", rates[i]);
3551
3552 buf[j] = '\0'; /* necessary when j == 0 */
3553}
3554EXPORT_SYMBOL_HDA(snd_print_pcm_rates);
3555
3556void snd_print_pcm_bits(int pcm, char *buf, int buflen)
3557{
3558 static unsigned int bits[] = { 8, 16, 20, 24, 32 };
3559 int i, j;
3560
3561 for (i = 0, j = 0; i < ARRAY_SIZE(bits); i++)
3562 if (pcm & (AC_SUPPCM_BITS_8 << i))
3563 j += snprintf(buf + j, buflen - j, " %d", bits[i]);
3564
3565 buf[j] = '\0'; /* necessary when j == 0 */
3566}
3567EXPORT_SYMBOL_HDA(snd_print_pcm_bits);
3568
3569MODULE_DESCRIPTION("HDA codec core");
3570MODULE_LICENSE("GPL");
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 60468f562400..729fc7642d7f 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -520,6 +520,36 @@ enum {
520#define HDA_MAX_CODEC_ADDRESS 0x0f 520#define HDA_MAX_CODEC_ADDRESS 0x0f
521 521
522/* 522/*
523 * generic arrays
524 */
525struct snd_array {
526 unsigned int used;
527 unsigned int alloced;
528 unsigned int elem_size;
529 unsigned int alloc_align;
530 void *list;
531};
532
533void *snd_array_new(struct snd_array *array);
534void snd_array_free(struct snd_array *array);
535static inline void snd_array_init(struct snd_array *array, unsigned int size,
536 unsigned int align)
537{
538 array->elem_size = size;
539 array->alloc_align = align;
540}
541
542static inline void *snd_array_elem(struct snd_array *array, unsigned int idx)
543{
544 return array->list + idx * array->elem_size;
545}
546
547static inline unsigned int snd_array_index(struct snd_array *array, void *ptr)
548{
549 return (unsigned long)(ptr - array->list) / array->elem_size;
550}
551
552/*
523 * Structures 553 * Structures
524 */ 554 */
525 555
@@ -536,15 +566,17 @@ typedef u16 hda_nid_t;
536/* bus operators */ 566/* bus operators */
537struct hda_bus_ops { 567struct hda_bus_ops {
538 /* send a single command */ 568 /* send a single command */
539 int (*command)(struct hda_codec *codec, hda_nid_t nid, int direct, 569 int (*command)(struct hda_bus *bus, unsigned int cmd);
540 unsigned int verb, unsigned int parm);
541 /* get a response from the last command */ 570 /* get a response from the last command */
542 unsigned int (*get_response)(struct hda_codec *codec); 571 unsigned int (*get_response)(struct hda_bus *bus);
543 /* free the private data */ 572 /* free the private data */
544 void (*private_free)(struct hda_bus *); 573 void (*private_free)(struct hda_bus *);
574 /* attach a PCM stream */
575 int (*attach_pcm)(struct hda_bus *bus, struct hda_codec *codec,
576 struct hda_pcm *pcm);
545#ifdef CONFIG_SND_HDA_POWER_SAVE 577#ifdef CONFIG_SND_HDA_POWER_SAVE
546 /* notify power-up/down from codec to controller */ 578 /* notify power-up/down from codec to controller */
547 void (*pm_notify)(struct hda_codec *codec); 579 void (*pm_notify)(struct hda_bus *bus);
548#endif 580#endif
549}; 581};
550 582
@@ -553,6 +585,7 @@ struct hda_bus_template {
553 void *private_data; 585 void *private_data;
554 struct pci_dev *pci; 586 struct pci_dev *pci;
555 const char *modelname; 587 const char *modelname;
588 int *power_save;
556 struct hda_bus_ops ops; 589 struct hda_bus_ops ops;
557}; 590};
558 591
@@ -569,6 +602,7 @@ struct hda_bus {
569 void *private_data; 602 void *private_data;
570 struct pci_dev *pci; 603 struct pci_dev *pci;
571 const char *modelname; 604 const char *modelname;
605 int *power_save;
572 struct hda_bus_ops ops; 606 struct hda_bus_ops ops;
573 607
574 /* codec linked list */ 608 /* codec linked list */
@@ -581,10 +615,12 @@ struct hda_bus {
581 /* unsolicited event queue */ 615 /* unsolicited event queue */
582 struct hda_bus_unsolicited *unsol; 616 struct hda_bus_unsolicited *unsol;
583 617
584 struct snd_info_entry *proc; 618 /* assigned PCMs */
619 DECLARE_BITMAP(pcm_dev_bits, SNDRV_PCM_DEVICES);
585 620
586 /* misc op flags */ 621 /* misc op flags */
587 unsigned int needs_damn_long_delay :1; 622 unsigned int needs_damn_long_delay :1;
623 unsigned int shutdown :1; /* being unloaded */
588}; 624};
589 625
590/* 626/*
@@ -604,6 +640,16 @@ struct hda_codec_preset {
604 int (*patch)(struct hda_codec *codec); 640 int (*patch)(struct hda_codec *codec);
605}; 641};
606 642
643struct hda_codec_preset_list {
644 const struct hda_codec_preset *preset;
645 struct module *owner;
646 struct list_head list;
647};
648
649/* initial hook */
650int snd_hda_add_codec_preset(struct hda_codec_preset_list *preset);
651int snd_hda_delete_codec_preset(struct hda_codec_preset_list *preset);
652
607/* ops set by the preset patch */ 653/* ops set by the preset patch */
608struct hda_codec_ops { 654struct hda_codec_ops {
609 int (*build_controls)(struct hda_codec *codec); 655 int (*build_controls)(struct hda_codec *codec);
@@ -635,10 +681,7 @@ struct hda_amp_info {
635 681
636struct hda_cache_rec { 682struct hda_cache_rec {
637 u16 hash[64]; /* hash table for index */ 683 u16 hash[64]; /* hash table for index */
638 unsigned int num_entries; /* number of assigned entries */ 684 struct snd_array buf; /* record entries */
639 unsigned int size; /* allocated size */
640 unsigned int record_size; /* record size (including header) */
641 void *buffer; /* hash table entries */
642}; 685};
643 686
644/* PCM callbacks */ 687/* PCM callbacks */
@@ -680,7 +723,8 @@ struct hda_pcm {
680 char *name; 723 char *name;
681 struct hda_pcm_stream stream[2]; 724 struct hda_pcm_stream stream[2];
682 unsigned int pcm_type; /* HDA_PCM_TYPE_XXX */ 725 unsigned int pcm_type; /* HDA_PCM_TYPE_XXX */
683 int device; /* assigned device number */ 726 int device; /* device number to assign */
727 struct snd_pcm *pcm; /* assigned PCM instance */
684}; 728};
685 729
686/* codec information */ 730/* codec information */
@@ -699,6 +743,9 @@ struct hda_codec {
699 743
700 /* detected preset */ 744 /* detected preset */
701 const struct hda_codec_preset *preset; 745 const struct hda_codec_preset *preset;
746 struct module *owner;
747 const char *name; /* codec name */
748 const char *modelname; /* model name for preset */
702 749
703 /* set by patch */ 750 /* set by patch */
704 struct hda_codec_ops patch_ops; 751 struct hda_codec_ops patch_ops;
@@ -718,6 +765,8 @@ struct hda_codec {
718 hda_nid_t start_nid; 765 hda_nid_t start_nid;
719 u32 *wcaps; 766 u32 *wcaps;
720 767
768 struct snd_array mixers; /* list of assigned mixer elements */
769
721 struct hda_cache_rec amp_cache; /* cache for amp access */ 770 struct hda_cache_rec amp_cache; /* cache for amp access */
722 struct hda_cache_rec cmd_cache; /* cache for other commands */ 771 struct hda_cache_rec cmd_cache; /* cache for other commands */
723 772
@@ -727,7 +776,11 @@ struct hda_codec {
727 unsigned int spdif_in_enable; /* SPDIF input enable? */ 776 unsigned int spdif_in_enable; /* SPDIF input enable? */
728 hda_nid_t *slave_dig_outs; /* optional digital out slave widgets */ 777 hda_nid_t *slave_dig_outs; /* optional digital out slave widgets */
729 778
779#ifdef CONFIG_SND_HDA_HWDEP
730 struct snd_hwdep *hwdep; /* assigned hwdep device */ 780 struct snd_hwdep *hwdep; /* assigned hwdep device */
781 struct snd_array init_verbs; /* additional init verbs */
782 struct snd_array hints; /* additional hints */
783#endif
731 784
732 /* misc flags */ 785 /* misc flags */
733 unsigned int spdif_status_reset :1; /* needs to toggle SPDIF for each 786 unsigned int spdif_status_reset :1; /* needs to toggle SPDIF for each
@@ -740,6 +793,10 @@ struct hda_codec {
740 int power_count; /* current (global) power refcount */ 793 int power_count; /* current (global) power refcount */
741 struct delayed_work power_work; /* delayed task for powerdown */ 794 struct delayed_work power_work; /* delayed task for powerdown */
742#endif 795#endif
796
797 /* codec-specific additional proc output */
798 void (*proc_widget_hook)(struct snd_info_buffer *buffer,
799 struct hda_codec *codec, hda_nid_t nid);
743}; 800};
744 801
745/* direction */ 802/* direction */
@@ -754,7 +811,7 @@ enum {
754int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp, 811int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp,
755 struct hda_bus **busp); 812 struct hda_bus **busp);
756int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, 813int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
757 struct hda_codec **codecp); 814 int do_init, struct hda_codec **codecp);
758 815
759/* 816/*
760 * low level functions 817 * low level functions
@@ -799,11 +856,13 @@ void snd_hda_codec_resume_cache(struct hda_codec *codec);
799 * Mixer 856 * Mixer
800 */ 857 */
801int snd_hda_build_controls(struct hda_bus *bus); 858int snd_hda_build_controls(struct hda_bus *bus);
859int snd_hda_codec_build_controls(struct hda_codec *codec);
802 860
803/* 861/*
804 * PCM 862 * PCM
805 */ 863 */
806int snd_hda_build_pcms(struct hda_bus *bus); 864int snd_hda_build_pcms(struct hda_bus *bus);
865int snd_hda_codec_build_pcms(struct hda_codec *codec);
807void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, 866void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
808 u32 stream_tag, 867 u32 stream_tag,
809 int channel_id, int format); 868 int channel_id, int format);
@@ -812,8 +871,6 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate,
812 unsigned int channels, 871 unsigned int channels,
813 unsigned int format, 872 unsigned int format,
814 unsigned int maxbps); 873 unsigned int maxbps);
815int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
816 u32 *ratesp, u64 *formatsp, unsigned int *bpsp);
817int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid, 874int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid,
818 unsigned int format); 875 unsigned int format);
819 876
@@ -831,18 +888,38 @@ int snd_hda_resume(struct hda_bus *bus);
831#endif 888#endif
832 889
833/* 890/*
891 * get widget information
892 */
893const char *snd_hda_get_jack_connectivity(u32 cfg);
894const char *snd_hda_get_jack_type(u32 cfg);
895const char *snd_hda_get_jack_location(u32 cfg);
896
897/*
834 * power saving 898 * power saving
835 */ 899 */
836#ifdef CONFIG_SND_HDA_POWER_SAVE 900#ifdef CONFIG_SND_HDA_POWER_SAVE
837void snd_hda_power_up(struct hda_codec *codec); 901void snd_hda_power_up(struct hda_codec *codec);
838void snd_hda_power_down(struct hda_codec *codec); 902void snd_hda_power_down(struct hda_codec *codec);
839#define snd_hda_codec_needs_resume(codec) codec->power_count 903#define snd_hda_codec_needs_resume(codec) codec->power_count
840int snd_hda_codecs_inuse(struct hda_bus *bus);
841#else 904#else
842static inline void snd_hda_power_up(struct hda_codec *codec) {} 905static inline void snd_hda_power_up(struct hda_codec *codec) {}
843static inline void snd_hda_power_down(struct hda_codec *codec) {} 906static inline void snd_hda_power_down(struct hda_codec *codec) {}
844#define snd_hda_codec_needs_resume(codec) 1 907#define snd_hda_codec_needs_resume(codec) 1
845#define snd_hda_codecs_inuse(bus) 1 908#endif
909
910/*
911 * Codec modularization
912 */
913
914/* Export symbols only for communication with codec drivers;
915 * When built in kernel, all HD-audio drivers are supposed to be statically
916 * linked to the kernel. Thus, the symbols don't have to (or shouldn't) be
917 * exported unless it's built as a module.
918 */
919#ifdef MODULE
920#define EXPORT_SYMBOL_HDA(sym) EXPORT_SYMBOL_GPL(sym)
921#else
922#define EXPORT_SYMBOL_HDA(sym)
846#endif 923#endif
847 924
848#endif /* __SOUND_HDA_CODEC_H */ 925#endif /* __SOUND_HDA_CODEC_H */
diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c
new file mode 100644
index 000000000000..fcad5ec31773
--- /dev/null
+++ b/sound/pci/hda/hda_eld.c
@@ -0,0 +1,590 @@
1/*
2 * Generic routines and proc interface for ELD(EDID Like Data) information
3 *
4 * Copyright(c) 2008 Intel Corporation.
5 *
6 * Authors:
7 * Wu Fengguang <wfg@linux.intel.com>
8 *
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
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This driver is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24#include <linux/init.h>
25#include <sound/core.h>
26#include <asm/unaligned.h>
27#include "hda_codec.h"
28#include "hda_local.h"
29
30enum eld_versions {
31 ELD_VER_CEA_861D = 2,
32 ELD_VER_PARTIAL = 31,
33};
34
35enum cea_edid_versions {
36 CEA_EDID_VER_NONE = 0,
37 CEA_EDID_VER_CEA861 = 1,
38 CEA_EDID_VER_CEA861A = 2,
39 CEA_EDID_VER_CEA861BCD = 3,
40 CEA_EDID_VER_RESERVED = 4,
41};
42
43static char *cea_speaker_allocation_names[] = {
44 /* 0 */ "FL/FR",
45 /* 1 */ "LFE",
46 /* 2 */ "FC",
47 /* 3 */ "RL/RR",
48 /* 4 */ "RC",
49 /* 5 */ "FLC/FRC",
50 /* 6 */ "RLC/RRC",
51 /* 7 */ "FLW/FRW",
52 /* 8 */ "FLH/FRH",
53 /* 9 */ "TC",
54 /* 10 */ "FCH",
55};
56
57static char *eld_connection_type_names[4] = {
58 "HDMI",
59 "DisplayPort",
60 "2-reserved",
61 "3-reserved"
62};
63
64enum cea_audio_coding_types {
65 AUDIO_CODING_TYPE_REF_STREAM_HEADER = 0,
66 AUDIO_CODING_TYPE_LPCM = 1,
67 AUDIO_CODING_TYPE_AC3 = 2,
68 AUDIO_CODING_TYPE_MPEG1 = 3,
69 AUDIO_CODING_TYPE_MP3 = 4,
70 AUDIO_CODING_TYPE_MPEG2 = 5,
71 AUDIO_CODING_TYPE_AACLC = 6,
72 AUDIO_CODING_TYPE_DTS = 7,
73 AUDIO_CODING_TYPE_ATRAC = 8,
74 AUDIO_CODING_TYPE_SACD = 9,
75 AUDIO_CODING_TYPE_EAC3 = 10,
76 AUDIO_CODING_TYPE_DTS_HD = 11,
77 AUDIO_CODING_TYPE_MLP = 12,
78 AUDIO_CODING_TYPE_DST = 13,
79 AUDIO_CODING_TYPE_WMAPRO = 14,
80 AUDIO_CODING_TYPE_REF_CXT = 15,
81 /* also include valid xtypes below */
82 AUDIO_CODING_TYPE_HE_AAC = 15,
83 AUDIO_CODING_TYPE_HE_AAC2 = 16,
84 AUDIO_CODING_TYPE_MPEG_SURROUND = 17,
85};
86
87enum cea_audio_coding_xtypes {
88 AUDIO_CODING_XTYPE_HE_REF_CT = 0,
89 AUDIO_CODING_XTYPE_HE_AAC = 1,
90 AUDIO_CODING_XTYPE_HE_AAC2 = 2,
91 AUDIO_CODING_XTYPE_MPEG_SURROUND = 3,
92 AUDIO_CODING_XTYPE_FIRST_RESERVED = 4,
93};
94
95static char *cea_audio_coding_type_names[] = {
96 /* 0 */ "undefined",
97 /* 1 */ "LPCM",
98 /* 2 */ "AC-3",
99 /* 3 */ "MPEG1",
100 /* 4 */ "MP3",
101 /* 5 */ "MPEG2",
102 /* 6 */ "AAC-LC",
103 /* 7 */ "DTS",
104 /* 8 */ "ATRAC",
105 /* 9 */ "DSD (One Bit Audio)",
106 /* 10 */ "E-AC-3/DD+ (Dolby Digital Plus)",
107 /* 11 */ "DTS-HD",
108 /* 12 */ "MLP (Dolby TrueHD)",
109 /* 13 */ "DST",
110 /* 14 */ "WMAPro",
111 /* 15 */ "HE-AAC",
112 /* 16 */ "HE-AACv2",
113 /* 17 */ "MPEG Surround",
114};
115
116/*
117 * The following two lists are shared between
118 * - HDMI audio InfoFrame (source to sink)
119 * - CEA E-EDID Extension (sink to source)
120 */
121
122/*
123 * SS1:SS0 index => sample size
124 */
125static int cea_sample_sizes[4] = {
126 0, /* 0: Refer to Stream Header */
127 AC_SUPPCM_BITS_16, /* 1: 16 bits */
128 AC_SUPPCM_BITS_20, /* 2: 20 bits */
129 AC_SUPPCM_BITS_24, /* 3: 24 bits */
130};
131
132/*
133 * SF2:SF1:SF0 index => sampling frequency
134 */
135static int cea_sampling_frequencies[8] = {
136 0, /* 0: Refer to Stream Header */
137 SNDRV_PCM_RATE_32000, /* 1: 32000Hz */
138 SNDRV_PCM_RATE_44100, /* 2: 44100Hz */
139 SNDRV_PCM_RATE_48000, /* 3: 48000Hz */
140 SNDRV_PCM_RATE_88200, /* 4: 88200Hz */
141 SNDRV_PCM_RATE_96000, /* 5: 96000Hz */
142 SNDRV_PCM_RATE_176400, /* 6: 176400Hz */
143 SNDRV_PCM_RATE_192000, /* 7: 192000Hz */
144};
145
146static unsigned char hdmi_get_eld_byte(struct hda_codec *codec, hda_nid_t nid,
147 int byte_index)
148{
149 unsigned int val;
150
151 val = snd_hda_codec_read(codec, nid, 0,
152 AC_VERB_GET_HDMI_ELDD, byte_index);
153
154#ifdef BE_PARANOID
155 printk(KERN_INFO "HDMI: ELD data byte %d: 0x%x\n", byte_index, val);
156#endif
157
158 if ((val & AC_ELDD_ELD_VALID) == 0) {
159 snd_printd(KERN_INFO "HDMI: invalid ELD data byte %d\n",
160 byte_index);
161 val = 0;
162 }
163
164 return val & AC_ELDD_ELD_DATA;
165}
166
167#define GRAB_BITS(buf, byte, lowbit, bits) \
168({ \
169 BUILD_BUG_ON(lowbit > 7); \
170 BUILD_BUG_ON(bits > 8); \
171 BUILD_BUG_ON(bits <= 0); \
172 \
173 (buf[byte] >> (lowbit)) & ((1 << (bits)) - 1); \
174})
175
176static void hdmi_update_short_audio_desc(struct cea_sad *a,
177 const unsigned char *buf)
178{
179 int i;
180 int val;
181
182 val = GRAB_BITS(buf, 1, 0, 7);
183 a->rates = 0;
184 for (i = 0; i < 7; i++)
185 if (val & (1 << i))
186 a->rates |= cea_sampling_frequencies[i + 1];
187
188 a->channels = GRAB_BITS(buf, 0, 0, 3);
189 a->channels++;
190
191 a->format = GRAB_BITS(buf, 0, 3, 4);
192 switch (a->format) {
193 case AUDIO_CODING_TYPE_REF_STREAM_HEADER:
194 snd_printd(KERN_INFO
195 "HDMI: audio coding type 0 not expected\n");
196 break;
197
198 case AUDIO_CODING_TYPE_LPCM:
199 val = GRAB_BITS(buf, 2, 0, 3);
200 a->sample_bits = 0;
201 for (i = 0; i < 3; i++)
202 if (val & (1 << i))
203 a->sample_bits |= cea_sample_sizes[i + 1];
204 break;
205
206 case AUDIO_CODING_TYPE_AC3:
207 case AUDIO_CODING_TYPE_MPEG1:
208 case AUDIO_CODING_TYPE_MP3:
209 case AUDIO_CODING_TYPE_MPEG2:
210 case AUDIO_CODING_TYPE_AACLC:
211 case AUDIO_CODING_TYPE_DTS:
212 case AUDIO_CODING_TYPE_ATRAC:
213 a->max_bitrate = GRAB_BITS(buf, 2, 0, 8);
214 a->max_bitrate *= 8000;
215 break;
216
217 case AUDIO_CODING_TYPE_SACD:
218 break;
219
220 case AUDIO_CODING_TYPE_EAC3:
221 break;
222
223 case AUDIO_CODING_TYPE_DTS_HD:
224 break;
225
226 case AUDIO_CODING_TYPE_MLP:
227 break;
228
229 case AUDIO_CODING_TYPE_DST:
230 break;
231
232 case AUDIO_CODING_TYPE_WMAPRO:
233 a->profile = GRAB_BITS(buf, 2, 0, 3);
234 break;
235
236 case AUDIO_CODING_TYPE_REF_CXT:
237 a->format = GRAB_BITS(buf, 2, 3, 5);
238 if (a->format == AUDIO_CODING_XTYPE_HE_REF_CT ||
239 a->format >= AUDIO_CODING_XTYPE_FIRST_RESERVED) {
240 snd_printd(KERN_INFO
241 "HDMI: audio coding xtype %d not expected\n",
242 a->format);
243 a->format = 0;
244 } else
245 a->format += AUDIO_CODING_TYPE_HE_AAC -
246 AUDIO_CODING_XTYPE_HE_AAC;
247 break;
248 }
249}
250
251/*
252 * Be careful, ELD buf could be totally rubbish!
253 */
254static int hdmi_update_eld(struct hdmi_eld *e,
255 const unsigned char *buf, int size)
256{
257 int mnl;
258 int i;
259
260 e->eld_ver = GRAB_BITS(buf, 0, 3, 5);
261 if (e->eld_ver != ELD_VER_CEA_861D &&
262 e->eld_ver != ELD_VER_PARTIAL) {
263 snd_printd(KERN_INFO "HDMI: Unknown ELD version %d\n",
264 e->eld_ver);
265 goto out_fail;
266 }
267
268 e->eld_size = size;
269 e->baseline_len = GRAB_BITS(buf, 2, 0, 8);
270 mnl = GRAB_BITS(buf, 4, 0, 5);
271 e->cea_edid_ver = GRAB_BITS(buf, 4, 5, 3);
272
273 e->support_hdcp = GRAB_BITS(buf, 5, 0, 1);
274 e->support_ai = GRAB_BITS(buf, 5, 1, 1);
275 e->conn_type = GRAB_BITS(buf, 5, 2, 2);
276 e->sad_count = GRAB_BITS(buf, 5, 4, 4);
277
278 e->aud_synch_delay = GRAB_BITS(buf, 6, 0, 8) * 2;
279 e->spk_alloc = GRAB_BITS(buf, 7, 0, 7);
280
281 e->port_id = get_unaligned_le64(buf + 8);
282
283 /* not specified, but the spec's tendency is little endian */
284 e->manufacture_id = get_unaligned_le16(buf + 16);
285 e->product_id = get_unaligned_le16(buf + 18);
286
287 if (mnl > ELD_MAX_MNL) {
288 snd_printd(KERN_INFO "HDMI: MNL is reserved value %d\n", mnl);
289 goto out_fail;
290 } else if (ELD_FIXED_BYTES + mnl > size) {
291 snd_printd(KERN_INFO "HDMI: out of range MNL %d\n", mnl);
292 goto out_fail;
293 } else
294 strlcpy(e->monitor_name, buf + ELD_FIXED_BYTES, mnl);
295
296 for (i = 0; i < e->sad_count; i++) {
297 if (ELD_FIXED_BYTES + mnl + 3 * (i + 1) > size) {
298 snd_printd(KERN_INFO "HDMI: out of range SAD %d\n", i);
299 goto out_fail;
300 }
301 hdmi_update_short_audio_desc(e->sad + i,
302 buf + ELD_FIXED_BYTES + mnl + 3 * i);
303 }
304
305 return 0;
306
307out_fail:
308 e->eld_ver = 0;
309 return -EINVAL;
310}
311
312static int hdmi_present_sense(struct hda_codec *codec, hda_nid_t nid)
313{
314 return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_SENSE, 0);
315}
316
317static int hdmi_eld_valid(struct hda_codec *codec, hda_nid_t nid)
318{
319 int eldv;
320 int present;
321
322 present = hdmi_present_sense(codec, nid);
323 eldv = (present & AC_PINSENSE_ELDV);
324 present = (present & AC_PINSENSE_PRESENCE);
325
326#ifdef CONFIG_SND_DEBUG_VERBOSE
327 printk(KERN_INFO "HDMI: sink_present = %d, eld_valid = %d\n",
328 !!present, !!eldv);
329#endif
330
331 return eldv && present;
332}
333
334int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid)
335{
336 return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_DIP_SIZE,
337 AC_DIPSIZE_ELD_BUF);
338}
339
340int snd_hdmi_get_eld(struct hdmi_eld *eld,
341 struct hda_codec *codec, hda_nid_t nid)
342{
343 int i;
344 int ret;
345 int size;
346 unsigned char *buf;
347
348 if (!hdmi_eld_valid(codec, nid))
349 return -ENOENT;
350
351 size = snd_hdmi_get_eld_size(codec, nid);
352 if (size == 0) {
353 /* wfg: workaround for ASUS P5E-VM HDMI board */
354 snd_printd(KERN_INFO "HDMI: ELD buf size is 0, force 128\n");
355 size = 128;
356 }
357 if (size < ELD_FIXED_BYTES || size > PAGE_SIZE) {
358 snd_printd(KERN_INFO "HDMI: invalid ELD buf size %d\n", size);
359 return -ERANGE;
360 }
361
362 buf = kmalloc(size, GFP_KERNEL);
363 if (!buf)
364 return -ENOMEM;
365
366 for (i = 0; i < size; i++)
367 buf[i] = hdmi_get_eld_byte(codec, nid, i);
368
369 ret = hdmi_update_eld(eld, buf, size);
370
371 kfree(buf);
372 return ret;
373}
374
375static void hdmi_show_short_audio_desc(struct cea_sad *a)
376{
377 char buf[SND_PRINT_RATES_ADVISED_BUFSIZE];
378 char buf2[8 + SND_PRINT_BITS_ADVISED_BUFSIZE] = ", bits =";
379
380 if (!a->format)
381 return;
382
383 snd_print_pcm_rates(a->rates, buf, sizeof(buf));
384
385 if (a->format == AUDIO_CODING_TYPE_LPCM)
386 snd_print_pcm_bits(a->sample_bits, buf2 + 8, sizeof(buf2 - 8));
387 else if (a->max_bitrate)
388 snprintf(buf2, sizeof(buf2),
389 ", max bitrate = %d", a->max_bitrate);
390 else
391 buf2[0] = '\0';
392
393 printk(KERN_INFO "HDMI: supports coding type %s:"
394 " channels = %d, rates =%s%s\n",
395 cea_audio_coding_type_names[a->format],
396 a->channels,
397 buf,
398 buf2);
399}
400
401void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen)
402{
403 int i, j;
404
405 for (i = 0, j = 0; i < ARRAY_SIZE(cea_speaker_allocation_names); i++) {
406 if (spk_alloc & (1 << i))
407 j += snprintf(buf + j, buflen - j, " %s",
408 cea_speaker_allocation_names[i]);
409 }
410 buf[j] = '\0'; /* necessary when j == 0 */
411}
412
413void snd_hdmi_show_eld(struct hdmi_eld *e)
414{
415 int i;
416
417 printk(KERN_INFO "HDMI: detected monitor %s at connection type %s\n",
418 e->monitor_name,
419 eld_connection_type_names[e->conn_type]);
420
421 if (e->spk_alloc) {
422 char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE];
423 snd_print_channel_allocation(e->spk_alloc, buf, sizeof(buf));
424 printk(KERN_INFO "HDMI: available speakers:%s\n", buf);
425 }
426
427 for (i = 0; i < e->sad_count; i++)
428 hdmi_show_short_audio_desc(e->sad + i);
429}
430
431#ifdef CONFIG_PROC_FS
432
433static void hdmi_print_sad_info(int i, struct cea_sad *a,
434 struct snd_info_buffer *buffer)
435{
436 char buf[SND_PRINT_RATES_ADVISED_BUFSIZE];
437
438 snd_iprintf(buffer, "sad%d_coding_type\t[0x%x] %s\n",
439 i, a->format, cea_audio_coding_type_names[a->format]);
440 snd_iprintf(buffer, "sad%d_channels\t\t%d\n", i, a->channels);
441
442 snd_print_pcm_rates(a->rates, buf, sizeof(buf));
443 snd_iprintf(buffer, "sad%d_rates\t\t[0x%x]%s\n", i, a->rates, buf);
444
445 if (a->format == AUDIO_CODING_TYPE_LPCM) {
446 snd_print_pcm_bits(a->sample_bits, buf, sizeof(buf));
447 snd_iprintf(buffer, "sad%d_bits\t\t[0x%x]%s\n",
448 i, a->sample_bits, buf);
449 }
450
451 if (a->max_bitrate)
452 snd_iprintf(buffer, "sad%d_max_bitrate\t%d\n",
453 i, a->max_bitrate);
454
455 if (a->profile)
456 snd_iprintf(buffer, "sad%d_profile\t\t%d\n", i, a->profile);
457}
458
459static void hdmi_print_eld_info(struct snd_info_entry *entry,
460 struct snd_info_buffer *buffer)
461{
462 struct hdmi_eld *e = entry->private_data;
463 char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE];
464 int i;
465 static char *eld_versoin_names[32] = {
466 "reserved",
467 "reserved",
468 "CEA-861D or below",
469 [3 ... 30] = "reserved",
470 [31] = "partial"
471 };
472 static char *cea_edid_version_names[8] = {
473 "no CEA EDID Timing Extension block present",
474 "CEA-861",
475 "CEA-861-A",
476 "CEA-861-B, C or D",
477 [4 ... 7] = "reserved"
478 };
479
480 snd_iprintf(buffer, "monitor_name\t\t%s\n", e->monitor_name);
481 snd_iprintf(buffer, "connection_type\t\t%s\n",
482 eld_connection_type_names[e->conn_type]);
483 snd_iprintf(buffer, "eld_version\t\t[0x%x] %s\n", e->eld_ver,
484 eld_versoin_names[e->eld_ver]);
485 snd_iprintf(buffer, "edid_version\t\t[0x%x] %s\n", e->cea_edid_ver,
486 cea_edid_version_names[e->cea_edid_ver]);
487 snd_iprintf(buffer, "manufacture_id\t\t0x%x\n", e->manufacture_id);
488 snd_iprintf(buffer, "product_id\t\t0x%x\n", e->product_id);
489 snd_iprintf(buffer, "port_id\t\t\t0x%llx\n", (long long)e->port_id);
490 snd_iprintf(buffer, "support_hdcp\t\t%d\n", e->support_hdcp);
491 snd_iprintf(buffer, "support_ai\t\t%d\n", e->support_ai);
492 snd_iprintf(buffer, "audio_sync_delay\t%d\n", e->aud_synch_delay);
493
494 snd_print_channel_allocation(e->spk_alloc, buf, sizeof(buf));
495 snd_iprintf(buffer, "speakers\t\t[0x%x]%s\n", e->spk_alloc, buf);
496
497 snd_iprintf(buffer, "sad_count\t\t%d\n", e->sad_count);
498
499 for (i = 0; i < e->sad_count; i++)
500 hdmi_print_sad_info(i, e->sad + i, buffer);
501}
502
503static void hdmi_write_eld_info(struct snd_info_entry *entry,
504 struct snd_info_buffer *buffer)
505{
506 struct hdmi_eld *e = entry->private_data;
507 char line[64];
508 char name[64];
509 char *sname;
510 long long val;
511 int n;
512
513 while (!snd_info_get_line(buffer, line, sizeof(line))) {
514 if (sscanf(line, "%s %llx", name, &val) != 2)
515 continue;
516 /*
517 * We don't allow modification to these fields:
518 * monitor_name manufacture_id product_id
519 * eld_version edid_version
520 */
521 if (!strcmp(name, "connection_type"))
522 e->conn_type = val;
523 else if (!strcmp(name, "port_id"))
524 e->port_id = val;
525 else if (!strcmp(name, "support_hdcp"))
526 e->support_hdcp = val;
527 else if (!strcmp(name, "support_ai"))
528 e->support_ai = val;
529 else if (!strcmp(name, "audio_sync_delay"))
530 e->aud_synch_delay = val;
531 else if (!strcmp(name, "speakers"))
532 e->spk_alloc = val;
533 else if (!strcmp(name, "sad_count"))
534 e->sad_count = val;
535 else if (!strncmp(name, "sad", 3)) {
536 sname = name + 4;
537 n = name[3] - '0';
538 if (name[4] >= '0' && name[4] <= '9') {
539 sname++;
540 n = 10 * n + name[4] - '0';
541 }
542 if (n < 0 || n > 31) /* double the CEA limit */
543 continue;
544 if (!strcmp(sname, "_coding_type"))
545 e->sad[n].format = val;
546 else if (!strcmp(sname, "_channels"))
547 e->sad[n].channels = val;
548 else if (!strcmp(sname, "_rates"))
549 e->sad[n].rates = val;
550 else if (!strcmp(sname, "_bits"))
551 e->sad[n].sample_bits = val;
552 else if (!strcmp(sname, "_max_bitrate"))
553 e->sad[n].max_bitrate = val;
554 else if (!strcmp(sname, "_profile"))
555 e->sad[n].profile = val;
556 if (n >= e->sad_count)
557 e->sad_count = n + 1;
558 }
559 }
560}
561
562
563int snd_hda_eld_proc_new(struct hda_codec *codec, struct hdmi_eld *eld)
564{
565 char name[32];
566 struct snd_info_entry *entry;
567 int err;
568
569 snprintf(name, sizeof(name), "eld#%d", codec->addr);
570 err = snd_card_proc_new(codec->bus->card, name, &entry);
571 if (err < 0)
572 return err;
573
574 snd_info_set_text_ops(entry, eld, hdmi_print_eld_info);
575 entry->c.text.write = hdmi_write_eld_info;
576 entry->mode |= S_IWUSR;
577 eld->proc_entry = entry;
578
579 return 0;
580}
581
582void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld)
583{
584 if (!codec->bus->shutdown && eld->proc_entry) {
585 snd_device_free(codec->bus->card, eld->proc_entry);
586 eld->proc_entry = NULL;
587 }
588}
589
590#endif /* CONFIG_PROC_FS */
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index 0ca30894f7c6..65745e96dc70 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -723,7 +723,8 @@ static int create_mixer(struct hda_codec *codec, struct hda_gnode *node,
723 if (is_loopback) 723 if (is_loopback)
724 add_input_loopback(codec, node->nid, HDA_INPUT, index); 724 add_input_loopback(codec, node->nid, HDA_INPUT, index);
725 snd_printdd("[%s] NID=0x%x, DIR=IN, IDX=0x%x\n", name, node->nid, index); 725 snd_printdd("[%s] NID=0x%x, DIR=IN, IDX=0x%x\n", name, node->nid, index);
726 if ((err = snd_ctl_add(codec->bus->card, snd_ctl_new1(&knew, codec))) < 0) 726 err = snd_hda_ctl_add(codec, snd_ctl_new1(&knew, codec));
727 if (err < 0)
727 return err; 728 return err;
728 created = 1; 729 created = 1;
729 } else if ((node->wid_caps & AC_WCAP_OUT_AMP) && 730 } else if ((node->wid_caps & AC_WCAP_OUT_AMP) &&
@@ -732,7 +733,8 @@ static int create_mixer(struct hda_codec *codec, struct hda_gnode *node,
732 if (is_loopback) 733 if (is_loopback)
733 add_input_loopback(codec, node->nid, HDA_OUTPUT, 0); 734 add_input_loopback(codec, node->nid, HDA_OUTPUT, 0);
734 snd_printdd("[%s] NID=0x%x, DIR=OUT\n", name, node->nid); 735 snd_printdd("[%s] NID=0x%x, DIR=OUT\n", name, node->nid);
735 if ((err = snd_ctl_add(codec->bus->card, snd_ctl_new1(&knew, codec))) < 0) 736 err = snd_hda_ctl_add(codec, snd_ctl_new1(&knew, codec));
737 if (err < 0)
736 return err; 738 return err;
737 created = 1; 739 created = 1;
738 } 740 }
@@ -745,14 +747,16 @@ static int create_mixer(struct hda_codec *codec, struct hda_gnode *node,
745 (node->amp_in_caps & AC_AMPCAP_NUM_STEPS)) { 747 (node->amp_in_caps & AC_AMPCAP_NUM_STEPS)) {
746 knew = (struct snd_kcontrol_new)HDA_CODEC_VOLUME(name, node->nid, index, HDA_INPUT); 748 knew = (struct snd_kcontrol_new)HDA_CODEC_VOLUME(name, node->nid, index, HDA_INPUT);
747 snd_printdd("[%s] NID=0x%x, DIR=IN, IDX=0x%x\n", name, node->nid, index); 749 snd_printdd("[%s] NID=0x%x, DIR=IN, IDX=0x%x\n", name, node->nid, index);
748 if ((err = snd_ctl_add(codec->bus->card, snd_ctl_new1(&knew, codec))) < 0) 750 err = snd_hda_ctl_add(codec, snd_ctl_new1(&knew, codec));
751 if (err < 0)
749 return err; 752 return err;
750 created = 1; 753 created = 1;
751 } else if ((node->wid_caps & AC_WCAP_OUT_AMP) && 754 } else if ((node->wid_caps & AC_WCAP_OUT_AMP) &&
752 (node->amp_out_caps & AC_AMPCAP_NUM_STEPS)) { 755 (node->amp_out_caps & AC_AMPCAP_NUM_STEPS)) {
753 knew = (struct snd_kcontrol_new)HDA_CODEC_VOLUME(name, node->nid, 0, HDA_OUTPUT); 756 knew = (struct snd_kcontrol_new)HDA_CODEC_VOLUME(name, node->nid, 0, HDA_OUTPUT);
754 snd_printdd("[%s] NID=0x%x, DIR=OUT\n", name, node->nid); 757 snd_printdd("[%s] NID=0x%x, DIR=OUT\n", name, node->nid);
755 if ((err = snd_ctl_add(codec->bus->card, snd_ctl_new1(&knew, codec))) < 0) 758 err = snd_hda_ctl_add(codec, snd_ctl_new1(&knew, codec));
759 if (err < 0)
756 return err; 760 return err;
757 created = 1; 761 created = 1;
758 } 762 }
@@ -849,8 +853,8 @@ static int build_input_controls(struct hda_codec *codec)
849 } 853 }
850 854
851 /* create input MUX if multiple sources are available */ 855 /* create input MUX if multiple sources are available */
852 if ((err = snd_ctl_add(codec->bus->card, 856 err = snd_hda_ctl_add(codec, snd_ctl_new1(&cap_sel, codec));
853 snd_ctl_new1(&cap_sel, codec))) < 0) 857 if (err < 0)
854 return err; 858 return err;
855 859
856 /* no volume control? */ 860 /* no volume control? */
@@ -867,8 +871,8 @@ static int build_input_controls(struct hda_codec *codec)
867 HDA_CODEC_VOLUME(name, adc_node->nid, 871 HDA_CODEC_VOLUME(name, adc_node->nid,
868 spec->input_mux.items[i].index, 872 spec->input_mux.items[i].index,
869 HDA_INPUT); 873 HDA_INPUT);
870 if ((err = snd_ctl_add(codec->bus->card, 874 err = snd_hda_ctl_add(codec, snd_ctl_new1(&knew, codec));
871 snd_ctl_new1(&knew, codec))) < 0) 875 if (err < 0)
872 return err; 876 return err;
873 } 877 }
874 878
@@ -1097,3 +1101,4 @@ int snd_hda_parse_generic_codec(struct hda_codec *codec)
1097 snd_hda_generic_free(codec); 1101 snd_hda_generic_free(codec);
1098 return err; 1102 return err;
1099} 1103}
1104EXPORT_SYMBOL(snd_hda_parse_generic_codec);
diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c
index 6e18a422d993..300ab407cf42 100644
--- a/sound/pci/hda/hda_hwdep.c
+++ b/sound/pci/hda/hda_hwdep.c
@@ -23,10 +23,12 @@
23#include <linux/pci.h> 23#include <linux/pci.h>
24#include <linux/compat.h> 24#include <linux/compat.h>
25#include <linux/mutex.h> 25#include <linux/mutex.h>
26#include <linux/ctype.h>
26#include <sound/core.h> 27#include <sound/core.h>
27#include "hda_codec.h" 28#include "hda_codec.h"
28#include "hda_local.h" 29#include "hda_local.h"
29#include <sound/hda_hwdep.h> 30#include <sound/hda_hwdep.h>
31#include <sound/minors.h>
30 32
31/* 33/*
32 * write/read an out-of-bound verb 34 * write/read an out-of-bound verb
@@ -95,7 +97,26 @@ static int hda_hwdep_open(struct snd_hwdep *hw, struct file *file)
95 return 0; 97 return 0;
96} 98}
97 99
98int __devinit snd_hda_create_hwdep(struct hda_codec *codec) 100static void clear_hwdep_elements(struct hda_codec *codec)
101{
102 char **head;
103 int i;
104
105 /* clear init verbs */
106 snd_array_free(&codec->init_verbs);
107 /* clear hints */
108 head = codec->hints.list;
109 for (i = 0; i < codec->hints.used; i++, head++)
110 kfree(*head);
111 snd_array_free(&codec->hints);
112}
113
114static void hwdep_free(struct snd_hwdep *hwdep)
115{
116 clear_hwdep_elements(hwdep->private_data);
117}
118
119int /*__devinit*/ snd_hda_create_hwdep(struct hda_codec *codec)
99{ 120{
100 char hwname[16]; 121 char hwname[16];
101 struct snd_hwdep *hwdep; 122 struct snd_hwdep *hwdep;
@@ -109,6 +130,7 @@ int __devinit snd_hda_create_hwdep(struct hda_codec *codec)
109 sprintf(hwdep->name, "HDA Codec %d", codec->addr); 130 sprintf(hwdep->name, "HDA Codec %d", codec->addr);
110 hwdep->iface = SNDRV_HWDEP_IFACE_HDA; 131 hwdep->iface = SNDRV_HWDEP_IFACE_HDA;
111 hwdep->private_data = codec; 132 hwdep->private_data = codec;
133 hwdep->private_free = hwdep_free;
112 hwdep->exclusive = 1; 134 hwdep->exclusive = 1;
113 135
114 hwdep->ops.open = hda_hwdep_open; 136 hwdep->ops.open = hda_hwdep_open;
@@ -117,5 +139,215 @@ int __devinit snd_hda_create_hwdep(struct hda_codec *codec)
117 hwdep->ops.ioctl_compat = hda_hwdep_ioctl_compat; 139 hwdep->ops.ioctl_compat = hda_hwdep_ioctl_compat;
118#endif 140#endif
119 141
142 snd_array_init(&codec->init_verbs, sizeof(struct hda_verb), 32);
143 snd_array_init(&codec->hints, sizeof(char *), 32);
144
120 return 0; 145 return 0;
121} 146}
147
148#ifdef CONFIG_SND_HDA_RECONFIG
149
150/*
151 * sysfs interface
152 */
153
154static int clear_codec(struct hda_codec *codec)
155{
156 snd_hda_codec_reset(codec);
157 clear_hwdep_elements(codec);
158 return 0;
159}
160
161static int reconfig_codec(struct hda_codec *codec)
162{
163 int err;
164
165 snd_printk(KERN_INFO "hda-codec: reconfiguring\n");
166 snd_hda_codec_reset(codec);
167 err = snd_hda_codec_configure(codec);
168 if (err < 0)
169 return err;
170 /* rebuild PCMs */
171 err = snd_hda_codec_build_pcms(codec);
172 if (err < 0)
173 return err;
174 /* rebuild mixers */
175 err = snd_hda_codec_build_controls(codec);
176 if (err < 0)
177 return err;
178 return 0;
179}
180
181/*
182 * allocate a string at most len chars, and remove the trailing EOL
183 */
184static char *kstrndup_noeol(const char *src, size_t len)
185{
186 char *s = kstrndup(src, len, GFP_KERNEL);
187 char *p;
188 if (!s)
189 return NULL;
190 p = strchr(s, '\n');
191 if (p)
192 *p = 0;
193 return s;
194}
195
196#define CODEC_INFO_SHOW(type) \
197static ssize_t type##_show(struct device *dev, \
198 struct device_attribute *attr, \
199 char *buf) \
200{ \
201 struct snd_hwdep *hwdep = dev_get_drvdata(dev); \
202 struct hda_codec *codec = hwdep->private_data; \
203 return sprintf(buf, "0x%x\n", codec->type); \
204}
205
206#define CODEC_INFO_STR_SHOW(type) \
207static ssize_t type##_show(struct device *dev, \
208 struct device_attribute *attr, \
209 char *buf) \
210{ \
211 struct snd_hwdep *hwdep = dev_get_drvdata(dev); \
212 struct hda_codec *codec = hwdep->private_data; \
213 return sprintf(buf, "%s\n", \
214 codec->type ? codec->type : ""); \
215}
216
217CODEC_INFO_SHOW(vendor_id);
218CODEC_INFO_SHOW(subsystem_id);
219CODEC_INFO_SHOW(revision_id);
220CODEC_INFO_SHOW(afg);
221CODEC_INFO_SHOW(mfg);
222CODEC_INFO_STR_SHOW(name);
223CODEC_INFO_STR_SHOW(modelname);
224
225#define CODEC_INFO_STORE(type) \
226static ssize_t type##_store(struct device *dev, \
227 struct device_attribute *attr, \
228 const char *buf, size_t count) \
229{ \
230 struct snd_hwdep *hwdep = dev_get_drvdata(dev); \
231 struct hda_codec *codec = hwdep->private_data; \
232 char *after; \
233 codec->type = simple_strtoul(buf, &after, 0); \
234 return count; \
235}
236
237#define CODEC_INFO_STR_STORE(type) \
238static ssize_t type##_store(struct device *dev, \
239 struct device_attribute *attr, \
240 const char *buf, size_t count) \
241{ \
242 struct snd_hwdep *hwdep = dev_get_drvdata(dev); \
243 struct hda_codec *codec = hwdep->private_data; \
244 char *s = kstrndup_noeol(buf, 64); \
245 if (!s) \
246 return -ENOMEM; \
247 kfree(codec->type); \
248 codec->type = s; \
249 return count; \
250}
251
252CODEC_INFO_STORE(vendor_id);
253CODEC_INFO_STORE(subsystem_id);
254CODEC_INFO_STORE(revision_id);
255CODEC_INFO_STR_STORE(name);
256CODEC_INFO_STR_STORE(modelname);
257
258#define CODEC_ACTION_STORE(type) \
259static ssize_t type##_store(struct device *dev, \
260 struct device_attribute *attr, \
261 const char *buf, size_t count) \
262{ \
263 struct snd_hwdep *hwdep = dev_get_drvdata(dev); \
264 struct hda_codec *codec = hwdep->private_data; \
265 int err = 0; \
266 if (*buf) \
267 err = type##_codec(codec); \
268 return err < 0 ? err : count; \
269}
270
271CODEC_ACTION_STORE(reconfig);
272CODEC_ACTION_STORE(clear);
273
274static ssize_t init_verbs_store(struct device *dev,
275 struct device_attribute *attr,
276 const char *buf, size_t count)
277{
278 struct snd_hwdep *hwdep = dev_get_drvdata(dev);
279 struct hda_codec *codec = hwdep->private_data;
280 char *p;
281 struct hda_verb verb, *v;
282
283 verb.nid = simple_strtoul(buf, &p, 0);
284 verb.verb = simple_strtoul(p, &p, 0);
285 verb.param = simple_strtoul(p, &p, 0);
286 if (!verb.nid || !verb.verb || !verb.param)
287 return -EINVAL;
288 v = snd_array_new(&codec->init_verbs);
289 if (!v)
290 return -ENOMEM;
291 *v = verb;
292 return count;
293}
294
295static ssize_t hints_store(struct device *dev,
296 struct device_attribute *attr,
297 const char *buf, size_t count)
298{
299 struct snd_hwdep *hwdep = dev_get_drvdata(dev);
300 struct hda_codec *codec = hwdep->private_data;
301 char *p;
302 char **hint;
303
304 if (!*buf || isspace(*buf) || *buf == '#' || *buf == '\n')
305 return count;
306 p = kstrndup_noeol(buf, 1024);
307 if (!p)
308 return -ENOMEM;
309 hint = snd_array_new(&codec->hints);
310 if (!hint) {
311 kfree(p);
312 return -ENOMEM;
313 }
314 *hint = p;
315 return count;
316}
317
318#define CODEC_ATTR_RW(type) \
319 __ATTR(type, 0644, type##_show, type##_store)
320#define CODEC_ATTR_RO(type) \
321 __ATTR_RO(type)
322#define CODEC_ATTR_WO(type) \
323 __ATTR(type, 0200, NULL, type##_store)
324
325static struct device_attribute codec_attrs[] = {
326 CODEC_ATTR_RW(vendor_id),
327 CODEC_ATTR_RW(subsystem_id),
328 CODEC_ATTR_RW(revision_id),
329 CODEC_ATTR_RO(afg),
330 CODEC_ATTR_RO(mfg),
331 CODEC_ATTR_RW(name),
332 CODEC_ATTR_RW(modelname),
333 CODEC_ATTR_WO(init_verbs),
334 CODEC_ATTR_WO(hints),
335 CODEC_ATTR_WO(reconfig),
336 CODEC_ATTR_WO(clear),
337};
338
339/*
340 * create sysfs files on hwdep directory
341 */
342int snd_hda_hwdep_add_sysfs(struct hda_codec *codec)
343{
344 struct snd_hwdep *hwdep = codec->hwdep;
345 int i;
346
347 for (i = 0; i < ARRAY_SIZE(codec_attrs); i++)
348 snd_add_device_sysfs_file(SNDRV_DEVICE_TYPE_HWDEP, hwdep->card,
349 hwdep->device, &codec_attrs[i]);
350 return 0;
351}
352
353#endif /* CONFIG_SND_HDA_RECONFIG */
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 35722ec920cb..f04de115ee11 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -58,6 +58,7 @@ static char *model[SNDRV_CARDS];
58static int position_fix[SNDRV_CARDS]; 58static int position_fix[SNDRV_CARDS];
59static int bdl_pos_adj[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1}; 59static int bdl_pos_adj[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};
60static int probe_mask[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1}; 60static int probe_mask[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};
61static int probe_only[SNDRV_CARDS];
61static int single_cmd; 62static int single_cmd;
62static int enable_msi; 63static int enable_msi;
63 64
@@ -76,6 +77,8 @@ module_param_array(bdl_pos_adj, int, NULL, 0644);
76MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset."); 77MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset.");
77module_param_array(probe_mask, int, NULL, 0444); 78module_param_array(probe_mask, int, NULL, 0444);
78MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1)."); 79MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1).");
80module_param_array(probe_only, bool, NULL, 0444);
81MODULE_PARM_DESC(probe_only, "Only probing and no codec initialization.");
79module_param(single_cmd, bool, 0444); 82module_param(single_cmd, bool, 0444);
80MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs " 83MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs "
81 "(for debugging only)."); 84 "(for debugging only).");
@@ -83,7 +86,10 @@ module_param(enable_msi, int, 0444);
83MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)"); 86MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)");
84 87
85#ifdef CONFIG_SND_HDA_POWER_SAVE 88#ifdef CONFIG_SND_HDA_POWER_SAVE
86/* power_save option is defined in hda_codec.c */ 89static int power_save = CONFIG_SND_HDA_POWER_SAVE_DEFAULT;
90module_param(power_save, int, 0644);
91MODULE_PARM_DESC(power_save, "Automatic power-saving timeout "
92 "(in second, 0 = disable).");
87 93
88/* reset the HD-audio controller in power save mode. 94/* reset the HD-audio controller in power save mode.
89 * this may give more power-saving, but will take longer time to 95 * this may give more power-saving, but will take longer time to
@@ -292,6 +298,8 @@ enum {
292/* Define VIA HD Audio Device ID*/ 298/* Define VIA HD Audio Device ID*/
293#define VIA_HDAC_DEVICE_ID 0x3288 299#define VIA_HDAC_DEVICE_ID 0x3288
294 300
301/* HD Audio class code */
302#define PCI_CLASS_MULTIMEDIA_HD_AUDIO 0x0403
295 303
296/* 304/*
297 */ 305 */
@@ -392,6 +400,7 @@ struct azx {
392 unsigned int msi :1; 400 unsigned int msi :1;
393 unsigned int irq_pending_warned :1; 401 unsigned int irq_pending_warned :1;
394 unsigned int via_dmapos_patch :1; /* enable DMA-position fix for VIA */ 402 unsigned int via_dmapos_patch :1; /* enable DMA-position fix for VIA */
403 unsigned int probing :1; /* codec probing phase */
395 404
396 /* for debugging */ 405 /* for debugging */
397 unsigned int last_cmd; /* last issued command (to sync) */ 406 unsigned int last_cmd; /* last issued command (to sync) */
@@ -414,6 +423,7 @@ enum {
414 AZX_DRIVER_ULI, 423 AZX_DRIVER_ULI,
415 AZX_DRIVER_NVIDIA, 424 AZX_DRIVER_NVIDIA,
416 AZX_DRIVER_TERA, 425 AZX_DRIVER_TERA,
426 AZX_DRIVER_GENERIC,
417 AZX_NUM_DRIVERS, /* keep this as last entry */ 427 AZX_NUM_DRIVERS, /* keep this as last entry */
418}; 428};
419 429
@@ -427,6 +437,7 @@ static char *driver_short_names[] __devinitdata = {
427 [AZX_DRIVER_ULI] = "HDA ULI M5461", 437 [AZX_DRIVER_ULI] = "HDA ULI M5461",
428 [AZX_DRIVER_NVIDIA] = "HDA NVidia", 438 [AZX_DRIVER_NVIDIA] = "HDA NVidia",
429 [AZX_DRIVER_TERA] = "HDA Teradici", 439 [AZX_DRIVER_TERA] = "HDA Teradici",
440 [AZX_DRIVER_GENERIC] = "HD-Audio Generic",
430}; 441};
431 442
432/* 443/*
@@ -527,9 +538,9 @@ static void azx_free_cmd_io(struct azx *chip)
527} 538}
528 539
529/* send a command */ 540/* send a command */
530static int azx_corb_send_cmd(struct hda_codec *codec, u32 val) 541static int azx_corb_send_cmd(struct hda_bus *bus, u32 val)
531{ 542{
532 struct azx *chip = codec->bus->private_data; 543 struct azx *chip = bus->private_data;
533 unsigned int wp; 544 unsigned int wp;
534 545
535 /* add command to corb */ 546 /* add command to corb */
@@ -577,9 +588,9 @@ static void azx_update_rirb(struct azx *chip)
577} 588}
578 589
579/* receive a response */ 590/* receive a response */
580static unsigned int azx_rirb_get_response(struct hda_codec *codec) 591static unsigned int azx_rirb_get_response(struct hda_bus *bus)
581{ 592{
582 struct azx *chip = codec->bus->private_data; 593 struct azx *chip = bus->private_data;
583 unsigned long timeout; 594 unsigned long timeout;
584 595
585 again: 596 again:
@@ -596,7 +607,7 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec)
596 } 607 }
597 if (time_after(jiffies, timeout)) 608 if (time_after(jiffies, timeout))
598 break; 609 break;
599 if (codec->bus->needs_damn_long_delay) 610 if (bus->needs_damn_long_delay)
600 msleep(2); /* temporary workaround */ 611 msleep(2); /* temporary workaround */
601 else { 612 else {
602 udelay(10); 613 udelay(10);
@@ -624,6 +635,14 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec)
624 goto again; 635 goto again;
625 } 636 }
626 637
638 if (chip->probing) {
639 /* If this critical timeout happens during the codec probing
640 * phase, this is likely an access to a non-existing codec
641 * slot. Better to return an error and reset the system.
642 */
643 return -1;
644 }
645
627 snd_printk(KERN_ERR "hda_intel: azx_get_response timeout, " 646 snd_printk(KERN_ERR "hda_intel: azx_get_response timeout, "
628 "switching to single_cmd mode: last cmd=0x%08x\n", 647 "switching to single_cmd mode: last cmd=0x%08x\n",
629 chip->last_cmd); 648 chip->last_cmd);
@@ -646,9 +665,9 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec)
646 */ 665 */
647 666
648/* send a command */ 667/* send a command */
649static int azx_single_send_cmd(struct hda_codec *codec, u32 val) 668static int azx_single_send_cmd(struct hda_bus *bus, u32 val)
650{ 669{
651 struct azx *chip = codec->bus->private_data; 670 struct azx *chip = bus->private_data;
652 int timeout = 50; 671 int timeout = 50;
653 672
654 while (timeout--) { 673 while (timeout--) {
@@ -671,9 +690,9 @@ static int azx_single_send_cmd(struct hda_codec *codec, u32 val)
671} 690}
672 691
673/* receive a response */ 692/* receive a response */
674static unsigned int azx_single_get_response(struct hda_codec *codec) 693static unsigned int azx_single_get_response(struct hda_bus *bus)
675{ 694{
676 struct azx *chip = codec->bus->private_data; 695 struct azx *chip = bus->private_data;
677 int timeout = 50; 696 int timeout = 50;
678 697
679 while (timeout--) { 698 while (timeout--) {
@@ -696,38 +715,29 @@ static unsigned int azx_single_get_response(struct hda_codec *codec)
696 */ 715 */
697 716
698/* send a command */ 717/* send a command */
699static int azx_send_cmd(struct hda_codec *codec, hda_nid_t nid, 718static int azx_send_cmd(struct hda_bus *bus, unsigned int val)
700 int direct, unsigned int verb,
701 unsigned int para)
702{ 719{
703 struct azx *chip = codec->bus->private_data; 720 struct azx *chip = bus->private_data;
704 u32 val;
705
706 val = (u32)(codec->addr & 0x0f) << 28;
707 val |= (u32)direct << 27;
708 val |= (u32)nid << 20;
709 val |= verb << 8;
710 val |= para;
711 chip->last_cmd = val;
712 721
722 chip->last_cmd = val;
713 if (chip->single_cmd) 723 if (chip->single_cmd)
714 return azx_single_send_cmd(codec, val); 724 return azx_single_send_cmd(bus, val);
715 else 725 else
716 return azx_corb_send_cmd(codec, val); 726 return azx_corb_send_cmd(bus, val);
717} 727}
718 728
719/* get a response */ 729/* get a response */
720static unsigned int azx_get_response(struct hda_codec *codec) 730static unsigned int azx_get_response(struct hda_bus *bus)
721{ 731{
722 struct azx *chip = codec->bus->private_data; 732 struct azx *chip = bus->private_data;
723 if (chip->single_cmd) 733 if (chip->single_cmd)
724 return azx_single_get_response(codec); 734 return azx_single_get_response(bus);
725 else 735 else
726 return azx_rirb_get_response(codec); 736 return azx_rirb_get_response(bus);
727} 737}
728 738
729#ifdef CONFIG_SND_HDA_POWER_SAVE 739#ifdef CONFIG_SND_HDA_POWER_SAVE
730static void azx_power_notify(struct hda_codec *codec); 740static void azx_power_notify(struct hda_bus *bus);
731#endif 741#endif
732 742
733/* reset codec link */ 743/* reset codec link */
@@ -1184,6 +1194,28 @@ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev)
1184 return 0; 1194 return 0;
1185} 1195}
1186 1196
1197/*
1198 * Probe the given codec address
1199 */
1200static int probe_codec(struct azx *chip, int addr)
1201{
1202 unsigned int cmd = (addr << 28) | (AC_NODE_ROOT << 20) |
1203 (AC_VERB_PARAMETERS << 8) | AC_PAR_VENDOR_ID;
1204 unsigned int res;
1205
1206 chip->probing = 1;
1207 azx_send_cmd(chip->bus, cmd);
1208 res = azx_get_response(chip->bus);
1209 chip->probing = 0;
1210 if (res == -1)
1211 return -EIO;
1212 snd_printdd("hda_intel: codec #%d probed OK\n", addr);
1213 return 0;
1214}
1215
1216static int azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
1217 struct hda_pcm *cpcm);
1218static void azx_stop_chip(struct azx *chip);
1187 1219
1188/* 1220/*
1189 * Codec initialization 1221 * Codec initialization
@@ -1194,21 +1226,13 @@ static unsigned int azx_max_codecs[AZX_NUM_DRIVERS] __devinitdata = {
1194 [AZX_DRIVER_TERA] = 1, 1226 [AZX_DRIVER_TERA] = 1,
1195}; 1227};
1196 1228
1197/* number of slots to probe as default
1198 * this can be different from azx_max_codecs[] -- e.g. some boards
1199 * report wrongly the non-existing 4th slot availability
1200 */
1201static unsigned int azx_default_codecs[AZX_NUM_DRIVERS] __devinitdata = {
1202 [AZX_DRIVER_ICH] = 3,
1203 [AZX_DRIVER_ATI] = 3,
1204};
1205
1206static int __devinit azx_codec_create(struct azx *chip, const char *model, 1229static int __devinit azx_codec_create(struct azx *chip, const char *model,
1207 unsigned int codec_probe_mask) 1230 unsigned int codec_probe_mask,
1231 int no_init)
1208{ 1232{
1209 struct hda_bus_template bus_temp; 1233 struct hda_bus_template bus_temp;
1210 int c, codecs, audio_codecs, err; 1234 int c, codecs, err;
1211 int def_slots, max_slots; 1235 int max_slots;
1212 1236
1213 memset(&bus_temp, 0, sizeof(bus_temp)); 1237 memset(&bus_temp, 0, sizeof(bus_temp));
1214 bus_temp.private_data = chip; 1238 bus_temp.private_data = chip;
@@ -1216,7 +1240,9 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model,
1216 bus_temp.pci = chip->pci; 1240 bus_temp.pci = chip->pci;
1217 bus_temp.ops.command = azx_send_cmd; 1241 bus_temp.ops.command = azx_send_cmd;
1218 bus_temp.ops.get_response = azx_get_response; 1242 bus_temp.ops.get_response = azx_get_response;
1243 bus_temp.ops.attach_pcm = azx_attach_pcm_stream;
1219#ifdef CONFIG_SND_HDA_POWER_SAVE 1244#ifdef CONFIG_SND_HDA_POWER_SAVE
1245 bus_temp.power_save = &power_save;
1220 bus_temp.ops.pm_notify = azx_power_notify; 1246 bus_temp.ops.pm_notify = azx_power_notify;
1221#endif 1247#endif
1222 1248
@@ -1227,33 +1253,43 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model,
1227 if (chip->driver_type == AZX_DRIVER_NVIDIA) 1253 if (chip->driver_type == AZX_DRIVER_NVIDIA)
1228 chip->bus->needs_damn_long_delay = 1; 1254 chip->bus->needs_damn_long_delay = 1;
1229 1255
1230 codecs = audio_codecs = 0; 1256 codecs = 0;
1231 max_slots = azx_max_codecs[chip->driver_type]; 1257 max_slots = azx_max_codecs[chip->driver_type];
1232 if (!max_slots) 1258 if (!max_slots)
1233 max_slots = AZX_MAX_CODECS; 1259 max_slots = AZX_MAX_CODECS;
1234 def_slots = azx_default_codecs[chip->driver_type]; 1260
1235 if (!def_slots) 1261 /* First try to probe all given codec slots */
1236 def_slots = max_slots; 1262 for (c = 0; c < max_slots; c++) {
1237 for (c = 0; c < def_slots; c++) { 1263 if ((chip->codec_mask & (1 << c)) & codec_probe_mask) {
1264 if (probe_codec(chip, c) < 0) {
1265 /* Some BIOSen give you wrong codec addresses
1266 * that don't exist
1267 */
1268 snd_printk(KERN_WARNING
1269 "hda_intel: Codec #%d probe error; "
1270 "disabling it...\n", c);
1271 chip->codec_mask &= ~(1 << c);
1272 /* More badly, accessing to a non-existing
1273 * codec often screws up the controller chip,
1274 * and distrubs the further communications.
1275 * Thus if an error occurs during probing,
1276 * better to reset the controller chip to
1277 * get back to the sanity state.
1278 */
1279 azx_stop_chip(chip);
1280 azx_init_chip(chip);
1281 }
1282 }
1283 }
1284
1285 /* Then create codec instances */
1286 for (c = 0; c < max_slots; c++) {
1238 if ((chip->codec_mask & (1 << c)) & codec_probe_mask) { 1287 if ((chip->codec_mask & (1 << c)) & codec_probe_mask) {
1239 struct hda_codec *codec; 1288 struct hda_codec *codec;
1240 err = snd_hda_codec_new(chip->bus, c, &codec); 1289 err = snd_hda_codec_new(chip->bus, c, !no_init, &codec);
1241 if (err < 0) 1290 if (err < 0)
1242 continue; 1291 continue;
1243 codecs++; 1292 codecs++;
1244 if (codec->afg)
1245 audio_codecs++;
1246 }
1247 }
1248 if (!audio_codecs) {
1249 /* probe additional slots if no codec is found */
1250 for (; c < max_slots; c++) {
1251 if ((chip->codec_mask & (1 << c)) & codec_probe_mask) {
1252 err = snd_hda_codec_new(chip->bus, c, NULL);
1253 if (err < 0)
1254 continue;
1255 codecs++;
1256 }
1257 } 1293 }
1258 } 1294 }
1259 if (!codecs) { 1295 if (!codecs) {
@@ -1722,111 +1758,59 @@ static struct snd_pcm_ops azx_pcm_ops = {
1722 1758
1723static void azx_pcm_free(struct snd_pcm *pcm) 1759static void azx_pcm_free(struct snd_pcm *pcm)
1724{ 1760{
1725 kfree(pcm->private_data); 1761 struct azx_pcm *apcm = pcm->private_data;
1762 if (apcm) {
1763 apcm->chip->pcm[pcm->device] = NULL;
1764 kfree(apcm);
1765 }
1726} 1766}
1727 1767
1728static int __devinit create_codec_pcm(struct azx *chip, struct hda_codec *codec, 1768static int
1729 struct hda_pcm *cpcm) 1769azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
1770 struct hda_pcm *cpcm)
1730{ 1771{
1731 int err; 1772 struct azx *chip = bus->private_data;
1732 struct snd_pcm *pcm; 1773 struct snd_pcm *pcm;
1733 struct azx_pcm *apcm; 1774 struct azx_pcm *apcm;
1775 int pcm_dev = cpcm->device;
1776 int s, err;
1734 1777
1735 /* if no substreams are defined for both playback and capture, 1778 if (pcm_dev >= AZX_MAX_PCMS) {
1736 * it's just a placeholder. ignore it. 1779 snd_printk(KERN_ERR SFX "Invalid PCM device number %d\n",
1737 */ 1780 pcm_dev);
1738 if (!cpcm->stream[0].substreams && !cpcm->stream[1].substreams)
1739 return 0;
1740
1741 if (snd_BUG_ON(!cpcm->name))
1742 return -EINVAL; 1781 return -EINVAL;
1743 1782 }
1744 err = snd_pcm_new(chip->card, cpcm->name, cpcm->device, 1783 if (chip->pcm[pcm_dev]) {
1745 cpcm->stream[0].substreams, 1784 snd_printk(KERN_ERR SFX "PCM %d already exists\n", pcm_dev);
1746 cpcm->stream[1].substreams, 1785 return -EBUSY;
1786 }
1787 err = snd_pcm_new(chip->card, cpcm->name, pcm_dev,
1788 cpcm->stream[SNDRV_PCM_STREAM_PLAYBACK].substreams,
1789 cpcm->stream[SNDRV_PCM_STREAM_CAPTURE].substreams,
1747 &pcm); 1790 &pcm);
1748 if (err < 0) 1791 if (err < 0)
1749 return err; 1792 return err;
1750 strcpy(pcm->name, cpcm->name); 1793 strcpy(pcm->name, cpcm->name);
1751 apcm = kmalloc(sizeof(*apcm), GFP_KERNEL); 1794 apcm = kzalloc(sizeof(*apcm), GFP_KERNEL);
1752 if (apcm == NULL) 1795 if (apcm == NULL)
1753 return -ENOMEM; 1796 return -ENOMEM;
1754 apcm->chip = chip; 1797 apcm->chip = chip;
1755 apcm->codec = codec; 1798 apcm->codec = codec;
1756 apcm->hinfo[0] = &cpcm->stream[0];
1757 apcm->hinfo[1] = &cpcm->stream[1];
1758 pcm->private_data = apcm; 1799 pcm->private_data = apcm;
1759 pcm->private_free = azx_pcm_free; 1800 pcm->private_free = azx_pcm_free;
1760 if (cpcm->stream[0].substreams) 1801 if (cpcm->pcm_type == HDA_PCM_TYPE_MODEM)
1761 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &azx_pcm_ops); 1802 pcm->dev_class = SNDRV_PCM_CLASS_MODEM;
1762 if (cpcm->stream[1].substreams) 1803 chip->pcm[pcm_dev] = pcm;
1763 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &azx_pcm_ops); 1804 cpcm->pcm = pcm;
1805 for (s = 0; s < 2; s++) {
1806 apcm->hinfo[s] = &cpcm->stream[s];
1807 if (cpcm->stream[s].substreams)
1808 snd_pcm_set_ops(pcm, s, &azx_pcm_ops);
1809 }
1810 /* buffer pre-allocation */
1764 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG, 1811 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
1765 snd_dma_pci_data(chip->pci), 1812 snd_dma_pci_data(chip->pci),
1766 1024 * 64, 32 * 1024 * 1024); 1813 1024 * 64, 32 * 1024 * 1024);
1767 chip->pcm[cpcm->device] = pcm;
1768 return 0;
1769}
1770
1771static int __devinit azx_pcm_create(struct azx *chip)
1772{
1773 static const char *dev_name[HDA_PCM_NTYPES] = {
1774 "Audio", "SPDIF", "HDMI", "Modem"
1775 };
1776 /* starting device index for each PCM type */
1777 static int dev_idx[HDA_PCM_NTYPES] = {
1778 [HDA_PCM_TYPE_AUDIO] = 0,
1779 [HDA_PCM_TYPE_SPDIF] = 1,
1780 [HDA_PCM_TYPE_HDMI] = 3,
1781 [HDA_PCM_TYPE_MODEM] = 6
1782 };
1783 /* normal audio device indices; not linear to keep compatibility */
1784 static int audio_idx[4] = { 0, 2, 4, 5 };
1785 struct hda_codec *codec;
1786 int c, err;
1787 int num_devs[HDA_PCM_NTYPES];
1788
1789 err = snd_hda_build_pcms(chip->bus);
1790 if (err < 0)
1791 return err;
1792
1793 /* create audio PCMs */
1794 memset(num_devs, 0, sizeof(num_devs));
1795 list_for_each_entry(codec, &chip->bus->codec_list, list) {
1796 for (c = 0; c < codec->num_pcms; c++) {
1797 struct hda_pcm *cpcm = &codec->pcm_info[c];
1798 int type = cpcm->pcm_type;
1799 switch (type) {
1800 case HDA_PCM_TYPE_AUDIO:
1801 if (num_devs[type] >= ARRAY_SIZE(audio_idx)) {
1802 snd_printk(KERN_WARNING
1803 "Too many audio devices\n");
1804 continue;
1805 }
1806 cpcm->device = audio_idx[num_devs[type]];
1807 break;
1808 case HDA_PCM_TYPE_SPDIF:
1809 case HDA_PCM_TYPE_HDMI:
1810 case HDA_PCM_TYPE_MODEM:
1811 if (num_devs[type]) {
1812 snd_printk(KERN_WARNING
1813 "%s already defined\n",
1814 dev_name[type]);
1815 continue;
1816 }
1817 cpcm->device = dev_idx[type];
1818 break;
1819 default:
1820 snd_printk(KERN_WARNING
1821 "Invalid PCM type %d\n", type);
1822 continue;
1823 }
1824 num_devs[type]++;
1825 err = create_codec_pcm(chip, codec, cpcm);
1826 if (err < 0)
1827 return err;
1828 }
1829 }
1830 return 0; 1814 return 0;
1831} 1815}
1832 1816
@@ -1903,13 +1887,13 @@ static void azx_stop_chip(struct azx *chip)
1903 1887
1904#ifdef CONFIG_SND_HDA_POWER_SAVE 1888#ifdef CONFIG_SND_HDA_POWER_SAVE
1905/* power-up/down the controller */ 1889/* power-up/down the controller */
1906static void azx_power_notify(struct hda_codec *codec) 1890static void azx_power_notify(struct hda_bus *bus)
1907{ 1891{
1908 struct azx *chip = codec->bus->private_data; 1892 struct azx *chip = bus->private_data;
1909 struct hda_codec *c; 1893 struct hda_codec *c;
1910 int power_on = 0; 1894 int power_on = 0;
1911 1895
1912 list_for_each_entry(c, &codec->bus->codec_list, list) { 1896 list_for_each_entry(c, &bus->codec_list, list) {
1913 if (c->power_on) { 1897 if (c->power_on) {
1914 power_on = 1; 1898 power_on = 1;
1915 break; 1899 break;
@@ -1926,6 +1910,18 @@ static void azx_power_notify(struct hda_codec *codec)
1926/* 1910/*
1927 * power management 1911 * power management
1928 */ 1912 */
1913
1914static int snd_hda_codecs_inuse(struct hda_bus *bus)
1915{
1916 struct hda_codec *codec;
1917
1918 list_for_each_entry(codec, &bus->codec_list, list) {
1919 if (snd_hda_codec_needs_resume(codec))
1920 return 1;
1921 }
1922 return 0;
1923}
1924
1929static int azx_suspend(struct pci_dev *pci, pm_message_t state) 1925static int azx_suspend(struct pci_dev *pci, pm_message_t state)
1930{ 1926{
1931 struct snd_card *card = pci_get_drvdata(pci); 1927 struct snd_card *card = pci_get_drvdata(pci);
@@ -1951,13 +1947,16 @@ static int azx_suspend(struct pci_dev *pci, pm_message_t state)
1951 return 0; 1947 return 0;
1952} 1948}
1953 1949
1950static int azx_resume_early(struct pci_dev *pci)
1951{
1952 return pci_restore_state(pci);
1953}
1954
1954static int azx_resume(struct pci_dev *pci) 1955static int azx_resume(struct pci_dev *pci)
1955{ 1956{
1956 struct snd_card *card = pci_get_drvdata(pci); 1957 struct snd_card *card = pci_get_drvdata(pci);
1957 struct azx *chip = card->private_data; 1958 struct azx *chip = card->private_data;
1958 1959
1959 pci_set_power_state(pci, PCI_D0);
1960 pci_restore_state(pci);
1961 if (pci_enable_device(pci) < 0) { 1960 if (pci_enable_device(pci) < 0) {
1962 printk(KERN_ERR "hda-intel: pci_enable_device failed, " 1961 printk(KERN_ERR "hda-intel: pci_enable_device failed, "
1963 "disabling device\n"); 1962 "disabling device\n");
@@ -2095,6 +2094,10 @@ static struct snd_pci_quirk probe_mask_list[] __devinitdata = {
2095 SND_PCI_QUIRK(0x1014, 0x05b7, "Thinkpad Z60", 0x01), 2094 SND_PCI_QUIRK(0x1014, 0x05b7, "Thinkpad Z60", 0x01),
2096 SND_PCI_QUIRK(0x17aa, 0x2010, "Thinkpad X/T/R60", 0x01), 2095 SND_PCI_QUIRK(0x17aa, 0x2010, "Thinkpad X/T/R60", 0x01),
2097 SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X/T/R61", 0x01), 2096 SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X/T/R61", 0x01),
2097 /* broken BIOS */
2098 SND_PCI_QUIRK(0x1028, 0x20ac, "Dell Studio Desktop", 0x01),
2099 /* including bogus ALC268 in slot#2 that conflicts with ALC888 */
2100 SND_PCI_QUIRK(0x17c0, 0x4085, "Medion MD96630", 0x01),
2098 {} 2101 {}
2099}; 2102};
2100 2103
@@ -2229,6 +2232,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
2229 chip->playback_streams = ATIHDMI_NUM_PLAYBACK; 2232 chip->playback_streams = ATIHDMI_NUM_PLAYBACK;
2230 chip->capture_streams = ATIHDMI_NUM_CAPTURE; 2233 chip->capture_streams = ATIHDMI_NUM_CAPTURE;
2231 break; 2234 break;
2235 case AZX_DRIVER_GENERIC:
2232 default: 2236 default:
2233 chip->playback_streams = ICH6_NUM_PLAYBACK; 2237 chip->playback_streams = ICH6_NUM_PLAYBACK;
2234 chip->capture_streams = ICH6_NUM_CAPTURE; 2238 chip->capture_streams = ICH6_NUM_CAPTURE;
@@ -2338,40 +2342,31 @@ static int __devinit azx_probe(struct pci_dev *pci,
2338 } 2342 }
2339 2343
2340 err = azx_create(card, pci, dev, pci_id->driver_data, &chip); 2344 err = azx_create(card, pci, dev, pci_id->driver_data, &chip);
2341 if (err < 0) { 2345 if (err < 0)
2342 snd_card_free(card); 2346 goto out_free;
2343 return err;
2344 }
2345 card->private_data = chip; 2347 card->private_data = chip;
2346 2348
2347 /* create codec instances */ 2349 /* create codec instances */
2348 err = azx_codec_create(chip, model[dev], probe_mask[dev]); 2350 err = azx_codec_create(chip, model[dev], probe_mask[dev],
2349 if (err < 0) { 2351 probe_only[dev]);
2350 snd_card_free(card); 2352 if (err < 0)
2351 return err; 2353 goto out_free;
2352 }
2353 2354
2354 /* create PCM streams */ 2355 /* create PCM streams */
2355 err = azx_pcm_create(chip); 2356 err = snd_hda_build_pcms(chip->bus);
2356 if (err < 0) { 2357 if (err < 0)
2357 snd_card_free(card); 2358 goto out_free;
2358 return err;
2359 }
2360 2359
2361 /* create mixer controls */ 2360 /* create mixer controls */
2362 err = azx_mixer_create(chip); 2361 err = azx_mixer_create(chip);
2363 if (err < 0) { 2362 if (err < 0)
2364 snd_card_free(card); 2363 goto out_free;
2365 return err;
2366 }
2367 2364
2368 snd_card_set_dev(card, &pci->dev); 2365 snd_card_set_dev(card, &pci->dev);
2369 2366
2370 err = snd_card_register(card); 2367 err = snd_card_register(card);
2371 if (err < 0) { 2368 if (err < 0)
2372 snd_card_free(card); 2369 goto out_free;
2373 return err;
2374 }
2375 2370
2376 pci_set_drvdata(pci, card); 2371 pci_set_drvdata(pci, card);
2377 chip->running = 1; 2372 chip->running = 1;
@@ -2380,6 +2375,9 @@ static int __devinit azx_probe(struct pci_dev *pci,
2380 2375
2381 dev++; 2376 dev++;
2382 return err; 2377 return err;
2378out_free:
2379 snd_card_free(card);
2380 return err;
2383} 2381}
2384 2382
2385static void __devexit azx_remove(struct pci_dev *pci) 2383static void __devexit azx_remove(struct pci_dev *pci)
@@ -2453,6 +2451,11 @@ static struct pci_device_id azx_ids[] = {
2453 { PCI_DEVICE(0x10de, 0x0bd7), .driver_data = AZX_DRIVER_NVIDIA }, 2451 { PCI_DEVICE(0x10de, 0x0bd7), .driver_data = AZX_DRIVER_NVIDIA },
2454 /* Teradici */ 2452 /* Teradici */
2455 { PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA }, 2453 { PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA },
2454 /* AMD Generic, PCI class code and Vendor ID for HD Audio */
2455 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_ANY_ID),
2456 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
2457 .class_mask = 0xffffff,
2458 .driver_data = AZX_DRIVER_GENERIC },
2456 { 0, } 2459 { 0, }
2457}; 2460};
2458MODULE_DEVICE_TABLE(pci, azx_ids); 2461MODULE_DEVICE_TABLE(pci, azx_ids);
@@ -2465,6 +2468,7 @@ static struct pci_driver driver = {
2465 .remove = __devexit_p(azx_remove), 2468 .remove = __devexit_p(azx_remove),
2466#ifdef CONFIG_PM 2469#ifdef CONFIG_PM
2467 .suspend = azx_suspend, 2470 .suspend = azx_suspend,
2471 .resume_early = azx_resume_early,
2468 .resume = azx_resume, 2472 .resume = azx_resume,
2469#endif 2473#endif
2470}; 2474};
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 7957fefda730..6f2fe0f9fdd8 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -96,6 +96,8 @@ struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec,
96 const char *name); 96 const char *name);
97int snd_hda_add_vmaster(struct hda_codec *codec, char *name, 97int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
98 unsigned int *tlv, const char **slaves); 98 unsigned int *tlv, const char **slaves);
99void snd_hda_codec_reset(struct hda_codec *codec);
100int snd_hda_codec_configure(struct hda_codec *codec);
99 101
100/* amp value bits */ 102/* amp value bits */
101#define HDA_AMP_MUTE 0x80 103#define HDA_AMP_MUTE 0x80
@@ -282,6 +284,12 @@ int snd_hda_codec_proc_new(struct hda_codec *codec);
282static inline int snd_hda_codec_proc_new(struct hda_codec *codec) { return 0; } 284static inline int snd_hda_codec_proc_new(struct hda_codec *codec) { return 0; }
283#endif 285#endif
284 286
287#define SND_PRINT_RATES_ADVISED_BUFSIZE 80
288void snd_print_pcm_rates(int pcm, char *buf, int buflen);
289
290#define SND_PRINT_BITS_ADVISED_BUFSIZE 16
291void snd_print_pcm_bits(int pcm, char *buf, int buflen);
292
285/* 293/*
286 * Misc 294 * Misc
287 */ 295 */
@@ -364,17 +372,17 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
364/* amp values */ 372/* amp values */
365#define AMP_IN_MUTE(idx) (0x7080 | ((idx)<<8)) 373#define AMP_IN_MUTE(idx) (0x7080 | ((idx)<<8))
366#define AMP_IN_UNMUTE(idx) (0x7000 | ((idx)<<8)) 374#define AMP_IN_UNMUTE(idx) (0x7000 | ((idx)<<8))
367#define AMP_OUT_MUTE 0xb080 375#define AMP_OUT_MUTE 0xb080
368#define AMP_OUT_UNMUTE 0xb000 376#define AMP_OUT_UNMUTE 0xb000
369#define AMP_OUT_ZERO 0xb000 377#define AMP_OUT_ZERO 0xb000
370/* pinctl values */ 378/* pinctl values */
371#define PIN_IN (AC_PINCTL_IN_EN) 379#define PIN_IN (AC_PINCTL_IN_EN)
372#define PIN_VREFHIZ (AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ) 380#define PIN_VREFHIZ (AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ)
373#define PIN_VREF50 (AC_PINCTL_IN_EN | AC_PINCTL_VREF_50) 381#define PIN_VREF50 (AC_PINCTL_IN_EN | AC_PINCTL_VREF_50)
374#define PIN_VREFGRD (AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD) 382#define PIN_VREFGRD (AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD)
375#define PIN_VREF80 (AC_PINCTL_IN_EN | AC_PINCTL_VREF_80) 383#define PIN_VREF80 (AC_PINCTL_IN_EN | AC_PINCTL_VREF_80)
376#define PIN_VREF100 (AC_PINCTL_IN_EN | AC_PINCTL_VREF_100) 384#define PIN_VREF100 (AC_PINCTL_IN_EN | AC_PINCTL_VREF_100)
377#define PIN_OUT (AC_PINCTL_OUT_EN) 385#define PIN_OUT (AC_PINCTL_OUT_EN)
378#define PIN_HP (AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN) 386#define PIN_HP (AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN)
379#define PIN_HP_AMP (AC_PINCTL_HP_EN) 387#define PIN_HP_AMP (AC_PINCTL_HP_EN)
380 388
@@ -393,10 +401,26 @@ u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction);
393int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, 401int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
394 unsigned int caps); 402 unsigned int caps);
395 403
404int snd_hda_ctl_add(struct hda_codec *codec, struct snd_kcontrol *kctl);
405void snd_hda_ctls_clear(struct hda_codec *codec);
406
396/* 407/*
397 * hwdep interface 408 * hwdep interface
398 */ 409 */
410#ifdef CONFIG_SND_HDA_HWDEP
399int snd_hda_create_hwdep(struct hda_codec *codec); 411int snd_hda_create_hwdep(struct hda_codec *codec);
412#else
413static inline int snd_hda_create_hwdep(struct hda_codec *codec) { return 0; }
414#endif
415
416#ifdef CONFIG_SND_HDA_RECONFIG
417int snd_hda_hwdep_add_sysfs(struct hda_codec *codec);
418#else
419static inline int snd_hda_hwdep_add_sysfs(struct hda_codec *codec)
420{
421 return 0;
422}
423#endif
400 424
401/* 425/*
402 * power-management 426 * power-management
@@ -430,4 +454,66 @@ int snd_hda_check_amp_list_power(struct hda_codec *codec,
430#define get_amp_direction(kc) (((kc)->private_value >> 18) & 0x1) 454#define get_amp_direction(kc) (((kc)->private_value >> 18) & 0x1)
431#define get_amp_index(kc) (((kc)->private_value >> 19) & 0xf) 455#define get_amp_index(kc) (((kc)->private_value >> 19) & 0xf)
432 456
457/*
458 * CEA Short Audio Descriptor data
459 */
460struct cea_sad {
461 int channels;
462 int format; /* (format == 0) indicates invalid SAD */
463 int rates;
464 int sample_bits; /* for LPCM */
465 int max_bitrate; /* for AC3...ATRAC */
466 int profile; /* for WMAPRO */
467};
468
469#define ELD_FIXED_BYTES 20
470#define ELD_MAX_MNL 16
471#define ELD_MAX_SAD 16
472
473/*
474 * ELD: EDID Like Data
475 */
476struct hdmi_eld {
477 int eld_size;
478 int baseline_len;
479 int eld_ver; /* (eld_ver == 0) indicates invalid ELD */
480 int cea_edid_ver;
481 char monitor_name[ELD_MAX_MNL + 1];
482 int manufacture_id;
483 int product_id;
484 u64 port_id;
485 int support_hdcp;
486 int support_ai;
487 int conn_type;
488 int aud_synch_delay;
489 int spk_alloc;
490 int sad_count;
491 struct cea_sad sad[ELD_MAX_SAD];
492#ifdef CONFIG_PROC_FS
493 struct snd_info_entry *proc_entry;
494#endif
495};
496
497int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid);
498int snd_hdmi_get_eld(struct hdmi_eld *, struct hda_codec *, hda_nid_t);
499void snd_hdmi_show_eld(struct hdmi_eld *eld);
500
501#ifdef CONFIG_PROC_FS
502int snd_hda_eld_proc_new(struct hda_codec *codec, struct hdmi_eld *eld);
503void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld);
504#else
505static inline int snd_hda_eld_proc_new(struct hda_codec *codec,
506 struct hdmi_eld *eld)
507{
508 return 0;
509}
510static inline void snd_hda_eld_proc_free(struct hda_codec *codec,
511 struct hdmi_eld *eld)
512{
513}
514#endif
515
516#define SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE 80
517void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen);
518
433#endif /* __SOUND_HDA_LOCAL_H */ 519#endif /* __SOUND_HDA_LOCAL_H */
diff --git a/sound/pci/hda/hda_patch.h b/sound/pci/hda/hda_patch.h
deleted file mode 100644
index dfbcfa88da44..000000000000
--- a/sound/pci/hda/hda_patch.h
+++ /dev/null
@@ -1,22 +0,0 @@
1/*
2 * HDA Patches - included by hda_codec.c
3 */
4
5/* Realtek codecs */
6extern struct hda_codec_preset snd_hda_preset_realtek[];
7/* C-Media codecs */
8extern struct hda_codec_preset snd_hda_preset_cmedia[];
9/* Analog Devices codecs */
10extern struct hda_codec_preset snd_hda_preset_analog[];
11/* SigmaTel codecs */
12extern struct hda_codec_preset snd_hda_preset_sigmatel[];
13/* SiLabs 3054/3055 modem codecs */
14extern struct hda_codec_preset snd_hda_preset_si3054[];
15/* ATI HDMI codecs */
16extern struct hda_codec_preset snd_hda_preset_atihdmi[];
17/* Conexant audio codec */
18extern struct hda_codec_preset snd_hda_preset_conexant[];
19/* VIA codecs */
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 c39af986bff1..7ca66d654148 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -91,31 +91,21 @@ static void print_amp_vals(struct snd_info_buffer *buffer,
91 91
92static void print_pcm_rates(struct snd_info_buffer *buffer, unsigned int pcm) 92static void print_pcm_rates(struct snd_info_buffer *buffer, unsigned int pcm)
93{ 93{
94 static unsigned int rates[] = { 94 char buf[SND_PRINT_RATES_ADVISED_BUFSIZE];
95 8000, 11025, 16000, 22050, 32000, 44100, 48000, 88200,
96 96000, 176400, 192000, 384000
97 };
98 int i;
99 95
100 pcm &= AC_SUPPCM_RATES; 96 pcm &= AC_SUPPCM_RATES;
101 snd_iprintf(buffer, " rates [0x%x]:", pcm); 97 snd_iprintf(buffer, " rates [0x%x]:", pcm);
102 for (i = 0; i < ARRAY_SIZE(rates); i++) 98 snd_print_pcm_rates(pcm, buf, sizeof(buf));
103 if (pcm & (1 << i)) 99 snd_iprintf(buffer, "%s\n", buf);
104 snd_iprintf(buffer, " %d", rates[i]);
105 snd_iprintf(buffer, "\n");
106} 100}
107 101
108static void print_pcm_bits(struct snd_info_buffer *buffer, unsigned int pcm) 102static void print_pcm_bits(struct snd_info_buffer *buffer, unsigned int pcm)
109{ 103{
110 static unsigned int bits[] = { 8, 16, 20, 24, 32 }; 104 char buf[SND_PRINT_BITS_ADVISED_BUFSIZE];
111 int i;
112 105
113 pcm = (pcm >> 16) & 0xff; 106 snd_iprintf(buffer, " bits [0x%x]:", (pcm >> 16) & 0xff);
114 snd_iprintf(buffer, " bits [0x%x]:", pcm); 107 snd_print_pcm_bits(pcm, buf, sizeof(buf));
115 for (i = 0; i < ARRAY_SIZE(bits); i++) 108 snd_iprintf(buffer, "%s\n", buf);
116 if (pcm & (1 << i))
117 snd_iprintf(buffer, " %d", bits[i]);
118 snd_iprintf(buffer, "\n");
119} 109}
120 110
121static void print_pcm_formats(struct snd_info_buffer *buffer, 111static void print_pcm_formats(struct snd_info_buffer *buffer,
@@ -145,32 +135,6 @@ static void print_pcm_caps(struct snd_info_buffer *buffer,
145 print_pcm_formats(buffer, stream); 135 print_pcm_formats(buffer, stream);
146} 136}
147 137
148static const char *get_jack_location(u32 cfg)
149{
150 static char *bases[7] = {
151 "N/A", "Rear", "Front", "Left", "Right", "Top", "Bottom",
152 };
153 static unsigned char specials_idx[] = {
154 0x07, 0x08,
155 0x17, 0x18, 0x19,
156 0x37, 0x38
157 };
158 static char *specials[] = {
159 "Rear Panel", "Drive Bar",
160 "Riser", "HDMI", "ATAPI",
161 "Mobile-In", "Mobile-Out"
162 };
163 int i;
164 cfg = (cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT;
165 if ((cfg & 0x0f) < 7)
166 return bases[cfg & 0x0f];
167 for (i = 0; i < ARRAY_SIZE(specials_idx); i++) {
168 if (cfg == specials_idx[i])
169 return specials[i];
170 }
171 return "UNKNOWN";
172}
173
174static const char *get_jack_connection(u32 cfg) 138static const char *get_jack_connection(u32 cfg)
175{ 139{
176 static char *names[16] = { 140 static char *names[16] = {
@@ -206,13 +170,6 @@ static void print_pin_caps(struct snd_info_buffer *buffer,
206 int *supports_vref) 170 int *supports_vref)
207{ 171{
208 static char *jack_conns[4] = { "Jack", "N/A", "Fixed", "Both" }; 172 static char *jack_conns[4] = { "Jack", "N/A", "Fixed", "Both" };
209 static char *jack_types[16] = {
210 "Line Out", "Speaker", "HP Out", "CD",
211 "SPDIF Out", "Digital Out", "Modem Line", "Modem Hand",
212 "Line In", "Aux", "Mic", "Telephony",
213 "SPDIF In", "Digitial In", "Reserved", "Other"
214 };
215 static char *jack_locations[4] = { "Ext", "Int", "Sep", "Oth" };
216 unsigned int caps, val; 173 unsigned int caps, val;
217 174
218 caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP); 175 caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
@@ -274,9 +231,9 @@ static void print_pin_caps(struct snd_info_buffer *buffer,
274 caps = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONFIG_DEFAULT, 0); 231 caps = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONFIG_DEFAULT, 0);
275 snd_iprintf(buffer, " Pin Default 0x%08x: [%s] %s at %s %s\n", caps, 232 snd_iprintf(buffer, " Pin Default 0x%08x: [%s] %s at %s %s\n", caps,
276 jack_conns[(caps & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT], 233 jack_conns[(caps & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT],
277 jack_types[(caps & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT], 234 snd_hda_get_jack_type(caps),
278 jack_locations[(caps >> (AC_DEFCFG_LOCATION_SHIFT + 4)) & 3], 235 snd_hda_get_jack_connectivity(caps),
279 get_jack_location(caps)); 236 snd_hda_get_jack_location(caps));
280 snd_iprintf(buffer, " Conn = %s, Color = %s\n", 237 snd_iprintf(buffer, " Conn = %s, Color = %s\n",
281 get_jack_connection(caps), 238 get_jack_connection(caps),
282 get_jack_color(caps)); 239 get_jack_color(caps));
@@ -457,17 +414,6 @@ static void print_conn_list(struct snd_info_buffer *buffer,
457 } 414 }
458} 415}
459 416
460static void print_realtek_coef(struct snd_info_buffer *buffer,
461 struct hda_codec *codec, hda_nid_t nid)
462{
463 int coeff = snd_hda_codec_read(codec, nid, 0,
464 AC_VERB_GET_PROC_COEF, 0);
465 snd_iprintf(buffer, " Processing Coefficient: 0x%02x\n", coeff);
466 coeff = snd_hda_codec_read(codec, nid, 0,
467 AC_VERB_GET_COEF_INDEX, 0);
468 snd_iprintf(buffer, " Coefficient Index: 0x%02x\n", coeff);
469}
470
471static void print_gpio(struct snd_info_buffer *buffer, 417static void print_gpio(struct snd_info_buffer *buffer,
472 struct hda_codec *codec, hda_nid_t nid) 418 struct hda_codec *codec, hda_nid_t nid)
473{ 419{
@@ -500,12 +446,13 @@ static void print_gpio(struct snd_info_buffer *buffer,
500 for (i = 0; i < max; ++i) 446 for (i = 0; i < max; ++i)
501 snd_iprintf(buffer, 447 snd_iprintf(buffer,
502 " IO[%d]: enable=%d, dir=%d, wake=%d, " 448 " IO[%d]: enable=%d, dir=%d, wake=%d, "
503 "sticky=%d, data=%d\n", i, 449 "sticky=%d, data=%d, unsol=%d\n", i,
504 (enable & (1<<i)) ? 1 : 0, 450 (enable & (1<<i)) ? 1 : 0,
505 (direction & (1<<i)) ? 1 : 0, 451 (direction & (1<<i)) ? 1 : 0,
506 (wake & (1<<i)) ? 1 : 0, 452 (wake & (1<<i)) ? 1 : 0,
507 (sticky & (1<<i)) ? 1 : 0, 453 (sticky & (1<<i)) ? 1 : 0,
508 (data & (1<<i)) ? 1 : 0); 454 (data & (1<<i)) ? 1 : 0,
455 (unsol & (1<<i)) ? 1 : 0);
509 /* FIXME: add GPO and GPI pin information */ 456 /* FIXME: add GPO and GPI pin information */
510} 457}
511 458
@@ -513,12 +460,11 @@ static void print_codec_info(struct snd_info_entry *entry,
513 struct snd_info_buffer *buffer) 460 struct snd_info_buffer *buffer)
514{ 461{
515 struct hda_codec *codec = entry->private_data; 462 struct hda_codec *codec = entry->private_data;
516 char buf[32];
517 hda_nid_t nid; 463 hda_nid_t nid;
518 int i, nodes; 464 int i, nodes;
519 465
520 snd_hda_get_codec_name(codec, buf, sizeof(buf)); 466 snd_iprintf(buffer, "Codec: %s\n",
521 snd_iprintf(buffer, "Codec: %s\n", buf); 467 codec->name ? codec->name : "Not Set");
522 snd_iprintf(buffer, "Address: %d\n", codec->addr); 468 snd_iprintf(buffer, "Address: %d\n", codec->addr);
523 snd_iprintf(buffer, "Vendor Id: 0x%x\n", codec->vendor_id); 469 snd_iprintf(buffer, "Vendor Id: 0x%x\n", codec->vendor_id);
524 snd_iprintf(buffer, "Subsystem Id: 0x%x\n", codec->subsystem_id); 470 snd_iprintf(buffer, "Subsystem Id: 0x%x\n", codec->subsystem_id);
@@ -547,6 +493,8 @@ static void print_codec_info(struct snd_info_entry *entry,
547 } 493 }
548 494
549 print_gpio(buffer, codec, codec->afg); 495 print_gpio(buffer, codec, codec->afg);
496 if (codec->proc_widget_hook)
497 codec->proc_widget_hook(buffer, codec, codec->afg);
550 498
551 for (i = 0; i < nodes; i++, nid++) { 499 for (i = 0; i < nodes; i++, nid++) {
552 unsigned int wid_caps = 500 unsigned int wid_caps =
@@ -649,9 +597,8 @@ static void print_codec_info(struct snd_info_entry *entry,
649 if (wid_caps & AC_WCAP_PROC_WID) 597 if (wid_caps & AC_WCAP_PROC_WID)
650 print_proc_caps(buffer, codec, nid); 598 print_proc_caps(buffer, codec, nid);
651 599
652 /* NID 0x20 == Realtek Define Registers */ 600 if (codec->proc_widget_hook)
653 if (codec->vendor_id == 0x10ec && nid == 0x20) 601 codec->proc_widget_hook(buffer, codec, nid);
654 print_realtek_coef(buffer, codec, nid);
655 } 602 }
656 snd_hda_power_down(codec); 603 snd_hda_power_down(codec);
657} 604}
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 686c77491dea..26247cfe749d 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -27,7 +27,6 @@
27#include <sound/core.h> 27#include <sound/core.h>
28#include "hda_codec.h" 28#include "hda_codec.h"
29#include "hda_local.h" 29#include "hda_local.h"
30#include "hda_patch.h"
31 30
32struct ad198x_spec { 31struct ad198x_spec {
33 struct snd_kcontrol_new *mixers[5]; 32 struct snd_kcontrol_new *mixers[5];
@@ -67,8 +66,7 @@ struct ad198x_spec {
67 66
68 /* dynamic controls, init_verbs and input_mux */ 67 /* dynamic controls, init_verbs and input_mux */
69 struct auto_pin_cfg autocfg; 68 struct auto_pin_cfg autocfg;
70 unsigned int num_kctl_alloc, num_kctl_used; 69 struct snd_array kctls;
71 struct snd_kcontrol_new *kctl_alloc;
72 struct hda_input_mux private_imux; 70 struct hda_input_mux private_imux;
73 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; 71 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
74 72
@@ -154,6 +152,8 @@ static const char *ad_slave_sws[] = {
154 NULL 152 NULL
155}; 153};
156 154
155static void ad198x_free_kctls(struct hda_codec *codec);
156
157static int ad198x_build_controls(struct hda_codec *codec) 157static int ad198x_build_controls(struct hda_codec *codec)
158{ 158{
159 struct ad198x_spec *spec = codec->spec; 159 struct ad198x_spec *spec = codec->spec;
@@ -202,6 +202,7 @@ static int ad198x_build_controls(struct hda_codec *codec)
202 return err; 202 return err;
203 } 203 }
204 204
205 ad198x_free_kctls(codec); /* no longer needed */
205 return 0; 206 return 0;
206} 207}
207 208
@@ -375,16 +376,27 @@ static int ad198x_build_pcms(struct hda_codec *codec)
375 return 0; 376 return 0;
376} 377}
377 378
378static void ad198x_free(struct hda_codec *codec) 379static void ad198x_free_kctls(struct hda_codec *codec)
379{ 380{
380 struct ad198x_spec *spec = codec->spec; 381 struct ad198x_spec *spec = codec->spec;
381 unsigned int i;
382 382
383 if (spec->kctl_alloc) { 383 if (spec->kctls.list) {
384 for (i = 0; i < spec->num_kctl_used; i++) 384 struct snd_kcontrol_new *kctl = spec->kctls.list;
385 kfree(spec->kctl_alloc[i].name); 385 int i;
386 kfree(spec->kctl_alloc); 386 for (i = 0; i < spec->kctls.used; i++)
387 kfree(kctl[i].name);
387 } 388 }
389 snd_array_free(&spec->kctls);
390}
391
392static void ad198x_free(struct hda_codec *codec)
393{
394 struct ad198x_spec *spec = codec->spec;
395
396 if (!spec)
397 return;
398
399 ad198x_free_kctls(codec);
388 kfree(codec->spec); 400 kfree(codec->spec);
389} 401}
390 402
@@ -629,6 +641,36 @@ static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = {
629 HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw), 641 HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw),
630 HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT), 642 HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT),
631 HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), 643 HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT),
644 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0, HDA_OUTPUT),
645 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0, HDA_OUTPUT),
646 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
647 HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
648 HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT),
649 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
650 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
651 {
652 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
653 .name = "Capture Source",
654 .info = ad198x_mux_enum_info,
655 .get = ad198x_mux_enum_get,
656 .put = ad198x_mux_enum_put,
657 },
658 {
659 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
660 .name = "External Amplifier",
661 .info = ad198x_eapd_info,
662 .get = ad198x_eapd_get,
663 .put = ad198x_eapd_put,
664 .private_value = 0x1b | (1 << 8), /* port-D, inversed */
665 },
666 { } /* end */
667};
668
669static struct snd_kcontrol_new ad1986a_samsung_mixers[] = {
670 HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
671 HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw),
672 HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT),
673 HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT),
632 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), 674 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
633 HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT), 675 HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
634 HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT), 676 HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT),
@@ -917,6 +959,7 @@ enum {
917 AD1986A_LAPTOP_EAPD, 959 AD1986A_LAPTOP_EAPD,
918 AD1986A_LAPTOP_AUTOMUTE, 960 AD1986A_LAPTOP_AUTOMUTE,
919 AD1986A_ULTRA, 961 AD1986A_ULTRA,
962 AD1986A_SAMSUNG,
920 AD1986A_MODELS 963 AD1986A_MODELS
921}; 964};
922 965
@@ -927,6 +970,7 @@ static const char *ad1986a_models[AD1986A_MODELS] = {
927 [AD1986A_LAPTOP_EAPD] = "laptop-eapd", 970 [AD1986A_LAPTOP_EAPD] = "laptop-eapd",
928 [AD1986A_LAPTOP_AUTOMUTE] = "laptop-automute", 971 [AD1986A_LAPTOP_AUTOMUTE] = "laptop-automute",
929 [AD1986A_ULTRA] = "ultra", 972 [AD1986A_ULTRA] = "ultra",
973 [AD1986A_SAMSUNG] = "samsung",
930}; 974};
931 975
932static struct snd_pci_quirk ad1986a_cfg_tbl[] = { 976static struct snd_pci_quirk ad1986a_cfg_tbl[] = {
@@ -949,9 +993,9 @@ static struct snd_pci_quirk ad1986a_cfg_tbl[] = {
949 SND_PCI_QUIRK(0x1179, 0xff40, "Toshiba", AD1986A_LAPTOP_EAPD), 993 SND_PCI_QUIRK(0x1179, 0xff40, "Toshiba", AD1986A_LAPTOP_EAPD),
950 SND_PCI_QUIRK(0x144d, 0xb03c, "Samsung R55", AD1986A_3STACK), 994 SND_PCI_QUIRK(0x144d, 0xb03c, "Samsung R55", AD1986A_3STACK),
951 SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_LAPTOP), 995 SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_LAPTOP),
952 SND_PCI_QUIRK(0x144d, 0xc023, "Samsung X60", AD1986A_LAPTOP_EAPD), 996 SND_PCI_QUIRK(0x144d, 0xc023, "Samsung X60", AD1986A_SAMSUNG),
953 SND_PCI_QUIRK(0x144d, 0xc024, "Samsung R65", AD1986A_LAPTOP_EAPD), 997 SND_PCI_QUIRK(0x144d, 0xc024, "Samsung R65", AD1986A_SAMSUNG),
954 SND_PCI_QUIRK(0x144d, 0xc026, "Samsung X11", AD1986A_LAPTOP_EAPD), 998 SND_PCI_QUIRK(0x144d, 0xc026, "Samsung X11", AD1986A_SAMSUNG),
955 SND_PCI_QUIRK(0x144d, 0xc027, "Samsung Q1", AD1986A_ULTRA), 999 SND_PCI_QUIRK(0x144d, 0xc027, "Samsung Q1", AD1986A_ULTRA),
956 SND_PCI_QUIRK(0x144d, 0xc504, "Samsung Q35", AD1986A_3STACK), 1000 SND_PCI_QUIRK(0x144d, 0xc504, "Samsung Q35", AD1986A_3STACK),
957 SND_PCI_QUIRK(0x17aa, 0x1011, "Lenovo M55", AD1986A_LAPTOP), 1001 SND_PCI_QUIRK(0x17aa, 0x1011, "Lenovo M55", AD1986A_LAPTOP),
@@ -1033,6 +1077,17 @@ static int patch_ad1986a(struct hda_codec *codec)
1033 break; 1077 break;
1034 case AD1986A_LAPTOP_EAPD: 1078 case AD1986A_LAPTOP_EAPD:
1035 spec->mixers[0] = ad1986a_laptop_eapd_mixers; 1079 spec->mixers[0] = ad1986a_laptop_eapd_mixers;
1080 spec->num_init_verbs = 2;
1081 spec->init_verbs[1] = ad1986a_eapd_init_verbs;
1082 spec->multiout.max_channels = 2;
1083 spec->multiout.num_dacs = 1;
1084 spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1085 if (!is_jack_available(codec, 0x25))
1086 spec->multiout.dig_out_nid = 0;
1087 spec->input_mux = &ad1986a_laptop_eapd_capture_source;
1088 break;
1089 case AD1986A_SAMSUNG:
1090 spec->mixers[0] = ad1986a_samsung_mixers;
1036 spec->num_init_verbs = 3; 1091 spec->num_init_verbs = 3;
1037 spec->init_verbs[1] = ad1986a_eapd_init_verbs; 1092 spec->init_verbs[1] = ad1986a_eapd_init_verbs;
1038 spec->init_verbs[2] = ad1986a_automic_verbs; 1093 spec->init_verbs[2] = ad1986a_automic_verbs;
@@ -2452,9 +2507,6 @@ static struct hda_amp_list ad1988_loopbacks[] = {
2452 * Automatic parse of I/O pins from the BIOS configuration 2507 * Automatic parse of I/O pins from the BIOS configuration
2453 */ 2508 */
2454 2509
2455#define NUM_CONTROL_ALLOC 32
2456#define NUM_VERB_ALLOC 32
2457
2458enum { 2510enum {
2459 AD_CTL_WIDGET_VOL, 2511 AD_CTL_WIDGET_VOL,
2460 AD_CTL_WIDGET_MUTE, 2512 AD_CTL_WIDGET_MUTE,
@@ -2472,27 +2524,15 @@ static int add_control(struct ad198x_spec *spec, int type, const char *name,
2472{ 2524{
2473 struct snd_kcontrol_new *knew; 2525 struct snd_kcontrol_new *knew;
2474 2526
2475 if (spec->num_kctl_used >= spec->num_kctl_alloc) { 2527 snd_array_init(&spec->kctls, sizeof(*knew), 32);
2476 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC; 2528 knew = snd_array_new(&spec->kctls);
2477 2529 if (!knew)
2478 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); /* array + terminator */ 2530 return -ENOMEM;
2479 if (! knew)
2480 return -ENOMEM;
2481 if (spec->kctl_alloc) {
2482 memcpy(knew, spec->kctl_alloc, sizeof(*knew) * spec->num_kctl_alloc);
2483 kfree(spec->kctl_alloc);
2484 }
2485 spec->kctl_alloc = knew;
2486 spec->num_kctl_alloc = num;
2487 }
2488
2489 knew = &spec->kctl_alloc[spec->num_kctl_used];
2490 *knew = ad1988_control_templates[type]; 2531 *knew = ad1988_control_templates[type];
2491 knew->name = kstrdup(name, GFP_KERNEL); 2532 knew->name = kstrdup(name, GFP_KERNEL);
2492 if (! knew->name) 2533 if (! knew->name)
2493 return -ENOMEM; 2534 return -ENOMEM;
2494 knew->private_value = val; 2535 knew->private_value = val;
2495 spec->num_kctl_used++;
2496 return 0; 2536 return 0;
2497} 2537}
2498 2538
@@ -2846,8 +2886,8 @@ static int ad1988_parse_auto_config(struct hda_codec *codec)
2846 if (spec->autocfg.dig_in_pin) 2886 if (spec->autocfg.dig_in_pin)
2847 spec->dig_in_nid = AD1988_SPDIF_IN; 2887 spec->dig_in_nid = AD1988_SPDIF_IN;
2848 2888
2849 if (spec->kctl_alloc) 2889 if (spec->kctls.list)
2850 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 2890 spec->mixers[spec->num_mixers++] = spec->kctls.list;
2851 2891
2852 spec->init_verbs[spec->num_init_verbs++] = ad1988_6stack_init_verbs; 2892 spec->init_verbs[spec->num_init_verbs++] = ad1988_6stack_init_verbs;
2853 2893
@@ -3861,6 +3901,7 @@ static const char *ad1884a_models[AD1884A_MODELS] = {
3861static struct snd_pci_quirk ad1884a_cfg_tbl[] = { 3901static struct snd_pci_quirk ad1884a_cfg_tbl[] = {
3862 SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE), 3902 SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE),
3863 SND_PCI_QUIRK(0x103c, 0x3056, "HP", AD1884A_MOBILE), 3903 SND_PCI_QUIRK(0x103c, 0x3056, "HP", AD1884A_MOBILE),
3904 SND_PCI_QUIRK(0x103c, 0x30e6, "HP 6730b", AD1884A_LAPTOP),
3864 SND_PCI_QUIRK(0x103c, 0x30e7, "HP EliteBook 8530p", AD1884A_LAPTOP), 3905 SND_PCI_QUIRK(0x103c, 0x30e7, "HP EliteBook 8530p", AD1884A_LAPTOP),
3865 SND_PCI_QUIRK(0x103c, 0x3614, "HP 6730s", AD1884A_LAPTOP), 3906 SND_PCI_QUIRK(0x103c, 0x3614, "HP 6730s", AD1884A_LAPTOP),
3866 SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X300", AD1884A_THINKPAD), 3907 SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X300", AD1884A_THINKPAD),
@@ -4267,7 +4308,7 @@ static int patch_ad1882(struct hda_codec *codec)
4267/* 4308/*
4268 * patch entries 4309 * patch entries
4269 */ 4310 */
4270struct hda_codec_preset snd_hda_preset_analog[] = { 4311static struct hda_codec_preset snd_hda_preset_analog[] = {
4271 { .id = 0x11d4184a, .name = "AD1884A", .patch = patch_ad1884a }, 4312 { .id = 0x11d4184a, .name = "AD1884A", .patch = patch_ad1884a },
4272 { .id = 0x11d41882, .name = "AD1882", .patch = patch_ad1882 }, 4313 { .id = 0x11d41882, .name = "AD1882", .patch = patch_ad1882 },
4273 { .id = 0x11d41883, .name = "AD1883", .patch = patch_ad1884a }, 4314 { .id = 0x11d41883, .name = "AD1883", .patch = patch_ad1884a },
@@ -4285,3 +4326,26 @@ struct hda_codec_preset snd_hda_preset_analog[] = {
4285 { .id = 0x11d4989b, .name = "AD1989B", .patch = patch_ad1988 }, 4326 { .id = 0x11d4989b, .name = "AD1989B", .patch = patch_ad1988 },
4286 {} /* terminator */ 4327 {} /* terminator */
4287}; 4328};
4329
4330MODULE_ALIAS("snd-hda-codec-id:11d4*");
4331
4332MODULE_LICENSE("GPL");
4333MODULE_DESCRIPTION("Analog Devices HD-audio codec");
4334
4335static struct hda_codec_preset_list analog_list = {
4336 .preset = snd_hda_preset_analog,
4337 .owner = THIS_MODULE,
4338};
4339
4340static int __init patch_analog_init(void)
4341{
4342 return snd_hda_add_codec_preset(&analog_list);
4343}
4344
4345static void __exit patch_analog_exit(void)
4346{
4347 snd_hda_delete_codec_preset(&analog_list);
4348}
4349
4350module_init(patch_analog_init)
4351module_exit(patch_analog_exit)
diff --git a/sound/pci/hda/patch_atihdmi.c b/sound/pci/hda/patch_atihdmi.c
index ba61575983fd..233e4778bba9 100644
--- a/sound/pci/hda/patch_atihdmi.c
+++ b/sound/pci/hda/patch_atihdmi.c
@@ -27,7 +27,6 @@
27#include <sound/core.h> 27#include <sound/core.h>
28#include "hda_codec.h" 28#include "hda_codec.h"
29#include "hda_local.h" 29#include "hda_local.h"
30#include "hda_patch.h"
31 30
32struct atihdmi_spec { 31struct atihdmi_spec {
33 struct hda_multi_out multiout; 32 struct hda_multi_out multiout;
@@ -187,13 +186,40 @@ static int patch_atihdmi(struct hda_codec *codec)
187/* 186/*
188 * patch entries 187 * patch entries
189 */ 188 */
190struct hda_codec_preset snd_hda_preset_atihdmi[] = { 189static struct hda_codec_preset snd_hda_preset_atihdmi[] = {
191 { .id = 0x1002793c, .name = "ATI RS600 HDMI", .patch = patch_atihdmi }, 190 { .id = 0x1002793c, .name = "RS600 HDMI", .patch = patch_atihdmi },
192 { .id = 0x10027919, .name = "ATI RS600 HDMI", .patch = patch_atihdmi }, 191 { .id = 0x10027919, .name = "RS600 HDMI", .patch = patch_atihdmi },
193 { .id = 0x1002791a, .name = "ATI RS690/780 HDMI", .patch = patch_atihdmi }, 192 { .id = 0x1002791a, .name = "RS690/780 HDMI", .patch = patch_atihdmi },
194 { .id = 0x1002aa01, .name = "ATI R6xx HDMI", .patch = patch_atihdmi }, 193 { .id = 0x1002aa01, .name = "R6xx HDMI", .patch = patch_atihdmi },
195 { .id = 0x10951390, .name = "SiI1390 HDMI", .patch = patch_atihdmi }, 194 { .id = 0x10951390, .name = "SiI1390 HDMI", .patch = patch_atihdmi },
196 { .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_atihdmi },
197 { .id = 0x17e80047, .name = "Chrontel HDMI", .patch = patch_atihdmi }, 195 { .id = 0x17e80047, .name = "Chrontel HDMI", .patch = patch_atihdmi },
198 {} /* terminator */ 196 {} /* terminator */
199}; 197};
198
199MODULE_ALIAS("snd-hda-codec-id:1002793c");
200MODULE_ALIAS("snd-hda-codec-id:10027919");
201MODULE_ALIAS("snd-hda-codec-id:1002791a");
202MODULE_ALIAS("snd-hda-codec-id:1002aa01");
203MODULE_ALIAS("snd-hda-codec-id:10951390");
204MODULE_ALIAS("snd-hda-codec-id:17e80047");
205
206MODULE_LICENSE("GPL");
207MODULE_DESCRIPTION("ATI HDMI HD-audio codec");
208
209static struct hda_codec_preset_list atihdmi_list = {
210 .preset = snd_hda_preset_atihdmi,
211 .owner = THIS_MODULE,
212};
213
214static int __init patch_atihdmi_init(void)
215{
216 return snd_hda_add_codec_preset(&atihdmi_list);
217}
218
219static void __exit patch_atihdmi_exit(void)
220{
221 snd_hda_delete_codec_preset(&atihdmi_list);
222}
223
224module_init(patch_atihdmi_init)
225module_exit(patch_atihdmi_exit)
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c
index 6ef57fbfb6eb..f3ebe837f2d5 100644
--- a/sound/pci/hda/patch_cmedia.c
+++ b/sound/pci/hda/patch_cmedia.c
@@ -28,7 +28,6 @@
28#include <sound/core.h> 28#include <sound/core.h>
29#include "hda_codec.h" 29#include "hda_codec.h"
30#include "hda_local.h" 30#include "hda_local.h"
31#include "hda_patch.h"
32#define NUM_PINS 11 31#define NUM_PINS 11
33 32
34 33
@@ -736,8 +735,32 @@ static int patch_cmi9880(struct hda_codec *codec)
736/* 735/*
737 * patch entries 736 * patch entries
738 */ 737 */
739struct hda_codec_preset snd_hda_preset_cmedia[] = { 738static struct hda_codec_preset snd_hda_preset_cmedia[] = {
740 { .id = 0x13f69880, .name = "CMI9880", .patch = patch_cmi9880 }, 739 { .id = 0x13f69880, .name = "CMI9880", .patch = patch_cmi9880 },
741 { .id = 0x434d4980, .name = "CMI9880", .patch = patch_cmi9880 }, 740 { .id = 0x434d4980, .name = "CMI9880", .patch = patch_cmi9880 },
742 {} /* terminator */ 741 {} /* terminator */
743}; 742};
743
744MODULE_ALIAS("snd-hda-codec-id:13f69880");
745MODULE_ALIAS("snd-hda-codec-id:434d4980");
746
747MODULE_LICENSE("GPL");
748MODULE_DESCRIPTION("C-Media HD-audio codec");
749
750static struct hda_codec_preset_list cmedia_list = {
751 .preset = snd_hda_preset_cmedia,
752 .owner = THIS_MODULE,
753};
754
755static int __init patch_cmedia_init(void)
756{
757 return snd_hda_add_codec_preset(&cmedia_list);
758}
759
760static void __exit patch_cmedia_exit(void)
761{
762 snd_hda_delete_codec_preset(&cmedia_list);
763}
764
765module_init(patch_cmedia_init)
766module_exit(patch_cmedia_exit)
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 7c1eb23f0cec..b20e1cede00b 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -27,7 +27,6 @@
27#include <sound/core.h> 27#include <sound/core.h>
28#include "hda_codec.h" 28#include "hda_codec.h"
29#include "hda_local.h" 29#include "hda_local.h"
30#include "hda_patch.h"
31 30
32#define CXT_PIN_DIR_IN 0x00 31#define CXT_PIN_DIR_IN 0x00
33#define CXT_PIN_DIR_OUT 0x01 32#define CXT_PIN_DIR_OUT 0x01
@@ -86,8 +85,6 @@ struct conexant_spec {
86 85
87 /* dynamic controls, init_verbs and input_mux */ 86 /* dynamic controls, init_verbs and input_mux */
88 struct auto_pin_cfg autocfg; 87 struct auto_pin_cfg autocfg;
89 unsigned int num_kctl_alloc, num_kctl_used;
90 struct snd_kcontrol_new *kctl_alloc;
91 struct hda_input_mux private_imux; 88 struct hda_input_mux private_imux;
92 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; 89 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
93 90
@@ -344,15 +341,6 @@ static int conexant_init(struct hda_codec *codec)
344 341
345static void conexant_free(struct hda_codec *codec) 342static void conexant_free(struct hda_codec *codec)
346{ 343{
347 struct conexant_spec *spec = codec->spec;
348 unsigned int i;
349
350 if (spec->kctl_alloc) {
351 for (i = 0; i < spec->num_kctl_used; i++)
352 kfree(spec->kctl_alloc[i].name);
353 kfree(spec->kctl_alloc);
354 }
355
356 kfree(codec->spec); 344 kfree(codec->spec);
357} 345}
358 346
@@ -1782,7 +1770,7 @@ static int patch_cxt5051(struct hda_codec *codec)
1782/* 1770/*
1783 */ 1771 */
1784 1772
1785struct hda_codec_preset snd_hda_preset_conexant[] = { 1773static struct hda_codec_preset snd_hda_preset_conexant[] = {
1786 { .id = 0x14f15045, .name = "CX20549 (Venice)", 1774 { .id = 0x14f15045, .name = "CX20549 (Venice)",
1787 .patch = patch_cxt5045 }, 1775 .patch = patch_cxt5045 },
1788 { .id = 0x14f15047, .name = "CX20551 (Waikiki)", 1776 { .id = 0x14f15047, .name = "CX20551 (Waikiki)",
@@ -1791,3 +1779,28 @@ struct hda_codec_preset snd_hda_preset_conexant[] = {
1791 .patch = patch_cxt5051 }, 1779 .patch = patch_cxt5051 },
1792 {} /* terminator */ 1780 {} /* terminator */
1793}; 1781};
1782
1783MODULE_ALIAS("snd-hda-codec-id:14f15045");
1784MODULE_ALIAS("snd-hda-codec-id:14f15047");
1785MODULE_ALIAS("snd-hda-codec-id:14f15051");
1786
1787MODULE_LICENSE("GPL");
1788MODULE_DESCRIPTION("Conexant HD-audio codec");
1789
1790static struct hda_codec_preset_list conexant_list = {
1791 .preset = snd_hda_preset_conexant,
1792 .owner = THIS_MODULE,
1793};
1794
1795static int __init patch_conexant_init(void)
1796{
1797 return snd_hda_add_codec_preset(&conexant_list);
1798}
1799
1800static void __exit patch_conexant_exit(void)
1801{
1802 snd_hda_delete_codec_preset(&conexant_list);
1803}
1804
1805module_init(patch_conexant_init)
1806module_exit(patch_conexant_exit)
diff --git a/sound/pci/hda/patch_intelhdmi.c b/sound/pci/hda/patch_intelhdmi.c
new file mode 100644
index 000000000000..3564f4e4b74c
--- /dev/null
+++ b/sound/pci/hda/patch_intelhdmi.c
@@ -0,0 +1,711 @@
1/*
2 *
3 * patch_intelhdmi.c - Patch for Intel HDMI codecs
4 *
5 * Copyright(c) 2008 Intel Corporation. All rights reserved.
6 *
7 * Authors:
8 * Jiang Zhe <zhe.jiang@intel.com>
9 * Wu Fengguang <wfg@linux.intel.com>
10 *
11 * Maintained by:
12 * Wu Fengguang <wfg@linux.intel.com>
13 *
14 * This program is free software; you can redistribute it and/or modify it
15 * under the terms of the GNU General Public License as published by the Free
16 * Software Foundation; either version 2 of the License, or (at your option)
17 * any later version.
18 *
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
21 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 * for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software Foundation,
26 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 */
28
29#include <linux/init.h>
30#include <linux/delay.h>
31#include <linux/slab.h>
32#include <sound/core.h>
33#include "hda_codec.h"
34#include "hda_local.h"
35
36#define CVT_NID 0x02 /* audio converter */
37#define PIN_NID 0x03 /* HDMI output pin */
38
39#define INTEL_HDMI_EVENT_TAG 0x08
40
41struct intel_hdmi_spec {
42 struct hda_multi_out multiout;
43 struct hda_pcm pcm_rec;
44 struct hdmi_eld sink_eld;
45};
46
47static struct hda_verb pinout_enable_verb[] = {
48 {PIN_NID, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
49 {} /* terminator */
50};
51
52static struct hda_verb pinout_disable_verb[] = {
53 {PIN_NID, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00},
54 {}
55};
56
57static struct hda_verb unsolicited_response_verb[] = {
58 {PIN_NID, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN |
59 INTEL_HDMI_EVENT_TAG},
60 {}
61};
62
63static struct hda_verb def_chan_map[] = {
64 {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x00},
65 {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x11},
66 {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x22},
67 {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x33},
68 {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x44},
69 {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x55},
70 {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x66},
71 {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x77},
72 {}
73};
74
75
76struct hdmi_audio_infoframe {
77 u8 type; /* 0x84 */
78 u8 ver; /* 0x01 */
79 u8 len; /* 0x0a */
80
81 u8 checksum; /* PB0 */
82 u8 CC02_CT47; /* CC in bits 0:2, CT in 4:7 */
83 u8 SS01_SF24;
84 u8 CXT04;
85 u8 CA;
86 u8 LFEPBL01_LSV36_DM_INH7;
87 u8 reserved[5]; /* PB6 - PB10 */
88};
89
90/*
91 * CEA speaker placement:
92 *
93 * FLH FCH FRH
94 * FLW FL FLC FC FRC FR FRW
95 *
96 * LFE
97 * TC
98 *
99 * RL RLC RC RRC RR
100 *
101 * The Left/Right Surround channel _notions_ LS/RS in SMPTE 320M corresponds to
102 * CEA RL/RR; The SMPTE channel _assignment_ C/LFE is swapped to CEA LFE/FC.
103 */
104enum cea_speaker_placement {
105 FL = (1 << 0), /* Front Left */
106 FC = (1 << 1), /* Front Center */
107 FR = (1 << 2), /* Front Right */
108 FLC = (1 << 3), /* Front Left Center */
109 FRC = (1 << 4), /* Front Right Center */
110 RL = (1 << 5), /* Rear Left */
111 RC = (1 << 6), /* Rear Center */
112 RR = (1 << 7), /* Rear Right */
113 RLC = (1 << 8), /* Rear Left Center */
114 RRC = (1 << 9), /* Rear Right Center */
115 LFE = (1 << 10), /* Low Frequency Effect */
116 FLW = (1 << 11), /* Front Left Wide */
117 FRW = (1 << 12), /* Front Right Wide */
118 FLH = (1 << 13), /* Front Left High */
119 FCH = (1 << 14), /* Front Center High */
120 FRH = (1 << 15), /* Front Right High */
121 TC = (1 << 16), /* Top Center */
122};
123
124/*
125 * ELD SA bits in the CEA Speaker Allocation data block
126 */
127static int eld_speaker_allocation_bits[] = {
128 [0] = FL | FR,
129 [1] = LFE,
130 [2] = FC,
131 [3] = RL | RR,
132 [4] = RC,
133 [5] = FLC | FRC,
134 [6] = RLC | RRC,
135 /* the following are not defined in ELD yet */
136 [7] = FLW | FRW,
137 [8] = FLH | FRH,
138 [9] = TC,
139 [10] = FCH,
140};
141
142struct cea_channel_speaker_allocation {
143 int ca_index;
144 int speakers[8];
145
146 /* derived values, just for convenience */
147 int channels;
148 int spk_mask;
149};
150
151/*
152 * This is an ordered list!
153 *
154 * The preceding ones have better chances to be selected by
155 * hdmi_setup_channel_allocation().
156 */
157static struct cea_channel_speaker_allocation channel_allocations[] = {
158/* channel: 8 7 6 5 4 3 2 1 */
159{ .ca_index = 0x00, .speakers = { 0, 0, 0, 0, 0, 0, FR, FL } },
160 /* 2.1 */
161{ .ca_index = 0x01, .speakers = { 0, 0, 0, 0, 0, LFE, FR, FL } },
162 /* Dolby Surround */
163{ .ca_index = 0x02, .speakers = { 0, 0, 0, 0, FC, 0, FR, FL } },
164{ .ca_index = 0x03, .speakers = { 0, 0, 0, 0, FC, LFE, FR, FL } },
165{ .ca_index = 0x04, .speakers = { 0, 0, 0, RC, 0, 0, FR, FL } },
166{ .ca_index = 0x05, .speakers = { 0, 0, 0, RC, 0, LFE, FR, FL } },
167{ .ca_index = 0x06, .speakers = { 0, 0, 0, RC, FC, 0, FR, FL } },
168{ .ca_index = 0x07, .speakers = { 0, 0, 0, RC, FC, LFE, FR, FL } },
169{ .ca_index = 0x08, .speakers = { 0, 0, RR, RL, 0, 0, FR, FL } },
170{ .ca_index = 0x09, .speakers = { 0, 0, RR, RL, 0, LFE, FR, FL } },
171{ .ca_index = 0x0a, .speakers = { 0, 0, RR, RL, FC, 0, FR, FL } },
172 /* 5.1 */
173{ .ca_index = 0x0b, .speakers = { 0, 0, RR, RL, FC, LFE, FR, FL } },
174{ .ca_index = 0x0c, .speakers = { 0, RC, RR, RL, 0, 0, FR, FL } },
175{ .ca_index = 0x0d, .speakers = { 0, RC, RR, RL, 0, LFE, FR, FL } },
176{ .ca_index = 0x0e, .speakers = { 0, RC, RR, RL, FC, 0, FR, FL } },
177 /* 6.1 */
178{ .ca_index = 0x0f, .speakers = { 0, RC, RR, RL, FC, LFE, FR, FL } },
179{ .ca_index = 0x10, .speakers = { RRC, RLC, RR, RL, 0, 0, FR, FL } },
180{ .ca_index = 0x11, .speakers = { RRC, RLC, RR, RL, 0, LFE, FR, FL } },
181{ .ca_index = 0x12, .speakers = { RRC, RLC, RR, RL, FC, 0, FR, FL } },
182 /* 7.1 */
183{ .ca_index = 0x13, .speakers = { RRC, RLC, RR, RL, FC, LFE, FR, FL } },
184{ .ca_index = 0x14, .speakers = { FRC, FLC, 0, 0, 0, 0, FR, FL } },
185{ .ca_index = 0x15, .speakers = { FRC, FLC, 0, 0, 0, LFE, FR, FL } },
186{ .ca_index = 0x16, .speakers = { FRC, FLC, 0, 0, FC, 0, FR, FL } },
187{ .ca_index = 0x17, .speakers = { FRC, FLC, 0, 0, FC, LFE, FR, FL } },
188{ .ca_index = 0x18, .speakers = { FRC, FLC, 0, RC, 0, 0, FR, FL } },
189{ .ca_index = 0x19, .speakers = { FRC, FLC, 0, RC, 0, LFE, FR, FL } },
190{ .ca_index = 0x1a, .speakers = { FRC, FLC, 0, RC, FC, 0, FR, FL } },
191{ .ca_index = 0x1b, .speakers = { FRC, FLC, 0, RC, FC, LFE, FR, FL } },
192{ .ca_index = 0x1c, .speakers = { FRC, FLC, RR, RL, 0, 0, FR, FL } },
193{ .ca_index = 0x1d, .speakers = { FRC, FLC, RR, RL, 0, LFE, FR, FL } },
194{ .ca_index = 0x1e, .speakers = { FRC, FLC, RR, RL, FC, 0, FR, FL } },
195{ .ca_index = 0x1f, .speakers = { FRC, FLC, RR, RL, FC, LFE, FR, FL } },
196{ .ca_index = 0x20, .speakers = { 0, FCH, RR, RL, FC, 0, FR, FL } },
197{ .ca_index = 0x21, .speakers = { 0, FCH, RR, RL, FC, LFE, FR, FL } },
198{ .ca_index = 0x22, .speakers = { TC, 0, RR, RL, FC, 0, FR, FL } },
199{ .ca_index = 0x23, .speakers = { TC, 0, RR, RL, FC, LFE, FR, FL } },
200{ .ca_index = 0x24, .speakers = { FRH, FLH, RR, RL, 0, 0, FR, FL } },
201{ .ca_index = 0x25, .speakers = { FRH, FLH, RR, RL, 0, LFE, FR, FL } },
202{ .ca_index = 0x26, .speakers = { FRW, FLW, RR, RL, 0, 0, FR, FL } },
203{ .ca_index = 0x27, .speakers = { FRW, FLW, RR, RL, 0, LFE, FR, FL } },
204{ .ca_index = 0x28, .speakers = { TC, RC, RR, RL, FC, 0, FR, FL } },
205{ .ca_index = 0x29, .speakers = { TC, RC, RR, RL, FC, LFE, FR, FL } },
206{ .ca_index = 0x2a, .speakers = { FCH, RC, RR, RL, FC, 0, FR, FL } },
207{ .ca_index = 0x2b, .speakers = { FCH, RC, RR, RL, FC, LFE, FR, FL } },
208{ .ca_index = 0x2c, .speakers = { TC, FCH, RR, RL, FC, 0, FR, FL } },
209{ .ca_index = 0x2d, .speakers = { TC, FCH, RR, RL, FC, LFE, FR, FL } },
210{ .ca_index = 0x2e, .speakers = { FRH, FLH, RR, RL, FC, 0, FR, FL } },
211{ .ca_index = 0x2f, .speakers = { FRH, FLH, RR, RL, FC, LFE, FR, FL } },
212{ .ca_index = 0x30, .speakers = { FRW, FLW, RR, RL, FC, 0, FR, FL } },
213{ .ca_index = 0x31, .speakers = { FRW, FLW, RR, RL, FC, LFE, FR, FL } },
214};
215
216/*
217 * HDMI routines
218 */
219
220#ifdef BE_PARANOID
221static void hdmi_get_dip_index(struct hda_codec *codec, hda_nid_t nid,
222 int *packet_index, int *byte_index)
223{
224 int val;
225
226 val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_DIP_INDEX, 0);
227
228 *packet_index = val >> 5;
229 *byte_index = val & 0x1f;
230}
231#endif
232
233static void hdmi_set_dip_index(struct hda_codec *codec, hda_nid_t nid,
234 int packet_index, int byte_index)
235{
236 int val;
237
238 val = (packet_index << 5) | (byte_index & 0x1f);
239
240 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_HDMI_DIP_INDEX, val);
241}
242
243static void hdmi_write_dip_byte(struct hda_codec *codec, hda_nid_t nid,
244 unsigned char val)
245{
246 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_HDMI_DIP_DATA, val);
247}
248
249static void hdmi_enable_output(struct hda_codec *codec)
250{
251 /* Enable Audio InfoFrame Transmission */
252 hdmi_set_dip_index(codec, PIN_NID, 0x0, 0x0);
253 snd_hda_codec_write(codec, PIN_NID, 0, AC_VERB_SET_HDMI_DIP_XMIT,
254 AC_DIPXMIT_BEST);
255 /* Unmute */
256 if (get_wcaps(codec, PIN_NID) & AC_WCAP_OUT_AMP)
257 snd_hda_codec_write(codec, PIN_NID, 0,
258 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
259 /* Enable pin out */
260 snd_hda_sequence_write(codec, pinout_enable_verb);
261}
262
263static void hdmi_disable_output(struct hda_codec *codec)
264{
265 snd_hda_sequence_write(codec, pinout_disable_verb);
266 if (get_wcaps(codec, PIN_NID) & AC_WCAP_OUT_AMP)
267 snd_hda_codec_write(codec, PIN_NID, 0,
268 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
269
270 /*
271 * FIXME: noises may arise when playing music after reloading the
272 * kernel module, until the next X restart or monitor repower.
273 */
274}
275
276static int hdmi_get_channel_count(struct hda_codec *codec)
277{
278 return 1 + snd_hda_codec_read(codec, CVT_NID, 0,
279 AC_VERB_GET_CVT_CHAN_COUNT, 0);
280}
281
282static void hdmi_set_channel_count(struct hda_codec *codec, int chs)
283{
284 snd_hda_codec_write(codec, CVT_NID, 0,
285 AC_VERB_SET_CVT_CHAN_COUNT, chs - 1);
286
287 if (chs != hdmi_get_channel_count(codec))
288 snd_printd(KERN_INFO "HDMI channel count: expect %d, get %d\n",
289 chs, hdmi_get_channel_count(codec));
290}
291
292static void hdmi_debug_channel_mapping(struct hda_codec *codec)
293{
294#ifdef CONFIG_SND_DEBUG_VERBOSE
295 int i;
296 int slot;
297
298 for (i = 0; i < 8; i++) {
299 slot = snd_hda_codec_read(codec, CVT_NID, 0,
300 AC_VERB_GET_HDMI_CHAN_SLOT, i);
301 printk(KERN_DEBUG "HDMI: ASP channel %d => slot %d\n",
302 slot >> 4, slot & 0x7);
303 }
304#endif
305}
306
307static void hdmi_parse_eld(struct hda_codec *codec)
308{
309 struct intel_hdmi_spec *spec = codec->spec;
310 struct hdmi_eld *eld = &spec->sink_eld;
311
312 if (!snd_hdmi_get_eld(eld, codec, PIN_NID))
313 snd_hdmi_show_eld(eld);
314}
315
316
317/*
318 * Audio InfoFrame routines
319 */
320
321static void hdmi_debug_dip_size(struct hda_codec *codec)
322{
323#ifdef CONFIG_SND_DEBUG_VERBOSE
324 int i;
325 int size;
326
327 size = snd_hdmi_get_eld_size(codec, PIN_NID);
328 printk(KERN_DEBUG "HDMI: ELD buf size is %d\n", size);
329
330 for (i = 0; i < 8; i++) {
331 size = snd_hda_codec_read(codec, PIN_NID, 0,
332 AC_VERB_GET_HDMI_DIP_SIZE, i);
333 printk(KERN_DEBUG "HDMI: DIP GP[%d] buf size is %d\n", i, size);
334 }
335#endif
336}
337
338static void hdmi_clear_dip_buffers(struct hda_codec *codec)
339{
340#ifdef BE_PARANOID
341 int i, j;
342 int size;
343 int pi, bi;
344 for (i = 0; i < 8; i++) {
345 size = snd_hda_codec_read(codec, PIN_NID, 0,
346 AC_VERB_GET_HDMI_DIP_SIZE, i);
347 if (size == 0)
348 continue;
349
350 hdmi_set_dip_index(codec, PIN_NID, i, 0x0);
351 for (j = 1; j < 1000; j++) {
352 hdmi_write_dip_byte(codec, PIN_NID, 0x0);
353 hdmi_get_dip_index(codec, PIN_NID, &pi, &bi);
354 if (pi != i)
355 snd_printd(KERN_INFO "dip index %d: %d != %d\n",
356 bi, pi, i);
357 if (bi == 0) /* byte index wrapped around */
358 break;
359 }
360 snd_printd(KERN_INFO
361 "HDMI: DIP GP[%d] buf reported size=%d, written=%d\n",
362 i, size, j);
363 }
364#endif
365}
366
367static void hdmi_fill_audio_infoframe(struct hda_codec *codec,
368 struct hdmi_audio_infoframe *ai)
369{
370 u8 *params = (u8 *)ai;
371 int i;
372
373 hdmi_debug_dip_size(codec);
374 hdmi_clear_dip_buffers(codec); /* be paranoid */
375
376 hdmi_set_dip_index(codec, PIN_NID, 0x0, 0x0);
377 for (i = 0; i < sizeof(ai); i++)
378 hdmi_write_dip_byte(codec, PIN_NID, params[i]);
379}
380
381/*
382 * Compute derived values in channel_allocations[].
383 */
384static void init_channel_allocations(void)
385{
386 int i, j;
387 struct cea_channel_speaker_allocation *p;
388
389 for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
390 p = channel_allocations + i;
391 p->channels = 0;
392 p->spk_mask = 0;
393 for (j = 0; j < ARRAY_SIZE(p->speakers); j++)
394 if (p->speakers[j]) {
395 p->channels++;
396 p->spk_mask |= p->speakers[j];
397 }
398 }
399}
400
401/*
402 * The transformation takes two steps:
403 *
404 * eld->spk_alloc => (eld_speaker_allocation_bits[]) => spk_mask
405 * spk_mask => (channel_allocations[]) => ai->CA
406 *
407 * TODO: it could select the wrong CA from multiple candidates.
408*/
409static int hdmi_setup_channel_allocation(struct hda_codec *codec,
410 struct hdmi_audio_infoframe *ai)
411{
412 struct intel_hdmi_spec *spec = codec->spec;
413 struct hdmi_eld *eld = &spec->sink_eld;
414 int i;
415 int spk_mask = 0;
416 int channels = 1 + (ai->CC02_CT47 & 0x7);
417 char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE];
418
419 /*
420 * CA defaults to 0 for basic stereo audio
421 */
422 if (!eld->eld_ver)
423 return 0;
424 if (!eld->spk_alloc)
425 return 0;
426 if (channels <= 2)
427 return 0;
428
429 /*
430 * expand ELD's speaker allocation mask
431 *
432 * ELD tells the speaker mask in a compact(paired) form,
433 * expand ELD's notions to match the ones used by Audio InfoFrame.
434 */
435 for (i = 0; i < ARRAY_SIZE(eld_speaker_allocation_bits); i++) {
436 if (eld->spk_alloc & (1 << i))
437 spk_mask |= eld_speaker_allocation_bits[i];
438 }
439
440 /* search for the first working match in the CA table */
441 for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
442 if (channels == channel_allocations[i].channels &&
443 (spk_mask & channel_allocations[i].spk_mask) ==
444 channel_allocations[i].spk_mask) {
445 ai->CA = channel_allocations[i].ca_index;
446 break;
447 }
448 }
449
450 snd_print_channel_allocation(eld->spk_alloc, buf, sizeof(buf));
451 snd_printdd(KERN_INFO
452 "HDMI: select CA 0x%x for %d-channel allocation: %s\n",
453 ai->CA, channels, buf);
454
455 return ai->CA;
456}
457
458static void hdmi_setup_channel_mapping(struct hda_codec *codec,
459 struct hdmi_audio_infoframe *ai)
460{
461 if (!ai->CA)
462 return;
463
464 /*
465 * TODO: adjust channel mapping if necessary
466 * ALSA sequence is front/surr/clfe/side?
467 */
468
469 snd_hda_sequence_write(codec, def_chan_map);
470 hdmi_debug_channel_mapping(codec);
471}
472
473
474static void hdmi_setup_audio_infoframe(struct hda_codec *codec,
475 struct snd_pcm_substream *substream)
476{
477 struct hdmi_audio_infoframe ai = {
478 .type = 0x84,
479 .ver = 0x01,
480 .len = 0x0a,
481 .CC02_CT47 = substream->runtime->channels - 1,
482 };
483
484 hdmi_setup_channel_allocation(codec, &ai);
485 hdmi_setup_channel_mapping(codec, &ai);
486
487 hdmi_fill_audio_infoframe(codec, &ai);
488}
489
490
491/*
492 * Unsolicited events
493 */
494
495static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
496{
497 int pind = !!(res & AC_UNSOL_RES_PD);
498 int eldv = !!(res & AC_UNSOL_RES_ELDV);
499
500 printk(KERN_INFO
501 "HDMI hot plug event: Presence_Detect=%d ELD_Valid=%d\n",
502 pind, eldv);
503
504 if (pind && eldv) {
505 hdmi_parse_eld(codec);
506 /* TODO: do real things about ELD */
507 }
508}
509
510static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res)
511{
512 int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
513 int cp_state = !!(res & AC_UNSOL_RES_CP_STATE);
514 int cp_ready = !!(res & AC_UNSOL_RES_CP_READY);
515
516 printk(KERN_INFO
517 "HDMI content protection event: SUBTAG=0x%x CP_STATE=%d CP_READY=%d\n",
518 subtag,
519 cp_state,
520 cp_ready);
521
522 /* TODO */
523 if (cp_state)
524 ;
525 if (cp_ready)
526 ;
527}
528
529
530static void intel_hdmi_unsol_event(struct hda_codec *codec, unsigned int res)
531{
532 int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
533 int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
534
535 if (tag != INTEL_HDMI_EVENT_TAG) {
536 snd_printd(KERN_INFO "Unexpected HDMI event tag 0x%x\n", tag);
537 return;
538 }
539
540 if (subtag == 0)
541 hdmi_intrinsic_event(codec, res);
542 else
543 hdmi_non_intrinsic_event(codec, res);
544}
545
546/*
547 * Callbacks
548 */
549
550static int intel_hdmi_playback_pcm_open(struct hda_pcm_stream *hinfo,
551 struct hda_codec *codec,
552 struct snd_pcm_substream *substream)
553{
554 struct intel_hdmi_spec *spec = codec->spec;
555
556 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
557}
558
559static int intel_hdmi_playback_pcm_close(struct hda_pcm_stream *hinfo,
560 struct hda_codec *codec,
561 struct snd_pcm_substream *substream)
562{
563 struct intel_hdmi_spec *spec = codec->spec;
564
565 hdmi_disable_output(codec);
566
567 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
568}
569
570static int intel_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
571 struct hda_codec *codec,
572 unsigned int stream_tag,
573 unsigned int format,
574 struct snd_pcm_substream *substream)
575{
576 struct intel_hdmi_spec *spec = codec->spec;
577
578 snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
579 format, substream);
580
581 hdmi_set_channel_count(codec, substream->runtime->channels);
582
583 hdmi_setup_audio_infoframe(codec, substream);
584
585 hdmi_enable_output(codec);
586
587 return 0;
588}
589
590static struct hda_pcm_stream intel_hdmi_pcm_playback = {
591 .substreams = 1,
592 .channels_min = 2,
593 .channels_max = 8,
594 .nid = CVT_NID, /* NID to query formats and rates and setup streams */
595 .ops = {
596 .open = intel_hdmi_playback_pcm_open,
597 .close = intel_hdmi_playback_pcm_close,
598 .prepare = intel_hdmi_playback_pcm_prepare
599 },
600};
601
602static int intel_hdmi_build_pcms(struct hda_codec *codec)
603{
604 struct intel_hdmi_spec *spec = codec->spec;
605 struct hda_pcm *info = &spec->pcm_rec;
606
607 codec->num_pcms = 1;
608 codec->pcm_info = info;
609
610 info->name = "INTEL HDMI";
611 info->pcm_type = HDA_PCM_TYPE_HDMI;
612 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = intel_hdmi_pcm_playback;
613
614 return 0;
615}
616
617static int intel_hdmi_build_controls(struct hda_codec *codec)
618{
619 struct intel_hdmi_spec *spec = codec->spec;
620 int err;
621
622 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
623 if (err < 0)
624 return err;
625
626 return 0;
627}
628
629static int intel_hdmi_init(struct hda_codec *codec)
630{
631 /* disable audio output as early as possible */
632 hdmi_disable_output(codec);
633
634 snd_hda_sequence_write(codec, unsolicited_response_verb);
635
636 return 0;
637}
638
639static void intel_hdmi_free(struct hda_codec *codec)
640{
641 struct intel_hdmi_spec *spec = codec->spec;
642
643 snd_hda_eld_proc_free(codec, &spec->sink_eld);
644 kfree(spec);
645}
646
647static struct hda_codec_ops intel_hdmi_patch_ops = {
648 .init = intel_hdmi_init,
649 .free = intel_hdmi_free,
650 .build_pcms = intel_hdmi_build_pcms,
651 .build_controls = intel_hdmi_build_controls,
652 .unsol_event = intel_hdmi_unsol_event,
653};
654
655static int patch_intel_hdmi(struct hda_codec *codec)
656{
657 struct intel_hdmi_spec *spec;
658
659 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
660 if (spec == NULL)
661 return -ENOMEM;
662
663 spec->multiout.num_dacs = 0; /* no analog */
664 spec->multiout.max_channels = 8;
665 spec->multiout.dig_out_nid = CVT_NID;
666
667 codec->spec = spec;
668 codec->patch_ops = intel_hdmi_patch_ops;
669
670 snd_hda_eld_proc_new(codec, &spec->sink_eld);
671
672 init_channel_allocations();
673
674 return 0;
675}
676
677static struct hda_codec_preset snd_hda_preset_intelhdmi[] = {
678 { .id = 0x808629fb, .name = "G45 DEVCL", .patch = patch_intel_hdmi },
679 { .id = 0x80862801, .name = "G45 DEVBLC", .patch = patch_intel_hdmi },
680 { .id = 0x80862802, .name = "G45 DEVCTG", .patch = patch_intel_hdmi },
681 { .id = 0x80862803, .name = "G45 DEVELK", .patch = patch_intel_hdmi },
682 { .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_intel_hdmi },
683 {} /* terminator */
684};
685
686MODULE_ALIAS("snd-hda-codec-id:808629fb");
687MODULE_ALIAS("snd-hda-codec-id:80862801");
688MODULE_ALIAS("snd-hda-codec-id:80862802");
689MODULE_ALIAS("snd-hda-codec-id:80862803");
690MODULE_ALIAS("snd-hda-codec-id:10951392");
691
692MODULE_LICENSE("GPL");
693MODULE_DESCRIPTION("Intel HDMI HD-audio codec");
694
695static struct hda_codec_preset_list intel_list = {
696 .preset = snd_hda_preset_intelhdmi,
697 .owner = THIS_MODULE,
698};
699
700static int __init patch_intelhdmi_init(void)
701{
702 return snd_hda_add_codec_preset(&intel_list);
703}
704
705static void __exit patch_intelhdmi_exit(void)
706{
707 snd_hda_delete_codec_preset(&intel_list);
708}
709
710module_init(patch_intelhdmi_init)
711module_exit(patch_intelhdmi_exit)
diff --git a/sound/pci/hda/patch_nvhdmi.c b/sound/pci/hda/patch_nvhdmi.c
index 2eed2c8b98da..0270fda0bda5 100644
--- a/sound/pci/hda/patch_nvhdmi.c
+++ b/sound/pci/hda/patch_nvhdmi.c
@@ -158,8 +158,34 @@ static int patch_nvhdmi(struct hda_codec *codec)
158/* 158/*
159 * patch entries 159 * patch entries
160 */ 160 */
161struct hda_codec_preset snd_hda_preset_nvhdmi[] = { 161static struct hda_codec_preset snd_hda_preset_nvhdmi[] = {
162 { .id = 0x10de0002, .name = "NVIDIA MCP78 HDMI", .patch = patch_nvhdmi }, 162 { .id = 0x10de0002, .name = "MCP78 HDMI", .patch = patch_nvhdmi },
163 { .id = 0x10de0007, .name = "NVIDIA MCP7A HDMI", .patch = patch_nvhdmi }, 163 { .id = 0x10de0007, .name = "MCP7A HDMI", .patch = patch_nvhdmi },
164 { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi },
164 {} /* terminator */ 165 {} /* terminator */
165}; 166};
167
168MODULE_ALIAS("snd-hda-codec-id:10de0002");
169MODULE_ALIAS("snd-hda-codec-id:10de0007");
170MODULE_ALIAS("snd-hda-codec-id:10de0067");
171
172MODULE_LICENSE("GPL");
173MODULE_DESCRIPTION("Nvidia HDMI HD-audio codec");
174
175static struct hda_codec_preset_list nvhdmi_list = {
176 .preset = snd_hda_preset_nvhdmi,
177 .owner = THIS_MODULE,
178};
179
180static int __init patch_nvhdmi_init(void)
181{
182 return snd_hda_add_codec_preset(&nvhdmi_list);
183}
184
185static void __exit patch_nvhdmi_exit(void)
186{
187 snd_hda_delete_codec_preset(&nvhdmi_list);
188}
189
190module_init(patch_nvhdmi_init)
191module_exit(patch_nvhdmi_exit)
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index a378c0145125..0bd4e6bf354d 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -30,7 +30,6 @@
30#include <sound/core.h> 30#include <sound/core.h>
31#include "hda_codec.h" 31#include "hda_codec.h"
32#include "hda_local.h" 32#include "hda_local.h"
33#include "hda_patch.h"
34 33
35#define ALC880_FRONT_EVENT 0x01 34#define ALC880_FRONT_EVENT 0x01
36#define ALC880_DCVOL_EVENT 0x02 35#define ALC880_DCVOL_EVENT 0x02
@@ -114,6 +113,7 @@ enum {
114 ALC268_3ST, 113 ALC268_3ST,
115 ALC268_TOSHIBA, 114 ALC268_TOSHIBA,
116 ALC268_ACER, 115 ALC268_ACER,
116 ALC268_ACER_DMIC,
117 ALC268_ACER_ASPIRE_ONE, 117 ALC268_ACER_ASPIRE_ONE,
118 ALC268_DELL, 118 ALC268_DELL,
119 ALC268_ZEPTO, 119 ALC268_ZEPTO,
@@ -130,6 +130,8 @@ enum {
130 ALC269_QUANTA_FL1, 130 ALC269_QUANTA_FL1,
131 ALC269_ASUS_EEEPC_P703, 131 ALC269_ASUS_EEEPC_P703,
132 ALC269_ASUS_EEEPC_P901, 132 ALC269_ASUS_EEEPC_P901,
133 ALC269_FUJITSU,
134 ALC269_LIFEBOOK,
133 ALC269_AUTO, 135 ALC269_AUTO,
134 ALC269_MODEL_LAST /* last tag */ 136 ALC269_MODEL_LAST /* last tag */
135}; 137};
@@ -152,6 +154,7 @@ enum {
152enum { 154enum {
153 ALC660VD_3ST, 155 ALC660VD_3ST,
154 ALC660VD_3ST_DIG, 156 ALC660VD_3ST_DIG,
157 ALC660VD_ASUS_V1S,
155 ALC861VD_3ST, 158 ALC861VD_3ST,
156 ALC861VD_3ST_DIG, 159 ALC861VD_3ST_DIG,
157 ALC861VD_6ST_DIG, 160 ALC861VD_6ST_DIG,
@@ -212,6 +215,7 @@ enum {
212 ALC883_TARGA_2ch_DIG, 215 ALC883_TARGA_2ch_DIG,
213 ALC883_ACER, 216 ALC883_ACER,
214 ALC883_ACER_ASPIRE, 217 ALC883_ACER_ASPIRE,
218 ALC888_ACER_ASPIRE_4930G,
215 ALC883_MEDION, 219 ALC883_MEDION,
216 ALC883_MEDION_MD2, 220 ALC883_MEDION_MD2,
217 ALC883_LAPTOP_EAPD, 221 ALC883_LAPTOP_EAPD,
@@ -225,9 +229,11 @@ enum {
225 ALC883_MITAC, 229 ALC883_MITAC,
226 ALC883_CLEVO_M720, 230 ALC883_CLEVO_M720,
227 ALC883_FUJITSU_PI2515, 231 ALC883_FUJITSU_PI2515,
232 ALC888_FUJITSU_XA3530,
228 ALC883_3ST_6ch_INTEL, 233 ALC883_3ST_6ch_INTEL,
229 ALC888_ASUS_M90V, 234 ALC888_ASUS_M90V,
230 ALC888_ASUS_EEE1601, 235 ALC888_ASUS_EEE1601,
236 ALC1200_ASUS_P5Q,
231 ALC883_AUTO, 237 ALC883_AUTO,
232 ALC883_MODEL_LAST, 238 ALC883_MODEL_LAST,
233}; 239};
@@ -239,6 +245,7 @@ struct alc_spec {
239 /* codec parameterization */ 245 /* codec parameterization */
240 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ 246 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
241 unsigned int num_mixers; 247 unsigned int num_mixers;
248 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
242 249
243 const struct hda_verb *init_verbs[5]; /* initialization verbs 250 const struct hda_verb *init_verbs[5]; /* initialization verbs
244 * don't forget NULL 251 * don't forget NULL
@@ -268,6 +275,7 @@ struct alc_spec {
268 hda_nid_t *adc_nids; 275 hda_nid_t *adc_nids;
269 hda_nid_t *capsrc_nids; 276 hda_nid_t *capsrc_nids;
270 hda_nid_t dig_in_nid; /* digital-in NID; optional */ 277 hda_nid_t dig_in_nid; /* digital-in NID; optional */
278 unsigned char is_mix_capture; /* matrix-style capture (non-mux) */
271 279
272 /* capture source */ 280 /* capture source */
273 unsigned int num_mux_defs; 281 unsigned int num_mux_defs;
@@ -284,8 +292,7 @@ struct alc_spec {
284 292
285 /* dynamic controls, init_verbs and input_mux */ 293 /* dynamic controls, init_verbs and input_mux */
286 struct auto_pin_cfg autocfg; 294 struct auto_pin_cfg autocfg;
287 unsigned int num_kctl_alloc, num_kctl_used; 295 struct snd_array kctls;
288 struct snd_kcontrol_new *kctl_alloc;
289 struct hda_input_mux private_imux; 296 struct hda_input_mux private_imux;
290 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; 297 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
291 298
@@ -323,6 +330,7 @@ struct alc_config_preset {
323 struct snd_kcontrol_new *mixers[5]; /* should be identical size 330 struct snd_kcontrol_new *mixers[5]; /* should be identical size
324 * with spec 331 * with spec
325 */ 332 */
333 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
326 const struct hda_verb *init_verbs[5]; 334 const struct hda_verb *init_verbs[5];
327 unsigned int num_dacs; 335 unsigned int num_dacs;
328 hda_nid_t *dac_nids; 336 hda_nid_t *dac_nids;
@@ -375,14 +383,39 @@ static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
375{ 383{
376 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 384 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
377 struct alc_spec *spec = codec->spec; 385 struct alc_spec *spec = codec->spec;
386 const struct hda_input_mux *imux;
378 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 387 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
379 unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; 388 unsigned int mux_idx;
380 hda_nid_t nid = spec->capsrc_nids ? 389 hda_nid_t nid = spec->capsrc_nids ?
381 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx]; 390 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
382 return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
383 nid, &spec->cur_mux[adc_idx]);
384}
385 391
392 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
393 imux = &spec->input_mux[mux_idx];
394
395 if (spec->is_mix_capture) {
396 /* Matrix-mixer style (e.g. ALC882) */
397 unsigned int *cur_val = &spec->cur_mux[adc_idx];
398 unsigned int i, idx;
399
400 idx = ucontrol->value.enumerated.item[0];
401 if (idx >= imux->num_items)
402 idx = imux->num_items - 1;
403 if (*cur_val == idx)
404 return 0;
405 for (i = 0; i < imux->num_items; i++) {
406 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
407 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
408 imux->items[i].index,
409 HDA_AMP_MUTE, v);
410 }
411 *cur_val = idx;
412 return 1;
413 } else {
414 /* MUX style (e.g. ALC880) */
415 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
416 &spec->cur_mux[adc_idx]);
417 }
418}
386 419
387/* 420/*
388 * channel mode setting 421 * channel mode setting
@@ -717,6 +750,43 @@ static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
717#endif /* CONFIG_SND_DEBUG */ 750#endif /* CONFIG_SND_DEBUG */
718 751
719/* 752/*
753 */
754static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
755{
756 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
757 return;
758 spec->mixers[spec->num_mixers++] = mix;
759}
760
761static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
762{
763 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
764 return;
765 spec->init_verbs[spec->num_init_verbs++] = verb;
766}
767
768#ifdef CONFIG_PROC_FS
769/*
770 * hook for proc
771 */
772static void print_realtek_coef(struct snd_info_buffer *buffer,
773 struct hda_codec *codec, hda_nid_t nid)
774{
775 int coeff;
776
777 if (nid != 0x20)
778 return;
779 coeff = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
780 snd_iprintf(buffer, " Processing Coefficient: 0x%02x\n", coeff);
781 coeff = snd_hda_codec_read(codec, nid, 0,
782 AC_VERB_GET_COEF_INDEX, 0);
783 snd_iprintf(buffer, " Coefficient Index: 0x%02x\n", coeff);
784}
785#else
786#define print_realtek_coef NULL
787#endif
788
789/*
720 * set up from the preset table 790 * set up from the preset table
721 */ 791 */
722static void setup_preset(struct alc_spec *spec, 792static void setup_preset(struct alc_spec *spec,
@@ -725,11 +795,11 @@ static void setup_preset(struct alc_spec *spec,
725 int i; 795 int i;
726 796
727 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++) 797 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
728 spec->mixers[spec->num_mixers++] = preset->mixers[i]; 798 add_mixer(spec, preset->mixers[i]);
799 spec->cap_mixer = preset->cap_mixer;
729 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i]; 800 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
730 i++) 801 i++)
731 spec->init_verbs[spec->num_init_verbs++] = 802 add_verb(spec, preset->init_verbs[i]);
732 preset->init_verbs[i];
733 803
734 spec->channel_mode = preset->channel_mode; 804 spec->channel_mode = preset->channel_mode;
735 spec->num_channel_mode = preset->num_channel_mode; 805 spec->num_channel_mode = preset->num_channel_mode;
@@ -1107,6 +1177,226 @@ static void alc_fix_pincfg(struct hda_codec *codec,
1107} 1177}
1108 1178
1109/* 1179/*
1180 * ALC888
1181 */
1182
1183/*
1184 * 2ch mode
1185 */
1186static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1187/* Mic-in jack as mic in */
1188 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1189 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1190/* Line-in jack as Line in */
1191 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1192 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1193/* Line-Out as Front */
1194 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1195 { } /* end */
1196};
1197
1198/*
1199 * 4ch mode
1200 */
1201static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1202/* Mic-in jack as mic in */
1203 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1204 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1205/* Line-in jack as Surround */
1206 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1207 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1208/* Line-Out as Front */
1209 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1210 { } /* end */
1211};
1212
1213/*
1214 * 6ch mode
1215 */
1216static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1217/* Mic-in jack as CLFE */
1218 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1219 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1220/* Line-in jack as Surround */
1221 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1222 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1223/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1224 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1225 { } /* end */
1226};
1227
1228/*
1229 * 8ch mode
1230 */
1231static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1232/* Mic-in jack as CLFE */
1233 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1234 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1235/* Line-in jack as Surround */
1236 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1237 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1238/* Line-Out as Side */
1239 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1240 { } /* end */
1241};
1242
1243static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1244 { 2, alc888_4ST_ch2_intel_init },
1245 { 4, alc888_4ST_ch4_intel_init },
1246 { 6, alc888_4ST_ch6_intel_init },
1247 { 8, alc888_4ST_ch8_intel_init },
1248};
1249
1250/*
1251 * ALC888 Fujitsu Siemens Amillo xa3530
1252 */
1253
1254static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1255/* Front Mic: set to PIN_IN (empty by default) */
1256 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1257/* Connect Internal HP to Front */
1258 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1259 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1260 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1261/* Connect Bass HP to Front */
1262 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1263 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1264 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1265/* Connect Line-Out side jack (SPDIF) to Side */
1266 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1267 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1268 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1269/* Connect Mic jack to CLFE */
1270 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1271 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1272 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1273/* Connect Line-in jack to Surround */
1274 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1275 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1276 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1277/* Connect HP out jack to Front */
1278 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1279 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1280 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1281/* Enable unsolicited event for HP jack and Line-out jack */
1282 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1283 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1284 {}
1285};
1286
1287static void alc888_fujitsu_xa3530_automute(struct hda_codec *codec)
1288{
1289 unsigned int present;
1290 unsigned int bits;
1291 /* Line out presence */
1292 present = snd_hda_codec_read(codec, 0x17, 0,
1293 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1294 /* HP out presence */
1295 present = present || snd_hda_codec_read(codec, 0x1b, 0,
1296 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1297 bits = present ? HDA_AMP_MUTE : 0;
1298 /* Toggle internal speakers muting */
1299 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
1300 HDA_AMP_MUTE, bits);
1301 /* Toggle internal bass muting */
1302 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
1303 HDA_AMP_MUTE, bits);
1304}
1305
1306static void alc888_fujitsu_xa3530_unsol_event(struct hda_codec *codec,
1307 unsigned int res)
1308{
1309 if (res >> 26 == ALC880_HP_EVENT)
1310 alc888_fujitsu_xa3530_automute(codec);
1311}
1312
1313
1314/*
1315 * ALC888 Acer Aspire 4930G model
1316 */
1317
1318static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1319/* Front Mic: set to PIN_IN (empty by default) */
1320 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1321/* Unselect Front Mic by default in input mixer 3 */
1322 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1323/* Enable unsolicited event for HP jack */
1324 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1325/* Connect Internal HP to front */
1326 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1327 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1328 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1329/* Connect HP out to front */
1330 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1331 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1332 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1333 { }
1334};
1335
1336static struct hda_input_mux alc888_2_capture_sources[2] = {
1337 /* Front mic only available on one ADC */
1338 {
1339 .num_items = 4,
1340 .items = {
1341 { "Mic", 0x0 },
1342 { "Line", 0x2 },
1343 { "CD", 0x4 },
1344 { "Front Mic", 0xb },
1345 },
1346 },
1347 {
1348 .num_items = 3,
1349 .items = {
1350 { "Mic", 0x0 },
1351 { "Line", 0x2 },
1352 { "CD", 0x4 },
1353 },
1354 }
1355};
1356
1357static struct snd_kcontrol_new alc888_base_mixer[] = {
1358 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1359 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1360 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1361 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1362 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1363 HDA_OUTPUT),
1364 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1365 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1366 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1367 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1368 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1369 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1370 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1371 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1372 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1373 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1374 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1375 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1376 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1377 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1378 { } /* end */
1379};
1380
1381static void alc888_acer_aspire_4930g_automute(struct hda_codec *codec)
1382{
1383 unsigned int present;
1384 unsigned int bits;
1385 present = snd_hda_codec_read(codec, 0x15, 0,
1386 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1387 bits = present ? HDA_AMP_MUTE : 0;
1388 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
1389 HDA_AMP_MUTE, bits);
1390}
1391
1392static void alc888_acer_aspire_4930g_unsol_event(struct hda_codec *codec,
1393 unsigned int res)
1394{
1395 if (res >> 26 == ALC880_HP_EVENT)
1396 alc888_acer_aspire_4930g_automute(codec);
1397}
1398
1399/*
1110 * ALC880 3-stack model 1400 * ALC880 3-stack model
1111 * 1401 *
1112 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e) 1402 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
@@ -1205,49 +1495,126 @@ static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
1205}; 1495};
1206 1496
1207/* capture mixer elements */ 1497/* capture mixer elements */
1208static struct snd_kcontrol_new alc880_capture_mixer[] = { 1498static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
1209 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT), 1499 struct snd_ctl_elem_info *uinfo)
1210 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT), 1500{
1211 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT), 1501 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1212 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT), 1502 struct alc_spec *spec = codec->spec;
1213 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT), 1503 int err;
1214 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
1215 {
1216 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1217 /* The multiple "Capture Source" controls confuse alsamixer
1218 * So call somewhat different..
1219 */
1220 /* .name = "Capture Source", */
1221 .name = "Input Source",
1222 .count = 3,
1223 .info = alc_mux_enum_info,
1224 .get = alc_mux_enum_get,
1225 .put = alc_mux_enum_put,
1226 },
1227 { } /* end */
1228};
1229 1504
1230/* capture mixer elements (in case NID 0x07 not available) */ 1505 mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
1231static struct snd_kcontrol_new alc880_capture_alt_mixer[] = { 1506 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1232 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 1507 HDA_INPUT);
1233 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 1508 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
1234 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 1509 mutex_unlock(&codec->spdif_mutex); /* reuse spdif_mutex */
1235 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 1510 return err;
1236 { 1511}
1237 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1512
1238 /* The multiple "Capture Source" controls confuse alsamixer 1513static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1239 * So call somewhat different.. 1514 unsigned int size, unsigned int __user *tlv)
1240 */ 1515{
1241 /* .name = "Capture Source", */ 1516 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1242 .name = "Input Source", 1517 struct alc_spec *spec = codec->spec;
1243 .count = 2, 1518 int err;
1244 .info = alc_mux_enum_info,
1245 .get = alc_mux_enum_get,
1246 .put = alc_mux_enum_put,
1247 },
1248 { } /* end */
1249};
1250 1519
1520 mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
1521 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1522 HDA_INPUT);
1523 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
1524 mutex_unlock(&codec->spdif_mutex); /* reuse spdif_mutex */
1525 return err;
1526}
1527
1528typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
1529 struct snd_ctl_elem_value *ucontrol);
1530
1531static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
1532 struct snd_ctl_elem_value *ucontrol,
1533 getput_call_t func)
1534{
1535 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1536 struct alc_spec *spec = codec->spec;
1537 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1538 int err;
1539
1540 mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
1541 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
1542 3, 0, HDA_INPUT);
1543 err = func(kcontrol, ucontrol);
1544 mutex_unlock(&codec->spdif_mutex); /* reuse spdif_mutex */
1545 return err;
1546}
1547
1548static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
1549 struct snd_ctl_elem_value *ucontrol)
1550{
1551 return alc_cap_getput_caller(kcontrol, ucontrol,
1552 snd_hda_mixer_amp_volume_get);
1553}
1554
1555static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
1556 struct snd_ctl_elem_value *ucontrol)
1557{
1558 return alc_cap_getput_caller(kcontrol, ucontrol,
1559 snd_hda_mixer_amp_volume_put);
1560}
1561
1562/* capture mixer elements */
1563#define alc_cap_sw_info snd_ctl_boolean_stereo_info
1564
1565static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
1566 struct snd_ctl_elem_value *ucontrol)
1567{
1568 return alc_cap_getput_caller(kcontrol, ucontrol,
1569 snd_hda_mixer_amp_switch_get);
1570}
1571
1572static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
1573 struct snd_ctl_elem_value *ucontrol)
1574{
1575 return alc_cap_getput_caller(kcontrol, ucontrol,
1576 snd_hda_mixer_amp_switch_put);
1577}
1578
1579#define DEFINE_CAPMIX(num) \
1580static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
1581 { \
1582 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1583 .name = "Capture Switch", \
1584 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
1585 .count = num, \
1586 .info = alc_cap_sw_info, \
1587 .get = alc_cap_sw_get, \
1588 .put = alc_cap_sw_put, \
1589 }, \
1590 { \
1591 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1592 .name = "Capture Volume", \
1593 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
1594 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
1595 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
1596 .count = num, \
1597 .info = alc_cap_vol_info, \
1598 .get = alc_cap_vol_get, \
1599 .put = alc_cap_vol_put, \
1600 .tlv = { .c = alc_cap_vol_tlv }, \
1601 }, \
1602 { \
1603 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1604 /* .name = "Capture Source", */ \
1605 .name = "Input Source", \
1606 .count = num, \
1607 .info = alc_mux_enum_info, \
1608 .get = alc_mux_enum_get, \
1609 .put = alc_mux_enum_put, \
1610 }, \
1611 { } /* end */ \
1612}
1613
1614/* up to three ADCs */
1615DEFINE_CAPMIX(1);
1616DEFINE_CAPMIX(2);
1617DEFINE_CAPMIX(3);
1251 1618
1252 1619
1253/* 1620/*
@@ -1533,18 +1900,6 @@ static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1533 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT), 1900 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1534 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 1901 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1535 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 1902 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1536 {
1537 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1538 /* The multiple "Capture Source" controls confuse alsamixer
1539 * So call somewhat different..
1540 */
1541 /* .name = "Capture Source", */
1542 .name = "Input Source",
1543 .count = 1,
1544 .info = alc_mux_enum_info,
1545 .get = alc_mux_enum_get,
1546 .put = alc_mux_enum_put,
1547 },
1548 { } /* end */ 1903 { } /* end */
1549}; 1904};
1550 1905
@@ -1619,6 +1974,7 @@ static const char *alc_slave_vols[] = {
1619 "Speaker Playback Volume", 1974 "Speaker Playback Volume",
1620 "Mono Playback Volume", 1975 "Mono Playback Volume",
1621 "Line-Out Playback Volume", 1976 "Line-Out Playback Volume",
1977 "PCM Playback Volume",
1622 NULL, 1978 NULL,
1623}; 1979};
1624 1980
@@ -1638,6 +1994,9 @@ static const char *alc_slave_sws[] = {
1638/* 1994/*
1639 * build control elements 1995 * build control elements
1640 */ 1996 */
1997
1998static void alc_free_kctls(struct hda_codec *codec);
1999
1641static int alc_build_controls(struct hda_codec *codec) 2000static int alc_build_controls(struct hda_codec *codec)
1642{ 2001{
1643 struct alc_spec *spec = codec->spec; 2002 struct alc_spec *spec = codec->spec;
@@ -1649,7 +2008,11 @@ static int alc_build_controls(struct hda_codec *codec)
1649 if (err < 0) 2008 if (err < 0)
1650 return err; 2009 return err;
1651 } 2010 }
1652 2011 if (spec->cap_mixer) {
2012 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2013 if (err < 0)
2014 return err;
2015 }
1653 if (spec->multiout.dig_out_nid) { 2016 if (spec->multiout.dig_out_nid) {
1654 err = snd_hda_create_spdif_out_ctls(codec, 2017 err = snd_hda_create_spdif_out_ctls(codec,
1655 spec->multiout.dig_out_nid); 2018 spec->multiout.dig_out_nid);
@@ -1684,6 +2047,7 @@ static int alc_build_controls(struct hda_codec *codec)
1684 return err; 2047 return err;
1685 } 2048 }
1686 2049
2050 alc_free_kctls(codec); /* no longer needed */
1687 return 0; 2051 return 0;
1688} 2052}
1689 2053
@@ -2774,19 +3138,27 @@ static int alc_build_pcms(struct hda_codec *codec)
2774 return 0; 3138 return 0;
2775} 3139}
2776 3140
3141static void alc_free_kctls(struct hda_codec *codec)
3142{
3143 struct alc_spec *spec = codec->spec;
3144
3145 if (spec->kctls.list) {
3146 struct snd_kcontrol_new *kctl = spec->kctls.list;
3147 int i;
3148 for (i = 0; i < spec->kctls.used; i++)
3149 kfree(kctl[i].name);
3150 }
3151 snd_array_free(&spec->kctls);
3152}
3153
2777static void alc_free(struct hda_codec *codec) 3154static void alc_free(struct hda_codec *codec)
2778{ 3155{
2779 struct alc_spec *spec = codec->spec; 3156 struct alc_spec *spec = codec->spec;
2780 unsigned int i;
2781 3157
2782 if (!spec) 3158 if (!spec)
2783 return; 3159 return;
2784 3160
2785 if (spec->kctl_alloc) { 3161 alc_free_kctls(codec);
2786 for (i = 0; i < spec->num_kctl_used; i++)
2787 kfree(spec->kctl_alloc[i].name);
2788 kfree(spec->kctl_alloc);
2789 }
2790 kfree(spec); 3162 kfree(spec);
2791 codec->spec = NULL; /* to be sure */ 3163 codec->spec = NULL; /* to be sure */
2792} 3164}
@@ -3268,6 +3640,8 @@ static struct alc_config_preset alc880_presets[] = {
3268 alc880_gpio2_init_verbs }, 3640 alc880_gpio2_init_verbs },
3269 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 3641 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3270 .dac_nids = alc880_dac_nids, 3642 .dac_nids = alc880_dac_nids,
3643 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
3644 .num_adc_nids = 1, /* single ADC */
3271 .hp_nid = 0x03, 3645 .hp_nid = 0x03,
3272 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 3646 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3273 .channel_mode = alc880_2_jack_modes, 3647 .channel_mode = alc880_2_jack_modes,
@@ -3532,9 +3906,6 @@ static struct alc_config_preset alc880_presets[] = {
3532 * Automatic parse of I/O pins from the BIOS configuration 3906 * Automatic parse of I/O pins from the BIOS configuration
3533 */ 3907 */
3534 3908
3535#define NUM_CONTROL_ALLOC 32
3536#define NUM_VERB_ALLOC 32
3537
3538enum { 3909enum {
3539 ALC_CTL_WIDGET_VOL, 3910 ALC_CTL_WIDGET_VOL,
3540 ALC_CTL_WIDGET_MUTE, 3911 ALC_CTL_WIDGET_MUTE,
@@ -3552,29 +3923,15 @@ static int add_control(struct alc_spec *spec, int type, const char *name,
3552{ 3923{
3553 struct snd_kcontrol_new *knew; 3924 struct snd_kcontrol_new *knew;
3554 3925
3555 if (spec->num_kctl_used >= spec->num_kctl_alloc) { 3926 snd_array_init(&spec->kctls, sizeof(*knew), 32);
3556 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC; 3927 knew = snd_array_new(&spec->kctls);
3557 3928 if (!knew)
3558 /* array + terminator */ 3929 return -ENOMEM;
3559 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
3560 if (!knew)
3561 return -ENOMEM;
3562 if (spec->kctl_alloc) {
3563 memcpy(knew, spec->kctl_alloc,
3564 sizeof(*knew) * spec->num_kctl_alloc);
3565 kfree(spec->kctl_alloc);
3566 }
3567 spec->kctl_alloc = knew;
3568 spec->num_kctl_alloc = num;
3569 }
3570
3571 knew = &spec->kctl_alloc[spec->num_kctl_used];
3572 *knew = alc880_control_templates[type]; 3930 *knew = alc880_control_templates[type];
3573 knew->name = kstrdup(name, GFP_KERNEL); 3931 knew->name = kstrdup(name, GFP_KERNEL);
3574 if (!knew->name) 3932 if (!knew->name)
3575 return -ENOMEM; 3933 return -ENOMEM;
3576 knew->private_value = val; 3934 knew->private_value = val;
3577 spec->num_kctl_used++;
3578 return 0; 3935 return 0;
3579} 3936}
3580 3937
@@ -3898,10 +4255,10 @@ static int alc880_parse_auto_config(struct hda_codec *codec)
3898 if (spec->autocfg.dig_in_pin) 4255 if (spec->autocfg.dig_in_pin)
3899 spec->dig_in_nid = ALC880_DIGIN_NID; 4256 spec->dig_in_nid = ALC880_DIGIN_NID;
3900 4257
3901 if (spec->kctl_alloc) 4258 if (spec->kctls.list)
3902 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 4259 add_mixer(spec, spec->kctls.list);
3903 4260
3904 spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs; 4261 add_verb(spec, alc880_volume_init_verbs);
3905 4262
3906 spec->num_mux_defs = 1; 4263 spec->num_mux_defs = 1;
3907 spec->input_mux = &spec->private_imux; 4264 spec->input_mux = &spec->private_imux;
@@ -3925,6 +4282,17 @@ static void alc880_auto_init(struct hda_codec *codec)
3925 * OK, here we have finally the patch for ALC880 4282 * OK, here we have finally the patch for ALC880
3926 */ 4283 */
3927 4284
4285static void set_capture_mixer(struct alc_spec *spec)
4286{
4287 static struct snd_kcontrol_new *caps[3] = {
4288 alc_capture_mixer1,
4289 alc_capture_mixer2,
4290 alc_capture_mixer3,
4291 };
4292 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3)
4293 spec->cap_mixer = caps[spec->num_adc_nids - 1];
4294}
4295
3928static int patch_alc880(struct hda_codec *codec) 4296static int patch_alc880(struct hda_codec *codec)
3929{ 4297{
3930 struct alc_spec *spec; 4298 struct alc_spec *spec;
@@ -3980,16 +4348,12 @@ static int patch_alc880(struct hda_codec *codec)
3980 if (wcap != AC_WID_AUD_IN) { 4348 if (wcap != AC_WID_AUD_IN) {
3981 spec->adc_nids = alc880_adc_nids_alt; 4349 spec->adc_nids = alc880_adc_nids_alt;
3982 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt); 4350 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
3983 spec->mixers[spec->num_mixers] =
3984 alc880_capture_alt_mixer;
3985 spec->num_mixers++;
3986 } else { 4351 } else {
3987 spec->adc_nids = alc880_adc_nids; 4352 spec->adc_nids = alc880_adc_nids;
3988 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids); 4353 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3989 spec->mixers[spec->num_mixers] = alc880_capture_mixer;
3990 spec->num_mixers++;
3991 } 4354 }
3992 } 4355 }
4356 set_capture_mixer(spec);
3993 4357
3994 spec->vmaster_nid = 0x0c; 4358 spec->vmaster_nid = 0x0c;
3995 4359
@@ -4000,6 +4364,7 @@ static int patch_alc880(struct hda_codec *codec)
4000 if (!spec->loopback.amplist) 4364 if (!spec->loopback.amplist)
4001 spec->loopback.amplist = alc880_loopbacks; 4365 spec->loopback.amplist = alc880_loopbacks;
4002#endif 4366#endif
4367 codec->proc_widget_hook = print_realtek_coef;
4003 4368
4004 return 0; 4369 return 0;
4005} 4370}
@@ -4024,11 +4389,6 @@ static hda_nid_t alc260_adc_nids_alt[1] = {
4024 0x05, 4389 0x05,
4025}; 4390};
4026 4391
4027static hda_nid_t alc260_hp_adc_nids[2] = {
4028 /* ADC1, 0 */
4029 0x05, 0x04
4030};
4031
4032/* NIDs used when simultaneous access to both ADCs makes sense. Note that 4392/* NIDs used when simultaneous access to both ADCs makes sense. Note that
4033 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC. 4393 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
4034 */ 4394 */
@@ -4157,13 +4517,13 @@ static void alc260_hp_master_update(struct hda_codec *codec,
4157 struct alc_spec *spec = codec->spec; 4517 struct alc_spec *spec = codec->spec;
4158 unsigned int val = spec->master_sw ? PIN_HP : 0; 4518 unsigned int val = spec->master_sw ? PIN_HP : 0;
4159 /* change HP and line-out pins */ 4519 /* change HP and line-out pins */
4160 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 4520 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4161 val); 4521 val);
4162 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 4522 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4163 val); 4523 val);
4164 /* mono (speaker) depending on the HP jack sense */ 4524 /* mono (speaker) depending on the HP jack sense */
4165 val = (val && !spec->jack_present) ? PIN_OUT : 0; 4525 val = (val && !spec->jack_present) ? PIN_OUT : 0;
4166 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 4526 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4167 val); 4527 val);
4168} 4528}
4169 4529
@@ -4242,7 +4602,7 @@ static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
4242 .info = snd_ctl_boolean_mono_info, 4602 .info = snd_ctl_boolean_mono_info,
4243 .get = alc260_hp_master_sw_get, 4603 .get = alc260_hp_master_sw_get,
4244 .put = alc260_hp_master_sw_put, 4604 .put = alc260_hp_master_sw_put,
4245 .private_value = (0x10 << 16) | (0x15 << 8) | 0x11 4605 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
4246 }, 4606 },
4247 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT), 4607 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4248 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT), 4608 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
@@ -4295,7 +4655,7 @@ static void alc260_hp_3013_automute(struct hda_codec *codec)
4295 present = snd_hda_codec_read(codec, 0x15, 0, 4655 present = snd_hda_codec_read(codec, 0x15, 0,
4296 AC_VERB_GET_PIN_SENSE, 0); 4656 AC_VERB_GET_PIN_SENSE, 0);
4297 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0; 4657 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4298 alc260_hp_master_update(codec, 0x10, 0x15, 0x11); 4658 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
4299} 4659}
4300 4660
4301static void alc260_hp_3013_unsol_event(struct hda_codec *codec, 4661static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
@@ -4427,45 +4787,6 @@ static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
4427 { } /* end */ 4787 { } /* end */
4428}; 4788};
4429 4789
4430/* capture mixer elements */
4431static struct snd_kcontrol_new alc260_capture_mixer[] = {
4432 HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
4433 HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
4434 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
4435 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
4436 {
4437 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4438 /* The multiple "Capture Source" controls confuse alsamixer
4439 * So call somewhat different..
4440 */
4441 /* .name = "Capture Source", */
4442 .name = "Input Source",
4443 .count = 2,
4444 .info = alc_mux_enum_info,
4445 .get = alc_mux_enum_get,
4446 .put = alc_mux_enum_put,
4447 },
4448 { } /* end */
4449};
4450
4451static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
4452 HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
4453 HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
4454 {
4455 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4456 /* The multiple "Capture Source" controls confuse alsamixer
4457 * So call somewhat different..
4458 */
4459 /* .name = "Capture Source", */
4460 .name = "Input Source",
4461 .count = 1,
4462 .info = alc_mux_enum_info,
4463 .get = alc_mux_enum_get,
4464 .put = alc_mux_enum_put,
4465 },
4466 { } /* end */
4467};
4468
4469/* 4790/*
4470 * initialization verbs 4791 * initialization verbs
4471 */ 4792 */
@@ -5282,7 +5603,6 @@ static struct hda_verb alc260_volume_init_verbs[] = {
5282static int alc260_parse_auto_config(struct hda_codec *codec) 5603static int alc260_parse_auto_config(struct hda_codec *codec)
5283{ 5604{
5284 struct alc_spec *spec = codec->spec; 5605 struct alc_spec *spec = codec->spec;
5285 unsigned int wcap;
5286 int err; 5606 int err;
5287 static hda_nid_t alc260_ignore[] = { 0x17, 0 }; 5607 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
5288 5608
@@ -5293,7 +5613,7 @@ static int alc260_parse_auto_config(struct hda_codec *codec)
5293 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg); 5613 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
5294 if (err < 0) 5614 if (err < 0)
5295 return err; 5615 return err;
5296 if (!spec->kctl_alloc) 5616 if (!spec->kctls.list)
5297 return 0; /* can't find valid BIOS pin config */ 5617 return 0; /* can't find valid BIOS pin config */
5298 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg); 5618 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
5299 if (err < 0) 5619 if (err < 0)
@@ -5303,28 +5623,14 @@ static int alc260_parse_auto_config(struct hda_codec *codec)
5303 5623
5304 if (spec->autocfg.dig_out_pin) 5624 if (spec->autocfg.dig_out_pin)
5305 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID; 5625 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
5306 if (spec->kctl_alloc) 5626 if (spec->kctls.list)
5307 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 5627 add_mixer(spec, spec->kctls.list);
5308 5628
5309 spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs; 5629 add_verb(spec, alc260_volume_init_verbs);
5310 5630
5311 spec->num_mux_defs = 1; 5631 spec->num_mux_defs = 1;
5312 spec->input_mux = &spec->private_imux; 5632 spec->input_mux = &spec->private_imux;
5313 5633
5314 /* check whether NID 0x04 is valid */
5315 wcap = get_wcaps(codec, 0x04);
5316 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
5317 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
5318 spec->adc_nids = alc260_adc_nids_alt;
5319 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
5320 spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
5321 } else {
5322 spec->adc_nids = alc260_adc_nids;
5323 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
5324 spec->mixers[spec->num_mixers] = alc260_capture_mixer;
5325 }
5326 spec->num_mixers++;
5327
5328 store_pin_configs(codec); 5634 store_pin_configs(codec);
5329 return 1; 5635 return 1;
5330} 5636}
@@ -5394,12 +5700,11 @@ static struct alc_config_preset alc260_presets[] = {
5394 [ALC260_BASIC] = { 5700 [ALC260_BASIC] = {
5395 .mixers = { alc260_base_output_mixer, 5701 .mixers = { alc260_base_output_mixer,
5396 alc260_input_mixer, 5702 alc260_input_mixer,
5397 alc260_pc_beep_mixer, 5703 alc260_pc_beep_mixer },
5398 alc260_capture_mixer },
5399 .init_verbs = { alc260_init_verbs }, 5704 .init_verbs = { alc260_init_verbs },
5400 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 5705 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5401 .dac_nids = alc260_dac_nids, 5706 .dac_nids = alc260_dac_nids,
5402 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), 5707 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5403 .adc_nids = alc260_adc_nids, 5708 .adc_nids = alc260_adc_nids,
5404 .num_channel_mode = ARRAY_SIZE(alc260_modes), 5709 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5405 .channel_mode = alc260_modes, 5710 .channel_mode = alc260_modes,
@@ -5407,14 +5712,13 @@ static struct alc_config_preset alc260_presets[] = {
5407 }, 5712 },
5408 [ALC260_HP] = { 5713 [ALC260_HP] = {
5409 .mixers = { alc260_hp_output_mixer, 5714 .mixers = { alc260_hp_output_mixer,
5410 alc260_input_mixer, 5715 alc260_input_mixer },
5411 alc260_capture_alt_mixer },
5412 .init_verbs = { alc260_init_verbs, 5716 .init_verbs = { alc260_init_verbs,
5413 alc260_hp_unsol_verbs }, 5717 alc260_hp_unsol_verbs },
5414 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 5718 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5415 .dac_nids = alc260_dac_nids, 5719 .dac_nids = alc260_dac_nids,
5416 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids), 5720 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5417 .adc_nids = alc260_hp_adc_nids, 5721 .adc_nids = alc260_adc_nids_alt,
5418 .num_channel_mode = ARRAY_SIZE(alc260_modes), 5722 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5419 .channel_mode = alc260_modes, 5723 .channel_mode = alc260_modes,
5420 .input_mux = &alc260_capture_source, 5724 .input_mux = &alc260_capture_source,
@@ -5423,14 +5727,13 @@ static struct alc_config_preset alc260_presets[] = {
5423 }, 5727 },
5424 [ALC260_HP_DC7600] = { 5728 [ALC260_HP_DC7600] = {
5425 .mixers = { alc260_hp_dc7600_mixer, 5729 .mixers = { alc260_hp_dc7600_mixer,
5426 alc260_input_mixer, 5730 alc260_input_mixer },
5427 alc260_capture_alt_mixer },
5428 .init_verbs = { alc260_init_verbs, 5731 .init_verbs = { alc260_init_verbs,
5429 alc260_hp_dc7600_verbs }, 5732 alc260_hp_dc7600_verbs },
5430 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 5733 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5431 .dac_nids = alc260_dac_nids, 5734 .dac_nids = alc260_dac_nids,
5432 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids), 5735 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5433 .adc_nids = alc260_hp_adc_nids, 5736 .adc_nids = alc260_adc_nids_alt,
5434 .num_channel_mode = ARRAY_SIZE(alc260_modes), 5737 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5435 .channel_mode = alc260_modes, 5738 .channel_mode = alc260_modes,
5436 .input_mux = &alc260_capture_source, 5739 .input_mux = &alc260_capture_source,
@@ -5439,14 +5742,13 @@ static struct alc_config_preset alc260_presets[] = {
5439 }, 5742 },
5440 [ALC260_HP_3013] = { 5743 [ALC260_HP_3013] = {
5441 .mixers = { alc260_hp_3013_mixer, 5744 .mixers = { alc260_hp_3013_mixer,
5442 alc260_input_mixer, 5745 alc260_input_mixer },
5443 alc260_capture_alt_mixer },
5444 .init_verbs = { alc260_hp_3013_init_verbs, 5746 .init_verbs = { alc260_hp_3013_init_verbs,
5445 alc260_hp_3013_unsol_verbs }, 5747 alc260_hp_3013_unsol_verbs },
5446 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 5748 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5447 .dac_nids = alc260_dac_nids, 5749 .dac_nids = alc260_dac_nids,
5448 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids), 5750 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5449 .adc_nids = alc260_hp_adc_nids, 5751 .adc_nids = alc260_adc_nids_alt,
5450 .num_channel_mode = ARRAY_SIZE(alc260_modes), 5752 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5451 .channel_mode = alc260_modes, 5753 .channel_mode = alc260_modes,
5452 .input_mux = &alc260_capture_source, 5754 .input_mux = &alc260_capture_source,
@@ -5454,8 +5756,7 @@ static struct alc_config_preset alc260_presets[] = {
5454 .init_hook = alc260_hp_3013_automute, 5756 .init_hook = alc260_hp_3013_automute,
5455 }, 5757 },
5456 [ALC260_FUJITSU_S702X] = { 5758 [ALC260_FUJITSU_S702X] = {
5457 .mixers = { alc260_fujitsu_mixer, 5759 .mixers = { alc260_fujitsu_mixer },
5458 alc260_capture_mixer },
5459 .init_verbs = { alc260_fujitsu_init_verbs }, 5760 .init_verbs = { alc260_fujitsu_init_verbs },
5460 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 5761 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5461 .dac_nids = alc260_dac_nids, 5762 .dac_nids = alc260_dac_nids,
@@ -5467,8 +5768,7 @@ static struct alc_config_preset alc260_presets[] = {
5467 .input_mux = alc260_fujitsu_capture_sources, 5768 .input_mux = alc260_fujitsu_capture_sources,
5468 }, 5769 },
5469 [ALC260_ACER] = { 5770 [ALC260_ACER] = {
5470 .mixers = { alc260_acer_mixer, 5771 .mixers = { alc260_acer_mixer },
5471 alc260_capture_mixer },
5472 .init_verbs = { alc260_acer_init_verbs }, 5772 .init_verbs = { alc260_acer_init_verbs },
5473 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 5773 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5474 .dac_nids = alc260_dac_nids, 5774 .dac_nids = alc260_dac_nids,
@@ -5480,8 +5780,7 @@ static struct alc_config_preset alc260_presets[] = {
5480 .input_mux = alc260_acer_capture_sources, 5780 .input_mux = alc260_acer_capture_sources,
5481 }, 5781 },
5482 [ALC260_WILL] = { 5782 [ALC260_WILL] = {
5483 .mixers = { alc260_will_mixer, 5783 .mixers = { alc260_will_mixer },
5484 alc260_capture_mixer },
5485 .init_verbs = { alc260_init_verbs, alc260_will_verbs }, 5784 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
5486 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 5785 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5487 .dac_nids = alc260_dac_nids, 5786 .dac_nids = alc260_dac_nids,
@@ -5493,8 +5792,7 @@ static struct alc_config_preset alc260_presets[] = {
5493 .input_mux = &alc260_capture_source, 5792 .input_mux = &alc260_capture_source,
5494 }, 5793 },
5495 [ALC260_REPLACER_672V] = { 5794 [ALC260_REPLACER_672V] = {
5496 .mixers = { alc260_replacer_672v_mixer, 5795 .mixers = { alc260_replacer_672v_mixer },
5497 alc260_capture_mixer },
5498 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs }, 5796 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
5499 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 5797 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5500 .dac_nids = alc260_dac_nids, 5798 .dac_nids = alc260_dac_nids,
@@ -5509,8 +5807,7 @@ static struct alc_config_preset alc260_presets[] = {
5509 }, 5807 },
5510#ifdef CONFIG_SND_DEBUG 5808#ifdef CONFIG_SND_DEBUG
5511 [ALC260_TEST] = { 5809 [ALC260_TEST] = {
5512 .mixers = { alc260_test_mixer, 5810 .mixers = { alc260_test_mixer },
5513 alc260_capture_mixer },
5514 .init_verbs = { alc260_test_init_verbs }, 5811 .init_verbs = { alc260_test_init_verbs },
5515 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids), 5812 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
5516 .dac_nids = alc260_test_dac_nids, 5813 .dac_nids = alc260_test_dac_nids,
@@ -5569,6 +5866,21 @@ static int patch_alc260(struct hda_codec *codec)
5569 spec->stream_digital_playback = &alc260_pcm_digital_playback; 5866 spec->stream_digital_playback = &alc260_pcm_digital_playback;
5570 spec->stream_digital_capture = &alc260_pcm_digital_capture; 5867 spec->stream_digital_capture = &alc260_pcm_digital_capture;
5571 5868
5869 if (!spec->adc_nids && spec->input_mux) {
5870 /* check whether NID 0x04 is valid */
5871 unsigned int wcap = get_wcaps(codec, 0x04);
5872 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
5873 /* get type */
5874 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
5875 spec->adc_nids = alc260_adc_nids_alt;
5876 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
5877 } else {
5878 spec->adc_nids = alc260_adc_nids;
5879 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
5880 }
5881 }
5882 set_capture_mixer(spec);
5883
5572 spec->vmaster_nid = 0x08; 5884 spec->vmaster_nid = 0x08;
5573 5885
5574 codec->patch_ops = alc_patch_ops; 5886 codec->patch_ops = alc_patch_ops;
@@ -5578,6 +5890,7 @@ static int patch_alc260(struct hda_codec *codec)
5578 if (!spec->loopback.amplist) 5890 if (!spec->loopback.amplist)
5579 spec->loopback.amplist = alc260_loopbacks; 5891 spec->loopback.amplist = alc260_loopbacks;
5580#endif 5892#endif
5893 codec->proc_widget_hook = print_realtek_coef;
5581 5894
5582 return 0; 5895 return 0;
5583} 5896}
@@ -5625,36 +5938,6 @@ static struct hda_input_mux alc882_capture_source = {
5625 { "CD", 0x4 }, 5938 { "CD", 0x4 },
5626 }, 5939 },
5627}; 5940};
5628#define alc882_mux_enum_info alc_mux_enum_info
5629#define alc882_mux_enum_get alc_mux_enum_get
5630
5631static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
5632 struct snd_ctl_elem_value *ucontrol)
5633{
5634 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5635 struct alc_spec *spec = codec->spec;
5636 const struct hda_input_mux *imux = spec->input_mux;
5637 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
5638 hda_nid_t nid = spec->capsrc_nids ?
5639 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
5640 unsigned int *cur_val = &spec->cur_mux[adc_idx];
5641 unsigned int i, idx;
5642
5643 idx = ucontrol->value.enumerated.item[0];
5644 if (idx >= imux->num_items)
5645 idx = imux->num_items - 1;
5646 if (*cur_val == idx)
5647 return 0;
5648 for (i = 0; i < imux->num_items; i++) {
5649 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
5650 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
5651 imux->items[i].index,
5652 HDA_AMP_MUTE, v);
5653 }
5654 *cur_val = idx;
5655 return 1;
5656}
5657
5658/* 5941/*
5659 * 2ch mode 5942 * 2ch mode
5660 */ 5943 */
@@ -6337,49 +6620,6 @@ static struct hda_verb alc882_auto_init_verbs[] = {
6337 { } 6620 { }
6338}; 6621};
6339 6622
6340/* capture mixer elements */
6341static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
6342 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6343 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6344 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6345 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6346 {
6347 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6348 /* The multiple "Capture Source" controls confuse alsamixer
6349 * So call somewhat different..
6350 */
6351 /* .name = "Capture Source", */
6352 .name = "Input Source",
6353 .count = 2,
6354 .info = alc882_mux_enum_info,
6355 .get = alc882_mux_enum_get,
6356 .put = alc882_mux_enum_put,
6357 },
6358 { } /* end */
6359};
6360
6361static struct snd_kcontrol_new alc882_capture_mixer[] = {
6362 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
6363 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
6364 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
6365 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
6366 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
6367 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
6368 {
6369 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6370 /* The multiple "Capture Source" controls confuse alsamixer
6371 * So call somewhat different..
6372 */
6373 /* .name = "Capture Source", */
6374 .name = "Input Source",
6375 .count = 3,
6376 .info = alc882_mux_enum_info,
6377 .get = alc882_mux_enum_get,
6378 .put = alc882_mux_enum_put,
6379 },
6380 { } /* end */
6381};
6382
6383#ifdef CONFIG_SND_HDA_POWER_SAVE 6623#ifdef CONFIG_SND_HDA_POWER_SAVE
6384#define alc882_loopbacks alc880_loopbacks 6624#define alc882_loopbacks alc880_loopbacks
6385#endif 6625#endif
@@ -6508,8 +6748,7 @@ static struct alc_config_preset alc882_presets[] = {
6508 .init_hook = alc885_imac24_init_hook, 6748 .init_hook = alc885_imac24_init_hook,
6509 }, 6749 },
6510 [ALC882_TARGA] = { 6750 [ALC882_TARGA] = {
6511 .mixers = { alc882_targa_mixer, alc882_chmode_mixer, 6751 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
6512 alc882_capture_mixer },
6513 .init_verbs = { alc882_init_verbs, alc882_targa_verbs}, 6752 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
6514 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 6753 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6515 .dac_nids = alc882_dac_nids, 6754 .dac_nids = alc882_dac_nids,
@@ -6525,8 +6764,7 @@ static struct alc_config_preset alc882_presets[] = {
6525 .init_hook = alc882_targa_automute, 6764 .init_hook = alc882_targa_automute,
6526 }, 6765 },
6527 [ALC882_ASUS_A7J] = { 6766 [ALC882_ASUS_A7J] = {
6528 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer, 6767 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
6529 alc882_capture_mixer },
6530 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs}, 6768 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
6531 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 6769 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6532 .dac_nids = alc882_dac_nids, 6770 .dac_nids = alc882_dac_nids,
@@ -6831,6 +7069,7 @@ static int patch_alc882(struct hda_codec *codec)
6831 spec->stream_digital_playback = &alc882_pcm_digital_playback; 7069 spec->stream_digital_playback = &alc882_pcm_digital_playback;
6832 spec->stream_digital_capture = &alc882_pcm_digital_capture; 7070 spec->stream_digital_capture = &alc882_pcm_digital_capture;
6833 7071
7072 spec->is_mix_capture = 1; /* matrix-style capture */
6834 if (!spec->adc_nids && spec->input_mux) { 7073 if (!spec->adc_nids && spec->input_mux) {
6835 /* check whether NID 0x07 is valid */ 7074 /* check whether NID 0x07 is valid */
6836 unsigned int wcap = get_wcaps(codec, 0x07); 7075 unsigned int wcap = get_wcaps(codec, 0x07);
@@ -6840,17 +7079,13 @@ static int patch_alc882(struct hda_codec *codec)
6840 spec->adc_nids = alc882_adc_nids_alt; 7079 spec->adc_nids = alc882_adc_nids_alt;
6841 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt); 7080 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
6842 spec->capsrc_nids = alc882_capsrc_nids_alt; 7081 spec->capsrc_nids = alc882_capsrc_nids_alt;
6843 spec->mixers[spec->num_mixers] =
6844 alc882_capture_alt_mixer;
6845 spec->num_mixers++;
6846 } else { 7082 } else {
6847 spec->adc_nids = alc882_adc_nids; 7083 spec->adc_nids = alc882_adc_nids;
6848 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids); 7084 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
6849 spec->capsrc_nids = alc882_capsrc_nids; 7085 spec->capsrc_nids = alc882_capsrc_nids;
6850 spec->mixers[spec->num_mixers] = alc882_capture_mixer;
6851 spec->num_mixers++;
6852 } 7086 }
6853 } 7087 }
7088 set_capture_mixer(spec);
6854 7089
6855 spec->vmaster_nid = 0x0c; 7090 spec->vmaster_nid = 0x0c;
6856 7091
@@ -6861,6 +7096,7 @@ static int patch_alc882(struct hda_codec *codec)
6861 if (!spec->loopback.amplist) 7096 if (!spec->loopback.amplist)
6862 spec->loopback.amplist = alc882_loopbacks; 7097 spec->loopback.amplist = alc882_loopbacks;
6863#endif 7098#endif
7099 codec->proc_widget_hook = print_realtek_coef;
6864 7100
6865 return 0; 7101 return 0;
6866} 7102}
@@ -6879,6 +7115,8 @@ static int patch_alc882(struct hda_codec *codec)
6879#define ALC883_DIGOUT_NID 0x06 7115#define ALC883_DIGOUT_NID 0x06
6880#define ALC883_DIGIN_NID 0x0a 7116#define ALC883_DIGIN_NID 0x0a
6881 7117
7118#define ALC1200_DIGOUT_NID 0x10
7119
6882static hda_nid_t alc883_dac_nids[4] = { 7120static hda_nid_t alc883_dac_nids[4] = {
6883 /* front, rear, clfe, rear_surr */ 7121 /* front, rear, clfe, rear_surr */
6884 0x02, 0x03, 0x04, 0x05 7122 0x02, 0x03, 0x04, 0x05
@@ -6889,8 +7127,20 @@ static hda_nid_t alc883_adc_nids[2] = {
6889 0x08, 0x09, 7127 0x08, 0x09,
6890}; 7128};
6891 7129
7130static hda_nid_t alc883_adc_nids_alt[1] = {
7131 /* ADC1 */
7132 0x08,
7133};
7134
7135static hda_nid_t alc883_adc_nids_rev[2] = {
7136 /* ADC2-1 */
7137 0x09, 0x08
7138};
7139
6892static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 }; 7140static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
6893 7141
7142static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7143
6894/* input MUX */ 7144/* input MUX */
6895/* FIXME: should be a matrix-type input source selection */ 7145/* FIXME: should be a matrix-type input source selection */
6896 7146
@@ -6957,11 +7207,6 @@ static struct hda_input_mux alc883_asus_eee1601_capture_source = {
6957 }, 7207 },
6958}; 7208};
6959 7209
6960#define alc883_mux_enum_info alc_mux_enum_info
6961#define alc883_mux_enum_get alc_mux_enum_get
6962/* ALC883 has the ALC882-type input selection */
6963#define alc883_mux_enum_put alc882_mux_enum_put
6964
6965/* 7210/*
6966 * 2ch mode 7211 * 2ch mode
6967 */ 7212 */
@@ -7115,19 +7360,6 @@ static struct snd_kcontrol_new alc883_base_mixer[] = {
7115 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7360 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7116 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 7361 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7117 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 7362 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7118 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7119 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7120 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7121 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7122 {
7123 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7124 /* .name = "Capture Source", */
7125 .name = "Input Source",
7126 .count = 2,
7127 .info = alc883_mux_enum_info,
7128 .get = alc883_mux_enum_get,
7129 .put = alc883_mux_enum_put,
7130 },
7131 { } /* end */ 7363 { } /* end */
7132}; 7364};
7133 7365
@@ -7145,19 +7377,6 @@ static struct snd_kcontrol_new alc883_mitac_mixer[] = {
7145 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7377 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7146 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 7378 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7147 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7379 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7148 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7149 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7150 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7151 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7152 {
7153 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7154 /* .name = "Capture Source", */
7155 .name = "Input Source",
7156 .count = 2,
7157 .info = alc883_mux_enum_info,
7158 .get = alc883_mux_enum_get,
7159 .put = alc883_mux_enum_put,
7160 },
7161 { } /* end */ 7380 { } /* end */
7162}; 7381};
7163 7382
@@ -7172,19 +7391,6 @@ static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
7172 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7391 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7173 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 7392 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7174 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7393 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7175 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7176 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7177 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7178 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7179 {
7180 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7181 /* .name = "Capture Source", */
7182 .name = "Input Source",
7183 .count = 2,
7184 .info = alc883_mux_enum_info,
7185 .get = alc883_mux_enum_get,
7186 .put = alc883_mux_enum_put,
7187 },
7188 { } /* end */ 7394 { } /* end */
7189}; 7395};
7190 7396
@@ -7199,19 +7405,6 @@ static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
7199 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7405 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7200 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 7406 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7201 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7407 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7202 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7203 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7204 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7205 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7206 {
7207 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7208 /* .name = "Capture Source", */
7209 .name = "Input Source",
7210 .count = 2,
7211 .info = alc883_mux_enum_info,
7212 .get = alc883_mux_enum_get,
7213 .put = alc883_mux_enum_put,
7214 },
7215 { } /* end */ 7408 { } /* end */
7216}; 7409};
7217 7410
@@ -7231,19 +7424,6 @@ static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
7231 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7424 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7232 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 7425 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7233 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 7426 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7234 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7235 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7236 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7237 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7238 {
7239 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7240 /* .name = "Capture Source", */
7241 .name = "Input Source",
7242 .count = 2,
7243 .info = alc883_mux_enum_info,
7244 .get = alc883_mux_enum_get,
7245 .put = alc883_mux_enum_put,
7246 },
7247 { } /* end */ 7427 { } /* end */
7248}; 7428};
7249 7429
@@ -7269,17 +7449,6 @@ static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
7269 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7449 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7270 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 7450 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7271 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 7451 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7272 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7273 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7274 {
7275 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7276 /* .name = "Capture Source", */
7277 .name = "Input Source",
7278 .count = 1,
7279 .info = alc883_mux_enum_info,
7280 .get = alc883_mux_enum_get,
7281 .put = alc883_mux_enum_put,
7282 },
7283 { } /* end */ 7452 { } /* end */
7284}; 7453};
7285 7454
@@ -7306,19 +7475,6 @@ static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
7306 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7475 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7307 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 7476 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7308 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 7477 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7309 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7310 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7311 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7312 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7313 {
7314 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7315 /* .name = "Capture Source", */
7316 .name = "Input Source",
7317 .count = 2,
7318 .info = alc883_mux_enum_info,
7319 .get = alc883_mux_enum_get,
7320 .put = alc883_mux_enum_put,
7321 },
7322 { } /* end */ 7478 { } /* end */
7323}; 7479};
7324 7480
@@ -7344,18 +7500,6 @@ static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
7344 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7500 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7345 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 7501 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7346 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 7502 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7347 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7348 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7349
7350 {
7351 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7352 /* .name = "Capture Source", */
7353 .name = "Input Source",
7354 .count = 1,
7355 .info = alc883_mux_enum_info,
7356 .get = alc883_mux_enum_get,
7357 .put = alc883_mux_enum_put,
7358 },
7359 { } /* end */ 7503 { } /* end */
7360}; 7504};
7361 7505
@@ -7376,19 +7520,6 @@ static struct snd_kcontrol_new alc883_tagra_mixer[] = {
7376 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7520 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7377 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7521 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7378 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7522 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7379 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7380 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7381 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7382 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7383 {
7384 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7385 /* .name = "Capture Source", */
7386 .name = "Input Source",
7387 .count = 2,
7388 .info = alc883_mux_enum_info,
7389 .get = alc883_mux_enum_get,
7390 .put = alc883_mux_enum_put,
7391 },
7392 { } /* end */ 7523 { } /* end */
7393}; 7524};
7394 7525
@@ -7404,19 +7535,6 @@ static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
7404 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7535 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7405 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 7536 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7406 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7537 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7407 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7408 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7409 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7410 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7411 {
7412 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7413 /* .name = "Capture Source", */
7414 .name = "Input Source",
7415 .count = 2,
7416 .info = alc883_mux_enum_info,
7417 .get = alc883_mux_enum_get,
7418 .put = alc883_mux_enum_put,
7419 },
7420 { } /* end */ 7538 { } /* end */
7421}; 7539};
7422 7540
@@ -7429,17 +7547,6 @@ static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
7429 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7547 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7430 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7548 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7431 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7549 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7432 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7433 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7434 {
7435 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7436 /* .name = "Capture Source", */
7437 .name = "Input Source",
7438 .count = 1,
7439 .info = alc883_mux_enum_info,
7440 .get = alc883_mux_enum_get,
7441 .put = alc883_mux_enum_put,
7442 },
7443 { } /* end */ 7550 { } /* end */
7444}; 7551};
7445 7552
@@ -7453,19 +7560,6 @@ static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
7453 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7560 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7454 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7561 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7455 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7562 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7456 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7457 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7458 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7459 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7460 {
7461 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7462 /* .name = "Capture Source", */
7463 .name = "Input Source",
7464 .count = 2,
7465 .info = alc883_mux_enum_info,
7466 .get = alc883_mux_enum_get,
7467 .put = alc883_mux_enum_put,
7468 },
7469 { } /* end */ 7563 { } /* end */
7470}; 7564};
7471 7565
@@ -7479,19 +7573,6 @@ static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
7479 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7573 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7480 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7574 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7481 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7575 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7482 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7483 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7484 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7485 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7486 {
7487 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7488 /* .name = "Capture Source", */
7489 .name = "Input Source",
7490 .count = 2,
7491 .info = alc883_mux_enum_info,
7492 .get = alc883_mux_enum_get,
7493 .put = alc883_mux_enum_put,
7494 },
7495 { } /* end */ 7576 { } /* end */
7496}; 7577};
7497 7578
@@ -7504,19 +7585,6 @@ static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
7504 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7585 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7505 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7586 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7506 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7587 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7507 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7508 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7509 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7510 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7511 {
7512 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7513 /* .name = "Capture Source", */
7514 .name = "Input Source",
7515 .count = 2,
7516 .info = alc883_mux_enum_info,
7517 .get = alc883_mux_enum_get,
7518 .put = alc883_mux_enum_put,
7519 },
7520 { } /* end */ 7588 { } /* end */
7521}; 7589};
7522 7590
@@ -7544,19 +7612,6 @@ static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
7544 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7612 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7545 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 7613 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7546 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7614 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7547 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7548 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7549 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7550 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7551 {
7552 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7553 /* .name = "Capture Source", */
7554 .name = "Input Source",
7555 .count = 2,
7556 .info = alc883_mux_enum_info,
7557 .get = alc883_mux_enum_get,
7558 .put = alc883_mux_enum_put,
7559 },
7560 { } /* end */ 7615 { } /* end */
7561}; 7616};
7562 7617
@@ -7587,6 +7642,10 @@ static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
7587 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7642 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7588 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7643 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7589 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7644 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7645 { } /* end */
7646};
7647
7648static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
7590 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol), 7649 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
7591 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch), 7650 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
7592 { 7651 {
@@ -7594,9 +7653,9 @@ static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
7594 /* .name = "Capture Source", */ 7653 /* .name = "Capture Source", */
7595 .name = "Input Source", 7654 .name = "Input Source",
7596 .count = 1, 7655 .count = 1,
7597 .info = alc883_mux_enum_info, 7656 .info = alc_mux_enum_info,
7598 .get = alc883_mux_enum_get, 7657 .get = alc_mux_enum_get,
7599 .put = alc883_mux_enum_put, 7658 .put = alc_mux_enum_put,
7600 }, 7659 },
7601 { } /* end */ 7660 { } /* end */
7602}; 7661};
@@ -8251,27 +8310,6 @@ static struct hda_verb alc883_auto_init_verbs[] = {
8251 { } 8310 { }
8252}; 8311};
8253 8312
8254/* capture mixer elements */
8255static struct snd_kcontrol_new alc883_capture_mixer[] = {
8256 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8257 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8258 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
8259 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
8260 {
8261 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8262 /* The multiple "Capture Source" controls confuse alsamixer
8263 * So call somewhat different..
8264 */
8265 /* .name = "Capture Source", */
8266 .name = "Input Source",
8267 .count = 2,
8268 .info = alc882_mux_enum_info,
8269 .get = alc882_mux_enum_get,
8270 .put = alc882_mux_enum_put,
8271 },
8272 { } /* end */
8273};
8274
8275static struct hda_verb alc888_asus_m90v_verbs[] = { 8313static struct hda_verb alc888_asus_m90v_verbs[] = {
8276 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8314 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8277 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8315 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
@@ -8394,6 +8432,7 @@ static const char *alc883_models[ALC883_MODEL_LAST] = {
8394 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig", 8432 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
8395 [ALC883_ACER] = "acer", 8433 [ALC883_ACER] = "acer",
8396 [ALC883_ACER_ASPIRE] = "acer-aspire", 8434 [ALC883_ACER_ASPIRE] = "acer-aspire",
8435 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
8397 [ALC883_MEDION] = "medion", 8436 [ALC883_MEDION] = "medion",
8398 [ALC883_MEDION_MD2] = "medion-md2", 8437 [ALC883_MEDION_MD2] = "medion-md2",
8399 [ALC883_LAPTOP_EAPD] = "laptop-eapd", 8438 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
@@ -8407,7 +8446,9 @@ static const char *alc883_models[ALC883_MODEL_LAST] = {
8407 [ALC883_MITAC] = "mitac", 8446 [ALC883_MITAC] = "mitac",
8408 [ALC883_CLEVO_M720] = "clevo-m720", 8447 [ALC883_CLEVO_M720] = "clevo-m720",
8409 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515", 8448 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
8449 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
8410 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel", 8450 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
8451 [ALC1200_ASUS_P5Q] = "asus-p5q",
8411 [ALC883_AUTO] = "auto", 8452 [ALC883_AUTO] = "auto",
8412}; 8453};
8413 8454
@@ -8418,6 +8459,8 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
8418 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE), 8459 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
8419 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE), 8460 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
8420 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE), 8461 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
8462 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
8463 ALC888_ACER_ASPIRE_4930G),
8421 SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */ 8464 SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
8422 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL), 8465 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
8423 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG), 8466 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
@@ -8426,6 +8469,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
8426 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG), 8469 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
8427 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V), 8470 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
8428 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG), 8471 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
8472 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
8429 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601), 8473 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
8430 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG), 8474 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
8431 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG), 8475 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
@@ -8452,6 +8496,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
8452 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG), 8496 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
8453 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG), 8497 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
8454 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG), 8498 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
8499 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
8455 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG), 8500 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
8456 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG), 8501 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
8457 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG), 8502 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
@@ -8463,6 +8508,8 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
8463 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch), 8508 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
8464 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION), 8509 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
8465 SND_PCI_QUIRK(0x1734, 0x1108, "Fujitsu AMILO Pi2515", ALC883_FUJITSU_PI2515), 8510 SND_PCI_QUIRK(0x1734, 0x1108, "Fujitsu AMILO Pi2515", ALC883_FUJITSU_PI2515),
8511 SND_PCI_QUIRK(0x1734, 0x113d, "Fujitsu AMILO Xa3530",
8512 ALC888_FUJITSU_XA3530),
8466 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch), 8513 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
8467 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763), 8514 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8468 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763), 8515 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
@@ -8553,6 +8600,8 @@ static struct alc_config_preset alc883_presets[] = {
8553 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs}, 8600 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8554 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8601 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8555 .dac_nids = alc883_dac_nids, 8602 .dac_nids = alc883_dac_nids,
8603 .adc_nids = alc883_adc_nids_alt,
8604 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8556 .dig_out_nid = ALC883_DIGOUT_NID, 8605 .dig_out_nid = ALC883_DIGOUT_NID,
8557 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 8606 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8558 .channel_mode = alc883_3ST_2ch_modes, 8607 .channel_mode = alc883_3ST_2ch_modes,
@@ -8586,6 +8635,26 @@ static struct alc_config_preset alc883_presets[] = {
8586 .unsol_event = alc883_acer_aspire_unsol_event, 8635 .unsol_event = alc883_acer_aspire_unsol_event,
8587 .init_hook = alc883_acer_aspire_automute, 8636 .init_hook = alc883_acer_aspire_automute,
8588 }, 8637 },
8638 [ALC888_ACER_ASPIRE_4930G] = {
8639 .mixers = { alc888_base_mixer,
8640 alc883_chmode_mixer },
8641 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
8642 alc888_acer_aspire_4930g_verbs },
8643 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8644 .dac_nids = alc883_dac_nids,
8645 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
8646 .adc_nids = alc883_adc_nids_rev,
8647 .capsrc_nids = alc883_capsrc_nids_rev,
8648 .dig_out_nid = ALC883_DIGOUT_NID,
8649 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8650 .channel_mode = alc883_3ST_6ch_modes,
8651 .need_dac_fix = 1,
8652 .num_mux_defs =
8653 ARRAY_SIZE(alc888_2_capture_sources),
8654 .input_mux = alc888_2_capture_sources,
8655 .unsol_event = alc888_acer_aspire_4930g_unsol_event,
8656 .init_hook = alc888_acer_aspire_4930g_automute,
8657 },
8589 [ALC883_MEDION] = { 8658 [ALC883_MEDION] = {
8590 .mixers = { alc883_fivestack_mixer, 8659 .mixers = { alc883_fivestack_mixer,
8591 alc883_chmode_mixer }, 8660 alc883_chmode_mixer },
@@ -8593,6 +8662,8 @@ static struct alc_config_preset alc883_presets[] = {
8593 alc883_medion_eapd_verbs }, 8662 alc883_medion_eapd_verbs },
8594 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8663 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8595 .dac_nids = alc883_dac_nids, 8664 .dac_nids = alc883_dac_nids,
8665 .adc_nids = alc883_adc_nids_alt,
8666 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8596 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 8667 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8597 .channel_mode = alc883_sixstack_modes, 8668 .channel_mode = alc883_sixstack_modes,
8598 .input_mux = &alc883_capture_source, 8669 .input_mux = &alc883_capture_source,
@@ -8635,6 +8706,8 @@ static struct alc_config_preset alc883_presets[] = {
8635 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs}, 8706 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
8636 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8707 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8637 .dac_nids = alc883_dac_nids, 8708 .dac_nids = alc883_dac_nids,
8709 .adc_nids = alc883_adc_nids_alt,
8710 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8638 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 8711 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8639 .channel_mode = alc883_3ST_2ch_modes, 8712 .channel_mode = alc883_3ST_2ch_modes,
8640 .input_mux = &alc883_lenovo_101e_capture_source, 8713 .input_mux = &alc883_lenovo_101e_capture_source,
@@ -8725,14 +8798,30 @@ static struct alc_config_preset alc883_presets[] = {
8725 .unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event, 8798 .unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event,
8726 .init_hook = alc883_2ch_fujitsu_pi2515_automute, 8799 .init_hook = alc883_2ch_fujitsu_pi2515_automute,
8727 }, 8800 },
8801 [ALC888_FUJITSU_XA3530] = {
8802 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
8803 .init_verbs = { alc883_init_verbs,
8804 alc888_fujitsu_xa3530_verbs },
8805 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8806 .dac_nids = alc883_dac_nids,
8807 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
8808 .adc_nids = alc883_adc_nids_rev,
8809 .capsrc_nids = alc883_capsrc_nids_rev,
8810 .dig_out_nid = ALC883_DIGOUT_NID,
8811 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
8812 .channel_mode = alc888_4ST_8ch_intel_modes,
8813 .num_mux_defs =
8814 ARRAY_SIZE(alc888_2_capture_sources),
8815 .input_mux = alc888_2_capture_sources,
8816 .unsol_event = alc888_fujitsu_xa3530_unsol_event,
8817 .init_hook = alc888_fujitsu_xa3530_automute,
8818 },
8728 [ALC888_LENOVO_SKY] = { 8819 [ALC888_LENOVO_SKY] = {
8729 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer }, 8820 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
8730 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs}, 8821 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
8731 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8822 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8732 .dac_nids = alc883_dac_nids, 8823 .dac_nids = alc883_dac_nids,
8733 .dig_out_nid = ALC883_DIGOUT_NID, 8824 .dig_out_nid = ALC883_DIGOUT_NID,
8734 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
8735 .adc_nids = alc883_adc_nids,
8736 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 8825 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8737 .channel_mode = alc883_sixstack_modes, 8826 .channel_mode = alc883_sixstack_modes,
8738 .need_dac_fix = 1, 8827 .need_dac_fix = 1,
@@ -8756,6 +8845,7 @@ static struct alc_config_preset alc883_presets[] = {
8756 }, 8845 },
8757 [ALC888_ASUS_EEE1601] = { 8846 [ALC888_ASUS_EEE1601] = {
8758 .mixers = { alc883_asus_eee1601_mixer }, 8847 .mixers = { alc883_asus_eee1601_mixer },
8848 .cap_mixer = alc883_asus_eee1601_cap_mixer,
8759 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs }, 8849 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
8760 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8850 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8761 .dac_nids = alc883_dac_nids, 8851 .dac_nids = alc883_dac_nids,
@@ -8768,6 +8858,17 @@ static struct alc_config_preset alc883_presets[] = {
8768 .unsol_event = alc883_eee1601_unsol_event, 8858 .unsol_event = alc883_eee1601_unsol_event,
8769 .init_hook = alc883_eee1601_inithook, 8859 .init_hook = alc883_eee1601_inithook,
8770 }, 8860 },
8861 [ALC1200_ASUS_P5Q] = {
8862 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8863 .init_verbs = { alc883_init_verbs },
8864 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8865 .dac_nids = alc883_dac_nids,
8866 .dig_out_nid = ALC1200_DIGOUT_NID,
8867 .dig_in_nid = ALC883_DIGIN_NID,
8868 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8869 .channel_mode = alc883_sixstack_modes,
8870 .input_mux = &alc883_capture_source,
8871 },
8771}; 8872};
8772 8873
8773 8874
@@ -8862,8 +8963,6 @@ static int alc883_parse_auto_config(struct hda_codec *codec)
8862 8963
8863 /* hack - override the init verbs */ 8964 /* hack - override the init verbs */
8864 spec->init_verbs[0] = alc883_auto_init_verbs; 8965 spec->init_verbs[0] = alc883_auto_init_verbs;
8865 spec->mixers[spec->num_mixers] = alc883_capture_mixer;
8866 spec->num_mixers++;
8867 8966
8868 return 1; /* config found */ 8967 return 1; /* config found */
8869} 8968}
@@ -8946,9 +9045,15 @@ static int patch_alc883(struct hda_codec *codec)
8946 spec->stream_digital_playback = &alc883_pcm_digital_playback; 9045 spec->stream_digital_playback = &alc883_pcm_digital_playback;
8947 spec->stream_digital_capture = &alc883_pcm_digital_capture; 9046 spec->stream_digital_capture = &alc883_pcm_digital_capture;
8948 9047
8949 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids); 9048 if (!spec->num_adc_nids) {
8950 spec->adc_nids = alc883_adc_nids; 9049 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
8951 spec->capsrc_nids = alc883_capsrc_nids; 9050 spec->adc_nids = alc883_adc_nids;
9051 }
9052 if (!spec->capsrc_nids)
9053 spec->capsrc_nids = alc883_capsrc_nids;
9054 spec->is_mix_capture = 1; /* matrix-style capture */
9055 if (!spec->cap_mixer)
9056 set_capture_mixer(spec);
8952 9057
8953 spec->vmaster_nid = 0x0c; 9058 spec->vmaster_nid = 0x0c;
8954 9059
@@ -8960,6 +9065,7 @@ static int patch_alc883(struct hda_codec *codec)
8960 if (!spec->loopback.amplist) 9065 if (!spec->loopback.amplist)
8961 spec->loopback.amplist = alc883_loopbacks; 9066 spec->loopback.amplist = alc883_loopbacks;
8962#endif 9067#endif
9068 codec->proc_widget_hook = print_realtek_coef;
8963 9069
8964 return 0; 9070 return 0;
8965} 9071}
@@ -9439,20 +9545,6 @@ static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
9439 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 9545 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9440 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9546 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9441 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9547 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9442 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
9443 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
9444 {
9445 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9446 /* The multiple "Capture Source" controls confuse alsamixer
9447 * So call somewhat different..
9448 */
9449 /* .name = "Capture Source", */
9450 .name = "Input Source",
9451 .count = 1,
9452 .info = alc_mux_enum_info,
9453 .get = alc_mux_enum_get,
9454 .put = alc_mux_enum_put,
9455 },
9456 { } /* end */ 9548 { } /* end */
9457}; 9549};
9458 9550
@@ -9969,7 +10061,7 @@ static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
9969 struct alc_spec *spec = codec->spec; 10061 struct alc_spec *spec = codec->spec;
9970 int ret; 10062 int ret;
9971 10063
9972 ret = alc882_mux_enum_put(kcontrol, ucontrol); 10064 ret = alc_mux_enum_put(kcontrol, ucontrol);
9973 if (!ret) 10065 if (!ret)
9974 return 0; 10066 return 0;
9975 /* reprogram the HP pin as mic or HP according to the input source */ 10067 /* reprogram the HP pin as mic or HP according to the input source */
@@ -9986,8 +10078,8 @@ static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
9986 { 10078 {
9987 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 10079 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9988 .name = "Capture Source", 10080 .name = "Capture Source",
9989 .info = alc882_mux_enum_info, 10081 .info = alc_mux_enum_info,
9990 .get = alc882_mux_enum_get, 10082 .get = alc_mux_enum_get,
9991 .put = alc262_ultra_mux_enum_put, 10083 .put = alc262_ultra_mux_enum_put,
9992 }, 10084 },
9993 { } /* end */ 10085 { } /* end */
@@ -10380,10 +10472,10 @@ static int alc262_parse_auto_config(struct hda_codec *codec)
10380 if (spec->autocfg.dig_in_pin) 10472 if (spec->autocfg.dig_in_pin)
10381 spec->dig_in_nid = ALC262_DIGIN_NID; 10473 spec->dig_in_nid = ALC262_DIGIN_NID;
10382 10474
10383 if (spec->kctl_alloc) 10475 if (spec->kctls.list)
10384 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 10476 add_mixer(spec, spec->kctls.list);
10385 10477
10386 spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs; 10478 add_verb(spec, alc262_volume_init_verbs);
10387 spec->num_mux_defs = 1; 10479 spec->num_mux_defs = 1;
10388 spec->input_mux = &spec->private_imux; 10480 spec->input_mux = &spec->private_imux;
10389 10481
@@ -10466,6 +10558,8 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = {
10466 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD), 10558 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10467 SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD), 10559 SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10468 SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD), 10560 SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
10561 SND_PCI_QUIRK(0x104d, 0x9033, "Sony VAIO VGN-SR19XN",
10562 ALC262_SONY_ASSAMD),
10469 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1", 10563 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
10470 ALC262_TOSHIBA_RX1), 10564 ALC262_TOSHIBA_RX1),
10471 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06), 10565 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
@@ -10624,7 +10718,8 @@ static struct alc_config_preset alc262_presets[] = {
10624 .init_hook = alc262_hippo_automute, 10718 .init_hook = alc262_hippo_automute,
10625 }, 10719 },
10626 [ALC262_ULTRA] = { 10720 [ALC262_ULTRA] = {
10627 .mixers = { alc262_ultra_mixer, alc262_ultra_capture_mixer }, 10721 .mixers = { alc262_ultra_mixer },
10722 .cap_mixer = alc262_ultra_capture_mixer,
10628 .init_verbs = { alc262_ultra_verbs }, 10723 .init_verbs = { alc262_ultra_verbs },
10629 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 10724 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10630 .dac_nids = alc262_dac_nids, 10725 .dac_nids = alc262_dac_nids,
@@ -10750,6 +10845,7 @@ static int patch_alc262(struct hda_codec *codec)
10750 spec->stream_digital_playback = &alc262_pcm_digital_playback; 10845 spec->stream_digital_playback = &alc262_pcm_digital_playback;
10751 spec->stream_digital_capture = &alc262_pcm_digital_capture; 10846 spec->stream_digital_capture = &alc262_pcm_digital_capture;
10752 10847
10848 spec->is_mix_capture = 1;
10753 if (!spec->adc_nids && spec->input_mux) { 10849 if (!spec->adc_nids && spec->input_mux) {
10754 /* check whether NID 0x07 is valid */ 10850 /* check whether NID 0x07 is valid */
10755 unsigned int wcap = get_wcaps(codec, 0x07); 10851 unsigned int wcap = get_wcaps(codec, 0x07);
@@ -10760,17 +10856,14 @@ static int patch_alc262(struct hda_codec *codec)
10760 spec->adc_nids = alc262_adc_nids_alt; 10856 spec->adc_nids = alc262_adc_nids_alt;
10761 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt); 10857 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
10762 spec->capsrc_nids = alc262_capsrc_nids_alt; 10858 spec->capsrc_nids = alc262_capsrc_nids_alt;
10763 spec->mixers[spec->num_mixers] =
10764 alc262_capture_alt_mixer;
10765 spec->num_mixers++;
10766 } else { 10859 } else {
10767 spec->adc_nids = alc262_adc_nids; 10860 spec->adc_nids = alc262_adc_nids;
10768 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids); 10861 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
10769 spec->capsrc_nids = alc262_capsrc_nids; 10862 spec->capsrc_nids = alc262_capsrc_nids;
10770 spec->mixers[spec->num_mixers] = alc262_capture_mixer;
10771 spec->num_mixers++;
10772 } 10863 }
10773 } 10864 }
10865 if (!spec->cap_mixer)
10866 set_capture_mixer(spec);
10774 10867
10775 spec->vmaster_nid = 0x0c; 10868 spec->vmaster_nid = 0x0c;
10776 10869
@@ -10781,6 +10874,7 @@ static int patch_alc262(struct hda_codec *codec)
10781 if (!spec->loopback.amplist) 10874 if (!spec->loopback.amplist)
10782 spec->loopback.amplist = alc262_loopbacks; 10875 spec->loopback.amplist = alc262_loopbacks;
10783#endif 10876#endif
10877 codec->proc_widget_hook = print_realtek_coef;
10784 10878
10785 return 0; 10879 return 0;
10786} 10880}
@@ -10942,6 +11036,22 @@ static struct snd_kcontrol_new alc268_acer_mixer[] = {
10942 { } 11036 { }
10943}; 11037};
10944 11038
11039static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
11040 /* output mixer control */
11041 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11042 {
11043 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11044 .name = "Master Playback Switch",
11045 .info = snd_hda_mixer_amp_switch_info,
11046 .get = snd_hda_mixer_amp_switch_get,
11047 .put = alc268_acer_master_sw_put,
11048 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11049 },
11050 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11051 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11052 { }
11053};
11054
10945static struct hda_verb alc268_acer_aspire_one_verbs[] = { 11055static struct hda_verb alc268_acer_aspire_one_verbs[] = {
10946 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11056 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10947 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11057 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
@@ -11218,10 +11328,6 @@ static struct hda_verb alc268_volume_init_verbs[] = {
11218 { } 11328 { }
11219}; 11329};
11220 11330
11221#define alc268_mux_enum_info alc_mux_enum_info
11222#define alc268_mux_enum_get alc_mux_enum_get
11223#define alc268_mux_enum_put alc_mux_enum_put
11224
11225static struct snd_kcontrol_new alc268_capture_alt_mixer[] = { 11331static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
11226 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), 11332 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11227 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), 11333 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
@@ -11233,9 +11339,9 @@ static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
11233 /* .name = "Capture Source", */ 11339 /* .name = "Capture Source", */
11234 .name = "Input Source", 11340 .name = "Input Source",
11235 .count = 1, 11341 .count = 1,
11236 .info = alc268_mux_enum_info, 11342 .info = alc_mux_enum_info,
11237 .get = alc268_mux_enum_get, 11343 .get = alc_mux_enum_get,
11238 .put = alc268_mux_enum_put, 11344 .put = alc_mux_enum_put,
11239 }, 11345 },
11240 { } /* end */ 11346 { } /* end */
11241}; 11347};
@@ -11253,9 +11359,9 @@ static struct snd_kcontrol_new alc268_capture_mixer[] = {
11253 /* .name = "Capture Source", */ 11359 /* .name = "Capture Source", */
11254 .name = "Input Source", 11360 .name = "Input Source",
11255 .count = 2, 11361 .count = 2,
11256 .info = alc268_mux_enum_info, 11362 .info = alc_mux_enum_info,
11257 .get = alc268_mux_enum_get, 11363 .get = alc_mux_enum_get,
11258 .put = alc268_mux_enum_put, 11364 .put = alc_mux_enum_put,
11259 }, 11365 },
11260 { } /* end */ 11366 { } /* end */
11261}; 11367};
@@ -11274,6 +11380,15 @@ static struct hda_input_mux alc268_acer_capture_source = {
11274 .num_items = 3, 11380 .num_items = 3,
11275 .items = { 11381 .items = {
11276 { "Mic", 0x0 }, 11382 { "Mic", 0x0 },
11383 { "Internal Mic", 0x1 },
11384 { "Line", 0x2 },
11385 },
11386};
11387
11388static struct hda_input_mux alc268_acer_dmic_capture_source = {
11389 .num_items = 3,
11390 .items = {
11391 { "Mic", 0x0 },
11277 { "Internal Mic", 0x6 }, 11392 { "Internal Mic", 0x6 },
11278 { "Line", 0x2 }, 11393 { "Line", 0x2 },
11279 }, 11394 },
@@ -11512,13 +11627,13 @@ static int alc268_parse_auto_config(struct hda_codec *codec)
11512 if (spec->autocfg.dig_out_pin) 11627 if (spec->autocfg.dig_out_pin)
11513 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID; 11628 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
11514 11629
11515 if (spec->kctl_alloc) 11630 if (spec->kctls.list)
11516 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 11631 add_mixer(spec, spec->kctls.list);
11517 11632
11518 if (spec->autocfg.speaker_pins[0] != 0x1d) 11633 if (spec->autocfg.speaker_pins[0] != 0x1d)
11519 spec->mixers[spec->num_mixers++] = alc268_beep_mixer; 11634 add_mixer(spec, alc268_beep_mixer);
11520 11635
11521 spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs; 11636 add_verb(spec, alc268_volume_init_verbs);
11522 spec->num_mux_defs = 1; 11637 spec->num_mux_defs = 1;
11523 spec->input_mux = &spec->private_imux; 11638 spec->input_mux = &spec->private_imux;
11524 11639
@@ -11554,6 +11669,7 @@ static const char *alc268_models[ALC268_MODEL_LAST] = {
11554 [ALC268_3ST] = "3stack", 11669 [ALC268_3ST] = "3stack",
11555 [ALC268_TOSHIBA] = "toshiba", 11670 [ALC268_TOSHIBA] = "toshiba",
11556 [ALC268_ACER] = "acer", 11671 [ALC268_ACER] = "acer",
11672 [ALC268_ACER_DMIC] = "acer-dmic",
11557 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire", 11673 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
11558 [ALC268_DELL] = "dell", 11674 [ALC268_DELL] = "dell",
11559 [ALC268_ZEPTO] = "zepto", 11675 [ALC268_ZEPTO] = "zepto",
@@ -11649,6 +11765,23 @@ static struct alc_config_preset alc268_presets[] = {
11649 .unsol_event = alc268_acer_unsol_event, 11765 .unsol_event = alc268_acer_unsol_event,
11650 .init_hook = alc268_acer_init_hook, 11766 .init_hook = alc268_acer_init_hook,
11651 }, 11767 },
11768 [ALC268_ACER_DMIC] = {
11769 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
11770 alc268_beep_mixer },
11771 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11772 alc268_acer_verbs },
11773 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11774 .dac_nids = alc268_dac_nids,
11775 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11776 .adc_nids = alc268_adc_nids_alt,
11777 .capsrc_nids = alc268_capsrc_nids,
11778 .hp_nid = 0x02,
11779 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11780 .channel_mode = alc268_modes,
11781 .input_mux = &alc268_acer_dmic_capture_source,
11782 .unsol_event = alc268_acer_unsol_event,
11783 .init_hook = alc268_acer_init_hook,
11784 },
11652 [ALC268_ACER_ASPIRE_ONE] = { 11785 [ALC268_ACER_ASPIRE_ONE] = {
11653 .mixers = { alc268_acer_aspire_one_mixer, 11786 .mixers = { alc268_acer_aspire_one_mixer,
11654 alc268_capture_alt_mixer }, 11787 alc268_capture_alt_mixer },
@@ -11787,15 +11920,11 @@ static int patch_alc268(struct hda_codec *codec)
11787 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) { 11920 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
11788 spec->adc_nids = alc268_adc_nids_alt; 11921 spec->adc_nids = alc268_adc_nids_alt;
11789 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt); 11922 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
11790 spec->mixers[spec->num_mixers] = 11923 add_mixer(spec, alc268_capture_alt_mixer);
11791 alc268_capture_alt_mixer;
11792 spec->num_mixers++;
11793 } else { 11924 } else {
11794 spec->adc_nids = alc268_adc_nids; 11925 spec->adc_nids = alc268_adc_nids;
11795 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids); 11926 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
11796 spec->mixers[spec->num_mixers] = 11927 add_mixer(spec, alc268_capture_mixer);
11797 alc268_capture_mixer;
11798 spec->num_mixers++;
11799 } 11928 }
11800 spec->capsrc_nids = alc268_capsrc_nids; 11929 spec->capsrc_nids = alc268_capsrc_nids;
11801 /* set default input source */ 11930 /* set default input source */
@@ -11811,6 +11940,8 @@ static int patch_alc268(struct hda_codec *codec)
11811 if (board_config == ALC268_AUTO) 11940 if (board_config == ALC268_AUTO)
11812 spec->init_hook = alc268_auto_init; 11941 spec->init_hook = alc268_auto_init;
11813 11942
11943 codec->proc_widget_hook = print_realtek_coef;
11944
11814 return 0; 11945 return 0;
11815} 11946}
11816 11947
@@ -11893,6 +12024,31 @@ static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
11893 { } 12024 { }
11894}; 12025};
11895 12026
12027static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
12028 /* output mixer control */
12029 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12030 {
12031 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12032 .name = "Master Playback Switch",
12033 .info = snd_hda_mixer_amp_switch_info,
12034 .get = snd_hda_mixer_amp_switch_get,
12035 .put = alc268_acer_master_sw_put,
12036 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12037 },
12038 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12039 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12040 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12041 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12042 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12043 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12044 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
12045 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
12046 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
12047 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x04, HDA_INPUT),
12048 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x04, HDA_INPUT),
12049 { }
12050};
12051
11896/* bind volumes of both NID 0x0c and 0x0d */ 12052/* bind volumes of both NID 0x0c and 0x0d */
11897static struct hda_bind_ctls alc269_epc_bind_vol = { 12053static struct hda_bind_ctls alc269_epc_bind_vol = {
11898 .ops = &snd_hda_bind_vol, 12054 .ops = &snd_hda_bind_vol,
@@ -11911,28 +12067,18 @@ static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
11911}; 12067};
11912 12068
11913/* capture mixer elements */ 12069/* capture mixer elements */
11914static struct snd_kcontrol_new alc269_capture_mixer[] = { 12070static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
11915 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 12071 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11916 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 12072 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11917 { 12073 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11918 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11919 /* The multiple "Capture Source" controls confuse alsamixer
11920 * So call somewhat different..
11921 */
11922 /* .name = "Capture Source", */
11923 .name = "Input Source",
11924 .count = 1,
11925 .info = alc_mux_enum_info,
11926 .get = alc_mux_enum_get,
11927 .put = alc_mux_enum_put,
11928 },
11929 { } /* end */ 12074 { } /* end */
11930}; 12075};
11931 12076
11932/* capture mixer elements */ 12077/* FSC amilo */
11933static struct snd_kcontrol_new alc269_epc_capture_mixer[] = { 12078static struct snd_kcontrol_new alc269_fujitsu_mixer[] = {
11934 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 12079 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11935 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 12080 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12081 HDA_BIND_VOL("PCM Playback Volume", &alc269_epc_bind_vol),
11936 { } /* end */ 12082 { } /* end */
11937}; 12083};
11938 12084
@@ -11953,6 +12099,20 @@ static struct hda_verb alc269_quanta_fl1_verbs[] = {
11953 { } 12099 { }
11954}; 12100};
11955 12101
12102static struct hda_verb alc269_lifebook_verbs[] = {
12103 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12104 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
12105 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12106 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12107 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12108 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12109 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12110 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12111 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12112 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12113 { }
12114};
12115
11956/* toggle speaker-output according to the hp-jack state */ 12116/* toggle speaker-output according to the hp-jack state */
11957static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec) 12117static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
11958{ 12118{
@@ -11978,6 +12138,37 @@ static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
11978 AC_VERB_SET_PROC_COEF, 0x480); 12138 AC_VERB_SET_PROC_COEF, 0x480);
11979} 12139}
11980 12140
12141/* toggle speaker-output according to the hp-jacks state */
12142static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
12143{
12144 unsigned int present;
12145 unsigned char bits;
12146
12147 /* Check laptop headphone socket */
12148 present = snd_hda_codec_read(codec, 0x15, 0,
12149 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12150
12151 /* Check port replicator headphone socket */
12152 present |= snd_hda_codec_read(codec, 0x1a, 0,
12153 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12154
12155 bits = present ? AMP_IN_MUTE(0) : 0;
12156 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12157 AMP_IN_MUTE(0), bits);
12158 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12159 AMP_IN_MUTE(0), bits);
12160
12161 snd_hda_codec_write(codec, 0x20, 0,
12162 AC_VERB_SET_COEF_INDEX, 0x0c);
12163 snd_hda_codec_write(codec, 0x20, 0,
12164 AC_VERB_SET_PROC_COEF, 0x680);
12165
12166 snd_hda_codec_write(codec, 0x20, 0,
12167 AC_VERB_SET_COEF_INDEX, 0x0c);
12168 snd_hda_codec_write(codec, 0x20, 0,
12169 AC_VERB_SET_PROC_COEF, 0x480);
12170}
12171
11981static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec) 12172static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec)
11982{ 12173{
11983 unsigned int present; 12174 unsigned int present;
@@ -11988,6 +12179,29 @@ static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec)
11988 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1); 12179 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1);
11989} 12180}
11990 12181
12182static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
12183{
12184 unsigned int present_laptop;
12185 unsigned int present_dock;
12186
12187 present_laptop = snd_hda_codec_read(codec, 0x18, 0,
12188 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12189
12190 present_dock = snd_hda_codec_read(codec, 0x1b, 0,
12191 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12192
12193 /* Laptop mic port overrides dock mic port, design decision */
12194 if (present_dock)
12195 snd_hda_codec_write(codec, 0x23, 0,
12196 AC_VERB_SET_CONNECT_SEL, 0x3);
12197 if (present_laptop)
12198 snd_hda_codec_write(codec, 0x23, 0,
12199 AC_VERB_SET_CONNECT_SEL, 0x0);
12200 if (!present_dock && !present_laptop)
12201 snd_hda_codec_write(codec, 0x23, 0,
12202 AC_VERB_SET_CONNECT_SEL, 0x1);
12203}
12204
11991static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec, 12205static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
11992 unsigned int res) 12206 unsigned int res)
11993{ 12207{
@@ -11997,12 +12211,27 @@ static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
11997 alc269_quanta_fl1_mic_automute(codec); 12211 alc269_quanta_fl1_mic_automute(codec);
11998} 12212}
11999 12213
12214static void alc269_lifebook_unsol_event(struct hda_codec *codec,
12215 unsigned int res)
12216{
12217 if ((res >> 26) == ALC880_HP_EVENT)
12218 alc269_lifebook_speaker_automute(codec);
12219 if ((res >> 26) == ALC880_MIC_EVENT)
12220 alc269_lifebook_mic_autoswitch(codec);
12221}
12222
12000static void alc269_quanta_fl1_init_hook(struct hda_codec *codec) 12223static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
12001{ 12224{
12002 alc269_quanta_fl1_speaker_automute(codec); 12225 alc269_quanta_fl1_speaker_automute(codec);
12003 alc269_quanta_fl1_mic_automute(codec); 12226 alc269_quanta_fl1_mic_automute(codec);
12004} 12227}
12005 12228
12229static void alc269_lifebook_init_hook(struct hda_codec *codec)
12230{
12231 alc269_lifebook_speaker_automute(codec);
12232 alc269_lifebook_mic_autoswitch(codec);
12233}
12234
12006static struct hda_verb alc269_eeepc_dmic_init_verbs[] = { 12235static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
12007 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 12236 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12008 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05}, 12237 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
@@ -12303,17 +12532,17 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
12303 if (spec->autocfg.dig_out_pin) 12532 if (spec->autocfg.dig_out_pin)
12304 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID; 12533 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
12305 12534
12306 if (spec->kctl_alloc) 12535 if (spec->kctls.list)
12307 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 12536 add_mixer(spec, spec->kctls.list);
12308 12537
12309 /* create a beep mixer control if the pin 0x1d isn't assigned */ 12538 /* create a beep mixer control if the pin 0x1d isn't assigned */
12310 for (i = 0; i < ARRAY_SIZE(spec->autocfg.input_pins); i++) 12539 for (i = 0; i < ARRAY_SIZE(spec->autocfg.input_pins); i++)
12311 if (spec->autocfg.input_pins[i] == 0x1d) 12540 if (spec->autocfg.input_pins[i] == 0x1d)
12312 break; 12541 break;
12313 if (i >= ARRAY_SIZE(spec->autocfg.input_pins)) 12542 if (i >= ARRAY_SIZE(spec->autocfg.input_pins))
12314 spec->mixers[spec->num_mixers++] = alc269_beep_mixer; 12543 add_mixer(spec, alc269_beep_mixer);
12315 12544
12316 spec->init_verbs[spec->num_init_verbs++] = alc269_init_verbs; 12545 add_verb(spec, alc269_init_verbs);
12317 spec->num_mux_defs = 1; 12546 spec->num_mux_defs = 1;
12318 spec->input_mux = &spec->private_imux; 12547 spec->input_mux = &spec->private_imux;
12319 /* set default input source */ 12548 /* set default input source */
@@ -12325,8 +12554,8 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
12325 if (err < 0) 12554 if (err < 0)
12326 return err; 12555 return err;
12327 12556
12328 spec->mixers[spec->num_mixers] = alc269_capture_mixer; 12557 if (!spec->cap_mixer)
12329 spec->num_mixers++; 12558 set_capture_mixer(spec);
12330 12559
12331 store_pin_configs(codec); 12560 store_pin_configs(codec);
12332 return 1; 12561 return 1;
@@ -12355,7 +12584,9 @@ static const char *alc269_models[ALC269_MODEL_LAST] = {
12355 [ALC269_BASIC] = "basic", 12584 [ALC269_BASIC] = "basic",
12356 [ALC269_QUANTA_FL1] = "quanta", 12585 [ALC269_QUANTA_FL1] = "quanta",
12357 [ALC269_ASUS_EEEPC_P703] = "eeepc-p703", 12586 [ALC269_ASUS_EEEPC_P703] = "eeepc-p703",
12358 [ALC269_ASUS_EEEPC_P901] = "eeepc-p901" 12587 [ALC269_ASUS_EEEPC_P901] = "eeepc-p901",
12588 [ALC269_FUJITSU] = "fujitsu",
12589 [ALC269_LIFEBOOK] = "lifebook"
12359}; 12590};
12360 12591
12361static struct snd_pci_quirk alc269_cfg_tbl[] = { 12592static struct snd_pci_quirk alc269_cfg_tbl[] = {
@@ -12366,12 +12597,14 @@ static struct snd_pci_quirk alc269_cfg_tbl[] = {
12366 ALC269_ASUS_EEEPC_P901), 12597 ALC269_ASUS_EEEPC_P901),
12367 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101", 12598 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
12368 ALC269_ASUS_EEEPC_P901), 12599 ALC269_ASUS_EEEPC_P901),
12600 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
12601 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
12369 {} 12602 {}
12370}; 12603};
12371 12604
12372static struct alc_config_preset alc269_presets[] = { 12605static struct alc_config_preset alc269_presets[] = {
12373 [ALC269_BASIC] = { 12606 [ALC269_BASIC] = {
12374 .mixers = { alc269_base_mixer, alc269_capture_mixer }, 12607 .mixers = { alc269_base_mixer },
12375 .init_verbs = { alc269_init_verbs }, 12608 .init_verbs = { alc269_init_verbs },
12376 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 12609 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12377 .dac_nids = alc269_dac_nids, 12610 .dac_nids = alc269_dac_nids,
@@ -12393,7 +12626,8 @@ static struct alc_config_preset alc269_presets[] = {
12393 .init_hook = alc269_quanta_fl1_init_hook, 12626 .init_hook = alc269_quanta_fl1_init_hook,
12394 }, 12627 },
12395 [ALC269_ASUS_EEEPC_P703] = { 12628 [ALC269_ASUS_EEEPC_P703] = {
12396 .mixers = { alc269_eeepc_mixer, alc269_epc_capture_mixer }, 12629 .mixers = { alc269_eeepc_mixer },
12630 .cap_mixer = alc269_epc_capture_mixer,
12397 .init_verbs = { alc269_init_verbs, 12631 .init_verbs = { alc269_init_verbs,
12398 alc269_eeepc_amic_init_verbs }, 12632 alc269_eeepc_amic_init_verbs },
12399 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 12633 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
@@ -12406,7 +12640,8 @@ static struct alc_config_preset alc269_presets[] = {
12406 .init_hook = alc269_eeepc_amic_inithook, 12640 .init_hook = alc269_eeepc_amic_inithook,
12407 }, 12641 },
12408 [ALC269_ASUS_EEEPC_P901] = { 12642 [ALC269_ASUS_EEEPC_P901] = {
12409 .mixers = { alc269_eeepc_mixer, alc269_epc_capture_mixer}, 12643 .mixers = { alc269_eeepc_mixer },
12644 .cap_mixer = alc269_epc_capture_mixer,
12410 .init_verbs = { alc269_init_verbs, 12645 .init_verbs = { alc269_init_verbs,
12411 alc269_eeepc_dmic_init_verbs }, 12646 alc269_eeepc_dmic_init_verbs },
12412 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 12647 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
@@ -12418,6 +12653,32 @@ static struct alc_config_preset alc269_presets[] = {
12418 .unsol_event = alc269_eeepc_dmic_unsol_event, 12653 .unsol_event = alc269_eeepc_dmic_unsol_event,
12419 .init_hook = alc269_eeepc_dmic_inithook, 12654 .init_hook = alc269_eeepc_dmic_inithook,
12420 }, 12655 },
12656 [ALC269_FUJITSU] = {
12657 .mixers = { alc269_fujitsu_mixer, alc269_beep_mixer },
12658 .cap_mixer = alc269_epc_capture_mixer,
12659 .init_verbs = { alc269_init_verbs,
12660 alc269_eeepc_dmic_init_verbs },
12661 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12662 .dac_nids = alc269_dac_nids,
12663 .hp_nid = 0x03,
12664 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12665 .channel_mode = alc269_modes,
12666 .input_mux = &alc269_eeepc_dmic_capture_source,
12667 .unsol_event = alc269_eeepc_dmic_unsol_event,
12668 .init_hook = alc269_eeepc_dmic_inithook,
12669 },
12670 [ALC269_LIFEBOOK] = {
12671 .mixers = { alc269_lifebook_mixer },
12672 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
12673 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12674 .dac_nids = alc269_dac_nids,
12675 .hp_nid = 0x03,
12676 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12677 .channel_mode = alc269_modes,
12678 .input_mux = &alc269_capture_source,
12679 .unsol_event = alc269_lifebook_unsol_event,
12680 .init_hook = alc269_lifebook_init_hook,
12681 },
12421}; 12682};
12422 12683
12423static int patch_alc269(struct hda_codec *codec) 12684static int patch_alc269(struct hda_codec *codec)
@@ -12472,6 +12733,8 @@ static int patch_alc269(struct hda_codec *codec)
12472 spec->adc_nids = alc269_adc_nids; 12733 spec->adc_nids = alc269_adc_nids;
12473 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids); 12734 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
12474 spec->capsrc_nids = alc269_capsrc_nids; 12735 spec->capsrc_nids = alc269_capsrc_nids;
12736 if (!spec->cap_mixer)
12737 set_capture_mixer(spec);
12475 12738
12476 codec->patch_ops = alc_patch_ops; 12739 codec->patch_ops = alc_patch_ops;
12477 if (board_config == ALC269_AUTO) 12740 if (board_config == ALC269_AUTO)
@@ -12480,6 +12743,7 @@ static int patch_alc269(struct hda_codec *codec)
12480 if (!spec->loopback.amplist) 12743 if (!spec->loopback.amplist)
12481 spec->loopback.amplist = alc269_loopbacks; 12744 spec->loopback.amplist = alc269_loopbacks;
12482#endif 12745#endif
12746 codec->proc_widget_hook = print_realtek_coef;
12483 12747
12484 return 0; 12748 return 0;
12485} 12749}
@@ -12612,17 +12876,6 @@ static struct snd_kcontrol_new alc861_base_mixer[] = {
12612 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 12876 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12613 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), 12877 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12614 12878
12615 /* Capture mixer control */
12616 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12617 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12618 {
12619 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12620 .name = "Capture Source",
12621 .count = 1,
12622 .info = alc_mux_enum_info,
12623 .get = alc_mux_enum_get,
12624 .put = alc_mux_enum_put,
12625 },
12626 { } /* end */ 12879 { } /* end */
12627}; 12880};
12628 12881
@@ -12646,17 +12899,6 @@ static struct snd_kcontrol_new alc861_3ST_mixer[] = {
12646 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 12899 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12647 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), 12900 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12648 12901
12649 /* Capture mixer control */
12650 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12651 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12652 {
12653 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12654 .name = "Capture Source",
12655 .count = 1,
12656 .info = alc_mux_enum_info,
12657 .get = alc_mux_enum_get,
12658 .put = alc_mux_enum_put,
12659 },
12660 { 12902 {
12661 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12903 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12662 .name = "Channel Mode", 12904 .name = "Channel Mode",
@@ -12674,18 +12916,6 @@ static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
12674 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 12916 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12675 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 12917 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12676 12918
12677 /*Capture mixer control */
12678 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12679 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12680 {
12681 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12682 .name = "Capture Source",
12683 .count = 1,
12684 .info = alc_mux_enum_info,
12685 .get = alc_mux_enum_get,
12686 .put = alc_mux_enum_put,
12687 },
12688
12689 { } /* end */ 12919 { } /* end */
12690}; 12920};
12691 12921
@@ -12709,17 +12939,6 @@ static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
12709 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 12939 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12710 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), 12940 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12711 12941
12712 /* Capture mixer control */
12713 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12714 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12715 {
12716 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12717 .name = "Capture Source",
12718 .count = 1,
12719 .info = alc_mux_enum_info,
12720 .get = alc_mux_enum_get,
12721 .put = alc_mux_enum_put,
12722 },
12723 { 12942 {
12724 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12943 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12725 .name = "Channel Mode", 12944 .name = "Channel Mode",
@@ -12751,17 +12970,6 @@ static struct snd_kcontrol_new alc861_asus_mixer[] = {
12751 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 12970 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12752 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT), 12971 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
12753 12972
12754 /* Capture mixer control */
12755 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12756 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12757 {
12758 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12759 .name = "Capture Source",
12760 .count = 1,
12761 .info = alc_mux_enum_info,
12762 .get = alc_mux_enum_get,
12763 .put = alc_mux_enum_put,
12764 },
12765 { 12973 {
12766 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12974 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12767 .name = "Channel Mode", 12975 .name = "Channel Mode",
@@ -13293,25 +13501,6 @@ static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
13293 return 0; 13501 return 0;
13294} 13502}
13295 13503
13296static struct snd_kcontrol_new alc861_capture_mixer[] = {
13297 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13298 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13299
13300 {
13301 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13302 /* The multiple "Capture Source" controls confuse alsamixer
13303 * So call somewhat different..
13304 */
13305 /* .name = "Capture Source", */
13306 .name = "Input Source",
13307 .count = 1,
13308 .info = alc_mux_enum_info,
13309 .get = alc_mux_enum_get,
13310 .put = alc_mux_enum_put,
13311 },
13312 { } /* end */
13313};
13314
13315static void alc861_auto_set_output_and_unmute(struct hda_codec *codec, 13504static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
13316 hda_nid_t nid, 13505 hda_nid_t nid,
13317 int pin_type, int dac_idx) 13506 int pin_type, int dac_idx)
@@ -13402,18 +13591,17 @@ static int alc861_parse_auto_config(struct hda_codec *codec)
13402 if (spec->autocfg.dig_out_pin) 13591 if (spec->autocfg.dig_out_pin)
13403 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID; 13592 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
13404 13593
13405 if (spec->kctl_alloc) 13594 if (spec->kctls.list)
13406 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 13595 add_mixer(spec, spec->kctls.list);
13407 13596
13408 spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs; 13597 add_verb(spec, alc861_auto_init_verbs);
13409 13598
13410 spec->num_mux_defs = 1; 13599 spec->num_mux_defs = 1;
13411 spec->input_mux = &spec->private_imux; 13600 spec->input_mux = &spec->private_imux;
13412 13601
13413 spec->adc_nids = alc861_adc_nids; 13602 spec->adc_nids = alc861_adc_nids;
13414 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids); 13603 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
13415 spec->mixers[spec->num_mixers] = alc861_capture_mixer; 13604 set_capture_mixer(spec);
13416 spec->num_mixers++;
13417 13605
13418 store_pin_configs(codec); 13606 store_pin_configs(codec);
13419 return 1; 13607 return 1;
@@ -13644,6 +13832,7 @@ static int patch_alc861(struct hda_codec *codec)
13644 if (!spec->loopback.amplist) 13832 if (!spec->loopback.amplist)
13645 spec->loopback.amplist = alc861_loopbacks; 13833 spec->loopback.amplist = alc861_loopbacks;
13646#endif 13834#endif
13835 codec->proc_widget_hook = print_realtek_coef;
13647 13836
13648 return 0; 13837 return 0;
13649} 13838}
@@ -13709,11 +13898,6 @@ static struct hda_input_mux alc861vd_hp_capture_source = {
13709 }, 13898 },
13710}; 13899};
13711 13900
13712#define alc861vd_mux_enum_info alc_mux_enum_info
13713#define alc861vd_mux_enum_get alc_mux_enum_get
13714/* ALC861VD has the ALC882-type input selection (but has only one ADC) */
13715#define alc861vd_mux_enum_put alc882_mux_enum_put
13716
13717/* 13901/*
13718 * 2ch mode 13902 * 2ch mode
13719 */ 13903 */
@@ -13759,25 +13943,6 @@ static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
13759 { } /* end */ 13943 { } /* end */
13760}; 13944};
13761 13945
13762static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
13763 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13764 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13765
13766 {
13767 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13768 /* The multiple "Capture Source" controls confuse alsamixer
13769 * So call somewhat different..
13770 */
13771 /* .name = "Capture Source", */
13772 .name = "Input Source",
13773 .count = 1,
13774 .info = alc861vd_mux_enum_info,
13775 .get = alc861vd_mux_enum_get,
13776 .put = alc861vd_mux_enum_put,
13777 },
13778 { } /* end */
13779};
13780
13781/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 13946/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
13782 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 13947 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
13783 */ 13948 */
@@ -14169,6 +14334,7 @@ static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int re
14169static const char *alc861vd_models[ALC861VD_MODEL_LAST] = { 14334static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
14170 [ALC660VD_3ST] = "3stack-660", 14335 [ALC660VD_3ST] = "3stack-660",
14171 [ALC660VD_3ST_DIG] = "3stack-660-digout", 14336 [ALC660VD_3ST_DIG] = "3stack-660-digout",
14337 [ALC660VD_ASUS_V1S] = "asus-v1s",
14172 [ALC861VD_3ST] = "3stack", 14338 [ALC861VD_3ST] = "3stack",
14173 [ALC861VD_3ST_DIG] = "3stack-digout", 14339 [ALC861VD_3ST_DIG] = "3stack-digout",
14174 [ALC861VD_6ST_DIG] = "6stack-digout", 14340 [ALC861VD_6ST_DIG] = "6stack-digout",
@@ -14183,7 +14349,7 @@ static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
14183 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP), 14349 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
14184 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST), 14350 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
14185 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST), 14351 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
14186 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC861VD_LENOVO), 14352 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
14187 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG), 14353 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
14188 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST), 14354 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
14189 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO), 14355 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
@@ -14290,6 +14456,21 @@ static struct alc_config_preset alc861vd_presets[] = {
14290 .unsol_event = alc861vd_dallas_unsol_event, 14456 .unsol_event = alc861vd_dallas_unsol_event,
14291 .init_hook = alc861vd_dallas_automute, 14457 .init_hook = alc861vd_dallas_automute,
14292 }, 14458 },
14459 [ALC660VD_ASUS_V1S] = {
14460 .mixers = { alc861vd_lenovo_mixer },
14461 .init_verbs = { alc861vd_volume_init_verbs,
14462 alc861vd_3stack_init_verbs,
14463 alc861vd_eapd_verbs,
14464 alc861vd_lenovo_unsol_verbs },
14465 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14466 .dac_nids = alc660vd_dac_nids,
14467 .dig_out_nid = ALC861VD_DIGOUT_NID,
14468 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14469 .channel_mode = alc861vd_3stack_2ch_modes,
14470 .input_mux = &alc861vd_capture_source,
14471 .unsol_event = alc861vd_lenovo_unsol_event,
14472 .init_hook = alc861vd_lenovo_automute,
14473 },
14293}; 14474};
14294 14475
14295/* 14476/*
@@ -14514,11 +14695,10 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec)
14514 if (spec->autocfg.dig_out_pin) 14695 if (spec->autocfg.dig_out_pin)
14515 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID; 14696 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
14516 14697
14517 if (spec->kctl_alloc) 14698 if (spec->kctls.list)
14518 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 14699 add_mixer(spec, spec->kctls.list);
14519 14700
14520 spec->init_verbs[spec->num_init_verbs++] 14701 add_verb(spec, alc861vd_volume_init_verbs);
14521 = alc861vd_volume_init_verbs;
14522 14702
14523 spec->num_mux_defs = 1; 14703 spec->num_mux_defs = 1;
14524 spec->input_mux = &spec->private_imux; 14704 spec->input_mux = &spec->private_imux;
@@ -14585,7 +14765,7 @@ static int patch_alc861vd(struct hda_codec *codec)
14585 spec->stream_name_analog = "ALC660-VD Analog"; 14765 spec->stream_name_analog = "ALC660-VD Analog";
14586 spec->stream_name_digital = "ALC660-VD Digital"; 14766 spec->stream_name_digital = "ALC660-VD Digital";
14587 /* always turn on EAPD */ 14767 /* always turn on EAPD */
14588 spec->init_verbs[spec->num_init_verbs++] = alc660vd_eapd_verbs; 14768 add_verb(spec, alc660vd_eapd_verbs);
14589 } else { 14769 } else {
14590 spec->stream_name_analog = "ALC861VD Analog"; 14770 spec->stream_name_analog = "ALC861VD Analog";
14591 spec->stream_name_digital = "ALC861VD Digital"; 14771 spec->stream_name_digital = "ALC861VD Digital";
@@ -14600,9 +14780,9 @@ static int patch_alc861vd(struct hda_codec *codec)
14600 spec->adc_nids = alc861vd_adc_nids; 14780 spec->adc_nids = alc861vd_adc_nids;
14601 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids); 14781 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
14602 spec->capsrc_nids = alc861vd_capsrc_nids; 14782 spec->capsrc_nids = alc861vd_capsrc_nids;
14783 spec->is_mix_capture = 1;
14603 14784
14604 spec->mixers[spec->num_mixers] = alc861vd_capture_mixer; 14785 set_capture_mixer(spec);
14605 spec->num_mixers++;
14606 14786
14607 spec->vmaster_nid = 0x02; 14787 spec->vmaster_nid = 0x02;
14608 14788
@@ -14614,6 +14794,7 @@ static int patch_alc861vd(struct hda_codec *codec)
14614 if (!spec->loopback.amplist) 14794 if (!spec->loopback.amplist)
14615 spec->loopback.amplist = alc861vd_loopbacks; 14795 spec->loopback.amplist = alc861vd_loopbacks;
14616#endif 14796#endif
14797 codec->proc_widget_hook = print_realtek_coef;
14617 14798
14618 return 0; 14799 return 0;
14619} 14800}
@@ -14689,10 +14870,6 @@ static struct hda_input_mux alc663_m51va_capture_source = {
14689 }, 14870 },
14690}; 14871};
14691 14872
14692#define alc662_mux_enum_info alc_mux_enum_info
14693#define alc662_mux_enum_get alc_mux_enum_get
14694#define alc662_mux_enum_put alc882_mux_enum_put
14695
14696/* 14873/*
14697 * 2ch mode 14874 * 2ch mode
14698 */ 14875 */
@@ -15278,25 +15455,6 @@ static struct hda_verb alc662_ecs_init_verbs[] = {
15278 {} 15455 {}
15279}; 15456};
15280 15457
15281/* capture mixer elements */
15282static struct snd_kcontrol_new alc662_capture_mixer[] = {
15283 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15284 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
15285 {
15286 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15287 /* The multiple "Capture Source" controls confuse alsamixer
15288 * So call somewhat different..
15289 */
15290 /* .name = "Capture Source", */
15291 .name = "Input Source",
15292 .count = 1,
15293 .info = alc662_mux_enum_info,
15294 .get = alc662_mux_enum_get,
15295 .put = alc662_mux_enum_put,
15296 },
15297 { } /* end */
15298};
15299
15300static struct snd_kcontrol_new alc662_auto_capture_mixer[] = { 15458static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
15301 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 15459 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15302 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 15460 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
@@ -15868,7 +16026,7 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = {
15868 16026
15869static struct alc_config_preset alc662_presets[] = { 16027static struct alc_config_preset alc662_presets[] = {
15870 [ALC662_3ST_2ch_DIG] = { 16028 [ALC662_3ST_2ch_DIG] = {
15871 .mixers = { alc662_3ST_2ch_mixer, alc662_capture_mixer }, 16029 .mixers = { alc662_3ST_2ch_mixer },
15872 .init_verbs = { alc662_init_verbs }, 16030 .init_verbs = { alc662_init_verbs },
15873 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16031 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15874 .dac_nids = alc662_dac_nids, 16032 .dac_nids = alc662_dac_nids,
@@ -15879,8 +16037,7 @@ static struct alc_config_preset alc662_presets[] = {
15879 .input_mux = &alc662_capture_source, 16037 .input_mux = &alc662_capture_source,
15880 }, 16038 },
15881 [ALC662_3ST_6ch_DIG] = { 16039 [ALC662_3ST_6ch_DIG] = {
15882 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer, 16040 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
15883 alc662_capture_mixer },
15884 .init_verbs = { alc662_init_verbs }, 16041 .init_verbs = { alc662_init_verbs },
15885 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16042 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15886 .dac_nids = alc662_dac_nids, 16043 .dac_nids = alc662_dac_nids,
@@ -15892,8 +16049,7 @@ static struct alc_config_preset alc662_presets[] = {
15892 .input_mux = &alc662_capture_source, 16049 .input_mux = &alc662_capture_source,
15893 }, 16050 },
15894 [ALC662_3ST_6ch] = { 16051 [ALC662_3ST_6ch] = {
15895 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer, 16052 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
15896 alc662_capture_mixer },
15897 .init_verbs = { alc662_init_verbs }, 16053 .init_verbs = { alc662_init_verbs },
15898 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16054 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15899 .dac_nids = alc662_dac_nids, 16055 .dac_nids = alc662_dac_nids,
@@ -15903,8 +16059,7 @@ static struct alc_config_preset alc662_presets[] = {
15903 .input_mux = &alc662_capture_source, 16059 .input_mux = &alc662_capture_source,
15904 }, 16060 },
15905 [ALC662_5ST_DIG] = { 16061 [ALC662_5ST_DIG] = {
15906 .mixers = { alc662_base_mixer, alc662_chmode_mixer, 16062 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
15907 alc662_capture_mixer },
15908 .init_verbs = { alc662_init_verbs }, 16063 .init_verbs = { alc662_init_verbs },
15909 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16064 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15910 .dac_nids = alc662_dac_nids, 16065 .dac_nids = alc662_dac_nids,
@@ -15915,7 +16070,7 @@ static struct alc_config_preset alc662_presets[] = {
15915 .input_mux = &alc662_capture_source, 16070 .input_mux = &alc662_capture_source,
15916 }, 16071 },
15917 [ALC662_LENOVO_101E] = { 16072 [ALC662_LENOVO_101E] = {
15918 .mixers = { alc662_lenovo_101e_mixer, alc662_capture_mixer }, 16073 .mixers = { alc662_lenovo_101e_mixer },
15919 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs }, 16074 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
15920 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16075 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15921 .dac_nids = alc662_dac_nids, 16076 .dac_nids = alc662_dac_nids,
@@ -15926,7 +16081,7 @@ static struct alc_config_preset alc662_presets[] = {
15926 .init_hook = alc662_lenovo_101e_all_automute, 16081 .init_hook = alc662_lenovo_101e_all_automute,
15927 }, 16082 },
15928 [ALC662_ASUS_EEEPC_P701] = { 16083 [ALC662_ASUS_EEEPC_P701] = {
15929 .mixers = { alc662_eeepc_p701_mixer, alc662_capture_mixer }, 16084 .mixers = { alc662_eeepc_p701_mixer },
15930 .init_verbs = { alc662_init_verbs, 16085 .init_verbs = { alc662_init_verbs,
15931 alc662_eeepc_sue_init_verbs }, 16086 alc662_eeepc_sue_init_verbs },
15932 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16087 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
@@ -15938,7 +16093,7 @@ static struct alc_config_preset alc662_presets[] = {
15938 .init_hook = alc662_eeepc_inithook, 16093 .init_hook = alc662_eeepc_inithook,
15939 }, 16094 },
15940 [ALC662_ASUS_EEEPC_EP20] = { 16095 [ALC662_ASUS_EEEPC_EP20] = {
15941 .mixers = { alc662_eeepc_ep20_mixer, alc662_capture_mixer, 16096 .mixers = { alc662_eeepc_ep20_mixer,
15942 alc662_chmode_mixer }, 16097 alc662_chmode_mixer },
15943 .init_verbs = { alc662_init_verbs, 16098 .init_verbs = { alc662_init_verbs,
15944 alc662_eeepc_ep20_sue_init_verbs }, 16099 alc662_eeepc_ep20_sue_init_verbs },
@@ -15951,7 +16106,7 @@ static struct alc_config_preset alc662_presets[] = {
15951 .init_hook = alc662_eeepc_ep20_inithook, 16106 .init_hook = alc662_eeepc_ep20_inithook,
15952 }, 16107 },
15953 [ALC662_ECS] = { 16108 [ALC662_ECS] = {
15954 .mixers = { alc662_ecs_mixer, alc662_capture_mixer }, 16109 .mixers = { alc662_ecs_mixer },
15955 .init_verbs = { alc662_init_verbs, 16110 .init_verbs = { alc662_init_verbs,
15956 alc662_ecs_init_verbs }, 16111 alc662_ecs_init_verbs },
15957 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16112 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
@@ -15963,7 +16118,7 @@ static struct alc_config_preset alc662_presets[] = {
15963 .init_hook = alc662_eeepc_inithook, 16118 .init_hook = alc662_eeepc_inithook,
15964 }, 16119 },
15965 [ALC663_ASUS_M51VA] = { 16120 [ALC663_ASUS_M51VA] = {
15966 .mixers = { alc663_m51va_mixer, alc662_capture_mixer}, 16121 .mixers = { alc663_m51va_mixer },
15967 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs }, 16122 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
15968 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16123 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15969 .dac_nids = alc662_dac_nids, 16124 .dac_nids = alc662_dac_nids,
@@ -15975,7 +16130,7 @@ static struct alc_config_preset alc662_presets[] = {
15975 .init_hook = alc663_m51va_inithook, 16130 .init_hook = alc663_m51va_inithook,
15976 }, 16131 },
15977 [ALC663_ASUS_G71V] = { 16132 [ALC663_ASUS_G71V] = {
15978 .mixers = { alc663_g71v_mixer, alc662_capture_mixer}, 16133 .mixers = { alc663_g71v_mixer },
15979 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs }, 16134 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
15980 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16135 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15981 .dac_nids = alc662_dac_nids, 16136 .dac_nids = alc662_dac_nids,
@@ -15987,7 +16142,7 @@ static struct alc_config_preset alc662_presets[] = {
15987 .init_hook = alc663_g71v_inithook, 16142 .init_hook = alc663_g71v_inithook,
15988 }, 16143 },
15989 [ALC663_ASUS_H13] = { 16144 [ALC663_ASUS_H13] = {
15990 .mixers = { alc663_m51va_mixer, alc662_capture_mixer}, 16145 .mixers = { alc663_m51va_mixer },
15991 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs }, 16146 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
15992 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16147 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15993 .dac_nids = alc662_dac_nids, 16148 .dac_nids = alc662_dac_nids,
@@ -15998,7 +16153,7 @@ static struct alc_config_preset alc662_presets[] = {
15998 .init_hook = alc663_m51va_inithook, 16153 .init_hook = alc663_m51va_inithook,
15999 }, 16154 },
16000 [ALC663_ASUS_G50V] = { 16155 [ALC663_ASUS_G50V] = {
16001 .mixers = { alc663_g50v_mixer, alc662_capture_mixer}, 16156 .mixers = { alc663_g50v_mixer },
16002 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs }, 16157 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
16003 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16158 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16004 .dac_nids = alc662_dac_nids, 16159 .dac_nids = alc662_dac_nids,
@@ -16010,7 +16165,8 @@ static struct alc_config_preset alc662_presets[] = {
16010 .init_hook = alc663_g50v_inithook, 16165 .init_hook = alc663_g50v_inithook,
16011 }, 16166 },
16012 [ALC663_ASUS_MODE1] = { 16167 [ALC663_ASUS_MODE1] = {
16013 .mixers = { alc663_m51va_mixer, alc662_auto_capture_mixer }, 16168 .mixers = { alc663_m51va_mixer },
16169 .cap_mixer = alc662_auto_capture_mixer,
16014 .init_verbs = { alc662_init_verbs, 16170 .init_verbs = { alc662_init_verbs,
16015 alc663_21jd_amic_init_verbs }, 16171 alc663_21jd_amic_init_verbs },
16016 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16172 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
@@ -16024,7 +16180,8 @@ static struct alc_config_preset alc662_presets[] = {
16024 .init_hook = alc663_mode1_inithook, 16180 .init_hook = alc663_mode1_inithook,
16025 }, 16181 },
16026 [ALC662_ASUS_MODE2] = { 16182 [ALC662_ASUS_MODE2] = {
16027 .mixers = { alc662_1bjd_mixer, alc662_auto_capture_mixer }, 16183 .mixers = { alc662_1bjd_mixer },
16184 .cap_mixer = alc662_auto_capture_mixer,
16028 .init_verbs = { alc662_init_verbs, 16185 .init_verbs = { alc662_init_verbs,
16029 alc662_1bjd_amic_init_verbs }, 16186 alc662_1bjd_amic_init_verbs },
16030 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16187 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
@@ -16037,7 +16194,8 @@ static struct alc_config_preset alc662_presets[] = {
16037 .init_hook = alc662_mode2_inithook, 16194 .init_hook = alc662_mode2_inithook,
16038 }, 16195 },
16039 [ALC663_ASUS_MODE3] = { 16196 [ALC663_ASUS_MODE3] = {
16040 .mixers = { alc663_two_hp_m1_mixer, alc662_auto_capture_mixer }, 16197 .mixers = { alc663_two_hp_m1_mixer },
16198 .cap_mixer = alc662_auto_capture_mixer,
16041 .init_verbs = { alc662_init_verbs, 16199 .init_verbs = { alc662_init_verbs,
16042 alc663_two_hp_amic_m1_init_verbs }, 16200 alc663_two_hp_amic_m1_init_verbs },
16043 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16201 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
@@ -16051,8 +16209,8 @@ static struct alc_config_preset alc662_presets[] = {
16051 .init_hook = alc663_mode3_inithook, 16209 .init_hook = alc663_mode3_inithook,
16052 }, 16210 },
16053 [ALC663_ASUS_MODE4] = { 16211 [ALC663_ASUS_MODE4] = {
16054 .mixers = { alc663_asus_21jd_clfe_mixer, 16212 .mixers = { alc663_asus_21jd_clfe_mixer },
16055 alc662_auto_capture_mixer}, 16213 .cap_mixer = alc662_auto_capture_mixer,
16056 .init_verbs = { alc662_init_verbs, 16214 .init_verbs = { alc662_init_verbs,
16057 alc663_21jd_amic_init_verbs}, 16215 alc663_21jd_amic_init_verbs},
16058 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16216 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
@@ -16066,8 +16224,8 @@ static struct alc_config_preset alc662_presets[] = {
16066 .init_hook = alc663_mode4_inithook, 16224 .init_hook = alc663_mode4_inithook,
16067 }, 16225 },
16068 [ALC663_ASUS_MODE5] = { 16226 [ALC663_ASUS_MODE5] = {
16069 .mixers = { alc663_asus_15jd_clfe_mixer, 16227 .mixers = { alc663_asus_15jd_clfe_mixer },
16070 alc662_auto_capture_mixer }, 16228 .cap_mixer = alc662_auto_capture_mixer,
16071 .init_verbs = { alc662_init_verbs, 16229 .init_verbs = { alc662_init_verbs,
16072 alc663_15jd_amic_init_verbs }, 16230 alc663_15jd_amic_init_verbs },
16073 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16231 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
@@ -16081,7 +16239,8 @@ static struct alc_config_preset alc662_presets[] = {
16081 .init_hook = alc663_mode5_inithook, 16239 .init_hook = alc663_mode5_inithook,
16082 }, 16240 },
16083 [ALC663_ASUS_MODE6] = { 16241 [ALC663_ASUS_MODE6] = {
16084 .mixers = { alc663_two_hp_m2_mixer, alc662_auto_capture_mixer }, 16242 .mixers = { alc663_two_hp_m2_mixer },
16243 .cap_mixer = alc662_auto_capture_mixer,
16085 .init_verbs = { alc662_init_verbs, 16244 .init_verbs = { alc662_init_verbs,
16086 alc663_two_hp_amic_m2_init_verbs }, 16245 alc663_two_hp_amic_m2_init_verbs },
16087 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16246 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
@@ -16342,24 +16501,20 @@ static int alc662_parse_auto_config(struct hda_codec *codec)
16342 if (spec->autocfg.dig_out_pin) 16501 if (spec->autocfg.dig_out_pin)
16343 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID; 16502 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
16344 16503
16345 if (spec->kctl_alloc) 16504 if (spec->kctls.list)
16346 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 16505 add_mixer(spec, spec->kctls.list);
16347 16506
16348 spec->num_mux_defs = 1; 16507 spec->num_mux_defs = 1;
16349 spec->input_mux = &spec->private_imux; 16508 spec->input_mux = &spec->private_imux;
16350 16509
16351 spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs; 16510 add_verb(spec, alc662_auto_init_verbs);
16352 if (codec->vendor_id == 0x10ec0663) 16511 if (codec->vendor_id == 0x10ec0663)
16353 spec->init_verbs[spec->num_init_verbs++] = 16512 add_verb(spec, alc663_auto_init_verbs);
16354 alc663_auto_init_verbs;
16355 16513
16356 err = alc_auto_add_mic_boost(codec); 16514 err = alc_auto_add_mic_boost(codec);
16357 if (err < 0) 16515 if (err < 0)
16358 return err; 16516 return err;
16359 16517
16360 spec->mixers[spec->num_mixers] = alc662_capture_mixer;
16361 spec->num_mixers++;
16362
16363 store_pin_configs(codec); 16518 store_pin_configs(codec);
16364 return 1; 16519 return 1;
16365} 16520}
@@ -16435,6 +16590,10 @@ static int patch_alc662(struct hda_codec *codec)
16435 spec->adc_nids = alc662_adc_nids; 16590 spec->adc_nids = alc662_adc_nids;
16436 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids); 16591 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
16437 spec->capsrc_nids = alc662_capsrc_nids; 16592 spec->capsrc_nids = alc662_capsrc_nids;
16593 spec->is_mix_capture = 1;
16594
16595 if (!spec->cap_mixer)
16596 set_capture_mixer(spec);
16438 16597
16439 spec->vmaster_nid = 0x02; 16598 spec->vmaster_nid = 0x02;
16440 16599
@@ -16445,6 +16604,7 @@ static int patch_alc662(struct hda_codec *codec)
16445 if (!spec->loopback.amplist) 16604 if (!spec->loopback.amplist)
16446 spec->loopback.amplist = alc662_loopbacks; 16605 spec->loopback.amplist = alc662_loopbacks;
16447#endif 16606#endif
16607 codec->proc_widget_hook = print_realtek_coef;
16448 16608
16449 return 0; 16609 return 0;
16450} 16610}
@@ -16452,7 +16612,7 @@ static int patch_alc662(struct hda_codec *codec)
16452/* 16612/*
16453 * patch entries 16613 * patch entries
16454 */ 16614 */
16455struct hda_codec_preset snd_hda_preset_realtek[] = { 16615static struct hda_codec_preset snd_hda_preset_realtek[] = {
16456 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, 16616 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
16457 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, 16617 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
16458 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 }, 16618 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
@@ -16484,3 +16644,26 @@ struct hda_codec_preset snd_hda_preset_realtek[] = {
16484 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 }, 16644 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
16485 {} /* terminator */ 16645 {} /* terminator */
16486}; 16646};
16647
16648MODULE_ALIAS("snd-hda-codec-id:10ec*");
16649
16650MODULE_LICENSE("GPL");
16651MODULE_DESCRIPTION("Realtek HD-audio codec");
16652
16653static struct hda_codec_preset_list realtek_list = {
16654 .preset = snd_hda_preset_realtek,
16655 .owner = THIS_MODULE,
16656};
16657
16658static int __init patch_realtek_init(void)
16659{
16660 return snd_hda_add_codec_preset(&realtek_list);
16661}
16662
16663static void __exit patch_realtek_exit(void)
16664{
16665 snd_hda_delete_codec_preset(&realtek_list);
16666}
16667
16668module_init(patch_realtek_init)
16669module_exit(patch_realtek_exit)
diff --git a/sound/pci/hda/patch_si3054.c b/sound/pci/hda/patch_si3054.c
index 9332b63e406c..43b436c5d01b 100644
--- a/sound/pci/hda/patch_si3054.c
+++ b/sound/pci/hda/patch_si3054.c
@@ -28,7 +28,6 @@
28#include <sound/core.h> 28#include <sound/core.h>
29#include "hda_codec.h" 29#include "hda_codec.h"
30#include "hda_local.h" 30#include "hda_local.h"
31#include "hda_patch.h"
32 31
33/* si3054 verbs */ 32/* si3054 verbs */
34#define SI3054_VERB_READ_NODE 0x900 33#define SI3054_VERB_READ_NODE 0x900
@@ -283,7 +282,7 @@ static int patch_si3054(struct hda_codec *codec)
283/* 282/*
284 * patch entries 283 * patch entries
285 */ 284 */
286struct hda_codec_preset snd_hda_preset_si3054[] = { 285static struct hda_codec_preset snd_hda_preset_si3054[] = {
287 { .id = 0x163c3055, .name = "Si3054", .patch = patch_si3054 }, 286 { .id = 0x163c3055, .name = "Si3054", .patch = patch_si3054 },
288 { .id = 0x163c3155, .name = "Si3054", .patch = patch_si3054 }, 287 { .id = 0x163c3155, .name = "Si3054", .patch = patch_si3054 },
289 { .id = 0x11c13026, .name = "Si3054", .patch = patch_si3054 }, 288 { .id = 0x11c13026, .name = "Si3054", .patch = patch_si3054 },
@@ -301,3 +300,35 @@ struct hda_codec_preset snd_hda_preset_si3054[] = {
301 {} 300 {}
302}; 301};
303 302
303MODULE_ALIAS("snd-hda-codec-id:163c3055");
304MODULE_ALIAS("snd-hda-codec-id:163c3155");
305MODULE_ALIAS("snd-hda-codec-id:11c13026");
306MODULE_ALIAS("snd-hda-codec-id:11c13055");
307MODULE_ALIAS("snd-hda-codec-id:11c13155");
308MODULE_ALIAS("snd-hda-codec-id:10573055");
309MODULE_ALIAS("snd-hda-codec-id:10573057");
310MODULE_ALIAS("snd-hda-codec-id:10573155");
311MODULE_ALIAS("snd-hda-codec-id:11063288");
312MODULE_ALIAS("snd-hda-codec-id:15433155");
313MODULE_ALIAS("snd-hda-codec-id:18540018");
314
315MODULE_LICENSE("GPL");
316MODULE_DESCRIPTION("Si3054 HD-audio modem codec");
317
318static struct hda_codec_preset_list si3054_list = {
319 .preset = snd_hda_preset_si3054,
320 .owner = THIS_MODULE,
321};
322
323static int __init patch_si3054_init(void)
324{
325 return snd_hda_add_codec_preset(&si3054_list);
326}
327
328static void __exit patch_si3054_exit(void)
329{
330 snd_hda_delete_codec_preset(&si3054_list);
331}
332
333module_init(patch_si3054_init)
334module_exit(patch_si3054_exit)
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index b77f330d2650..35b83dc6e19e 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -30,17 +30,17 @@
30#include <linux/pci.h> 30#include <linux/pci.h>
31#include <sound/core.h> 31#include <sound/core.h>
32#include <sound/asoundef.h> 32#include <sound/asoundef.h>
33#include <sound/jack.h>
33#include "hda_codec.h" 34#include "hda_codec.h"
34#include "hda_local.h" 35#include "hda_local.h"
35#include "hda_patch.h"
36#include "hda_beep.h" 36#include "hda_beep.h"
37 37
38#define NUM_CONTROL_ALLOC 32 38enum {
39 39 STAC_VREF_EVENT = 1,
40#define STAC_VREF_EVENT 0x00 40 STAC_INSERT_EVENT,
41#define STAC_INSERT_EVENT 0x10 41 STAC_PWR_EVENT,
42#define STAC_PWR_EVENT 0x20 42 STAC_HP_EVENT,
43#define STAC_HP_EVENT 0x30 43};
44 44
45enum { 45enum {
46 STAC_REF, 46 STAC_REF,
@@ -137,6 +137,19 @@ enum {
137 STAC_927X_MODELS 137 STAC_927X_MODELS
138}; 138};
139 139
140struct sigmatel_event {
141 hda_nid_t nid;
142 unsigned char type;
143 unsigned char tag;
144 int data;
145};
146
147struct sigmatel_jack {
148 hda_nid_t nid;
149 int type;
150 struct snd_jack *jack;
151};
152
140struct sigmatel_spec { 153struct sigmatel_spec {
141 struct snd_kcontrol_new *mixers[4]; 154 struct snd_kcontrol_new *mixers[4];
142 unsigned int num_mixers; 155 unsigned int num_mixers;
@@ -144,8 +157,6 @@ struct sigmatel_spec {
144 int board_config; 157 int board_config;
145 unsigned int eapd_switch: 1; 158 unsigned int eapd_switch: 1;
146 unsigned int surr_switch: 1; 159 unsigned int surr_switch: 1;
147 unsigned int line_switch: 1;
148 unsigned int mic_switch: 1;
149 unsigned int alt_switch: 1; 160 unsigned int alt_switch: 1;
150 unsigned int hp_detect: 1; 161 unsigned int hp_detect: 1;
151 unsigned int spdif_mute: 1; 162 unsigned int spdif_mute: 1;
@@ -170,12 +181,20 @@ struct sigmatel_spec {
170 hda_nid_t *pwr_nids; 181 hda_nid_t *pwr_nids;
171 hda_nid_t *dac_list; 182 hda_nid_t *dac_list;
172 183
184 /* jack detection */
185 struct snd_array jacks;
186
187 /* events */
188 struct snd_array events;
189
173 /* playback */ 190 /* playback */
174 struct hda_input_mux *mono_mux; 191 struct hda_input_mux *mono_mux;
175 struct hda_input_mux *amp_mux; 192 struct hda_input_mux *amp_mux;
176 unsigned int cur_mmux; 193 unsigned int cur_mmux;
177 struct hda_multi_out multiout; 194 struct hda_multi_out multiout;
178 hda_nid_t dac_nids[5]; 195 hda_nid_t dac_nids[5];
196 hda_nid_t hp_dacs[5];
197 hda_nid_t speaker_dacs[5];
179 198
180 /* capture */ 199 /* capture */
181 hda_nid_t *adc_nids; 200 hda_nid_t *adc_nids;
@@ -199,7 +218,6 @@ struct sigmatel_spec {
199 hda_nid_t *pin_nids; 218 hda_nid_t *pin_nids;
200 unsigned int num_pins; 219 unsigned int num_pins;
201 unsigned int *pin_configs; 220 unsigned int *pin_configs;
202 unsigned int *bios_pin_configs;
203 221
204 /* codec specific stuff */ 222 /* codec specific stuff */
205 struct hda_verb *init; 223 struct hda_verb *init;
@@ -220,15 +238,16 @@ struct sigmatel_spec {
220 /* i/o switches */ 238 /* i/o switches */
221 unsigned int io_switch[2]; 239 unsigned int io_switch[2];
222 unsigned int clfe_swap; 240 unsigned int clfe_swap;
223 unsigned int hp_switch; /* NID of HP as line-out */ 241 hda_nid_t line_switch; /* shared line-in for input and output */
242 hda_nid_t mic_switch; /* shared mic-in for input and output */
243 hda_nid_t hp_switch; /* NID of HP as line-out */
224 unsigned int aloopback; 244 unsigned int aloopback;
225 245
226 struct hda_pcm pcm_rec[2]; /* PCM information */ 246 struct hda_pcm pcm_rec[2]; /* PCM information */
227 247
228 /* dynamic controls and input_mux */ 248 /* dynamic controls and input_mux */
229 struct auto_pin_cfg autocfg; 249 struct auto_pin_cfg autocfg;
230 unsigned int num_kctl_alloc, num_kctl_used; 250 struct snd_array kctls;
231 struct snd_kcontrol_new *kctl_alloc;
232 struct hda_input_mux private_dimux; 251 struct hda_input_mux private_dimux;
233 struct hda_input_mux private_imux; 252 struct hda_input_mux private_imux;
234 struct hda_input_mux private_smux; 253 struct hda_input_mux private_smux;
@@ -272,9 +291,6 @@ static hda_nid_t stac92hd73xx_dmic_nids[STAC92HD73XX_NUM_DMICS + 1] = {
272}; 291};
273 292
274#define STAC92HD73_DAC_COUNT 5 293#define STAC92HD73_DAC_COUNT 5
275static hda_nid_t stac92hd73xx_dac_nids[STAC92HD73_DAC_COUNT] = {
276 0x15, 0x16, 0x17, 0x18, 0x19,
277};
278 294
279static hda_nid_t stac92hd73xx_mux_nids[4] = { 295static hda_nid_t stac92hd73xx_mux_nids[4] = {
280 0x28, 0x29, 0x2a, 0x2b, 296 0x28, 0x29, 0x2a, 0x2b,
@@ -293,11 +309,7 @@ static hda_nid_t stac92hd83xxx_dmic_nids[STAC92HD83XXX_NUM_DMICS + 1] = {
293 0x11, 0x12, 0 309 0x11, 0x12, 0
294}; 310};
295 311
296#define STAC92HD81_DAC_COUNT 2
297#define STAC92HD83_DAC_COUNT 3 312#define STAC92HD83_DAC_COUNT 3
298static hda_nid_t stac92hd83xxx_dac_nids[STAC92HD73_DAC_COUNT] = {
299 0x13, 0x14, 0x22,
300};
301 313
302static hda_nid_t stac92hd83xxx_dmux_nids[2] = { 314static hda_nid_t stac92hd83xxx_dmux_nids[2] = {
303 0x17, 0x18, 315 0x17, 0x18,
@@ -339,10 +351,6 @@ static hda_nid_t stac92hd71bxx_smux_nids[2] = {
339 0x24, 0x25, 351 0x24, 0x25,
340}; 352};
341 353
342static hda_nid_t stac92hd71bxx_dac_nids[1] = {
343 0x10, /*0x11, */
344};
345
346#define STAC92HD71BXX_NUM_DMICS 2 354#define STAC92HD71BXX_NUM_DMICS 2
347static hda_nid_t stac92hd71bxx_dmic_nids[STAC92HD71BXX_NUM_DMICS + 1] = { 355static hda_nid_t stac92hd71bxx_dmic_nids[STAC92HD71BXX_NUM_DMICS + 1] = {
348 0x18, 0x19, 0 356 0x18, 0x19, 0
@@ -574,12 +582,12 @@ static int stac92xx_smux_enum_put(struct snd_kcontrol *kcontrol,
574 else 582 else
575 nid = codec->slave_dig_outs[smux_idx - 1]; 583 nid = codec->slave_dig_outs[smux_idx - 1];
576 if (spec->cur_smux[smux_idx] == smux->num_items - 1) 584 if (spec->cur_smux[smux_idx] == smux->num_items - 1)
577 val = AMP_OUT_MUTE; 585 val = HDA_AMP_MUTE;
578 else 586 else
579 val = AMP_OUT_UNMUTE; 587 val = 0;
580 /* un/mute SPDIF out */ 588 /* un/mute SPDIF out */
581 snd_hda_codec_write_cache(codec, nid, 0, 589 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
582 AC_VERB_SET_AMP_GAIN_MUTE, val); 590 HDA_AMP_MUTE, val);
583 } 591 }
584 return 0; 592 return 0;
585} 593}
@@ -744,10 +752,6 @@ static struct hda_verb stac9200_eapd_init[] = {
744static struct hda_verb stac92hd73xx_6ch_core_init[] = { 752static struct hda_verb stac92hd73xx_6ch_core_init[] = {
745 /* set master volume and direct control */ 753 /* set master volume and direct control */
746 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 754 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
747 /* setup audio connections */
748 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00},
749 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x01},
750 { 0x11, AC_VERB_SET_CONNECT_SEL, 0x02},
751 /* setup adcs to point to mixer */ 755 /* setup adcs to point to mixer */
752 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b}, 756 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
753 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b}, 757 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
@@ -766,10 +770,6 @@ static struct hda_verb dell_eq_core_init[] = {
766 /* set master volume to max value without distortion 770 /* set master volume to max value without distortion
767 * and direct control */ 771 * and direct control */
768 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec}, 772 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec},
769 /* setup audio connections */
770 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
771 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x02},
772 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x01},
773 /* setup adcs to point to mixer */ 773 /* setup adcs to point to mixer */
774 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b}, 774 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
775 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b}, 775 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
@@ -783,10 +783,6 @@ static struct hda_verb dell_eq_core_init[] = {
783 783
784static struct hda_verb dell_m6_core_init[] = { 784static struct hda_verb dell_m6_core_init[] = {
785 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 785 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
786 /* setup audio connections */
787 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
788 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01},
789 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x02},
790 /* setup adcs to point to mixer */ 786 /* setup adcs to point to mixer */
791 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b}, 787 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
792 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b}, 788 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
@@ -801,13 +797,6 @@ static struct hda_verb dell_m6_core_init[] = {
801static struct hda_verb stac92hd73xx_8ch_core_init[] = { 797static struct hda_verb stac92hd73xx_8ch_core_init[] = {
802 /* set master volume and direct control */ 798 /* set master volume and direct control */
803 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 799 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
804 /* setup audio connections */
805 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00},
806 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x01},
807 { 0x11, AC_VERB_SET_CONNECT_SEL, 0x02},
808 /* connect hp ports to dac3 */
809 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x03},
810 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x03},
811 /* setup adcs to point to mixer */ 800 /* setup adcs to point to mixer */
812 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b}, 801 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
813 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b}, 802 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
@@ -825,15 +814,8 @@ static struct hda_verb stac92hd73xx_8ch_core_init[] = {
825static struct hda_verb stac92hd73xx_10ch_core_init[] = { 814static struct hda_verb stac92hd73xx_10ch_core_init[] = {
826 /* set master volume and direct control */ 815 /* set master volume and direct control */
827 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 816 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
828 /* setup audio connections */
829 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
830 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x01 },
831 { 0x11, AC_VERB_SET_CONNECT_SEL, 0x02 },
832 /* dac3 is connected to import3 mux */ 817 /* dac3 is connected to import3 mux */
833 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0xb07f}, 818 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0xb07f},
834 /* connect hp ports to dac4 */
835 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x04},
836 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x04},
837 /* setup adcs to point to mixer */ 819 /* setup adcs to point to mixer */
838 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b}, 820 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
839 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b}, 821 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
@@ -865,8 +847,6 @@ static struct hda_verb stac92hd83xxx_core_init[] = {
865static struct hda_verb stac92hd71bxx_core_init[] = { 847static struct hda_verb stac92hd71bxx_core_init[] = {
866 /* set master volume and direct control */ 848 /* set master volume and direct control */
867 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 849 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
868 /* connect headphone jack to dac1 */
869 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01},
870 /* unmute right and left channels for nodes 0x0a, 0xd, 0x0f */ 850 /* unmute right and left channels for nodes 0x0a, 0xd, 0x0f */
871 { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 851 { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
872 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 852 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
@@ -886,8 +866,6 @@ static struct hda_verb stac92hd71bxx_analog_core_init[] = {
886 866
887 /* set master volume and direct control */ 867 /* set master volume and direct control */
888 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 868 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
889 /* connect headphone jack to dac1 */
890 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01},
891 /* unmute right and left channels for nodes 0x0a, 0xd */ 869 /* unmute right and left channels for nodes 0x0a, 0xd */
892 { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 870 { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
893 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 871 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
@@ -1087,21 +1065,21 @@ static struct snd_kcontrol_new stac92hd83xxx_mixer[] = {
1087 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x18, 0x0, HDA_OUTPUT), 1065 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x18, 0x0, HDA_OUTPUT),
1088 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x18, 0x0, HDA_OUTPUT), 1066 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x18, 0x0, HDA_OUTPUT),
1089 1067
1090 HDA_CODEC_VOLUME("DAC0 Capture Volume", 0x1b, 0, HDA_INPUT), 1068 HDA_CODEC_VOLUME("DAC0 Capture Volume", 0x1b, 0x3, HDA_INPUT),
1091 HDA_CODEC_MUTE("DAC0 Capture Switch", 0x1b, 0, HDA_INPUT), 1069 HDA_CODEC_MUTE("DAC0 Capture Switch", 0x1b, 0x3, HDA_INPUT),
1092 1070
1093 HDA_CODEC_VOLUME("DAC1 Capture Volume", 0x1b, 0x1, HDA_INPUT), 1071 HDA_CODEC_VOLUME("DAC1 Capture Volume", 0x1b, 0x4, HDA_INPUT),
1094 HDA_CODEC_MUTE("DAC1 Capture Switch", 0x1b, 0x1, HDA_INPUT), 1072 HDA_CODEC_MUTE("DAC1 Capture Switch", 0x1b, 0x4, HDA_INPUT),
1095 1073
1096 HDA_CODEC_VOLUME("Front Mic Capture Volume", 0x1b, 0x2, HDA_INPUT), 1074 HDA_CODEC_VOLUME("Front Mic Capture Volume", 0x1b, 0x0, HDA_INPUT),
1097 HDA_CODEC_MUTE("Front Mic Capture Switch", 0x1b, 0x2, HDA_INPUT), 1075 HDA_CODEC_MUTE("Front Mic Capture Switch", 0x1b, 0x0, HDA_INPUT),
1098 1076
1099 HDA_CODEC_VOLUME("Line In Capture Volume", 0x1b, 0x3, HDA_INPUT), 1077 HDA_CODEC_VOLUME("Line In Capture Volume", 0x1b, 0x2, HDA_INPUT),
1100 HDA_CODEC_MUTE("Line In Capture Switch", 0x1b, 0x3, HDA_INPUT), 1078 HDA_CODEC_MUTE("Line In Capture Switch", 0x1b, 0x2, HDA_INPUT),
1101 1079
1102 /* 1080 /*
1103 HDA_CODEC_VOLUME("Mic Capture Volume", 0x1b, 0x4, HDA_INPUT), 1081 HDA_CODEC_VOLUME("Mic Capture Volume", 0x1b, 0x1, HDA_INPUT),
1104 HDA_CODEC_MUTE("Mic Capture Switch", 0x1b 0x4, HDA_INPUT), 1082 HDA_CODEC_MUTE("Mic Capture Switch", 0x1b 0x1, HDA_INPUT),
1105 */ 1083 */
1106 { } /* end */ 1084 { } /* end */
1107}; 1085};
@@ -1240,9 +1218,14 @@ static const char *slave_sws[] = {
1240 NULL 1218 NULL
1241}; 1219};
1242 1220
1221static void stac92xx_free_kctls(struct hda_codec *codec);
1222static int stac92xx_add_jack(struct hda_codec *codec, hda_nid_t nid, int type);
1223
1243static int stac92xx_build_controls(struct hda_codec *codec) 1224static int stac92xx_build_controls(struct hda_codec *codec)
1244{ 1225{
1245 struct sigmatel_spec *spec = codec->spec; 1226 struct sigmatel_spec *spec = codec->spec;
1227 struct auto_pin_cfg *cfg = &spec->autocfg;
1228 hda_nid_t nid;
1246 int err; 1229 int err;
1247 int i; 1230 int i;
1248 1231
@@ -1257,7 +1240,7 @@ static int stac92xx_build_controls(struct hda_codec *codec)
1257 } 1240 }
1258 if (spec->num_dmuxes > 0) { 1241 if (spec->num_dmuxes > 0) {
1259 stac_dmux_mixer.count = spec->num_dmuxes; 1242 stac_dmux_mixer.count = spec->num_dmuxes;
1260 err = snd_ctl_add(codec->bus->card, 1243 err = snd_hda_ctl_add(codec,
1261 snd_ctl_new1(&stac_dmux_mixer, codec)); 1244 snd_ctl_new1(&stac_dmux_mixer, codec));
1262 if (err < 0) 1245 if (err < 0)
1263 return err; 1246 return err;
@@ -1273,7 +1256,7 @@ static int stac92xx_build_controls(struct hda_codec *codec)
1273 spec->spdif_mute = 1; 1256 spec->spdif_mute = 1;
1274 } 1257 }
1275 stac_smux_mixer.count = spec->num_smuxes; 1258 stac_smux_mixer.count = spec->num_smuxes;
1276 err = snd_ctl_add(codec->bus->card, 1259 err = snd_hda_ctl_add(codec,
1277 snd_ctl_new1(&stac_smux_mixer, codec)); 1260 snd_ctl_new1(&stac_smux_mixer, codec));
1278 if (err < 0) 1261 if (err < 0)
1279 return err; 1262 return err;
@@ -1312,6 +1295,37 @@ static int stac92xx_build_controls(struct hda_codec *codec)
1312 return err; 1295 return err;
1313 } 1296 }
1314 1297
1298 stac92xx_free_kctls(codec); /* no longer needed */
1299
1300 /* create jack input elements */
1301 if (spec->hp_detect) {
1302 for (i = 0; i < cfg->hp_outs; i++) {
1303 int type = SND_JACK_HEADPHONE;
1304 nid = cfg->hp_pins[i];
1305 /* jack detection */
1306 if (cfg->hp_outs == i)
1307 type |= SND_JACK_LINEOUT;
1308 err = stac92xx_add_jack(codec, nid, type);
1309 if (err < 0)
1310 return err;
1311 }
1312 }
1313 for (i = 0; i < cfg->line_outs; i++) {
1314 err = stac92xx_add_jack(codec, cfg->line_out_pins[i],
1315 SND_JACK_LINEOUT);
1316 if (err < 0)
1317 return err;
1318 }
1319 for (i = 0; i < AUTO_PIN_LAST; i++) {
1320 nid = cfg->input_pins[i];
1321 if (nid) {
1322 err = stac92xx_add_jack(codec, nid,
1323 SND_JACK_MICROPHONE);
1324 if (err < 0)
1325 return err;
1326 }
1327 }
1328
1315 return 0; 1329 return 0;
1316} 1330}
1317 1331
@@ -1720,6 +1734,8 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = {
1720 "HP dv5", STAC_HP_M4), 1734 "HP dv5", STAC_HP_M4),
1721 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f4, 1735 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f4,
1722 "HP dv7", STAC_HP_M4), 1736 "HP dv7", STAC_HP_M4),
1737 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30fc,
1738 "HP dv7", STAC_HP_M4),
1723 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361a, 1739 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361a,
1724 "unknown HP", STAC_HP_M4), 1740 "unknown HP", STAC_HP_M4),
1725 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233, 1741 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233,
@@ -2203,12 +2219,11 @@ static int stac92xx_save_bios_config_regs(struct hda_codec *codec)
2203 int i; 2219 int i;
2204 struct sigmatel_spec *spec = codec->spec; 2220 struct sigmatel_spec *spec = codec->spec;
2205 2221
2206 if (! spec->bios_pin_configs) { 2222 kfree(spec->pin_configs);
2207 spec->bios_pin_configs = kcalloc(spec->num_pins, 2223 spec->pin_configs = kcalloc(spec->num_pins, sizeof(*spec->pin_configs),
2208 sizeof(*spec->bios_pin_configs), GFP_KERNEL); 2224 GFP_KERNEL);
2209 if (! spec->bios_pin_configs) 2225 if (!spec->pin_configs)
2210 return -ENOMEM; 2226 return -ENOMEM;
2211 }
2212 2227
2213 for (i = 0; i < spec->num_pins; i++) { 2228 for (i = 0; i < spec->num_pins; i++) {
2214 hda_nid_t nid = spec->pin_nids[i]; 2229 hda_nid_t nid = spec->pin_nids[i];
@@ -2218,7 +2233,7 @@ static int stac92xx_save_bios_config_regs(struct hda_codec *codec)
2218 AC_VERB_GET_CONFIG_DEFAULT, 0x00); 2233 AC_VERB_GET_CONFIG_DEFAULT, 0x00);
2219 snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x bios pin config %8.8x\n", 2234 snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x bios pin config %8.8x\n",
2220 nid, pin_cfg); 2235 nid, pin_cfg);
2221 spec->bios_pin_configs[i] = pin_cfg; 2236 spec->pin_configs[i] = pin_cfg;
2222 } 2237 }
2223 2238
2224 return 0; 2239 return 0;
@@ -2260,6 +2275,39 @@ static void stac92xx_set_config_regs(struct hda_codec *codec)
2260 spec->pin_configs[i]); 2275 spec->pin_configs[i]);
2261} 2276}
2262 2277
2278static int stac_save_pin_cfgs(struct hda_codec *codec, unsigned int *pins)
2279{
2280 struct sigmatel_spec *spec = codec->spec;
2281
2282 if (!pins)
2283 return stac92xx_save_bios_config_regs(codec);
2284
2285 kfree(spec->pin_configs);
2286 spec->pin_configs = kmemdup(pins,
2287 spec->num_pins * sizeof(*pins),
2288 GFP_KERNEL);
2289 if (!spec->pin_configs)
2290 return -ENOMEM;
2291
2292 stac92xx_set_config_regs(codec);
2293 return 0;
2294}
2295
2296static void stac_change_pin_config(struct hda_codec *codec, hda_nid_t nid,
2297 unsigned int cfg)
2298{
2299 struct sigmatel_spec *spec = codec->spec;
2300 int i;
2301
2302 for (i = 0; i < spec->num_pins; i++) {
2303 if (spec->pin_nids[i] == nid) {
2304 spec->pin_configs[i] = cfg;
2305 stac92xx_set_config_reg(codec, nid, cfg);
2306 break;
2307 }
2308 }
2309}
2310
2263/* 2311/*
2264 * Analog playback callbacks 2312 * Analog playback callbacks
2265 */ 2313 */
@@ -2337,7 +2385,7 @@ static int stac92xx_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2337 2385
2338 if (spec->powerdown_adcs) { 2386 if (spec->powerdown_adcs) {
2339 msleep(40); 2387 msleep(40);
2340 snd_hda_codec_write_cache(codec, nid, 0, 2388 snd_hda_codec_write(codec, nid, 0,
2341 AC_VERB_SET_POWER_STATE, AC_PWRST_D0); 2389 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
2342 } 2390 }
2343 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format); 2391 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
@@ -2353,7 +2401,7 @@ static int stac92xx_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2353 2401
2354 snd_hda_codec_cleanup_stream(codec, nid); 2402 snd_hda_codec_cleanup_stream(codec, nid);
2355 if (spec->powerdown_adcs) 2403 if (spec->powerdown_adcs)
2356 snd_hda_codec_write_cache(codec, nid, 0, 2404 snd_hda_codec_write(codec, nid, 0,
2357 AC_VERB_SET_POWER_STATE, AC_PWRST_D3); 2405 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
2358 return 0; 2406 return 0;
2359} 2407}
@@ -2485,6 +2533,9 @@ static int stac92xx_hp_switch_get(struct snd_kcontrol *kcontrol,
2485 return 0; 2533 return 0;
2486} 2534}
2487 2535
2536static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid,
2537 unsigned char type);
2538
2488static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol, 2539static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol,
2489 struct snd_ctl_elem_value *ucontrol) 2540 struct snd_ctl_elem_value *ucontrol)
2490{ 2541{
@@ -2497,7 +2548,7 @@ static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol,
2497 /* check to be sure that the ports are upto date with 2548 /* check to be sure that the ports are upto date with
2498 * switch changes 2549 * switch changes
2499 */ 2550 */
2500 codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26); 2551 stac_issue_unsol_event(codec, nid, STAC_HP_EVENT);
2501 2552
2502 return 1; 2553 return 1;
2503} 2554}
@@ -2537,7 +2588,7 @@ static int stac92xx_io_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_
2537 * appropriately according to the pin direction 2588 * appropriately according to the pin direction
2538 */ 2589 */
2539 if (spec->hp_detect) 2590 if (spec->hp_detect)
2540 codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26); 2591 stac_issue_unsol_event(codec, nid, STAC_HP_EVENT);
2541 2592
2542 return 1; 2593 return 1;
2543} 2594}
@@ -2632,28 +2683,16 @@ static int stac92xx_add_control_temp(struct sigmatel_spec *spec,
2632{ 2683{
2633 struct snd_kcontrol_new *knew; 2684 struct snd_kcontrol_new *knew;
2634 2685
2635 if (spec->num_kctl_used >= spec->num_kctl_alloc) { 2686 snd_array_init(&spec->kctls, sizeof(*knew), 32);
2636 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC; 2687 knew = snd_array_new(&spec->kctls);
2637 2688 if (!knew)
2638 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); /* array + terminator */ 2689 return -ENOMEM;
2639 if (! knew)
2640 return -ENOMEM;
2641 if (spec->kctl_alloc) {
2642 memcpy(knew, spec->kctl_alloc, sizeof(*knew) * spec->num_kctl_alloc);
2643 kfree(spec->kctl_alloc);
2644 }
2645 spec->kctl_alloc = knew;
2646 spec->num_kctl_alloc = num;
2647 }
2648
2649 knew = &spec->kctl_alloc[spec->num_kctl_used];
2650 *knew = *ktemp; 2690 *knew = *ktemp;
2651 knew->index = idx; 2691 knew->index = idx;
2652 knew->name = kstrdup(name, GFP_KERNEL); 2692 knew->name = kstrdup(name, GFP_KERNEL);
2653 if (!knew->name) 2693 if (!knew->name)
2654 return -ENOMEM; 2694 return -ENOMEM;
2655 knew->private_value = val; 2695 knew->private_value = val;
2656 spec->num_kctl_used++;
2657 return 0; 2696 return 0;
2658} 2697}
2659 2698
@@ -2674,70 +2713,53 @@ static inline int stac92xx_add_control(struct sigmatel_spec *spec, int type,
2674 return stac92xx_add_control_idx(spec, type, 0, name, val); 2713 return stac92xx_add_control_idx(spec, type, 0, name, val);
2675} 2714}
2676 2715
2677/* flag inputs as additional dynamic lineouts */ 2716/* check whether the line-input can be used as line-out */
2678static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cfg *cfg) 2717static hda_nid_t check_line_out_switch(struct hda_codec *codec)
2679{ 2718{
2680 struct sigmatel_spec *spec = codec->spec; 2719 struct sigmatel_spec *spec = codec->spec;
2681 unsigned int wcaps, wtype; 2720 struct auto_pin_cfg *cfg = &spec->autocfg;
2682 int i, num_dacs = 0; 2721 hda_nid_t nid;
2683 2722 unsigned int pincap;
2684 /* use the wcaps cache to count all DACs available for line-outs */
2685 for (i = 0; i < codec->num_nodes; i++) {
2686 wcaps = codec->wcaps[i];
2687 wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
2688 2723
2689 if (wtype == AC_WID_AUD_OUT && !(wcaps & AC_WCAP_DIGITAL)) 2724 if (cfg->line_out_type != AUTO_PIN_LINE_OUT)
2690 num_dacs++; 2725 return 0;
2691 } 2726 nid = cfg->input_pins[AUTO_PIN_LINE];
2727 pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
2728 if (pincap & AC_PINCAP_OUT)
2729 return nid;
2730 return 0;
2731}
2692 2732
2693 snd_printdd("%s: total dac count=%d\n", __func__, num_dacs); 2733/* check whether the mic-input can be used as line-out */
2694 2734static hda_nid_t check_mic_out_switch(struct hda_codec *codec)
2695 switch (cfg->line_outs) { 2735{
2696 case 3: 2736 struct sigmatel_spec *spec = codec->spec;
2697 /* add line-in as side */ 2737 struct auto_pin_cfg *cfg = &spec->autocfg;
2698 if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 3) { 2738 unsigned int def_conf, pincap;
2699 cfg->line_out_pins[cfg->line_outs] = 2739 unsigned int mic_pin;
2700 cfg->input_pins[AUTO_PIN_LINE]; 2740
2701 spec->line_switch = 1; 2741 if (cfg->line_out_type != AUTO_PIN_LINE_OUT)
2702 cfg->line_outs++; 2742 return 0;
2703 } 2743 mic_pin = AUTO_PIN_MIC;
2704 break; 2744 for (;;) {
2705 case 2: 2745 hda_nid_t nid = cfg->input_pins[mic_pin];
2706 /* add line-in as clfe and mic as side */ 2746 def_conf = snd_hda_codec_read(codec, nid, 0,
2707 if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 2) { 2747 AC_VERB_GET_CONFIG_DEFAULT, 0);
2708 cfg->line_out_pins[cfg->line_outs] = 2748 /* some laptops have an internal analog microphone
2709 cfg->input_pins[AUTO_PIN_LINE]; 2749 * which can't be used as a output */
2710 spec->line_switch = 1; 2750 if (get_defcfg_connect(def_conf) != AC_JACK_PORT_FIXED) {
2711 cfg->line_outs++; 2751 pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
2712 } 2752 if (pincap & AC_PINCAP_OUT)
2713 if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 3) { 2753 return nid;
2714 cfg->line_out_pins[cfg->line_outs] =
2715 cfg->input_pins[AUTO_PIN_MIC];
2716 spec->mic_switch = 1;
2717 cfg->line_outs++;
2718 }
2719 break;
2720 case 1:
2721 /* add line-in as surr and mic as clfe */
2722 if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 1) {
2723 cfg->line_out_pins[cfg->line_outs] =
2724 cfg->input_pins[AUTO_PIN_LINE];
2725 spec->line_switch = 1;
2726 cfg->line_outs++;
2727 }
2728 if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 2) {
2729 cfg->line_out_pins[cfg->line_outs] =
2730 cfg->input_pins[AUTO_PIN_MIC];
2731 spec->mic_switch = 1;
2732 cfg->line_outs++;
2733 } 2754 }
2734 break; 2755 if (mic_pin == AUTO_PIN_MIC)
2756 mic_pin = AUTO_PIN_FRONT_MIC;
2757 else
2758 break;
2735 } 2759 }
2736
2737 return 0; 2760 return 0;
2738} 2761}
2739 2762
2740
2741static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid) 2763static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
2742{ 2764{
2743 int i; 2765 int i;
@@ -2750,6 +2772,52 @@ static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
2750 return 0; 2772 return 0;
2751} 2773}
2752 2774
2775static int check_all_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
2776{
2777 int i;
2778 if (is_in_dac_nids(spec, nid))
2779 return 1;
2780 for (i = 0; i < spec->autocfg.hp_outs; i++)
2781 if (spec->hp_dacs[i] == nid)
2782 return 1;
2783 for (i = 0; i < spec->autocfg.speaker_outs; i++)
2784 if (spec->speaker_dacs[i] == nid)
2785 return 1;
2786 return 0;
2787}
2788
2789static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t nid)
2790{
2791 struct sigmatel_spec *spec = codec->spec;
2792 int j, conn_len;
2793 hda_nid_t conn[HDA_MAX_CONNECTIONS];
2794 unsigned int wcaps, wtype;
2795
2796 conn_len = snd_hda_get_connections(codec, nid, conn,
2797 HDA_MAX_CONNECTIONS);
2798 for (j = 0; j < conn_len; j++) {
2799 wcaps = snd_hda_param_read(codec, conn[j],
2800 AC_PAR_AUDIO_WIDGET_CAP);
2801 wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
2802 /* we check only analog outputs */
2803 if (wtype != AC_WID_AUD_OUT || (wcaps & AC_WCAP_DIGITAL))
2804 continue;
2805 /* if this route has a free DAC, assign it */
2806 if (!check_all_dac_nids(spec, conn[j])) {
2807 if (conn_len > 1) {
2808 /* select this DAC in the pin's input mux */
2809 snd_hda_codec_write_cache(codec, nid, 0,
2810 AC_VERB_SET_CONNECT_SEL, j);
2811 }
2812 return conn[j];
2813 }
2814 }
2815 return 0;
2816}
2817
2818static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid);
2819static int add_spec_extra_dacs(struct sigmatel_spec *spec, hda_nid_t nid);
2820
2753/* 2821/*
2754 * Fill in the dac_nids table from the parsed pin configuration 2822 * Fill in the dac_nids table from the parsed pin configuration
2755 * This function only works when every pin in line_out_pins[] 2823 * This function only works when every pin in line_out_pins[]
@@ -2757,31 +2825,17 @@ static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
2757 * codecs are not connected directly to a DAC, such as the 9200 2825 * codecs are not connected directly to a DAC, such as the 9200
2758 * and 9202/925x. For those, dac_nids[] must be hard-coded. 2826 * and 9202/925x. For those, dac_nids[] must be hard-coded.
2759 */ 2827 */
2760static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec, 2828static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec)
2761 struct auto_pin_cfg *cfg)
2762{ 2829{
2763 struct sigmatel_spec *spec = codec->spec; 2830 struct sigmatel_spec *spec = codec->spec;
2764 int i, j, conn_len = 0; 2831 struct auto_pin_cfg *cfg = &spec->autocfg;
2765 hda_nid_t nid, conn[HDA_MAX_CONNECTIONS]; 2832 int i;
2766 unsigned int wcaps, wtype; 2833 hda_nid_t nid, dac;
2767 2834
2768 for (i = 0; i < cfg->line_outs; i++) { 2835 for (i = 0; i < cfg->line_outs; i++) {
2769 nid = cfg->line_out_pins[i]; 2836 nid = cfg->line_out_pins[i];
2770 conn_len = snd_hda_get_connections(codec, nid, conn, 2837 dac = get_unassigned_dac(codec, nid);
2771 HDA_MAX_CONNECTIONS); 2838 if (!dac) {
2772 for (j = 0; j < conn_len; j++) {
2773 wcaps = snd_hda_param_read(codec, conn[j],
2774 AC_PAR_AUDIO_WIDGET_CAP);
2775 wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
2776 if (wtype != AC_WID_AUD_OUT ||
2777 (wcaps & AC_WCAP_DIGITAL))
2778 continue;
2779 /* conn[j] is a DAC routed to this line-out */
2780 if (!is_in_dac_nids(spec, conn[j]))
2781 break;
2782 }
2783
2784 if (j == conn_len) {
2785 if (spec->multiout.num_dacs > 0) { 2839 if (spec->multiout.num_dacs > 0) {
2786 /* we have already working output pins, 2840 /* we have already working output pins,
2787 * so let's drop the broken ones again 2841 * so let's drop the broken ones again
@@ -2795,24 +2849,64 @@ static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec,
2795 __func__, nid); 2849 __func__, nid);
2796 return -ENODEV; 2850 return -ENODEV;
2797 } 2851 }
2852 add_spec_dacs(spec, dac);
2853 }
2798 2854
2799 spec->multiout.dac_nids[i] = conn[j]; 2855 /* add line-in as output */
2800 spec->multiout.num_dacs++; 2856 nid = check_line_out_switch(codec);
2801 if (conn_len > 1) { 2857 if (nid) {
2802 /* select this DAC in the pin's input mux */ 2858 dac = get_unassigned_dac(codec, nid);
2803 snd_hda_codec_write_cache(codec, nid, 0, 2859 if (dac) {
2804 AC_VERB_SET_CONNECT_SEL, j); 2860 snd_printdd("STAC: Add line-in 0x%x as output %d\n",
2861 nid, cfg->line_outs);
2862 cfg->line_out_pins[cfg->line_outs] = nid;
2863 cfg->line_outs++;
2864 spec->line_switch = nid;
2865 add_spec_dacs(spec, dac);
2866 }
2867 }
2868 /* add mic as output */
2869 nid = check_mic_out_switch(codec);
2870 if (nid) {
2871 dac = get_unassigned_dac(codec, nid);
2872 if (dac) {
2873 snd_printdd("STAC: Add mic-in 0x%x as output %d\n",
2874 nid, cfg->line_outs);
2875 cfg->line_out_pins[cfg->line_outs] = nid;
2876 cfg->line_outs++;
2877 spec->mic_switch = nid;
2878 add_spec_dacs(spec, dac);
2879 }
2880 }
2805 2881
2882 for (i = 0; i < cfg->hp_outs; i++) {
2883 nid = cfg->hp_pins[i];
2884 dac = get_unassigned_dac(codec, nid);
2885 if (dac) {
2886 if (!spec->multiout.hp_nid)
2887 spec->multiout.hp_nid = dac;
2888 else
2889 add_spec_extra_dacs(spec, dac);
2806 } 2890 }
2891 spec->hp_dacs[i] = dac;
2892 }
2893
2894 for (i = 0; i < cfg->speaker_outs; i++) {
2895 nid = cfg->speaker_pins[i];
2896 dac = get_unassigned_dac(codec, nid);
2897 if (dac)
2898 add_spec_extra_dacs(spec, dac);
2899 spec->speaker_dacs[i] = dac;
2807 } 2900 }
2808 2901
2809 snd_printd("dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n", 2902 snd_printd("stac92xx: dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
2810 spec->multiout.num_dacs, 2903 spec->multiout.num_dacs,
2811 spec->multiout.dac_nids[0], 2904 spec->multiout.dac_nids[0],
2812 spec->multiout.dac_nids[1], 2905 spec->multiout.dac_nids[1],
2813 spec->multiout.dac_nids[2], 2906 spec->multiout.dac_nids[2],
2814 spec->multiout.dac_nids[3], 2907 spec->multiout.dac_nids[3],
2815 spec->multiout.dac_nids[4]); 2908 spec->multiout.dac_nids[4]);
2909
2816 return 0; 2910 return 0;
2817} 2911}
2818 2912
@@ -2837,9 +2931,7 @@ static int create_controls(struct sigmatel_spec *spec, const char *pfx, hda_nid_
2837 2931
2838static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid) 2932static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid)
2839{ 2933{
2840 if (!spec->multiout.hp_nid) 2934 if (spec->multiout.num_dacs > 4) {
2841 spec->multiout.hp_nid = nid;
2842 else if (spec->multiout.num_dacs > 4) {
2843 printk(KERN_WARNING "stac92xx: No space for DAC 0x%x\n", nid); 2935 printk(KERN_WARNING "stac92xx: No space for DAC 0x%x\n", nid);
2844 return 1; 2936 return 1;
2845 } else { 2937 } else {
@@ -2849,35 +2941,47 @@ static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid)
2849 return 0; 2941 return 0;
2850} 2942}
2851 2943
2852static int check_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid) 2944static int add_spec_extra_dacs(struct sigmatel_spec *spec, hda_nid_t nid)
2853{ 2945{
2854 if (is_in_dac_nids(spec, nid)) 2946 int i;
2855 return 1; 2947 for (i = 0; i < ARRAY_SIZE(spec->multiout.extra_out_nid); i++) {
2948 if (!spec->multiout.extra_out_nid[i]) {
2949 spec->multiout.extra_out_nid[i] = nid;
2950 return 0;
2951 }
2952 }
2953 printk(KERN_WARNING "stac92xx: No space for extra DAC 0x%x\n", nid);
2954 return 1;
2955}
2956
2957static int is_unique_dac(struct sigmatel_spec *spec, hda_nid_t nid)
2958{
2959 int i;
2960
2961 if (spec->autocfg.line_outs != 1)
2962 return 0;
2856 if (spec->multiout.hp_nid == nid) 2963 if (spec->multiout.hp_nid == nid)
2857 return 1; 2964 return 0;
2858 return 0; 2965 for (i = 0; i < ARRAY_SIZE(spec->multiout.extra_out_nid); i++)
2966 if (spec->multiout.extra_out_nid[i] == nid)
2967 return 0;
2968 return 1;
2859} 2969}
2860 2970
2861/* add playback controls from the parsed DAC table */ 2971/* add playback controls from the parsed DAC table */
2862static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec, 2972static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec,
2863 const struct auto_pin_cfg *cfg) 2973 const struct auto_pin_cfg *cfg)
2864{ 2974{
2975 struct sigmatel_spec *spec = codec->spec;
2865 static const char *chname[4] = { 2976 static const char *chname[4] = {
2866 "Front", "Surround", NULL /*CLFE*/, "Side" 2977 "Front", "Surround", NULL /*CLFE*/, "Side"
2867 }; 2978 };
2868 hda_nid_t nid = 0; 2979 hda_nid_t nid = 0;
2869 int i, err; 2980 int i, err;
2981 unsigned int wid_caps;
2870 2982
2871 struct sigmatel_spec *spec = codec->spec; 2983 for (i = 0; i < cfg->line_outs && spec->multiout.dac_nids[i]; i++) {
2872 unsigned int wid_caps, pincap;
2873
2874
2875 for (i = 0; i < cfg->line_outs && i < spec->multiout.num_dacs; i++) {
2876 if (!spec->multiout.dac_nids[i])
2877 continue;
2878
2879 nid = spec->multiout.dac_nids[i]; 2984 nid = spec->multiout.dac_nids[i];
2880
2881 if (i == 2) { 2985 if (i == 2) {
2882 /* Center/LFE */ 2986 /* Center/LFE */
2883 err = create_controls(spec, "Center", nid, 1); 2987 err = create_controls(spec, "Center", nid, 1);
@@ -2899,16 +3003,24 @@ static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec,
2899 } 3003 }
2900 3004
2901 } else { 3005 } else {
2902 err = create_controls(spec, chname[i], nid, 3); 3006 const char *name = chname[i];
3007 /* if it's a single DAC, assign a better name */
3008 if (!i && is_unique_dac(spec, nid)) {
3009 switch (cfg->line_out_type) {
3010 case AUTO_PIN_HP_OUT:
3011 name = "Headphone";
3012 break;
3013 case AUTO_PIN_SPEAKER_OUT:
3014 name = "Speaker";
3015 break;
3016 }
3017 }
3018 err = create_controls(spec, name, nid, 3);
2903 if (err < 0) 3019 if (err < 0)
2904 return err; 3020 return err;
2905 } 3021 }
2906 } 3022 }
2907 3023
2908 if ((spec->multiout.num_dacs - cfg->line_outs) > 0 &&
2909 cfg->hp_outs == 1 && !spec->multiout.hp_nid)
2910 spec->multiout.hp_nid = nid;
2911
2912 if (cfg->hp_outs > 1 && cfg->line_out_type == AUTO_PIN_LINE_OUT) { 3024 if (cfg->hp_outs > 1 && cfg->line_out_type == AUTO_PIN_LINE_OUT) {
2913 err = stac92xx_add_control(spec, 3025 err = stac92xx_add_control(spec,
2914 STAC_CTL_WIDGET_HP_SWITCH, 3026 STAC_CTL_WIDGET_HP_SWITCH,
@@ -2919,45 +3031,19 @@ static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec,
2919 } 3031 }
2920 3032
2921 if (spec->line_switch) { 3033 if (spec->line_switch) {
2922 nid = cfg->input_pins[AUTO_PIN_LINE]; 3034 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_IO_SWITCH,
2923 pincap = snd_hda_param_read(codec, nid, 3035 "Line In as Output Switch",
2924 AC_PAR_PIN_CAP); 3036 spec->line_switch << 8);
2925 if (pincap & AC_PINCAP_OUT) { 3037 if (err < 0)
2926 err = stac92xx_add_control(spec, 3038 return err;
2927 STAC_CTL_WIDGET_IO_SWITCH,
2928 "Line In as Output Switch", nid << 8);
2929 if (err < 0)
2930 return err;
2931 }
2932 } 3039 }
2933 3040
2934 if (spec->mic_switch) { 3041 if (spec->mic_switch) {
2935 unsigned int def_conf; 3042 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_IO_SWITCH,
2936 unsigned int mic_pin = AUTO_PIN_MIC; 3043 "Mic as Output Switch",
2937again: 3044 (spec->mic_switch << 8) | 1);
2938 nid = cfg->input_pins[mic_pin]; 3045 if (err < 0)
2939 def_conf = snd_hda_codec_read(codec, nid, 0, 3046 return err;
2940 AC_VERB_GET_CONFIG_DEFAULT, 0);
2941 /* some laptops have an internal analog microphone
2942 * which can't be used as a output */
2943 if (get_defcfg_connect(def_conf) != AC_JACK_PORT_FIXED) {
2944 pincap = snd_hda_param_read(codec, nid,
2945 AC_PAR_PIN_CAP);
2946 if (pincap & AC_PINCAP_OUT) {
2947 err = stac92xx_add_control(spec,
2948 STAC_CTL_WIDGET_IO_SWITCH,
2949 "Mic as Output Switch", (nid << 8) | 1);
2950 nid = snd_hda_codec_read(codec, nid, 0,
2951 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
2952 if (!check_in_dac_nids(spec, nid))
2953 add_spec_dacs(spec, nid);
2954 if (err < 0)
2955 return err;
2956 }
2957 } else if (mic_pin == AUTO_PIN_MIC) {
2958 mic_pin = AUTO_PIN_FRONT_MIC;
2959 goto again;
2960 }
2961 } 3047 }
2962 3048
2963 return 0; 3049 return 0;
@@ -2969,55 +3055,39 @@ static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec,
2969{ 3055{
2970 struct sigmatel_spec *spec = codec->spec; 3056 struct sigmatel_spec *spec = codec->spec;
2971 hda_nid_t nid; 3057 hda_nid_t nid;
2972 int i, old_num_dacs, err; 3058 int i, err, nums;
2973 3059
2974 old_num_dacs = spec->multiout.num_dacs; 3060 nums = 0;
2975 for (i = 0; i < cfg->hp_outs; i++) { 3061 for (i = 0; i < cfg->hp_outs; i++) {
3062 static const char *pfxs[] = {
3063 "Headphone", "Headphone2", "Headphone3",
3064 };
2976 unsigned int wid_caps = get_wcaps(codec, cfg->hp_pins[i]); 3065 unsigned int wid_caps = get_wcaps(codec, cfg->hp_pins[i]);
2977 if (wid_caps & AC_WCAP_UNSOL_CAP) 3066 if (wid_caps & AC_WCAP_UNSOL_CAP)
2978 spec->hp_detect = 1; 3067 spec->hp_detect = 1;
2979 nid = snd_hda_codec_read(codec, cfg->hp_pins[i], 0, 3068 if (nums >= ARRAY_SIZE(pfxs))
2980 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
2981 if (check_in_dac_nids(spec, nid))
2982 nid = 0;
2983 if (! nid)
2984 continue; 3069 continue;
2985 add_spec_dacs(spec, nid); 3070 nid = spec->hp_dacs[i];
2986 } 3071 if (!nid)
2987 for (i = 0; i < cfg->speaker_outs; i++) {
2988 nid = snd_hda_codec_read(codec, cfg->speaker_pins[i], 0,
2989 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
2990 if (check_in_dac_nids(spec, nid))
2991 nid = 0;
2992 if (! nid)
2993 continue; 3072 continue;
2994 add_spec_dacs(spec, nid); 3073 err = create_controls(spec, pfxs[nums++], nid, 3);
2995 } 3074 if (err < 0)
2996 for (i = 0; i < cfg->line_outs; i++) { 3075 return err;
2997 nid = snd_hda_codec_read(codec, cfg->line_out_pins[i], 0,
2998 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
2999 if (check_in_dac_nids(spec, nid))
3000 nid = 0;
3001 if (! nid)
3002 continue;
3003 add_spec_dacs(spec, nid);
3004 } 3076 }
3005 for (i = old_num_dacs; i < spec->multiout.num_dacs; i++) { 3077 nums = 0;
3078 for (i = 0; i < cfg->speaker_outs; i++) {
3006 static const char *pfxs[] = { 3079 static const char *pfxs[] = {
3007 "Speaker", "External Speaker", "Speaker2", 3080 "Speaker", "External Speaker", "Speaker2",
3008 }; 3081 };
3009 err = create_controls(spec, pfxs[i - old_num_dacs], 3082 if (nums >= ARRAY_SIZE(pfxs))
3010 spec->multiout.dac_nids[i], 3); 3083 continue;
3011 if (err < 0) 3084 nid = spec->speaker_dacs[i];
3012 return err; 3085 if (!nid)
3013 } 3086 continue;
3014 if (spec->multiout.hp_nid) { 3087 err = create_controls(spec, pfxs[nums++], nid, 3);
3015 err = create_controls(spec, "Headphone",
3016 spec->multiout.hp_nid, 3);
3017 if (err < 0) 3088 if (err < 0)
3018 return err; 3089 return err;
3019 } 3090 }
3020
3021 return 0; 3091 return 0;
3022} 3092}
3023 3093
@@ -3355,7 +3425,6 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
3355{ 3425{
3356 struct sigmatel_spec *spec = codec->spec; 3426 struct sigmatel_spec *spec = codec->spec;
3357 int err; 3427 int err;
3358 int hp_speaker_swap = 0;
3359 3428
3360 if ((err = snd_hda_parse_pin_def_config(codec, 3429 if ((err = snd_hda_parse_pin_def_config(codec,
3361 &spec->autocfg, 3430 &spec->autocfg,
@@ -3373,13 +3442,15 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
3373 * speaker_outs so that the following routines can handle 3442 * speaker_outs so that the following routines can handle
3374 * HP pins as primary outputs. 3443 * HP pins as primary outputs.
3375 */ 3444 */
3445 snd_printdd("stac92xx: Enabling multi-HPs workaround\n");
3376 memcpy(spec->autocfg.speaker_pins, spec->autocfg.line_out_pins, 3446 memcpy(spec->autocfg.speaker_pins, spec->autocfg.line_out_pins,
3377 sizeof(spec->autocfg.line_out_pins)); 3447 sizeof(spec->autocfg.line_out_pins));
3378 spec->autocfg.speaker_outs = spec->autocfg.line_outs; 3448 spec->autocfg.speaker_outs = spec->autocfg.line_outs;
3379 memcpy(spec->autocfg.line_out_pins, spec->autocfg.hp_pins, 3449 memcpy(spec->autocfg.line_out_pins, spec->autocfg.hp_pins,
3380 sizeof(spec->autocfg.hp_pins)); 3450 sizeof(spec->autocfg.hp_pins));
3381 spec->autocfg.line_outs = spec->autocfg.hp_outs; 3451 spec->autocfg.line_outs = spec->autocfg.hp_outs;
3382 hp_speaker_swap = 1; 3452 spec->autocfg.line_out_type = AUTO_PIN_HP_OUT;
3453 spec->autocfg.hp_outs = 0;
3383 } 3454 }
3384 if (spec->autocfg.mono_out_pin) { 3455 if (spec->autocfg.mono_out_pin) {
3385 int dir = get_wcaps(codec, spec->autocfg.mono_out_pin) & 3456 int dir = get_wcaps(codec, spec->autocfg.mono_out_pin) &
@@ -3431,11 +3502,11 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
3431 AC_PINCTL_OUT_EN); 3502 AC_PINCTL_OUT_EN);
3432 } 3503 }
3433 3504
3434 if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) < 0) 3505 if (!spec->multiout.num_dacs) {
3435 return err; 3506 err = stac92xx_auto_fill_dac_nids(codec);
3436 if (spec->multiout.num_dacs == 0) 3507 if (err < 0)
3437 if ((err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg)) < 0)
3438 return err; 3508 return err;
3509 }
3439 3510
3440 err = stac92xx_auto_create_multi_out_ctls(codec, &spec->autocfg); 3511 err = stac92xx_auto_create_multi_out_ctls(codec, &spec->autocfg);
3441 3512
@@ -3473,19 +3544,6 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
3473 } 3544 }
3474#endif 3545#endif
3475 3546
3476 if (hp_speaker_swap == 1) {
3477 /* Restore the hp_outs and line_outs */
3478 memcpy(spec->autocfg.hp_pins, spec->autocfg.line_out_pins,
3479 sizeof(spec->autocfg.line_out_pins));
3480 spec->autocfg.hp_outs = spec->autocfg.line_outs;
3481 memcpy(spec->autocfg.line_out_pins, spec->autocfg.speaker_pins,
3482 sizeof(spec->autocfg.speaker_pins));
3483 spec->autocfg.line_outs = spec->autocfg.speaker_outs;
3484 memset(spec->autocfg.speaker_pins, 0,
3485 sizeof(spec->autocfg.speaker_pins));
3486 spec->autocfg.speaker_outs = 0;
3487 }
3488
3489 err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg); 3547 err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg);
3490 3548
3491 if (err < 0) 3549 if (err < 0)
@@ -3530,11 +3588,12 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
3530 if (dig_in && spec->autocfg.dig_in_pin) 3588 if (dig_in && spec->autocfg.dig_in_pin)
3531 spec->dig_in_nid = dig_in; 3589 spec->dig_in_nid = dig_in;
3532 3590
3533 if (spec->kctl_alloc) 3591 if (spec->kctls.list)
3534 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 3592 spec->mixers[spec->num_mixers++] = spec->kctls.list;
3535 3593
3536 spec->input_mux = &spec->private_imux; 3594 spec->input_mux = &spec->private_imux;
3537 spec->dinput_mux = &spec->private_dimux; 3595 if (!spec->dinput_mux)
3596 spec->dinput_mux = &spec->private_dimux;
3538 spec->sinput_mux = &spec->private_smux; 3597 spec->sinput_mux = &spec->private_smux;
3539 spec->mono_mux = &spec->private_mono_mux; 3598 spec->mono_mux = &spec->private_mono_mux;
3540 spec->amp_mux = &spec->private_amp_mux; 3599 spec->amp_mux = &spec->private_amp_mux;
@@ -3638,8 +3697,8 @@ static int stac9200_parse_auto_config(struct hda_codec *codec)
3638 if (spec->autocfg.dig_in_pin) 3697 if (spec->autocfg.dig_in_pin)
3639 spec->dig_in_nid = 0x04; 3698 spec->dig_in_nid = 0x04;
3640 3699
3641 if (spec->kctl_alloc) 3700 if (spec->kctls.list)
3642 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 3701 spec->mixers[spec->num_mixers++] = spec->kctls.list;
3643 3702
3644 spec->input_mux = &spec->private_imux; 3703 spec->input_mux = &spec->private_imux;
3645 spec->dinput_mux = &spec->private_dimux; 3704 spec->dinput_mux = &spec->private_dimux;
@@ -3683,13 +3742,101 @@ static void stac_gpio_set(struct hda_codec *codec, unsigned int mask,
3683 AC_VERB_SET_GPIO_DATA, gpiostate); /* sync */ 3742 AC_VERB_SET_GPIO_DATA, gpiostate); /* sync */
3684} 3743}
3685 3744
3745static int stac92xx_add_jack(struct hda_codec *codec,
3746 hda_nid_t nid, int type)
3747{
3748#ifdef CONFIG_SND_JACK
3749 struct sigmatel_spec *spec = codec->spec;
3750 struct sigmatel_jack *jack;
3751 int def_conf = snd_hda_codec_read(codec, nid,
3752 0, AC_VERB_GET_CONFIG_DEFAULT, 0);
3753 int connectivity = get_defcfg_connect(def_conf);
3754 char name[32];
3755
3756 if (connectivity && connectivity != AC_JACK_PORT_FIXED)
3757 return 0;
3758
3759 snd_array_init(&spec->jacks, sizeof(*jack), 32);
3760 jack = snd_array_new(&spec->jacks);
3761 if (!jack)
3762 return -ENOMEM;
3763 jack->nid = nid;
3764 jack->type = type;
3765
3766 sprintf(name, "%s at %s %s Jack",
3767 snd_hda_get_jack_type(def_conf),
3768 snd_hda_get_jack_connectivity(def_conf),
3769 snd_hda_get_jack_location(def_conf));
3770
3771 return snd_jack_new(codec->bus->card, name, type, &jack->jack);
3772#else
3773 return 0;
3774#endif
3775}
3776
3777static int stac_add_event(struct sigmatel_spec *spec, hda_nid_t nid,
3778 unsigned char type, int data)
3779{
3780 struct sigmatel_event *event;
3781
3782 snd_array_init(&spec->events, sizeof(*event), 32);
3783 event = snd_array_new(&spec->events);
3784 if (!event)
3785 return -ENOMEM;
3786 event->nid = nid;
3787 event->type = type;
3788 event->tag = spec->events.used;
3789 event->data = data;
3790
3791 return event->tag;
3792}
3793
3794static struct sigmatel_event *stac_get_event(struct hda_codec *codec,
3795 hda_nid_t nid, unsigned char type)
3796{
3797 struct sigmatel_spec *spec = codec->spec;
3798 struct sigmatel_event *event = spec->events.list;
3799 int i;
3800
3801 for (i = 0; i < spec->events.used; i++, event++) {
3802 if (event->nid == nid && event->type == type)
3803 return event;
3804 }
3805 return NULL;
3806}
3807
3808static struct sigmatel_event *stac_get_event_from_tag(struct hda_codec *codec,
3809 unsigned char tag)
3810{
3811 struct sigmatel_spec *spec = codec->spec;
3812 struct sigmatel_event *event = spec->events.list;
3813 int i;
3814
3815 for (i = 0; i < spec->events.used; i++, event++) {
3816 if (event->tag == tag)
3817 return event;
3818 }
3819 return NULL;
3820}
3821
3686static void enable_pin_detect(struct hda_codec *codec, hda_nid_t nid, 3822static void enable_pin_detect(struct hda_codec *codec, hda_nid_t nid,
3687 unsigned int event) 3823 unsigned int type)
3688{ 3824{
3689 if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) 3825 struct sigmatel_event *event;
3690 snd_hda_codec_write_cache(codec, nid, 0, 3826 int tag;
3691 AC_VERB_SET_UNSOLICITED_ENABLE, 3827
3692 (AC_USRSP_EN | event)); 3828 if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP))
3829 return;
3830 event = stac_get_event(codec, nid, type);
3831 if (event)
3832 tag = event->tag;
3833 else
3834 tag = stac_add_event(codec->spec, nid, type, 0);
3835 if (tag < 0)
3836 return;
3837 snd_hda_codec_write_cache(codec, nid, 0,
3838 AC_VERB_SET_UNSOLICITED_ENABLE,
3839 AC_USRSP_EN | tag);
3693} 3840}
3694 3841
3695static int is_nid_hp_pin(struct auto_pin_cfg *cfg, hda_nid_t nid) 3842static int is_nid_hp_pin(struct auto_pin_cfg *cfg, hda_nid_t nid)
@@ -3709,9 +3856,8 @@ static void stac92xx_power_down(struct hda_codec *codec)
3709 /* power down inactive DACs */ 3856 /* power down inactive DACs */
3710 hda_nid_t *dac; 3857 hda_nid_t *dac;
3711 for (dac = spec->dac_list; *dac; dac++) 3858 for (dac = spec->dac_list; *dac; dac++)
3712 if (!is_in_dac_nids(spec, *dac) && 3859 if (!check_all_dac_nids(spec, *dac))
3713 spec->multiout.hp_nid != *dac) 3860 snd_hda_codec_write(codec, *dac, 0,
3714 snd_hda_codec_write_cache(codec, *dac, 0,
3715 AC_VERB_SET_POWER_STATE, AC_PWRST_D3); 3861 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
3716} 3862}
3717 3863
@@ -3730,7 +3876,7 @@ static int stac92xx_init(struct hda_codec *codec)
3730 /* power down adcs initially */ 3876 /* power down adcs initially */
3731 if (spec->powerdown_adcs) 3877 if (spec->powerdown_adcs)
3732 for (i = 0; i < spec->num_adcs; i++) 3878 for (i = 0; i < spec->num_adcs; i++)
3733 snd_hda_codec_write_cache(codec, 3879 snd_hda_codec_write(codec,
3734 spec->adc_nids[i], 0, 3880 spec->adc_nids[i], 0,
3735 AC_VERB_SET_POWER_STATE, AC_PWRST_D3); 3881 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
3736 3882
@@ -3746,37 +3892,51 @@ static int stac92xx_init(struct hda_codec *codec)
3746 /* set up pins */ 3892 /* set up pins */
3747 if (spec->hp_detect) { 3893 if (spec->hp_detect) {
3748 /* Enable unsolicited responses on the HP widget */ 3894 /* Enable unsolicited responses on the HP widget */
3749 for (i = 0; i < cfg->hp_outs; i++) 3895 for (i = 0; i < cfg->hp_outs; i++) {
3750 enable_pin_detect(codec, cfg->hp_pins[i], 3896 hda_nid_t nid = cfg->hp_pins[i];
3751 STAC_HP_EVENT); 3897 enable_pin_detect(codec, nid, STAC_HP_EVENT);
3898 }
3752 /* force to enable the first line-out; the others are set up 3899 /* force to enable the first line-out; the others are set up
3753 * in unsol_event 3900 * in unsol_event
3754 */ 3901 */
3755 stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0], 3902 stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0],
3756 AC_PINCTL_OUT_EN); 3903 AC_PINCTL_OUT_EN);
3757 stac92xx_auto_init_hp_out(codec);
3758 /* fake event to set up pins */ 3904 /* fake event to set up pins */
3759 codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26); 3905 stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0],
3906 STAC_HP_EVENT);
3760 } else { 3907 } else {
3761 stac92xx_auto_init_multi_out(codec); 3908 stac92xx_auto_init_multi_out(codec);
3762 stac92xx_auto_init_hp_out(codec); 3909 stac92xx_auto_init_hp_out(codec);
3910 for (i = 0; i < cfg->hp_outs; i++)
3911 stac_toggle_power_map(codec, cfg->hp_pins[i], 1);
3763 } 3912 }
3764 for (i = 0; i < AUTO_PIN_LAST; i++) { 3913 for (i = 0; i < AUTO_PIN_LAST; i++) {
3765 hda_nid_t nid = cfg->input_pins[i]; 3914 hda_nid_t nid = cfg->input_pins[i];
3766 if (nid) { 3915 if (nid) {
3767 unsigned int pinctl; 3916 unsigned int pinctl, conf;
3768 if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC) { 3917 if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC) {
3769 /* for mic pins, force to initialize */ 3918 /* for mic pins, force to initialize */
3770 pinctl = stac92xx_get_vref(codec, nid); 3919 pinctl = stac92xx_get_vref(codec, nid);
3920 pinctl |= AC_PINCTL_IN_EN;
3921 stac92xx_auto_set_pinctl(codec, nid, pinctl);
3771 } else { 3922 } else {
3772 pinctl = snd_hda_codec_read(codec, nid, 0, 3923 pinctl = snd_hda_codec_read(codec, nid, 0,
3773 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 3924 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3774 /* if PINCTL already set then skip */ 3925 /* if PINCTL already set then skip */
3775 if (pinctl & AC_PINCTL_IN_EN) 3926 if (!(pinctl & AC_PINCTL_IN_EN)) {
3776 continue; 3927 pinctl |= AC_PINCTL_IN_EN;
3928 stac92xx_auto_set_pinctl(codec, nid,
3929 pinctl);
3930 }
3931 }
3932 conf = snd_hda_codec_read(codec, nid, 0,
3933 AC_VERB_GET_CONFIG_DEFAULT, 0);
3934 if (get_defcfg_connect(conf) != AC_JACK_PORT_FIXED) {
3935 enable_pin_detect(codec, nid,
3936 STAC_INSERT_EVENT);
3937 stac_issue_unsol_event(codec, nid,
3938 STAC_INSERT_EVENT);
3777 } 3939 }
3778 pinctl |= AC_PINCTL_IN_EN;
3779 stac92xx_auto_set_pinctl(codec, nid, pinctl);
3780 } 3940 }
3781 } 3941 }
3782 for (i = 0; i < spec->num_dmics; i++) 3942 for (i = 0; i < spec->num_dmics; i++)
@@ -3791,9 +3951,14 @@ static int stac92xx_init(struct hda_codec *codec)
3791 for (i = 0; i < spec->num_pwrs; i++) { 3951 for (i = 0; i < spec->num_pwrs; i++) {
3792 hda_nid_t nid = spec->pwr_nids[i]; 3952 hda_nid_t nid = spec->pwr_nids[i];
3793 int pinctl, def_conf; 3953 int pinctl, def_conf;
3794 int event = STAC_PWR_EVENT;
3795 3954
3796 if (is_nid_hp_pin(cfg, nid) && spec->hp_detect) 3955 /* power on when no jack detection is available */
3956 if (!spec->hp_detect) {
3957 stac_toggle_power_map(codec, nid, 1);
3958 continue;
3959 }
3960
3961 if (is_nid_hp_pin(cfg, nid))
3797 continue; /* already has an unsol event */ 3962 continue; /* already has an unsol event */
3798 3963
3799 pinctl = snd_hda_codec_read(codec, nid, 0, 3964 pinctl = snd_hda_codec_read(codec, nid, 0,
@@ -3802,8 +3967,10 @@ static int stac92xx_init(struct hda_codec *codec)
3802 * any attempts on powering down a input port cause the 3967 * any attempts on powering down a input port cause the
3803 * referenced VREF to act quirky. 3968 * referenced VREF to act quirky.
3804 */ 3969 */
3805 if (pinctl & AC_PINCTL_IN_EN) 3970 if (pinctl & AC_PINCTL_IN_EN) {
3971 stac_toggle_power_map(codec, nid, 1);
3806 continue; 3972 continue;
3973 }
3807 def_conf = snd_hda_codec_read(codec, nid, 0, 3974 def_conf = snd_hda_codec_read(codec, nid, 0,
3808 AC_VERB_GET_CONFIG_DEFAULT, 0); 3975 AC_VERB_GET_CONFIG_DEFAULT, 0);
3809 def_conf = get_defcfg_connect(def_conf); 3976 def_conf = get_defcfg_connect(def_conf);
@@ -3814,30 +3981,54 @@ static int stac92xx_init(struct hda_codec *codec)
3814 stac_toggle_power_map(codec, nid, 1); 3981 stac_toggle_power_map(codec, nid, 1);
3815 continue; 3982 continue;
3816 } 3983 }
3817 enable_pin_detect(codec, spec->pwr_nids[i], event | i); 3984 if (!stac_get_event(codec, nid, STAC_INSERT_EVENT)) {
3818 codec->patch_ops.unsol_event(codec, (event | i) << 26); 3985 enable_pin_detect(codec, nid, STAC_PWR_EVENT);
3986 stac_issue_unsol_event(codec, nid, STAC_PWR_EVENT);
3987 }
3819 } 3988 }
3820 if (spec->dac_list) 3989 if (spec->dac_list)
3821 stac92xx_power_down(codec); 3990 stac92xx_power_down(codec);
3822 return 0; 3991 return 0;
3823} 3992}
3824 3993
3994static void stac92xx_free_jacks(struct hda_codec *codec)
3995{
3996#ifdef CONFIG_SND_JACK
3997 /* free jack instances manually when clearing/reconfiguring */
3998 struct sigmatel_spec *spec = codec->spec;
3999 if (!codec->bus->shutdown && spec->jacks.list) {
4000 struct sigmatel_jack *jacks = spec->jacks.list;
4001 int i;
4002 for (i = 0; i < spec->jacks.used; i++)
4003 snd_device_free(codec->bus->card, &jacks[i].jack);
4004 }
4005 snd_array_free(&spec->jacks);
4006#endif
4007}
4008
4009static void stac92xx_free_kctls(struct hda_codec *codec)
4010{
4011 struct sigmatel_spec *spec = codec->spec;
4012
4013 if (spec->kctls.list) {
4014 struct snd_kcontrol_new *kctl = spec->kctls.list;
4015 int i;
4016 for (i = 0; i < spec->kctls.used; i++)
4017 kfree(kctl[i].name);
4018 }
4019 snd_array_free(&spec->kctls);
4020}
4021
3825static void stac92xx_free(struct hda_codec *codec) 4022static void stac92xx_free(struct hda_codec *codec)
3826{ 4023{
3827 struct sigmatel_spec *spec = codec->spec; 4024 struct sigmatel_spec *spec = codec->spec;
3828 int i;
3829 4025
3830 if (! spec) 4026 if (! spec)
3831 return; 4027 return;
3832 4028
3833 if (spec->kctl_alloc) { 4029 kfree(spec->pin_configs);
3834 for (i = 0; i < spec->num_kctl_used; i++) 4030 stac92xx_free_jacks(codec);
3835 kfree(spec->kctl_alloc[i].name); 4031 snd_array_free(&spec->events);
3836 kfree(spec->kctl_alloc);
3837 }
3838
3839 if (spec->bios_pin_configs)
3840 kfree(spec->bios_pin_configs);
3841 4032
3842 kfree(spec); 4033 kfree(spec);
3843 snd_hda_detach_beep_device(codec); 4034 snd_hda_detach_beep_device(codec);
@@ -3856,11 +4047,7 @@ static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid,
3856 * "xxx as Output" mixer switch 4047 * "xxx as Output" mixer switch
3857 */ 4048 */
3858 struct sigmatel_spec *spec = codec->spec; 4049 struct sigmatel_spec *spec = codec->spec;
3859 struct auto_pin_cfg *cfg = &spec->autocfg; 4050 if (nid == spec->line_switch || nid == spec->mic_switch)
3860 if ((nid == cfg->input_pins[AUTO_PIN_LINE] &&
3861 spec->line_switch) ||
3862 (nid == cfg->input_pins[AUTO_PIN_MIC] &&
3863 spec->mic_switch))
3864 return; 4051 return;
3865 } 4052 }
3866 4053
@@ -3884,20 +4071,13 @@ static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid,
3884 pin_ctl & ~flag); 4071 pin_ctl & ~flag);
3885} 4072}
3886 4073
3887static int get_hp_pin_presence(struct hda_codec *codec, hda_nid_t nid) 4074static int get_pin_presence(struct hda_codec *codec, hda_nid_t nid)
3888{ 4075{
3889 if (!nid) 4076 if (!nid)
3890 return 0; 4077 return 0;
3891 if (snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_SENSE, 0x00) 4078 if (snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_SENSE, 0x00)
3892 & (1 << 31)) { 4079 & (1 << 31))
3893 unsigned int pinctl; 4080 return 1;
3894 pinctl = snd_hda_codec_read(codec, nid, 0,
3895 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3896 if (pinctl & AC_PINCTL_IN_EN)
3897 return 0; /* mic- or line-input */
3898 else
3899 return 1; /* HP-output */
3900 }
3901 return 0; 4081 return 0;
3902} 4082}
3903 4083
@@ -3909,11 +4089,9 @@ static int no_hp_sensing(struct sigmatel_spec *spec, int i)
3909 struct auto_pin_cfg *cfg = &spec->autocfg; 4089 struct auto_pin_cfg *cfg = &spec->autocfg;
3910 4090
3911 /* ignore sensing of shared line and mic jacks */ 4091 /* ignore sensing of shared line and mic jacks */
3912 if (spec->line_switch && 4092 if (cfg->hp_pins[i] == spec->line_switch)
3913 cfg->hp_pins[i] == cfg->input_pins[AUTO_PIN_LINE])
3914 return 1; 4093 return 1;
3915 if (spec->mic_switch && 4094 if (cfg->hp_pins[i] == spec->mic_switch)
3916 cfg->hp_pins[i] == cfg->input_pins[AUTO_PIN_MIC])
3917 return 1; 4095 return 1;
3918 /* ignore if the pin is set as line-out */ 4096 /* ignore if the pin is set as line-out */
3919 if (cfg->hp_pins[i] == spec->hp_switch) 4097 if (cfg->hp_pins[i] == spec->hp_switch)
@@ -3921,7 +4099,7 @@ static int no_hp_sensing(struct sigmatel_spec *spec, int i)
3921 return 0; 4099 return 0;
3922} 4100}
3923 4101
3924static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res) 4102static void stac92xx_hp_detect(struct hda_codec *codec)
3925{ 4103{
3926 struct sigmatel_spec *spec = codec->spec; 4104 struct sigmatel_spec *spec = codec->spec;
3927 struct auto_pin_cfg *cfg = &spec->autocfg; 4105 struct auto_pin_cfg *cfg = &spec->autocfg;
@@ -3937,7 +4115,14 @@ static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res)
3937 break; 4115 break;
3938 if (no_hp_sensing(spec, i)) 4116 if (no_hp_sensing(spec, i))
3939 continue; 4117 continue;
3940 presence = get_hp_pin_presence(codec, cfg->hp_pins[i]); 4118 presence = get_pin_presence(codec, cfg->hp_pins[i]);
4119 if (presence) {
4120 unsigned int pinctl;
4121 pinctl = snd_hda_codec_read(codec, cfg->hp_pins[i], 0,
4122 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4123 if (pinctl & AC_PINCTL_IN_EN)
4124 presence = 0; /* mic- or line-input */
4125 }
3941 } 4126 }
3942 4127
3943 if (presence) { 4128 if (presence) {
@@ -4014,50 +4199,145 @@ static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid,
4014 4199
4015static void stac92xx_pin_sense(struct hda_codec *codec, hda_nid_t nid) 4200static void stac92xx_pin_sense(struct hda_codec *codec, hda_nid_t nid)
4016{ 4201{
4017 stac_toggle_power_map(codec, nid, get_hp_pin_presence(codec, nid)); 4202 stac_toggle_power_map(codec, nid, get_pin_presence(codec, nid));
4203}
4204
4205static void stac92xx_report_jack(struct hda_codec *codec, hda_nid_t nid)
4206{
4207 struct sigmatel_spec *spec = codec->spec;
4208 struct sigmatel_jack *jacks = spec->jacks.list;
4209
4210 if (jacks) {
4211 int i;
4212 for (i = 0; i < spec->jacks.used; i++) {
4213 if (jacks->nid == nid) {
4214 unsigned int pin_ctl =
4215 snd_hda_codec_read(codec, nid,
4216 0, AC_VERB_GET_PIN_WIDGET_CONTROL,
4217 0x00);
4218 int type = jacks->type;
4219 if (type == (SND_JACK_LINEOUT
4220 | SND_JACK_HEADPHONE))
4221 type = (pin_ctl & AC_PINCTL_HP_EN)
4222 ? SND_JACK_HEADPHONE : SND_JACK_LINEOUT;
4223 snd_jack_report(jacks->jack,
4224 get_pin_presence(codec, nid)
4225 ? type : 0);
4226 }
4227 jacks++;
4228 }
4229 }
4230}
4231
4232static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid,
4233 unsigned char type)
4234{
4235 struct sigmatel_event *event = stac_get_event(codec, nid, type);
4236 if (!event)
4237 return;
4238 codec->patch_ops.unsol_event(codec, (unsigned)event->tag << 26);
4018} 4239}
4019 4240
4020static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) 4241static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
4021{ 4242{
4022 struct sigmatel_spec *spec = codec->spec; 4243 struct sigmatel_spec *spec = codec->spec;
4023 int idx = res >> 26 & 0x0f; 4244 struct sigmatel_event *event;
4245 int tag, data;
4024 4246
4025 switch ((res >> 26) & 0x70) { 4247 tag = (res >> 26) & 0x7f;
4248 event = stac_get_event_from_tag(codec, tag);
4249 if (!event)
4250 return;
4251
4252 switch (event->type) {
4026 case STAC_HP_EVENT: 4253 case STAC_HP_EVENT:
4027 stac92xx_hp_detect(codec, res); 4254 stac92xx_hp_detect(codec);
4028 /* fallthru */ 4255 /* fallthru */
4256 case STAC_INSERT_EVENT:
4029 case STAC_PWR_EVENT: 4257 case STAC_PWR_EVENT:
4030 if (spec->num_pwrs > 0) 4258 if (spec->num_pwrs > 0)
4031 stac92xx_pin_sense(codec, idx); 4259 stac92xx_pin_sense(codec, event->nid);
4260 stac92xx_report_jack(codec, event->nid);
4032 break; 4261 break;
4033 case STAC_VREF_EVENT: { 4262 case STAC_VREF_EVENT:
4034 int data = snd_hda_codec_read(codec, codec->afg, 0, 4263 data = snd_hda_codec_read(codec, codec->afg, 0,
4035 AC_VERB_GET_GPIO_DATA, 0); 4264 AC_VERB_GET_GPIO_DATA, 0);
4036 /* toggle VREF state based on GPIOx status */ 4265 /* toggle VREF state based on GPIOx status */
4037 snd_hda_codec_write(codec, codec->afg, 0, 0x7e0, 4266 snd_hda_codec_write(codec, codec->afg, 0, 0x7e0,
4038 !!(data & (1 << idx))); 4267 !!(data & (1 << event->data)));
4039 break; 4268 break;
4040 }
4041 } 4269 }
4042} 4270}
4043 4271
4272#ifdef CONFIG_PROC_FS
4273static void stac92hd_proc_hook(struct snd_info_buffer *buffer,
4274 struct hda_codec *codec, hda_nid_t nid)
4275{
4276 if (nid == codec->afg)
4277 snd_iprintf(buffer, "Power-Map: 0x%02x\n",
4278 snd_hda_codec_read(codec, nid, 0, 0x0fec, 0x0));
4279}
4280
4281static void analog_loop_proc_hook(struct snd_info_buffer *buffer,
4282 struct hda_codec *codec,
4283 unsigned int verb)
4284{
4285 snd_iprintf(buffer, "Analog Loopback: 0x%02x\n",
4286 snd_hda_codec_read(codec, codec->afg, 0, verb, 0));
4287}
4288
4289/* stac92hd71bxx, stac92hd73xx */
4290static void stac92hd7x_proc_hook(struct snd_info_buffer *buffer,
4291 struct hda_codec *codec, hda_nid_t nid)
4292{
4293 stac92hd_proc_hook(buffer, codec, nid);
4294 if (nid == codec->afg)
4295 analog_loop_proc_hook(buffer, codec, 0xfa0);
4296}
4297
4298static void stac9205_proc_hook(struct snd_info_buffer *buffer,
4299 struct hda_codec *codec, hda_nid_t nid)
4300{
4301 if (nid == codec->afg)
4302 analog_loop_proc_hook(buffer, codec, 0xfe0);
4303}
4304
4305static void stac927x_proc_hook(struct snd_info_buffer *buffer,
4306 struct hda_codec *codec, hda_nid_t nid)
4307{
4308 if (nid == codec->afg)
4309 analog_loop_proc_hook(buffer, codec, 0xfeb);
4310}
4311#else
4312#define stac92hd_proc_hook NULL
4313#define stac92hd7x_proc_hook NULL
4314#define stac9205_proc_hook NULL
4315#define stac927x_proc_hook NULL
4316#endif
4317
4044#ifdef SND_HDA_NEEDS_RESUME 4318#ifdef SND_HDA_NEEDS_RESUME
4045static int stac92xx_resume(struct hda_codec *codec) 4319static int stac92xx_resume(struct hda_codec *codec)
4046{ 4320{
4047 struct sigmatel_spec *spec = codec->spec; 4321 struct sigmatel_spec *spec = codec->spec;
4048 4322
4049 stac92xx_set_config_regs(codec); 4323 stac92xx_set_config_regs(codec);
4050 snd_hda_sequence_write(codec, spec->init); 4324 stac92xx_init(codec);
4051 stac_gpio_set(codec, spec->gpio_mask,
4052 spec->gpio_dir, spec->gpio_data);
4053 snd_hda_codec_resume_amp(codec); 4325 snd_hda_codec_resume_amp(codec);
4054 snd_hda_codec_resume_cache(codec); 4326 snd_hda_codec_resume_cache(codec);
4055 /* power down inactive DACs */ 4327 /* fake event to set up pins again to override cached values */
4056 if (spec->dac_list)
4057 stac92xx_power_down(codec);
4058 /* invoke unsolicited event to reset the HP state */
4059 if (spec->hp_detect) 4328 if (spec->hp_detect)
4060 codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26); 4329 stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0],
4330 STAC_HP_EVENT);
4331 return 0;
4332}
4333
4334static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state)
4335{
4336 struct sigmatel_spec *spec = codec->spec;
4337 if (spec->eapd_mask)
4338 stac_gpio_set(codec, spec->gpio_mask,
4339 spec->gpio_dir, spec->gpio_data &
4340 ~spec->eapd_mask);
4061 return 0; 4341 return 0;
4062} 4342}
4063#endif 4343#endif
@@ -4069,6 +4349,7 @@ static struct hda_codec_ops stac92xx_patch_ops = {
4069 .free = stac92xx_free, 4349 .free = stac92xx_free,
4070 .unsol_event = stac92xx_unsol_event, 4350 .unsol_event = stac92xx_unsol_event,
4071#ifdef SND_HDA_NEEDS_RESUME 4351#ifdef SND_HDA_NEEDS_RESUME
4352 .suspend = stac92xx_suspend,
4072 .resume = stac92xx_resume, 4353 .resume = stac92xx_resume,
4073#endif 4354#endif
4074}; 4355};
@@ -4091,14 +4372,12 @@ static int patch_stac9200(struct hda_codec *codec)
4091 if (spec->board_config < 0) { 4372 if (spec->board_config < 0) {
4092 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9200, using BIOS defaults\n"); 4373 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9200, using BIOS defaults\n");
4093 err = stac92xx_save_bios_config_regs(codec); 4374 err = stac92xx_save_bios_config_regs(codec);
4094 if (err < 0) { 4375 } else
4095 stac92xx_free(codec); 4376 err = stac_save_pin_cfgs(codec,
4096 return err; 4377 stac9200_brd_tbl[spec->board_config]);
4097 } 4378 if (err < 0) {
4098 spec->pin_configs = spec->bios_pin_configs; 4379 stac92xx_free(codec);
4099 } else { 4380 return err;
4100 spec->pin_configs = stac9200_brd_tbl[spec->board_config];
4101 stac92xx_set_config_regs(codec);
4102 } 4381 }
4103 4382
4104 spec->multiout.max_channels = 2; 4383 spec->multiout.max_channels = 2;
@@ -4154,14 +4433,12 @@ static int patch_stac925x(struct hda_codec *codec)
4154 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC925x," 4433 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC925x,"
4155 "using BIOS defaults\n"); 4434 "using BIOS defaults\n");
4156 err = stac92xx_save_bios_config_regs(codec); 4435 err = stac92xx_save_bios_config_regs(codec);
4157 if (err < 0) { 4436 } else
4158 stac92xx_free(codec); 4437 err = stac_save_pin_cfgs(codec,
4159 return err; 4438 stac925x_brd_tbl[spec->board_config]);
4160 } 4439 if (err < 0) {
4161 spec->pin_configs = spec->bios_pin_configs; 4440 stac92xx_free(codec);
4162 } else if (stac925x_brd_tbl[spec->board_config] != NULL){ 4441 return err;
4163 spec->pin_configs = stac925x_brd_tbl[spec->board_config];
4164 stac92xx_set_config_regs(codec);
4165 } 4442 }
4166 4443
4167 spec->multiout.max_channels = 2; 4444 spec->multiout.max_channels = 2;
@@ -4225,6 +4502,7 @@ static int patch_stac92hd73xx(struct hda_codec *codec)
4225 struct sigmatel_spec *spec; 4502 struct sigmatel_spec *spec;
4226 hda_nid_t conn[STAC92HD73_DAC_COUNT + 2]; 4503 hda_nid_t conn[STAC92HD73_DAC_COUNT + 2];
4227 int err = 0; 4504 int err = 0;
4505 int num_dacs;
4228 4506
4229 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 4507 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4230 if (spec == NULL) 4508 if (spec == NULL)
@@ -4243,43 +4521,37 @@ again:
4243 snd_printdd(KERN_INFO "hda_codec: Unknown model for" 4521 snd_printdd(KERN_INFO "hda_codec: Unknown model for"
4244 " STAC92HD73XX, using BIOS defaults\n"); 4522 " STAC92HD73XX, using BIOS defaults\n");
4245 err = stac92xx_save_bios_config_regs(codec); 4523 err = stac92xx_save_bios_config_regs(codec);
4246 if (err < 0) { 4524 } else
4247 stac92xx_free(codec); 4525 err = stac_save_pin_cfgs(codec,
4248 return err; 4526 stac92hd73xx_brd_tbl[spec->board_config]);
4249 } 4527 if (err < 0) {
4250 spec->pin_configs = spec->bios_pin_configs; 4528 stac92xx_free(codec);
4251 } else { 4529 return err;
4252 spec->pin_configs = stac92hd73xx_brd_tbl[spec->board_config];
4253 stac92xx_set_config_regs(codec);
4254 } 4530 }
4255 4531
4256 spec->multiout.num_dacs = snd_hda_get_connections(codec, 0x0a, 4532 num_dacs = snd_hda_get_connections(codec, 0x0a,
4257 conn, STAC92HD73_DAC_COUNT + 2) - 1; 4533 conn, STAC92HD73_DAC_COUNT + 2) - 1;
4258 4534
4259 if (spec->multiout.num_dacs < 0) { 4535 if (num_dacs < 3 || num_dacs > 5) {
4260 printk(KERN_WARNING "hda_codec: Could not determine " 4536 printk(KERN_WARNING "hda_codec: Could not determine "
4261 "number of channels defaulting to DAC count\n"); 4537 "number of channels defaulting to DAC count\n");
4262 spec->multiout.num_dacs = STAC92HD73_DAC_COUNT; 4538 num_dacs = STAC92HD73_DAC_COUNT;
4263 } 4539 }
4264 4540 switch (num_dacs) {
4265 switch (spec->multiout.num_dacs) {
4266 case 0x3: /* 6 Channel */ 4541 case 0x3: /* 6 Channel */
4267 spec->multiout.hp_nid = 0x17;
4268 spec->mixer = stac92hd73xx_6ch_mixer; 4542 spec->mixer = stac92hd73xx_6ch_mixer;
4269 spec->init = stac92hd73xx_6ch_core_init; 4543 spec->init = stac92hd73xx_6ch_core_init;
4270 break; 4544 break;
4271 case 0x4: /* 8 Channel */ 4545 case 0x4: /* 8 Channel */
4272 spec->multiout.hp_nid = 0x18;
4273 spec->mixer = stac92hd73xx_8ch_mixer; 4546 spec->mixer = stac92hd73xx_8ch_mixer;
4274 spec->init = stac92hd73xx_8ch_core_init; 4547 spec->init = stac92hd73xx_8ch_core_init;
4275 break; 4548 break;
4276 case 0x5: /* 10 Channel */ 4549 case 0x5: /* 10 Channel */
4277 spec->multiout.hp_nid = 0x19;
4278 spec->mixer = stac92hd73xx_10ch_mixer; 4550 spec->mixer = stac92hd73xx_10ch_mixer;
4279 spec->init = stac92hd73xx_10ch_core_init; 4551 spec->init = stac92hd73xx_10ch_core_init;
4280 }; 4552 }
4553 spec->multiout.dac_nids = spec->dac_nids;
4281 4554
4282 spec->multiout.dac_nids = stac92hd73xx_dac_nids;
4283 spec->aloopback_mask = 0x01; 4555 spec->aloopback_mask = 0x01;
4284 spec->aloopback_shift = 8; 4556 spec->aloopback_shift = 8;
4285 4557
@@ -4310,9 +4582,8 @@ again:
4310 spec->amp_nids = &stac92hd73xx_amp_nids[DELL_M6_AMP]; 4582 spec->amp_nids = &stac92hd73xx_amp_nids[DELL_M6_AMP];
4311 spec->eapd_switch = 0; 4583 spec->eapd_switch = 0;
4312 spec->num_amps = 1; 4584 spec->num_amps = 1;
4313 spec->multiout.hp_nid = 0; /* dual HPs */
4314 4585
4315 if (!spec->init) 4586 if (spec->board_config != STAC_DELL_EQ)
4316 spec->init = dell_m6_core_init; 4587 spec->init = dell_m6_core_init;
4317 switch (spec->board_config) { 4588 switch (spec->board_config) {
4318 case STAC_DELL_M6_AMIC: /* Analog Mics */ 4589 case STAC_DELL_M6_AMIC: /* Analog Mics */
@@ -4370,6 +4641,8 @@ again:
4370 4641
4371 codec->patch_ops = stac92xx_patch_ops; 4642 codec->patch_ops = stac92xx_patch_ops;
4372 4643
4644 codec->proc_widget_hook = stac92hd7x_proc_hook;
4645
4373 return 0; 4646 return 0;
4374} 4647}
4375 4648
@@ -4401,17 +4674,15 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
4401 spec->pwr_nids = stac92hd83xxx_pwr_nids; 4674 spec->pwr_nids = stac92hd83xxx_pwr_nids;
4402 spec->pwr_mapping = stac92hd83xxx_pwr_mapping; 4675 spec->pwr_mapping = stac92hd83xxx_pwr_mapping;
4403 spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids); 4676 spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids);
4404 spec->multiout.dac_nids = stac92hd83xxx_dac_nids; 4677 spec->multiout.dac_nids = spec->dac_nids;
4405 4678
4406 spec->init = stac92hd83xxx_core_init; 4679 spec->init = stac92hd83xxx_core_init;
4407 switch (codec->vendor_id) { 4680 switch (codec->vendor_id) {
4408 case 0x111d7605: 4681 case 0x111d7605:
4409 spec->multiout.num_dacs = STAC92HD81_DAC_COUNT;
4410 break; 4682 break;
4411 default: 4683 default:
4412 spec->num_pwrs--; 4684 spec->num_pwrs--;
4413 spec->init++; /* switch to config #2 */ 4685 spec->init++; /* switch to config #2 */
4414 spec->multiout.num_dacs = STAC92HD83_DAC_COUNT;
4415 } 4686 }
4416 4687
4417 spec->mixer = stac92hd83xxx_mixer; 4688 spec->mixer = stac92hd83xxx_mixer;
@@ -4430,14 +4701,12 @@ again:
4430 snd_printdd(KERN_INFO "hda_codec: Unknown model for" 4701 snd_printdd(KERN_INFO "hda_codec: Unknown model for"
4431 " STAC92HD83XXX, using BIOS defaults\n"); 4702 " STAC92HD83XXX, using BIOS defaults\n");
4432 err = stac92xx_save_bios_config_regs(codec); 4703 err = stac92xx_save_bios_config_regs(codec);
4433 if (err < 0) { 4704 } else
4434 stac92xx_free(codec); 4705 err = stac_save_pin_cfgs(codec,
4435 return err; 4706 stac92hd83xxx_brd_tbl[spec->board_config]);
4436 } 4707 if (err < 0) {
4437 spec->pin_configs = spec->bios_pin_configs; 4708 stac92xx_free(codec);
4438 } else { 4709 return err;
4439 spec->pin_configs = stac92hd83xxx_brd_tbl[spec->board_config];
4440 stac92xx_set_config_regs(codec);
4441 } 4710 }
4442 4711
4443 err = stac92xx_parse_auto_config(codec, 0x1d, 0); 4712 err = stac92xx_parse_auto_config(codec, 0x1d, 0);
@@ -4458,56 +4727,10 @@ again:
4458 4727
4459 codec->patch_ops = stac92xx_patch_ops; 4728 codec->patch_ops = stac92xx_patch_ops;
4460 4729
4461 return 0; 4730 codec->proc_widget_hook = stac92hd_proc_hook;
4462}
4463 4731
4464#ifdef SND_HDA_NEEDS_RESUME
4465static void stac92hd71xx_set_power_state(struct hda_codec *codec, int pwr)
4466{
4467 struct sigmatel_spec *spec = codec->spec;
4468 int i;
4469 snd_hda_codec_write_cache(codec, codec->afg, 0,
4470 AC_VERB_SET_POWER_STATE, pwr);
4471
4472 msleep(1);
4473 for (i = 0; i < spec->num_adcs; i++) {
4474 snd_hda_codec_write_cache(codec,
4475 spec->adc_nids[i], 0,
4476 AC_VERB_SET_POWER_STATE, pwr);
4477 }
4478};
4479
4480static int stac92hd71xx_resume(struct hda_codec *codec)
4481{
4482 stac92hd71xx_set_power_state(codec, AC_PWRST_D0);
4483 return stac92xx_resume(codec);
4484}
4485
4486static int stac92hd71xx_suspend(struct hda_codec *codec, pm_message_t state)
4487{
4488 struct sigmatel_spec *spec = codec->spec;
4489
4490 stac92hd71xx_set_power_state(codec, AC_PWRST_D3);
4491 if (spec->eapd_mask)
4492 stac_gpio_set(codec, spec->gpio_mask,
4493 spec->gpio_dir, spec->gpio_data &
4494 ~spec->eapd_mask);
4495 return 0; 4732 return 0;
4496}; 4733}
4497
4498#endif
4499
4500static struct hda_codec_ops stac92hd71bxx_patch_ops = {
4501 .build_controls = stac92xx_build_controls,
4502 .build_pcms = stac92xx_build_pcms,
4503 .init = stac92xx_init,
4504 .free = stac92xx_free,
4505 .unsol_event = stac92xx_unsol_event,
4506#ifdef SND_HDA_NEEDS_RESUME
4507 .resume = stac92hd71xx_resume,
4508 .suspend = stac92hd71xx_suspend,
4509#endif
4510};
4511 4734
4512static struct hda_input_mux stac92hd71bxx_dmux = { 4735static struct hda_input_mux stac92hd71bxx_dmux = {
4513 .num_items = 4, 4736 .num_items = 4,
@@ -4544,14 +4767,12 @@ again:
4544 snd_printdd(KERN_INFO "hda_codec: Unknown model for" 4767 snd_printdd(KERN_INFO "hda_codec: Unknown model for"
4545 " STAC92HD71BXX, using BIOS defaults\n"); 4768 " STAC92HD71BXX, using BIOS defaults\n");
4546 err = stac92xx_save_bios_config_regs(codec); 4769 err = stac92xx_save_bios_config_regs(codec);
4547 if (err < 0) { 4770 } else
4548 stac92xx_free(codec); 4771 err = stac_save_pin_cfgs(codec,
4549 return err; 4772 stac92hd71bxx_brd_tbl[spec->board_config]);
4550 } 4773 if (err < 0) {
4551 spec->pin_configs = spec->bios_pin_configs; 4774 stac92xx_free(codec);
4552 } else { 4775 return err;
4553 spec->pin_configs = stac92hd71bxx_brd_tbl[spec->board_config];
4554 stac92xx_set_config_regs(codec);
4555 } 4776 }
4556 4777
4557 if (spec->board_config > STAC_92HD71BXX_REF) { 4778 if (spec->board_config > STAC_92HD71BXX_REF) {
@@ -4574,21 +4795,21 @@ again:
4574 switch (spec->board_config) { 4795 switch (spec->board_config) {
4575 case STAC_HP_M4: 4796 case STAC_HP_M4:
4576 /* Enable VREF power saving on GPIO1 detect */ 4797 /* Enable VREF power saving on GPIO1 detect */
4798 err = stac_add_event(spec, codec->afg,
4799 STAC_VREF_EVENT, 0x02);
4800 if (err < 0)
4801 return err;
4577 snd_hda_codec_write_cache(codec, codec->afg, 0, 4802 snd_hda_codec_write_cache(codec, codec->afg, 0,
4578 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x02); 4803 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x02);
4579 snd_hda_codec_write_cache(codec, codec->afg, 0, 4804 snd_hda_codec_write_cache(codec, codec->afg, 0,
4580 AC_VERB_SET_UNSOLICITED_ENABLE, 4805 AC_VERB_SET_UNSOLICITED_ENABLE,
4581 (AC_USRSP_EN | STAC_VREF_EVENT | 0x01)); 4806 AC_USRSP_EN | err);
4582 spec->gpio_mask |= 0x02; 4807 spec->gpio_mask |= 0x02;
4583 break; 4808 break;
4584 } 4809 }
4585 if ((codec->revision_id & 0xf) == 0 || 4810 if ((codec->revision_id & 0xf) == 0 ||
4586 (codec->revision_id & 0xf) == 1) { 4811 (codec->revision_id & 0xf) == 1)
4587#ifdef SND_HDA_NEEDS_RESUME
4588 codec->patch_ops = stac92hd71bxx_patch_ops;
4589#endif
4590 spec->stream_delay = 40; /* 40 milliseconds */ 4812 spec->stream_delay = 40; /* 40 milliseconds */
4591 }
4592 4813
4593 /* no output amps */ 4814 /* no output amps */
4594 spec->num_pwrs = 0; 4815 spec->num_pwrs = 0;
@@ -4597,15 +4818,11 @@ again:
4597 4818
4598 /* disable VSW */ 4819 /* disable VSW */
4599 spec->init = &stac92hd71bxx_analog_core_init[HD_DISABLE_PORTF]; 4820 spec->init = &stac92hd71bxx_analog_core_init[HD_DISABLE_PORTF];
4600 stac92xx_set_config_reg(codec, 0xf, 0x40f000f0); 4821 stac_change_pin_config(codec, 0xf, 0x40f000f0);
4601 break; 4822 break;
4602 case 0x111d7603: /* 6 Port with Analog Mixer */ 4823 case 0x111d7603: /* 6 Port with Analog Mixer */
4603 if ((codec->revision_id & 0xf) == 1) { 4824 if ((codec->revision_id & 0xf) == 1)
4604#ifdef SND_HDA_NEEDS_RESUME
4605 codec->patch_ops = stac92hd71bxx_patch_ops;
4606#endif
4607 spec->stream_delay = 40; /* 40 milliseconds */ 4825 spec->stream_delay = 40; /* 40 milliseconds */
4608 }
4609 4826
4610 /* no output amps */ 4827 /* no output amps */
4611 spec->num_pwrs = 0; 4828 spec->num_pwrs = 0;
@@ -4635,7 +4852,7 @@ again:
4635 switch (spec->board_config) { 4852 switch (spec->board_config) {
4636 case STAC_HP_M4: 4853 case STAC_HP_M4:
4637 /* enable internal microphone */ 4854 /* enable internal microphone */
4638 stac92xx_set_config_reg(codec, 0x0e, 0x01813040); 4855 stac_change_pin_config(codec, 0x0e, 0x01813040);
4639 stac92xx_auto_set_pinctl(codec, 0x0e, 4856 stac92xx_auto_set_pinctl(codec, 0x0e,
4640 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80); 4857 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80);
4641 /* fallthru */ 4858 /* fallthru */
@@ -4656,9 +4873,7 @@ again:
4656 spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); 4873 spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids);
4657 }; 4874 };
4658 4875
4659 spec->multiout.num_dacs = 1; 4876 spec->multiout.dac_nids = spec->dac_nids;
4660 spec->multiout.hp_nid = 0x11;
4661 spec->multiout.dac_nids = stac92hd71bxx_dac_nids;
4662 if (spec->dinput_mux) 4877 if (spec->dinput_mux)
4663 spec->private_dimux.num_items += 4878 spec->private_dimux.num_items +=
4664 spec->num_dmics - 4879 spec->num_dmics -
@@ -4680,6 +4895,8 @@ again:
4680 return err; 4895 return err;
4681 } 4896 }
4682 4897
4898 codec->proc_widget_hook = stac92hd7x_proc_hook;
4899
4683 return 0; 4900 return 0;
4684}; 4901};
4685 4902
@@ -4741,14 +4958,12 @@ static int patch_stac922x(struct hda_codec *codec)
4741 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, " 4958 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, "
4742 "using BIOS defaults\n"); 4959 "using BIOS defaults\n");
4743 err = stac92xx_save_bios_config_regs(codec); 4960 err = stac92xx_save_bios_config_regs(codec);
4744 if (err < 0) { 4961 } else
4745 stac92xx_free(codec); 4962 err = stac_save_pin_cfgs(codec,
4746 return err; 4963 stac922x_brd_tbl[spec->board_config]);
4747 } 4964 if (err < 0) {
4748 spec->pin_configs = spec->bios_pin_configs; 4965 stac92xx_free(codec);
4749 } else if (stac922x_brd_tbl[spec->board_config] != NULL) { 4966 return err;
4750 spec->pin_configs = stac922x_brd_tbl[spec->board_config];
4751 stac92xx_set_config_regs(codec);
4752 } 4967 }
4753 4968
4754 spec->adc_nids = stac922x_adc_nids; 4969 spec->adc_nids = stac922x_adc_nids;
@@ -4811,14 +5026,12 @@ static int patch_stac927x(struct hda_codec *codec)
4811 snd_printdd(KERN_INFO "hda_codec: Unknown model for" 5026 snd_printdd(KERN_INFO "hda_codec: Unknown model for"
4812 "STAC927x, using BIOS defaults\n"); 5027 "STAC927x, using BIOS defaults\n");
4813 err = stac92xx_save_bios_config_regs(codec); 5028 err = stac92xx_save_bios_config_regs(codec);
4814 if (err < 0) { 5029 } else
4815 stac92xx_free(codec); 5030 err = stac_save_pin_cfgs(codec,
4816 return err; 5031 stac927x_brd_tbl[spec->board_config]);
4817 } 5032 if (err < 0) {
4818 spec->pin_configs = spec->bios_pin_configs; 5033 stac92xx_free(codec);
4819 } else { 5034 return err;
4820 spec->pin_configs = stac927x_brd_tbl[spec->board_config];
4821 stac92xx_set_config_regs(codec);
4822 } 5035 }
4823 5036
4824 spec->digbeep_nid = 0x23; 5037 spec->digbeep_nid = 0x23;
@@ -4848,15 +5061,15 @@ static int patch_stac927x(struct hda_codec *codec)
4848 case 0x10280209: 5061 case 0x10280209:
4849 case 0x1028022e: 5062 case 0x1028022e:
4850 /* correct the device field to SPDIF out */ 5063 /* correct the device field to SPDIF out */
4851 stac92xx_set_config_reg(codec, 0x21, 0x01442070); 5064 stac_change_pin_config(codec, 0x21, 0x01442070);
4852 break; 5065 break;
4853 }; 5066 };
4854 /* configure the analog microphone on some laptops */ 5067 /* configure the analog microphone on some laptops */
4855 stac92xx_set_config_reg(codec, 0x0c, 0x90a79130); 5068 stac_change_pin_config(codec, 0x0c, 0x90a79130);
4856 /* correct the front output jack as a hp out */ 5069 /* correct the front output jack as a hp out */
4857 stac92xx_set_config_reg(codec, 0x0f, 0x0227011f); 5070 stac_change_pin_config(codec, 0x0f, 0x0227011f);
4858 /* correct the front input jack as a mic */ 5071 /* correct the front input jack as a mic */
4859 stac92xx_set_config_reg(codec, 0x0e, 0x02a79130); 5072 stac_change_pin_config(codec, 0x0e, 0x02a79130);
4860 /* fallthru */ 5073 /* fallthru */
4861 case STAC_DELL_3ST: 5074 case STAC_DELL_3ST:
4862 /* GPIO2 High = Enable EAPD */ 5075 /* GPIO2 High = Enable EAPD */
@@ -4904,6 +5117,8 @@ static int patch_stac927x(struct hda_codec *codec)
4904 5117
4905 codec->patch_ops = stac92xx_patch_ops; 5118 codec->patch_ops = stac92xx_patch_ops;
4906 5119
5120 codec->proc_widget_hook = stac927x_proc_hook;
5121
4907 /* 5122 /*
4908 * !!FIXME!! 5123 * !!FIXME!!
4909 * The STAC927x seem to require fairly long delays for certain 5124 * The STAC927x seem to require fairly long delays for certain
@@ -4942,14 +5157,12 @@ static int patch_stac9205(struct hda_codec *codec)
4942 if (spec->board_config < 0) { 5157 if (spec->board_config < 0) {
4943 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9205, using BIOS defaults\n"); 5158 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9205, using BIOS defaults\n");
4944 err = stac92xx_save_bios_config_regs(codec); 5159 err = stac92xx_save_bios_config_regs(codec);
4945 if (err < 0) { 5160 } else
4946 stac92xx_free(codec); 5161 err = stac_save_pin_cfgs(codec,
4947 return err; 5162 stac9205_brd_tbl[spec->board_config]);
4948 } 5163 if (err < 0) {
4949 spec->pin_configs = spec->bios_pin_configs; 5164 stac92xx_free(codec);
4950 } else { 5165 return err;
4951 spec->pin_configs = stac9205_brd_tbl[spec->board_config];
4952 stac92xx_set_config_regs(codec);
4953 } 5166 }
4954 5167
4955 spec->digbeep_nid = 0x23; 5168 spec->digbeep_nid = 0x23;
@@ -4976,15 +5189,18 @@ static int patch_stac9205(struct hda_codec *codec)
4976 switch (spec->board_config){ 5189 switch (spec->board_config){
4977 case STAC_9205_DELL_M43: 5190 case STAC_9205_DELL_M43:
4978 /* Enable SPDIF in/out */ 5191 /* Enable SPDIF in/out */
4979 stac92xx_set_config_reg(codec, 0x1f, 0x01441030); 5192 stac_change_pin_config(codec, 0x1f, 0x01441030);
4980 stac92xx_set_config_reg(codec, 0x20, 0x1c410030); 5193 stac_change_pin_config(codec, 0x20, 0x1c410030);
4981 5194
4982 /* Enable unsol response for GPIO4/Dock HP connection */ 5195 /* Enable unsol response for GPIO4/Dock HP connection */
5196 err = stac_add_event(spec, codec->afg, STAC_VREF_EVENT, 0x01);
5197 if (err < 0)
5198 return err;
4983 snd_hda_codec_write_cache(codec, codec->afg, 0, 5199 snd_hda_codec_write_cache(codec, codec->afg, 0,
4984 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x10); 5200 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x10);
4985 snd_hda_codec_write_cache(codec, codec->afg, 0, 5201 snd_hda_codec_write_cache(codec, codec->afg, 0,
4986 AC_VERB_SET_UNSOLICITED_ENABLE, 5202 AC_VERB_SET_UNSOLICITED_ENABLE,
4987 (AC_USRSP_EN | STAC_HP_EVENT)); 5203 AC_USRSP_EN | err);
4988 5204
4989 spec->gpio_dir = 0x0b; 5205 spec->gpio_dir = 0x0b;
4990 spec->eapd_mask = 0x01; 5206 spec->eapd_mask = 0x01;
@@ -5022,6 +5238,8 @@ static int patch_stac9205(struct hda_codec *codec)
5022 5238
5023 codec->patch_ops = stac92xx_patch_ops; 5239 codec->patch_ops = stac92xx_patch_ops;
5024 5240
5241 codec->proc_widget_hook = stac9205_proc_hook;
5242
5025 return 0; 5243 return 0;
5026} 5244}
5027 5245
@@ -5078,29 +5296,11 @@ static struct hda_verb vaio_ar_init[] = {
5078 {} 5296 {}
5079}; 5297};
5080 5298
5081/* bind volumes of both NID 0x02 and 0x05 */
5082static struct hda_bind_ctls vaio_bind_master_vol = {
5083 .ops = &snd_hda_bind_vol,
5084 .values = {
5085 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
5086 HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT),
5087 0
5088 },
5089};
5090
5091/* bind volumes of both NID 0x02 and 0x05 */
5092static struct hda_bind_ctls vaio_bind_master_sw = {
5093 .ops = &snd_hda_bind_sw,
5094 .values = {
5095 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
5096 HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT),
5097 0,
5098 },
5099};
5100
5101static struct snd_kcontrol_new vaio_mixer[] = { 5299static struct snd_kcontrol_new vaio_mixer[] = {
5102 HDA_BIND_VOL("Master Playback Volume", &vaio_bind_master_vol), 5300 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x02, 0, HDA_OUTPUT),
5103 HDA_BIND_SW("Master Playback Switch", &vaio_bind_master_sw), 5301 HDA_CODEC_MUTE("Headphone Playback Switch", 0x02, 0, HDA_OUTPUT),
5302 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x05, 0, HDA_OUTPUT),
5303 HDA_CODEC_MUTE("Speaker Playback Switch", 0x05, 0, HDA_OUTPUT),
5104 /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */ 5304 /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */
5105 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT), 5305 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT),
5106 HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT), 5306 HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT),
@@ -5116,8 +5316,10 @@ static struct snd_kcontrol_new vaio_mixer[] = {
5116}; 5316};
5117 5317
5118static struct snd_kcontrol_new vaio_ar_mixer[] = { 5318static struct snd_kcontrol_new vaio_ar_mixer[] = {
5119 HDA_BIND_VOL("Master Playback Volume", &vaio_bind_master_vol), 5319 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x02, 0, HDA_OUTPUT),
5120 HDA_BIND_SW("Master Playback Switch", &vaio_bind_master_sw), 5320 HDA_CODEC_MUTE("Headphone Playback Switch", 0x02, 0, HDA_OUTPUT),
5321 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x05, 0, HDA_OUTPUT),
5322 HDA_CODEC_MUTE("Speaker Playback Switch", 0x05, 0, HDA_OUTPUT),
5121 /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */ 5323 /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */
5122 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT), 5324 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT),
5123 HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT), 5325 HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT),
@@ -5158,7 +5360,7 @@ static int stac9872_vaio_init(struct hda_codec *codec)
5158 5360
5159static void stac9872_vaio_hp_detect(struct hda_codec *codec, unsigned int res) 5361static void stac9872_vaio_hp_detect(struct hda_codec *codec, unsigned int res)
5160{ 5362{
5161 if (get_hp_pin_presence(codec, 0x0a)) { 5363 if (get_pin_presence(codec, 0x0a)) {
5162 stac92xx_reset_pinctl(codec, 0x0f, AC_PINCTL_OUT_EN); 5364 stac92xx_reset_pinctl(codec, 0x0f, AC_PINCTL_OUT_EN);
5163 stac92xx_set_pinctl(codec, 0x0a, AC_PINCTL_OUT_EN); 5365 stac92xx_set_pinctl(codec, 0x0a, AC_PINCTL_OUT_EN);
5164 } else { 5366 } else {
@@ -5269,7 +5471,7 @@ static int patch_stac9872(struct hda_codec *codec)
5269/* 5471/*
5270 * patch entries 5472 * patch entries
5271 */ 5473 */
5272struct hda_codec_preset snd_hda_preset_sigmatel[] = { 5474static struct hda_codec_preset snd_hda_preset_sigmatel[] = {
5273 { .id = 0x83847690, .name = "STAC9200", .patch = patch_stac9200 }, 5475 { .id = 0x83847690, .name = "STAC9200", .patch = patch_stac9200 },
5274 { .id = 0x83847882, .name = "STAC9220 A1", .patch = patch_stac922x }, 5476 { .id = 0x83847882, .name = "STAC9220 A1", .patch = patch_stac922x },
5275 { .id = 0x83847680, .name = "STAC9221 A1", .patch = patch_stac922x }, 5477 { .id = 0x83847680, .name = "STAC9221 A1", .patch = patch_stac922x },
@@ -5333,3 +5535,27 @@ struct hda_codec_preset snd_hda_preset_sigmatel[] = {
5333 { .id = 0x111d76b7, .name = "92HD71B5X", .patch = patch_stac92hd71bxx }, 5535 { .id = 0x111d76b7, .name = "92HD71B5X", .patch = patch_stac92hd71bxx },
5334 {} /* terminator */ 5536 {} /* terminator */
5335}; 5537};
5538
5539MODULE_ALIAS("snd-hda-codec-id:8384*");
5540MODULE_ALIAS("snd-hda-codec-id:111d*");
5541
5542MODULE_LICENSE("GPL");
5543MODULE_DESCRIPTION("IDT/Sigmatel HD-audio codec");
5544
5545static struct hda_codec_preset_list sigmatel_list = {
5546 .preset = snd_hda_preset_sigmatel,
5547 .owner = THIS_MODULE,
5548};
5549
5550static int __init patch_sigmatel_init(void)
5551{
5552 return snd_hda_add_codec_preset(&sigmatel_list);
5553}
5554
5555static void __exit patch_sigmatel_exit(void)
5556{
5557 snd_hda_delete_codec_preset(&sigmatel_list);
5558}
5559
5560module_init(patch_sigmatel_init)
5561module_exit(patch_sigmatel_exit)
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index 63e4871e5d8f..c761394cbe84 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -47,15 +47,11 @@
47#include <sound/asoundef.h> 47#include <sound/asoundef.h>
48#include "hda_codec.h" 48#include "hda_codec.h"
49#include "hda_local.h" 49#include "hda_local.h"
50#include "hda_patch.h"
51 50
52/* amp values */ 51/* amp values */
53#define AMP_VAL_IDX_SHIFT 19 52#define AMP_VAL_IDX_SHIFT 19
54#define AMP_VAL_IDX_MASK (0x0f<<19) 53#define AMP_VAL_IDX_MASK (0x0f<<19)
55 54
56#define NUM_CONTROL_ALLOC 32
57#define NUM_VERB_ALLOC 32
58
59/* Pin Widget NID */ 55/* Pin Widget NID */
60#define VT1708_HP_NID 0x13 56#define VT1708_HP_NID 0x13
61#define VT1708_DIGOUT_NID 0x14 57#define VT1708_DIGOUT_NID 0x14
@@ -145,8 +141,6 @@ enum {
145 AUTO_SEQ_SIDE 141 AUTO_SEQ_SIDE
146}; 142};
147 143
148#define get_amp_nid(kc) ((kc)->private_value & 0xffff)
149
150/* Some VT1708S based boards gets the micboost setting wrong, so we have 144/* 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. */ 145 * 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, 146static int mic_boost_tlv(struct snd_kcontrol *kcontrol, int op_flag,
@@ -227,8 +221,7 @@ struct via_spec {
227 221
228 /* dynamic controls, init_verbs and input_mux */ 222 /* dynamic controls, init_verbs and input_mux */
229 struct auto_pin_cfg autocfg; 223 struct auto_pin_cfg autocfg;
230 unsigned int num_kctl_alloc, num_kctl_used; 224 struct snd_array kctls;
231 struct snd_kcontrol_new *kctl_alloc;
232 struct hda_input_mux private_imux[2]; 225 struct hda_input_mux private_imux[2];
233 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; 226 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
234 227
@@ -272,33 +265,31 @@ static int via_add_control(struct via_spec *spec, int type, const char *name,
272{ 265{
273 struct snd_kcontrol_new *knew; 266 struct snd_kcontrol_new *knew;
274 267
275 if (spec->num_kctl_used >= spec->num_kctl_alloc) { 268 snd_array_init(&spec->kctls, sizeof(*knew), 32);
276 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC; 269 knew = snd_array_new(&spec->kctls);
277 270 if (!knew)
278 /* array + terminator */ 271 return -ENOMEM;
279 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
280 if (!knew)
281 return -ENOMEM;
282 if (spec->kctl_alloc) {
283 memcpy(knew, spec->kctl_alloc,
284 sizeof(*knew) * spec->num_kctl_alloc);
285 kfree(spec->kctl_alloc);
286 }
287 spec->kctl_alloc = knew;
288 spec->num_kctl_alloc = num;
289 }
290
291 knew = &spec->kctl_alloc[spec->num_kctl_used];
292 *knew = vt1708_control_templates[type]; 272 *knew = vt1708_control_templates[type];
293 knew->name = kstrdup(name, GFP_KERNEL); 273 knew->name = kstrdup(name, GFP_KERNEL);
294
295 if (!knew->name) 274 if (!knew->name)
296 return -ENOMEM; 275 return -ENOMEM;
297 knew->private_value = val; 276 knew->private_value = val;
298 spec->num_kctl_used++;
299 return 0; 277 return 0;
300} 278}
301 279
280static void via_free_kctls(struct hda_codec *codec)
281{
282 struct via_spec *spec = codec->spec;
283
284 if (spec->kctls.list) {
285 struct snd_kcontrol_new *kctl = spec->kctls.list;
286 int i;
287 for (i = 0; i < spec->kctls.used; i++)
288 kfree(kctl[i].name);
289 }
290 snd_array_free(&spec->kctls);
291}
292
302/* create input playback/capture controls for the given pin */ 293/* create input playback/capture controls for the given pin */
303static int via_new_analog_input(struct via_spec *spec, hda_nid_t pin, 294static int via_new_analog_input(struct via_spec *spec, hda_nid_t pin,
304 const char *ctlname, int idx, int mix_nid) 295 const char *ctlname, int idx, int mix_nid)
@@ -896,6 +887,7 @@ static int via_build_controls(struct hda_codec *codec)
896 if (err < 0) 887 if (err < 0)
897 return err; 888 return err;
898 } 889 }
890 via_free_kctls(codec); /* no longer needed */
899 return 0; 891 return 0;
900} 892}
901 893
@@ -941,17 +933,11 @@ static int via_build_pcms(struct hda_codec *codec)
941static void via_free(struct hda_codec *codec) 933static void via_free(struct hda_codec *codec)
942{ 934{
943 struct via_spec *spec = codec->spec; 935 struct via_spec *spec = codec->spec;
944 unsigned int i;
945 936
946 if (!spec) 937 if (!spec)
947 return; 938 return;
948 939
949 if (spec->kctl_alloc) { 940 via_free_kctls(codec);
950 for (i = 0; i < spec->num_kctl_used; i++)
951 kfree(spec->kctl_alloc[i].name);
952 kfree(spec->kctl_alloc);
953 }
954
955 kfree(codec->spec); 941 kfree(codec->spec);
956} 942}
957 943
@@ -1373,8 +1359,8 @@ static int vt1708_parse_auto_config(struct hda_codec *codec)
1373 if (spec->autocfg.dig_in_pin) 1359 if (spec->autocfg.dig_in_pin)
1374 spec->dig_in_nid = VT1708_DIGIN_NID; 1360 spec->dig_in_nid = VT1708_DIGIN_NID;
1375 1361
1376 if (spec->kctl_alloc) 1362 if (spec->kctls.list)
1377 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 1363 spec->mixers[spec->num_mixers++] = spec->kctls.list;
1378 1364
1379 spec->init_verbs[spec->num_iverbs++] = vt1708_volume_init_verbs; 1365 spec->init_verbs[spec->num_iverbs++] = vt1708_volume_init_verbs;
1380 1366
@@ -1846,8 +1832,8 @@ static int vt1709_parse_auto_config(struct hda_codec *codec)
1846 if (spec->autocfg.dig_in_pin) 1832 if (spec->autocfg.dig_in_pin)
1847 spec->dig_in_nid = VT1709_DIGIN_NID; 1833 spec->dig_in_nid = VT1709_DIGIN_NID;
1848 1834
1849 if (spec->kctl_alloc) 1835 if (spec->kctls.list)
1850 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 1836 spec->mixers[spec->num_mixers++] = spec->kctls.list;
1851 1837
1852 spec->input_mux = &spec->private_imux[0]; 1838 spec->input_mux = &spec->private_imux[0];
1853 1839
@@ -2390,8 +2376,8 @@ static int vt1708B_parse_auto_config(struct hda_codec *codec)
2390 if (spec->autocfg.dig_in_pin) 2376 if (spec->autocfg.dig_in_pin)
2391 spec->dig_in_nid = VT1708B_DIGIN_NID; 2377 spec->dig_in_nid = VT1708B_DIGIN_NID;
2392 2378
2393 if (spec->kctl_alloc) 2379 if (spec->kctls.list)
2394 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 2380 spec->mixers[spec->num_mixers++] = spec->kctls.list;
2395 2381
2396 spec->input_mux = &spec->private_imux[0]; 2382 spec->input_mux = &spec->private_imux[0];
2397 2383
@@ -2855,8 +2841,8 @@ static int vt1708S_parse_auto_config(struct hda_codec *codec)
2855 2841
2856 spec->extra_dig_out_nid = 0x15; 2842 spec->extra_dig_out_nid = 0x15;
2857 2843
2858 if (spec->kctl_alloc) 2844 if (spec->kctls.list)
2859 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 2845 spec->mixers[spec->num_mixers++] = spec->kctls.list;
2860 2846
2861 spec->input_mux = &spec->private_imux[0]; 2847 spec->input_mux = &spec->private_imux[0];
2862 2848
@@ -3174,8 +3160,8 @@ static int vt1702_parse_auto_config(struct hda_codec *codec)
3174 3160
3175 spec->extra_dig_out_nid = 0x1B; 3161 spec->extra_dig_out_nid = 0x1B;
3176 3162
3177 if (spec->kctl_alloc) 3163 if (spec->kctls.list)
3178 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 3164 spec->mixers[spec->num_mixers++] = spec->kctls.list;
3179 3165
3180 spec->input_mux = &spec->private_imux[0]; 3166 spec->input_mux = &spec->private_imux[0];
3181 3167
@@ -3262,74 +3248,97 @@ static int patch_vt1702(struct hda_codec *codec)
3262/* 3248/*
3263 * patch entries 3249 * patch entries
3264 */ 3250 */
3265struct hda_codec_preset snd_hda_preset_via[] = { 3251static struct hda_codec_preset snd_hda_preset_via[] = {
3266 { .id = 0x11061708, .name = "VIA VT1708", .patch = patch_vt1708}, 3252 { .id = 0x11061708, .name = "VT1708", .patch = patch_vt1708},
3267 { .id = 0x11061709, .name = "VIA VT1708", .patch = patch_vt1708}, 3253 { .id = 0x11061709, .name = "VT1708", .patch = patch_vt1708},
3268 { .id = 0x1106170A, .name = "VIA VT1708", .patch = patch_vt1708}, 3254 { .id = 0x1106170a, .name = "VT1708", .patch = patch_vt1708},
3269 { .id = 0x1106170B, .name = "VIA VT1708", .patch = patch_vt1708}, 3255 { .id = 0x1106170b, .name = "VT1708", .patch = patch_vt1708},
3270 { .id = 0x1106E710, .name = "VIA VT1709 10-Ch", 3256 { .id = 0x1106e710, .name = "VT1709 10-Ch",
3271 .patch = patch_vt1709_10ch}, 3257 .patch = patch_vt1709_10ch},
3272 { .id = 0x1106E711, .name = "VIA VT1709 10-Ch", 3258 { .id = 0x1106e711, .name = "VT1709 10-Ch",
3273 .patch = patch_vt1709_10ch}, 3259 .patch = patch_vt1709_10ch},
3274 { .id = 0x1106E712, .name = "VIA VT1709 10-Ch", 3260 { .id = 0x1106e712, .name = "VT1709 10-Ch",
3275 .patch = patch_vt1709_10ch}, 3261 .patch = patch_vt1709_10ch},
3276 { .id = 0x1106E713, .name = "VIA VT1709 10-Ch", 3262 { .id = 0x1106e713, .name = "VT1709 10-Ch",
3277 .patch = patch_vt1709_10ch}, 3263 .patch = patch_vt1709_10ch},
3278 { .id = 0x1106E714, .name = "VIA VT1709 6-Ch", 3264 { .id = 0x1106e714, .name = "VT1709 6-Ch",
3279 .patch = patch_vt1709_6ch}, 3265 .patch = patch_vt1709_6ch},
3280 { .id = 0x1106E715, .name = "VIA VT1709 6-Ch", 3266 { .id = 0x1106e715, .name = "VT1709 6-Ch",
3281 .patch = patch_vt1709_6ch}, 3267 .patch = patch_vt1709_6ch},
3282 { .id = 0x1106E716, .name = "VIA VT1709 6-Ch", 3268 { .id = 0x1106e716, .name = "VT1709 6-Ch",
3283 .patch = patch_vt1709_6ch}, 3269 .patch = patch_vt1709_6ch},
3284 { .id = 0x1106E717, .name = "VIA VT1709 6-Ch", 3270 { .id = 0x1106e717, .name = "VT1709 6-Ch",
3285 .patch = patch_vt1709_6ch}, 3271 .patch = patch_vt1709_6ch},
3286 { .id = 0x1106E720, .name = "VIA VT1708B 8-Ch", 3272 { .id = 0x1106e720, .name = "VT1708B 8-Ch",
3287 .patch = patch_vt1708B_8ch}, 3273 .patch = patch_vt1708B_8ch},
3288 { .id = 0x1106E721, .name = "VIA VT1708B 8-Ch", 3274 { .id = 0x1106e721, .name = "VT1708B 8-Ch",
3289 .patch = patch_vt1708B_8ch}, 3275 .patch = patch_vt1708B_8ch},
3290 { .id = 0x1106E722, .name = "VIA VT1708B 8-Ch", 3276 { .id = 0x1106e722, .name = "VT1708B 8-Ch",
3291 .patch = patch_vt1708B_8ch}, 3277 .patch = patch_vt1708B_8ch},
3292 { .id = 0x1106E723, .name = "VIA VT1708B 8-Ch", 3278 { .id = 0x1106e723, .name = "VT1708B 8-Ch",
3293 .patch = patch_vt1708B_8ch}, 3279 .patch = patch_vt1708B_8ch},
3294 { .id = 0x1106E724, .name = "VIA VT1708B 4-Ch", 3280 { .id = 0x1106e724, .name = "VT1708B 4-Ch",
3295 .patch = patch_vt1708B_4ch}, 3281 .patch = patch_vt1708B_4ch},
3296 { .id = 0x1106E725, .name = "VIA VT1708B 4-Ch", 3282 { .id = 0x1106e725, .name = "VT1708B 4-Ch",
3297 .patch = patch_vt1708B_4ch}, 3283 .patch = patch_vt1708B_4ch},
3298 { .id = 0x1106E726, .name = "VIA VT1708B 4-Ch", 3284 { .id = 0x1106e726, .name = "VT1708B 4-Ch",
3299 .patch = patch_vt1708B_4ch}, 3285 .patch = patch_vt1708B_4ch},
3300 { .id = 0x1106E727, .name = "VIA VT1708B 4-Ch", 3286 { .id = 0x1106e727, .name = "VT1708B 4-Ch",
3301 .patch = patch_vt1708B_4ch}, 3287 .patch = patch_vt1708B_4ch},
3302 { .id = 0x11060397, .name = "VIA VT1708S", 3288 { .id = 0x11060397, .name = "VT1708S",
3303 .patch = patch_vt1708S}, 3289 .patch = patch_vt1708S},
3304 { .id = 0x11061397, .name = "VIA VT1708S", 3290 { .id = 0x11061397, .name = "VT1708S",
3305 .patch = patch_vt1708S}, 3291 .patch = patch_vt1708S},
3306 { .id = 0x11062397, .name = "VIA VT1708S", 3292 { .id = 0x11062397, .name = "VT1708S",
3307 .patch = patch_vt1708S}, 3293 .patch = patch_vt1708S},
3308 { .id = 0x11063397, .name = "VIA VT1708S", 3294 { .id = 0x11063397, .name = "VT1708S",
3309 .patch = patch_vt1708S}, 3295 .patch = patch_vt1708S},
3310 { .id = 0x11064397, .name = "VIA VT1708S", 3296 { .id = 0x11064397, .name = "VT1708S",
3311 .patch = patch_vt1708S}, 3297 .patch = patch_vt1708S},
3312 { .id = 0x11065397, .name = "VIA VT1708S", 3298 { .id = 0x11065397, .name = "VT1708S",
3313 .patch = patch_vt1708S}, 3299 .patch = patch_vt1708S},
3314 { .id = 0x11066397, .name = "VIA VT1708S", 3300 { .id = 0x11066397, .name = "VT1708S",
3315 .patch = patch_vt1708S}, 3301 .patch = patch_vt1708S},
3316 { .id = 0x11067397, .name = "VIA VT1708S", 3302 { .id = 0x11067397, .name = "VT1708S",
3317 .patch = patch_vt1708S}, 3303 .patch = patch_vt1708S},
3318 { .id = 0x11060398, .name = "VIA VT1702", 3304 { .id = 0x11060398, .name = "VT1702",
3319 .patch = patch_vt1702}, 3305 .patch = patch_vt1702},
3320 { .id = 0x11061398, .name = "VIA VT1702", 3306 { .id = 0x11061398, .name = "VT1702",
3321 .patch = patch_vt1702}, 3307 .patch = patch_vt1702},
3322 { .id = 0x11062398, .name = "VIA VT1702", 3308 { .id = 0x11062398, .name = "VT1702",
3323 .patch = patch_vt1702}, 3309 .patch = patch_vt1702},
3324 { .id = 0x11063398, .name = "VIA VT1702", 3310 { .id = 0x11063398, .name = "VT1702",
3325 .patch = patch_vt1702}, 3311 .patch = patch_vt1702},
3326 { .id = 0x11064398, .name = "VIA VT1702", 3312 { .id = 0x11064398, .name = "VT1702",
3327 .patch = patch_vt1702}, 3313 .patch = patch_vt1702},
3328 { .id = 0x11065398, .name = "VIA VT1702", 3314 { .id = 0x11065398, .name = "VT1702",
3329 .patch = patch_vt1702}, 3315 .patch = patch_vt1702},
3330 { .id = 0x11066398, .name = "VIA VT1702", 3316 { .id = 0x11066398, .name = "VT1702",
3331 .patch = patch_vt1702}, 3317 .patch = patch_vt1702},
3332 { .id = 0x11067398, .name = "VIA VT1702", 3318 { .id = 0x11067398, .name = "VT1702",
3333 .patch = patch_vt1702}, 3319 .patch = patch_vt1702},
3334 {} /* terminator */ 3320 {} /* terminator */
3335}; 3321};
3322
3323MODULE_ALIAS("snd-hda-codec-id:1106*");
3324
3325static struct hda_codec_preset_list via_list = {
3326 .preset = snd_hda_preset_via,
3327 .owner = THIS_MODULE,
3328};
3329
3330MODULE_LICENSE("GPL");
3331MODULE_DESCRIPTION("VIA HD-audio codec");
3332
3333static int __init patch_via_init(void)
3334{
3335 return snd_hda_add_codec_preset(&via_list);
3336}
3337
3338static void __exit patch_via_exit(void)
3339{
3340 snd_hda_delete_codec_preset(&via_list);
3341}
3342
3343module_init(patch_via_init)
3344module_exit(patch_via_exit)
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index 1b3f11702713..0dfa0540ce2c 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -382,23 +382,25 @@ static irqreturn_t snd_vt1724_interrupt(int irq, void *dev_id)
382 unsigned char status_mask = 382 unsigned char status_mask =
383 VT1724_IRQ_MPU_RX | VT1724_IRQ_MPU_TX | VT1724_IRQ_MTPCM; 383 VT1724_IRQ_MPU_RX | VT1724_IRQ_MPU_TX | VT1724_IRQ_MTPCM;
384 int handled = 0; 384 int handled = 0;
385#ifdef CONFIG_SND_DEBUG
386 int timeout = 0; 385 int timeout = 0;
387#endif
388 386
389 while (1) { 387 while (1) {
390 status = inb(ICEREG1724(ice, IRQSTAT)); 388 status = inb(ICEREG1724(ice, IRQSTAT));
391 status &= status_mask; 389 status &= status_mask;
392 if (status == 0) 390 if (status == 0)
393 break; 391 break;
394#ifdef CONFIG_SND_DEBUG
395 if (++timeout > 10) { 392 if (++timeout > 10) {
396 printk(KERN_ERR 393 status = inb(ICEREG1724(ice, IRQSTAT));
397 "ice1724: Too long irq loop, status = 0x%x\n", 394 printk(KERN_ERR "ice1724: Too long irq loop, "
398 status); 395 "status = 0x%x\n", status);
396 if (status & VT1724_IRQ_MPU_TX) {
397 printk(KERN_ERR "ice1724: Disabling MPU_TX\n");
398 outb(inb(ICEREG1724(ice, IRQMASK)) |
399 VT1724_IRQ_MPU_TX,
400 ICEREG1724(ice, IRQMASK));
401 }
399 break; 402 break;
400 } 403 }
401#endif
402 handled = 1; 404 handled = 1;
403 if (status & VT1724_IRQ_MPU_TX) { 405 if (status & VT1724_IRQ_MPU_TX) {
404 spin_lock(&ice->reg_lock); 406 spin_lock(&ice->reg_lock);
@@ -2351,7 +2353,6 @@ static int __devinit snd_vt1724_create(struct snd_card *card,
2351{ 2353{
2352 struct snd_ice1712 *ice; 2354 struct snd_ice1712 *ice;
2353 int err; 2355 int err;
2354 unsigned char mask;
2355 static struct snd_device_ops ops = { 2356 static struct snd_device_ops ops = {
2356 .dev_free = snd_vt1724_dev_free, 2357 .dev_free = snd_vt1724_dev_free,
2357 }; 2358 };
@@ -2412,9 +2413,9 @@ static int __devinit snd_vt1724_create(struct snd_card *card,
2412 return -EIO; 2413 return -EIO;
2413 } 2414 }
2414 2415
2415 /* unmask used interrupts */ 2416 /* MPU_RX and TX irq masks are cleared later dynamically */
2416 mask = VT1724_IRQ_MPU_RX | VT1724_IRQ_MPU_TX; 2417 outb(VT1724_IRQ_MPU_RX | VT1724_IRQ_MPU_TX , ICEREG1724(ice, IRQMASK));
2417 outb(mask, ICEREG1724(ice, IRQMASK)); 2418
2418 /* don't handle FIFO overrun/underruns (just yet), 2419 /* don't handle FIFO overrun/underruns (just yet),
2419 * since they cause machine lockups 2420 * since they cause machine lockups
2420 */ 2421 */
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index 9ff3f9e34404..59bbaf8f3e5b 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -1670,7 +1670,7 @@ static irqreturn_t snd_m3_interrupt(int irq, void *dev_id)
1670 return IRQ_NONE; 1670 return IRQ_NONE;
1671 1671
1672 if (status & HV_INT_PENDING) 1672 if (status & HV_INT_PENDING)
1673 tasklet_hi_schedule(&chip->hwvol_tq); 1673 tasklet_schedule(&chip->hwvol_tq);
1674 1674
1675 /* 1675 /*
1676 * ack an assp int if its running 1676 * ack an assp int if its running
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c
index ae7601f353a7..f23a73577c22 100644
--- a/sound/pci/mixart/mixart.c
+++ b/sound/pci/mixart/mixart.c
@@ -1010,7 +1010,7 @@ static int __devinit snd_mixart_create(struct mixart_mgr *mgr, struct snd_card *
1010 .dev_free = snd_mixart_chip_dev_free, 1010 .dev_free = snd_mixart_chip_dev_free,
1011 }; 1011 };
1012 1012
1013 mgr->chip[idx] = chip = kzalloc(sizeof(*chip), GFP_KERNEL); 1013 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
1014 if (! chip) { 1014 if (! chip) {
1015 snd_printk(KERN_ERR "cannot allocate chip\n"); 1015 snd_printk(KERN_ERR "cannot allocate chip\n");
1016 return -ENOMEM; 1016 return -ENOMEM;
@@ -1025,6 +1025,7 @@ static int __devinit snd_mixart_create(struct mixart_mgr *mgr, struct snd_card *
1025 return err; 1025 return err;
1026 } 1026 }
1027 1027
1028 mgr->chip[idx] = chip;
1028 snd_card_set_dev(card, &mgr->pci->dev); 1029 snd_card_set_dev(card, &mgr->pci->dev);
1029 1030
1030 return 0; 1031 return 0;
@@ -1377,6 +1378,7 @@ static int __devinit snd_mixart_probe(struct pci_dev *pci,
1377 sprintf(card->longname, "%s [PCM #%d]", mgr->longname, i); 1378 sprintf(card->longname, "%s [PCM #%d]", mgr->longname, i);
1378 1379
1379 if ((err = snd_mixart_create(mgr, card, i)) < 0) { 1380 if ((err = snd_mixart_create(mgr, card, i)) < 0) {
1381 snd_card_free(card);
1380 snd_mixart_free(mgr); 1382 snd_mixart_free(mgr);
1381 return err; 1383 return err;
1382 } 1384 }
diff --git a/sound/pci/mixart/mixart_core.c b/sound/pci/mixart/mixart_core.c
index b9a06c279397..d3350f383966 100644
--- a/sound/pci/mixart/mixart_core.c
+++ b/sound/pci/mixart/mixart_core.c
@@ -550,7 +550,7 @@ irqreturn_t snd_mixart_interrupt(int irq, void *dev_id)
550 mgr->msg_fifo[mgr->msg_fifo_writeptr] = msg; 550 mgr->msg_fifo[mgr->msg_fifo_writeptr] = msg;
551 mgr->msg_fifo_writeptr++; 551 mgr->msg_fifo_writeptr++;
552 mgr->msg_fifo_writeptr %= MSG_FIFO_SIZE; 552 mgr->msg_fifo_writeptr %= MSG_FIFO_SIZE;
553 tasklet_hi_schedule(&mgr->msg_taskq); 553 tasklet_schedule(&mgr->msg_taskq);
554 } 554 }
555 spin_unlock(&mgr->msg_lock); 555 spin_unlock(&mgr->msg_lock);
556 break; 556 break;
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c
index b60f6212745a..de999c6d6dd3 100644
--- a/sound/pci/oxygen/oxygen.c
+++ b/sound/pci/oxygen/oxygen.c
@@ -61,6 +61,7 @@ MODULE_PARM_DESC(enable, "enable card");
61enum { 61enum {
62 MODEL_CMEDIA_REF, /* C-Media's reference design */ 62 MODEL_CMEDIA_REF, /* C-Media's reference design */
63 MODEL_MERIDIAN, /* AuzenTech X-Meridian */ 63 MODEL_MERIDIAN, /* AuzenTech X-Meridian */
64 MODEL_HALO, /* HT-Omega Claro halo */
64}; 65};
65 66
66static struct pci_device_id oxygen_ids[] __devinitdata = { 67static struct pci_device_id oxygen_ids[] __devinitdata = {
@@ -74,6 +75,7 @@ static struct pci_device_id oxygen_ids[] __devinitdata = {
74 { OXYGEN_PCI_SUBID(0x1a58, 0x0910), .driver_data = MODEL_CMEDIA_REF }, 75 { OXYGEN_PCI_SUBID(0x1a58, 0x0910), .driver_data = MODEL_CMEDIA_REF },
75 { OXYGEN_PCI_SUBID(0x415a, 0x5431), .driver_data = MODEL_MERIDIAN }, 76 { OXYGEN_PCI_SUBID(0x415a, 0x5431), .driver_data = MODEL_MERIDIAN },
76 { OXYGEN_PCI_SUBID(0x7284, 0x9761), .driver_data = MODEL_CMEDIA_REF }, 77 { OXYGEN_PCI_SUBID(0x7284, 0x9761), .driver_data = MODEL_CMEDIA_REF },
78 { OXYGEN_PCI_SUBID(0x7284, 0x9781), .driver_data = MODEL_HALO },
77 { } 79 { }
78}; 80};
79MODULE_DEVICE_TABLE(pci, oxygen_ids); 81MODULE_DEVICE_TABLE(pci, oxygen_ids);
@@ -301,6 +303,8 @@ static int generic_probe(struct oxygen *chip, unsigned long driver_data)
301 PLAYBACK_1_TO_SPDIF | 303 PLAYBACK_1_TO_SPDIF |
302 CAPTURE_0_FROM_I2S_2 | 304 CAPTURE_0_FROM_I2S_2 |
303 CAPTURE_1_FROM_SPDIF; 305 CAPTURE_1_FROM_SPDIF;
306 }
307 if (driver_data == MODEL_MERIDIAN || driver_data == MODEL_HALO) {
304 chip->model.misc_flags = OXYGEN_MISC_MIDI; 308 chip->model.misc_flags = OXYGEN_MISC_MIDI;
305 chip->model.device_config |= MIDI_OUTPUT | MIDI_INPUT; 309 chip->model.device_config |= MIDI_OUTPUT | MIDI_INPUT;
306 } 310 }
diff --git a/sound/pci/pcxhr/Makefile b/sound/pci/pcxhr/Makefile
index 10473c05918d..b06128e918ca 100644
--- a/sound/pci/pcxhr/Makefile
+++ b/sound/pci/pcxhr/Makefile
@@ -1,2 +1,2 @@
1snd-pcxhr-objs := pcxhr.o pcxhr_hwdep.o pcxhr_mixer.o pcxhr_core.o 1snd-pcxhr-objs := pcxhr.o pcxhr_hwdep.o pcxhr_mixer.o pcxhr_core.o pcxhr_mix22.o
2obj-$(CONFIG_SND_PCXHR) += snd-pcxhr.o 2obj-$(CONFIG_SND_PCXHR) += snd-pcxhr.o
diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c
index 73de6e989b3d..27cf2c28d113 100644
--- a/sound/pci/pcxhr/pcxhr.c
+++ b/sound/pci/pcxhr/pcxhr.c
@@ -40,18 +40,20 @@
40#include "pcxhr_mixer.h" 40#include "pcxhr_mixer.h"
41#include "pcxhr_hwdep.h" 41#include "pcxhr_hwdep.h"
42#include "pcxhr_core.h" 42#include "pcxhr_core.h"
43#include "pcxhr_mix22.h"
43 44
44#define DRIVER_NAME "pcxhr" 45#define DRIVER_NAME "pcxhr"
45 46
46MODULE_AUTHOR("Markus Bollinger <bollinger@digigram.com>"); 47MODULE_AUTHOR("Markus Bollinger <bollinger@digigram.com>, "
48 "Marc Titinger <titinger@digigram.com>");
47MODULE_DESCRIPTION("Digigram " DRIVER_NAME " " PCXHR_DRIVER_VERSION_STRING); 49MODULE_DESCRIPTION("Digigram " DRIVER_NAME " " PCXHR_DRIVER_VERSION_STRING);
48MODULE_LICENSE("GPL"); 50MODULE_LICENSE("GPL");
49MODULE_SUPPORTED_DEVICE("{{Digigram," DRIVER_NAME "}}"); 51MODULE_SUPPORTED_DEVICE("{{Digigram," DRIVER_NAME "}}");
50 52
51static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ 53static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
52static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ 54static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
53static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ 55static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */
54static int mono[SNDRV_CARDS]; /* capture in mono only */ 56static int mono[SNDRV_CARDS]; /* capture mono only */
55 57
56module_param_array(index, int, NULL, 0444); 58module_param_array(index, int, NULL, 0444);
57MODULE_PARM_DESC(index, "Index value for Digigram " DRIVER_NAME " soundcard"); 59MODULE_PARM_DESC(index, "Index value for Digigram " DRIVER_NAME " soundcard");
@@ -67,18 +69,58 @@ enum {
67 PCI_ID_PCX882HR, 69 PCI_ID_PCX882HR,
68 PCI_ID_VX881HR, 70 PCI_ID_VX881HR,
69 PCI_ID_PCX881HR, 71 PCI_ID_PCX881HR,
72 PCI_ID_VX882E,
73 PCI_ID_PCX882E,
74 PCI_ID_VX881E,
75 PCI_ID_PCX881E,
76 PCI_ID_VX1222HR,
70 PCI_ID_PCX1222HR, 77 PCI_ID_PCX1222HR,
78 PCI_ID_VX1221HR,
71 PCI_ID_PCX1221HR, 79 PCI_ID_PCX1221HR,
80 PCI_ID_VX1222E,
81 PCI_ID_PCX1222E,
82 PCI_ID_VX1221E,
83 PCI_ID_PCX1221E,
84 PCI_ID_VX222HR,
85 PCI_ID_VX222E,
86 PCI_ID_PCX22HR,
87 PCI_ID_PCX22E,
88 PCI_ID_VX222HRMIC,
89 PCI_ID_VX222E_MIC,
90 PCI_ID_PCX924HR,
91 PCI_ID_PCX924E,
92 PCI_ID_PCX924HRMIC,
93 PCI_ID_PCX924E_MIC,
72 PCI_ID_LAST 94 PCI_ID_LAST
73}; 95};
74 96
75static struct pci_device_id pcxhr_ids[] = { 97static struct pci_device_id pcxhr_ids[] = {
76 { 0x10b5, 0x9656, 0x1369, 0xb001, 0, 0, PCI_ID_VX882HR, }, /* VX882HR */ 98 { 0x10b5, 0x9656, 0x1369, 0xb001, 0, 0, PCI_ID_VX882HR, },
77 { 0x10b5, 0x9656, 0x1369, 0xb101, 0, 0, PCI_ID_PCX882HR, }, /* PCX882HR */ 99 { 0x10b5, 0x9656, 0x1369, 0xb101, 0, 0, PCI_ID_PCX882HR, },
78 { 0x10b5, 0x9656, 0x1369, 0xb201, 0, 0, PCI_ID_VX881HR, }, /* VX881HR */ 100 { 0x10b5, 0x9656, 0x1369, 0xb201, 0, 0, PCI_ID_VX881HR, },
79 { 0x10b5, 0x9656, 0x1369, 0xb301, 0, 0, PCI_ID_PCX881HR, }, /* PCX881HR */ 101 { 0x10b5, 0x9656, 0x1369, 0xb301, 0, 0, PCI_ID_PCX881HR, },
80 { 0x10b5, 0x9656, 0x1369, 0xb501, 0, 0, PCI_ID_PCX1222HR, }, /* PCX1222HR */ 102 { 0x10b5, 0x9056, 0x1369, 0xb021, 0, 0, PCI_ID_VX882E, },
81 { 0x10b5, 0x9656, 0x1369, 0xb701, 0, 0, PCI_ID_PCX1221HR, }, /* PCX1221HR */ 103 { 0x10b5, 0x9056, 0x1369, 0xb121, 0, 0, PCI_ID_PCX882E, },
104 { 0x10b5, 0x9056, 0x1369, 0xb221, 0, 0, PCI_ID_VX881E, },
105 { 0x10b5, 0x9056, 0x1369, 0xb321, 0, 0, PCI_ID_PCX881E, },
106 { 0x10b5, 0x9656, 0x1369, 0xb401, 0, 0, PCI_ID_VX1222HR, },
107 { 0x10b5, 0x9656, 0x1369, 0xb501, 0, 0, PCI_ID_PCX1222HR, },
108 { 0x10b5, 0x9656, 0x1369, 0xb601, 0, 0, PCI_ID_VX1221HR, },
109 { 0x10b5, 0x9656, 0x1369, 0xb701, 0, 0, PCI_ID_PCX1221HR, },
110 { 0x10b5, 0x9056, 0x1369, 0xb421, 0, 0, PCI_ID_VX1222E, },
111 { 0x10b5, 0x9056, 0x1369, 0xb521, 0, 0, PCI_ID_PCX1222E, },
112 { 0x10b5, 0x9056, 0x1369, 0xb621, 0, 0, PCI_ID_VX1221E, },
113 { 0x10b5, 0x9056, 0x1369, 0xb721, 0, 0, PCI_ID_PCX1221E, },
114 { 0x10b5, 0x9056, 0x1369, 0xba01, 0, 0, PCI_ID_VX222HR, },
115 { 0x10b5, 0x9056, 0x1369, 0xba21, 0, 0, PCI_ID_VX222E, },
116 { 0x10b5, 0x9056, 0x1369, 0xbd01, 0, 0, PCI_ID_PCX22HR, },
117 { 0x10b5, 0x9056, 0x1369, 0xbd21, 0, 0, PCI_ID_PCX22E, },
118 { 0x10b5, 0x9056, 0x1369, 0xbc01, 0, 0, PCI_ID_VX222HRMIC, },
119 { 0x10b5, 0x9056, 0x1369, 0xbc21, 0, 0, PCI_ID_VX222E_MIC, },
120 { 0x10b5, 0x9056, 0x1369, 0xbb01, 0, 0, PCI_ID_PCX924HR, },
121 { 0x10b5, 0x9056, 0x1369, 0xbb21, 0, 0, PCI_ID_PCX924E, },
122 { 0x10b5, 0x9056, 0x1369, 0xbf01, 0, 0, PCI_ID_PCX924HRMIC, },
123 { 0x10b5, 0x9056, 0x1369, 0xbf21, 0, 0, PCI_ID_PCX924E_MIC, },
82 { 0, } 124 { 0, }
83}; 125};
84 126
@@ -88,27 +130,55 @@ struct board_parameters {
88 char* board_name; 130 char* board_name;
89 short playback_chips; 131 short playback_chips;
90 short capture_chips; 132 short capture_chips;
133 short fw_file_set;
91 short firmware_num; 134 short firmware_num;
92}; 135};
93static struct board_parameters pcxhr_board_params[] = { 136static struct board_parameters pcxhr_board_params[] = {
94[PCI_ID_VX882HR] = { "VX882HR", 4, 4, 41, }, 137[PCI_ID_VX882HR] = { "VX882HR", 4, 4, 0, 41 },
95[PCI_ID_PCX882HR] = { "PCX882HR", 4, 4, 41, }, 138[PCI_ID_PCX882HR] = { "PCX882HR", 4, 4, 0, 41 },
96[PCI_ID_VX881HR] = { "VX881HR", 4, 4, 41, }, 139[PCI_ID_VX881HR] = { "VX881HR", 4, 4, 0, 41 },
97[PCI_ID_PCX881HR] = { "PCX881HR", 4, 4, 41, }, 140[PCI_ID_PCX881HR] = { "PCX881HR", 4, 4, 0, 41 },
98[PCI_ID_PCX1222HR] = { "PCX1222HR", 6, 1, 42, }, 141[PCI_ID_VX882E] = { "VX882e", 4, 4, 1, 41 },
99[PCI_ID_PCX1221HR] = { "PCX1221HR", 6, 1, 42, }, 142[PCI_ID_PCX882E] = { "PCX882e", 4, 4, 1, 41 },
143[PCI_ID_VX881E] = { "VX881e", 4, 4, 1, 41 },
144[PCI_ID_PCX881E] = { "PCX881e", 4, 4, 1, 41 },
145[PCI_ID_VX1222HR] = { "VX1222HR", 6, 1, 2, 42 },
146[PCI_ID_PCX1222HR] = { "PCX1222HR", 6, 1, 2, 42 },
147[PCI_ID_VX1221HR] = { "VX1221HR", 6, 1, 2, 42 },
148[PCI_ID_PCX1221HR] = { "PCX1221HR", 6, 1, 2, 42 },
149[PCI_ID_VX1222E] = { "VX1222e", 6, 1, 3, 42 },
150[PCI_ID_PCX1222E] = { "PCX1222e", 6, 1, 3, 42 },
151[PCI_ID_VX1221E] = { "VX1221e", 6, 1, 3, 42 },
152[PCI_ID_PCX1221E] = { "PCX1221e", 6, 1, 3, 42 },
153[PCI_ID_VX222HR] = { "VX222HR", 1, 1, 4, 44 },
154[PCI_ID_VX222E] = { "VX222e", 1, 1, 4, 44 },
155[PCI_ID_PCX22HR] = { "PCX22HR", 1, 0, 4, 44 },
156[PCI_ID_PCX22E] = { "PCX22e", 1, 0, 4, 44 },
157[PCI_ID_VX222HRMIC] = { "VX222HR-Mic", 1, 1, 5, 44 },
158[PCI_ID_VX222E_MIC] = { "VX222e-Mic", 1, 1, 5, 44 },
159[PCI_ID_PCX924HR] = { "PCX924HR", 1, 1, 5, 44 },
160[PCI_ID_PCX924E] = { "PCX924e", 1, 1, 5, 44 },
161[PCI_ID_PCX924HRMIC] = { "PCX924HR-Mic", 1, 1, 5, 44 },
162[PCI_ID_PCX924E_MIC] = { "PCX924e-Mic", 1, 1, 5, 44 },
100}; 163};
101 164
165/* boards without hw AES1 and SRC onboard are all using fw_file_set==4 */
166/* VX222HR, VX222e, PCX22HR and PCX22e */
167#define PCXHR_BOARD_HAS_AES1(x) (x->fw_file_set != 4)
168/* some boards do not support 192kHz on digital AES input plugs */
169#define PCXHR_BOARD_AESIN_NO_192K(x) ((x->capture_chips == 0) || \
170 (x->fw_file_set == 0) || \
171 (x->fw_file_set == 2))
102 172
103static int pcxhr_pll_freq_register(unsigned int freq, unsigned int* pllreg, 173static int pcxhr_pll_freq_register(unsigned int freq, unsigned int* pllreg,
104 unsigned int* realfreq) 174 unsigned int* realfreq)
105{ 175{
106 unsigned int reg; 176 unsigned int reg;
107 177
108 if (freq < 6900 || freq > 110250) 178 if (freq < 6900 || freq > 110000)
109 return -EINVAL; 179 return -EINVAL;
110 reg = (28224000 * 10) / freq; 180 reg = (28224000 * 2) / freq;
111 reg = (reg + 5) / 10; 181 reg = (reg - 1) / 2;
112 if (reg < 0x200) 182 if (reg < 0x200)
113 *pllreg = reg + 0x800; 183 *pllreg = reg + 0x800;
114 else if (reg < 0x400) 184 else if (reg < 0x400)
@@ -121,7 +191,7 @@ static int pcxhr_pll_freq_register(unsigned int freq, unsigned int* pllreg,
121 reg &= ~3; 191 reg &= ~3;
122 } 192 }
123 if (realfreq) 193 if (realfreq)
124 *realfreq = ((28224000 * 10) / reg + 5) / 10; 194 *realfreq = (28224000 / (reg + 1));
125 return 0; 195 return 0;
126} 196}
127 197
@@ -151,11 +221,6 @@ static int pcxhr_pll_freq_register(unsigned int freq, unsigned int* pllreg,
151#define PCXHR_FREQ_AES_3 0x03 221#define PCXHR_FREQ_AES_3 0x03
152#define PCXHR_FREQ_AES_4 0x0d 222#define PCXHR_FREQ_AES_4 0x0d
153 223
154#define PCXHR_MODIFY_CLOCK_S_BIT 0x04
155
156#define PCXHR_IRQ_TIMER_FREQ 92000
157#define PCXHR_IRQ_TIMER_PERIOD 48
158
159static int pcxhr_get_clock_reg(struct pcxhr_mgr *mgr, unsigned int rate, 224static int pcxhr_get_clock_reg(struct pcxhr_mgr *mgr, unsigned int rate,
160 unsigned int *reg, unsigned int *freq) 225 unsigned int *reg, unsigned int *freq)
161{ 226{
@@ -196,19 +261,32 @@ static int pcxhr_get_clock_reg(struct pcxhr_mgr *mgr, unsigned int rate,
196 err = pcxhr_send_msg(mgr, &rmh); 261 err = pcxhr_send_msg(mgr, &rmh);
197 if (err < 0) { 262 if (err < 0) {
198 snd_printk(KERN_ERR 263 snd_printk(KERN_ERR
199 "error CMD_ACCESS_IO_WRITE for PLL register : %x!\n", 264 "error CMD_ACCESS_IO_WRITE "
200 err ); 265 "for PLL register : %x!\n", err);
201 return err; 266 return err;
202 } 267 }
203 } 268 }
204 break; 269 break;
205 case PCXHR_CLOCK_TYPE_WORD_CLOCK : val = PCXHR_FREQ_WORD_CLOCK; break; 270 case PCXHR_CLOCK_TYPE_WORD_CLOCK:
206 case PCXHR_CLOCK_TYPE_AES_SYNC : val = PCXHR_FREQ_SYNC_AES; break; 271 val = PCXHR_FREQ_WORD_CLOCK;
207 case PCXHR_CLOCK_TYPE_AES_1 : val = PCXHR_FREQ_AES_1; break; 272 break;
208 case PCXHR_CLOCK_TYPE_AES_2 : val = PCXHR_FREQ_AES_2; break; 273 case PCXHR_CLOCK_TYPE_AES_SYNC:
209 case PCXHR_CLOCK_TYPE_AES_3 : val = PCXHR_FREQ_AES_3; break; 274 val = PCXHR_FREQ_SYNC_AES;
210 case PCXHR_CLOCK_TYPE_AES_4 : val = PCXHR_FREQ_AES_4; break; 275 break;
211 default : return -EINVAL; 276 case PCXHR_CLOCK_TYPE_AES_1:
277 val = PCXHR_FREQ_AES_1;
278 break;
279 case PCXHR_CLOCK_TYPE_AES_2:
280 val = PCXHR_FREQ_AES_2;
281 break;
282 case PCXHR_CLOCK_TYPE_AES_3:
283 val = PCXHR_FREQ_AES_3;
284 break;
285 case PCXHR_CLOCK_TYPE_AES_4:
286 val = PCXHR_FREQ_AES_4;
287 break;
288 default:
289 return -EINVAL;
212 } 290 }
213 *reg = val; 291 *reg = val;
214 *freq = realfreq; 292 *freq = realfreq;
@@ -216,14 +294,13 @@ static int pcxhr_get_clock_reg(struct pcxhr_mgr *mgr, unsigned int rate,
216} 294}
217 295
218 296
219int pcxhr_set_clock(struct pcxhr_mgr *mgr, unsigned int rate) 297static int pcxhr_sub_set_clock(struct pcxhr_mgr *mgr,
298 unsigned int rate,
299 int *changed)
220{ 300{
221 unsigned int val, realfreq, speed; 301 unsigned int val, realfreq, speed;
222 struct pcxhr_rmh rmh; 302 struct pcxhr_rmh rmh;
223 int err, changed; 303 int err;
224
225 if (rate == 0)
226 return 0; /* nothing to do */
227 304
228 err = pcxhr_get_clock_reg(mgr, rate, &val, &realfreq); 305 err = pcxhr_get_clock_reg(mgr, rate, &val, &realfreq);
229 if (err) 306 if (err)
@@ -237,13 +314,17 @@ int pcxhr_set_clock(struct pcxhr_mgr *mgr, unsigned int rate)
237 else 314 else
238 speed = 2; /* quad speed */ 315 speed = 2; /* quad speed */
239 if (mgr->codec_speed != speed) { 316 if (mgr->codec_speed != speed) {
240 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE); /* mute outputs */ 317 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE); /* mute outputs */
241 rmh.cmd[0] |= IO_NUM_REG_MUTE_OUT; 318 rmh.cmd[0] |= IO_NUM_REG_MUTE_OUT;
319 if (DSP_EXT_CMD_SET(mgr)) {
320 rmh.cmd[1] = 1;
321 rmh.cmd_len = 2;
322 }
242 err = pcxhr_send_msg(mgr, &rmh); 323 err = pcxhr_send_msg(mgr, &rmh);
243 if (err) 324 if (err)
244 return err; 325 return err;
245 326
246 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE); /* set speed ratio */ 327 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE); /* set speed ratio */
247 rmh.cmd[0] |= IO_NUM_SPEED_RATIO; 328 rmh.cmd[0] |= IO_NUM_SPEED_RATIO;
248 rmh.cmd[1] = speed; 329 rmh.cmd[1] = speed;
249 rmh.cmd_len = 2; 330 rmh.cmd_len = 2;
@@ -253,25 +334,57 @@ int pcxhr_set_clock(struct pcxhr_mgr *mgr, unsigned int rate)
253 } 334 }
254 /* set the new frequency */ 335 /* set the new frequency */
255 snd_printdd("clock register : set %x\n", val); 336 snd_printdd("clock register : set %x\n", val);
256 err = pcxhr_write_io_num_reg_cont(mgr, PCXHR_FREQ_REG_MASK, val, &changed); 337 err = pcxhr_write_io_num_reg_cont(mgr, PCXHR_FREQ_REG_MASK,
338 val, changed);
257 if (err) 339 if (err)
258 return err; 340 return err;
341
259 mgr->sample_rate_real = realfreq; 342 mgr->sample_rate_real = realfreq;
260 mgr->cur_clock_type = mgr->use_clock_type; 343 mgr->cur_clock_type = mgr->use_clock_type;
261 344
262 /* unmute after codec speed modes */ 345 /* unmute after codec speed modes */
263 if (mgr->codec_speed != speed) { 346 if (mgr->codec_speed != speed) {
264 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ); /* unmute outputs */ 347 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ); /* unmute outputs */
265 rmh.cmd[0] |= IO_NUM_REG_MUTE_OUT; 348 rmh.cmd[0] |= IO_NUM_REG_MUTE_OUT;
349 if (DSP_EXT_CMD_SET(mgr)) {
350 rmh.cmd[1] = 1;
351 rmh.cmd_len = 2;
352 }
266 err = pcxhr_send_msg(mgr, &rmh); 353 err = pcxhr_send_msg(mgr, &rmh);
267 if (err) 354 if (err)
268 return err; 355 return err;
269 mgr->codec_speed = speed; /* save new codec speed */ 356 mgr->codec_speed = speed; /* save new codec speed */
270 } 357 }
271 358
359 snd_printdd("pcxhr_sub_set_clock to %dHz (realfreq=%d)\n",
360 rate, realfreq);
361 return 0;
362}
363
364#define PCXHR_MODIFY_CLOCK_S_BIT 0x04
365
366#define PCXHR_IRQ_TIMER_FREQ 92000
367#define PCXHR_IRQ_TIMER_PERIOD 48
368
369int pcxhr_set_clock(struct pcxhr_mgr *mgr, unsigned int rate)
370{
371 struct pcxhr_rmh rmh;
372 int err, changed;
373
374 if (rate == 0)
375 return 0; /* nothing to do */
376
377 if (mgr->is_hr_stereo)
378 err = hr222_sub_set_clock(mgr, rate, &changed);
379 else
380 err = pcxhr_sub_set_clock(mgr, rate, &changed);
381
382 if (err)
383 return err;
384
272 if (changed) { 385 if (changed) {
273 pcxhr_init_rmh(&rmh, CMD_MODIFY_CLOCK); 386 pcxhr_init_rmh(&rmh, CMD_MODIFY_CLOCK);
274 rmh.cmd[0] |= PCXHR_MODIFY_CLOCK_S_BIT; /* resync fifos */ 387 rmh.cmd[0] |= PCXHR_MODIFY_CLOCK_S_BIT; /* resync fifos */
275 if (rate < PCXHR_IRQ_TIMER_FREQ) 388 if (rate < PCXHR_IRQ_TIMER_FREQ)
276 rmh.cmd[1] = PCXHR_IRQ_TIMER_PERIOD; 389 rmh.cmd[1] = PCXHR_IRQ_TIMER_PERIOD;
277 else 390 else
@@ -282,26 +395,39 @@ int pcxhr_set_clock(struct pcxhr_mgr *mgr, unsigned int rate)
282 if (err) 395 if (err)
283 return err; 396 return err;
284 } 397 }
285 snd_printdd("pcxhr_set_clock to %dHz (realfreq=%d)\n", rate, realfreq);
286 return 0; 398 return 0;
287} 399}
288 400
289 401
290int pcxhr_get_external_clock(struct pcxhr_mgr *mgr, enum pcxhr_clock_type clock_type, 402static int pcxhr_sub_get_external_clock(struct pcxhr_mgr *mgr,
291 int *sample_rate) 403 enum pcxhr_clock_type clock_type,
404 int *sample_rate)
292{ 405{
293 struct pcxhr_rmh rmh; 406 struct pcxhr_rmh rmh;
294 unsigned char reg; 407 unsigned char reg;
295 int err, rate; 408 int err, rate;
296 409
297 switch (clock_type) { 410 switch (clock_type) {
298 case PCXHR_CLOCK_TYPE_WORD_CLOCK : reg = REG_STATUS_WORD_CLOCK; break; 411 case PCXHR_CLOCK_TYPE_WORD_CLOCK:
299 case PCXHR_CLOCK_TYPE_AES_SYNC : reg = REG_STATUS_AES_SYNC; break; 412 reg = REG_STATUS_WORD_CLOCK;
300 case PCXHR_CLOCK_TYPE_AES_1 : reg = REG_STATUS_AES_1; break; 413 break;
301 case PCXHR_CLOCK_TYPE_AES_2 : reg = REG_STATUS_AES_2; break; 414 case PCXHR_CLOCK_TYPE_AES_SYNC:
302 case PCXHR_CLOCK_TYPE_AES_3 : reg = REG_STATUS_AES_3; break; 415 reg = REG_STATUS_AES_SYNC;
303 case PCXHR_CLOCK_TYPE_AES_4 : reg = REG_STATUS_AES_4; break; 416 break;
304 default : return -EINVAL; 417 case PCXHR_CLOCK_TYPE_AES_1:
418 reg = REG_STATUS_AES_1;
419 break;
420 case PCXHR_CLOCK_TYPE_AES_2:
421 reg = REG_STATUS_AES_2;
422 break;
423 case PCXHR_CLOCK_TYPE_AES_3:
424 reg = REG_STATUS_AES_3;
425 break;
426 case PCXHR_CLOCK_TYPE_AES_4:
427 reg = REG_STATUS_AES_4;
428 break;
429 default:
430 return -EINVAL;
305 } 431 }
306 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ); 432 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ);
307 rmh.cmd_len = 2; 433 rmh.cmd_len = 2;
@@ -311,7 +437,7 @@ int pcxhr_get_external_clock(struct pcxhr_mgr *mgr, enum pcxhr_clock_type clock_
311 err = pcxhr_send_msg(mgr, &rmh); 437 err = pcxhr_send_msg(mgr, &rmh);
312 if (err) 438 if (err)
313 return err; 439 return err;
314 udelay(100); /* wait minimum 2 sample_frames at 32kHz ! */ 440 udelay(100); /* wait minimum 2 sample_frames at 32kHz ! */
315 mgr->last_reg_stat = reg; 441 mgr->last_reg_stat = reg;
316 } 442 }
317 rmh.cmd[1] = REG_STATUS_CURRENT; 443 rmh.cmd[1] = REG_STATUS_CURRENT;
@@ -336,6 +462,18 @@ int pcxhr_get_external_clock(struct pcxhr_mgr *mgr, enum pcxhr_clock_type clock_
336} 462}
337 463
338 464
465int pcxhr_get_external_clock(struct pcxhr_mgr *mgr,
466 enum pcxhr_clock_type clock_type,
467 int *sample_rate)
468{
469 if (mgr->is_hr_stereo)
470 return hr222_get_external_clock(mgr, clock_type,
471 sample_rate);
472 else
473 return pcxhr_sub_get_external_clock(mgr, clock_type,
474 sample_rate);
475}
476
339/* 477/*
340 * start or stop playback/capture substream 478 * start or stop playback/capture substream
341 */ 479 */
@@ -350,7 +488,8 @@ static int pcxhr_set_stream_state(struct pcxhr_stream *stream)
350 start = 1; 488 start = 1;
351 else { 489 else {
352 if (stream->status != PCXHR_STREAM_STATUS_SCHEDULE_STOP) { 490 if (stream->status != PCXHR_STREAM_STATUS_SCHEDULE_STOP) {
353 snd_printk(KERN_ERR "ERROR pcxhr_set_stream_state CANNOT be stopped\n"); 491 snd_printk(KERN_ERR "ERROR pcxhr_set_stream_state "
492 "CANNOT be stopped\n");
354 return -EINVAL; 493 return -EINVAL;
355 } 494 }
356 start = 0; 495 start = 0;
@@ -359,11 +498,12 @@ static int pcxhr_set_stream_state(struct pcxhr_stream *stream)
359 return -EINVAL; 498 return -EINVAL;
360 499
361 stream->timer_abs_periods = 0; 500 stream->timer_abs_periods = 0;
362 stream->timer_period_frag = 0; /* reset theoretical stream pos */ 501 stream->timer_period_frag = 0; /* reset theoretical stream pos */
363 stream->timer_buf_periods = 0; 502 stream->timer_buf_periods = 0;
364 stream->timer_is_synced = 0; 503 stream->timer_is_synced = 0;
365 504
366 stream_mask = stream->pipe->is_capture ? 1 : 1<<stream->substream->number; 505 stream_mask =
506 stream->pipe->is_capture ? 1 : 1<<stream->substream->number;
367 507
368 pcxhr_init_rmh(&rmh, start ? CMD_START_STREAM : CMD_STOP_STREAM); 508 pcxhr_init_rmh(&rmh, start ? CMD_START_STREAM : CMD_STOP_STREAM);
369 pcxhr_set_pipe_cmd_params(&rmh, stream->pipe->is_capture, 509 pcxhr_set_pipe_cmd_params(&rmh, stream->pipe->is_capture,
@@ -373,8 +513,10 @@ static int pcxhr_set_stream_state(struct pcxhr_stream *stream)
373 513
374 err = pcxhr_send_msg(chip->mgr, &rmh); 514 err = pcxhr_send_msg(chip->mgr, &rmh);
375 if (err) 515 if (err)
376 snd_printk(KERN_ERR "ERROR pcxhr_set_stream_state err=%x;\n", err); 516 snd_printk(KERN_ERR "ERROR pcxhr_set_stream_state err=%x;\n",
377 stream->status = start ? PCXHR_STREAM_STATUS_STARTED : PCXHR_STREAM_STATUS_STOPPED; 517 err);
518 stream->status =
519 start ? PCXHR_STREAM_STATUS_STARTED : PCXHR_STREAM_STATUS_STOPPED;
378 return err; 520 return err;
379} 521}
380 522
@@ -399,13 +541,15 @@ static int pcxhr_set_format(struct pcxhr_stream *stream)
399 header = HEADER_FMT_BASE_LIN; 541 header = HEADER_FMT_BASE_LIN;
400 break; 542 break;
401 case SNDRV_PCM_FORMAT_S16_LE: 543 case SNDRV_PCM_FORMAT_S16_LE:
402 header = HEADER_FMT_BASE_LIN | HEADER_FMT_16BITS | HEADER_FMT_INTEL; 544 header = HEADER_FMT_BASE_LIN |
545 HEADER_FMT_16BITS | HEADER_FMT_INTEL;
403 break; 546 break;
404 case SNDRV_PCM_FORMAT_S16_BE: 547 case SNDRV_PCM_FORMAT_S16_BE:
405 header = HEADER_FMT_BASE_LIN | HEADER_FMT_16BITS; 548 header = HEADER_FMT_BASE_LIN | HEADER_FMT_16BITS;
406 break; 549 break;
407 case SNDRV_PCM_FORMAT_S24_3LE: 550 case SNDRV_PCM_FORMAT_S24_3LE:
408 header = HEADER_FMT_BASE_LIN | HEADER_FMT_24BITS | HEADER_FMT_INTEL; 551 header = HEADER_FMT_BASE_LIN |
552 HEADER_FMT_24BITS | HEADER_FMT_INTEL;
409 break; 553 break;
410 case SNDRV_PCM_FORMAT_S24_3BE: 554 case SNDRV_PCM_FORMAT_S24_3BE:
411 header = HEADER_FMT_BASE_LIN | HEADER_FMT_24BITS; 555 header = HEADER_FMT_BASE_LIN | HEADER_FMT_24BITS;
@@ -414,7 +558,8 @@ static int pcxhr_set_format(struct pcxhr_stream *stream)
414 header = HEADER_FMT_BASE_FLOAT | HEADER_FMT_INTEL; 558 header = HEADER_FMT_BASE_FLOAT | HEADER_FMT_INTEL;
415 break; 559 break;
416 default: 560 default:
417 snd_printk(KERN_ERR "error pcxhr_set_format() : unknown format\n"); 561 snd_printk(KERN_ERR
562 "error pcxhr_set_format() : unknown format\n");
418 return -EINVAL; 563 return -EINVAL;
419 } 564 }
420 chip = snd_pcm_substream_chip(stream->substream); 565 chip = snd_pcm_substream_chip(stream->substream);
@@ -432,14 +577,31 @@ static int pcxhr_set_format(struct pcxhr_stream *stream)
432 is_capture = stream->pipe->is_capture; 577 is_capture = stream->pipe->is_capture;
433 stream_num = is_capture ? 0 : stream->substream->number; 578 stream_num = is_capture ? 0 : stream->substream->number;
434 579
435 pcxhr_init_rmh(&rmh, is_capture ? CMD_FORMAT_STREAM_IN : CMD_FORMAT_STREAM_OUT); 580 pcxhr_init_rmh(&rmh, is_capture ?
436 pcxhr_set_pipe_cmd_params(&rmh, is_capture, stream->pipe->first_audio, stream_num, 0); 581 CMD_FORMAT_STREAM_IN : CMD_FORMAT_STREAM_OUT);
437 if (is_capture) 582 pcxhr_set_pipe_cmd_params(&rmh, is_capture, stream->pipe->first_audio,
438 rmh.cmd[0] |= 1<<12; 583 stream_num, 0);
584 if (is_capture) {
585 /* bug with old dsp versions: */
586 /* bit 12 also sets the format of the playback stream */
587 if (DSP_EXT_CMD_SET(chip->mgr))
588 rmh.cmd[0] |= 1<<10;
589 else
590 rmh.cmd[0] |= 1<<12;
591 }
439 rmh.cmd[1] = 0; 592 rmh.cmd[1] = 0;
440 rmh.cmd[2] = header >> 8; 593 rmh.cmd_len = 2;
441 rmh.cmd[3] = (header & 0xff) << 16; 594 if (DSP_EXT_CMD_SET(chip->mgr)) {
442 rmh.cmd_len = 4; 595 /* add channels and set bit 19 if channels>2 */
596 rmh.cmd[1] = stream->channels;
597 if (!is_capture) {
598 /* playback : add channel mask to command */
599 rmh.cmd[2] = (stream->channels == 1) ? 0x01 : 0x03;
600 rmh.cmd_len = 3;
601 }
602 }
603 rmh.cmd[rmh.cmd_len++] = header >> 8;
604 rmh.cmd[rmh.cmd_len++] = (header & 0xff) << 16;
443 err = pcxhr_send_msg(chip->mgr, &rmh); 605 err = pcxhr_send_msg(chip->mgr, &rmh);
444 if (err) 606 if (err)
445 snd_printk(KERN_ERR "ERROR pcxhr_set_format err=%x;\n", err); 607 snd_printk(KERN_ERR "ERROR pcxhr_set_format err=%x;\n", err);
@@ -456,30 +618,38 @@ static int pcxhr_update_r_buffer(struct pcxhr_stream *stream)
456 is_capture = (subs->stream == SNDRV_PCM_STREAM_CAPTURE); 618 is_capture = (subs->stream == SNDRV_PCM_STREAM_CAPTURE);
457 stream_num = is_capture ? 0 : subs->number; 619 stream_num = is_capture ? 0 : subs->number;
458 620
459 snd_printdd("pcxhr_update_r_buffer(pcm%c%d) : addr(%p) bytes(%zx) subs(%d)\n", 621 snd_printdd("pcxhr_update_r_buffer(pcm%c%d) : "
622 "addr(%p) bytes(%zx) subs(%d)\n",
460 is_capture ? 'c' : 'p', 623 is_capture ? 'c' : 'p',
461 chip->chip_idx, (void *)(long)subs->runtime->dma_addr, 624 chip->chip_idx, (void *)(long)subs->runtime->dma_addr,
462 subs->runtime->dma_bytes, subs->number); 625 subs->runtime->dma_bytes, subs->number);
463 626
464 pcxhr_init_rmh(&rmh, CMD_UPDATE_R_BUFFERS); 627 pcxhr_init_rmh(&rmh, CMD_UPDATE_R_BUFFERS);
465 pcxhr_set_pipe_cmd_params(&rmh, is_capture, stream->pipe->first_audio, stream_num, 0); 628 pcxhr_set_pipe_cmd_params(&rmh, is_capture, stream->pipe->first_audio,
629 stream_num, 0);
466 630
467 /* max buffer size is 2 MByte */ 631 /* max buffer size is 2 MByte */
468 snd_BUG_ON(subs->runtime->dma_bytes >= 0x200000); 632 snd_BUG_ON(subs->runtime->dma_bytes >= 0x200000);
469 rmh.cmd[1] = subs->runtime->dma_bytes * 8; /* size in bits */ 633 /* size in bits */
470 rmh.cmd[2] = subs->runtime->dma_addr >> 24; /* most significant byte */ 634 rmh.cmd[1] = subs->runtime->dma_bytes * 8;
471 rmh.cmd[2] |= 1<<19; /* this is a circular buffer */ 635 /* most significant byte */
472 rmh.cmd[3] = subs->runtime->dma_addr & MASK_DSP_WORD; /* least 3 significant bytes */ 636 rmh.cmd[2] = subs->runtime->dma_addr >> 24;
637 /* this is a circular buffer */
638 rmh.cmd[2] |= 1<<19;
639 /* least 3 significant bytes */
640 rmh.cmd[3] = subs->runtime->dma_addr & MASK_DSP_WORD;
473 rmh.cmd_len = 4; 641 rmh.cmd_len = 4;
474 err = pcxhr_send_msg(chip->mgr, &rmh); 642 err = pcxhr_send_msg(chip->mgr, &rmh);
475 if (err) 643 if (err)
476 snd_printk(KERN_ERR "ERROR CMD_UPDATE_R_BUFFERS err=%x;\n", err); 644 snd_printk(KERN_ERR
645 "ERROR CMD_UPDATE_R_BUFFERS err=%x;\n", err);
477 return err; 646 return err;
478} 647}
479 648
480 649
481#if 0 650#if 0
482static int pcxhr_pipe_sample_count(struct pcxhr_stream *stream, snd_pcm_uframes_t *sample_count) 651static int pcxhr_pipe_sample_count(struct pcxhr_stream *stream,
652 snd_pcm_uframes_t *sample_count)
483{ 653{
484 struct pcxhr_rmh rmh; 654 struct pcxhr_rmh rmh;
485 int err; 655 int err;
@@ -533,8 +703,8 @@ static void pcxhr_trigger_tasklet(unsigned long arg)
533 for (j = 0; j < chip->nb_streams_play; j++) { 703 for (j = 0; j < chip->nb_streams_play; j++) {
534 if (pcxhr_stream_scheduled_get_pipe(&chip->playback_stream[j], &pipe)) { 704 if (pcxhr_stream_scheduled_get_pipe(&chip->playback_stream[j], &pipe)) {
535 playback_mask |= (1 << pipe->first_audio); 705 playback_mask |= (1 << pipe->first_audio);
536 break; /* add only once, as all playback streams of 706 break; /* add only once, as all playback
537 * one chip use the same pipe 707 * streams of one chip use the same pipe
538 */ 708 */
539 } 709 }
540 } 710 }
@@ -545,19 +715,21 @@ static void pcxhr_trigger_tasklet(unsigned long arg)
545 return; 715 return;
546 } 716 }
547 717
548 snd_printdd("pcxhr_trigger_tasklet : playback_mask=%x capture_mask=%x\n", 718 snd_printdd("pcxhr_trigger_tasklet : "
719 "playback_mask=%x capture_mask=%x\n",
549 playback_mask, capture_mask); 720 playback_mask, capture_mask);
550 721
551 /* synchronous stop of all the pipes concerned */ 722 /* synchronous stop of all the pipes concerned */
552 err = pcxhr_set_pipe_state(mgr, playback_mask, capture_mask, 0); 723 err = pcxhr_set_pipe_state(mgr, playback_mask, capture_mask, 0);
553 if (err) { 724 if (err) {
554 mutex_unlock(&mgr->setup_mutex); 725 mutex_unlock(&mgr->setup_mutex);
555 snd_printk(KERN_ERR "pcxhr_trigger_tasklet : error stop pipes (P%x C%x)\n", 726 snd_printk(KERN_ERR "pcxhr_trigger_tasklet : "
727 "error stop pipes (P%x C%x)\n",
556 playback_mask, capture_mask); 728 playback_mask, capture_mask);
557 return; 729 return;
558 } 730 }
559 731
560 /* unfortunately the dsp lost format and buffer info with the stop pipe */ 732 /* the dsp lost format and buffer info with the stop pipe */
561 for (i = 0; i < mgr->num_cards; i++) { 733 for (i = 0; i < mgr->num_cards; i++) {
562 struct pcxhr_stream *stream; 734 struct pcxhr_stream *stream;
563 chip = mgr->chip[i]; 735 chip = mgr->chip[i];
@@ -596,12 +768,15 @@ static void pcxhr_trigger_tasklet(unsigned long arg)
596 err = pcxhr_set_pipe_state(mgr, playback_mask, capture_mask, 1); 768 err = pcxhr_set_pipe_state(mgr, playback_mask, capture_mask, 1);
597 if (err) { 769 if (err) {
598 mutex_unlock(&mgr->setup_mutex); 770 mutex_unlock(&mgr->setup_mutex);
599 snd_printk(KERN_ERR "pcxhr_trigger_tasklet : error start pipes (P%x C%x)\n", 771 snd_printk(KERN_ERR "pcxhr_trigger_tasklet : "
772 "error start pipes (P%x C%x)\n",
600 playback_mask, capture_mask); 773 playback_mask, capture_mask);
601 return; 774 return;
602 } 775 }
603 776
604 /* put the streams into the running state now (increment pointer by interrupt) */ 777 /* put the streams into the running state now
778 * (increment pointer by interrupt)
779 */
605 spin_lock_irqsave(&mgr->lock, flags); 780 spin_lock_irqsave(&mgr->lock, flags);
606 for ( i =0; i < mgr->num_cards; i++) { 781 for ( i =0; i < mgr->num_cards; i++) {
607 struct pcxhr_stream *stream; 782 struct pcxhr_stream *stream;
@@ -615,7 +790,7 @@ static void pcxhr_trigger_tasklet(unsigned long arg)
615 stream = &chip->playback_stream[j]; 790 stream = &chip->playback_stream[j];
616 if (stream->status == PCXHR_STREAM_STATUS_STARTED) { 791 if (stream->status == PCXHR_STREAM_STATUS_STARTED) {
617 /* playback will already have advanced ! */ 792 /* playback will already have advanced ! */
618 stream->timer_period_frag += PCXHR_GRANULARITY; 793 stream->timer_period_frag += mgr->granularity;
619 stream->status = PCXHR_STREAM_STATUS_RUNNING; 794 stream->status = PCXHR_STREAM_STATUS_RUNNING;
620 } 795 }
621 } 796 }
@@ -653,7 +828,7 @@ static int pcxhr_trigger(struct snd_pcm_substream *subs, int cmd)
653 PCXHR_STREAM_STATUS_SCHEDULE_RUN; 828 PCXHR_STREAM_STATUS_SCHEDULE_RUN;
654 snd_pcm_trigger_done(s, subs); 829 snd_pcm_trigger_done(s, subs);
655 } 830 }
656 tasklet_hi_schedule(&chip->mgr->trigger_taskq); 831 tasklet_schedule(&chip->mgr->trigger_taskq);
657 } else { 832 } else {
658 stream = subs->runtime->private_data; 833 stream = subs->runtime->private_data;
659 snd_printdd("Only one Substream %c %d\n", 834 snd_printdd("Only one Substream %c %d\n",
@@ -697,12 +872,14 @@ static int pcxhr_hardware_timer(struct pcxhr_mgr *mgr, int start)
697 872
698 pcxhr_init_rmh(&rmh, CMD_SET_TIMER_INTERRUPT); 873 pcxhr_init_rmh(&rmh, CMD_SET_TIMER_INTERRUPT);
699 if (start) { 874 if (start) {
700 mgr->dsp_time_last = PCXHR_DSP_TIME_INVALID; /* last dsp time invalid */ 875 /* last dsp time invalid */
701 rmh.cmd[0] |= PCXHR_GRANULARITY; 876 mgr->dsp_time_last = PCXHR_DSP_TIME_INVALID;
877 rmh.cmd[0] |= mgr->granularity;
702 } 878 }
703 err = pcxhr_send_msg(mgr, &rmh); 879 err = pcxhr_send_msg(mgr, &rmh);
704 if (err < 0) 880 if (err < 0)
705 snd_printk(KERN_ERR "error pcxhr_hardware_timer err(%x)\n", err); 881 snd_printk(KERN_ERR "error pcxhr_hardware_timer err(%x)\n",
882 err);
706 return err; 883 return err;
707} 884}
708 885
@@ -713,38 +890,16 @@ static int pcxhr_prepare(struct snd_pcm_substream *subs)
713{ 890{
714 struct snd_pcxhr *chip = snd_pcm_substream_chip(subs); 891 struct snd_pcxhr *chip = snd_pcm_substream_chip(subs);
715 struct pcxhr_mgr *mgr = chip->mgr; 892 struct pcxhr_mgr *mgr = chip->mgr;
716 /*
717 struct pcxhr_stream *stream = (pcxhr_stream_t*)subs->runtime->private_data;
718 */
719 int err = 0; 893 int err = 0;
720 894
721 snd_printdd("pcxhr_prepare : period_size(%lx) periods(%x) buffer_size(%lx)\n", 895 snd_printdd("pcxhr_prepare : period_size(%lx) periods(%x) buffer_size(%lx)\n",
722 subs->runtime->period_size, subs->runtime->periods, 896 subs->runtime->period_size, subs->runtime->periods,
723 subs->runtime->buffer_size); 897 subs->runtime->buffer_size);
724 898
725 /*
726 if(subs->runtime->period_size <= PCXHR_GRANULARITY) {
727 snd_printk(KERN_ERR "pcxhr_prepare : error period_size too small (%x)\n",
728 (unsigned int)subs->runtime->period_size);
729 return -EINVAL;
730 }
731 */
732
733 mutex_lock(&mgr->setup_mutex); 899 mutex_lock(&mgr->setup_mutex);
734 900
735 do { 901 do {
736 /* if the stream was stopped before, format and buffer were reset */
737 /*
738 if(stream->status == PCXHR_STREAM_STATUS_STOPPED) {
739 err = pcxhr_set_format(stream);
740 if(err) break;
741 err = pcxhr_update_r_buffer(stream);
742 if(err) break;
743 }
744 */
745
746 /* only the first stream can choose the sample rate */ 902 /* only the first stream can choose the sample rate */
747 /* the further opened streams will be limited to its frequency (see open) */
748 /* set the clock only once (first stream) */ 903 /* set the clock only once (first stream) */
749 if (mgr->sample_rate != subs->runtime->rate) { 904 if (mgr->sample_rate != subs->runtime->rate) {
750 err = pcxhr_set_clock(mgr, subs->runtime->rate); 905 err = pcxhr_set_clock(mgr, subs->runtime->rate);
@@ -787,22 +942,9 @@ static int pcxhr_hw_params(struct snd_pcm_substream *subs,
787 stream->channels = channels; 942 stream->channels = channels;
788 stream->format = format; 943 stream->format = format;
789 944
790 /* set the format to the board */
791 /*
792 err = pcxhr_set_format(stream);
793 if(err) {
794 mutex_unlock(&mgr->setup_mutex);
795 return err;
796 }
797 */
798 /* allocate buffer */ 945 /* allocate buffer */
799 err = snd_pcm_lib_malloc_pages(subs, params_buffer_bytes(hw)); 946 err = snd_pcm_lib_malloc_pages(subs, params_buffer_bytes(hw));
800 947
801 /*
802 if (err > 0) {
803 err = pcxhr_update_r_buffer(stream);
804 }
805 */
806 mutex_unlock(&mgr->setup_mutex); 948 mutex_unlock(&mgr->setup_mutex);
807 949
808 return err; 950 return err;
@@ -820,14 +962,18 @@ static int pcxhr_hw_free(struct snd_pcm_substream *subs)
820 */ 962 */
821static struct snd_pcm_hardware pcxhr_caps = 963static struct snd_pcm_hardware pcxhr_caps =
822{ 964{
823 .info = ( SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 965 .info = (SNDRV_PCM_INFO_MMAP |
824 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START | 966 SNDRV_PCM_INFO_INTERLEAVED |
825 0 /*SNDRV_PCM_INFO_PAUSE*/), 967 SNDRV_PCM_INFO_MMAP_VALID |
826 .formats = ( SNDRV_PCM_FMTBIT_U8 | 968 SNDRV_PCM_INFO_SYNC_START),
827 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | 969 .formats = (SNDRV_PCM_FMTBIT_U8 |
828 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE | 970 SNDRV_PCM_FMTBIT_S16_LE |
829 SNDRV_PCM_FMTBIT_FLOAT_LE ), 971 SNDRV_PCM_FMTBIT_S16_BE |
830 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_192000, 972 SNDRV_PCM_FMTBIT_S24_3LE |
973 SNDRV_PCM_FMTBIT_S24_3BE |
974 SNDRV_PCM_FMTBIT_FLOAT_LE),
975 .rates = (SNDRV_PCM_RATE_CONTINUOUS |
976 SNDRV_PCM_RATE_8000_192000),
831 .rate_min = 8000, 977 .rate_min = 8000,
832 .rate_max = 192000, 978 .rate_max = 192000,
833 .channels_min = 1, 979 .channels_min = 1,
@@ -847,6 +993,7 @@ static int pcxhr_open(struct snd_pcm_substream *subs)
847 struct pcxhr_mgr *mgr = chip->mgr; 993 struct pcxhr_mgr *mgr = chip->mgr;
848 struct snd_pcm_runtime *runtime = subs->runtime; 994 struct snd_pcm_runtime *runtime = subs->runtime;
849 struct pcxhr_stream *stream; 995 struct pcxhr_stream *stream;
996 int err;
850 997
851 mutex_lock(&mgr->setup_mutex); 998 mutex_lock(&mgr->setup_mutex);
852 999
@@ -874,6 +1021,18 @@ static int pcxhr_open(struct snd_pcm_substream *subs)
874 return -EBUSY; 1021 return -EBUSY;
875 } 1022 }
876 1023
1024 /* float format support is in some cases buggy on stereo cards */
1025 if (mgr->is_hr_stereo)
1026 runtime->hw.formats &= ~SNDRV_PCM_FMTBIT_FLOAT_LE;
1027
1028 /* buffer-size should better be multiple of period-size */
1029 err = snd_pcm_hw_constraint_integer(runtime,
1030 SNDRV_PCM_HW_PARAM_PERIODS);
1031 if (err < 0) {
1032 mutex_unlock(&mgr->setup_mutex);
1033 return err;
1034 }
1035
877 /* if a sample rate is already used or fixed by external clock, 1036 /* if a sample rate is already used or fixed by external clock,
878 * the stream cannot change 1037 * the stream cannot change
879 */ 1038 */
@@ -889,7 +1048,8 @@ static int pcxhr_open(struct snd_pcm_substream *subs)
889 mutex_unlock(&mgr->setup_mutex); 1048 mutex_unlock(&mgr->setup_mutex);
890 return -EBUSY; 1049 return -EBUSY;
891 } 1050 }
892 runtime->hw.rate_min = runtime->hw.rate_max = external_rate; 1051 runtime->hw.rate_min = external_rate;
1052 runtime->hw.rate_max = external_rate;
893 } 1053 }
894 } 1054 }
895 1055
@@ -899,9 +1059,11 @@ static int pcxhr_open(struct snd_pcm_substream *subs)
899 1059
900 runtime->private_data = stream; 1060 runtime->private_data = stream;
901 1061
902 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 4); 1062 /* better get a divisor of granularity values (96 or 192) */
903 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 4); 1063 snd_pcm_hw_constraint_step(runtime, 0,
904 1064 SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 32);
1065 snd_pcm_hw_constraint_step(runtime, 0,
1066 SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 32);
905 snd_pcm_set_sync(subs); 1067 snd_pcm_set_sync(subs);
906 1068
907 mgr->ref_count_rate++; 1069 mgr->ref_count_rate++;
@@ -919,11 +1081,12 @@ static int pcxhr_close(struct snd_pcm_substream *subs)
919 1081
920 mutex_lock(&mgr->setup_mutex); 1082 mutex_lock(&mgr->setup_mutex);
921 1083
922 snd_printdd("pcxhr_close chip%d subs%d\n", chip->chip_idx, subs->number); 1084 snd_printdd("pcxhr_close chip%d subs%d\n",
1085 chip->chip_idx, subs->number);
923 1086
924 /* sample rate released */ 1087 /* sample rate released */
925 if (--mgr->ref_count_rate == 0) { 1088 if (--mgr->ref_count_rate == 0) {
926 mgr->sample_rate = 0; /* the sample rate is no more locked */ 1089 mgr->sample_rate = 0; /* the sample rate is no more locked */
927 pcxhr_hardware_timer(mgr, 0); /* stop the DSP-timer */ 1090 pcxhr_hardware_timer(mgr, 0); /* stop the DSP-timer */
928 } 1091 }
929 1092
@@ -1016,7 +1179,8 @@ static int pcxhr_chip_dev_free(struct snd_device *device)
1016 1179
1017/* 1180/*
1018 */ 1181 */
1019static int __devinit pcxhr_create(struct pcxhr_mgr *mgr, struct snd_card *card, int idx) 1182static int __devinit pcxhr_create(struct pcxhr_mgr *mgr,
1183 struct snd_card *card, int idx)
1020{ 1184{
1021 int err; 1185 int err;
1022 struct snd_pcxhr *chip; 1186 struct snd_pcxhr *chip;
@@ -1024,7 +1188,7 @@ static int __devinit pcxhr_create(struct pcxhr_mgr *mgr, struct snd_card *card,
1024 .dev_free = pcxhr_chip_dev_free, 1188 .dev_free = pcxhr_chip_dev_free,
1025 }; 1189 };
1026 1190
1027 mgr->chip[idx] = chip = kzalloc(sizeof(*chip), GFP_KERNEL); 1191 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
1028 if (! chip) { 1192 if (! chip) {
1029 snd_printk(KERN_ERR "cannot allocate chip\n"); 1193 snd_printk(KERN_ERR "cannot allocate chip\n");
1030 return -ENOMEM; 1194 return -ENOMEM;
@@ -1040,7 +1204,7 @@ static int __devinit pcxhr_create(struct pcxhr_mgr *mgr, struct snd_card *card,
1040 1204
1041 if (idx < mgr->capture_chips) { 1205 if (idx < mgr->capture_chips) {
1042 if (mgr->mono_capture) 1206 if (mgr->mono_capture)
1043 chip->nb_streams_capt = 2; /* 2 mono streams (left+right) */ 1207 chip->nb_streams_capt = 2; /* 2 mono streams */
1044 else 1208 else
1045 chip->nb_streams_capt = 1; /* or 1 stereo stream */ 1209 chip->nb_streams_capt = 1; /* or 1 stereo stream */
1046 } 1210 }
@@ -1050,13 +1214,15 @@ static int __devinit pcxhr_create(struct pcxhr_mgr *mgr, struct snd_card *card,
1050 return err; 1214 return err;
1051 } 1215 }
1052 1216
1217 mgr->chip[idx] = chip;
1053 snd_card_set_dev(card, &mgr->pci->dev); 1218 snd_card_set_dev(card, &mgr->pci->dev);
1054 1219
1055 return 0; 1220 return 0;
1056} 1221}
1057 1222
1058/* proc interface */ 1223/* proc interface */
1059static void pcxhr_proc_info(struct snd_info_entry *entry, struct snd_info_buffer *buffer) 1224static void pcxhr_proc_info(struct snd_info_entry *entry,
1225 struct snd_info_buffer *buffer)
1060{ 1226{
1061 struct snd_pcxhr *chip = entry->private_data; 1227 struct snd_pcxhr *chip = entry->private_data;
1062 struct pcxhr_mgr *mgr = chip->mgr; 1228 struct pcxhr_mgr *mgr = chip->mgr;
@@ -1069,8 +1235,10 @@ static void pcxhr_proc_info(struct snd_info_entry *entry, struct snd_info_buffer
1069 short ver_maj = (mgr->dsp_version >> 16) & 0xff; 1235 short ver_maj = (mgr->dsp_version >> 16) & 0xff;
1070 short ver_min = (mgr->dsp_version >> 8) & 0xff; 1236 short ver_min = (mgr->dsp_version >> 8) & 0xff;
1071 short ver_build = mgr->dsp_version & 0xff; 1237 short ver_build = mgr->dsp_version & 0xff;
1072 snd_iprintf(buffer, "module version %s\n", PCXHR_DRIVER_VERSION_STRING); 1238 snd_iprintf(buffer, "module version %s\n",
1073 snd_iprintf(buffer, "dsp version %d.%d.%d\n", ver_maj, ver_min, ver_build); 1239 PCXHR_DRIVER_VERSION_STRING);
1240 snd_iprintf(buffer, "dsp version %d.%d.%d\n",
1241 ver_maj, ver_min, ver_build);
1074 if (mgr->board_has_analog) 1242 if (mgr->board_has_analog)
1075 snd_iprintf(buffer, "analog io available\n"); 1243 snd_iprintf(buffer, "analog io available\n");
1076 else 1244 else
@@ -1084,18 +1252,22 @@ static void pcxhr_proc_info(struct snd_info_entry *entry, struct snd_info_buffer
1084 if (ref > 0) { 1252 if (ref > 0) {
1085 if (mgr->sample_rate_real != 0 && 1253 if (mgr->sample_rate_real != 0 &&
1086 mgr->sample_rate_real != 48000) { 1254 mgr->sample_rate_real != 48000) {
1087 ref = (ref * 48000) / mgr->sample_rate_real; 1255 ref = (ref * 48000) /
1088 if (mgr->sample_rate_real >= PCXHR_IRQ_TIMER_FREQ) 1256 mgr->sample_rate_real;
1257 if (mgr->sample_rate_real >=
1258 PCXHR_IRQ_TIMER_FREQ)
1089 ref *= 2; 1259 ref *= 2;
1090 } 1260 }
1091 cur = 100 - (100 * cur) / ref; 1261 cur = 100 - (100 * cur) / ref;
1092 snd_iprintf(buffer, "cpu load %d%%\n", cur); 1262 snd_iprintf(buffer, "cpu load %d%%\n", cur);
1093 snd_iprintf(buffer, "buffer pool %d/%d kWords\n", 1263 snd_iprintf(buffer, "buffer pool %d/%d\n",
1094 rmh.stat[2], rmh.stat[3]); 1264 rmh.stat[2], rmh.stat[3]);
1095 } 1265 }
1096 } 1266 }
1097 snd_iprintf(buffer, "dma granularity : %d\n", PCXHR_GRANULARITY); 1267 snd_iprintf(buffer, "dma granularity : %d\n",
1098 snd_iprintf(buffer, "dsp time errors : %d\n", mgr->dsp_time_err); 1268 mgr->granularity);
1269 snd_iprintf(buffer, "dsp time errors : %d\n",
1270 mgr->dsp_time_err);
1099 snd_iprintf(buffer, "dsp async pipe xrun errors : %d\n", 1271 snd_iprintf(buffer, "dsp async pipe xrun errors : %d\n",
1100 mgr->async_err_pipe_xrun); 1272 mgr->async_err_pipe_xrun);
1101 snd_iprintf(buffer, "dsp async stream xrun errors : %d\n", 1273 snd_iprintf(buffer, "dsp async stream xrun errors : %d\n",
@@ -1110,33 +1282,52 @@ static void pcxhr_proc_info(struct snd_info_entry *entry, struct snd_info_buffer
1110 rmh.cmd_idx = CMD_LAST_INDEX; 1282 rmh.cmd_idx = CMD_LAST_INDEX;
1111 if( ! pcxhr_send_msg(mgr, &rmh) ) { 1283 if( ! pcxhr_send_msg(mgr, &rmh) ) {
1112 int i; 1284 int i;
1285 if (rmh.stat_len > 8)
1286 rmh.stat_len = 8;
1113 for (i = 0; i < rmh.stat_len; i++) 1287 for (i = 0; i < rmh.stat_len; i++)
1114 snd_iprintf(buffer, "debug[%02d] = %06x\n", i, rmh.stat[i]); 1288 snd_iprintf(buffer, "debug[%02d] = %06x\n",
1289 i, rmh.stat[i]);
1115 } 1290 }
1116 } else 1291 } else
1117 snd_iprintf(buffer, "no firmware loaded\n"); 1292 snd_iprintf(buffer, "no firmware loaded\n");
1118 snd_iprintf(buffer, "\n"); 1293 snd_iprintf(buffer, "\n");
1119} 1294}
1120static void pcxhr_proc_sync(struct snd_info_entry *entry, struct snd_info_buffer *buffer) 1295static void pcxhr_proc_sync(struct snd_info_entry *entry,
1296 struct snd_info_buffer *buffer)
1121{ 1297{
1122 struct snd_pcxhr *chip = entry->private_data; 1298 struct snd_pcxhr *chip = entry->private_data;
1123 struct pcxhr_mgr *mgr = chip->mgr; 1299 struct pcxhr_mgr *mgr = chip->mgr;
1124 static char *texts[7] = { 1300 static const char *textsHR22[3] = {
1125 "Internal", "Word", "AES Sync", "AES 1", "AES 2", "AES 3", "AES 4" 1301 "Internal", "AES Sync", "AES 1"
1302 };
1303 static const char *textsPCXHR[7] = {
1304 "Internal", "Word", "AES Sync",
1305 "AES 1", "AES 2", "AES 3", "AES 4"
1126 }; 1306 };
1307 const char **texts;
1308 int max_clock;
1309 if (mgr->is_hr_stereo) {
1310 texts = textsHR22;
1311 max_clock = HR22_CLOCK_TYPE_MAX;
1312 } else {
1313 texts = textsPCXHR;
1314 max_clock = PCXHR_CLOCK_TYPE_MAX;
1315 }
1127 1316
1128 snd_iprintf(buffer, "\n%s\n", mgr->longname); 1317 snd_iprintf(buffer, "\n%s\n", mgr->longname);
1129 snd_iprintf(buffer, "Current Sample Clock\t: %s\n", texts[mgr->cur_clock_type]); 1318 snd_iprintf(buffer, "Current Sample Clock\t: %s\n",
1130 snd_iprintf(buffer, "Current Sample Rate\t= %d\n", mgr->sample_rate_real); 1319 texts[mgr->cur_clock_type]);
1131 1320 snd_iprintf(buffer, "Current Sample Rate\t= %d\n",
1321 mgr->sample_rate_real);
1132 /* commands available when embedded DSP is running */ 1322 /* commands available when embedded DSP is running */
1133 if (mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX)) { 1323 if (mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX)) {
1134 int i, err, sample_rate; 1324 int i, err, sample_rate;
1135 for (i = PCXHR_CLOCK_TYPE_WORD_CLOCK; i< (3 + mgr->capture_chips); i++) { 1325 for (i = 1; i <= max_clock; i++) {
1136 err = pcxhr_get_external_clock(mgr, i, &sample_rate); 1326 err = pcxhr_get_external_clock(mgr, i, &sample_rate);
1137 if (err) 1327 if (err)
1138 break; 1328 break;
1139 snd_iprintf(buffer, "%s Clock\t\t= %d\n", texts[i], sample_rate); 1329 snd_iprintf(buffer, "%s Clock\t\t= %d\n",
1330 texts[i], sample_rate);
1140 } 1331 }
1141 } else 1332 } else
1142 snd_iprintf(buffer, "no firmware loaded\n"); 1333 snd_iprintf(buffer, "no firmware loaded\n");
@@ -1194,7 +1385,8 @@ static int pcxhr_free(struct pcxhr_mgr *mgr)
1194/* 1385/*
1195 * probe function - creates the card manager 1386 * probe function - creates the card manager
1196 */ 1387 */
1197static int __devinit pcxhr_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) 1388static int __devinit pcxhr_probe(struct pci_dev *pci,
1389 const struct pci_device_id *pci_id)
1198{ 1390{
1199 static int dev; 1391 static int dev;
1200 struct pcxhr_mgr *mgr; 1392 struct pcxhr_mgr *mgr;
@@ -1217,7 +1409,8 @@ static int __devinit pcxhr_probe(struct pci_dev *pci, const struct pci_device_id
1217 1409
1218 /* check if we can restrict PCI DMA transfers to 32 bits */ 1410 /* check if we can restrict PCI DMA transfers to 32 bits */
1219 if (pci_set_dma_mask(pci, DMA_32BIT_MASK) < 0) { 1411 if (pci_set_dma_mask(pci, DMA_32BIT_MASK) < 0) {
1220 snd_printk(KERN_ERR "architecture does not support 32bit PCI busmaster DMA\n"); 1412 snd_printk(KERN_ERR "architecture does not support "
1413 "32bit PCI busmaster DMA\n");
1221 pci_disable_device(pci); 1414 pci_disable_device(pci);
1222 return -ENXIO; 1415 return -ENXIO;
1223 } 1416 }
@@ -1234,11 +1427,25 @@ static int __devinit pcxhr_probe(struct pci_dev *pci, const struct pci_device_id
1234 pci_disable_device(pci); 1427 pci_disable_device(pci);
1235 return -ENODEV; 1428 return -ENODEV;
1236 } 1429 }
1237 card_name = pcxhr_board_params[pci_id->driver_data].board_name; 1430 card_name =
1238 mgr->playback_chips = pcxhr_board_params[pci_id->driver_data].playback_chips; 1431 pcxhr_board_params[pci_id->driver_data].board_name;
1239 mgr->capture_chips = pcxhr_board_params[pci_id->driver_data].capture_chips; 1432 mgr->playback_chips =
1240 mgr->firmware_num = pcxhr_board_params[pci_id->driver_data].firmware_num; 1433 pcxhr_board_params[pci_id->driver_data].playback_chips;
1434 mgr->capture_chips =
1435 pcxhr_board_params[pci_id->driver_data].capture_chips;
1436 mgr->fw_file_set =
1437 pcxhr_board_params[pci_id->driver_data].fw_file_set;
1438 mgr->firmware_num =
1439 pcxhr_board_params[pci_id->driver_data].firmware_num;
1241 mgr->mono_capture = mono[dev]; 1440 mgr->mono_capture = mono[dev];
1441 mgr->is_hr_stereo = (mgr->playback_chips == 1);
1442 mgr->board_has_aes1 = PCXHR_BOARD_HAS_AES1(mgr);
1443 mgr->board_aes_in_192k = !PCXHR_BOARD_AESIN_NO_192K(mgr);
1444
1445 if (mgr->is_hr_stereo)
1446 mgr->granularity = PCXHR_GRANULARITY_HR22;
1447 else
1448 mgr->granularity = PCXHR_GRANULARITY;
1242 1449
1243 /* resource assignment */ 1450 /* resource assignment */
1244 if ((err = pci_request_regions(pci, card_name)) < 0) { 1451 if ((err = pci_request_regions(pci, card_name)) < 0) {
@@ -1261,7 +1468,8 @@ static int __devinit pcxhr_probe(struct pci_dev *pci, const struct pci_device_id
1261 mgr->irq = pci->irq; 1468 mgr->irq = pci->irq;
1262 1469
1263 sprintf(mgr->shortname, "Digigram %s", card_name); 1470 sprintf(mgr->shortname, "Digigram %s", card_name);
1264 sprintf(mgr->longname, "%s at 0x%lx & 0x%lx, 0x%lx irq %i", mgr->shortname, 1471 sprintf(mgr->longname, "%s at 0x%lx & 0x%lx, 0x%lx irq %i",
1472 mgr->shortname,
1265 mgr->port[0], mgr->port[1], mgr->port[2], mgr->irq); 1473 mgr->port[0], mgr->port[1], mgr->port[2], mgr->irq);
1266 1474
1267 /* ISR spinlock */ 1475 /* ISR spinlock */
@@ -1272,10 +1480,14 @@ static int __devinit pcxhr_probe(struct pci_dev *pci, const struct pci_device_id
1272 mutex_init(&mgr->setup_mutex); 1480 mutex_init(&mgr->setup_mutex);
1273 1481
1274 /* init taslket */ 1482 /* init taslket */
1275 tasklet_init(&mgr->msg_taskq, pcxhr_msg_tasklet, (unsigned long) mgr); 1483 tasklet_init(&mgr->msg_taskq, pcxhr_msg_tasklet,
1276 tasklet_init(&mgr->trigger_taskq, pcxhr_trigger_tasklet, (unsigned long) mgr); 1484 (unsigned long) mgr);
1485 tasklet_init(&mgr->trigger_taskq, pcxhr_trigger_tasklet,
1486 (unsigned long) mgr);
1487
1277 mgr->prmh = kmalloc(sizeof(*mgr->prmh) + 1488 mgr->prmh = kmalloc(sizeof(*mgr->prmh) +
1278 sizeof(u32) * (PCXHR_SIZE_MAX_LONG_STATUS - PCXHR_SIZE_MAX_STATUS), 1489 sizeof(u32) * (PCXHR_SIZE_MAX_LONG_STATUS -
1490 PCXHR_SIZE_MAX_STATUS),
1279 GFP_KERNEL); 1491 GFP_KERNEL);
1280 if (! mgr->prmh) { 1492 if (! mgr->prmh) {
1281 pcxhr_free(mgr); 1493 pcxhr_free(mgr);
@@ -1296,7 +1508,8 @@ static int __devinit pcxhr_probe(struct pci_dev *pci, const struct pci_device_id
1296 else 1508 else
1297 idx = index[dev] + i; 1509 idx = index[dev] + i;
1298 1510
1299 snprintf(tmpid, sizeof(tmpid), "%s-%d", id[dev] ? id[dev] : card_name, i); 1511 snprintf(tmpid, sizeof(tmpid), "%s-%d",
1512 id[dev] ? id[dev] : card_name, i);
1300 card = snd_card_new(idx, tmpid, THIS_MODULE, 0); 1513 card = snd_card_new(idx, tmpid, THIS_MODULE, 0);
1301 1514
1302 if (! card) { 1515 if (! card) {
@@ -1310,6 +1523,7 @@ static int __devinit pcxhr_probe(struct pci_dev *pci, const struct pci_device_id
1310 sprintf(card->longname, "%s [PCM #%d]", mgr->longname, i); 1523 sprintf(card->longname, "%s [PCM #%d]", mgr->longname, i);
1311 1524
1312 if ((err = pcxhr_create(mgr, card, i)) < 0) { 1525 if ((err = pcxhr_create(mgr, card, i)) < 0) {
1526 snd_card_free(card);
1313 pcxhr_free(mgr); 1527 pcxhr_free(mgr);
1314 return err; 1528 return err;
1315 } 1529 }
diff --git a/sound/pci/pcxhr/pcxhr.h b/sound/pci/pcxhr/pcxhr.h
index 652064787a55..84131a916c92 100644
--- a/sound/pci/pcxhr/pcxhr.h
+++ b/sound/pci/pcxhr/pcxhr.h
@@ -27,15 +27,18 @@
27#include <linux/mutex.h> 27#include <linux/mutex.h>
28#include <sound/pcm.h> 28#include <sound/pcm.h>
29 29
30#define PCXHR_DRIVER_VERSION 0x000804 /* 0.8.4 */ 30#define PCXHR_DRIVER_VERSION 0x000905 /* 0.9.5 */
31#define PCXHR_DRIVER_VERSION_STRING "0.8.4" /* 0.8.4 */ 31#define PCXHR_DRIVER_VERSION_STRING "0.9.5" /* 0.9.5 */
32 32
33 33
34#define PCXHR_MAX_CARDS 6 34#define PCXHR_MAX_CARDS 6
35#define PCXHR_PLAYBACK_STREAMS 4 35#define PCXHR_PLAYBACK_STREAMS 4
36 36
37#define PCXHR_GRANULARITY 96 /* transfer granularity (should be min 96 and multiple of 48) */ 37#define PCXHR_GRANULARITY 96 /* min 96 and multiple of 48 */
38#define PCXHR_GRANULARITY_MIN 96 /* transfer granularity of pipes and the dsp time (MBOX4) */ 38/* transfer granularity of pipes and the dsp time (MBOX4) */
39#define PCXHR_GRANULARITY_MIN 96
40/* TODO : granularity could be 64 or 128 */
41#define PCXHR_GRANULARITY_HR22 192 /* granularity for stereo cards */
39 42
40struct snd_pcxhr; 43struct snd_pcxhr;
41struct pcxhr_mgr; 44struct pcxhr_mgr;
@@ -51,6 +54,11 @@ enum pcxhr_clock_type {
51 PCXHR_CLOCK_TYPE_AES_2, 54 PCXHR_CLOCK_TYPE_AES_2,
52 PCXHR_CLOCK_TYPE_AES_3, 55 PCXHR_CLOCK_TYPE_AES_3,
53 PCXHR_CLOCK_TYPE_AES_4, 56 PCXHR_CLOCK_TYPE_AES_4,
57 PCXHR_CLOCK_TYPE_MAX = PCXHR_CLOCK_TYPE_AES_4,
58 HR22_CLOCK_TYPE_INTERNAL = PCXHR_CLOCK_TYPE_INTERNAL,
59 HR22_CLOCK_TYPE_AES_SYNC,
60 HR22_CLOCK_TYPE_AES_1,
61 HR22_CLOCK_TYPE_MAX = HR22_CLOCK_TYPE_AES_1,
54}; 62};
55 63
56struct pcxhr_mgr { 64struct pcxhr_mgr {
@@ -61,6 +69,8 @@ struct pcxhr_mgr {
61 69
62 int irq; 70 int irq;
63 71
72 int granularity;
73
64 /* card access with 1 mem bar and 2 io bar's */ 74 /* card access with 1 mem bar and 2 io bar's */
65 unsigned long port[3]; 75 unsigned long port[3];
66 76
@@ -83,11 +93,16 @@ struct pcxhr_mgr {
83 /* hardware interface */ 93 /* hardware interface */
84 unsigned int dsp_loaded; /* bit flags of loaded dsp indices */ 94 unsigned int dsp_loaded; /* bit flags of loaded dsp indices */
85 unsigned int dsp_version; /* read from embedded once firmware is loaded */ 95 unsigned int dsp_version; /* read from embedded once firmware is loaded */
86 int board_has_analog; /* if 0 the board is digital only */ 96 int playback_chips;
87 int mono_capture; /* if 1 the board does mono capture */ 97 int capture_chips;
88 int playback_chips; /* 4 or 6 */ 98 int fw_file_set;
89 int capture_chips; /* 4 or 1 */ 99 int firmware_num;
90 int firmware_num; /* 41 or 42 */ 100 int is_hr_stereo:1;
101 int board_has_aes1:1; /* if 1 board has AES1 plug and SRC */
102 int board_has_analog:1; /* if 0 the board is digital only */
103 int board_has_mic:1; /* if 1 the board has microphone input */
104 int board_aes_in_192k:1;/* if 1 the aes input plugs do support 192kHz */
105 int mono_capture:1; /* if 1 the board does mono capture */
91 106
92 struct snd_dma_buffer hostport; 107 struct snd_dma_buffer hostport;
93 108
@@ -106,6 +121,9 @@ struct pcxhr_mgr {
106 int async_err_stream_xrun; 121 int async_err_stream_xrun;
107 int async_err_pipe_xrun; 122 int async_err_pipe_xrun;
108 int async_err_other_last; 123 int async_err_other_last;
124
125 unsigned char xlx_cfg; /* copy of PCXHR_XLX_CFG register */
126 unsigned char xlx_selmic; /* copy of PCXHR_XLX_SELMIC register */
109}; 127};
110 128
111 129
@@ -155,24 +173,30 @@ struct snd_pcxhr {
155 173
156 struct snd_pcm *pcm; /* PCM */ 174 struct snd_pcm *pcm; /* PCM */
157 175
158 struct pcxhr_pipe playback_pipe; /* 1 stereo pipe only */ 176 struct pcxhr_pipe playback_pipe; /* 1 stereo pipe only */
159 struct pcxhr_pipe capture_pipe[2]; /* 1 stereo pipe or 2 mono pipes */ 177 struct pcxhr_pipe capture_pipe[2]; /* 1 stereo or 2 mono pipes */
160 178
161 struct pcxhr_stream playback_stream[PCXHR_PLAYBACK_STREAMS]; 179 struct pcxhr_stream playback_stream[PCXHR_PLAYBACK_STREAMS];
162 struct pcxhr_stream capture_stream[2]; /* 1 stereo stream or 2 mono streams */ 180 struct pcxhr_stream capture_stream[2]; /* 1 stereo or 2 mono streams */
163 int nb_streams_play; 181 int nb_streams_play;
164 int nb_streams_capt; 182 int nb_streams_capt;
165 183
166 int analog_playback_active[2]; /* Mixer : Master Playback active (!mute) */ 184 int analog_playback_active[2]; /* Mixer : Master Playback !mute */
167 int analog_playback_volume[2]; /* Mixer : Master Playback Volume */ 185 int analog_playback_volume[2]; /* Mixer : Master Playback Volume */
168 int analog_capture_volume[2]; /* Mixer : Master Capture Volume */ 186 int analog_capture_volume[2]; /* Mixer : Master Capture Volume */
169 int digital_playback_active[PCXHR_PLAYBACK_STREAMS][2]; /* Mixer : Digital Playback Active [streams][stereo]*/ 187 int digital_playback_active[PCXHR_PLAYBACK_STREAMS][2];
170 int digital_playback_volume[PCXHR_PLAYBACK_STREAMS][2]; /* Mixer : Digital Playback Volume [streams][stereo]*/ 188 int digital_playback_volume[PCXHR_PLAYBACK_STREAMS][2];
171 int digital_capture_volume[2]; /* Mixer : Digital Capture Volume [stereo] */ 189 int digital_capture_volume[2]; /* Mixer : Digital Capture Volume */
172 int monitoring_active[2]; /* Mixer : Monitoring Active */ 190 int monitoring_active[2]; /* Mixer : Monitoring Active */
173 int monitoring_volume[2]; /* Mixer : Monitoring Volume */ 191 int monitoring_volume[2]; /* Mixer : Monitoring Volume */
174 int audio_capture_source; /* Mixer : Audio Capture Source */ 192 int audio_capture_source; /* Mixer : Audio Capture Source */
175 unsigned char aes_bits[5]; /* Mixer : IEC958_AES bits */ 193 int mic_volume; /* used by cards with MIC only */
194 int mic_boost; /* used by cards with MIC only */
195 int mic_active; /* used by cards with MIC only */
196 int analog_capture_active; /* used by cards with MIC only */
197 int phantom_power; /* used by cards with MIC only */
198
199 unsigned char aes_bits[5]; /* Mixer : IEC958_AES bits */
176}; 200};
177 201
178struct pcxhr_hostport 202struct pcxhr_hostport
@@ -184,6 +208,8 @@ struct pcxhr_hostport
184/* exported */ 208/* exported */
185int pcxhr_create_pcm(struct snd_pcxhr *chip); 209int pcxhr_create_pcm(struct snd_pcxhr *chip);
186int pcxhr_set_clock(struct pcxhr_mgr *mgr, unsigned int rate); 210int pcxhr_set_clock(struct pcxhr_mgr *mgr, unsigned int rate);
187int pcxhr_get_external_clock(struct pcxhr_mgr *mgr, enum pcxhr_clock_type clock_type, int *sample_rate); 211int pcxhr_get_external_clock(struct pcxhr_mgr *mgr,
212 enum pcxhr_clock_type clock_type,
213 int *sample_rate);
188 214
189#endif /* __SOUND_PCXHR_H */ 215#endif /* __SOUND_PCXHR_H */
diff --git a/sound/pci/pcxhr/pcxhr_core.c b/sound/pci/pcxhr/pcxhr_core.c
index 7143259cfe34..833e7180ad2d 100644
--- a/sound/pci/pcxhr/pcxhr_core.c
+++ b/sound/pci/pcxhr/pcxhr_core.c
@@ -132,13 +132,15 @@ static int pcxhr_check_reg_bit(struct pcxhr_mgr *mgr, unsigned int reg,
132 *read = PCXHR_INPB(mgr, reg); 132 *read = PCXHR_INPB(mgr, reg);
133 if ((*read & mask) == bit) { 133 if ((*read & mask) == bit) {
134 if (i > 100) 134 if (i > 100)
135 snd_printdd("ATTENTION! check_reg(%x) loopcount=%d\n", 135 snd_printdd("ATTENTION! check_reg(%x) "
136 "loopcount=%d\n",
136 reg, i); 137 reg, i);
137 return 0; 138 return 0;
138 } 139 }
139 i++; 140 i++;
140 } while (time_after_eq(end_time, jiffies)); 141 } while (time_after_eq(end_time, jiffies));
141 snd_printk(KERN_ERR "pcxhr_check_reg_bit: timeout, reg=%x, mask=0x%x, val=0x%x\n", 142 snd_printk(KERN_ERR
143 "pcxhr_check_reg_bit: timeout, reg=%x, mask=0x%x, val=%x\n",
142 reg, mask, *read); 144 reg, mask, *read);
143 return -EIO; 145 return -EIO;
144} 146}
@@ -159,18 +161,22 @@ static int pcxhr_check_reg_bit(struct pcxhr_mgr *mgr, unsigned int reg,
159#define PCXHR_IT_TEST_XILINX (0x0000003C | PCXHR_MASK_IT_HF1 | \ 161#define PCXHR_IT_TEST_XILINX (0x0000003C | PCXHR_MASK_IT_HF1 | \
160 PCXHR_MASK_IT_MANAGE_HF5) 162 PCXHR_MASK_IT_MANAGE_HF5)
161#define PCXHR_IT_DOWNLOAD_BOOT (0x0000000C | PCXHR_MASK_IT_HF1 | \ 163#define PCXHR_IT_DOWNLOAD_BOOT (0x0000000C | PCXHR_MASK_IT_HF1 | \
162 PCXHR_MASK_IT_MANAGE_HF5 | PCXHR_MASK_IT_WAIT) 164 PCXHR_MASK_IT_MANAGE_HF5 | \
165 PCXHR_MASK_IT_WAIT)
163#define PCXHR_IT_RESET_BOARD_FUNC (0x0000000C | PCXHR_MASK_IT_HF0 | \ 166#define PCXHR_IT_RESET_BOARD_FUNC (0x0000000C | PCXHR_MASK_IT_HF0 | \
164 PCXHR_MASK_IT_MANAGE_HF5 | PCXHR_MASK_IT_WAIT_EXTRA) 167 PCXHR_MASK_IT_MANAGE_HF5 | \
168 PCXHR_MASK_IT_WAIT_EXTRA)
165#define PCXHR_IT_DOWNLOAD_DSP (0x0000000C | \ 169#define PCXHR_IT_DOWNLOAD_DSP (0x0000000C | \
166 PCXHR_MASK_IT_MANAGE_HF5 | PCXHR_MASK_IT_WAIT) 170 PCXHR_MASK_IT_MANAGE_HF5 | \
171 PCXHR_MASK_IT_WAIT)
167#define PCXHR_IT_DEBUG (0x0000005A | PCXHR_MASK_IT_NO_HF0_HF1) 172#define PCXHR_IT_DEBUG (0x0000005A | PCXHR_MASK_IT_NO_HF0_HF1)
168#define PCXHR_IT_RESET_SEMAPHORE (0x0000005C | PCXHR_MASK_IT_NO_HF0_HF1) 173#define PCXHR_IT_RESET_SEMAPHORE (0x0000005C | PCXHR_MASK_IT_NO_HF0_HF1)
169#define PCXHR_IT_MESSAGE (0x00000074 | PCXHR_MASK_IT_NO_HF0_HF1) 174#define PCXHR_IT_MESSAGE (0x00000074 | PCXHR_MASK_IT_NO_HF0_HF1)
170#define PCXHR_IT_RESET_CHK (0x00000076 | PCXHR_MASK_IT_NO_HF0_HF1) 175#define PCXHR_IT_RESET_CHK (0x00000076 | PCXHR_MASK_IT_NO_HF0_HF1)
171#define PCXHR_IT_UPDATE_RBUFFER (0x00000078 | PCXHR_MASK_IT_NO_HF0_HF1) 176#define PCXHR_IT_UPDATE_RBUFFER (0x00000078 | PCXHR_MASK_IT_NO_HF0_HF1)
172 177
173static int pcxhr_send_it_dsp(struct pcxhr_mgr *mgr, unsigned int itdsp, int atomic) 178static int pcxhr_send_it_dsp(struct pcxhr_mgr *mgr,
179 unsigned int itdsp, int atomic)
174{ 180{
175 int err; 181 int err;
176 unsigned char reg; 182 unsigned char reg;
@@ -178,17 +184,21 @@ static int pcxhr_send_it_dsp(struct pcxhr_mgr *mgr, unsigned int itdsp, int atom
178 if (itdsp & PCXHR_MASK_IT_MANAGE_HF5) { 184 if (itdsp & PCXHR_MASK_IT_MANAGE_HF5) {
179 /* clear hf5 bit */ 185 /* clear hf5 bit */
180 PCXHR_OUTPL(mgr, PCXHR_PLX_MBOX0, 186 PCXHR_OUTPL(mgr, PCXHR_PLX_MBOX0,
181 PCXHR_INPL(mgr, PCXHR_PLX_MBOX0) & ~PCXHR_MBOX0_HF5); 187 PCXHR_INPL(mgr, PCXHR_PLX_MBOX0) &
188 ~PCXHR_MBOX0_HF5);
182 } 189 }
183 if ((itdsp & PCXHR_MASK_IT_NO_HF0_HF1) == 0) { 190 if ((itdsp & PCXHR_MASK_IT_NO_HF0_HF1) == 0) {
184 reg = PCXHR_ICR_HI08_RREQ | PCXHR_ICR_HI08_TREQ | PCXHR_ICR_HI08_HDRQ; 191 reg = (PCXHR_ICR_HI08_RREQ |
192 PCXHR_ICR_HI08_TREQ |
193 PCXHR_ICR_HI08_HDRQ);
185 if (itdsp & PCXHR_MASK_IT_HF0) 194 if (itdsp & PCXHR_MASK_IT_HF0)
186 reg |= PCXHR_ICR_HI08_HF0; 195 reg |= PCXHR_ICR_HI08_HF0;
187 if (itdsp & PCXHR_MASK_IT_HF1) 196 if (itdsp & PCXHR_MASK_IT_HF1)
188 reg |= PCXHR_ICR_HI08_HF1; 197 reg |= PCXHR_ICR_HI08_HF1;
189 PCXHR_OUTPB(mgr, PCXHR_DSP_ICR, reg); 198 PCXHR_OUTPB(mgr, PCXHR_DSP_ICR, reg);
190 } 199 }
191 reg = (unsigned char)(((itdsp & PCXHR_MASK_EXTRA_INFO) >> 1) | PCXHR_CVR_HI08_HC); 200 reg = (unsigned char)(((itdsp & PCXHR_MASK_EXTRA_INFO) >> 1) |
201 PCXHR_CVR_HI08_HC);
192 PCXHR_OUTPB(mgr, PCXHR_DSP_CVR, reg); 202 PCXHR_OUTPB(mgr, PCXHR_DSP_CVR, reg);
193 if (itdsp & PCXHR_MASK_IT_WAIT) { 203 if (itdsp & PCXHR_MASK_IT_WAIT) {
194 if (atomic) 204 if (atomic)
@@ -211,10 +221,14 @@ static int pcxhr_send_it_dsp(struct pcxhr_mgr *mgr, unsigned int itdsp, int atom
211 } 221 }
212 if (itdsp & PCXHR_MASK_IT_MANAGE_HF5) { 222 if (itdsp & PCXHR_MASK_IT_MANAGE_HF5) {
213 /* wait for hf5 bit */ 223 /* wait for hf5 bit */
214 err = pcxhr_check_reg_bit(mgr, PCXHR_PLX_MBOX0, PCXHR_MBOX0_HF5, 224 err = pcxhr_check_reg_bit(mgr, PCXHR_PLX_MBOX0,
215 PCXHR_MBOX0_HF5, PCXHR_TIMEOUT_DSP, &reg); 225 PCXHR_MBOX0_HF5,
226 PCXHR_MBOX0_HF5,
227 PCXHR_TIMEOUT_DSP,
228 &reg);
216 if (err) { 229 if (err) {
217 snd_printk(KERN_ERR "pcxhr_send_it_dsp : TIMEOUT HF5\n"); 230 snd_printk(KERN_ERR
231 "pcxhr_send_it_dsp : TIMEOUT HF5\n");
218 return err; 232 return err;
219 } 233 }
220 } 234 }
@@ -263,7 +277,8 @@ void pcxhr_enable_dsp(struct pcxhr_mgr *mgr)
263/* 277/*
264 * load the xilinx image 278 * load the xilinx image
265 */ 279 */
266int pcxhr_load_xilinx_binary(struct pcxhr_mgr *mgr, const struct firmware *xilinx, int second) 280int pcxhr_load_xilinx_binary(struct pcxhr_mgr *mgr,
281 const struct firmware *xilinx, int second)
267{ 282{
268 unsigned int i; 283 unsigned int i;
269 unsigned int chipsc; 284 unsigned int chipsc;
@@ -274,7 +289,9 @@ int pcxhr_load_xilinx_binary(struct pcxhr_mgr *mgr, const struct firmware *xilin
274 /* test first xilinx */ 289 /* test first xilinx */
275 chipsc = PCXHR_INPL(mgr, PCXHR_PLX_CHIPSC); 290 chipsc = PCXHR_INPL(mgr, PCXHR_PLX_CHIPSC);
276 /* REV01 cards do not support the PCXHR_CHIPSC_GPI_USERI bit anymore */ 291 /* REV01 cards do not support the PCXHR_CHIPSC_GPI_USERI bit anymore */
277 /* this bit will always be 1; no possibility to test presence of first xilinx */ 292 /* this bit will always be 1;
293 * no possibility to test presence of first xilinx
294 */
278 if(second) { 295 if(second) {
279 if ((chipsc & PCXHR_CHIPSC_GPI_USERI) == 0) { 296 if ((chipsc & PCXHR_CHIPSC_GPI_USERI) == 0) {
280 snd_printk(KERN_ERR "error loading first xilinx\n"); 297 snd_printk(KERN_ERR "error loading first xilinx\n");
@@ -290,7 +307,8 @@ int pcxhr_load_xilinx_binary(struct pcxhr_mgr *mgr, const struct firmware *xilin
290 data = *image; 307 data = *image;
291 mask = 0x80; 308 mask = 0x80;
292 while (mask) { 309 while (mask) {
293 chipsc &= ~(PCXHR_CHIPSC_DATA_CLK | PCXHR_CHIPSC_DATA_IN); 310 chipsc &= ~(PCXHR_CHIPSC_DATA_CLK |
311 PCXHR_CHIPSC_DATA_IN);
294 if (data & mask) 312 if (data & mask)
295 chipsc |= PCXHR_CHIPSC_DATA_IN; 313 chipsc |= PCXHR_CHIPSC_DATA_IN;
296 PCXHR_OUTPL(mgr, PCXHR_PLX_CHIPSC, chipsc); 314 PCXHR_OUTPL(mgr, PCXHR_PLX_CHIPSC, chipsc);
@@ -330,15 +348,20 @@ static int pcxhr_download_dsp(struct pcxhr_mgr *mgr, const struct firmware *dsp)
330 data = dsp->data + i; 348 data = dsp->data + i;
331 if (i == 0) { 349 if (i == 0) {
332 /* test data header consistency */ 350 /* test data header consistency */
333 len = (unsigned int)((data[0]<<16) + (data[1]<<8) + data[2]); 351 len = (unsigned int)((data[0]<<16) +
334 if (len && dsp->size != (len + 2) * 3) 352 (data[1]<<8) +
353 data[2]);
354 if (len && (dsp->size != (len + 2) * 3))
335 return -EINVAL; 355 return -EINVAL;
336 } 356 }
337 /* wait DSP ready for new transfer */ 357 /* wait DSP ready for new transfer */
338 err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR, PCXHR_ISR_HI08_TRDY, 358 err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR,
339 PCXHR_ISR_HI08_TRDY, PCXHR_TIMEOUT_DSP, &dummy); 359 PCXHR_ISR_HI08_TRDY,
360 PCXHR_ISR_HI08_TRDY,
361 PCXHR_TIMEOUT_DSP, &dummy);
340 if (err) { 362 if (err) {
341 snd_printk(KERN_ERR "dsp loading error at position %d\n", i); 363 snd_printk(KERN_ERR
364 "dsp loading error at position %d\n", i);
342 return err; 365 return err;
343 } 366 }
344 /* send host data */ 367 /* send host data */
@@ -357,7 +380,8 @@ static int pcxhr_download_dsp(struct pcxhr_mgr *mgr, const struct firmware *dsp)
357/* 380/*
358 * load the eeprom image 381 * load the eeprom image
359 */ 382 */
360int pcxhr_load_eeprom_binary(struct pcxhr_mgr *mgr, const struct firmware *eeprom) 383int pcxhr_load_eeprom_binary(struct pcxhr_mgr *mgr,
384 const struct firmware *eeprom)
361{ 385{
362 int err; 386 int err;
363 unsigned char reg; 387 unsigned char reg;
@@ -365,7 +389,9 @@ int pcxhr_load_eeprom_binary(struct pcxhr_mgr *mgr, const struct firmware *eepro
365 /* init value of the ICR register */ 389 /* init value of the ICR register */
366 reg = PCXHR_ICR_HI08_RREQ | PCXHR_ICR_HI08_TREQ | PCXHR_ICR_HI08_HDRQ; 390 reg = PCXHR_ICR_HI08_RREQ | PCXHR_ICR_HI08_TREQ | PCXHR_ICR_HI08_HDRQ;
367 if (PCXHR_INPL(mgr, PCXHR_PLX_MBOX0) & PCXHR_MBOX0_BOOT_HERE) { 391 if (PCXHR_INPL(mgr, PCXHR_PLX_MBOX0) & PCXHR_MBOX0_BOOT_HERE) {
368 /* no need to load the eeprom binary, but init the HI08 interface */ 392 /* no need to load the eeprom binary,
393 * but init the HI08 interface
394 */
369 PCXHR_OUTPB(mgr, PCXHR_DSP_ICR, reg | PCXHR_ICR_HI08_INIT); 395 PCXHR_OUTPB(mgr, PCXHR_DSP_ICR, reg | PCXHR_ICR_HI08_INIT);
370 msleep(PCXHR_WAIT_DEFAULT); 396 msleep(PCXHR_WAIT_DEFAULT);
371 PCXHR_OUTPB(mgr, PCXHR_DSP_ICR, reg); 397 PCXHR_OUTPB(mgr, PCXHR_DSP_ICR, reg);
@@ -429,8 +455,10 @@ int pcxhr_load_dsp_binary(struct pcxhr_mgr *mgr, const struct firmware *dsp)
429 if (err) 455 if (err)
430 return err; 456 return err;
431 /* wait for chk bit */ 457 /* wait for chk bit */
432 return pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR, PCXHR_ISR_HI08_CHK, 458 return pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR,
433 PCXHR_ISR_HI08_CHK, PCXHR_TIMEOUT_DSP, &dummy); 459 PCXHR_ISR_HI08_CHK,
460 PCXHR_ISR_HI08_CHK,
461 PCXHR_TIMEOUT_DSP, &dummy);
434} 462}
435 463
436 464
@@ -443,8 +471,8 @@ struct pcxhr_cmd_info {
443/* RMH status type */ 471/* RMH status type */
444enum { 472enum {
445 RMH_SSIZE_FIXED = 0, /* status size fix (st_length = 0..x) */ 473 RMH_SSIZE_FIXED = 0, /* status size fix (st_length = 0..x) */
446 RMH_SSIZE_ARG = 1, /* status size given in the LSB byte (used with st_length = 1) */ 474 RMH_SSIZE_ARG = 1, /* status size given in the LSB byte */
447 RMH_SSIZE_MASK = 2, /* status size given in bitmask (used with st_length = 1) */ 475 RMH_SSIZE_MASK = 2, /* status size given in bitmask */
448}; 476};
449 477
450/* 478/*
@@ -474,7 +502,7 @@ static struct pcxhr_cmd_info pcxhr_dsp_cmds[] = {
474[CMD_UPDATE_R_BUFFERS] = { 0x840000, 0, RMH_SSIZE_FIXED }, 502[CMD_UPDATE_R_BUFFERS] = { 0x840000, 0, RMH_SSIZE_FIXED },
475[CMD_FORMAT_STREAM_OUT] = { 0x860000, 0, RMH_SSIZE_FIXED }, 503[CMD_FORMAT_STREAM_OUT] = { 0x860000, 0, RMH_SSIZE_FIXED },
476[CMD_FORMAT_STREAM_IN] = { 0x870000, 0, RMH_SSIZE_FIXED }, 504[CMD_FORMAT_STREAM_IN] = { 0x870000, 0, RMH_SSIZE_FIXED },
477[CMD_STREAM_SAMPLE_COUNT] = { 0x902000, 2, RMH_SSIZE_FIXED }, /* stat_len = nb_streams * 2 */ 505[CMD_STREAM_SAMPLE_COUNT] = { 0x902000, 2, RMH_SSIZE_FIXED },
478[CMD_AUDIO_LEVEL_ADJUST] = { 0xc22000, 0, RMH_SSIZE_FIXED }, 506[CMD_AUDIO_LEVEL_ADJUST] = { 0xc22000, 0, RMH_SSIZE_FIXED },
479}; 507};
480 508
@@ -524,10 +552,13 @@ static int pcxhr_read_rmh_status(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
524 552
525 for (i = 0; i < rmh->stat_len; i++) { 553 for (i = 0; i < rmh->stat_len; i++) {
526 /* wait for receiver full */ 554 /* wait for receiver full */
527 err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR, PCXHR_ISR_HI08_RXDF, 555 err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR,
528 PCXHR_ISR_HI08_RXDF, PCXHR_TIMEOUT_DSP, &reg); 556 PCXHR_ISR_HI08_RXDF,
557 PCXHR_ISR_HI08_RXDF,
558 PCXHR_TIMEOUT_DSP, &reg);
529 if (err) { 559 if (err) {
530 snd_printk(KERN_ERR "ERROR RMH stat: ISR:RXDF=1 (ISR = %x; i=%d )\n", 560 snd_printk(KERN_ERR "ERROR RMH stat: "
561 "ISR:RXDF=1 (ISR = %x; i=%d )\n",
531 reg, i); 562 reg, i);
532 return err; 563 return err;
533 } 564 }
@@ -537,10 +568,10 @@ static int pcxhr_read_rmh_status(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
537 data |= PCXHR_INPB(mgr, PCXHR_DSP_TXL); 568 data |= PCXHR_INPB(mgr, PCXHR_DSP_TXL);
538 569
539 /* need to update rmh->stat_len on the fly ?? */ 570 /* need to update rmh->stat_len on the fly ?? */
540 if (i==0) { 571 if (!i) {
541 if (rmh->dsp_stat != RMH_SSIZE_FIXED) { 572 if (rmh->dsp_stat != RMH_SSIZE_FIXED) {
542 if (rmh->dsp_stat == RMH_SSIZE_ARG) { 573 if (rmh->dsp_stat == RMH_SSIZE_ARG) {
543 rmh->stat_len = (u16)(data & 0x0000ff) + 1; 574 rmh->stat_len = (data & 0x0000ff) + 1;
544 data &= 0xffff00; 575 data &= 0xffff00;
545 } else { 576 } else {
546 /* rmh->dsp_stat == RMH_SSIZE_MASK */ 577 /* rmh->dsp_stat == RMH_SSIZE_MASK */
@@ -562,7 +593,8 @@ static int pcxhr_read_rmh_status(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
562 rmh->stat[i] = data; 593 rmh->stat[i] = data;
563 } 594 }
564 if (rmh->stat_len > max_stat_len) { 595 if (rmh->stat_len > max_stat_len) {
565 snd_printdd("PCXHR : rmh->stat_len=%x too big\n", rmh->stat_len); 596 snd_printdd("PCXHR : rmh->stat_len=%x too big\n",
597 rmh->stat_len);
566 rmh->stat_len = max_stat_len; 598 rmh->stat_len = max_stat_len;
567 } 599 }
568 return 0; 600 return 0;
@@ -605,7 +637,8 @@ static int pcxhr_send_msg_nolock(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
605 data &= 0xff7fff; /* MASK_1_WORD_COMMAND */ 637 data &= 0xff7fff; /* MASK_1_WORD_COMMAND */
606#ifdef CONFIG_SND_DEBUG_VERBOSE 638#ifdef CONFIG_SND_DEBUG_VERBOSE
607 if (rmh->cmd_idx < CMD_LAST_INDEX) 639 if (rmh->cmd_idx < CMD_LAST_INDEX)
608 snd_printdd("MSG cmd[0]=%x (%s)\n", data, cmd_names[rmh->cmd_idx]); 640 snd_printdd("MSG cmd[0]=%x (%s)\n",
641 data, cmd_names[rmh->cmd_idx]);
609#endif 642#endif
610 643
611 err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR, PCXHR_ISR_HI08_TRDY, 644 err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR, PCXHR_ISR_HI08_TRDY,
@@ -619,8 +652,10 @@ static int pcxhr_send_msg_nolock(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
619 if (rmh->cmd_len > 1) { 652 if (rmh->cmd_len > 1) {
620 /* send length */ 653 /* send length */
621 data = rmh->cmd_len - 1; 654 data = rmh->cmd_len - 1;
622 err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR, PCXHR_ISR_HI08_TRDY, 655 err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR,
623 PCXHR_ISR_HI08_TRDY, PCXHR_TIMEOUT_DSP, &reg); 656 PCXHR_ISR_HI08_TRDY,
657 PCXHR_ISR_HI08_TRDY,
658 PCXHR_TIMEOUT_DSP, &reg);
624 if (err) 659 if (err)
625 return err; 660 return err;
626 PCXHR_OUTPB(mgr, PCXHR_DSP_TXH, (data>>16)&0xFF); 661 PCXHR_OUTPB(mgr, PCXHR_DSP_TXH, (data>>16)&0xFF);
@@ -653,8 +688,10 @@ static int pcxhr_send_msg_nolock(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
653 /* test status ISR */ 688 /* test status ISR */
654 if (reg & PCXHR_ISR_HI08_ERR) { 689 if (reg & PCXHR_ISR_HI08_ERR) {
655 /* ERROR, wait for receiver full */ 690 /* ERROR, wait for receiver full */
656 err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR, PCXHR_ISR_HI08_RXDF, 691 err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR,
657 PCXHR_ISR_HI08_RXDF, PCXHR_TIMEOUT_DSP, &reg); 692 PCXHR_ISR_HI08_RXDF,
693 PCXHR_ISR_HI08_RXDF,
694 PCXHR_TIMEOUT_DSP, &reg);
658 if (err) { 695 if (err) {
659 snd_printk(KERN_ERR "ERROR RMH: ISR:RXDF=1 (ISR = %x)\n", reg); 696 snd_printk(KERN_ERR "ERROR RMH: ISR:RXDF=1 (ISR = %x)\n", reg);
660 return err; 697 return err;
@@ -663,7 +700,8 @@ static int pcxhr_send_msg_nolock(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
663 data = PCXHR_INPB(mgr, PCXHR_DSP_TXH) << 16; 700 data = PCXHR_INPB(mgr, PCXHR_DSP_TXH) << 16;
664 data |= PCXHR_INPB(mgr, PCXHR_DSP_TXM) << 8; 701 data |= PCXHR_INPB(mgr, PCXHR_DSP_TXM) << 8;
665 data |= PCXHR_INPB(mgr, PCXHR_DSP_TXL); 702 data |= PCXHR_INPB(mgr, PCXHR_DSP_TXL);
666 snd_printk(KERN_ERR "ERROR RMH(%d): 0x%x\n", rmh->cmd_idx, data); 703 snd_printk(KERN_ERR "ERROR RMH(%d): 0x%x\n",
704 rmh->cmd_idx, data);
667 err = -EINVAL; 705 err = -EINVAL;
668 } else { 706 } else {
669 /* read the response data */ 707 /* read the response data */
@@ -732,8 +770,9 @@ int pcxhr_send_msg(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
732static inline int pcxhr_pipes_running(struct pcxhr_mgr *mgr) 770static inline int pcxhr_pipes_running(struct pcxhr_mgr *mgr)
733{ 771{
734 int start_mask = PCXHR_INPL(mgr, PCXHR_PLX_MBOX2); 772 int start_mask = PCXHR_INPL(mgr, PCXHR_PLX_MBOX2);
735 /* least segnificant 12 bits are the pipe states for the playback audios */ 773 /* least segnificant 12 bits are the pipe states
736 /* next 12 bits are the pipe states for the capture audios 774 * for the playback audios
775 * next 12 bits are the pipe states for the capture audios
737 * (PCXHR_PIPE_STATE_CAPTURE_OFFSET) 776 * (PCXHR_PIPE_STATE_CAPTURE_OFFSET)
738 */ 777 */
739 start_mask &= 0xffffff; 778 start_mask &= 0xffffff;
@@ -744,7 +783,8 @@ static inline int pcxhr_pipes_running(struct pcxhr_mgr *mgr)
744#define PCXHR_PIPE_STATE_CAPTURE_OFFSET 12 783#define PCXHR_PIPE_STATE_CAPTURE_OFFSET 12
745#define MAX_WAIT_FOR_DSP 20 784#define MAX_WAIT_FOR_DSP 20
746 785
747static int pcxhr_prepair_pipe_start(struct pcxhr_mgr *mgr, int audio_mask, int *retry) 786static int pcxhr_prepair_pipe_start(struct pcxhr_mgr *mgr,
787 int audio_mask, int *retry)
748{ 788{
749 struct pcxhr_rmh rmh; 789 struct pcxhr_rmh rmh;
750 int err; 790 int err;
@@ -760,17 +800,20 @@ static int pcxhr_prepair_pipe_start(struct pcxhr_mgr *mgr, int audio_mask, int *
760 } else { 800 } else {
761 /* can start capture pipe */ 801 /* can start capture pipe */
762 pcxhr_set_pipe_cmd_params(&rmh, 1, audio - 802 pcxhr_set_pipe_cmd_params(&rmh, 1, audio -
763 PCXHR_PIPE_STATE_CAPTURE_OFFSET, 803 PCXHR_PIPE_STATE_CAPTURE_OFFSET,
764 0, 0); 804 0, 0);
765 } 805 }
766 err = pcxhr_send_msg(mgr, &rmh); 806 err = pcxhr_send_msg(mgr, &rmh);
767 if (err) { 807 if (err) {
768 snd_printk(KERN_ERR 808 snd_printk(KERN_ERR
769 "error pipe start (CMD_CAN_START_PIPE) err=%x!\n", 809 "error pipe start "
810 "(CMD_CAN_START_PIPE) err=%x!\n",
770 err); 811 err);
771 return err; 812 return err;
772 } 813 }
773 /* if the pipe couldn't be prepaired for start, retry it later */ 814 /* if the pipe couldn't be prepaired for start,
815 * retry it later
816 */
774 if (rmh.stat[0] == 0) 817 if (rmh.stat[0] == 0)
775 *retry |= (1<<audio); 818 *retry |= (1<<audio);
776 } 819 }
@@ -795,14 +838,14 @@ static int pcxhr_stop_pipes(struct pcxhr_mgr *mgr, int audio_mask)
795 } else { 838 } else {
796 /* stop capture pipe */ 839 /* stop capture pipe */
797 pcxhr_set_pipe_cmd_params(&rmh, 1, audio - 840 pcxhr_set_pipe_cmd_params(&rmh, 1, audio -
798 PCXHR_PIPE_STATE_CAPTURE_OFFSET, 841 PCXHR_PIPE_STATE_CAPTURE_OFFSET,
799 0, 0); 842 0, 0);
800 } 843 }
801 err = pcxhr_send_msg(mgr, &rmh); 844 err = pcxhr_send_msg(mgr, &rmh);
802 if (err) { 845 if (err) {
803 snd_printk(KERN_ERR 846 snd_printk(KERN_ERR
804 "error pipe stop (CMD_STOP_PIPE) err=%x!\n", 847 "error pipe stop "
805 err); 848 "(CMD_STOP_PIPE) err=%x!\n", err);
806 return err; 849 return err;
807 } 850 }
808 } 851 }
@@ -822,15 +865,16 @@ static int pcxhr_toggle_pipes(struct pcxhr_mgr *mgr, int audio_mask)
822 if (audio_mask & 1) { 865 if (audio_mask & 1) {
823 pcxhr_init_rmh(&rmh, CMD_CONF_PIPE); 866 pcxhr_init_rmh(&rmh, CMD_CONF_PIPE);
824 if (audio < PCXHR_PIPE_STATE_CAPTURE_OFFSET) 867 if (audio < PCXHR_PIPE_STATE_CAPTURE_OFFSET)
825 pcxhr_set_pipe_cmd_params(&rmh, 0, 0, 0, 1 << audio); 868 pcxhr_set_pipe_cmd_params(&rmh, 0, 0, 0,
869 1 << audio);
826 else 870 else
827 pcxhr_set_pipe_cmd_params(&rmh, 1, 0, 0, 871 pcxhr_set_pipe_cmd_params(&rmh, 1, 0, 0,
828 1 << (audio - PCXHR_PIPE_STATE_CAPTURE_OFFSET)); 872 1 << (audio - PCXHR_PIPE_STATE_CAPTURE_OFFSET));
829 err = pcxhr_send_msg(mgr, &rmh); 873 err = pcxhr_send_msg(mgr, &rmh);
830 if (err) { 874 if (err) {
831 snd_printk(KERN_ERR 875 snd_printk(KERN_ERR
832 "error pipe start (CMD_CONF_PIPE) err=%x!\n", 876 "error pipe start "
833 err); 877 "(CMD_CONF_PIPE) err=%x!\n", err);
834 return err; 878 return err;
835 } 879 }
836 } 880 }
@@ -841,7 +885,9 @@ static int pcxhr_toggle_pipes(struct pcxhr_mgr *mgr, int audio_mask)
841 pcxhr_init_rmh(&rmh, CMD_SEND_IRQA); 885 pcxhr_init_rmh(&rmh, CMD_SEND_IRQA);
842 err = pcxhr_send_msg(mgr, &rmh); 886 err = pcxhr_send_msg(mgr, &rmh);
843 if (err) { 887 if (err) {
844 snd_printk(KERN_ERR "error pipe start (CMD_SEND_IRQA) err=%x!\n", err ); 888 snd_printk(KERN_ERR
889 "error pipe start (CMD_SEND_IRQA) err=%x!\n",
890 err);
845 return err; 891 return err;
846 } 892 }
847 return 0; 893 return 0;
@@ -849,7 +895,8 @@ static int pcxhr_toggle_pipes(struct pcxhr_mgr *mgr, int audio_mask)
849 895
850 896
851 897
852int pcxhr_set_pipe_state(struct pcxhr_mgr *mgr, int playback_mask, int capture_mask, int start) 898int pcxhr_set_pipe_state(struct pcxhr_mgr *mgr, int playback_mask,
899 int capture_mask, int start)
853{ 900{
854 int state, i, err; 901 int state, i, err;
855 int audio_mask; 902 int audio_mask;
@@ -858,21 +905,23 @@ int pcxhr_set_pipe_state(struct pcxhr_mgr *mgr, int playback_mask, int capture_m
858 struct timeval my_tv1, my_tv2; 905 struct timeval my_tv1, my_tv2;
859 do_gettimeofday(&my_tv1); 906 do_gettimeofday(&my_tv1);
860#endif 907#endif
861 audio_mask = (playback_mask | (capture_mask << PCXHR_PIPE_STATE_CAPTURE_OFFSET)); 908 audio_mask = (playback_mask |
909 (capture_mask << PCXHR_PIPE_STATE_CAPTURE_OFFSET));
862 /* current pipe state (playback + record) */ 910 /* current pipe state (playback + record) */
863 state = pcxhr_pipes_running(mgr); 911 state = pcxhr_pipes_running(mgr);
864 snd_printdd("pcxhr_set_pipe_state %s (mask %x current %x)\n", 912 snd_printdd("pcxhr_set_pipe_state %s (mask %x current %x)\n",
865 start ? "START" : "STOP", audio_mask, state); 913 start ? "START" : "STOP", audio_mask, state);
866 if (start) { 914 if (start) {
867 audio_mask &= ~state; /* start only pipes that are not yet started */ 915 /* start only pipes that are not yet started */
916 audio_mask &= ~state;
868 state = audio_mask; 917 state = audio_mask;
869 for (i = 0; i < MAX_WAIT_FOR_DSP; i++) { 918 for (i = 0; i < MAX_WAIT_FOR_DSP; i++) {
870 err = pcxhr_prepair_pipe_start(mgr, state, &state); 919 err = pcxhr_prepair_pipe_start(mgr, state, &state);
871 if (err) 920 if (err)
872 return err; 921 return err;
873 if (state == 0) 922 if (state == 0)
874 break; /* success, all pipes prepaired for start */ 923 break; /* success, all pipes prepaired */
875 mdelay(1); /* otherwise wait 1 millisecond and retry */ 924 mdelay(1); /* wait 1 millisecond and retry */
876 } 925 }
877 } else { 926 } else {
878 audio_mask &= state; /* stop only pipes that are started */ 927 audio_mask &= state; /* stop only pipes that are started */
@@ -891,7 +940,7 @@ int pcxhr_set_pipe_state(struct pcxhr_mgr *mgr, int playback_mask, int capture_m
891 if ((state & audio_mask) == (start ? audio_mask : 0)) 940 if ((state & audio_mask) == (start ? audio_mask : 0))
892 break; 941 break;
893 if (++i >= MAX_WAIT_FOR_DSP * 100) { 942 if (++i >= MAX_WAIT_FOR_DSP * 100) {
894 snd_printk(KERN_ERR "error pipe start/stop (ED_NO_RESPONSE_AT_IRQA)\n"); 943 snd_printk(KERN_ERR "error pipe start/stop\n");
895 return -EBUSY; 944 return -EBUSY;
896 } 945 }
897 udelay(10); /* wait 10 microseconds */ 946 udelay(10); /* wait 10 microseconds */
@@ -918,7 +967,8 @@ int pcxhr_write_io_num_reg_cont(struct pcxhr_mgr *mgr, unsigned int mask,
918 967
919 spin_lock_irqsave(&mgr->msg_lock, flags); 968 spin_lock_irqsave(&mgr->msg_lock, flags);
920 if ((mgr->io_num_reg_cont & mask) == value) { 969 if ((mgr->io_num_reg_cont & mask) == value) {
921 snd_printdd("IO_NUM_REG_CONT mask %x already is set to %x\n", mask, value); 970 snd_printdd("IO_NUM_REG_CONT mask %x already is set to %x\n",
971 mask, value);
922 if (changed) 972 if (changed)
923 *changed = 0; 973 *changed = 0;
924 spin_unlock_irqrestore(&mgr->msg_lock, flags); 974 spin_unlock_irqrestore(&mgr->msg_lock, flags);
@@ -971,7 +1021,8 @@ static int pcxhr_handle_async_err(struct pcxhr_mgr *mgr, u32 err,
971 err = ((err >> 12) & 0xfff); 1021 err = ((err >> 12) & 0xfff);
972 if (!err) 1022 if (!err)
973 return 0; 1023 return 0;
974 snd_printdd("CMD_ASYNC : Error %s %s Pipe %d err=%x\n", err_src_name[err_src], 1024 snd_printdd("CMD_ASYNC : Error %s %s Pipe %d err=%x\n",
1025 err_src_name[err_src],
975 is_capture ? "Record" : "Play", pipe, err); 1026 is_capture ? "Record" : "Play", pipe, err);
976 if (err == 0xe01) 1027 if (err == 0xe01)
977 mgr->async_err_stream_xrun++; 1028 mgr->async_err_stream_xrun++;
@@ -996,6 +1047,13 @@ void pcxhr_msg_tasklet(unsigned long arg)
996 snd_printdd("TASKLET : PCXHR_IRQ_TIME_CODE event occured\n"); 1047 snd_printdd("TASKLET : PCXHR_IRQ_TIME_CODE event occured\n");
997 if (mgr->src_it_dsp & PCXHR_IRQ_NOTIFY) 1048 if (mgr->src_it_dsp & PCXHR_IRQ_NOTIFY)
998 snd_printdd("TASKLET : PCXHR_IRQ_NOTIFY event occured\n"); 1049 snd_printdd("TASKLET : PCXHR_IRQ_NOTIFY event occured\n");
1050 if (mgr->src_it_dsp & (PCXHR_IRQ_FREQ_CHANGE | PCXHR_IRQ_TIME_CODE)) {
1051 /* clear events FREQ_CHANGE and TIME_CODE */
1052 pcxhr_init_rmh(prmh, CMD_TEST_IT);
1053 err = pcxhr_send_msg(mgr, prmh);
1054 snd_printdd("CMD_TEST_IT : err=%x, stat=%x\n",
1055 err, prmh->stat[0]);
1056 }
999 if (mgr->src_it_dsp & PCXHR_IRQ_ASYNC) { 1057 if (mgr->src_it_dsp & PCXHR_IRQ_ASYNC) {
1000 snd_printdd("TASKLET : PCXHR_IRQ_ASYNC event occured\n"); 1058 snd_printdd("TASKLET : PCXHR_IRQ_ASYNC event occured\n");
1001 1059
@@ -1005,18 +1063,22 @@ void pcxhr_msg_tasklet(unsigned long arg)
1005 prmh->stat_len = PCXHR_SIZE_MAX_LONG_STATUS; 1063 prmh->stat_len = PCXHR_SIZE_MAX_LONG_STATUS;
1006 err = pcxhr_send_msg(mgr, prmh); 1064 err = pcxhr_send_msg(mgr, prmh);
1007 if (err) 1065 if (err)
1008 snd_printk(KERN_ERR "ERROR pcxhr_msg_tasklet=%x;\n", err); 1066 snd_printk(KERN_ERR "ERROR pcxhr_msg_tasklet=%x;\n",
1067 err);
1009 i = 1; 1068 i = 1;
1010 while (i < prmh->stat_len) { 1069 while (i < prmh->stat_len) {
1011 int nb_audio = (prmh->stat[i] >> FIELD_SIZE) & MASK_FIRST_FIELD; 1070 int nb_audio = ((prmh->stat[i] >> FIELD_SIZE) &
1012 int nb_stream = (prmh->stat[i] >> (2*FIELD_SIZE)) & MASK_FIRST_FIELD; 1071 MASK_FIRST_FIELD);
1072 int nb_stream = ((prmh->stat[i] >> (2*FIELD_SIZE)) &
1073 MASK_FIRST_FIELD);
1013 int pipe = prmh->stat[i] & MASK_FIRST_FIELD; 1074 int pipe = prmh->stat[i] & MASK_FIRST_FIELD;
1014 int is_capture = prmh->stat[i] & 0x400000; 1075 int is_capture = prmh->stat[i] & 0x400000;
1015 u32 err2; 1076 u32 err2;
1016 1077
1017 if (prmh->stat[i] & 0x800000) { /* if BIT_END */ 1078 if (prmh->stat[i] & 0x800000) { /* if BIT_END */
1018 snd_printdd("TASKLET : End%sPipe %d\n", 1079 snd_printdd("TASKLET : End%sPipe %d\n",
1019 is_capture ? "Record" : "Play", pipe); 1080 is_capture ? "Record" : "Play",
1081 pipe);
1020 } 1082 }
1021 i++; 1083 i++;
1022 err2 = prmh->stat[i] ? prmh->stat[i] : prmh->stat[i+1]; 1084 err2 = prmh->stat[i] ? prmh->stat[i] : prmh->stat[i+1];
@@ -1062,7 +1124,7 @@ static u_int64_t pcxhr_stream_read_position(struct pcxhr_mgr *mgr,
1062 pcxhr_init_rmh(&rmh, CMD_STREAM_SAMPLE_COUNT); 1124 pcxhr_init_rmh(&rmh, CMD_STREAM_SAMPLE_COUNT);
1063 pcxhr_set_pipe_cmd_params(&rmh, stream->pipe->is_capture, 1125 pcxhr_set_pipe_cmd_params(&rmh, stream->pipe->is_capture,
1064 stream->pipe->first_audio, 0, stream_mask); 1126 stream->pipe->first_audio, 0, stream_mask);
1065 /* rmh.stat_len = 2; */ /* 2 resp data for each stream of the pipe */ 1127 /* rmh.stat_len = 2; */ /* 2 resp data for each stream of the pipe */
1066 1128
1067 err = pcxhr_send_msg(mgr, &rmh); 1129 err = pcxhr_send_msg(mgr, &rmh);
1068 if (err) 1130 if (err)
@@ -1072,18 +1134,21 @@ static u_int64_t pcxhr_stream_read_position(struct pcxhr_mgr *mgr,
1072 hw_sample_count += (u_int64_t)rmh.stat[1]; 1134 hw_sample_count += (u_int64_t)rmh.stat[1];
1073 1135
1074 snd_printdd("stream %c%d : abs samples real(%ld) timer(%ld)\n", 1136 snd_printdd("stream %c%d : abs samples real(%ld) timer(%ld)\n",
1075 stream->pipe->is_capture ? 'C':'P', stream->substream->number, 1137 stream->pipe->is_capture ? 'C' : 'P',
1138 stream->substream->number,
1076 (long unsigned int)hw_sample_count, 1139 (long unsigned int)hw_sample_count,
1077 (long unsigned int)(stream->timer_abs_periods + 1140 (long unsigned int)(stream->timer_abs_periods +
1078 stream->timer_period_frag + PCXHR_GRANULARITY)); 1141 stream->timer_period_frag +
1079 1142 mgr->granularity));
1080 return hw_sample_count; 1143 return hw_sample_count;
1081} 1144}
1082 1145
1083static void pcxhr_update_timer_pos(struct pcxhr_mgr *mgr, 1146static void pcxhr_update_timer_pos(struct pcxhr_mgr *mgr,
1084 struct pcxhr_stream *stream, int samples_to_add) 1147 struct pcxhr_stream *stream,
1148 int samples_to_add)
1085{ 1149{
1086 if (stream->substream && (stream->status == PCXHR_STREAM_STATUS_RUNNING)) { 1150 if (stream->substream &&
1151 (stream->status == PCXHR_STREAM_STATUS_RUNNING)) {
1087 u_int64_t new_sample_count; 1152 u_int64_t new_sample_count;
1088 int elapsed = 0; 1153 int elapsed = 0;
1089 int hardware_read = 0; 1154 int hardware_read = 0;
@@ -1092,20 +1157,22 @@ static void pcxhr_update_timer_pos(struct pcxhr_mgr *mgr,
1092 if (samples_to_add < 0) { 1157 if (samples_to_add < 0) {
1093 stream->timer_is_synced = 0; 1158 stream->timer_is_synced = 0;
1094 /* add default if no hardware_read possible */ 1159 /* add default if no hardware_read possible */
1095 samples_to_add = PCXHR_GRANULARITY; 1160 samples_to_add = mgr->granularity;
1096 } 1161 }
1097 1162
1098 if (!stream->timer_is_synced) { 1163 if (!stream->timer_is_synced) {
1099 if (stream->timer_abs_periods != 0 || 1164 if ((stream->timer_abs_periods != 0) ||
1100 stream->timer_period_frag + PCXHR_GRANULARITY >= 1165 ((stream->timer_period_frag + samples_to_add) >=
1101 runtime->period_size) { 1166 runtime->period_size)) {
1102 new_sample_count = pcxhr_stream_read_position(mgr, stream); 1167 new_sample_count =
1168 pcxhr_stream_read_position(mgr, stream);
1103 hardware_read = 1; 1169 hardware_read = 1;
1104 if (new_sample_count >= PCXHR_GRANULARITY_MIN) { 1170 if (new_sample_count >= mgr->granularity) {
1105 /* sub security offset because of jitter and 1171 /* sub security offset because of
1106 * finer granularity of dsp time (MBOX4) 1172 * jitter and finer granularity of
1173 * dsp time (MBOX4)
1107 */ 1174 */
1108 new_sample_count -= PCXHR_GRANULARITY_MIN; 1175 new_sample_count -= mgr->granularity;
1109 stream->timer_is_synced = 1; 1176 stream->timer_is_synced = 1;
1110 } 1177 }
1111 } 1178 }
@@ -1128,12 +1195,15 @@ static void pcxhr_update_timer_pos(struct pcxhr_mgr *mgr,
1128 stream->timer_buf_periods = 0; 1195 stream->timer_buf_periods = 0;
1129 stream->timer_abs_periods = new_elapse_pos; 1196 stream->timer_abs_periods = new_elapse_pos;
1130 } 1197 }
1131 if (new_sample_count >= stream->timer_abs_periods) 1198 if (new_sample_count >= stream->timer_abs_periods) {
1132 stream->timer_period_frag = (u_int32_t)(new_sample_count - 1199 stream->timer_period_frag =
1133 stream->timer_abs_periods); 1200 (u_int32_t)(new_sample_count -
1134 else 1201 stream->timer_abs_periods);
1135 snd_printk(KERN_ERR "ERROR new_sample_count too small ??? %lx\n", 1202 } else {
1203 snd_printk(KERN_ERR
1204 "ERROR new_sample_count too small ??? %ld\n",
1136 (long unsigned int)new_sample_count); 1205 (long unsigned int)new_sample_count);
1206 }
1137 1207
1138 if (elapsed) { 1208 if (elapsed) {
1139 spin_unlock(&mgr->lock); 1209 spin_unlock(&mgr->lock);
@@ -1143,7 +1213,6 @@ static void pcxhr_update_timer_pos(struct pcxhr_mgr *mgr,
1143 } 1213 }
1144} 1214}
1145 1215
1146
1147irqreturn_t pcxhr_interrupt(int irq, void *dev_id) 1216irqreturn_t pcxhr_interrupt(int irq, void *dev_id)
1148{ 1217{
1149 struct pcxhr_mgr *mgr = dev_id; 1218 struct pcxhr_mgr *mgr = dev_id;
@@ -1156,7 +1225,8 @@ irqreturn_t pcxhr_interrupt(int irq, void *dev_id)
1156 reg = PCXHR_INPL(mgr, PCXHR_PLX_IRQCS); 1225 reg = PCXHR_INPL(mgr, PCXHR_PLX_IRQCS);
1157 if (! (reg & PCXHR_IRQCS_ACTIVE_PCIDB)) { 1226 if (! (reg & PCXHR_IRQCS_ACTIVE_PCIDB)) {
1158 spin_unlock(&mgr->lock); 1227 spin_unlock(&mgr->lock);
1159 return IRQ_NONE; /* this device did not cause the interrupt */ 1228 /* this device did not cause the interrupt */
1229 return IRQ_NONE;
1160 } 1230 }
1161 1231
1162 /* clear interrupt */ 1232 /* clear interrupt */
@@ -1167,10 +1237,12 @@ irqreturn_t pcxhr_interrupt(int irq, void *dev_id)
1167 if (reg & PCXHR_IRQ_TIMER) { 1237 if (reg & PCXHR_IRQ_TIMER) {
1168 int timer_toggle = reg & PCXHR_IRQ_TIMER; 1238 int timer_toggle = reg & PCXHR_IRQ_TIMER;
1169 /* is a 24 bit counter */ 1239 /* is a 24 bit counter */
1170 int dsp_time_new = PCXHR_INPL(mgr, PCXHR_PLX_MBOX4) & PCXHR_DSP_TIME_MASK; 1240 int dsp_time_new =
1241 PCXHR_INPL(mgr, PCXHR_PLX_MBOX4) & PCXHR_DSP_TIME_MASK;
1171 int dsp_time_diff = dsp_time_new - mgr->dsp_time_last; 1242 int dsp_time_diff = dsp_time_new - mgr->dsp_time_last;
1172 1243
1173 if (dsp_time_diff < 0 && mgr->dsp_time_last != PCXHR_DSP_TIME_INVALID) { 1244 if ((dsp_time_diff < 0) &&
1245 (mgr->dsp_time_last != PCXHR_DSP_TIME_INVALID)) {
1174 snd_printdd("ERROR DSP TIME old(%d) new(%d) -> " 1246 snd_printdd("ERROR DSP TIME old(%d) new(%d) -> "
1175 "resynchronize all streams\n", 1247 "resynchronize all streams\n",
1176 mgr->dsp_time_last, dsp_time_new); 1248 mgr->dsp_time_last, dsp_time_new);
@@ -1178,42 +1250,51 @@ irqreturn_t pcxhr_interrupt(int irq, void *dev_id)
1178 } 1250 }
1179#ifdef CONFIG_SND_DEBUG_VERBOSE 1251#ifdef CONFIG_SND_DEBUG_VERBOSE
1180 if (dsp_time_diff == 0) 1252 if (dsp_time_diff == 0)
1181 snd_printdd("ERROR DSP TIME NO DIFF time(%d)\n", dsp_time_new); 1253 snd_printdd("ERROR DSP TIME NO DIFF time(%d)\n",
1182 else if (dsp_time_diff >= (2*PCXHR_GRANULARITY)) 1254 dsp_time_new);
1255 else if (dsp_time_diff >= (2*mgr->granularity))
1183 snd_printdd("ERROR DSP TIME TOO BIG old(%d) add(%d)\n", 1256 snd_printdd("ERROR DSP TIME TOO BIG old(%d) add(%d)\n",
1184 mgr->dsp_time_last, dsp_time_new - mgr->dsp_time_last); 1257 mgr->dsp_time_last,
1258 dsp_time_new - mgr->dsp_time_last);
1259 else if (dsp_time_diff % mgr->granularity)
1260 snd_printdd("ERROR DSP TIME increased by %d\n",
1261 dsp_time_diff);
1185#endif 1262#endif
1186 mgr->dsp_time_last = dsp_time_new; 1263 mgr->dsp_time_last = dsp_time_new;
1187 1264
1188 if (timer_toggle == mgr->timer_toggle) 1265 if (timer_toggle == mgr->timer_toggle) {
1189 snd_printdd("ERROR TIMER TOGGLE\n"); 1266 snd_printdd("ERROR TIMER TOGGLE\n");
1267 mgr->dsp_time_err++;
1268 }
1190 mgr->timer_toggle = timer_toggle; 1269 mgr->timer_toggle = timer_toggle;
1191 1270
1192 reg &= ~PCXHR_IRQ_TIMER; 1271 reg &= ~PCXHR_IRQ_TIMER;
1193 for (i = 0; i < mgr->num_cards; i++) { 1272 for (i = 0; i < mgr->num_cards; i++) {
1194 chip = mgr->chip[i]; 1273 chip = mgr->chip[i];
1195 for (j = 0; j < chip->nb_streams_capt; j++) 1274 for (j = 0; j < chip->nb_streams_capt; j++)
1196 pcxhr_update_timer_pos(mgr, &chip->capture_stream[j], 1275 pcxhr_update_timer_pos(mgr,
1197 dsp_time_diff); 1276 &chip->capture_stream[j],
1277 dsp_time_diff);
1198 } 1278 }
1199 for (i = 0; i < mgr->num_cards; i++) { 1279 for (i = 0; i < mgr->num_cards; i++) {
1200 chip = mgr->chip[i]; 1280 chip = mgr->chip[i];
1201 for (j = 0; j < chip->nb_streams_play; j++) 1281 for (j = 0; j < chip->nb_streams_play; j++)
1202 pcxhr_update_timer_pos(mgr, &chip->playback_stream[j], 1282 pcxhr_update_timer_pos(mgr,
1203 dsp_time_diff); 1283 &chip->playback_stream[j],
1284 dsp_time_diff);
1204 } 1285 }
1205 } 1286 }
1206 /* other irq's handled in the tasklet */ 1287 /* other irq's handled in the tasklet */
1207 if (reg & PCXHR_IRQ_MASK) { 1288 if (reg & PCXHR_IRQ_MASK) {
1208 1289 if (reg & PCXHR_IRQ_ASYNC) {
1209 /* as we didn't request any notifications, some kind of xrun error 1290 /* as we didn't request any async notifications,
1210 * will probably occured 1291 * some kind of xrun error will probably occured
1211 */ 1292 */
1212 /* better resynchronize all streams next interrupt : */ 1293 /* better resynchronize all streams next interrupt : */
1213 mgr->dsp_time_last = PCXHR_DSP_TIME_INVALID; 1294 mgr->dsp_time_last = PCXHR_DSP_TIME_INVALID;
1214 1295 }
1215 mgr->src_it_dsp = reg; 1296 mgr->src_it_dsp = reg;
1216 tasklet_hi_schedule(&mgr->msg_taskq); 1297 tasklet_schedule(&mgr->msg_taskq);
1217 } 1298 }
1218#ifdef CONFIG_SND_DEBUG_VERBOSE 1299#ifdef CONFIG_SND_DEBUG_VERBOSE
1219 if (reg & PCXHR_FATAL_DSP_ERR) 1300 if (reg & PCXHR_FATAL_DSP_ERR)
diff --git a/sound/pci/pcxhr/pcxhr_core.h b/sound/pci/pcxhr/pcxhr_core.h
index d9a4ab609875..bbbd66d13a64 100644
--- a/sound/pci/pcxhr/pcxhr_core.h
+++ b/sound/pci/pcxhr/pcxhr_core.h
@@ -65,7 +65,7 @@ enum {
65 CMD_RESYNC_AUDIO_INPUTS, /* cmd_len = 1 stat_len = 0 */ 65 CMD_RESYNC_AUDIO_INPUTS, /* cmd_len = 1 stat_len = 0 */
66 CMD_GET_DSP_RESOURCES, /* cmd_len = 1 stat_len = 4 */ 66 CMD_GET_DSP_RESOURCES, /* cmd_len = 1 stat_len = 4 */
67 CMD_SET_TIMER_INTERRUPT, /* cmd_len = 1 stat_len = 0 */ 67 CMD_SET_TIMER_INTERRUPT, /* cmd_len = 1 stat_len = 0 */
68 CMD_RES_PIPE, /* cmd_len = 2 stat_len = 0 */ 68 CMD_RES_PIPE, /* cmd_len >=2 stat_len = 0 */
69 CMD_FREE_PIPE, /* cmd_len = 1 stat_len = 0 */ 69 CMD_FREE_PIPE, /* cmd_len = 1 stat_len = 0 */
70 CMD_CONF_PIPE, /* cmd_len = 2 stat_len = 0 */ 70 CMD_CONF_PIPE, /* cmd_len = 2 stat_len = 0 */
71 CMD_STOP_PIPE, /* cmd_len = 1 stat_len = 0 */ 71 CMD_STOP_PIPE, /* cmd_len = 1 stat_len = 0 */
@@ -96,6 +96,8 @@ void pcxhr_init_rmh(struct pcxhr_rmh *rmh, int cmd);
96void pcxhr_set_pipe_cmd_params(struct pcxhr_rmh* rmh, int capture, unsigned int param1, 96void pcxhr_set_pipe_cmd_params(struct pcxhr_rmh* rmh, int capture, unsigned int param1,
97 unsigned int param2, unsigned int param3); 97 unsigned int param2, unsigned int param3);
98 98
99#define DSP_EXT_CMD_SET(x) (x->dsp_version > 0x012800)
100
99/* 101/*
100 send the rmh 102 send the rmh
101 */ 103 */
@@ -110,6 +112,7 @@ int pcxhr_send_msg(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh);
110#define IO_NUM_REG_STATUS 5 112#define IO_NUM_REG_STATUS 5
111#define IO_NUM_REG_CUER 10 113#define IO_NUM_REG_CUER 10
112#define IO_NUM_UER_CHIP_REG 11 114#define IO_NUM_UER_CHIP_REG 11
115#define IO_NUM_REG_CONFIG_SRC 12
113#define IO_NUM_REG_OUT_ANA_LEVEL 20 116#define IO_NUM_REG_OUT_ANA_LEVEL 20
114#define IO_NUM_REG_IN_ANA_LEVEL 21 117#define IO_NUM_REG_IN_ANA_LEVEL 21
115 118
diff --git a/sound/pci/pcxhr/pcxhr_hwdep.c b/sound/pci/pcxhr/pcxhr_hwdep.c
index 96640d9c227d..592743a298b0 100644
--- a/sound/pci/pcxhr/pcxhr_hwdep.c
+++ b/sound/pci/pcxhr/pcxhr_hwdep.c
@@ -31,6 +31,7 @@
31#include "pcxhr_mixer.h" 31#include "pcxhr_mixer.h"
32#include "pcxhr_hwdep.h" 32#include "pcxhr_hwdep.h"
33#include "pcxhr_core.h" 33#include "pcxhr_core.h"
34#include "pcxhr_mix22.h"
34 35
35 36
36#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE) 37#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
@@ -40,10 +41,10 @@
40#endif 41#endif
41 42
42 43
44static int pcxhr_sub_init(struct pcxhr_mgr *mgr);
43/* 45/*
44 * get basic information and init pcxhr card 46 * get basic information and init pcxhr card
45 */ 47 */
46
47static int pcxhr_init_board(struct pcxhr_mgr *mgr) 48static int pcxhr_init_board(struct pcxhr_mgr *mgr)
48{ 49{
49 int err; 50 int err;
@@ -68,7 +69,7 @@ static int pcxhr_init_board(struct pcxhr_mgr *mgr)
68 if ((rmh.stat[0] & MASK_FIRST_FIELD) != mgr->playback_chips * 2) 69 if ((rmh.stat[0] & MASK_FIRST_FIELD) != mgr->playback_chips * 2)
69 return -EINVAL; 70 return -EINVAL;
70 /* test 8 or 2 phys in */ 71 /* test 8 or 2 phys in */
71 if (((rmh.stat[0] >> (2 * FIELD_SIZE)) & MASK_FIRST_FIELD) != 72 if (((rmh.stat[0] >> (2 * FIELD_SIZE)) & MASK_FIRST_FIELD) <
72 mgr->capture_chips * 2) 73 mgr->capture_chips * 2)
73 return -EINVAL; 74 return -EINVAL;
74 /* test max nb substream per board */ 75 /* test max nb substream per board */
@@ -77,20 +78,34 @@ static int pcxhr_init_board(struct pcxhr_mgr *mgr)
77 /* test max nb substream per pipe */ 78 /* test max nb substream per pipe */
78 if (((rmh.stat[1] >> 7) & 0x5F) < PCXHR_PLAYBACK_STREAMS) 79 if (((rmh.stat[1] >> 7) & 0x5F) < PCXHR_PLAYBACK_STREAMS)
79 return -EINVAL; 80 return -EINVAL;
81 snd_printdd("supported formats : playback=%x capture=%x\n",
82 rmh.stat[2], rmh.stat[3]);
80 83
81 pcxhr_init_rmh(&rmh, CMD_VERSION); 84 pcxhr_init_rmh(&rmh, CMD_VERSION);
82 /* firmware num for DSP */ 85 /* firmware num for DSP */
83 rmh.cmd[0] |= mgr->firmware_num; 86 rmh.cmd[0] |= mgr->firmware_num;
84 /* transfer granularity in samples (should be multiple of 48) */ 87 /* transfer granularity in samples (should be multiple of 48) */
85 rmh.cmd[1] = (1<<23) + PCXHR_GRANULARITY; 88 rmh.cmd[1] = (1<<23) + mgr->granularity;
86 rmh.cmd_len = 2; 89 rmh.cmd_len = 2;
87 err = pcxhr_send_msg(mgr, &rmh); 90 err = pcxhr_send_msg(mgr, &rmh);
88 if (err) 91 if (err)
89 return err; 92 return err;
90 snd_printdd("PCXHR DSP version is %d.%d.%d\n", 93 snd_printdd("PCXHR DSP version is %d.%d.%d\n", (rmh.stat[0]>>16)&0xff,
91 (rmh.stat[0]>>16)&0xff, (rmh.stat[0]>>8)&0xff, rmh.stat[0]&0xff); 94 (rmh.stat[0]>>8)&0xff, rmh.stat[0]&0xff);
92 mgr->dsp_version = rmh.stat[0]; 95 mgr->dsp_version = rmh.stat[0];
93 96
97 if (mgr->is_hr_stereo)
98 err = hr222_sub_init(mgr);
99 else
100 err = pcxhr_sub_init(mgr);
101 return err;
102}
103
104static int pcxhr_sub_init(struct pcxhr_mgr *mgr)
105{
106 int err;
107 struct pcxhr_rmh rmh;
108
94 /* get options */ 109 /* get options */
95 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ); 110 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ);
96 rmh.cmd[0] |= IO_NUM_REG_STATUS; 111 rmh.cmd[0] |= IO_NUM_REG_STATUS;
@@ -100,20 +115,22 @@ static int pcxhr_init_board(struct pcxhr_mgr *mgr)
100 if (err) 115 if (err)
101 return err; 116 return err;
102 117
103 if ((rmh.stat[1] & REG_STATUS_OPT_DAUGHTER_MASK) == REG_STATUS_OPT_ANALOG_BOARD) 118 if ((rmh.stat[1] & REG_STATUS_OPT_DAUGHTER_MASK) ==
104 mgr->board_has_analog = 1; /* analog addon board available */ 119 REG_STATUS_OPT_ANALOG_BOARD)
105 else 120 mgr->board_has_analog = 1; /* analog addon board found */
106 /* analog addon board not available -> no support for instance */
107 return -EINVAL;
108 121
109 /* unmute inputs */ 122 /* unmute inputs */
110 err = pcxhr_write_io_num_reg_cont(mgr, REG_CONT_UNMUTE_INPUTS, 123 err = pcxhr_write_io_num_reg_cont(mgr, REG_CONT_UNMUTE_INPUTS,
111 REG_CONT_UNMUTE_INPUTS, NULL); 124 REG_CONT_UNMUTE_INPUTS, NULL);
112 if (err) 125 if (err)
113 return err; 126 return err;
114 /* unmute outputs */ 127 /* unmute outputs (a write to IO_NUM_REG_MUTE_OUT mutes!) */
115 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ); /* a write to IO_NUM_REG_MUTE_OUT mutes! */ 128 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ);
116 rmh.cmd[0] |= IO_NUM_REG_MUTE_OUT; 129 rmh.cmd[0] |= IO_NUM_REG_MUTE_OUT;
130 if (DSP_EXT_CMD_SET(mgr)) {
131 rmh.cmd[1] = 1; /* unmute digital plugs */
132 rmh.cmd_len = 2;
133 }
117 err = pcxhr_send_msg(mgr, &rmh); 134 err = pcxhr_send_msg(mgr, &rmh);
118 return err; 135 return err;
119} 136}
@@ -124,19 +141,25 @@ void pcxhr_reset_board(struct pcxhr_mgr *mgr)
124 141
125 if (mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX)) { 142 if (mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX)) {
126 /* mute outputs */ 143 /* mute outputs */
144 if (!mgr->is_hr_stereo) {
127 /* a read to IO_NUM_REG_MUTE_OUT register unmutes! */ 145 /* a read to IO_NUM_REG_MUTE_OUT register unmutes! */
128 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE); 146 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE);
129 rmh.cmd[0] |= IO_NUM_REG_MUTE_OUT; 147 rmh.cmd[0] |= IO_NUM_REG_MUTE_OUT;
130 pcxhr_send_msg(mgr, &rmh); 148 pcxhr_send_msg(mgr, &rmh);
131 /* mute inputs */ 149 /* mute inputs */
132 pcxhr_write_io_num_reg_cont(mgr, REG_CONT_UNMUTE_INPUTS, 0, NULL); 150 pcxhr_write_io_num_reg_cont(mgr, REG_CONT_UNMUTE_INPUTS,
151 0, NULL);
152 }
153 /* stereo cards mute with reset of dsp */
133 } 154 }
134 /* reset pcxhr dsp */ 155 /* reset pcxhr dsp */
135 if (mgr->dsp_loaded & ( 1 << PCXHR_FIRMWARE_DSP_EPRM_INDEX)) 156 if (mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_EPRM_INDEX))
136 pcxhr_reset_dsp(mgr); 157 pcxhr_reset_dsp(mgr);
137 /* reset second xilinx */ 158 /* reset second xilinx */
138 if (mgr->dsp_loaded & ( 1 << PCXHR_FIRMWARE_XLX_COM_INDEX)) 159 if (mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_XLX_COM_INDEX)) {
139 pcxhr_reset_xilinx_com(mgr); 160 pcxhr_reset_xilinx_com(mgr);
161 mgr->dsp_loaded = 1;
162 }
140 return; 163 return;
141} 164}
142 165
@@ -144,8 +167,9 @@ void pcxhr_reset_board(struct pcxhr_mgr *mgr)
144/* 167/*
145 * allocate a playback/capture pipe (pcmp0/pcmc0) 168 * allocate a playback/capture pipe (pcmp0/pcmc0)
146 */ 169 */
147static int pcxhr_dsp_allocate_pipe( struct pcxhr_mgr *mgr, struct pcxhr_pipe *pipe, 170static int pcxhr_dsp_allocate_pipe(struct pcxhr_mgr *mgr,
148 int is_capture, int pin) 171 struct pcxhr_pipe *pipe,
172 int is_capture, int pin)
149{ 173{
150 int stream_count, audio_count; 174 int stream_count, audio_count;
151 int err; 175 int err;
@@ -161,15 +185,23 @@ static int pcxhr_dsp_allocate_pipe( struct pcxhr_mgr *mgr, struct pcxhr_pipe *pi
161 stream_count = PCXHR_PLAYBACK_STREAMS; 185 stream_count = PCXHR_PLAYBACK_STREAMS;
162 audio_count = 2; /* always stereo */ 186 audio_count = 2; /* always stereo */
163 } 187 }
164 snd_printdd("snd_add_ref_pipe pin(%d) pcm%c0\n", pin, is_capture ? 'c' : 'p'); 188 snd_printdd("snd_add_ref_pipe pin(%d) pcm%c0\n",
189 pin, is_capture ? 'c' : 'p');
165 pipe->is_capture = is_capture; 190 pipe->is_capture = is_capture;
166 pipe->first_audio = pin; 191 pipe->first_audio = pin;
167 /* define pipe (P_PCM_ONLY_MASK (0x020000) is not necessary) */ 192 /* define pipe (P_PCM_ONLY_MASK (0x020000) is not necessary) */
168 pcxhr_init_rmh(&rmh, CMD_RES_PIPE); 193 pcxhr_init_rmh(&rmh, CMD_RES_PIPE);
169 pcxhr_set_pipe_cmd_params(&rmh, is_capture, pin, audio_count, stream_count); 194 pcxhr_set_pipe_cmd_params(&rmh, is_capture, pin,
195 audio_count, stream_count);
196 rmh.cmd[1] |= 0x020000; /* add P_PCM_ONLY_MASK */
197 if (DSP_EXT_CMD_SET(mgr)) {
198 /* add channel mask to command */
199 rmh.cmd[rmh.cmd_len++] = (audio_count == 1) ? 0x01 : 0x03;
200 }
170 err = pcxhr_send_msg(mgr, &rmh); 201 err = pcxhr_send_msg(mgr, &rmh);
171 if (err < 0) { 202 if (err < 0) {
172 snd_printk(KERN_ERR "error pipe allocation (CMD_RES_PIPE) err=%x!\n", err ); 203 snd_printk(KERN_ERR "error pipe allocation "
204 "(CMD_RES_PIPE) err=%x!\n", err);
173 return err; 205 return err;
174 } 206 }
175 pipe->status = PCXHR_PIPE_DEFINED; 207 pipe->status = PCXHR_PIPE_DEFINED;
@@ -199,10 +231,12 @@ static int pcxhr_dsp_free_pipe( struct pcxhr_mgr *mgr, struct pcxhr_pipe *pipe)
199 snd_printk(KERN_ERR "error stopping pipe!\n"); 231 snd_printk(KERN_ERR "error stopping pipe!\n");
200 /* release the pipe */ 232 /* release the pipe */
201 pcxhr_init_rmh(&rmh, CMD_FREE_PIPE); 233 pcxhr_init_rmh(&rmh, CMD_FREE_PIPE);
202 pcxhr_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->first_audio, 0, 0); 234 pcxhr_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->first_audio,
235 0, 0);
203 err = pcxhr_send_msg(mgr, &rmh); 236 err = pcxhr_send_msg(mgr, &rmh);
204 if (err < 0) 237 if (err < 0)
205 snd_printk(KERN_ERR "error pipe release (CMD_FREE_PIPE) err(%x)\n", err); 238 snd_printk(KERN_ERR "error pipe release "
239 "(CMD_FREE_PIPE) err(%x)\n", err);
206 pipe->status = PCXHR_PIPE_UNDEFINED; 240 pipe->status = PCXHR_PIPE_UNDEFINED;
207 return err; 241 return err;
208} 242}
@@ -248,15 +282,16 @@ static int pcxhr_start_pipes(struct pcxhr_mgr *mgr)
248 for (i = 0; i < mgr->num_cards; i++) { 282 for (i = 0; i < mgr->num_cards; i++) {
249 chip = mgr->chip[i]; 283 chip = mgr->chip[i];
250 if (chip->nb_streams_play) 284 if (chip->nb_streams_play)
251 playback_mask |= (1 << chip->playback_pipe.first_audio); 285 playback_mask |= 1 << chip->playback_pipe.first_audio;
252 for (j = 0; j < chip->nb_streams_capt; j++) 286 for (j = 0; j < chip->nb_streams_capt; j++)
253 capture_mask |= (1 << chip->capture_pipe[j].first_audio); 287 capture_mask |= 1 << chip->capture_pipe[j].first_audio;
254 } 288 }
255 return pcxhr_set_pipe_state(mgr, playback_mask, capture_mask, 1); 289 return pcxhr_set_pipe_state(mgr, playback_mask, capture_mask, 1);
256} 290}
257 291
258 292
259static int pcxhr_dsp_load(struct pcxhr_mgr *mgr, int index, const struct firmware *dsp) 293static int pcxhr_dsp_load(struct pcxhr_mgr *mgr, int index,
294 const struct firmware *dsp)
260{ 295{
261 int err, card_index; 296 int err, card_index;
262 297
@@ -330,22 +365,33 @@ static int pcxhr_dsp_load(struct pcxhr_mgr *mgr, int index, const struct firmwar
330 365
331int pcxhr_setup_firmware(struct pcxhr_mgr *mgr) 366int pcxhr_setup_firmware(struct pcxhr_mgr *mgr)
332{ 367{
333 static char *fw_files[5] = { 368 static char *fw_files[][5] = {
334 "xi_1_882.dat", 369 [0] = { "xlxint.dat", "xlxc882hr.dat",
335 "xc_1_882.dat", 370 "dspe882.e56", "dspb882hr.b56", "dspd882.d56" },
336 "e321_512.e56", 371 [1] = { "xlxint.dat", "xlxc882e.dat",
337 "b321_512.b56", 372 "dspe882.e56", "dspb882e.b56", "dspd882.d56" },
338 "d321_512.d56" 373 [2] = { "xlxint.dat", "xlxc1222hr.dat",
374 "dspe882.e56", "dspb1222hr.b56", "dspd1222.d56" },
375 [3] = { "xlxint.dat", "xlxc1222e.dat",
376 "dspe882.e56", "dspb1222e.b56", "dspd1222.d56" },
377 [4] = { NULL, "xlxc222.dat",
378 "dspe924.e56", "dspb924.b56", "dspd222.d56" },
379 [5] = { NULL, "xlxc924.dat",
380 "dspe924.e56", "dspb924.b56", "dspd222.d56" },
339 }; 381 };
340 char path[32]; 382 char path[32];
341 383
342 const struct firmware *fw_entry; 384 const struct firmware *fw_entry;
343 int i, err; 385 int i, err;
386 int fw_set = mgr->fw_file_set;
344 387
345 for (i = 0; i < ARRAY_SIZE(fw_files); i++) { 388 for (i = 0; i < 5; i++) {
346 sprintf(path, "pcxhr/%s", fw_files[i]); 389 if (!fw_files[fw_set][i])
390 continue;
391 sprintf(path, "pcxhr/%s", fw_files[fw_set][i]);
347 if (request_firmware(&fw_entry, path, &mgr->pci->dev)) { 392 if (request_firmware(&fw_entry, path, &mgr->pci->dev)) {
348 snd_printk(KERN_ERR "pcxhr: can't load firmware %s\n", path); 393 snd_printk(KERN_ERR "pcxhr: can't load firmware %s\n",
394 path);
349 return -ENOENT; 395 return -ENOENT;
350 } 396 }
351 /* fake hwdep dsp record */ 397 /* fake hwdep dsp record */
@@ -358,11 +404,26 @@ int pcxhr_setup_firmware(struct pcxhr_mgr *mgr)
358 return 0; 404 return 0;
359} 405}
360 406
361MODULE_FIRMWARE("pcxhr/xi_1_882.dat"); 407MODULE_FIRMWARE("pcxhr/xlxint.dat");
362MODULE_FIRMWARE("pcxhr/xc_1_882.dat"); 408MODULE_FIRMWARE("pcxhr/xlxc882hr.dat");
363MODULE_FIRMWARE("pcxhr/e321_512.e56"); 409MODULE_FIRMWARE("pcxhr/xlxc882e.dat");
364MODULE_FIRMWARE("pcxhr/b321_512.b56"); 410MODULE_FIRMWARE("pcxhr/dspe882.e56");
365MODULE_FIRMWARE("pcxhr/d321_512.d56"); 411MODULE_FIRMWARE("pcxhr/dspb882hr.b56");
412MODULE_FIRMWARE("pcxhr/dspb882e.b56");
413MODULE_FIRMWARE("pcxhr/dspd882.d56");
414
415MODULE_FIRMWARE("pcxhr/xlxc1222hr.dat");
416MODULE_FIRMWARE("pcxhr/xlxc1222e.dat");
417MODULE_FIRMWARE("pcxhr/dspb1222hr.b56");
418MODULE_FIRMWARE("pcxhr/dspb1222e.b56");
419MODULE_FIRMWARE("pcxhr/dspd1222.d56");
420
421MODULE_FIRMWARE("pcxhr/xlxc222.dat");
422MODULE_FIRMWARE("pcxhr/xlxc924.dat");
423MODULE_FIRMWARE("pcxhr/dspe924.e56");
424MODULE_FIRMWARE("pcxhr/dspb924.b56");
425MODULE_FIRMWARE("pcxhr/dspd222.d56");
426
366 427
367#else /* old style firmware loading */ 428#else /* old style firmware loading */
368 429
@@ -373,7 +434,8 @@ MODULE_FIRMWARE("pcxhr/d321_512.d56");
373static int pcxhr_hwdep_dsp_status(struct snd_hwdep *hw, 434static int pcxhr_hwdep_dsp_status(struct snd_hwdep *hw,
374 struct snd_hwdep_dsp_status *info) 435 struct snd_hwdep_dsp_status *info)
375{ 436{
376 strcpy(info->id, "pcxhr"); 437 struct pcxhr_mgr *mgr = hw->private_data;
438 sprintf(info->id, "pcxhr%d", mgr->fw_file_set);
377 info->num_dsps = PCXHR_FIRMWARE_FILES_MAX_INDEX; 439 info->num_dsps = PCXHR_FIRMWARE_FILES_MAX_INDEX;
378 440
379 if (hw->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX)) 441 if (hw->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX))
@@ -393,8 +455,8 @@ static int pcxhr_hwdep_dsp_load(struct snd_hwdep *hw,
393 fw.size = dsp->length; 455 fw.size = dsp->length;
394 fw.data = vmalloc(fw.size); 456 fw.data = vmalloc(fw.size);
395 if (! fw.data) { 457 if (! fw.data) {
396 snd_printk(KERN_ERR "pcxhr: cannot allocate dsp image (%lu bytes)\n", 458 snd_printk(KERN_ERR "pcxhr: cannot allocate dsp image "
397 (unsigned long)fw.size); 459 "(%lu bytes)\n", (unsigned long)fw.size);
398 return -ENOMEM; 460 return -ENOMEM;
399 } 461 }
400 if (copy_from_user((void *)fw.data, dsp->image, dsp->length)) { 462 if (copy_from_user((void *)fw.data, dsp->image, dsp->length)) {
@@ -424,8 +486,11 @@ int pcxhr_setup_firmware(struct pcxhr_mgr *mgr)
424 int err; 486 int err;
425 struct snd_hwdep *hw; 487 struct snd_hwdep *hw;
426 488
427 /* only create hwdep interface for first cardX (see "index" module parameter)*/ 489 /* only create hwdep interface for first cardX
428 if ((err = snd_hwdep_new(mgr->chip[0]->card, PCXHR_HWDEP_ID, 0, &hw)) < 0) 490 * (see "index" module parameter)
491 */
492 err = snd_hwdep_new(mgr->chip[0]->card, PCXHR_HWDEP_ID, 0, &hw);
493 if (err < 0)
429 return err; 494 return err;
430 495
431 hw->iface = SNDRV_HWDEP_IFACE_PCXHR; 496 hw->iface = SNDRV_HWDEP_IFACE_PCXHR;
@@ -435,10 +500,13 @@ int pcxhr_setup_firmware(struct pcxhr_mgr *mgr)
435 hw->ops.dsp_status = pcxhr_hwdep_dsp_status; 500 hw->ops.dsp_status = pcxhr_hwdep_dsp_status;
436 hw->ops.dsp_load = pcxhr_hwdep_dsp_load; 501 hw->ops.dsp_load = pcxhr_hwdep_dsp_load;
437 hw->exclusive = 1; 502 hw->exclusive = 1;
503 /* stereo cards don't need fw_file_0 -> dsp_loaded = 1 */
504 hw->dsp_loaded = mgr->is_hr_stereo ? 1 : 0;
438 mgr->dsp_loaded = 0; 505 mgr->dsp_loaded = 0;
439 sprintf(hw->name, PCXHR_HWDEP_ID); 506 sprintf(hw->name, PCXHR_HWDEP_ID);
440 507
441 if ((err = snd_card_register(mgr->chip[0]->card)) < 0) 508 err = snd_card_register(mgr->chip[0]->card);
509 if (err < 0)
442 return err; 510 return err;
443 return 0; 511 return 0;
444} 512}
diff --git a/sound/pci/pcxhr/pcxhr_mix22.c b/sound/pci/pcxhr/pcxhr_mix22.c
new file mode 100644
index 000000000000..ff019126b672
--- /dev/null
+++ b/sound/pci/pcxhr/pcxhr_mix22.c
@@ -0,0 +1,820 @@
1/*
2 * Driver for Digigram pcxhr compatible soundcards
3 *
4 * mixer interface for stereo cards
5 *
6 * Copyright (c) 2004 by Digigram <alsa@digigram.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#include <linux/delay.h>
24#include <linux/io.h>
25#include <sound/core.h>
26#include <sound/control.h>
27#include <sound/tlv.h>
28#include <sound/asoundef.h>
29#include "pcxhr.h"
30#include "pcxhr_core.h"
31#include "pcxhr_mix22.h"
32
33
34/* registers used on the DSP and Xilinx (port 2) : HR stereo cards only */
35#define PCXHR_DSP_RESET 0x20
36#define PCXHR_XLX_CFG 0x24
37#define PCXHR_XLX_RUER 0x28
38#define PCXHR_XLX_DATA 0x2C
39#define PCXHR_XLX_STATUS 0x30
40#define PCXHR_XLX_LOFREQ 0x34
41#define PCXHR_XLX_HIFREQ 0x38
42#define PCXHR_XLX_CSUER 0x3C
43#define PCXHR_XLX_SELMIC 0x40
44
45#define PCXHR_DSP 2
46
47/* byte access only ! */
48#define PCXHR_INPB(mgr, x) inb((mgr)->port[PCXHR_DSP] + (x))
49#define PCXHR_OUTPB(mgr, x, data) outb((data), (mgr)->port[PCXHR_DSP] + (x))
50
51
52/* values for PCHR_DSP_RESET register */
53#define PCXHR_DSP_RESET_DSP 0x01
54#define PCXHR_DSP_RESET_MUTE 0x02
55#define PCXHR_DSP_RESET_CODEC 0x08
56
57/* values for PCHR_XLX_CFG register */
58#define PCXHR_CFG_SYNCDSP_MASK 0x80
59#define PCXHR_CFG_DEPENDENCY_MASK 0x60
60#define PCXHR_CFG_INDEPENDANT_SEL 0x00
61#define PCXHR_CFG_MASTER_SEL 0x40
62#define PCXHR_CFG_SLAVE_SEL 0x20
63#define PCXHR_CFG_DATA_UER1_SEL_MASK 0x10 /* 0 (UER0), 1(UER1) */
64#define PCXHR_CFG_DATAIN_SEL_MASK 0x08 /* 0 (ana), 1 (UER) */
65#define PCXHR_CFG_SRC_MASK 0x04 /* 0 (Bypass), 1 (SRC Actif) */
66#define PCXHR_CFG_CLOCK_UER1_SEL_MASK 0x02 /* 0 (UER0), 1(UER1) */
67#define PCXHR_CFG_CLOCKIN_SEL_MASK 0x01 /* 0 (internal), 1 (AES/EBU) */
68
69/* values for PCHR_XLX_DATA register */
70#define PCXHR_DATA_CODEC 0x80
71#define AKM_POWER_CONTROL_CMD 0xA007
72#define AKM_RESET_ON_CMD 0xA100
73#define AKM_RESET_OFF_CMD 0xA103
74#define AKM_CLOCK_INF_55K_CMD 0xA240
75#define AKM_CLOCK_SUP_55K_CMD 0xA24D
76#define AKM_MUTE_CMD 0xA38D
77#define AKM_UNMUTE_CMD 0xA30D
78#define AKM_LEFT_LEVEL_CMD 0xA600
79#define AKM_RIGHT_LEVEL_CMD 0xA700
80
81/* values for PCHR_XLX_STATUS register - READ */
82#define PCXHR_STAT_SRC_LOCK 0x01
83#define PCXHR_STAT_LEVEL_IN 0x02
84#define PCXHR_STAT_MIC_CAPS 0x10
85/* values for PCHR_XLX_STATUS register - WRITE */
86#define PCXHR_STAT_FREQ_SYNC_MASK 0x01
87#define PCXHR_STAT_FREQ_UER1_MASK 0x02
88#define PCXHR_STAT_FREQ_SAVE_MASK 0x80
89
90/* values for PCHR_XLX_CSUER register */
91#define PCXHR_SUER1_BIT_U_READ_MASK 0x80
92#define PCXHR_SUER1_BIT_C_READ_MASK 0x40
93#define PCXHR_SUER1_DATA_PRESENT_MASK 0x20
94#define PCXHR_SUER1_CLOCK_PRESENT_MASK 0x10
95#define PCXHR_SUER_BIT_U_READ_MASK 0x08
96#define PCXHR_SUER_BIT_C_READ_MASK 0x04
97#define PCXHR_SUER_DATA_PRESENT_MASK 0x02
98#define PCXHR_SUER_CLOCK_PRESENT_MASK 0x01
99
100#define PCXHR_SUER_BIT_U_WRITE_MASK 0x02
101#define PCXHR_SUER_BIT_C_WRITE_MASK 0x01
102
103/* values for PCXHR_XLX_SELMIC register - WRITE */
104#define PCXHR_SELMIC_PREAMPLI_OFFSET 2
105#define PCXHR_SELMIC_PREAMPLI_MASK 0x0C
106#define PCXHR_SELMIC_PHANTOM_ALIM 0x80
107
108
109static const unsigned char g_hr222_p_level[] = {
110 0x00, /* [000] -49.5 dB: AKM[000] = -1.#INF dB (mute) */
111 0x01, /* [001] -49.0 dB: AKM[001] = -48.131 dB (diff=0.86920 dB) */
112 0x01, /* [002] -48.5 dB: AKM[001] = -48.131 dB (diff=0.36920 dB) */
113 0x01, /* [003] -48.0 dB: AKM[001] = -48.131 dB (diff=0.13080 dB) */
114 0x01, /* [004] -47.5 dB: AKM[001] = -48.131 dB (diff=0.63080 dB) */
115 0x01, /* [005] -46.5 dB: AKM[001] = -48.131 dB (diff=1.63080 dB) */
116 0x01, /* [006] -47.0 dB: AKM[001] = -48.131 dB (diff=1.13080 dB) */
117 0x01, /* [007] -46.0 dB: AKM[001] = -48.131 dB (diff=2.13080 dB) */
118 0x01, /* [008] -45.5 dB: AKM[001] = -48.131 dB (diff=2.63080 dB) */
119 0x02, /* [009] -45.0 dB: AKM[002] = -42.110 dB (diff=2.88980 dB) */
120 0x02, /* [010] -44.5 dB: AKM[002] = -42.110 dB (diff=2.38980 dB) */
121 0x02, /* [011] -44.0 dB: AKM[002] = -42.110 dB (diff=1.88980 dB) */
122 0x02, /* [012] -43.5 dB: AKM[002] = -42.110 dB (diff=1.38980 dB) */
123 0x02, /* [013] -43.0 dB: AKM[002] = -42.110 dB (diff=0.88980 dB) */
124 0x02, /* [014] -42.5 dB: AKM[002] = -42.110 dB (diff=0.38980 dB) */
125 0x02, /* [015] -42.0 dB: AKM[002] = -42.110 dB (diff=0.11020 dB) */
126 0x02, /* [016] -41.5 dB: AKM[002] = -42.110 dB (diff=0.61020 dB) */
127 0x02, /* [017] -41.0 dB: AKM[002] = -42.110 dB (diff=1.11020 dB) */
128 0x02, /* [018] -40.5 dB: AKM[002] = -42.110 dB (diff=1.61020 dB) */
129 0x03, /* [019] -40.0 dB: AKM[003] = -38.588 dB (diff=1.41162 dB) */
130 0x03, /* [020] -39.5 dB: AKM[003] = -38.588 dB (diff=0.91162 dB) */
131 0x03, /* [021] -39.0 dB: AKM[003] = -38.588 dB (diff=0.41162 dB) */
132 0x03, /* [022] -38.5 dB: AKM[003] = -38.588 dB (diff=0.08838 dB) */
133 0x03, /* [023] -38.0 dB: AKM[003] = -38.588 dB (diff=0.58838 dB) */
134 0x03, /* [024] -37.5 dB: AKM[003] = -38.588 dB (diff=1.08838 dB) */
135 0x04, /* [025] -37.0 dB: AKM[004] = -36.090 dB (diff=0.91040 dB) */
136 0x04, /* [026] -36.5 dB: AKM[004] = -36.090 dB (diff=0.41040 dB) */
137 0x04, /* [027] -36.0 dB: AKM[004] = -36.090 dB (diff=0.08960 dB) */
138 0x04, /* [028] -35.5 dB: AKM[004] = -36.090 dB (diff=0.58960 dB) */
139 0x05, /* [029] -35.0 dB: AKM[005] = -34.151 dB (diff=0.84860 dB) */
140 0x05, /* [030] -34.5 dB: AKM[005] = -34.151 dB (diff=0.34860 dB) */
141 0x05, /* [031] -34.0 dB: AKM[005] = -34.151 dB (diff=0.15140 dB) */
142 0x05, /* [032] -33.5 dB: AKM[005] = -34.151 dB (diff=0.65140 dB) */
143 0x06, /* [033] -33.0 dB: AKM[006] = -32.568 dB (diff=0.43222 dB) */
144 0x06, /* [034] -32.5 dB: AKM[006] = -32.568 dB (diff=0.06778 dB) */
145 0x06, /* [035] -32.0 dB: AKM[006] = -32.568 dB (diff=0.56778 dB) */
146 0x07, /* [036] -31.5 dB: AKM[007] = -31.229 dB (diff=0.27116 dB) */
147 0x07, /* [037] -31.0 dB: AKM[007] = -31.229 dB (diff=0.22884 dB) */
148 0x08, /* [038] -30.5 dB: AKM[008] = -30.069 dB (diff=0.43100 dB) */
149 0x08, /* [039] -30.0 dB: AKM[008] = -30.069 dB (diff=0.06900 dB) */
150 0x09, /* [040] -29.5 dB: AKM[009] = -29.046 dB (diff=0.45405 dB) */
151 0x09, /* [041] -29.0 dB: AKM[009] = -29.046 dB (diff=0.04595 dB) */
152 0x0a, /* [042] -28.5 dB: AKM[010] = -28.131 dB (diff=0.36920 dB) */
153 0x0a, /* [043] -28.0 dB: AKM[010] = -28.131 dB (diff=0.13080 dB) */
154 0x0b, /* [044] -27.5 dB: AKM[011] = -27.303 dB (diff=0.19705 dB) */
155 0x0b, /* [045] -27.0 dB: AKM[011] = -27.303 dB (diff=0.30295 dB) */
156 0x0c, /* [046] -26.5 dB: AKM[012] = -26.547 dB (diff=0.04718 dB) */
157 0x0d, /* [047] -26.0 dB: AKM[013] = -25.852 dB (diff=0.14806 dB) */
158 0x0e, /* [048] -25.5 dB: AKM[014] = -25.208 dB (diff=0.29176 dB) */
159 0x0e, /* [049] -25.0 dB: AKM[014] = -25.208 dB (diff=0.20824 dB) */
160 0x0f, /* [050] -24.5 dB: AKM[015] = -24.609 dB (diff=0.10898 dB) */
161 0x10, /* [051] -24.0 dB: AKM[016] = -24.048 dB (diff=0.04840 dB) */
162 0x11, /* [052] -23.5 dB: AKM[017] = -23.522 dB (diff=0.02183 dB) */
163 0x12, /* [053] -23.0 dB: AKM[018] = -23.025 dB (diff=0.02535 dB) */
164 0x13, /* [054] -22.5 dB: AKM[019] = -22.556 dB (diff=0.05573 dB) */
165 0x14, /* [055] -22.0 dB: AKM[020] = -22.110 dB (diff=0.11020 dB) */
166 0x15, /* [056] -21.5 dB: AKM[021] = -21.686 dB (diff=0.18642 dB) */
167 0x17, /* [057] -21.0 dB: AKM[023] = -20.896 dB (diff=0.10375 dB) */
168 0x18, /* [058] -20.5 dB: AKM[024] = -20.527 dB (diff=0.02658 dB) */
169 0x1a, /* [059] -20.0 dB: AKM[026] = -19.831 dB (diff=0.16866 dB) */
170 0x1b, /* [060] -19.5 dB: AKM[027] = -19.504 dB (diff=0.00353 dB) */
171 0x1d, /* [061] -19.0 dB: AKM[029] = -18.883 dB (diff=0.11716 dB) */
172 0x1e, /* [062] -18.5 dB: AKM[030] = -18.588 dB (diff=0.08838 dB) */
173 0x20, /* [063] -18.0 dB: AKM[032] = -18.028 dB (diff=0.02780 dB) */
174 0x22, /* [064] -17.5 dB: AKM[034] = -17.501 dB (diff=0.00123 dB) */
175 0x24, /* [065] -17.0 dB: AKM[036] = -17.005 dB (diff=0.00475 dB) */
176 0x26, /* [066] -16.5 dB: AKM[038] = -16.535 dB (diff=0.03513 dB) */
177 0x28, /* [067] -16.0 dB: AKM[040] = -16.090 dB (diff=0.08960 dB) */
178 0x2b, /* [068] -15.5 dB: AKM[043] = -15.461 dB (diff=0.03857 dB) */
179 0x2d, /* [069] -15.0 dB: AKM[045] = -15.067 dB (diff=0.06655 dB) */
180 0x30, /* [070] -14.5 dB: AKM[048] = -14.506 dB (diff=0.00598 dB) */
181 0x33, /* [071] -14.0 dB: AKM[051] = -13.979 dB (diff=0.02060 dB) */
182 0x36, /* [072] -13.5 dB: AKM[054] = -13.483 dB (diff=0.01707 dB) */
183 0x39, /* [073] -13.0 dB: AKM[057] = -13.013 dB (diff=0.01331 dB) */
184 0x3c, /* [074] -12.5 dB: AKM[060] = -12.568 dB (diff=0.06778 dB) */
185 0x40, /* [075] -12.0 dB: AKM[064] = -12.007 dB (diff=0.00720 dB) */
186 0x44, /* [076] -11.5 dB: AKM[068] = -11.481 dB (diff=0.01937 dB) */
187 0x48, /* [077] -11.0 dB: AKM[072] = -10.984 dB (diff=0.01585 dB) */
188 0x4c, /* [078] -10.5 dB: AKM[076] = -10.515 dB (diff=0.01453 dB) */
189 0x51, /* [079] -10.0 dB: AKM[081] = -9.961 dB (diff=0.03890 dB) */
190 0x55, /* [080] -9.5 dB: AKM[085] = -9.542 dB (diff=0.04243 dB) */
191 0x5a, /* [081] -9.0 dB: AKM[090] = -9.046 dB (diff=0.04595 dB) */
192 0x60, /* [082] -8.5 dB: AKM[096] = -8.485 dB (diff=0.01462 dB) */
193 0x66, /* [083] -8.0 dB: AKM[102] = -7.959 dB (diff=0.04120 dB) */
194 0x6c, /* [084] -7.5 dB: AKM[108] = -7.462 dB (diff=0.03767 dB) */
195 0x72, /* [085] -7.0 dB: AKM[114] = -6.993 dB (diff=0.00729 dB) */
196 0x79, /* [086] -6.5 dB: AKM[121] = -6.475 dB (diff=0.02490 dB) */
197 0x80, /* [087] -6.0 dB: AKM[128] = -5.987 dB (diff=0.01340 dB) */
198 0x87, /* [088] -5.5 dB: AKM[135] = -5.524 dB (diff=0.02413 dB) */
199 0x8f, /* [089] -5.0 dB: AKM[143] = -5.024 dB (diff=0.02408 dB) */
200 0x98, /* [090] -4.5 dB: AKM[152] = -4.494 dB (diff=0.00607 dB) */
201 0xa1, /* [091] -4.0 dB: AKM[161] = -3.994 dB (diff=0.00571 dB) */
202 0xaa, /* [092] -3.5 dB: AKM[170] = -3.522 dB (diff=0.02183 dB) */
203 0xb5, /* [093] -3.0 dB: AKM[181] = -2.977 dB (diff=0.02277 dB) */
204 0xbf, /* [094] -2.5 dB: AKM[191] = -2.510 dB (diff=0.01014 dB) */
205 0xcb, /* [095] -2.0 dB: AKM[203] = -1.981 dB (diff=0.01912 dB) */
206 0xd7, /* [096] -1.5 dB: AKM[215] = -1.482 dB (diff=0.01797 dB) */
207 0xe3, /* [097] -1.0 dB: AKM[227] = -1.010 dB (diff=0.01029 dB) */
208 0xf1, /* [098] -0.5 dB: AKM[241] = -0.490 dB (diff=0.00954 dB) */
209 0xff, /* [099] +0.0 dB: AKM[255] = +0.000 dB (diff=0.00000 dB) */
210};
211
212
213static void hr222_config_akm(struct pcxhr_mgr *mgr, unsigned short data)
214{
215 unsigned short mask = 0x8000;
216 /* activate access to codec registers */
217 PCXHR_INPB(mgr, PCXHR_XLX_HIFREQ);
218
219 while (mask) {
220 PCXHR_OUTPB(mgr, PCXHR_XLX_DATA,
221 data & mask ? PCXHR_DATA_CODEC : 0);
222 mask >>= 1;
223 }
224 /* termiate access to codec registers */
225 PCXHR_INPB(mgr, PCXHR_XLX_RUER);
226}
227
228
229static int hr222_set_hw_playback_level(struct pcxhr_mgr *mgr,
230 int idx, int level)
231{
232 unsigned short cmd;
233 if (idx > 1 ||
234 level < 0 ||
235 level >= ARRAY_SIZE(g_hr222_p_level))
236 return -EINVAL;
237
238 if (idx == 0)
239 cmd = AKM_LEFT_LEVEL_CMD;
240 else
241 cmd = AKM_RIGHT_LEVEL_CMD;
242
243 /* conversion from PmBoardCodedLevel to AKM nonlinear programming */
244 cmd += g_hr222_p_level[level];
245
246 hr222_config_akm(mgr, cmd);
247 return 0;
248}
249
250
251static int hr222_set_hw_capture_level(struct pcxhr_mgr *mgr,
252 int level_l, int level_r, int level_mic)
253{
254 /* program all input levels at the same time */
255 unsigned int data;
256 int i;
257
258 if (!mgr->capture_chips)
259 return -EINVAL; /* no PCX22 */
260
261 data = ((level_mic & 0xff) << 24); /* micro is mono, but apply */
262 data |= ((level_mic & 0xff) << 16); /* level on both channels */
263 data |= ((level_r & 0xff) << 8); /* line input right channel */
264 data |= (level_l & 0xff); /* line input left channel */
265
266 PCXHR_INPB(mgr, PCXHR_XLX_DATA); /* activate input codec */
267 /* send 32 bits (4 x 8 bits) */
268 for (i = 0; i < 32; i++, data <<= 1) {
269 PCXHR_OUTPB(mgr, PCXHR_XLX_DATA,
270 (data & 0x80000000) ? PCXHR_DATA_CODEC : 0);
271 }
272 PCXHR_INPB(mgr, PCXHR_XLX_RUER); /* close input level codec */
273 return 0;
274}
275
276static void hr222_micro_boost(struct pcxhr_mgr *mgr, int level);
277
278int hr222_sub_init(struct pcxhr_mgr *mgr)
279{
280 unsigned char reg;
281
282 mgr->board_has_analog = 1; /* analog always available */
283 mgr->xlx_cfg = PCXHR_CFG_SYNCDSP_MASK;
284
285 reg = PCXHR_INPB(mgr, PCXHR_XLX_STATUS);
286 if (reg & PCXHR_STAT_MIC_CAPS)
287 mgr->board_has_mic = 1; /* microphone available */
288 snd_printdd("MIC input available = %d\n", mgr->board_has_mic);
289
290 /* reset codec */
291 PCXHR_OUTPB(mgr, PCXHR_DSP_RESET,
292 PCXHR_DSP_RESET_DSP);
293 msleep(5);
294 PCXHR_OUTPB(mgr, PCXHR_DSP_RESET,
295 PCXHR_DSP_RESET_DSP |
296 PCXHR_DSP_RESET_MUTE |
297 PCXHR_DSP_RESET_CODEC);
298 msleep(5);
299
300 /* config AKM */
301 hr222_config_akm(mgr, AKM_POWER_CONTROL_CMD);
302 hr222_config_akm(mgr, AKM_CLOCK_INF_55K_CMD);
303 hr222_config_akm(mgr, AKM_UNMUTE_CMD);
304 hr222_config_akm(mgr, AKM_RESET_OFF_CMD);
305
306 /* init micro boost */
307 hr222_micro_boost(mgr, 0);
308
309 return 0;
310}
311
312
313/* calc PLL register */
314/* TODO : there is a very similar fct in pcxhr.c */
315static int hr222_pll_freq_register(unsigned int freq,
316 unsigned int *pllreg,
317 unsigned int *realfreq)
318{
319 unsigned int reg;
320
321 if (freq < 6900 || freq > 219000)
322 return -EINVAL;
323 reg = (28224000 * 2) / freq;
324 reg = (reg - 1) / 2;
325 if (reg < 0x100)
326 *pllreg = reg + 0xC00;
327 else if (reg < 0x200)
328 *pllreg = reg + 0x800;
329 else if (reg < 0x400)
330 *pllreg = reg & 0x1ff;
331 else if (reg < 0x800) {
332 *pllreg = ((reg >> 1) & 0x1ff) + 0x200;
333 reg &= ~1;
334 } else {
335 *pllreg = ((reg >> 2) & 0x1ff) + 0x400;
336 reg &= ~3;
337 }
338 if (realfreq)
339 *realfreq = (28224000 / (reg + 1));
340 return 0;
341}
342
343int hr222_sub_set_clock(struct pcxhr_mgr *mgr,
344 unsigned int rate,
345 int *changed)
346{
347 unsigned int speed, pllreg = 0;
348 int err;
349 unsigned realfreq = rate;
350
351 switch (mgr->use_clock_type) {
352 case HR22_CLOCK_TYPE_INTERNAL:
353 err = hr222_pll_freq_register(rate, &pllreg, &realfreq);
354 if (err)
355 return err;
356
357 mgr->xlx_cfg &= ~(PCXHR_CFG_CLOCKIN_SEL_MASK |
358 PCXHR_CFG_CLOCK_UER1_SEL_MASK);
359 break;
360 case HR22_CLOCK_TYPE_AES_SYNC:
361 mgr->xlx_cfg |= PCXHR_CFG_CLOCKIN_SEL_MASK;
362 mgr->xlx_cfg &= ~PCXHR_CFG_CLOCK_UER1_SEL_MASK;
363 break;
364 case HR22_CLOCK_TYPE_AES_1:
365 if (!mgr->board_has_aes1)
366 return -EINVAL;
367
368 mgr->xlx_cfg |= (PCXHR_CFG_CLOCKIN_SEL_MASK |
369 PCXHR_CFG_CLOCK_UER1_SEL_MASK);
370 break;
371 default:
372 return -EINVAL;
373 }
374 hr222_config_akm(mgr, AKM_MUTE_CMD);
375
376 if (mgr->use_clock_type == HR22_CLOCK_TYPE_INTERNAL) {
377 PCXHR_OUTPB(mgr, PCXHR_XLX_HIFREQ, pllreg >> 8);
378 PCXHR_OUTPB(mgr, PCXHR_XLX_LOFREQ, pllreg & 0xff);
379 }
380
381 /* set clock source */
382 PCXHR_OUTPB(mgr, PCXHR_XLX_CFG, mgr->xlx_cfg);
383
384 /* codec speed modes */
385 speed = rate < 55000 ? 0 : 1;
386 if (mgr->codec_speed != speed) {
387 mgr->codec_speed = speed;
388 if (speed == 0)
389 hr222_config_akm(mgr, AKM_CLOCK_INF_55K_CMD);
390 else
391 hr222_config_akm(mgr, AKM_CLOCK_SUP_55K_CMD);
392 }
393
394 mgr->sample_rate_real = realfreq;
395 mgr->cur_clock_type = mgr->use_clock_type;
396
397 if (changed)
398 *changed = 1;
399
400 hr222_config_akm(mgr, AKM_UNMUTE_CMD);
401
402 snd_printdd("set_clock to %dHz (realfreq=%d pllreg=%x)\n",
403 rate, realfreq, pllreg);
404 return 0;
405}
406
407int hr222_get_external_clock(struct pcxhr_mgr *mgr,
408 enum pcxhr_clock_type clock_type,
409 int *sample_rate)
410{
411 int rate, calc_rate = 0;
412 unsigned int ticks;
413 unsigned char mask, reg;
414
415 if (clock_type == HR22_CLOCK_TYPE_AES_SYNC) {
416
417 mask = (PCXHR_SUER_CLOCK_PRESENT_MASK |
418 PCXHR_SUER_DATA_PRESENT_MASK);
419 reg = PCXHR_STAT_FREQ_SYNC_MASK;
420
421 } else if (clock_type == HR22_CLOCK_TYPE_AES_1 && mgr->board_has_aes1) {
422
423 mask = (PCXHR_SUER1_CLOCK_PRESENT_MASK |
424 PCXHR_SUER1_DATA_PRESENT_MASK);
425 reg = PCXHR_STAT_FREQ_UER1_MASK;
426
427 } else {
428 snd_printdd("get_external_clock : type %d not supported\n",
429 clock_type);
430 return -EINVAL; /* other clocks not supported */
431 }
432
433 if ((PCXHR_INPB(mgr, PCXHR_XLX_CSUER) & mask) != mask) {
434 snd_printdd("get_external_clock(%d) = 0 Hz\n", clock_type);
435 *sample_rate = 0;
436 return 0; /* no external clock locked */
437 }
438
439 PCXHR_OUTPB(mgr, PCXHR_XLX_STATUS, reg); /* calculate freq */
440
441 /* save the measured clock frequency */
442 reg |= PCXHR_STAT_FREQ_SAVE_MASK;
443
444 if (mgr->last_reg_stat != reg) {
445 udelay(500); /* wait min 2 cycles of lowest freq (8000) */
446 mgr->last_reg_stat = reg;
447 }
448
449 PCXHR_OUTPB(mgr, PCXHR_XLX_STATUS, reg); /* save */
450
451 /* get the frequency */
452 ticks = (unsigned int)PCXHR_INPB(mgr, PCXHR_XLX_CFG);
453 ticks = (ticks & 0x03) << 8;
454 ticks |= (unsigned int)PCXHR_INPB(mgr, PCXHR_DSP_RESET);
455
456 if (ticks != 0)
457 calc_rate = 28224000 / ticks;
458 /* rounding */
459 if (calc_rate > 184200)
460 rate = 192000;
461 else if (calc_rate > 152200)
462 rate = 176400;
463 else if (calc_rate > 112000)
464 rate = 128000;
465 else if (calc_rate > 92100)
466 rate = 96000;
467 else if (calc_rate > 76100)
468 rate = 88200;
469 else if (calc_rate > 56000)
470 rate = 64000;
471 else if (calc_rate > 46050)
472 rate = 48000;
473 else if (calc_rate > 38050)
474 rate = 44100;
475 else if (calc_rate > 28000)
476 rate = 32000;
477 else if (calc_rate > 23025)
478 rate = 24000;
479 else if (calc_rate > 19025)
480 rate = 22050;
481 else if (calc_rate > 14000)
482 rate = 16000;
483 else if (calc_rate > 11512)
484 rate = 12000;
485 else if (calc_rate > 9512)
486 rate = 11025;
487 else if (calc_rate > 7000)
488 rate = 8000;
489 else
490 rate = 0;
491
492 snd_printdd("External clock is at %d Hz (measured %d Hz)\n",
493 rate, calc_rate);
494 *sample_rate = rate;
495 return 0;
496}
497
498
499int hr222_update_analog_audio_level(struct snd_pcxhr *chip,
500 int is_capture, int channel)
501{
502 snd_printdd("hr222_update_analog_audio_level(%s chan=%d)\n",
503 is_capture ? "capture" : "playback", channel);
504 if (is_capture) {
505 int level_l, level_r, level_mic;
506 /* we have to update all levels */
507 if (chip->analog_capture_active) {
508 level_l = chip->analog_capture_volume[0];
509 level_r = chip->analog_capture_volume[1];
510 } else {
511 level_l = HR222_LINE_CAPTURE_LEVEL_MIN;
512 level_r = HR222_LINE_CAPTURE_LEVEL_MIN;
513 }
514 if (chip->mic_active)
515 level_mic = chip->mic_volume;
516 else
517 level_mic = HR222_MICRO_CAPTURE_LEVEL_MIN;
518 return hr222_set_hw_capture_level(chip->mgr,
519 level_l, level_r, level_mic);
520 } else {
521 int vol;
522 if (chip->analog_playback_active[channel])
523 vol = chip->analog_playback_volume[channel];
524 else
525 vol = HR222_LINE_PLAYBACK_LEVEL_MIN;
526 return hr222_set_hw_playback_level(chip->mgr, channel, vol);
527 }
528}
529
530
531/*texts[5] = {"Line", "Digital", "Digi+SRC", "Mic", "Line+Mic"}*/
532#define SOURCE_LINE 0
533#define SOURCE_DIGITAL 1
534#define SOURCE_DIGISRC 2
535#define SOURCE_MIC 3
536#define SOURCE_LINEMIC 4
537
538int hr222_set_audio_source(struct snd_pcxhr *chip)
539{
540 int digital = 0;
541 /* default analog source */
542 chip->mgr->xlx_cfg &= ~(PCXHR_CFG_SRC_MASK |
543 PCXHR_CFG_DATAIN_SEL_MASK |
544 PCXHR_CFG_DATA_UER1_SEL_MASK);
545
546 if (chip->audio_capture_source == SOURCE_DIGISRC) {
547 chip->mgr->xlx_cfg |= PCXHR_CFG_SRC_MASK;
548 digital = 1;
549 } else {
550 if (chip->audio_capture_source == SOURCE_DIGITAL)
551 digital = 1;
552 }
553 if (digital) {
554 chip->mgr->xlx_cfg |= PCXHR_CFG_DATAIN_SEL_MASK;
555 if (chip->mgr->board_has_aes1) {
556 /* get data from the AES1 plug */
557 chip->mgr->xlx_cfg |= PCXHR_CFG_DATA_UER1_SEL_MASK;
558 }
559 /* chip->mic_active = 0; */
560 /* chip->analog_capture_active = 0; */
561 } else {
562 int update_lvl = 0;
563 chip->analog_capture_active = 0;
564 chip->mic_active = 0;
565 if (chip->audio_capture_source == SOURCE_LINE ||
566 chip->audio_capture_source == SOURCE_LINEMIC) {
567 if (chip->analog_capture_active == 0)
568 update_lvl = 1;
569 chip->analog_capture_active = 1;
570 }
571 if (chip->audio_capture_source == SOURCE_MIC ||
572 chip->audio_capture_source == SOURCE_LINEMIC) {
573 if (chip->mic_active == 0)
574 update_lvl = 1;
575 chip->mic_active = 1;
576 }
577 if (update_lvl) {
578 /* capture: update all 3 mutes/unmutes with one call */
579 hr222_update_analog_audio_level(chip, 1, 0);
580 }
581 }
582 /* set the source infos (max 3 bits modified) */
583 PCXHR_OUTPB(chip->mgr, PCXHR_XLX_CFG, chip->mgr->xlx_cfg);
584 return 0;
585}
586
587
588int hr222_iec958_capture_byte(struct snd_pcxhr *chip,
589 int aes_idx, unsigned char *aes_bits)
590{
591 unsigned char idx = (unsigned char)(aes_idx * 8);
592 unsigned char temp = 0;
593 unsigned char mask = chip->mgr->board_has_aes1 ?
594 PCXHR_SUER1_BIT_C_READ_MASK : PCXHR_SUER_BIT_C_READ_MASK;
595 int i;
596 for (i = 0; i < 8; i++) {
597 PCXHR_OUTPB(chip->mgr, PCXHR_XLX_RUER, idx++); /* idx < 192 */
598 temp <<= 1;
599 if (PCXHR_INPB(chip->mgr, PCXHR_XLX_CSUER) & mask)
600 temp |= 1;
601 }
602 snd_printdd("read iec958 AES %d byte %d = 0x%x\n",
603 chip->chip_idx, aes_idx, temp);
604 *aes_bits = temp;
605 return 0;
606}
607
608
609int hr222_iec958_update_byte(struct snd_pcxhr *chip,
610 int aes_idx, unsigned char aes_bits)
611{
612 int i;
613 unsigned char new_bits = aes_bits;
614 unsigned char old_bits = chip->aes_bits[aes_idx];
615 unsigned char idx = (unsigned char)(aes_idx * 8);
616 for (i = 0; i < 8; i++) {
617 if ((old_bits & 0x01) != (new_bits & 0x01)) {
618 /* idx < 192 */
619 PCXHR_OUTPB(chip->mgr, PCXHR_XLX_RUER, idx);
620 /* write C and U bit */
621 PCXHR_OUTPB(chip->mgr, PCXHR_XLX_CSUER, new_bits&0x01 ?
622 PCXHR_SUER_BIT_C_WRITE_MASK : 0);
623 }
624 idx++;
625 old_bits >>= 1;
626 new_bits >>= 1;
627 }
628 chip->aes_bits[aes_idx] = aes_bits;
629 return 0;
630}
631
632static void hr222_micro_boost(struct pcxhr_mgr *mgr, int level)
633{
634 unsigned char boost_mask;
635 boost_mask = (unsigned char) (level << PCXHR_SELMIC_PREAMPLI_OFFSET);
636 if (boost_mask & (~PCXHR_SELMIC_PREAMPLI_MASK))
637 return; /* only values form 0 to 3 accepted */
638
639 mgr->xlx_selmic &= ~PCXHR_SELMIC_PREAMPLI_MASK;
640 mgr->xlx_selmic |= boost_mask;
641
642 PCXHR_OUTPB(mgr, PCXHR_XLX_SELMIC, mgr->xlx_selmic);
643
644 snd_printdd("hr222_micro_boost : set %x\n", boost_mask);
645}
646
647static void hr222_phantom_power(struct pcxhr_mgr *mgr, int power)
648{
649 if (power)
650 mgr->xlx_selmic |= PCXHR_SELMIC_PHANTOM_ALIM;
651 else
652 mgr->xlx_selmic &= ~PCXHR_SELMIC_PHANTOM_ALIM;
653
654 PCXHR_OUTPB(mgr, PCXHR_XLX_SELMIC, mgr->xlx_selmic);
655
656 snd_printdd("hr222_phantom_power : set %d\n", power);
657}
658
659
660/* mic level */
661static const DECLARE_TLV_DB_SCALE(db_scale_mic_hr222, -9850, 50, 650);
662
663static int hr222_mic_vol_info(struct snd_kcontrol *kcontrol,
664 struct snd_ctl_elem_info *uinfo)
665{
666 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
667 uinfo->count = 1;
668 uinfo->value.integer.min = HR222_MICRO_CAPTURE_LEVEL_MIN; /* -98 dB */
669 /* gains from 9 dB to 31.5 dB not recommended; use micboost instead */
670 uinfo->value.integer.max = HR222_MICRO_CAPTURE_LEVEL_MAX; /* +7 dB */
671 return 0;
672}
673
674static int hr222_mic_vol_get(struct snd_kcontrol *kcontrol,
675 struct snd_ctl_elem_value *ucontrol)
676{
677 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
678 mutex_lock(&chip->mgr->mixer_mutex);
679 ucontrol->value.integer.value[0] = chip->mic_volume;
680 mutex_unlock(&chip->mgr->mixer_mutex);
681 return 0;
682}
683
684static int hr222_mic_vol_put(struct snd_kcontrol *kcontrol,
685 struct snd_ctl_elem_value *ucontrol)
686{
687 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
688 int changed = 0;
689 mutex_lock(&chip->mgr->mixer_mutex);
690 if (chip->mic_volume != ucontrol->value.integer.value[0]) {
691 changed = 1;
692 chip->mic_volume = ucontrol->value.integer.value[0];
693 hr222_update_analog_audio_level(chip, 1, 0);
694 }
695 mutex_unlock(&chip->mgr->mixer_mutex);
696 return changed;
697}
698
699static struct snd_kcontrol_new hr222_control_mic_level = {
700 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
701 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
702 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
703 .name = "Mic Capture Volume",
704 .info = hr222_mic_vol_info,
705 .get = hr222_mic_vol_get,
706 .put = hr222_mic_vol_put,
707 .tlv = { .p = db_scale_mic_hr222 },
708};
709
710
711/* mic boost level */
712static const DECLARE_TLV_DB_SCALE(db_scale_micboost_hr222, 0, 1800, 5400);
713
714static int hr222_mic_boost_info(struct snd_kcontrol *kcontrol,
715 struct snd_ctl_elem_info *uinfo)
716{
717 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
718 uinfo->count = 1;
719 uinfo->value.integer.min = 0; /* 0 dB */
720 uinfo->value.integer.max = 3; /* 54 dB */
721 return 0;
722}
723
724static int hr222_mic_boost_get(struct snd_kcontrol *kcontrol,
725 struct snd_ctl_elem_value *ucontrol)
726{
727 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
728 mutex_lock(&chip->mgr->mixer_mutex);
729 ucontrol->value.integer.value[0] = chip->mic_boost;
730 mutex_unlock(&chip->mgr->mixer_mutex);
731 return 0;
732}
733
734static int hr222_mic_boost_put(struct snd_kcontrol *kcontrol,
735 struct snd_ctl_elem_value *ucontrol)
736{
737 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
738 int changed = 0;
739 mutex_lock(&chip->mgr->mixer_mutex);
740 if (chip->mic_boost != ucontrol->value.integer.value[0]) {
741 changed = 1;
742 chip->mic_boost = ucontrol->value.integer.value[0];
743 hr222_micro_boost(chip->mgr, chip->mic_boost);
744 }
745 mutex_unlock(&chip->mgr->mixer_mutex);
746 return changed;
747}
748
749static struct snd_kcontrol_new hr222_control_mic_boost = {
750 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
751 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
752 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
753 .name = "MicBoost Capture Volume",
754 .info = hr222_mic_boost_info,
755 .get = hr222_mic_boost_get,
756 .put = hr222_mic_boost_put,
757 .tlv = { .p = db_scale_micboost_hr222 },
758};
759
760
761/******************* Phantom power switch *******************/
762#define hr222_phantom_power_info snd_ctl_boolean_mono_info
763
764static int hr222_phantom_power_get(struct snd_kcontrol *kcontrol,
765 struct snd_ctl_elem_value *ucontrol)
766{
767 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
768 mutex_lock(&chip->mgr->mixer_mutex);
769 ucontrol->value.integer.value[0] = chip->phantom_power;
770 mutex_unlock(&chip->mgr->mixer_mutex);
771 return 0;
772}
773
774static int hr222_phantom_power_put(struct snd_kcontrol *kcontrol,
775 struct snd_ctl_elem_value *ucontrol)
776{
777 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
778 int power, changed = 0;
779
780 mutex_lock(&chip->mgr->mixer_mutex);
781 power = !!ucontrol->value.integer.value[0];
782 if (chip->phantom_power != power) {
783 hr222_phantom_power(chip->mgr, power);
784 chip->phantom_power = power;
785 changed = 1;
786 }
787 mutex_unlock(&chip->mgr->mixer_mutex);
788 return changed;
789}
790
791static struct snd_kcontrol_new hr222_phantom_power_switch = {
792 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
793 .name = "Phantom Power Switch",
794 .info = hr222_phantom_power_info,
795 .get = hr222_phantom_power_get,
796 .put = hr222_phantom_power_put,
797};
798
799
800int hr222_add_mic_controls(struct snd_pcxhr *chip)
801{
802 int err;
803 if (!chip->mgr->board_has_mic)
804 return 0;
805
806 /* controls */
807 err = snd_ctl_add(chip->card, snd_ctl_new1(&hr222_control_mic_level,
808 chip));
809 if (err < 0)
810 return err;
811
812 err = snd_ctl_add(chip->card, snd_ctl_new1(&hr222_control_mic_boost,
813 chip));
814 if (err < 0)
815 return err;
816
817 err = snd_ctl_add(chip->card, snd_ctl_new1(&hr222_phantom_power_switch,
818 chip));
819 return err;
820}
diff --git a/sound/pci/pcxhr/pcxhr_mix22.h b/sound/pci/pcxhr/pcxhr_mix22.h
new file mode 100644
index 000000000000..6b318b2f0100
--- /dev/null
+++ b/sound/pci/pcxhr/pcxhr_mix22.h
@@ -0,0 +1,56 @@
1/*
2 * Driver for Digigram pcxhr compatible soundcards
3 *
4 * low level interface with interrupt ans message handling
5 *
6 * Copyright (c) 2004 by Digigram <alsa@digigram.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#ifndef __SOUND_PCXHR_MIX22_H
24#define __SOUND_PCXHR_MIX22_H
25
26struct pcxhr_mgr;
27
28int hr222_sub_init(struct pcxhr_mgr *mgr);
29int hr222_sub_set_clock(struct pcxhr_mgr *mgr, unsigned int rate,
30 int *changed);
31int hr222_get_external_clock(struct pcxhr_mgr *mgr,
32 enum pcxhr_clock_type clock_type,
33 int *sample_rate);
34
35#define HR222_LINE_PLAYBACK_LEVEL_MIN 0 /* -25.5 dB */
36#define HR222_LINE_PLAYBACK_ZERO_LEVEL 51 /* 0.0 dB */
37#define HR222_LINE_PLAYBACK_LEVEL_MAX 99 /* +24.0 dB */
38
39#define HR222_LINE_CAPTURE_LEVEL_MIN 0 /* -111.5 dB */
40#define HR222_LINE_CAPTURE_ZERO_LEVEL 223 /* 0.0 dB */
41#define HR222_LINE_CAPTURE_LEVEL_MAX 255 /* +16 dB */
42#define HR222_MICRO_CAPTURE_LEVEL_MIN 0 /* -98.5 dB */
43#define HR222_MICRO_CAPTURE_LEVEL_MAX 210 /* +6.5 dB */
44
45int hr222_update_analog_audio_level(struct snd_pcxhr *chip,
46 int is_capture,
47 int channel);
48int hr222_set_audio_source(struct snd_pcxhr *chip);
49int hr222_iec958_capture_byte(struct snd_pcxhr *chip, int aes_idx,
50 unsigned char *aes_bits);
51int hr222_iec958_update_byte(struct snd_pcxhr *chip, int aes_idx,
52 unsigned char aes_bits);
53
54int hr222_add_mic_controls(struct snd_pcxhr *chip);
55
56#endif /* __SOUND_PCXHR_MIX22_H */
diff --git a/sound/pci/pcxhr/pcxhr_mixer.c b/sound/pci/pcxhr/pcxhr_mixer.c
index aabc7bc5321e..2436e374586f 100644
--- a/sound/pci/pcxhr/pcxhr_mixer.c
+++ b/sound/pci/pcxhr/pcxhr_mixer.c
@@ -33,20 +33,24 @@
33#include <sound/tlv.h> 33#include <sound/tlv.h>
34#include <sound/asoundef.h> 34#include <sound/asoundef.h>
35#include "pcxhr_mixer.h" 35#include "pcxhr_mixer.h"
36#include "pcxhr_mix22.h"
36 37
38#define PCXHR_LINE_CAPTURE_LEVEL_MIN 0 /* -112.0 dB */
39#define PCXHR_LINE_CAPTURE_LEVEL_MAX 255 /* +15.5 dB */
40#define PCXHR_LINE_CAPTURE_ZERO_LEVEL 224 /* 0.0 dB ( 0 dBu -> 0 dBFS ) */
37 41
38#define PCXHR_ANALOG_CAPTURE_LEVEL_MIN 0 /* -96.0 dB */ 42#define PCXHR_LINE_PLAYBACK_LEVEL_MIN 0 /* -104.0 dB */
39#define PCXHR_ANALOG_CAPTURE_LEVEL_MAX 255 /* +31.5 dB */ 43#define PCXHR_LINE_PLAYBACK_LEVEL_MAX 128 /* +24.0 dB */
40#define PCXHR_ANALOG_CAPTURE_ZERO_LEVEL 224 /* +16.0 dB ( +31.5 dB - fix level +15.5 dB ) */ 44#define PCXHR_LINE_PLAYBACK_ZERO_LEVEL 104 /* 0.0 dB ( 0 dBFS -> 0 dBu ) */
41 45
42#define PCXHR_ANALOG_PLAYBACK_LEVEL_MIN 0 /* -128.0 dB */ 46static const DECLARE_TLV_DB_SCALE(db_scale_analog_capture, -11200, 50, 1550);
43#define PCXHR_ANALOG_PLAYBACK_LEVEL_MAX 128 /* 0.0 dB */
44#define PCXHR_ANALOG_PLAYBACK_ZERO_LEVEL 104 /* -24.0 dB ( 0.0 dB - fix level +24.0 dB ) */
45
46static const DECLARE_TLV_DB_SCALE(db_scale_analog_capture, -9600, 50, 3150);
47static const DECLARE_TLV_DB_SCALE(db_scale_analog_playback, -10400, 100, 2400); 47static const DECLARE_TLV_DB_SCALE(db_scale_analog_playback, -10400, 100, 2400);
48 48
49static int pcxhr_update_analog_audio_level(struct snd_pcxhr *chip, int is_capture, int channel) 49static const DECLARE_TLV_DB_SCALE(db_scale_a_hr222_capture, -11150, 50, 1600);
50static const DECLARE_TLV_DB_SCALE(db_scale_a_hr222_playback, -2550, 50, 2400);
51
52static int pcxhr_update_analog_audio_level(struct snd_pcxhr *chip,
53 int is_capture, int channel)
50{ 54{
51 int err, vol; 55 int err, vol;
52 struct pcxhr_rmh rmh; 56 struct pcxhr_rmh rmh;
@@ -60,15 +64,17 @@ static int pcxhr_update_analog_audio_level(struct snd_pcxhr *chip, int is_captur
60 if (chip->analog_playback_active[channel]) 64 if (chip->analog_playback_active[channel])
61 vol = chip->analog_playback_volume[channel]; 65 vol = chip->analog_playback_volume[channel];
62 else 66 else
63 vol = PCXHR_ANALOG_PLAYBACK_LEVEL_MIN; 67 vol = PCXHR_LINE_PLAYBACK_LEVEL_MIN;
64 rmh.cmd[2] = PCXHR_ANALOG_PLAYBACK_LEVEL_MAX - vol; /* playback analog levels are inversed */ 68 /* playback analog levels are inversed */
69 rmh.cmd[2] = PCXHR_LINE_PLAYBACK_LEVEL_MAX - vol;
65 } 70 }
66 rmh.cmd[1] = 1 << ((2 * chip->chip_idx) + channel); /* audio mask */ 71 rmh.cmd[1] = 1 << ((2 * chip->chip_idx) + channel); /* audio mask */
67 rmh.cmd_len = 3; 72 rmh.cmd_len = 3;
68 err = pcxhr_send_msg(chip->mgr, &rmh); 73 err = pcxhr_send_msg(chip->mgr, &rmh);
69 if (err < 0) { 74 if (err < 0) {
70 snd_printk(KERN_DEBUG "error update_analog_audio_level card(%d) " 75 snd_printk(KERN_DEBUG "error update_analog_audio_level card(%d)"
71 "is_capture(%d) err(%x)\n", chip->chip_idx, is_capture, err); 76 " is_capture(%d) err(%x)\n",
77 chip->chip_idx, is_capture, err);
72 return -EINVAL; 78 return -EINVAL;
73 } 79 }
74 return 0; 80 return 0;
@@ -80,14 +86,34 @@ static int pcxhr_update_analog_audio_level(struct snd_pcxhr *chip, int is_captur
80static int pcxhr_analog_vol_info(struct snd_kcontrol *kcontrol, 86static int pcxhr_analog_vol_info(struct snd_kcontrol *kcontrol,
81 struct snd_ctl_elem_info *uinfo) 87 struct snd_ctl_elem_info *uinfo)
82{ 88{
89 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
90
83 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 91 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
84 uinfo->count = 2; 92 uinfo->count = 2;
85 if (kcontrol->private_value == 0) { /* playback */ 93 if (kcontrol->private_value == 0) { /* playback */
86 uinfo->value.integer.min = PCXHR_ANALOG_PLAYBACK_LEVEL_MIN; /* -128 dB */ 94 if (chip->mgr->is_hr_stereo) {
87 uinfo->value.integer.max = PCXHR_ANALOG_PLAYBACK_LEVEL_MAX; /* 0 dB */ 95 uinfo->value.integer.min =
96 HR222_LINE_PLAYBACK_LEVEL_MIN; /* -25 dB */
97 uinfo->value.integer.max =
98 HR222_LINE_PLAYBACK_LEVEL_MAX; /* +24 dB */
99 } else {
100 uinfo->value.integer.min =
101 PCXHR_LINE_PLAYBACK_LEVEL_MIN; /*-104 dB */
102 uinfo->value.integer.max =
103 PCXHR_LINE_PLAYBACK_LEVEL_MAX; /* +24 dB */
104 }
88 } else { /* capture */ 105 } else { /* capture */
89 uinfo->value.integer.min = PCXHR_ANALOG_CAPTURE_LEVEL_MIN; /* -96 dB */ 106 if (chip->mgr->is_hr_stereo) {
90 uinfo->value.integer.max = PCXHR_ANALOG_CAPTURE_LEVEL_MAX; /* 31.5 dB */ 107 uinfo->value.integer.min =
108 HR222_LINE_CAPTURE_LEVEL_MIN; /*-112 dB */
109 uinfo->value.integer.max =
110 HR222_LINE_CAPTURE_LEVEL_MAX; /* +15.5 dB */
111 } else {
112 uinfo->value.integer.min =
113 PCXHR_LINE_CAPTURE_LEVEL_MIN; /*-112 dB */
114 uinfo->value.integer.max =
115 PCXHR_LINE_CAPTURE_LEVEL_MAX; /* +15.5 dB */
116 }
91 } 117 }
92 return 0; 118 return 0;
93} 119}
@@ -98,11 +124,11 @@ static int pcxhr_analog_vol_get(struct snd_kcontrol *kcontrol,
98 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol); 124 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
99 mutex_lock(&chip->mgr->mixer_mutex); 125 mutex_lock(&chip->mgr->mixer_mutex);
100 if (kcontrol->private_value == 0) { /* playback */ 126 if (kcontrol->private_value == 0) { /* playback */
101 ucontrol->value.integer.value[0] = chip->analog_playback_volume[0]; 127 ucontrol->value.integer.value[0] = chip->analog_playback_volume[0];
102 ucontrol->value.integer.value[1] = chip->analog_playback_volume[1]; 128 ucontrol->value.integer.value[1] = chip->analog_playback_volume[1];
103 } else { /* capture */ 129 } else { /* capture */
104 ucontrol->value.integer.value[0] = chip->analog_capture_volume[0]; 130 ucontrol->value.integer.value[0] = chip->analog_capture_volume[0];
105 ucontrol->value.integer.value[1] = chip->analog_capture_volume[1]; 131 ucontrol->value.integer.value[1] = chip->analog_capture_volume[1];
106 } 132 }
107 mutex_unlock(&chip->mgr->mixer_mutex); 133 mutex_unlock(&chip->mgr->mixer_mutex);
108 return 0; 134 return 0;
@@ -123,18 +149,35 @@ static int pcxhr_analog_vol_put(struct snd_kcontrol *kcontrol,
123 &chip->analog_capture_volume[i] : 149 &chip->analog_capture_volume[i] :
124 &chip->analog_playback_volume[i]; 150 &chip->analog_playback_volume[i];
125 if (is_capture) { 151 if (is_capture) {
126 if (new_volume < PCXHR_ANALOG_CAPTURE_LEVEL_MIN || 152 if (chip->mgr->is_hr_stereo) {
127 new_volume > PCXHR_ANALOG_CAPTURE_LEVEL_MAX) 153 if (new_volume < HR222_LINE_CAPTURE_LEVEL_MIN ||
128 continue; 154 new_volume > HR222_LINE_CAPTURE_LEVEL_MAX)
155 continue;
156 } else {
157 if (new_volume < PCXHR_LINE_CAPTURE_LEVEL_MIN ||
158 new_volume > PCXHR_LINE_CAPTURE_LEVEL_MAX)
159 continue;
160 }
129 } else { 161 } else {
130 if (new_volume < PCXHR_ANALOG_PLAYBACK_LEVEL_MIN || 162 if (chip->mgr->is_hr_stereo) {
131 new_volume > PCXHR_ANALOG_PLAYBACK_LEVEL_MAX) 163 if (new_volume < HR222_LINE_PLAYBACK_LEVEL_MIN ||
132 continue; 164 new_volume > HR222_LINE_PLAYBACK_LEVEL_MAX)
165 continue;
166 } else {
167 if (new_volume < PCXHR_LINE_PLAYBACK_LEVEL_MIN ||
168 new_volume > PCXHR_LINE_PLAYBACK_LEVEL_MAX)
169 continue;
170 }
133 } 171 }
134 if (*stored_volume != new_volume) { 172 if (*stored_volume != new_volume) {
135 *stored_volume = new_volume; 173 *stored_volume = new_volume;
136 changed = 1; 174 changed = 1;
137 pcxhr_update_analog_audio_level(chip, is_capture, i); 175 if (chip->mgr->is_hr_stereo)
176 hr222_update_analog_audio_level(chip,
177 is_capture, i);
178 else
179 pcxhr_update_analog_audio_level(chip,
180 is_capture, i);
138 } 181 }
139 } 182 }
140 mutex_unlock(&chip->mgr->mixer_mutex); 183 mutex_unlock(&chip->mgr->mixer_mutex);
@@ -153,6 +196,7 @@ static struct snd_kcontrol_new pcxhr_control_analog_level = {
153}; 196};
154 197
155/* shared */ 198/* shared */
199
156#define pcxhr_sw_info snd_ctl_boolean_stereo_info 200#define pcxhr_sw_info snd_ctl_boolean_stereo_info
157 201
158static int pcxhr_audio_sw_get(struct snd_kcontrol *kcontrol, 202static int pcxhr_audio_sw_get(struct snd_kcontrol *kcontrol,
@@ -180,7 +224,10 @@ static int pcxhr_audio_sw_put(struct snd_kcontrol *kcontrol,
180 !!ucontrol->value.integer.value[i]; 224 !!ucontrol->value.integer.value[i];
181 changed = 1; 225 changed = 1;
182 /* update playback levels */ 226 /* update playback levels */
183 pcxhr_update_analog_audio_level(chip, 0, i); 227 if (chip->mgr->is_hr_stereo)
228 hr222_update_analog_audio_level(chip, 0, i);
229 else
230 pcxhr_update_analog_audio_level(chip, 0, i);
184 } 231 }
185 } 232 }
186 mutex_unlock(&chip->mgr->mixer_mutex); 233 mutex_unlock(&chip->mgr->mixer_mutex);
@@ -251,7 +298,8 @@ static int pcxhr_update_playback_stream_level(struct snd_pcxhr* chip, int idx)
251#define VALID_AUDIO_IO_MUTE_LEVEL 0x000004 298#define VALID_AUDIO_IO_MUTE_LEVEL 0x000004
252#define VALID_AUDIO_IO_MUTE_MONITOR_1 0x000008 299#define VALID_AUDIO_IO_MUTE_MONITOR_1 0x000008
253 300
254static int pcxhr_update_audio_pipe_level(struct snd_pcxhr* chip, int capture, int channel) 301static int pcxhr_update_audio_pipe_level(struct snd_pcxhr *chip,
302 int capture, int channel)
255{ 303{
256 int err; 304 int err;
257 struct pcxhr_rmh rmh; 305 struct pcxhr_rmh rmh;
@@ -264,18 +312,20 @@ static int pcxhr_update_audio_pipe_level(struct snd_pcxhr* chip, int capture, in
264 312
265 pcxhr_init_rmh(&rmh, CMD_AUDIO_LEVEL_ADJUST); 313 pcxhr_init_rmh(&rmh, CMD_AUDIO_LEVEL_ADJUST);
266 /* add channel mask */ 314 /* add channel mask */
267 pcxhr_set_pipe_cmd_params(&rmh, capture, 0, 0, 1 << (channel + pipe->first_audio)); 315 pcxhr_set_pipe_cmd_params(&rmh, capture, 0, 0,
268 /* TODO : if mask (3 << pipe->first_audio) is used, left and right channel 316 1 << (channel + pipe->first_audio));
269 * will be programmed to the same params 317 /* TODO : if mask (3 << pipe->first_audio) is used, left and right
270 */ 318 * channel will be programmed to the same params */
271 if (capture) { 319 if (capture) {
272 rmh.cmd[0] |= VALID_AUDIO_IO_DIGITAL_LEVEL; 320 rmh.cmd[0] |= VALID_AUDIO_IO_DIGITAL_LEVEL;
273 /* VALID_AUDIO_IO_MUTE_LEVEL not yet handled (capture pipe level) */ 321 /* VALID_AUDIO_IO_MUTE_LEVEL not yet handled
322 * (capture pipe level) */
274 rmh.cmd[2] = chip->digital_capture_volume[channel]; 323 rmh.cmd[2] = chip->digital_capture_volume[channel];
275 } else { 324 } else {
276 rmh.cmd[0] |= VALID_AUDIO_IO_MONITOR_LEVEL | VALID_AUDIO_IO_MUTE_MONITOR_1; 325 rmh.cmd[0] |= VALID_AUDIO_IO_MONITOR_LEVEL |
277 /* VALID_AUDIO_IO_DIGITAL_LEVEL and VALID_AUDIO_IO_MUTE_LEVEL not yet 326 VALID_AUDIO_IO_MUTE_MONITOR_1;
278 * handled (playback pipe level) 327 /* VALID_AUDIO_IO_DIGITAL_LEVEL and VALID_AUDIO_IO_MUTE_LEVEL
328 * not yet handled (playback pipe level)
279 */ 329 */
280 rmh.cmd[2] = chip->monitoring_volume[channel] << 10; 330 rmh.cmd[2] = chip->monitoring_volume[channel] << 10;
281 if (chip->monitoring_active[channel] == 0) 331 if (chip->monitoring_active[channel] == 0)
@@ -284,8 +334,8 @@ static int pcxhr_update_audio_pipe_level(struct snd_pcxhr* chip, int capture, in
284 rmh.cmd_len = 3; 334 rmh.cmd_len = 3;
285 335
286 err = pcxhr_send_msg(chip->mgr, &rmh); 336 err = pcxhr_send_msg(chip->mgr, &rmh);
287 if(err<0) { 337 if (err < 0) {
288 snd_printk(KERN_DEBUG "error update_audio_level card(%d) err(%x)\n", 338 snd_printk(KERN_DEBUG "error update_audio_level(%d) err=%x\n",
289 chip->chip_idx, err); 339 chip->chip_idx, err);
290 return -EINVAL; 340 return -EINVAL;
291 } 341 }
@@ -309,15 +359,15 @@ static int pcxhr_pcm_vol_get(struct snd_kcontrol *kcontrol,
309 struct snd_ctl_elem_value *ucontrol) 359 struct snd_ctl_elem_value *ucontrol)
310{ 360{
311 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol); 361 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
312 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */ 362 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */
313 int *stored_volume; 363 int *stored_volume;
314 int is_capture = kcontrol->private_value; 364 int is_capture = kcontrol->private_value;
315 365
316 mutex_lock(&chip->mgr->mixer_mutex); 366 mutex_lock(&chip->mgr->mixer_mutex);
317 if (is_capture) 367 if (is_capture) /* digital capture */
318 stored_volume = chip->digital_capture_volume; /* digital capture */ 368 stored_volume = chip->digital_capture_volume;
319 else 369 else /* digital playback */
320 stored_volume = chip->digital_playback_volume[idx]; /* digital playback */ 370 stored_volume = chip->digital_playback_volume[idx];
321 ucontrol->value.integer.value[0] = stored_volume[0]; 371 ucontrol->value.integer.value[0] = stored_volume[0];
322 ucontrol->value.integer.value[1] = stored_volume[1]; 372 ucontrol->value.integer.value[1] = stored_volume[1];
323 mutex_unlock(&chip->mgr->mixer_mutex); 373 mutex_unlock(&chip->mgr->mixer_mutex);
@@ -328,7 +378,7 @@ static int pcxhr_pcm_vol_put(struct snd_kcontrol *kcontrol,
328 struct snd_ctl_elem_value *ucontrol) 378 struct snd_ctl_elem_value *ucontrol)
329{ 379{
330 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol); 380 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
331 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */ 381 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */
332 int changed = 0; 382 int changed = 0;
333 int is_capture = kcontrol->private_value; 383 int is_capture = kcontrol->private_value;
334 int *stored_volume; 384 int *stored_volume;
@@ -384,7 +434,8 @@ static int pcxhr_pcm_sw_get(struct snd_kcontrol *kcontrol,
384 return 0; 434 return 0;
385} 435}
386 436
387static int pcxhr_pcm_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 437static int pcxhr_pcm_sw_put(struct snd_kcontrol *kcontrol,
438 struct snd_ctl_elem_value *ucontrol)
388{ 439{
389 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol); 440 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
390 int changed = 0; 441 int changed = 0;
@@ -444,8 +495,8 @@ static int pcxhr_monitor_vol_put(struct snd_kcontrol *kcontrol,
444 if (chip->monitoring_volume[i] != 495 if (chip->monitoring_volume[i] !=
445 ucontrol->value.integer.value[i]) { 496 ucontrol->value.integer.value[i]) {
446 chip->monitoring_volume[i] = 497 chip->monitoring_volume[i] =
447 !!ucontrol->value.integer.value[i]; 498 ucontrol->value.integer.value[i];
448 if(chip->monitoring_active[i]) 499 if (chip->monitoring_active[i])
449 /* update monitoring volume and mute */ 500 /* update monitoring volume and mute */
450 /* do only when monitoring is unmuted */ 501 /* do only when monitoring is unmuted */
451 pcxhr_update_audio_pipe_level(chip, 0, i); 502 pcxhr_update_audio_pipe_level(chip, 0, i);
@@ -460,7 +511,7 @@ static struct snd_kcontrol_new pcxhr_control_monitor_vol = {
460 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 511 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
461 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 512 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
462 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 513 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
463 .name = "Monitoring Volume", 514 .name = "Monitoring Playback Volume",
464 .info = pcxhr_digital_vol_info, /* shared */ 515 .info = pcxhr_digital_vol_info, /* shared */
465 .get = pcxhr_monitor_vol_get, 516 .get = pcxhr_monitor_vol_get,
466 .put = pcxhr_monitor_vol_put, 517 .put = pcxhr_monitor_vol_put,
@@ -511,7 +562,7 @@ static int pcxhr_monitor_sw_put(struct snd_kcontrol *kcontrol,
511 562
512static struct snd_kcontrol_new pcxhr_control_monitor_sw = { 563static struct snd_kcontrol_new pcxhr_control_monitor_sw = {
513 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 564 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
514 .name = "Monitoring Switch", 565 .name = "Monitoring Playback Switch",
515 .info = pcxhr_sw_info, /* shared */ 566 .info = pcxhr_sw_info, /* shared */
516 .get = pcxhr_monitor_sw_get, 567 .get = pcxhr_monitor_sw_get,
517 .put = pcxhr_monitor_sw_put 568 .put = pcxhr_monitor_sw_put
@@ -533,7 +584,7 @@ static int pcxhr_set_audio_source(struct snd_pcxhr* chip)
533 struct pcxhr_rmh rmh; 584 struct pcxhr_rmh rmh;
534 unsigned int mask, reg; 585 unsigned int mask, reg;
535 unsigned int codec; 586 unsigned int codec;
536 int err, use_src, changed; 587 int err, changed;
537 588
538 switch (chip->chip_idx) { 589 switch (chip->chip_idx) {
539 case 0 : mask = PCXHR_SOURCE_AUDIO01_UER; codec = CS8420_01_CS; break; 590 case 0 : mask = PCXHR_SOURCE_AUDIO01_UER; codec = CS8420_01_CS; break;
@@ -542,13 +593,10 @@ static int pcxhr_set_audio_source(struct snd_pcxhr* chip)
542 case 3 : mask = PCXHR_SOURCE_AUDIO67_UER; codec = CS8420_67_CS; break; 593 case 3 : mask = PCXHR_SOURCE_AUDIO67_UER; codec = CS8420_67_CS; break;
543 default: return -EINVAL; 594 default: return -EINVAL;
544 } 595 }
545 reg = 0; /* audio source from analog plug */
546 use_src = 0; /* do not activate codec SRC */
547
548 if (chip->audio_capture_source != 0) { 596 if (chip->audio_capture_source != 0) {
549 reg = mask; /* audio source from digital plug */ 597 reg = mask; /* audio source from digital plug */
550 if (chip->audio_capture_source == 2) 598 } else {
551 use_src = 1; 599 reg = 0; /* audio source from analog plug */
552 } 600 }
553 /* set the input source */ 601 /* set the input source */
554 pcxhr_write_io_num_reg_cont(chip->mgr, mask, reg, &changed); 602 pcxhr_write_io_num_reg_cont(chip->mgr, mask, reg, &changed);
@@ -560,29 +608,61 @@ static int pcxhr_set_audio_source(struct snd_pcxhr* chip)
560 if (err) 608 if (err)
561 return err; 609 return err;
562 } 610 }
563 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE); /* set codec SRC on off */ 611 if (chip->mgr->board_aes_in_192k) {
564 rmh.cmd_len = 3; 612 int i;
565 rmh.cmd[0] |= IO_NUM_UER_CHIP_REG; 613 unsigned int src_config = 0xC0;
566 rmh.cmd[1] = codec; 614 /* update all src configs with one call */
567 rmh.cmd[2] = (CS8420_DATA_FLOW_CTL & CHIP_SIG_AND_MAP_SPI) | (use_src ? 0x41 : 0x54); 615 for (i = 0; (i < 4) && (i < chip->mgr->capture_chips); i++) {
568 err = pcxhr_send_msg(chip->mgr, &rmh); 616 if (chip->mgr->chip[i]->audio_capture_source == 2)
569 if(err) 617 src_config |= (1 << (3 - i));
570 return err; 618 }
571 rmh.cmd[2] = (CS8420_CLOCK_SRC_CTL & CHIP_SIG_AND_MAP_SPI) | (use_src ? 0x41 : 0x49); 619 /* set codec SRC on off */
572 err = pcxhr_send_msg(chip->mgr, &rmh); 620 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE);
621 rmh.cmd_len = 2;
622 rmh.cmd[0] |= IO_NUM_REG_CONFIG_SRC;
623 rmh.cmd[1] = src_config;
624 err = pcxhr_send_msg(chip->mgr, &rmh);
625 } else {
626 int use_src = 0;
627 if (chip->audio_capture_source == 2)
628 use_src = 1;
629 /* set codec SRC on off */
630 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE);
631 rmh.cmd_len = 3;
632 rmh.cmd[0] |= IO_NUM_UER_CHIP_REG;
633 rmh.cmd[1] = codec;
634 rmh.cmd[2] = ((CS8420_DATA_FLOW_CTL & CHIP_SIG_AND_MAP_SPI) |
635 (use_src ? 0x41 : 0x54));
636 err = pcxhr_send_msg(chip->mgr, &rmh);
637 if (err)
638 return err;
639 rmh.cmd[2] = ((CS8420_CLOCK_SRC_CTL & CHIP_SIG_AND_MAP_SPI) |
640 (use_src ? 0x41 : 0x49));
641 err = pcxhr_send_msg(chip->mgr, &rmh);
642 }
573 return err; 643 return err;
574} 644}
575 645
576static int pcxhr_audio_src_info(struct snd_kcontrol *kcontrol, 646static int pcxhr_audio_src_info(struct snd_kcontrol *kcontrol,
577 struct snd_ctl_elem_info *uinfo) 647 struct snd_ctl_elem_info *uinfo)
578{ 648{
579 static char *texts[3] = {"Analog", "Digital", "Digi+SRC"}; 649 static const char *texts[5] = {
650 "Line", "Digital", "Digi+SRC", "Mic", "Line+Mic"
651 };
652 int i;
653 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
580 654
655 i = 2; /* no SRC, no Mic available */
656 if (chip->mgr->board_has_aes1) {
657 i = 3; /* SRC available */
658 if (chip->mgr->board_has_mic)
659 i = 5; /* Mic and MicroMix available */
660 }
581 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 661 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
582 uinfo->count = 1; 662 uinfo->count = 1;
583 uinfo->value.enumerated.items = 3; 663 uinfo->value.enumerated.items = i;
584 if (uinfo->value.enumerated.item > 2) 664 if (uinfo->value.enumerated.item > (i-1))
585 uinfo->value.enumerated.item = 2; 665 uinfo->value.enumerated.item = i-1;
586 strcpy(uinfo->value.enumerated.name, 666 strcpy(uinfo->value.enumerated.name,
587 texts[uinfo->value.enumerated.item]); 667 texts[uinfo->value.enumerated.item]);
588 return 0; 668 return 0;
@@ -601,13 +681,21 @@ static int pcxhr_audio_src_put(struct snd_kcontrol *kcontrol,
601{ 681{
602 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol); 682 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
603 int ret = 0; 683 int ret = 0;
604 684 int i = 2; /* no SRC, no Mic available */
605 if (ucontrol->value.enumerated.item[0] >= 3) 685 if (chip->mgr->board_has_aes1) {
686 i = 3; /* SRC available */
687 if (chip->mgr->board_has_mic)
688 i = 5; /* Mic and MicroMix available */
689 }
690 if (ucontrol->value.enumerated.item[0] >= i)
606 return -EINVAL; 691 return -EINVAL;
607 mutex_lock(&chip->mgr->mixer_mutex); 692 mutex_lock(&chip->mgr->mixer_mutex);
608 if (chip->audio_capture_source != ucontrol->value.enumerated.item[0]) { 693 if (chip->audio_capture_source != ucontrol->value.enumerated.item[0]) {
609 chip->audio_capture_source = ucontrol->value.enumerated.item[0]; 694 chip->audio_capture_source = ucontrol->value.enumerated.item[0];
610 pcxhr_set_audio_source(chip); 695 if (chip->mgr->is_hr_stereo)
696 hr222_set_audio_source(chip);
697 else
698 pcxhr_set_audio_source(chip);
611 ret = 1; 699 ret = 1;
612 } 700 }
613 mutex_unlock(&chip->mgr->mixer_mutex); 701 mutex_unlock(&chip->mgr->mixer_mutex);
@@ -626,25 +714,46 @@ static struct snd_kcontrol_new pcxhr_control_audio_src = {
626/* 714/*
627 * clock type selection 715 * clock type selection
628 * enum pcxhr_clock_type { 716 * enum pcxhr_clock_type {
629 * PCXHR_CLOCK_TYPE_INTERNAL = 0, 717 * PCXHR_CLOCK_TYPE_INTERNAL = 0,
630 * PCXHR_CLOCK_TYPE_WORD_CLOCK, 718 * PCXHR_CLOCK_TYPE_WORD_CLOCK,
631 * PCXHR_CLOCK_TYPE_AES_SYNC, 719 * PCXHR_CLOCK_TYPE_AES_SYNC,
632 * PCXHR_CLOCK_TYPE_AES_1, 720 * PCXHR_CLOCK_TYPE_AES_1,
633 * PCXHR_CLOCK_TYPE_AES_2, 721 * PCXHR_CLOCK_TYPE_AES_2,
634 * PCXHR_CLOCK_TYPE_AES_3, 722 * PCXHR_CLOCK_TYPE_AES_3,
635 * PCXHR_CLOCK_TYPE_AES_4, 723 * PCXHR_CLOCK_TYPE_AES_4,
636 * }; 724 * PCXHR_CLOCK_TYPE_MAX = PCXHR_CLOCK_TYPE_AES_4,
725 * HR22_CLOCK_TYPE_INTERNAL = PCXHR_CLOCK_TYPE_INTERNAL,
726 * HR22_CLOCK_TYPE_AES_SYNC,
727 * HR22_CLOCK_TYPE_AES_1,
728 * HR22_CLOCK_TYPE_MAX = HR22_CLOCK_TYPE_AES_1,
729 * };
637 */ 730 */
638 731
639static int pcxhr_clock_type_info(struct snd_kcontrol *kcontrol, 732static int pcxhr_clock_type_info(struct snd_kcontrol *kcontrol,
640 struct snd_ctl_elem_info *uinfo) 733 struct snd_ctl_elem_info *uinfo)
641{ 734{
642 static char *texts[7] = { 735 static const char *textsPCXHR[7] = {
643 "Internal", "WordClock", "AES Sync", "AES 1", "AES 2", "AES 3", "AES 4" 736 "Internal", "WordClock", "AES Sync",
737 "AES 1", "AES 2", "AES 3", "AES 4"
738 };
739 static const char *textsHR22[3] = {
740 "Internal", "AES Sync", "AES 1"
644 }; 741 };
742 const char **texts;
645 struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol); 743 struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol);
646 int clock_items = 3 + mgr->capture_chips; 744 int clock_items = 2; /* at least Internal and AES Sync clock */
647 745 if (mgr->board_has_aes1) {
746 clock_items += mgr->capture_chips; /* add AES x */
747 if (!mgr->is_hr_stereo)
748 clock_items += 1; /* add word clock */
749 }
750 if (mgr->is_hr_stereo) {
751 texts = textsHR22;
752 snd_BUG_ON(clock_items > (HR22_CLOCK_TYPE_MAX+1));
753 } else {
754 texts = textsPCXHR;
755 snd_BUG_ON(clock_items > (PCXHR_CLOCK_TYPE_MAX+1));
756 }
648 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 757 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
649 uinfo->count = 1; 758 uinfo->count = 1;
650 uinfo->value.enumerated.items = clock_items; 759 uinfo->value.enumerated.items = clock_items;
@@ -667,9 +776,13 @@ static int pcxhr_clock_type_put(struct snd_kcontrol *kcontrol,
667 struct snd_ctl_elem_value *ucontrol) 776 struct snd_ctl_elem_value *ucontrol)
668{ 777{
669 struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol); 778 struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol);
670 unsigned int clock_items = 3 + mgr->capture_chips;
671 int rate, ret = 0; 779 int rate, ret = 0;
672 780 unsigned int clock_items = 2; /* at least Internal and AES Sync clock */
781 if (mgr->board_has_aes1) {
782 clock_items += mgr->capture_chips; /* add AES x */
783 if (!mgr->is_hr_stereo)
784 clock_items += 1; /* add word clock */
785 }
673 if (ucontrol->value.enumerated.item[0] >= clock_items) 786 if (ucontrol->value.enumerated.item[0] >= clock_items)
674 return -EINVAL; 787 return -EINVAL;
675 mutex_lock(&mgr->mixer_mutex); 788 mutex_lock(&mgr->mixer_mutex);
@@ -677,7 +790,8 @@ static int pcxhr_clock_type_put(struct snd_kcontrol *kcontrol,
677 mutex_lock(&mgr->setup_mutex); 790 mutex_lock(&mgr->setup_mutex);
678 mgr->use_clock_type = ucontrol->value.enumerated.item[0]; 791 mgr->use_clock_type = ucontrol->value.enumerated.item[0];
679 if (mgr->use_clock_type) 792 if (mgr->use_clock_type)
680 pcxhr_get_external_clock(mgr, mgr->use_clock_type, &rate); 793 pcxhr_get_external_clock(mgr, mgr->use_clock_type,
794 &rate);
681 else 795 else
682 rate = mgr->sample_rate; 796 rate = mgr->sample_rate;
683 if (rate) { 797 if (rate) {
@@ -686,7 +800,7 @@ static int pcxhr_clock_type_put(struct snd_kcontrol *kcontrol,
686 mgr->sample_rate = rate; 800 mgr->sample_rate = rate;
687 } 801 }
688 mutex_unlock(&mgr->setup_mutex); 802 mutex_unlock(&mgr->setup_mutex);
689 ret = 1; /* return 1 even if the set was not done. ok ? */ 803 ret = 1; /* return 1 even if the set was not done. ok ? */
690 } 804 }
691 mutex_unlock(&mgr->mixer_mutex); 805 mutex_unlock(&mgr->mixer_mutex);
692 return ret; 806 return ret;
@@ -747,14 +861,16 @@ static struct snd_kcontrol_new pcxhr_control_clock_rate = {
747/* 861/*
748 * IEC958 status bits 862 * IEC958 status bits
749 */ 863 */
750static int pcxhr_iec958_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 864static int pcxhr_iec958_info(struct snd_kcontrol *kcontrol,
865 struct snd_ctl_elem_info *uinfo)
751{ 866{
752 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; 867 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
753 uinfo->count = 1; 868 uinfo->count = 1;
754 return 0; 869 return 0;
755} 870}
756 871
757static int pcxhr_iec958_capture_byte(struct snd_pcxhr *chip, int aes_idx, unsigned char* aes_bits) 872static int pcxhr_iec958_capture_byte(struct snd_pcxhr *chip,
873 int aes_idx, unsigned char *aes_bits)
758{ 874{
759 int i, err; 875 int i, err;
760 unsigned char temp; 876 unsigned char temp;
@@ -763,39 +879,61 @@ static int pcxhr_iec958_capture_byte(struct snd_pcxhr *chip, int aes_idx, unsign
763 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ); 879 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ);
764 rmh.cmd[0] |= IO_NUM_UER_CHIP_REG; 880 rmh.cmd[0] |= IO_NUM_UER_CHIP_REG;
765 switch (chip->chip_idx) { 881 switch (chip->chip_idx) {
766 case 0: rmh.cmd[1] = CS8420_01_CS; break; /* use CS8416_01_CS for AES SYNC plug */ 882 /* instead of CS8420_01_CS use CS8416_01_CS for AES SYNC plug */
883 case 0: rmh.cmd[1] = CS8420_01_CS; break;
767 case 1: rmh.cmd[1] = CS8420_23_CS; break; 884 case 1: rmh.cmd[1] = CS8420_23_CS; break;
768 case 2: rmh.cmd[1] = CS8420_45_CS; break; 885 case 2: rmh.cmd[1] = CS8420_45_CS; break;
769 case 3: rmh.cmd[1] = CS8420_67_CS; break; 886 case 3: rmh.cmd[1] = CS8420_67_CS; break;
770 default: return -EINVAL; 887 default: return -EINVAL;
771 } 888 }
772 switch (aes_idx) { 889 if (chip->mgr->board_aes_in_192k) {
773 case 0: rmh.cmd[2] = CS8420_CSB0; break; /* use CS8416_CSBx for AES SYNC plug */ 890 switch (aes_idx) {
774 case 1: rmh.cmd[2] = CS8420_CSB1; break; 891 case 0: rmh.cmd[2] = CS8416_CSB0; break;
775 case 2: rmh.cmd[2] = CS8420_CSB2; break; 892 case 1: rmh.cmd[2] = CS8416_CSB1; break;
776 case 3: rmh.cmd[2] = CS8420_CSB3; break; 893 case 2: rmh.cmd[2] = CS8416_CSB2; break;
777 case 4: rmh.cmd[2] = CS8420_CSB4; break; 894 case 3: rmh.cmd[2] = CS8416_CSB3; break;
778 default: return -EINVAL; 895 case 4: rmh.cmd[2] = CS8416_CSB4; break;
896 default: return -EINVAL;
897 }
898 } else {
899 switch (aes_idx) {
900 /* instead of CS8420_CSB0 use CS8416_CSBx for AES SYNC plug */
901 case 0: rmh.cmd[2] = CS8420_CSB0; break;
902 case 1: rmh.cmd[2] = CS8420_CSB1; break;
903 case 2: rmh.cmd[2] = CS8420_CSB2; break;
904 case 3: rmh.cmd[2] = CS8420_CSB3; break;
905 case 4: rmh.cmd[2] = CS8420_CSB4; break;
906 default: return -EINVAL;
907 }
779 } 908 }
780 rmh.cmd[1] &= 0x0fffff; /* size and code the chip id for the fpga */ 909 /* size and code the chip id for the fpga */
781 rmh.cmd[2] &= CHIP_SIG_AND_MAP_SPI; /* chip signature + map for spi read */ 910 rmh.cmd[1] &= 0x0fffff;
911 /* chip signature + map for spi read */
912 rmh.cmd[2] &= CHIP_SIG_AND_MAP_SPI;
782 rmh.cmd_len = 3; 913 rmh.cmd_len = 3;
783 err = pcxhr_send_msg(chip->mgr, &rmh); 914 err = pcxhr_send_msg(chip->mgr, &rmh);
784 if (err) 915 if (err)
785 return err; 916 return err;
786 temp = 0; 917
787 for (i = 0; i < 8; i++) { 918 if (chip->mgr->board_aes_in_192k) {
788 /* attention : reversed bit order (not with CS8416_01_CS) */ 919 temp = (unsigned char)rmh.stat[1];
789 temp <<= 1; 920 } else {
790 if (rmh.stat[1] & (1 << i)) 921 temp = 0;
791 temp |= 1; 922 /* reversed bit order (not with CS8416_01_CS) */
923 for (i = 0; i < 8; i++) {
924 temp <<= 1;
925 if (rmh.stat[1] & (1 << i))
926 temp |= 1;
927 }
792 } 928 }
793 snd_printdd("read iec958 AES %d byte %d = 0x%x\n", chip->chip_idx, aes_idx, temp); 929 snd_printdd("read iec958 AES %d byte %d = 0x%x\n",
930 chip->chip_idx, aes_idx, temp);
794 *aes_bits = temp; 931 *aes_bits = temp;
795 return 0; 932 return 0;
796} 933}
797 934
798static int pcxhr_iec958_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 935static int pcxhr_iec958_get(struct snd_kcontrol *kcontrol,
936 struct snd_ctl_elem_value *ucontrol)
799{ 937{
800 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol); 938 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
801 unsigned char aes_bits; 939 unsigned char aes_bits;
@@ -806,7 +944,12 @@ static int pcxhr_iec958_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v
806 if (kcontrol->private_value == 0) /* playback */ 944 if (kcontrol->private_value == 0) /* playback */
807 aes_bits = chip->aes_bits[i]; 945 aes_bits = chip->aes_bits[i];
808 else { /* capture */ 946 else { /* capture */
809 err = pcxhr_iec958_capture_byte(chip, i, &aes_bits); 947 if (chip->mgr->is_hr_stereo)
948 err = hr222_iec958_capture_byte(chip, i,
949 &aes_bits);
950 else
951 err = pcxhr_iec958_capture_byte(chip, i,
952 &aes_bits);
810 if (err) 953 if (err)
811 break; 954 break;
812 } 955 }
@@ -825,7 +968,8 @@ static int pcxhr_iec958_mask_get(struct snd_kcontrol *kcontrol,
825 return 0; 968 return 0;
826} 969}
827 970
828static int pcxhr_iec958_update_byte(struct snd_pcxhr *chip, int aes_idx, unsigned char aes_bits) 971static int pcxhr_iec958_update_byte(struct snd_pcxhr *chip,
972 int aes_idx, unsigned char aes_bits)
829{ 973{
830 int i, err, cmd; 974 int i, err, cmd;
831 unsigned char new_bits = aes_bits; 975 unsigned char new_bits = aes_bits;
@@ -834,12 +978,12 @@ static int pcxhr_iec958_update_byte(struct snd_pcxhr *chip, int aes_idx, unsigne
834 978
835 for (i = 0; i < 8; i++) { 979 for (i = 0; i < 8; i++) {
836 if ((old_bits & 0x01) != (new_bits & 0x01)) { 980 if ((old_bits & 0x01) != (new_bits & 0x01)) {
837 cmd = chip->chip_idx & 0x03; /* chip index 0..3 */ 981 cmd = chip->chip_idx & 0x03; /* chip index 0..3 */
838 if(chip->chip_idx > 3) 982 if (chip->chip_idx > 3)
839 /* new bit used if chip_idx>3 (PCX1222HR) */ 983 /* new bit used if chip_idx>3 (PCX1222HR) */
840 cmd |= 1 << 22; 984 cmd |= 1 << 22;
841 cmd |= ((aes_idx << 3) + i) << 2; /* add bit offset */ 985 cmd |= ((aes_idx << 3) + i) << 2; /* add bit offset */
842 cmd |= (new_bits & 0x01) << 23; /* add bit value */ 986 cmd |= (new_bits & 0x01) << 23; /* add bit value */
843 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE); 987 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE);
844 rmh.cmd[0] |= IO_NUM_REG_CUER; 988 rmh.cmd[0] |= IO_NUM_REG_CUER;
845 rmh.cmd[1] = cmd; 989 rmh.cmd[1] = cmd;
@@ -867,7 +1011,12 @@ static int pcxhr_iec958_put(struct snd_kcontrol *kcontrol,
867 mutex_lock(&chip->mgr->mixer_mutex); 1011 mutex_lock(&chip->mgr->mixer_mutex);
868 for (i = 0; i < 5; i++) { 1012 for (i = 0; i < 5; i++) {
869 if (ucontrol->value.iec958.status[i] != chip->aes_bits[i]) { 1013 if (ucontrol->value.iec958.status[i] != chip->aes_bits[i]) {
870 pcxhr_iec958_update_byte(chip, i, ucontrol->value.iec958.status[i]); 1014 if (chip->mgr->is_hr_stereo)
1015 hr222_iec958_update_byte(chip, i,
1016 ucontrol->value.iec958.status[i]);
1017 else
1018 pcxhr_iec958_update_byte(chip, i,
1019 ucontrol->value.iec958.status[i]);
871 changed = 1; 1020 changed = 1;
872 } 1021 }
873 } 1022 }
@@ -917,29 +1066,53 @@ static void pcxhr_init_audio_levels(struct snd_pcxhr *chip)
917 /* at boot time the digital volumes are unmuted 0dB */ 1066 /* at boot time the digital volumes are unmuted 0dB */
918 for (j = 0; j < PCXHR_PLAYBACK_STREAMS; j++) { 1067 for (j = 0; j < PCXHR_PLAYBACK_STREAMS; j++) {
919 chip->digital_playback_active[j][i] = 1; 1068 chip->digital_playback_active[j][i] = 1;
920 chip->digital_playback_volume[j][i] = PCXHR_DIGITAL_ZERO_LEVEL; 1069 chip->digital_playback_volume[j][i] =
1070 PCXHR_DIGITAL_ZERO_LEVEL;
921 } 1071 }
922 /* after boot, only two bits are set on the uer interface */ 1072 /* after boot, only two bits are set on the uer
923 chip->aes_bits[0] = IEC958_AES0_PROFESSIONAL | IEC958_AES0_PRO_FS_48000; 1073 * interface
924/* only for test purpose, remove later */ 1074 */
1075 chip->aes_bits[0] = (IEC958_AES0_PROFESSIONAL |
1076 IEC958_AES0_PRO_FS_48000);
925#ifdef CONFIG_SND_DEBUG 1077#ifdef CONFIG_SND_DEBUG
926 /* analog volumes for playback (is LEVEL_MIN after boot) */ 1078 /* analog volumes for playback
1079 * (is LEVEL_MIN after boot)
1080 */
927 chip->analog_playback_active[i] = 1; 1081 chip->analog_playback_active[i] = 1;
928 chip->analog_playback_volume[i] = PCXHR_ANALOG_PLAYBACK_ZERO_LEVEL; 1082 if (chip->mgr->is_hr_stereo)
929 pcxhr_update_analog_audio_level(chip, 0, i); 1083 chip->analog_playback_volume[i] =
1084 HR222_LINE_PLAYBACK_ZERO_LEVEL;
1085 else {
1086 chip->analog_playback_volume[i] =
1087 PCXHR_LINE_PLAYBACK_ZERO_LEVEL;
1088 pcxhr_update_analog_audio_level(chip, 0, i);
1089 }
930#endif 1090#endif
931/* test end */ 1091 /* stereo cards need to be initialised after boot */
1092 if (chip->mgr->is_hr_stereo)
1093 hr222_update_analog_audio_level(chip, 0, i);
932 } 1094 }
933 if (chip->nb_streams_capt) { 1095 if (chip->nb_streams_capt) {
934 /* at boot time the digital volumes are unmuted 0dB */ 1096 /* at boot time the digital volumes are unmuted 0dB */
935 chip->digital_capture_volume[i] = PCXHR_DIGITAL_ZERO_LEVEL; 1097 chip->digital_capture_volume[i] =
936/* only for test purpose, remove later */ 1098 PCXHR_DIGITAL_ZERO_LEVEL;
1099 chip->analog_capture_active = 1;
937#ifdef CONFIG_SND_DEBUG 1100#ifdef CONFIG_SND_DEBUG
938 /* analog volumes for playback (is LEVEL_MIN after boot) */ 1101 /* analog volumes for playback
939 chip->analog_capture_volume[i] = PCXHR_ANALOG_CAPTURE_ZERO_LEVEL; 1102 * (is LEVEL_MIN after boot)
940 pcxhr_update_analog_audio_level(chip, 1, i); 1103 */
1104 if (chip->mgr->is_hr_stereo)
1105 chip->analog_capture_volume[i] =
1106 HR222_LINE_CAPTURE_ZERO_LEVEL;
1107 else {
1108 chip->analog_capture_volume[i] =
1109 PCXHR_LINE_CAPTURE_ZERO_LEVEL;
1110 pcxhr_update_analog_audio_level(chip, 1, i);
1111 }
941#endif 1112#endif
942/* test end */ 1113 /* stereo cards need to be initialised after boot */
1114 if (chip->mgr->is_hr_stereo)
1115 hr222_update_analog_audio_level(chip, 1, i);
943 } 1116 }
944 } 1117 }
945 1118
@@ -963,90 +1136,125 @@ int pcxhr_create_mixer(struct pcxhr_mgr *mgr)
963 temp = pcxhr_control_analog_level; 1136 temp = pcxhr_control_analog_level;
964 temp.name = "Master Playback Volume"; 1137 temp.name = "Master Playback Volume";
965 temp.private_value = 0; /* playback */ 1138 temp.private_value = 0; /* playback */
966 temp.tlv.p = db_scale_analog_playback; 1139 if (mgr->is_hr_stereo)
967 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0) 1140 temp.tlv.p = db_scale_a_hr222_playback;
1141 else
1142 temp.tlv.p = db_scale_analog_playback;
1143 err = snd_ctl_add(chip->card,
1144 snd_ctl_new1(&temp, chip));
1145 if (err < 0)
968 return err; 1146 return err;
1147
969 /* output mute controls */ 1148 /* output mute controls */
970 if ((err = snd_ctl_add(chip->card, 1149 err = snd_ctl_add(chip->card,
971 snd_ctl_new1(&pcxhr_control_output_switch, 1150 snd_ctl_new1(&pcxhr_control_output_switch,
972 chip))) < 0) 1151 chip));
1152 if (err < 0)
973 return err; 1153 return err;
974 1154
975 temp = snd_pcxhr_pcm_vol; 1155 temp = snd_pcxhr_pcm_vol;
976 temp.name = "PCM Playback Volume"; 1156 temp.name = "PCM Playback Volume";
977 temp.count = PCXHR_PLAYBACK_STREAMS; 1157 temp.count = PCXHR_PLAYBACK_STREAMS;
978 temp.private_value = 0; /* playback */ 1158 temp.private_value = 0; /* playback */
979 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0) 1159 err = snd_ctl_add(chip->card,
1160 snd_ctl_new1(&temp, chip));
1161 if (err < 0)
980 return err; 1162 return err;
981 1163
982 if ((err = snd_ctl_add(chip->card, 1164 err = snd_ctl_add(chip->card,
983 snd_ctl_new1(&pcxhr_control_pcm_switch, 1165 snd_ctl_new1(&pcxhr_control_pcm_switch, chip));
984 chip))) < 0) 1166 if (err < 0)
985 return err; 1167 return err;
986 1168
987 /* IEC958 controls */ 1169 /* IEC958 controls */
988 if ((err = snd_ctl_add(chip->card, 1170 err = snd_ctl_add(chip->card,
989 snd_ctl_new1(&pcxhr_control_playback_iec958_mask, 1171 snd_ctl_new1(&pcxhr_control_playback_iec958_mask,
990 chip))) < 0) 1172 chip));
1173 if (err < 0)
991 return err; 1174 return err;
992 if ((err = snd_ctl_add(chip->card, 1175
993 snd_ctl_new1(&pcxhr_control_playback_iec958, 1176 err = snd_ctl_add(chip->card,
994 chip))) < 0) 1177 snd_ctl_new1(&pcxhr_control_playback_iec958,
1178 chip));
1179 if (err < 0)
995 return err; 1180 return err;
996 } 1181 }
997 if (chip->nb_streams_capt) { 1182 if (chip->nb_streams_capt) {
998 /* analog input level control only on first two chips !*/ 1183 /* analog input level control */
999 temp = pcxhr_control_analog_level; 1184 temp = pcxhr_control_analog_level;
1000 temp.name = "Master Capture Volume"; 1185 temp.name = "Line Capture Volume";
1001 temp.private_value = 1; /* capture */ 1186 temp.private_value = 1; /* capture */
1002 temp.tlv.p = db_scale_analog_capture; 1187 if (mgr->is_hr_stereo)
1003 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0) 1188 temp.tlv.p = db_scale_a_hr222_capture;
1189 else
1190 temp.tlv.p = db_scale_analog_capture;
1191
1192 err = snd_ctl_add(chip->card,
1193 snd_ctl_new1(&temp, chip));
1194 if (err < 0)
1004 return err; 1195 return err;
1005 1196
1006 temp = snd_pcxhr_pcm_vol; 1197 temp = snd_pcxhr_pcm_vol;
1007 temp.name = "PCM Capture Volume"; 1198 temp.name = "PCM Capture Volume";
1008 temp.count = 1; 1199 temp.count = 1;
1009 temp.private_value = 1; /* capture */ 1200 temp.private_value = 1; /* capture */
1010 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0) 1201
1202 err = snd_ctl_add(chip->card,
1203 snd_ctl_new1(&temp, chip));
1204 if (err < 0)
1011 return err; 1205 return err;
1206
1012 /* Audio source */ 1207 /* Audio source */
1013 if ((err = snd_ctl_add(chip->card, 1208 err = snd_ctl_add(chip->card,
1014 snd_ctl_new1(&pcxhr_control_audio_src, 1209 snd_ctl_new1(&pcxhr_control_audio_src, chip));
1015 chip))) < 0) 1210 if (err < 0)
1016 return err; 1211 return err;
1212
1017 /* IEC958 controls */ 1213 /* IEC958 controls */
1018 if ((err = snd_ctl_add(chip->card, 1214 err = snd_ctl_add(chip->card,
1019 snd_ctl_new1(&pcxhr_control_capture_iec958_mask, 1215 snd_ctl_new1(&pcxhr_control_capture_iec958_mask,
1020 chip))) < 0) 1216 chip));
1217 if (err < 0)
1021 return err; 1218 return err;
1022 if ((err = snd_ctl_add(chip->card, 1219
1023 snd_ctl_new1(&pcxhr_control_capture_iec958, 1220 err = snd_ctl_add(chip->card,
1024 chip))) < 0) 1221 snd_ctl_new1(&pcxhr_control_capture_iec958,
1222 chip));
1223 if (err < 0)
1025 return err; 1224 return err;
1225
1226 if (mgr->is_hr_stereo) {
1227 err = hr222_add_mic_controls(chip);
1228 if (err < 0)
1229 return err;
1230 }
1026 } 1231 }
1027 /* monitoring only if playback and capture device available */ 1232 /* monitoring only if playback and capture device available */
1028 if (chip->nb_streams_capt > 0 && chip->nb_streams_play > 0) { 1233 if (chip->nb_streams_capt > 0 && chip->nb_streams_play > 0) {
1029 /* monitoring */ 1234 /* monitoring */
1030 if ((err = snd_ctl_add(chip->card, 1235 err = snd_ctl_add(chip->card,
1031 snd_ctl_new1(&pcxhr_control_monitor_vol, 1236 snd_ctl_new1(&pcxhr_control_monitor_vol, chip));
1032 chip))) < 0) 1237 if (err < 0)
1033 return err; 1238 return err;
1034 if ((err = snd_ctl_add(chip->card, 1239
1035 snd_ctl_new1(&pcxhr_control_monitor_sw, 1240 err = snd_ctl_add(chip->card,
1036 chip))) < 0) 1241 snd_ctl_new1(&pcxhr_control_monitor_sw, chip));
1242 if (err < 0)
1037 return err; 1243 return err;
1038 } 1244 }
1039 1245
1040 if (i == 0) { 1246 if (i == 0) {
1041 /* clock mode only one control per pcxhr */ 1247 /* clock mode only one control per pcxhr */
1042 if ((err = snd_ctl_add(chip->card, 1248 err = snd_ctl_add(chip->card,
1043 snd_ctl_new1(&pcxhr_control_clock_type, 1249 snd_ctl_new1(&pcxhr_control_clock_type, mgr));
1044 mgr))) < 0) 1250 if (err < 0)
1045 return err; 1251 return err;
1046 /* non standard control used to scan the external clock presence/frequencies */ 1252 /* non standard control used to scan
1047 if ((err = snd_ctl_add(chip->card, 1253 * the external clock presence/frequencies
1048 snd_ctl_new1(&pcxhr_control_clock_rate, 1254 */
1049 mgr))) < 0) 1255 err = snd_ctl_add(chip->card,
1256 snd_ctl_new1(&pcxhr_control_clock_rate, mgr));
1257 if (err < 0)
1050 return err; 1258 return err;
1051 } 1259 }
1052 1260
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c
index e9f0706ed3e4..3caacfb9d8e0 100644
--- a/sound/pci/riptide/riptide.c
+++ b/sound/pci/riptide/riptide.c
@@ -172,7 +172,7 @@ MODULE_PARM_DESC(opl3_port, "OPL3 port # for Riptide driver.");
172 172
173#define MAX_WRITE_RETRY 10 /* cmd interface limits */ 173#define MAX_WRITE_RETRY 10 /* cmd interface limits */
174#define MAX_ERROR_COUNT 10 174#define MAX_ERROR_COUNT 10
175#define CMDIF_TIMEOUT 500000 175#define CMDIF_TIMEOUT 50000
176#define RESET_TRIES 5 176#define RESET_TRIES 5
177 177
178#define READ_PORT_ULONG(p) inl((unsigned long)&(p)) 178#define READ_PORT_ULONG(p) inl((unsigned long)&(p))
@@ -1754,7 +1754,7 @@ snd_riptide_interrupt(int irq, void *dev_id)
1754 if (IS_EOBIRQ(cif->hwport) || IS_EOSIRQ(cif->hwport) || 1754 if (IS_EOBIRQ(cif->hwport) || IS_EOSIRQ(cif->hwport) ||
1755 IS_EOCIRQ(cif->hwport)) { 1755 IS_EOCIRQ(cif->hwport)) {
1756 chip->handled_irqs++; 1756 chip->handled_irqs++;
1757 tasklet_hi_schedule(&chip->riptide_tq); 1757 tasklet_schedule(&chip->riptide_tq);
1758 } 1758 }
1759 if (chip->rmidi && IS_MPUIRQ(cif->hwport)) { 1759 if (chip->rmidi && IS_MPUIRQ(cif->hwport)) {
1760 chip->handled_irqs++; 1760 chip->handled_irqs++;
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 736246f98acc..44d0c15e2b71 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -1452,7 +1452,7 @@ static int snd_hdsp_create_midi (struct snd_card *card, struct hdsp *hdsp, int i
1452 if (snd_rawmidi_new (card, buf, id, 1, 1, &hdsp->midi[id].rmidi) < 0) 1452 if (snd_rawmidi_new (card, buf, id, 1, 1, &hdsp->midi[id].rmidi) < 0)
1453 return -1; 1453 return -1;
1454 1454
1455 sprintf (hdsp->midi[id].rmidi->name, "%s MIDI %d", card->id, id+1); 1455 sprintf(hdsp->midi[id].rmidi->name, "HDSP MIDI %d", id+1);
1456 hdsp->midi[id].rmidi->private_data = &hdsp->midi[id]; 1456 hdsp->midi[id].rmidi->private_data = &hdsp->midi[id];
1457 1457
1458 snd_rawmidi_set_ops (hdsp->midi[id].rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_hdsp_midi_output); 1458 snd_rawmidi_set_ops (hdsp->midi[id].rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_hdsp_midi_output);
@@ -3750,7 +3750,7 @@ static irqreturn_t snd_hdsp_interrupt(int irq, void *dev_id)
3750 } 3750 }
3751 } 3751 }
3752 if (hdsp->use_midi_tasklet && schedule) 3752 if (hdsp->use_midi_tasklet && schedule)
3753 tasklet_hi_schedule(&hdsp->midi_tasklet); 3753 tasklet_schedule(&hdsp->midi_tasklet);
3754 return IRQ_HANDLED; 3754 return IRQ_HANDLED;
3755} 3755}
3756 3756
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index 98762f909d64..71231cf1b2b0 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -1293,7 +1293,7 @@ static int __devinit snd_hdspm_create_midi (struct snd_card *card,
1293 if (err < 0) 1293 if (err < 0)
1294 return err; 1294 return err;
1295 1295
1296 sprintf (hdspm->midi[id].rmidi->name, "%s MIDI %d", card->id, id+1); 1296 sprintf(hdspm->midi[id].rmidi->name, "HDSPM MIDI %d", id+1);
1297 hdspm->midi[id].rmidi->private_data = &hdspm->midi[id]; 1297 hdspm->midi[id].rmidi->private_data = &hdspm->midi[id];
1298 1298
1299 snd_rawmidi_set_ops(hdspm->midi[id].rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, 1299 snd_rawmidi_set_ops(hdspm->midi[id].rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
@@ -3476,7 +3476,7 @@ static irqreturn_t snd_hdspm_interrupt(int irq, void *dev_id)
3476 schedule = 1; 3476 schedule = 1;
3477 } 3477 }
3478 if (schedule) 3478 if (schedule)
3479 tasklet_hi_schedule(&hdspm->midi_tasklet); 3479 tasklet_schedule(&hdspm->midi_tasklet);
3480 return IRQ_HANDLED; 3480 return IRQ_HANDLED;
3481} 3481}
3482 3482
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf_irq.c b/sound/pcmcia/pdaudiocf/pdaudiocf_irq.c
index fa4b11398b1f..ea903c8e90dd 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf_irq.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf_irq.c
@@ -41,7 +41,7 @@ irqreturn_t pdacf_interrupt(int irq, void *dev)
41 if (stat & PDAUDIOCF_IRQOVR) /* should never happen */ 41 if (stat & PDAUDIOCF_IRQOVR) /* should never happen */
42 snd_printk(KERN_ERR "PDAUDIOCF SRAM buffer overrun detected!\n"); 42 snd_printk(KERN_ERR "PDAUDIOCF SRAM buffer overrun detected!\n");
43 if (chip->pcm_substream) 43 if (chip->pcm_substream)
44 tasklet_hi_schedule(&chip->tq); 44 tasklet_schedule(&chip->tq);
45 if (!(stat & PDAUDIOCF_IRQAKM)) 45 if (!(stat & PDAUDIOCF_IRQAKM))
46 stat |= PDAUDIOCF_IRQAKM; /* check rate */ 46 stat |= PDAUDIOCF_IRQAKM; /* check rate */
47 } 47 }
diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c
index a38c0c790d2b..af76ee862d27 100644
--- a/sound/ppc/pmac.c
+++ b/sound/ppc/pmac.c
@@ -1033,7 +1033,7 @@ static int __init snd_pmac_detect(struct snd_pmac *chip)
1033 } 1033 }
1034 if (of_device_is_compatible(sound, "tumbler")) { 1034 if (of_device_is_compatible(sound, "tumbler")) {
1035 chip->model = PMAC_TUMBLER; 1035 chip->model = PMAC_TUMBLER;
1036 chip->can_capture = 0; /* no capture */ 1036 chip->can_capture = machine_is_compatible("PowerMac4,2");
1037 chip->can_duplex = 0; 1037 chip->can_duplex = 0;
1038 // chip->can_byte_swap = 0; /* FIXME: check this */ 1038 // chip->can_byte_swap = 0; /* FIXME: check this */
1039 chip->num_freqs = ARRAY_SIZE(tumbler_freqs); 1039 chip->num_freqs = ARRAY_SIZE(tumbler_freqs);
diff --git a/sound/ppc/tumbler.c b/sound/ppc/tumbler.c
index f746e15b8481..3eb223385416 100644
--- a/sound/ppc/tumbler.c
+++ b/sound/ppc/tumbler.c
@@ -875,7 +875,8 @@ static struct snd_kcontrol_new snapper_mixers[] __initdata = {
875 .put = tumbler_put_master_switch 875 .put = tumbler_put_master_switch
876 }, 876 },
877 DEFINE_SNAPPER_MIX("PCM Playback Volume", 0, VOL_IDX_PCM), 877 DEFINE_SNAPPER_MIX("PCM Playback Volume", 0, VOL_IDX_PCM),
878 DEFINE_SNAPPER_MIX("PCM Playback Volume", 1, VOL_IDX_PCM2), 878 /* Alternative PCM is assigned to Mic analog loopback on iBook G4 */
879 DEFINE_SNAPPER_MIX("Mic Playback Volume", 0, VOL_IDX_PCM2),
879 DEFINE_SNAPPER_MIX("Monitor Mix Volume", 0, VOL_IDX_ADC), 880 DEFINE_SNAPPER_MIX("Monitor Mix Volume", 0, VOL_IDX_ADC),
880 DEFINE_SNAPPER_MONO("Tone Control - Bass", bass), 881 DEFINE_SNAPPER_MONO("Tone Control - Bass", bass),
881 DEFINE_SNAPPER_MONO("Tone Control - Treble", treble), 882 DEFINE_SNAPPER_MONO("Tone Control - Treble", treble),
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index 4dfda6674bec..ef025c66cc66 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -22,17 +22,16 @@ if SND_SOC
22config SND_SOC_AC97_BUS 22config SND_SOC_AC97_BUS
23 bool 23 bool
24 24
25# All the supported Soc's 25# All the supported SoCs
26source "sound/soc/at32/Kconfig" 26source "sound/soc/atmel/Kconfig"
27source "sound/soc/at91/Kconfig"
28source "sound/soc/au1x/Kconfig" 27source "sound/soc/au1x/Kconfig"
28source "sound/soc/blackfin/Kconfig"
29source "sound/soc/davinci/Kconfig"
30source "sound/soc/fsl/Kconfig"
31source "sound/soc/omap/Kconfig"
29source "sound/soc/pxa/Kconfig" 32source "sound/soc/pxa/Kconfig"
30source "sound/soc/s3c24xx/Kconfig" 33source "sound/soc/s3c24xx/Kconfig"
31source "sound/soc/sh/Kconfig" 34source "sound/soc/sh/Kconfig"
32source "sound/soc/fsl/Kconfig"
33source "sound/soc/davinci/Kconfig"
34source "sound/soc/omap/Kconfig"
35source "sound/soc/blackfin/Kconfig"
36 35
37# Supported codecs 36# Supported codecs
38source "sound/soc/codecs/Kconfig" 37source "sound/soc/codecs/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index d849349f2c66..86a9b1f5b0f3 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -1,5 +1,13 @@
1snd-soc-core-objs := soc-core.o soc-dapm.o 1snd-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/
5obj-$(CONFIG_SND_SOC) += omap/ au1x/ blackfin/ 5obj-$(CONFIG_SND_SOC) += atmel/
6obj-$(CONFIG_SND_SOC) += au1x/
7obj-$(CONFIG_SND_SOC) += blackfin/
8obj-$(CONFIG_SND_SOC) += davinci/
9obj-$(CONFIG_SND_SOC) += fsl/
10obj-$(CONFIG_SND_SOC) += omap/
11obj-$(CONFIG_SND_SOC) += pxa/
12obj-$(CONFIG_SND_SOC) += s3c24xx/
13obj-$(CONFIG_SND_SOC) += sh/
diff --git a/sound/soc/at32/Kconfig b/sound/soc/at32/Kconfig
deleted file mode 100644
index b0765e86c085..000000000000
--- a/sound/soc/at32/Kconfig
+++ /dev/null
@@ -1,34 +0,0 @@
1config SND_AT32_SOC
2 tristate "SoC Audio for the Atmel AT32 System-on-a-Chip"
3 depends on AVR32 && SND_SOC
4 help
5 Say Y or M if you want to add support for codecs attached to
6 the AT32 SSC interface. You will also need to
7 to select the audio interfaces to support below.
8
9
10config SND_AT32_SOC_SSC
11 tristate
12
13
14
15config SND_AT32_SOC_PLAYPAQ
16 tristate "SoC Audio support for PlayPaq with WM8510"
17 depends on SND_AT32_SOC && BOARD_PLAYPAQ
18 select SND_AT32_SOC_SSC
19 select SND_SOC_WM8510
20 help
21 Say Y or M here if you want to add support for SoC audio
22 on the LRS PlayPaq.
23
24
25
26config SND_AT32_SOC_PLAYPAQ_SLAVE
27 bool "Run CODEC on PlayPaq in slave mode"
28 depends on SND_AT32_SOC_PLAYPAQ
29 default n
30 help
31 Say Y if you want to run with the AT32 SSC generating the BCLK
32 and FRAME signals on the PlayPaq. Unless you want to play
33 with the AT32 as the SSC master, you probably want to say N here,
34 as this will give you better sound quality.
diff --git a/sound/soc/at32/Makefile b/sound/soc/at32/Makefile
deleted file mode 100644
index c03e55ececeb..000000000000
--- a/sound/soc/at32/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
1# AT32 Platform Support
2snd-soc-at32-objs := at32-pcm.o
3snd-soc-at32-ssc-objs := at32-ssc.o
4
5obj-$(CONFIG_SND_AT32_SOC) += snd-soc-at32.o
6obj-$(CONFIG_SND_AT32_SOC_SSC) += snd-soc-at32-ssc.o
7
8# AT32 Machine Support
9snd-soc-playpaq-objs := playpaq_wm8510.o
10
11obj-$(CONFIG_SND_AT32_SOC_PLAYPAQ) += snd-soc-playpaq.o
diff --git a/sound/soc/at32/at32-pcm.c b/sound/soc/at32/at32-pcm.c
deleted file mode 100644
index c83584f989a9..000000000000
--- a/sound/soc/at32/at32-pcm.c
+++ /dev/null
@@ -1,492 +0,0 @@
1/* sound/soc/at32/at32-pcm.c
2 * ASoC PCM interface for Atmel AT32 SoC
3 *
4 * Copyright (C) 2008 Long Range Systems
5 * Geoffrey Wossum <gwossum@acm.org>
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 * Note that this is basically a port of the sound/soc/at91-pcm.c to
12 * the AVR32 kernel. Thanks to Frank Mandarino for that code.
13 */
14
15#include <linux/module.h>
16#include <linux/init.h>
17#include <linux/platform_device.h>
18#include <linux/slab.h>
19#include <linux/dma-mapping.h>
20#include <linux/atmel_pdc.h>
21
22#include <sound/core.h>
23#include <sound/pcm.h>
24#include <sound/pcm_params.h>
25#include <sound/soc.h>
26
27#include "at32-pcm.h"
28
29
30
31/*--------------------------------------------------------------------------*\
32 * Hardware definition
33\*--------------------------------------------------------------------------*/
34/* TODO: These values were taken from the AT91 platform driver, check
35 * them against real values for AT32
36 */
37static const struct snd_pcm_hardware at32_pcm_hardware = {
38 .info = (SNDRV_PCM_INFO_MMAP |
39 SNDRV_PCM_INFO_MMAP_VALID |
40 SNDRV_PCM_INFO_INTERLEAVED |
41 SNDRV_PCM_INFO_BLOCK_TRANSFER |
42 SNDRV_PCM_INFO_PAUSE),
43
44 .formats = SNDRV_PCM_FMTBIT_S16,
45 .period_bytes_min = 32,
46 .period_bytes_max = 8192, /* 512 frames * 16 bytes / frame */
47 .periods_min = 2,
48 .periods_max = 1024,
49 .buffer_bytes_max = 32 * 1024,
50};
51
52
53
54/*--------------------------------------------------------------------------*\
55 * Data types
56\*--------------------------------------------------------------------------*/
57struct at32_runtime_data {
58 struct at32_pcm_dma_params *params;
59 dma_addr_t dma_buffer; /* physical address of DMA buffer */
60 dma_addr_t dma_buffer_end; /* first address beyond DMA buffer */
61 size_t period_size;
62
63 dma_addr_t period_ptr; /* physical address of next period */
64 int periods; /* period index of period_ptr */
65
66 /* Save PDC registers (for power management) */
67 u32 pdc_xpr_save;
68 u32 pdc_xcr_save;
69 u32 pdc_xnpr_save;
70 u32 pdc_xncr_save;
71};
72
73
74
75/*--------------------------------------------------------------------------*\
76 * Helper functions
77\*--------------------------------------------------------------------------*/
78static int at32_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
79{
80 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
81 struct snd_dma_buffer *dmabuf = &substream->dma_buffer;
82 size_t size = at32_pcm_hardware.buffer_bytes_max;
83
84 dmabuf->dev.type = SNDRV_DMA_TYPE_DEV;
85 dmabuf->dev.dev = pcm->card->dev;
86 dmabuf->private_data = NULL;
87 dmabuf->area = dma_alloc_coherent(pcm->card->dev, size,
88 &dmabuf->addr, GFP_KERNEL);
89 pr_debug("at32_pcm: preallocate_dma_buffer: "
90 "area=%p, addr=%p, size=%ld\n",
91 (void *)dmabuf->area, (void *)dmabuf->addr, size);
92
93 if (!dmabuf->area)
94 return -ENOMEM;
95
96 dmabuf->bytes = size;
97 return 0;
98}
99
100
101
102/*--------------------------------------------------------------------------*\
103 * ISR
104\*--------------------------------------------------------------------------*/
105static void at32_pcm_dma_irq(u32 ssc_sr, struct snd_pcm_substream *substream)
106{
107 struct snd_pcm_runtime *rtd = substream->runtime;
108 struct at32_runtime_data *prtd = rtd->private_data;
109 struct at32_pcm_dma_params *params = prtd->params;
110 static int count;
111
112 count++;
113 if (ssc_sr & params->mask->ssc_endbuf) {
114 pr_warning("at32-pcm: buffer %s on %s (SSC_SR=%#x, count=%d)\n",
115 substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
116 "underrun" : "overrun", params->name, ssc_sr, count);
117
118 /* re-start the PDC */
119 ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
120 params->mask->pdc_disable);
121 prtd->period_ptr += prtd->period_size;
122 if (prtd->period_ptr >= prtd->dma_buffer_end)
123 prtd->period_ptr = prtd->dma_buffer;
124
125
126 ssc_writex(params->ssc->regs, params->pdc->xpr,
127 prtd->period_ptr);
128 ssc_writex(params->ssc->regs, params->pdc->xcr,
129 prtd->period_size / params->pdc_xfer_size);
130 ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
131 params->mask->pdc_enable);
132 }
133
134
135 if (ssc_sr & params->mask->ssc_endx) {
136 /* Load the PDC next pointer and counter registers */
137 prtd->period_ptr += prtd->period_size;
138 if (prtd->period_ptr >= prtd->dma_buffer_end)
139 prtd->period_ptr = prtd->dma_buffer;
140 ssc_writex(params->ssc->regs, params->pdc->xnpr,
141 prtd->period_ptr);
142 ssc_writex(params->ssc->regs, params->pdc->xncr,
143 prtd->period_size / params->pdc_xfer_size);
144 }
145
146
147 snd_pcm_period_elapsed(substream);
148}
149
150
151
152/*--------------------------------------------------------------------------*\
153 * PCM operations
154\*--------------------------------------------------------------------------*/
155static int at32_pcm_hw_params(struct snd_pcm_substream *substream,
156 struct snd_pcm_hw_params *params)
157{
158 struct snd_pcm_runtime *runtime = substream->runtime;
159 struct at32_runtime_data *prtd = runtime->private_data;
160 struct snd_soc_pcm_runtime *rtd = substream->private_data;
161
162 /* this may get called several times by oss emulation
163 * with different params
164 */
165 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
166 runtime->dma_bytes = params_buffer_bytes(params);
167
168 prtd->params = rtd->dai->cpu_dai->dma_data;
169 prtd->params->dma_intr_handler = at32_pcm_dma_irq;
170
171 prtd->dma_buffer = runtime->dma_addr;
172 prtd->dma_buffer_end = runtime->dma_addr + runtime->dma_bytes;
173 prtd->period_size = params_period_bytes(params);
174
175 pr_debug("hw_params: DMA for %s initialized "
176 "(dma_bytes=%ld, period_size=%ld)\n",
177 prtd->params->name, runtime->dma_bytes, prtd->period_size);
178
179 return 0;
180}
181
182
183
184static int at32_pcm_hw_free(struct snd_pcm_substream *substream)
185{
186 struct at32_runtime_data *prtd = substream->runtime->private_data;
187 struct at32_pcm_dma_params *params = prtd->params;
188
189 if (params != NULL) {
190 ssc_writex(params->ssc->regs, SSC_PDC_PTCR,
191 params->mask->pdc_disable);
192 prtd->params->dma_intr_handler = NULL;
193 }
194
195 return 0;
196}
197
198
199
200static int at32_pcm_prepare(struct snd_pcm_substream *substream)
201{
202 struct at32_runtime_data *prtd = substream->runtime->private_data;
203 struct at32_pcm_dma_params *params = prtd->params;
204
205 ssc_writex(params->ssc->regs, SSC_IDR,
206 params->mask->ssc_endx | params->mask->ssc_endbuf);
207 ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
208 params->mask->pdc_disable);
209
210 return 0;
211}
212
213
214static int at32_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
215{
216 struct snd_pcm_runtime *rtd = substream->runtime;
217 struct at32_runtime_data *prtd = rtd->private_data;
218 struct at32_pcm_dma_params *params = prtd->params;
219 int ret = 0;
220
221 pr_debug("at32_pcm_trigger: buffer_size = %ld, "
222 "dma_area = %p, dma_bytes = %ld\n",
223 rtd->buffer_size, rtd->dma_area, rtd->dma_bytes);
224
225 switch (cmd) {
226 case SNDRV_PCM_TRIGGER_START:
227 prtd->period_ptr = prtd->dma_buffer;
228
229 ssc_writex(params->ssc->regs, params->pdc->xpr,
230 prtd->period_ptr);
231 ssc_writex(params->ssc->regs, params->pdc->xcr,
232 prtd->period_size / params->pdc_xfer_size);
233
234 prtd->period_ptr += prtd->period_size;
235 ssc_writex(params->ssc->regs, params->pdc->xnpr,
236 prtd->period_ptr);
237 ssc_writex(params->ssc->regs, params->pdc->xncr,
238 prtd->period_size / params->pdc_xfer_size);
239
240 pr_debug("trigger: period_ptr=%lx, xpr=%x, "
241 "xcr=%d, xnpr=%x, xncr=%d\n",
242 (unsigned long)prtd->period_ptr,
243 ssc_readx(params->ssc->regs, params->pdc->xpr),
244 ssc_readx(params->ssc->regs, params->pdc->xcr),
245 ssc_readx(params->ssc->regs, params->pdc->xnpr),
246 ssc_readx(params->ssc->regs, params->pdc->xncr));
247
248 ssc_writex(params->ssc->regs, SSC_IER,
249 params->mask->ssc_endx | params->mask->ssc_endbuf);
250 ssc_writex(params->ssc->regs, SSC_PDC_PTCR,
251 params->mask->pdc_enable);
252
253 pr_debug("sr=%x, imr=%x\n",
254 ssc_readx(params->ssc->regs, SSC_SR),
255 ssc_readx(params->ssc->regs, SSC_IER));
256 break; /* SNDRV_PCM_TRIGGER_START */
257
258
259
260 case SNDRV_PCM_TRIGGER_STOP:
261 case SNDRV_PCM_TRIGGER_SUSPEND:
262 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
263 ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
264 params->mask->pdc_disable);
265 break;
266
267
268 case SNDRV_PCM_TRIGGER_RESUME:
269 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
270 ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
271 params->mask->pdc_enable);
272 break;
273
274 default:
275 ret = -EINVAL;
276 }
277
278 return ret;
279}
280
281
282
283static snd_pcm_uframes_t at32_pcm_pointer(struct snd_pcm_substream *substream)
284{
285 struct snd_pcm_runtime *runtime = substream->runtime;
286 struct at32_runtime_data *prtd = runtime->private_data;
287 struct at32_pcm_dma_params *params = prtd->params;
288 dma_addr_t ptr;
289 snd_pcm_uframes_t x;
290
291 ptr = (dma_addr_t) ssc_readx(params->ssc->regs, params->pdc->xpr);
292 x = bytes_to_frames(runtime, ptr - prtd->dma_buffer);
293
294 if (x == runtime->buffer_size)
295 x = 0;
296
297 return x;
298}
299
300
301
302static int at32_pcm_open(struct snd_pcm_substream *substream)
303{
304 struct snd_pcm_runtime *runtime = substream->runtime;
305 struct at32_runtime_data *prtd;
306 int ret = 0;
307
308 snd_soc_set_runtime_hwparams(substream, &at32_pcm_hardware);
309
310 /* ensure that buffer size is a multiple of period size */
311 ret = snd_pcm_hw_constraint_integer(runtime,
312 SNDRV_PCM_HW_PARAM_PERIODS);
313 if (ret < 0)
314 goto out;
315
316 prtd = kzalloc(sizeof(*prtd), GFP_KERNEL);
317 if (prtd == NULL) {
318 ret = -ENOMEM;
319 goto out;
320 }
321 runtime->private_data = prtd;
322
323
324out:
325 return ret;
326}
327
328
329
330static int at32_pcm_close(struct snd_pcm_substream *substream)
331{
332 struct at32_runtime_data *prtd = substream->runtime->private_data;
333
334 kfree(prtd);
335 return 0;
336}
337
338
339static int at32_pcm_mmap(struct snd_pcm_substream *substream,
340 struct vm_area_struct *vma)
341{
342 return remap_pfn_range(vma, vma->vm_start,
343 substream->dma_buffer.addr >> PAGE_SHIFT,
344 vma->vm_end - vma->vm_start, vma->vm_page_prot);
345}
346
347
348
349static struct snd_pcm_ops at32_pcm_ops = {
350 .open = at32_pcm_open,
351 .close = at32_pcm_close,
352 .ioctl = snd_pcm_lib_ioctl,
353 .hw_params = at32_pcm_hw_params,
354 .hw_free = at32_pcm_hw_free,
355 .prepare = at32_pcm_prepare,
356 .trigger = at32_pcm_trigger,
357 .pointer = at32_pcm_pointer,
358 .mmap = at32_pcm_mmap,
359};
360
361
362
363/*--------------------------------------------------------------------------*\
364 * ASoC platform driver
365\*--------------------------------------------------------------------------*/
366static u64 at32_pcm_dmamask = 0xffffffff;
367
368static int at32_pcm_new(struct snd_card *card,
369 struct snd_soc_dai *dai,
370 struct snd_pcm *pcm)
371{
372 int ret = 0;
373
374 if (!card->dev->dma_mask)
375 card->dev->dma_mask = &at32_pcm_dmamask;
376 if (!card->dev->coherent_dma_mask)
377 card->dev->coherent_dma_mask = 0xffffffff;
378
379 if (dai->playback.channels_min) {
380 ret = at32_pcm_preallocate_dma_buffer(
381 pcm, SNDRV_PCM_STREAM_PLAYBACK);
382 if (ret)
383 goto out;
384 }
385
386 if (dai->capture.channels_min) {
387 pr_debug("at32-pcm: Allocating PCM capture DMA buffer\n");
388 ret = at32_pcm_preallocate_dma_buffer(
389 pcm, SNDRV_PCM_STREAM_CAPTURE);
390 if (ret)
391 goto out;
392 }
393
394
395out:
396 return ret;
397}
398
399
400
401static void at32_pcm_free_dma_buffers(struct snd_pcm *pcm)
402{
403 struct snd_pcm_substream *substream;
404 struct snd_dma_buffer *buf;
405 int stream;
406
407 for (stream = 0; stream < 2; stream++) {
408 substream = pcm->streams[stream].substream;
409 if (substream == NULL)
410 continue;
411
412 buf = &substream->dma_buffer;
413 if (!buf->area)
414 continue;
415 dma_free_coherent(pcm->card->dev, buf->bytes,
416 buf->area, buf->addr);
417 buf->area = NULL;
418 }
419}
420
421
422
423#ifdef CONFIG_PM
424static int at32_pcm_suspend(struct platform_device *pdev,
425 struct snd_soc_dai *dai)
426{
427 struct snd_pcm_runtime *runtime = dai->runtime;
428 struct at32_runtime_data *prtd;
429 struct at32_pcm_dma_params *params;
430
431 if (runtime == NULL)
432 return 0;
433 prtd = runtime->private_data;
434 params = prtd->params;
435
436 /* Disable the PDC and save the PDC registers */
437 ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
438 params->mask->pdc_disable);
439
440 prtd->pdc_xpr_save = ssc_readx(params->ssc->regs, params->pdc->xpr);
441 prtd->pdc_xcr_save = ssc_readx(params->ssc->regs, params->pdc->xcr);
442 prtd->pdc_xnpr_save = ssc_readx(params->ssc->regs, params->pdc->xnpr);
443 prtd->pdc_xncr_save = ssc_readx(params->ssc->regs, params->pdc->xncr);
444
445 return 0;
446}
447
448
449
450static int at32_pcm_resume(struct platform_device *pdev,
451 struct snd_soc_dai *dai)
452{
453 struct snd_pcm_runtime *runtime = dai->runtime;
454 struct at32_runtime_data *prtd;
455 struct at32_pcm_dma_params *params;
456
457 if (runtime == NULL)
458 return 0;
459 prtd = runtime->private_data;
460 params = prtd->params;
461
462 /* Restore the PDC registers and enable the PDC */
463 ssc_writex(params->ssc->regs, params->pdc->xpr, prtd->pdc_xpr_save);
464 ssc_writex(params->ssc->regs, params->pdc->xcr, prtd->pdc_xcr_save);
465 ssc_writex(params->ssc->regs, params->pdc->xnpr, prtd->pdc_xnpr_save);
466 ssc_writex(params->ssc->regs, params->pdc->xncr, prtd->pdc_xncr_save);
467
468 ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR, params->mask->pdc_enable);
469 return 0;
470}
471#else /* CONFIG_PM */
472# define at32_pcm_suspend NULL
473# define at32_pcm_resume NULL
474#endif /* CONFIG_PM */
475
476
477
478struct snd_soc_platform at32_soc_platform = {
479 .name = "at32-audio",
480 .pcm_ops = &at32_pcm_ops,
481 .pcm_new = at32_pcm_new,
482 .pcm_free = at32_pcm_free_dma_buffers,
483 .suspend = at32_pcm_suspend,
484 .resume = at32_pcm_resume,
485};
486EXPORT_SYMBOL_GPL(at32_soc_platform);
487
488
489
490MODULE_AUTHOR("Geoffrey Wossum <gwossum@acm.org>");
491MODULE_DESCRIPTION("Atmel AT32 PCM module");
492MODULE_LICENSE("GPL");
diff --git a/sound/soc/at32/at32-pcm.h b/sound/soc/at32/at32-pcm.h
deleted file mode 100644
index 2a52430417da..000000000000
--- a/sound/soc/at32/at32-pcm.h
+++ /dev/null
@@ -1,79 +0,0 @@
1/* sound/soc/at32/at32-pcm.h
2 * ASoC PCM interface for Atmel AT32 SoC
3 *
4 * Copyright (C) 2008 Long Range Systems
5 * Geoffrey Wossum <gwossum@acm.org>
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 __SOUND_SOC_AT32_AT32_PCM_H
13#define __SOUND_SOC_AT32_AT32_PCM_H __FILE__
14
15#include <linux/atmel-ssc.h>
16
17
18/*
19 * Registers and status bits that are required by the PCM driver
20 * TODO: Is ptcr really used?
21 */
22struct at32_pdc_regs {
23 u32 xpr; /* PDC RX/TX pointer */
24 u32 xcr; /* PDC RX/TX counter */
25 u32 xnpr; /* PDC next RX/TX pointer */
26 u32 xncr; /* PDC next RX/TX counter */
27 u32 ptcr; /* PDC transfer control */
28};
29
30
31
32/*
33 * SSC mask info
34 */
35struct at32_ssc_mask {
36 u32 ssc_enable; /* SSC RX/TX enable */
37 u32 ssc_disable; /* SSC RX/TX disable */
38 u32 ssc_endx; /* SSC ENDTX or ENDRX */
39 u32 ssc_endbuf; /* SSC TXBUFF or RXBUFF */
40 u32 pdc_enable; /* PDC RX/TX enable */
41 u32 pdc_disable; /* PDC RX/TX disable */
42};
43
44
45
46/*
47 * This structure, shared between the PCM driver and the interface,
48 * contains all information required by the PCM driver to perform the
49 * PDC DMA operation. All fields except dma_intr_handler() are initialized
50 * by the interface. The dms_intr_handler() pointer is set by the PCM
51 * driver and called by the interface SSC interrupt handler if it is
52 * non-NULL.
53 */
54struct at32_pcm_dma_params {
55 char *name; /* stream identifier */
56 int pdc_xfer_size; /* PDC counter increment in bytes */
57 struct ssc_device *ssc; /* SSC device for stream */
58 struct at32_pdc_regs *pdc; /* PDC register info */
59 struct at32_ssc_mask *mask; /* SSC mask info */
60 struct snd_pcm_substream *substream;
61 void (*dma_intr_handler) (u32, struct snd_pcm_substream *);
62};
63
64
65
66/*
67 * The AT32 ASoC platform driver
68 */
69extern struct snd_soc_platform at32_soc_platform;
70
71
72
73/*
74 * SSC register access (since ssc_writel() / ssc_readl() require literal name)
75 */
76#define ssc_readx(base, reg) (__raw_readl((base) + (reg)))
77#define ssc_writex(base, reg, value) __raw_writel((value), (base) + (reg))
78
79#endif /* __SOUND_SOC_AT32_AT32_PCM_H */
diff --git a/sound/soc/at32/at32-ssc.c b/sound/soc/at32/at32-ssc.c
deleted file mode 100644
index 4ef6492c902e..000000000000
--- a/sound/soc/at32/at32-ssc.c
+++ /dev/null
@@ -1,849 +0,0 @@
1/* sound/soc/at32/at32-ssc.c
2 * ASoC platform driver for AT32 using SSC as DAI
3 *
4 * Copyright (C) 2008 Long Range Systems
5 * Geoffrey Wossum <gwossum@acm.org>
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 * Note that this is basically a port of the sound/soc/at91-ssc.c to
12 * the AVR32 kernel. Thanks to Frank Mandarino for that code.
13 */
14
15/* #define DEBUG */
16
17#include <linux/init.h>
18#include <linux/module.h>
19#include <linux/interrupt.h>
20#include <linux/device.h>
21#include <linux/delay.h>
22#include <linux/clk.h>
23#include <linux/io.h>
24#include <linux/atmel_pdc.h>
25#include <linux/atmel-ssc.h>
26
27#include <sound/core.h>
28#include <sound/pcm.h>
29#include <sound/pcm_params.h>
30#include <sound/initval.h>
31#include <sound/soc.h>
32
33#include "at32-pcm.h"
34#include "at32-ssc.h"
35
36
37
38/*-------------------------------------------------------------------------*\
39 * Constants
40\*-------------------------------------------------------------------------*/
41#define NUM_SSC_DEVICES 3
42
43/*
44 * SSC direction masks
45 */
46#define SSC_DIR_MASK_UNUSED 0
47#define SSC_DIR_MASK_PLAYBACK 1
48#define SSC_DIR_MASK_CAPTURE 2
49
50/*
51 * SSC register values that Atmel left out of <linux/atmel-ssc.h>. These
52 * are expected to be used with SSC_BF
53 */
54/* START bit field values */
55#define SSC_START_CONTINUOUS 0
56#define SSC_START_TX_RX 1
57#define SSC_START_LOW_RF 2
58#define SSC_START_HIGH_RF 3
59#define SSC_START_FALLING_RF 4
60#define SSC_START_RISING_RF 5
61#define SSC_START_LEVEL_RF 6
62#define SSC_START_EDGE_RF 7
63#define SSS_START_COMPARE_0 8
64
65/* CKI bit field values */
66#define SSC_CKI_FALLING 0
67#define SSC_CKI_RISING 1
68
69/* CKO bit field values */
70#define SSC_CKO_NONE 0
71#define SSC_CKO_CONTINUOUS 1
72#define SSC_CKO_TRANSFER 2
73
74/* CKS bit field values */
75#define SSC_CKS_DIV 0
76#define SSC_CKS_CLOCK 1
77#define SSC_CKS_PIN 2
78
79/* FSEDGE bit field values */
80#define SSC_FSEDGE_POSITIVE 0
81#define SSC_FSEDGE_NEGATIVE 1
82
83/* FSOS bit field values */
84#define SSC_FSOS_NONE 0
85#define SSC_FSOS_NEGATIVE 1
86#define SSC_FSOS_POSITIVE 2
87#define SSC_FSOS_LOW 3
88#define SSC_FSOS_HIGH 4
89#define SSC_FSOS_TOGGLE 5
90
91#define START_DELAY 1
92
93
94
95/*-------------------------------------------------------------------------*\
96 * Module data
97\*-------------------------------------------------------------------------*/
98/*
99 * SSC PDC registered required by the PCM DMA engine
100 */
101static struct at32_pdc_regs pdc_tx_reg = {
102 .xpr = SSC_PDC_TPR,
103 .xcr = SSC_PDC_TCR,
104 .xnpr = SSC_PDC_TNPR,
105 .xncr = SSC_PDC_TNCR,
106};
107
108
109
110static struct at32_pdc_regs pdc_rx_reg = {
111 .xpr = SSC_PDC_RPR,
112 .xcr = SSC_PDC_RCR,
113 .xnpr = SSC_PDC_RNPR,
114 .xncr = SSC_PDC_RNCR,
115};
116
117
118
119/*
120 * SSC and PDC status bits for transmit and receive
121 */
122static struct at32_ssc_mask ssc_tx_mask = {
123 .ssc_enable = SSC_BIT(CR_TXEN),
124 .ssc_disable = SSC_BIT(CR_TXDIS),
125 .ssc_endx = SSC_BIT(SR_ENDTX),
126 .ssc_endbuf = SSC_BIT(SR_TXBUFE),
127 .pdc_enable = SSC_BIT(PDC_PTCR_TXTEN),
128 .pdc_disable = SSC_BIT(PDC_PTCR_TXTDIS),
129};
130
131
132
133static struct at32_ssc_mask ssc_rx_mask = {
134 .ssc_enable = SSC_BIT(CR_RXEN),
135 .ssc_disable = SSC_BIT(CR_RXDIS),
136 .ssc_endx = SSC_BIT(SR_ENDRX),
137 .ssc_endbuf = SSC_BIT(SR_RXBUFF),
138 .pdc_enable = SSC_BIT(PDC_PTCR_RXTEN),
139 .pdc_disable = SSC_BIT(PDC_PTCR_RXTDIS),
140};
141
142
143
144/*
145 * DMA parameters for each SSC
146 */
147static struct at32_pcm_dma_params ssc_dma_params[NUM_SSC_DEVICES][2] = {
148 {
149 {
150 .name = "SSC0 PCM out",
151 .pdc = &pdc_tx_reg,
152 .mask = &ssc_tx_mask,
153 },
154 {
155 .name = "SSC0 PCM in",
156 .pdc = &pdc_rx_reg,
157 .mask = &ssc_rx_mask,
158 },
159 },
160 {
161 {
162 .name = "SSC1 PCM out",
163 .pdc = &pdc_tx_reg,
164 .mask = &ssc_tx_mask,
165 },
166 {
167 .name = "SSC1 PCM in",
168 .pdc = &pdc_rx_reg,
169 .mask = &ssc_rx_mask,
170 },
171 },
172 {
173 {
174 .name = "SSC2 PCM out",
175 .pdc = &pdc_tx_reg,
176 .mask = &ssc_tx_mask,
177 },
178 {
179 .name = "SSC2 PCM in",
180 .pdc = &pdc_rx_reg,
181 .mask = &ssc_rx_mask,
182 },
183 },
184};
185
186
187
188static struct at32_ssc_info ssc_info[NUM_SSC_DEVICES] = {
189 {
190 .name = "ssc0",
191 .lock = __SPIN_LOCK_UNLOCKED(ssc_info[0].lock),
192 .dir_mask = SSC_DIR_MASK_UNUSED,
193 .initialized = 0,
194 },
195 {
196 .name = "ssc1",
197 .lock = __SPIN_LOCK_UNLOCKED(ssc_info[1].lock),
198 .dir_mask = SSC_DIR_MASK_UNUSED,
199 .initialized = 0,
200 },
201 {
202 .name = "ssc2",
203 .lock = __SPIN_LOCK_UNLOCKED(ssc_info[2].lock),
204 .dir_mask = SSC_DIR_MASK_UNUSED,
205 .initialized = 0,
206 },
207};
208
209
210
211
212/*-------------------------------------------------------------------------*\
213 * ISR
214\*-------------------------------------------------------------------------*/
215/*
216 * SSC interrupt handler. Passes PDC interrupts to the DMA interrupt
217 * handler in the PCM driver.
218 */
219static irqreturn_t at32_ssc_interrupt(int irq, void *dev_id)
220{
221 struct at32_ssc_info *ssc_p = dev_id;
222 struct at32_pcm_dma_params *dma_params;
223 u32 ssc_sr;
224 u32 ssc_substream_mask;
225 int i;
226
227 ssc_sr = (ssc_readl(ssc_p->ssc->regs, SR) &
228 ssc_readl(ssc_p->ssc->regs, IMR));
229
230 /*
231 * Loop through substreams attached to this SSC. If a DMA-related
232 * interrupt occured on that substream, call the DMA interrupt
233 * handler function, if one has been registered in the dma_param
234 * structure by the PCM driver.
235 */
236 for (i = 0; i < ARRAY_SIZE(ssc_p->dma_params); i++) {
237 dma_params = ssc_p->dma_params[i];
238
239 if ((dma_params != NULL) &&
240 (dma_params->dma_intr_handler != NULL)) {
241 ssc_substream_mask = (dma_params->mask->ssc_endx |
242 dma_params->mask->ssc_endbuf);
243 if (ssc_sr & ssc_substream_mask) {
244 dma_params->dma_intr_handler(ssc_sr,
245 dma_params->
246 substream);
247 }
248 }
249 }
250
251
252 return IRQ_HANDLED;
253}
254
255/*-------------------------------------------------------------------------*\
256 * DAI functions
257\*-------------------------------------------------------------------------*/
258/*
259 * Startup. Only that one substream allowed in each direction.
260 */
261static int at32_ssc_startup(struct snd_pcm_substream *substream)
262{
263 struct snd_soc_pcm_runtime *rtd = substream->private_data;
264 struct at32_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
265 int dir_mask;
266
267 dir_mask = ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
268 SSC_DIR_MASK_PLAYBACK : SSC_DIR_MASK_CAPTURE);
269
270 spin_lock_irq(&ssc_p->lock);
271 if (ssc_p->dir_mask & dir_mask) {
272 spin_unlock_irq(&ssc_p->lock);
273 return -EBUSY;
274 }
275 ssc_p->dir_mask |= dir_mask;
276 spin_unlock_irq(&ssc_p->lock);
277
278 return 0;
279}
280
281
282
283/*
284 * Shutdown. Clear DMA parameters and shutdown the SSC if there
285 * are no other substreams open.
286 */
287static void at32_ssc_shutdown(struct snd_pcm_substream *substream)
288{
289 struct snd_soc_pcm_runtime *rtd = substream->private_data;
290 struct at32_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
291 struct at32_pcm_dma_params *dma_params;
292 int dir_mask;
293
294 dma_params = ssc_p->dma_params[substream->stream];
295
296 if (dma_params != NULL) {
297 ssc_writel(dma_params->ssc->regs, CR,
298 dma_params->mask->ssc_disable);
299 pr_debug("%s disabled SSC_SR=0x%08x\n",
300 (substream->stream ? "receiver" : "transmit"),
301 ssc_readl(ssc_p->ssc->regs, SR));
302
303 dma_params->ssc = NULL;
304 dma_params->substream = NULL;
305 ssc_p->dma_params[substream->stream] = NULL;
306 }
307
308
309 dir_mask = 1 << substream->stream;
310 spin_lock_irq(&ssc_p->lock);
311 ssc_p->dir_mask &= ~dir_mask;
312 if (!ssc_p->dir_mask) {
313 /* Shutdown the SSC clock */
314 pr_debug("at32-ssc: Stopping user %d clock\n",
315 ssc_p->ssc->user);
316 clk_disable(ssc_p->ssc->clk);
317
318 if (ssc_p->initialized) {
319 free_irq(ssc_p->ssc->irq, ssc_p);
320 ssc_p->initialized = 0;
321 }
322
323 /* Reset the SSC */
324 ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST));
325
326 /* clear the SSC dividers */
327 ssc_p->cmr_div = 0;
328 ssc_p->tcmr_period = 0;
329 ssc_p->rcmr_period = 0;
330 }
331 spin_unlock_irq(&ssc_p->lock);
332}
333
334
335
336/*
337 * Set the SSC system clock rate
338 */
339static int at32_ssc_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
340 int clk_id, unsigned int freq, int dir)
341{
342 /* TODO: What the heck do I do here? */
343 return 0;
344}
345
346
347
348/*
349 * Record DAI format for use by hw_params()
350 */
351static int at32_ssc_set_dai_fmt(struct snd_soc_dai *cpu_dai,
352 unsigned int fmt)
353{
354 struct at32_ssc_info *ssc_p = &ssc_info[cpu_dai->id];
355
356 ssc_p->daifmt = fmt;
357 return 0;
358}
359
360
361
362/*
363 * Record SSC clock dividers for use in hw_params()
364 */
365static int at32_ssc_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
366 int div_id, int div)
367{
368 struct at32_ssc_info *ssc_p = &ssc_info[cpu_dai->id];
369
370 switch (div_id) {
371 case AT32_SSC_CMR_DIV:
372 /*
373 * The same master clock divider is used for both
374 * transmit and receive, so if a value has already
375 * been set, it must match this value
376 */
377 if (ssc_p->cmr_div == 0)
378 ssc_p->cmr_div = div;
379 else if (div != ssc_p->cmr_div)
380 return -EBUSY;
381 break;
382
383 case AT32_SSC_TCMR_PERIOD:
384 ssc_p->tcmr_period = div;
385 break;
386
387 case AT32_SSC_RCMR_PERIOD:
388 ssc_p->rcmr_period = div;
389 break;
390
391 default:
392 return -EINVAL;
393 }
394
395 return 0;
396}
397
398
399
400/*
401 * Configure the SSC
402 */
403static int at32_ssc_hw_params(struct snd_pcm_substream *substream,
404 struct snd_pcm_hw_params *params)
405{
406 struct snd_soc_pcm_runtime *rtd = substream->private_data;
407 int id = rtd->dai->cpu_dai->id;
408 struct at32_ssc_info *ssc_p = &ssc_info[id];
409 struct at32_pcm_dma_params *dma_params;
410 int channels, bits;
411 u32 tfmr, rfmr, tcmr, rcmr;
412 int start_event;
413 int ret;
414
415
416 /*
417 * Currently, there is only one set of dma_params for each direction.
418 * If more are added, this code will have to be changed to select
419 * the proper set
420 */
421 dma_params = &ssc_dma_params[id][substream->stream];
422 dma_params->ssc = ssc_p->ssc;
423 dma_params->substream = substream;
424
425 ssc_p->dma_params[substream->stream] = dma_params;
426
427
428 /*
429 * The cpu_dai->dma_data field is only used to communicate the
430 * appropriate DMA parameters to the PCM driver's hw_params()
431 * function. It should not be used for other purposes as it
432 * is common to all substreams.
433 */
434 rtd->dai->cpu_dai->dma_data = dma_params;
435
436 channels = params_channels(params);
437
438
439 /*
440 * Determine sample size in bits and the PDC increment
441 */
442 switch (params_format(params)) {
443 case SNDRV_PCM_FORMAT_S8:
444 bits = 8;
445 dma_params->pdc_xfer_size = 1;
446 break;
447
448 case SNDRV_PCM_FORMAT_S16:
449 bits = 16;
450 dma_params->pdc_xfer_size = 2;
451 break;
452
453 case SNDRV_PCM_FORMAT_S24:
454 bits = 24;
455 dma_params->pdc_xfer_size = 4;
456 break;
457
458 case SNDRV_PCM_FORMAT_S32:
459 bits = 32;
460 dma_params->pdc_xfer_size = 4;
461 break;
462
463 default:
464 pr_warning("at32-ssc: Unsupported PCM format %d",
465 params_format(params));
466 return -EINVAL;
467 }
468 pr_debug("at32-ssc: bits = %d, pdc_xfer_size = %d, channels = %d\n",
469 bits, dma_params->pdc_xfer_size, channels);
470
471
472 /*
473 * The SSC only supports up to 16-bit samples in I2S format, due
474 * to the size of the Frame Mode Register FSLEN field.
475 */
476 if ((ssc_p->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_I2S)
477 if (bits > 16) {
478 pr_warning("at32-ssc: "
479 "sample size %d is too large for I2S\n",
480 bits);
481 return -EINVAL;
482 }
483
484
485 /*
486 * Compute the SSC register settings
487 */
488 switch (ssc_p->daifmt & (SND_SOC_DAIFMT_FORMAT_MASK |
489 SND_SOC_DAIFMT_MASTER_MASK)) {
490 case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS:
491 /*
492 * I2S format, SSC provides BCLK and LRS clocks.
493 *
494 * The SSC transmit and receive clocks are generated from the
495 * MCK divider, and the BCLK signal is output on the SSC TK line
496 */
497 pr_debug("at32-ssc: SSC mode is I2S BCLK / FRAME master\n");
498 rcmr = (SSC_BF(RCMR_PERIOD, ssc_p->rcmr_period) |
499 SSC_BF(RCMR_STTDLY, START_DELAY) |
500 SSC_BF(RCMR_START, SSC_START_FALLING_RF) |
501 SSC_BF(RCMR_CKI, SSC_CKI_RISING) |
502 SSC_BF(RCMR_CKO, SSC_CKO_NONE) |
503 SSC_BF(RCMR_CKS, SSC_CKS_DIV));
504
505 rfmr = (SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE) |
506 SSC_BF(RFMR_FSOS, SSC_FSOS_NEGATIVE) |
507 SSC_BF(RFMR_FSLEN, bits - 1) |
508 SSC_BF(RFMR_DATNB, channels - 1) |
509 SSC_BIT(RFMR_MSBF) | SSC_BF(RFMR_DATLEN, bits - 1));
510
511 tcmr = (SSC_BF(TCMR_PERIOD, ssc_p->tcmr_period) |
512 SSC_BF(TCMR_STTDLY, START_DELAY) |
513 SSC_BF(TCMR_START, SSC_START_FALLING_RF) |
514 SSC_BF(TCMR_CKI, SSC_CKI_FALLING) |
515 SSC_BF(TCMR_CKO, SSC_CKO_CONTINUOUS) |
516 SSC_BF(TCMR_CKS, SSC_CKS_DIV));
517
518 tfmr = (SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE) |
519 SSC_BF(TFMR_FSOS, SSC_FSOS_NEGATIVE) |
520 SSC_BF(TFMR_FSLEN, bits - 1) |
521 SSC_BF(TFMR_DATNB, channels - 1) | SSC_BIT(TFMR_MSBF) |
522 SSC_BF(TFMR_DATLEN, bits - 1));
523 break;
524
525
526 case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM:
527 /*
528 * I2S format, CODEC supplies BCLK and LRC clock.
529 *
530 * The SSC transmit clock is obtained from the BCLK signal
531 * on the TK line, and the SSC receive clock is generated from
532 * the transmit clock.
533 *
534 * For single channel data, one sample is transferred on the
535 * falling edge of the LRC clock. For two channel data, one
536 * sample is transferred on both edges of the LRC clock.
537 */
538 pr_debug("at32-ssc: SSC mode is I2S BCLK / FRAME slave\n");
539 start_event = ((channels == 1) ?
540 SSC_START_FALLING_RF : SSC_START_EDGE_RF);
541
542 rcmr = (SSC_BF(RCMR_STTDLY, START_DELAY) |
543 SSC_BF(RCMR_START, start_event) |
544 SSC_BF(RCMR_CKI, SSC_CKI_RISING) |
545 SSC_BF(RCMR_CKO, SSC_CKO_NONE) |
546 SSC_BF(RCMR_CKS, SSC_CKS_CLOCK));
547
548 rfmr = (SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE) |
549 SSC_BF(RFMR_FSOS, SSC_FSOS_NONE) |
550 SSC_BIT(RFMR_MSBF) | SSC_BF(RFMR_DATLEN, bits - 1));
551
552 tcmr = (SSC_BF(TCMR_STTDLY, START_DELAY) |
553 SSC_BF(TCMR_START, start_event) |
554 SSC_BF(TCMR_CKI, SSC_CKI_FALLING) |
555 SSC_BF(TCMR_CKO, SSC_CKO_NONE) |
556 SSC_BF(TCMR_CKS, SSC_CKS_PIN));
557
558 tfmr = (SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE) |
559 SSC_BF(TFMR_FSOS, SSC_FSOS_NONE) |
560 SSC_BIT(TFMR_MSBF) | SSC_BF(TFMR_DATLEN, bits - 1));
561 break;
562
563
564 case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBS_CFS:
565 /*
566 * DSP/PCM Mode A format, SSC provides BCLK and LRC clocks.
567 *
568 * The SSC transmit and receive clocks are generated from the
569 * MCK divider, and the BCLK signal is output on the SSC TK line
570 */
571 pr_debug("at32-ssc: SSC mode is DSP A BCLK / FRAME master\n");
572 rcmr = (SSC_BF(RCMR_PERIOD, ssc_p->rcmr_period) |
573 SSC_BF(RCMR_STTDLY, 1) |
574 SSC_BF(RCMR_START, SSC_START_RISING_RF) |
575 SSC_BF(RCMR_CKI, SSC_CKI_RISING) |
576 SSC_BF(RCMR_CKO, SSC_CKO_NONE) |
577 SSC_BF(RCMR_CKS, SSC_CKS_DIV));
578
579 rfmr = (SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE) |
580 SSC_BF(RFMR_FSOS, SSC_FSOS_POSITIVE) |
581 SSC_BF(RFMR_DATNB, channels - 1) |
582 SSC_BIT(RFMR_MSBF) | SSC_BF(RFMR_DATLEN, bits - 1));
583
584 tcmr = (SSC_BF(TCMR_PERIOD, ssc_p->tcmr_period) |
585 SSC_BF(TCMR_STTDLY, 1) |
586 SSC_BF(TCMR_START, SSC_START_RISING_RF) |
587 SSC_BF(TCMR_CKI, SSC_CKI_RISING) |
588 SSC_BF(TCMR_CKO, SSC_CKO_CONTINUOUS) |
589 SSC_BF(TCMR_CKS, SSC_CKS_DIV));
590
591 tfmr = (SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE) |
592 SSC_BF(TFMR_FSOS, SSC_FSOS_POSITIVE) |
593 SSC_BF(TFMR_DATNB, channels - 1) |
594 SSC_BIT(TFMR_MSBF) | SSC_BF(TFMR_DATLEN, bits - 1));
595 break;
596
597
598 case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBM_CFM:
599 default:
600 pr_warning("at32-ssc: unsupported DAI format 0x%x\n",
601 ssc_p->daifmt);
602 return -EINVAL;
603 break;
604 }
605 pr_debug("at32-ssc: RCMR=%08x RFMR=%08x TCMR=%08x TFMR=%08x\n",
606 rcmr, rfmr, tcmr, tfmr);
607
608
609 if (!ssc_p->initialized) {
610 /* enable peripheral clock */
611 pr_debug("at32-ssc: Starting clock\n");
612 clk_enable(ssc_p->ssc->clk);
613
614 /* Reset the SSC and its PDC registers */
615 ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST));
616
617 ssc_writel(ssc_p->ssc->regs, PDC_RPR, 0);
618 ssc_writel(ssc_p->ssc->regs, PDC_RCR, 0);
619 ssc_writel(ssc_p->ssc->regs, PDC_RNPR, 0);
620 ssc_writel(ssc_p->ssc->regs, PDC_RNCR, 0);
621
622 ssc_writel(ssc_p->ssc->regs, PDC_TPR, 0);
623 ssc_writel(ssc_p->ssc->regs, PDC_TCR, 0);
624 ssc_writel(ssc_p->ssc->regs, PDC_TNPR, 0);
625 ssc_writel(ssc_p->ssc->regs, PDC_TNCR, 0);
626
627 ret = request_irq(ssc_p->ssc->irq, at32_ssc_interrupt, 0,
628 ssc_p->name, ssc_p);
629 if (ret < 0) {
630 pr_warning("at32-ssc: request irq failed (%d)\n", ret);
631 pr_debug("at32-ssc: Stopping clock\n");
632 clk_disable(ssc_p->ssc->clk);
633 return ret;
634 }
635
636 ssc_p->initialized = 1;
637 }
638
639 /* Set SSC clock mode register */
640 ssc_writel(ssc_p->ssc->regs, CMR, ssc_p->cmr_div);
641
642 /* set receive clock mode and format */
643 ssc_writel(ssc_p->ssc->regs, RCMR, rcmr);
644 ssc_writel(ssc_p->ssc->regs, RFMR, rfmr);
645
646 /* set transmit clock mode and format */
647 ssc_writel(ssc_p->ssc->regs, TCMR, tcmr);
648 ssc_writel(ssc_p->ssc->regs, TFMR, tfmr);
649
650 pr_debug("at32-ssc: SSC initialized\n");
651 return 0;
652}
653
654
655
656static int at32_ssc_prepare(struct snd_pcm_substream *substream)
657{
658 struct snd_soc_pcm_runtime *rtd = substream->private_data;
659 struct at32_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
660 struct at32_pcm_dma_params *dma_params;
661
662 dma_params = ssc_p->dma_params[substream->stream];
663
664 ssc_writel(dma_params->ssc->regs, CR, dma_params->mask->ssc_enable);
665
666 return 0;
667}
668
669
670
671#ifdef CONFIG_PM
672static int at32_ssc_suspend(struct platform_device *pdev,
673 struct snd_soc_dai *cpu_dai)
674{
675 struct at32_ssc_info *ssc_p;
676
677 if (!cpu_dai->active)
678 return 0;
679
680 ssc_p = &ssc_info[cpu_dai->id];
681
682 /* Save the status register before disabling transmit and receive */
683 ssc_p->ssc_state.ssc_sr = ssc_readl(ssc_p->ssc->regs, SR);
684 ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_TXDIS) | SSC_BIT(CR_RXDIS));
685
686 /* Save the current interrupt mask, then disable unmasked interrupts */
687 ssc_p->ssc_state.ssc_imr = ssc_readl(ssc_p->ssc->regs, IMR);
688 ssc_writel(ssc_p->ssc->regs, IDR, ssc_p->ssc_state.ssc_imr);
689
690 ssc_p->ssc_state.ssc_cmr = ssc_readl(ssc_p->ssc->regs, CMR);
691 ssc_p->ssc_state.ssc_rcmr = ssc_readl(ssc_p->ssc->regs, RCMR);
692 ssc_p->ssc_state.ssc_rfmr = ssc_readl(ssc_p->ssc->regs, RFMR);
693 ssc_p->ssc_state.ssc_tcmr = ssc_readl(ssc_p->ssc->regs, TCMR);
694 ssc_p->ssc_state.ssc_tfmr = ssc_readl(ssc_p->ssc->regs, TFMR);
695
696 return 0;
697}
698
699
700
701static int at32_ssc_resume(struct platform_device *pdev,
702 struct snd_soc_dai *cpu_dai)
703{
704 struct at32_ssc_info *ssc_p;
705 u32 cr;
706
707 if (!cpu_dai->active)
708 return 0;
709
710 ssc_p = &ssc_info[cpu_dai->id];
711
712 /* restore SSC register settings */
713 ssc_writel(ssc_p->ssc->regs, TFMR, ssc_p->ssc_state.ssc_tfmr);
714 ssc_writel(ssc_p->ssc->regs, TCMR, ssc_p->ssc_state.ssc_tcmr);
715 ssc_writel(ssc_p->ssc->regs, RFMR, ssc_p->ssc_state.ssc_rfmr);
716 ssc_writel(ssc_p->ssc->regs, RCMR, ssc_p->ssc_state.ssc_rcmr);
717 ssc_writel(ssc_p->ssc->regs, CMR, ssc_p->ssc_state.ssc_cmr);
718
719 /* re-enable interrupts */
720 ssc_writel(ssc_p->ssc->regs, IER, ssc_p->ssc_state.ssc_imr);
721
722 /* Re-enable recieve and transmit as appropriate */
723 cr = 0;
724 cr |=
725 (ssc_p->ssc_state.ssc_sr & SSC_BIT(SR_RXEN)) ? SSC_BIT(CR_RXEN) : 0;
726 cr |=
727 (ssc_p->ssc_state.ssc_sr & SSC_BIT(SR_TXEN)) ? SSC_BIT(CR_TXEN) : 0;
728 ssc_writel(ssc_p->ssc->regs, CR, cr);
729
730 return 0;
731}
732#else /* CONFIG_PM */
733# define at32_ssc_suspend NULL
734# define at32_ssc_resume NULL
735#endif /* CONFIG_PM */
736
737
738#define AT32_SSC_RATES \
739 (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \
740 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
741 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
742
743
744#define AT32_SSC_FORMATS \
745 (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16 | \
746 SNDRV_PCM_FMTBIT_S24 | SNDRV_PCM_FMTBIT_S32)
747
748
749struct snd_soc_dai at32_ssc_dai[NUM_SSC_DEVICES] = {
750 {
751 .name = "at32-ssc0",
752 .id = 0,
753 .type = SND_SOC_DAI_PCM,
754 .suspend = at32_ssc_suspend,
755 .resume = at32_ssc_resume,
756 .playback = {
757 .channels_min = 1,
758 .channels_max = 2,
759 .rates = AT32_SSC_RATES,
760 .formats = AT32_SSC_FORMATS,
761 },
762 .capture = {
763 .channels_min = 1,
764 .channels_max = 2,
765 .rates = AT32_SSC_RATES,
766 .formats = AT32_SSC_FORMATS,
767 },
768 .ops = {
769 .startup = at32_ssc_startup,
770 .shutdown = at32_ssc_shutdown,
771 .prepare = at32_ssc_prepare,
772 .hw_params = at32_ssc_hw_params,
773 },
774 .dai_ops = {
775 .set_sysclk = at32_ssc_set_dai_sysclk,
776 .set_fmt = at32_ssc_set_dai_fmt,
777 .set_clkdiv = at32_ssc_set_dai_clkdiv,
778 },
779 .private_data = &ssc_info[0],
780 },
781 {
782 .name = "at32-ssc1",
783 .id = 1,
784 .type = SND_SOC_DAI_PCM,
785 .suspend = at32_ssc_suspend,
786 .resume = at32_ssc_resume,
787 .playback = {
788 .channels_min = 1,
789 .channels_max = 2,
790 .rates = AT32_SSC_RATES,
791 .formats = AT32_SSC_FORMATS,
792 },
793 .capture = {
794 .channels_min = 1,
795 .channels_max = 2,
796 .rates = AT32_SSC_RATES,
797 .formats = AT32_SSC_FORMATS,
798 },
799 .ops = {
800 .startup = at32_ssc_startup,
801 .shutdown = at32_ssc_shutdown,
802 .prepare = at32_ssc_prepare,
803 .hw_params = at32_ssc_hw_params,
804 },
805 .dai_ops = {
806 .set_sysclk = at32_ssc_set_dai_sysclk,
807 .set_fmt = at32_ssc_set_dai_fmt,
808 .set_clkdiv = at32_ssc_set_dai_clkdiv,
809 },
810 .private_data = &ssc_info[1],
811 },
812 {
813 .name = "at32-ssc2",
814 .id = 2,
815 .type = SND_SOC_DAI_PCM,
816 .suspend = at32_ssc_suspend,
817 .resume = at32_ssc_resume,
818 .playback = {
819 .channels_min = 1,
820 .channels_max = 2,
821 .rates = AT32_SSC_RATES,
822 .formats = AT32_SSC_FORMATS,
823 },
824 .capture = {
825 .channels_min = 1,
826 .channels_max = 2,
827 .rates = AT32_SSC_RATES,
828 .formats = AT32_SSC_FORMATS,
829 },
830 .ops = {
831 .startup = at32_ssc_startup,
832 .shutdown = at32_ssc_shutdown,
833 .prepare = at32_ssc_prepare,
834 .hw_params = at32_ssc_hw_params,
835 },
836 .dai_ops = {
837 .set_sysclk = at32_ssc_set_dai_sysclk,
838 .set_fmt = at32_ssc_set_dai_fmt,
839 .set_clkdiv = at32_ssc_set_dai_clkdiv,
840 },
841 .private_data = &ssc_info[2],
842 },
843};
844EXPORT_SYMBOL_GPL(at32_ssc_dai);
845
846
847MODULE_AUTHOR("Geoffrey Wossum <gwossum@acm.org>");
848MODULE_DESCRIPTION("AT32 SSC ASoC Interface");
849MODULE_LICENSE("GPL");
diff --git a/sound/soc/at32/at32-ssc.h b/sound/soc/at32/at32-ssc.h
deleted file mode 100644
index 3c052dbbe460..000000000000
--- a/sound/soc/at32/at32-ssc.h
+++ /dev/null
@@ -1,59 +0,0 @@
1/* sound/soc/at32/at32-ssc.h
2 * ASoC SSC interface for Atmel AT32 SoC
3 *
4 * Copyright (C) 2008 Long Range Systems
5 * Geoffrey Wossum <gwossum@acm.org>
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 __SOUND_SOC_AT32_AT32_SSC_H
13#define __SOUND_SOC_AT32_AT32_SSC_H __FILE__
14
15#include <linux/types.h>
16#include <linux/atmel-ssc.h>
17
18#include "at32-pcm.h"
19
20
21
22struct at32_ssc_state {
23 u32 ssc_cmr;
24 u32 ssc_rcmr;
25 u32 ssc_rfmr;
26 u32 ssc_tcmr;
27 u32 ssc_tfmr;
28 u32 ssc_sr;
29 u32 ssc_imr;
30};
31
32
33
34struct at32_ssc_info {
35 char *name;
36 struct ssc_device *ssc;
37 spinlock_t lock; /* lock for dir_mask */
38 unsigned short dir_mask; /* 0=unused, 1=playback, 2=capture */
39 unsigned short initialized; /* true if SSC has been initialized */
40 unsigned short daifmt;
41 unsigned short cmr_div;
42 unsigned short tcmr_period;
43 unsigned short rcmr_period;
44 struct at32_pcm_dma_params *dma_params[2];
45 struct at32_ssc_state ssc_state;
46};
47
48
49/* SSC divider ids */
50#define AT32_SSC_CMR_DIV 0 /* MCK divider for BCLK */
51#define AT32_SSC_TCMR_PERIOD 1 /* BCLK divider for transmit FS */
52#define AT32_SSC_RCMR_PERIOD 2 /* BCLK divider for receive FS */
53
54
55extern struct snd_soc_dai at32_ssc_dai[];
56
57
58
59#endif /* __SOUND_SOC_AT32_AT32_SSC_H */
diff --git a/sound/soc/at91/Kconfig b/sound/soc/at91/Kconfig
deleted file mode 100644
index 85a883299c2e..000000000000
--- a/sound/soc/at91/Kconfig
+++ /dev/null
@@ -1,10 +0,0 @@
1config SND_AT91_SOC
2 tristate "SoC Audio for the Atmel AT91 System-on-Chip"
3 depends on ARCH_AT91
4 help
5 Say Y or M if you want to add support for codecs attached to
6 the AT91 SSC interface. You will also need
7 to select the audio interfaces to support below.
8
9config SND_AT91_SOC_SSC
10 tristate
diff --git a/sound/soc/at91/Makefile b/sound/soc/at91/Makefile
deleted file mode 100644
index b817f11df286..000000000000
--- a/sound/soc/at91/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
1# AT91 Platform Support
2snd-soc-at91-objs := at91-pcm.o
3snd-soc-at91-ssc-objs := at91-ssc.o
4
5obj-$(CONFIG_SND_AT91_SOC) += snd-soc-at91.o
6obj-$(CONFIG_SND_AT91_SOC_SSC) += snd-soc-at91-ssc.o
diff --git a/sound/soc/at91/at91-pcm.c b/sound/soc/at91/at91-pcm.c
deleted file mode 100644
index 7ab48bd25e4c..000000000000
--- a/sound/soc/at91/at91-pcm.c
+++ /dev/null
@@ -1,434 +0,0 @@
1/*
2 * at91-pcm.c -- ALSA PCM interface for the Atmel AT91 SoC
3 *
4 * Author: Frank Mandarino <fmandarino@endrelia.com>
5 * Endrelia Technologies Inc.
6 * Created: Mar 3, 2006
7 *
8 * Based on pxa2xx-pcm.c by:
9 *
10 * Author: Nicolas Pitre
11 * Created: Nov 30, 2004
12 * Copyright: (C) 2004 MontaVista Software, Inc.
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 version 2 as
16 * published by the Free Software Foundation.
17 */
18
19#include <linux/module.h>
20#include <linux/init.h>
21#include <linux/platform_device.h>
22#include <linux/slab.h>
23#include <linux/dma-mapping.h>
24#include <linux/atmel_pdc.h>
25
26#include <sound/core.h>
27#include <sound/pcm.h>
28#include <sound/pcm_params.h>
29#include <sound/soc.h>
30
31#include <mach/hardware.h>
32#include <mach/at91_ssc.h>
33
34#include "at91-pcm.h"
35
36#if 0
37#define DBG(x...) printk(KERN_INFO "at91-pcm: " x)
38#else
39#define DBG(x...)
40#endif
41
42static const struct snd_pcm_hardware at91_pcm_hardware = {
43 .info = SNDRV_PCM_INFO_MMAP |
44 SNDRV_PCM_INFO_MMAP_VALID |
45 SNDRV_PCM_INFO_INTERLEAVED |
46 SNDRV_PCM_INFO_PAUSE,
47 .formats = SNDRV_PCM_FMTBIT_S16_LE,
48 .period_bytes_min = 32,
49 .period_bytes_max = 8192,
50 .periods_min = 2,
51 .periods_max = 1024,
52 .buffer_bytes_max = 32 * 1024,
53};
54
55struct at91_runtime_data {
56 struct at91_pcm_dma_params *params;
57 dma_addr_t dma_buffer; /* physical address of dma buffer */
58 dma_addr_t dma_buffer_end; /* first address beyond DMA buffer */
59 size_t period_size;
60 dma_addr_t period_ptr; /* physical address of next period */
61 u32 pdc_xpr_save; /* PDC register save */
62 u32 pdc_xcr_save;
63 u32 pdc_xnpr_save;
64 u32 pdc_xncr_save;
65};
66
67static void at91_pcm_dma_irq(u32 ssc_sr,
68 struct snd_pcm_substream *substream)
69{
70 struct at91_runtime_data *prtd = substream->runtime->private_data;
71 struct at91_pcm_dma_params *params = prtd->params;
72 static int count = 0;
73
74 count++;
75
76 if (ssc_sr & params->mask->ssc_endbuf) {
77
78 printk(KERN_WARNING
79 "at91-pcm: buffer %s on %s (SSC_SR=%#x, count=%d)\n",
80 substream->stream == SNDRV_PCM_STREAM_PLAYBACK
81 ? "underrun" : "overrun",
82 params->name, ssc_sr, count);
83
84 /* re-start the PDC */
85 at91_ssc_write(params->ssc_base + ATMEL_PDC_PTCR, params->mask->pdc_disable);
86
87 prtd->period_ptr += prtd->period_size;
88 if (prtd->period_ptr >= prtd->dma_buffer_end) {
89 prtd->period_ptr = prtd->dma_buffer;
90 }
91
92 at91_ssc_write(params->ssc_base + params->pdc->xpr, prtd->period_ptr);
93 at91_ssc_write(params->ssc_base + params->pdc->xcr,
94 prtd->period_size / params->pdc_xfer_size);
95
96 at91_ssc_write(params->ssc_base + ATMEL_PDC_PTCR, params->mask->pdc_enable);
97 }
98
99 if (ssc_sr & params->mask->ssc_endx) {
100
101 /* Load the PDC next pointer and counter registers */
102 prtd->period_ptr += prtd->period_size;
103 if (prtd->period_ptr >= prtd->dma_buffer_end) {
104 prtd->period_ptr = prtd->dma_buffer;
105 }
106 at91_ssc_write(params->ssc_base + params->pdc->xnpr,
107 prtd->period_ptr);
108 at91_ssc_write(params->ssc_base + params->pdc->xncr,
109 prtd->period_size / params->pdc_xfer_size);
110 }
111
112 snd_pcm_period_elapsed(substream);
113}
114
115static int at91_pcm_hw_params(struct snd_pcm_substream *substream,
116 struct snd_pcm_hw_params *params)
117{
118 struct snd_pcm_runtime *runtime = substream->runtime;
119 struct at91_runtime_data *prtd = runtime->private_data;
120 struct snd_soc_pcm_runtime *rtd = substream->private_data;
121
122 /* this may get called several times by oss emulation
123 * with different params */
124
125 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
126 runtime->dma_bytes = params_buffer_bytes(params);
127
128 prtd->params = rtd->dai->cpu_dai->dma_data;
129 prtd->params->dma_intr_handler = at91_pcm_dma_irq;
130
131 prtd->dma_buffer = runtime->dma_addr;
132 prtd->dma_buffer_end = runtime->dma_addr + runtime->dma_bytes;
133 prtd->period_size = params_period_bytes(params);
134
135 DBG("hw_params: DMA for %s initialized (dma_bytes=%d, period_size=%d)\n",
136 prtd->params->name, runtime->dma_bytes, prtd->period_size);
137 return 0;
138}
139
140static int at91_pcm_hw_free(struct snd_pcm_substream *substream)
141{
142 struct at91_runtime_data *prtd = substream->runtime->private_data;
143 struct at91_pcm_dma_params *params = prtd->params;
144
145 if (params != NULL) {
146 at91_ssc_write(params->ssc_base + ATMEL_PDC_PTCR, params->mask->pdc_disable);
147 prtd->params->dma_intr_handler = NULL;
148 }
149
150 return 0;
151}
152
153static int at91_pcm_prepare(struct snd_pcm_substream *substream)
154{
155 struct at91_runtime_data *prtd = substream->runtime->private_data;
156 struct at91_pcm_dma_params *params = prtd->params;
157
158 at91_ssc_write(params->ssc_base + AT91_SSC_IDR,
159 params->mask->ssc_endx | params->mask->ssc_endbuf);
160
161 at91_ssc_write(params->ssc_base + ATMEL_PDC_PTCR, params->mask->pdc_disable);
162 return 0;
163}
164
165static int at91_pcm_trigger(struct snd_pcm_substream *substream,
166 int cmd)
167{
168 struct at91_runtime_data *prtd = substream->runtime->private_data;
169 struct at91_pcm_dma_params *params = prtd->params;
170 int ret = 0;
171
172 switch (cmd) {
173 case SNDRV_PCM_TRIGGER_START:
174 prtd->period_ptr = prtd->dma_buffer;
175
176 at91_ssc_write(params->ssc_base + params->pdc->xpr, prtd->period_ptr);
177 at91_ssc_write(params->ssc_base + params->pdc->xcr,
178 prtd->period_size / params->pdc_xfer_size);
179
180 prtd->period_ptr += prtd->period_size;
181 at91_ssc_write(params->ssc_base + params->pdc->xnpr, prtd->period_ptr);
182 at91_ssc_write(params->ssc_base + params->pdc->xncr,
183 prtd->period_size / params->pdc_xfer_size);
184
185 DBG("trigger: period_ptr=%lx, xpr=%lx, xcr=%ld, xnpr=%lx, xncr=%ld\n",
186 (unsigned long) prtd->period_ptr,
187 at91_ssc_read(params->ssc_base + params->pdc->xpr),
188 at91_ssc_read(params->ssc_base + params->pdc->xcr),
189 at91_ssc_read(params->ssc_base + params->pdc->xnpr),
190 at91_ssc_read(params->ssc_base + params->pdc->xncr));
191
192 at91_ssc_write(params->ssc_base + AT91_SSC_IER,
193 params->mask->ssc_endx | params->mask->ssc_endbuf);
194
195 at91_ssc_write(params->ssc_base + ATMEL_PDC_PTCR,
196 params->mask->pdc_enable);
197
198 DBG("sr=%lx imr=%lx\n",
199 at91_ssc_read(params->ssc_base + AT91_SSC_SR),
200 at91_ssc_read(params->ssc_base + AT91_SSC_IMR));
201 break;
202
203 case SNDRV_PCM_TRIGGER_STOP:
204 case SNDRV_PCM_TRIGGER_SUSPEND:
205 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
206 at91_ssc_write(params->ssc_base + ATMEL_PDC_PTCR, params->mask->pdc_disable);
207 break;
208
209 case SNDRV_PCM_TRIGGER_RESUME:
210 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
211 at91_ssc_write(params->ssc_base + ATMEL_PDC_PTCR, params->mask->pdc_enable);
212 break;
213
214 default:
215 ret = -EINVAL;
216 }
217
218 return ret;
219}
220
221static snd_pcm_uframes_t at91_pcm_pointer(
222 struct snd_pcm_substream *substream)
223{
224 struct snd_pcm_runtime *runtime = substream->runtime;
225 struct at91_runtime_data *prtd = runtime->private_data;
226 struct at91_pcm_dma_params *params = prtd->params;
227 dma_addr_t ptr;
228 snd_pcm_uframes_t x;
229
230 ptr = (dma_addr_t) at91_ssc_read(params->ssc_base + params->pdc->xpr);
231 x = bytes_to_frames(runtime, ptr - prtd->dma_buffer);
232
233 if (x == runtime->buffer_size)
234 x = 0;
235 return x;
236}
237
238static int at91_pcm_open(struct snd_pcm_substream *substream)
239{
240 struct snd_pcm_runtime *runtime = substream->runtime;
241 struct at91_runtime_data *prtd;
242 int ret = 0;
243
244 snd_soc_set_runtime_hwparams(substream, &at91_pcm_hardware);
245
246 /* ensure that buffer size is a multiple of period size */
247 ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
248 if (ret < 0)
249 goto out;
250
251 prtd = kzalloc(sizeof(struct at91_runtime_data), GFP_KERNEL);
252 if (prtd == NULL) {
253 ret = -ENOMEM;
254 goto out;
255 }
256 runtime->private_data = prtd;
257
258 out:
259 return ret;
260}
261
262static int at91_pcm_close(struct snd_pcm_substream *substream)
263{
264 struct at91_runtime_data *prtd = substream->runtime->private_data;
265
266 kfree(prtd);
267 return 0;
268}
269
270static int at91_pcm_mmap(struct snd_pcm_substream *substream,
271 struct vm_area_struct *vma)
272{
273 struct snd_pcm_runtime *runtime = substream->runtime;
274
275 return dma_mmap_writecombine(substream->pcm->card->dev, vma,
276 runtime->dma_area,
277 runtime->dma_addr,
278 runtime->dma_bytes);
279}
280
281struct snd_pcm_ops at91_pcm_ops = {
282 .open = at91_pcm_open,
283 .close = at91_pcm_close,
284 .ioctl = snd_pcm_lib_ioctl,
285 .hw_params = at91_pcm_hw_params,
286 .hw_free = at91_pcm_hw_free,
287 .prepare = at91_pcm_prepare,
288 .trigger = at91_pcm_trigger,
289 .pointer = at91_pcm_pointer,
290 .mmap = at91_pcm_mmap,
291};
292
293static int at91_pcm_preallocate_dma_buffer(struct snd_pcm *pcm,
294 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 = at91_pcm_hardware.buffer_bytes_max;
299
300 buf->dev.type = SNDRV_DMA_TYPE_DEV;
301 buf->dev.dev = pcm->card->dev;
302 buf->private_data = NULL;
303 buf->area = dma_alloc_writecombine(pcm->card->dev, size,
304 &buf->addr, GFP_KERNEL);
305
306 DBG("preallocate_dma_buffer: area=%p, addr=%p, size=%d\n",
307 (void *) buf->area,
308 (void *) buf->addr,
309 size);
310
311 if (!buf->area)
312 return -ENOMEM;
313
314 buf->bytes = size;
315 return 0;
316}
317
318static u64 at91_pcm_dmamask = 0xffffffff;
319
320static int at91_pcm_new(struct snd_card *card,
321 struct snd_soc_dai *dai, struct snd_pcm *pcm)
322{
323 int ret = 0;
324
325 if (!card->dev->dma_mask)
326 card->dev->dma_mask = &at91_pcm_dmamask;
327 if (!card->dev->coherent_dma_mask)
328 card->dev->coherent_dma_mask = 0xffffffff;
329
330 if (dai->playback.channels_min) {
331 ret = at91_pcm_preallocate_dma_buffer(pcm,
332 SNDRV_PCM_STREAM_PLAYBACK);
333 if (ret)
334 goto out;
335 }
336
337 if (dai->capture.channels_min) {
338 ret = at91_pcm_preallocate_dma_buffer(pcm,
339 SNDRV_PCM_STREAM_CAPTURE);
340 if (ret)
341 goto out;
342 }
343 out:
344 return ret;
345}
346
347static void at91_pcm_free_dma_buffers(struct snd_pcm *pcm)
348{
349 struct snd_pcm_substream *substream;
350 struct snd_dma_buffer *buf;
351 int stream;
352
353 for (stream = 0; stream < 2; stream++) {
354 substream = pcm->streams[stream].substream;
355 if (!substream)
356 continue;
357
358 buf = &substream->dma_buffer;
359 if (!buf->area)
360 continue;
361
362 dma_free_writecombine(pcm->card->dev, buf->bytes,
363 buf->area, buf->addr);
364 buf->area = NULL;
365 }
366}
367
368#ifdef CONFIG_PM
369static int at91_pcm_suspend(struct platform_device *pdev,
370 struct snd_soc_dai *dai)
371{
372 struct snd_pcm_runtime *runtime = dai->runtime;
373 struct at91_runtime_data *prtd;
374 struct at91_pcm_dma_params *params;
375
376 if (!runtime)
377 return 0;
378
379 prtd = runtime->private_data;
380 params = prtd->params;
381
382 /* disable the PDC and save the PDC registers */
383
384 at91_ssc_write(params->ssc_base + ATMEL_PDC_PTCR, params->mask->pdc_disable);
385
386 prtd->pdc_xpr_save = at91_ssc_read(params->ssc_base + params->pdc->xpr);
387 prtd->pdc_xcr_save = at91_ssc_read(params->ssc_base + params->pdc->xcr);
388 prtd->pdc_xnpr_save = at91_ssc_read(params->ssc_base + params->pdc->xnpr);
389 prtd->pdc_xncr_save = at91_ssc_read(params->ssc_base + params->pdc->xncr);
390
391 return 0;
392}
393
394static int at91_pcm_resume(struct platform_device *pdev,
395 struct snd_soc_dai *dai)
396{
397 struct snd_pcm_runtime *runtime = dai->runtime;
398 struct at91_runtime_data *prtd;
399 struct at91_pcm_dma_params *params;
400
401 if (!runtime)
402 return 0;
403
404 prtd = runtime->private_data;
405 params = prtd->params;
406
407 /* restore the PDC registers and enable the PDC */
408 at91_ssc_write(params->ssc_base + params->pdc->xpr, prtd->pdc_xpr_save);
409 at91_ssc_write(params->ssc_base + params->pdc->xcr, prtd->pdc_xcr_save);
410 at91_ssc_write(params->ssc_base + params->pdc->xnpr, prtd->pdc_xnpr_save);
411 at91_ssc_write(params->ssc_base + params->pdc->xncr, prtd->pdc_xncr_save);
412
413 at91_ssc_write(params->ssc_base + ATMEL_PDC_PTCR, params->mask->pdc_enable);
414 return 0;
415}
416#else
417#define at91_pcm_suspend NULL
418#define at91_pcm_resume NULL
419#endif
420
421struct snd_soc_platform at91_soc_platform = {
422 .name = "at91-audio",
423 .pcm_ops = &at91_pcm_ops,
424 .pcm_new = at91_pcm_new,
425 .pcm_free = at91_pcm_free_dma_buffers,
426 .suspend = at91_pcm_suspend,
427 .resume = at91_pcm_resume,
428};
429
430EXPORT_SYMBOL_GPL(at91_soc_platform);
431
432MODULE_AUTHOR("Frank Mandarino <fmandarino@endrelia.com>");
433MODULE_DESCRIPTION("Atmel AT91 PCM module");
434MODULE_LICENSE("GPL");
diff --git a/sound/soc/at91/at91-pcm.h b/sound/soc/at91/at91-pcm.h
deleted file mode 100644
index e5aada2cb102..000000000000
--- a/sound/soc/at91/at91-pcm.h
+++ /dev/null
@@ -1,72 +0,0 @@
1/*
2 * at91-pcm.h - ALSA PCM interface for the Atmel AT91 SoC
3 *
4 * Author: Frank Mandarino <fmandarino@endrelia.com>
5 * Endrelia Technologies Inc.
6 * Created: Mar 3, 2006
7 *
8 * Based on pxa2xx-pcm.h by:
9 *
10 * Author: Nicolas Pitre
11 * Created: Nov 30, 2004
12 * Copyright: MontaVista Software, Inc.
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 version 2 as
16 * published by the Free Software Foundation.
17 */
18
19#ifndef _AT91_PCM_H
20#define _AT91_PCM_H
21
22#include <mach/hardware.h>
23
24struct at91_ssc_periph {
25 void __iomem *base;
26 u32 pid;
27};
28
29/*
30 * Registers and status bits that are required by the PCM driver.
31 */
32struct at91_pdc_regs {
33 unsigned int xpr; /* PDC recv/trans pointer */
34 unsigned int xcr; /* PDC recv/trans counter */
35 unsigned int xnpr; /* PDC next recv/trans pointer */
36 unsigned int xncr; /* PDC next recv/trans counter */
37 unsigned int ptcr; /* PDC transfer control */
38};
39
40struct at91_ssc_mask {
41 u32 ssc_enable; /* SSC recv/trans enable */
42 u32 ssc_disable; /* SSC recv/trans disable */
43 u32 ssc_endx; /* SSC ENDTX or ENDRX */
44 u32 ssc_endbuf; /* SSC TXBUFE or RXBUFF */
45 u32 pdc_enable; /* PDC recv/trans enable */
46 u32 pdc_disable; /* PDC recv/trans disable */
47};
48
49/*
50 * This structure, shared between the PCM driver and the interface,
51 * contains all information required by the PCM driver to perform the
52 * PDC DMA operation. All fields except dma_intr_handler() are initialized
53 * by the interface. The dms_intr_handler() pointer is set by the PCM
54 * driver and called by the interface SSC interrupt handler if it is
55 * non-NULL.
56 */
57struct at91_pcm_dma_params {
58 char *name; /* stream identifier */
59 int pdc_xfer_size; /* PDC counter increment in bytes */
60 void __iomem *ssc_base; /* SSC base address */
61 struct at91_pdc_regs *pdc; /* PDC receive or transmit registers */
62 struct at91_ssc_mask *mask;/* SSC & PDC status bits */
63 struct snd_pcm_substream *substream;
64 void (*dma_intr_handler)(u32, struct snd_pcm_substream *);
65};
66
67extern struct snd_soc_platform at91_soc_platform;
68
69#define at91_ssc_read(a) ((unsigned long) __raw_readl(a))
70#define at91_ssc_write(a,v) __raw_writel((v),(a))
71
72#endif /* _AT91_PCM_H */
diff --git a/sound/soc/at91/at91-ssc.c b/sound/soc/at91/at91-ssc.c
deleted file mode 100644
index 1b61cc461261..000000000000
--- a/sound/soc/at91/at91-ssc.c
+++ /dev/null
@@ -1,791 +0,0 @@
1/*
2 * at91-ssc.c -- ALSA SoC AT91 SSC Audio Layer Platform driver
3 *
4 * Author: Frank Mandarino <fmandarino@endrelia.com>
5 * Endrelia Technologies Inc.
6 *
7 * Based on pxa2xx Platform drivers by
8 * Liam Girdwood <lrg@slimlogic.co.uk>
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 *
15 */
16
17#include <linux/init.h>
18#include <linux/module.h>
19#include <linux/interrupt.h>
20#include <linux/device.h>
21#include <linux/delay.h>
22#include <linux/clk.h>
23#include <linux/atmel_pdc.h>
24
25#include <sound/core.h>
26#include <sound/pcm.h>
27#include <sound/pcm_params.h>
28#include <sound/initval.h>
29#include <sound/soc.h>
30
31#include <mach/hardware.h>
32#include <mach/at91_pmc.h>
33#include <mach/at91_ssc.h>
34
35#include "at91-pcm.h"
36#include "at91-ssc.h"
37
38#if 0
39#define DBG(x...) printk(KERN_DEBUG "at91-ssc:" x)
40#else
41#define DBG(x...)
42#endif
43
44#if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9G20)
45#define NUM_SSC_DEVICES 1
46#else
47#define NUM_SSC_DEVICES 3
48#endif
49
50
51/*
52 * SSC PDC registers required by the PCM DMA engine.
53 */
54static struct at91_pdc_regs pdc_tx_reg = {
55 .xpr = ATMEL_PDC_TPR,
56 .xcr = ATMEL_PDC_TCR,
57 .xnpr = ATMEL_PDC_TNPR,
58 .xncr = ATMEL_PDC_TNCR,
59};
60
61static struct at91_pdc_regs pdc_rx_reg = {
62 .xpr = ATMEL_PDC_RPR,
63 .xcr = ATMEL_PDC_RCR,
64 .xnpr = ATMEL_PDC_RNPR,
65 .xncr = ATMEL_PDC_RNCR,
66};
67
68/*
69 * SSC & PDC status bits for transmit and receive.
70 */
71static struct at91_ssc_mask ssc_tx_mask = {
72 .ssc_enable = AT91_SSC_TXEN,
73 .ssc_disable = AT91_SSC_TXDIS,
74 .ssc_endx = AT91_SSC_ENDTX,
75 .ssc_endbuf = AT91_SSC_TXBUFE,
76 .pdc_enable = ATMEL_PDC_TXTEN,
77 .pdc_disable = ATMEL_PDC_TXTDIS,
78};
79
80static struct at91_ssc_mask ssc_rx_mask = {
81 .ssc_enable = AT91_SSC_RXEN,
82 .ssc_disable = AT91_SSC_RXDIS,
83 .ssc_endx = AT91_SSC_ENDRX,
84 .ssc_endbuf = AT91_SSC_RXBUFF,
85 .pdc_enable = ATMEL_PDC_RXTEN,
86 .pdc_disable = ATMEL_PDC_RXTDIS,
87};
88
89
90/*
91 * DMA parameters.
92 */
93static struct at91_pcm_dma_params ssc_dma_params[NUM_SSC_DEVICES][2] = {
94 {{
95 .name = "SSC0 PCM out",
96 .pdc = &pdc_tx_reg,
97 .mask = &ssc_tx_mask,
98 },
99 {
100 .name = "SSC0 PCM in",
101 .pdc = &pdc_rx_reg,
102 .mask = &ssc_rx_mask,
103 }},
104#if NUM_SSC_DEVICES == 3
105 {{
106 .name = "SSC1 PCM out",
107 .pdc = &pdc_tx_reg,
108 .mask = &ssc_tx_mask,
109 },
110 {
111 .name = "SSC1 PCM in",
112 .pdc = &pdc_rx_reg,
113 .mask = &ssc_rx_mask,
114 }},
115 {{
116 .name = "SSC2 PCM out",
117 .pdc = &pdc_tx_reg,
118 .mask = &ssc_tx_mask,
119 },
120 {
121 .name = "SSC2 PCM in",
122 .pdc = &pdc_rx_reg,
123 .mask = &ssc_rx_mask,
124 }},
125#endif
126};
127
128struct at91_ssc_state {
129 u32 ssc_cmr;
130 u32 ssc_rcmr;
131 u32 ssc_rfmr;
132 u32 ssc_tcmr;
133 u32 ssc_tfmr;
134 u32 ssc_sr;
135 u32 ssc_imr;
136};
137
138static struct at91_ssc_info {
139 char *name;
140 struct at91_ssc_periph ssc;
141 spinlock_t lock; /* lock for dir_mask */
142 unsigned short dir_mask; /* 0=unused, 1=playback, 2=capture */
143 unsigned short initialized; /* 1=SSC has been initialized */
144 unsigned short daifmt;
145 unsigned short cmr_div;
146 unsigned short tcmr_period;
147 unsigned short rcmr_period;
148 struct at91_pcm_dma_params *dma_params[2];
149 struct at91_ssc_state ssc_state;
150
151} ssc_info[NUM_SSC_DEVICES] = {
152 {
153 .name = "ssc0",
154 .lock = __SPIN_LOCK_UNLOCKED(ssc_info[0].lock),
155 .dir_mask = 0,
156 .initialized = 0,
157 },
158#if NUM_SSC_DEVICES == 3
159 {
160 .name = "ssc1",
161 .lock = __SPIN_LOCK_UNLOCKED(ssc_info[1].lock),
162 .dir_mask = 0,
163 .initialized = 0,
164 },
165 {
166 .name = "ssc2",
167 .lock = __SPIN_LOCK_UNLOCKED(ssc_info[2].lock),
168 .dir_mask = 0,
169 .initialized = 0,
170 },
171#endif
172};
173
174static unsigned int at91_ssc_sysclk;
175
176/*
177 * SSC interrupt handler. Passes PDC interrupts to the DMA
178 * interrupt handler in the PCM driver.
179 */
180static irqreturn_t at91_ssc_interrupt(int irq, void *dev_id)
181{
182 struct at91_ssc_info *ssc_p = dev_id;
183 struct at91_pcm_dma_params *dma_params;
184 u32 ssc_sr;
185 int i;
186
187 ssc_sr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_SR)
188 & at91_ssc_read(ssc_p->ssc.base + AT91_SSC_IMR);
189
190 /*
191 * Loop through the substreams attached to this SSC. If
192 * a DMA-related interrupt occurred on that substream, call
193 * the DMA interrupt handler function, if one has been
194 * registered in the dma_params structure by the PCM driver.
195 */
196 for (i = 0; i < ARRAY_SIZE(ssc_p->dma_params); i++) {
197 dma_params = ssc_p->dma_params[i];
198
199 if (dma_params != NULL && dma_params->dma_intr_handler != NULL &&
200 (ssc_sr &
201 (dma_params->mask->ssc_endx | dma_params->mask->ssc_endbuf)))
202
203 dma_params->dma_intr_handler(ssc_sr, dma_params->substream);
204 }
205
206 return IRQ_HANDLED;
207}
208
209/*
210 * Startup. Only that one substream allowed in each direction.
211 */
212static int at91_ssc_startup(struct snd_pcm_substream *substream)
213{
214 struct snd_soc_pcm_runtime *rtd = substream->private_data;
215 struct at91_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
216 int dir_mask;
217
218 DBG("ssc_startup: SSC_SR=0x%08lx\n",
219 at91_ssc_read(ssc_p->ssc.base + AT91_SSC_SR));
220 dir_mask = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0x1 : 0x2;
221
222 spin_lock_irq(&ssc_p->lock);
223 if (ssc_p->dir_mask & dir_mask) {
224 spin_unlock_irq(&ssc_p->lock);
225 return -EBUSY;
226 }
227 ssc_p->dir_mask |= dir_mask;
228 spin_unlock_irq(&ssc_p->lock);
229
230 return 0;
231}
232
233/*
234 * Shutdown. Clear DMA parameters and shutdown the SSC if there
235 * are no other substreams open.
236 */
237static void at91_ssc_shutdown(struct snd_pcm_substream *substream)
238{
239 struct snd_soc_pcm_runtime *rtd = substream->private_data;
240 struct at91_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
241 struct at91_pcm_dma_params *dma_params;
242 int dir, dir_mask;
243
244 dir = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1;
245 dma_params = ssc_p->dma_params[dir];
246
247 if (dma_params != NULL) {
248 at91_ssc_write(dma_params->ssc_base + AT91_SSC_CR,
249 dma_params->mask->ssc_disable);
250 DBG("%s disabled SSC_SR=0x%08lx\n", (dir ? "receive" : "transmit"),
251 at91_ssc_read(ssc_p->ssc.base + AT91_SSC_SR));
252
253 dma_params->ssc_base = NULL;
254 dma_params->substream = NULL;
255 ssc_p->dma_params[dir] = NULL;
256 }
257
258 dir_mask = 1 << dir;
259
260 spin_lock_irq(&ssc_p->lock);
261 ssc_p->dir_mask &= ~dir_mask;
262 if (!ssc_p->dir_mask) {
263 /* Shutdown the SSC clock. */
264 DBG("Stopping pid %d clock\n", ssc_p->ssc.pid);
265 at91_sys_write(AT91_PMC_PCDR, 1<<ssc_p->ssc.pid);
266
267 if (ssc_p->initialized) {
268 free_irq(ssc_p->ssc.pid, ssc_p);
269 ssc_p->initialized = 0;
270 }
271
272 /* Reset the SSC */
273 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CR, AT91_SSC_SWRST);
274
275 /* Clear the SSC dividers */
276 ssc_p->cmr_div = ssc_p->tcmr_period = ssc_p->rcmr_period = 0;
277 }
278 spin_unlock_irq(&ssc_p->lock);
279}
280
281/*
282 * Record the SSC system clock rate.
283 */
284static int at91_ssc_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
285 int clk_id, unsigned int freq, int dir)
286{
287 /*
288 * The only clock supplied to the SSC is the AT91 master clock,
289 * which is only used if the SSC is generating BCLK and/or
290 * LRC clocks.
291 */
292 switch (clk_id) {
293 case AT91_SYSCLK_MCK:
294 at91_ssc_sysclk = freq;
295 break;
296 default:
297 return -EINVAL;
298 }
299
300 return 0;
301}
302
303/*
304 * Record the DAI format for use in hw_params().
305 */
306static int at91_ssc_set_dai_fmt(struct snd_soc_dai *cpu_dai,
307 unsigned int fmt)
308{
309 struct at91_ssc_info *ssc_p = &ssc_info[cpu_dai->id];
310
311 ssc_p->daifmt = fmt;
312 return 0;
313}
314
315/*
316 * Record SSC clock dividers for use in hw_params().
317 */
318static int at91_ssc_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
319 int div_id, int div)
320{
321 struct at91_ssc_info *ssc_p = &ssc_info[cpu_dai->id];
322
323 switch (div_id) {
324 case AT91SSC_CMR_DIV:
325 /*
326 * The same master clock divider is used for both
327 * transmit and receive, so if a value has already
328 * been set, it must match this value.
329 */
330 if (ssc_p->cmr_div == 0)
331 ssc_p->cmr_div = div;
332 else
333 if (div != ssc_p->cmr_div)
334 return -EBUSY;
335 break;
336
337 case AT91SSC_TCMR_PERIOD:
338 ssc_p->tcmr_period = div;
339 break;
340
341 case AT91SSC_RCMR_PERIOD:
342 ssc_p->rcmr_period = div;
343 break;
344
345 default:
346 return -EINVAL;
347 }
348
349 return 0;
350}
351
352/*
353 * Configure the SSC.
354 */
355static int at91_ssc_hw_params(struct snd_pcm_substream *substream,
356 struct snd_pcm_hw_params *params)
357{
358 struct snd_soc_pcm_runtime *rtd = substream->private_data;
359 int id = rtd->dai->cpu_dai->id;
360 struct at91_ssc_info *ssc_p = &ssc_info[id];
361 struct at91_pcm_dma_params *dma_params;
362 int dir, channels, bits;
363 u32 tfmr, rfmr, tcmr, rcmr;
364 int start_event;
365 int ret;
366
367 /*
368 * Currently, there is only one set of dma params for
369 * each direction. If more are added, this code will
370 * have to be changed to select the proper set.
371 */
372 dir = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1;
373
374 dma_params = &ssc_dma_params[id][dir];
375 dma_params->ssc_base = ssc_p->ssc.base;
376 dma_params->substream = substream;
377
378 ssc_p->dma_params[dir] = dma_params;
379
380 /*
381 * The cpu_dai->dma_data field is only used to communicate the
382 * appropriate DMA parameters to the pcm driver hw_params()
383 * function. It should not be used for other purposes
384 * as it is common to all substreams.
385 */
386 rtd->dai->cpu_dai->dma_data = dma_params;
387
388 channels = params_channels(params);
389
390 /*
391 * Determine sample size in bits and the PDC increment.
392 */
393 switch(params_format(params)) {
394 case SNDRV_PCM_FORMAT_S8:
395 bits = 8;
396 dma_params->pdc_xfer_size = 1;
397 break;
398 case SNDRV_PCM_FORMAT_S16_LE:
399 bits = 16;
400 dma_params->pdc_xfer_size = 2;
401 break;
402 case SNDRV_PCM_FORMAT_S24_LE:
403 bits = 24;
404 dma_params->pdc_xfer_size = 4;
405 break;
406 case SNDRV_PCM_FORMAT_S32_LE:
407 bits = 32;
408 dma_params->pdc_xfer_size = 4;
409 break;
410 default:
411 printk(KERN_WARNING "at91-ssc: unsupported PCM format\n");
412 return -EINVAL;
413 }
414
415 /*
416 * The SSC only supports up to 16-bit samples in I2S format, due
417 * to the size of the Frame Mode Register FSLEN field.
418 */
419 if ((ssc_p->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_I2S
420 && bits > 16) {
421 printk(KERN_WARNING
422 "at91-ssc: sample size %d is too large for I2S\n", bits);
423 return -EINVAL;
424 }
425
426 /*
427 * Compute SSC register settings.
428 */
429 switch (ssc_p->daifmt
430 & (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_MASTER_MASK)) {
431
432 case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS:
433 /*
434 * I2S format, SSC provides BCLK and LRC clocks.
435 *
436 * The SSC transmit and receive clocks are generated from the
437 * MCK divider, and the BCLK signal is output on the SSC TK line.
438 */
439 rcmr = (( ssc_p->rcmr_period << 24) & AT91_SSC_PERIOD)
440 | (( 1 << 16) & AT91_SSC_STTDLY)
441 | (( AT91_SSC_START_FALLING_RF ) & AT91_SSC_START)
442 | (( AT91_SSC_CK_RISING ) & AT91_SSC_CKI)
443 | (( AT91_SSC_CKO_NONE ) & AT91_SSC_CKO)
444 | (( AT91_SSC_CKS_DIV ) & AT91_SSC_CKS);
445
446 rfmr = (( AT91_SSC_FSEDGE_POSITIVE ) & AT91_SSC_FSEDGE)
447 | (( AT91_SSC_FSOS_NEGATIVE ) & AT91_SSC_FSOS)
448 | (((bits - 1) << 16) & AT91_SSC_FSLEN)
449 | (((channels - 1) << 8) & AT91_SSC_DATNB)
450 | (( 1 << 7) & AT91_SSC_MSBF)
451 | (( 0 << 5) & AT91_SSC_LOOP)
452 | (((bits - 1) << 0) & AT91_SSC_DATALEN);
453
454 tcmr = (( ssc_p->tcmr_period << 24) & AT91_SSC_PERIOD)
455 | (( 1 << 16) & AT91_SSC_STTDLY)
456 | (( AT91_SSC_START_FALLING_RF ) & AT91_SSC_START)
457 | (( AT91_SSC_CKI_FALLING ) & AT91_SSC_CKI)
458 | (( AT91_SSC_CKO_CONTINUOUS ) & AT91_SSC_CKO)
459 | (( AT91_SSC_CKS_DIV ) & AT91_SSC_CKS);
460
461 tfmr = (( AT91_SSC_FSEDGE_POSITIVE ) & AT91_SSC_FSEDGE)
462 | (( 0 << 23) & AT91_SSC_FSDEN)
463 | (( AT91_SSC_FSOS_NEGATIVE ) & AT91_SSC_FSOS)
464 | (((bits - 1) << 16) & AT91_SSC_FSLEN)
465 | (((channels - 1) << 8) & AT91_SSC_DATNB)
466 | (( 1 << 7) & AT91_SSC_MSBF)
467 | (( 0 << 5) & AT91_SSC_DATDEF)
468 | (((bits - 1) << 0) & AT91_SSC_DATALEN);
469 break;
470
471 case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM:
472 /*
473 * I2S format, CODEC supplies BCLK and LRC clocks.
474 *
475 * The SSC transmit clock is obtained from the BCLK signal on
476 * on the TK line, and the SSC receive clock is generated from the
477 * transmit clock.
478 *
479 * For single channel data, one sample is transferred on the falling
480 * edge of the LRC clock. For two channel data, one sample is
481 * transferred on both edges of the LRC clock.
482 */
483 start_event = channels == 1
484 ? AT91_SSC_START_FALLING_RF
485 : AT91_SSC_START_EDGE_RF;
486
487 rcmr = (( 0 << 24) & AT91_SSC_PERIOD)
488 | (( 1 << 16) & AT91_SSC_STTDLY)
489 | (( start_event ) & AT91_SSC_START)
490 | (( AT91_SSC_CK_RISING ) & AT91_SSC_CKI)
491 | (( AT91_SSC_CKO_NONE ) & AT91_SSC_CKO)
492 | (( AT91_SSC_CKS_CLOCK ) & AT91_SSC_CKS);
493
494 rfmr = (( AT91_SSC_FSEDGE_POSITIVE ) & AT91_SSC_FSEDGE)
495 | (( AT91_SSC_FSOS_NONE ) & AT91_SSC_FSOS)
496 | (( 0 << 16) & AT91_SSC_FSLEN)
497 | (( 0 << 8) & AT91_SSC_DATNB)
498 | (( 1 << 7) & AT91_SSC_MSBF)
499 | (( 0 << 5) & AT91_SSC_LOOP)
500 | (((bits - 1) << 0) & AT91_SSC_DATALEN);
501
502 tcmr = (( 0 << 24) & AT91_SSC_PERIOD)
503 | (( 1 << 16) & AT91_SSC_STTDLY)
504 | (( start_event ) & AT91_SSC_START)
505 | (( AT91_SSC_CKI_FALLING ) & AT91_SSC_CKI)
506 | (( AT91_SSC_CKO_NONE ) & AT91_SSC_CKO)
507 | (( AT91_SSC_CKS_PIN ) & AT91_SSC_CKS);
508
509 tfmr = (( AT91_SSC_FSEDGE_POSITIVE ) & AT91_SSC_FSEDGE)
510 | (( 0 << 23) & AT91_SSC_FSDEN)
511 | (( AT91_SSC_FSOS_NONE ) & AT91_SSC_FSOS)
512 | (( 0 << 16) & AT91_SSC_FSLEN)
513 | (( 0 << 8) & AT91_SSC_DATNB)
514 | (( 1 << 7) & AT91_SSC_MSBF)
515 | (( 0 << 5) & AT91_SSC_DATDEF)
516 | (((bits - 1) << 0) & AT91_SSC_DATALEN);
517 break;
518
519 case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBS_CFS:
520 /*
521 * DSP/PCM Mode A format, SSC provides BCLK and LRC clocks.
522 *
523 * The SSC transmit and receive clocks are generated from the
524 * MCK divider, and the BCLK signal is output on the SSC TK line.
525 */
526 rcmr = (( ssc_p->rcmr_period << 24) & AT91_SSC_PERIOD)
527 | (( 1 << 16) & AT91_SSC_STTDLY)
528 | (( AT91_SSC_START_RISING_RF ) & AT91_SSC_START)
529 | (( AT91_SSC_CK_RISING ) & AT91_SSC_CKI)
530 | (( AT91_SSC_CKO_NONE ) & AT91_SSC_CKO)
531 | (( AT91_SSC_CKS_DIV ) & AT91_SSC_CKS);
532
533 rfmr = (( AT91_SSC_FSEDGE_POSITIVE ) & AT91_SSC_FSEDGE)
534 | (( AT91_SSC_FSOS_POSITIVE ) & AT91_SSC_FSOS)
535 | (( 0 << 16) & AT91_SSC_FSLEN)
536 | (((channels - 1) << 8) & AT91_SSC_DATNB)
537 | (( 1 << 7) & AT91_SSC_MSBF)
538 | (( 0 << 5) & AT91_SSC_LOOP)
539 | (((bits - 1) << 0) & AT91_SSC_DATALEN);
540
541 tcmr = (( ssc_p->tcmr_period << 24) & AT91_SSC_PERIOD)
542 | (( 1 << 16) & AT91_SSC_STTDLY)
543 | (( AT91_SSC_START_RISING_RF ) & AT91_SSC_START)
544 | (( AT91_SSC_CK_RISING ) & AT91_SSC_CKI)
545 | (( AT91_SSC_CKO_CONTINUOUS ) & AT91_SSC_CKO)
546 | (( AT91_SSC_CKS_DIV ) & AT91_SSC_CKS);
547
548 tfmr = (( AT91_SSC_FSEDGE_POSITIVE ) & AT91_SSC_FSEDGE)
549 | (( 0 << 23) & AT91_SSC_FSDEN)
550 | (( AT91_SSC_FSOS_POSITIVE ) & AT91_SSC_FSOS)
551 | (( 0 << 16) & AT91_SSC_FSLEN)
552 | (((channels - 1) << 8) & AT91_SSC_DATNB)
553 | (( 1 << 7) & AT91_SSC_MSBF)
554 | (( 0 << 5) & AT91_SSC_DATDEF)
555 | (((bits - 1) << 0) & AT91_SSC_DATALEN);
556
557
558
559 break;
560
561 case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBM_CFM:
562 default:
563 printk(KERN_WARNING "at91-ssc: unsupported DAI format 0x%x.\n",
564 ssc_p->daifmt);
565 return -EINVAL;
566 break;
567 }
568 DBG("RCMR=%08x RFMR=%08x TCMR=%08x TFMR=%08x\n", rcmr, rfmr, tcmr, tfmr);
569
570 if (!ssc_p->initialized) {
571
572 /* Enable PMC peripheral clock for this SSC */
573 DBG("Starting pid %d clock\n", ssc_p->ssc.pid);
574 at91_sys_write(AT91_PMC_PCER, 1<<ssc_p->ssc.pid);
575
576 /* Reset the SSC and its PDC registers */
577 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CR, AT91_SSC_SWRST);
578
579 at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_RPR, 0);
580 at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_RCR, 0);
581 at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_RNPR, 0);
582 at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_RNCR, 0);
583 at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_TPR, 0);
584 at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_TCR, 0);
585 at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_TNPR, 0);
586 at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_TNCR, 0);
587
588 if ((ret = request_irq(ssc_p->ssc.pid, at91_ssc_interrupt,
589 0, ssc_p->name, ssc_p)) < 0) {
590 printk(KERN_WARNING "at91-ssc: request_irq failure\n");
591
592 DBG("Stopping pid %d clock\n", ssc_p->ssc.pid);
593 at91_sys_write(AT91_PMC_PCDR, 1<<ssc_p->ssc.pid);
594 return ret;
595 }
596
597 ssc_p->initialized = 1;
598 }
599
600 /* set SSC clock mode register */
601 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CMR, ssc_p->cmr_div);
602
603 /* set receive clock mode and format */
604 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_RCMR, rcmr);
605 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_RFMR, rfmr);
606
607 /* set transmit clock mode and format */
608 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_TCMR, tcmr);
609 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_TFMR, tfmr);
610
611 DBG("hw_params: SSC initialized\n");
612 return 0;
613}
614
615
616static int at91_ssc_prepare(struct snd_pcm_substream *substream)
617{
618 struct snd_soc_pcm_runtime *rtd = substream->private_data;
619 struct at91_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
620 struct at91_pcm_dma_params *dma_params;
621 int dir;
622
623 dir = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1;
624 dma_params = ssc_p->dma_params[dir];
625
626 at91_ssc_write(dma_params->ssc_base + AT91_SSC_CR,
627 dma_params->mask->ssc_enable);
628
629 DBG("%s enabled SSC_SR=0x%08lx\n", dir ? "receive" : "transmit",
630 at91_ssc_read(dma_params->ssc_base + AT91_SSC_SR));
631 return 0;
632}
633
634
635#ifdef CONFIG_PM
636static int at91_ssc_suspend(struct platform_device *pdev,
637 struct snd_soc_dai *cpu_dai)
638{
639 struct at91_ssc_info *ssc_p;
640
641 if(!cpu_dai->active)
642 return 0;
643
644 ssc_p = &ssc_info[cpu_dai->id];
645
646 /* Save the status register before disabling transmit and receive. */
647 ssc_p->ssc_state.ssc_sr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_SR);
648 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CR,
649 AT91_SSC_TXDIS | AT91_SSC_RXDIS);
650
651 /* Save the current interrupt mask, then disable unmasked interrupts. */
652 ssc_p->ssc_state.ssc_imr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_IMR);
653 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_IDR, ssc_p->ssc_state.ssc_imr);
654
655 ssc_p->ssc_state.ssc_cmr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_CMR);
656 ssc_p->ssc_state.ssc_rcmr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_RCMR);
657 ssc_p->ssc_state.ssc_rfmr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_RFMR);
658 ssc_p->ssc_state.ssc_tcmr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_TCMR);
659 ssc_p->ssc_state.ssc_tfmr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_TFMR);
660
661 return 0;
662}
663
664static int at91_ssc_resume(struct platform_device *pdev,
665 struct snd_soc_dai *cpu_dai)
666{
667 struct at91_ssc_info *ssc_p;
668
669 if(!cpu_dai->active)
670 return 0;
671
672 ssc_p = &ssc_info[cpu_dai->id];
673
674 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_TFMR, ssc_p->ssc_state.ssc_tfmr);
675 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_TCMR, ssc_p->ssc_state.ssc_tcmr);
676 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_RFMR, ssc_p->ssc_state.ssc_rfmr);
677 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_RCMR, ssc_p->ssc_state.ssc_rcmr);
678 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CMR, ssc_p->ssc_state.ssc_cmr);
679
680 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_IER, ssc_p->ssc_state.ssc_imr);
681
682 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CR,
683 ((ssc_p->ssc_state.ssc_sr & AT91_SSC_RXENA) ? AT91_SSC_RXEN : 0) |
684 ((ssc_p->ssc_state.ssc_sr & AT91_SSC_TXENA) ? AT91_SSC_TXEN : 0));
685
686 return 0;
687}
688
689#else
690#define at91_ssc_suspend NULL
691#define at91_ssc_resume NULL
692#endif
693
694#define AT91_SSC_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
695 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
696 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
697 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
698 SNDRV_PCM_RATE_96000)
699
700#define AT91_SSC_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\
701 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
702
703struct snd_soc_dai at91_ssc_dai[NUM_SSC_DEVICES] = {
704 { .name = "at91-ssc0",
705 .id = 0,
706 .type = SND_SOC_DAI_PCM,
707 .suspend = at91_ssc_suspend,
708 .resume = at91_ssc_resume,
709 .playback = {
710 .channels_min = 1,
711 .channels_max = 2,
712 .rates = AT91_SSC_RATES,
713 .formats = AT91_SSC_FORMATS,},
714 .capture = {
715 .channels_min = 1,
716 .channels_max = 2,
717 .rates = AT91_SSC_RATES,
718 .formats = AT91_SSC_FORMATS,},
719 .ops = {
720 .startup = at91_ssc_startup,
721 .shutdown = at91_ssc_shutdown,
722 .prepare = at91_ssc_prepare,
723 .hw_params = at91_ssc_hw_params,},
724 .dai_ops = {
725 .set_sysclk = at91_ssc_set_dai_sysclk,
726 .set_fmt = at91_ssc_set_dai_fmt,
727 .set_clkdiv = at91_ssc_set_dai_clkdiv,},
728 .private_data = &ssc_info[0].ssc,
729 },
730#if NUM_SSC_DEVICES == 3
731 { .name = "at91-ssc1",
732 .id = 1,
733 .type = SND_SOC_DAI_PCM,
734 .suspend = at91_ssc_suspend,
735 .resume = at91_ssc_resume,
736 .playback = {
737 .channels_min = 1,
738 .channels_max = 2,
739 .rates = AT91_SSC_RATES,
740 .formats = AT91_SSC_FORMATS,},
741 .capture = {
742 .channels_min = 1,
743 .channels_max = 2,
744 .rates = AT91_SSC_RATES,
745 .formats = AT91_SSC_FORMATS,},
746 .ops = {
747 .startup = at91_ssc_startup,
748 .shutdown = at91_ssc_shutdown,
749 .prepare = at91_ssc_prepare,
750 .hw_params = at91_ssc_hw_params,},
751 .dai_ops = {
752 .set_sysclk = at91_ssc_set_dai_sysclk,
753 .set_fmt = at91_ssc_set_dai_fmt,
754 .set_clkdiv = at91_ssc_set_dai_clkdiv,},
755 .private_data = &ssc_info[1].ssc,
756 },
757 { .name = "at91-ssc2",
758 .id = 2,
759 .type = SND_SOC_DAI_PCM,
760 .suspend = at91_ssc_suspend,
761 .resume = at91_ssc_resume,
762 .playback = {
763 .channels_min = 1,
764 .channels_max = 2,
765 .rates = AT91_SSC_RATES,
766 .formats = AT91_SSC_FORMATS,},
767 .capture = {
768 .channels_min = 1,
769 .channels_max = 2,
770 .rates = AT91_SSC_RATES,
771 .formats = AT91_SSC_FORMATS,},
772 .ops = {
773 .startup = at91_ssc_startup,
774 .shutdown = at91_ssc_shutdown,
775 .prepare = at91_ssc_prepare,
776 .hw_params = at91_ssc_hw_params,},
777 .dai_ops = {
778 .set_sysclk = at91_ssc_set_dai_sysclk,
779 .set_fmt = at91_ssc_set_dai_fmt,
780 .set_clkdiv = at91_ssc_set_dai_clkdiv,},
781 .private_data = &ssc_info[2].ssc,
782 },
783#endif
784};
785
786EXPORT_SYMBOL_GPL(at91_ssc_dai);
787
788/* Module information */
789MODULE_AUTHOR("Frank Mandarino, fmandarino@endrelia.com, www.endrelia.com");
790MODULE_DESCRIPTION("AT91 SSC ASoC Interface");
791MODULE_LICENSE("GPL");
diff --git a/sound/soc/at91/at91-ssc.h b/sound/soc/at91/at91-ssc.h
deleted file mode 100644
index 6b7bf382d06f..000000000000
--- a/sound/soc/at91/at91-ssc.h
+++ /dev/null
@@ -1,27 +0,0 @@
1/*
2 * at91-ssc.h - ALSA SSC interface for the Atmel AT91 SoC
3 *
4 * Author: Frank Mandarino <fmandarino@endrelia.com>
5 * Endrelia Technologies Inc.
6 * Created: Jan 9, 2007
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef _AT91_SSC_H
14#define _AT91_SSC_H
15
16/* SSC system clock ids */
17#define AT91_SYSCLK_MCK 0 /* SSC uses AT91 MCK as system clock */
18
19/* SSC divider ids */
20#define AT91SSC_CMR_DIV 0 /* MCK divider for BCLK */
21#define AT91SSC_TCMR_PERIOD 1 /* BCLK divider for transmit FS */
22#define AT91SSC_RCMR_PERIOD 2 /* BCLK divider for receive FS */
23
24extern struct snd_soc_dai at91_ssc_dai[];
25
26#endif /* _AT91_SSC_H */
27
diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig
new file mode 100644
index 000000000000..a608d7009dbd
--- /dev/null
+++ b/sound/soc/atmel/Kconfig
@@ -0,0 +1,43 @@
1config SND_ATMEL_SOC
2 tristate "SoC Audio for the Atmel System-on-Chip"
3 depends on ARCH_AT91 || AVR32
4 help
5 Say Y or M if you want to add support for codecs attached to
6 the ATMEL SSC interface. You will also need
7 to select the audio interfaces to support below.
8
9config SND_ATMEL_SOC_SSC
10 tristate
11 depends on SND_ATMEL_SOC
12 help
13 Say Y or M if you want to add support for codecs the
14 ATMEL SSC interface. You will also needs to select the individual
15 machine drivers to support below.
16
17config SND_AT91_SOC_SAM9G20_WM8731
18 tristate "SoC Audio support for WM8731-based At91sam9g20 evaluation board"
19 depends on ATMEL_SSC && ARCH_AT91SAM9G20 && SND_ATMEL_SOC
20 select SND_ATMEL_SOC_SSC
21 select SND_SOC_WM8731
22 help
23 Say Y if you want to add support for SoC audio on WM8731-based
24 AT91sam9g20 evaluation board.
25
26config SND_AT32_SOC_PLAYPAQ
27 tristate "SoC Audio support for PlayPaq with WM8510"
28 depends on SND_ATMEL_SOC && BOARD_PLAYPAQ
29 select SND_ATMEL_SOC_SSC
30 select SND_SOC_WM8510
31 help
32 Say Y or M here if you want to add support for SoC audio
33 on the LRS PlayPaq.
34
35config SND_AT32_SOC_PLAYPAQ_SLAVE
36 bool "Run CODEC on PlayPaq in slave mode"
37 depends on SND_AT32_SOC_PLAYPAQ
38 default n
39 help
40 Say Y if you want to run with the AT32 SSC generating the BCLK
41 and FRAME signals on the PlayPaq. Unless you want to play
42 with the AT32 as the SSC master, you probably want to say N here,
43 as this will give you better sound quality.
diff --git a/sound/soc/atmel/Makefile b/sound/soc/atmel/Makefile
new file mode 100644
index 000000000000..f54a7cc68e66
--- /dev/null
+++ b/sound/soc/atmel/Makefile
@@ -0,0 +1,15 @@
1# AT91 Platform Support
2snd-soc-atmel-pcm-objs := atmel-pcm.o
3snd-soc-atmel_ssc_dai-objs := atmel_ssc_dai.o
4
5obj-$(CONFIG_SND_ATMEL_SOC) += snd-soc-atmel-pcm.o
6obj-$(CONFIG_SND_ATMEL_SOC_SSC) += snd-soc-atmel_ssc_dai.o
7
8# AT91 Machine Support
9snd-soc-sam9g20-wm8731-objs := sam9g20_wm8731.o
10
11# AT32 Machine Support
12snd-soc-playpaq-objs := playpaq_wm8510.o
13
14obj-$(CONFIG_SND_AT91_SOC_SAM9G20_WM8731) += snd-soc-sam9g20-wm8731.o
15obj-$(CONFIG_SND_AT32_SOC_PLAYPAQ) += snd-soc-playpaq.o
diff --git a/sound/soc/atmel/atmel-pcm.c b/sound/soc/atmel/atmel-pcm.c
new file mode 100644
index 000000000000..1fac5efd285b
--- /dev/null
+++ b/sound/soc/atmel/atmel-pcm.c
@@ -0,0 +1,494 @@
1/*
2 * atmel-pcm.c -- ALSA PCM interface for the Atmel atmel SoC.
3 *
4 * Copyright (C) 2005 SAN People
5 * Copyright (C) 2008 Atmel
6 *
7 * Authors: Sedji Gaouaou <sedji.gaouaou@atmel.com>
8 *
9 * Based on at91-pcm. by:
10 * Frank Mandarino <fmandarino@endrelia.com>
11 * Copyright 2006 Endrelia Technologies Inc.
12 *
13 * Based on pxa2xx-pcm.c by:
14 *
15 * Author: Nicolas Pitre
16 * Created: Nov 30, 2004
17 * Copyright: (C) 2004 MontaVista Software, Inc.
18 *
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 2 of the License, or
22 * (at your option) any later version.
23 *
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
28 *
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32 */
33
34#include <linux/module.h>
35#include <linux/init.h>
36#include <linux/platform_device.h>
37#include <linux/slab.h>
38#include <linux/dma-mapping.h>
39#include <linux/atmel_pdc.h>
40#include <linux/atmel-ssc.h>
41
42#include <sound/core.h>
43#include <sound/pcm.h>
44#include <sound/pcm_params.h>
45#include <sound/soc.h>
46
47#include <mach/hardware.h>
48
49#include "atmel-pcm.h"
50
51
52/*--------------------------------------------------------------------------*\
53 * Hardware definition
54\*--------------------------------------------------------------------------*/
55/* TODO: These values were taken from the AT91 platform driver, check
56 * them against real values for AT32
57 */
58static const struct snd_pcm_hardware atmel_pcm_hardware = {
59 .info = SNDRV_PCM_INFO_MMAP |
60 SNDRV_PCM_INFO_MMAP_VALID |
61 SNDRV_PCM_INFO_INTERLEAVED |
62 SNDRV_PCM_INFO_PAUSE,
63 .formats = SNDRV_PCM_FMTBIT_S16_LE,
64 .period_bytes_min = 32,
65 .period_bytes_max = 8192,
66 .periods_min = 2,
67 .periods_max = 1024,
68 .buffer_bytes_max = 32 * 1024,
69};
70
71
72/*--------------------------------------------------------------------------*\
73 * Data types
74\*--------------------------------------------------------------------------*/
75struct atmel_runtime_data {
76 struct atmel_pcm_dma_params *params;
77 dma_addr_t dma_buffer; /* physical address of dma buffer */
78 dma_addr_t dma_buffer_end; /* first address beyond DMA buffer */
79 size_t period_size;
80
81 dma_addr_t period_ptr; /* physical address of next period */
82 int periods; /* period index of period_ptr */
83
84 /* PDC register save */
85 u32 pdc_xpr_save;
86 u32 pdc_xcr_save;
87 u32 pdc_xnpr_save;
88 u32 pdc_xncr_save;
89};
90
91
92/*--------------------------------------------------------------------------*\
93 * Helper functions
94\*--------------------------------------------------------------------------*/
95static int atmel_pcm_preallocate_dma_buffer(struct snd_pcm *pcm,
96 int stream)
97{
98 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
99 struct snd_dma_buffer *buf = &substream->dma_buffer;
100 size_t size = atmel_pcm_hardware.buffer_bytes_max;
101
102 buf->dev.type = SNDRV_DMA_TYPE_DEV;
103 buf->dev.dev = pcm->card->dev;
104 buf->private_data = NULL;
105 buf->area = dma_alloc_coherent(pcm->card->dev, size,
106 &buf->addr, GFP_KERNEL);
107 pr_debug("atmel-pcm:"
108 "preallocate_dma_buffer: area=%p, addr=%p, size=%d\n",
109 (void *) buf->area,
110 (void *) buf->addr,
111 size);
112
113 if (!buf->area)
114 return -ENOMEM;
115
116 buf->bytes = size;
117 return 0;
118}
119/*--------------------------------------------------------------------------*\
120 * ISR
121\*--------------------------------------------------------------------------*/
122static void atmel_pcm_dma_irq(u32 ssc_sr,
123 struct snd_pcm_substream *substream)
124{
125 struct atmel_runtime_data *prtd = substream->runtime->private_data;
126 struct atmel_pcm_dma_params *params = prtd->params;
127 static int count;
128
129 count++;
130
131 if (ssc_sr & params->mask->ssc_endbuf) {
132 pr_warning("atmel-pcm: buffer %s on %s"
133 " (SSC_SR=%#x, count=%d)\n",
134 substream->stream == SNDRV_PCM_STREAM_PLAYBACK
135 ? "underrun" : "overrun",
136 params->name, ssc_sr, count);
137
138 /* re-start the PDC */
139 ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
140 params->mask->pdc_disable);
141 prtd->period_ptr += prtd->period_size;
142 if (prtd->period_ptr >= prtd->dma_buffer_end)
143 prtd->period_ptr = prtd->dma_buffer;
144
145 ssc_writex(params->ssc->regs, params->pdc->xpr,
146 prtd->period_ptr);
147 ssc_writex(params->ssc->regs, params->pdc->xcr,
148 prtd->period_size / params->pdc_xfer_size);
149 ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
150 params->mask->pdc_enable);
151 }
152
153 if (ssc_sr & params->mask->ssc_endx) {
154 /* Load the PDC next pointer and counter registers */
155 prtd->period_ptr += prtd->period_size;
156 if (prtd->period_ptr >= prtd->dma_buffer_end)
157 prtd->period_ptr = prtd->dma_buffer;
158
159 ssc_writex(params->ssc->regs, params->pdc->xnpr,
160 prtd->period_ptr);
161 ssc_writex(params->ssc->regs, params->pdc->xncr,
162 prtd->period_size / params->pdc_xfer_size);
163 }
164
165 snd_pcm_period_elapsed(substream);
166}
167
168
169/*--------------------------------------------------------------------------*\
170 * PCM operations
171\*--------------------------------------------------------------------------*/
172static int atmel_pcm_hw_params(struct snd_pcm_substream *substream,
173 struct snd_pcm_hw_params *params)
174{
175 struct snd_pcm_runtime *runtime = substream->runtime;
176 struct atmel_runtime_data *prtd = runtime->private_data;
177 struct snd_soc_pcm_runtime *rtd = substream->private_data;
178
179 /* this may get called several times by oss emulation
180 * with different params */
181
182 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
183 runtime->dma_bytes = params_buffer_bytes(params);
184
185 prtd->params = rtd->dai->cpu_dai->dma_data;
186 prtd->params->dma_intr_handler = atmel_pcm_dma_irq;
187
188 prtd->dma_buffer = runtime->dma_addr;
189 prtd->dma_buffer_end = runtime->dma_addr + runtime->dma_bytes;
190 prtd->period_size = params_period_bytes(params);
191
192 pr_debug("atmel-pcm: "
193 "hw_params: DMA for %s initialized "
194 "(dma_bytes=%u, period_size=%u)\n",
195 prtd->params->name,
196 runtime->dma_bytes,
197 prtd->period_size);
198 return 0;
199}
200
201static int atmel_pcm_hw_free(struct snd_pcm_substream *substream)
202{
203 struct atmel_runtime_data *prtd = substream->runtime->private_data;
204 struct atmel_pcm_dma_params *params = prtd->params;
205
206 if (params != NULL) {
207 ssc_writex(params->ssc->regs, SSC_PDC_PTCR,
208 params->mask->pdc_disable);
209 prtd->params->dma_intr_handler = NULL;
210 }
211
212 return 0;
213}
214
215static int atmel_pcm_prepare(struct snd_pcm_substream *substream)
216{
217 struct atmel_runtime_data *prtd = substream->runtime->private_data;
218 struct atmel_pcm_dma_params *params = prtd->params;
219
220 ssc_writex(params->ssc->regs, SSC_IDR,
221 params->mask->ssc_endx | params->mask->ssc_endbuf);
222 ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
223 params->mask->pdc_disable);
224 return 0;
225}
226
227static int atmel_pcm_trigger(struct snd_pcm_substream *substream,
228 int cmd)
229{
230 struct snd_pcm_runtime *rtd = substream->runtime;
231 struct atmel_runtime_data *prtd = rtd->private_data;
232 struct atmel_pcm_dma_params *params = prtd->params;
233 int ret = 0;
234
235 pr_debug("atmel-pcm:buffer_size = %ld,"
236 "dma_area = %p, dma_bytes = %u\n",
237 rtd->buffer_size, rtd->dma_area, rtd->dma_bytes);
238
239 switch (cmd) {
240 case SNDRV_PCM_TRIGGER_START:
241 prtd->period_ptr = prtd->dma_buffer;
242
243 ssc_writex(params->ssc->regs, params->pdc->xpr,
244 prtd->period_ptr);
245 ssc_writex(params->ssc->regs, params->pdc->xcr,
246 prtd->period_size / params->pdc_xfer_size);
247
248 prtd->period_ptr += prtd->period_size;
249 ssc_writex(params->ssc->regs, params->pdc->xnpr,
250 prtd->period_ptr);
251 ssc_writex(params->ssc->regs, params->pdc->xncr,
252 prtd->period_size / params->pdc_xfer_size);
253
254 pr_debug("atmel-pcm: trigger: "
255 "period_ptr=%lx, xpr=%u, "
256 "xcr=%u, xnpr=%u, xncr=%u\n",
257 (unsigned long)prtd->period_ptr,
258 ssc_readx(params->ssc->regs, params->pdc->xpr),
259 ssc_readx(params->ssc->regs, params->pdc->xcr),
260 ssc_readx(params->ssc->regs, params->pdc->xnpr),
261 ssc_readx(params->ssc->regs, params->pdc->xncr));
262
263 ssc_writex(params->ssc->regs, SSC_IER,
264 params->mask->ssc_endx | params->mask->ssc_endbuf);
265 ssc_writex(params->ssc->regs, SSC_PDC_PTCR,
266 params->mask->pdc_enable);
267
268 pr_debug("sr=%u imr=%u\n",
269 ssc_readx(params->ssc->regs, SSC_SR),
270 ssc_readx(params->ssc->regs, SSC_IER));
271 break; /* SNDRV_PCM_TRIGGER_START */
272
273 case SNDRV_PCM_TRIGGER_STOP:
274 case SNDRV_PCM_TRIGGER_SUSPEND:
275 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
276 ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
277 params->mask->pdc_disable);
278 break;
279
280 case SNDRV_PCM_TRIGGER_RESUME:
281 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
282 ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
283 params->mask->pdc_enable);
284 break;
285
286 default:
287 ret = -EINVAL;
288 }
289
290 return ret;
291}
292
293static snd_pcm_uframes_t atmel_pcm_pointer(
294 struct snd_pcm_substream *substream)
295{
296 struct snd_pcm_runtime *runtime = substream->runtime;
297 struct atmel_runtime_data *prtd = runtime->private_data;
298 struct atmel_pcm_dma_params *params = prtd->params;
299 dma_addr_t ptr;
300 snd_pcm_uframes_t x;
301
302 ptr = (dma_addr_t) ssc_readx(params->ssc->regs, params->pdc->xpr);
303 x = bytes_to_frames(runtime, ptr - prtd->dma_buffer);
304
305 if (x == runtime->buffer_size)
306 x = 0;
307
308 return x;
309}
310
311static int atmel_pcm_open(struct snd_pcm_substream *substream)
312{
313 struct snd_pcm_runtime *runtime = substream->runtime;
314 struct atmel_runtime_data *prtd;
315 int ret = 0;
316
317 snd_soc_set_runtime_hwparams(substream, &atmel_pcm_hardware);
318
319 /* ensure that buffer size is a multiple of period size */
320 ret = snd_pcm_hw_constraint_integer(runtime,
321 SNDRV_PCM_HW_PARAM_PERIODS);
322 if (ret < 0)
323 goto out;
324
325 prtd = kzalloc(sizeof(struct atmel_runtime_data), GFP_KERNEL);
326 if (prtd == NULL) {
327 ret = -ENOMEM;
328 goto out;
329 }
330 runtime->private_data = prtd;
331
332 out:
333 return ret;
334}
335
336static int atmel_pcm_close(struct snd_pcm_substream *substream)
337{
338 struct atmel_runtime_data *prtd = substream->runtime->private_data;
339
340 kfree(prtd);
341 return 0;
342}
343
344static int atmel_pcm_mmap(struct snd_pcm_substream *substream,
345 struct vm_area_struct *vma)
346{
347 return remap_pfn_range(vma, vma->vm_start,
348 substream->dma_buffer.addr >> PAGE_SHIFT,
349 vma->vm_end - vma->vm_start, vma->vm_page_prot);
350}
351
352struct snd_pcm_ops atmel_pcm_ops = {
353 .open = atmel_pcm_open,
354 .close = atmel_pcm_close,
355 .ioctl = snd_pcm_lib_ioctl,
356 .hw_params = atmel_pcm_hw_params,
357 .hw_free = atmel_pcm_hw_free,
358 .prepare = atmel_pcm_prepare,
359 .trigger = atmel_pcm_trigger,
360 .pointer = atmel_pcm_pointer,
361 .mmap = atmel_pcm_mmap,
362};
363
364
365/*--------------------------------------------------------------------------*\
366 * ASoC platform driver
367\*--------------------------------------------------------------------------*/
368static u64 atmel_pcm_dmamask = 0xffffffff;
369
370static int atmel_pcm_new(struct snd_card *card,
371 struct snd_soc_dai *dai, struct snd_pcm *pcm)
372{
373 int ret = 0;
374
375 if (!card->dev->dma_mask)
376 card->dev->dma_mask = &atmel_pcm_dmamask;
377 if (!card->dev->coherent_dma_mask)
378 card->dev->coherent_dma_mask = 0xffffffff;
379
380 if (dai->playback.channels_min) {
381 ret = atmel_pcm_preallocate_dma_buffer(pcm,
382 SNDRV_PCM_STREAM_PLAYBACK);
383 if (ret)
384 goto out;
385 }
386
387 if (dai->capture.channels_min) {
388 pr_debug("at32-pcm:"
389 "Allocating PCM capture DMA buffer\n");
390 ret = atmel_pcm_preallocate_dma_buffer(pcm,
391 SNDRV_PCM_STREAM_CAPTURE);
392 if (ret)
393 goto out;
394 }
395 out:
396 return ret;
397}
398
399static void atmel_pcm_free_dma_buffers(struct snd_pcm *pcm)
400{
401 struct snd_pcm_substream *substream;
402 struct snd_dma_buffer *buf;
403 int stream;
404
405 for (stream = 0; stream < 2; stream++) {
406 substream = pcm->streams[stream].substream;
407 if (!substream)
408 continue;
409
410 buf = &substream->dma_buffer;
411 if (!buf->area)
412 continue;
413 dma_free_coherent(pcm->card->dev, buf->bytes,
414 buf->area, buf->addr);
415 buf->area = NULL;
416 }
417}
418
419#ifdef CONFIG_PM
420static int atmel_pcm_suspend(struct snd_soc_dai *dai)
421{
422 struct snd_pcm_runtime *runtime = dai->runtime;
423 struct atmel_runtime_data *prtd;
424 struct atmel_pcm_dma_params *params;
425
426 if (!runtime)
427 return 0;
428
429 prtd = runtime->private_data;
430 params = prtd->params;
431
432 /* disable the PDC and save the PDC registers */
433
434 ssc_writel(params->ssc->regs, PDC_PTCR, params->mask->pdc_disable);
435
436 prtd->pdc_xpr_save = ssc_readx(params->ssc->regs, params->pdc->xpr);
437 prtd->pdc_xcr_save = ssc_readx(params->ssc->regs, params->pdc->xcr);
438 prtd->pdc_xnpr_save = ssc_readx(params->ssc->regs, params->pdc->xnpr);
439 prtd->pdc_xncr_save = ssc_readx(params->ssc->regs, params->pdc->xncr);
440
441 return 0;
442}
443
444static int atmel_pcm_resume(struct snd_soc_dai *dai)
445{
446 struct snd_pcm_runtime *runtime = dai->runtime;
447 struct atmel_runtime_data *prtd;
448 struct atmel_pcm_dma_params *params;
449
450 if (!runtime)
451 return 0;
452
453 prtd = runtime->private_data;
454 params = prtd->params;
455
456 /* restore the PDC registers and enable the PDC */
457 ssc_writex(params->ssc->regs, params->pdc->xpr, prtd->pdc_xpr_save);
458 ssc_writex(params->ssc->regs, params->pdc->xcr, prtd->pdc_xcr_save);
459 ssc_writex(params->ssc->regs, params->pdc->xnpr, prtd->pdc_xnpr_save);
460 ssc_writex(params->ssc->regs, params->pdc->xncr, prtd->pdc_xncr_save);
461
462 ssc_writel(params->ssc->regs, PDC_PTCR, params->mask->pdc_enable);
463 return 0;
464}
465#else
466#define atmel_pcm_suspend NULL
467#define atmel_pcm_resume NULL
468#endif
469
470struct snd_soc_platform atmel_soc_platform = {
471 .name = "atmel-audio",
472 .pcm_ops = &atmel_pcm_ops,
473 .pcm_new = atmel_pcm_new,
474 .pcm_free = atmel_pcm_free_dma_buffers,
475 .suspend = atmel_pcm_suspend,
476 .resume = atmel_pcm_resume,
477};
478EXPORT_SYMBOL_GPL(atmel_soc_platform);
479
480static int __init atmel_pcm_modinit(void)
481{
482 return snd_soc_register_platform(&atmel_soc_platform);
483}
484module_init(atmel_pcm_modinit);
485
486static void __exit atmel_pcm_modexit(void)
487{
488 snd_soc_unregister_platform(&atmel_soc_platform);
489}
490module_exit(atmel_pcm_modexit);
491
492MODULE_AUTHOR("Sedji Gaouaou <sedji.gaouaou@atmel.com>");
493MODULE_DESCRIPTION("Atmel PCM module");
494MODULE_LICENSE("GPL");
diff --git a/sound/soc/atmel/atmel-pcm.h b/sound/soc/atmel/atmel-pcm.h
new file mode 100644
index 000000000000..ec9b2824b663
--- /dev/null
+++ b/sound/soc/atmel/atmel-pcm.h
@@ -0,0 +1,86 @@
1/*
2 * at91-pcm.h - ALSA PCM interface for the Atmel AT91 SoC.
3 *
4 * Copyright (C) 2005 SAN People
5 * Copyright (C) 2008 Atmel
6 *
7 * Authors: Sedji Gaouaou <sedji.gaouaou@atmel.com>
8 *
9 * Based on at91-pcm. by:
10 * Frank Mandarino <fmandarino@endrelia.com>
11 * Copyright 2006 Endrelia Technologies Inc.
12 *
13 * Based on pxa2xx-pcm.c by:
14 *
15 * Author: Nicolas Pitre
16 * Created: Nov 30, 2004
17 * Copyright: (C) 2004 MontaVista Software, Inc.
18 *
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 2 of the License, or
22 * (at your option) any later version.
23 *
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
28 *
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32 */
33
34#ifndef _ATMEL_PCM_H
35#define _ATMEL_PCM_H
36
37#include <linux/atmel-ssc.h>
38
39/*
40 * Registers and status bits that are required by the PCM driver.
41 */
42struct atmel_pdc_regs {
43 unsigned int xpr; /* PDC recv/trans pointer */
44 unsigned int xcr; /* PDC recv/trans counter */
45 unsigned int xnpr; /* PDC next recv/trans pointer */
46 unsigned int xncr; /* PDC next recv/trans counter */
47 unsigned int ptcr; /* PDC transfer control */
48};
49
50struct atmel_ssc_mask {
51 u32 ssc_enable; /* SSC recv/trans enable */
52 u32 ssc_disable; /* SSC recv/trans disable */
53 u32 ssc_endx; /* SSC ENDTX or ENDRX */
54 u32 ssc_endbuf; /* SSC TXBUFE or RXBUFF */
55 u32 pdc_enable; /* PDC recv/trans enable */
56 u32 pdc_disable; /* PDC recv/trans disable */
57};
58
59/*
60 * This structure, shared between the PCM driver and the interface,
61 * contains all information required by the PCM driver to perform the
62 * PDC DMA operation. All fields except dma_intr_handler() are initialized
63 * by the interface. The dms_intr_handler() pointer is set by the PCM
64 * driver and called by the interface SSC interrupt handler if it is
65 * non-NULL.
66 */
67struct atmel_pcm_dma_params {
68 char *name; /* stream identifier */
69 int pdc_xfer_size; /* PDC counter increment in bytes */
70 struct ssc_device *ssc; /* SSC device for stream */
71 struct atmel_pdc_regs *pdc; /* PDC receive or transmit registers */
72 struct atmel_ssc_mask *mask; /* SSC & PDC status bits */
73 struct snd_pcm_substream *substream;
74 void (*dma_intr_handler)(u32, struct snd_pcm_substream *);
75};
76
77extern struct snd_soc_platform atmel_soc_platform;
78
79
80/*
81 * SSC register access (since ssc_writel() / ssc_readl() require literal name)
82 */
83#define ssc_readx(base, reg) (__raw_readl((base) + (reg)))
84#define ssc_writex(base, reg, value) __raw_writel((value), (base) + (reg))
85
86#endif /* _ATMEL_PCM_H */
diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c
new file mode 100644
index 000000000000..c5d67900d666
--- /dev/null
+++ b/sound/soc/atmel/atmel_ssc_dai.c
@@ -0,0 +1,790 @@
1/*
2 * atmel_ssc_dai.c -- ALSA SoC ATMEL SSC Audio Layer Platform driver
3 *
4 * Copyright (C) 2005 SAN People
5 * Copyright (C) 2008 Atmel
6 *
7 * Author: Sedji Gaouaou <sedji.gaouaou@atmel.com>
8 * ATMEL CORP.
9 *
10 * Based on at91-ssc.c by
11 * Frank Mandarino <fmandarino@endrelia.com>
12 * Based on pxa2xx Platform drivers by
13 * Liam Girdwood <liam.girdwood@wolfsonmicro.com>
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, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 */
29
30#include <linux/init.h>
31#include <linux/module.h>
32#include <linux/interrupt.h>
33#include <linux/device.h>
34#include <linux/delay.h>
35#include <linux/clk.h>
36#include <linux/atmel_pdc.h>
37
38#include <linux/atmel-ssc.h>
39#include <sound/core.h>
40#include <sound/pcm.h>
41#include <sound/pcm_params.h>
42#include <sound/initval.h>
43#include <sound/soc.h>
44
45#include <mach/hardware.h>
46
47#include "atmel-pcm.h"
48#include "atmel_ssc_dai.h"
49
50
51#if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9G20)
52#define NUM_SSC_DEVICES 1
53#else
54#define NUM_SSC_DEVICES 3
55#endif
56
57/*
58 * SSC PDC registers required by the PCM DMA engine.
59 */
60static struct atmel_pdc_regs pdc_tx_reg = {
61 .xpr = ATMEL_PDC_TPR,
62 .xcr = ATMEL_PDC_TCR,
63 .xnpr = ATMEL_PDC_TNPR,
64 .xncr = ATMEL_PDC_TNCR,
65};
66
67static struct atmel_pdc_regs pdc_rx_reg = {
68 .xpr = ATMEL_PDC_RPR,
69 .xcr = ATMEL_PDC_RCR,
70 .xnpr = ATMEL_PDC_RNPR,
71 .xncr = ATMEL_PDC_RNCR,
72};
73
74/*
75 * SSC & PDC status bits for transmit and receive.
76 */
77static struct atmel_ssc_mask ssc_tx_mask = {
78 .ssc_enable = SSC_BIT(CR_TXEN),
79 .ssc_disable = SSC_BIT(CR_TXDIS),
80 .ssc_endx = SSC_BIT(SR_ENDTX),
81 .ssc_endbuf = SSC_BIT(SR_TXBUFE),
82 .pdc_enable = ATMEL_PDC_TXTEN,
83 .pdc_disable = ATMEL_PDC_TXTDIS,
84};
85
86static struct atmel_ssc_mask ssc_rx_mask = {
87 .ssc_enable = SSC_BIT(CR_RXEN),
88 .ssc_disable = SSC_BIT(CR_RXDIS),
89 .ssc_endx = SSC_BIT(SR_ENDRX),
90 .ssc_endbuf = SSC_BIT(SR_RXBUFF),
91 .pdc_enable = ATMEL_PDC_RXTEN,
92 .pdc_disable = ATMEL_PDC_RXTDIS,
93};
94
95
96/*
97 * DMA parameters.
98 */
99static struct atmel_pcm_dma_params ssc_dma_params[NUM_SSC_DEVICES][2] = {
100 {{
101 .name = "SSC0 PCM out",
102 .pdc = &pdc_tx_reg,
103 .mask = &ssc_tx_mask,
104 },
105 {
106 .name = "SSC0 PCM in",
107 .pdc = &pdc_rx_reg,
108 .mask = &ssc_rx_mask,
109 } },
110#if NUM_SSC_DEVICES == 3
111 {{
112 .name = "SSC1 PCM out",
113 .pdc = &pdc_tx_reg,
114 .mask = &ssc_tx_mask,
115 },
116 {
117 .name = "SSC1 PCM in",
118 .pdc = &pdc_rx_reg,
119 .mask = &ssc_rx_mask,
120 } },
121 {{
122 .name = "SSC2 PCM out",
123 .pdc = &pdc_tx_reg,
124 .mask = &ssc_tx_mask,
125 },
126 {
127 .name = "SSC2 PCM in",
128 .pdc = &pdc_rx_reg,
129 .mask = &ssc_rx_mask,
130 } },
131#endif
132};
133
134
135static struct atmel_ssc_info ssc_info[NUM_SSC_DEVICES] = {
136 {
137 .name = "ssc0",
138 .lock = __SPIN_LOCK_UNLOCKED(ssc_info[0].lock),
139 .dir_mask = SSC_DIR_MASK_UNUSED,
140 .initialized = 0,
141 },
142#if NUM_SSC_DEVICES == 3
143 {
144 .name = "ssc1",
145 .lock = __SPIN_LOCK_UNLOCKED(ssc_info[1].lock),
146 .dir_mask = SSC_DIR_MASK_UNUSED,
147 .initialized = 0,
148 },
149 {
150 .name = "ssc2",
151 .lock = __SPIN_LOCK_UNLOCKED(ssc_info[2].lock),
152 .dir_mask = SSC_DIR_MASK_UNUSED,
153 .initialized = 0,
154 },
155#endif
156};
157
158
159/*
160 * SSC interrupt handler. Passes PDC interrupts to the DMA
161 * interrupt handler in the PCM driver.
162 */
163static irqreturn_t atmel_ssc_interrupt(int irq, void *dev_id)
164{
165 struct atmel_ssc_info *ssc_p = dev_id;
166 struct atmel_pcm_dma_params *dma_params;
167 u32 ssc_sr;
168 u32 ssc_substream_mask;
169 int i;
170
171 ssc_sr = (unsigned long)ssc_readl(ssc_p->ssc->regs, SR)
172 & (unsigned long)ssc_readl(ssc_p->ssc->regs, IMR);
173
174 /*
175 * Loop through the substreams attached to this SSC. If
176 * a DMA-related interrupt occurred on that substream, call
177 * the DMA interrupt handler function, if one has been
178 * registered in the dma_params structure by the PCM driver.
179 */
180 for (i = 0; i < ARRAY_SIZE(ssc_p->dma_params); i++) {
181 dma_params = ssc_p->dma_params[i];
182
183 if ((dma_params != NULL) &&
184 (dma_params->dma_intr_handler != NULL)) {
185 ssc_substream_mask = (dma_params->mask->ssc_endx |
186 dma_params->mask->ssc_endbuf);
187 if (ssc_sr & ssc_substream_mask) {
188 dma_params->dma_intr_handler(ssc_sr,
189 dma_params->
190 substream);
191 }
192 }
193 }
194
195 return IRQ_HANDLED;
196}
197
198
199/*-------------------------------------------------------------------------*\
200 * DAI functions
201\*-------------------------------------------------------------------------*/
202/*
203 * Startup. Only that one substream allowed in each direction.
204 */
205static int atmel_ssc_startup(struct snd_pcm_substream *substream,
206 struct snd_soc_dai *dai)
207{
208 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
209 struct atmel_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
210 int dir_mask;
211
212 pr_debug("atmel_ssc_startup: SSC_SR=0x%u\n",
213 ssc_readl(ssc_p->ssc->regs, SR));
214
215 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
216 dir_mask = SSC_DIR_MASK_PLAYBACK;
217 else
218 dir_mask = SSC_DIR_MASK_CAPTURE;
219
220 spin_lock_irq(&ssc_p->lock);
221 if (ssc_p->dir_mask & dir_mask) {
222 spin_unlock_irq(&ssc_p->lock);
223 return -EBUSY;
224 }
225 ssc_p->dir_mask |= dir_mask;
226 spin_unlock_irq(&ssc_p->lock);
227
228 return 0;
229}
230
231/*
232 * Shutdown. Clear DMA parameters and shutdown the SSC if there
233 * are no other substreams open.
234 */
235static void atmel_ssc_shutdown(struct snd_pcm_substream *substream,
236 struct snd_soc_dai *dai)
237{
238 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
239 struct atmel_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
240 struct atmel_pcm_dma_params *dma_params;
241 int dir, dir_mask;
242
243 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
244 dir = 0;
245 else
246 dir = 1;
247
248 dma_params = ssc_p->dma_params[dir];
249
250 if (dma_params != NULL) {
251 ssc_writel(ssc_p->ssc->regs, CR, dma_params->mask->ssc_disable);
252 pr_debug("atmel_ssc_shutdown: %s disabled SSC_SR=0x%08x\n",
253 (dir ? "receive" : "transmit"),
254 ssc_readl(ssc_p->ssc->regs, SR));
255
256 dma_params->ssc = NULL;
257 dma_params->substream = NULL;
258 ssc_p->dma_params[dir] = NULL;
259 }
260
261 dir_mask = 1 << dir;
262
263 spin_lock_irq(&ssc_p->lock);
264 ssc_p->dir_mask &= ~dir_mask;
265 if (!ssc_p->dir_mask) {
266 if (ssc_p->initialized) {
267 /* Shutdown the SSC clock. */
268 pr_debug("atmel_ssc_dau: Stopping clock\n");
269 clk_disable(ssc_p->ssc->clk);
270
271 free_irq(ssc_p->ssc->irq, ssc_p);
272 ssc_p->initialized = 0;
273 }
274
275 /* Reset the SSC */
276 ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST));
277 /* Clear the SSC dividers */
278 ssc_p->cmr_div = ssc_p->tcmr_period = ssc_p->rcmr_period = 0;
279 }
280 spin_unlock_irq(&ssc_p->lock);
281}
282
283
284/*
285 * Record the DAI format for use in hw_params().
286 */
287static int atmel_ssc_set_dai_fmt(struct snd_soc_dai *cpu_dai,
288 unsigned int fmt)
289{
290 struct atmel_ssc_info *ssc_p = &ssc_info[cpu_dai->id];
291
292 ssc_p->daifmt = fmt;
293 return 0;
294}
295
296/*
297 * Record SSC clock dividers for use in hw_params().
298 */
299static int atmel_ssc_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
300 int div_id, int div)
301{
302 struct atmel_ssc_info *ssc_p = &ssc_info[cpu_dai->id];
303
304 switch (div_id) {
305 case ATMEL_SSC_CMR_DIV:
306 /*
307 * The same master clock divider is used for both
308 * transmit and receive, so if a value has already
309 * been set, it must match this value.
310 */
311 if (ssc_p->cmr_div == 0)
312 ssc_p->cmr_div = div;
313 else
314 if (div != ssc_p->cmr_div)
315 return -EBUSY;
316 break;
317
318 case ATMEL_SSC_TCMR_PERIOD:
319 ssc_p->tcmr_period = div;
320 break;
321
322 case ATMEL_SSC_RCMR_PERIOD:
323 ssc_p->rcmr_period = div;
324 break;
325
326 default:
327 return -EINVAL;
328 }
329
330 return 0;
331}
332
333/*
334 * Configure the SSC.
335 */
336static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
337 struct snd_pcm_hw_params *params,
338 struct snd_soc_dai *dai)
339{
340 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
341 int id = rtd->dai->cpu_dai->id;
342 struct atmel_ssc_info *ssc_p = &ssc_info[id];
343 struct atmel_pcm_dma_params *dma_params;
344 int dir, channels, bits;
345 u32 tfmr, rfmr, tcmr, rcmr;
346 int start_event;
347 int ret;
348
349 /*
350 * Currently, there is only one set of dma params for
351 * each direction. If more are added, this code will
352 * have to be changed to select the proper set.
353 */
354 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
355 dir = 0;
356 else
357 dir = 1;
358
359 dma_params = &ssc_dma_params[id][dir];
360 dma_params->ssc = ssc_p->ssc;
361 dma_params->substream = substream;
362
363 ssc_p->dma_params[dir] = dma_params;
364
365 /*
366 * The cpu_dai->dma_data field is only used to communicate the
367 * appropriate DMA parameters to the pcm driver hw_params()
368 * function. It should not be used for other purposes
369 * as it is common to all substreams.
370 */
371 rtd->dai->cpu_dai->dma_data = dma_params;
372
373 channels = params_channels(params);
374
375 /*
376 * Determine sample size in bits and the PDC increment.
377 */
378 switch (params_format(params)) {
379 case SNDRV_PCM_FORMAT_S8:
380 bits = 8;
381 dma_params->pdc_xfer_size = 1;
382 break;
383 case SNDRV_PCM_FORMAT_S16_LE:
384 bits = 16;
385 dma_params->pdc_xfer_size = 2;
386 break;
387 case SNDRV_PCM_FORMAT_S24_LE:
388 bits = 24;
389 dma_params->pdc_xfer_size = 4;
390 break;
391 case SNDRV_PCM_FORMAT_S32_LE:
392 bits = 32;
393 dma_params->pdc_xfer_size = 4;
394 break;
395 default:
396 printk(KERN_WARNING "atmel_ssc_dai: unsupported PCM format");
397 return -EINVAL;
398 }
399
400 /*
401 * The SSC only supports up to 16-bit samples in I2S format, due
402 * to the size of the Frame Mode Register FSLEN field.
403 */
404 if ((ssc_p->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_I2S
405 && bits > 16) {
406 printk(KERN_WARNING
407 "atmel_ssc_dai: sample size %d"
408 "is too large for I2S\n", bits);
409 return -EINVAL;
410 }
411
412 /*
413 * Compute SSC register settings.
414 */
415 switch (ssc_p->daifmt
416 & (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_MASTER_MASK)) {
417
418 case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS:
419 /*
420 * I2S format, SSC provides BCLK and LRC clocks.
421 *
422 * The SSC transmit and receive clocks are generated
423 * from the MCK divider, and the BCLK signal
424 * is output on the SSC TK line.
425 */
426 rcmr = SSC_BF(RCMR_PERIOD, ssc_p->rcmr_period)
427 | SSC_BF(RCMR_STTDLY, START_DELAY)
428 | SSC_BF(RCMR_START, SSC_START_FALLING_RF)
429 | SSC_BF(RCMR_CKI, SSC_CKI_RISING)
430 | SSC_BF(RCMR_CKO, SSC_CKO_NONE)
431 | SSC_BF(RCMR_CKS, SSC_CKS_DIV);
432
433 rfmr = SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
434 | SSC_BF(RFMR_FSOS, SSC_FSOS_NEGATIVE)
435 | SSC_BF(RFMR_FSLEN, (bits - 1))
436 | SSC_BF(RFMR_DATNB, (channels - 1))
437 | SSC_BIT(RFMR_MSBF)
438 | SSC_BF(RFMR_LOOP, 0)
439 | SSC_BF(RFMR_DATLEN, (bits - 1));
440
441 tcmr = SSC_BF(TCMR_PERIOD, ssc_p->tcmr_period)
442 | SSC_BF(TCMR_STTDLY, START_DELAY)
443 | SSC_BF(TCMR_START, SSC_START_FALLING_RF)
444 | SSC_BF(TCMR_CKI, SSC_CKI_FALLING)
445 | SSC_BF(TCMR_CKO, SSC_CKO_CONTINUOUS)
446 | SSC_BF(TCMR_CKS, SSC_CKS_DIV);
447
448 tfmr = SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
449 | SSC_BF(TFMR_FSDEN, 0)
450 | SSC_BF(TFMR_FSOS, SSC_FSOS_NEGATIVE)
451 | SSC_BF(TFMR_FSLEN, (bits - 1))
452 | SSC_BF(TFMR_DATNB, (channels - 1))
453 | SSC_BIT(TFMR_MSBF)
454 | SSC_BF(TFMR_DATDEF, 0)
455 | SSC_BF(TFMR_DATLEN, (bits - 1));
456 break;
457
458 case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM:
459 /*
460 * I2S format, CODEC supplies BCLK and LRC clocks.
461 *
462 * The SSC transmit clock is obtained from the BCLK signal on
463 * on the TK line, and the SSC receive clock is
464 * generated from the transmit clock.
465 *
466 * For single channel data, one sample is transferred
467 * on the falling edge of the LRC clock.
468 * For two channel data, one sample is
469 * transferred on both edges of the LRC clock.
470 */
471 start_event = ((channels == 1)
472 ? SSC_START_FALLING_RF
473 : SSC_START_EDGE_RF);
474
475 rcmr = SSC_BF(RCMR_PERIOD, 0)
476 | SSC_BF(RCMR_STTDLY, START_DELAY)
477 | SSC_BF(RCMR_START, start_event)
478 | SSC_BF(RCMR_CKI, SSC_CKI_RISING)
479 | SSC_BF(RCMR_CKO, SSC_CKO_NONE)
480 | SSC_BF(RCMR_CKS, SSC_CKS_CLOCK);
481
482 rfmr = SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
483 | SSC_BF(RFMR_FSOS, SSC_FSOS_NONE)
484 | SSC_BF(RFMR_FSLEN, 0)
485 | SSC_BF(RFMR_DATNB, 0)
486 | SSC_BIT(RFMR_MSBF)
487 | SSC_BF(RFMR_LOOP, 0)
488 | SSC_BF(RFMR_DATLEN, (bits - 1));
489
490 tcmr = SSC_BF(TCMR_PERIOD, 0)
491 | SSC_BF(TCMR_STTDLY, START_DELAY)
492 | SSC_BF(TCMR_START, start_event)
493 | SSC_BF(TCMR_CKI, SSC_CKI_FALLING)
494 | SSC_BF(TCMR_CKO, SSC_CKO_NONE)
495 | SSC_BF(TCMR_CKS, SSC_CKS_PIN);
496
497 tfmr = SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
498 | SSC_BF(TFMR_FSDEN, 0)
499 | SSC_BF(TFMR_FSOS, SSC_FSOS_NONE)
500 | SSC_BF(TFMR_FSLEN, 0)
501 | SSC_BF(TFMR_DATNB, 0)
502 | SSC_BIT(TFMR_MSBF)
503 | SSC_BF(TFMR_DATDEF, 0)
504 | SSC_BF(TFMR_DATLEN, (bits - 1));
505 break;
506
507 case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBS_CFS:
508 /*
509 * DSP/PCM Mode A format, SSC provides BCLK and LRC clocks.
510 *
511 * The SSC transmit and receive clocks are generated from the
512 * MCK divider, and the BCLK signal is output
513 * on the SSC TK line.
514 */
515 rcmr = SSC_BF(RCMR_PERIOD, ssc_p->rcmr_period)
516 | SSC_BF(RCMR_STTDLY, 1)
517 | SSC_BF(RCMR_START, SSC_START_RISING_RF)
518 | SSC_BF(RCMR_CKI, SSC_CKI_RISING)
519 | SSC_BF(RCMR_CKO, SSC_CKO_NONE)
520 | SSC_BF(RCMR_CKS, SSC_CKS_DIV);
521
522 rfmr = SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
523 | SSC_BF(RFMR_FSOS, SSC_FSOS_POSITIVE)
524 | SSC_BF(RFMR_FSLEN, 0)
525 | SSC_BF(RFMR_DATNB, (channels - 1))
526 | SSC_BIT(RFMR_MSBF)
527 | SSC_BF(RFMR_LOOP, 0)
528 | SSC_BF(RFMR_DATLEN, (bits - 1));
529
530 tcmr = SSC_BF(TCMR_PERIOD, ssc_p->tcmr_period)
531 | SSC_BF(TCMR_STTDLY, 1)
532 | SSC_BF(TCMR_START, SSC_START_RISING_RF)
533 | SSC_BF(TCMR_CKI, SSC_CKI_RISING)
534 | SSC_BF(TCMR_CKO, SSC_CKO_CONTINUOUS)
535 | SSC_BF(TCMR_CKS, SSC_CKS_DIV);
536
537 tfmr = SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
538 | SSC_BF(TFMR_FSDEN, 0)
539 | SSC_BF(TFMR_FSOS, SSC_FSOS_POSITIVE)
540 | SSC_BF(TFMR_FSLEN, 0)
541 | SSC_BF(TFMR_DATNB, (channels - 1))
542 | SSC_BIT(TFMR_MSBF)
543 | SSC_BF(TFMR_DATDEF, 0)
544 | SSC_BF(TFMR_DATLEN, (bits - 1));
545 break;
546
547 case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBM_CFM:
548 default:
549 printk(KERN_WARNING "atmel_ssc_dai: unsupported DAI format 0x%x\n",
550 ssc_p->daifmt);
551 return -EINVAL;
552 break;
553 }
554 pr_debug("atmel_ssc_hw_params: "
555 "RCMR=%08x RFMR=%08x TCMR=%08x TFMR=%08x\n",
556 rcmr, rfmr, tcmr, tfmr);
557
558 if (!ssc_p->initialized) {
559
560 /* Enable PMC peripheral clock for this SSC */
561 pr_debug("atmel_ssc_dai: Starting clock\n");
562 clk_enable(ssc_p->ssc->clk);
563
564 /* Reset the SSC and its PDC registers */
565 ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST));
566
567 ssc_writel(ssc_p->ssc->regs, PDC_RPR, 0);
568 ssc_writel(ssc_p->ssc->regs, PDC_RCR, 0);
569 ssc_writel(ssc_p->ssc->regs, PDC_RNPR, 0);
570 ssc_writel(ssc_p->ssc->regs, PDC_RNCR, 0);
571
572 ssc_writel(ssc_p->ssc->regs, PDC_TPR, 0);
573 ssc_writel(ssc_p->ssc->regs, PDC_TCR, 0);
574 ssc_writel(ssc_p->ssc->regs, PDC_TNPR, 0);
575 ssc_writel(ssc_p->ssc->regs, PDC_TNCR, 0);
576
577 ret = request_irq(ssc_p->ssc->irq, atmel_ssc_interrupt, 0,
578 ssc_p->name, ssc_p);
579 if (ret < 0) {
580 printk(KERN_WARNING
581 "atmel_ssc_dai: request_irq failure\n");
582 pr_debug("Atmel_ssc_dai: Stoping clock\n");
583 clk_disable(ssc_p->ssc->clk);
584 return ret;
585 }
586
587 ssc_p->initialized = 1;
588 }
589
590 /* set SSC clock mode register */
591 ssc_writel(ssc_p->ssc->regs, CMR, ssc_p->cmr_div);
592
593 /* set receive clock mode and format */
594 ssc_writel(ssc_p->ssc->regs, RCMR, rcmr);
595 ssc_writel(ssc_p->ssc->regs, RFMR, rfmr);
596
597 /* set transmit clock mode and format */
598 ssc_writel(ssc_p->ssc->regs, TCMR, tcmr);
599 ssc_writel(ssc_p->ssc->regs, TFMR, tfmr);
600
601 pr_debug("atmel_ssc_dai,hw_params: SSC initialized\n");
602 return 0;
603}
604
605
606static int atmel_ssc_prepare(struct snd_pcm_substream *substream,
607 struct snd_soc_dai *dai)
608{
609 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
610 struct atmel_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
611 struct atmel_pcm_dma_params *dma_params;
612 int dir;
613
614 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
615 dir = 0;
616 else
617 dir = 1;
618
619 dma_params = ssc_p->dma_params[dir];
620
621 ssc_writel(ssc_p->ssc->regs, CR, dma_params->mask->ssc_enable);
622
623 pr_debug("%s enabled SSC_SR=0x%08x\n",
624 dir ? "receive" : "transmit",
625 ssc_readl(ssc_p->ssc->regs, SR));
626 return 0;
627}
628
629
630#ifdef CONFIG_PM
631static int atmel_ssc_suspend(struct snd_soc_dai *cpu_dai)
632{
633 struct atmel_ssc_info *ssc_p;
634
635 if (!cpu_dai->active)
636 return 0;
637
638 ssc_p = &ssc_info[cpu_dai->id];
639
640 /* Save the status register before disabling transmit and receive */
641 ssc_p->ssc_state.ssc_sr = ssc_readl(ssc_p->ssc->regs, SR);
642 ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_TXDIS) | SSC_BIT(CR_RXDIS));
643
644 /* Save the current interrupt mask, then disable unmasked interrupts */
645 ssc_p->ssc_state.ssc_imr = ssc_readl(ssc_p->ssc->regs, IMR);
646 ssc_writel(ssc_p->ssc->regs, IDR, ssc_p->ssc_state.ssc_imr);
647
648 ssc_p->ssc_state.ssc_cmr = ssc_readl(ssc_p->ssc->regs, CMR);
649 ssc_p->ssc_state.ssc_rcmr = ssc_readl(ssc_p->ssc->regs, RCMR);
650 ssc_p->ssc_state.ssc_rfmr = ssc_readl(ssc_p->ssc->regs, RFMR);
651 ssc_p->ssc_state.ssc_tcmr = ssc_readl(ssc_p->ssc->regs, TCMR);
652 ssc_p->ssc_state.ssc_tfmr = ssc_readl(ssc_p->ssc->regs, TFMR);
653
654 return 0;
655}
656
657
658
659static int atmel_ssc_resume(struct snd_soc_dai *cpu_dai)
660{
661 struct atmel_ssc_info *ssc_p;
662 u32 cr;
663
664 if (!cpu_dai->active)
665 return 0;
666
667 ssc_p = &ssc_info[cpu_dai->id];
668
669 /* restore SSC register settings */
670 ssc_writel(ssc_p->ssc->regs, TFMR, ssc_p->ssc_state.ssc_tfmr);
671 ssc_writel(ssc_p->ssc->regs, TCMR, ssc_p->ssc_state.ssc_tcmr);
672 ssc_writel(ssc_p->ssc->regs, RFMR, ssc_p->ssc_state.ssc_rfmr);
673 ssc_writel(ssc_p->ssc->regs, RCMR, ssc_p->ssc_state.ssc_rcmr);
674 ssc_writel(ssc_p->ssc->regs, CMR, ssc_p->ssc_state.ssc_cmr);
675
676 /* re-enable interrupts */
677 ssc_writel(ssc_p->ssc->regs, IER, ssc_p->ssc_state.ssc_imr);
678
679 /* Re-enable recieve and transmit as appropriate */
680 cr = 0;
681 cr |=
682 (ssc_p->ssc_state.ssc_sr & SSC_BIT(SR_RXEN)) ? SSC_BIT(CR_RXEN) : 0;
683 cr |=
684 (ssc_p->ssc_state.ssc_sr & SSC_BIT(SR_TXEN)) ? SSC_BIT(CR_TXEN) : 0;
685 ssc_writel(ssc_p->ssc->regs, CR, cr);
686
687 return 0;
688}
689#else /* CONFIG_PM */
690# define atmel_ssc_suspend NULL
691# define atmel_ssc_resume NULL
692#endif /* CONFIG_PM */
693
694
695#define ATMEL_SSC_RATES (SNDRV_PCM_RATE_8000_96000)
696
697#define ATMEL_SSC_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\
698 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
699
700struct snd_soc_dai atmel_ssc_dai[NUM_SSC_DEVICES] = {
701 { .name = "atmel-ssc0",
702 .id = 0,
703 .suspend = atmel_ssc_suspend,
704 .resume = atmel_ssc_resume,
705 .playback = {
706 .channels_min = 1,
707 .channels_max = 2,
708 .rates = ATMEL_SSC_RATES,
709 .formats = ATMEL_SSC_FORMATS,},
710 .capture = {
711 .channels_min = 1,
712 .channels_max = 2,
713 .rates = ATMEL_SSC_RATES,
714 .formats = ATMEL_SSC_FORMATS,},
715 .ops = {
716 .startup = atmel_ssc_startup,
717 .shutdown = atmel_ssc_shutdown,
718 .prepare = atmel_ssc_prepare,
719 .hw_params = atmel_ssc_hw_params,
720 .set_fmt = atmel_ssc_set_dai_fmt,
721 .set_clkdiv = atmel_ssc_set_dai_clkdiv,},
722 .private_data = &ssc_info[0],
723 },
724#if NUM_SSC_DEVICES == 3
725 { .name = "atmel-ssc1",
726 .id = 1,
727 .suspend = atmel_ssc_suspend,
728 .resume = atmel_ssc_resume,
729 .playback = {
730 .channels_min = 1,
731 .channels_max = 2,
732 .rates = ATMEL_SSC_RATES,
733 .formats = ATMEL_SSC_FORMATS,},
734 .capture = {
735 .channels_min = 1,
736 .channels_max = 2,
737 .rates = ATMEL_SSC_RATES,
738 .formats = ATMEL_SSC_FORMATS,},
739 .ops = {
740 .startup = atmel_ssc_startup,
741 .shutdown = atmel_ssc_shutdown,
742 .prepare = atmel_ssc_prepare,
743 .hw_params = atmel_ssc_hw_params,
744 .set_fmt = atmel_ssc_set_dai_fmt,
745 .set_clkdiv = atmel_ssc_set_dai_clkdiv,},
746 .private_data = &ssc_info[1],
747 },
748 { .name = "atmel-ssc2",
749 .id = 2,
750 .suspend = atmel_ssc_suspend,
751 .resume = atmel_ssc_resume,
752 .playback = {
753 .channels_min = 1,
754 .channels_max = 2,
755 .rates = ATMEL_SSC_RATES,
756 .formats = ATMEL_SSC_FORMATS,},
757 .capture = {
758 .channels_min = 1,
759 .channels_max = 2,
760 .rates = ATMEL_SSC_RATES,
761 .formats = ATMEL_SSC_FORMATS,},
762 .ops = {
763 .startup = atmel_ssc_startup,
764 .shutdown = atmel_ssc_shutdown,
765 .prepare = atmel_ssc_prepare,
766 .hw_params = atmel_ssc_hw_params,
767 .set_fmt = atmel_ssc_set_dai_fmt,
768 .set_clkdiv = atmel_ssc_set_dai_clkdiv,},
769 .private_data = &ssc_info[2],
770 },
771#endif
772};
773EXPORT_SYMBOL_GPL(atmel_ssc_dai);
774
775static int __init atmel_ssc_modinit(void)
776{
777 return snd_soc_register_dais(atmel_ssc_dai, ARRAY_SIZE(atmel_ssc_dai));
778}
779module_init(atmel_ssc_modinit);
780
781static void __exit atmel_ssc_modexit(void)
782{
783 snd_soc_unregister_dais(atmel_ssc_dai, ARRAY_SIZE(atmel_ssc_dai));
784}
785module_exit(atmel_ssc_modexit);
786
787/* Module information */
788MODULE_AUTHOR("Sedji Gaouaou, sedji.gaouaou@atmel.com, www.atmel.com");
789MODULE_DESCRIPTION("ATMEL SSC ASoC Interface");
790MODULE_LICENSE("GPL");
diff --git a/sound/soc/atmel/atmel_ssc_dai.h b/sound/soc/atmel/atmel_ssc_dai.h
new file mode 100644
index 000000000000..a828746e8a2f
--- /dev/null
+++ b/sound/soc/atmel/atmel_ssc_dai.h
@@ -0,0 +1,121 @@
1/*
2 * atmel_ssc_dai.h - ALSA SSC interface for the Atmel SoC
3 *
4 * Copyright (C) 2005 SAN People
5 * Copyright (C) 2008 Atmel
6 *
7 * Author: Sedji Gaouaou <sedji.gaouaou@atmel.com>
8 * ATMEL CORP.
9 *
10 * Based on at91-ssc.c by
11 * Frank Mandarino <fmandarino@endrelia.com>
12 * Based on pxa2xx Platform drivers by
13 * Liam Girdwood <liam.girdwood@wolfsonmicro.com>
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, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 */
29
30#ifndef _ATMEL_SSC_DAI_H
31#define _ATMEL_SSC_DAI_H
32
33#include <linux/types.h>
34#include <linux/atmel-ssc.h>
35
36#include "atmel-pcm.h"
37
38/* SSC system clock ids */
39#define ATMEL_SYSCLK_MCK 0 /* SSC uses AT91 MCK as system clock */
40
41/* SSC divider ids */
42#define ATMEL_SSC_CMR_DIV 0 /* MCK divider for BCLK */
43#define ATMEL_SSC_TCMR_PERIOD 1 /* BCLK divider for transmit FS */
44#define ATMEL_SSC_RCMR_PERIOD 2 /* BCLK divider for receive FS */
45/*
46 * SSC direction masks
47 */
48#define SSC_DIR_MASK_UNUSED 0
49#define SSC_DIR_MASK_PLAYBACK 1
50#define SSC_DIR_MASK_CAPTURE 2
51
52/*
53 * SSC register values that Atmel left out of <linux/atmel-ssc.h>. These
54 * are expected to be used with SSC_BF
55 */
56/* START bit field values */
57#define SSC_START_CONTINUOUS 0
58#define SSC_START_TX_RX 1
59#define SSC_START_LOW_RF 2
60#define SSC_START_HIGH_RF 3
61#define SSC_START_FALLING_RF 4
62#define SSC_START_RISING_RF 5
63#define SSC_START_LEVEL_RF 6
64#define SSC_START_EDGE_RF 7
65#define SSS_START_COMPARE_0 8
66
67/* CKI bit field values */
68#define SSC_CKI_FALLING 0
69#define SSC_CKI_RISING 1
70
71/* CKO bit field values */
72#define SSC_CKO_NONE 0
73#define SSC_CKO_CONTINUOUS 1
74#define SSC_CKO_TRANSFER 2
75
76/* CKS bit field values */
77#define SSC_CKS_DIV 0
78#define SSC_CKS_CLOCK 1
79#define SSC_CKS_PIN 2
80
81/* FSEDGE bit field values */
82#define SSC_FSEDGE_POSITIVE 0
83#define SSC_FSEDGE_NEGATIVE 1
84
85/* FSOS bit field values */
86#define SSC_FSOS_NONE 0
87#define SSC_FSOS_NEGATIVE 1
88#define SSC_FSOS_POSITIVE 2
89#define SSC_FSOS_LOW 3
90#define SSC_FSOS_HIGH 4
91#define SSC_FSOS_TOGGLE 5
92
93#define START_DELAY 1
94
95struct atmel_ssc_state {
96 u32 ssc_cmr;
97 u32 ssc_rcmr;
98 u32 ssc_rfmr;
99 u32 ssc_tcmr;
100 u32 ssc_tfmr;
101 u32 ssc_sr;
102 u32 ssc_imr;
103};
104
105
106struct atmel_ssc_info {
107 char *name;
108 struct ssc_device *ssc;
109 spinlock_t lock; /* lock for dir_mask */
110 unsigned short dir_mask; /* 0=unused, 1=playback, 2=capture */
111 unsigned short initialized; /* true if SSC has been initialized */
112 unsigned short daifmt;
113 unsigned short cmr_div;
114 unsigned short tcmr_period;
115 unsigned short rcmr_period;
116 struct atmel_pcm_dma_params *dma_params[2];
117 struct atmel_ssc_state ssc_state;
118};
119extern struct snd_soc_dai atmel_ssc_dai[];
120
121#endif /* _AT91_SSC_DAI_H */
diff --git a/sound/soc/at32/playpaq_wm8510.c b/sound/soc/atmel/playpaq_wm8510.c
index b1966e4dfcd3..43dd8cee83c6 100644
--- a/sound/soc/at32/playpaq_wm8510.c
+++ b/sound/soc/atmel/playpaq_wm8510.c
@@ -22,7 +22,6 @@
22 22
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/moduleparam.h> 24#include <linux/moduleparam.h>
25#include <linux/version.h>
26#include <linux/kernel.h> 25#include <linux/kernel.h>
27#include <linux/errno.h> 26#include <linux/errno.h>
28#include <linux/clk.h> 27#include <linux/clk.h>
@@ -40,8 +39,8 @@
40#include <mach/portmux.h> 39#include <mach/portmux.h>
41 40
42#include "../codecs/wm8510.h" 41#include "../codecs/wm8510.h"
43#include "at32-pcm.h" 42#include "atmel-pcm.h"
44#include "at32-ssc.h" 43#include "atmel_ssc_dai.h"
45 44
46 45
47/*-------------------------------------------------------------------------*\ 46/*-------------------------------------------------------------------------*\
@@ -362,8 +361,9 @@ static struct snd_soc_dai_link playpaq_wm8510_dai = {
362 361
363 362
364 363
365static struct snd_soc_machine snd_soc_machine_playpaq = { 364static struct snd_soc_card snd_soc_playpaq = {
366 .name = "LRS_PlayPaq_WM8510", 365 .name = "LRS_PlayPaq_WM8510",
366 .platform = &at32_soc_platform,
367 .dai_link = &playpaq_wm8510_dai, 367 .dai_link = &playpaq_wm8510_dai,
368 .num_links = 1, 368 .num_links = 1,
369}; 369};
@@ -378,8 +378,7 @@ static struct wm8510_setup_data playpaq_wm8510_setup = {
378 378
379 379
380static struct snd_soc_device playpaq_wm8510_snd_devdata = { 380static struct snd_soc_device playpaq_wm8510_snd_devdata = {
381 .machine = &snd_soc_machine_playpaq, 381 .card = &snd_soc_playpaq,
382 .platform = &at32_soc_platform,
383 .codec_dev = &soc_codec_dev_wm8510, 382 .codec_dev = &soc_codec_dev_wm8510,
384 .codec_data = &playpaq_wm8510_setup, 383 .codec_data = &playpaq_wm8510_setup,
385}; 384};
diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c
new file mode 100644
index 000000000000..1fb59a9d3719
--- /dev/null
+++ b/sound/soc/atmel/sam9g20_wm8731.c
@@ -0,0 +1,328 @@
1/*
2 * sam9g20_wm8731 -- SoC audio for AT91SAM9G20-based
3 * ATMEL AT91SAM9G20ek board.
4 *
5 * Copyright (C) 2005 SAN People
6 * Copyright (C) 2008 Atmel
7 *
8 * Authors: Sedji Gaouaou <sedji.gaouaou@atmel.com>
9 *
10 * Based on ati_b1_wm8731.c by:
11 * Frank Mandarino <fmandarino@endrelia.com>
12 * Copyright 2006 Endrelia Technologies Inc.
13 * Based on corgi.c by:
14 * Copyright 2005 Wolfson Microelectronics PLC.
15 * Copyright 2005 Openedhand Ltd.
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 */
31
32#include <linux/module.h>
33#include <linux/moduleparam.h>
34#include <linux/kernel.h>
35#include <linux/clk.h>
36#include <linux/timer.h>
37#include <linux/interrupt.h>
38#include <linux/platform_device.h>
39
40#include <linux/atmel-ssc.h>
41
42#include <sound/core.h>
43#include <sound/pcm.h>
44#include <sound/pcm_params.h>
45#include <sound/soc.h>
46#include <sound/soc-dapm.h>
47
48#include <mach/hardware.h>
49#include <mach/gpio.h>
50
51#include "../codecs/wm8731.h"
52#include "atmel-pcm.h"
53#include "atmel_ssc_dai.h"
54
55
56static int at91sam9g20ek_startup(struct snd_pcm_substream *substream)
57{
58 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
59 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
60 int ret;
61
62 /* codec system clock is supplied by PCK0, set to 12MHz */
63 ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK,
64 12000000, SND_SOC_CLOCK_IN);
65 if (ret < 0)
66 return ret;
67
68 return 0;
69}
70
71static void at91sam9g20ek_shutdown(struct snd_pcm_substream *substream)
72{
73 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
74
75 dev_dbg(rtd->socdev->dev, "shutdown");
76}
77
78static int at91sam9g20ek_hw_params(struct snd_pcm_substream *substream,
79 struct snd_pcm_hw_params *params)
80{
81 struct snd_soc_pcm_runtime *rtd = substream->private_data;
82 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
83 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
84 struct atmel_ssc_info *ssc_p = cpu_dai->private_data;
85 struct ssc_device *ssc = ssc_p->ssc;
86 int ret;
87
88 unsigned int rate;
89 int cmr_div, period;
90
91 if (ssc == NULL) {
92 printk(KERN_INFO "at91sam9g20ek_hw_params: ssc is NULL!\n");
93 return -EINVAL;
94 }
95
96 /* set codec DAI configuration */
97 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
98 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
99 if (ret < 0)
100 return ret;
101
102 /* set cpu DAI configuration */
103 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
104 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
105 if (ret < 0)
106 return ret;
107
108 /*
109 * The SSC clock dividers depend on the sample rate. The CMR.DIV
110 * field divides the system master clock MCK to drive the SSC TK
111 * signal which provides the codec BCLK. The TCMR.PERIOD and
112 * RCMR.PERIOD fields further divide the BCLK signal to drive
113 * the SSC TF and RF signals which provide the codec DACLRC and
114 * ADCLRC clocks.
115 *
116 * The dividers were determined through trial and error, where a
117 * CMR.DIV value is chosen such that the resulting BCLK value is
118 * divisible, or almost divisible, by (2 * sample rate), and then
119 * the TCMR.PERIOD or RCMR.PERIOD is BCLK / (2 * sample rate) - 1.
120 */
121 rate = params_rate(params);
122
123 switch (rate) {
124 case 8000:
125 cmr_div = 55; /* BCLK = 133MHz/(2*55) = 1.209MHz */
126 period = 74; /* LRC = BCLK/(2*(74+1)) ~= 8060,6Hz */
127 break;
128 case 11025:
129 cmr_div = 67; /* BCLK = 133MHz/(2*60) = 1.108MHz */
130 period = 45; /* LRC = BCLK/(2*(49+1)) = 11083,3Hz */
131 break;
132 case 16000:
133 cmr_div = 63; /* BCLK = 133MHz/(2*63) = 1.055MHz */
134 period = 32; /* LRC = BCLK/(2*(32+1)) = 15993,2Hz */
135 break;
136 case 22050:
137 cmr_div = 52; /* BCLK = 133MHz/(2*52) = 1.278MHz */
138 period = 28; /* LRC = BCLK/(2*(28+1)) = 22049Hz */
139 break;
140 case 32000:
141 cmr_div = 66; /* BCLK = 133MHz/(2*66) = 1.007MHz */
142 period = 15; /* LRC = BCLK/(2*(15+1)) = 31486,742Hz */
143 break;
144 case 44100:
145 cmr_div = 29; /* BCLK = 133MHz/(2*29) = 2.293MHz */
146 period = 25; /* LRC = BCLK/(2*(25+1)) = 44098Hz */
147 break;
148 case 48000:
149 cmr_div = 33; /* BCLK = 133MHz/(2*33) = 2.015MHz */
150 period = 20; /* LRC = BCLK/(2*(20+1)) = 47979,79Hz */
151 break;
152 case 88200:
153 cmr_div = 29; /* BCLK = 133MHz/(2*29) = 2.293MHz */
154 period = 12; /* LRC = BCLK/(2*(12+1)) = 88196Hz */
155 break;
156 case 96000:
157 cmr_div = 23; /* BCLK = 133MHz/(2*23) = 2.891MHz */
158 period = 14; /* LRC = BCLK/(2*(14+1)) = 96376Hz */
159 break;
160 default:
161 printk(KERN_WARNING "unsupported rate %d"
162 " on at91sam9g20ek board\n", rate);
163 return -EINVAL;
164 }
165
166 /* set the MCK divider for BCLK */
167 ret = snd_soc_dai_set_clkdiv(cpu_dai, ATMEL_SSC_CMR_DIV, cmr_div);
168 if (ret < 0)
169 return ret;
170
171 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
172 /* set the BCLK divider for DACLRC */
173 ret = snd_soc_dai_set_clkdiv(cpu_dai,
174 ATMEL_SSC_TCMR_PERIOD, period);
175 } else {
176 /* set the BCLK divider for ADCLRC */
177 ret = snd_soc_dai_set_clkdiv(cpu_dai,
178 ATMEL_SSC_RCMR_PERIOD, period);
179 }
180 if (ret < 0)
181 return ret;
182
183 return 0;
184}
185
186static struct snd_soc_ops at91sam9g20ek_ops = {
187 .startup = at91sam9g20ek_startup,
188 .hw_params = at91sam9g20ek_hw_params,
189 .shutdown = at91sam9g20ek_shutdown,
190};
191
192
193static const struct snd_soc_dapm_widget at91sam9g20ek_dapm_widgets[] = {
194 SND_SOC_DAPM_MIC("Int Mic", NULL),
195 SND_SOC_DAPM_SPK("Ext Spk", NULL),
196};
197
198static const struct snd_soc_dapm_route intercon[] = {
199
200 /* speaker connected to LHPOUT */
201 {"Ext Spk", NULL, "LHPOUT"},
202
203 /* mic is connected to Mic Jack, with WM8731 Mic Bias */
204 {"MICIN", NULL, "Mic Bias"},
205 {"Mic Bias", NULL, "Int Mic"},
206};
207
208/*
209 * Logic for a wm8731 as connected on a at91sam9g20ek board.
210 */
211static int at91sam9g20ek_wm8731_init(struct snd_soc_codec *codec)
212{
213 printk(KERN_DEBUG
214 "at91sam9g20ek_wm8731 "
215 ": at91sam9g20ek_wm8731_init() called\n");
216
217 /* Add specific widgets */
218 snd_soc_dapm_new_controls(codec, at91sam9g20ek_dapm_widgets,
219 ARRAY_SIZE(at91sam9g20ek_dapm_widgets));
220 /* Set up specific audio path interconnects */
221 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
222
223 /* not connected */
224 snd_soc_dapm_disable_pin(codec, "RLINEIN");
225 snd_soc_dapm_disable_pin(codec, "LLINEIN");
226
227 /* always connected */
228 snd_soc_dapm_enable_pin(codec, "Int Mic");
229 snd_soc_dapm_enable_pin(codec, "Ext Spk");
230
231 snd_soc_dapm_sync(codec);
232
233 return 0;
234}
235
236static struct snd_soc_dai_link at91sam9g20ek_dai = {
237 .name = "WM8731",
238 .stream_name = "WM8731 PCM",
239 .cpu_dai = &atmel_ssc_dai[0],
240 .codec_dai = &wm8731_dai,
241 .init = at91sam9g20ek_wm8731_init,
242 .ops = &at91sam9g20ek_ops,
243};
244
245static struct snd_soc_card snd_soc_at91sam9g20ek = {
246 .name = "WM8731",
247 .platform = &atmel_soc_platform,
248 .dai_link = &at91sam9g20ek_dai,
249 .num_links = 1,
250};
251
252static struct wm8731_setup_data at91sam9g20ek_wm8731_setup = {
253 .i2c_bus = 0,
254 .i2c_address = 0x1b,
255};
256
257static struct snd_soc_device at91sam9g20ek_snd_devdata = {
258 .card = &snd_soc_at91sam9g20ek,
259 .codec_dev = &soc_codec_dev_wm8731,
260 .codec_data = &at91sam9g20ek_wm8731_setup,
261};
262
263static struct platform_device *at91sam9g20ek_snd_device;
264
265static int __init at91sam9g20ek_init(void)
266{
267 struct atmel_ssc_info *ssc_p = at91sam9g20ek_dai.cpu_dai->private_data;
268 struct ssc_device *ssc = NULL;
269 int ret;
270
271 /*
272 * Request SSC device
273 */
274 ssc = ssc_request(0);
275 if (IS_ERR(ssc)) {
276 ret = PTR_ERR(ssc);
277 ssc = NULL;
278 goto err_ssc;
279 }
280 ssc_p->ssc = ssc;
281
282 at91sam9g20ek_snd_device = platform_device_alloc("soc-audio", -1);
283 if (!at91sam9g20ek_snd_device) {
284 printk(KERN_DEBUG
285 "platform device allocation failed\n");
286 ret = -ENOMEM;
287 }
288
289 platform_set_drvdata(at91sam9g20ek_snd_device,
290 &at91sam9g20ek_snd_devdata);
291 at91sam9g20ek_snd_devdata.dev = &at91sam9g20ek_snd_device->dev;
292
293 ret = platform_device_add(at91sam9g20ek_snd_device);
294 if (ret) {
295 printk(KERN_DEBUG
296 "platform device allocation failed\n");
297 platform_device_put(at91sam9g20ek_snd_device);
298 }
299
300 return ret;
301
302err_ssc:
303 return ret;
304}
305
306static void __exit at91sam9g20ek_exit(void)
307{
308 struct atmel_ssc_info *ssc_p = at91sam9g20ek_dai.cpu_dai->private_data;
309 struct ssc_device *ssc;
310
311 if (ssc_p != NULL) {
312 ssc = ssc_p->ssc;
313 if (ssc != NULL)
314 ssc_free(ssc);
315 ssc_p->ssc = NULL;
316 }
317
318 platform_device_unregister(at91sam9g20ek_snd_device);
319 at91sam9g20ek_snd_device = NULL;
320}
321
322module_init(at91sam9g20ek_init);
323module_exit(at91sam9g20ek_exit);
324
325/* Module information */
326MODULE_AUTHOR("Sedji Gaouaou <sedji.gaouaou@atmel.com>");
327MODULE_DESCRIPTION("ALSA SoC AT91SAM9G20EK_WM8731");
328MODULE_LICENSE("GPL");
diff --git a/sound/soc/au1x/dbdma2.c b/sound/soc/au1x/dbdma2.c
index 1466d9328800..74c823d60f91 100644
--- a/sound/soc/au1x/dbdma2.c
+++ b/sound/soc/au1x/dbdma2.c
@@ -406,11 +406,12 @@ static int __init au1xpsc_audio_dbdma_init(void)
406{ 406{
407 au1xpsc_audio_pcmdma[PCM_TX] = NULL; 407 au1xpsc_audio_pcmdma[PCM_TX] = NULL;
408 au1xpsc_audio_pcmdma[PCM_RX] = NULL; 408 au1xpsc_audio_pcmdma[PCM_RX] = NULL;
409 return 0; 409 return snd_soc_register_platform(&au1xpsc_soc_platform);
410} 410}
411 411
412static void __exit au1xpsc_audio_dbdma_exit(void) 412static void __exit au1xpsc_audio_dbdma_exit(void)
413{ 413{
414 snd_soc_unregister_platform(&au1xpsc_soc_platform);
414} 415}
415 416
416module_init(au1xpsc_audio_dbdma_init); 417module_init(au1xpsc_audio_dbdma_init);
diff --git a/sound/soc/au1x/psc-ac97.c b/sound/soc/au1x/psc-ac97.c
index 57facbad6825..f0e30aec7f23 100644
--- a/sound/soc/au1x/psc-ac97.c
+++ b/sound/soc/au1x/psc-ac97.c
@@ -160,7 +160,8 @@ struct snd_ac97_bus_ops soc_ac97_ops = {
160EXPORT_SYMBOL_GPL(soc_ac97_ops); 160EXPORT_SYMBOL_GPL(soc_ac97_ops);
161 161
162static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream, 162static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream,
163 struct snd_pcm_hw_params *params) 163 struct snd_pcm_hw_params *params,
164 struct snd_soc_dai *dai)
164{ 165{
165 /* FIXME */ 166 /* FIXME */
166 struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata; 167 struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata;
@@ -210,7 +211,7 @@ static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream,
210} 211}
211 212
212static int au1xpsc_ac97_trigger(struct snd_pcm_substream *substream, 213static int au1xpsc_ac97_trigger(struct snd_pcm_substream *substream,
213 int cmd) 214 int cmd, struct snd_soc_dai *dai)
214{ 215{
215 /* FIXME */ 216 /* FIXME */
216 struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata; 217 struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata;
@@ -313,8 +314,7 @@ static void au1xpsc_ac97_remove(struct platform_device *pdev,
313 au1xpsc_ac97_workdata = NULL; 314 au1xpsc_ac97_workdata = NULL;
314} 315}
315 316
316static int au1xpsc_ac97_suspend(struct platform_device *pdev, 317static int au1xpsc_ac97_suspend(struct snd_soc_dai *dai)
317 struct snd_soc_dai *dai)
318{ 318{
319 /* save interesting registers and disable PSC */ 319 /* save interesting registers and disable PSC */
320 au1xpsc_ac97_workdata->pm[0] = 320 au1xpsc_ac97_workdata->pm[0] =
@@ -328,8 +328,7 @@ static int au1xpsc_ac97_suspend(struct platform_device *pdev,
328 return 0; 328 return 0;
329} 329}
330 330
331static int au1xpsc_ac97_resume(struct platform_device *pdev, 331static int au1xpsc_ac97_resume(struct snd_soc_dai *dai)
332 struct snd_soc_dai *dai)
333{ 332{
334 /* restore PSC clock config */ 333 /* restore PSC clock config */
335 au_writel(au1xpsc_ac97_workdata->pm[0] | PSC_SEL_PS_AC97MODE, 334 au_writel(au1xpsc_ac97_workdata->pm[0] | PSC_SEL_PS_AC97MODE,
@@ -345,7 +344,7 @@ static int au1xpsc_ac97_resume(struct platform_device *pdev,
345 344
346struct snd_soc_dai au1xpsc_ac97_dai = { 345struct snd_soc_dai au1xpsc_ac97_dai = {
347 .name = "au1xpsc_ac97", 346 .name = "au1xpsc_ac97",
348 .type = SND_SOC_DAI_AC97, 347 .ac97_control = 1,
349 .probe = au1xpsc_ac97_probe, 348 .probe = au1xpsc_ac97_probe,
350 .remove = au1xpsc_ac97_remove, 349 .remove = au1xpsc_ac97_remove,
351 .suspend = au1xpsc_ac97_suspend, 350 .suspend = au1xpsc_ac97_suspend,
@@ -372,11 +371,12 @@ EXPORT_SYMBOL_GPL(au1xpsc_ac97_dai);
372static int __init au1xpsc_ac97_init(void) 371static int __init au1xpsc_ac97_init(void)
373{ 372{
374 au1xpsc_ac97_workdata = NULL; 373 au1xpsc_ac97_workdata = NULL;
375 return 0; 374 return snd_soc_register_dai(&au1xpsc_ac97_dai);
376} 375}
377 376
378static void __exit au1xpsc_ac97_exit(void) 377static void __exit au1xpsc_ac97_exit(void)
379{ 378{
379 snd_soc_unregister_dai(&au1xpsc_ac97_dai);
380} 380}
381 381
382module_init(au1xpsc_ac97_init); 382module_init(au1xpsc_ac97_init);
diff --git a/sound/soc/au1x/psc-i2s.c b/sound/soc/au1x/psc-i2s.c
index 9384702c7ebd..f916de4400ed 100644
--- a/sound/soc/au1x/psc-i2s.c
+++ b/sound/soc/au1x/psc-i2s.c
@@ -116,7 +116,8 @@ out:
116} 116}
117 117
118static int au1xpsc_i2s_hw_params(struct snd_pcm_substream *substream, 118static int au1xpsc_i2s_hw_params(struct snd_pcm_substream *substream,
119 struct snd_pcm_hw_params *params) 119 struct snd_pcm_hw_params *params,
120 struct snd_soc_dai *dai)
120{ 121{
121 struct au1xpsc_audio_data *pscdata = au1xpsc_i2s_workdata; 122 struct au1xpsc_audio_data *pscdata = au1xpsc_i2s_workdata;
122 123
@@ -240,7 +241,8 @@ static int au1xpsc_i2s_stop(struct au1xpsc_audio_data *pscdata, int stype)
240 return 0; 241 return 0;
241} 242}
242 243
243static int au1xpsc_i2s_trigger(struct snd_pcm_substream *substream, int cmd) 244static int au1xpsc_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
245 struct snd_soc_dai *dai)
244{ 246{
245 struct au1xpsc_audio_data *pscdata = au1xpsc_i2s_workdata; 247 struct au1xpsc_audio_data *pscdata = au1xpsc_i2s_workdata;
246 int ret, stype = SUBSTREAM_TYPE(substream); 248 int ret, stype = SUBSTREAM_TYPE(substream);
@@ -337,8 +339,7 @@ static void au1xpsc_i2s_remove(struct platform_device *pdev,
337 au1xpsc_i2s_workdata = NULL; 339 au1xpsc_i2s_workdata = NULL;
338} 340}
339 341
340static int au1xpsc_i2s_suspend(struct platform_device *pdev, 342static int au1xpsc_i2s_suspend(struct snd_soc_dai *cpu_dai)
341 struct snd_soc_dai *cpu_dai)
342{ 343{
343 /* save interesting register and disable PSC */ 344 /* save interesting register and disable PSC */
344 au1xpsc_i2s_workdata->pm[0] = 345 au1xpsc_i2s_workdata->pm[0] =
@@ -352,8 +353,7 @@ static int au1xpsc_i2s_suspend(struct platform_device *pdev,
352 return 0; 353 return 0;
353} 354}
354 355
355static int au1xpsc_i2s_resume(struct platform_device *pdev, 356static int au1xpsc_i2s_resume(struct snd_soc_dai *cpu_dai)
356 struct snd_soc_dai *cpu_dai)
357{ 357{
358 /* select I2S mode and PSC clock */ 358 /* select I2S mode and PSC clock */
359 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(au1xpsc_i2s_workdata)); 359 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(au1xpsc_i2s_workdata));
@@ -369,7 +369,6 @@ static int au1xpsc_i2s_resume(struct platform_device *pdev,
369 369
370struct snd_soc_dai au1xpsc_i2s_dai = { 370struct snd_soc_dai au1xpsc_i2s_dai = {
371 .name = "au1xpsc_i2s", 371 .name = "au1xpsc_i2s",
372 .type = SND_SOC_DAI_I2S,
373 .probe = au1xpsc_i2s_probe, 372 .probe = au1xpsc_i2s_probe,
374 .remove = au1xpsc_i2s_remove, 373 .remove = au1xpsc_i2s_remove,
375 .suspend = au1xpsc_i2s_suspend, 374 .suspend = au1xpsc_i2s_suspend,
@@ -389,8 +388,6 @@ struct snd_soc_dai au1xpsc_i2s_dai = {
389 .ops = { 388 .ops = {
390 .trigger = au1xpsc_i2s_trigger, 389 .trigger = au1xpsc_i2s_trigger,
391 .hw_params = au1xpsc_i2s_hw_params, 390 .hw_params = au1xpsc_i2s_hw_params,
392 },
393 .dai_ops = {
394 .set_fmt = au1xpsc_i2s_set_fmt, 391 .set_fmt = au1xpsc_i2s_set_fmt,
395 }, 392 },
396}; 393};
@@ -399,11 +396,12 @@ EXPORT_SYMBOL(au1xpsc_i2s_dai);
399static int __init au1xpsc_i2s_init(void) 396static int __init au1xpsc_i2s_init(void)
400{ 397{
401 au1xpsc_i2s_workdata = NULL; 398 au1xpsc_i2s_workdata = NULL;
402 return 0; 399 return snd_soc_register_dai(&au1xpsc_i2s_dai);
403} 400}
404 401
405static void __exit au1xpsc_i2s_exit(void) 402static void __exit au1xpsc_i2s_exit(void)
406{ 403{
404 snd_soc_unregister_dai(&au1xpsc_i2s_dai);
407} 405}
408 406
409module_init(au1xpsc_i2s_init); 407module_init(au1xpsc_i2s_init);
diff --git a/sound/soc/au1x/sample-ac97.c b/sound/soc/au1x/sample-ac97.c
index f75ae7f62c3d..27683eb7905e 100644
--- a/sound/soc/au1x/sample-ac97.c
+++ b/sound/soc/au1x/sample-ac97.c
@@ -42,14 +42,14 @@ static struct snd_soc_dai_link au1xpsc_sample_ac97_dai = {
42 .ops = NULL, 42 .ops = NULL,
43}; 43};
44 44
45static struct snd_soc_machine au1xpsc_sample_ac97_machine = { 45static struct snd_soc_card au1xpsc_sample_ac97_machine = {
46 .name = "Au1xxx PSC AC97 Audio", 46 .name = "Au1xxx PSC AC97 Audio",
47 .dai_link = &au1xpsc_sample_ac97_dai, 47 .dai_link = &au1xpsc_sample_ac97_dai,
48 .num_links = 1, 48 .num_links = 1,
49}; 49};
50 50
51static struct snd_soc_device au1xpsc_sample_ac97_devdata = { 51static struct snd_soc_device au1xpsc_sample_ac97_devdata = {
52 .machine = &au1xpsc_sample_ac97_machine, 52 .card = &au1xpsc_sample_ac97_machine,
53 .platform = &au1xpsc_soc_platform, /* see dbdma2.c */ 53 .platform = &au1xpsc_soc_platform, /* see dbdma2.c */
54 .codec_dev = &soc_codec_dev_ac97, 54 .codec_dev = &soc_codec_dev_ac97,
55}; 55};
diff --git a/sound/soc/blackfin/Kconfig b/sound/soc/blackfin/Kconfig
index dc006206f622..0a2f8f9eff53 100644
--- a/sound/soc/blackfin/Kconfig
+++ b/sound/soc/blackfin/Kconfig
@@ -1,6 +1,6 @@
1config SND_BF5XX_I2S 1config SND_BF5XX_I2S
2 tristate "SoC I2S Audio for the ADI BF5xx chip" 2 tristate "SoC I2S Audio for the ADI BF5xx chip"
3 depends on BLACKFIN && SND_SOC 3 depends on BLACKFIN
4 help 4 help
5 Say Y or M if you want to add support for codecs attached to 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 6 the Blackfin SPORT (synchronous serial ports) interface in I2S
@@ -13,7 +13,6 @@ config SND_BF5XX_SOC_SSM2602
13 select SND_BF5XX_SOC_I2S 13 select SND_BF5XX_SOC_I2S
14 select SND_SOC_SSM2602 14 select SND_SOC_SSM2602
15 select I2C 15 select I2C
16 select I2C_BLACKFIN_TWI
17 help 16 help
18 Say Y if you want to add support for SoC audio on BF527-EZKIT. 17 Say Y if you want to add support for SoC audio on BF527-EZKIT.
19 18
@@ -35,7 +34,7 @@ config SND_BFIN_AD73311_SE
35 34
36config SND_BF5XX_AC97 35config SND_BF5XX_AC97
37 tristate "SoC AC97 Audio for the ADI BF5xx chip" 36 tristate "SoC AC97 Audio for the ADI BF5xx chip"
38 depends on BLACKFIN && SND_SOC 37 depends on BLACKFIN
39 help 38 help
40 Say Y or M if you want to add support for codecs attached to 39 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 40 the Blackfin SPORT (synchronous serial ports) interface in slot 16
@@ -47,7 +46,7 @@ config SND_BF5XX_AC97
47 properly with this driver. This driver is known to work with the 46 properly with this driver. This driver is known to work with the
48 Analog Devices line of AC97 codecs. 47 Analog Devices line of AC97 codecs.
49 48
50config SND_MMAP_SUPPORT 49config SND_BF5XX_MMAP_SUPPORT
51 bool "Enable MMAP Support" 50 bool "Enable MMAP Support"
52 depends on SND_BF5XX_AC97 51 depends on SND_BF5XX_AC97
53 default y 52 default y
@@ -55,9 +54,17 @@ config SND_MMAP_SUPPORT
55 Say y if you want AC97 driver to support mmap mode. 54 Say y if you want AC97 driver to support mmap mode.
56 We introduce an intermediate buffer to simulate mmap. 55 We introduce an intermediate buffer to simulate mmap.
57 56
57config SND_BF5XX_MULTICHAN_SUPPORT
58 bool "Enable Multichannel Support"
59 depends on SND_BF5XX_AC97
60 default n
61 help
62 Say y if you want AC97 driver to support up to 5.1 channel audio.
63 this mode will consume much more memory for DMA.
64
58config SND_BF5XX_SOC_SPORT 65config SND_BF5XX_SOC_SPORT
59 tristate 66 tristate
60 67
61config SND_BF5XX_SOC_I2S 68config SND_BF5XX_SOC_I2S
62 tristate 69 tristate
63 select SND_BF5XX_SOC_SPORT 70 select SND_BF5XX_SOC_SPORT
@@ -80,7 +87,7 @@ config SND_BF5XX_SPORT_NUM
80 int "Set a SPORT for Sound chip" 87 int "Set a SPORT for Sound chip"
81 depends on (SND_BF5XX_I2S || SND_BF5XX_AC97) 88 depends on (SND_BF5XX_I2S || SND_BF5XX_AC97)
82 range 0 3 if BF54x 89 range 0 3 if BF54x
83 range 0 1 if (BF53x || BF561) 90 range 0 1 if !BF54x
84 default 0 91 default 0
85 help 92 help
86 Set the correct SPORT for sound chip. 93 Set the correct SPORT for sound chip.
@@ -90,12 +97,13 @@ config SND_BF5XX_HAVE_COLD_RESET
90 depends on SND_BF5XX_AC97 97 depends on SND_BF5XX_AC97
91 default y if BFIN548_EZKIT 98 default y if BFIN548_EZKIT
92 default n if !BFIN548_EZKIT 99 default n if !BFIN548_EZKIT
93 100
94config SND_BF5XX_RESET_GPIO_NUM 101config SND_BF5XX_RESET_GPIO_NUM
95 int "Set a GPIO for cold reset" 102 int "Set a GPIO for cold reset"
96 depends on SND_BF5XX_HAVE_COLD_RESET 103 depends on SND_BF5XX_HAVE_COLD_RESET
97 range 0 159 104 range 0 159
98 default 19 if BFIN548_EZKIT 105 default 19 if BFIN548_EZKIT
99 default 5 if BFIN537_STAMP 106 default 5 if BFIN537_STAMP
107 default 0
100 help 108 help
101 Set the correct GPIO for RESET the sound chip. 109 Set the correct GPIO for RESET the sound chip.
diff --git a/sound/soc/blackfin/bf5xx-ac97-pcm.c b/sound/soc/blackfin/bf5xx-ac97-pcm.c
index 25e50d2ea1ec..8067cfafa3a7 100644
--- a/sound/soc/blackfin/bf5xx-ac97-pcm.c
+++ b/sound/soc/blackfin/bf5xx-ac97-pcm.c
@@ -43,24 +43,34 @@
43#include "bf5xx-ac97.h" 43#include "bf5xx-ac97.h"
44#include "bf5xx-sport.h" 44#include "bf5xx-sport.h"
45 45
46#if defined(CONFIG_SND_MMAP_SUPPORT) 46static unsigned int ac97_chan_mask[] = {
47 SP_FL, /* Mono */
48 SP_STEREO, /* Stereo */
49 SP_2DOT1, /* 2.1*/
50 SP_QUAD,/*Quadraquic*/
51 SP_FL | SP_FR | SP_FC | SP_SL | SP_SR,/*5 channels */
52 SP_5DOT1, /* 5.1 */
53};
54
55#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
47static void bf5xx_mmap_copy(struct snd_pcm_substream *substream, 56static void bf5xx_mmap_copy(struct snd_pcm_substream *substream,
48 snd_pcm_uframes_t count) 57 snd_pcm_uframes_t count)
49{ 58{
50 struct snd_pcm_runtime *runtime = substream->runtime; 59 struct snd_pcm_runtime *runtime = substream->runtime;
51 struct sport_device *sport = runtime->private_data; 60 struct sport_device *sport = runtime->private_data;
61 unsigned int chan_mask = ac97_chan_mask[runtime->channels - 1];
52 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 62 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
53 bf5xx_pcm_to_ac97( 63 bf5xx_pcm_to_ac97((struct ac97_frame *)sport->tx_dma_buf +
54 (struct ac97_frame *)sport->tx_dma_buf + sport->tx_pos, 64 sport->tx_pos, (__u16 *)runtime->dma_area + sport->tx_pos *
55 (__u32 *)runtime->dma_area + sport->tx_pos, count); 65 runtime->channels, count, chan_mask);
56 sport->tx_pos += runtime->period_size; 66 sport->tx_pos += runtime->period_size;
57 if (sport->tx_pos >= runtime->buffer_size) 67 if (sport->tx_pos >= runtime->buffer_size)
58 sport->tx_pos %= runtime->buffer_size; 68 sport->tx_pos %= runtime->buffer_size;
59 sport->tx_delay_pos = sport->tx_pos; 69 sport->tx_delay_pos = sport->tx_pos;
60 } else { 70 } else {
61 bf5xx_ac97_to_pcm( 71 bf5xx_ac97_to_pcm((struct ac97_frame *)sport->rx_dma_buf +
62 (struct ac97_frame *)sport->rx_dma_buf + sport->rx_pos, 72 sport->rx_pos, (__u16 *)runtime->dma_area + sport->rx_pos *
63 (__u32 *)runtime->dma_area + sport->rx_pos, count); 73 runtime->channels, count);
64 sport->rx_pos += runtime->period_size; 74 sport->rx_pos += runtime->period_size;
65 if (sport->rx_pos >= runtime->buffer_size) 75 if (sport->rx_pos >= runtime->buffer_size)
66 sport->rx_pos %= runtime->buffer_size; 76 sport->rx_pos %= runtime->buffer_size;
@@ -71,7 +81,7 @@ static void bf5xx_mmap_copy(struct snd_pcm_substream *substream,
71static void bf5xx_dma_irq(void *data) 81static void bf5xx_dma_irq(void *data)
72{ 82{
73 struct snd_pcm_substream *pcm = data; 83 struct snd_pcm_substream *pcm = data;
74#if defined(CONFIG_SND_MMAP_SUPPORT) 84#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
75 struct snd_pcm_runtime *runtime = pcm->runtime; 85 struct snd_pcm_runtime *runtime = pcm->runtime;
76 struct sport_device *sport = runtime->private_data; 86 struct sport_device *sport = runtime->private_data;
77 bf5xx_mmap_copy(pcm, runtime->period_size); 87 bf5xx_mmap_copy(pcm, runtime->period_size);
@@ -90,17 +100,14 @@ static void bf5xx_dma_irq(void *data)
90 * The total rx/tx buffer is for ac97 frame to hold all pcm data 100 * The total rx/tx buffer is for ac97 frame to hold all pcm data
91 * is 0x20000 * sizeof(struct ac97_frame) / 4. 101 * is 0x20000 * sizeof(struct ac97_frame) / 4.
92 */ 102 */
93#ifdef CONFIG_SND_MMAP_SUPPORT
94static const struct snd_pcm_hardware bf5xx_pcm_hardware = { 103static const struct snd_pcm_hardware bf5xx_pcm_hardware = {
95 .info = SNDRV_PCM_INFO_INTERLEAVED | 104 .info = SNDRV_PCM_INFO_INTERLEAVED |
105#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
96 SNDRV_PCM_INFO_MMAP | 106 SNDRV_PCM_INFO_MMAP |
97 SNDRV_PCM_INFO_MMAP_VALID | 107 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 108#endif
109 SNDRV_PCM_INFO_BLOCK_TRANSFER,
110
104 .formats = SNDRV_PCM_FMTBIT_S16_LE, 111 .formats = SNDRV_PCM_FMTBIT_S16_LE,
105 .period_bytes_min = 32, 112 .period_bytes_min = 32,
106 .period_bytes_max = 0x10000, 113 .period_bytes_max = 0x10000,
@@ -123,10 +130,20 @@ static int bf5xx_pcm_hw_params(struct snd_pcm_substream *substream,
123 130
124static int bf5xx_pcm_hw_free(struct snd_pcm_substream *substream) 131static int bf5xx_pcm_hw_free(struct snd_pcm_substream *substream)
125{ 132{
133#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
126 struct snd_pcm_runtime *runtime = substream->runtime; 134 struct snd_pcm_runtime *runtime = substream->runtime;
135 struct sport_device *sport = runtime->private_data;
127 136
128 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 137 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
129 memset(runtime->dma_area, 0, runtime->buffer_size); 138 sport->once = 0;
139 if (runtime->dma_area)
140 memset(runtime->dma_area, 0, runtime->buffer_size);
141 memset(sport->tx_dma_buf, 0, runtime->buffer_size *
142 sizeof(struct ac97_frame));
143 } else
144 memset(sport->rx_dma_buf, 0, runtime->buffer_size *
145 sizeof(struct ac97_frame));
146#endif
130 snd_pcm_lib_free_pages(substream); 147 snd_pcm_lib_free_pages(substream);
131 return 0; 148 return 0;
132} 149}
@@ -139,7 +156,7 @@ static int bf5xx_pcm_prepare(struct snd_pcm_substream *substream)
139 /* An intermediate buffer is introduced for implementing mmap for 156 /* An intermediate buffer is introduced for implementing mmap for
140 * SPORT working in TMD mode(include AC97). 157 * SPORT working in TMD mode(include AC97).
141 */ 158 */
142#if defined(CONFIG_SND_MMAP_SUPPORT) 159#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
143 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 160 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
144 sport_set_tx_callback(sport, bf5xx_dma_irq, substream); 161 sport_set_tx_callback(sport, bf5xx_dma_irq, substream);
145 sport_config_tx_dma(sport, sport->tx_dma_buf, runtime->periods, 162 sport_config_tx_dma(sport, sport->tx_dma_buf, runtime->periods,
@@ -173,24 +190,24 @@ static int bf5xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
173 switch (cmd) { 190 switch (cmd) {
174 case SNDRV_PCM_TRIGGER_START: 191 case SNDRV_PCM_TRIGGER_START:
175 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 192 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
193#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
176 bf5xx_mmap_copy(substream, runtime->period_size); 194 bf5xx_mmap_copy(substream, runtime->period_size);
177 snd_pcm_period_elapsed(substream);
178 sport->tx_delay_pos = 0; 195 sport->tx_delay_pos = 0;
196#endif
179 sport_tx_start(sport); 197 sport_tx_start(sport);
180 } 198 } else
181 else
182 sport_rx_start(sport); 199 sport_rx_start(sport);
183 break; 200 break;
184 case SNDRV_PCM_TRIGGER_STOP: 201 case SNDRV_PCM_TRIGGER_STOP:
185 case SNDRV_PCM_TRIGGER_SUSPEND: 202 case SNDRV_PCM_TRIGGER_SUSPEND:
186 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 203 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
187 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 204 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
188#if defined(CONFIG_SND_MMAP_SUPPORT) 205#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
189 sport->tx_pos = 0; 206 sport->tx_pos = 0;
190#endif 207#endif
191 sport_tx_stop(sport); 208 sport_tx_stop(sport);
192 } else { 209 } else {
193#if defined(CONFIG_SND_MMAP_SUPPORT) 210#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
194 sport->rx_pos = 0; 211 sport->rx_pos = 0;
195#endif 212#endif
196 sport_rx_stop(sport); 213 sport_rx_stop(sport);
@@ -208,7 +225,7 @@ static snd_pcm_uframes_t bf5xx_pcm_pointer(struct snd_pcm_substream *substream)
208 struct sport_device *sport = runtime->private_data; 225 struct sport_device *sport = runtime->private_data;
209 unsigned int curr; 226 unsigned int curr;
210 227
211#if defined(CONFIG_SND_MMAP_SUPPORT) 228#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
212 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 229 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
213 curr = sport->tx_delay_pos; 230 curr = sport->tx_delay_pos;
214 else 231 else
@@ -249,22 +266,7 @@ static int bf5xx_pcm_open(struct snd_pcm_substream *substream)
249 return ret; 266 return ret;
250} 267}
251 268
252static int bf5xx_pcm_close(struct snd_pcm_substream *substream) 269#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
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, 270static int bf5xx_pcm_mmap(struct snd_pcm_substream *substream,
269 struct vm_area_struct *vma) 271 struct vm_area_struct *vma)
270{ 272{
@@ -281,32 +283,29 @@ static int bf5xx_pcm_copy(struct snd_pcm_substream *substream, int channel,
281 void __user *buf, snd_pcm_uframes_t count) 283 void __user *buf, snd_pcm_uframes_t count)
282{ 284{
283 struct snd_pcm_runtime *runtime = substream->runtime; 285 struct snd_pcm_runtime *runtime = substream->runtime;
284 286 unsigned int chan_mask = ac97_chan_mask[runtime->channels - 1];
285 pr_debug("%s copy pos:0x%lx count:0x%lx\n", 287 pr_debug("%s copy pos:0x%lx count:0x%lx\n",
286 substream->stream ? "Capture" : "Playback", pos, count); 288 substream->stream ? "Capture" : "Playback", pos, count);
287 289
288 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 290 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
289 bf5xx_pcm_to_ac97( 291 bf5xx_pcm_to_ac97((struct ac97_frame *)runtime->dma_area + pos,
290 (struct ac97_frame *)runtime->dma_area + pos, 292 (__u16 *)buf, count, chan_mask);
291 buf, count);
292 else 293 else
293 bf5xx_ac97_to_pcm( 294 bf5xx_ac97_to_pcm((struct ac97_frame *)runtime->dma_area + pos,
294 (struct ac97_frame *)runtime->dma_area + pos, 295 (__u16 *)buf, count);
295 buf, count);
296 return 0; 296 return 0;
297} 297}
298#endif 298#endif
299 299
300struct snd_pcm_ops bf5xx_pcm_ac97_ops = { 300struct snd_pcm_ops bf5xx_pcm_ac97_ops = {
301 .open = bf5xx_pcm_open, 301 .open = bf5xx_pcm_open,
302 .close = bf5xx_pcm_close,
303 .ioctl = snd_pcm_lib_ioctl, 302 .ioctl = snd_pcm_lib_ioctl,
304 .hw_params = bf5xx_pcm_hw_params, 303 .hw_params = bf5xx_pcm_hw_params,
305 .hw_free = bf5xx_pcm_hw_free, 304 .hw_free = bf5xx_pcm_hw_free,
306 .prepare = bf5xx_pcm_prepare, 305 .prepare = bf5xx_pcm_prepare,
307 .trigger = bf5xx_pcm_trigger, 306 .trigger = bf5xx_pcm_trigger,
308 .pointer = bf5xx_pcm_pointer, 307 .pointer = bf5xx_pcm_pointer,
309#ifdef CONFIG_SND_MMAP_SUPPORT 308#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
310 .mmap = bf5xx_pcm_mmap, 309 .mmap = bf5xx_pcm_mmap,
311#else 310#else
312 .copy = bf5xx_pcm_copy, 311 .copy = bf5xx_pcm_copy,
@@ -344,7 +343,7 @@ static int bf5xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
344 * Need to allocate local buffer when enable 343 * Need to allocate local buffer when enable
345 * MMAP for SPORT working in TMD mode (include AC97). 344 * MMAP for SPORT working in TMD mode (include AC97).
346 */ 345 */
347#if defined(CONFIG_SND_MMAP_SUPPORT) 346#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
348 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 347 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
349 if (!sport_handle->tx_dma_buf) { 348 if (!sport_handle->tx_dma_buf) {
350 sport_handle->tx_dma_buf = dma_alloc_coherent(NULL, \ 349 sport_handle->tx_dma_buf = dma_alloc_coherent(NULL, \
@@ -381,7 +380,7 @@ static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
381 struct snd_pcm_substream *substream; 380 struct snd_pcm_substream *substream;
382 struct snd_dma_buffer *buf; 381 struct snd_dma_buffer *buf;
383 int stream; 382 int stream;
384#if defined(CONFIG_SND_MMAP_SUPPORT) 383#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
385 size_t size = bf5xx_pcm_hardware.buffer_bytes_max * 384 size_t size = bf5xx_pcm_hardware.buffer_bytes_max *
386 sizeof(struct ac97_frame) / 4; 385 sizeof(struct ac97_frame) / 4;
387#endif 386#endif
@@ -395,7 +394,7 @@ static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
395 continue; 394 continue;
396 dma_free_coherent(NULL, buf->bytes, buf->area, 0); 395 dma_free_coherent(NULL, buf->bytes, buf->area, 0);
397 buf->area = NULL; 396 buf->area = NULL;
398#if defined(CONFIG_SND_MMAP_SUPPORT) 397#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
399 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 398 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
400 if (sport_handle->tx_dma_buf) 399 if (sport_handle->tx_dma_buf)
401 dma_free_coherent(NULL, size, \ 400 dma_free_coherent(NULL, size, \
@@ -452,6 +451,18 @@ struct snd_soc_platform bf5xx_ac97_soc_platform = {
452}; 451};
453EXPORT_SYMBOL_GPL(bf5xx_ac97_soc_platform); 452EXPORT_SYMBOL_GPL(bf5xx_ac97_soc_platform);
454 453
454static int __init bfin_ac97_init(void)
455{
456 return snd_soc_register_platform(&bf5xx_ac97_soc_platform);
457}
458module_init(bfin_ac97_init);
459
460static void __exit bfin_ac97_exit(void)
461{
462 snd_soc_unregister_platform(&bf5xx_ac97_soc_platform);
463}
464module_exit(bfin_ac97_exit);
465
455MODULE_AUTHOR("Cliff Cai"); 466MODULE_AUTHOR("Cliff Cai");
456MODULE_DESCRIPTION("ADI Blackfin AC97 PCM DMA module"); 467MODULE_DESCRIPTION("ADI Blackfin AC97 PCM DMA module");
457MODULE_LICENSE("GPL"); 468MODULE_LICENSE("GPL");
diff --git a/sound/soc/blackfin/bf5xx-ac97.c b/sound/soc/blackfin/bf5xx-ac97.c
index 5e5aafb6485f..3be2be60576d 100644
--- a/sound/soc/blackfin/bf5xx-ac97.c
+++ b/sound/soc/blackfin/bf5xx-ac97.c
@@ -54,71 +54,103 @@
54static int *cmd_count; 54static int *cmd_count;
55static int sport_num = CONFIG_SND_BF5XX_SPORT_NUM; 55static int sport_num = CONFIG_SND_BF5XX_SPORT_NUM;
56 56
57#if defined(CONFIG_BF54x) 57static u16 sport_req[][7] = {
58 PIN_REQ_SPORT_0,
59#ifdef PIN_REQ_SPORT_1
60 PIN_REQ_SPORT_1,
61#endif
62#ifdef PIN_REQ_SPORT_2
63 PIN_REQ_SPORT_2,
64#endif
65#ifdef PIN_REQ_SPORT_3
66 PIN_REQ_SPORT_3,
67#endif
68 };
69
58static struct sport_param sport_params[4] = { 70static struct sport_param sport_params[4] = {
59 { 71 {
60 .dma_rx_chan = CH_SPORT0_RX, 72 .dma_rx_chan = CH_SPORT0_RX,
61 .dma_tx_chan = CH_SPORT0_TX, 73 .dma_tx_chan = CH_SPORT0_TX,
62 .err_irq = IRQ_SPORT0_ERR, 74 .err_irq = IRQ_SPORT0_ERROR,
63 .regs = (struct sport_register *)SPORT0_TCR1, 75 .regs = (struct sport_register *)SPORT0_TCR1,
64 }, 76 },
77#ifdef PIN_REQ_SPORT_1
65 { 78 {
66 .dma_rx_chan = CH_SPORT1_RX, 79 .dma_rx_chan = CH_SPORT1_RX,
67 .dma_tx_chan = CH_SPORT1_TX, 80 .dma_tx_chan = CH_SPORT1_TX,
68 .err_irq = IRQ_SPORT1_ERR, 81 .err_irq = IRQ_SPORT1_ERROR,
69 .regs = (struct sport_register *)SPORT1_TCR1, 82 .regs = (struct sport_register *)SPORT1_TCR1,
70 }, 83 },
84#endif
85#ifdef PIN_REQ_SPORT_2
71 { 86 {
72 .dma_rx_chan = CH_SPORT2_RX, 87 .dma_rx_chan = CH_SPORT2_RX,
73 .dma_tx_chan = CH_SPORT2_TX, 88 .dma_tx_chan = CH_SPORT2_TX,
74 .err_irq = IRQ_SPORT2_ERR, 89 .err_irq = IRQ_SPORT2_ERROR,
75 .regs = (struct sport_register *)SPORT2_TCR1, 90 .regs = (struct sport_register *)SPORT2_TCR1,
76 }, 91 },
92#endif
93#ifdef PIN_REQ_SPORT_3
77 { 94 {
78 .dma_rx_chan = CH_SPORT3_RX, 95 .dma_rx_chan = CH_SPORT3_RX,
79 .dma_tx_chan = CH_SPORT3_TX, 96 .dma_tx_chan = CH_SPORT3_TX,
80 .err_irq = IRQ_SPORT3_ERR, 97 .err_irq = IRQ_SPORT3_ERROR,
81 .regs = (struct sport_register *)SPORT3_TCR1, 98 .regs = (struct sport_register *)SPORT3_TCR1,
82 } 99 }
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#endif
101};
100 102
101void bf5xx_pcm_to_ac97(struct ac97_frame *dst, const __u32 *src, \ 103void bf5xx_pcm_to_ac97(struct ac97_frame *dst, const __u16 *src,
102 size_t count) 104 size_t count, unsigned int chan_mask)
103{ 105{
104 while (count--) { 106 while (count--) {
105 dst->ac97_tag = TAG_VALID | TAG_PCM; 107 dst->ac97_tag = TAG_VALID;
106 (dst++)->ac97_pcm = *src++; 108 if (chan_mask & SP_FL) {
109 dst->ac97_pcm_r = *src++;
110 dst->ac97_tag |= TAG_PCM_RIGHT;
111 }
112 if (chan_mask & SP_FR) {
113 dst->ac97_pcm_l = *src++;
114 dst->ac97_tag |= TAG_PCM_LEFT;
115
116 }
117#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
118 if (chan_mask & SP_SR) {
119 dst->ac97_sl = *src++;
120 dst->ac97_tag |= TAG_PCM_SL;
121 }
122 if (chan_mask & SP_SL) {
123 dst->ac97_sr = *src++;
124 dst->ac97_tag |= TAG_PCM_SR;
125 }
126 if (chan_mask & SP_LFE) {
127 dst->ac97_lfe = *src++;
128 dst->ac97_tag |= TAG_PCM_LFE;
129 }
130 if (chan_mask & SP_FC) {
131 dst->ac97_center = *src++;
132 dst->ac97_tag |= TAG_PCM_CENTER;
133 }
134#endif
135 dst++;
107 } 136 }
108} 137}
109EXPORT_SYMBOL(bf5xx_pcm_to_ac97); 138EXPORT_SYMBOL(bf5xx_pcm_to_ac97);
110 139
111void bf5xx_ac97_to_pcm(const struct ac97_frame *src, __u32 *dst, \ 140void bf5xx_ac97_to_pcm(const struct ac97_frame *src, __u16 *dst,
112 size_t count) 141 size_t count)
113{ 142{
114 while (count--) 143 while (count--) {
115 *(dst++) = (src++)->ac97_pcm; 144 *(dst++) = src->ac97_pcm_l;
145 *(dst++) = src->ac97_pcm_r;
146 src++;
147 }
116} 148}
117EXPORT_SYMBOL(bf5xx_ac97_to_pcm); 149EXPORT_SYMBOL(bf5xx_ac97_to_pcm);
118 150
119static unsigned int sport_tx_curr_frag(struct sport_device *sport) 151static unsigned int sport_tx_curr_frag(struct sport_device *sport)
120{ 152{
121 return sport->tx_curr_frag = sport_curr_offset_tx(sport) / \ 153 return sport->tx_curr_frag = sport_curr_offset_tx(sport) /
122 sport->tx_fragsize; 154 sport->tx_fragsize;
123} 155}
124 156
@@ -130,7 +162,7 @@ static void enqueue_cmd(struct snd_ac97 *ac97, __u16 addr, __u16 data)
130 162
131 sport_incfrag(sport, &nextfrag, 1); 163 sport_incfrag(sport, &nextfrag, 1);
132 164
133 nextwrite = (struct ac97_frame *)(sport->tx_buf + \ 165 nextwrite = (struct ac97_frame *)(sport->tx_buf +
134 nextfrag * sport->tx_fragsize); 166 nextfrag * sport->tx_fragsize);
135 pr_debug("sport->tx_buf:%p, nextfrag:0x%x nextwrite:%p, cmd_count:%d\n", 167 pr_debug("sport->tx_buf:%p, nextfrag:0x%x nextwrite:%p, cmd_count:%d\n",
136 sport->tx_buf, nextfrag, nextwrite, cmd_count[nextfrag]); 168 sport->tx_buf, nextfrag, nextwrite, cmd_count[nextfrag]);
@@ -237,8 +269,7 @@ struct snd_ac97_bus_ops soc_ac97_ops = {
237EXPORT_SYMBOL_GPL(soc_ac97_ops); 269EXPORT_SYMBOL_GPL(soc_ac97_ops);
238 270
239#ifdef CONFIG_PM 271#ifdef CONFIG_PM
240static int bf5xx_ac97_suspend(struct platform_device *pdev, 272static int bf5xx_ac97_suspend(struct snd_soc_dai *dai)
241 struct snd_soc_dai *dai)
242{ 273{
243 struct sport_device *sport = 274 struct sport_device *sport =
244 (struct sport_device *)dai->private_data; 275 (struct sport_device *)dai->private_data;
@@ -253,8 +284,7 @@ static int bf5xx_ac97_suspend(struct platform_device *pdev,
253 return 0; 284 return 0;
254} 285}
255 286
256static int bf5xx_ac97_resume(struct platform_device *pdev, 287static int bf5xx_ac97_resume(struct snd_soc_dai *dai)
257 struct snd_soc_dai *dai)
258{ 288{
259 int ret; 289 int ret;
260 struct sport_device *sport = 290 struct sport_device *sport =
@@ -297,20 +327,15 @@ static int bf5xx_ac97_resume(struct platform_device *pdev,
297static int bf5xx_ac97_probe(struct platform_device *pdev, 327static int bf5xx_ac97_probe(struct platform_device *pdev,
298 struct snd_soc_dai *dai) 328 struct snd_soc_dai *dai)
299{ 329{
300 int ret; 330 int ret = 0;
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); 331 cmd_count = (int *)get_zeroed_page(GFP_KERNEL);
308 if (cmd_count == NULL) 332 if (cmd_count == NULL)
309 return -ENOMEM; 333 return -ENOMEM;
310 334
311 if (peripheral_request_list(&sport_req[sport_num][0], "soc-audio")) { 335 if (peripheral_request_list(&sport_req[sport_num][0], "soc-audio")) {
312 pr_err("Requesting Peripherals failed\n"); 336 pr_err("Requesting Peripherals failed\n");
313 return -EFAULT; 337 ret = -EFAULT;
338 goto peripheral_err;
314 } 339 }
315 340
316#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET 341#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
@@ -318,54 +343,54 @@ static int bf5xx_ac97_probe(struct platform_device *pdev,
318 if (gpio_request(CONFIG_SND_BF5XX_RESET_GPIO_NUM, "SND_AD198x RESET")) { 343 if (gpio_request(CONFIG_SND_BF5XX_RESET_GPIO_NUM, "SND_AD198x RESET")) {
319 pr_err("Failed to request GPIO_%d for reset\n", 344 pr_err("Failed to request GPIO_%d for reset\n",
320 CONFIG_SND_BF5XX_RESET_GPIO_NUM); 345 CONFIG_SND_BF5XX_RESET_GPIO_NUM);
321 peripheral_free_list(&sport_req[sport_num][0]); 346 ret = -1;
322 return -1; 347 goto gpio_err;
323 } 348 }
324 gpio_direction_output(CONFIG_SND_BF5XX_RESET_GPIO_NUM, 1); 349 gpio_direction_output(CONFIG_SND_BF5XX_RESET_GPIO_NUM, 1);
325#endif 350#endif
326 sport_handle = sport_init(&sport_params[sport_num], 2, \ 351 sport_handle = sport_init(&sport_params[sport_num], 2, \
327 sizeof(struct ac97_frame), NULL); 352 sizeof(struct ac97_frame), NULL);
328 if (!sport_handle) { 353 if (!sport_handle) {
329 peripheral_free_list(&sport_req[sport_num][0]); 354 ret = -ENODEV;
330#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET 355 goto sport_err;
331 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
332#endif
333 return -ENODEV;
334 } 356 }
335 /*SPORT works in TDM mode to simulate AC97 transfers*/ 357 /*SPORT works in TDM mode to simulate AC97 transfers*/
336 ret = sport_set_multichannel(sport_handle, 16, 0x1F, 1); 358 ret = sport_set_multichannel(sport_handle, 16, 0x1F, 1);
337 if (ret) { 359 if (ret) {
338 pr_err("SPORT is busy!\n"); 360 pr_err("SPORT is busy!\n");
339 kfree(sport_handle); 361 ret = -EBUSY;
340 peripheral_free_list(&sport_req[sport_num][0]); 362 goto sport_config_err;
341#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
342 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
343#endif
344 return -EBUSY;
345 } 363 }
346 364
347 ret = sport_config_rx(sport_handle, IRFS, 0xF, 0, (16*16-1)); 365 ret = sport_config_rx(sport_handle, IRFS, 0xF, 0, (16*16-1));
348 if (ret) { 366 if (ret) {
349 pr_err("SPORT is busy!\n"); 367 pr_err("SPORT is busy!\n");
350 kfree(sport_handle); 368 ret = -EBUSY;
351 peripheral_free_list(&sport_req[sport_num][0]); 369 goto sport_config_err;
352#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
353 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
354#endif
355 return -EBUSY;
356 } 370 }
357 371
358 ret = sport_config_tx(sport_handle, ITFS, 0xF, 0, (16*16-1)); 372 ret = sport_config_tx(sport_handle, ITFS, 0xF, 0, (16*16-1));
359 if (ret) { 373 if (ret) {
360 pr_err("SPORT is busy!\n"); 374 pr_err("SPORT is busy!\n");
361 kfree(sport_handle); 375 ret = -EBUSY;
362 peripheral_free_list(&sport_req[sport_num][0]); 376 goto sport_config_err;
363#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
364 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
365#endif
366 return -EBUSY;
367 } 377 }
378
368 return 0; 379 return 0;
380
381sport_config_err:
382 kfree(sport_handle);
383sport_err:
384#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
385 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
386#endif
387gpio_err:
388 peripheral_free_list(&sport_req[sport_num][0]);
389peripheral_err:
390 free_page((unsigned long)cmd_count);
391 cmd_count = NULL;
392
393 return ret;
369} 394}
370 395
371static void bf5xx_ac97_remove(struct platform_device *pdev, 396static void bf5xx_ac97_remove(struct platform_device *pdev,
@@ -373,6 +398,7 @@ static void bf5xx_ac97_remove(struct platform_device *pdev,
373{ 398{
374 free_page((unsigned long)cmd_count); 399 free_page((unsigned long)cmd_count);
375 cmd_count = NULL; 400 cmd_count = NULL;
401 peripheral_free_list(&sport_req[sport_num][0]);
376#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET 402#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
377 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM); 403 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
378#endif 404#endif
@@ -381,7 +407,7 @@ static void bf5xx_ac97_remove(struct platform_device *pdev,
381struct snd_soc_dai bfin_ac97_dai = { 407struct snd_soc_dai bfin_ac97_dai = {
382 .name = "bf5xx-ac97", 408 .name = "bf5xx-ac97",
383 .id = 0, 409 .id = 0,
384 .type = SND_SOC_DAI_AC97, 410 .ac97_control = 1,
385 .probe = bf5xx_ac97_probe, 411 .probe = bf5xx_ac97_probe,
386 .remove = bf5xx_ac97_remove, 412 .remove = bf5xx_ac97_remove,
387 .suspend = bf5xx_ac97_suspend, 413 .suspend = bf5xx_ac97_suspend,
@@ -389,7 +415,11 @@ struct snd_soc_dai bfin_ac97_dai = {
389 .playback = { 415 .playback = {
390 .stream_name = "AC97 Playback", 416 .stream_name = "AC97 Playback",
391 .channels_min = 2, 417 .channels_min = 2,
418#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
419 .channels_max = 6,
420#else
392 .channels_max = 2, 421 .channels_max = 2,
422#endif
393 .rates = SNDRV_PCM_RATE_48000, 423 .rates = SNDRV_PCM_RATE_48000,
394 .formats = SNDRV_PCM_FMTBIT_S16_LE, }, 424 .formats = SNDRV_PCM_FMTBIT_S16_LE, },
395 .capture = { 425 .capture = {
@@ -401,6 +431,18 @@ struct snd_soc_dai bfin_ac97_dai = {
401}; 431};
402EXPORT_SYMBOL_GPL(bfin_ac97_dai); 432EXPORT_SYMBOL_GPL(bfin_ac97_dai);
403 433
434static int __init bfin_ac97_init(void)
435{
436 return snd_soc_register_dai(&bfin_ac97_dai);
437}
438module_init(bfin_ac97_init);
439
440static void __exit bfin_ac97_exit(void)
441{
442 snd_soc_unregister_dai(&bfin_ac97_dai);
443}
444module_exit(bfin_ac97_exit);
445
404MODULE_AUTHOR("Roy Huang"); 446MODULE_AUTHOR("Roy Huang");
405MODULE_DESCRIPTION("AC97 driver for ADI Blackfin"); 447MODULE_DESCRIPTION("AC97 driver for ADI Blackfin");
406MODULE_LICENSE("GPL"); 448MODULE_LICENSE("GPL");
diff --git a/sound/soc/blackfin/bf5xx-ac97.h b/sound/soc/blackfin/bf5xx-ac97.h
index 3f77cc558dc0..3f2a911fe0cb 100644
--- a/sound/soc/blackfin/bf5xx-ac97.h
+++ b/sound/soc/blackfin/bf5xx-ac97.h
@@ -16,21 +16,46 @@ struct ac97_frame {
16 u16 ac97_tag; /* slot 0 */ 16 u16 ac97_tag; /* slot 0 */
17 u16 ac97_addr; /* slot 1 */ 17 u16 ac97_addr; /* slot 1 */
18 u16 ac97_data; /* slot 2 */ 18 u16 ac97_data; /* slot 2 */
19 u32 ac97_pcm; /* slot 3 and 4: left and right pcm data */ 19 u16 ac97_pcm_l; /*slot 3:front left*/
20 u16 ac97_pcm_r; /*slot 4:front left*/
21#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
22 u16 ac97_mdm_l1;
23 u16 ac97_center; /*slot 6:center*/
24 u16 ac97_sl; /*slot 7:surround left*/
25 u16 ac97_sr; /*slot 8:surround right*/
26 u16 ac97_lfe; /*slot 9:lfe*/
27#endif
20} __attribute__ ((packed)); 28} __attribute__ ((packed));
21 29
30/* Speaker location */
31#define SP_FL 0x0001
32#define SP_FR 0x0010
33#define SP_FC 0x0002
34#define SP_LFE 0x0020
35#define SP_SL 0x0004
36#define SP_SR 0x0040
37
38#define SP_STEREO (SP_FL | SP_FR)
39#define SP_2DOT1 (SP_FL | SP_FR | SP_LFE)
40#define SP_QUAD (SP_FL | SP_FR | SP_SL | SP_SR)
41#define SP_5DOT1 (SP_FL | SP_FR | SP_FC | SP_LFE | SP_SL | SP_SR)
42
22#define TAG_VALID 0x8000 43#define TAG_VALID 0x8000
23#define TAG_CMD 0x6000 44#define TAG_CMD 0x6000
24#define TAG_PCM_LEFT 0x1000 45#define TAG_PCM_LEFT 0x1000
25#define TAG_PCM_RIGHT 0x0800 46#define TAG_PCM_RIGHT 0x0800
26#define TAG_PCM (TAG_PCM_LEFT | TAG_PCM_RIGHT) 47#define TAG_PCM_MDM_L1 0x0400
48#define TAG_PCM_CENTER 0x0200
49#define TAG_PCM_SL 0x0100
50#define TAG_PCM_SR 0x0080
51#define TAG_PCM_LFE 0x0040
27 52
28extern struct snd_soc_dai bfin_ac97_dai; 53extern struct snd_soc_dai bfin_ac97_dai;
29 54
30void bf5xx_pcm_to_ac97(struct ac97_frame *dst, const __u32 *src, \ 55void bf5xx_pcm_to_ac97(struct ac97_frame *dst, const __u16 *src, \
31 size_t count); 56 size_t count, unsigned int chan_mask);
32 57
33void bf5xx_ac97_to_pcm(const struct ac97_frame *src, __u32 *dst, \ 58void bf5xx_ac97_to_pcm(const struct ac97_frame *src, __u16 *dst, \
34 size_t count); 59 size_t count);
35 60
36#endif 61#endif
diff --git a/sound/soc/blackfin/bf5xx-ad1980.c b/sound/soc/blackfin/bf5xx-ad1980.c
index 124425d22320..d8f591273778 100644
--- a/sound/soc/blackfin/bf5xx-ad1980.c
+++ b/sound/soc/blackfin/bf5xx-ad1980.c
@@ -43,7 +43,7 @@
43#include "bf5xx-ac97-pcm.h" 43#include "bf5xx-ac97-pcm.h"
44#include "bf5xx-ac97.h" 44#include "bf5xx-ac97.h"
45 45
46static struct snd_soc_machine bf5xx_board; 46static struct snd_soc_card bf5xx_board;
47 47
48static int bf5xx_board_startup(struct snd_pcm_substream *substream) 48static int bf5xx_board_startup(struct snd_pcm_substream *substream)
49{ 49{
@@ -67,15 +67,15 @@ static struct snd_soc_dai_link bf5xx_board_dai = {
67 .ops = &bf5xx_board_ops, 67 .ops = &bf5xx_board_ops,
68}; 68};
69 69
70static struct snd_soc_machine bf5xx_board = { 70static struct snd_soc_card bf5xx_board = {
71 .name = "bf5xx-board", 71 .name = "bf5xx-board",
72 .platform = &bf5xx_ac97_soc_platform,
72 .dai_link = &bf5xx_board_dai, 73 .dai_link = &bf5xx_board_dai,
73 .num_links = 1, 74 .num_links = 1,
74}; 75};
75 76
76static struct snd_soc_device bf5xx_board_snd_devdata = { 77static struct snd_soc_device bf5xx_board_snd_devdata = {
77 .machine = &bf5xx_board, 78 .card = &bf5xx_board,
78 .platform = &bf5xx_ac97_soc_platform,
79 .codec_dev = &soc_codec_dev_ad1980, 79 .codec_dev = &soc_codec_dev_ad1980,
80}; 80};
81 81
diff --git a/sound/soc/blackfin/bf5xx-ad73311.c b/sound/soc/blackfin/bf5xx-ad73311.c
index 622c9b909532..7f2a5e199075 100644
--- a/sound/soc/blackfin/bf5xx-ad73311.c
+++ b/sound/soc/blackfin/bf5xx-ad73311.c
@@ -65,7 +65,7 @@
65 65
66#define GPIO_SE CONFIG_SND_BFIN_AD73311_SE 66#define GPIO_SE CONFIG_SND_BFIN_AD73311_SE
67 67
68static struct snd_soc_machine bf5xx_ad73311; 68static struct snd_soc_card bf5xx_ad73311;
69 69
70static int snd_ad73311_startup(void) 70static int snd_ad73311_startup(void)
71{ 71{
@@ -168,7 +168,7 @@ static int bf5xx_ad73311_hw_params(struct snd_pcm_substream *substream,
168 params_format(params)); 168 params_format(params));
169 169
170 /* set cpu DAI configuration */ 170 /* set cpu DAI configuration */
171 ret = cpu_dai->dai_ops.set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A | 171 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A |
172 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); 172 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
173 if (ret < 0) 173 if (ret < 0)
174 return ret; 174 return ret;
@@ -190,16 +190,16 @@ static struct snd_soc_dai_link bf5xx_ad73311_dai = {
190 .ops = &bf5xx_ad73311_ops, 190 .ops = &bf5xx_ad73311_ops,
191}; 191};
192 192
193static struct snd_soc_machine bf5xx_ad73311 = { 193static struct snd_soc_card bf5xx_ad73311 = {
194 .name = "bf5xx_ad73311", 194 .name = "bf5xx_ad73311",
195 .platform = &bf5xx_i2s_soc_platform,
195 .probe = bf5xx_probe, 196 .probe = bf5xx_probe,
196 .dai_link = &bf5xx_ad73311_dai, 197 .dai_link = &bf5xx_ad73311_dai,
197 .num_links = 1, 198 .num_links = 1,
198}; 199};
199 200
200static struct snd_soc_device bf5xx_ad73311_snd_devdata = { 201static struct snd_soc_device bf5xx_ad73311_snd_devdata = {
201 .machine = &bf5xx_ad73311, 202 .card = &bf5xx_ad73311,
202 .platform = &bf5xx_i2s_soc_platform,
203 .codec_dev = &soc_codec_dev_ad73311, 203 .codec_dev = &soc_codec_dev_ad73311,
204}; 204};
205 205
diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.c b/sound/soc/blackfin/bf5xx-i2s-pcm.c
index 61fccf925192..53d290b3ea47 100644
--- a/sound/soc/blackfin/bf5xx-i2s-pcm.c
+++ b/sound/soc/blackfin/bf5xx-i2s-pcm.c
@@ -283,6 +283,18 @@ struct snd_soc_platform bf5xx_i2s_soc_platform = {
283}; 283};
284EXPORT_SYMBOL_GPL(bf5xx_i2s_soc_platform); 284EXPORT_SYMBOL_GPL(bf5xx_i2s_soc_platform);
285 285
286static int __init bfin_i2s_init(void)
287{
288 return snd_soc_register_platform(&bf5xx_i2s_soc_platform);
289}
290module_init(bfin_i2s_init);
291
292static void __exit bfin_i2s_exit(void)
293{
294 snd_soc_unregister_platform(&bf5xx_i2s_soc_platform);
295}
296module_exit(bfin_i2s_exit);
297
286MODULE_AUTHOR("Cliff Cai"); 298MODULE_AUTHOR("Cliff Cai");
287MODULE_DESCRIPTION("ADI Blackfin I2S PCM DMA module"); 299MODULE_DESCRIPTION("ADI Blackfin I2S PCM DMA module");
288MODULE_LICENSE("GPL"); 300MODULE_LICENSE("GPL");
diff --git a/sound/soc/blackfin/bf5xx-i2s.c b/sound/soc/blackfin/bf5xx-i2s.c
index e020c160ee44..d1d95d2393fe 100644
--- a/sound/soc/blackfin/bf5xx-i2s.c
+++ b/sound/soc/blackfin/bf5xx-i2s.c
@@ -132,7 +132,8 @@ static int bf5xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
132 return ret; 132 return ret;
133} 133}
134 134
135static int bf5xx_i2s_startup(struct snd_pcm_substream *substream) 135static int bf5xx_i2s_startup(struct snd_pcm_substream *substream,
136 struct snd_soc_dai *dai)
136{ 137{
137 pr_debug("%s enter\n", __func__); 138 pr_debug("%s enter\n", __func__);
138 139
@@ -142,7 +143,8 @@ static int bf5xx_i2s_startup(struct snd_pcm_substream *substream)
142} 143}
143 144
144static int bf5xx_i2s_hw_params(struct snd_pcm_substream *substream, 145static int bf5xx_i2s_hw_params(struct snd_pcm_substream *substream,
145 struct snd_pcm_hw_params *params) 146 struct snd_pcm_hw_params *params,
147 struct snd_soc_dai *dai)
146{ 148{
147 int ret = 0; 149 int ret = 0;
148 150
@@ -193,7 +195,8 @@ static int bf5xx_i2s_hw_params(struct snd_pcm_substream *substream,
193 return 0; 195 return 0;
194} 196}
195 197
196static void bf5xx_i2s_shutdown(struct snd_pcm_substream *substream) 198static void bf5xx_i2s_shutdown(struct snd_pcm_substream *substream,
199 struct snd_soc_dai *dai)
197{ 200{
198 pr_debug("%s enter\n", __func__); 201 pr_debug("%s enter\n", __func__);
199 bf5xx_i2s.counter--; 202 bf5xx_i2s.counter--;
@@ -219,16 +222,14 @@ static int bf5xx_i2s_probe(struct platform_device *pdev,
219 return 0; 222 return 0;
220} 223}
221 224
222static void bf5xx_i2s_remove(struct platform_device *pdev, 225static void bf5xx_i2s_remove(struct snd_soc_dai *dai)
223 struct snd_soc_dai *dai)
224{ 226{
225 pr_debug("%s enter\n", __func__); 227 pr_debug("%s enter\n", __func__);
226 peripheral_free_list(&sport_req[sport_num][0]); 228 peripheral_free_list(&sport_req[sport_num][0]);
227} 229}
228 230
229#ifdef CONFIG_PM 231#ifdef CONFIG_PM
230static int bf5xx_i2s_suspend(struct platform_device *dev, 232static int bf5xx_i2s_suspend(struct snd_soc_dai *dai)
231 struct snd_soc_dai *dai)
232{ 233{
233 struct sport_device *sport = 234 struct sport_device *sport =
234 (struct sport_device *)dai->private_data; 235 (struct sport_device *)dai->private_data;
@@ -289,7 +290,6 @@ static int bf5xx_i2s_resume(struct platform_device *pdev,
289struct snd_soc_dai bf5xx_i2s_dai = { 290struct snd_soc_dai bf5xx_i2s_dai = {
290 .name = "bf5xx-i2s", 291 .name = "bf5xx-i2s",
291 .id = 0, 292 .id = 0,
292 .type = SND_SOC_DAI_I2S,
293 .probe = bf5xx_i2s_probe, 293 .probe = bf5xx_i2s_probe,
294 .remove = bf5xx_i2s_remove, 294 .remove = bf5xx_i2s_remove,
295 .suspend = bf5xx_i2s_suspend, 295 .suspend = bf5xx_i2s_suspend,
@@ -307,13 +307,24 @@ struct snd_soc_dai bf5xx_i2s_dai = {
307 .ops = { 307 .ops = {
308 .startup = bf5xx_i2s_startup, 308 .startup = bf5xx_i2s_startup,
309 .shutdown = bf5xx_i2s_shutdown, 309 .shutdown = bf5xx_i2s_shutdown,
310 .hw_params = bf5xx_i2s_hw_params,}, 310 .hw_params = bf5xx_i2s_hw_params,
311 .dai_ops = {
312 .set_fmt = bf5xx_i2s_set_dai_fmt, 311 .set_fmt = bf5xx_i2s_set_dai_fmt,
313 }, 312 },
314}; 313};
315EXPORT_SYMBOL_GPL(bf5xx_i2s_dai); 314EXPORT_SYMBOL_GPL(bf5xx_i2s_dai);
316 315
316static int __init bfin_i2s_init(void)
317{
318 return snd_soc_register_dai(&bf5xx_i2s_dai);
319}
320module_init(bfin_i2s_init);
321
322static void __exit bfin_i2s_exit(void)
323{
324 snd_soc_unregister_dai(&bf5xx_i2s_dai);
325}
326module_exit(bfin_i2s_exit);
327
317/* Module information */ 328/* Module information */
318MODULE_AUTHOR("Cliff Cai"); 329MODULE_AUTHOR("Cliff Cai");
319MODULE_DESCRIPTION("I2S driver for ADI Blackfin"); 330MODULE_DESCRIPTION("I2S driver for ADI Blackfin");
diff --git a/sound/soc/blackfin/bf5xx-sport.h b/sound/soc/blackfin/bf5xx-sport.h
index fcadcc081f7f..2e63dea73e9c 100644
--- a/sound/soc/blackfin/bf5xx-sport.h
+++ b/sound/soc/blackfin/bf5xx-sport.h
@@ -116,7 +116,7 @@ struct sport_device {
116 void *err_data; 116 void *err_data;
117 unsigned char *tx_dma_buf; 117 unsigned char *tx_dma_buf;
118 unsigned char *rx_dma_buf; 118 unsigned char *rx_dma_buf;
119#ifdef CONFIG_SND_MMAP_SUPPORT 119#ifdef CONFIG_SND_BF5XX_MMAP_SUPPORT
120 dma_addr_t tx_dma_phy; 120 dma_addr_t tx_dma_phy;
121 dma_addr_t rx_dma_phy; 121 dma_addr_t rx_dma_phy;
122 int tx_pos;/*pcm sample count*/ 122 int tx_pos;/*pcm sample count*/
diff --git a/sound/soc/blackfin/bf5xx-ssm2602.c b/sound/soc/blackfin/bf5xx-ssm2602.c
index e15f67fd7769..bc0cdded7116 100644
--- a/sound/soc/blackfin/bf5xx-ssm2602.c
+++ b/sound/soc/blackfin/bf5xx-ssm2602.c
@@ -44,7 +44,7 @@
44#include "bf5xx-i2s-pcm.h" 44#include "bf5xx-i2s-pcm.h"
45#include "bf5xx-i2s.h" 45#include "bf5xx-i2s.h"
46 46
47static struct snd_soc_machine bf5xx_ssm2602; 47static struct snd_soc_card bf5xx_ssm2602;
48 48
49static int bf5xx_ssm2602_startup(struct snd_pcm_substream *substream) 49static int bf5xx_ssm2602_startup(struct snd_pcm_substream *substream)
50{ 50{
@@ -92,17 +92,17 @@ static int bf5xx_ssm2602_hw_params(struct snd_pcm_substream *substream,
92 */ 92 */
93 93
94 /* set codec DAI configuration */ 94 /* set codec DAI configuration */
95 ret = codec_dai->dai_ops.set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | 95 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
96 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); 96 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
97 if (ret < 0) 97 if (ret < 0)
98 return ret; 98 return ret;
99 /* set cpu DAI configuration */ 99 /* set cpu DAI configuration */
100 ret = cpu_dai->dai_ops.set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | 100 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
101 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); 101 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
102 if (ret < 0) 102 if (ret < 0)
103 return ret; 103 return ret;
104 104
105 ret = codec_dai->dai_ops.set_sysclk(codec_dai, SSM2602_SYSCLK, clk, 105 ret = snd_soc_dai_set_sysclk(codec_dai, SSM2602_SYSCLK, clk,
106 SND_SOC_CLOCK_IN); 106 SND_SOC_CLOCK_IN);
107 if (ret < 0) 107 if (ret < 0)
108 return ret; 108 return ret;
@@ -135,15 +135,15 @@ static struct ssm2602_setup_data bf5xx_ssm2602_setup = {
135 .i2c_address = 0x1b, 135 .i2c_address = 0x1b,
136}; 136};
137 137
138static struct snd_soc_machine bf5xx_ssm2602 = { 138static struct snd_soc_card bf5xx_ssm2602 = {
139 .name = "bf5xx_ssm2602", 139 .name = "bf5xx_ssm2602",
140 .platform = &bf5xx_i2s_soc_platform,
140 .dai_link = &bf5xx_ssm2602_dai, 141 .dai_link = &bf5xx_ssm2602_dai,
141 .num_links = 1, 142 .num_links = 1,
142}; 143};
143 144
144static struct snd_soc_device bf5xx_ssm2602_snd_devdata = { 145static struct snd_soc_device bf5xx_ssm2602_snd_devdata = {
145 .machine = &bf5xx_ssm2602, 146 .card = &bf5xx_ssm2602,
146 .platform = &bf5xx_i2s_soc_platform,
147 .codec_dev = &soc_codec_dev_ssm2602, 147 .codec_dev = &soc_codec_dev_ssm2602,
148 .codec_data = &bf5xx_ssm2602_setup, 148 .codec_data = &bf5xx_ssm2602_setup,
149}; 149};
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 38a0e3b620a7..c41289b5f586 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -1,31 +1,40 @@
1config SND_SOC_ALL_CODECS 1config SND_SOC_ALL_CODECS
2 tristate "Build all ASoC CODEC drivers" 2 tristate "Build all ASoC CODEC drivers"
3 depends on I2C 3 select SND_SOC_AC97_CODEC if SND_SOC_AC97_BUS
4 select SPI 4 select SND_SOC_AD1980 if SND_SOC_AC97_BUS
5 select SPI_MASTER 5 select SND_SOC_AD73311 if I2C
6 select SND_SOC_AD73311 6 select SND_SOC_AK4535 if I2C
7 select SND_SOC_AK4535 7 select SND_SOC_CS4270 if I2C
8 select SND_SOC_CS4270 8 select SND_SOC_PCM3008
9 select SND_SOC_SSM2602 9 select SND_SOC_SSM2602 if I2C
10 select SND_SOC_TLV320AIC23 10 select SND_SOC_TLV320AIC23 if I2C
11 select SND_SOC_TLV320AIC26 11 select SND_SOC_TLV320AIC26 if SPI_MASTER
12 select SND_SOC_TLV320AIC3X 12 select SND_SOC_TLV320AIC3X if I2C
13 select SND_SOC_UDA1380 13 select SND_SOC_TWL4030 if TWL4030_CORE
14 select SND_SOC_WM8510 14 select SND_SOC_UDA134X
15 select SND_SOC_WM8580 15 select SND_SOC_UDA1380 if I2C
16 select SND_SOC_WM8731 16 select SND_SOC_WM8350 if MFD_WM8350
17 select SND_SOC_WM8750 17 select SND_SOC_WM8510 if (I2C || SPI_MASTER)
18 select SND_SOC_WM8753 18 select SND_SOC_WM8580 if I2C
19 select SND_SOC_WM8900 19 select SND_SOC_WM8728 if (I2C || SPI_MASTER)
20 select SND_SOC_WM8903 20 select SND_SOC_WM8731 if (I2C || SPI_MASTER)
21 select SND_SOC_WM8971 21 select SND_SOC_WM8750 if (I2C || SPI_MASTER)
22 select SND_SOC_WM8990 22 select SND_SOC_WM8753 if (I2C || SPI_MASTER)
23 select SND_SOC_WM8900 if I2C
24 select SND_SOC_WM8903 if I2C
25 select SND_SOC_WM8971 if I2C
26 select SND_SOC_WM8990 if I2C
27 select SND_SOC_WM9712 if SND_SOC_AC97_BUS
28 select SND_SOC_WM9713 if SND_SOC_AC97_BUS
23 help 29 help
24 Normally ASoC codec drivers are only built if a machine driver which 30 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 31 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 32 driver. Selecting this option will allow these drivers to be built
27 without an explicit machine driver for test and development purposes. 33 without an explicit machine driver for test and development purposes.
28 34
35 Support for the bus types used to access the codecs to be built must
36 be selected separately.
37
29 If unsure select "N". 38 If unsure select "N".
30 39
31 40
@@ -60,6 +69,12 @@ config SND_SOC_CS4270_VD33_ERRATA
60 bool 69 bool
61 depends on SND_SOC_CS4270 70 depends on SND_SOC_CS4270
62 71
72config SND_SOC_L3
73 tristate
74
75config SND_SOC_PCM3008
76 tristate
77
63config SND_SOC_SSM2602 78config SND_SOC_SSM2602
64 tristate 79 tristate
65 80
@@ -75,15 +90,29 @@ config SND_SOC_TLV320AIC3X
75 tristate 90 tristate
76 depends on I2C 91 depends on I2C
77 92
93config SND_SOC_TWL4030
94 tristate
95 depends on TWL4030_CORE
96
97config SND_SOC_UDA134X
98 tristate
99 select SND_SOC_L3
100
78config SND_SOC_UDA1380 101config SND_SOC_UDA1380
79 tristate 102 tristate
80 103
104config SND_SOC_WM8350
105 tristate
106
81config SND_SOC_WM8510 107config SND_SOC_WM8510
82 tristate 108 tristate
83 109
84config SND_SOC_WM8580 110config SND_SOC_WM8580
85 tristate 111 tristate
86 112
113config SND_SOC_WM8728
114 tristate
115
87config SND_SOC_WM8731 116config SND_SOC_WM8731
88 tristate 117 tristate
89 118
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 90f0a585fc70..c4ddc9aa2bbd 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -3,13 +3,19 @@ snd-soc-ad1980-objs := ad1980.o
3snd-soc-ad73311-objs := ad73311.o 3snd-soc-ad73311-objs := ad73311.o
4snd-soc-ak4535-objs := ak4535.o 4snd-soc-ak4535-objs := ak4535.o
5snd-soc-cs4270-objs := cs4270.o 5snd-soc-cs4270-objs := cs4270.o
6snd-soc-l3-objs := l3.o
7snd-soc-pcm3008-objs := pcm3008.o
6snd-soc-ssm2602-objs := ssm2602.o 8snd-soc-ssm2602-objs := ssm2602.o
7snd-soc-tlv320aic23-objs := tlv320aic23.o 9snd-soc-tlv320aic23-objs := tlv320aic23.o
8snd-soc-tlv320aic26-objs := tlv320aic26.o 10snd-soc-tlv320aic26-objs := tlv320aic26.o
9snd-soc-tlv320aic3x-objs := tlv320aic3x.o 11snd-soc-tlv320aic3x-objs := tlv320aic3x.o
12snd-soc-twl4030-objs := twl4030.o
13snd-soc-uda134x-objs := uda134x.o
10snd-soc-uda1380-objs := uda1380.o 14snd-soc-uda1380-objs := uda1380.o
15snd-soc-wm8350-objs := wm8350.o
11snd-soc-wm8510-objs := wm8510.o 16snd-soc-wm8510-objs := wm8510.o
12snd-soc-wm8580-objs := wm8580.o 17snd-soc-wm8580-objs := wm8580.o
18snd-soc-wm8728-objs := wm8728.o
13snd-soc-wm8731-objs := wm8731.o 19snd-soc-wm8731-objs := wm8731.o
14snd-soc-wm8750-objs := wm8750.o 20snd-soc-wm8750-objs := wm8750.o
15snd-soc-wm8753-objs := wm8753.o 21snd-soc-wm8753-objs := wm8753.o
@@ -25,13 +31,19 @@ obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o
25obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o 31obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o
26obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o 32obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o
27obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o 33obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
34obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
35obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o
28obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o 36obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o
29obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o 37obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o
30obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o 38obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o
31obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o 39obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o
40obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o
41obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o
32obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o 42obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o
43obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o
33obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o 44obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o
34obj-$(CONFIG_SND_SOC_WM8580) += snd-soc-wm8580.o 45obj-$(CONFIG_SND_SOC_WM8580) += snd-soc-wm8580.o
46obj-$(CONFIG_SND_SOC_WM8728) += snd-soc-wm8728.o
35obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o 47obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o
36obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o 48obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o
37obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o 49obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o
diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c
index bd1ebdc6c86c..fb53e6511af2 100644
--- a/sound/soc/codecs/ac97.c
+++ b/sound/soc/codecs/ac97.c
@@ -24,7 +24,8 @@
24 24
25#define AC97_VERSION "0.6" 25#define AC97_VERSION "0.6"
26 26
27static int ac97_prepare(struct snd_pcm_substream *substream) 27static int ac97_prepare(struct snd_pcm_substream *substream,
28 struct snd_soc_dai *dai)
28{ 29{
29 struct snd_pcm_runtime *runtime = substream->runtime; 30 struct snd_pcm_runtime *runtime = substream->runtime;
30 struct snd_soc_pcm_runtime *rtd = substream->private_data; 31 struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -42,7 +43,7 @@ static int ac97_prepare(struct snd_pcm_substream *substream)
42 43
43struct snd_soc_dai ac97_dai = { 44struct snd_soc_dai ac97_dai = {
44 .name = "AC97 HiFi", 45 .name = "AC97 HiFi",
45 .type = SND_SOC_DAI_AC97, 46 .ac97_control = 1,
46 .playback = { 47 .playback = {
47 .stream_name = "AC97 Playback", 48 .stream_name = "AC97 Playback",
48 .channels_min = 1, 49 .channels_min = 1,
@@ -113,7 +114,7 @@ static int ac97_soc_probe(struct platform_device *pdev)
113 if (ret < 0) 114 if (ret < 0)
114 goto bus_err; 115 goto bus_err;
115 116
116 ret = snd_soc_register_card(socdev); 117 ret = snd_soc_init_card(socdev);
117 if (ret < 0) 118 if (ret < 0)
118 goto bus_err; 119 goto bus_err;
119 return 0; 120 return 0;
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index 1397b8e06c0b..73fdbb4d4a3d 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -85,6 +85,9 @@ SOC_DOUBLE("Line HP Swap Switch", AC97_AD_MISC, 10, 5, 1, 0),
85SOC_DOUBLE("Surround Playback Volume", AC97_SURROUND_MASTER, 8, 0, 31, 1), 85SOC_DOUBLE("Surround Playback Volume", AC97_SURROUND_MASTER, 8, 0, 31, 1),
86SOC_DOUBLE("Surround Playback Switch", AC97_SURROUND_MASTER, 15, 7, 1, 1), 86SOC_DOUBLE("Surround Playback Switch", AC97_SURROUND_MASTER, 15, 7, 1, 1),
87 87
88SOC_DOUBLE("Center/LFE Playback Volume", AC97_CENTER_LFE_MASTER, 8, 0, 31, 1),
89SOC_DOUBLE("Center/LFE Playback Switch", AC97_CENTER_LFE_MASTER, 15, 7, 1, 1),
90
88SOC_ENUM("Capture Source", ad1980_cap_src), 91SOC_ENUM("Capture Source", ad1980_cap_src),
89 92
90SOC_SINGLE("Mic Boost Switch", AC97_MIC, 6, 1, 0), 93SOC_SINGLE("Mic Boost Switch", AC97_MIC, 6, 1, 0),
@@ -142,10 +145,11 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
142 145
143struct snd_soc_dai ad1980_dai = { 146struct snd_soc_dai ad1980_dai = {
144 .name = "AC97", 147 .name = "AC97",
148 .ac97_control = 1,
145 .playback = { 149 .playback = {
146 .stream_name = "Playback", 150 .stream_name = "Playback",
147 .channels_min = 2, 151 .channels_min = 2,
148 .channels_max = 2, 152 .channels_max = 6,
149 .rates = SNDRV_PCM_RATE_48000, 153 .rates = SNDRV_PCM_RATE_48000,
150 .formats = SNDRV_PCM_FMTBIT_S16_LE, }, 154 .formats = SNDRV_PCM_FMTBIT_S16_LE, },
151 .capture = { 155 .capture = {
@@ -192,6 +196,7 @@ static int ad1980_soc_probe(struct platform_device *pdev)
192 struct snd_soc_codec *codec; 196 struct snd_soc_codec *codec;
193 int ret = 0; 197 int ret = 0;
194 u16 vendor_id2; 198 u16 vendor_id2;
199 u16 ext_status;
195 200
196 printk(KERN_INFO "AD1980 SoC Audio Codec\n"); 201 printk(KERN_INFO "AD1980 SoC Audio Codec\n");
197 202
@@ -234,7 +239,7 @@ static int ad1980_soc_probe(struct platform_device *pdev)
234 239
235 ret = ad1980_reset(codec, 0); 240 ret = ad1980_reset(codec, 0);
236 if (ret < 0) { 241 if (ret < 0) {
237 printk(KERN_ERR "AC97 link error\n"); 242 printk(KERN_ERR "Failed to reset AD1980: AC97 link error\n");
238 goto reset_err; 243 goto reset_err;
239 } 244 }
240 245
@@ -253,12 +258,19 @@ static int ad1980_soc_probe(struct platform_device *pdev)
253 "supported\n"); 258 "supported\n");
254 } 259 }
255 260
256 ac97_write(codec, AC97_MASTER, 0x0000); /* unmute line out volume */ 261 /* unmute captures and playbacks volume */
257 ac97_write(codec, AC97_PCM, 0x0000); /* unmute PCM out volume */ 262 ac97_write(codec, AC97_MASTER, 0x0000);
258 ac97_write(codec, AC97_REC_GAIN, 0x0000);/* unmute record volume */ 263 ac97_write(codec, AC97_PCM, 0x0000);
264 ac97_write(codec, AC97_REC_GAIN, 0x0000);
265 ac97_write(codec, AC97_CENTER_LFE_MASTER, 0x0000);
266 ac97_write(codec, AC97_SURROUND_MASTER, 0x0000);
267
268 /*power on LFE/CENTER/Surround DACs*/
269 ext_status = ac97_read(codec, AC97_EXTENDED_STATUS);
270 ac97_write(codec, AC97_EXTENDED_STATUS, ext_status&~0x3800);
259 271
260 ad1980_add_controls(codec); 272 ad1980_add_controls(codec);
261 ret = snd_soc_register_card(socdev); 273 ret = snd_soc_init_card(socdev);
262 if (ret < 0) { 274 if (ret < 0) {
263 printk(KERN_ERR "ad1980: failed to register card\n"); 275 printk(KERN_ERR "ad1980: failed to register card\n");
264 goto reset_err; 276 goto reset_err;
diff --git a/sound/soc/codecs/ad73311.c b/sound/soc/codecs/ad73311.c
index 37af8607b00a..b09289a1e55a 100644
--- a/sound/soc/codecs/ad73311.c
+++ b/sound/soc/codecs/ad73311.c
@@ -8,14 +8,10 @@
8 * 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
9 * Free Software Foundation; either version 2 of the License, or (at your 9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. 10 * option) any later version.
11 *
12 * Revision history
13 * 25th Sep 2008 Initial version.
14 */ 11 */
15 12
16#include <linux/init.h> 13#include <linux/init.h>
17#include <linux/module.h> 14#include <linux/module.h>
18#include <linux/version.h>
19#include <linux/kernel.h> 15#include <linux/kernel.h>
20#include <linux/device.h> 16#include <linux/device.h>
21#include <sound/core.h> 17#include <sound/core.h>
@@ -68,7 +64,7 @@ static int ad73311_soc_probe(struct platform_device *pdev)
68 goto pcm_err; 64 goto pcm_err;
69 } 65 }
70 66
71 ret = snd_soc_register_card(socdev); 67 ret = snd_soc_init_card(socdev);
72 if (ret < 0) { 68 if (ret < 0) {
73 printk(KERN_ERR "ad73311: failed to register card\n"); 69 printk(KERN_ERR "ad73311: failed to register card\n");
74 goto register_err; 70 goto register_err;
@@ -102,6 +98,18 @@ struct snd_soc_codec_device soc_codec_dev_ad73311 = {
102}; 98};
103EXPORT_SYMBOL_GPL(soc_codec_dev_ad73311); 99EXPORT_SYMBOL_GPL(soc_codec_dev_ad73311);
104 100
101static int __init ad73311_init(void)
102{
103 return snd_soc_register_dai(&ad73311_dai);
104}
105module_init(ad73311_init);
106
107static void __exit ad73311_exit(void)
108{
109 snd_soc_unregister_dai(&ad73311_dai);
110}
111module_exit(ad73311_exit);
112
105MODULE_DESCRIPTION("ASoC ad73311 driver"); 113MODULE_DESCRIPTION("ASoC ad73311 driver");
106MODULE_AUTHOR("Cliff Cai "); 114MODULE_AUTHOR("Cliff Cai ");
107MODULE_LICENSE("GPL"); 115MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
index 2a89b5888e11..81300d8d42ca 100644
--- a/sound/soc/codecs/ak4535.c
+++ b/sound/soc/codecs/ak4535.c
@@ -339,7 +339,8 @@ static int ak4535_set_dai_sysclk(struct snd_soc_dai *codec_dai,
339} 339}
340 340
341static int ak4535_hw_params(struct snd_pcm_substream *substream, 341static int ak4535_hw_params(struct snd_pcm_substream *substream,
342 struct snd_pcm_hw_params *params) 342 struct snd_pcm_hw_params *params,
343 struct snd_soc_dai *dai)
343{ 344{
344 struct snd_soc_pcm_runtime *rtd = substream->private_data; 345 struct snd_soc_pcm_runtime *rtd = substream->private_data;
345 struct snd_soc_device *socdev = rtd->socdev; 346 struct snd_soc_device *socdev = rtd->socdev;
@@ -451,8 +452,6 @@ struct snd_soc_dai ak4535_dai = {
451 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 452 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
452 .ops = { 453 .ops = {
453 .hw_params = ak4535_hw_params, 454 .hw_params = ak4535_hw_params,
454 },
455 .dai_ops = {
456 .set_fmt = ak4535_set_dai_fmt, 455 .set_fmt = ak4535_set_dai_fmt,
457 .digital_mute = ak4535_mute, 456 .digital_mute = ak4535_mute,
458 .set_sysclk = ak4535_set_dai_sysclk, 457 .set_sysclk = ak4535_set_dai_sysclk,
@@ -513,7 +512,7 @@ static int ak4535_init(struct snd_soc_device *socdev)
513 512
514 ak4535_add_controls(codec); 513 ak4535_add_controls(codec);
515 ak4535_add_widgets(codec); 514 ak4535_add_widgets(codec);
516 ret = snd_soc_register_card(socdev); 515 ret = snd_soc_init_card(socdev);
517 if (ret < 0) { 516 if (ret < 0) {
518 printk(KERN_ERR "ak4535: failed to register card\n"); 517 printk(KERN_ERR "ak4535: failed to register card\n");
519 goto card_err; 518 goto card_err;
@@ -689,6 +688,18 @@ struct snd_soc_codec_device soc_codec_dev_ak4535 = {
689}; 688};
690EXPORT_SYMBOL_GPL(soc_codec_dev_ak4535); 689EXPORT_SYMBOL_GPL(soc_codec_dev_ak4535);
691 690
691static int __init ak4535_modinit(void)
692{
693 return snd_soc_register_dai(&ak4535_dai);
694}
695module_init(ak4535_modinit);
696
697static void __exit ak4535_exit(void)
698{
699 snd_soc_unregister_dai(&ak4535_dai);
700}
701module_exit(ak4535_exit);
702
692MODULE_DESCRIPTION("Soc AK4535 driver"); 703MODULE_DESCRIPTION("Soc AK4535 driver");
693MODULE_AUTHOR("Richard Purdie"); 704MODULE_AUTHOR("Richard Purdie");
694MODULE_LICENSE("GPL"); 705MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index 0bbd94501d7e..f1aa0c34421c 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -360,13 +360,14 @@ static int cs4270_i2c_write(struct snd_soc_codec *codec, unsigned int reg,
360/* 360/*
361 * Program the CS4270 with the given hardware parameters. 361 * Program the CS4270 with the given hardware parameters.
362 * 362 *
363 * The .dai_ops functions are used to provide board-specific data, like 363 * The .ops functions are used to provide board-specific data, like
364 * input frequencies, to this driver. This function takes that information, 364 * input frequencies, to this driver. This function takes that information,
365 * combines it with the hardware parameters provided, and programs the 365 * combines it with the hardware parameters provided, and programs the
366 * hardware accordingly. 366 * hardware accordingly.
367 */ 367 */
368static int cs4270_hw_params(struct snd_pcm_substream *substream, 368static int cs4270_hw_params(struct snd_pcm_substream *substream,
369 struct snd_pcm_hw_params *params) 369 struct snd_pcm_hw_params *params,
370 struct snd_soc_dai *dai)
370{ 371{
371 struct snd_soc_pcm_runtime *rtd = substream->private_data; 372 struct snd_soc_pcm_runtime *rtd = substream->private_data;
372 struct snd_soc_device *socdev = rtd->socdev; 373 struct snd_soc_device *socdev = rtd->socdev;
@@ -450,6 +451,19 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream,
450 return ret; 451 return ret;
451 } 452 }
452 453
454 /* Disable automatic volume control. It's enabled by default, and
455 * it causes volume change commands to be delayed, sometimes until
456 * after playback has started.
457 */
458
459 reg = cs4270_read_reg_cache(codec, CS4270_TRANS);
460 reg &= ~(CS4270_TRANS_SOFT | CS4270_TRANS_ZERO);
461 ret = cs4270_i2c_write(codec, CS4270_TRANS, reg);
462 if (ret < 0) {
463 printk(KERN_ERR "I2C write failed\n");
464 return ret;
465 }
466
453 /* Thaw and power-up the codec */ 467 /* Thaw and power-up the codec */
454 468
455 ret = snd_soc_write(codec, CS4270_PWRCTL, 0); 469 ret = snd_soc_write(codec, CS4270_PWRCTL, 0);
@@ -697,10 +711,10 @@ static int cs4270_probe(struct platform_device *pdev)
697 if (codec->control_data) { 711 if (codec->control_data) {
698 /* Initialize codec ops */ 712 /* Initialize codec ops */
699 cs4270_dai.ops.hw_params = cs4270_hw_params; 713 cs4270_dai.ops.hw_params = cs4270_hw_params;
700 cs4270_dai.dai_ops.set_sysclk = cs4270_set_dai_sysclk; 714 cs4270_dai.ops.set_sysclk = cs4270_set_dai_sysclk;
701 cs4270_dai.dai_ops.set_fmt = cs4270_set_dai_fmt; 715 cs4270_dai.ops.set_fmt = cs4270_set_dai_fmt;
702#ifdef CONFIG_SND_SOC_CS4270_HWMUTE 716#ifdef CONFIG_SND_SOC_CS4270_HWMUTE
703 cs4270_dai.dai_ops.digital_mute = cs4270_mute; 717 cs4270_dai.ops.digital_mute = cs4270_mute;
704#endif 718#endif
705 } else 719 } else
706 printk(KERN_INFO "cs4270: no I2C device found, " 720 printk(KERN_INFO "cs4270: no I2C device found, "
@@ -709,7 +723,7 @@ static int cs4270_probe(struct platform_device *pdev)
709 printk(KERN_INFO "cs4270: I2C disabled, using stand-alone mode\n"); 723 printk(KERN_INFO "cs4270: I2C disabled, using stand-alone mode\n");
710#endif 724#endif
711 725
712 ret = snd_soc_register_card(socdev); 726 ret = snd_soc_init_card(socdev);
713 if (ret < 0) { 727 if (ret < 0) {
714 printk(KERN_ERR "cs4270: failed to register card\n"); 728 printk(KERN_ERR "cs4270: failed to register card\n");
715 goto error_del_driver; 729 goto error_del_driver;
@@ -760,6 +774,18 @@ struct snd_soc_codec_device soc_codec_device_cs4270 = {
760}; 774};
761EXPORT_SYMBOL_GPL(soc_codec_device_cs4270); 775EXPORT_SYMBOL_GPL(soc_codec_device_cs4270);
762 776
777static int __init cs4270_init(void)
778{
779 return snd_soc_register_dai(&cs4270_dai);
780}
781module_init(cs4270_init);
782
783static void __exit cs4270_exit(void)
784{
785 snd_soc_unregister_dai(&cs4270_dai);
786}
787module_exit(cs4270_exit);
788
763MODULE_AUTHOR("Timur Tabi <timur@freescale.com>"); 789MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
764MODULE_DESCRIPTION("Cirrus Logic CS4270 ALSA SoC Codec Driver"); 790MODULE_DESCRIPTION("Cirrus Logic CS4270 ALSA SoC Codec Driver");
765MODULE_LICENSE("GPL"); 791MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/l3.c b/sound/soc/codecs/l3.c
new file mode 100644
index 000000000000..5353af58862c
--- /dev/null
+++ b/sound/soc/codecs/l3.c
@@ -0,0 +1,91 @@
1/*
2 * L3 code
3 *
4 * Copyright (C) 2008, Christian Pellegrin <chripell@evolware.org>
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 * based on:
12 *
13 * L3 bus algorithm module.
14 *
15 * Copyright (C) 2001 Russell King, All Rights Reserved.
16 *
17 *
18 */
19
20#include <linux/module.h>
21#include <linux/kernel.h>
22#include <linux/delay.h>
23
24#include <sound/l3.h>
25
26/*
27 * Send one byte of data to the chip. Data is latched into the chip on
28 * the rising edge of the clock.
29 */
30static void sendbyte(struct l3_pins *adap, unsigned int byte)
31{
32 int i;
33
34 for (i = 0; i < 8; i++) {
35 adap->setclk(0);
36 udelay(adap->data_hold);
37 adap->setdat(byte & 1);
38 udelay(adap->data_setup);
39 adap->setclk(1);
40 udelay(adap->clock_high);
41 byte >>= 1;
42 }
43}
44
45/*
46 * Send a set of bytes to the chip. We need to pulse the MODE line
47 * between each byte, but never at the start nor at the end of the
48 * transfer.
49 */
50static void sendbytes(struct l3_pins *adap, const u8 *buf,
51 int len)
52{
53 int i;
54
55 for (i = 0; i < len; i++) {
56 if (i) {
57 udelay(adap->mode_hold);
58 adap->setmode(0);
59 udelay(adap->mode);
60 }
61 adap->setmode(1);
62 udelay(adap->mode_setup);
63 sendbyte(adap, buf[i]);
64 }
65}
66
67int l3_write(struct l3_pins *adap, u8 addr, u8 *data, int len)
68{
69 adap->setclk(1);
70 adap->setdat(1);
71 adap->setmode(1);
72 udelay(adap->mode);
73
74 adap->setmode(0);
75 udelay(adap->mode_setup);
76 sendbyte(adap, addr);
77 udelay(adap->mode_hold);
78
79 sendbytes(adap, data, len);
80
81 adap->setclk(1);
82 adap->setdat(1);
83 adap->setmode(0);
84
85 return len;
86}
87EXPORT_SYMBOL_GPL(l3_write);
88
89MODULE_DESCRIPTION("L3 bit-banging driver");
90MODULE_AUTHOR("Christian Pellegrin <chripell@evolware.org>");
91MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/pcm3008.c b/sound/soc/codecs/pcm3008.c
new file mode 100644
index 000000000000..9a3e67e5319c
--- /dev/null
+++ b/sound/soc/codecs/pcm3008.c
@@ -0,0 +1,212 @@
1/*
2 * ALSA Soc PCM3008 codec support
3 *
4 * Author: Hugo Villeneuve
5 * Copyright (C) 2008 Lyrtech inc
6 *
7 * Based on AC97 Soc codec, original copyright follow:
8 * Copyright 2005 Wolfson Microelectronics PLC.
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 * Generic PCM3008 support.
16 */
17
18#include <linux/init.h>
19#include <linux/kernel.h>
20#include <linux/device.h>
21#include <linux/gpio.h>
22#include <sound/core.h>
23#include <sound/pcm.h>
24#include <sound/initval.h>
25#include <sound/soc.h>
26
27#include "pcm3008.h"
28
29#define PCM3008_VERSION "0.2"
30
31#define PCM3008_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
32 SNDRV_PCM_RATE_48000)
33
34struct snd_soc_dai pcm3008_dai = {
35 .name = "PCM3008 HiFi",
36 .playback = {
37 .stream_name = "PCM3008 Playback",
38 .channels_min = 1,
39 .channels_max = 2,
40 .rates = PCM3008_RATES,
41 .formats = SNDRV_PCM_FMTBIT_S16_LE,
42 },
43 .capture = {
44 .stream_name = "PCM3008 Capture",
45 .channels_min = 1,
46 .channels_max = 2,
47 .rates = PCM3008_RATES,
48 .formats = SNDRV_PCM_FMTBIT_S16_LE,
49 },
50};
51EXPORT_SYMBOL_GPL(pcm3008_dai);
52
53static void pcm3008_gpio_free(struct pcm3008_setup_data *setup)
54{
55 gpio_free(setup->dem0_pin);
56 gpio_free(setup->dem1_pin);
57 gpio_free(setup->pdad_pin);
58 gpio_free(setup->pdda_pin);
59}
60
61static int pcm3008_soc_probe(struct platform_device *pdev)
62{
63 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
64 struct snd_soc_codec *codec;
65 struct pcm3008_setup_data *setup = socdev->codec_data;
66 int ret = 0;
67
68 printk(KERN_INFO "PCM3008 SoC Audio Codec %s\n", PCM3008_VERSION);
69
70 socdev->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
71 if (!socdev->codec)
72 return -ENOMEM;
73
74 codec = socdev->codec;
75 mutex_init(&codec->mutex);
76
77 codec->name = "PCM3008";
78 codec->owner = THIS_MODULE;
79 codec->dai = &pcm3008_dai;
80 codec->num_dai = 1;
81 codec->write = NULL;
82 codec->read = NULL;
83 INIT_LIST_HEAD(&codec->dapm_widgets);
84 INIT_LIST_HEAD(&codec->dapm_paths);
85
86 /* Register PCMs. */
87 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
88 if (ret < 0) {
89 printk(KERN_ERR "pcm3008: failed to create pcms\n");
90 goto pcm_err;
91 }
92
93 /* Register Card. */
94 ret = snd_soc_init_card(socdev);
95 if (ret < 0) {
96 printk(KERN_ERR "pcm3008: failed to register card\n");
97 goto card_err;
98 }
99
100 /* DEM1 DEM0 DE-EMPHASIS_MODE
101 * Low Low De-emphasis 44.1 kHz ON
102 * Low High De-emphasis OFF
103 * High Low De-emphasis 48 kHz ON
104 * High High De-emphasis 32 kHz ON
105 */
106
107 /* Configure DEM0 GPIO (turning OFF DAC De-emphasis). */
108 ret = gpio_request(setup->dem0_pin, "codec_dem0");
109 if (ret == 0)
110 ret = gpio_direction_output(setup->dem0_pin, 1);
111 if (ret != 0)
112 goto gpio_err;
113
114 /* Configure DEM1 GPIO (turning OFF DAC De-emphasis). */
115 ret = gpio_request(setup->dem1_pin, "codec_dem1");
116 if (ret == 0)
117 ret = gpio_direction_output(setup->dem1_pin, 0);
118 if (ret != 0)
119 goto gpio_err;
120
121 /* Configure PDAD GPIO. */
122 ret = gpio_request(setup->pdad_pin, "codec_pdad");
123 if (ret == 0)
124 ret = gpio_direction_output(setup->pdad_pin, 1);
125 if (ret != 0)
126 goto gpio_err;
127
128 /* Configure PDDA GPIO. */
129 ret = gpio_request(setup->pdda_pin, "codec_pdda");
130 if (ret == 0)
131 ret = gpio_direction_output(setup->pdda_pin, 1);
132 if (ret != 0)
133 goto gpio_err;
134
135 return ret;
136
137gpio_err:
138 pcm3008_gpio_free(setup);
139card_err:
140 snd_soc_free_pcms(socdev);
141pcm_err:
142 kfree(socdev->codec);
143
144 return ret;
145}
146
147static int pcm3008_soc_remove(struct platform_device *pdev)
148{
149 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
150 struct snd_soc_codec *codec = socdev->codec;
151 struct pcm3008_setup_data *setup = socdev->codec_data;
152
153 if (!codec)
154 return 0;
155
156 pcm3008_gpio_free(setup);
157 snd_soc_free_pcms(socdev);
158 kfree(socdev->codec);
159
160 return 0;
161}
162
163#ifdef CONFIG_PM
164static int pcm3008_soc_suspend(struct platform_device *pdev, pm_message_t msg)
165{
166 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
167 struct pcm3008_setup_data *setup = socdev->codec_data;
168
169 gpio_set_value(setup->pdad_pin, 0);
170 gpio_set_value(setup->pdda_pin, 0);
171
172 return 0;
173}
174
175static int pcm3008_soc_resume(struct platform_device *pdev)
176{
177 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
178 struct pcm3008_setup_data *setup = socdev->codec_data;
179
180 gpio_set_value(setup->pdad_pin, 1);
181 gpio_set_value(setup->pdda_pin, 1);
182
183 return 0;
184}
185#else
186#define pcm3008_soc_suspend NULL
187#define pcm3008_soc_resume NULL
188#endif
189
190struct snd_soc_codec_device soc_codec_dev_pcm3008 = {
191 .probe = pcm3008_soc_probe,
192 .remove = pcm3008_soc_remove,
193 .suspend = pcm3008_soc_suspend,
194 .resume = pcm3008_soc_resume,
195};
196EXPORT_SYMBOL_GPL(soc_codec_dev_pcm3008);
197
198static int __init pcm3008_init(void)
199{
200 return snd_soc_register_dai(&pcm3008_dai);
201}
202module_init(pcm3008_init);
203
204static void __exit pcm3008_exit(void)
205{
206 snd_soc_unregister_dai(&pcm3008_dai);
207}
208module_exit(pcm3008_exit);
209
210MODULE_DESCRIPTION("Soc PCM3008 driver");
211MODULE_AUTHOR("Hugo Villeneuve");
212MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/pcm3008.h b/sound/soc/codecs/pcm3008.h
new file mode 100644
index 000000000000..d04e87d3c060
--- /dev/null
+++ b/sound/soc/codecs/pcm3008.h
@@ -0,0 +1,25 @@
1/*
2 * PCM3008 ALSA SoC Layer
3 *
4 * Author: Hugo Villeneuve
5 * Copyright (C) 2008 Lyrtech inc
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 __LINUX_SND_SOC_PCM3008_H
13#define __LINUX_SND_SOC_PCM3008_H
14
15struct pcm3008_setup_data {
16 unsigned dem0_pin;
17 unsigned dem1_pin;
18 unsigned pdad_pin;
19 unsigned pdda_pin;
20};
21
22extern struct snd_soc_codec_device soc_codec_dev_pcm3008;
23extern struct snd_soc_dai pcm3008_dai;
24
25#endif
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
index 44ef0dacd564..cac373616768 100644
--- a/sound/soc/codecs/ssm2602.c
+++ b/sound/soc/codecs/ssm2602.c
@@ -285,16 +285,23 @@ static inline int get_coeff(int mclk, int rate)
285} 285}
286 286
287static int ssm2602_hw_params(struct snd_pcm_substream *substream, 287static int ssm2602_hw_params(struct snd_pcm_substream *substream,
288 struct snd_pcm_hw_params *params) 288 struct snd_pcm_hw_params *params,
289 struct snd_soc_dai *dai)
289{ 290{
290 u16 srate; 291 u16 srate;
291 struct snd_soc_pcm_runtime *rtd = substream->private_data; 292 struct snd_soc_pcm_runtime *rtd = substream->private_data;
292 struct snd_soc_device *socdev = rtd->socdev; 293 struct snd_soc_device *socdev = rtd->socdev;
293 struct snd_soc_codec *codec = socdev->codec; 294 struct snd_soc_codec *codec = socdev->codec;
294 struct ssm2602_priv *ssm2602 = codec->private_data; 295 struct ssm2602_priv *ssm2602 = codec->private_data;
296 struct i2c_client *i2c = codec->control_data;
295 u16 iface = ssm2602_read_reg_cache(codec, SSM2602_IFACE) & 0xfff3; 297 u16 iface = ssm2602_read_reg_cache(codec, SSM2602_IFACE) & 0xfff3;
296 int i = get_coeff(ssm2602->sysclk, params_rate(params)); 298 int i = get_coeff(ssm2602->sysclk, params_rate(params));
297 299
300 if (substream == ssm2602->slave_substream) {
301 dev_dbg(&i2c->dev, "Ignoring hw_params for slave substream\n");
302 return 0;
303 }
304
298 /*no match is found*/ 305 /*no match is found*/
299 if (i == ARRAY_SIZE(coeff_div)) 306 if (i == ARRAY_SIZE(coeff_div))
300 return -EINVAL; 307 return -EINVAL;
@@ -324,19 +331,26 @@ static int ssm2602_hw_params(struct snd_pcm_substream *substream,
324 return 0; 331 return 0;
325} 332}
326 333
327static int ssm2602_startup(struct snd_pcm_substream *substream) 334static int ssm2602_startup(struct snd_pcm_substream *substream,
335 struct snd_soc_dai *dai)
328{ 336{
329 struct snd_soc_pcm_runtime *rtd = substream->private_data; 337 struct snd_soc_pcm_runtime *rtd = substream->private_data;
330 struct snd_soc_device *socdev = rtd->socdev; 338 struct snd_soc_device *socdev = rtd->socdev;
331 struct snd_soc_codec *codec = socdev->codec; 339 struct snd_soc_codec *codec = socdev->codec;
332 struct ssm2602_priv *ssm2602 = codec->private_data; 340 struct ssm2602_priv *ssm2602 = codec->private_data;
341 struct i2c_client *i2c = codec->control_data;
333 struct snd_pcm_runtime *master_runtime; 342 struct snd_pcm_runtime *master_runtime;
334 343
335 /* The DAI has shared clocks so if we already have a playback or 344 /* The DAI has shared clocks so if we already have a playback or
336 * capture going then constrain this substream to match it. 345 * capture going then constrain this substream to match it.
346 * TODO: the ssm2602 allows pairs of non-matching PB/REC rates
337 */ 347 */
338 if (ssm2602->master_substream) { 348 if (ssm2602->master_substream) {
339 master_runtime = ssm2602->master_substream->runtime; 349 master_runtime = ssm2602->master_substream->runtime;
350 dev_dbg(&i2c->dev, "Constraining to %d bits at %dHz\n",
351 master_runtime->sample_bits,
352 master_runtime->rate);
353
340 snd_pcm_hw_constraint_minmax(substream->runtime, 354 snd_pcm_hw_constraint_minmax(substream->runtime,
341 SNDRV_PCM_HW_PARAM_RATE, 355 SNDRV_PCM_HW_PARAM_RATE,
342 master_runtime->rate, 356 master_runtime->rate,
@@ -354,7 +368,8 @@ static int ssm2602_startup(struct snd_pcm_substream *substream)
354 return 0; 368 return 0;
355} 369}
356 370
357static int ssm2602_pcm_prepare(struct snd_pcm_substream *substream) 371static int ssm2602_pcm_prepare(struct snd_pcm_substream *substream,
372 struct snd_soc_dai *dai)
358{ 373{
359 struct snd_soc_pcm_runtime *rtd = substream->private_data; 374 struct snd_soc_pcm_runtime *rtd = substream->private_data;
360 struct snd_soc_device *socdev = rtd->socdev; 375 struct snd_soc_device *socdev = rtd->socdev;
@@ -365,14 +380,21 @@ static int ssm2602_pcm_prepare(struct snd_pcm_substream *substream)
365 return 0; 380 return 0;
366} 381}
367 382
368static void ssm2602_shutdown(struct snd_pcm_substream *substream) 383static void ssm2602_shutdown(struct snd_pcm_substream *substream,
384 struct snd_soc_dai *dai)
369{ 385{
370 struct snd_soc_pcm_runtime *rtd = substream->private_data; 386 struct snd_soc_pcm_runtime *rtd = substream->private_data;
371 struct snd_soc_device *socdev = rtd->socdev; 387 struct snd_soc_device *socdev = rtd->socdev;
372 struct snd_soc_codec *codec = socdev->codec; 388 struct snd_soc_codec *codec = socdev->codec;
389 struct ssm2602_priv *ssm2602 = codec->private_data;
373 /* deactivate */ 390 /* deactivate */
374 if (!codec->active) 391 if (!codec->active)
375 ssm2602_write(codec, SSM2602_ACTIVE, 0); 392 ssm2602_write(codec, SSM2602_ACTIVE, 0);
393
394 if (ssm2602->master_substream == substream)
395 ssm2602->master_substream = ssm2602->slave_substream;
396
397 ssm2602->slave_substream = NULL;
376} 398}
377 399
378static int ssm2602_mute(struct snd_soc_dai *dai, int mute) 400static int ssm2602_mute(struct snd_soc_dai *dai, int mute)
@@ -432,10 +454,10 @@ static int ssm2602_set_dai_fmt(struct snd_soc_dai *codec_dai,
432 iface |= 0x0001; 454 iface |= 0x0001;
433 break; 455 break;
434 case SND_SOC_DAIFMT_DSP_A: 456 case SND_SOC_DAIFMT_DSP_A:
435 iface |= 0x0003; 457 iface |= 0x0013;
436 break; 458 break;
437 case SND_SOC_DAIFMT_DSP_B: 459 case SND_SOC_DAIFMT_DSP_B:
438 iface |= 0x0013; 460 iface |= 0x0003;
439 break; 461 break;
440 default: 462 default:
441 return -EINVAL; 463 return -EINVAL;
@@ -496,6 +518,9 @@ static int ssm2602_set_bias_level(struct snd_soc_codec *codec,
496 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\ 518 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
497 SNDRV_PCM_RATE_96000) 519 SNDRV_PCM_RATE_96000)
498 520
521#define SSM2602_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
522 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
523
499struct snd_soc_dai ssm2602_dai = { 524struct snd_soc_dai ssm2602_dai = {
500 .name = "SSM2602", 525 .name = "SSM2602",
501 .playback = { 526 .playback = {
@@ -503,20 +528,18 @@ struct snd_soc_dai ssm2602_dai = {
503 .channels_min = 2, 528 .channels_min = 2,
504 .channels_max = 2, 529 .channels_max = 2,
505 .rates = SSM2602_RATES, 530 .rates = SSM2602_RATES,
506 .formats = SNDRV_PCM_FMTBIT_S32_LE,}, 531 .formats = SSM2602_FORMATS,},
507 .capture = { 532 .capture = {
508 .stream_name = "Capture", 533 .stream_name = "Capture",
509 .channels_min = 2, 534 .channels_min = 2,
510 .channels_max = 2, 535 .channels_max = 2,
511 .rates = SSM2602_RATES, 536 .rates = SSM2602_RATES,
512 .formats = SNDRV_PCM_FMTBIT_S32_LE,}, 537 .formats = SSM2602_FORMATS,},
513 .ops = { 538 .ops = {
514 .startup = ssm2602_startup, 539 .startup = ssm2602_startup,
515 .prepare = ssm2602_pcm_prepare, 540 .prepare = ssm2602_pcm_prepare,
516 .hw_params = ssm2602_hw_params, 541 .hw_params = ssm2602_hw_params,
517 .shutdown = ssm2602_shutdown, 542 .shutdown = ssm2602_shutdown,
518 },
519 .dai_ops = {
520 .digital_mute = ssm2602_mute, 543 .digital_mute = ssm2602_mute,
521 .set_sysclk = ssm2602_set_dai_sysclk, 544 .set_sysclk = ssm2602_set_dai_sysclk,
522 .set_fmt = ssm2602_set_dai_fmt, 545 .set_fmt = ssm2602_set_dai_fmt,
@@ -601,7 +624,7 @@ static int ssm2602_init(struct snd_soc_device *socdev)
601 624
602 ssm2602_add_controls(codec); 625 ssm2602_add_controls(codec);
603 ssm2602_add_widgets(codec); 626 ssm2602_add_widgets(codec);
604 ret = snd_soc_register_card(socdev); 627 ret = snd_soc_init_card(socdev);
605 if (ret < 0) { 628 if (ret < 0) {
606 pr_err("ssm2602: failed to register card\n"); 629 pr_err("ssm2602: failed to register card\n");
607 goto card_err; 630 goto card_err;
@@ -770,6 +793,18 @@ struct snd_soc_codec_device soc_codec_dev_ssm2602 = {
770}; 793};
771EXPORT_SYMBOL_GPL(soc_codec_dev_ssm2602); 794EXPORT_SYMBOL_GPL(soc_codec_dev_ssm2602);
772 795
796static int __init ssm2602_modinit(void)
797{
798 return snd_soc_register_dai(&ssm2602_dai);
799}
800module_init(ssm2602_modinit);
801
802static void __exit ssm2602_exit(void)
803{
804 snd_soc_unregister_dai(&ssm2602_dai);
805}
806module_exit(ssm2602_exit);
807
773MODULE_DESCRIPTION("ASoC ssm2602 driver"); 808MODULE_DESCRIPTION("ASoC ssm2602 driver");
774MODULE_AUTHOR("Cliff Cai"); 809MODULE_AUTHOR("Cliff Cai");
775MODULE_LICENSE("GPL"); 810MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index 44308dac9e18..cfdea007c4cb 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -37,12 +37,6 @@
37 37
38#define AIC23_VERSION "0.1" 38#define AIC23_VERSION "0.1"
39 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/* 40/*
47 * AIC23 register cache 41 * AIC23 register cache
48 */ 42 */
@@ -261,20 +255,156 @@ static const struct snd_soc_dapm_route intercon[] = {
261 255
262}; 256};
263 257
264/* tlv320aic23 related */ 258/* AIC23 driver data */
265static const struct tlv320aic23_srate_reg_info srate_reg_info[] = { 259struct aic23 {
266 {4000, 0x06, 1}, /* 4000 */ 260 struct snd_soc_codec codec;
267 {8000, 0x06, 0}, /* 8000 */ 261 int mclk;
268 {16000, 0x0C, 1}, /* 16000 */ 262 int requested_adc;
269 {22050, 0x11, 1}, /* 22050 */ 263 int requested_dac;
270 {24000, 0x00, 1}, /* 24000 */ 264};
271 {32000, 0x0C, 0}, /* 32000 */ 265
272 {44100, 0x11, 0}, /* 44100 */ 266/*
273 {48000, 0x00, 0}, /* 48000 */ 267 * Common Crystals used
274 {88200, 0x1F, 0}, /* 88200 */ 268 * 11.2896 Mhz /128 = *88.2k /192 = 58.8k
275 {96000, 0x0E, 0}, /* 96000 */ 269 * 12.0000 Mhz /125 = *96k /136 = 88.235K
270 * 12.2880 Mhz /128 = *96k /192 = 64k
271 * 16.9344 Mhz /128 = 132.3k /192 = *88.2k
272 * 18.4320 Mhz /128 = 144k /192 = *96k
273 */
274
275/*
276 * Normal BOSR 0-256/2 = 128, 1-384/2 = 192
277 * USB BOSR 0-250/2 = 125, 1-272/2 = 136
278 */
279static const int bosr_usb_divisor_table[] = {
280 128, 125, 192, 136
281};
282#define LOWER_GROUP ((1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<6) | (1<<7))
283#define UPPER_GROUP ((1<<8) | (1<<9) | (1<<10) | (1<<11) | (1<<15))
284static const unsigned short sr_valid_mask[] = {
285 LOWER_GROUP|UPPER_GROUP, /* Normal, bosr - 0*/
286 LOWER_GROUP|UPPER_GROUP, /* Normal, bosr - 1*/
287 LOWER_GROUP, /* Usb, bosr - 0*/
288 UPPER_GROUP, /* Usb, bosr - 1*/
289};
290/*
291 * Every divisor is a factor of 11*12
292 */
293#define SR_MULT (11*12)
294#define A(x) (x) ? (SR_MULT/x) : 0
295static const unsigned char sr_adc_mult_table[] = {
296 A(2), A(2), A(12), A(12), A(0), A(0), A(3), A(1),
297 A(2), A(2), A(11), A(11), A(0), A(0), A(0), A(1)
298};
299static const unsigned char sr_dac_mult_table[] = {
300 A(2), A(12), A(2), A(12), A(0), A(0), A(3), A(1),
301 A(2), A(11), A(2), A(11), A(0), A(0), A(0), A(1)
276}; 302};
277 303
304static unsigned get_score(int adc, int adc_l, int adc_h, int need_adc,
305 int dac, int dac_l, int dac_h, int need_dac)
306{
307 if ((adc >= adc_l) && (adc <= adc_h) &&
308 (dac >= dac_l) && (dac <= dac_h)) {
309 int diff_adc = need_adc - adc;
310 int diff_dac = need_dac - dac;
311 return abs(diff_adc) + abs(diff_dac);
312 }
313 return UINT_MAX;
314}
315
316static int find_rate(int mclk, u32 need_adc, u32 need_dac)
317{
318 int i, j;
319 int best_i = -1;
320 int best_j = -1;
321 int best_div = 0;
322 unsigned best_score = UINT_MAX;
323 int adc_l, adc_h, dac_l, dac_h;
324
325 need_adc *= SR_MULT;
326 need_dac *= SR_MULT;
327 /*
328 * rates given are +/- 1/32
329 */
330 adc_l = need_adc - (need_adc >> 5);
331 adc_h = need_adc + (need_adc >> 5);
332 dac_l = need_dac - (need_dac >> 5);
333 dac_h = need_dac + (need_dac >> 5);
334 for (i = 0; i < ARRAY_SIZE(bosr_usb_divisor_table); i++) {
335 int base = mclk / bosr_usb_divisor_table[i];
336 int mask = sr_valid_mask[i];
337 for (j = 0; j < ARRAY_SIZE(sr_adc_mult_table);
338 j++, mask >>= 1) {
339 int adc;
340 int dac;
341 int score;
342 if ((mask & 1) == 0)
343 continue;
344 adc = base * sr_adc_mult_table[j];
345 dac = base * sr_dac_mult_table[j];
346 score = get_score(adc, adc_l, adc_h, need_adc,
347 dac, dac_l, dac_h, need_dac);
348 if (best_score > score) {
349 best_score = score;
350 best_i = i;
351 best_j = j;
352 best_div = 0;
353 }
354 score = get_score((adc >> 1), adc_l, adc_h, need_adc,
355 (dac >> 1), dac_l, dac_h, need_dac);
356 /* prefer to have a /2 */
357 if ((score != UINT_MAX) && (best_score >= score)) {
358 best_score = score;
359 best_i = i;
360 best_j = j;
361 best_div = 1;
362 }
363 }
364 }
365 return (best_j << 2) | best_i | (best_div << TLV320AIC23_CLKIN_SHIFT);
366}
367
368#ifdef DEBUG
369static void get_current_sample_rates(struct snd_soc_codec *codec, int mclk,
370 u32 *sample_rate_adc, u32 *sample_rate_dac)
371{
372 int src = tlv320aic23_read_reg_cache(codec, TLV320AIC23_SRATE);
373 int sr = (src >> 2) & 0x0f;
374 int val = (mclk / bosr_usb_divisor_table[src & 3]);
375 int adc = (val * sr_adc_mult_table[sr]) / SR_MULT;
376 int dac = (val * sr_dac_mult_table[sr]) / SR_MULT;
377 if (src & TLV320AIC23_CLKIN_HALF) {
378 adc >>= 1;
379 dac >>= 1;
380 }
381 *sample_rate_adc = adc;
382 *sample_rate_dac = dac;
383}
384#endif
385
386static int set_sample_rate_control(struct snd_soc_codec *codec, int mclk,
387 u32 sample_rate_adc, u32 sample_rate_dac)
388{
389 /* Search for the right sample rate */
390 int data = find_rate(mclk, sample_rate_adc, sample_rate_dac);
391 if (data < 0) {
392 printk(KERN_ERR "%s:Invalid rate %u,%u requested\n",
393 __func__, sample_rate_adc, sample_rate_dac);
394 return -EINVAL;
395 }
396 tlv320aic23_write(codec, TLV320AIC23_SRATE, data);
397#ifdef DEBUG
398 {
399 u32 adc, dac;
400 get_current_sample_rates(codec, mclk, &adc, &dac);
401 printk(KERN_DEBUG "actual samplerate = %u,%u reg=%x\n",
402 adc, dac, data);
403 }
404#endif
405 return 0;
406}
407
278static int tlv320aic23_add_widgets(struct snd_soc_codec *codec) 408static int tlv320aic23_add_widgets(struct snd_soc_codec *codec)
279{ 409{
280 snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets, 410 snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets,
@@ -288,32 +418,36 @@ static int tlv320aic23_add_widgets(struct snd_soc_codec *codec)
288} 418}
289 419
290static int tlv320aic23_hw_params(struct snd_pcm_substream *substream, 420static int tlv320aic23_hw_params(struct snd_pcm_substream *substream,
291 struct snd_pcm_hw_params *params) 421 struct snd_pcm_hw_params *params,
422 struct snd_soc_dai *dai)
292{ 423{
293 struct snd_soc_pcm_runtime *rtd = substream->private_data; 424 struct snd_soc_pcm_runtime *rtd = substream->private_data;
294 struct snd_soc_device *socdev = rtd->socdev; 425 struct snd_soc_device *socdev = rtd->socdev;
295 struct snd_soc_codec *codec = socdev->codec; 426 struct snd_soc_codec *codec = socdev->codec;
296 u16 iface_reg, data; 427 u16 iface_reg;
297 u8 count = 0; 428 int ret;
429 struct aic23 *aic23 = container_of(codec, struct aic23, codec);
430 u32 sample_rate_adc = aic23->requested_adc;
431 u32 sample_rate_dac = aic23->requested_dac;
432 u32 sample_rate = params_rate(params);
433
434 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
435 aic23->requested_dac = sample_rate_dac = sample_rate;
436 if (!sample_rate_adc)
437 sample_rate_adc = sample_rate;
438 } else {
439 aic23->requested_adc = sample_rate_adc = sample_rate;
440 if (!sample_rate_dac)
441 sample_rate_dac = sample_rate;
442 }
443 ret = set_sample_rate_control(codec, aic23->mclk, sample_rate_adc,
444 sample_rate_dac);
445 if (ret < 0)
446 return ret;
298 447
299 iface_reg = 448 iface_reg =
300 tlv320aic23_read_reg_cache(codec, 449 tlv320aic23_read_reg_cache(codec,
301 TLV320AIC23_DIGT_FMT) & ~(0x03 << 2); 450 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)) { 451 switch (params_format(params)) {
318 case SNDRV_PCM_FORMAT_S16_LE: 452 case SNDRV_PCM_FORMAT_S16_LE:
319 break; 453 break;
@@ -332,7 +466,8 @@ static int tlv320aic23_hw_params(struct snd_pcm_substream *substream,
332 return 0; 466 return 0;
333} 467}
334 468
335static int tlv320aic23_pcm_prepare(struct snd_pcm_substream *substream) 469static int tlv320aic23_pcm_prepare(struct snd_pcm_substream *substream,
470 struct snd_soc_dai *dai)
336{ 471{
337 struct snd_soc_pcm_runtime *rtd = substream->private_data; 472 struct snd_soc_pcm_runtime *rtd = substream->private_data;
338 struct snd_soc_device *socdev = rtd->socdev; 473 struct snd_soc_device *socdev = rtd->socdev;
@@ -344,17 +479,23 @@ static int tlv320aic23_pcm_prepare(struct snd_pcm_substream *substream)
344 return 0; 479 return 0;
345} 480}
346 481
347static void tlv320aic23_shutdown(struct snd_pcm_substream *substream) 482static void tlv320aic23_shutdown(struct snd_pcm_substream *substream,
483 struct snd_soc_dai *dai)
348{ 484{
349 struct snd_soc_pcm_runtime *rtd = substream->private_data; 485 struct snd_soc_pcm_runtime *rtd = substream->private_data;
350 struct snd_soc_device *socdev = rtd->socdev; 486 struct snd_soc_device *socdev = rtd->socdev;
351 struct snd_soc_codec *codec = socdev->codec; 487 struct snd_soc_codec *codec = socdev->codec;
488 struct aic23 *aic23 = container_of(codec, struct aic23, codec);
352 489
353 /* deactivate */ 490 /* deactivate */
354 if (!codec->active) { 491 if (!codec->active) {
355 udelay(50); 492 udelay(50);
356 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0); 493 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0);
357 } 494 }
495 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
496 aic23->requested_dac = 0;
497 else
498 aic23->requested_adc = 0;
358} 499}
359 500
360static int tlv320aic23_mute(struct snd_soc_dai *dai, int mute) 501static int tlv320aic23_mute(struct snd_soc_dai *dai, int mute)
@@ -400,7 +541,7 @@ static int tlv320aic23_set_dai_fmt(struct snd_soc_dai *codec_dai,
400 case SND_SOC_DAIFMT_I2S: 541 case SND_SOC_DAIFMT_I2S:
401 iface_reg |= TLV320AIC23_FOR_I2S; 542 iface_reg |= TLV320AIC23_FOR_I2S;
402 break; 543 break;
403 case SND_SOC_DAIFMT_DSP_A: 544 case SND_SOC_DAIFMT_DSP_B:
404 iface_reg |= TLV320AIC23_FOR_DSP; 545 iface_reg |= TLV320AIC23_FOR_DSP;
405 break; 546 break;
406 case SND_SOC_DAIFMT_RIGHT_J: 547 case SND_SOC_DAIFMT_RIGHT_J:
@@ -422,12 +563,9 @@ static int tlv320aic23_set_dai_sysclk(struct snd_soc_dai *codec_dai,
422 int clk_id, unsigned int freq, int dir) 563 int clk_id, unsigned int freq, int dir)
423{ 564{
424 struct snd_soc_codec *codec = codec_dai->codec; 565 struct snd_soc_codec *codec = codec_dai->codec;
425 566 struct aic23 *aic23 = container_of(codec, struct aic23, codec);
426 switch (freq) { 567 aic23->mclk = freq;
427 case 12000000: 568 return 0;
428 return 0;
429 }
430 return -EINVAL;
431} 569}
432 570
433static int tlv320aic23_set_bias_level(struct snd_soc_codec *codec, 571static int tlv320aic23_set_bias_level(struct snd_soc_codec *codec,
@@ -478,12 +616,10 @@ struct snd_soc_dai tlv320aic23_dai = {
478 .prepare = tlv320aic23_pcm_prepare, 616 .prepare = tlv320aic23_pcm_prepare,
479 .hw_params = tlv320aic23_hw_params, 617 .hw_params = tlv320aic23_hw_params,
480 .shutdown = tlv320aic23_shutdown, 618 .shutdown = tlv320aic23_shutdown,
481 }, 619 .digital_mute = tlv320aic23_mute,
482 .dai_ops = { 620 .set_fmt = tlv320aic23_set_dai_fmt,
483 .digital_mute = tlv320aic23_mute, 621 .set_sysclk = tlv320aic23_set_dai_sysclk,
484 .set_fmt = tlv320aic23_set_dai_fmt, 622 }
485 .set_sysclk = tlv320aic23_set_dai_sysclk,
486 }
487}; 623};
488EXPORT_SYMBOL_GPL(tlv320aic23_dai); 624EXPORT_SYMBOL_GPL(tlv320aic23_dai);
489 625
@@ -584,7 +720,7 @@ static int tlv320aic23_init(struct snd_soc_device *socdev)
584 720
585 tlv320aic23_add_controls(codec); 721 tlv320aic23_add_controls(codec);
586 tlv320aic23_add_widgets(codec); 722 tlv320aic23_add_widgets(codec);
587 ret = snd_soc_register_card(socdev); 723 ret = snd_soc_init_card(socdev);
588 if (ret < 0) { 724 if (ret < 0) {
589 printk(KERN_ERR "tlv320aic23: failed to register card\n"); 725 printk(KERN_ERR "tlv320aic23: failed to register card\n");
590 goto card_err; 726 goto card_err;
@@ -659,14 +795,15 @@ static int tlv320aic23_probe(struct platform_device *pdev)
659{ 795{
660 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 796 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
661 struct snd_soc_codec *codec; 797 struct snd_soc_codec *codec;
798 struct aic23 *aic23;
662 int ret = 0; 799 int ret = 0;
663 800
664 printk(KERN_INFO "AIC23 Audio Codec %s\n", AIC23_VERSION); 801 printk(KERN_INFO "AIC23 Audio Codec %s\n", AIC23_VERSION);
665 802
666 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 803 aic23 = kzalloc(sizeof(struct aic23), GFP_KERNEL);
667 if (codec == NULL) 804 if (aic23 == NULL)
668 return -ENOMEM; 805 return -ENOMEM;
669 806 codec = &aic23->codec;
670 socdev->codec = codec; 807 socdev->codec = codec;
671 mutex_init(&codec->mutex); 808 mutex_init(&codec->mutex);
672 INIT_LIST_HEAD(&codec->dapm_widgets); 809 INIT_LIST_HEAD(&codec->dapm_widgets);
@@ -687,6 +824,7 @@ static int tlv320aic23_remove(struct platform_device *pdev)
687{ 824{
688 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 825 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
689 struct snd_soc_codec *codec = socdev->codec; 826 struct snd_soc_codec *codec = socdev->codec;
827 struct aic23 *aic23 = container_of(codec, struct aic23, codec);
690 828
691 if (codec->control_data) 829 if (codec->control_data)
692 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_OFF); 830 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_OFF);
@@ -697,7 +835,7 @@ static int tlv320aic23_remove(struct platform_device *pdev)
697 i2c_del_driver(&tlv320aic23_i2c_driver); 835 i2c_del_driver(&tlv320aic23_i2c_driver);
698#endif 836#endif
699 kfree(codec->reg_cache); 837 kfree(codec->reg_cache);
700 kfree(codec); 838 kfree(aic23);
701 839
702 return 0; 840 return 0;
703} 841}
@@ -709,6 +847,18 @@ struct snd_soc_codec_device soc_codec_dev_tlv320aic23 = {
709}; 847};
710EXPORT_SYMBOL_GPL(soc_codec_dev_tlv320aic23); 848EXPORT_SYMBOL_GPL(soc_codec_dev_tlv320aic23);
711 849
850static int __init tlv320aic23_modinit(void)
851{
852 return snd_soc_register_dai(&tlv320aic23_dai);
853}
854module_init(tlv320aic23_modinit);
855
856static void __exit tlv320aic23_exit(void)
857{
858 snd_soc_unregister_dai(&tlv320aic23_dai);
859}
860module_exit(tlv320aic23_exit);
861
712MODULE_DESCRIPTION("ASoC TLV320AIC23 codec driver"); 862MODULE_DESCRIPTION("ASoC TLV320AIC23 codec driver");
713MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>"); 863MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>");
714MODULE_LICENSE("GPL"); 864MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c
index bed8a9e63ddc..29f2f1a017fd 100644
--- a/sound/soc/codecs/tlv320aic26.c
+++ b/sound/soc/codecs/tlv320aic26.c
@@ -125,7 +125,8 @@ static int aic26_reg_write(struct snd_soc_codec *codec, unsigned int reg,
125 * Digital Audio Interface Operations 125 * Digital Audio Interface Operations
126 */ 126 */
127static int aic26_hw_params(struct snd_pcm_substream *substream, 127static int aic26_hw_params(struct snd_pcm_substream *substream,
128 struct snd_pcm_hw_params *params) 128 struct snd_pcm_hw_params *params,
129 struct snd_soc_dai *dai)
129{ 130{
130 struct snd_soc_pcm_runtime *rtd = substream->private_data; 131 struct snd_soc_pcm_runtime *rtd = substream->private_data;
131 struct snd_soc_device *socdev = rtd->socdev; 132 struct snd_soc_device *socdev = rtd->socdev;
@@ -287,8 +288,6 @@ struct snd_soc_dai aic26_dai = {
287 }, 288 },
288 .ops = { 289 .ops = {
289 .hw_params = aic26_hw_params, 290 .hw_params = aic26_hw_params,
290 },
291 .dai_ops = {
292 .digital_mute = aic26_mute, 291 .digital_mute = aic26_mute,
293 .set_sysclk = aic26_set_sysclk, 292 .set_sysclk = aic26_set_sysclk,
294 .set_fmt = aic26_set_fmt, 293 .set_fmt = aic26_set_fmt,
@@ -360,7 +359,7 @@ static int aic26_probe(struct platform_device *pdev)
360 359
361 /* CODEC is setup, we can register the card now */ 360 /* CODEC is setup, we can register the card now */
362 dev_dbg(&pdev->dev, "Registering card\n"); 361 dev_dbg(&pdev->dev, "Registering card\n");
363 ret = snd_soc_register_card(socdev); 362 ret = snd_soc_init_card(socdev);
364 if (ret < 0) { 363 if (ret < 0) {
365 dev_err(&pdev->dev, "aic26: failed to register card\n"); 364 dev_err(&pdev->dev, "aic26: failed to register card\n");
366 goto card_err; 365 goto card_err;
@@ -427,7 +426,7 @@ static DEVICE_ATTR(keyclick, 0644, aic26_keyclick_show, aic26_keyclick_set);
427static int aic26_spi_probe(struct spi_device *spi) 426static int aic26_spi_probe(struct spi_device *spi)
428{ 427{
429 struct aic26 *aic26; 428 struct aic26 *aic26;
430 int rc, i, reg; 429 int ret, i, reg;
431 430
432 dev_dbg(&spi->dev, "probing tlv320aic26 spi device\n"); 431 dev_dbg(&spi->dev, "probing tlv320aic26 spi device\n");
433 432
@@ -457,6 +456,14 @@ static int aic26_spi_probe(struct spi_device *spi)
457 aic26->codec.reg_cache_size = AIC26_NUM_REGS; 456 aic26->codec.reg_cache_size = AIC26_NUM_REGS;
458 aic26->codec.reg_cache = aic26->reg_cache; 457 aic26->codec.reg_cache = aic26->reg_cache;
459 458
459 aic26_dai.dev = &spi->dev;
460 ret = snd_soc_register_dai(&aic26_dai);
461 if (ret != 0) {
462 dev_err(&spi->dev, "Failed to register DAI: %d\n", ret);
463 kfree(aic26);
464 return ret;
465 }
466
460 /* Reset the codec to power on defaults */ 467 /* Reset the codec to power on defaults */
461 aic26_reg_write(&aic26->codec, AIC26_REG_RESET, 0xBB00); 468 aic26_reg_write(&aic26->codec, AIC26_REG_RESET, 0xBB00);
462 469
@@ -475,8 +482,8 @@ static int aic26_spi_probe(struct spi_device *spi)
475 482
476 /* Register the sysfs files for debugging */ 483 /* Register the sysfs files for debugging */
477 /* Create SysFS files */ 484 /* Create SysFS files */
478 rc = device_create_file(&spi->dev, &dev_attr_keyclick); 485 ret = device_create_file(&spi->dev, &dev_attr_keyclick);
479 if (rc) 486 if (ret)
480 dev_info(&spi->dev, "error creating sysfs files\n"); 487 dev_info(&spi->dev, "error creating sysfs files\n");
481 488
482#if defined(CONFIG_SND_SOC_OF_SIMPLE) 489#if defined(CONFIG_SND_SOC_OF_SIMPLE)
@@ -493,6 +500,7 @@ static int aic26_spi_remove(struct spi_device *spi)
493{ 500{
494 struct aic26 *aic26 = dev_get_drvdata(&spi->dev); 501 struct aic26 *aic26 = dev_get_drvdata(&spi->dev);
495 502
503 snd_soc_unregister_dai(&aic26_dai);
496 kfree(aic26); 504 kfree(aic26);
497 505
498 return 0; 506 return 0;
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index cff276ee261e..b47a749c5ea2 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -253,11 +253,17 @@ static const struct snd_kcontrol_new aic3x_snd_controls[] = {
253 253
254 SOC_DOUBLE_R("Line DAC Playback Volume", DACL1_2_LLOPM_VOL, 254 SOC_DOUBLE_R("Line DAC Playback Volume", DACL1_2_LLOPM_VOL,
255 DACR1_2_RLOPM_VOL, 0, 0x7f, 1), 255 DACR1_2_RLOPM_VOL, 0, 0x7f, 1),
256 SOC_DOUBLE_R("Line DAC Playback Switch", LLOPM_CTRL, RLOPM_CTRL, 3, 256 SOC_SINGLE("LineL Playback Switch", LLOPM_CTRL, 3, 0x01, 0),
257 0x01, 0), 257 SOC_SINGLE("LineR Playback Switch", RLOPM_CTRL, 3, 0x01, 0),
258 SOC_DOUBLE_R("Line PGA Bypass Playback Volume", PGAL_2_LLOPM_VOL, 258 SOC_DOUBLE_R("LineL DAC Playback Volume", DACL1_2_LLOPM_VOL,
259 PGAR_2_RLOPM_VOL, 0, 0x7f, 1), 259 DACR1_2_LLOPM_VOL, 0, 0x7f, 1),
260 SOC_DOUBLE_R("Line Line2 Bypass Playback Volume", LINE2L_2_LLOPM_VOL, 260 SOC_SINGLE("LineL Left PGA Bypass Playback Volume", PGAL_2_LLOPM_VOL,
261 0, 0x7f, 1),
262 SOC_SINGLE("LineR Right PGA Bypass Playback Volume", PGAR_2_RLOPM_VOL,
263 0, 0x7f, 1),
264 SOC_DOUBLE_R("LineL Line2 Bypass Playback Volume", LINE2L_2_LLOPM_VOL,
265 LINE2R_2_LLOPM_VOL, 0, 0x7f, 1),
266 SOC_DOUBLE_R("LineR Line2 Bypass Playback Volume", LINE2L_2_RLOPM_VOL,
261 LINE2R_2_RLOPM_VOL, 0, 0x7f, 1), 267 LINE2R_2_RLOPM_VOL, 0, 0x7f, 1),
262 268
263 SOC_DOUBLE_R("Mono DAC Playback Volume", DACL1_2_MONOLOPM_VOL, 269 SOC_DOUBLE_R("Mono DAC Playback Volume", DACL1_2_MONOLOPM_VOL,
@@ -272,8 +278,12 @@ static const struct snd_kcontrol_new aic3x_snd_controls[] = {
272 DACR1_2_HPROUT_VOL, 0, 0x7f, 1), 278 DACR1_2_HPROUT_VOL, 0, 0x7f, 1),
273 SOC_DOUBLE_R("HP DAC Playback Switch", HPLOUT_CTRL, HPROUT_CTRL, 3, 279 SOC_DOUBLE_R("HP DAC Playback Switch", HPLOUT_CTRL, HPROUT_CTRL, 3,
274 0x01, 0), 280 0x01, 0),
275 SOC_DOUBLE_R("HP PGA Bypass Playback Volume", PGAL_2_HPLOUT_VOL, 281 SOC_DOUBLE_R("HP Right PGA Bypass Playback Volume", PGAR_2_HPLOUT_VOL,
276 PGAR_2_HPROUT_VOL, 0, 0x7f, 1), 282 PGAR_2_HPROUT_VOL, 0, 0x7f, 1),
283 SOC_SINGLE("HPL PGA Bypass Playback Volume", PGAL_2_HPLOUT_VOL,
284 0, 0x7f, 1),
285 SOC_SINGLE("HPR PGA Bypass Playback Volume", PGAL_2_HPROUT_VOL,
286 0, 0x7f, 1),
277 SOC_DOUBLE_R("HP Line2 Bypass Playback Volume", LINE2L_2_HPLOUT_VOL, 287 SOC_DOUBLE_R("HP Line2 Bypass Playback Volume", LINE2L_2_HPLOUT_VOL,
278 LINE2R_2_HPROUT_VOL, 0, 0x7f, 1), 288 LINE2R_2_HPROUT_VOL, 0, 0x7f, 1),
279 289
@@ -281,8 +291,10 @@ static const struct snd_kcontrol_new aic3x_snd_controls[] = {
281 DACR1_2_HPRCOM_VOL, 0, 0x7f, 1), 291 DACR1_2_HPRCOM_VOL, 0, 0x7f, 1),
282 SOC_DOUBLE_R("HPCOM DAC Playback Switch", HPLCOM_CTRL, HPRCOM_CTRL, 3, 292 SOC_DOUBLE_R("HPCOM DAC Playback Switch", HPLCOM_CTRL, HPRCOM_CTRL, 3,
283 0x01, 0), 293 0x01, 0),
284 SOC_DOUBLE_R("HPCOM PGA Bypass Playback Volume", PGAL_2_HPLCOM_VOL, 294 SOC_SINGLE("HPLCOM PGA Bypass Playback Volume", PGAL_2_HPLCOM_VOL,
285 PGAR_2_HPRCOM_VOL, 0, 0x7f, 1), 295 0, 0x7f, 1),
296 SOC_SINGLE("HPRCOM PGA Bypass Playback Volume", PGAL_2_HPRCOM_VOL,
297 0, 0x7f, 1),
286 SOC_DOUBLE_R("HPCOM Line2 Bypass Playback Volume", LINE2L_2_HPLCOM_VOL, 298 SOC_DOUBLE_R("HPCOM Line2 Bypass Playback Volume", LINE2L_2_HPLCOM_VOL,
287 LINE2R_2_HPRCOM_VOL, 0, 0x7f, 1), 299 LINE2R_2_HPRCOM_VOL, 0, 0x7f, 1),
288 300
@@ -333,7 +345,8 @@ SOC_DAPM_ENUM("Route", aic3x_enum[RHPCOM_ENUM]);
333 345
334/* Left DAC_L1 Mixer */ 346/* Left DAC_L1 Mixer */
335static const struct snd_kcontrol_new aic3x_left_dac_mixer_controls[] = { 347static const struct snd_kcontrol_new aic3x_left_dac_mixer_controls[] = {
336 SOC_DAPM_SINGLE("Line Switch", DACL1_2_LLOPM_VOL, 7, 1, 0), 348 SOC_DAPM_SINGLE("LineL Switch", DACL1_2_LLOPM_VOL, 7, 1, 0),
349 SOC_DAPM_SINGLE("LineR Switch", DACL1_2_RLOPM_VOL, 7, 1, 0),
337 SOC_DAPM_SINGLE("Mono Switch", DACL1_2_MONOLOPM_VOL, 7, 1, 0), 350 SOC_DAPM_SINGLE("Mono Switch", DACL1_2_MONOLOPM_VOL, 7, 1, 0),
338 SOC_DAPM_SINGLE("HP Switch", DACL1_2_HPLOUT_VOL, 7, 1, 0), 351 SOC_DAPM_SINGLE("HP Switch", DACL1_2_HPLOUT_VOL, 7, 1, 0),
339 SOC_DAPM_SINGLE("HPCOM Switch", DACL1_2_HPLCOM_VOL, 7, 1, 0), 352 SOC_DAPM_SINGLE("HPCOM Switch", DACL1_2_HPLCOM_VOL, 7, 1, 0),
@@ -341,7 +354,8 @@ static const struct snd_kcontrol_new aic3x_left_dac_mixer_controls[] = {
341 354
342/* Right DAC_R1 Mixer */ 355/* Right DAC_R1 Mixer */
343static const struct snd_kcontrol_new aic3x_right_dac_mixer_controls[] = { 356static const struct snd_kcontrol_new aic3x_right_dac_mixer_controls[] = {
344 SOC_DAPM_SINGLE("Line Switch", DACR1_2_RLOPM_VOL, 7, 1, 0), 357 SOC_DAPM_SINGLE("LineL Switch", DACR1_2_LLOPM_VOL, 7, 1, 0),
358 SOC_DAPM_SINGLE("LineR Switch", DACR1_2_RLOPM_VOL, 7, 1, 0),
345 SOC_DAPM_SINGLE("Mono Switch", DACR1_2_MONOLOPM_VOL, 7, 1, 0), 359 SOC_DAPM_SINGLE("Mono Switch", DACR1_2_MONOLOPM_VOL, 7, 1, 0),
346 SOC_DAPM_SINGLE("HP Switch", DACR1_2_HPROUT_VOL, 7, 1, 0), 360 SOC_DAPM_SINGLE("HP Switch", DACR1_2_HPROUT_VOL, 7, 1, 0),
347 SOC_DAPM_SINGLE("HPCOM Switch", DACR1_2_HPRCOM_VOL, 7, 1, 0), 361 SOC_DAPM_SINGLE("HPCOM Switch", DACR1_2_HPRCOM_VOL, 7, 1, 0),
@@ -350,14 +364,18 @@ static const struct snd_kcontrol_new aic3x_right_dac_mixer_controls[] = {
350/* Left PGA Mixer */ 364/* Left PGA Mixer */
351static const struct snd_kcontrol_new aic3x_left_pga_mixer_controls[] = { 365static const struct snd_kcontrol_new aic3x_left_pga_mixer_controls[] = {
352 SOC_DAPM_SINGLE_AIC3X("Line1L Switch", LINE1L_2_LADC_CTRL, 3, 1, 1), 366 SOC_DAPM_SINGLE_AIC3X("Line1L Switch", LINE1L_2_LADC_CTRL, 3, 1, 1),
367 SOC_DAPM_SINGLE_AIC3X("Line1R Switch", LINE1R_2_LADC_CTRL, 3, 1, 1),
353 SOC_DAPM_SINGLE_AIC3X("Line2L Switch", LINE2L_2_LADC_CTRL, 3, 1, 1), 368 SOC_DAPM_SINGLE_AIC3X("Line2L Switch", LINE2L_2_LADC_CTRL, 3, 1, 1),
354 SOC_DAPM_SINGLE_AIC3X("Mic3L Switch", MIC3LR_2_LADC_CTRL, 4, 1, 1), 369 SOC_DAPM_SINGLE_AIC3X("Mic3L Switch", MIC3LR_2_LADC_CTRL, 4, 1, 1),
370 SOC_DAPM_SINGLE_AIC3X("Mic3R Switch", MIC3LR_2_LADC_CTRL, 0, 1, 1),
355}; 371};
356 372
357/* Right PGA Mixer */ 373/* Right PGA Mixer */
358static const struct snd_kcontrol_new aic3x_right_pga_mixer_controls[] = { 374static const struct snd_kcontrol_new aic3x_right_pga_mixer_controls[] = {
359 SOC_DAPM_SINGLE_AIC3X("Line1R Switch", LINE1R_2_RADC_CTRL, 3, 1, 1), 375 SOC_DAPM_SINGLE_AIC3X("Line1R Switch", LINE1R_2_RADC_CTRL, 3, 1, 1),
376 SOC_DAPM_SINGLE_AIC3X("Line1L Switch", LINE1L_2_RADC_CTRL, 3, 1, 1),
360 SOC_DAPM_SINGLE_AIC3X("Line2R Switch", LINE2R_2_RADC_CTRL, 3, 1, 1), 377 SOC_DAPM_SINGLE_AIC3X("Line2R Switch", LINE2R_2_RADC_CTRL, 3, 1, 1),
378 SOC_DAPM_SINGLE_AIC3X("Mic3L Switch", MIC3LR_2_RADC_CTRL, 4, 1, 1),
361 SOC_DAPM_SINGLE_AIC3X("Mic3R Switch", MIC3LR_2_RADC_CTRL, 0, 1, 1), 379 SOC_DAPM_SINGLE_AIC3X("Mic3R Switch", MIC3LR_2_RADC_CTRL, 0, 1, 1),
362}; 380};
363 381
@@ -379,34 +397,42 @@ SOC_DAPM_ENUM("Route", aic3x_enum[LINE2R_ENUM]);
379 397
380/* Left PGA Bypass Mixer */ 398/* Left PGA Bypass Mixer */
381static const struct snd_kcontrol_new aic3x_left_pga_bp_mixer_controls[] = { 399static const struct snd_kcontrol_new aic3x_left_pga_bp_mixer_controls[] = {
382 SOC_DAPM_SINGLE("Line Switch", PGAL_2_LLOPM_VOL, 7, 1, 0), 400 SOC_DAPM_SINGLE("LineL Switch", PGAL_2_LLOPM_VOL, 7, 1, 0),
401 SOC_DAPM_SINGLE("LineR Switch", PGAL_2_RLOPM_VOL, 7, 1, 0),
383 SOC_DAPM_SINGLE("Mono Switch", PGAL_2_MONOLOPM_VOL, 7, 1, 0), 402 SOC_DAPM_SINGLE("Mono Switch", PGAL_2_MONOLOPM_VOL, 7, 1, 0),
384 SOC_DAPM_SINGLE("HP Switch", PGAL_2_HPLOUT_VOL, 7, 1, 0), 403 SOC_DAPM_SINGLE("HPL Switch", PGAL_2_HPLOUT_VOL, 7, 1, 0),
385 SOC_DAPM_SINGLE("HPCOM Switch", PGAL_2_HPLCOM_VOL, 7, 1, 0), 404 SOC_DAPM_SINGLE("HPR Switch", PGAL_2_HPROUT_VOL, 7, 1, 0),
405 SOC_DAPM_SINGLE("HPLCOM Switch", PGAL_2_HPLCOM_VOL, 7, 1, 0),
406 SOC_DAPM_SINGLE("HPRCOM Switch", PGAL_2_HPRCOM_VOL, 7, 1, 0),
386}; 407};
387 408
388/* Right PGA Bypass Mixer */ 409/* Right PGA Bypass Mixer */
389static const struct snd_kcontrol_new aic3x_right_pga_bp_mixer_controls[] = { 410static const struct snd_kcontrol_new aic3x_right_pga_bp_mixer_controls[] = {
390 SOC_DAPM_SINGLE("Line Switch", PGAR_2_RLOPM_VOL, 7, 1, 0), 411 SOC_DAPM_SINGLE("LineL Switch", PGAR_2_LLOPM_VOL, 7, 1, 0),
412 SOC_DAPM_SINGLE("LineR Switch", PGAR_2_RLOPM_VOL, 7, 1, 0),
391 SOC_DAPM_SINGLE("Mono Switch", PGAR_2_MONOLOPM_VOL, 7, 1, 0), 413 SOC_DAPM_SINGLE("Mono Switch", PGAR_2_MONOLOPM_VOL, 7, 1, 0),
392 SOC_DAPM_SINGLE("HP Switch", PGAR_2_HPROUT_VOL, 7, 1, 0), 414 SOC_DAPM_SINGLE("HPL Switch", PGAR_2_HPLOUT_VOL, 7, 1, 0),
393 SOC_DAPM_SINGLE("HPCOM Switch", PGAR_2_HPRCOM_VOL, 7, 1, 0), 415 SOC_DAPM_SINGLE("HPR Switch", PGAR_2_HPROUT_VOL, 7, 1, 0),
416 SOC_DAPM_SINGLE("HPLCOM Switch", PGAR_2_HPLCOM_VOL, 7, 1, 0),
417 SOC_DAPM_SINGLE("HPRCOM Switch", PGAR_2_HPRCOM_VOL, 7, 1, 0),
394}; 418};
395 419
396/* Left Line2 Bypass Mixer */ 420/* Left Line2 Bypass Mixer */
397static const struct snd_kcontrol_new aic3x_left_line2_bp_mixer_controls[] = { 421static const struct snd_kcontrol_new aic3x_left_line2_bp_mixer_controls[] = {
398 SOC_DAPM_SINGLE("Line Switch", LINE2L_2_LLOPM_VOL, 7, 1, 0), 422 SOC_DAPM_SINGLE("LineL Switch", LINE2L_2_LLOPM_VOL, 7, 1, 0),
423 SOC_DAPM_SINGLE("LineR Switch", LINE2L_2_RLOPM_VOL, 7, 1, 0),
399 SOC_DAPM_SINGLE("Mono Switch", LINE2L_2_MONOLOPM_VOL, 7, 1, 0), 424 SOC_DAPM_SINGLE("Mono Switch", LINE2L_2_MONOLOPM_VOL, 7, 1, 0),
400 SOC_DAPM_SINGLE("HP Switch", LINE2L_2_HPLOUT_VOL, 7, 1, 0), 425 SOC_DAPM_SINGLE("HP Switch", LINE2L_2_HPLOUT_VOL, 7, 1, 0),
401 SOC_DAPM_SINGLE("HPCOM Switch", LINE2L_2_HPLCOM_VOL, 7, 1, 0), 426 SOC_DAPM_SINGLE("HPLCOM Switch", LINE2L_2_HPLCOM_VOL, 7, 1, 0),
402}; 427};
403 428
404/* Right Line2 Bypass Mixer */ 429/* Right Line2 Bypass Mixer */
405static const struct snd_kcontrol_new aic3x_right_line2_bp_mixer_controls[] = { 430static const struct snd_kcontrol_new aic3x_right_line2_bp_mixer_controls[] = {
406 SOC_DAPM_SINGLE("Line Switch", LINE2R_2_RLOPM_VOL, 7, 1, 0), 431 SOC_DAPM_SINGLE("LineL Switch", LINE2R_2_LLOPM_VOL, 7, 1, 0),
432 SOC_DAPM_SINGLE("LineR Switch", LINE2R_2_RLOPM_VOL, 7, 1, 0),
407 SOC_DAPM_SINGLE("Mono Switch", LINE2R_2_MONOLOPM_VOL, 7, 1, 0), 433 SOC_DAPM_SINGLE("Mono Switch", LINE2R_2_MONOLOPM_VOL, 7, 1, 0),
408 SOC_DAPM_SINGLE("HP Switch", LINE2R_2_HPROUT_VOL, 7, 1, 0), 434 SOC_DAPM_SINGLE("HP Switch", LINE2R_2_HPROUT_VOL, 7, 1, 0),
409 SOC_DAPM_SINGLE("HPCOM Switch", LINE2R_2_HPRCOM_VOL, 7, 1, 0), 435 SOC_DAPM_SINGLE("HPRCOM Switch", LINE2R_2_HPRCOM_VOL, 7, 1, 0),
410}; 436};
411 437
412static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = { 438static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = {
@@ -439,22 +465,26 @@ static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = {
439 /* Mono Output */ 465 /* Mono Output */
440 SND_SOC_DAPM_PGA("Mono Out", MONOLOPM_CTRL, 0, 0, NULL, 0), 466 SND_SOC_DAPM_PGA("Mono Out", MONOLOPM_CTRL, 0, 0, NULL, 0),
441 467
442 /* Left Inputs to Left ADC */ 468 /* Inputs to Left ADC */
443 SND_SOC_DAPM_ADC("Left ADC", "Left Capture", LINE1L_2_LADC_CTRL, 2, 0), 469 SND_SOC_DAPM_ADC("Left ADC", "Left Capture", LINE1L_2_LADC_CTRL, 2, 0),
444 SND_SOC_DAPM_MIXER("Left PGA Mixer", SND_SOC_NOPM, 0, 0, 470 SND_SOC_DAPM_MIXER("Left PGA Mixer", SND_SOC_NOPM, 0, 0,
445 &aic3x_left_pga_mixer_controls[0], 471 &aic3x_left_pga_mixer_controls[0],
446 ARRAY_SIZE(aic3x_left_pga_mixer_controls)), 472 ARRAY_SIZE(aic3x_left_pga_mixer_controls)),
447 SND_SOC_DAPM_MUX("Left Line1L Mux", SND_SOC_NOPM, 0, 0, 473 SND_SOC_DAPM_MUX("Left Line1L Mux", SND_SOC_NOPM, 0, 0,
448 &aic3x_left_line1_mux_controls), 474 &aic3x_left_line1_mux_controls),
475 SND_SOC_DAPM_MUX("Left Line1R Mux", SND_SOC_NOPM, 0, 0,
476 &aic3x_left_line1_mux_controls),
449 SND_SOC_DAPM_MUX("Left Line2L Mux", SND_SOC_NOPM, 0, 0, 477 SND_SOC_DAPM_MUX("Left Line2L Mux", SND_SOC_NOPM, 0, 0,
450 &aic3x_left_line2_mux_controls), 478 &aic3x_left_line2_mux_controls),
451 479
452 /* Right Inputs to Right ADC */ 480 /* Inputs to Right ADC */
453 SND_SOC_DAPM_ADC("Right ADC", "Right Capture", 481 SND_SOC_DAPM_ADC("Right ADC", "Right Capture",
454 LINE1R_2_RADC_CTRL, 2, 0), 482 LINE1R_2_RADC_CTRL, 2, 0),
455 SND_SOC_DAPM_MIXER("Right PGA Mixer", SND_SOC_NOPM, 0, 0, 483 SND_SOC_DAPM_MIXER("Right PGA Mixer", SND_SOC_NOPM, 0, 0,
456 &aic3x_right_pga_mixer_controls[0], 484 &aic3x_right_pga_mixer_controls[0],
457 ARRAY_SIZE(aic3x_right_pga_mixer_controls)), 485 ARRAY_SIZE(aic3x_right_pga_mixer_controls)),
486 SND_SOC_DAPM_MUX("Right Line1L Mux", SND_SOC_NOPM, 0, 0,
487 &aic3x_right_line1_mux_controls),
458 SND_SOC_DAPM_MUX("Right Line1R Mux", SND_SOC_NOPM, 0, 0, 488 SND_SOC_DAPM_MUX("Right Line1R Mux", SND_SOC_NOPM, 0, 0,
459 &aic3x_right_line1_mux_controls), 489 &aic3x_right_line1_mux_controls),
460 SND_SOC_DAPM_MUX("Right Line2R Mux", SND_SOC_NOPM, 0, 0, 490 SND_SOC_DAPM_MUX("Right Line2R Mux", SND_SOC_NOPM, 0, 0,
@@ -531,7 +561,8 @@ static const struct snd_soc_dapm_route intercon[] = {
531 {"Left DAC Mux", "DAC_L2", "Left DAC"}, 561 {"Left DAC Mux", "DAC_L2", "Left DAC"},
532 {"Left DAC Mux", "DAC_L3", "Left DAC"}, 562 {"Left DAC Mux", "DAC_L3", "Left DAC"},
533 563
534 {"Left DAC_L1 Mixer", "Line Switch", "Left DAC Mux"}, 564 {"Left DAC_L1 Mixer", "LineL Switch", "Left DAC Mux"},
565 {"Left DAC_L1 Mixer", "LineR Switch", "Left DAC Mux"},
535 {"Left DAC_L1 Mixer", "Mono Switch", "Left DAC Mux"}, 566 {"Left DAC_L1 Mixer", "Mono Switch", "Left DAC Mux"},
536 {"Left DAC_L1 Mixer", "HP Switch", "Left DAC Mux"}, 567 {"Left DAC_L1 Mixer", "HP Switch", "Left DAC Mux"},
537 {"Left DAC_L1 Mixer", "HPCOM Switch", "Left DAC Mux"}, 568 {"Left DAC_L1 Mixer", "HPCOM Switch", "Left DAC Mux"},
@@ -557,7 +588,8 @@ static const struct snd_soc_dapm_route intercon[] = {
557 {"Right DAC Mux", "DAC_R2", "Right DAC"}, 588 {"Right DAC Mux", "DAC_R2", "Right DAC"},
558 {"Right DAC Mux", "DAC_R3", "Right DAC"}, 589 {"Right DAC Mux", "DAC_R3", "Right DAC"},
559 590
560 {"Right DAC_R1 Mixer", "Line Switch", "Right DAC Mux"}, 591 {"Right DAC_R1 Mixer", "LineL Switch", "Right DAC Mux"},
592 {"Right DAC_R1 Mixer", "LineR Switch", "Right DAC Mux"},
561 {"Right DAC_R1 Mixer", "Mono Switch", "Right DAC Mux"}, 593 {"Right DAC_R1 Mixer", "Mono Switch", "Right DAC Mux"},
562 {"Right DAC_R1 Mixer", "HP Switch", "Right DAC Mux"}, 594 {"Right DAC_R1 Mixer", "HP Switch", "Right DAC Mux"},
563 {"Right DAC_R1 Mixer", "HPCOM Switch", "Right DAC Mux"}, 595 {"Right DAC_R1 Mixer", "HPCOM Switch", "Right DAC Mux"},
@@ -592,8 +624,10 @@ static const struct snd_soc_dapm_route intercon[] = {
592 {"Left Line2L Mux", "differential", "LINE2L"}, 624 {"Left Line2L Mux", "differential", "LINE2L"},
593 625
594 {"Left PGA Mixer", "Line1L Switch", "Left Line1L Mux"}, 626 {"Left PGA Mixer", "Line1L Switch", "Left Line1L Mux"},
627 {"Left PGA Mixer", "Line1R Switch", "Left Line1R Mux"},
595 {"Left PGA Mixer", "Line2L Switch", "Left Line2L Mux"}, 628 {"Left PGA Mixer", "Line2L Switch", "Left Line2L Mux"},
596 {"Left PGA Mixer", "Mic3L Switch", "MIC3L"}, 629 {"Left PGA Mixer", "Mic3L Switch", "MIC3L"},
630 {"Left PGA Mixer", "Mic3R Switch", "MIC3R"},
597 631
598 {"Left ADC", NULL, "Left PGA Mixer"}, 632 {"Left ADC", NULL, "Left PGA Mixer"},
599 {"Left ADC", NULL, "GPIO1 dmic modclk"}, 633 {"Left ADC", NULL, "GPIO1 dmic modclk"},
@@ -605,18 +639,23 @@ static const struct snd_soc_dapm_route intercon[] = {
605 {"Right Line2R Mux", "single-ended", "LINE2R"}, 639 {"Right Line2R Mux", "single-ended", "LINE2R"},
606 {"Right Line2R Mux", "differential", "LINE2R"}, 640 {"Right Line2R Mux", "differential", "LINE2R"},
607 641
642 {"Right PGA Mixer", "Line1L Switch", "Right Line1L Mux"},
608 {"Right PGA Mixer", "Line1R Switch", "Right Line1R Mux"}, 643 {"Right PGA Mixer", "Line1R Switch", "Right Line1R Mux"},
609 {"Right PGA Mixer", "Line2R Switch", "Right Line2R Mux"}, 644 {"Right PGA Mixer", "Line2R Switch", "Right Line2R Mux"},
645 {"Right PGA Mixer", "Mic3L Switch", "MIC3L"},
610 {"Right PGA Mixer", "Mic3R Switch", "MIC3R"}, 646 {"Right PGA Mixer", "Mic3R Switch", "MIC3R"},
611 647
612 {"Right ADC", NULL, "Right PGA Mixer"}, 648 {"Right ADC", NULL, "Right PGA Mixer"},
613 {"Right ADC", NULL, "GPIO1 dmic modclk"}, 649 {"Right ADC", NULL, "GPIO1 dmic modclk"},
614 650
615 /* Left PGA Bypass */ 651 /* Left PGA Bypass */
616 {"Left PGA Bypass Mixer", "Line Switch", "Left PGA Mixer"}, 652 {"Left PGA Bypass Mixer", "LineL Switch", "Left PGA Mixer"},
653 {"Left PGA Bypass Mixer", "LineR Switch", "Left PGA Mixer"},
617 {"Left PGA Bypass Mixer", "Mono Switch", "Left PGA Mixer"}, 654 {"Left PGA Bypass Mixer", "Mono Switch", "Left PGA Mixer"},
618 {"Left PGA Bypass Mixer", "HP Switch", "Left PGA Mixer"}, 655 {"Left PGA Bypass Mixer", "HPL Switch", "Left PGA Mixer"},
619 {"Left PGA Bypass Mixer", "HPCOM Switch", "Left PGA Mixer"}, 656 {"Left PGA Bypass Mixer", "HPR Switch", "Left PGA Mixer"},
657 {"Left PGA Bypass Mixer", "HPLCOM Switch", "Left PGA Mixer"},
658 {"Left PGA Bypass Mixer", "HPRCOM Switch", "Left PGA Mixer"},
620 659
621 {"Left HPCOM Mux", "differential of HPLOUT", "Left PGA Bypass Mixer"}, 660 {"Left HPCOM Mux", "differential of HPLOUT", "Left PGA Bypass Mixer"},
622 {"Left HPCOM Mux", "constant VCM", "Left PGA Bypass Mixer"}, 661 {"Left HPCOM Mux", "constant VCM", "Left PGA Bypass Mixer"},
@@ -627,10 +666,13 @@ static const struct snd_soc_dapm_route intercon[] = {
627 {"Left HP Out", NULL, "Left PGA Bypass Mixer"}, 666 {"Left HP Out", NULL, "Left PGA Bypass Mixer"},
628 667
629 /* Right PGA Bypass */ 668 /* Right PGA Bypass */
630 {"Right PGA Bypass Mixer", "Line Switch", "Right PGA Mixer"}, 669 {"Right PGA Bypass Mixer", "LineL Switch", "Right PGA Mixer"},
670 {"Right PGA Bypass Mixer", "LineR Switch", "Right PGA Mixer"},
631 {"Right PGA Bypass Mixer", "Mono Switch", "Right PGA Mixer"}, 671 {"Right PGA Bypass Mixer", "Mono Switch", "Right PGA Mixer"},
632 {"Right PGA Bypass Mixer", "HP Switch", "Right PGA Mixer"}, 672 {"Right PGA Bypass Mixer", "HPL Switch", "Right PGA Mixer"},
633 {"Right PGA Bypass Mixer", "HPCOM Switch", "Right PGA Mixer"}, 673 {"Right PGA Bypass Mixer", "HPR Switch", "Right PGA Mixer"},
674 {"Right PGA Bypass Mixer", "HPLCOM Switch", "Right PGA Mixer"},
675 {"Right PGA Bypass Mixer", "HPRCOM Switch", "Right PGA Mixer"},
634 676
635 {"Right HPCOM Mux", "differential of HPROUT", "Right PGA Bypass Mixer"}, 677 {"Right HPCOM Mux", "differential of HPROUT", "Right PGA Bypass Mixer"},
636 {"Right HPCOM Mux", "constant VCM", "Right PGA Bypass Mixer"}, 678 {"Right HPCOM Mux", "constant VCM", "Right PGA Bypass Mixer"},
@@ -643,10 +685,11 @@ static const struct snd_soc_dapm_route intercon[] = {
643 {"Right HP Out", NULL, "Right PGA Bypass Mixer"}, 685 {"Right HP Out", NULL, "Right PGA Bypass Mixer"},
644 686
645 /* Left Line2 Bypass */ 687 /* Left Line2 Bypass */
646 {"Left Line2 Bypass Mixer", "Line Switch", "Left Line2L Mux"}, 688 {"Left Line2 Bypass Mixer", "LineL Switch", "Left Line2L Mux"},
689 {"Left Line2 Bypass Mixer", "LineR Switch", "Left Line2L Mux"},
647 {"Left Line2 Bypass Mixer", "Mono Switch", "Left Line2L Mux"}, 690 {"Left Line2 Bypass Mixer", "Mono Switch", "Left Line2L Mux"},
648 {"Left Line2 Bypass Mixer", "HP Switch", "Left Line2L Mux"}, 691 {"Left Line2 Bypass Mixer", "HP Switch", "Left Line2L Mux"},
649 {"Left Line2 Bypass Mixer", "HPCOM Switch", "Left Line2L Mux"}, 692 {"Left Line2 Bypass Mixer", "HPLCOM Switch", "Left Line2L Mux"},
650 693
651 {"Left HPCOM Mux", "differential of HPLOUT", "Left Line2 Bypass Mixer"}, 694 {"Left HPCOM Mux", "differential of HPLOUT", "Left Line2 Bypass Mixer"},
652 {"Left HPCOM Mux", "constant VCM", "Left Line2 Bypass Mixer"}, 695 {"Left HPCOM Mux", "constant VCM", "Left Line2 Bypass Mixer"},
@@ -657,10 +700,11 @@ static const struct snd_soc_dapm_route intercon[] = {
657 {"Left HP Out", NULL, "Left Line2 Bypass Mixer"}, 700 {"Left HP Out", NULL, "Left Line2 Bypass Mixer"},
658 701
659 /* Right Line2 Bypass */ 702 /* Right Line2 Bypass */
660 {"Right Line2 Bypass Mixer", "Line Switch", "Right Line2R Mux"}, 703 {"Right Line2 Bypass Mixer", "LineL Switch", "Right Line2R Mux"},
704 {"Right Line2 Bypass Mixer", "LineR Switch", "Right Line2R Mux"},
661 {"Right Line2 Bypass Mixer", "Mono Switch", "Right Line2R Mux"}, 705 {"Right Line2 Bypass Mixer", "Mono Switch", "Right Line2R Mux"},
662 {"Right Line2 Bypass Mixer", "HP Switch", "Right Line2R Mux"}, 706 {"Right Line2 Bypass Mixer", "HP Switch", "Right Line2R Mux"},
663 {"Right Line2 Bypass Mixer", "HPCOM Switch", "Right Line2R Mux"}, 707 {"Right Line2 Bypass Mixer", "HPRCOM Switch", "Right Line2R Mux"},
664 708
665 {"Right HPCOM Mux", "differential of HPROUT", "Right Line2 Bypass Mixer"}, 709 {"Right HPCOM Mux", "differential of HPROUT", "Right Line2 Bypass Mixer"},
666 {"Right HPCOM Mux", "constant VCM", "Right Line2 Bypass Mixer"}, 710 {"Right HPCOM Mux", "constant VCM", "Right Line2 Bypass Mixer"},
@@ -694,7 +738,8 @@ static int aic3x_add_widgets(struct snd_soc_codec *codec)
694} 738}
695 739
696static int aic3x_hw_params(struct snd_pcm_substream *substream, 740static int aic3x_hw_params(struct snd_pcm_substream *substream,
697 struct snd_pcm_hw_params *params) 741 struct snd_pcm_hw_params *params,
742 struct snd_soc_dai *dai)
698{ 743{
699 struct snd_soc_pcm_runtime *rtd = substream->private_data; 744 struct snd_soc_pcm_runtime *rtd = substream->private_data;
700 struct snd_soc_device *socdev = rtd->socdev; 745 struct snd_soc_device *socdev = rtd->socdev;
@@ -846,6 +891,7 @@ static int aic3x_set_dai_fmt(struct snd_soc_dai *codec_dai,
846 struct snd_soc_codec *codec = codec_dai->codec; 891 struct snd_soc_codec *codec = codec_dai->codec;
847 struct aic3x_priv *aic3x = codec->private_data; 892 struct aic3x_priv *aic3x = codec->private_data;
848 u8 iface_areg, iface_breg; 893 u8 iface_areg, iface_breg;
894 int delay = 0;
849 895
850 iface_areg = aic3x_read_reg_cache(codec, AIC3X_ASD_INTF_CTRLA) & 0x3f; 896 iface_areg = aic3x_read_reg_cache(codec, AIC3X_ASD_INTF_CTRLA) & 0x3f;
851 iface_breg = aic3x_read_reg_cache(codec, AIC3X_ASD_INTF_CTRLB) & 0x3f; 897 iface_breg = aic3x_read_reg_cache(codec, AIC3X_ASD_INTF_CTRLB) & 0x3f;
@@ -871,6 +917,8 @@ static int aic3x_set_dai_fmt(struct snd_soc_dai *codec_dai,
871 SND_SOC_DAIFMT_INV_MASK)) { 917 SND_SOC_DAIFMT_INV_MASK)) {
872 case (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF): 918 case (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF):
873 break; 919 break;
920 case (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF):
921 delay = 1;
874 case (SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF): 922 case (SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF):
875 iface_breg |= (0x01 << 6); 923 iface_breg |= (0x01 << 6);
876 break; 924 break;
@@ -887,6 +935,7 @@ static int aic3x_set_dai_fmt(struct snd_soc_dai *codec_dai,
887 /* set iface */ 935 /* set iface */
888 aic3x_write(codec, AIC3X_ASD_INTF_CTRLA, iface_areg); 936 aic3x_write(codec, AIC3X_ASD_INTF_CTRLA, iface_areg);
889 aic3x_write(codec, AIC3X_ASD_INTF_CTRLB, iface_breg); 937 aic3x_write(codec, AIC3X_ASD_INTF_CTRLB, iface_breg);
938 aic3x_write(codec, AIC3X_ASD_INTF_CTRLC, delay);
890 939
891 return 0; 940 return 0;
892} 941}
@@ -981,14 +1030,41 @@ int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio)
981} 1030}
982EXPORT_SYMBOL_GPL(aic3x_get_gpio); 1031EXPORT_SYMBOL_GPL(aic3x_get_gpio);
983 1032
1033void aic3x_set_headset_detection(struct snd_soc_codec *codec, int detect,
1034 int headset_debounce, int button_debounce)
1035{
1036 u8 val;
1037
1038 val = ((detect & AIC3X_HEADSET_DETECT_MASK)
1039 << AIC3X_HEADSET_DETECT_SHIFT) |
1040 ((headset_debounce & AIC3X_HEADSET_DEBOUNCE_MASK)
1041 << AIC3X_HEADSET_DEBOUNCE_SHIFT) |
1042 ((button_debounce & AIC3X_BUTTON_DEBOUNCE_MASK)
1043 << AIC3X_BUTTON_DEBOUNCE_SHIFT);
1044
1045 if (detect & AIC3X_HEADSET_DETECT_MASK)
1046 val |= AIC3X_HEADSET_DETECT_ENABLED;
1047
1048 aic3x_write(codec, AIC3X_HEADSET_DETECT_CTRL_A, val);
1049}
1050EXPORT_SYMBOL_GPL(aic3x_set_headset_detection);
1051
984int aic3x_headset_detected(struct snd_soc_codec *codec) 1052int aic3x_headset_detected(struct snd_soc_codec *codec)
985{ 1053{
986 u8 val; 1054 u8 val;
987 aic3x_read(codec, AIC3X_RT_IRQ_FLAGS_REG, &val); 1055 aic3x_read(codec, AIC3X_HEADSET_DETECT_CTRL_B, &val);
988 return (val >> 2) & 1; 1056 return (val >> 4) & 1;
989} 1057}
990EXPORT_SYMBOL_GPL(aic3x_headset_detected); 1058EXPORT_SYMBOL_GPL(aic3x_headset_detected);
991 1059
1060int aic3x_button_pressed(struct snd_soc_codec *codec)
1061{
1062 u8 val;
1063 aic3x_read(codec, AIC3X_HEADSET_DETECT_CTRL_B, &val);
1064 return (val >> 5) & 1;
1065}
1066EXPORT_SYMBOL_GPL(aic3x_button_pressed);
1067
992#define AIC3X_RATES SNDRV_PCM_RATE_8000_96000 1068#define AIC3X_RATES SNDRV_PCM_RATE_8000_96000
993#define AIC3X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ 1069#define AIC3X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
994 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) 1070 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
@@ -1009,8 +1085,6 @@ struct snd_soc_dai aic3x_dai = {
1009 .formats = AIC3X_FORMATS,}, 1085 .formats = AIC3X_FORMATS,},
1010 .ops = { 1086 .ops = {
1011 .hw_params = aic3x_hw_params, 1087 .hw_params = aic3x_hw_params,
1012 },
1013 .dai_ops = {
1014 .digital_mute = aic3x_mute, 1088 .digital_mute = aic3x_mute,
1015 .set_sysclk = aic3x_set_dai_sysclk, 1089 .set_sysclk = aic3x_set_dai_sysclk,
1016 .set_fmt = aic3x_set_dai_fmt, 1090 .set_fmt = aic3x_set_dai_fmt,
@@ -1152,7 +1226,7 @@ static int aic3x_init(struct snd_soc_device *socdev)
1152 1226
1153 aic3x_add_controls(codec); 1227 aic3x_add_controls(codec);
1154 aic3x_add_widgets(codec); 1228 aic3x_add_widgets(codec);
1155 ret = snd_soc_register_card(socdev); 1229 ret = snd_soc_init_card(socdev);
1156 if (ret < 0) { 1230 if (ret < 0) {
1157 printk(KERN_ERR "aic3x: failed to register card\n"); 1231 printk(KERN_ERR "aic3x: failed to register card\n");
1158 goto card_err; 1232 goto card_err;
@@ -1341,6 +1415,18 @@ struct snd_soc_codec_device soc_codec_dev_aic3x = {
1341}; 1415};
1342EXPORT_SYMBOL_GPL(soc_codec_dev_aic3x); 1416EXPORT_SYMBOL_GPL(soc_codec_dev_aic3x);
1343 1417
1418static int __init aic3x_modinit(void)
1419{
1420 return snd_soc_register_dai(&aic3x_dai);
1421}
1422module_init(aic3x_modinit);
1423
1424static void __exit aic3x_exit(void)
1425{
1426 snd_soc_unregister_dai(&aic3x_dai);
1427}
1428module_exit(aic3x_exit);
1429
1344MODULE_DESCRIPTION("ASoC TLV320AIC3X codec driver"); 1430MODULE_DESCRIPTION("ASoC TLV320AIC3X codec driver");
1345MODULE_AUTHOR("Vladimir Barinov"); 1431MODULE_AUTHOR("Vladimir Barinov");
1346MODULE_LICENSE("GPL"); 1432MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/tlv320aic3x.h b/sound/soc/codecs/tlv320aic3x.h
index 00a195aa02e4..ac827e578c4d 100644
--- a/sound/soc/codecs/tlv320aic3x.h
+++ b/sound/soc/codecs/tlv320aic3x.h
@@ -35,11 +35,15 @@
35#define AIC3X_ASD_INTF_CTRLA 8 35#define AIC3X_ASD_INTF_CTRLA 8
36/* Audio serial data interface control register B */ 36/* Audio serial data interface control register B */
37#define AIC3X_ASD_INTF_CTRLB 9 37#define AIC3X_ASD_INTF_CTRLB 9
38/* Audio serial data interface control register C */
39#define AIC3X_ASD_INTF_CTRLC 10
38/* Audio overflow status and PLL R value programming register */ 40/* Audio overflow status and PLL R value programming register */
39#define AIC3X_OVRF_STATUS_AND_PLLR_REG 11 41#define AIC3X_OVRF_STATUS_AND_PLLR_REG 11
40/* Audio codec digital filter control register */ 42/* Audio codec digital filter control register */
41#define AIC3X_CODEC_DFILT_CTRL 12 43#define AIC3X_CODEC_DFILT_CTRL 12
42 44/* Headset/button press detection register */
45#define AIC3X_HEADSET_DETECT_CTRL_A 13
46#define AIC3X_HEADSET_DETECT_CTRL_B 14
43/* ADC PGA Gain control registers */ 47/* ADC PGA Gain control registers */
44#define LADC_VOL 15 48#define LADC_VOL 15
45#define RADC_VOL 16 49#define RADC_VOL 16
@@ -48,7 +52,9 @@
48#define MIC3LR_2_RADC_CTRL 18 52#define MIC3LR_2_RADC_CTRL 18
49/* Line1 Input control registers */ 53/* Line1 Input control registers */
50#define LINE1L_2_LADC_CTRL 19 54#define LINE1L_2_LADC_CTRL 19
55#define LINE1R_2_LADC_CTRL 21
51#define LINE1R_2_RADC_CTRL 22 56#define LINE1R_2_RADC_CTRL 22
57#define LINE1L_2_RADC_CTRL 24
52/* Line2 Input control registers */ 58/* Line2 Input control registers */
53#define LINE2L_2_LADC_CTRL 20 59#define LINE2L_2_LADC_CTRL 20
54#define LINE2R_2_RADC_CTRL 23 60#define LINE2R_2_RADC_CTRL 23
@@ -79,6 +85,8 @@
79#define LINE2L_2_HPLOUT_VOL 45 85#define LINE2L_2_HPLOUT_VOL 45
80#define LINE2R_2_HPROUT_VOL 62 86#define LINE2R_2_HPROUT_VOL 62
81#define PGAL_2_HPLOUT_VOL 46 87#define PGAL_2_HPLOUT_VOL 46
88#define PGAL_2_HPROUT_VOL 60
89#define PGAR_2_HPLOUT_VOL 49
82#define PGAR_2_HPROUT_VOL 63 90#define PGAR_2_HPROUT_VOL 63
83#define DACL1_2_HPLOUT_VOL 47 91#define DACL1_2_HPLOUT_VOL 47
84#define DACR1_2_HPROUT_VOL 64 92#define DACR1_2_HPROUT_VOL 64
@@ -88,6 +96,8 @@
88#define LINE2L_2_HPLCOM_VOL 52 96#define LINE2L_2_HPLCOM_VOL 52
89#define LINE2R_2_HPRCOM_VOL 69 97#define LINE2R_2_HPRCOM_VOL 69
90#define PGAL_2_HPLCOM_VOL 53 98#define PGAL_2_HPLCOM_VOL 53
99#define PGAR_2_HPLCOM_VOL 56
100#define PGAL_2_HPRCOM_VOL 67
91#define PGAR_2_HPRCOM_VOL 70 101#define PGAR_2_HPRCOM_VOL 70
92#define DACL1_2_HPLCOM_VOL 54 102#define DACL1_2_HPLCOM_VOL 54
93#define DACR1_2_HPRCOM_VOL 71 103#define DACR1_2_HPRCOM_VOL 71
@@ -103,11 +113,17 @@
103#define MONOLOPM_CTRL 79 113#define MONOLOPM_CTRL 79
104/* Line Output Plus/Minus control registers */ 114/* Line Output Plus/Minus control registers */
105#define LINE2L_2_LLOPM_VOL 80 115#define LINE2L_2_LLOPM_VOL 80
116#define LINE2L_2_RLOPM_VOL 87
117#define LINE2R_2_LLOPM_VOL 83
106#define LINE2R_2_RLOPM_VOL 90 118#define LINE2R_2_RLOPM_VOL 90
107#define PGAL_2_LLOPM_VOL 81 119#define PGAL_2_LLOPM_VOL 81
120#define PGAL_2_RLOPM_VOL 88
121#define PGAR_2_LLOPM_VOL 84
108#define PGAR_2_RLOPM_VOL 91 122#define PGAR_2_RLOPM_VOL 91
109#define DACL1_2_LLOPM_VOL 82 123#define DACL1_2_LLOPM_VOL 82
124#define DACL1_2_RLOPM_VOL 89
110#define DACR1_2_RLOPM_VOL 92 125#define DACR1_2_RLOPM_VOL 92
126#define DACR1_2_LLOPM_VOL 85
111#define LLOPM_CTRL 86 127#define LLOPM_CTRL 86
112#define RLOPM_CTRL 93 128#define RLOPM_CTRL 93
113/* GPIO/IRQ registers */ 129/* GPIO/IRQ registers */
@@ -221,7 +237,49 @@ enum {
221 237
222void aic3x_set_gpio(struct snd_soc_codec *codec, int gpio, int state); 238void aic3x_set_gpio(struct snd_soc_codec *codec, int gpio, int state);
223int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio); 239int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio);
240
241/* headset detection / button API */
242
243/* The AIC3x supports detection of stereo headsets (GND + left + right signal)
244 * and cellular headsets (GND + speaker output + microphone input).
245 * It is recommended to enable MIC bias for this function to work properly.
246 * For more information, please refer to the datasheet. */
247enum {
248 AIC3X_HEADSET_DETECT_OFF = 0,
249 AIC3X_HEADSET_DETECT_STEREO = 1,
250 AIC3X_HEADSET_DETECT_CELLULAR = 2,
251 AIC3X_HEADSET_DETECT_BOTH = 3
252};
253
254enum {
255 AIC3X_HEADSET_DEBOUNCE_16MS = 0,
256 AIC3X_HEADSET_DEBOUNCE_32MS = 1,
257 AIC3X_HEADSET_DEBOUNCE_64MS = 2,
258 AIC3X_HEADSET_DEBOUNCE_128MS = 3,
259 AIC3X_HEADSET_DEBOUNCE_256MS = 4,
260 AIC3X_HEADSET_DEBOUNCE_512MS = 5
261};
262
263enum {
264 AIC3X_BUTTON_DEBOUNCE_0MS = 0,
265 AIC3X_BUTTON_DEBOUNCE_8MS = 1,
266 AIC3X_BUTTON_DEBOUNCE_16MS = 2,
267 AIC3X_BUTTON_DEBOUNCE_32MS = 3
268};
269
270#define AIC3X_HEADSET_DETECT_ENABLED 0x80
271#define AIC3X_HEADSET_DETECT_SHIFT 5
272#define AIC3X_HEADSET_DETECT_MASK 3
273#define AIC3X_HEADSET_DEBOUNCE_SHIFT 2
274#define AIC3X_HEADSET_DEBOUNCE_MASK 7
275#define AIC3X_BUTTON_DEBOUNCE_SHIFT 0
276#define AIC3X_BUTTON_DEBOUNCE_MASK 3
277
278/* see the enums above for valid parameters to this function */
279void aic3x_set_headset_detection(struct snd_soc_codec *codec, int detect,
280 int headset_debounce, int button_debounce);
224int aic3x_headset_detected(struct snd_soc_codec *codec); 281int aic3x_headset_detected(struct snd_soc_codec *codec);
282int aic3x_button_pressed(struct snd_soc_codec *codec);
225 283
226struct aic3x_setup_data { 284struct aic3x_setup_data {
227 int i2c_bus; 285 int i2c_bus;
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
new file mode 100644
index 000000000000..51848880504a
--- /dev/null
+++ b/sound/soc/codecs/twl4030.c
@@ -0,0 +1,1317 @@
1/*
2 * ALSA SoC TWL4030 codec driver
3 *
4 * Author: Steve Sakoman, <steve@sakoman.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21
22#include <linux/module.h>
23#include <linux/moduleparam.h>
24#include <linux/init.h>
25#include <linux/delay.h>
26#include <linux/pm.h>
27#include <linux/i2c.h>
28#include <linux/platform_device.h>
29#include <linux/i2c/twl4030.h>
30#include <sound/core.h>
31#include <sound/pcm.h>
32#include <sound/pcm_params.h>
33#include <sound/soc.h>
34#include <sound/soc-dapm.h>
35#include <sound/initval.h>
36#include <sound/tlv.h>
37
38#include "twl4030.h"
39
40/*
41 * twl4030 register cache & default register settings
42 */
43static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {
44 0x00, /* this register not used */
45 0x93, /* REG_CODEC_MODE (0x1) */
46 0xc3, /* REG_OPTION (0x2) */
47 0x00, /* REG_UNKNOWN (0x3) */
48 0x00, /* REG_MICBIAS_CTL (0x4) */
49 0x20, /* REG_ANAMICL (0x5) */
50 0x00, /* REG_ANAMICR (0x6) */
51 0x00, /* REG_AVADC_CTL (0x7) */
52 0x00, /* REG_ADCMICSEL (0x8) */
53 0x00, /* REG_DIGMIXING (0x9) */
54 0x0c, /* REG_ATXL1PGA (0xA) */
55 0x0c, /* REG_ATXR1PGA (0xB) */
56 0x00, /* REG_AVTXL2PGA (0xC) */
57 0x00, /* REG_AVTXR2PGA (0xD) */
58 0x01, /* REG_AUDIO_IF (0xE) */
59 0x00, /* REG_VOICE_IF (0xF) */
60 0x00, /* REG_ARXR1PGA (0x10) */
61 0x00, /* REG_ARXL1PGA (0x11) */
62 0x6c, /* REG_ARXR2PGA (0x12) */
63 0x6c, /* REG_ARXL2PGA (0x13) */
64 0x00, /* REG_VRXPGA (0x14) */
65 0x00, /* REG_VSTPGA (0x15) */
66 0x00, /* REG_VRX2ARXPGA (0x16) */
67 0x0c, /* REG_AVDAC_CTL (0x17) */
68 0x00, /* REG_ARX2VTXPGA (0x18) */
69 0x00, /* REG_ARXL1_APGA_CTL (0x19) */
70 0x00, /* REG_ARXR1_APGA_CTL (0x1A) */
71 0x4b, /* REG_ARXL2_APGA_CTL (0x1B) */
72 0x4b, /* REG_ARXR2_APGA_CTL (0x1C) */
73 0x00, /* REG_ATX2ARXPGA (0x1D) */
74 0x00, /* REG_BT_IF (0x1E) */
75 0x00, /* REG_BTPGA (0x1F) */
76 0x00, /* REG_BTSTPGA (0x20) */
77 0x00, /* REG_EAR_CTL (0x21) */
78 0x24, /* REG_HS_SEL (0x22) */
79 0x0a, /* REG_HS_GAIN_SET (0x23) */
80 0x00, /* REG_HS_POPN_SET (0x24) */
81 0x00, /* REG_PREDL_CTL (0x25) */
82 0x00, /* REG_PREDR_CTL (0x26) */
83 0x00, /* REG_PRECKL_CTL (0x27) */
84 0x00, /* REG_PRECKR_CTL (0x28) */
85 0x00, /* REG_HFL_CTL (0x29) */
86 0x00, /* REG_HFR_CTL (0x2A) */
87 0x00, /* REG_ALC_CTL (0x2B) */
88 0x00, /* REG_ALC_SET1 (0x2C) */
89 0x00, /* REG_ALC_SET2 (0x2D) */
90 0x00, /* REG_BOOST_CTL (0x2E) */
91 0x00, /* REG_SOFTVOL_CTL (0x2F) */
92 0x00, /* REG_DTMF_FREQSEL (0x30) */
93 0x00, /* REG_DTMF_TONEXT1H (0x31) */
94 0x00, /* REG_DTMF_TONEXT1L (0x32) */
95 0x00, /* REG_DTMF_TONEXT2H (0x33) */
96 0x00, /* REG_DTMF_TONEXT2L (0x34) */
97 0x00, /* REG_DTMF_TONOFF (0x35) */
98 0x00, /* REG_DTMF_WANONOFF (0x36) */
99 0x00, /* REG_I2S_RX_SCRAMBLE_H (0x37) */
100 0x00, /* REG_I2S_RX_SCRAMBLE_M (0x38) */
101 0x00, /* REG_I2S_RX_SCRAMBLE_L (0x39) */
102 0x16, /* REG_APLL_CTL (0x3A) */
103 0x00, /* REG_DTMF_CTL (0x3B) */
104 0x00, /* REG_DTMF_PGA_CTL2 (0x3C) */
105 0x00, /* REG_DTMF_PGA_CTL1 (0x3D) */
106 0x00, /* REG_MISC_SET_1 (0x3E) */
107 0x00, /* REG_PCMBTMUX (0x3F) */
108 0x00, /* not used (0x40) */
109 0x00, /* not used (0x41) */
110 0x00, /* not used (0x42) */
111 0x00, /* REG_RX_PATH_SEL (0x43) */
112 0x00, /* REG_VDL_APGA_CTL (0x44) */
113 0x00, /* REG_VIBRA_CTL (0x45) */
114 0x00, /* REG_VIBRA_SET (0x46) */
115 0x00, /* REG_VIBRA_PWM_SET (0x47) */
116 0x00, /* REG_ANAMIC_GAIN (0x48) */
117 0x00, /* REG_MISC_SET_2 (0x49) */
118};
119
120/*
121 * read twl4030 register cache
122 */
123static inline unsigned int twl4030_read_reg_cache(struct snd_soc_codec *codec,
124 unsigned int reg)
125{
126 u8 *cache = codec->reg_cache;
127
128 return cache[reg];
129}
130
131/*
132 * write twl4030 register cache
133 */
134static inline void twl4030_write_reg_cache(struct snd_soc_codec *codec,
135 u8 reg, u8 value)
136{
137 u8 *cache = codec->reg_cache;
138
139 if (reg >= TWL4030_CACHEREGNUM)
140 return;
141 cache[reg] = value;
142}
143
144/*
145 * write to the twl4030 register space
146 */
147static int twl4030_write(struct snd_soc_codec *codec,
148 unsigned int reg, unsigned int value)
149{
150 twl4030_write_reg_cache(codec, reg, value);
151 return twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, value, reg);
152}
153
154static void twl4030_clear_codecpdz(struct snd_soc_codec *codec)
155{
156 u8 mode;
157
158 mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE);
159 twl4030_write(codec, TWL4030_REG_CODEC_MODE,
160 mode & ~TWL4030_CODECPDZ);
161
162 /* REVISIT: this delay is present in TI sample drivers */
163 /* but there seems to be no TRM requirement for it */
164 udelay(10);
165}
166
167static void twl4030_set_codecpdz(struct snd_soc_codec *codec)
168{
169 u8 mode;
170
171 mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE);
172 twl4030_write(codec, TWL4030_REG_CODEC_MODE,
173 mode | TWL4030_CODECPDZ);
174
175 /* REVISIT: this delay is present in TI sample drivers */
176 /* but there seems to be no TRM requirement for it */
177 udelay(10);
178}
179
180static void twl4030_init_chip(struct snd_soc_codec *codec)
181{
182 int i;
183
184 /* clear CODECPDZ prior to setting register defaults */
185 twl4030_clear_codecpdz(codec);
186
187 /* set all audio section registers to reasonable defaults */
188 for (i = TWL4030_REG_OPTION; i <= TWL4030_REG_MISC_SET_2; i++)
189 twl4030_write(codec, i, twl4030_reg[i]);
190
191}
192
193/* Earpiece */
194static const char *twl4030_earpiece_texts[] =
195 {"Off", "DACL1", "DACL2", "Invalid", "DACR1"};
196
197static const struct soc_enum twl4030_earpiece_enum =
198 SOC_ENUM_SINGLE(TWL4030_REG_EAR_CTL, 1,
199 ARRAY_SIZE(twl4030_earpiece_texts),
200 twl4030_earpiece_texts);
201
202static const struct snd_kcontrol_new twl4030_dapm_earpiece_control =
203SOC_DAPM_ENUM("Route", twl4030_earpiece_enum);
204
205/* PreDrive Left */
206static const char *twl4030_predrivel_texts[] =
207 {"Off", "DACL1", "DACL2", "Invalid", "DACR2"};
208
209static const struct soc_enum twl4030_predrivel_enum =
210 SOC_ENUM_SINGLE(TWL4030_REG_PREDL_CTL, 1,
211 ARRAY_SIZE(twl4030_predrivel_texts),
212 twl4030_predrivel_texts);
213
214static const struct snd_kcontrol_new twl4030_dapm_predrivel_control =
215SOC_DAPM_ENUM("Route", twl4030_predrivel_enum);
216
217/* PreDrive Right */
218static const char *twl4030_predriver_texts[] =
219 {"Off", "DACR1", "DACR2", "Invalid", "DACL2"};
220
221static const struct soc_enum twl4030_predriver_enum =
222 SOC_ENUM_SINGLE(TWL4030_REG_PREDR_CTL, 1,
223 ARRAY_SIZE(twl4030_predriver_texts),
224 twl4030_predriver_texts);
225
226static const struct snd_kcontrol_new twl4030_dapm_predriver_control =
227SOC_DAPM_ENUM("Route", twl4030_predriver_enum);
228
229/* Headset Left */
230static const char *twl4030_hsol_texts[] =
231 {"Off", "DACL1", "DACL2"};
232
233static const struct soc_enum twl4030_hsol_enum =
234 SOC_ENUM_SINGLE(TWL4030_REG_HS_SEL, 1,
235 ARRAY_SIZE(twl4030_hsol_texts),
236 twl4030_hsol_texts);
237
238static const struct snd_kcontrol_new twl4030_dapm_hsol_control =
239SOC_DAPM_ENUM("Route", twl4030_hsol_enum);
240
241/* Headset Right */
242static const char *twl4030_hsor_texts[] =
243 {"Off", "DACR1", "DACR2"};
244
245static const struct soc_enum twl4030_hsor_enum =
246 SOC_ENUM_SINGLE(TWL4030_REG_HS_SEL, 4,
247 ARRAY_SIZE(twl4030_hsor_texts),
248 twl4030_hsor_texts);
249
250static const struct snd_kcontrol_new twl4030_dapm_hsor_control =
251SOC_DAPM_ENUM("Route", twl4030_hsor_enum);
252
253/* Carkit Left */
254static const char *twl4030_carkitl_texts[] =
255 {"Off", "DACL1", "DACL2"};
256
257static const struct soc_enum twl4030_carkitl_enum =
258 SOC_ENUM_SINGLE(TWL4030_REG_PRECKL_CTL, 1,
259 ARRAY_SIZE(twl4030_carkitl_texts),
260 twl4030_carkitl_texts);
261
262static const struct snd_kcontrol_new twl4030_dapm_carkitl_control =
263SOC_DAPM_ENUM("Route", twl4030_carkitl_enum);
264
265/* Carkit Right */
266static const char *twl4030_carkitr_texts[] =
267 {"Off", "DACR1", "DACR2"};
268
269static const struct soc_enum twl4030_carkitr_enum =
270 SOC_ENUM_SINGLE(TWL4030_REG_PRECKR_CTL, 1,
271 ARRAY_SIZE(twl4030_carkitr_texts),
272 twl4030_carkitr_texts);
273
274static const struct snd_kcontrol_new twl4030_dapm_carkitr_control =
275SOC_DAPM_ENUM("Route", twl4030_carkitr_enum);
276
277/* Handsfree Left */
278static const char *twl4030_handsfreel_texts[] =
279 {"Voice", "DACL1", "DACL2", "DACR2"};
280
281static const struct soc_enum twl4030_handsfreel_enum =
282 SOC_ENUM_SINGLE(TWL4030_REG_HFL_CTL, 0,
283 ARRAY_SIZE(twl4030_handsfreel_texts),
284 twl4030_handsfreel_texts);
285
286static const struct snd_kcontrol_new twl4030_dapm_handsfreel_control =
287SOC_DAPM_ENUM("Route", twl4030_handsfreel_enum);
288
289/* Handsfree Right */
290static const char *twl4030_handsfreer_texts[] =
291 {"Voice", "DACR1", "DACR2", "DACL2"};
292
293static const struct soc_enum twl4030_handsfreer_enum =
294 SOC_ENUM_SINGLE(TWL4030_REG_HFR_CTL, 0,
295 ARRAY_SIZE(twl4030_handsfreer_texts),
296 twl4030_handsfreer_texts);
297
298static const struct snd_kcontrol_new twl4030_dapm_handsfreer_control =
299SOC_DAPM_ENUM("Route", twl4030_handsfreer_enum);
300
301static int outmixer_event(struct snd_soc_dapm_widget *w,
302 struct snd_kcontrol *kcontrol, int event)
303{
304 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
305 int ret = 0;
306 int val;
307
308 switch (e->reg) {
309 case TWL4030_REG_PREDL_CTL:
310 case TWL4030_REG_PREDR_CTL:
311 case TWL4030_REG_EAR_CTL:
312 val = w->value >> e->shift_l;
313 if (val == 3) {
314 printk(KERN_WARNING
315 "Invalid MUX setting for register 0x%02x (%d)\n",
316 e->reg, val);
317 ret = -1;
318 }
319 break;
320 }
321
322 return ret;
323}
324
325static int handsfree_event(struct snd_soc_dapm_widget *w,
326 struct snd_kcontrol *kcontrol, int event)
327{
328 struct soc_enum *e = (struct soc_enum *)w->kcontrols->private_value;
329 unsigned char hs_ctl;
330
331 hs_ctl = twl4030_read_reg_cache(w->codec, e->reg);
332
333 if (hs_ctl & TWL4030_HF_CTL_REF_EN) {
334 hs_ctl |= TWL4030_HF_CTL_RAMP_EN;
335 twl4030_write(w->codec, e->reg, hs_ctl);
336 hs_ctl |= TWL4030_HF_CTL_LOOP_EN;
337 twl4030_write(w->codec, e->reg, hs_ctl);
338 hs_ctl |= TWL4030_HF_CTL_HB_EN;
339 twl4030_write(w->codec, e->reg, hs_ctl);
340 } else {
341 hs_ctl &= ~(TWL4030_HF_CTL_RAMP_EN | TWL4030_HF_CTL_LOOP_EN
342 | TWL4030_HF_CTL_HB_EN);
343 twl4030_write(w->codec, e->reg, hs_ctl);
344 }
345
346 return 0;
347}
348
349/*
350 * Some of the gain controls in TWL (mostly those which are associated with
351 * the outputs) are implemented in an interesting way:
352 * 0x0 : Power down (mute)
353 * 0x1 : 6dB
354 * 0x2 : 0 dB
355 * 0x3 : -6 dB
356 * Inverting not going to help with these.
357 * Custom volsw and volsw_2r get/put functions to handle these gain bits.
358 */
359#define SOC_DOUBLE_TLV_TWL4030(xname, xreg, shift_left, shift_right, xmax,\
360 xinvert, tlv_array) \
361{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
362 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
363 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
364 .tlv.p = (tlv_array), \
365 .info = snd_soc_info_volsw, \
366 .get = snd_soc_get_volsw_twl4030, \
367 .put = snd_soc_put_volsw_twl4030, \
368 .private_value = (unsigned long)&(struct soc_mixer_control) \
369 {.reg = xreg, .shift = shift_left, .rshift = shift_right,\
370 .max = xmax, .invert = xinvert} }
371#define SOC_DOUBLE_R_TLV_TWL4030(xname, reg_left, reg_right, xshift, xmax,\
372 xinvert, tlv_array) \
373{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
374 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
375 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
376 .tlv.p = (tlv_array), \
377 .info = snd_soc_info_volsw_2r, \
378 .get = snd_soc_get_volsw_r2_twl4030,\
379 .put = snd_soc_put_volsw_r2_twl4030, \
380 .private_value = (unsigned long)&(struct soc_mixer_control) \
381 {.reg = reg_left, .rreg = reg_right, .shift = xshift, \
382 .rshift = xshift, .max = xmax, .invert = xinvert} }
383#define SOC_SINGLE_TLV_TWL4030(xname, xreg, xshift, xmax, xinvert, tlv_array) \
384 SOC_DOUBLE_TLV_TWL4030(xname, xreg, xshift, xshift, xmax, \
385 xinvert, tlv_array)
386
387static int snd_soc_get_volsw_twl4030(struct snd_kcontrol *kcontrol,
388 struct snd_ctl_elem_value *ucontrol)
389{
390 struct soc_mixer_control *mc =
391 (struct soc_mixer_control *)kcontrol->private_value;
392 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
393 unsigned int reg = mc->reg;
394 unsigned int shift = mc->shift;
395 unsigned int rshift = mc->rshift;
396 int max = mc->max;
397 int mask = (1 << fls(max)) - 1;
398
399 ucontrol->value.integer.value[0] =
400 (snd_soc_read(codec, reg) >> shift) & mask;
401 if (ucontrol->value.integer.value[0])
402 ucontrol->value.integer.value[0] =
403 max + 1 - ucontrol->value.integer.value[0];
404
405 if (shift != rshift) {
406 ucontrol->value.integer.value[1] =
407 (snd_soc_read(codec, reg) >> rshift) & mask;
408 if (ucontrol->value.integer.value[1])
409 ucontrol->value.integer.value[1] =
410 max + 1 - ucontrol->value.integer.value[1];
411 }
412
413 return 0;
414}
415
416static int snd_soc_put_volsw_twl4030(struct snd_kcontrol *kcontrol,
417 struct snd_ctl_elem_value *ucontrol)
418{
419 struct soc_mixer_control *mc =
420 (struct soc_mixer_control *)kcontrol->private_value;
421 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
422 unsigned int reg = mc->reg;
423 unsigned int shift = mc->shift;
424 unsigned int rshift = mc->rshift;
425 int max = mc->max;
426 int mask = (1 << fls(max)) - 1;
427 unsigned short val, val2, val_mask;
428
429 val = (ucontrol->value.integer.value[0] & mask);
430
431 val_mask = mask << shift;
432 if (val)
433 val = max + 1 - val;
434 val = val << shift;
435 if (shift != rshift) {
436 val2 = (ucontrol->value.integer.value[1] & mask);
437 val_mask |= mask << rshift;
438 if (val2)
439 val2 = max + 1 - val2;
440 val |= val2 << rshift;
441 }
442 return snd_soc_update_bits(codec, reg, val_mask, val);
443}
444
445static int snd_soc_get_volsw_r2_twl4030(struct snd_kcontrol *kcontrol,
446 struct snd_ctl_elem_value *ucontrol)
447{
448 struct soc_mixer_control *mc =
449 (struct soc_mixer_control *)kcontrol->private_value;
450 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
451 unsigned int reg = mc->reg;
452 unsigned int reg2 = mc->rreg;
453 unsigned int shift = mc->shift;
454 int max = mc->max;
455 int mask = (1<<fls(max))-1;
456
457 ucontrol->value.integer.value[0] =
458 (snd_soc_read(codec, reg) >> shift) & mask;
459 ucontrol->value.integer.value[1] =
460 (snd_soc_read(codec, reg2) >> shift) & mask;
461
462 if (ucontrol->value.integer.value[0])
463 ucontrol->value.integer.value[0] =
464 max + 1 - ucontrol->value.integer.value[0];
465 if (ucontrol->value.integer.value[1])
466 ucontrol->value.integer.value[1] =
467 max + 1 - ucontrol->value.integer.value[1];
468
469 return 0;
470}
471
472static int snd_soc_put_volsw_r2_twl4030(struct snd_kcontrol *kcontrol,
473 struct snd_ctl_elem_value *ucontrol)
474{
475 struct soc_mixer_control *mc =
476 (struct soc_mixer_control *)kcontrol->private_value;
477 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
478 unsigned int reg = mc->reg;
479 unsigned int reg2 = mc->rreg;
480 unsigned int shift = mc->shift;
481 int max = mc->max;
482 int mask = (1 << fls(max)) - 1;
483 int err;
484 unsigned short val, val2, val_mask;
485
486 val_mask = mask << shift;
487 val = (ucontrol->value.integer.value[0] & mask);
488 val2 = (ucontrol->value.integer.value[1] & mask);
489
490 if (val)
491 val = max + 1 - val;
492 if (val2)
493 val2 = max + 1 - val2;
494
495 val = val << shift;
496 val2 = val2 << shift;
497
498 err = snd_soc_update_bits(codec, reg, val_mask, val);
499 if (err < 0)
500 return err;
501
502 err = snd_soc_update_bits(codec, reg2, val_mask, val2);
503 return err;
504}
505
506static int twl4030_get_left_input(struct snd_kcontrol *kcontrol,
507 struct snd_ctl_elem_value *ucontrol)
508{
509 struct snd_soc_codec *codec = kcontrol->private_data;
510 u8 reg = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICL);
511 int result = 0;
512
513 /* one bit must be set a time */
514 reg &= TWL4030_CKMIC_EN | TWL4030_AUXL_EN | TWL4030_HSMIC_EN
515 | TWL4030_MAINMIC_EN;
516 if (reg != 0) {
517 result++;
518 while ((reg & 1) == 0) {
519 result++;
520 reg >>= 1;
521 }
522 }
523
524 ucontrol->value.integer.value[0] = result;
525 return 0;
526}
527
528static int twl4030_put_left_input(struct snd_kcontrol *kcontrol,
529 struct snd_ctl_elem_value *ucontrol)
530{
531 struct snd_soc_codec *codec = kcontrol->private_data;
532 int value = ucontrol->value.integer.value[0];
533 u8 anamicl, micbias, avadc_ctl;
534
535 anamicl = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICL);
536 anamicl &= ~(TWL4030_CKMIC_EN | TWL4030_AUXL_EN | TWL4030_HSMIC_EN
537 | TWL4030_MAINMIC_EN);
538 micbias = twl4030_read_reg_cache(codec, TWL4030_REG_MICBIAS_CTL);
539 micbias &= ~(TWL4030_HSMICBIAS_EN | TWL4030_MICBIAS1_EN);
540 avadc_ctl = twl4030_read_reg_cache(codec, TWL4030_REG_AVADC_CTL);
541
542 switch (value) {
543 case 1:
544 anamicl |= TWL4030_MAINMIC_EN;
545 micbias |= TWL4030_MICBIAS1_EN;
546 break;
547 case 2:
548 anamicl |= TWL4030_HSMIC_EN;
549 micbias |= TWL4030_HSMICBIAS_EN;
550 break;
551 case 3:
552 anamicl |= TWL4030_AUXL_EN;
553 break;
554 case 4:
555 anamicl |= TWL4030_CKMIC_EN;
556 break;
557 default:
558 break;
559 }
560
561 /* If some input is selected, enable amp and ADC */
562 if (value != 0) {
563 anamicl |= TWL4030_MICAMPL_EN;
564 avadc_ctl |= TWL4030_ADCL_EN;
565 } else {
566 anamicl &= ~TWL4030_MICAMPL_EN;
567 avadc_ctl &= ~TWL4030_ADCL_EN;
568 }
569
570 twl4030_write(codec, TWL4030_REG_ANAMICL, anamicl);
571 twl4030_write(codec, TWL4030_REG_MICBIAS_CTL, micbias);
572 twl4030_write(codec, TWL4030_REG_AVADC_CTL, avadc_ctl);
573
574 return 1;
575}
576
577static int twl4030_get_right_input(struct snd_kcontrol *kcontrol,
578 struct snd_ctl_elem_value *ucontrol)
579{
580 struct snd_soc_codec *codec = kcontrol->private_data;
581 u8 reg = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICR);
582 int value = 0;
583
584 reg &= TWL4030_SUBMIC_EN|TWL4030_AUXR_EN;
585 switch (reg) {
586 case TWL4030_SUBMIC_EN:
587 value = 1;
588 break;
589 case TWL4030_AUXR_EN:
590 value = 2;
591 break;
592 default:
593 break;
594 }
595
596 ucontrol->value.integer.value[0] = value;
597 return 0;
598}
599
600static int twl4030_put_right_input(struct snd_kcontrol *kcontrol,
601 struct snd_ctl_elem_value *ucontrol)
602{
603 struct snd_soc_codec *codec = kcontrol->private_data;
604 int value = ucontrol->value.integer.value[0];
605 u8 anamicr, micbias, avadc_ctl;
606
607 anamicr = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICR);
608 anamicr &= ~(TWL4030_SUBMIC_EN|TWL4030_AUXR_EN);
609 micbias = twl4030_read_reg_cache(codec, TWL4030_REG_MICBIAS_CTL);
610 micbias &= ~TWL4030_MICBIAS2_EN;
611 avadc_ctl = twl4030_read_reg_cache(codec, TWL4030_REG_AVADC_CTL);
612
613 switch (value) {
614 case 1:
615 anamicr |= TWL4030_SUBMIC_EN;
616 micbias |= TWL4030_MICBIAS2_EN;
617 break;
618 case 2:
619 anamicr |= TWL4030_AUXR_EN;
620 break;
621 default:
622 break;
623 }
624
625 if (value != 0) {
626 anamicr |= TWL4030_MICAMPR_EN;
627 avadc_ctl |= TWL4030_ADCR_EN;
628 } else {
629 anamicr &= ~TWL4030_MICAMPR_EN;
630 avadc_ctl &= ~TWL4030_ADCR_EN;
631 }
632
633 twl4030_write(codec, TWL4030_REG_ANAMICR, anamicr);
634 twl4030_write(codec, TWL4030_REG_MICBIAS_CTL, micbias);
635 twl4030_write(codec, TWL4030_REG_AVADC_CTL, avadc_ctl);
636
637 return 1;
638}
639
640static const char *twl4030_left_in_sel[] = {
641 "None",
642 "Main Mic",
643 "Headset Mic",
644 "Line In",
645 "Carkit Mic",
646};
647
648static const char *twl4030_right_in_sel[] = {
649 "None",
650 "Sub Mic",
651 "Line In",
652};
653
654static const struct soc_enum twl4030_left_input_mux =
655 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(twl4030_left_in_sel),
656 twl4030_left_in_sel);
657
658static const struct soc_enum twl4030_right_input_mux =
659 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(twl4030_right_in_sel),
660 twl4030_right_in_sel);
661
662/*
663 * FGAIN volume control:
664 * from -62 to 0 dB in 1 dB steps (mute instead of -63 dB)
665 */
666static DECLARE_TLV_DB_SCALE(digital_fine_tlv, -6300, 100, 1);
667
668/*
669 * CGAIN volume control:
670 * 0 dB to 12 dB in 6 dB steps
671 * value 2 and 3 means 12 dB
672 */
673static DECLARE_TLV_DB_SCALE(digital_coarse_tlv, 0, 600, 0);
674
675/*
676 * Analog playback gain
677 * -24 dB to 12 dB in 2 dB steps
678 */
679static DECLARE_TLV_DB_SCALE(analog_tlv, -2400, 200, 0);
680
681/*
682 * Gain controls tied to outputs
683 * -6 dB to 6 dB in 6 dB steps (mute instead of -12)
684 */
685static DECLARE_TLV_DB_SCALE(output_tvl, -1200, 600, 1);
686
687/*
688 * Capture gain after the ADCs
689 * from 0 dB to 31 dB in 1 dB steps
690 */
691static DECLARE_TLV_DB_SCALE(digital_capture_tlv, 0, 100, 0);
692
693/*
694 * Gain control for input amplifiers
695 * 0 dB to 30 dB in 6 dB steps
696 */
697static DECLARE_TLV_DB_SCALE(input_gain_tlv, 0, 600, 0);
698
699static const struct snd_kcontrol_new twl4030_snd_controls[] = {
700 /* Common playback gain controls */
701 SOC_DOUBLE_R_TLV("DAC1 Digital Fine Playback Volume",
702 TWL4030_REG_ARXL1PGA, TWL4030_REG_ARXR1PGA,
703 0, 0x3f, 0, digital_fine_tlv),
704 SOC_DOUBLE_R_TLV("DAC2 Digital Fine Playback Volume",
705 TWL4030_REG_ARXL2PGA, TWL4030_REG_ARXR2PGA,
706 0, 0x3f, 0, digital_fine_tlv),
707
708 SOC_DOUBLE_R_TLV("DAC1 Digital Coarse Playback Volume",
709 TWL4030_REG_ARXL1PGA, TWL4030_REG_ARXR1PGA,
710 6, 0x2, 0, digital_coarse_tlv),
711 SOC_DOUBLE_R_TLV("DAC2 Digital Coarse Playback Volume",
712 TWL4030_REG_ARXL2PGA, TWL4030_REG_ARXR2PGA,
713 6, 0x2, 0, digital_coarse_tlv),
714
715 SOC_DOUBLE_R_TLV("DAC1 Analog Playback Volume",
716 TWL4030_REG_ARXL1_APGA_CTL, TWL4030_REG_ARXR1_APGA_CTL,
717 3, 0x12, 1, analog_tlv),
718 SOC_DOUBLE_R_TLV("DAC2 Analog Playback Volume",
719 TWL4030_REG_ARXL2_APGA_CTL, TWL4030_REG_ARXR2_APGA_CTL,
720 3, 0x12, 1, analog_tlv),
721 SOC_DOUBLE_R("DAC1 Analog Playback Switch",
722 TWL4030_REG_ARXL1_APGA_CTL, TWL4030_REG_ARXR1_APGA_CTL,
723 1, 1, 0),
724 SOC_DOUBLE_R("DAC2 Analog Playback Switch",
725 TWL4030_REG_ARXL2_APGA_CTL, TWL4030_REG_ARXR2_APGA_CTL,
726 1, 1, 0),
727
728 /* Separate output gain controls */
729 SOC_DOUBLE_R_TLV_TWL4030("PreDriv Playback Volume",
730 TWL4030_REG_PREDL_CTL, TWL4030_REG_PREDR_CTL,
731 4, 3, 0, output_tvl),
732
733 SOC_DOUBLE_TLV_TWL4030("Headset Playback Volume",
734 TWL4030_REG_HS_GAIN_SET, 0, 2, 3, 0, output_tvl),
735
736 SOC_DOUBLE_R_TLV_TWL4030("Carkit Playback Volume",
737 TWL4030_REG_PRECKL_CTL, TWL4030_REG_PRECKR_CTL,
738 4, 3, 0, output_tvl),
739
740 SOC_SINGLE_TLV_TWL4030("Earpiece Playback Volume",
741 TWL4030_REG_EAR_CTL, 4, 3, 0, output_tvl),
742
743 /* Common capture gain controls */
744 SOC_DOUBLE_R_TLV("Capture Volume",
745 TWL4030_REG_ATXL1PGA, TWL4030_REG_ATXR1PGA,
746 0, 0x1f, 0, digital_capture_tlv),
747
748 SOC_DOUBLE_TLV("Input Boost Volume", TWL4030_REG_ANAMIC_GAIN,
749 0, 3, 5, 0, input_gain_tlv),
750
751 /* Input source controls */
752 SOC_ENUM_EXT("Left Input Source", twl4030_left_input_mux,
753 twl4030_get_left_input, twl4030_put_left_input),
754 SOC_ENUM_EXT("Right Input Source", twl4030_right_input_mux,
755 twl4030_get_right_input, twl4030_put_right_input),
756};
757
758/* add non dapm controls */
759static int twl4030_add_controls(struct snd_soc_codec *codec)
760{
761 int err, i;
762
763 for (i = 0; i < ARRAY_SIZE(twl4030_snd_controls); i++) {
764 err = snd_ctl_add(codec->card,
765 snd_soc_cnew(&twl4030_snd_controls[i],
766 codec, NULL));
767 if (err < 0)
768 return err;
769 }
770
771 return 0;
772}
773
774static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
775 SND_SOC_DAPM_INPUT("INL"),
776 SND_SOC_DAPM_INPUT("INR"),
777
778 SND_SOC_DAPM_OUTPUT("OUTL"),
779 SND_SOC_DAPM_OUTPUT("OUTR"),
780 SND_SOC_DAPM_OUTPUT("EARPIECE"),
781 SND_SOC_DAPM_OUTPUT("PREDRIVEL"),
782 SND_SOC_DAPM_OUTPUT("PREDRIVER"),
783 SND_SOC_DAPM_OUTPUT("HSOL"),
784 SND_SOC_DAPM_OUTPUT("HSOR"),
785 SND_SOC_DAPM_OUTPUT("CARKITL"),
786 SND_SOC_DAPM_OUTPUT("CARKITR"),
787 SND_SOC_DAPM_OUTPUT("HFL"),
788 SND_SOC_DAPM_OUTPUT("HFR"),
789
790 /* DACs */
791 SND_SOC_DAPM_DAC("DAC Right1", "Right Front Playback",
792 TWL4030_REG_AVDAC_CTL, 0, 0),
793 SND_SOC_DAPM_DAC("DAC Left1", "Left Front Playback",
794 TWL4030_REG_AVDAC_CTL, 1, 0),
795 SND_SOC_DAPM_DAC("DAC Right2", "Right Rear Playback",
796 TWL4030_REG_AVDAC_CTL, 2, 0),
797 SND_SOC_DAPM_DAC("DAC Left2", "Left Rear Playback",
798 TWL4030_REG_AVDAC_CTL, 3, 0),
799
800 /* Analog PGAs */
801 SND_SOC_DAPM_PGA("ARXR1_APGA", TWL4030_REG_ARXR1_APGA_CTL,
802 0, 0, NULL, 0),
803 SND_SOC_DAPM_PGA("ARXL1_APGA", TWL4030_REG_ARXL1_APGA_CTL,
804 0, 0, NULL, 0),
805 SND_SOC_DAPM_PGA("ARXR2_APGA", TWL4030_REG_ARXR2_APGA_CTL,
806 0, 0, NULL, 0),
807 SND_SOC_DAPM_PGA("ARXL2_APGA", TWL4030_REG_ARXL2_APGA_CTL,
808 0, 0, NULL, 0),
809
810 /* Output MUX controls */
811 /* Earpiece */
812 SND_SOC_DAPM_MUX_E("Earpiece Mux", SND_SOC_NOPM, 0, 0,
813 &twl4030_dapm_earpiece_control, outmixer_event,
814 SND_SOC_DAPM_PRE_REG),
815 /* PreDrivL/R */
816 SND_SOC_DAPM_MUX_E("PredriveL Mux", SND_SOC_NOPM, 0, 0,
817 &twl4030_dapm_predrivel_control, outmixer_event,
818 SND_SOC_DAPM_PRE_REG),
819 SND_SOC_DAPM_MUX_E("PredriveR Mux", SND_SOC_NOPM, 0, 0,
820 &twl4030_dapm_predriver_control, outmixer_event,
821 SND_SOC_DAPM_PRE_REG),
822 /* HeadsetL/R */
823 SND_SOC_DAPM_MUX("HeadsetL Mux", SND_SOC_NOPM, 0, 0,
824 &twl4030_dapm_hsol_control),
825 SND_SOC_DAPM_MUX("HeadsetR Mux", SND_SOC_NOPM, 0, 0,
826 &twl4030_dapm_hsor_control),
827 /* CarkitL/R */
828 SND_SOC_DAPM_MUX("CarkitL Mux", SND_SOC_NOPM, 0, 0,
829 &twl4030_dapm_carkitl_control),
830 SND_SOC_DAPM_MUX("CarkitR Mux", SND_SOC_NOPM, 0, 0,
831 &twl4030_dapm_carkitr_control),
832 /* HandsfreeL/R */
833 SND_SOC_DAPM_MUX_E("HandsfreeL Mux", TWL4030_REG_HFL_CTL, 5, 0,
834 &twl4030_dapm_handsfreel_control, handsfree_event,
835 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
836 SND_SOC_DAPM_MUX_E("HandsfreeR Mux", TWL4030_REG_HFR_CTL, 5, 0,
837 &twl4030_dapm_handsfreer_control, handsfree_event,
838 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
839
840 SND_SOC_DAPM_ADC("ADCL", "Left Capture", SND_SOC_NOPM, 0, 0),
841 SND_SOC_DAPM_ADC("ADCR", "Right Capture", SND_SOC_NOPM, 0, 0),
842};
843
844static const struct snd_soc_dapm_route intercon[] = {
845 {"ARXL1_APGA", NULL, "DAC Left1"},
846 {"ARXR1_APGA", NULL, "DAC Right1"},
847 {"ARXL2_APGA", NULL, "DAC Left2"},
848 {"ARXR2_APGA", NULL, "DAC Right2"},
849
850 /* Internal playback routings */
851 /* Earpiece */
852 {"Earpiece Mux", "DACL1", "ARXL1_APGA"},
853 {"Earpiece Mux", "DACL2", "ARXL2_APGA"},
854 {"Earpiece Mux", "DACR1", "ARXR1_APGA"},
855 /* PreDrivL */
856 {"PredriveL Mux", "DACL1", "ARXL1_APGA"},
857 {"PredriveL Mux", "DACL2", "ARXL2_APGA"},
858 {"PredriveL Mux", "DACR2", "ARXR2_APGA"},
859 /* PreDrivR */
860 {"PredriveR Mux", "DACR1", "ARXR1_APGA"},
861 {"PredriveR Mux", "DACR2", "ARXR2_APGA"},
862 {"PredriveR Mux", "DACL2", "ARXL2_APGA"},
863 /* HeadsetL */
864 {"HeadsetL Mux", "DACL1", "ARXL1_APGA"},
865 {"HeadsetL Mux", "DACL2", "ARXL2_APGA"},
866 /* HeadsetR */
867 {"HeadsetR Mux", "DACR1", "ARXR1_APGA"},
868 {"HeadsetR Mux", "DACR2", "ARXR2_APGA"},
869 /* CarkitL */
870 {"CarkitL Mux", "DACL1", "ARXL1_APGA"},
871 {"CarkitL Mux", "DACL2", "ARXL2_APGA"},
872 /* CarkitR */
873 {"CarkitR Mux", "DACR1", "ARXR1_APGA"},
874 {"CarkitR Mux", "DACR2", "ARXR2_APGA"},
875 /* HandsfreeL */
876 {"HandsfreeL Mux", "DACL1", "ARXL1_APGA"},
877 {"HandsfreeL Mux", "DACL2", "ARXL2_APGA"},
878 {"HandsfreeL Mux", "DACR2", "ARXR2_APGA"},
879 /* HandsfreeR */
880 {"HandsfreeR Mux", "DACR1", "ARXR1_APGA"},
881 {"HandsfreeR Mux", "DACR2", "ARXR2_APGA"},
882 {"HandsfreeR Mux", "DACL2", "ARXL2_APGA"},
883
884 /* outputs */
885 {"OUTL", NULL, "ARXL2_APGA"},
886 {"OUTR", NULL, "ARXR2_APGA"},
887 {"EARPIECE", NULL, "Earpiece Mux"},
888 {"PREDRIVEL", NULL, "PredriveL Mux"},
889 {"PREDRIVER", NULL, "PredriveR Mux"},
890 {"HSOL", NULL, "HeadsetL Mux"},
891 {"HSOR", NULL, "HeadsetR Mux"},
892 {"CARKITL", NULL, "CarkitL Mux"},
893 {"CARKITR", NULL, "CarkitR Mux"},
894 {"HFL", NULL, "HandsfreeL Mux"},
895 {"HFR", NULL, "HandsfreeR Mux"},
896
897 /* inputs */
898 {"ADCL", NULL, "INL"},
899 {"ADCR", NULL, "INR"},
900};
901
902static int twl4030_add_widgets(struct snd_soc_codec *codec)
903{
904 snd_soc_dapm_new_controls(codec, twl4030_dapm_widgets,
905 ARRAY_SIZE(twl4030_dapm_widgets));
906
907 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
908
909 snd_soc_dapm_new_widgets(codec);
910 return 0;
911}
912
913static void twl4030_power_up(struct snd_soc_codec *codec)
914{
915 u8 anamicl, regmisc1, byte, popn;
916 int i = 0;
917
918 /* set CODECPDZ to turn on codec */
919 twl4030_set_codecpdz(codec);
920
921 /* initiate offset cancellation */
922 anamicl = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICL);
923 twl4030_write(codec, TWL4030_REG_ANAMICL,
924 anamicl | TWL4030_CNCL_OFFSET_START);
925
926 /* wait for offset cancellation to complete */
927 do {
928 /* this takes a little while, so don't slam i2c */
929 udelay(2000);
930 twl4030_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte,
931 TWL4030_REG_ANAMICL);
932 } while ((i++ < 100) &&
933 ((byte & TWL4030_CNCL_OFFSET_START) ==
934 TWL4030_CNCL_OFFSET_START));
935
936 /* anti-pop when changing analog gain */
937 regmisc1 = twl4030_read_reg_cache(codec, TWL4030_REG_MISC_SET_1);
938 twl4030_write(codec, TWL4030_REG_MISC_SET_1,
939 regmisc1 | TWL4030_SMOOTH_ANAVOL_EN);
940
941 /* toggle CODECPDZ as per TRM */
942 twl4030_clear_codecpdz(codec);
943 twl4030_set_codecpdz(codec);
944
945 /* program anti-pop with bias ramp delay */
946 popn = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET);
947 popn &= TWL4030_RAMP_DELAY;
948 popn |= TWL4030_RAMP_DELAY_645MS;
949 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, popn);
950 popn |= TWL4030_VMID_EN;
951 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, popn);
952
953 /* enable anti-pop ramp */
954 popn |= TWL4030_RAMP_EN;
955 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, popn);
956}
957
958static void twl4030_power_down(struct snd_soc_codec *codec)
959{
960 u8 popn;
961
962 /* disable anti-pop ramp */
963 popn = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET);
964 popn &= ~TWL4030_RAMP_EN;
965 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, popn);
966
967 /* disable bias out */
968 popn &= ~TWL4030_VMID_EN;
969 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, popn);
970
971 /* power down */
972 twl4030_clear_codecpdz(codec);
973}
974
975static int twl4030_set_bias_level(struct snd_soc_codec *codec,
976 enum snd_soc_bias_level level)
977{
978 switch (level) {
979 case SND_SOC_BIAS_ON:
980 twl4030_power_up(codec);
981 break;
982 case SND_SOC_BIAS_PREPARE:
983 /* TODO: develop a twl4030_prepare function */
984 break;
985 case SND_SOC_BIAS_STANDBY:
986 /* TODO: develop a twl4030_standby function */
987 twl4030_power_down(codec);
988 break;
989 case SND_SOC_BIAS_OFF:
990 twl4030_power_down(codec);
991 break;
992 }
993 codec->bias_level = level;
994
995 return 0;
996}
997
998static int twl4030_hw_params(struct snd_pcm_substream *substream,
999 struct snd_pcm_hw_params *params,
1000 struct snd_soc_dai *dai)
1001{
1002 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1003 struct snd_soc_device *socdev = rtd->socdev;
1004 struct snd_soc_codec *codec = socdev->codec;
1005 u8 mode, old_mode, format, old_format;
1006
1007
1008 /* bit rate */
1009 old_mode = twl4030_read_reg_cache(codec,
1010 TWL4030_REG_CODEC_MODE) & ~TWL4030_CODECPDZ;
1011 mode = old_mode & ~TWL4030_APLL_RATE;
1012
1013 switch (params_rate(params)) {
1014 case 8000:
1015 mode |= TWL4030_APLL_RATE_8000;
1016 break;
1017 case 11025:
1018 mode |= TWL4030_APLL_RATE_11025;
1019 break;
1020 case 12000:
1021 mode |= TWL4030_APLL_RATE_12000;
1022 break;
1023 case 16000:
1024 mode |= TWL4030_APLL_RATE_16000;
1025 break;
1026 case 22050:
1027 mode |= TWL4030_APLL_RATE_22050;
1028 break;
1029 case 24000:
1030 mode |= TWL4030_APLL_RATE_24000;
1031 break;
1032 case 32000:
1033 mode |= TWL4030_APLL_RATE_32000;
1034 break;
1035 case 44100:
1036 mode |= TWL4030_APLL_RATE_44100;
1037 break;
1038 case 48000:
1039 mode |= TWL4030_APLL_RATE_48000;
1040 break;
1041 default:
1042 printk(KERN_ERR "TWL4030 hw params: unknown rate %d\n",
1043 params_rate(params));
1044 return -EINVAL;
1045 }
1046
1047 if (mode != old_mode) {
1048 /* change rate and set CODECPDZ */
1049 twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode);
1050 twl4030_set_codecpdz(codec);
1051 }
1052
1053 /* sample size */
1054 old_format = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF);
1055 format = old_format;
1056 format &= ~TWL4030_DATA_WIDTH;
1057 switch (params_format(params)) {
1058 case SNDRV_PCM_FORMAT_S16_LE:
1059 format |= TWL4030_DATA_WIDTH_16S_16W;
1060 break;
1061 case SNDRV_PCM_FORMAT_S24_LE:
1062 format |= TWL4030_DATA_WIDTH_32S_24W;
1063 break;
1064 default:
1065 printk(KERN_ERR "TWL4030 hw params: unknown format %d\n",
1066 params_format(params));
1067 return -EINVAL;
1068 }
1069
1070 if (format != old_format) {
1071
1072 /* clear CODECPDZ before changing format (codec requirement) */
1073 twl4030_clear_codecpdz(codec);
1074
1075 /* change format */
1076 twl4030_write(codec, TWL4030_REG_AUDIO_IF, format);
1077
1078 /* set CODECPDZ afterwards */
1079 twl4030_set_codecpdz(codec);
1080 }
1081 return 0;
1082}
1083
1084static int twl4030_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1085 int clk_id, unsigned int freq, int dir)
1086{
1087 struct snd_soc_codec *codec = codec_dai->codec;
1088 u8 infreq;
1089
1090 switch (freq) {
1091 case 19200000:
1092 infreq = TWL4030_APLL_INFREQ_19200KHZ;
1093 break;
1094 case 26000000:
1095 infreq = TWL4030_APLL_INFREQ_26000KHZ;
1096 break;
1097 case 38400000:
1098 infreq = TWL4030_APLL_INFREQ_38400KHZ;
1099 break;
1100 default:
1101 printk(KERN_ERR "TWL4030 set sysclk: unknown rate %d\n",
1102 freq);
1103 return -EINVAL;
1104 }
1105
1106 infreq |= TWL4030_APLL_EN;
1107 twl4030_write(codec, TWL4030_REG_APLL_CTL, infreq);
1108
1109 return 0;
1110}
1111
1112static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai,
1113 unsigned int fmt)
1114{
1115 struct snd_soc_codec *codec = codec_dai->codec;
1116 u8 old_format, format;
1117
1118 /* get format */
1119 old_format = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF);
1120 format = old_format;
1121
1122 /* set master/slave audio interface */
1123 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1124 case SND_SOC_DAIFMT_CBM_CFM:
1125 format &= ~(TWL4030_AIF_SLAVE_EN);
1126 format &= ~(TWL4030_CLK256FS_EN);
1127 break;
1128 case SND_SOC_DAIFMT_CBS_CFS:
1129 format |= TWL4030_AIF_SLAVE_EN;
1130 format |= TWL4030_CLK256FS_EN;
1131 break;
1132 default:
1133 return -EINVAL;
1134 }
1135
1136 /* interface format */
1137 format &= ~TWL4030_AIF_FORMAT;
1138 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1139 case SND_SOC_DAIFMT_I2S:
1140 format |= TWL4030_AIF_FORMAT_CODEC;
1141 break;
1142 default:
1143 return -EINVAL;
1144 }
1145
1146 if (format != old_format) {
1147
1148 /* clear CODECPDZ before changing format (codec requirement) */
1149 twl4030_clear_codecpdz(codec);
1150
1151 /* change format */
1152 twl4030_write(codec, TWL4030_REG_AUDIO_IF, format);
1153
1154 /* set CODECPDZ afterwards */
1155 twl4030_set_codecpdz(codec);
1156 }
1157
1158 return 0;
1159}
1160
1161#define TWL4030_RATES (SNDRV_PCM_RATE_8000_48000)
1162#define TWL4030_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FORMAT_S24_LE)
1163
1164struct snd_soc_dai twl4030_dai = {
1165 .name = "twl4030",
1166 .playback = {
1167 .stream_name = "Playback",
1168 .channels_min = 2,
1169 .channels_max = 2,
1170 .rates = TWL4030_RATES,
1171 .formats = TWL4030_FORMATS,},
1172 .capture = {
1173 .stream_name = "Capture",
1174 .channels_min = 2,
1175 .channels_max = 2,
1176 .rates = TWL4030_RATES,
1177 .formats = TWL4030_FORMATS,},
1178 .ops = {
1179 .hw_params = twl4030_hw_params,
1180 .set_sysclk = twl4030_set_dai_sysclk,
1181 .set_fmt = twl4030_set_dai_fmt,
1182 }
1183};
1184EXPORT_SYMBOL_GPL(twl4030_dai);
1185
1186static int twl4030_suspend(struct platform_device *pdev, pm_message_t state)
1187{
1188 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1189 struct snd_soc_codec *codec = socdev->codec;
1190
1191 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF);
1192
1193 return 0;
1194}
1195
1196static int twl4030_resume(struct platform_device *pdev)
1197{
1198 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1199 struct snd_soc_codec *codec = socdev->codec;
1200
1201 twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1202 twl4030_set_bias_level(codec, codec->suspend_bias_level);
1203 return 0;
1204}
1205
1206/*
1207 * initialize the driver
1208 * register the mixer and dsp interfaces with the kernel
1209 */
1210
1211static int twl4030_init(struct snd_soc_device *socdev)
1212{
1213 struct snd_soc_codec *codec = socdev->codec;
1214 int ret = 0;
1215
1216 printk(KERN_INFO "TWL4030 Audio Codec init \n");
1217
1218 codec->name = "twl4030";
1219 codec->owner = THIS_MODULE;
1220 codec->read = twl4030_read_reg_cache;
1221 codec->write = twl4030_write;
1222 codec->set_bias_level = twl4030_set_bias_level;
1223 codec->dai = &twl4030_dai;
1224 codec->num_dai = 1;
1225 codec->reg_cache_size = sizeof(twl4030_reg);
1226 codec->reg_cache = kmemdup(twl4030_reg, sizeof(twl4030_reg),
1227 GFP_KERNEL);
1228 if (codec->reg_cache == NULL)
1229 return -ENOMEM;
1230
1231 /* register pcms */
1232 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1233 if (ret < 0) {
1234 printk(KERN_ERR "twl4030: failed to create pcms\n");
1235 goto pcm_err;
1236 }
1237
1238 twl4030_init_chip(codec);
1239
1240 /* power on device */
1241 twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1242
1243 twl4030_add_controls(codec);
1244 twl4030_add_widgets(codec);
1245
1246 ret = snd_soc_init_card(socdev);
1247 if (ret < 0) {
1248 printk(KERN_ERR "twl4030: failed to register card\n");
1249 goto card_err;
1250 }
1251
1252 return ret;
1253
1254card_err:
1255 snd_soc_free_pcms(socdev);
1256 snd_soc_dapm_free(socdev);
1257pcm_err:
1258 kfree(codec->reg_cache);
1259 return ret;
1260}
1261
1262static struct snd_soc_device *twl4030_socdev;
1263
1264static int twl4030_probe(struct platform_device *pdev)
1265{
1266 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1267 struct snd_soc_codec *codec;
1268
1269 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
1270 if (codec == NULL)
1271 return -ENOMEM;
1272
1273 socdev->codec = codec;
1274 mutex_init(&codec->mutex);
1275 INIT_LIST_HEAD(&codec->dapm_widgets);
1276 INIT_LIST_HEAD(&codec->dapm_paths);
1277
1278 twl4030_socdev = socdev;
1279 twl4030_init(socdev);
1280
1281 return 0;
1282}
1283
1284static int twl4030_remove(struct platform_device *pdev)
1285{
1286 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1287 struct snd_soc_codec *codec = socdev->codec;
1288
1289 printk(KERN_INFO "TWL4030 Audio Codec remove\n");
1290 kfree(codec);
1291
1292 return 0;
1293}
1294
1295struct snd_soc_codec_device soc_codec_dev_twl4030 = {
1296 .probe = twl4030_probe,
1297 .remove = twl4030_remove,
1298 .suspend = twl4030_suspend,
1299 .resume = twl4030_resume,
1300};
1301EXPORT_SYMBOL_GPL(soc_codec_dev_twl4030);
1302
1303static int __init twl4030_modinit(void)
1304{
1305 return snd_soc_register_dai(&twl4030_dai);
1306}
1307module_init(twl4030_modinit);
1308
1309static void __exit twl4030_exit(void)
1310{
1311 snd_soc_unregister_dai(&twl4030_dai);
1312}
1313module_exit(twl4030_exit);
1314
1315MODULE_DESCRIPTION("ASoC TWL4030 codec driver");
1316MODULE_AUTHOR("Steve Sakoman");
1317MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/twl4030.h b/sound/soc/codecs/twl4030.h
new file mode 100644
index 000000000000..54615c76802b
--- /dev/null
+++ b/sound/soc/codecs/twl4030.h
@@ -0,0 +1,219 @@
1/*
2 * ALSA SoC TWL4030 codec driver
3 *
4 * Author: Steve Sakoman <steve@sakoman.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21
22#ifndef __TWL4030_AUDIO_H__
23#define __TWL4030_AUDIO_H__
24
25#define TWL4030_REG_CODEC_MODE 0x1
26#define TWL4030_REG_OPTION 0x2
27#define TWL4030_REG_UNKNOWN 0x3
28#define TWL4030_REG_MICBIAS_CTL 0x4
29#define TWL4030_REG_ANAMICL 0x5
30#define TWL4030_REG_ANAMICR 0x6
31#define TWL4030_REG_AVADC_CTL 0x7
32#define TWL4030_REG_ADCMICSEL 0x8
33#define TWL4030_REG_DIGMIXING 0x9
34#define TWL4030_REG_ATXL1PGA 0xA
35#define TWL4030_REG_ATXR1PGA 0xB
36#define TWL4030_REG_AVTXL2PGA 0xC
37#define TWL4030_REG_AVTXR2PGA 0xD
38#define TWL4030_REG_AUDIO_IF 0xE
39#define TWL4030_REG_VOICE_IF 0xF
40#define TWL4030_REG_ARXR1PGA 0x10
41#define TWL4030_REG_ARXL1PGA 0x11
42#define TWL4030_REG_ARXR2PGA 0x12
43#define TWL4030_REG_ARXL2PGA 0x13
44#define TWL4030_REG_VRXPGA 0x14
45#define TWL4030_REG_VSTPGA 0x15
46#define TWL4030_REG_VRX2ARXPGA 0x16
47#define TWL4030_REG_AVDAC_CTL 0x17
48#define TWL4030_REG_ARX2VTXPGA 0x18
49#define TWL4030_REG_ARXL1_APGA_CTL 0x19
50#define TWL4030_REG_ARXR1_APGA_CTL 0x1A
51#define TWL4030_REG_ARXL2_APGA_CTL 0x1B
52#define TWL4030_REG_ARXR2_APGA_CTL 0x1C
53#define TWL4030_REG_ATX2ARXPGA 0x1D
54#define TWL4030_REG_BT_IF 0x1E
55#define TWL4030_REG_BTPGA 0x1F
56#define TWL4030_REG_BTSTPGA 0x20
57#define TWL4030_REG_EAR_CTL 0x21
58#define TWL4030_REG_HS_SEL 0x22
59#define TWL4030_REG_HS_GAIN_SET 0x23
60#define TWL4030_REG_HS_POPN_SET 0x24
61#define TWL4030_REG_PREDL_CTL 0x25
62#define TWL4030_REG_PREDR_CTL 0x26
63#define TWL4030_REG_PRECKL_CTL 0x27
64#define TWL4030_REG_PRECKR_CTL 0x28
65#define TWL4030_REG_HFL_CTL 0x29
66#define TWL4030_REG_HFR_CTL 0x2A
67#define TWL4030_REG_ALC_CTL 0x2B
68#define TWL4030_REG_ALC_SET1 0x2C
69#define TWL4030_REG_ALC_SET2 0x2D
70#define TWL4030_REG_BOOST_CTL 0x2E
71#define TWL4030_REG_SOFTVOL_CTL 0x2F
72#define TWL4030_REG_DTMF_FREQSEL 0x30
73#define TWL4030_REG_DTMF_TONEXT1H 0x31
74#define TWL4030_REG_DTMF_TONEXT1L 0x32
75#define TWL4030_REG_DTMF_TONEXT2H 0x33
76#define TWL4030_REG_DTMF_TONEXT2L 0x34
77#define TWL4030_REG_DTMF_TONOFF 0x35
78#define TWL4030_REG_DTMF_WANONOFF 0x36
79#define TWL4030_REG_I2S_RX_SCRAMBLE_H 0x37
80#define TWL4030_REG_I2S_RX_SCRAMBLE_M 0x38
81#define TWL4030_REG_I2S_RX_SCRAMBLE_L 0x39
82#define TWL4030_REG_APLL_CTL 0x3A
83#define TWL4030_REG_DTMF_CTL 0x3B
84#define TWL4030_REG_DTMF_PGA_CTL2 0x3C
85#define TWL4030_REG_DTMF_PGA_CTL1 0x3D
86#define TWL4030_REG_MISC_SET_1 0x3E
87#define TWL4030_REG_PCMBTMUX 0x3F
88#define TWL4030_REG_RX_PATH_SEL 0x43
89#define TWL4030_REG_VDL_APGA_CTL 0x44
90#define TWL4030_REG_VIBRA_CTL 0x45
91#define TWL4030_REG_VIBRA_SET 0x46
92#define TWL4030_REG_VIBRA_PWM_SET 0x47
93#define TWL4030_REG_ANAMIC_GAIN 0x48
94#define TWL4030_REG_MISC_SET_2 0x49
95
96#define TWL4030_CACHEREGNUM (TWL4030_REG_MISC_SET_2 + 1)
97
98/* Bitfield Definitions */
99
100/* TWL4030_CODEC_MODE (0x01) Fields */
101
102#define TWL4030_APLL_RATE 0xF0
103#define TWL4030_APLL_RATE_8000 0x00
104#define TWL4030_APLL_RATE_11025 0x10
105#define TWL4030_APLL_RATE_12000 0x20
106#define TWL4030_APLL_RATE_16000 0x40
107#define TWL4030_APLL_RATE_22050 0x50
108#define TWL4030_APLL_RATE_24000 0x60
109#define TWL4030_APLL_RATE_32000 0x80
110#define TWL4030_APLL_RATE_44100 0x90
111#define TWL4030_APLL_RATE_48000 0xA0
112#define TWL4030_SEL_16K 0x04
113#define TWL4030_CODECPDZ 0x02
114#define TWL4030_OPT_MODE 0x01
115
116/* TWL4030_REG_MICBIAS_CTL (0x04) Fields */
117
118#define TWL4030_MICBIAS2_CTL 0x40
119#define TWL4030_MICBIAS1_CTL 0x20
120#define TWL4030_HSMICBIAS_EN 0x04
121#define TWL4030_MICBIAS2_EN 0x02
122#define TWL4030_MICBIAS1_EN 0x01
123
124/* ANAMICL (0x05) Fields */
125
126#define TWL4030_CNCL_OFFSET_START 0x80
127#define TWL4030_OFFSET_CNCL_SEL 0x60
128#define TWL4030_OFFSET_CNCL_SEL_ARX1 0x00
129#define TWL4030_OFFSET_CNCL_SEL_ARX2 0x20
130#define TWL4030_OFFSET_CNCL_SEL_VRX 0x40
131#define TWL4030_OFFSET_CNCL_SEL_ALL 0x60
132#define TWL4030_MICAMPL_EN 0x10
133#define TWL4030_CKMIC_EN 0x08
134#define TWL4030_AUXL_EN 0x04
135#define TWL4030_HSMIC_EN 0x02
136#define TWL4030_MAINMIC_EN 0x01
137
138/* ANAMICR (0x06) Fields */
139
140#define TWL4030_MICAMPR_EN 0x10
141#define TWL4030_AUXR_EN 0x04
142#define TWL4030_SUBMIC_EN 0x01
143
144/* AVADC_CTL (0x07) Fields */
145
146#define TWL4030_ADCL_EN 0x08
147#define TWL4030_AVADC_CLK_PRIORITY 0x04
148#define TWL4030_ADCR_EN 0x02
149
150/* AUDIO_IF (0x0E) Fields */
151
152#define TWL4030_AIF_SLAVE_EN 0x80
153#define TWL4030_DATA_WIDTH 0x60
154#define TWL4030_DATA_WIDTH_16S_16W 0x00
155#define TWL4030_DATA_WIDTH_32S_16W 0x40
156#define TWL4030_DATA_WIDTH_32S_24W 0x60
157#define TWL4030_AIF_FORMAT 0x18
158#define TWL4030_AIF_FORMAT_CODEC 0x00
159#define TWL4030_AIF_FORMAT_LEFT 0x08
160#define TWL4030_AIF_FORMAT_RIGHT 0x10
161#define TWL4030_AIF_FORMAT_TDM 0x18
162#define TWL4030_AIF_TRI_EN 0x04
163#define TWL4030_CLK256FS_EN 0x02
164#define TWL4030_AIF_EN 0x01
165
166/* HS_GAIN_SET (0x23) Fields */
167
168#define TWL4030_HSR_GAIN 0x0C
169#define TWL4030_HSR_GAIN_PWR_DOWN 0x00
170#define TWL4030_HSR_GAIN_PLUS_6DB 0x04
171#define TWL4030_HSR_GAIN_0DB 0x08
172#define TWL4030_HSR_GAIN_MINUS_6DB 0x0C
173#define TWL4030_HSL_GAIN 0x03
174#define TWL4030_HSL_GAIN_PWR_DOWN 0x00
175#define TWL4030_HSL_GAIN_PLUS_6DB 0x01
176#define TWL4030_HSL_GAIN_0DB 0x02
177#define TWL4030_HSL_GAIN_MINUS_6DB 0x03
178
179/* HS_POPN_SET (0x24) Fields */
180
181#define TWL4030_VMID_EN 0x40
182#define TWL4030_EXTMUTE 0x20
183#define TWL4030_RAMP_DELAY 0x1C
184#define TWL4030_RAMP_DELAY_20MS 0x00
185#define TWL4030_RAMP_DELAY_40MS 0x04
186#define TWL4030_RAMP_DELAY_81MS 0x08
187#define TWL4030_RAMP_DELAY_161MS 0x0C
188#define TWL4030_RAMP_DELAY_323MS 0x10
189#define TWL4030_RAMP_DELAY_645MS 0x14
190#define TWL4030_RAMP_DELAY_1291MS 0x18
191#define TWL4030_RAMP_DELAY_2581MS 0x1C
192#define TWL4030_RAMP_EN 0x02
193
194/* HFL_CTL (0x29, 0x2A) Fields */
195#define TWL4030_HF_CTL_HB_EN 0x04
196#define TWL4030_HF_CTL_LOOP_EN 0x08
197#define TWL4030_HF_CTL_RAMP_EN 0x10
198#define TWL4030_HF_CTL_REF_EN 0x20
199
200/* APLL_CTL (0x3A) Fields */
201
202#define TWL4030_APLL_EN 0x10
203#define TWL4030_APLL_INFREQ 0x0F
204#define TWL4030_APLL_INFREQ_19200KHZ 0x05
205#define TWL4030_APLL_INFREQ_26000KHZ 0x06
206#define TWL4030_APLL_INFREQ_38400KHZ 0x0F
207
208/* REG_MISC_SET_1 (0x3E) Fields */
209
210#define TWL4030_CLK64_EN 0x80
211#define TWL4030_SCRAMBLE_EN 0x40
212#define TWL4030_FMLOOP_EN 0x20
213#define TWL4030_SMOOTH_ANAVOL_EN 0x02
214#define TWL4030_DIGMIC_LR_SWAP_EN 0x01
215
216extern struct snd_soc_dai twl4030_dai;
217extern struct snd_soc_codec_device soc_codec_dev_twl4030;
218
219#endif /* End of __TWL4030_AUDIO_H__ */
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c
new file mode 100644
index 000000000000..a2c5064a774b
--- /dev/null
+++ b/sound/soc/codecs/uda134x.c
@@ -0,0 +1,668 @@
1/*
2 * uda134x.c -- UDA134X ALSA SoC Codec driver
3 *
4 * Modifications by Christian Pellegrin <chripell@evolware.org>
5 *
6 * Copyright 2007 Dension Audio Systems Ltd.
7 * Author: Zoltan Devai
8 *
9 * Based on the WM87xx drivers by Liam Girdwood and Richard Purdie
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 version 2 as
13 * published by the Free Software Foundation.
14 */
15
16#include <linux/module.h>
17#include <linux/delay.h>
18#include <sound/pcm.h>
19#include <sound/pcm_params.h>
20#include <sound/soc.h>
21#include <sound/soc-dapm.h>
22#include <sound/initval.h>
23
24#include <sound/uda134x.h>
25#include <sound/l3.h>
26
27#include "uda134x.h"
28
29
30#define POWER_OFF_ON_STANDBY 1
31/*
32 ALSA SOC usually puts the device in standby mode when it's not used
33 for sometime. If you define POWER_OFF_ON_STANDBY the driver will
34 turn off the ADC/DAC when this callback is invoked and turn it back
35 on when needed. Unfortunately this will result in a very light bump
36 (it can be audible only with good earphones). If this bothers you
37 just comment this line, you will have slightly higher power
38 consumption . Please note that sending the L3 command for ADC is
39 enough to make the bump, so it doesn't make difference if you
40 completely take off power from the codec.
41 */
42
43#define UDA134X_RATES SNDRV_PCM_RATE_8000_48000
44#define UDA134X_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | \
45 SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S20_3LE)
46
47struct uda134x_priv {
48 int sysclk;
49 int dai_fmt;
50
51 struct snd_pcm_substream *master_substream;
52 struct snd_pcm_substream *slave_substream;
53};
54
55/* In-data addresses are hard-coded into the reg-cache values */
56static const char uda134x_reg[UDA134X_REGS_NUM] = {
57 /* Extended address registers */
58 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
59 /* Status, data regs */
60 0x00, 0x83, 0x00, 0x40, 0x80, 0x00,
61};
62
63/*
64 * The codec has no support for reading its registers except for peak level...
65 */
66static inline unsigned int uda134x_read_reg_cache(struct snd_soc_codec *codec,
67 unsigned int reg)
68{
69 u8 *cache = codec->reg_cache;
70
71 if (reg >= UDA134X_REGS_NUM)
72 return -1;
73 return cache[reg];
74}
75
76/*
77 * Write the register cache
78 */
79static inline void uda134x_write_reg_cache(struct snd_soc_codec *codec,
80 u8 reg, unsigned int value)
81{
82 u8 *cache = codec->reg_cache;
83
84 if (reg >= UDA134X_REGS_NUM)
85 return;
86 cache[reg] = value;
87}
88
89/*
90 * Write to the uda134x registers
91 *
92 */
93static int uda134x_write(struct snd_soc_codec *codec, unsigned int reg,
94 unsigned int value)
95{
96 int ret;
97 u8 addr;
98 u8 data = value;
99 struct uda134x_platform_data *pd = codec->control_data;
100
101 pr_debug("%s reg: %02X, value:%02X\n", __func__, reg, value);
102
103 if (reg >= UDA134X_REGS_NUM) {
104 printk(KERN_ERR "%s unkown register: reg: %d",
105 __func__, reg);
106 return -EINVAL;
107 }
108
109 uda134x_write_reg_cache(codec, reg, value);
110
111 switch (reg) {
112 case UDA134X_STATUS0:
113 case UDA134X_STATUS1:
114 addr = UDA134X_STATUS_ADDR;
115 break;
116 case UDA134X_DATA000:
117 case UDA134X_DATA001:
118 case UDA134X_DATA010:
119 addr = UDA134X_DATA0_ADDR;
120 break;
121 case UDA134X_DATA1:
122 addr = UDA134X_DATA1_ADDR;
123 break;
124 default:
125 /* It's an extended address register */
126 addr = (reg | UDA134X_EXTADDR_PREFIX);
127
128 ret = l3_write(&pd->l3,
129 UDA134X_DATA0_ADDR, &addr, 1);
130 if (ret != 1)
131 return -EIO;
132
133 addr = UDA134X_DATA0_ADDR;
134 data = (value | UDA134X_EXTDATA_PREFIX);
135 break;
136 }
137
138 ret = l3_write(&pd->l3,
139 addr, &data, 1);
140 if (ret != 1)
141 return -EIO;
142
143 return 0;
144}
145
146static inline void uda134x_reset(struct snd_soc_codec *codec)
147{
148 u8 reset_reg = uda134x_read_reg_cache(codec, UDA134X_STATUS0);
149 uda134x_write(codec, UDA134X_STATUS0, reset_reg | (1<<6));
150 msleep(1);
151 uda134x_write(codec, UDA134X_STATUS0, reset_reg & ~(1<<6));
152}
153
154static int uda134x_mute(struct snd_soc_dai *dai, int mute)
155{
156 struct snd_soc_codec *codec = dai->codec;
157 u8 mute_reg = uda134x_read_reg_cache(codec, UDA134X_DATA010);
158
159 pr_debug("%s mute: %d\n", __func__, mute);
160
161 if (mute)
162 mute_reg |= (1<<2);
163 else
164 mute_reg &= ~(1<<2);
165
166 uda134x_write(codec, UDA134X_DATA010, mute_reg & ~(1<<2));
167
168 return 0;
169}
170
171static int uda134x_startup(struct snd_pcm_substream *substream,
172 struct snd_soc_dai *dai)
173{
174 struct snd_soc_pcm_runtime *rtd = substream->private_data;
175 struct snd_soc_device *socdev = rtd->socdev;
176 struct snd_soc_codec *codec = socdev->codec;
177 struct uda134x_priv *uda134x = codec->private_data;
178 struct snd_pcm_runtime *master_runtime;
179
180 if (uda134x->master_substream) {
181 master_runtime = uda134x->master_substream->runtime;
182
183 pr_debug("%s constraining to %d bits at %d\n", __func__,
184 master_runtime->sample_bits,
185 master_runtime->rate);
186
187 snd_pcm_hw_constraint_minmax(substream->runtime,
188 SNDRV_PCM_HW_PARAM_RATE,
189 master_runtime->rate,
190 master_runtime->rate);
191
192 snd_pcm_hw_constraint_minmax(substream->runtime,
193 SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
194 master_runtime->sample_bits,
195 master_runtime->sample_bits);
196
197 uda134x->slave_substream = substream;
198 } else
199 uda134x->master_substream = substream;
200
201 return 0;
202}
203
204static void uda134x_shutdown(struct snd_pcm_substream *substream,
205 struct snd_soc_dai *dai)
206{
207 struct snd_soc_pcm_runtime *rtd = substream->private_data;
208 struct snd_soc_device *socdev = rtd->socdev;
209 struct snd_soc_codec *codec = socdev->codec;
210 struct uda134x_priv *uda134x = codec->private_data;
211
212 if (uda134x->master_substream == substream)
213 uda134x->master_substream = uda134x->slave_substream;
214
215 uda134x->slave_substream = NULL;
216}
217
218static int uda134x_hw_params(struct snd_pcm_substream *substream,
219 struct snd_pcm_hw_params *params,
220 struct snd_soc_dai *dai)
221{
222 struct snd_soc_pcm_runtime *rtd = substream->private_data;
223 struct snd_soc_device *socdev = rtd->socdev;
224 struct snd_soc_codec *codec = socdev->codec;
225 struct uda134x_priv *uda134x = codec->private_data;
226 u8 hw_params;
227
228 if (substream == uda134x->slave_substream) {
229 pr_debug("%s ignoring hw_params for slave substream\n",
230 __func__);
231 return 0;
232 }
233
234 hw_params = uda134x_read_reg_cache(codec, UDA134X_STATUS0);
235 hw_params &= STATUS0_SYSCLK_MASK;
236 hw_params &= STATUS0_DAIFMT_MASK;
237
238 pr_debug("%s sysclk: %d, rate:%d\n", __func__,
239 uda134x->sysclk, params_rate(params));
240
241 /* set SYSCLK / fs ratio */
242 switch (uda134x->sysclk / params_rate(params)) {
243 case 512:
244 break;
245 case 384:
246 hw_params |= (1<<4);
247 break;
248 case 256:
249 hw_params |= (1<<5);
250 break;
251 default:
252 printk(KERN_ERR "%s unsupported fs\n", __func__);
253 return -EINVAL;
254 }
255
256 pr_debug("%s dai_fmt: %d, params_format:%d\n", __func__,
257 uda134x->dai_fmt, params_format(params));
258
259 /* set DAI format and word length */
260 switch (uda134x->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
261 case SND_SOC_DAIFMT_I2S:
262 break;
263 case SND_SOC_DAIFMT_RIGHT_J:
264 switch (params_format(params)) {
265 case SNDRV_PCM_FORMAT_S16_LE:
266 hw_params |= (1<<1);
267 break;
268 case SNDRV_PCM_FORMAT_S18_3LE:
269 hw_params |= (1<<2);
270 break;
271 case SNDRV_PCM_FORMAT_S20_3LE:
272 hw_params |= ((1<<2) | (1<<1));
273 break;
274 default:
275 printk(KERN_ERR "%s unsupported format (right)\n",
276 __func__);
277 return -EINVAL;
278 }
279 break;
280 case SND_SOC_DAIFMT_LEFT_J:
281 hw_params |= (1<<3);
282 break;
283 default:
284 printk(KERN_ERR "%s unsupported format\n", __func__);
285 return -EINVAL;
286 }
287
288 uda134x_write(codec, UDA134X_STATUS0, hw_params);
289
290 return 0;
291}
292
293static int uda134x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
294 int clk_id, unsigned int freq, int dir)
295{
296 struct snd_soc_codec *codec = codec_dai->codec;
297 struct uda134x_priv *uda134x = codec->private_data;
298
299 pr_debug("%s clk_id: %d, freq: %d, dir: %d\n", __func__,
300 clk_id, freq, dir);
301
302 /* Anything between 256fs*8Khz and 512fs*48Khz should be acceptable
303 because the codec is slave. Of course limitations of the clock
304 master (the IIS controller) apply.
305 We'll error out on set_hw_params if it's not OK */
306 if ((freq >= (256 * 8000)) && (freq <= (512 * 48000))) {
307 uda134x->sysclk = freq;
308 return 0;
309 }
310
311 printk(KERN_ERR "%s unsupported sysclk\n", __func__);
312 return -EINVAL;
313}
314
315static int uda134x_set_dai_fmt(struct snd_soc_dai *codec_dai,
316 unsigned int fmt)
317{
318 struct snd_soc_codec *codec = codec_dai->codec;
319 struct uda134x_priv *uda134x = codec->private_data;
320
321 pr_debug("%s fmt: %08X\n", __func__, fmt);
322
323 /* codec supports only full slave mode */
324 if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) {
325 printk(KERN_ERR "%s unsupported slave mode\n", __func__);
326 return -EINVAL;
327 }
328
329 /* no support for clock inversion */
330 if ((fmt & SND_SOC_DAIFMT_INV_MASK) != SND_SOC_DAIFMT_NB_NF) {
331 printk(KERN_ERR "%s unsupported clock inversion\n", __func__);
332 return -EINVAL;
333 }
334
335 /* We can't setup DAI format here as it depends on the word bit num */
336 /* so let's just store the value for later */
337 uda134x->dai_fmt = fmt;
338
339 return 0;
340}
341
342static int uda134x_set_bias_level(struct snd_soc_codec *codec,
343 enum snd_soc_bias_level level)
344{
345 u8 reg;
346 struct uda134x_platform_data *pd = codec->control_data;
347 int i;
348 u8 *cache = codec->reg_cache;
349
350 pr_debug("%s bias level %d\n", __func__, level);
351
352 switch (level) {
353 case SND_SOC_BIAS_ON:
354 /* ADC, DAC on */
355 reg = uda134x_read_reg_cache(codec, UDA134X_STATUS1);
356 uda134x_write(codec, UDA134X_STATUS1, reg | 0x03);
357 break;
358 case SND_SOC_BIAS_PREPARE:
359 /* power on */
360 if (pd->power) {
361 pd->power(1);
362 /* Sync reg_cache with the hardware */
363 for (i = 0; i < ARRAY_SIZE(uda134x_reg); i++)
364 codec->write(codec, i, *cache++);
365 }
366 break;
367 case SND_SOC_BIAS_STANDBY:
368 /* ADC, DAC power off */
369 reg = uda134x_read_reg_cache(codec, UDA134X_STATUS1);
370 uda134x_write(codec, UDA134X_STATUS1, reg & ~(0x03));
371 break;
372 case SND_SOC_BIAS_OFF:
373 /* power off */
374 if (pd->power)
375 pd->power(0);
376 break;
377 }
378 codec->bias_level = level;
379 return 0;
380}
381
382static const char *uda134x_dsp_setting[] = {"Flat", "Minimum1",
383 "Minimum2", "Maximum"};
384static const char *uda134x_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"};
385static const char *uda134x_mixmode[] = {"Differential", "Analog1",
386 "Analog2", "Both"};
387
388static const struct soc_enum uda134x_mixer_enum[] = {
389SOC_ENUM_SINGLE(UDA134X_DATA010, 0, 0x04, uda134x_dsp_setting),
390SOC_ENUM_SINGLE(UDA134X_DATA010, 3, 0x04, uda134x_deemph),
391SOC_ENUM_SINGLE(UDA134X_EA010, 0, 0x04, uda134x_mixmode),
392};
393
394static const struct snd_kcontrol_new uda1341_snd_controls[] = {
395SOC_SINGLE("Master Playback Volume", UDA134X_DATA000, 0, 0x3F, 1),
396SOC_SINGLE("Capture Volume", UDA134X_EA010, 2, 0x07, 0),
397SOC_SINGLE("Analog1 Volume", UDA134X_EA000, 0, 0x1F, 1),
398SOC_SINGLE("Analog2 Volume", UDA134X_EA001, 0, 0x1F, 1),
399
400SOC_SINGLE("Mic Sensitivity", UDA134X_EA010, 2, 7, 0),
401SOC_SINGLE("Mic Volume", UDA134X_EA101, 0, 0x1F, 0),
402
403SOC_SINGLE("Tone Control - Bass", UDA134X_DATA001, 2, 0xF, 0),
404SOC_SINGLE("Tone Control - Treble", UDA134X_DATA001, 0, 3, 0),
405
406SOC_ENUM("Sound Processing Filter", uda134x_mixer_enum[0]),
407SOC_ENUM("PCM Playback De-emphasis", uda134x_mixer_enum[1]),
408SOC_ENUM("Input Mux", uda134x_mixer_enum[2]),
409
410SOC_SINGLE("AGC Switch", UDA134X_EA100, 4, 1, 0),
411SOC_SINGLE("AGC Target Volume", UDA134X_EA110, 0, 0x03, 1),
412SOC_SINGLE("AGC Timing", UDA134X_EA110, 2, 0x07, 0),
413
414SOC_SINGLE("DAC +6dB Switch", UDA134X_STATUS1, 6, 1, 0),
415SOC_SINGLE("ADC +6dB Switch", UDA134X_STATUS1, 5, 1, 0),
416SOC_SINGLE("ADC Polarity Switch", UDA134X_STATUS1, 4, 1, 0),
417SOC_SINGLE("DAC Polarity Switch", UDA134X_STATUS1, 3, 1, 0),
418SOC_SINGLE("Double Speed Playback Switch", UDA134X_STATUS1, 2, 1, 0),
419SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0, 0, 1, 0),
420};
421
422static const struct snd_kcontrol_new uda1340_snd_controls[] = {
423SOC_SINGLE("Master Playback Volume", UDA134X_DATA000, 0, 0x3F, 1),
424
425SOC_SINGLE("Tone Control - Bass", UDA134X_DATA001, 2, 0xF, 0),
426SOC_SINGLE("Tone Control - Treble", UDA134X_DATA001, 0, 3, 0),
427
428SOC_ENUM("Sound Processing Filter", uda134x_mixer_enum[0]),
429SOC_ENUM("PCM Playback De-emphasis", uda134x_mixer_enum[1]),
430
431SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0, 0, 1, 0),
432};
433
434static int uda134x_add_controls(struct snd_soc_codec *codec)
435{
436 int err, i, n;
437 const struct snd_kcontrol_new *ctrls;
438 struct uda134x_platform_data *pd = codec->control_data;
439
440 switch (pd->model) {
441 case UDA134X_UDA1340:
442 case UDA134X_UDA1344:
443 n = ARRAY_SIZE(uda1340_snd_controls);
444 ctrls = uda1340_snd_controls;
445 break;
446 case UDA134X_UDA1341:
447 n = ARRAY_SIZE(uda1341_snd_controls);
448 ctrls = uda1341_snd_controls;
449 break;
450 default:
451 printk(KERN_ERR "%s unkown codec type: %d",
452 __func__, pd->model);
453 return -EINVAL;
454 }
455
456 for (i = 0; i < n; i++) {
457 err = snd_ctl_add(codec->card,
458 snd_soc_cnew(&ctrls[i],
459 codec, NULL));
460 if (err < 0)
461 return err;
462 }
463
464 return 0;
465}
466
467struct snd_soc_dai uda134x_dai = {
468 .name = "UDA134X",
469 /* playback capabilities */
470 .playback = {
471 .stream_name = "Playback",
472 .channels_min = 1,
473 .channels_max = 2,
474 .rates = UDA134X_RATES,
475 .formats = UDA134X_FORMATS,
476 },
477 /* capture capabilities */
478 .capture = {
479 .stream_name = "Capture",
480 .channels_min = 1,
481 .channels_max = 2,
482 .rates = UDA134X_RATES,
483 .formats = UDA134X_FORMATS,
484 },
485 /* pcm operations */
486 .ops = {
487 .startup = uda134x_startup,
488 .shutdown = uda134x_shutdown,
489 .hw_params = uda134x_hw_params,
490 .digital_mute = uda134x_mute,
491 .set_sysclk = uda134x_set_dai_sysclk,
492 .set_fmt = uda134x_set_dai_fmt,
493 }
494};
495EXPORT_SYMBOL(uda134x_dai);
496
497
498static int uda134x_soc_probe(struct platform_device *pdev)
499{
500 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
501 struct snd_soc_codec *codec;
502 struct uda134x_priv *uda134x;
503 void *codec_setup_data = socdev->codec_data;
504 int ret = -ENOMEM;
505 struct uda134x_platform_data *pd;
506
507 printk(KERN_INFO "UDA134X SoC Audio Codec\n");
508
509 if (!codec_setup_data) {
510 printk(KERN_ERR "UDA134X SoC codec: "
511 "missing L3 bitbang function\n");
512 return -ENODEV;
513 }
514
515 pd = codec_setup_data;
516 switch (pd->model) {
517 case UDA134X_UDA1340:
518 case UDA134X_UDA1341:
519 case UDA134X_UDA1344:
520 break;
521 default:
522 printk(KERN_ERR "UDA134X SoC codec: "
523 "unsupported model %d\n",
524 pd->model);
525 return -EINVAL;
526 }
527
528 socdev->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
529 if (socdev->codec == NULL)
530 return ret;
531
532 codec = socdev->codec;
533
534 uda134x = kzalloc(sizeof(struct uda134x_priv), GFP_KERNEL);
535 if (uda134x == NULL)
536 goto priv_err;
537 codec->private_data = uda134x;
538
539 codec->reg_cache = kmemdup(uda134x_reg, sizeof(uda134x_reg),
540 GFP_KERNEL);
541 if (codec->reg_cache == NULL)
542 goto reg_err;
543
544 mutex_init(&codec->mutex);
545
546 codec->reg_cache_size = sizeof(uda134x_reg);
547 codec->reg_cache_step = 1;
548
549 codec->name = "UDA134X";
550 codec->owner = THIS_MODULE;
551 codec->dai = &uda134x_dai;
552 codec->num_dai = 1;
553 codec->read = uda134x_read_reg_cache;
554 codec->write = uda134x_write;
555#ifdef POWER_OFF_ON_STANDBY
556 codec->set_bias_level = uda134x_set_bias_level;
557#endif
558 INIT_LIST_HEAD(&codec->dapm_widgets);
559 INIT_LIST_HEAD(&codec->dapm_paths);
560
561 codec->control_data = codec_setup_data;
562
563 if (pd->power)
564 pd->power(1);
565
566 uda134x_reset(codec);
567
568 /* register pcms */
569 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
570 if (ret < 0) {
571 printk(KERN_ERR "UDA134X: failed to register pcms\n");
572 goto pcm_err;
573 }
574
575 ret = uda134x_add_controls(codec);
576 if (ret < 0) {
577 printk(KERN_ERR "UDA134X: failed to register controls\n");
578 goto pcm_err;
579 }
580
581 ret = snd_soc_init_card(socdev);
582 if (ret < 0) {
583 printk(KERN_ERR "UDA134X: failed to register card\n");
584 goto card_err;
585 }
586
587 return 0;
588
589card_err:
590 snd_soc_free_pcms(socdev);
591 snd_soc_dapm_free(socdev);
592pcm_err:
593 kfree(codec->reg_cache);
594reg_err:
595 kfree(codec->private_data);
596priv_err:
597 kfree(codec);
598 return ret;
599}
600
601/* power down chip */
602static int uda134x_soc_remove(struct platform_device *pdev)
603{
604 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
605 struct snd_soc_codec *codec = socdev->codec;
606
607 uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
608 uda134x_set_bias_level(codec, SND_SOC_BIAS_OFF);
609
610 snd_soc_free_pcms(socdev);
611 snd_soc_dapm_free(socdev);
612
613 kfree(codec->private_data);
614 kfree(codec->reg_cache);
615 kfree(codec);
616
617 return 0;
618}
619
620#if defined(CONFIG_PM)
621static int uda134x_soc_suspend(struct platform_device *pdev,
622 pm_message_t state)
623{
624 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
625 struct snd_soc_codec *codec = socdev->codec;
626
627 uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
628 uda134x_set_bias_level(codec, SND_SOC_BIAS_OFF);
629 return 0;
630}
631
632static int uda134x_soc_resume(struct platform_device *pdev)
633{
634 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
635 struct snd_soc_codec *codec = socdev->codec;
636
637 uda134x_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
638 uda134x_set_bias_level(codec, SND_SOC_BIAS_ON);
639 return 0;
640}
641#else
642#define uda134x_soc_suspend NULL
643#define uda134x_soc_resume NULL
644#endif /* CONFIG_PM */
645
646struct snd_soc_codec_device soc_codec_dev_uda134x = {
647 .probe = uda134x_soc_probe,
648 .remove = uda134x_soc_remove,
649 .suspend = uda134x_soc_suspend,
650 .resume = uda134x_soc_resume,
651};
652EXPORT_SYMBOL_GPL(soc_codec_dev_uda134x);
653
654static int __init uda134x_init(void)
655{
656 return snd_soc_register_dai(&uda134x_dai);
657}
658module_init(uda134x_init);
659
660static void __exit uda134x_exit(void)
661{
662 snd_soc_unregister_dai(&uda134x_dai);
663}
664module_exit(uda134x_exit);
665
666MODULE_DESCRIPTION("UDA134X ALSA soc codec driver");
667MODULE_AUTHOR("Zoltan Devai, Christian Pellegrin <chripell@evolware.org>");
668MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/uda134x.h b/sound/soc/codecs/uda134x.h
new file mode 100644
index 000000000000..94f440490b31
--- /dev/null
+++ b/sound/soc/codecs/uda134x.h
@@ -0,0 +1,36 @@
1#ifndef _UDA134X_CODEC_H
2#define _UDA134X_CODEC_H
3
4#define UDA134X_L3ADDR 5
5#define UDA134X_DATA0_ADDR ((UDA134X_L3ADDR << 2) | 0)
6#define UDA134X_DATA1_ADDR ((UDA134X_L3ADDR << 2) | 1)
7#define UDA134X_STATUS_ADDR ((UDA134X_L3ADDR << 2) | 2)
8
9#define UDA134X_EXTADDR_PREFIX 0xC0
10#define UDA134X_EXTDATA_PREFIX 0xE0
11
12/* UDA134X registers */
13#define UDA134X_EA000 0
14#define UDA134X_EA001 1
15#define UDA134X_EA010 2
16#define UDA134X_EA011 3
17#define UDA134X_EA100 4
18#define UDA134X_EA101 5
19#define UDA134X_EA110 6
20#define UDA134X_EA111 7
21#define UDA134X_STATUS0 8
22#define UDA134X_STATUS1 9
23#define UDA134X_DATA000 10
24#define UDA134X_DATA001 11
25#define UDA134X_DATA010 12
26#define UDA134X_DATA1 13
27
28#define UDA134X_REGS_NUM 14
29
30#define STATUS0_DAIFMT_MASK (~(7<<1))
31#define STATUS0_SYSCLK_MASK (~(3<<4))
32
33extern struct snd_soc_dai uda134x_dai;
34extern struct snd_soc_codec_device soc_codec_dev_uda134x;
35
36#endif
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c
index a69ee72a7af5..e6bf0844fbf3 100644
--- a/sound/soc/codecs/uda1380.c
+++ b/sound/soc/codecs/uda1380.c
@@ -407,7 +407,8 @@ static int uda1380_set_dai_fmt(struct snd_soc_dai *codec_dai,
407 * when the DAI is being clocked by the CPU DAI. It's up to the 407 * when the DAI is being clocked by the CPU DAI. It's up to the
408 * machine and cpu DAI driver to do this before we are called. 408 * machine and cpu DAI driver to do this before we are called.
409 */ 409 */
410static int uda1380_pcm_prepare(struct snd_pcm_substream *substream) 410static int uda1380_pcm_prepare(struct snd_pcm_substream *substream,
411 struct snd_soc_dai *dai)
411{ 412{
412 struct snd_soc_pcm_runtime *rtd = substream->private_data; 413 struct snd_soc_pcm_runtime *rtd = substream->private_data;
413 struct snd_soc_device *socdev = rtd->socdev; 414 struct snd_soc_device *socdev = rtd->socdev;
@@ -439,7 +440,8 @@ static int uda1380_pcm_prepare(struct snd_pcm_substream *substream)
439} 440}
440 441
441static int uda1380_pcm_hw_params(struct snd_pcm_substream *substream, 442static int uda1380_pcm_hw_params(struct snd_pcm_substream *substream,
442 struct snd_pcm_hw_params *params) 443 struct snd_pcm_hw_params *params,
444 struct snd_soc_dai *dai)
443{ 445{
444 struct snd_soc_pcm_runtime *rtd = substream->private_data; 446 struct snd_soc_pcm_runtime *rtd = substream->private_data;
445 struct snd_soc_device *socdev = rtd->socdev; 447 struct snd_soc_device *socdev = rtd->socdev;
@@ -477,7 +479,8 @@ static int uda1380_pcm_hw_params(struct snd_pcm_substream *substream,
477 return 0; 479 return 0;
478} 480}
479 481
480static void uda1380_pcm_shutdown(struct snd_pcm_substream *substream) 482static void uda1380_pcm_shutdown(struct snd_pcm_substream *substream,
483 struct snd_soc_dai *dai)
481{ 484{
482 struct snd_soc_pcm_runtime *rtd = substream->private_data; 485 struct snd_soc_pcm_runtime *rtd = substream->private_data;
483 struct snd_soc_device *socdev = rtd->socdev; 486 struct snd_soc_device *socdev = rtd->socdev;
@@ -560,8 +563,6 @@ struct snd_soc_dai uda1380_dai[] = {
560 .hw_params = uda1380_pcm_hw_params, 563 .hw_params = uda1380_pcm_hw_params,
561 .shutdown = uda1380_pcm_shutdown, 564 .shutdown = uda1380_pcm_shutdown,
562 .prepare = uda1380_pcm_prepare, 565 .prepare = uda1380_pcm_prepare,
563 },
564 .dai_ops = {
565 .digital_mute = uda1380_mute, 566 .digital_mute = uda1380_mute,
566 .set_fmt = uda1380_set_dai_fmt, 567 .set_fmt = uda1380_set_dai_fmt,
567 }, 568 },
@@ -579,8 +580,6 @@ struct snd_soc_dai uda1380_dai[] = {
579 .hw_params = uda1380_pcm_hw_params, 580 .hw_params = uda1380_pcm_hw_params,
580 .shutdown = uda1380_pcm_shutdown, 581 .shutdown = uda1380_pcm_shutdown,
581 .prepare = uda1380_pcm_prepare, 582 .prepare = uda1380_pcm_prepare,
582 },
583 .dai_ops = {
584 .digital_mute = uda1380_mute, 583 .digital_mute = uda1380_mute,
585 .set_fmt = uda1380_set_dai_fmt, 584 .set_fmt = uda1380_set_dai_fmt,
586 }, 585 },
@@ -598,8 +597,6 @@ struct snd_soc_dai uda1380_dai[] = {
598 .hw_params = uda1380_pcm_hw_params, 597 .hw_params = uda1380_pcm_hw_params,
599 .shutdown = uda1380_pcm_shutdown, 598 .shutdown = uda1380_pcm_shutdown,
600 .prepare = uda1380_pcm_prepare, 599 .prepare = uda1380_pcm_prepare,
601 },
602 .dai_ops = {
603 .set_fmt = uda1380_set_dai_fmt, 600 .set_fmt = uda1380_set_dai_fmt,
604 }, 601 },
605}, 602},
@@ -680,7 +677,7 @@ static int uda1380_init(struct snd_soc_device *socdev, int dac_clk)
680 /* uda1380 init */ 677 /* uda1380 init */
681 uda1380_add_controls(codec); 678 uda1380_add_controls(codec);
682 uda1380_add_widgets(codec); 679 uda1380_add_widgets(codec);
683 ret = snd_soc_register_card(socdev); 680 ret = snd_soc_init_card(socdev);
684 if (ret < 0) { 681 if (ret < 0) {
685 pr_err("uda1380: failed to register card\n"); 682 pr_err("uda1380: failed to register card\n");
686 goto card_err; 683 goto card_err;
@@ -844,6 +841,18 @@ struct snd_soc_codec_device soc_codec_dev_uda1380 = {
844}; 841};
845EXPORT_SYMBOL_GPL(soc_codec_dev_uda1380); 842EXPORT_SYMBOL_GPL(soc_codec_dev_uda1380);
846 843
844static int __init uda1380_modinit(void)
845{
846 return snd_soc_register_dais(uda1380_dai, ARRAY_SIZE(uda1380_dai));
847}
848module_init(uda1380_modinit);
849
850static void __exit uda1380_exit(void)
851{
852 snd_soc_unregister_dais(uda1380_dai, ARRAY_SIZE(uda1380_dai));
853}
854module_exit(uda1380_exit);
855
847MODULE_AUTHOR("Giorgio Padrin"); 856MODULE_AUTHOR("Giorgio Padrin");
848MODULE_DESCRIPTION("Audio support for codec Philips UDA1380"); 857MODULE_DESCRIPTION("Audio support for codec Philips UDA1380");
849MODULE_LICENSE("GPL"); 858MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
new file mode 100644
index 000000000000..e3989d406f54
--- /dev/null
+++ b/sound/soc/codecs/wm8350.c
@@ -0,0 +1,1583 @@
1/*
2 * wm8350.c -- WM8350 ALSA SoC audio driver
3 *
4 * Copyright (C) 2007, 2008 Wolfson Microelectronics PLC.
5 *
6 * Author: Liam Girdwood <lg@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/pm.h>
18#include <linux/platform_device.h>
19#include <linux/mfd/wm8350/audio.h>
20#include <linux/mfd/wm8350/core.h>
21#include <linux/regulator/consumer.h>
22#include <sound/core.h>
23#include <sound/pcm.h>
24#include <sound/pcm_params.h>
25#include <sound/soc.h>
26#include <sound/soc-dapm.h>
27#include <sound/initval.h>
28#include <sound/tlv.h>
29
30#include "wm8350.h"
31
32#define WM8350_OUTn_0dB 0x39
33
34#define WM8350_RAMP_NONE 0
35#define WM8350_RAMP_UP 1
36#define WM8350_RAMP_DOWN 2
37
38/* We only include the analogue supplies here; the digital supplies
39 * need to be available well before this driver can be probed.
40 */
41static const char *supply_names[] = {
42 "AVDD",
43 "HPVDD",
44};
45
46struct wm8350_output {
47 u16 active;
48 u16 left_vol;
49 u16 right_vol;
50 u16 ramp;
51 u16 mute;
52};
53
54struct wm8350_data {
55 struct snd_soc_codec codec;
56 struct wm8350_output out1;
57 struct wm8350_output out2;
58 struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)];
59};
60
61static unsigned int wm8350_codec_cache_read(struct snd_soc_codec *codec,
62 unsigned int reg)
63{
64 struct wm8350 *wm8350 = codec->control_data;
65 return wm8350->reg_cache[reg];
66}
67
68static unsigned int wm8350_codec_read(struct snd_soc_codec *codec,
69 unsigned int reg)
70{
71 struct wm8350 *wm8350 = codec->control_data;
72 return wm8350_reg_read(wm8350, reg);
73}
74
75static int wm8350_codec_write(struct snd_soc_codec *codec, unsigned int reg,
76 unsigned int value)
77{
78 struct wm8350 *wm8350 = codec->control_data;
79 return wm8350_reg_write(wm8350, reg, value);
80}
81
82/*
83 * Ramp OUT1 PGA volume to minimise pops at stream startup and shutdown.
84 */
85static inline int wm8350_out1_ramp_step(struct snd_soc_codec *codec)
86{
87 struct wm8350_data *wm8350_data = codec->private_data;
88 struct wm8350_output *out1 = &wm8350_data->out1;
89 struct wm8350 *wm8350 = codec->control_data;
90 int left_complete = 0, right_complete = 0;
91 u16 reg, val;
92
93 /* left channel */
94 reg = wm8350_reg_read(wm8350, WM8350_LOUT1_VOLUME);
95 val = (reg & WM8350_OUT1L_VOL_MASK) >> WM8350_OUT1L_VOL_SHIFT;
96
97 if (out1->ramp == WM8350_RAMP_UP) {
98 /* ramp step up */
99 if (val < out1->left_vol) {
100 val++;
101 reg &= ~WM8350_OUT1L_VOL_MASK;
102 wm8350_reg_write(wm8350, WM8350_LOUT1_VOLUME,
103 reg | (val << WM8350_OUT1L_VOL_SHIFT));
104 } else
105 left_complete = 1;
106 } else if (out1->ramp == WM8350_RAMP_DOWN) {
107 /* ramp step down */
108 if (val > 0) {
109 val--;
110 reg &= ~WM8350_OUT1L_VOL_MASK;
111 wm8350_reg_write(wm8350, WM8350_LOUT1_VOLUME,
112 reg | (val << WM8350_OUT1L_VOL_SHIFT));
113 } else
114 left_complete = 1;
115 } else
116 return 1;
117
118 /* right channel */
119 reg = wm8350_reg_read(wm8350, WM8350_ROUT1_VOLUME);
120 val = (reg & WM8350_OUT1R_VOL_MASK) >> WM8350_OUT1R_VOL_SHIFT;
121 if (out1->ramp == WM8350_RAMP_UP) {
122 /* ramp step up */
123 if (val < out1->right_vol) {
124 val++;
125 reg &= ~WM8350_OUT1R_VOL_MASK;
126 wm8350_reg_write(wm8350, WM8350_ROUT1_VOLUME,
127 reg | (val << WM8350_OUT1R_VOL_SHIFT));
128 } else
129 right_complete = 1;
130 } else if (out1->ramp == WM8350_RAMP_DOWN) {
131 /* ramp step down */
132 if (val > 0) {
133 val--;
134 reg &= ~WM8350_OUT1R_VOL_MASK;
135 wm8350_reg_write(wm8350, WM8350_ROUT1_VOLUME,
136 reg | (val << WM8350_OUT1R_VOL_SHIFT));
137 } else
138 right_complete = 1;
139 }
140
141 /* only hit the update bit if either volume has changed this step */
142 if (!left_complete || !right_complete)
143 wm8350_set_bits(wm8350, WM8350_LOUT1_VOLUME, WM8350_OUT1_VU);
144
145 return left_complete & right_complete;
146}
147
148/*
149 * Ramp OUT2 PGA volume to minimise pops at stream startup and shutdown.
150 */
151static inline int wm8350_out2_ramp_step(struct snd_soc_codec *codec)
152{
153 struct wm8350_data *wm8350_data = codec->private_data;
154 struct wm8350_output *out2 = &wm8350_data->out2;
155 struct wm8350 *wm8350 = codec->control_data;
156 int left_complete = 0, right_complete = 0;
157 u16 reg, val;
158
159 /* left channel */
160 reg = wm8350_reg_read(wm8350, WM8350_LOUT2_VOLUME);
161 val = (reg & WM8350_OUT2L_VOL_MASK) >> WM8350_OUT1L_VOL_SHIFT;
162 if (out2->ramp == WM8350_RAMP_UP) {
163 /* ramp step up */
164 if (val < out2->left_vol) {
165 val++;
166 reg &= ~WM8350_OUT2L_VOL_MASK;
167 wm8350_reg_write(wm8350, WM8350_LOUT2_VOLUME,
168 reg | (val << WM8350_OUT1L_VOL_SHIFT));
169 } else
170 left_complete = 1;
171 } else if (out2->ramp == WM8350_RAMP_DOWN) {
172 /* ramp step down */
173 if (val > 0) {
174 val--;
175 reg &= ~WM8350_OUT2L_VOL_MASK;
176 wm8350_reg_write(wm8350, WM8350_LOUT2_VOLUME,
177 reg | (val << WM8350_OUT1L_VOL_SHIFT));
178 } else
179 left_complete = 1;
180 } else
181 return 1;
182
183 /* right channel */
184 reg = wm8350_reg_read(wm8350, WM8350_ROUT2_VOLUME);
185 val = (reg & WM8350_OUT2R_VOL_MASK) >> WM8350_OUT1R_VOL_SHIFT;
186 if (out2->ramp == WM8350_RAMP_UP) {
187 /* ramp step up */
188 if (val < out2->right_vol) {
189 val++;
190 reg &= ~WM8350_OUT2R_VOL_MASK;
191 wm8350_reg_write(wm8350, WM8350_ROUT2_VOLUME,
192 reg | (val << WM8350_OUT1R_VOL_SHIFT));
193 } else
194 right_complete = 1;
195 } else if (out2->ramp == WM8350_RAMP_DOWN) {
196 /* ramp step down */
197 if (val > 0) {
198 val--;
199 reg &= ~WM8350_OUT2R_VOL_MASK;
200 wm8350_reg_write(wm8350, WM8350_ROUT2_VOLUME,
201 reg | (val << WM8350_OUT1R_VOL_SHIFT));
202 } else
203 right_complete = 1;
204 }
205
206 /* only hit the update bit if either volume has changed this step */
207 if (!left_complete || !right_complete)
208 wm8350_set_bits(wm8350, WM8350_LOUT2_VOLUME, WM8350_OUT2_VU);
209
210 return left_complete & right_complete;
211}
212
213/*
214 * This work ramps both output PGAs at stream start/stop time to
215 * minimise pop associated with DAPM power switching.
216 * It's best to enable Zero Cross when ramping occurs to minimise any
217 * zipper noises.
218 */
219static void wm8350_pga_work(struct work_struct *work)
220{
221 struct snd_soc_codec *codec =
222 container_of(work, struct snd_soc_codec, delayed_work.work);
223 struct wm8350_data *wm8350_data = codec->private_data;
224 struct wm8350_output *out1 = &wm8350_data->out1,
225 *out2 = &wm8350_data->out2;
226 int i, out1_complete, out2_complete;
227
228 /* do we need to ramp at all ? */
229 if (out1->ramp == WM8350_RAMP_NONE && out2->ramp == WM8350_RAMP_NONE)
230 return;
231
232 /* PGA volumes have 6 bits of resolution to ramp */
233 for (i = 0; i <= 63; i++) {
234 out1_complete = 1, out2_complete = 1;
235 if (out1->ramp != WM8350_RAMP_NONE)
236 out1_complete = wm8350_out1_ramp_step(codec);
237 if (out2->ramp != WM8350_RAMP_NONE)
238 out2_complete = wm8350_out2_ramp_step(codec);
239
240 /* ramp finished ? */
241 if (out1_complete && out2_complete)
242 break;
243
244 /* we need to delay longer on the up ramp */
245 if (out1->ramp == WM8350_RAMP_UP ||
246 out2->ramp == WM8350_RAMP_UP) {
247 /* delay is longer over 0dB as increases are larger */
248 if (i >= WM8350_OUTn_0dB)
249 schedule_timeout_interruptible(msecs_to_jiffies
250 (2));
251 else
252 schedule_timeout_interruptible(msecs_to_jiffies
253 (1));
254 } else
255 udelay(50); /* doesn't matter if we delay longer */
256 }
257
258 out1->ramp = WM8350_RAMP_NONE;
259 out2->ramp = WM8350_RAMP_NONE;
260}
261
262/*
263 * WM8350 Controls
264 */
265
266static int pga_event(struct snd_soc_dapm_widget *w,
267 struct snd_kcontrol *kcontrol, int event)
268{
269 struct snd_soc_codec *codec = w->codec;
270 struct wm8350_data *wm8350_data = codec->private_data;
271 struct wm8350_output *out;
272
273 switch (w->shift) {
274 case 0:
275 case 1:
276 out = &wm8350_data->out1;
277 break;
278 case 2:
279 case 3:
280 out = &wm8350_data->out2;
281 break;
282
283 default:
284 BUG();
285 return -1;
286 }
287
288 switch (event) {
289 case SND_SOC_DAPM_POST_PMU:
290 out->ramp = WM8350_RAMP_UP;
291 out->active = 1;
292
293 if (!delayed_work_pending(&codec->delayed_work))
294 schedule_delayed_work(&codec->delayed_work,
295 msecs_to_jiffies(1));
296 break;
297
298 case SND_SOC_DAPM_PRE_PMD:
299 out->ramp = WM8350_RAMP_DOWN;
300 out->active = 0;
301
302 if (!delayed_work_pending(&codec->delayed_work))
303 schedule_delayed_work(&codec->delayed_work,
304 msecs_to_jiffies(1));
305 break;
306 }
307
308 return 0;
309}
310
311static int wm8350_put_volsw_2r_vu(struct snd_kcontrol *kcontrol,
312 struct snd_ctl_elem_value *ucontrol)
313{
314 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
315 struct wm8350_data *wm8350_priv = codec->private_data;
316 struct wm8350_output *out = NULL;
317 struct soc_mixer_control *mc =
318 (struct soc_mixer_control *)kcontrol->private_value;
319 int ret;
320 unsigned int reg = mc->reg;
321 u16 val;
322
323 /* For OUT1 and OUT2 we shadow the values and only actually write
324 * them out when active in order to ensure the amplifier comes on
325 * as quietly as possible. */
326 switch (reg) {
327 case WM8350_LOUT1_VOLUME:
328 out = &wm8350_priv->out1;
329 break;
330 case WM8350_LOUT2_VOLUME:
331 out = &wm8350_priv->out2;
332 break;
333 default:
334 break;
335 }
336
337 if (out) {
338 out->left_vol = ucontrol->value.integer.value[0];
339 out->right_vol = ucontrol->value.integer.value[1];
340 if (!out->active)
341 return 1;
342 }
343
344 ret = snd_soc_put_volsw_2r(kcontrol, ucontrol);
345 if (ret < 0)
346 return ret;
347
348 /* now hit the volume update bits (always bit 8) */
349 val = wm8350_codec_read(codec, reg);
350 wm8350_codec_write(codec, reg, val | WM8350_OUT1_VU);
351 return 1;
352}
353
354static int wm8350_get_volsw_2r(struct snd_kcontrol *kcontrol,
355 struct snd_ctl_elem_value *ucontrol)
356{
357 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
358 struct wm8350_data *wm8350_priv = codec->private_data;
359 struct wm8350_output *out1 = &wm8350_priv->out1;
360 struct wm8350_output *out2 = &wm8350_priv->out2;
361 struct soc_mixer_control *mc =
362 (struct soc_mixer_control *)kcontrol->private_value;
363 unsigned int reg = mc->reg;
364
365 /* If these are cached registers use the cache */
366 switch (reg) {
367 case WM8350_LOUT1_VOLUME:
368 ucontrol->value.integer.value[0] = out1->left_vol;
369 ucontrol->value.integer.value[1] = out1->right_vol;
370 return 0;
371
372 case WM8350_LOUT2_VOLUME:
373 ucontrol->value.integer.value[0] = out2->left_vol;
374 ucontrol->value.integer.value[1] = out2->right_vol;
375 return 0;
376
377 default:
378 break;
379 }
380
381 return snd_soc_get_volsw_2r(kcontrol, ucontrol);
382}
383
384/* double control with volume update */
385#define SOC_WM8350_DOUBLE_R_TLV(xname, reg_left, reg_right, xshift, xmax, \
386 xinvert, tlv_array) \
387{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
388 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
389 SNDRV_CTL_ELEM_ACCESS_READWRITE | \
390 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
391 .tlv.p = (tlv_array), \
392 .info = snd_soc_info_volsw_2r, \
393 .get = wm8350_get_volsw_2r, .put = wm8350_put_volsw_2r_vu, \
394 .private_value = (unsigned long)&(struct soc_mixer_control) \
395 {.reg = reg_left, .rreg = reg_right, .shift = xshift, \
396 .rshift = xshift, .max = xmax, .invert = xinvert}, }
397
398static const char *wm8350_deemp[] = { "None", "32kHz", "44.1kHz", "48kHz" };
399static const char *wm8350_pol[] = { "Normal", "Inv R", "Inv L", "Inv L & R" };
400static const char *wm8350_dacmutem[] = { "Normal", "Soft" };
401static const char *wm8350_dacmutes[] = { "Fast", "Slow" };
402static const char *wm8350_dacfilter[] = { "Normal", "Sloping" };
403static const char *wm8350_adcfilter[] = { "None", "High Pass" };
404static const char *wm8350_adchp[] = { "44.1kHz", "8kHz", "16kHz", "32kHz" };
405static const char *wm8350_lr[] = { "Left", "Right" };
406
407static const struct soc_enum wm8350_enum[] = {
408 SOC_ENUM_SINGLE(WM8350_DAC_CONTROL, 4, 4, wm8350_deemp),
409 SOC_ENUM_SINGLE(WM8350_DAC_CONTROL, 0, 4, wm8350_pol),
410 SOC_ENUM_SINGLE(WM8350_DAC_MUTE_VOLUME, 14, 2, wm8350_dacmutem),
411 SOC_ENUM_SINGLE(WM8350_DAC_MUTE_VOLUME, 13, 2, wm8350_dacmutes),
412 SOC_ENUM_SINGLE(WM8350_DAC_MUTE_VOLUME, 12, 2, wm8350_dacfilter),
413 SOC_ENUM_SINGLE(WM8350_ADC_CONTROL, 15, 2, wm8350_adcfilter),
414 SOC_ENUM_SINGLE(WM8350_ADC_CONTROL, 8, 4, wm8350_adchp),
415 SOC_ENUM_SINGLE(WM8350_ADC_CONTROL, 0, 4, wm8350_pol),
416 SOC_ENUM_SINGLE(WM8350_INPUT_MIXER_VOLUME, 15, 2, wm8350_lr),
417};
418
419static DECLARE_TLV_DB_LINEAR(pre_amp_tlv, -1200, 3525);
420static DECLARE_TLV_DB_LINEAR(out_pga_tlv, -5700, 600);
421static DECLARE_TLV_DB_SCALE(dac_pcm_tlv, -7163, 36, 1);
422static DECLARE_TLV_DB_SCALE(adc_pcm_tlv, -12700, 50, 1);
423static DECLARE_TLV_DB_SCALE(out_mix_tlv, -1500, 300, 1);
424
425static const unsigned int capture_sd_tlv[] = {
426 TLV_DB_RANGE_HEAD(2),
427 0, 12, TLV_DB_SCALE_ITEM(-3600, 300, 1),
428 13, 15, TLV_DB_SCALE_ITEM(0, 0, 0),
429};
430
431static const struct snd_kcontrol_new wm8350_snd_controls[] = {
432 SOC_ENUM("Playback Deemphasis", wm8350_enum[0]),
433 SOC_ENUM("Playback DAC Inversion", wm8350_enum[1]),
434 SOC_WM8350_DOUBLE_R_TLV("Playback PCM Volume",
435 WM8350_DAC_DIGITAL_VOLUME_L,
436 WM8350_DAC_DIGITAL_VOLUME_R,
437 0, 255, 0, dac_pcm_tlv),
438 SOC_ENUM("Playback PCM Mute Function", wm8350_enum[2]),
439 SOC_ENUM("Playback PCM Mute Speed", wm8350_enum[3]),
440 SOC_ENUM("Playback PCM Filter", wm8350_enum[4]),
441 SOC_ENUM("Capture PCM Filter", wm8350_enum[5]),
442 SOC_ENUM("Capture PCM HP Filter", wm8350_enum[6]),
443 SOC_ENUM("Capture ADC Inversion", wm8350_enum[7]),
444 SOC_WM8350_DOUBLE_R_TLV("Capture PCM Volume",
445 WM8350_ADC_DIGITAL_VOLUME_L,
446 WM8350_ADC_DIGITAL_VOLUME_R,
447 0, 255, 0, adc_pcm_tlv),
448 SOC_DOUBLE_TLV("Capture Sidetone Volume",
449 WM8350_ADC_DIVIDER,
450 8, 4, 15, 1, capture_sd_tlv),
451 SOC_WM8350_DOUBLE_R_TLV("Capture Volume",
452 WM8350_LEFT_INPUT_VOLUME,
453 WM8350_RIGHT_INPUT_VOLUME,
454 2, 63, 0, pre_amp_tlv),
455 SOC_DOUBLE_R("Capture ZC Switch",
456 WM8350_LEFT_INPUT_VOLUME,
457 WM8350_RIGHT_INPUT_VOLUME, 13, 1, 0),
458 SOC_SINGLE_TLV("Left Input Left Sidetone Volume",
459 WM8350_OUTPUT_LEFT_MIXER_VOLUME, 1, 7, 0, out_mix_tlv),
460 SOC_SINGLE_TLV("Left Input Right Sidetone Volume",
461 WM8350_OUTPUT_LEFT_MIXER_VOLUME,
462 5, 7, 0, out_mix_tlv),
463 SOC_SINGLE_TLV("Left Input Bypass Volume",
464 WM8350_OUTPUT_LEFT_MIXER_VOLUME,
465 9, 7, 0, out_mix_tlv),
466 SOC_SINGLE_TLV("Right Input Left Sidetone Volume",
467 WM8350_OUTPUT_RIGHT_MIXER_VOLUME,
468 1, 7, 0, out_mix_tlv),
469 SOC_SINGLE_TLV("Right Input Right Sidetone Volume",
470 WM8350_OUTPUT_RIGHT_MIXER_VOLUME,
471 5, 7, 0, out_mix_tlv),
472 SOC_SINGLE_TLV("Right Input Bypass Volume",
473 WM8350_OUTPUT_RIGHT_MIXER_VOLUME,
474 13, 7, 0, out_mix_tlv),
475 SOC_SINGLE("Left Input Mixer +20dB Switch",
476 WM8350_INPUT_MIXER_VOLUME_L, 0, 1, 0),
477 SOC_SINGLE("Right Input Mixer +20dB Switch",
478 WM8350_INPUT_MIXER_VOLUME_R, 0, 1, 0),
479 SOC_SINGLE_TLV("Out4 Capture Volume",
480 WM8350_INPUT_MIXER_VOLUME,
481 1, 7, 0, out_mix_tlv),
482 SOC_WM8350_DOUBLE_R_TLV("Out1 Playback Volume",
483 WM8350_LOUT1_VOLUME,
484 WM8350_ROUT1_VOLUME,
485 2, 63, 0, out_pga_tlv),
486 SOC_DOUBLE_R("Out1 Playback ZC Switch",
487 WM8350_LOUT1_VOLUME,
488 WM8350_ROUT1_VOLUME, 13, 1, 0),
489 SOC_WM8350_DOUBLE_R_TLV("Out2 Playback Volume",
490 WM8350_LOUT2_VOLUME,
491 WM8350_ROUT2_VOLUME,
492 2, 63, 0, out_pga_tlv),
493 SOC_DOUBLE_R("Out2 Playback ZC Switch", WM8350_LOUT2_VOLUME,
494 WM8350_ROUT2_VOLUME, 13, 1, 0),
495 SOC_SINGLE("Out2 Right Invert Switch", WM8350_ROUT2_VOLUME, 10, 1, 0),
496 SOC_SINGLE_TLV("Out2 Beep Volume", WM8350_BEEP_VOLUME,
497 5, 7, 0, out_mix_tlv),
498
499 SOC_DOUBLE_R("Out1 Playback Switch",
500 WM8350_LOUT1_VOLUME,
501 WM8350_ROUT1_VOLUME,
502 14, 1, 1),
503 SOC_DOUBLE_R("Out2 Playback Switch",
504 WM8350_LOUT2_VOLUME,
505 WM8350_ROUT2_VOLUME,
506 14, 1, 1),
507};
508
509/*
510 * DAPM Controls
511 */
512
513/* Left Playback Mixer */
514static const struct snd_kcontrol_new wm8350_left_play_mixer_controls[] = {
515 SOC_DAPM_SINGLE("Playback Switch",
516 WM8350_LEFT_MIXER_CONTROL, 11, 1, 0),
517 SOC_DAPM_SINGLE("Left Bypass Switch",
518 WM8350_LEFT_MIXER_CONTROL, 2, 1, 0),
519 SOC_DAPM_SINGLE("Right Playback Switch",
520 WM8350_LEFT_MIXER_CONTROL, 12, 1, 0),
521 SOC_DAPM_SINGLE("Left Sidetone Switch",
522 WM8350_LEFT_MIXER_CONTROL, 0, 1, 0),
523 SOC_DAPM_SINGLE("Right Sidetone Switch",
524 WM8350_LEFT_MIXER_CONTROL, 1, 1, 0),
525};
526
527/* Right Playback Mixer */
528static const struct snd_kcontrol_new wm8350_right_play_mixer_controls[] = {
529 SOC_DAPM_SINGLE("Playback Switch",
530 WM8350_RIGHT_MIXER_CONTROL, 12, 1, 0),
531 SOC_DAPM_SINGLE("Right Bypass Switch",
532 WM8350_RIGHT_MIXER_CONTROL, 3, 1, 0),
533 SOC_DAPM_SINGLE("Left Playback Switch",
534 WM8350_RIGHT_MIXER_CONTROL, 11, 1, 0),
535 SOC_DAPM_SINGLE("Left Sidetone Switch",
536 WM8350_RIGHT_MIXER_CONTROL, 0, 1, 0),
537 SOC_DAPM_SINGLE("Right Sidetone Switch",
538 WM8350_RIGHT_MIXER_CONTROL, 1, 1, 0),
539};
540
541/* Out4 Mixer */
542static const struct snd_kcontrol_new wm8350_out4_mixer_controls[] = {
543 SOC_DAPM_SINGLE("Right Playback Switch",
544 WM8350_OUT4_MIXER_CONTROL, 12, 1, 0),
545 SOC_DAPM_SINGLE("Left Playback Switch",
546 WM8350_OUT4_MIXER_CONTROL, 11, 1, 0),
547 SOC_DAPM_SINGLE("Right Capture Switch",
548 WM8350_OUT4_MIXER_CONTROL, 9, 1, 0),
549 SOC_DAPM_SINGLE("Out3 Playback Switch",
550 WM8350_OUT4_MIXER_CONTROL, 2, 1, 0),
551 SOC_DAPM_SINGLE("Right Mixer Switch",
552 WM8350_OUT4_MIXER_CONTROL, 1, 1, 0),
553 SOC_DAPM_SINGLE("Left Mixer Switch",
554 WM8350_OUT4_MIXER_CONTROL, 0, 1, 0),
555};
556
557/* Out3 Mixer */
558static const struct snd_kcontrol_new wm8350_out3_mixer_controls[] = {
559 SOC_DAPM_SINGLE("Left Playback Switch",
560 WM8350_OUT3_MIXER_CONTROL, 11, 1, 0),
561 SOC_DAPM_SINGLE("Left Capture Switch",
562 WM8350_OUT3_MIXER_CONTROL, 8, 1, 0),
563 SOC_DAPM_SINGLE("Out4 Playback Switch",
564 WM8350_OUT3_MIXER_CONTROL, 3, 1, 0),
565 SOC_DAPM_SINGLE("Left Mixer Switch",
566 WM8350_OUT3_MIXER_CONTROL, 0, 1, 0),
567};
568
569/* Left Input Mixer */
570static const struct snd_kcontrol_new wm8350_left_capt_mixer_controls[] = {
571 SOC_DAPM_SINGLE_TLV("L2 Capture Volume",
572 WM8350_INPUT_MIXER_VOLUME_L, 1, 7, 0, out_mix_tlv),
573 SOC_DAPM_SINGLE_TLV("L3 Capture Volume",
574 WM8350_INPUT_MIXER_VOLUME_L, 9, 7, 0, out_mix_tlv),
575 SOC_DAPM_SINGLE("PGA Capture Switch",
576 WM8350_LEFT_INPUT_VOLUME, 14, 1, 0),
577};
578
579/* Right Input Mixer */
580static const struct snd_kcontrol_new wm8350_right_capt_mixer_controls[] = {
581 SOC_DAPM_SINGLE_TLV("L2 Capture Volume",
582 WM8350_INPUT_MIXER_VOLUME_R, 5, 7, 0, out_mix_tlv),
583 SOC_DAPM_SINGLE_TLV("L3 Capture Volume",
584 WM8350_INPUT_MIXER_VOLUME_R, 13, 7, 0, out_mix_tlv),
585 SOC_DAPM_SINGLE("PGA Capture Switch",
586 WM8350_RIGHT_INPUT_VOLUME, 14, 1, 0),
587};
588
589/* Left Mic Mixer */
590static const struct snd_kcontrol_new wm8350_left_mic_mixer_controls[] = {
591 SOC_DAPM_SINGLE("INN Capture Switch", WM8350_INPUT_CONTROL, 1, 1, 0),
592 SOC_DAPM_SINGLE("INP Capture Switch", WM8350_INPUT_CONTROL, 0, 1, 0),
593 SOC_DAPM_SINGLE("IN2 Capture Switch", WM8350_INPUT_CONTROL, 2, 1, 0),
594};
595
596/* Right Mic Mixer */
597static const struct snd_kcontrol_new wm8350_right_mic_mixer_controls[] = {
598 SOC_DAPM_SINGLE("INN Capture Switch", WM8350_INPUT_CONTROL, 9, 1, 0),
599 SOC_DAPM_SINGLE("INP Capture Switch", WM8350_INPUT_CONTROL, 8, 1, 0),
600 SOC_DAPM_SINGLE("IN2 Capture Switch", WM8350_INPUT_CONTROL, 10, 1, 0),
601};
602
603/* Beep Switch */
604static const struct snd_kcontrol_new wm8350_beep_switch_controls =
605SOC_DAPM_SINGLE("Switch", WM8350_BEEP_VOLUME, 15, 1, 1);
606
607/* Out4 Capture Mux */
608static const struct snd_kcontrol_new wm8350_out4_capture_controls =
609SOC_DAPM_ENUM("Route", wm8350_enum[8]);
610
611static const struct snd_soc_dapm_widget wm8350_dapm_widgets[] = {
612
613 SND_SOC_DAPM_PGA("IN3R PGA", WM8350_POWER_MGMT_2, 11, 0, NULL, 0),
614 SND_SOC_DAPM_PGA("IN3L PGA", WM8350_POWER_MGMT_2, 10, 0, NULL, 0),
615 SND_SOC_DAPM_PGA_E("Right Out2 PGA", WM8350_POWER_MGMT_3, 3, 0, NULL,
616 0, pga_event,
617 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
618 SND_SOC_DAPM_PGA_E("Left Out2 PGA", WM8350_POWER_MGMT_3, 2, 0, NULL, 0,
619 pga_event,
620 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
621 SND_SOC_DAPM_PGA_E("Right Out1 PGA", WM8350_POWER_MGMT_3, 1, 0, NULL,
622 0, pga_event,
623 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
624 SND_SOC_DAPM_PGA_E("Left Out1 PGA", WM8350_POWER_MGMT_3, 0, 0, NULL, 0,
625 pga_event,
626 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
627
628 SND_SOC_DAPM_MIXER("Right Capture Mixer", WM8350_POWER_MGMT_2,
629 7, 0, &wm8350_right_capt_mixer_controls[0],
630 ARRAY_SIZE(wm8350_right_capt_mixer_controls)),
631
632 SND_SOC_DAPM_MIXER("Left Capture Mixer", WM8350_POWER_MGMT_2,
633 6, 0, &wm8350_left_capt_mixer_controls[0],
634 ARRAY_SIZE(wm8350_left_capt_mixer_controls)),
635
636 SND_SOC_DAPM_MIXER("Out4 Mixer", WM8350_POWER_MGMT_2, 5, 0,
637 &wm8350_out4_mixer_controls[0],
638 ARRAY_SIZE(wm8350_out4_mixer_controls)),
639
640 SND_SOC_DAPM_MIXER("Out3 Mixer", WM8350_POWER_MGMT_2, 4, 0,
641 &wm8350_out3_mixer_controls[0],
642 ARRAY_SIZE(wm8350_out3_mixer_controls)),
643
644 SND_SOC_DAPM_MIXER("Right Playback Mixer", WM8350_POWER_MGMT_2, 1, 0,
645 &wm8350_right_play_mixer_controls[0],
646 ARRAY_SIZE(wm8350_right_play_mixer_controls)),
647
648 SND_SOC_DAPM_MIXER("Left Playback Mixer", WM8350_POWER_MGMT_2, 0, 0,
649 &wm8350_left_play_mixer_controls[0],
650 ARRAY_SIZE(wm8350_left_play_mixer_controls)),
651
652 SND_SOC_DAPM_MIXER("Left Mic Mixer", WM8350_POWER_MGMT_2, 8, 0,
653 &wm8350_left_mic_mixer_controls[0],
654 ARRAY_SIZE(wm8350_left_mic_mixer_controls)),
655
656 SND_SOC_DAPM_MIXER("Right Mic Mixer", WM8350_POWER_MGMT_2, 9, 0,
657 &wm8350_right_mic_mixer_controls[0],
658 ARRAY_SIZE(wm8350_right_mic_mixer_controls)),
659
660 /* virtual mixer for Beep and Out2R */
661 SND_SOC_DAPM_MIXER("Out2 Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
662
663 SND_SOC_DAPM_SWITCH("Beep", WM8350_POWER_MGMT_3, 7, 0,
664 &wm8350_beep_switch_controls),
665
666 SND_SOC_DAPM_ADC("Right ADC", "Right Capture",
667 WM8350_POWER_MGMT_4, 3, 0),
668 SND_SOC_DAPM_ADC("Left ADC", "Left Capture",
669 WM8350_POWER_MGMT_4, 2, 0),
670 SND_SOC_DAPM_DAC("Right DAC", "Right Playback",
671 WM8350_POWER_MGMT_4, 5, 0),
672 SND_SOC_DAPM_DAC("Left DAC", "Left Playback",
673 WM8350_POWER_MGMT_4, 4, 0),
674
675 SND_SOC_DAPM_MICBIAS("Mic Bias", WM8350_POWER_MGMT_1, 4, 0),
676
677 SND_SOC_DAPM_MUX("Out4 Capture Channel", SND_SOC_NOPM, 0, 0,
678 &wm8350_out4_capture_controls),
679
680 SND_SOC_DAPM_OUTPUT("OUT1R"),
681 SND_SOC_DAPM_OUTPUT("OUT1L"),
682 SND_SOC_DAPM_OUTPUT("OUT2R"),
683 SND_SOC_DAPM_OUTPUT("OUT2L"),
684 SND_SOC_DAPM_OUTPUT("OUT3"),
685 SND_SOC_DAPM_OUTPUT("OUT4"),
686
687 SND_SOC_DAPM_INPUT("IN1RN"),
688 SND_SOC_DAPM_INPUT("IN1RP"),
689 SND_SOC_DAPM_INPUT("IN2R"),
690 SND_SOC_DAPM_INPUT("IN1LP"),
691 SND_SOC_DAPM_INPUT("IN1LN"),
692 SND_SOC_DAPM_INPUT("IN2L"),
693 SND_SOC_DAPM_INPUT("IN3R"),
694 SND_SOC_DAPM_INPUT("IN3L"),
695};
696
697static const struct snd_soc_dapm_route audio_map[] = {
698
699 /* left playback mixer */
700 {"Left Playback Mixer", "Playback Switch", "Left DAC"},
701 {"Left Playback Mixer", "Left Bypass Switch", "IN3L PGA"},
702 {"Left Playback Mixer", "Right Playback Switch", "Right DAC"},
703 {"Left Playback Mixer", "Left Sidetone Switch", "Left Mic Mixer"},
704 {"Left Playback Mixer", "Right Sidetone Switch", "Right Mic Mixer"},
705
706 /* right playback mixer */
707 {"Right Playback Mixer", "Playback Switch", "Right DAC"},
708 {"Right Playback Mixer", "Right Bypass Switch", "IN3R PGA"},
709 {"Right Playback Mixer", "Left Playback Switch", "Left DAC"},
710 {"Right Playback Mixer", "Left Sidetone Switch", "Left Mic Mixer"},
711 {"Right Playback Mixer", "Right Sidetone Switch", "Right Mic Mixer"},
712
713 /* out4 playback mixer */
714 {"Out4 Mixer", "Right Playback Switch", "Right DAC"},
715 {"Out4 Mixer", "Left Playback Switch", "Left DAC"},
716 {"Out4 Mixer", "Right Capture Switch", "Right Capture Mixer"},
717 {"Out4 Mixer", "Out3 Playback Switch", "Out3 Mixer"},
718 {"Out4 Mixer", "Right Mixer Switch", "Right Playback Mixer"},
719 {"Out4 Mixer", "Left Mixer Switch", "Left Playback Mixer"},
720 {"OUT4", NULL, "Out4 Mixer"},
721
722 /* out3 playback mixer */
723 {"Out3 Mixer", "Left Playback Switch", "Left DAC"},
724 {"Out3 Mixer", "Left Capture Switch", "Left Capture Mixer"},
725 {"Out3 Mixer", "Left Mixer Switch", "Left Playback Mixer"},
726 {"Out3 Mixer", "Out4 Playback Switch", "Out4 Mixer"},
727 {"OUT3", NULL, "Out3 Mixer"},
728
729 /* out2 */
730 {"Right Out2 PGA", NULL, "Right Playback Mixer"},
731 {"Left Out2 PGA", NULL, "Left Playback Mixer"},
732 {"OUT2L", NULL, "Left Out2 PGA"},
733 {"OUT2R", NULL, "Right Out2 PGA"},
734
735 /* out1 */
736 {"Right Out1 PGA", NULL, "Right Playback Mixer"},
737 {"Left Out1 PGA", NULL, "Left Playback Mixer"},
738 {"OUT1L", NULL, "Left Out1 PGA"},
739 {"OUT1R", NULL, "Right Out1 PGA"},
740
741 /* ADCs */
742 {"Left ADC", NULL, "Left Capture Mixer"},
743 {"Right ADC", NULL, "Right Capture Mixer"},
744
745 /* Left capture mixer */
746 {"Left Capture Mixer", "L2 Capture Volume", "IN2L"},
747 {"Left Capture Mixer", "L3 Capture Volume", "IN3L PGA"},
748 {"Left Capture Mixer", "PGA Capture Switch", "Left Mic Mixer"},
749 {"Left Capture Mixer", NULL, "Out4 Capture Channel"},
750
751 /* Right capture mixer */
752 {"Right Capture Mixer", "L2 Capture Volume", "IN2R"},
753 {"Right Capture Mixer", "L3 Capture Volume", "IN3R PGA"},
754 {"Right Capture Mixer", "PGA Capture Switch", "Right Mic Mixer"},
755 {"Right Capture Mixer", NULL, "Out4 Capture Channel"},
756
757 /* L3 Inputs */
758 {"IN3L PGA", NULL, "IN3L"},
759 {"IN3R PGA", NULL, "IN3R"},
760
761 /* Left Mic mixer */
762 {"Left Mic Mixer", "INN Capture Switch", "IN1LN"},
763 {"Left Mic Mixer", "INP Capture Switch", "IN1LP"},
764 {"Left Mic Mixer", "IN2 Capture Switch", "IN2L"},
765
766 /* Right Mic mixer */
767 {"Right Mic Mixer", "INN Capture Switch", "IN1RN"},
768 {"Right Mic Mixer", "INP Capture Switch", "IN1RP"},
769 {"Right Mic Mixer", "IN2 Capture Switch", "IN2R"},
770
771 /* out 4 capture */
772 {"Out4 Capture Channel", NULL, "Out4 Mixer"},
773
774 /* Beep */
775 {"Beep", NULL, "IN3R PGA"},
776};
777
778static int wm8350_add_controls(struct snd_soc_codec *codec)
779{
780 int err, i;
781
782 for (i = 0; i < ARRAY_SIZE(wm8350_snd_controls); i++) {
783 err = snd_ctl_add(codec->card,
784 snd_soc_cnew(&wm8350_snd_controls[i],
785 codec, NULL));
786 if (err < 0)
787 return err;
788 }
789
790 return 0;
791}
792
793static int wm8350_add_widgets(struct snd_soc_codec *codec)
794{
795 int ret;
796
797 ret = snd_soc_dapm_new_controls(codec,
798 wm8350_dapm_widgets,
799 ARRAY_SIZE(wm8350_dapm_widgets));
800 if (ret != 0) {
801 dev_err(codec->dev, "dapm control register failed\n");
802 return ret;
803 }
804
805 /* set up audio paths */
806 ret = snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
807 if (ret != 0) {
808 dev_err(codec->dev, "DAPM route register failed\n");
809 return ret;
810 }
811
812 return snd_soc_dapm_new_widgets(codec);
813}
814
815static int wm8350_set_dai_sysclk(struct snd_soc_dai *codec_dai,
816 int clk_id, unsigned int freq, int dir)
817{
818 struct snd_soc_codec *codec = codec_dai->codec;
819 struct wm8350 *wm8350 = codec->control_data;
820 u16 fll_4;
821
822 switch (clk_id) {
823 case WM8350_MCLK_SEL_MCLK:
824 wm8350_clear_bits(wm8350, WM8350_CLOCK_CONTROL_1,
825 WM8350_MCLK_SEL);
826 break;
827 case WM8350_MCLK_SEL_PLL_MCLK:
828 case WM8350_MCLK_SEL_PLL_DAC:
829 case WM8350_MCLK_SEL_PLL_ADC:
830 case WM8350_MCLK_SEL_PLL_32K:
831 wm8350_set_bits(wm8350, WM8350_CLOCK_CONTROL_1,
832 WM8350_MCLK_SEL);
833 fll_4 = wm8350_codec_read(codec, WM8350_FLL_CONTROL_4) &
834 ~WM8350_FLL_CLK_SRC_MASK;
835 wm8350_codec_write(codec, WM8350_FLL_CONTROL_4, fll_4 | clk_id);
836 break;
837 }
838
839 /* MCLK direction */
840 if (dir == WM8350_MCLK_DIR_OUT)
841 wm8350_set_bits(wm8350, WM8350_CLOCK_CONTROL_2,
842 WM8350_MCLK_DIR);
843 else
844 wm8350_clear_bits(wm8350, WM8350_CLOCK_CONTROL_2,
845 WM8350_MCLK_DIR);
846
847 return 0;
848}
849
850static int wm8350_set_clkdiv(struct snd_soc_dai *codec_dai, int div_id, int div)
851{
852 struct snd_soc_codec *codec = codec_dai->codec;
853 u16 val;
854
855 switch (div_id) {
856 case WM8350_ADC_CLKDIV:
857 val = wm8350_codec_read(codec, WM8350_ADC_DIVIDER) &
858 ~WM8350_ADC_CLKDIV_MASK;
859 wm8350_codec_write(codec, WM8350_ADC_DIVIDER, val | div);
860 break;
861 case WM8350_DAC_CLKDIV:
862 val = wm8350_codec_read(codec, WM8350_DAC_CLOCK_CONTROL) &
863 ~WM8350_DAC_CLKDIV_MASK;
864 wm8350_codec_write(codec, WM8350_DAC_CLOCK_CONTROL, val | div);
865 break;
866 case WM8350_BCLK_CLKDIV:
867 val = wm8350_codec_read(codec, WM8350_CLOCK_CONTROL_1) &
868 ~WM8350_BCLK_DIV_MASK;
869 wm8350_codec_write(codec, WM8350_CLOCK_CONTROL_1, val | div);
870 break;
871 case WM8350_OPCLK_CLKDIV:
872 val = wm8350_codec_read(codec, WM8350_CLOCK_CONTROL_1) &
873 ~WM8350_OPCLK_DIV_MASK;
874 wm8350_codec_write(codec, WM8350_CLOCK_CONTROL_1, val | div);
875 break;
876 case WM8350_SYS_CLKDIV:
877 val = wm8350_codec_read(codec, WM8350_CLOCK_CONTROL_1) &
878 ~WM8350_MCLK_DIV_MASK;
879 wm8350_codec_write(codec, WM8350_CLOCK_CONTROL_1, val | div);
880 break;
881 case WM8350_DACLR_CLKDIV:
882 val = wm8350_codec_read(codec, WM8350_DAC_LR_RATE) &
883 ~WM8350_DACLRC_RATE_MASK;
884 wm8350_codec_write(codec, WM8350_DAC_LR_RATE, val | div);
885 break;
886 case WM8350_ADCLR_CLKDIV:
887 val = wm8350_codec_read(codec, WM8350_ADC_LR_RATE) &
888 ~WM8350_ADCLRC_RATE_MASK;
889 wm8350_codec_write(codec, WM8350_ADC_LR_RATE, val | div);
890 break;
891 default:
892 return -EINVAL;
893 }
894
895 return 0;
896}
897
898static int wm8350_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
899{
900 struct snd_soc_codec *codec = codec_dai->codec;
901 u16 iface = wm8350_codec_read(codec, WM8350_AI_FORMATING) &
902 ~(WM8350_AIF_BCLK_INV | WM8350_AIF_LRCLK_INV | WM8350_AIF_FMT_MASK);
903 u16 master = wm8350_codec_read(codec, WM8350_AI_DAC_CONTROL) &
904 ~WM8350_BCLK_MSTR;
905 u16 dac_lrc = wm8350_codec_read(codec, WM8350_DAC_LR_RATE) &
906 ~WM8350_DACLRC_ENA;
907 u16 adc_lrc = wm8350_codec_read(codec, WM8350_ADC_LR_RATE) &
908 ~WM8350_ADCLRC_ENA;
909
910 /* set master/slave audio interface */
911 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
912 case SND_SOC_DAIFMT_CBM_CFM:
913 master |= WM8350_BCLK_MSTR;
914 dac_lrc |= WM8350_DACLRC_ENA;
915 adc_lrc |= WM8350_ADCLRC_ENA;
916 break;
917 case SND_SOC_DAIFMT_CBS_CFS:
918 break;
919 default:
920 return -EINVAL;
921 }
922
923 /* interface format */
924 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
925 case SND_SOC_DAIFMT_I2S:
926 iface |= 0x2 << 8;
927 break;
928 case SND_SOC_DAIFMT_RIGHT_J:
929 break;
930 case SND_SOC_DAIFMT_LEFT_J:
931 iface |= 0x1 << 8;
932 break;
933 case SND_SOC_DAIFMT_DSP_A:
934 iface |= 0x3 << 8;
935 break;
936 case SND_SOC_DAIFMT_DSP_B:
937 iface |= 0x3 << 8; /* lg not sure which mode */
938 break;
939 default:
940 return -EINVAL;
941 }
942
943 /* clock inversion */
944 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
945 case SND_SOC_DAIFMT_NB_NF:
946 break;
947 case SND_SOC_DAIFMT_IB_IF:
948 iface |= WM8350_AIF_LRCLK_INV | WM8350_AIF_BCLK_INV;
949 break;
950 case SND_SOC_DAIFMT_IB_NF:
951 iface |= WM8350_AIF_BCLK_INV;
952 break;
953 case SND_SOC_DAIFMT_NB_IF:
954 iface |= WM8350_AIF_LRCLK_INV;
955 break;
956 default:
957 return -EINVAL;
958 }
959
960 wm8350_codec_write(codec, WM8350_AI_FORMATING, iface);
961 wm8350_codec_write(codec, WM8350_AI_DAC_CONTROL, master);
962 wm8350_codec_write(codec, WM8350_DAC_LR_RATE, dac_lrc);
963 wm8350_codec_write(codec, WM8350_ADC_LR_RATE, adc_lrc);
964 return 0;
965}
966
967static int wm8350_pcm_trigger(struct snd_pcm_substream *substream,
968 int cmd, struct snd_soc_dai *codec_dai)
969{
970 struct snd_soc_codec *codec = codec_dai->codec;
971 int master = wm8350_codec_cache_read(codec, WM8350_AI_DAC_CONTROL) &
972 WM8350_BCLK_MSTR;
973 int enabled = 0;
974
975 /* Check that the DACs or ADCs are enabled since they are
976 * required for LRC in master mode. The DACs or ADCs need a
977 * valid audio path i.e. pin -> ADC or DAC -> pin before
978 * the LRC will be enabled in master mode. */
979 if (!master && cmd != SNDRV_PCM_TRIGGER_START)
980 return 0;
981
982 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
983 enabled = wm8350_codec_cache_read(codec, WM8350_POWER_MGMT_4) &
984 (WM8350_ADCR_ENA | WM8350_ADCL_ENA);
985 } else {
986 enabled = wm8350_codec_cache_read(codec, WM8350_POWER_MGMT_4) &
987 (WM8350_DACR_ENA | WM8350_DACL_ENA);
988 }
989
990 if (!enabled) {
991 dev_err(codec->dev,
992 "%s: invalid audio path - no clocks available\n",
993 __func__);
994 return -EINVAL;
995 }
996 return 0;
997}
998
999static int wm8350_pcm_hw_params(struct snd_pcm_substream *substream,
1000 struct snd_pcm_hw_params *params,
1001 struct snd_soc_dai *codec_dai)
1002{
1003 struct snd_soc_codec *codec = codec_dai->codec;
1004 u16 iface = wm8350_codec_read(codec, WM8350_AI_FORMATING) &
1005 ~WM8350_AIF_WL_MASK;
1006
1007 /* bit size */
1008 switch (params_format(params)) {
1009 case SNDRV_PCM_FORMAT_S16_LE:
1010 break;
1011 case SNDRV_PCM_FORMAT_S20_3LE:
1012 iface |= 0x1 << 10;
1013 break;
1014 case SNDRV_PCM_FORMAT_S24_LE:
1015 iface |= 0x2 << 10;
1016 break;
1017 case SNDRV_PCM_FORMAT_S32_LE:
1018 iface |= 0x3 << 10;
1019 break;
1020 }
1021
1022 wm8350_codec_write(codec, WM8350_AI_FORMATING, iface);
1023 return 0;
1024}
1025
1026static int wm8350_mute(struct snd_soc_dai *dai, int mute)
1027{
1028 struct snd_soc_codec *codec = dai->codec;
1029 struct wm8350 *wm8350 = codec->control_data;
1030
1031 if (mute)
1032 wm8350_set_bits(wm8350, WM8350_DAC_MUTE, WM8350_DAC_MUTE_ENA);
1033 else
1034 wm8350_clear_bits(wm8350, WM8350_DAC_MUTE, WM8350_DAC_MUTE_ENA);
1035 return 0;
1036}
1037
1038/* FLL divisors */
1039struct _fll_div {
1040 int div; /* FLL_OUTDIV */
1041 int n;
1042 int k;
1043 int ratio; /* FLL_FRATIO */
1044};
1045
1046/* The size in bits of the fll divide multiplied by 10
1047 * to allow rounding later */
1048#define FIXED_FLL_SIZE ((1 << 16) * 10)
1049
1050static inline int fll_factors(struct _fll_div *fll_div, unsigned int input,
1051 unsigned int output)
1052{
1053 u64 Kpart;
1054 unsigned int t1, t2, K, Nmod;
1055
1056 if (output >= 2815250 && output <= 3125000)
1057 fll_div->div = 0x4;
1058 else if (output >= 5625000 && output <= 6250000)
1059 fll_div->div = 0x3;
1060 else if (output >= 11250000 && output <= 12500000)
1061 fll_div->div = 0x2;
1062 else if (output >= 22500000 && output <= 25000000)
1063 fll_div->div = 0x1;
1064 else {
1065 printk(KERN_ERR "wm8350: fll freq %d out of range\n", output);
1066 return -EINVAL;
1067 }
1068
1069 if (input > 48000)
1070 fll_div->ratio = 1;
1071 else
1072 fll_div->ratio = 8;
1073
1074 t1 = output * (1 << (fll_div->div + 1));
1075 t2 = input * fll_div->ratio;
1076
1077 fll_div->n = t1 / t2;
1078 Nmod = t1 % t2;
1079
1080 if (Nmod) {
1081 Kpart = FIXED_FLL_SIZE * (long long)Nmod;
1082 do_div(Kpart, t2);
1083 K = Kpart & 0xFFFFFFFF;
1084
1085 /* Check if we need to round */
1086 if ((K % 10) >= 5)
1087 K += 5;
1088
1089 /* Move down to proper range now rounding is done */
1090 K /= 10;
1091 fll_div->k = K;
1092 } else
1093 fll_div->k = 0;
1094
1095 return 0;
1096}
1097
1098static int wm8350_set_fll(struct snd_soc_dai *codec_dai,
1099 int pll_id, unsigned int freq_in,
1100 unsigned int freq_out)
1101{
1102 struct snd_soc_codec *codec = codec_dai->codec;
1103 struct wm8350 *wm8350 = codec->control_data;
1104 struct _fll_div fll_div;
1105 int ret = 0;
1106 u16 fll_1, fll_4;
1107
1108 /* power down FLL - we need to do this for reconfiguration */
1109 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_4,
1110 WM8350_FLL_ENA | WM8350_FLL_OSC_ENA);
1111
1112 if (freq_out == 0 || freq_in == 0)
1113 return ret;
1114
1115 ret = fll_factors(&fll_div, freq_in, freq_out);
1116 if (ret < 0)
1117 return ret;
1118 dev_dbg(wm8350->dev,
1119 "FLL in %d FLL out %d N 0x%x K 0x%x div %d ratio %d",
1120 freq_in, freq_out, fll_div.n, fll_div.k, fll_div.div,
1121 fll_div.ratio);
1122
1123 /* set up N.K & dividers */
1124 fll_1 = wm8350_codec_read(codec, WM8350_FLL_CONTROL_1) &
1125 ~(WM8350_FLL_OUTDIV_MASK | WM8350_FLL_RSP_RATE_MASK | 0xc000);
1126 wm8350_codec_write(codec, WM8350_FLL_CONTROL_1,
1127 fll_1 | (fll_div.div << 8) | 0x50);
1128 wm8350_codec_write(codec, WM8350_FLL_CONTROL_2,
1129 (fll_div.ratio << 11) | (fll_div.
1130 n & WM8350_FLL_N_MASK));
1131 wm8350_codec_write(codec, WM8350_FLL_CONTROL_3, fll_div.k);
1132 fll_4 = wm8350_codec_read(codec, WM8350_FLL_CONTROL_4) &
1133 ~(WM8350_FLL_FRAC | WM8350_FLL_SLOW_LOCK_REF);
1134 wm8350_codec_write(codec, WM8350_FLL_CONTROL_4,
1135 fll_4 | (fll_div.k ? WM8350_FLL_FRAC : 0) |
1136 (fll_div.ratio == 8 ? WM8350_FLL_SLOW_LOCK_REF : 0));
1137
1138 /* power FLL on */
1139 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_FLL_OSC_ENA);
1140 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_FLL_ENA);
1141
1142 return 0;
1143}
1144
1145static int wm8350_set_bias_level(struct snd_soc_codec *codec,
1146 enum snd_soc_bias_level level)
1147{
1148 struct wm8350 *wm8350 = codec->control_data;
1149 struct wm8350_data *priv = codec->private_data;
1150 struct wm8350_audio_platform_data *platform =
1151 wm8350->codec.platform_data;
1152 u16 pm1;
1153 int ret;
1154
1155 switch (level) {
1156 case SND_SOC_BIAS_ON:
1157 pm1 = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_1) &
1158 ~(WM8350_VMID_MASK | WM8350_CODEC_ISEL_MASK);
1159 wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1,
1160 pm1 | WM8350_VMID_50K |
1161 platform->codec_current_on << 14);
1162 break;
1163
1164 case SND_SOC_BIAS_PREPARE:
1165 pm1 = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_1);
1166 pm1 &= ~WM8350_VMID_MASK;
1167 wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1,
1168 pm1 | WM8350_VMID_50K);
1169 break;
1170
1171 case SND_SOC_BIAS_STANDBY:
1172 if (codec->bias_level == SND_SOC_BIAS_OFF) {
1173 ret = regulator_bulk_enable(ARRAY_SIZE(priv->supplies),
1174 priv->supplies);
1175 if (ret != 0)
1176 return ret;
1177
1178 /* Enable the system clock */
1179 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_4,
1180 WM8350_SYSCLK_ENA);
1181
1182 /* mute DAC & outputs */
1183 wm8350_set_bits(wm8350, WM8350_DAC_MUTE,
1184 WM8350_DAC_MUTE_ENA);
1185
1186 /* discharge cap memory */
1187 wm8350_reg_write(wm8350, WM8350_ANTI_POP_CONTROL,
1188 platform->dis_out1 |
1189 (platform->dis_out2 << 2) |
1190 (platform->dis_out3 << 4) |
1191 (platform->dis_out4 << 6));
1192
1193 /* wait for discharge */
1194 schedule_timeout_interruptible(msecs_to_jiffies
1195 (platform->
1196 cap_discharge_msecs));
1197
1198 /* enable antipop */
1199 wm8350_reg_write(wm8350, WM8350_ANTI_POP_CONTROL,
1200 (platform->vmid_s_curve << 8));
1201
1202 /* ramp up vmid */
1203 wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1,
1204 (platform->
1205 codec_current_charge << 14) |
1206 WM8350_VMID_5K | WM8350_VMIDEN |
1207 WM8350_VBUFEN);
1208
1209 /* wait for vmid */
1210 schedule_timeout_interruptible(msecs_to_jiffies
1211 (platform->
1212 vmid_charge_msecs));
1213
1214 /* turn on vmid 300k */
1215 pm1 = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_1) &
1216 ~(WM8350_VMID_MASK | WM8350_CODEC_ISEL_MASK);
1217 pm1 |= WM8350_VMID_300K |
1218 (platform->codec_current_standby << 14);
1219 wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1,
1220 pm1);
1221
1222
1223 /* enable analogue bias */
1224 pm1 |= WM8350_BIASEN;
1225 wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1, pm1);
1226
1227 /* disable antipop */
1228 wm8350_reg_write(wm8350, WM8350_ANTI_POP_CONTROL, 0);
1229
1230 } else {
1231 /* turn on vmid 300k and reduce current */
1232 pm1 = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_1) &
1233 ~(WM8350_VMID_MASK | WM8350_CODEC_ISEL_MASK);
1234 wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1,
1235 pm1 | WM8350_VMID_300K |
1236 (platform->
1237 codec_current_standby << 14));
1238
1239 }
1240 break;
1241
1242 case SND_SOC_BIAS_OFF:
1243
1244 /* mute DAC & enable outputs */
1245 wm8350_set_bits(wm8350, WM8350_DAC_MUTE, WM8350_DAC_MUTE_ENA);
1246
1247 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_3,
1248 WM8350_OUT1L_ENA | WM8350_OUT1R_ENA |
1249 WM8350_OUT2L_ENA | WM8350_OUT2R_ENA);
1250
1251 /* enable anti pop S curve */
1252 wm8350_reg_write(wm8350, WM8350_ANTI_POP_CONTROL,
1253 (platform->vmid_s_curve << 8));
1254
1255 /* turn off vmid */
1256 pm1 = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_1) &
1257 ~WM8350_VMIDEN;
1258 wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1, pm1);
1259
1260 /* wait */
1261 schedule_timeout_interruptible(msecs_to_jiffies
1262 (platform->
1263 vmid_discharge_msecs));
1264
1265 wm8350_reg_write(wm8350, WM8350_ANTI_POP_CONTROL,
1266 (platform->vmid_s_curve << 8) |
1267 platform->dis_out1 |
1268 (platform->dis_out2 << 2) |
1269 (platform->dis_out3 << 4) |
1270 (platform->dis_out4 << 6));
1271
1272 /* turn off VBuf and drain */
1273 pm1 = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_1) &
1274 ~(WM8350_VBUFEN | WM8350_VMID_MASK);
1275 wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1,
1276 pm1 | WM8350_OUTPUT_DRAIN_EN);
1277
1278 /* wait */
1279 schedule_timeout_interruptible(msecs_to_jiffies
1280 (platform->drain_msecs));
1281
1282 pm1 &= ~WM8350_BIASEN;
1283 wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1, pm1);
1284
1285 /* disable anti-pop */
1286 wm8350_reg_write(wm8350, WM8350_ANTI_POP_CONTROL, 0);
1287
1288 wm8350_clear_bits(wm8350, WM8350_LOUT1_VOLUME,
1289 WM8350_OUT1L_ENA);
1290 wm8350_clear_bits(wm8350, WM8350_ROUT1_VOLUME,
1291 WM8350_OUT1R_ENA);
1292 wm8350_clear_bits(wm8350, WM8350_LOUT2_VOLUME,
1293 WM8350_OUT2L_ENA);
1294 wm8350_clear_bits(wm8350, WM8350_ROUT2_VOLUME,
1295 WM8350_OUT2R_ENA);
1296
1297 /* disable clock gen */
1298 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_4,
1299 WM8350_SYSCLK_ENA);
1300
1301 regulator_bulk_disable(ARRAY_SIZE(priv->supplies),
1302 priv->supplies);
1303 break;
1304 }
1305 codec->bias_level = level;
1306 return 0;
1307}
1308
1309static int wm8350_suspend(struct platform_device *pdev, pm_message_t state)
1310{
1311 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1312 struct snd_soc_codec *codec = socdev->codec;
1313
1314 wm8350_set_bias_level(codec, SND_SOC_BIAS_OFF);
1315 return 0;
1316}
1317
1318static int wm8350_resume(struct platform_device *pdev)
1319{
1320 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1321 struct snd_soc_codec *codec = socdev->codec;
1322
1323 wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1324
1325 if (codec->suspend_bias_level == SND_SOC_BIAS_ON)
1326 wm8350_set_bias_level(codec, SND_SOC_BIAS_ON);
1327
1328 return 0;
1329}
1330
1331static struct snd_soc_codec *wm8350_codec;
1332
1333static int wm8350_probe(struct platform_device *pdev)
1334{
1335 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1336 struct snd_soc_codec *codec;
1337 struct wm8350 *wm8350;
1338 struct wm8350_data *priv;
1339 int ret;
1340 struct wm8350_output *out1;
1341 struct wm8350_output *out2;
1342
1343 BUG_ON(!wm8350_codec);
1344
1345 socdev->codec = wm8350_codec;
1346 codec = socdev->codec;
1347 wm8350 = codec->control_data;
1348 priv = codec->private_data;
1349
1350 /* Enable the codec */
1351 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
1352
1353 /* Enable robust clocking mode in ADC */
1354 wm8350_codec_write(codec, WM8350_SECURITY, 0xa7);
1355 wm8350_codec_write(codec, 0xde, 0x13);
1356 wm8350_codec_write(codec, WM8350_SECURITY, 0);
1357
1358 /* read OUT1 & OUT2 volumes */
1359 out1 = &priv->out1;
1360 out2 = &priv->out2;
1361 out1->left_vol = (wm8350_reg_read(wm8350, WM8350_LOUT1_VOLUME) &
1362 WM8350_OUT1L_VOL_MASK) >> WM8350_OUT1L_VOL_SHIFT;
1363 out1->right_vol = (wm8350_reg_read(wm8350, WM8350_ROUT1_VOLUME) &
1364 WM8350_OUT1R_VOL_MASK) >> WM8350_OUT1R_VOL_SHIFT;
1365 out2->left_vol = (wm8350_reg_read(wm8350, WM8350_LOUT2_VOLUME) &
1366 WM8350_OUT2L_VOL_MASK) >> WM8350_OUT1L_VOL_SHIFT;
1367 out2->right_vol = (wm8350_reg_read(wm8350, WM8350_ROUT2_VOLUME) &
1368 WM8350_OUT2R_VOL_MASK) >> WM8350_OUT1R_VOL_SHIFT;
1369 wm8350_reg_write(wm8350, WM8350_LOUT1_VOLUME, 0);
1370 wm8350_reg_write(wm8350, WM8350_ROUT1_VOLUME, 0);
1371 wm8350_reg_write(wm8350, WM8350_LOUT2_VOLUME, 0);
1372 wm8350_reg_write(wm8350, WM8350_ROUT2_VOLUME, 0);
1373
1374 /* Latch VU bits & mute */
1375 wm8350_set_bits(wm8350, WM8350_LOUT1_VOLUME,
1376 WM8350_OUT1_VU | WM8350_OUT1L_MUTE);
1377 wm8350_set_bits(wm8350, WM8350_LOUT2_VOLUME,
1378 WM8350_OUT2_VU | WM8350_OUT2L_MUTE);
1379 wm8350_set_bits(wm8350, WM8350_ROUT1_VOLUME,
1380 WM8350_OUT1_VU | WM8350_OUT1R_MUTE);
1381 wm8350_set_bits(wm8350, WM8350_ROUT2_VOLUME,
1382 WM8350_OUT2_VU | WM8350_OUT2R_MUTE);
1383
1384 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1385 if (ret < 0) {
1386 dev_err(&pdev->dev, "failed to create pcms\n");
1387 return ret;
1388 }
1389
1390 wm8350_add_controls(codec);
1391 wm8350_add_widgets(codec);
1392
1393 wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1394
1395 ret = snd_soc_init_card(socdev);
1396 if (ret < 0) {
1397 dev_err(&pdev->dev, "failed to register card\n");
1398 goto card_err;
1399 }
1400
1401 return 0;
1402
1403card_err:
1404 snd_soc_free_pcms(socdev);
1405 snd_soc_dapm_free(socdev);
1406 return ret;
1407}
1408
1409static int wm8350_remove(struct platform_device *pdev)
1410{
1411 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1412 struct snd_soc_codec *codec = socdev->codec;
1413 struct wm8350 *wm8350 = codec->control_data;
1414 int ret;
1415
1416 /* cancel any work waiting to be queued. */
1417 ret = cancel_delayed_work(&codec->delayed_work);
1418
1419 /* if there was any work waiting then we run it now and
1420 * wait for its completion */
1421 if (ret) {
1422 schedule_delayed_work(&codec->delayed_work, 0);
1423 flush_scheduled_work();
1424 }
1425
1426 wm8350_set_bias_level(codec, SND_SOC_BIAS_OFF);
1427
1428 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
1429
1430 return 0;
1431}
1432
1433#define WM8350_RATES (SNDRV_PCM_RATE_8000_96000)
1434
1435#define WM8350_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
1436 SNDRV_PCM_FMTBIT_S20_3LE |\
1437 SNDRV_PCM_FMTBIT_S24_LE)
1438
1439struct snd_soc_dai wm8350_dai = {
1440 .name = "WM8350",
1441 .playback = {
1442 .stream_name = "Playback",
1443 .channels_min = 1,
1444 .channels_max = 2,
1445 .rates = WM8350_RATES,
1446 .formats = WM8350_FORMATS,
1447 },
1448 .capture = {
1449 .stream_name = "Capture",
1450 .channels_min = 1,
1451 .channels_max = 2,
1452 .rates = WM8350_RATES,
1453 .formats = WM8350_FORMATS,
1454 },
1455 .ops = {
1456 .hw_params = wm8350_pcm_hw_params,
1457 .digital_mute = wm8350_mute,
1458 .trigger = wm8350_pcm_trigger,
1459 .set_fmt = wm8350_set_dai_fmt,
1460 .set_sysclk = wm8350_set_dai_sysclk,
1461 .set_pll = wm8350_set_fll,
1462 .set_clkdiv = wm8350_set_clkdiv,
1463 },
1464};
1465EXPORT_SYMBOL_GPL(wm8350_dai);
1466
1467struct snd_soc_codec_device soc_codec_dev_wm8350 = {
1468 .probe = wm8350_probe,
1469 .remove = wm8350_remove,
1470 .suspend = wm8350_suspend,
1471 .resume = wm8350_resume,
1472};
1473EXPORT_SYMBOL_GPL(soc_codec_dev_wm8350);
1474
1475static int wm8350_codec_probe(struct platform_device *pdev)
1476{
1477 struct wm8350 *wm8350 = platform_get_drvdata(pdev);
1478 struct wm8350_data *priv;
1479 struct snd_soc_codec *codec;
1480 int ret, i;
1481
1482 if (wm8350->codec.platform_data == NULL) {
1483 dev_err(&pdev->dev, "No audio platform data supplied\n");
1484 return -EINVAL;
1485 }
1486
1487 priv = kzalloc(sizeof(struct wm8350_data), GFP_KERNEL);
1488 if (priv == NULL)
1489 return -ENOMEM;
1490
1491 for (i = 0; i < ARRAY_SIZE(supply_names); i++)
1492 priv->supplies[i].supply = supply_names[i];
1493
1494 ret = regulator_bulk_get(wm8350->dev, ARRAY_SIZE(priv->supplies),
1495 priv->supplies);
1496 if (ret != 0)
1497 goto err_priv;
1498
1499 codec = &priv->codec;
1500 wm8350->codec.codec = codec;
1501
1502 wm8350_dai.dev = &pdev->dev;
1503
1504 mutex_init(&codec->mutex);
1505 INIT_LIST_HEAD(&codec->dapm_widgets);
1506 INIT_LIST_HEAD(&codec->dapm_paths);
1507 codec->dev = &pdev->dev;
1508 codec->name = "WM8350";
1509 codec->owner = THIS_MODULE;
1510 codec->read = wm8350_codec_read;
1511 codec->write = wm8350_codec_write;
1512 codec->bias_level = SND_SOC_BIAS_OFF;
1513 codec->set_bias_level = wm8350_set_bias_level;
1514 codec->dai = &wm8350_dai;
1515 codec->num_dai = 1;
1516 codec->reg_cache_size = WM8350_MAX_REGISTER;
1517 codec->private_data = priv;
1518 codec->control_data = wm8350;
1519
1520 /* Put the codec into reset if it wasn't already */
1521 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
1522
1523 INIT_DELAYED_WORK(&codec->delayed_work, wm8350_pga_work);
1524 ret = snd_soc_register_codec(codec);
1525 if (ret != 0)
1526 goto err_supply;
1527
1528 wm8350_codec = codec;
1529
1530 ret = snd_soc_register_dai(&wm8350_dai);
1531 if (ret != 0)
1532 goto err_codec;
1533 return 0;
1534
1535err_codec:
1536 snd_soc_unregister_codec(codec);
1537err_supply:
1538 regulator_bulk_free(ARRAY_SIZE(priv->supplies), priv->supplies);
1539err_priv:
1540 kfree(priv);
1541 wm8350_codec = NULL;
1542 return ret;
1543}
1544
1545static int __devexit wm8350_codec_remove(struct platform_device *pdev)
1546{
1547 struct wm8350 *wm8350 = platform_get_drvdata(pdev);
1548 struct snd_soc_codec *codec = wm8350->codec.codec;
1549 struct wm8350_data *priv = codec->private_data;
1550
1551 snd_soc_unregister_dai(&wm8350_dai);
1552 snd_soc_unregister_codec(codec);
1553 regulator_bulk_free(ARRAY_SIZE(priv->supplies), priv->supplies);
1554 kfree(priv);
1555 wm8350_codec = NULL;
1556 return 0;
1557}
1558
1559static struct platform_driver wm8350_codec_driver = {
1560 .driver = {
1561 .name = "wm8350-codec",
1562 .owner = THIS_MODULE,
1563 },
1564 .probe = wm8350_codec_probe,
1565 .remove = __devexit_p(wm8350_codec_remove),
1566};
1567
1568static __init int wm8350_init(void)
1569{
1570 return platform_driver_register(&wm8350_codec_driver);
1571}
1572module_init(wm8350_init);
1573
1574static __exit void wm8350_exit(void)
1575{
1576 platform_driver_unregister(&wm8350_codec_driver);
1577}
1578module_exit(wm8350_exit);
1579
1580MODULE_DESCRIPTION("ASoC WM8350 driver");
1581MODULE_AUTHOR("Liam Girdwood");
1582MODULE_LICENSE("GPL");
1583MODULE_ALIAS("platform:wm8350-codec");
diff --git a/sound/soc/codecs/wm8350.h b/sound/soc/codecs/wm8350.h
new file mode 100644
index 000000000000..cc2887aa6c38
--- /dev/null
+++ b/sound/soc/codecs/wm8350.h
@@ -0,0 +1,20 @@
1/*
2 * wm8350.h - WM8903 audio codec interface
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
12#ifndef _WM8350_H
13#define _WM8350_H
14
15#include <sound/soc.h>
16
17extern struct snd_soc_dai wm8350_dai;
18extern struct snd_soc_codec_device soc_codec_dev_wm8350;
19
20#endif
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c
index d8ca2da8d634..40f8238df717 100644
--- a/sound/soc/codecs/wm8510.c
+++ b/sound/soc/codecs/wm8510.c
@@ -463,7 +463,8 @@ static int wm8510_set_dai_fmt(struct snd_soc_dai *codec_dai,
463} 463}
464 464
465static int wm8510_pcm_hw_params(struct snd_pcm_substream *substream, 465static int wm8510_pcm_hw_params(struct snd_pcm_substream *substream,
466 struct snd_pcm_hw_params *params) 466 struct snd_pcm_hw_params *params,
467 struct snd_soc_dai *dai)
467{ 468{
468 struct snd_soc_pcm_runtime *rtd = substream->private_data; 469 struct snd_soc_pcm_runtime *rtd = substream->private_data;
469 struct snd_soc_device *socdev = rtd->socdev; 470 struct snd_soc_device *socdev = rtd->socdev;
@@ -585,8 +586,6 @@ struct snd_soc_dai wm8510_dai = {
585 .formats = WM8510_FORMATS,}, 586 .formats = WM8510_FORMATS,},
586 .ops = { 587 .ops = {
587 .hw_params = wm8510_pcm_hw_params, 588 .hw_params = wm8510_pcm_hw_params,
588 },
589 .dai_ops = {
590 .digital_mute = wm8510_mute, 589 .digital_mute = wm8510_mute,
591 .set_fmt = wm8510_set_dai_fmt, 590 .set_fmt = wm8510_set_dai_fmt,
592 .set_clkdiv = wm8510_set_dai_clkdiv, 591 .set_clkdiv = wm8510_set_dai_clkdiv,
@@ -659,7 +658,7 @@ static int wm8510_init(struct snd_soc_device *socdev)
659 wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 658 wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
660 wm8510_add_controls(codec); 659 wm8510_add_controls(codec);
661 wm8510_add_widgets(codec); 660 wm8510_add_widgets(codec);
662 ret = snd_soc_register_card(socdev); 661 ret = snd_soc_init_card(socdev);
663 if (ret < 0) { 662 if (ret < 0) {
664 printk(KERN_ERR "wm8510: failed to register card\n"); 663 printk(KERN_ERR "wm8510: failed to register card\n");
665 goto card_err; 664 goto card_err;
@@ -890,6 +889,18 @@ struct snd_soc_codec_device soc_codec_dev_wm8510 = {
890}; 889};
891EXPORT_SYMBOL_GPL(soc_codec_dev_wm8510); 890EXPORT_SYMBOL_GPL(soc_codec_dev_wm8510);
892 891
892static int __init wm8510_modinit(void)
893{
894 return snd_soc_register_dai(&wm8510_dai);
895}
896module_init(wm8510_modinit);
897
898static void __exit wm8510_exit(void)
899{
900 snd_soc_unregister_dai(&wm8510_dai);
901}
902module_exit(wm8510_exit);
903
893MODULE_DESCRIPTION("ASoC WM8510 driver"); 904MODULE_DESCRIPTION("ASoC WM8510 driver");
894MODULE_AUTHOR("Liam Girdwood"); 905MODULE_AUTHOR("Liam Girdwood");
895MODULE_LICENSE("GPL"); 906MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
index 627ebfb4209b..d004e5845298 100644
--- a/sound/soc/codecs/wm8580.c
+++ b/sound/soc/codecs/wm8580.c
@@ -548,13 +548,13 @@ static int wm8580_set_dai_pll(struct snd_soc_dai *codec_dai,
548 * Set PCM DAI bit size and sample rate. 548 * Set PCM DAI bit size and sample rate.
549 */ 549 */
550static int wm8580_paif_hw_params(struct snd_pcm_substream *substream, 550static int wm8580_paif_hw_params(struct snd_pcm_substream *substream,
551 struct snd_pcm_hw_params *params) 551 struct snd_pcm_hw_params *params,
552 struct snd_soc_dai *dai)
552{ 553{
553 struct snd_soc_pcm_runtime *rtd = substream->private_data; 554 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; 555 struct snd_soc_device *socdev = rtd->socdev;
556 struct snd_soc_codec *codec = socdev->codec; 556 struct snd_soc_codec *codec = socdev->codec;
557 u16 paifb = wm8580_read(codec, WM8580_PAIF3 + dai->codec_dai->id); 557 u16 paifb = wm8580_read(codec, WM8580_PAIF3 + dai->id);
558 558
559 paifb &= ~WM8580_AIF_LENGTH_MASK; 559 paifb &= ~WM8580_AIF_LENGTH_MASK;
560 /* bit size */ 560 /* bit size */
@@ -574,7 +574,7 @@ static int wm8580_paif_hw_params(struct snd_pcm_substream *substream,
574 return -EINVAL; 574 return -EINVAL;
575 } 575 }
576 576
577 wm8580_write(codec, WM8580_PAIF3 + dai->codec_dai->id, paifb); 577 wm8580_write(codec, WM8580_PAIF3 + dai->id, paifb);
578 return 0; 578 return 0;
579} 579}
580 580
@@ -798,8 +798,6 @@ struct snd_soc_dai wm8580_dai[] = {
798 }, 798 },
799 .ops = { 799 .ops = {
800 .hw_params = wm8580_paif_hw_params, 800 .hw_params = wm8580_paif_hw_params,
801 },
802 .dai_ops = {
803 .set_fmt = wm8580_set_paif_dai_fmt, 801 .set_fmt = wm8580_set_paif_dai_fmt,
804 .set_clkdiv = wm8580_set_dai_clkdiv, 802 .set_clkdiv = wm8580_set_dai_clkdiv,
805 .set_pll = wm8580_set_dai_pll, 803 .set_pll = wm8580_set_dai_pll,
@@ -818,8 +816,6 @@ struct snd_soc_dai wm8580_dai[] = {
818 }, 816 },
819 .ops = { 817 .ops = {
820 .hw_params = wm8580_paif_hw_params, 818 .hw_params = wm8580_paif_hw_params,
821 },
822 .dai_ops = {
823 .set_fmt = wm8580_set_paif_dai_fmt, 819 .set_fmt = wm8580_set_paif_dai_fmt,
824 .set_clkdiv = wm8580_set_dai_clkdiv, 820 .set_clkdiv = wm8580_set_dai_clkdiv,
825 .set_pll = wm8580_set_dai_pll, 821 .set_pll = wm8580_set_dai_pll,
@@ -873,7 +869,7 @@ static int wm8580_init(struct snd_soc_device *socdev)
873 wm8580_add_controls(codec); 869 wm8580_add_controls(codec);
874 wm8580_add_widgets(codec); 870 wm8580_add_widgets(codec);
875 871
876 ret = snd_soc_register_card(socdev); 872 ret = snd_soc_init_card(socdev);
877 if (ret < 0) { 873 if (ret < 0) {
878 printk(KERN_ERR "wm8580: failed to register card\n"); 874 printk(KERN_ERR "wm8580: failed to register card\n");
879 goto card_err; 875 goto card_err;
@@ -900,85 +896,85 @@ static struct snd_soc_device *wm8580_socdev;
900 * low = 0x1a 896 * low = 0x1a
901 * high = 0x1b 897 * high = 0x1b
902 */ 898 */
903static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
904
905/* Magic definition of all other variables and things */
906I2C_CLIENT_INSMOD;
907 899
908static struct i2c_driver wm8580_i2c_driver; 900static int wm8580_i2c_probe(struct i2c_client *i2c,
909static struct i2c_client client_template; 901 const struct i2c_device_id *id)
910
911static int wm8580_codec_probe(struct i2c_adapter *adap, int addr, int kind)
912{ 902{
913 struct snd_soc_device *socdev = wm8580_socdev; 903 struct snd_soc_device *socdev = wm8580_socdev;
914 struct wm8580_setup_data *setup = socdev->codec_data;
915 struct snd_soc_codec *codec = socdev->codec; 904 struct snd_soc_codec *codec = socdev->codec;
916 struct i2c_client *i2c;
917 int ret; 905 int ret;
918 906
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); 907 i2c_set_clientdata(i2c, codec);
931 codec->control_data = i2c; 908 codec->control_data = i2c;
932 909
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); 910 ret = wm8580_init(socdev);
940 if (ret < 0) { 911 if (ret < 0)
941 dev_err(&i2c->dev, "failed to initialise WM8580\n"); 912 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; 913 return ret;
951} 914}
952 915
953static int wm8580_i2c_detach(struct i2c_client *client) 916static int wm8580_i2c_remove(struct i2c_client *client)
954{ 917{
955 struct snd_soc_codec *codec = i2c_get_clientdata(client); 918 struct snd_soc_codec *codec = i2c_get_clientdata(client);
956 i2c_detach_client(client);
957 kfree(codec->reg_cache); 919 kfree(codec->reg_cache);
958 kfree(client);
959 return 0; 920 return 0;
960} 921}
961 922
962static int wm8580_i2c_attach(struct i2c_adapter *adap) 923static const struct i2c_device_id wm8580_i2c_id[] = {
963{ 924 { "wm8580", 0 },
964 return i2c_probe(adap, &addr_data, wm8580_codec_probe); 925 { }
965} 926};
927MODULE_DEVICE_TABLE(i2c, wm8580_i2c_id);
966 928
967/* corgi i2c codec control layer */
968static struct i2c_driver wm8580_i2c_driver = { 929static struct i2c_driver wm8580_i2c_driver = {
969 .driver = { 930 .driver = {
970 .name = "WM8580 I2C Codec", 931 .name = "WM8580 I2C Codec",
971 .owner = THIS_MODULE, 932 .owner = THIS_MODULE,
972 }, 933 },
973 .attach_adapter = wm8580_i2c_attach, 934 .probe = wm8580_i2c_probe,
974 .detach_client = wm8580_i2c_detach, 935 .remove = wm8580_i2c_remove,
975 .command = NULL, 936 .id_table = wm8580_i2c_id,
976}; 937};
977 938
978static struct i2c_client client_template = { 939static int wm8580_add_i2c_device(struct platform_device *pdev,
979 .name = "WM8580", 940 const struct wm8580_setup_data *setup)
980 .driver = &wm8580_i2c_driver, 941{
981}; 942 struct i2c_board_info info;
943 struct i2c_adapter *adapter;
944 struct i2c_client *client;
945 int ret;
946
947 ret = i2c_add_driver(&wm8580_i2c_driver);
948 if (ret != 0) {
949 dev_err(&pdev->dev, "can't add i2c driver\n");
950 return ret;
951 }
952
953 memset(&info, 0, sizeof(struct i2c_board_info));
954 info.addr = setup->i2c_address;
955 strlcpy(info.type, "wm8580", I2C_NAME_SIZE);
956
957 adapter = i2c_get_adapter(setup->i2c_bus);
958 if (!adapter) {
959 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
960 setup->i2c_bus);
961 goto err_driver;
962 }
963
964 client = i2c_new_device(adapter, &info);
965 i2c_put_adapter(adapter);
966 if (!client) {
967 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
968 (unsigned int)info.addr);
969 goto err_driver;
970 }
971
972 return 0;
973
974err_driver:
975 i2c_del_driver(&wm8580_i2c_driver);
976 return -ENODEV;
977}
982#endif 978#endif
983 979
984static int wm8580_probe(struct platform_device *pdev) 980static int wm8580_probe(struct platform_device *pdev)
@@ -1011,11 +1007,8 @@ static int wm8580_probe(struct platform_device *pdev)
1011 1007
1012#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1008#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1013 if (setup->i2c_address) { 1009 if (setup->i2c_address) {
1014 normal_i2c[0] = setup->i2c_address;
1015 codec->hw_write = (hw_write_t)i2c_master_send; 1010 codec->hw_write = (hw_write_t)i2c_master_send;
1016 ret = i2c_add_driver(&wm8580_i2c_driver); 1011 ret = wm8580_add_i2c_device(pdev, setup);
1017 if (ret != 0)
1018 printk(KERN_ERR "can't add i2c driver");
1019 } 1012 }
1020#else 1013#else
1021 /* Add other interfaces here */ 1014 /* Add other interfaces here */
@@ -1034,6 +1027,7 @@ static int wm8580_remove(struct platform_device *pdev)
1034 snd_soc_free_pcms(socdev); 1027 snd_soc_free_pcms(socdev);
1035 snd_soc_dapm_free(socdev); 1028 snd_soc_dapm_free(socdev);
1036#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1029#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1030 i2c_unregister_device(codec->control_data);
1037 i2c_del_driver(&wm8580_i2c_driver); 1031 i2c_del_driver(&wm8580_i2c_driver);
1038#endif 1032#endif
1039 kfree(codec->private_data); 1033 kfree(codec->private_data);
@@ -1048,6 +1042,18 @@ struct snd_soc_codec_device soc_codec_dev_wm8580 = {
1048}; 1042};
1049EXPORT_SYMBOL_GPL(soc_codec_dev_wm8580); 1043EXPORT_SYMBOL_GPL(soc_codec_dev_wm8580);
1050 1044
1045static int __init wm8580_modinit(void)
1046{
1047 return snd_soc_register_dais(wm8580_dai, ARRAY_SIZE(wm8580_dai));
1048}
1049module_init(wm8580_modinit);
1050
1051static void __exit wm8580_exit(void)
1052{
1053 snd_soc_unregister_dais(wm8580_dai, ARRAY_SIZE(wm8580_dai));
1054}
1055module_exit(wm8580_exit);
1056
1051MODULE_DESCRIPTION("ASoC WM8580 driver"); 1057MODULE_DESCRIPTION("ASoC WM8580 driver");
1052MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 1058MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
1053MODULE_LICENSE("GPL"); 1059MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8580.h b/sound/soc/codecs/wm8580.h
index 589ddaba21d7..09e4422f6f2f 100644
--- a/sound/soc/codecs/wm8580.h
+++ b/sound/soc/codecs/wm8580.h
@@ -29,6 +29,7 @@
29#define WM8580_CLKSRC_NONE 5 29#define WM8580_CLKSRC_NONE 5
30 30
31struct wm8580_setup_data { 31struct wm8580_setup_data {
32 int i2c_bus;
32 unsigned short i2c_address; 33 unsigned short i2c_address;
33}; 34};
34 35
diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c
new file mode 100644
index 000000000000..80b11983e137
--- /dev/null
+++ b/sound/soc/codecs/wm8728.c
@@ -0,0 +1,585 @@
1/*
2 * wm8728.c -- WM8728 ALSA SoC Audio driver
3 *
4 * Copyright 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
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/pm.h>
18#include <linux/i2c.h>
19#include <linux/platform_device.h>
20#include <linux/spi/spi.h>
21#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/pcm_params.h>
24#include <sound/soc.h>
25#include <sound/soc-dapm.h>
26#include <sound/initval.h>
27#include <sound/tlv.h>
28
29#include "wm8728.h"
30
31struct snd_soc_codec_device soc_codec_dev_wm8728;
32
33/*
34 * We can't read the WM8728 register space so we cache them instead.
35 * Note that the defaults here aren't the physical defaults, we latch
36 * the volume update bits, mute the output and enable infinite zero
37 * detect.
38 */
39static const u16 wm8728_reg_defaults[] = {
40 0x1ff,
41 0x1ff,
42 0x001,
43 0x100,
44};
45
46static inline unsigned int wm8728_read_reg_cache(struct snd_soc_codec *codec,
47 unsigned int reg)
48{
49 u16 *cache = codec->reg_cache;
50 BUG_ON(reg > ARRAY_SIZE(wm8728_reg_defaults));
51 return cache[reg];
52}
53
54static inline void wm8728_write_reg_cache(struct snd_soc_codec *codec,
55 u16 reg, unsigned int value)
56{
57 u16 *cache = codec->reg_cache;
58 BUG_ON(reg > ARRAY_SIZE(wm8728_reg_defaults));
59 cache[reg] = value;
60}
61
62/*
63 * write to the WM8728 register space
64 */
65static int wm8728_write(struct snd_soc_codec *codec, unsigned int reg,
66 unsigned int value)
67{
68 u8 data[2];
69
70 /* data is
71 * D15..D9 WM8728 register offset
72 * D8...D0 register data
73 */
74 data[0] = (reg << 1) | ((value >> 8) & 0x0001);
75 data[1] = value & 0x00ff;
76
77 wm8728_write_reg_cache(codec, reg, value);
78
79 if (codec->hw_write(codec->control_data, data, 2) == 2)
80 return 0;
81 else
82 return -EIO;
83}
84
85static const DECLARE_TLV_DB_SCALE(wm8728_tlv, -12750, 50, 1);
86
87static const struct snd_kcontrol_new wm8728_snd_controls[] = {
88
89SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8728_DACLVOL, WM8728_DACRVOL,
90 0, 255, 0, wm8728_tlv),
91
92SOC_SINGLE("Deemphasis", WM8728_DACCTL, 1, 1, 0),
93};
94
95static int wm8728_add_controls(struct snd_soc_codec *codec)
96{
97 int err, i;
98
99 for (i = 0; i < ARRAY_SIZE(wm8728_snd_controls); i++) {
100 err = snd_ctl_add(codec->card,
101 snd_soc_cnew(&wm8728_snd_controls[i],
102 codec, NULL));
103 if (err < 0)
104 return err;
105 }
106
107 return 0;
108}
109
110/*
111 * DAPM controls.
112 */
113static const struct snd_soc_dapm_widget wm8728_dapm_widgets[] = {
114SND_SOC_DAPM_DAC("DAC", "HiFi Playback", SND_SOC_NOPM, 0, 0),
115SND_SOC_DAPM_OUTPUT("VOUTL"),
116SND_SOC_DAPM_OUTPUT("VOUTR"),
117};
118
119static const struct snd_soc_dapm_route intercon[] = {
120 {"VOUTL", NULL, "DAC"},
121 {"VOUTR", NULL, "DAC"},
122};
123
124static int wm8728_add_widgets(struct snd_soc_codec *codec)
125{
126 snd_soc_dapm_new_controls(codec, wm8728_dapm_widgets,
127 ARRAY_SIZE(wm8728_dapm_widgets));
128
129 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
130
131 snd_soc_dapm_new_widgets(codec);
132
133 return 0;
134}
135
136static int wm8728_mute(struct snd_soc_dai *dai, int mute)
137{
138 struct snd_soc_codec *codec = dai->codec;
139 u16 mute_reg = wm8728_read_reg_cache(codec, WM8728_DACCTL);
140
141 if (mute)
142 wm8728_write(codec, WM8728_DACCTL, mute_reg | 1);
143 else
144 wm8728_write(codec, WM8728_DACCTL, mute_reg & ~1);
145
146 return 0;
147}
148
149static int wm8728_hw_params(struct snd_pcm_substream *substream,
150 struct snd_pcm_hw_params *params,
151 struct snd_soc_dai *dai)
152{
153 struct snd_soc_pcm_runtime *rtd = substream->private_data;
154 struct snd_soc_device *socdev = rtd->socdev;
155 struct snd_soc_codec *codec = socdev->codec;
156 u16 dac = wm8728_read_reg_cache(codec, WM8728_DACCTL);
157
158 dac &= ~0x18;
159
160 switch (params_format(params)) {
161 case SNDRV_PCM_FORMAT_S16_LE:
162 break;
163 case SNDRV_PCM_FORMAT_S20_3LE:
164 dac |= 0x10;
165 break;
166 case SNDRV_PCM_FORMAT_S24_LE:
167 dac |= 0x08;
168 break;
169 default:
170 return -EINVAL;
171 }
172
173 wm8728_write(codec, WM8728_DACCTL, dac);
174
175 return 0;
176}
177
178static int wm8728_set_dai_fmt(struct snd_soc_dai *codec_dai,
179 unsigned int fmt)
180{
181 struct snd_soc_codec *codec = codec_dai->codec;
182 u16 iface = wm8728_read_reg_cache(codec, WM8728_IFCTL);
183
184 /* Currently only I2S is supported by the driver, though the
185 * hardware is more flexible.
186 */
187 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
188 case SND_SOC_DAIFMT_I2S:
189 iface |= 1;
190 break;
191 default:
192 return -EINVAL;
193 }
194
195 /* The hardware only support full slave mode */
196 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
197 case SND_SOC_DAIFMT_CBS_CFS:
198 break;
199 default:
200 return -EINVAL;
201 }
202
203 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
204 case SND_SOC_DAIFMT_NB_NF:
205 iface &= ~0x22;
206 break;
207 case SND_SOC_DAIFMT_IB_NF:
208 iface |= 0x20;
209 iface &= ~0x02;
210 break;
211 case SND_SOC_DAIFMT_NB_IF:
212 iface |= 0x02;
213 iface &= ~0x20;
214 break;
215 case SND_SOC_DAIFMT_IB_IF:
216 iface |= 0x22;
217 break;
218 default:
219 return -EINVAL;
220 }
221
222 wm8728_write(codec, WM8728_IFCTL, iface);
223 return 0;
224}
225
226static int wm8728_set_bias_level(struct snd_soc_codec *codec,
227 enum snd_soc_bias_level level)
228{
229 u16 reg;
230 int i;
231
232 switch (level) {
233 case SND_SOC_BIAS_ON:
234 case SND_SOC_BIAS_PREPARE:
235 case SND_SOC_BIAS_STANDBY:
236 if (codec->bias_level == SND_SOC_BIAS_OFF) {
237 /* Power everything up... */
238 reg = wm8728_read_reg_cache(codec, WM8728_DACCTL);
239 wm8728_write(codec, WM8728_DACCTL, reg & ~0x4);
240
241 /* ..then sync in the register cache. */
242 for (i = 0; i < ARRAY_SIZE(wm8728_reg_defaults); i++)
243 wm8728_write(codec, i,
244 wm8728_read_reg_cache(codec, i));
245 }
246 break;
247
248 case SND_SOC_BIAS_OFF:
249 reg = wm8728_read_reg_cache(codec, WM8728_DACCTL);
250 wm8728_write(codec, WM8728_DACCTL, reg | 0x4);
251 break;
252 }
253 codec->bias_level = level;
254 return 0;
255}
256
257#define WM8728_RATES (SNDRV_PCM_RATE_8000_192000)
258
259#define WM8728_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
260 SNDRV_PCM_FMTBIT_S24_LE)
261
262struct snd_soc_dai wm8728_dai = {
263 .name = "WM8728",
264 .playback = {
265 .stream_name = "Playback",
266 .channels_min = 2,
267 .channels_max = 2,
268 .rates = WM8728_RATES,
269 .formats = WM8728_FORMATS,
270 },
271 .ops = {
272 .hw_params = wm8728_hw_params,
273 .digital_mute = wm8728_mute,
274 .set_fmt = wm8728_set_dai_fmt,
275 }
276};
277EXPORT_SYMBOL_GPL(wm8728_dai);
278
279static int wm8728_suspend(struct platform_device *pdev, pm_message_t state)
280{
281 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
282 struct snd_soc_codec *codec = socdev->codec;
283
284 wm8728_set_bias_level(codec, SND_SOC_BIAS_OFF);
285
286 return 0;
287}
288
289static int wm8728_resume(struct platform_device *pdev)
290{
291 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
292 struct snd_soc_codec *codec = socdev->codec;
293
294 wm8728_set_bias_level(codec, codec->suspend_bias_level);
295
296 return 0;
297}
298
299/*
300 * initialise the WM8728 driver
301 * register the mixer and dsp interfaces with the kernel
302 */
303static int wm8728_init(struct snd_soc_device *socdev)
304{
305 struct snd_soc_codec *codec = socdev->codec;
306 int ret = 0;
307
308 codec->name = "WM8728";
309 codec->owner = THIS_MODULE;
310 codec->read = wm8728_read_reg_cache;
311 codec->write = wm8728_write;
312 codec->set_bias_level = wm8728_set_bias_level;
313 codec->dai = &wm8728_dai;
314 codec->num_dai = 1;
315 codec->bias_level = SND_SOC_BIAS_OFF;
316 codec->reg_cache_size = ARRAY_SIZE(wm8728_reg_defaults);
317 codec->reg_cache = kmemdup(wm8728_reg_defaults,
318 sizeof(wm8728_reg_defaults),
319 GFP_KERNEL);
320 if (codec->reg_cache == NULL)
321 return -ENOMEM;
322
323 /* register pcms */
324 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
325 if (ret < 0) {
326 printk(KERN_ERR "wm8728: failed to create pcms\n");
327 goto pcm_err;
328 }
329
330 /* power on device */
331 wm8728_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
332
333 wm8728_add_controls(codec);
334 wm8728_add_widgets(codec);
335 ret = snd_soc_init_card(socdev);
336 if (ret < 0) {
337 printk(KERN_ERR "wm8728: failed to register card\n");
338 goto card_err;
339 }
340
341 return ret;
342
343card_err:
344 snd_soc_free_pcms(socdev);
345 snd_soc_dapm_free(socdev);
346pcm_err:
347 kfree(codec->reg_cache);
348 return ret;
349}
350
351static struct snd_soc_device *wm8728_socdev;
352
353#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
354
355/*
356 * WM8728 2 wire address is determined by GPIO5
357 * state during powerup.
358 * low = 0x1a
359 * high = 0x1b
360 */
361
362static int wm8728_i2c_probe(struct i2c_client *i2c,
363 const struct i2c_device_id *id)
364{
365 struct snd_soc_device *socdev = wm8728_socdev;
366 struct snd_soc_codec *codec = socdev->codec;
367 int ret;
368
369 i2c_set_clientdata(i2c, codec);
370 codec->control_data = i2c;
371
372 ret = wm8728_init(socdev);
373 if (ret < 0)
374 pr_err("failed to initialise WM8728\n");
375
376 return ret;
377}
378
379static int wm8728_i2c_remove(struct i2c_client *client)
380{
381 struct snd_soc_codec *codec = i2c_get_clientdata(client);
382 kfree(codec->reg_cache);
383 return 0;
384}
385
386static const struct i2c_device_id wm8728_i2c_id[] = {
387 { "wm8728", 0 },
388 { }
389};
390MODULE_DEVICE_TABLE(i2c, wm8728_i2c_id);
391
392static struct i2c_driver wm8728_i2c_driver = {
393 .driver = {
394 .name = "WM8728 I2C Codec",
395 .owner = THIS_MODULE,
396 },
397 .probe = wm8728_i2c_probe,
398 .remove = wm8728_i2c_remove,
399 .id_table = wm8728_i2c_id,
400};
401
402static int wm8728_add_i2c_device(struct platform_device *pdev,
403 const struct wm8728_setup_data *setup)
404{
405 struct i2c_board_info info;
406 struct i2c_adapter *adapter;
407 struct i2c_client *client;
408 int ret;
409
410 ret = i2c_add_driver(&wm8728_i2c_driver);
411 if (ret != 0) {
412 dev_err(&pdev->dev, "can't add i2c driver\n");
413 return ret;
414 }
415
416 memset(&info, 0, sizeof(struct i2c_board_info));
417 info.addr = setup->i2c_address;
418 strlcpy(info.type, "wm8728", I2C_NAME_SIZE);
419
420 adapter = i2c_get_adapter(setup->i2c_bus);
421 if (!adapter) {
422 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
423 setup->i2c_bus);
424 goto err_driver;
425 }
426
427 client = i2c_new_device(adapter, &info);
428 i2c_put_adapter(adapter);
429 if (!client) {
430 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
431 (unsigned int)info.addr);
432 goto err_driver;
433 }
434
435 return 0;
436
437err_driver:
438 i2c_del_driver(&wm8728_i2c_driver);
439 return -ENODEV;
440}
441#endif
442
443#if defined(CONFIG_SPI_MASTER)
444static int __devinit wm8728_spi_probe(struct spi_device *spi)
445{
446 struct snd_soc_device *socdev = wm8728_socdev;
447 struct snd_soc_codec *codec = socdev->codec;
448 int ret;
449
450 codec->control_data = spi;
451
452 ret = wm8728_init(socdev);
453 if (ret < 0)
454 dev_err(&spi->dev, "failed to initialise WM8728\n");
455
456 return ret;
457}
458
459static int __devexit wm8728_spi_remove(struct spi_device *spi)
460{
461 return 0;
462}
463
464static struct spi_driver wm8728_spi_driver = {
465 .driver = {
466 .name = "wm8728",
467 .bus = &spi_bus_type,
468 .owner = THIS_MODULE,
469 },
470 .probe = wm8728_spi_probe,
471 .remove = __devexit_p(wm8728_spi_remove),
472};
473
474static int wm8728_spi_write(struct spi_device *spi, const char *data, int len)
475{
476 struct spi_transfer t;
477 struct spi_message m;
478 u8 msg[2];
479
480 if (len <= 0)
481 return 0;
482
483 msg[0] = data[0];
484 msg[1] = data[1];
485
486 spi_message_init(&m);
487 memset(&t, 0, (sizeof t));
488
489 t.tx_buf = &msg[0];
490 t.len = len;
491
492 spi_message_add_tail(&t, &m);
493 spi_sync(spi, &m);
494
495 return len;
496}
497#endif /* CONFIG_SPI_MASTER */
498
499static int wm8728_probe(struct platform_device *pdev)
500{
501 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
502 struct wm8728_setup_data *setup;
503 struct snd_soc_codec *codec;
504 int ret = 0;
505
506 setup = socdev->codec_data;
507 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
508 if (codec == NULL)
509 return -ENOMEM;
510
511 socdev->codec = codec;
512 mutex_init(&codec->mutex);
513 INIT_LIST_HEAD(&codec->dapm_widgets);
514 INIT_LIST_HEAD(&codec->dapm_paths);
515
516 wm8728_socdev = socdev;
517 ret = -ENODEV;
518
519#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
520 if (setup->i2c_address) {
521 codec->hw_write = (hw_write_t)i2c_master_send;
522 ret = wm8728_add_i2c_device(pdev, setup);
523 }
524#endif
525#if defined(CONFIG_SPI_MASTER)
526 if (setup->spi) {
527 codec->hw_write = (hw_write_t)wm8728_spi_write;
528 ret = spi_register_driver(&wm8728_spi_driver);
529 if (ret != 0)
530 printk(KERN_ERR "can't add spi driver");
531 }
532#endif
533
534 if (ret != 0)
535 kfree(codec);
536
537 return ret;
538}
539
540/* power down chip */
541static int wm8728_remove(struct platform_device *pdev)
542{
543 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
544 struct snd_soc_codec *codec = socdev->codec;
545
546 if (codec->control_data)
547 wm8728_set_bias_level(codec, SND_SOC_BIAS_OFF);
548
549 snd_soc_free_pcms(socdev);
550 snd_soc_dapm_free(socdev);
551#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
552 i2c_unregister_device(codec->control_data);
553 i2c_del_driver(&wm8728_i2c_driver);
554#endif
555#if defined(CONFIG_SPI_MASTER)
556 spi_unregister_driver(&wm8728_spi_driver);
557#endif
558 kfree(codec);
559
560 return 0;
561}
562
563struct snd_soc_codec_device soc_codec_dev_wm8728 = {
564 .probe = wm8728_probe,
565 .remove = wm8728_remove,
566 .suspend = wm8728_suspend,
567 .resume = wm8728_resume,
568};
569EXPORT_SYMBOL_GPL(soc_codec_dev_wm8728);
570
571static int __init wm8728_modinit(void)
572{
573 return snd_soc_register_dai(&wm8728_dai);
574}
575module_init(wm8728_modinit);
576
577static void __exit wm8728_exit(void)
578{
579 snd_soc_unregister_dai(&wm8728_dai);
580}
581module_exit(wm8728_exit);
582
583MODULE_DESCRIPTION("ASoC WM8728 driver");
584MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
585MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8728.h b/sound/soc/codecs/wm8728.h
new file mode 100644
index 000000000000..d269c132474b
--- /dev/null
+++ b/sound/soc/codecs/wm8728.h
@@ -0,0 +1,30 @@
1/*
2 * wm8728.h -- WM8728 ASoC codec driver
3 *
4 * Copyright 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
13#ifndef _WM8728_H
14#define _WM8728_H
15
16#define WM8728_DACLVOL 0x00
17#define WM8728_DACRVOL 0x01
18#define WM8728_DACCTL 0x02
19#define WM8728_IFCTL 0x03
20
21struct wm8728_setup_data {
22 int spi;
23 int i2c_bus;
24 unsigned short i2c_address;
25};
26
27extern struct snd_soc_dai wm8728_dai;
28extern struct snd_soc_codec_device soc_codec_dev_wm8728;
29
30#endif
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index 7f8a7e36b33e..c444b9f2701e 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -264,7 +264,8 @@ static inline int get_coeff(int mclk, int rate)
264} 264}
265 265
266static int wm8731_hw_params(struct snd_pcm_substream *substream, 266static int wm8731_hw_params(struct snd_pcm_substream *substream,
267 struct snd_pcm_hw_params *params) 267 struct snd_pcm_hw_params *params,
268 struct snd_soc_dai *dai)
268{ 269{
269 struct snd_soc_pcm_runtime *rtd = substream->private_data; 270 struct snd_soc_pcm_runtime *rtd = substream->private_data;
270 struct snd_soc_device *socdev = rtd->socdev; 271 struct snd_soc_device *socdev = rtd->socdev;
@@ -293,7 +294,8 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream,
293 return 0; 294 return 0;
294} 295}
295 296
296static int wm8731_pcm_prepare(struct snd_pcm_substream *substream) 297static int wm8731_pcm_prepare(struct snd_pcm_substream *substream,
298 struct snd_soc_dai *dai)
297{ 299{
298 struct snd_soc_pcm_runtime *rtd = substream->private_data; 300 struct snd_soc_pcm_runtime *rtd = substream->private_data;
299 struct snd_soc_device *socdev = rtd->socdev; 301 struct snd_soc_device *socdev = rtd->socdev;
@@ -305,7 +307,8 @@ static int wm8731_pcm_prepare(struct snd_pcm_substream *substream)
305 return 0; 307 return 0;
306} 308}
307 309
308static void wm8731_shutdown(struct snd_pcm_substream *substream) 310static void wm8731_shutdown(struct snd_pcm_substream *substream,
311 struct snd_soc_dai *dai)
309{ 312{
310 struct snd_soc_pcm_runtime *rtd = substream->private_data; 313 struct snd_soc_pcm_runtime *rtd = substream->private_data;
311 struct snd_soc_device *socdev = rtd->socdev; 314 struct snd_soc_device *socdev = rtd->socdev;
@@ -461,8 +464,6 @@ struct snd_soc_dai wm8731_dai = {
461 .prepare = wm8731_pcm_prepare, 464 .prepare = wm8731_pcm_prepare,
462 .hw_params = wm8731_hw_params, 465 .hw_params = wm8731_hw_params,
463 .shutdown = wm8731_shutdown, 466 .shutdown = wm8731_shutdown,
464 },
465 .dai_ops = {
466 .digital_mute = wm8731_mute, 467 .digital_mute = wm8731_mute,
467 .set_sysclk = wm8731_set_dai_sysclk, 468 .set_sysclk = wm8731_set_dai_sysclk,
468 .set_fmt = wm8731_set_dai_fmt, 469 .set_fmt = wm8731_set_dai_fmt,
@@ -544,7 +545,7 @@ static int wm8731_init(struct snd_soc_device *socdev)
544 545
545 wm8731_add_controls(codec); 546 wm8731_add_controls(codec);
546 wm8731_add_widgets(codec); 547 wm8731_add_widgets(codec);
547 ret = snd_soc_register_card(socdev); 548 ret = snd_soc_init_card(socdev);
548 if (ret < 0) { 549 if (ret < 0) {
549 printk(KERN_ERR "wm8731: failed to register card\n"); 550 printk(KERN_ERR "wm8731: failed to register card\n");
550 goto card_err; 551 goto card_err;
@@ -792,6 +793,18 @@ struct snd_soc_codec_device soc_codec_dev_wm8731 = {
792}; 793};
793EXPORT_SYMBOL_GPL(soc_codec_dev_wm8731); 794EXPORT_SYMBOL_GPL(soc_codec_dev_wm8731);
794 795
796static int __init wm8731_modinit(void)
797{
798 return snd_soc_register_dai(&wm8731_dai);
799}
800module_init(wm8731_modinit);
801
802static void __exit wm8731_exit(void)
803{
804 snd_soc_unregister_dai(&wm8731_dai);
805}
806module_exit(wm8731_exit);
807
795MODULE_DESCRIPTION("ASoC WM8731 driver"); 808MODULE_DESCRIPTION("ASoC WM8731 driver");
796MODULE_AUTHOR("Richard Purdie"); 809MODULE_AUTHOR("Richard Purdie");
797MODULE_LICENSE("GPL"); 810MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index 9b7296ee5b08..5997fa68e0d5 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.c
@@ -614,7 +614,8 @@ static int wm8750_set_dai_fmt(struct snd_soc_dai *codec_dai,
614} 614}
615 615
616static int wm8750_pcm_hw_params(struct snd_pcm_substream *substream, 616static int wm8750_pcm_hw_params(struct snd_pcm_substream *substream,
617 struct snd_pcm_hw_params *params) 617 struct snd_pcm_hw_params *params,
618 struct snd_soc_dai *dai)
618{ 619{
619 struct snd_soc_pcm_runtime *rtd = substream->private_data; 620 struct snd_soc_pcm_runtime *rtd = substream->private_data;
620 struct snd_soc_device *socdev = rtd->socdev; 621 struct snd_soc_device *socdev = rtd->socdev;
@@ -709,8 +710,6 @@ struct snd_soc_dai wm8750_dai = {
709 .formats = WM8750_FORMATS,}, 710 .formats = WM8750_FORMATS,},
710 .ops = { 711 .ops = {
711 .hw_params = wm8750_pcm_hw_params, 712 .hw_params = wm8750_pcm_hw_params,
712 },
713 .dai_ops = {
714 .digital_mute = wm8750_mute, 713 .digital_mute = wm8750_mute,
715 .set_fmt = wm8750_set_dai_fmt, 714 .set_fmt = wm8750_set_dai_fmt,
716 .set_sysclk = wm8750_set_dai_sysclk, 715 .set_sysclk = wm8750_set_dai_sysclk,
@@ -819,7 +818,7 @@ static int wm8750_init(struct snd_soc_device *socdev)
819 818
820 wm8750_add_controls(codec); 819 wm8750_add_controls(codec);
821 wm8750_add_widgets(codec); 820 wm8750_add_widgets(codec);
822 ret = snd_soc_register_card(socdev); 821 ret = snd_soc_init_card(socdev);
823 if (ret < 0) { 822 if (ret < 0) {
824 printk(KERN_ERR "wm8750: failed to register card\n"); 823 printk(KERN_ERR "wm8750: failed to register card\n");
825 goto card_err; 824 goto card_err;
@@ -1086,6 +1085,18 @@ struct snd_soc_codec_device soc_codec_dev_wm8750 = {
1086}; 1085};
1087EXPORT_SYMBOL_GPL(soc_codec_dev_wm8750); 1086EXPORT_SYMBOL_GPL(soc_codec_dev_wm8750);
1088 1087
1088static int __init wm8750_modinit(void)
1089{
1090 return snd_soc_register_dai(&wm8750_dai);
1091}
1092module_init(wm8750_modinit);
1093
1094static void __exit wm8750_exit(void)
1095{
1096 snd_soc_unregister_dai(&wm8750_dai);
1097}
1098module_exit(wm8750_exit);
1099
1089MODULE_DESCRIPTION("ASoC WM8750 driver"); 1100MODULE_DESCRIPTION("ASoC WM8750 driver");
1090MODULE_AUTHOR("Liam Girdwood"); 1101MODULE_AUTHOR("Liam Girdwood");
1091MODULE_LICENSE("GPL"); 1102MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index d426eaa22185..6c21b50c9375 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -922,7 +922,8 @@ static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_dai *codec_dai,
922 * Set PCM DAI bit size and sample rate. 922 * Set PCM DAI bit size and sample rate.
923 */ 923 */
924static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream, 924static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream,
925 struct snd_pcm_hw_params *params) 925 struct snd_pcm_hw_params *params,
926 struct snd_soc_dai *dai)
926{ 927{
927 struct snd_soc_pcm_runtime *rtd = substream->private_data; 928 struct snd_soc_pcm_runtime *rtd = substream->private_data;
928 struct snd_soc_device *socdev = rtd->socdev; 929 struct snd_soc_device *socdev = rtd->socdev;
@@ -1155,7 +1156,8 @@ static int wm8753_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai,
1155 * Set PCM DAI bit size and sample rate. 1156 * Set PCM DAI bit size and sample rate.
1156 */ 1157 */
1157static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream, 1158static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
1158 struct snd_pcm_hw_params *params) 1159 struct snd_pcm_hw_params *params,
1160 struct snd_soc_dai *dai)
1159{ 1161{
1160 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1162 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1161 struct snd_soc_device *socdev = rtd->socdev; 1163 struct snd_soc_device *socdev = rtd->socdev;
@@ -1323,16 +1325,15 @@ static const struct snd_soc_dai wm8753_all_dai[] = {
1323 .channels_min = 1, 1325 .channels_min = 1,
1324 .channels_max = 2, 1326 .channels_max = 2,
1325 .rates = WM8753_RATES, 1327 .rates = WM8753_RATES,
1326 .formats = WM8753_FORMATS,}, 1328 .formats = WM8753_FORMATS},
1327 .capture = { /* dummy for fast DAI switching */ 1329 .capture = { /* dummy for fast DAI switching */
1328 .stream_name = "Capture", 1330 .stream_name = "Capture",
1329 .channels_min = 1, 1331 .channels_min = 1,
1330 .channels_max = 2, 1332 .channels_max = 2,
1331 .rates = WM8753_RATES, 1333 .rates = WM8753_RATES,
1332 .formats = WM8753_FORMATS,}, 1334 .formats = WM8753_FORMATS},
1333 .ops = { 1335 .ops = {
1334 .hw_params = wm8753_i2s_hw_params,}, 1336 .hw_params = wm8753_i2s_hw_params,
1335 .dai_ops = {
1336 .digital_mute = wm8753_mute, 1337 .digital_mute = wm8753_mute,
1337 .set_fmt = wm8753_mode1h_set_dai_fmt, 1338 .set_fmt = wm8753_mode1h_set_dai_fmt,
1338 .set_clkdiv = wm8753_set_dai_clkdiv, 1339 .set_clkdiv = wm8753_set_dai_clkdiv,
@@ -1356,8 +1357,7 @@ static const struct snd_soc_dai wm8753_all_dai[] = {
1356 .rates = WM8753_RATES, 1357 .rates = WM8753_RATES,
1357 .formats = WM8753_FORMATS,}, 1358 .formats = WM8753_FORMATS,},
1358 .ops = { 1359 .ops = {
1359 .hw_params = wm8753_pcm_hw_params,}, 1360 .hw_params = wm8753_pcm_hw_params,
1360 .dai_ops = {
1361 .digital_mute = wm8753_mute, 1361 .digital_mute = wm8753_mute,
1362 .set_fmt = wm8753_mode1v_set_dai_fmt, 1362 .set_fmt = wm8753_mode1v_set_dai_fmt,
1363 .set_clkdiv = wm8753_set_dai_clkdiv, 1363 .set_clkdiv = wm8753_set_dai_clkdiv,
@@ -1385,8 +1385,7 @@ static const struct snd_soc_dai wm8753_all_dai[] = {
1385 .rates = WM8753_RATES, 1385 .rates = WM8753_RATES,
1386 .formats = WM8753_FORMATS,}, 1386 .formats = WM8753_FORMATS,},
1387 .ops = { 1387 .ops = {
1388 .hw_params = wm8753_pcm_hw_params,}, 1388 .hw_params = wm8753_pcm_hw_params,
1389 .dai_ops = {
1390 .digital_mute = wm8753_mute, 1389 .digital_mute = wm8753_mute,
1391 .set_fmt = wm8753_mode2_set_dai_fmt, 1390 .set_fmt = wm8753_mode2_set_dai_fmt,
1392 .set_clkdiv = wm8753_set_dai_clkdiv, 1391 .set_clkdiv = wm8753_set_dai_clkdiv,
@@ -1410,8 +1409,7 @@ static const struct snd_soc_dai wm8753_all_dai[] = {
1410 .rates = WM8753_RATES, 1409 .rates = WM8753_RATES,
1411 .formats = WM8753_FORMATS,}, 1410 .formats = WM8753_FORMATS,},
1412 .ops = { 1411 .ops = {
1413 .hw_params = wm8753_i2s_hw_params,}, 1412 .hw_params = wm8753_i2s_hw_params,
1414 .dai_ops = {
1415 .digital_mute = wm8753_mute, 1413 .digital_mute = wm8753_mute,
1416 .set_fmt = wm8753_mode3_4_set_dai_fmt, 1414 .set_fmt = wm8753_mode3_4_set_dai_fmt,
1417 .set_clkdiv = wm8753_set_dai_clkdiv, 1415 .set_clkdiv = wm8753_set_dai_clkdiv,
@@ -1439,8 +1437,7 @@ static const struct snd_soc_dai wm8753_all_dai[] = {
1439 .rates = WM8753_RATES, 1437 .rates = WM8753_RATES,
1440 .formats = WM8753_FORMATS,}, 1438 .formats = WM8753_FORMATS,},
1441 .ops = { 1439 .ops = {
1442 .hw_params = wm8753_i2s_hw_params,}, 1440 .hw_params = wm8753_i2s_hw_params,
1443 .dai_ops = {
1444 .digital_mute = wm8753_mute, 1441 .digital_mute = wm8753_mute,
1445 .set_fmt = wm8753_mode3_4_set_dai_fmt, 1442 .set_fmt = wm8753_mode3_4_set_dai_fmt,
1446 .set_clkdiv = wm8753_set_dai_clkdiv, 1443 .set_clkdiv = wm8753_set_dai_clkdiv,
@@ -1608,7 +1605,7 @@ static int wm8753_init(struct snd_soc_device *socdev)
1608 1605
1609 wm8753_add_controls(codec); 1606 wm8753_add_controls(codec);
1610 wm8753_add_widgets(codec); 1607 wm8753_add_widgets(codec);
1611 ret = snd_soc_register_card(socdev); 1608 ret = snd_soc_init_card(socdev);
1612 if (ret < 0) { 1609 if (ret < 0) {
1613 printk(KERN_ERR "wm8753: failed to register card\n"); 1610 printk(KERN_ERR "wm8753: failed to register card\n");
1614 goto card_err; 1611 goto card_err;
@@ -1877,6 +1874,18 @@ struct snd_soc_codec_device soc_codec_dev_wm8753 = {
1877}; 1874};
1878EXPORT_SYMBOL_GPL(soc_codec_dev_wm8753); 1875EXPORT_SYMBOL_GPL(soc_codec_dev_wm8753);
1879 1876
1877static int __init wm8753_modinit(void)
1878{
1879 return snd_soc_register_dais(wm8753_dai, ARRAY_SIZE(wm8753_dai));
1880}
1881module_init(wm8753_modinit);
1882
1883static void __exit wm8753_exit(void)
1884{
1885 snd_soc_unregister_dais(wm8753_dai, ARRAY_SIZE(wm8753_dai));
1886}
1887module_exit(wm8753_exit);
1888
1880MODULE_DESCRIPTION("ASoC WM8753 driver"); 1889MODULE_DESCRIPTION("ASoC WM8753 driver");
1881MODULE_AUTHOR("Liam Girdwood"); 1890MODULE_AUTHOR("Liam Girdwood");
1882MODULE_LICENSE("GPL"); 1891MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c
index 3b326c9b5586..6767de10ded0 100644
--- a/sound/soc/codecs/wm8900.c
+++ b/sound/soc/codecs/wm8900.c
@@ -138,6 +138,10 @@
138struct snd_soc_codec_device soc_codec_dev_wm8900; 138struct snd_soc_codec_device soc_codec_dev_wm8900;
139 139
140struct wm8900_priv { 140struct wm8900_priv {
141 struct snd_soc_codec codec;
142
143 u16 reg_cache[WM8900_MAXREG];
144
141 u32 fll_in; /* FLL input frequency */ 145 u32 fll_in; /* FLL input frequency */
142 u32 fll_out; /* FLL output frequency */ 146 u32 fll_out; /* FLL output frequency */
143}; 147};
@@ -727,7 +731,8 @@ static int wm8900_add_widgets(struct snd_soc_codec *codec)
727} 731}
728 732
729static int wm8900_hw_params(struct snd_pcm_substream *substream, 733static int wm8900_hw_params(struct snd_pcm_substream *substream,
730 struct snd_pcm_hw_params *params) 734 struct snd_pcm_hw_params *params,
735 struct snd_soc_dai *dai)
731{ 736{
732 struct snd_soc_pcm_runtime *rtd = substream->private_data; 737 struct snd_soc_pcm_runtime *rtd = substream->private_data;
733 struct snd_soc_device *socdev = rtd->socdev; 738 struct snd_soc_device *socdev = rtd->socdev;
@@ -1117,8 +1122,6 @@ struct snd_soc_dai wm8900_dai = {
1117 }, 1122 },
1118 .ops = { 1123 .ops = {
1119 .hw_params = wm8900_hw_params, 1124 .hw_params = wm8900_hw_params,
1120 },
1121 .dai_ops = {
1122 .set_clkdiv = wm8900_set_dai_clkdiv, 1125 .set_clkdiv = wm8900_set_dai_clkdiv,
1123 .set_pll = wm8900_set_dai_pll, 1126 .set_pll = wm8900_set_dai_pll,
1124 .set_fmt = wm8900_set_dai_fmt, 1127 .set_fmt = wm8900_set_dai_fmt,
@@ -1283,16 +1286,28 @@ static int wm8900_resume(struct platform_device *pdev)
1283 return 0; 1286 return 0;
1284} 1287}
1285 1288
1286/* 1289static struct snd_soc_codec *wm8900_codec;
1287 * initialise the WM8900 driver 1290
1288 * register the mixer and dsp interfaces with the kernel 1291static int wm8900_i2c_probe(struct i2c_client *i2c,
1289 */ 1292 const struct i2c_device_id *id)
1290static int wm8900_init(struct snd_soc_device *socdev)
1291{ 1293{
1292 struct snd_soc_codec *codec = socdev->codec; 1294 struct wm8900_priv *wm8900;
1293 int ret = 0; 1295 struct snd_soc_codec *codec;
1294 unsigned int reg; 1296 unsigned int reg;
1295 struct i2c_client *i2c_client = socdev->codec->control_data; 1297 int ret;
1298
1299 wm8900 = kzalloc(sizeof(struct wm8900_priv), GFP_KERNEL);
1300 if (wm8900 == NULL)
1301 return -ENOMEM;
1302
1303 codec = &wm8900->codec;
1304 codec->private_data = wm8900;
1305 codec->reg_cache = &wm8900->reg_cache[0];
1306 codec->reg_cache_size = WM8900_MAXREG;
1307
1308 mutex_init(&codec->mutex);
1309 INIT_LIST_HEAD(&codec->dapm_widgets);
1310 INIT_LIST_HEAD(&codec->dapm_paths);
1296 1311
1297 codec->name = "WM8900"; 1312 codec->name = "WM8900";
1298 codec->owner = THIS_MODULE; 1313 codec->owner = THIS_MODULE;
@@ -1300,33 +1315,28 @@ static int wm8900_init(struct snd_soc_device *socdev)
1300 codec->write = wm8900_write; 1315 codec->write = wm8900_write;
1301 codec->dai = &wm8900_dai; 1316 codec->dai = &wm8900_dai;
1302 codec->num_dai = 1; 1317 codec->num_dai = 1;
1303 codec->reg_cache_size = WM8900_MAXREG; 1318 codec->hw_write = (hw_write_t)i2c_master_send;
1304 codec->reg_cache = kmemdup(wm8900_reg_defaults, 1319 codec->control_data = i2c;
1305 sizeof(wm8900_reg_defaults), GFP_KERNEL); 1320 codec->set_bias_level = wm8900_set_bias_level;
1306 1321 codec->dev = &i2c->dev;
1307 if (codec->reg_cache == NULL)
1308 return -ENOMEM;
1309 1322
1310 reg = wm8900_read(codec, WM8900_REG_ID); 1323 reg = wm8900_read(codec, WM8900_REG_ID);
1311 if (reg != 0x8900) { 1324 if (reg != 0x8900) {
1312 dev_err(&i2c_client->dev, "Device is not a WM8900 - ID %x\n", 1325 dev_err(&i2c->dev, "Device is not a WM8900 - ID %x\n", reg);
1313 reg); 1326 ret = -ENODEV;
1314 return -ENODEV; 1327 goto err;
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 } 1328 }
1322 1329
1323 /* Read back from the chip */ 1330 /* Read back from the chip */
1324 reg = wm8900_chip_read(codec, WM8900_REG_POWER1); 1331 reg = wm8900_chip_read(codec, WM8900_REG_POWER1);
1325 reg = (reg >> 12) & 0xf; 1332 reg = (reg >> 12) & 0xf;
1326 dev_info(&i2c_client->dev, "WM8900 revision %d\n", reg); 1333 dev_info(&i2c->dev, "WM8900 revision %d\n", reg);
1327 1334
1328 wm8900_reset(codec); 1335 wm8900_reset(codec);
1329 1336
1337 /* Turn the chip on */
1338 wm8900_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1339
1330 /* Latch the volume update bits */ 1340 /* Latch the volume update bits */
1331 wm8900_write(codec, WM8900_REG_LINVOL, 1341 wm8900_write(codec, WM8900_REG_LINVOL,
1332 wm8900_read(codec, WM8900_REG_LINVOL) | 0x100); 1342 wm8900_read(codec, WM8900_REG_LINVOL) | 0x100);
@@ -1352,160 +1362,98 @@ static int wm8900_init(struct snd_soc_device *socdev)
1352 /* Set the DAC and mixer output bias */ 1362 /* Set the DAC and mixer output bias */
1353 wm8900_write(codec, WM8900_REG_OUTBIASCTL, 0x81); 1363 wm8900_write(codec, WM8900_REG_OUTBIASCTL, 0x81);
1354 1364
1355 /* Register pcms */ 1365 wm8900_dai.dev = &i2c->dev;
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 1366
1386static struct snd_soc_device *wm8900_socdev; 1367 wm8900_codec = codec;
1387 1368
1388#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1369 ret = snd_soc_register_codec(codec);
1389 1370 if (ret != 0) {
1390static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END }; 1371 dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
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; 1372 goto err;
1429 } 1373 }
1430 1374
1431 ret = wm8900_init(socdev); 1375 ret = snd_soc_register_dai(&wm8900_dai);
1432 if (ret < 0) { 1376 if (ret != 0) {
1433 dev_err(&adap->dev, "failed to initialise WM8900\n"); 1377 dev_err(&i2c->dev, "Failed to register DAI: %d\n", ret);
1434 goto err; 1378 goto err_codec;
1435 } 1379 }
1380
1436 return ret; 1381 return ret;
1437 1382
1383err_codec:
1384 snd_soc_unregister_codec(codec);
1438err: 1385err:
1439 kfree(codec); 1386 kfree(wm8900);
1440 kfree(i2c); 1387 wm8900_codec = NULL;
1441 return ret; 1388 return ret;
1442} 1389}
1443 1390
1444static int wm8900_i2c_detach(struct i2c_client *client) 1391static int wm8900_i2c_remove(struct i2c_client *client)
1445{ 1392{
1446 struct snd_soc_codec *codec = i2c_get_clientdata(client); 1393 snd_soc_unregister_dai(&wm8900_dai);
1447 i2c_detach_client(client); 1394 snd_soc_unregister_codec(wm8900_codec);
1448 kfree(codec->reg_cache); 1395
1449 kfree(client); 1396 wm8900_set_bias_level(wm8900_codec, SND_SOC_BIAS_OFF);
1397
1398 wm8900_dai.dev = NULL;
1399 kfree(wm8900_codec->private_data);
1400 wm8900_codec = NULL;
1401
1450 return 0; 1402 return 0;
1451} 1403}
1452 1404
1453static int wm8900_i2c_attach(struct i2c_adapter *adap) 1405static const struct i2c_device_id wm8900_i2c_id[] = {
1454{ 1406 { "wm8900", 0 },
1455 return i2c_probe(adap, &addr_data, wm8900_codec_probe); 1407 { }
1456} 1408};
1409MODULE_DEVICE_TABLE(i2c, wm8900_i2c_id);
1457 1410
1458/* corgi i2c codec control layer */
1459static struct i2c_driver wm8900_i2c_driver = { 1411static struct i2c_driver wm8900_i2c_driver = {
1460 .driver = { 1412 .driver = {
1461 .name = "WM8900 I2C codec", 1413 .name = "WM8900",
1462 .owner = THIS_MODULE, 1414 .owner = THIS_MODULE,
1463 }, 1415 },
1464 .attach_adapter = wm8900_i2c_attach, 1416 .probe = wm8900_i2c_probe,
1465 .detach_client = wm8900_i2c_detach, 1417 .remove = wm8900_i2c_remove,
1466 .command = NULL, 1418 .id_table = wm8900_i2c_id,
1467};
1468
1469static struct i2c_client client_template = {
1470 .name = "WM8900",
1471 .driver = &wm8900_i2c_driver,
1472}; 1419};
1473#endif
1474 1420
1475static int wm8900_probe(struct platform_device *pdev) 1421static int wm8900_probe(struct platform_device *pdev)
1476{ 1422{
1477 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1423 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1478 struct wm8900_setup_data *setup;
1479 struct snd_soc_codec *codec; 1424 struct snd_soc_codec *codec;
1480 int ret = 0; 1425 int ret = 0;
1481 1426
1482 dev_info(&pdev->dev, "WM8900 Audio Codec\n"); 1427 if (!wm8900_codec) {
1483 1428 dev_err(&pdev->dev, "I2C client not yet instantiated\n");
1484 setup = socdev->codec_data; 1429 return -ENODEV;
1485 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 1430 }
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 1431
1432 codec = wm8900_codec;
1493 socdev->codec = codec; 1433 socdev->codec = codec;
1494 1434
1495 codec->set_bias_level = wm8900_set_bias_level; 1435 /* Register pcms */
1436 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1437 if (ret < 0) {
1438 dev_err(&pdev->dev, "Failed to register new PCMs\n");
1439 goto pcm_err;
1440 }
1496 1441
1497 wm8900_socdev = socdev; 1442 wm8900_add_controls(codec);
1498#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1443 wm8900_add_widgets(codec);
1499 if (setup->i2c_address) { 1444
1500 normal_i2c[0] = setup->i2c_address; 1445 ret = snd_soc_init_card(socdev);
1501 codec->hw_write = (hw_write_t)i2c_master_send; 1446 if (ret < 0) {
1502 ret = i2c_add_driver(&wm8900_i2c_driver); 1447 dev_err(&pdev->dev, "Failed to register card\n");
1503 if (ret != 0) 1448 goto card_err;
1504 printk(KERN_ERR "can't add i2c driver");
1505 } 1449 }
1506#else 1450
1507#error Non-I2C interfaces not yet supported 1451 return ret;
1508#endif 1452
1453card_err:
1454 snd_soc_free_pcms(socdev);
1455 snd_soc_dapm_free(socdev);
1456pcm_err:
1509 return ret; 1457 return ret;
1510} 1458}
1511 1459
@@ -1513,17 +1461,9 @@ static int wm8900_probe(struct platform_device *pdev)
1513static int wm8900_remove(struct platform_device *pdev) 1461static int wm8900_remove(struct platform_device *pdev)
1514{ 1462{
1515 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1463 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 1464
1521 snd_soc_free_pcms(socdev); 1465 snd_soc_free_pcms(socdev);
1522 snd_soc_dapm_free(socdev); 1466 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 1467
1528 return 0; 1468 return 0;
1529} 1469}
@@ -1536,6 +1476,18 @@ struct snd_soc_codec_device soc_codec_dev_wm8900 = {
1536}; 1476};
1537EXPORT_SYMBOL_GPL(soc_codec_dev_wm8900); 1477EXPORT_SYMBOL_GPL(soc_codec_dev_wm8900);
1538 1478
1479static int __init wm8900_modinit(void)
1480{
1481 return i2c_add_driver(&wm8900_i2c_driver);
1482}
1483module_init(wm8900_modinit);
1484
1485static void __exit wm8900_exit(void)
1486{
1487 i2c_del_driver(&wm8900_i2c_driver);
1488}
1489module_exit(wm8900_exit);
1490
1539MODULE_DESCRIPTION("ASoC WM8900 driver"); 1491MODULE_DESCRIPTION("ASoC WM8900 driver");
1540MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfonmicro.com>"); 1492MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfonmicro.com>");
1541MODULE_LICENSE("GPL"); 1493MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8900.h b/sound/soc/codecs/wm8900.h
index ba450d99e902..fd15007d10c7 100644
--- a/sound/soc/codecs/wm8900.h
+++ b/sound/soc/codecs/wm8900.h
@@ -52,12 +52,6 @@
52#define WM8900_DAC_CLKDIV_5_5 0x14 52#define WM8900_DAC_CLKDIV_5_5 0x14
53#define WM8900_DAC_CLKDIV_6 0x18 53#define WM8900_DAC_CLKDIV_6 0x18
54 54
55#define WM8900_
56
57struct wm8900_setup_data {
58 unsigned short i2c_address;
59};
60
61extern struct snd_soc_dai wm8900_dai; 55extern struct snd_soc_dai wm8900_dai;
62extern struct snd_soc_codec_device soc_codec_dev_wm8900; 56extern struct snd_soc_codec_device soc_codec_dev_wm8900;
63 57
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index ce40d7877605..bde74546db4a 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -33,19 +33,6 @@
33 33
34#include "wm8903.h" 34#include "wm8903.h"
35 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 */ 36/* Register defaults at reset */
50static u16 wm8903_reg_defaults[] = { 37static u16 wm8903_reg_defaults[] = {
51 0x8903, /* R0 - SW Reset and ID */ 38 0x8903, /* R0 - SW Reset and ID */
@@ -223,6 +210,23 @@ static u16 wm8903_reg_defaults[] = {
223 0x0000, /* R172 - Analogue Output Bias 0 */ 210 0x0000, /* R172 - Analogue Output Bias 0 */
224}; 211};
225 212
213struct wm8903_priv {
214 struct snd_soc_codec codec;
215 u16 reg_cache[ARRAY_SIZE(wm8903_reg_defaults)];
216
217 int sysclk;
218
219 /* Reference counts */
220 int charge_pump_users;
221 int class_w_users;
222 int playback_active;
223 int capture_active;
224
225 struct snd_pcm_substream *master_substream;
226 struct snd_pcm_substream *slave_substream;
227};
228
229
226static unsigned int wm8903_read_reg_cache(struct snd_soc_codec *codec, 230static unsigned int wm8903_read_reg_cache(struct snd_soc_codec *codec,
227 unsigned int reg) 231 unsigned int reg)
228{ 232{
@@ -360,6 +364,8 @@ static void wm8903_sync_reg_cache(struct snd_soc_codec *codec, u16 *cache)
360static void wm8903_reset(struct snd_soc_codec *codec) 364static void wm8903_reset(struct snd_soc_codec *codec)
361{ 365{
362 wm8903_write(codec, WM8903_SW_RESET_AND_ID, 0); 366 wm8903_write(codec, WM8903_SW_RESET_AND_ID, 0);
367 memcpy(codec->reg_cache, wm8903_reg_defaults,
368 sizeof(wm8903_reg_defaults));
363} 369}
364 370
365#define WM8903_OUTPUT_SHORT 0x8 371#define WM8903_OUTPUT_SHORT 0x8
@@ -392,6 +398,7 @@ static int wm8903_output_event(struct snd_soc_dapm_widget *w,
392 break; 398 break;
393 default: 399 default:
394 BUG(); 400 BUG();
401 return -EINVAL; /* Spurious warning from some compilers */
395 } 402 }
396 403
397 switch (w->shift) { 404 switch (w->shift) {
@@ -403,6 +410,7 @@ static int wm8903_output_event(struct snd_soc_dapm_widget *w,
403 break; 410 break;
404 default: 411 default:
405 BUG(); 412 BUG();
413 return -EINVAL; /* Spurious warning from some compilers */
406 } 414 }
407 415
408 if (event & SND_SOC_DAPM_PRE_PMU) { 416 if (event & SND_SOC_DAPM_PRE_PMU) {
@@ -773,14 +781,14 @@ static const struct snd_kcontrol_new left_output_mixer[] = {
773SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_LEFT_MIX_0, 3, 1, 0), 781SOC_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), 782SOC_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), 783SOC_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), 784SOC_DAPM_SINGLE_W("Right Bypass Switch", WM8903_ANALOGUE_LEFT_MIX_0, 0, 1, 0),
777}; 785};
778 786
779static const struct snd_kcontrol_new right_output_mixer[] = { 787static const struct snd_kcontrol_new right_output_mixer[] = {
780SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_RIGHT_MIX_0, 3, 1, 0), 788SOC_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), 789SOC_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), 790SOC_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), 791SOC_DAPM_SINGLE_W("Right Bypass Switch", WM8903_ANALOGUE_RIGHT_MIX_0, 0, 1, 0),
784}; 792};
785 793
786static const struct snd_kcontrol_new left_speaker_mixer[] = { 794static const struct snd_kcontrol_new left_speaker_mixer[] = {
@@ -788,7 +796,7 @@ SOC_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), 796SOC_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), 797SOC_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, 798SOC_DAPM_SINGLE("Right Bypass Switch", WM8903_ANALOGUE_SPK_MIX_LEFT_0,
791 1, 1, 0), 799 0, 1, 0),
792}; 800};
793 801
794static const struct snd_kcontrol_new right_speaker_mixer[] = { 802static const struct snd_kcontrol_new right_speaker_mixer[] = {
@@ -797,7 +805,7 @@ SOC_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, 805SOC_DAPM_SINGLE("Left Bypass Switch", WM8903_ANALOGUE_SPK_MIX_RIGHT_0,
798 1, 1, 0), 806 1, 1, 0),
799SOC_DAPM_SINGLE("Right Bypass Switch", WM8903_ANALOGUE_SPK_MIX_RIGHT_0, 807SOC_DAPM_SINGLE("Right Bypass Switch", WM8903_ANALOGUE_SPK_MIX_RIGHT_0,
800 1, 1, 0), 808 0, 1, 0),
801}; 809};
802 810
803static const struct snd_soc_dapm_widget wm8903_dapm_widgets[] = { 811static const struct snd_soc_dapm_widget wm8903_dapm_widgets[] = {
@@ -989,6 +997,9 @@ static int wm8903_set_bias_level(struct snd_soc_codec *codec,
989 997
990 case SND_SOC_BIAS_STANDBY: 998 case SND_SOC_BIAS_STANDBY:
991 if (codec->bias_level == SND_SOC_BIAS_OFF) { 999 if (codec->bias_level == SND_SOC_BIAS_OFF) {
1000 wm8903_write(codec, WM8903_CLOCK_RATES_2,
1001 WM8903_CLK_SYS_ENA);
1002
992 wm8903_run_sequence(codec, 0); 1003 wm8903_run_sequence(codec, 0);
993 wm8903_sync_reg_cache(codec, codec->reg_cache); 1004 wm8903_sync_reg_cache(codec, codec->reg_cache);
994 1005
@@ -1019,6 +1030,9 @@ static int wm8903_set_bias_level(struct snd_soc_codec *codec,
1019 1030
1020 case SND_SOC_BIAS_OFF: 1031 case SND_SOC_BIAS_OFF:
1021 wm8903_run_sequence(codec, 32); 1032 wm8903_run_sequence(codec, 32);
1033 reg = wm8903_read(codec, WM8903_CLOCK_RATES_2);
1034 reg &= ~WM8903_CLK_SYS_ENA;
1035 wm8903_write(codec, WM8903_CLOCK_RATES_2, reg);
1022 break; 1036 break;
1023 } 1037 }
1024 1038
@@ -1257,7 +1271,8 @@ static struct {
1257 { 0, 0 }, 1271 { 0, 0 },
1258}; 1272};
1259 1273
1260static int wm8903_startup(struct snd_pcm_substream *substream) 1274static int wm8903_startup(struct snd_pcm_substream *substream,
1275 struct snd_soc_dai *dai)
1261{ 1276{
1262 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1277 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1263 struct snd_soc_device *socdev = rtd->socdev; 1278 struct snd_soc_device *socdev = rtd->socdev;
@@ -1298,7 +1313,8 @@ static int wm8903_startup(struct snd_pcm_substream *substream)
1298 return 0; 1313 return 0;
1299} 1314}
1300 1315
1301static void wm8903_shutdown(struct snd_pcm_substream *substream) 1316static void wm8903_shutdown(struct snd_pcm_substream *substream,
1317 struct snd_soc_dai *dai)
1302{ 1318{
1303 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1319 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1304 struct snd_soc_device *socdev = rtd->socdev; 1320 struct snd_soc_device *socdev = rtd->socdev;
@@ -1317,7 +1333,8 @@ static void wm8903_shutdown(struct snd_pcm_substream *substream)
1317} 1333}
1318 1334
1319static int wm8903_hw_params(struct snd_pcm_substream *substream, 1335static int wm8903_hw_params(struct snd_pcm_substream *substream,
1320 struct snd_pcm_hw_params *params) 1336 struct snd_pcm_hw_params *params,
1337 struct snd_soc_dai *dai)
1321{ 1338{
1322 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1339 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1323 struct snd_soc_device *socdev = rtd->socdev; 1340 struct snd_soc_device *socdev = rtd->socdev;
@@ -1515,8 +1532,6 @@ struct snd_soc_dai wm8903_dai = {
1515 .startup = wm8903_startup, 1532 .startup = wm8903_startup,
1516 .shutdown = wm8903_shutdown, 1533 .shutdown = wm8903_shutdown,
1517 .hw_params = wm8903_hw_params, 1534 .hw_params = wm8903_hw_params,
1518 },
1519 .dai_ops = {
1520 .digital_mute = wm8903_digital_mute, 1535 .digital_mute = wm8903_digital_mute,
1521 .set_fmt = wm8903_set_dai_fmt, 1536 .set_fmt = wm8903_set_dai_fmt,
1522 .set_sysclk = wm8903_set_dai_sysclk 1537 .set_sysclk = wm8903_set_dai_sysclk
@@ -1560,39 +1575,48 @@ static int wm8903_resume(struct platform_device *pdev)
1560 return 0; 1575 return 0;
1561} 1576}
1562 1577
1563/* 1578static struct snd_soc_codec *wm8903_codec;
1564 * initialise the WM8903 driver 1579
1565 * register the mixer and dsp interfaces with the kernel 1580static int wm8903_i2c_probe(struct i2c_client *i2c,
1566 */ 1581 const struct i2c_device_id *id)
1567static int wm8903_init(struct snd_soc_device *socdev)
1568{ 1582{
1569 struct snd_soc_codec *codec = socdev->codec; 1583 struct wm8903_priv *wm8903;
1570 struct i2c_client *i2c = codec->control_data; 1584 struct snd_soc_codec *codec;
1571 int ret = 0; 1585 int ret;
1572 u16 val; 1586 u16 val;
1573 1587
1574 val = wm8903_hw_read(codec, WM8903_SW_RESET_AND_ID); 1588 wm8903 = kzalloc(sizeof(struct wm8903_priv), GFP_KERNEL);
1575 if (val != wm8903_reg_defaults[WM8903_SW_RESET_AND_ID]) { 1589 if (wm8903 == NULL)
1576 dev_err(&i2c->dev, 1590 return -ENOMEM;
1577 "Device with ID register %x is not a WM8903\n", val); 1591
1578 return -ENODEV; 1592 codec = &wm8903->codec;
1579 }
1580 1593
1594 mutex_init(&codec->mutex);
1595 INIT_LIST_HEAD(&codec->dapm_widgets);
1596 INIT_LIST_HEAD(&codec->dapm_paths);
1597
1598 codec->dev = &i2c->dev;
1581 codec->name = "WM8903"; 1599 codec->name = "WM8903";
1582 codec->owner = THIS_MODULE; 1600 codec->owner = THIS_MODULE;
1583 codec->read = wm8903_read; 1601 codec->read = wm8903_read;
1584 codec->write = wm8903_write; 1602 codec->write = wm8903_write;
1603 codec->hw_write = (hw_write_t)i2c_master_send;
1585 codec->bias_level = SND_SOC_BIAS_OFF; 1604 codec->bias_level = SND_SOC_BIAS_OFF;
1586 codec->set_bias_level = wm8903_set_bias_level; 1605 codec->set_bias_level = wm8903_set_bias_level;
1587 codec->dai = &wm8903_dai; 1606 codec->dai = &wm8903_dai;
1588 codec->num_dai = 1; 1607 codec->num_dai = 1;
1589 codec->reg_cache_size = ARRAY_SIZE(wm8903_reg_defaults); 1608 codec->reg_cache_size = ARRAY_SIZE(wm8903->reg_cache);
1590 codec->reg_cache = kmemdup(wm8903_reg_defaults, 1609 codec->reg_cache = &wm8903->reg_cache[0];
1591 sizeof(wm8903_reg_defaults), 1610 codec->private_data = wm8903;
1592 GFP_KERNEL); 1611
1593 if (codec->reg_cache == NULL) { 1612 i2c_set_clientdata(i2c, codec);
1594 dev_err(&i2c->dev, "Failed to allocate register cache\n"); 1613 codec->control_data = i2c;
1595 return -ENOMEM; 1614
1615 val = wm8903_hw_read(codec, WM8903_SW_RESET_AND_ID);
1616 if (val != wm8903_reg_defaults[WM8903_SW_RESET_AND_ID]) {
1617 dev_err(&i2c->dev,
1618 "Device with ID register %x is not a WM8903\n", val);
1619 return -ENODEV;
1596 } 1620 }
1597 1621
1598 val = wm8903_read(codec, WM8903_REVISION_NUMBER); 1622 val = wm8903_read(codec, WM8903_REVISION_NUMBER);
@@ -1601,16 +1625,6 @@ static int wm8903_init(struct snd_soc_device *socdev)
1601 1625
1602 wm8903_reset(codec); 1626 wm8903_reset(codec);
1603 1627
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 */ 1628 /* power on device */
1615 wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1629 wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1616 1630
@@ -1645,47 +1659,45 @@ static int wm8903_init(struct snd_soc_device *socdev)
1645 val |= WM8903_DAC_MUTEMODE; 1659 val |= WM8903_DAC_MUTEMODE;
1646 wm8903_write(codec, WM8903_DAC_DIGITAL_1, val); 1660 wm8903_write(codec, WM8903_DAC_DIGITAL_1, val);
1647 1661
1648 wm8903_add_controls(codec); 1662 wm8903_dai.dev = &i2c->dev;
1649 wm8903_add_widgets(codec); 1663 wm8903_codec = codec;
1650 ret = snd_soc_register_card(socdev); 1664
1651 if (ret < 0) { 1665 ret = snd_soc_register_codec(codec);
1652 dev_err(&i2c->dev, "wm8903: failed to register card\n"); 1666 if (ret != 0) {
1653 goto card_err; 1667 dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
1668 goto err;
1669 }
1670
1671 ret = snd_soc_register_dai(&wm8903_dai);
1672 if (ret != 0) {
1673 dev_err(&i2c->dev, "Failed to register DAI: %d\n", ret);
1674 goto err_codec;
1654 } 1675 }
1655 1676
1656 return ret; 1677 return ret;
1657 1678
1658card_err: 1679err_codec:
1659 snd_soc_free_pcms(socdev); 1680 snd_soc_unregister_codec(codec);
1660 snd_soc_dapm_free(socdev); 1681err:
1661pcm_err: 1682 wm8903_codec = NULL;
1662 kfree(codec->reg_cache); 1683 kfree(wm8903);
1663 return ret; 1684 return ret;
1664} 1685}
1665 1686
1666static struct snd_soc_device *wm8903_socdev; 1687static int wm8903_i2c_remove(struct i2c_client *client)
1667
1668static int wm8903_i2c_probe(struct i2c_client *i2c,
1669 const struct i2c_device_id *id)
1670{ 1688{
1671 struct snd_soc_device *socdev = wm8903_socdev; 1689 struct snd_soc_codec *codec = i2c_get_clientdata(client);
1672 struct snd_soc_codec *codec = socdev->codec;
1673 int ret;
1674 1690
1675 i2c_set_clientdata(i2c, codec); 1691 snd_soc_unregister_dai(&wm8903_dai);
1676 codec->control_data = i2c; 1692 snd_soc_unregister_codec(codec);
1677 1693
1678 ret = wm8903_init(socdev); 1694 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF);
1679 if (ret < 0)
1680 dev_err(&i2c->dev, "Device initialisation failed\n");
1681 1695
1682 return ret; 1696 kfree(codec->private_data);
1683} 1697
1698 wm8903_codec = NULL;
1699 wm8903_dai.dev = NULL;
1684 1700
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; 1701 return 0;
1690} 1702}
1691 1703
@@ -1709,75 +1721,37 @@ static struct i2c_driver wm8903_i2c_driver = {
1709static int wm8903_probe(struct platform_device *pdev) 1721static int wm8903_probe(struct platform_device *pdev)
1710{ 1722{
1711 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1723 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; 1724 int ret = 0;
1719 1725
1720 setup = socdev->codec_data; 1726 if (!wm8903_codec) {
1721 1727 dev_err(&pdev->dev, "I2C device not yet probed\n");
1722 if (!setup->i2c_address) { 1728 goto err;
1723 dev_err(&pdev->dev, "No codec address provided\n");
1724 return -ENODEV;
1725 } 1729 }
1726 1730
1727 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 1731 socdev->codec = wm8903_codec;
1728 if (codec == NULL)
1729 return -ENOMEM;
1730 1732
1731 wm8903 = kzalloc(sizeof(struct wm8903_priv), GFP_KERNEL); 1733 /* register pcms */
1732 if (wm8903 == NULL) { 1734 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1733 ret = -ENOMEM; 1735 if (ret < 0) {
1734 goto err_codec; 1736 dev_err(&pdev->dev, "failed to create pcms\n");
1737 goto err;
1735 } 1738 }
1736 1739
1737 codec->private_data = wm8903; 1740 wm8903_add_controls(socdev->codec);
1738 socdev->codec = codec; 1741 wm8903_add_widgets(socdev->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 1742
1745 codec->hw_write = (hw_write_t)i2c_master_send; 1743 ret = snd_soc_init_card(socdev);
1746 ret = i2c_add_driver(&wm8903_i2c_driver); 1744 if (ret < 0) {
1747 if (ret != 0) { 1745 dev_err(&pdev->dev, "wm8903: failed to register card\n");
1748 dev_err(&pdev->dev, "can't add i2c driver\n"); 1746 goto card_err;
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 } 1747 }
1772 1748
1773 return ret; 1749 return ret;
1774 1750
1775err_adapter: 1751card_err:
1776 i2c_del_driver(&wm8903_i2c_driver); 1752 snd_soc_free_pcms(socdev);
1777err_priv: 1753 snd_soc_dapm_free(socdev);
1778 kfree(codec->private_data); 1754err:
1779err_codec:
1780 kfree(codec);
1781 return ret; 1755 return ret;
1782} 1756}
1783 1757
@@ -1792,10 +1766,6 @@ static int wm8903_remove(struct platform_device *pdev)
1792 1766
1793 snd_soc_free_pcms(socdev); 1767 snd_soc_free_pcms(socdev);
1794 snd_soc_dapm_free(socdev); 1768 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 1769
1800 return 0; 1770 return 0;
1801} 1771}
@@ -1808,6 +1778,18 @@ struct snd_soc_codec_device soc_codec_dev_wm8903 = {
1808}; 1778};
1809EXPORT_SYMBOL_GPL(soc_codec_dev_wm8903); 1779EXPORT_SYMBOL_GPL(soc_codec_dev_wm8903);
1810 1780
1781static int __init wm8903_modinit(void)
1782{
1783 return i2c_add_driver(&wm8903_i2c_driver);
1784}
1785module_init(wm8903_modinit);
1786
1787static void __exit wm8903_exit(void)
1788{
1789 i2c_del_driver(&wm8903_i2c_driver);
1790}
1791module_exit(wm8903_exit);
1792
1811MODULE_DESCRIPTION("ASoC WM8903 driver"); 1793MODULE_DESCRIPTION("ASoC WM8903 driver");
1812MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.cm>"); 1794MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.cm>");
1813MODULE_LICENSE("GPL"); 1795MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8903.h b/sound/soc/codecs/wm8903.h
index cec622f2f660..0ea27e2b9963 100644
--- a/sound/soc/codecs/wm8903.h
+++ b/sound/soc/codecs/wm8903.h
@@ -18,11 +18,6 @@
18extern struct snd_soc_dai wm8903_dai; 18extern struct snd_soc_dai wm8903_dai;
19extern struct snd_soc_codec_device soc_codec_dev_wm8903; 19extern struct snd_soc_codec_device soc_codec_dev_wm8903;
20 20
21struct wm8903_setup_data {
22 int i2c_bus;
23 int i2c_address;
24};
25
26#define WM8903_MCLK_DIV_2 1 21#define WM8903_MCLK_DIV_2 1
27#define WM8903_CLK_SYS 2 22#define WM8903_CLK_SYS 2
28#define WM8903_BCLK 3 23#define WM8903_BCLK 3
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
index f41a578ddd4f..88ead7f8dd98 100644
--- a/sound/soc/codecs/wm8971.c
+++ b/sound/soc/codecs/wm8971.c
@@ -541,7 +541,8 @@ static int wm8971_set_dai_fmt(struct snd_soc_dai *codec_dai,
541} 541}
542 542
543static int wm8971_pcm_hw_params(struct snd_pcm_substream *substream, 543static int wm8971_pcm_hw_params(struct snd_pcm_substream *substream,
544 struct snd_pcm_hw_params *params) 544 struct snd_pcm_hw_params *params,
545 struct snd_soc_dai *dai)
545{ 546{
546 struct snd_soc_pcm_runtime *rtd = substream->private_data; 547 struct snd_soc_pcm_runtime *rtd = substream->private_data;
547 struct snd_soc_device *socdev = rtd->socdev; 548 struct snd_soc_device *socdev = rtd->socdev;
@@ -634,8 +635,6 @@ struct snd_soc_dai wm8971_dai = {
634 .formats = WM8971_FORMATS,}, 635 .formats = WM8971_FORMATS,},
635 .ops = { 636 .ops = {
636 .hw_params = wm8971_pcm_hw_params, 637 .hw_params = wm8971_pcm_hw_params,
637 },
638 .dai_ops = {
639 .digital_mute = wm8971_mute, 638 .digital_mute = wm8971_mute,
640 .set_fmt = wm8971_set_dai_fmt, 639 .set_fmt = wm8971_set_dai_fmt,
641 .set_sysclk = wm8971_set_dai_sysclk, 640 .set_sysclk = wm8971_set_dai_sysclk,
@@ -748,7 +747,7 @@ static int wm8971_init(struct snd_soc_device *socdev)
748 747
749 wm8971_add_controls(codec); 748 wm8971_add_controls(codec);
750 wm8971_add_widgets(codec); 749 wm8971_add_widgets(codec);
751 ret = snd_soc_register_card(socdev); 750 ret = snd_soc_init_card(socdev);
752 if (ret < 0) { 751 if (ret < 0) {
753 printk(KERN_ERR "wm8971: failed to register card\n"); 752 printk(KERN_ERR "wm8971: failed to register card\n");
754 goto card_err; 753 goto card_err;
@@ -936,6 +935,18 @@ struct snd_soc_codec_device soc_codec_dev_wm8971 = {
936 935
937EXPORT_SYMBOL_GPL(soc_codec_dev_wm8971); 936EXPORT_SYMBOL_GPL(soc_codec_dev_wm8971);
938 937
938static int __init wm8971_modinit(void)
939{
940 return snd_soc_register_dai(&wm8971_dai);
941}
942module_init(wm8971_modinit);
943
944static void __exit wm8971_exit(void)
945{
946 snd_soc_unregister_dai(&wm8971_dai);
947}
948module_exit(wm8971_exit);
949
939MODULE_DESCRIPTION("ASoC WM8971 driver"); 950MODULE_DESCRIPTION("ASoC WM8971 driver");
940MODULE_AUTHOR("Lab126"); 951MODULE_AUTHOR("Lab126");
941MODULE_LICENSE("GPL"); 952MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index 572d22b0880b..5b5afc144478 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -106,6 +106,7 @@ static const u16 wm8990_reg[] = {
106 0x0008, /* R60 - PLL1 */ 106 0x0008, /* R60 - PLL1 */
107 0x0031, /* R61 - PLL2 */ 107 0x0031, /* R61 - PLL2 */
108 0x0026, /* R62 - PLL3 */ 108 0x0026, /* R62 - PLL3 */
109 0x0000, /* R63 - Driver internal */
109}; 110};
110 111
111/* 112/*
@@ -126,10 +127,9 @@ static inline void wm8990_write_reg_cache(struct snd_soc_codec *codec,
126 unsigned int reg, unsigned int value) 127 unsigned int reg, unsigned int value)
127{ 128{
128 u16 *cache = codec->reg_cache; 129 u16 *cache = codec->reg_cache;
129 BUG_ON(reg > (ARRAY_SIZE(wm8990_reg)) - 1);
130 130
131 /* Reset register is uncached */ 131 /* Reset register and reserved registers are uncached */
132 if (reg == 0) 132 if (reg == 0 || reg > ARRAY_SIZE(wm8990_reg) - 1)
133 return; 133 return;
134 134
135 cache[reg] = value; 135 cache[reg] = value;
@@ -1172,7 +1172,8 @@ static int wm8990_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
1172 * Set PCM DAI bit size and sample rate. 1172 * Set PCM DAI bit size and sample rate.
1173 */ 1173 */
1174static int wm8990_hw_params(struct snd_pcm_substream *substream, 1174static int wm8990_hw_params(struct snd_pcm_substream *substream,
1175 struct snd_pcm_hw_params *params) 1175 struct snd_pcm_hw_params *params,
1176 struct snd_soc_dai *dai)
1176{ 1177{
1177 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1178 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1178 struct snd_soc_device *socdev = rtd->socdev; 1179 struct snd_soc_device *socdev = rtd->socdev;
@@ -1222,8 +1223,14 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec,
1222 switch (level) { 1223 switch (level) {
1223 case SND_SOC_BIAS_ON: 1224 case SND_SOC_BIAS_ON:
1224 break; 1225 break;
1226
1225 case SND_SOC_BIAS_PREPARE: 1227 case SND_SOC_BIAS_PREPARE:
1228 /* VMID=2*50k */
1229 val = wm8990_read_reg_cache(codec, WM8990_POWER_MANAGEMENT_1) &
1230 ~WM8990_VMID_MODE_MASK;
1231 wm8990_write(codec, WM8990_POWER_MANAGEMENT_1, val | 0x2);
1226 break; 1232 break;
1233
1227 case SND_SOC_BIAS_STANDBY: 1234 case SND_SOC_BIAS_STANDBY:
1228 if (codec->bias_level == SND_SOC_BIAS_OFF) { 1235 if (codec->bias_level == SND_SOC_BIAS_OFF) {
1229 /* Enable all output discharge bits */ 1236 /* Enable all output discharge bits */
@@ -1272,10 +1279,17 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec,
1272 1279
1273 /* disable POBCTRL, SOFT_ST and BUFDCOPEN */ 1280 /* disable POBCTRL, SOFT_ST and BUFDCOPEN */
1274 wm8990_write(codec, WM8990_ANTIPOP2, WM8990_BUFIOEN); 1281 wm8990_write(codec, WM8990_ANTIPOP2, WM8990_BUFIOEN);
1275 } else {
1276 /* ON -> standby */
1277 1282
1283 /* Enable workaround for ADC clocking issue. */
1284 wm8990_write(codec, WM8990_EXT_ACCESS_ENA, 0x2);
1285 wm8990_write(codec, WM8990_EXT_CTL1, 0xa003);
1286 wm8990_write(codec, WM8990_EXT_ACCESS_ENA, 0);
1278 } 1287 }
1288
1289 /* VMID=2*250k */
1290 val = wm8990_read_reg_cache(codec, WM8990_POWER_MANAGEMENT_1) &
1291 ~WM8990_VMID_MODE_MASK;
1292 wm8990_write(codec, WM8990_POWER_MANAGEMENT_1, val | 0x4);
1279 break; 1293 break;
1280 1294
1281 case SND_SOC_BIAS_OFF: 1295 case SND_SOC_BIAS_OFF:
@@ -1349,8 +1363,7 @@ struct snd_soc_dai wm8990_dai = {
1349 .rates = WM8990_RATES, 1363 .rates = WM8990_RATES,
1350 .formats = WM8990_FORMATS,}, 1364 .formats = WM8990_FORMATS,},
1351 .ops = { 1365 .ops = {
1352 .hw_params = wm8990_hw_params,}, 1366 .hw_params = wm8990_hw_params,
1353 .dai_ops = {
1354 .digital_mute = wm8990_mute, 1367 .digital_mute = wm8990_mute,
1355 .set_fmt = wm8990_set_dai_fmt, 1368 .set_fmt = wm8990_set_dai_fmt,
1356 .set_clkdiv = wm8990_set_dai_clkdiv, 1369 .set_clkdiv = wm8990_set_dai_clkdiv,
@@ -1449,7 +1462,7 @@ static int wm8990_init(struct snd_soc_device *socdev)
1449 1462
1450 wm8990_add_controls(codec); 1463 wm8990_add_controls(codec);
1451 wm8990_add_widgets(codec); 1464 wm8990_add_widgets(codec);
1452 ret = snd_soc_register_card(socdev); 1465 ret = snd_soc_init_card(socdev);
1453 if (ret < 0) { 1466 if (ret < 0) {
1454 printk(KERN_ERR "wm8990: failed to register card\n"); 1467 printk(KERN_ERR "wm8990: failed to register card\n");
1455 goto card_err; 1468 goto card_err;
@@ -1630,6 +1643,18 @@ struct snd_soc_codec_device soc_codec_dev_wm8990 = {
1630}; 1643};
1631EXPORT_SYMBOL_GPL(soc_codec_dev_wm8990); 1644EXPORT_SYMBOL_GPL(soc_codec_dev_wm8990);
1632 1645
1646static int __init wm8990_modinit(void)
1647{
1648 return snd_soc_register_dai(&wm8990_dai);
1649}
1650module_init(wm8990_modinit);
1651
1652static void __exit wm8990_exit(void)
1653{
1654 snd_soc_unregister_dai(&wm8990_dai);
1655}
1656module_exit(wm8990_exit);
1657
1633MODULE_DESCRIPTION("ASoC WM8990 driver"); 1658MODULE_DESCRIPTION("ASoC WM8990 driver");
1634MODULE_AUTHOR("Liam Girdwood"); 1659MODULE_AUTHOR("Liam Girdwood");
1635MODULE_LICENSE("GPL"); 1660MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8990.h b/sound/soc/codecs/wm8990.h
index 0e192f3b0788..7114ddc88b4b 100644
--- a/sound/soc/codecs/wm8990.h
+++ b/sound/soc/codecs/wm8990.h
@@ -80,8 +80,8 @@
80#define WM8990_PLL3 0x3E 80#define WM8990_PLL3 0x3E
81#define WM8990_INTDRIVBITS 0x3F 81#define WM8990_INTDRIVBITS 0x3F
82 82
83#define WM8990_REGISTER_COUNT 60 83#define WM8990_EXT_ACCESS_ENA 0x75
84#define WM8990_MAX_REGISTER 0x3F 84#define WM8990_EXT_CTL1 0x7a
85 85
86/* 86/*
87 * Field Definitions. 87 * Field Definitions.
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index ffb471e420e2..af83d629078a 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -487,7 +487,8 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
487 return 0; 487 return 0;
488} 488}
489 489
490static int ac97_prepare(struct snd_pcm_substream *substream) 490static int ac97_prepare(struct snd_pcm_substream *substream,
491 struct snd_soc_dai *dai)
491{ 492{
492 struct snd_pcm_runtime *runtime = substream->runtime; 493 struct snd_pcm_runtime *runtime = substream->runtime;
493 struct snd_soc_pcm_runtime *rtd = substream->private_data; 494 struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -507,7 +508,8 @@ static int ac97_prepare(struct snd_pcm_substream *substream)
507 return ac97_write(codec, reg, runtime->rate); 508 return ac97_write(codec, reg, runtime->rate);
508} 509}
509 510
510static int ac97_aux_prepare(struct snd_pcm_substream *substream) 511static int ac97_aux_prepare(struct snd_pcm_substream *substream,
512 struct snd_soc_dai *dai)
511{ 513{
512 struct snd_pcm_runtime *runtime = substream->runtime; 514 struct snd_pcm_runtime *runtime = substream->runtime;
513 struct snd_soc_pcm_runtime *rtd = substream->private_data; 515 struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -533,7 +535,7 @@ static int ac97_aux_prepare(struct snd_pcm_substream *substream)
533struct snd_soc_dai wm9712_dai[] = { 535struct snd_soc_dai wm9712_dai[] = {
534{ 536{
535 .name = "AC97 HiFi", 537 .name = "AC97 HiFi",
536 .type = SND_SOC_DAI_AC97_BUS, 538 .ac97_control = 1,
537 .playback = { 539 .playback = {
538 .stream_name = "HiFi Playback", 540 .stream_name = "HiFi Playback",
539 .channels_min = 1, 541 .channels_min = 1,
@@ -688,7 +690,7 @@ static int wm9712_soc_probe(struct platform_device *pdev)
688 690
689 ret = wm9712_reset(codec, 0); 691 ret = wm9712_reset(codec, 0);
690 if (ret < 0) { 692 if (ret < 0) {
691 printk(KERN_ERR "AC97 link error\n"); 693 printk(KERN_ERR "Failed to reset WM9712: AC97 link error\n");
692 goto reset_err; 694 goto reset_err;
693 } 695 }
694 696
@@ -698,7 +700,7 @@ static int wm9712_soc_probe(struct platform_device *pdev)
698 wm9712_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 700 wm9712_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
699 wm9712_add_controls(codec); 701 wm9712_add_controls(codec);
700 wm9712_add_widgets(codec); 702 wm9712_add_widgets(codec);
701 ret = snd_soc_register_card(socdev); 703 ret = snd_soc_init_card(socdev);
702 if (ret < 0) { 704 if (ret < 0) {
703 printk(KERN_ERR "wm9712: failed to register card\n"); 705 printk(KERN_ERR "wm9712: failed to register card\n");
704 goto reset_err; 706 goto reset_err;
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index 945b32ed9884..f3ca8aaf0139 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -928,11 +928,10 @@ static int wm9713_set_dai_fmt(struct snd_soc_dai *codec_dai,
928} 928}
929 929
930static int wm9713_pcm_hw_params(struct snd_pcm_substream *substream, 930static int wm9713_pcm_hw_params(struct snd_pcm_substream *substream,
931 struct snd_pcm_hw_params *params) 931 struct snd_pcm_hw_params *params,
932 struct snd_soc_dai *dai)
932{ 933{
933 struct snd_soc_pcm_runtime *rtd = substream->private_data; 934 struct snd_soc_codec *codec = dai->codec;
934 struct snd_soc_device *socdev = rtd->socdev;
935 struct snd_soc_codec *codec = socdev->codec;
936 u16 reg = ac97_read(codec, AC97_CENTER_LFE_MASTER) & 0xfff3; 935 u16 reg = ac97_read(codec, AC97_CENTER_LFE_MASTER) & 0xfff3;
937 936
938 switch (params_format(params)) { 937 switch (params_format(params)) {
@@ -954,11 +953,10 @@ static int wm9713_pcm_hw_params(struct snd_pcm_substream *substream,
954 return 0; 953 return 0;
955} 954}
956 955
957static void wm9713_voiceshutdown(struct snd_pcm_substream *substream) 956static void wm9713_voiceshutdown(struct snd_pcm_substream *substream,
957 struct snd_soc_dai *dai)
958{ 958{
959 struct snd_soc_pcm_runtime *rtd = substream->private_data; 959 struct snd_soc_codec *codec = dai->codec;
960 struct snd_soc_device *socdev = rtd->socdev;
961 struct snd_soc_codec *codec = socdev->codec;
962 u16 status; 960 u16 status;
963 961
964 /* Gracefully shut down the voice interface. */ 962 /* Gracefully shut down the voice interface. */
@@ -969,12 +967,11 @@ static void wm9713_voiceshutdown(struct snd_pcm_substream *substream)
969 ac97_write(codec, AC97_EXTENDED_MID, status); 967 ac97_write(codec, AC97_EXTENDED_MID, status);
970} 968}
971 969
972static int ac97_hifi_prepare(struct snd_pcm_substream *substream) 970static int ac97_hifi_prepare(struct snd_pcm_substream *substream,
971 struct snd_soc_dai *dai)
973{ 972{
973 struct snd_soc_codec *codec = dai->codec;
974 struct snd_pcm_runtime *runtime = substream->runtime; 974 struct snd_pcm_runtime *runtime = substream->runtime;
975 struct snd_soc_pcm_runtime *rtd = substream->private_data;
976 struct snd_soc_device *socdev = rtd->socdev;
977 struct snd_soc_codec *codec = socdev->codec;
978 int reg; 975 int reg;
979 u16 vra; 976 u16 vra;
980 977
@@ -989,12 +986,11 @@ static int ac97_hifi_prepare(struct snd_pcm_substream *substream)
989 return ac97_write(codec, reg, runtime->rate); 986 return ac97_write(codec, reg, runtime->rate);
990} 987}
991 988
992static int ac97_aux_prepare(struct snd_pcm_substream *substream) 989static int ac97_aux_prepare(struct snd_pcm_substream *substream,
990 struct snd_soc_dai *dai)
993{ 991{
992 struct snd_soc_codec *codec = dai->codec;
994 struct snd_pcm_runtime *runtime = substream->runtime; 993 struct snd_pcm_runtime *runtime = substream->runtime;
995 struct snd_soc_pcm_runtime *rtd = substream->private_data;
996 struct snd_soc_device *socdev = rtd->socdev;
997 struct snd_soc_codec *codec = socdev->codec;
998 u16 vra, xsle; 994 u16 vra, xsle;
999 995
1000 vra = ac97_read(codec, AC97_EXTENDED_STATUS); 996 vra = ac97_read(codec, AC97_EXTENDED_STATUS);
@@ -1028,7 +1024,7 @@ static int ac97_aux_prepare(struct snd_pcm_substream *substream)
1028struct snd_soc_dai wm9713_dai[] = { 1024struct snd_soc_dai wm9713_dai[] = {
1029{ 1025{
1030 .name = "AC97 HiFi", 1026 .name = "AC97 HiFi",
1031 .type = SND_SOC_DAI_AC97_BUS, 1027 .ac97_control = 1,
1032 .playback = { 1028 .playback = {
1033 .stream_name = "HiFi Playback", 1029 .stream_name = "HiFi Playback",
1034 .channels_min = 1, 1030 .channels_min = 1,
@@ -1042,8 +1038,7 @@ struct snd_soc_dai wm9713_dai[] = {
1042 .rates = WM9713_RATES, 1038 .rates = WM9713_RATES,
1043 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 1039 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
1044 .ops = { 1040 .ops = {
1045 .prepare = ac97_hifi_prepare,}, 1041 .prepare = ac97_hifi_prepare,
1046 .dai_ops = {
1047 .set_clkdiv = wm9713_set_dai_clkdiv, 1042 .set_clkdiv = wm9713_set_dai_clkdiv,
1048 .set_pll = wm9713_set_dai_pll,}, 1043 .set_pll = wm9713_set_dai_pll,},
1049 }, 1044 },
@@ -1056,8 +1051,7 @@ struct snd_soc_dai wm9713_dai[] = {
1056 .rates = WM9713_RATES, 1051 .rates = WM9713_RATES,
1057 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 1052 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
1058 .ops = { 1053 .ops = {
1059 .prepare = ac97_aux_prepare,}, 1054 .prepare = ac97_aux_prepare,
1060 .dai_ops = {
1061 .set_clkdiv = wm9713_set_dai_clkdiv, 1055 .set_clkdiv = wm9713_set_dai_clkdiv,
1062 .set_pll = wm9713_set_dai_pll,}, 1056 .set_pll = wm9713_set_dai_pll,},
1063 }, 1057 },
@@ -1077,8 +1071,7 @@ struct snd_soc_dai wm9713_dai[] = {
1077 .formats = WM9713_PCM_FORMATS,}, 1071 .formats = WM9713_PCM_FORMATS,},
1078 .ops = { 1072 .ops = {
1079 .hw_params = wm9713_pcm_hw_params, 1073 .hw_params = wm9713_pcm_hw_params,
1080 .shutdown = wm9713_voiceshutdown,}, 1074 .shutdown = wm9713_voiceshutdown,
1081 .dai_ops = {
1082 .set_clkdiv = wm9713_set_dai_clkdiv, 1075 .set_clkdiv = wm9713_set_dai_clkdiv,
1083 .set_pll = wm9713_set_dai_pll, 1076 .set_pll = wm9713_set_dai_pll,
1084 .set_fmt = wm9713_set_dai_fmt, 1077 .set_fmt = wm9713_set_dai_fmt,
@@ -1097,6 +1090,8 @@ int wm9713_reset(struct snd_soc_codec *codec, int try_warm)
1097 } 1090 }
1098 1091
1099 soc_ac97_ops.reset(codec->ac97); 1092 soc_ac97_ops.reset(codec->ac97);
1093 if (soc_ac97_ops.warm_reset)
1094 soc_ac97_ops.warm_reset(codec->ac97);
1100 if (ac97_read(codec, 0) != wm9713_reg[0]) 1095 if (ac97_read(codec, 0) != wm9713_reg[0])
1101 return -EIO; 1096 return -EIO;
1102 return 0; 1097 return 0;
@@ -1240,7 +1235,7 @@ static int wm9713_soc_probe(struct platform_device *pdev)
1240 wm9713_reset(codec, 0); 1235 wm9713_reset(codec, 0);
1241 ret = wm9713_reset(codec, 1); 1236 ret = wm9713_reset(codec, 1);
1242 if (ret < 0) { 1237 if (ret < 0) {
1243 printk(KERN_ERR "AC97 link error\n"); 1238 printk(KERN_ERR "Failed to reset WM9713: AC97 link error\n");
1244 goto reset_err; 1239 goto reset_err;
1245 } 1240 }
1246 1241
@@ -1252,7 +1247,7 @@ static int wm9713_soc_probe(struct platform_device *pdev)
1252 1247
1253 wm9713_add_controls(codec); 1248 wm9713_add_controls(codec);
1254 wm9713_add_widgets(codec); 1249 wm9713_add_widgets(codec);
1255 ret = snd_soc_register_card(socdev); 1250 ret = snd_soc_init_card(socdev);
1256 if (ret < 0) 1251 if (ret < 0)
1257 goto reset_err; 1252 goto reset_err;
1258 return 0; 1253 return 0;
@@ -1288,7 +1283,6 @@ static int wm9713_soc_remove(struct platform_device *pdev)
1288 snd_soc_free_ac97_codec(codec); 1283 snd_soc_free_ac97_codec(codec);
1289 kfree(codec->private_data); 1284 kfree(codec->private_data);
1290 kfree(codec->reg_cache); 1285 kfree(codec->reg_cache);
1291 kfree(codec->dai);
1292 kfree(codec); 1286 kfree(codec);
1293 return 0; 1287 return 0;
1294} 1288}
diff --git a/sound/soc/davinci/Kconfig b/sound/soc/davinci/Kconfig
index 8f7e33834902..b502741692d6 100644
--- a/sound/soc/davinci/Kconfig
+++ b/sound/soc/davinci/Kconfig
@@ -17,3 +17,13 @@ config SND_DAVINCI_SOC_EVM
17 help 17 help
18 Say Y if you want to add support for SoC audio on TI 18 Say Y if you want to add support for SoC audio on TI
19 DaVinci EVM platform. 19 DaVinci EVM platform.
20
21config SND_DAVINCI_SOC_SFFSDR
22 tristate "SoC Audio support for SFFSDR"
23 depends on SND_DAVINCI_SOC && MACH_DAVINCI_SFFSDR
24 select SND_DAVINCI_SOC_I2S
25 select SND_SOC_PCM3008
26 select SFFSDR_FPGA
27 help
28 Say Y if you want to add support for SoC audio on
29 Lyrtech SFFSDR board.
diff --git a/sound/soc/davinci/Makefile b/sound/soc/davinci/Makefile
index ca772e5b4637..ca8bae1fc3f6 100644
--- a/sound/soc/davinci/Makefile
+++ b/sound/soc/davinci/Makefile
@@ -7,5 +7,7 @@ obj-$(CONFIG_SND_DAVINCI_SOC_I2S) += snd-soc-davinci-i2s.o
7 7
8# DAVINCI Machine Support 8# DAVINCI Machine Support
9snd-soc-evm-objs := davinci-evm.o 9snd-soc-evm-objs := davinci-evm.o
10snd-soc-sffsdr-objs := davinci-sffsdr.o
10 11
11obj-$(CONFIG_SND_DAVINCI_SOC_EVM) += snd-soc-evm.o 12obj-$(CONFIG_SND_DAVINCI_SOC_EVM) += snd-soc-evm.o
13obj-$(CONFIG_SND_DAVINCI_SOC_SFFSDR) += snd-soc-sffsdr.o
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c
index 9e6062cd6b59..01b948bb55a1 100644
--- a/sound/soc/davinci/davinci-evm.c
+++ b/sound/soc/davinci/davinci-evm.c
@@ -28,6 +28,8 @@
28 28
29#define EVM_CODEC_CLOCK 22579200 29#define EVM_CODEC_CLOCK 22579200
30 30
31#define AUDIO_FORMAT (SND_SOC_DAIFMT_DSP_B | \
32 SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_IB_NF)
31static int evm_hw_params(struct snd_pcm_substream *substream, 33static int evm_hw_params(struct snd_pcm_substream *substream,
32 struct snd_pcm_hw_params *params) 34 struct snd_pcm_hw_params *params)
33{ 35{
@@ -37,14 +39,12 @@ static int evm_hw_params(struct snd_pcm_substream *substream,
37 int ret = 0; 39 int ret = 0;
38 40
39 /* set codec DAI configuration */ 41 /* set codec DAI configuration */
40 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | 42 ret = snd_soc_dai_set_fmt(codec_dai, AUDIO_FORMAT);
41 SND_SOC_DAIFMT_CBM_CFM);
42 if (ret < 0) 43 if (ret < 0)
43 return ret; 44 return ret;
44 45
45 /* set cpu DAI configuration */ 46 /* set cpu DAI configuration */
46 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBM_CFM | 47 ret = snd_soc_dai_set_fmt(cpu_dai, AUDIO_FORMAT);
47 SND_SOC_DAIFMT_IB_NF);
48 if (ret < 0) 48 if (ret < 0)
49 return ret; 49 return ret;
50 50
@@ -128,8 +128,9 @@ static struct snd_soc_dai_link evm_dai = {
128}; 128};
129 129
130/* davinci-evm audio machine driver */ 130/* davinci-evm audio machine driver */
131static struct snd_soc_machine snd_soc_machine_evm = { 131static struct snd_soc_card snd_soc_card_evm = {
132 .name = "DaVinci EVM", 132 .name = "DaVinci EVM",
133 .platform = &davinci_soc_platform,
133 .dai_link = &evm_dai, 134 .dai_link = &evm_dai,
134 .num_links = 1, 135 .num_links = 1,
135}; 136};
@@ -142,8 +143,7 @@ static struct aic3x_setup_data evm_aic3x_setup = {
142 143
143/* evm audio subsystem */ 144/* evm audio subsystem */
144static struct snd_soc_device evm_snd_devdata = { 145static struct snd_soc_device evm_snd_devdata = {
145 .machine = &snd_soc_machine_evm, 146 .card = &snd_soc_card_evm,
146 .platform = &davinci_soc_platform,
147 .codec_dev = &soc_codec_dev_aic3x, 147 .codec_dev = &soc_codec_dev_aic3x,
148 .codec_data = &evm_aic3x_setup, 148 .codec_data = &evm_aic3x_setup,
149}; 149};
diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c
index abb5fedb0b1e..0fee779e3c76 100644
--- a/sound/soc/davinci/davinci-i2s.c
+++ b/sound/soc/davinci/davinci-i2s.c
@@ -59,6 +59,7 @@
59#define DAVINCI_MCBSP_PCR_CLKXP (1 << 1) 59#define DAVINCI_MCBSP_PCR_CLKXP (1 << 1)
60#define DAVINCI_MCBSP_PCR_FSRP (1 << 2) 60#define DAVINCI_MCBSP_PCR_FSRP (1 << 2)
61#define DAVINCI_MCBSP_PCR_FSXP (1 << 3) 61#define DAVINCI_MCBSP_PCR_FSXP (1 << 3)
62#define DAVINCI_MCBSP_PCR_SCLKME (1 << 7)
62#define DAVINCI_MCBSP_PCR_CLKRM (1 << 8) 63#define DAVINCI_MCBSP_PCR_CLKRM (1 << 8)
63#define DAVINCI_MCBSP_PCR_CLKXM (1 << 9) 64#define DAVINCI_MCBSP_PCR_CLKXM (1 << 9)
64#define DAVINCI_MCBSP_PCR_FSRM (1 << 10) 65#define DAVINCI_MCBSP_PCR_FSRM (1 << 10)
@@ -110,16 +111,59 @@ static void davinci_mcbsp_start(struct snd_pcm_substream *substream)
110{ 111{
111 struct snd_soc_pcm_runtime *rtd = substream->private_data; 112 struct snd_soc_pcm_runtime *rtd = substream->private_data;
112 struct davinci_mcbsp_dev *dev = rtd->dai->cpu_dai->private_data; 113 struct davinci_mcbsp_dev *dev = rtd->dai->cpu_dai->private_data;
114 struct snd_soc_device *socdev = rtd->socdev;
115 struct snd_soc_platform *platform = socdev->card->platform;
113 u32 w; 116 u32 w;
117 int ret;
114 118
115 /* Start the sample generator and enable transmitter/receiver */ 119 /* Start the sample generator and enable transmitter/receiver */
116 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG); 120 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
117 MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_GRST, 1); 121 MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_GRST, 1);
118 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 122 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w);
123
124 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
125 /* Stop the DMA to avoid data loss */
126 /* while the transmitter is out of reset to handle XSYNCERR */
127 if (platform->pcm_ops->trigger) {
128 ret = platform->pcm_ops->trigger(substream,
129 SNDRV_PCM_TRIGGER_STOP);
130 if (ret < 0)
131 printk(KERN_DEBUG "Playback DMA stop failed\n");
132 }
133
134 /* Enable the transmitter */
135 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
119 MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_XRST, 1); 136 MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_XRST, 1);
120 else 137 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w);
138
139 /* wait for any unexpected frame sync error to occur */
140 udelay(100);
141
142 /* Disable the transmitter to clear any outstanding XSYNCERR */
143 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
144 MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_XRST, 0);
145 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w);
146
147 /* Restart the DMA */
148 if (platform->pcm_ops->trigger) {
149 ret = platform->pcm_ops->trigger(substream,
150 SNDRV_PCM_TRIGGER_START);
151 if (ret < 0)
152 printk(KERN_DEBUG "Playback DMA start failed\n");
153 }
154 /* Enable the transmitter */
155 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
156 MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_XRST, 1);
157 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w);
158
159 } else {
160
161 /* Enable the reciever */
162 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
121 MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_RRST, 1); 163 MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_RRST, 1);
122 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w); 164 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w);
165 }
166
123 167
124 /* Start frame sync */ 168 /* Start frame sync */
125 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG); 169 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
@@ -144,7 +188,8 @@ static void davinci_mcbsp_stop(struct snd_pcm_substream *substream)
144 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w); 188 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w);
145} 189}
146 190
147static int davinci_i2s_startup(struct snd_pcm_substream *substream) 191static int davinci_i2s_startup(struct snd_pcm_substream *substream,
192 struct snd_soc_dai *dai)
148{ 193{
149 struct snd_soc_pcm_runtime *rtd = substream->private_data; 194 struct snd_soc_pcm_runtime *rtd = substream->private_data;
150 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 195 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -155,61 +200,138 @@ static int davinci_i2s_startup(struct snd_pcm_substream *substream)
155 return 0; 200 return 0;
156} 201}
157 202
203#define DEFAULT_BITPERSAMPLE 16
204
158static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, 205static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
159 unsigned int fmt) 206 unsigned int fmt)
160{ 207{
161 struct davinci_mcbsp_dev *dev = cpu_dai->private_data; 208 struct davinci_mcbsp_dev *dev = cpu_dai->private_data;
162 u32 w; 209 unsigned int pcr;
210 unsigned int srgr;
211 unsigned int rcr;
212 unsigned int xcr;
213 srgr = DAVINCI_MCBSP_SRGR_FSGM |
214 DAVINCI_MCBSP_SRGR_FPER(DEFAULT_BITPERSAMPLE * 2 - 1) |
215 DAVINCI_MCBSP_SRGR_FWID(DEFAULT_BITPERSAMPLE - 1);
163 216
164 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 217 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
165 case SND_SOC_DAIFMT_CBS_CFS: 218 case SND_SOC_DAIFMT_CBS_CFS:
166 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, 219 /* cpu is master */
167 DAVINCI_MCBSP_PCR_FSXM | 220 pcr = DAVINCI_MCBSP_PCR_FSXM |
168 DAVINCI_MCBSP_PCR_FSRM | 221 DAVINCI_MCBSP_PCR_FSRM |
169 DAVINCI_MCBSP_PCR_CLKXM | 222 DAVINCI_MCBSP_PCR_CLKXM |
170 DAVINCI_MCBSP_PCR_CLKRM); 223 DAVINCI_MCBSP_PCR_CLKRM;
171 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG, 224 break;
172 DAVINCI_MCBSP_SRGR_FSGM); 225 case SND_SOC_DAIFMT_CBM_CFS:
226 /* McBSP CLKR pin is the input for the Sample Rate Generator.
227 * McBSP FSR and FSX are driven by the Sample Rate Generator. */
228 pcr = DAVINCI_MCBSP_PCR_SCLKME |
229 DAVINCI_MCBSP_PCR_FSXM |
230 DAVINCI_MCBSP_PCR_FSRM;
173 break; 231 break;
174 case SND_SOC_DAIFMT_CBM_CFM: 232 case SND_SOC_DAIFMT_CBM_CFM:
175 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, 0); 233 /* codec is master */
234 pcr = 0;
176 break; 235 break;
177 default: 236 default:
237 printk(KERN_ERR "%s:bad master\n", __func__);
178 return -EINVAL; 238 return -EINVAL;
179 } 239 }
180 240
181 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 241 rcr = DAVINCI_MCBSP_RCR_RFRLEN1(1);
182 case SND_SOC_DAIFMT_IB_NF: 242 xcr = DAVINCI_MCBSP_XCR_XFIG | DAVINCI_MCBSP_XCR_XFRLEN1(1);
183 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_PCR_REG); 243 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
184 MOD_REG_BIT(w, DAVINCI_MCBSP_PCR_CLKXP | 244 case SND_SOC_DAIFMT_DSP_B:
185 DAVINCI_MCBSP_PCR_CLKRP, 1);
186 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, w);
187 break; 245 break;
188 case SND_SOC_DAIFMT_NB_IF: 246 case SND_SOC_DAIFMT_I2S:
189 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_PCR_REG); 247 /* Davinci doesn't support TRUE I2S, but some codecs will have
190 MOD_REG_BIT(w, DAVINCI_MCBSP_PCR_FSXP | 248 * the left and right channels contiguous. This allows
191 DAVINCI_MCBSP_PCR_FSRP, 1); 249 * dsp_a mode to be used with an inverted normal frame clk.
192 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, w); 250 * If your codec is master and does not have contiguous
251 * channels, then you will have sound on only one channel.
252 * Try using a different mode, or codec as slave.
253 *
254 * The TLV320AIC33 is an example of a codec where this works.
255 * It has a variable bit clock frequency allowing it to have
256 * valid data on every bit clock.
257 *
258 * The TLV320AIC23 is an example of a codec where this does not
259 * work. It has a fixed bit clock frequency with progressively
260 * more empty bit clock slots between channels as the sample
261 * rate is lowered.
262 */
263 fmt ^= SND_SOC_DAIFMT_NB_IF;
264 case SND_SOC_DAIFMT_DSP_A:
265 rcr |= DAVINCI_MCBSP_RCR_RDATDLY(1);
266 xcr |= DAVINCI_MCBSP_XCR_XDATDLY(1);
267 break;
268 default:
269 printk(KERN_ERR "%s:bad format\n", __func__);
270 return -EINVAL;
271 }
272
273 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
274 case SND_SOC_DAIFMT_NB_NF:
275 /* CLKRP Receive clock polarity,
276 * 1 - sampled on rising edge of CLKR
277 * valid on rising edge
278 * CLKXP Transmit clock polarity,
279 * 1 - clocked on falling edge of CLKX
280 * valid on rising edge
281 * FSRP Receive frame sync pol, 0 - active high
282 * FSXP Transmit frame sync pol, 0 - active high
283 */
284 pcr |= (DAVINCI_MCBSP_PCR_CLKXP | DAVINCI_MCBSP_PCR_CLKRP);
193 break; 285 break;
194 case SND_SOC_DAIFMT_IB_IF: 286 case SND_SOC_DAIFMT_IB_IF:
195 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_PCR_REG); 287 /* CLKRP Receive clock polarity,
196 MOD_REG_BIT(w, DAVINCI_MCBSP_PCR_CLKXP | 288 * 0 - sampled on falling edge of CLKR
197 DAVINCI_MCBSP_PCR_CLKRP | 289 * valid on falling edge
198 DAVINCI_MCBSP_PCR_FSXP | 290 * CLKXP Transmit clock polarity,
199 DAVINCI_MCBSP_PCR_FSRP, 1); 291 * 0 - clocked on rising edge of CLKX
200 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, w); 292 * valid on falling edge
293 * FSRP Receive frame sync pol, 1 - active low
294 * FSXP Transmit frame sync pol, 1 - active low
295 */
296 pcr |= (DAVINCI_MCBSP_PCR_FSXP | DAVINCI_MCBSP_PCR_FSRP);
201 break; 297 break;
202 case SND_SOC_DAIFMT_NB_NF: 298 case SND_SOC_DAIFMT_NB_IF:
299 /* CLKRP Receive clock polarity,
300 * 1 - sampled on rising edge of CLKR
301 * valid on rising edge
302 * CLKXP Transmit clock polarity,
303 * 1 - clocked on falling edge of CLKX
304 * valid on rising edge
305 * FSRP Receive frame sync pol, 1 - active low
306 * FSXP Transmit frame sync pol, 1 - active low
307 */
308 pcr |= (DAVINCI_MCBSP_PCR_CLKXP | DAVINCI_MCBSP_PCR_CLKRP |
309 DAVINCI_MCBSP_PCR_FSXP | DAVINCI_MCBSP_PCR_FSRP);
310 break;
311 case SND_SOC_DAIFMT_IB_NF:
312 /* CLKRP Receive clock polarity,
313 * 0 - sampled on falling edge of CLKR
314 * valid on falling edge
315 * CLKXP Transmit clock polarity,
316 * 0 - clocked on rising edge of CLKX
317 * valid on falling edge
318 * FSRP Receive frame sync pol, 0 - active high
319 * FSXP Transmit frame sync pol, 0 - active high
320 */
203 break; 321 break;
204 default: 322 default:
205 return -EINVAL; 323 return -EINVAL;
206 } 324 }
207 325 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG, srgr);
326 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, pcr);
327 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_RCR_REG, rcr);
328 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_XCR_REG, xcr);
208 return 0; 329 return 0;
209} 330}
210 331
211static int davinci_i2s_hw_params(struct snd_pcm_substream *substream, 332static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
212 struct snd_pcm_hw_params *params) 333 struct snd_pcm_hw_params *params,
334 struct snd_soc_dai *dai)
213{ 335{
214 struct snd_soc_pcm_runtime *rtd = substream->private_data; 336 struct snd_soc_pcm_runtime *rtd = substream->private_data;
215 struct davinci_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data; 337 struct davinci_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data;
@@ -219,25 +341,20 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
219 u32 w; 341 u32 w;
220 342
221 /* general line settings */ 343 /* general line settings */
222 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, 344 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
223 DAVINCI_MCBSP_SPCR_RINTM(3) | 345 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
224 DAVINCI_MCBSP_SPCR_XINTM(3) | 346 w |= DAVINCI_MCBSP_SPCR_RINTM(3) | DAVINCI_MCBSP_SPCR_FREE;
225 DAVINCI_MCBSP_SPCR_FREE); 347 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w);
226 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_RCR_REG, 348 } else {
227 DAVINCI_MCBSP_RCR_RFRLEN1(1) | 349 w |= DAVINCI_MCBSP_SPCR_XINTM(3) | DAVINCI_MCBSP_SPCR_FREE;
228 DAVINCI_MCBSP_RCR_RDATDLY(1)); 350 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w);
229 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_XCR_REG, 351 }
230 DAVINCI_MCBSP_XCR_XFRLEN1(1) |
231 DAVINCI_MCBSP_XCR_XDATDLY(1) |
232 DAVINCI_MCBSP_XCR_XFIG);
233 352
234 i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS); 353 i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS);
235 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SRGR_REG); 354 w = DAVINCI_MCBSP_SRGR_FSGM;
236 MOD_REG_BIT(w, DAVINCI_MCBSP_SRGR_FWID(snd_interval_value(i) - 1), 1); 355 MOD_REG_BIT(w, DAVINCI_MCBSP_SRGR_FWID(snd_interval_value(i) - 1), 1);
237 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG, w);
238 356
239 i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_FRAME_BITS); 357 i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_FRAME_BITS);
240 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SRGR_REG);
241 MOD_REG_BIT(w, DAVINCI_MCBSP_SRGR_FPER(snd_interval_value(i) - 1), 1); 358 MOD_REG_BIT(w, DAVINCI_MCBSP_SRGR_FPER(snd_interval_value(i) - 1), 1);
242 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG, w); 359 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG, w);
243 360
@@ -260,20 +377,24 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
260 return -EINVAL; 377 return -EINVAL;
261 } 378 }
262 379
263 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_RCR_REG); 380 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
264 MOD_REG_BIT(w, DAVINCI_MCBSP_RCR_RWDLEN1(mcbsp_word_length) | 381 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_RCR_REG);
265 DAVINCI_MCBSP_RCR_RWDLEN2(mcbsp_word_length), 1); 382 MOD_REG_BIT(w, DAVINCI_MCBSP_RCR_RWDLEN1(mcbsp_word_length) |
266 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_RCR_REG, w); 383 DAVINCI_MCBSP_RCR_RWDLEN2(mcbsp_word_length), 1);
384 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_RCR_REG, w);
267 385
268 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_XCR_REG); 386 } else {
269 MOD_REG_BIT(w, DAVINCI_MCBSP_XCR_XWDLEN1(mcbsp_word_length) | 387 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_XCR_REG);
270 DAVINCI_MCBSP_XCR_XWDLEN2(mcbsp_word_length), 1); 388 MOD_REG_BIT(w, DAVINCI_MCBSP_XCR_XWDLEN1(mcbsp_word_length) |
271 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_XCR_REG, w); 389 DAVINCI_MCBSP_XCR_XWDLEN2(mcbsp_word_length), 1);
390 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_XCR_REG, w);
272 391
392 }
273 return 0; 393 return 0;
274} 394}
275 395
276static int davinci_i2s_trigger(struct snd_pcm_substream *substream, int cmd) 396static int davinci_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
397 struct snd_soc_dai *dai)
277{ 398{
278 int ret = 0; 399 int ret = 0;
279 400
@@ -299,8 +420,8 @@ static int davinci_i2s_probe(struct platform_device *pdev,
299 struct snd_soc_dai *dai) 420 struct snd_soc_dai *dai)
300{ 421{
301 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 422 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
302 struct snd_soc_machine *machine = socdev->machine; 423 struct snd_soc_card *card = socdev->card;
303 struct snd_soc_dai *cpu_dai = machine->dai_link[pdev->id].cpu_dai; 424 struct snd_soc_dai *cpu_dai = card->dai_link[pdev->id].cpu_dai;
304 struct davinci_mcbsp_dev *dev; 425 struct davinci_mcbsp_dev *dev;
305 struct resource *mem, *ioarea; 426 struct resource *mem, *ioarea;
306 struct evm_snd_platform_data *pdata; 427 struct evm_snd_platform_data *pdata;
@@ -361,8 +482,8 @@ static void davinci_i2s_remove(struct platform_device *pdev,
361 struct snd_soc_dai *dai) 482 struct snd_soc_dai *dai)
362{ 483{
363 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 484 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
364 struct snd_soc_machine *machine = socdev->machine; 485 struct snd_soc_card *card = socdev->card;
365 struct snd_soc_dai *cpu_dai = machine->dai_link[pdev->id].cpu_dai; 486 struct snd_soc_dai *cpu_dai = card->dai_link[pdev->id].cpu_dai;
366 struct davinci_mcbsp_dev *dev = cpu_dai->private_data; 487 struct davinci_mcbsp_dev *dev = cpu_dai->private_data;
367 struct resource *mem; 488 struct resource *mem;
368 489
@@ -381,7 +502,6 @@ static void davinci_i2s_remove(struct platform_device *pdev,
381struct snd_soc_dai davinci_i2s_dai = { 502struct snd_soc_dai davinci_i2s_dai = {
382 .name = "davinci-i2s", 503 .name = "davinci-i2s",
383 .id = 0, 504 .id = 0,
384 .type = SND_SOC_DAI_I2S,
385 .probe = davinci_i2s_probe, 505 .probe = davinci_i2s_probe,
386 .remove = davinci_i2s_remove, 506 .remove = davinci_i2s_remove,
387 .playback = { 507 .playback = {
@@ -397,13 +517,24 @@ struct snd_soc_dai davinci_i2s_dai = {
397 .ops = { 517 .ops = {
398 .startup = davinci_i2s_startup, 518 .startup = davinci_i2s_startup,
399 .trigger = davinci_i2s_trigger, 519 .trigger = davinci_i2s_trigger,
400 .hw_params = davinci_i2s_hw_params,}, 520 .hw_params = davinci_i2s_hw_params,
401 .dai_ops = {
402 .set_fmt = davinci_i2s_set_dai_fmt, 521 .set_fmt = davinci_i2s_set_dai_fmt,
403 }, 522 },
404}; 523};
405EXPORT_SYMBOL_GPL(davinci_i2s_dai); 524EXPORT_SYMBOL_GPL(davinci_i2s_dai);
406 525
526static int __init davinci_i2s_init(void)
527{
528 return snd_soc_register_dai(&davinci_i2s_dai);
529}
530module_init(davinci_i2s_init);
531
532static void __exit davinci_i2s_exit(void)
533{
534 snd_soc_unregister_dai(&davinci_i2s_dai);
535}
536module_exit(davinci_i2s_exit);
537
407MODULE_AUTHOR("Vladimir Barinov"); 538MODULE_AUTHOR("Vladimir Barinov");
408MODULE_DESCRIPTION("TI DAVINCI I2S (McBSP) SoC Interface"); 539MODULE_DESCRIPTION("TI DAVINCI I2S (McBSP) SoC Interface");
409MODULE_LICENSE("GPL"); 540MODULE_LICENSE("GPL");
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c
index 76feaa657375..74abc9b4f1cc 100644
--- a/sound/soc/davinci/davinci-pcm.c
+++ b/sound/soc/davinci/davinci-pcm.c
@@ -14,6 +14,7 @@
14#include <linux/platform_device.h> 14#include <linux/platform_device.h>
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/dma-mapping.h> 16#include <linux/dma-mapping.h>
17#include <linux/kernel.h>
17 18
18#include <sound/core.h> 19#include <sound/core.h>
19#include <sound/pcm.h> 20#include <sound/pcm.h>
@@ -24,13 +25,6 @@
24 25
25#include "davinci-pcm.h" 26#include "davinci-pcm.h"
26 27
27#define DAVINCI_PCM_DEBUG 0
28#if DAVINCI_PCM_DEBUG
29#define DPRINTK(x...) printk(KERN_DEBUG x)
30#else
31#define DPRINTK(x...)
32#endif
33
34static struct snd_pcm_hardware davinci_pcm_hardware = { 28static struct snd_pcm_hardware davinci_pcm_hardware = {
35 .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | 29 .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
36 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | 30 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
@@ -78,8 +72,8 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream)
78 dma_offset = prtd->period * period_size; 72 dma_offset = prtd->period * period_size;
79 dma_pos = runtime->dma_addr + dma_offset; 73 dma_pos = runtime->dma_addr + dma_offset;
80 74
81 DPRINTK("audio_set_dma_params_play channel = %d dma_ptr = %x " 75 pr_debug("davinci_pcm: audio_set_dma_params_play channel = %d "
82 "period_size=%x\n", lch, dma_pos, period_size); 76 "dma_ptr = %x period_size=%x\n", lch, dma_pos, period_size);
83 77
84 data_type = prtd->params->data_type; 78 data_type = prtd->params->data_type;
85 count = period_size / data_type; 79 count = period_size / data_type;
@@ -112,7 +106,7 @@ static void davinci_pcm_dma_irq(int lch, u16 ch_status, void *data)
112 struct snd_pcm_substream *substream = data; 106 struct snd_pcm_substream *substream = data;
113 struct davinci_runtime_data *prtd = substream->runtime->private_data; 107 struct davinci_runtime_data *prtd = substream->runtime->private_data;
114 108
115 DPRINTK("lch=%d, status=0x%x\n", lch, ch_status); 109 pr_debug("davinci_pcm: lch=%d, status=0x%x\n", lch, ch_status);
116 110
117 if (unlikely(ch_status != DMA_COMPLETE)) 111 if (unlikely(ch_status != DMA_COMPLETE))
118 return; 112 return;
@@ -316,8 +310,8 @@ static int davinci_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
316 buf->area = dma_alloc_writecombine(pcm->card->dev, size, 310 buf->area = dma_alloc_writecombine(pcm->card->dev, size,
317 &buf->addr, GFP_KERNEL); 311 &buf->addr, GFP_KERNEL);
318 312
319 DPRINTK("preallocate_dma_buffer: area=%p, addr=%p, size=%d\n", 313 pr_debug("davinci_pcm: preallocate_dma_buffer: area=%p, addr=%p, "
320 (void *) buf->area, (void *) buf->addr, size); 314 "size=%d\n", (void *) buf->area, (void *) buf->addr, size);
321 315
322 if (!buf->area) 316 if (!buf->area)
323 return -ENOMEM; 317 return -ENOMEM;
@@ -384,6 +378,18 @@ struct snd_soc_platform davinci_soc_platform = {
384}; 378};
385EXPORT_SYMBOL_GPL(davinci_soc_platform); 379EXPORT_SYMBOL_GPL(davinci_soc_platform);
386 380
381static int __init davinci_soc_platform_init(void)
382{
383 return snd_soc_register_platform(&davinci_soc_platform);
384}
385module_init(davinci_soc_platform_init);
386
387static void __exit davinci_soc_platform_exit(void)
388{
389 snd_soc_unregister_platform(&davinci_soc_platform);
390}
391module_exit(davinci_soc_platform_exit);
392
387MODULE_AUTHOR("Vladimir Barinov"); 393MODULE_AUTHOR("Vladimir Barinov");
388MODULE_DESCRIPTION("TI DAVINCI PCM DMA module"); 394MODULE_DESCRIPTION("TI DAVINCI PCM DMA module");
389MODULE_LICENSE("GPL"); 395MODULE_LICENSE("GPL");
diff --git a/sound/soc/davinci/davinci-sffsdr.c b/sound/soc/davinci/davinci-sffsdr.c
new file mode 100644
index 000000000000..f67579d52765
--- /dev/null
+++ b/sound/soc/davinci/davinci-sffsdr.c
@@ -0,0 +1,157 @@
1/*
2 * ASoC driver for Lyrtech SFFSDR board.
3 *
4 * Author: Hugo Villeneuve
5 * Copyright (C) 2008 Lyrtech inc
6 *
7 * Based on ASoC driver for TI DAVINCI EVM platform, original copyright follow:
8 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/module.h>
16#include <linux/moduleparam.h>
17#include <linux/timer.h>
18#include <linux/interrupt.h>
19#include <linux/platform_device.h>
20#include <linux/gpio.h>
21#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/soc.h>
24#include <sound/soc-dapm.h>
25
26#include <asm/dma.h>
27#include <asm/plat-sffsdr/sffsdr-fpga.h>
28
29#include <mach/mcbsp.h>
30#include <mach/edma.h>
31
32#include "../codecs/pcm3008.h"
33#include "davinci-pcm.h"
34#include "davinci-i2s.h"
35
36static int sffsdr_hw_params(struct snd_pcm_substream *substream,
37 struct snd_pcm_hw_params *params,
38 struct snd_soc_dai *dai)
39{
40 struct snd_soc_pcm_runtime *rtd = substream->private_data;
41 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
42 int fs;
43 int ret = 0;
44
45 /* Set cpu DAI configuration:
46 * CLKX and CLKR are the inputs for the Sample Rate Generator.
47 * FSX and FSR are outputs, driven by the sample Rate Generator. */
48 ret = snd_soc_dai_set_fmt(cpu_dai,
49 SND_SOC_DAIFMT_RIGHT_J |
50 SND_SOC_DAIFMT_CBM_CFS |
51 SND_SOC_DAIFMT_IB_NF);
52 if (ret < 0)
53 return ret;
54
55 /* Fsref can be 32000, 44100 or 48000. */
56 fs = params_rate(params);
57
58 pr_debug("sffsdr_hw_params: rate = %d Hz\n", fs);
59
60 return sffsdr_fpga_set_codec_fs(fs);
61}
62
63static struct snd_soc_ops sffsdr_ops = {
64 .hw_params = sffsdr_hw_params,
65};
66
67/* davinci-sffsdr digital audio interface glue - connects codec <--> CPU */
68static struct snd_soc_dai_link sffsdr_dai = {
69 .name = "PCM3008", /* Codec name */
70 .stream_name = "PCM3008 HiFi",
71 .cpu_dai = &davinci_i2s_dai,
72 .codec_dai = &pcm3008_dai,
73 .ops = &sffsdr_ops,
74};
75
76/* davinci-sffsdr audio machine driver */
77static struct snd_soc_card snd_soc_sffsdr = {
78 .name = "DaVinci SFFSDR",
79 .platform = &davinci_soc_platform,
80 .dai_link = &sffsdr_dai,
81 .num_links = 1,
82};
83
84/* sffsdr audio private data */
85static struct pcm3008_setup_data sffsdr_pcm3008_setup = {
86 .dem0_pin = GPIO(45),
87 .dem1_pin = GPIO(46),
88 .pdad_pin = GPIO(47),
89 .pdda_pin = GPIO(38),
90};
91
92/* sffsdr audio subsystem */
93static struct snd_soc_device sffsdr_snd_devdata = {
94 .card = &snd_soc_sffsdr,
95 .codec_dev = &soc_codec_dev_pcm3008,
96 .codec_data = &sffsdr_pcm3008_setup,
97};
98
99static struct resource sffsdr_snd_resources[] = {
100 {
101 .start = DAVINCI_MCBSP_BASE,
102 .end = DAVINCI_MCBSP_BASE + SZ_8K - 1,
103 .flags = IORESOURCE_MEM,
104 },
105};
106
107static struct evm_snd_platform_data sffsdr_snd_data = {
108 .tx_dma_ch = DAVINCI_DMA_MCBSP_TX,
109 .rx_dma_ch = DAVINCI_DMA_MCBSP_RX,
110};
111
112static struct platform_device *sffsdr_snd_device;
113
114static int __init sffsdr_init(void)
115{
116 int ret;
117
118 sffsdr_snd_device = platform_device_alloc("soc-audio", 0);
119 if (!sffsdr_snd_device) {
120 printk(KERN_ERR "platform device allocation failed\n");
121 return -ENOMEM;
122 }
123
124 platform_set_drvdata(sffsdr_snd_device, &sffsdr_snd_devdata);
125 sffsdr_snd_devdata.dev = &sffsdr_snd_device->dev;
126 sffsdr_snd_device->dev.platform_data = &sffsdr_snd_data;
127
128 ret = platform_device_add_resources(sffsdr_snd_device,
129 sffsdr_snd_resources,
130 ARRAY_SIZE(sffsdr_snd_resources));
131 if (ret) {
132 printk(KERN_ERR "platform device add ressources failed\n");
133 goto error;
134 }
135
136 ret = platform_device_add(sffsdr_snd_device);
137 if (ret)
138 goto error;
139
140 return ret;
141
142error:
143 platform_device_put(sffsdr_snd_device);
144 return ret;
145}
146
147static void __exit sffsdr_exit(void)
148{
149 platform_device_unregister(sffsdr_snd_device);
150}
151
152module_init(sffsdr_init);
153module_exit(sffsdr_exit);
154
155MODULE_AUTHOR("Hugo Villeneuve");
156MODULE_DESCRIPTION("Lyrtech SFFSDR ASoC driver");
157MODULE_LICENSE("GPL");
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 8d73edc56102..95c12b26fe37 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -20,7 +20,7 @@ config SND_SOC_MPC8610_HPCD
20 20
21config SND_SOC_MPC5200_I2S 21config SND_SOC_MPC5200_I2S
22 tristate "Freescale MPC5200 PSC in I2S mode driver" 22 tristate "Freescale MPC5200 PSC in I2S mode driver"
23 depends on SND_SOC && PPC_MPC52xx && PPC_BESTCOMM 23 depends on PPC_MPC52xx && PPC_BESTCOMM
24 select SND_SOC_OF_SIMPLE 24 select SND_SOC_OF_SIMPLE
25 select PPC_BESTCOMM_GEN_BD 25 select PPC_BESTCOMM_GEN_BD
26 help 26 help
diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c
index d2d3da9729f2..64993eda5679 100644
--- a/sound/soc/fsl/fsl_dma.c
+++ b/sound/soc/fsl/fsl_dma.c
@@ -284,7 +284,7 @@ static irqreturn_t fsl_dma_isr(int irq, void *dev_id)
284 * fsl_dma_new: initialize this PCM driver. 284 * fsl_dma_new: initialize this PCM driver.
285 * 285 *
286 * This function is called when the codec driver calls snd_soc_new_pcms(), 286 * This function is called when the codec driver calls snd_soc_new_pcms(),
287 * once for each .dai_link in the machine driver's snd_soc_machine 287 * once for each .dai_link in the machine driver's snd_soc_card
288 * structure. 288 * structure.
289 */ 289 */
290static int fsl_dma_new(struct snd_card *card, struct snd_soc_dai *dai, 290static int fsl_dma_new(struct snd_card *card, struct snd_soc_dai *dai,
@@ -853,6 +853,18 @@ int fsl_dma_configure(struct fsl_dma_info *dma_info)
853} 853}
854EXPORT_SYMBOL_GPL(fsl_dma_configure); 854EXPORT_SYMBOL_GPL(fsl_dma_configure);
855 855
856static int __init fsl_soc_platform_init(void)
857{
858 return snd_soc_register_platform(&fsl_soc_platform);
859}
860module_init(fsl_soc_platform_init);
861
862static void __exit fsl_soc_platform_exit(void)
863{
864 snd_soc_unregister_platform(&fsl_soc_platform);
865}
866module_exit(fsl_soc_platform_exit);
867
856MODULE_AUTHOR("Timur Tabi <timur@freescale.com>"); 868MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
857MODULE_DESCRIPTION("Freescale Elo DMA ASoC PCM module"); 869MODULE_DESCRIPTION("Freescale Elo DMA ASoC PCM module");
858MODULE_LICENSE("GPL"); 870MODULE_LICENSE("GPL");
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 157a7895ffa1..c6d6eb71dc1d 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -266,7 +266,8 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
266 * If this is the first stream open, then grab the IRQ and program most of 266 * If this is the first stream open, then grab the IRQ and program most of
267 * the SSI registers. 267 * the SSI registers.
268 */ 268 */
269static int fsl_ssi_startup(struct snd_pcm_substream *substream) 269static int fsl_ssi_startup(struct snd_pcm_substream *substream,
270 struct snd_soc_dai *dai)
270{ 271{
271 struct snd_soc_pcm_runtime *rtd = substream->private_data; 272 struct snd_soc_pcm_runtime *rtd = substream->private_data;
272 struct fsl_ssi_private *ssi_private = rtd->dai->cpu_dai->private_data; 273 struct fsl_ssi_private *ssi_private = rtd->dai->cpu_dai->private_data;
@@ -411,7 +412,8 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream)
411 * Note: The SxCCR.DC and SxCCR.PM bits are only used if the SSI is the 412 * Note: The SxCCR.DC and SxCCR.PM bits are only used if the SSI is the
412 * clock master. 413 * clock master.
413 */ 414 */
414static int fsl_ssi_prepare(struct snd_pcm_substream *substream) 415static int fsl_ssi_prepare(struct snd_pcm_substream *substream,
416 struct snd_soc_dai *dai)
415{ 417{
416 struct snd_pcm_runtime *runtime = substream->runtime; 418 struct snd_pcm_runtime *runtime = substream->runtime;
417 struct snd_soc_pcm_runtime *rtd = substream->private_data; 419 struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -441,7 +443,8 @@ static int fsl_ssi_prepare(struct snd_pcm_substream *substream)
441 * The DMA channel is in external master start and pause mode, which 443 * The DMA channel is in external master start and pause mode, which
442 * means the SSI completely controls the flow of data. 444 * means the SSI completely controls the flow of data.
443 */ 445 */
444static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd) 446static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
447 struct snd_soc_dai *dai)
445{ 448{
446 struct snd_soc_pcm_runtime *rtd = substream->private_data; 449 struct snd_soc_pcm_runtime *rtd = substream->private_data;
447 struct fsl_ssi_private *ssi_private = rtd->dai->cpu_dai->private_data; 450 struct fsl_ssi_private *ssi_private = rtd->dai->cpu_dai->private_data;
@@ -490,7 +493,8 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd)
490 * 493 *
491 * Shutdown the SSI if there are no other substreams open. 494 * Shutdown the SSI if there are no other substreams open.
492 */ 495 */
493static void fsl_ssi_shutdown(struct snd_pcm_substream *substream) 496static void fsl_ssi_shutdown(struct snd_pcm_substream *substream,
497 struct snd_soc_dai *dai)
494{ 498{
495 struct snd_soc_pcm_runtime *rtd = substream->private_data; 499 struct snd_soc_pcm_runtime *rtd = substream->private_data;
496 struct fsl_ssi_private *ssi_private = rtd->dai->cpu_dai->private_data; 500 struct fsl_ssi_private *ssi_private = rtd->dai->cpu_dai->private_data;
@@ -578,8 +582,6 @@ static struct snd_soc_dai fsl_ssi_dai_template = {
578 .prepare = fsl_ssi_prepare, 582 .prepare = fsl_ssi_prepare,
579 .shutdown = fsl_ssi_shutdown, 583 .shutdown = fsl_ssi_shutdown,
580 .trigger = fsl_ssi_trigger, 584 .trigger = fsl_ssi_trigger,
581 },
582 .dai_ops = {
583 .set_sysclk = fsl_ssi_set_sysclk, 585 .set_sysclk = fsl_ssi_set_sysclk,
584 .set_fmt = fsl_ssi_set_fmt, 586 .set_fmt = fsl_ssi_set_fmt,
585 }, 587 },
@@ -671,6 +673,14 @@ struct snd_soc_dai *fsl_ssi_create_dai(struct fsl_ssi_info *ssi_info)
671 fsl_ssi_dai->private_data = ssi_private; 673 fsl_ssi_dai->private_data = ssi_private;
672 fsl_ssi_dai->name = ssi_private->name; 674 fsl_ssi_dai->name = ssi_private->name;
673 fsl_ssi_dai->id = ssi_info->id; 675 fsl_ssi_dai->id = ssi_info->id;
676 fsl_ssi_dai->dev = ssi_info->dev;
677
678 ret = snd_soc_register_dai(fsl_ssi_dai);
679 if (ret != 0) {
680 dev_err(ssi_info->dev, "failed to register DAI: %d\n", ret);
681 kfree(fsl_ssi_dai);
682 return NULL;
683 }
674 684
675 return fsl_ssi_dai; 685 return fsl_ssi_dai;
676} 686}
@@ -688,6 +698,8 @@ void fsl_ssi_destroy_dai(struct snd_soc_dai *fsl_ssi_dai)
688 698
689 device_remove_file(ssi_private->dev, &ssi_private->dev_attr); 699 device_remove_file(ssi_private->dev, &ssi_private->dev_attr);
690 700
701 snd_soc_unregister_dai(&ssi_private->cpu_dai);
702
691 kfree(ssi_private); 703 kfree(ssi_private);
692} 704}
693EXPORT_SYMBOL_GPL(fsl_ssi_destroy_dai); 705EXPORT_SYMBOL_GPL(fsl_ssi_destroy_dai);
diff --git a/sound/soc/fsl/mpc5200_psc_i2s.c b/sound/soc/fsl/mpc5200_psc_i2s.c
index 94a02eaa4825..9eb1ce185bd0 100644
--- a/sound/soc/fsl/mpc5200_psc_i2s.c
+++ b/sound/soc/fsl/mpc5200_psc_i2s.c
@@ -187,7 +187,8 @@ static irqreturn_t psc_i2s_bcom_irq(int irq, void *_psc_i2s_stream)
187 * If this is the first stream open, then grab the IRQ and program most of 187 * If this is the first stream open, then grab the IRQ and program most of
188 * the PSC registers. 188 * the PSC registers.
189 */ 189 */
190static int psc_i2s_startup(struct snd_pcm_substream *substream) 190static int psc_i2s_startup(struct snd_pcm_substream *substream,
191 struct snd_soc_dai *dai)
191{ 192{
192 struct snd_soc_pcm_runtime *rtd = substream->private_data; 193 struct snd_soc_pcm_runtime *rtd = substream->private_data;
193 struct psc_i2s *psc_i2s = rtd->dai->cpu_dai->private_data; 194 struct psc_i2s *psc_i2s = rtd->dai->cpu_dai->private_data;
@@ -220,7 +221,8 @@ static int psc_i2s_startup(struct snd_pcm_substream *substream)
220} 221}
221 222
222static int psc_i2s_hw_params(struct snd_pcm_substream *substream, 223static int psc_i2s_hw_params(struct snd_pcm_substream *substream,
223 struct snd_pcm_hw_params *params) 224 struct snd_pcm_hw_params *params,
225 struct snd_soc_dai *dai)
224{ 226{
225 struct snd_soc_pcm_runtime *rtd = substream->private_data; 227 struct snd_soc_pcm_runtime *rtd = substream->private_data;
226 struct psc_i2s *psc_i2s = rtd->dai->cpu_dai->private_data; 228 struct psc_i2s *psc_i2s = rtd->dai->cpu_dai->private_data;
@@ -256,7 +258,8 @@ static int psc_i2s_hw_params(struct snd_pcm_substream *substream,
256 return 0; 258 return 0;
257} 259}
258 260
259static int psc_i2s_hw_free(struct snd_pcm_substream *substream) 261static int psc_i2s_hw_free(struct snd_pcm_substream *substream,
262 struct snd_soc_dai *dai)
260{ 263{
261 snd_pcm_set_runtime_buffer(substream, NULL); 264 snd_pcm_set_runtime_buffer(substream, NULL);
262 return 0; 265 return 0;
@@ -268,7 +271,8 @@ static int psc_i2s_hw_free(struct snd_pcm_substream *substream)
268 * This function is called by ALSA to start, stop, pause, and resume the DMA 271 * This function is called by ALSA to start, stop, pause, and resume the DMA
269 * transfer of data. 272 * transfer of data.
270 */ 273 */
271static int psc_i2s_trigger(struct snd_pcm_substream *substream, int cmd) 274static int psc_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
275 struct snd_soc_dai *dai)
272{ 276{
273 struct snd_soc_pcm_runtime *rtd = substream->private_data; 277 struct snd_soc_pcm_runtime *rtd = substream->private_data;
274 struct psc_i2s *psc_i2s = rtd->dai->cpu_dai->private_data; 278 struct psc_i2s *psc_i2s = rtd->dai->cpu_dai->private_data;
@@ -383,7 +387,8 @@ static int psc_i2s_trigger(struct snd_pcm_substream *substream, int cmd)
383 * 387 *
384 * Shutdown the PSC if there are no other substreams open. 388 * Shutdown the PSC if there are no other substreams open.
385 */ 389 */
386static void psc_i2s_shutdown(struct snd_pcm_substream *substream) 390static void psc_i2s_shutdown(struct snd_pcm_substream *substream,
391 struct snd_soc_dai *dai)
387{ 392{
388 struct snd_soc_pcm_runtime *rtd = substream->private_data; 393 struct snd_soc_pcm_runtime *rtd = substream->private_data;
389 struct psc_i2s *psc_i2s = rtd->dai->cpu_dai->private_data; 394 struct psc_i2s *psc_i2s = rtd->dai->cpu_dai->private_data;
@@ -464,7 +469,6 @@ static int psc_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int format)
464 * psc_i2s_dai_template: template CPU Digital Audio Interface 469 * psc_i2s_dai_template: template CPU Digital Audio Interface
465 */ 470 */
466static struct snd_soc_dai psc_i2s_dai_template = { 471static struct snd_soc_dai psc_i2s_dai_template = {
467 .type = SND_SOC_DAI_I2S,
468 .playback = { 472 .playback = {
469 .channels_min = 2, 473 .channels_min = 2,
470 .channels_max = 2, 474 .channels_max = 2,
@@ -483,8 +487,6 @@ static struct snd_soc_dai psc_i2s_dai_template = {
483 .hw_free = psc_i2s_hw_free, 487 .hw_free = psc_i2s_hw_free,
484 .shutdown = psc_i2s_shutdown, 488 .shutdown = psc_i2s_shutdown,
485 .trigger = psc_i2s_trigger, 489 .trigger = psc_i2s_trigger,
486 },
487 .dai_ops = {
488 .set_sysclk = psc_i2s_set_sysclk, 490 .set_sysclk = psc_i2s_set_sysclk,
489 .set_fmt = psc_i2s_set_fmt, 491 .set_fmt = psc_i2s_set_fmt,
490 }, 492 },
@@ -826,6 +828,8 @@ static int __devinit psc_i2s_of_probe(struct of_device *op,
826 if (rc) 828 if (rc)
827 dev_info(psc_i2s->dev, "error creating sysfs files\n"); 829 dev_info(psc_i2s->dev, "error creating sysfs files\n");
828 830
831 snd_soc_register_platform(&psc_i2s_pcm_soc_platform);
832
829 /* Tell the ASoC OF helpers about it */ 833 /* Tell the ASoC OF helpers about it */
830 of_snd_soc_register_platform(&psc_i2s_pcm_soc_platform, op->node, 834 of_snd_soc_register_platform(&psc_i2s_pcm_soc_platform, op->node,
831 &psc_i2s->dai); 835 &psc_i2s->dai);
@@ -839,6 +843,8 @@ static int __devexit psc_i2s_of_remove(struct of_device *op)
839 843
840 dev_dbg(&op->dev, "psc_i2s_remove()\n"); 844 dev_dbg(&op->dev, "psc_i2s_remove()\n");
841 845
846 snd_soc_unregister_platform(&psc_i2s_pcm_soc_platform);
847
842 bcom_gen_bd_rx_release(psc_i2s->capture.bcom_task); 848 bcom_gen_bd_rx_release(psc_i2s->capture.bcom_task);
843 bcom_gen_bd_tx_release(psc_i2s->playback.bcom_task); 849 bcom_gen_bd_tx_release(psc_i2s->playback.bcom_task);
844 850
diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c
index 94f89debde1f..bcec3f60bad9 100644
--- a/sound/soc/fsl/mpc8610_hpcd.c
+++ b/sound/soc/fsl/mpc8610_hpcd.c
@@ -29,7 +29,7 @@
29struct mpc8610_hpcd_data { 29struct mpc8610_hpcd_data {
30 struct snd_soc_device sound_devdata; 30 struct snd_soc_device sound_devdata;
31 struct snd_soc_dai_link dai; 31 struct snd_soc_dai_link dai;
32 struct snd_soc_machine machine; 32 struct snd_soc_card machine;
33 unsigned int dai_format; 33 unsigned int dai_format;
34 unsigned int codec_clk_direction; 34 unsigned int codec_clk_direction;
35 unsigned int cpu_clk_direction; 35 unsigned int cpu_clk_direction;
@@ -185,7 +185,7 @@ static struct snd_soc_ops mpc8610_hpcd_ops = {
185/** 185/**
186 * mpc8610_hpcd_machine: ASoC machine data 186 * mpc8610_hpcd_machine: ASoC machine data
187 */ 187 */
188static struct snd_soc_machine mpc8610_hpcd_machine = { 188static struct snd_soc_card mpc8610_hpcd_machine = {
189 .probe = mpc8610_hpcd_machine_probe, 189 .probe = mpc8610_hpcd_machine_probe,
190 .remove = mpc8610_hpcd_machine_remove, 190 .remove = mpc8610_hpcd_machine_remove,
191 .name = "MPC8610 HPCD", 191 .name = "MPC8610 HPCD",
@@ -465,9 +465,9 @@ static int mpc8610_hpcd_probe(struct of_device *ofdev,
465 goto error; 465 goto error;
466 } 466 }
467 467
468 machine_data->sound_devdata.machine = &mpc8610_hpcd_machine; 468 machine_data->sound_devdata.card = &mpc8610_hpcd_machine;
469 machine_data->sound_devdata.codec_dev = &soc_codec_device_cs4270; 469 machine_data->sound_devdata.codec_dev = &soc_codec_device_cs4270;
470 machine_data->sound_devdata.platform = &fsl_soc_platform; 470 machine_data->machine.platform = &fsl_soc_platform;
471 471
472 sound_device->dev.platform_data = machine_data; 472 sound_device->dev.platform_data = machine_data;
473 473
diff --git a/sound/soc/fsl/soc-of-simple.c b/sound/soc/fsl/soc-of-simple.c
index 0382fdac51cd..8bc5cd9e972f 100644
--- a/sound/soc/fsl/soc-of-simple.c
+++ b/sound/soc/fsl/soc-of-simple.c
@@ -31,7 +31,7 @@ struct of_snd_soc_device {
31 int id; 31 int id;
32 struct list_head list; 32 struct list_head list;
33 struct snd_soc_device device; 33 struct snd_soc_device device;
34 struct snd_soc_machine machine; 34 struct snd_soc_card card;
35 struct snd_soc_dai_link dai_link; 35 struct snd_soc_dai_link dai_link;
36 struct platform_device *pdev; 36 struct platform_device *pdev;
37 struct device_node *platform_node; 37 struct device_node *platform_node;
@@ -58,9 +58,9 @@ of_snd_soc_get_device(struct device_node *codec_node)
58 /* Initialize the structure and add it to the global list */ 58 /* Initialize the structure and add it to the global list */
59 of_soc->codec_node = codec_node; 59 of_soc->codec_node = codec_node;
60 of_soc->id = of_snd_soc_next_index++; 60 of_soc->id = of_snd_soc_next_index++;
61 of_soc->machine.dai_link = &of_soc->dai_link; 61 of_soc->card.dai_link = &of_soc->dai_link;
62 of_soc->machine.num_links = 1; 62 of_soc->card.num_links = 1;
63 of_soc->device.machine = &of_soc->machine; 63 of_soc->device.card = &of_soc->card;
64 of_soc->dai_link.ops = &of_snd_soc_ops; 64 of_soc->dai_link.ops = &of_snd_soc_ops;
65 list_add(&of_soc->list, &of_snd_soc_device_list); 65 list_add(&of_soc->list, &of_snd_soc_device_list);
66 66
@@ -158,8 +158,8 @@ int of_snd_soc_register_platform(struct snd_soc_platform *platform,
158 158
159 of_soc->platform_node = node; 159 of_soc->platform_node = node;
160 of_soc->dai_link.cpu_dai = cpu_dai; 160 of_soc->dai_link.cpu_dai = cpu_dai;
161 of_soc->device.platform = platform; 161 of_soc->card.platform = platform;
162 of_soc->machine.name = of_soc->dai_link.cpu_dai->name; 162 of_soc->card.name = of_soc->dai_link.cpu_dai->name;
163 163
164 /* Now try to register the SoC device */ 164 /* Now try to register the SoC device */
165 of_snd_soc_register_device(of_soc); 165 of_snd_soc_register_device(of_soc);
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
index 8b7766b998d7..a7b1d77b2105 100644
--- a/sound/soc/omap/Kconfig
+++ b/sound/soc/omap/Kconfig
@@ -1,6 +1,6 @@
1config SND_OMAP_SOC 1config SND_OMAP_SOC
2 tristate "SoC Audio for the Texas Instruments OMAP chips" 2 tristate "SoC Audio for the Texas Instruments OMAP chips"
3 depends on ARCH_OMAP && SND_SOC 3 depends on ARCH_OMAP
4 4
5config SND_OMAP_SOC_MCBSP 5config SND_OMAP_SOC_MCBSP
6 tristate 6 tristate
@@ -21,3 +21,36 @@ config SND_OMAP_SOC_OSK5912
21 select SND_SOC_TLV320AIC23 21 select SND_SOC_TLV320AIC23
22 help 22 help
23 Say Y if you want to add support for SoC audio on osk5912. 23 Say Y if you want to add support for SoC audio on osk5912.
24
25config SND_OMAP_SOC_OVERO
26 tristate "SoC Audio support for Gumstix Overo"
27 depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OVERO
28 select SND_OMAP_SOC_MCBSP
29 select SND_SOC_TWL4030
30 help
31 Say Y if you want to add support for SoC audio on the Gumstix Overo.
32
33config SND_OMAP_SOC_OMAP2EVM
34 tristate "SoC Audio support for OMAP2EVM board"
35 depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP2EVM
36 select SND_OMAP_SOC_MCBSP
37 select SND_SOC_TWL4030
38 help
39 Say Y if you want to add support for SoC audio on the omap2evm board.
40
41config SND_OMAP_SOC_SDP3430
42 tristate "SoC Audio support for Texas Instruments SDP3430"
43 depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP_3430SDP
44 select SND_OMAP_SOC_MCBSP
45 select SND_SOC_TWL4030
46 help
47 Say Y if you want to add support for SoC audio on Texas Instruments
48 SDP3430.
49
50config SND_OMAP_SOC_OMAP3_PANDORA
51 tristate "SoC Audio support for OMAP3 Pandora"
52 depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP3_PANDORA
53 select SND_OMAP_SOC_MCBSP
54 select SND_SOC_TWL4030
55 help
56 Say Y if you want to add support for SoC audio on the OMAP3 Pandora.
diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile
index e09d1f297f64..76fedd96e365 100644
--- a/sound/soc/omap/Makefile
+++ b/sound/soc/omap/Makefile
@@ -8,6 +8,14 @@ obj-$(CONFIG_SND_OMAP_SOC_MCBSP) += snd-soc-omap-mcbsp.o
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 10snd-soc-osk5912-objs := osk5912.o
11snd-soc-overo-objs := overo.o
12snd-soc-omap2evm-objs := omap2evm.o
13snd-soc-sdp3430-objs := sdp3430.o
14snd-soc-omap3pandora-objs := omap3pandora.o
11 15
12obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o 16obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o
13obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o 17obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o
18obj-$(CONFIG_SND_OMAP_SOC_OVERO) += snd-soc-overo.o
19obj-$(CONFIG_MACH_OMAP2EVM) += snd-soc-omap2evm.o
20obj-$(CONFIG_SND_OMAP_SOC_SDP3430) += snd-soc-sdp3430.o
21obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c
index fae3ad36e0bf..25593fee9121 100644
--- a/sound/soc/omap/n810.c
+++ b/sound/soc/omap/n810.c
@@ -70,9 +70,13 @@ static void n810_ext_control(struct snd_soc_codec *codec)
70 70
71static int n810_startup(struct snd_pcm_substream *substream) 71static int n810_startup(struct snd_pcm_substream *substream)
72{ 72{
73 struct snd_pcm_runtime *runtime = substream->runtime;
73 struct snd_soc_pcm_runtime *rtd = substream->private_data; 74 struct snd_soc_pcm_runtime *rtd = substream->private_data;
74 struct snd_soc_codec *codec = rtd->socdev->codec; 75 struct snd_soc_codec *codec = rtd->socdev->codec;
75 76
77 snd_pcm_hw_constraint_minmax(runtime,
78 SNDRV_PCM_HW_PARAM_CHANNELS, 2, 2);
79
76 n810_ext_control(codec); 80 n810_ext_control(codec);
77 return clk_enable(sys_clkout2); 81 return clk_enable(sys_clkout2);
78} 82}
@@ -282,8 +286,9 @@ static struct snd_soc_dai_link n810_dai = {
282}; 286};
283 287
284/* Audio machine driver */ 288/* Audio machine driver */
285static struct snd_soc_machine snd_soc_machine_n810 = { 289static struct snd_soc_card snd_soc_n810 = {
286 .name = "N810", 290 .name = "N810",
291 .platform = &omap_soc_platform,
287 .dai_link = &n810_dai, 292 .dai_link = &n810_dai,
288 .num_links = 1, 293 .num_links = 1,
289}; 294};
@@ -298,8 +303,7 @@ static struct aic3x_setup_data n810_aic33_setup = {
298 303
299/* Audio subsystem */ 304/* Audio subsystem */
300static struct snd_soc_device n810_snd_devdata = { 305static struct snd_soc_device n810_snd_devdata = {
301 .machine = &snd_soc_machine_n810, 306 .card = &snd_soc_n810,
302 .platform = &omap_soc_platform,
303 .codec_dev = &soc_codec_dev_aic3x, 307 .codec_dev = &soc_codec_dev_aic3x,
304 .codec_data = &n810_aic33_setup, 308 .codec_data = &n810_aic33_setup,
305}; 309};
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index 8485a8a9d0ff..ec5e18a78758 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -36,9 +36,7 @@
36#include "omap-mcbsp.h" 36#include "omap-mcbsp.h"
37#include "omap-pcm.h" 37#include "omap-pcm.h"
38 38
39#define OMAP_MCBSP_RATES (SNDRV_PCM_RATE_44100 | \ 39#define OMAP_MCBSP_RATES (SNDRV_PCM_RATE_8000_96000)
40 SNDRV_PCM_RATE_48000 | \
41 SNDRV_PCM_RATE_KNOT)
42 40
43struct omap_mcbsp_data { 41struct omap_mcbsp_data {
44 unsigned int bus_id; 42 unsigned int bus_id;
@@ -140,7 +138,8 @@ static const unsigned long omap34xx_mcbsp_port[][2] = {
140static const unsigned long omap34xx_mcbsp_port[][2] = {}; 138static const unsigned long omap34xx_mcbsp_port[][2] = {};
141#endif 139#endif
142 140
143static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream) 141static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream,
142 struct snd_soc_dai *dai)
144{ 143{
145 struct snd_soc_pcm_runtime *rtd = substream->private_data; 144 struct snd_soc_pcm_runtime *rtd = substream->private_data;
146 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 145 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -153,7 +152,8 @@ static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream)
153 return err; 152 return err;
154} 153}
155 154
156static void omap_mcbsp_dai_shutdown(struct snd_pcm_substream *substream) 155static void omap_mcbsp_dai_shutdown(struct snd_pcm_substream *substream,
156 struct snd_soc_dai *dai)
157{ 157{
158 struct snd_soc_pcm_runtime *rtd = substream->private_data; 158 struct snd_soc_pcm_runtime *rtd = substream->private_data;
159 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 159 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -165,7 +165,8 @@ static void omap_mcbsp_dai_shutdown(struct snd_pcm_substream *substream)
165 } 165 }
166} 166}
167 167
168static int omap_mcbsp_dai_trigger(struct snd_pcm_substream *substream, int cmd) 168static int omap_mcbsp_dai_trigger(struct snd_pcm_substream *substream, int cmd,
169 struct snd_soc_dai *dai)
169{ 170{
170 struct snd_soc_pcm_runtime *rtd = substream->private_data; 171 struct snd_soc_pcm_runtime *rtd = substream->private_data;
171 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 172 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -194,14 +195,15 @@ static int omap_mcbsp_dai_trigger(struct snd_pcm_substream *substream, int cmd)
194} 195}
195 196
196static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, 197static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
197 struct snd_pcm_hw_params *params) 198 struct snd_pcm_hw_params *params,
199 struct snd_soc_dai *dai)
198{ 200{
199 struct snd_soc_pcm_runtime *rtd = substream->private_data; 201 struct snd_soc_pcm_runtime *rtd = substream->private_data;
200 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 202 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
201 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data); 203 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data);
202 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs; 204 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs;
203 int dma, bus_id = mcbsp_data->bus_id, id = cpu_dai->id; 205 int dma, bus_id = mcbsp_data->bus_id, id = cpu_dai->id;
204 int wlen; 206 int wlen, channels;
205 unsigned long port; 207 unsigned long port;
206 208
207 if (cpu_class_is_omap1()) { 209 if (cpu_class_is_omap1()) {
@@ -230,12 +232,17 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
230 return 0; 232 return 0;
231 } 233 }
232 234
233 switch (params_channels(params)) { 235 channels = params_channels(params);
236 switch (channels) {
234 case 2: 237 case 2:
235 /* Set 1 word per (McBPSP) frame and use dual-phase frames */ 238 /* Use dual-phase frames */
236 regs->rcr2 |= RFRLEN2(1 - 1) | RPHASE; 239 regs->rcr2 |= RPHASE;
240 regs->xcr2 |= XPHASE;
241 case 1:
242 /* Set 1 word per (McBSP) frame */
243 regs->rcr2 |= RFRLEN2(1 - 1);
237 regs->rcr1 |= RFRLEN1(1 - 1); 244 regs->rcr1 |= RFRLEN1(1 - 1);
238 regs->xcr2 |= XFRLEN2(1 - 1) | XPHASE; 245 regs->xcr2 |= XFRLEN2(1 - 1);
239 regs->xcr1 |= XFRLEN1(1 - 1); 246 regs->xcr1 |= XFRLEN1(1 - 1);
240 break; 247 break;
241 default: 248 default:
@@ -263,9 +270,9 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
263 regs->srgr2 |= FPER(wlen * 2 - 1); 270 regs->srgr2 |= FPER(wlen * 2 - 1);
264 regs->srgr1 |= FWID(wlen - 1); 271 regs->srgr1 |= FWID(wlen - 1);
265 break; 272 break;
266 case SND_SOC_DAIFMT_DSP_A: 273 case SND_SOC_DAIFMT_DSP_B:
267 regs->srgr2 |= FPER(wlen * 2 - 1); 274 regs->srgr2 |= FPER(wlen * channels - 1);
268 regs->srgr1 |= FWID(wlen * 2 - 2); 275 regs->srgr1 |= FWID(wlen * channels - 2);
269 break; 276 break;
270 } 277 }
271 278
@@ -302,7 +309,7 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
302 regs->rcr2 |= RDATDLY(1); 309 regs->rcr2 |= RDATDLY(1);
303 regs->xcr2 |= XDATDLY(1); 310 regs->xcr2 |= XDATDLY(1);
304 break; 311 break;
305 case SND_SOC_DAIFMT_DSP_A: 312 case SND_SOC_DAIFMT_DSP_B:
306 /* 0-bit data delay */ 313 /* 0-bit data delay */
307 regs->rcr2 |= RDATDLY(0); 314 regs->rcr2 |= RDATDLY(0);
308 regs->xcr2 |= XDATDLY(0); 315 regs->xcr2 |= XDATDLY(0);
@@ -452,17 +459,16 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
452 459
453#define OMAP_MCBSP_DAI_BUILDER(link_id) \ 460#define OMAP_MCBSP_DAI_BUILDER(link_id) \
454{ \ 461{ \
455 .name = "omap-mcbsp-dai-(link_id)", \ 462 .name = "omap-mcbsp-dai-"#link_id, \
456 .id = (link_id), \ 463 .id = (link_id), \
457 .type = SND_SOC_DAI_I2S, \
458 .playback = { \ 464 .playback = { \
459 .channels_min = 2, \ 465 .channels_min = 1, \
460 .channels_max = 2, \ 466 .channels_max = 2, \
461 .rates = OMAP_MCBSP_RATES, \ 467 .rates = OMAP_MCBSP_RATES, \
462 .formats = SNDRV_PCM_FMTBIT_S16_LE, \ 468 .formats = SNDRV_PCM_FMTBIT_S16_LE, \
463 }, \ 469 }, \
464 .capture = { \ 470 .capture = { \
465 .channels_min = 2, \ 471 .channels_min = 1, \
466 .channels_max = 2, \ 472 .channels_max = 2, \
467 .rates = OMAP_MCBSP_RATES, \ 473 .rates = OMAP_MCBSP_RATES, \
468 .formats = SNDRV_PCM_FMTBIT_S16_LE, \ 474 .formats = SNDRV_PCM_FMTBIT_S16_LE, \
@@ -472,8 +478,6 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
472 .shutdown = omap_mcbsp_dai_shutdown, \ 478 .shutdown = omap_mcbsp_dai_shutdown, \
473 .trigger = omap_mcbsp_dai_trigger, \ 479 .trigger = omap_mcbsp_dai_trigger, \
474 .hw_params = omap_mcbsp_dai_hw_params, \ 480 .hw_params = omap_mcbsp_dai_hw_params, \
475 }, \
476 .dai_ops = { \
477 .set_fmt = omap_mcbsp_dai_set_dai_fmt, \ 481 .set_fmt = omap_mcbsp_dai_set_dai_fmt, \
478 .set_clkdiv = omap_mcbsp_dai_set_clkdiv, \ 482 .set_clkdiv = omap_mcbsp_dai_set_clkdiv, \
479 .set_sysclk = omap_mcbsp_dai_set_dai_sysclk, \ 483 .set_sysclk = omap_mcbsp_dai_set_dai_sysclk, \
@@ -495,6 +499,19 @@ struct snd_soc_dai omap_mcbsp_dai[] = {
495 499
496EXPORT_SYMBOL_GPL(omap_mcbsp_dai); 500EXPORT_SYMBOL_GPL(omap_mcbsp_dai);
497 501
502static int __init snd_omap_mcbsp_init(void)
503{
504 return snd_soc_register_dais(omap_mcbsp_dai,
505 ARRAY_SIZE(omap_mcbsp_dai));
506}
507module_init(snd_omap_mcbsp_init);
508
509static void __exit snd_omap_mcbsp_exit(void)
510{
511 snd_soc_unregister_dais(omap_mcbsp_dai, ARRAY_SIZE(omap_mcbsp_dai));
512}
513module_exit(snd_omap_mcbsp_exit);
514
498MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@nokia.com>"); 515MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@nokia.com>");
499MODULE_DESCRIPTION("OMAP I2S SoC Interface"); 516MODULE_DESCRIPTION("OMAP I2S SoC Interface");
500MODULE_LICENSE("GPL"); 517MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c
index acd68efb2b75..b0362dfd5b71 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 (!err & !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
@@ -354,6 +354,18 @@ struct snd_soc_platform omap_soc_platform = {
354}; 354};
355EXPORT_SYMBOL_GPL(omap_soc_platform); 355EXPORT_SYMBOL_GPL(omap_soc_platform);
356 356
357static int __init omap_soc_platform_init(void)
358{
359 return snd_soc_register_platform(&omap_soc_platform);
360}
361module_init(omap_soc_platform_init);
362
363static void __exit omap_soc_platform_exit(void)
364{
365 snd_soc_unregister_platform(&omap_soc_platform);
366}
367module_exit(omap_soc_platform_exit);
368
357MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@nokia.com>"); 369MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@nokia.com>");
358MODULE_DESCRIPTION("OMAP PCM DMA module"); 370MODULE_DESCRIPTION("OMAP PCM DMA module");
359MODULE_LICENSE("GPL"); 371MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/omap2evm.c b/sound/soc/omap/omap2evm.c
new file mode 100644
index 000000000000..0c2322dcf02a
--- /dev/null
+++ b/sound/soc/omap/omap2evm.c
@@ -0,0 +1,151 @@
1/*
2 * omap2evm.c -- SoC audio machine driver for omap2evm board
3 *
4 * Author: Arun KS <arunks@mistralsolutions.com>
5 *
6 * Based on sound/soc/omap/overo.c by Steve Sakoman
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 <mach/gpio.h>
34#include <mach/mcbsp.h>
35
36#include "omap-mcbsp.h"
37#include "omap-pcm.h"
38#include "../codecs/twl4030.h"
39
40static int omap2evm_hw_params(struct snd_pcm_substream *substream,
41 struct snd_pcm_hw_params *params,
42 struct snd_soc_dai *dai)
43{
44 struct snd_soc_pcm_runtime *rtd = substream->private_data;
45 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
46 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
47 int ret;
48
49 /* Set codec DAI configuration */
50 ret = snd_soc_dai_set_fmt(codec_dai,
51 SND_SOC_DAIFMT_I2S |
52 SND_SOC_DAIFMT_NB_NF |
53 SND_SOC_DAIFMT_CBM_CFM);
54 if (ret < 0) {
55 printk(KERN_ERR "can't set codec DAI configuration\n");
56 return ret;
57 }
58
59 /* Set cpu DAI configuration */
60 ret = snd_soc_dai_set_fmt(cpu_dai,
61 SND_SOC_DAIFMT_I2S |
62 SND_SOC_DAIFMT_NB_NF |
63 SND_SOC_DAIFMT_CBM_CFM);
64 if (ret < 0) {
65 printk(KERN_ERR "can't set cpu DAI configuration\n");
66 return ret;
67 }
68
69 /* Set the codec system clock for DAC and ADC */
70 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
71 SND_SOC_CLOCK_IN);
72 if (ret < 0) {
73 printk(KERN_ERR "can't set codec system clock\n");
74 return ret;
75 }
76
77 return 0;
78}
79
80static struct snd_soc_ops omap2evm_ops = {
81 .hw_params = omap2evm_hw_params,
82};
83
84/* Digital audio interface glue - connects codec <--> CPU */
85static struct snd_soc_dai_link omap2evm_dai = {
86 .name = "TWL4030",
87 .stream_name = "TWL4030",
88 .cpu_dai = &omap_mcbsp_dai[0],
89 .codec_dai = &twl4030_dai,
90 .ops = &omap2evm_ops,
91};
92
93/* Audio machine driver */
94static struct snd_soc_card snd_soc_omap2evm = {
95 .name = "omap2evm",
96 .platform = &omap_soc_platform,
97 .dai_link = &omap2evm_dai,
98 .num_links = 1,
99};
100
101/* Audio subsystem */
102static struct snd_soc_device omap2evm_snd_devdata = {
103 .card = &snd_soc_omap2evm,
104 .codec_dev = &soc_codec_dev_twl4030,
105};
106
107static struct platform_device *omap2evm_snd_device;
108
109static int __init omap2evm_soc_init(void)
110{
111 int ret;
112
113 if (!machine_is_omap2evm()) {
114 pr_debug("Not omap2evm!\n");
115 return -ENODEV;
116 }
117 printk(KERN_INFO "omap2evm SoC init\n");
118
119 omap2evm_snd_device = platform_device_alloc("soc-audio", -1);
120 if (!omap2evm_snd_device) {
121 printk(KERN_ERR "Platform device allocation failed\n");
122 return -ENOMEM;
123 }
124
125 platform_set_drvdata(omap2evm_snd_device, &omap2evm_snd_devdata);
126 omap2evm_snd_devdata.dev = &omap2evm_snd_device->dev;
127 *(unsigned int *)omap2evm_dai.cpu_dai->private_data = 1; /* McBSP2 */
128
129 ret = platform_device_add(omap2evm_snd_device);
130 if (ret)
131 goto err1;
132
133 return 0;
134
135err1:
136 printk(KERN_ERR "Unable to add platform device\n");
137 platform_device_put(omap2evm_snd_device);
138
139 return ret;
140}
141module_init(omap2evm_soc_init);
142
143static void __exit omap2evm_soc_exit(void)
144{
145 platform_device_unregister(omap2evm_snd_device);
146}
147module_exit(omap2evm_soc_exit);
148
149MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>");
150MODULE_DESCRIPTION("ALSA SoC omap2evm");
151MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/omap3beagle.c b/sound/soc/omap/omap3beagle.c
new file mode 100644
index 000000000000..fd24a4acd2f5
--- /dev/null
+++ b/sound/soc/omap/omap3beagle.c
@@ -0,0 +1,149 @@
1/*
2 * omap3beagle.c -- SoC audio for OMAP3 Beagle
3 *
4 * Author: Steve Sakoman <steve@sakoman.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21
22#include <linux/clk.h>
23#include <linux/platform_device.h>
24#include <sound/core.h>
25#include <sound/pcm.h>
26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28
29#include <asm/mach-types.h>
30#include <mach/hardware.h>
31#include <mach/gpio.h>
32#include <mach/mcbsp.h>
33
34#include "omap-mcbsp.h"
35#include "omap-pcm.h"
36#include "../codecs/twl4030.h"
37
38static int omap3beagle_hw_params(struct snd_pcm_substream *substream,
39 struct snd_pcm_hw_params *params)
40{
41 struct snd_soc_pcm_runtime *rtd = substream->private_data;
42 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
43 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
44 int ret;
45
46 /* Set codec DAI configuration */
47 ret = snd_soc_dai_set_fmt(codec_dai,
48 SND_SOC_DAIFMT_I2S |
49 SND_SOC_DAIFMT_NB_NF |
50 SND_SOC_DAIFMT_CBM_CFM);
51 if (ret < 0) {
52 printk(KERN_ERR "can't set codec DAI configuration\n");
53 return ret;
54 }
55
56 /* Set cpu DAI configuration */
57 ret = snd_soc_dai_set_fmt(cpu_dai,
58 SND_SOC_DAIFMT_I2S |
59 SND_SOC_DAIFMT_NB_NF |
60 SND_SOC_DAIFMT_CBM_CFM);
61 if (ret < 0) {
62 printk(KERN_ERR "can't set cpu DAI configuration\n");
63 return ret;
64 }
65
66 /* Set the codec system clock for DAC and ADC */
67 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
68 SND_SOC_CLOCK_IN);
69 if (ret < 0) {
70 printk(KERN_ERR "can't set codec system clock\n");
71 return ret;
72 }
73
74 return 0;
75}
76
77static struct snd_soc_ops omap3beagle_ops = {
78 .hw_params = omap3beagle_hw_params,
79};
80
81/* Digital audio interface glue - connects codec <--> CPU */
82static struct snd_soc_dai_link omap3beagle_dai = {
83 .name = "TWL4030",
84 .stream_name = "TWL4030",
85 .cpu_dai = &omap_mcbsp_dai[0],
86 .codec_dai = &twl4030_dai,
87 .ops = &omap3beagle_ops,
88};
89
90/* Audio machine driver */
91static struct snd_soc_card snd_soc_omap3beagle = {
92 .name = "omap3beagle",
93 .platform = &omap_soc_platform,
94 .dai_link = &omap3beagle_dai,
95 .num_links = 1,
96};
97
98/* Audio subsystem */
99static struct snd_soc_device omap3beagle_snd_devdata = {
100 .card = &snd_soc_omap3beagle,
101 .codec_dev = &soc_codec_dev_twl4030,
102};
103
104static struct platform_device *omap3beagle_snd_device;
105
106static int __init omap3beagle_soc_init(void)
107{
108 int ret;
109
110 if (!machine_is_omap3_beagle()) {
111 pr_debug("Not OMAP3 Beagle!\n");
112 return -ENODEV;
113 }
114 pr_info("OMAP3 Beagle SoC init\n");
115
116 omap3beagle_snd_device = platform_device_alloc("soc-audio", -1);
117 if (!omap3beagle_snd_device) {
118 printk(KERN_ERR "Platform device allocation failed\n");
119 return -ENOMEM;
120 }
121
122 platform_set_drvdata(omap3beagle_snd_device, &omap3beagle_snd_devdata);
123 omap3beagle_snd_devdata.dev = &omap3beagle_snd_device->dev;
124 *(unsigned int *)omap3beagle_dai.cpu_dai->private_data = 1; /* McBSP2 */
125
126 ret = platform_device_add(omap3beagle_snd_device);
127 if (ret)
128 goto err1;
129
130 return 0;
131
132err1:
133 printk(KERN_ERR "Unable to add platform device\n");
134 platform_device_put(omap3beagle_snd_device);
135
136 return ret;
137}
138
139static void __exit omap3beagle_soc_exit(void)
140{
141 platform_device_unregister(omap3beagle_snd_device);
142}
143
144module_init(omap3beagle_soc_init);
145module_exit(omap3beagle_soc_exit);
146
147MODULE_AUTHOR("Steve Sakoman <steve@sakoman.com>");
148MODULE_DESCRIPTION("ALSA SoC OMAP3 Beagle");
149MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c
new file mode 100644
index 000000000000..bd91594496b1
--- /dev/null
+++ b/sound/soc/omap/omap3pandora.c
@@ -0,0 +1,311 @@
1/*
2 * omap3pandora.c -- SoC audio for Pandora Handheld Console
3 *
4 * Author: Gražvydas Ignotas <notasas@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21
22#include <linux/clk.h>
23#include <linux/platform_device.h>
24#include <linux/gpio.h>
25#include <linux/delay.h>
26
27#include <sound/core.h>
28#include <sound/pcm.h>
29#include <sound/soc.h>
30#include <sound/soc-dapm.h>
31
32#include <asm/mach-types.h>
33
34#include "omap-mcbsp.h"
35#include "omap-pcm.h"
36#include "../codecs/twl4030.h"
37
38#define OMAP3_PANDORA_DAC_POWER_GPIO 118
39#define OMAP3_PANDORA_AMP_POWER_GPIO 14
40
41#define PREFIX "ASoC omap3pandora: "
42
43static int omap3pandora_cmn_hw_params(struct snd_soc_dai *codec_dai,
44 struct snd_soc_dai *cpu_dai, unsigned int fmt)
45{
46 int ret;
47
48 /* Set codec DAI configuration */
49 ret = snd_soc_dai_set_fmt(codec_dai, fmt);
50 if (ret < 0) {
51 pr_err(PREFIX "can't set codec DAI configuration\n");
52 return ret;
53 }
54
55 /* Set cpu DAI configuration */
56 ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
57 if (ret < 0) {
58 pr_err(PREFIX "can't set cpu DAI configuration\n");
59 return ret;
60 }
61
62 /* Set the codec system clock for DAC and ADC */
63 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
64 SND_SOC_CLOCK_IN);
65 if (ret < 0) {
66 pr_err(PREFIX "can't set codec system clock\n");
67 return ret;
68 }
69
70 /* Set McBSP clock to external */
71 ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_SYSCLK_CLKS_EXT, 0,
72 SND_SOC_CLOCK_IN);
73 if (ret < 0) {
74 pr_err(PREFIX "can't set cpu system clock\n");
75 return ret;
76 }
77
78 ret = snd_soc_dai_set_clkdiv(cpu_dai, OMAP_MCBSP_CLKGDV, 8);
79 if (ret < 0) {
80 pr_err(PREFIX "can't set SRG clock divider\n");
81 return ret;
82 }
83
84 return 0;
85}
86
87static int omap3pandora_out_hw_params(struct snd_pcm_substream *substream,
88 struct snd_pcm_hw_params *params)
89{
90 struct snd_soc_pcm_runtime *rtd = substream->private_data;
91 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
92 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
93
94 return omap3pandora_cmn_hw_params(codec_dai, cpu_dai,
95 SND_SOC_DAIFMT_I2S |
96 SND_SOC_DAIFMT_IB_NF |
97 SND_SOC_DAIFMT_CBS_CFS);
98}
99
100static int omap3pandora_in_hw_params(struct snd_pcm_substream *substream,
101 struct snd_pcm_hw_params *params)
102{
103 struct snd_soc_pcm_runtime *rtd = substream->private_data;
104 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
105 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
106
107 return omap3pandora_cmn_hw_params(codec_dai, cpu_dai,
108 SND_SOC_DAIFMT_I2S |
109 SND_SOC_DAIFMT_NB_NF |
110 SND_SOC_DAIFMT_CBS_CFS);
111}
112
113static int omap3pandora_hp_event(struct snd_soc_dapm_widget *w,
114 struct snd_kcontrol *k, int event)
115{
116 if (SND_SOC_DAPM_EVENT_ON(event)) {
117 gpio_set_value(OMAP3_PANDORA_DAC_POWER_GPIO, 1);
118 gpio_set_value(OMAP3_PANDORA_AMP_POWER_GPIO, 1);
119 } else {
120 gpio_set_value(OMAP3_PANDORA_AMP_POWER_GPIO, 0);
121 mdelay(1);
122 gpio_set_value(OMAP3_PANDORA_DAC_POWER_GPIO, 0);
123 }
124
125 return 0;
126}
127
128/*
129 * Audio paths on Pandora board:
130 *
131 * |O| ---> PCM DAC +-> AMP -> Headphone Jack
132 * |M| A +--------> Line Out
133 * |A| <~~clk~~+
134 * |P| <--- TWL4030 <--------- Line In and MICs
135 */
136static const struct snd_soc_dapm_widget omap3pandora_out_dapm_widgets[] = {
137 SND_SOC_DAPM_DAC("PCM DAC", "Playback", SND_SOC_NOPM, 0, 0),
138 SND_SOC_DAPM_PGA_E("Headphone Amplifier", SND_SOC_NOPM,
139 0, 0, NULL, 0, omap3pandora_hp_event,
140 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
141 SND_SOC_DAPM_HP("Headphone Jack", NULL),
142 SND_SOC_DAPM_LINE("Line Out", NULL),
143};
144
145static const struct snd_soc_dapm_widget omap3pandora_in_dapm_widgets[] = {
146 SND_SOC_DAPM_MIC("Mic (Internal)", NULL),
147 SND_SOC_DAPM_MIC("Mic (external)", NULL),
148 SND_SOC_DAPM_LINE("Line In", NULL),
149};
150
151static const struct snd_soc_dapm_route omap3pandora_out_map[] = {
152 {"Headphone Amplifier", NULL, "PCM DAC"},
153 {"Line Out", NULL, "PCM DAC"},
154 {"Headphone Jack", NULL, "Headphone Amplifier"},
155};
156
157static const struct snd_soc_dapm_route omap3pandora_in_map[] = {
158 {"INL", NULL, "Line In"},
159 {"INR", NULL, "Line In"},
160 {"INL", NULL, "Mic (Internal)"},
161 {"INR", NULL, "Mic (external)"},
162};
163
164static int omap3pandora_out_init(struct snd_soc_codec *codec)
165{
166 int ret;
167
168 ret = snd_soc_dapm_new_controls(codec, omap3pandora_out_dapm_widgets,
169 ARRAY_SIZE(omap3pandora_out_dapm_widgets));
170 if (ret < 0)
171 return ret;
172
173 snd_soc_dapm_add_routes(codec, omap3pandora_out_map,
174 ARRAY_SIZE(omap3pandora_out_map));
175
176 return snd_soc_dapm_sync(codec);
177}
178
179static int omap3pandora_in_init(struct snd_soc_codec *codec)
180{
181 int ret;
182
183 ret = snd_soc_dapm_new_controls(codec, omap3pandora_in_dapm_widgets,
184 ARRAY_SIZE(omap3pandora_in_dapm_widgets));
185 if (ret < 0)
186 return ret;
187
188 snd_soc_dapm_add_routes(codec, omap3pandora_in_map,
189 ARRAY_SIZE(omap3pandora_in_map));
190
191 return snd_soc_dapm_sync(codec);
192}
193
194static struct snd_soc_ops omap3pandora_out_ops = {
195 .hw_params = omap3pandora_out_hw_params,
196};
197
198static struct snd_soc_ops omap3pandora_in_ops = {
199 .hw_params = omap3pandora_in_hw_params,
200};
201
202/* Digital audio interface glue - connects codec <--> CPU */
203static struct snd_soc_dai_link omap3pandora_dai[] = {
204 {
205 .name = "PCM1773",
206 .stream_name = "HiFi Out",
207 .cpu_dai = &omap_mcbsp_dai[0],
208 .codec_dai = &twl4030_dai,
209 .ops = &omap3pandora_out_ops,
210 .init = omap3pandora_out_init,
211 }, {
212 .name = "TWL4030",
213 .stream_name = "Line/Mic In",
214 .cpu_dai = &omap_mcbsp_dai[1],
215 .codec_dai = &twl4030_dai,
216 .ops = &omap3pandora_in_ops,
217 .init = omap3pandora_in_init,
218 }
219};
220
221/* SoC card */
222static struct snd_soc_card snd_soc_card_omap3pandora = {
223 .name = "omap3pandora",
224 .platform = &omap_soc_platform,
225 .dai_link = omap3pandora_dai,
226 .num_links = ARRAY_SIZE(omap3pandora_dai),
227};
228
229/* Audio subsystem */
230static struct snd_soc_device omap3pandora_snd_data = {
231 .card = &snd_soc_card_omap3pandora,
232 .codec_dev = &soc_codec_dev_twl4030,
233};
234
235static struct platform_device *omap3pandora_snd_device;
236
237static int __init omap3pandora_soc_init(void)
238{
239 int ret;
240
241 if (!machine_is_omap3_pandora()) {
242 pr_debug(PREFIX "Not OMAP3 Pandora\n");
243 return -ENODEV;
244 }
245 pr_info("OMAP3 Pandora SoC init\n");
246
247 ret = gpio_request(OMAP3_PANDORA_DAC_POWER_GPIO, "dac_power");
248 if (ret) {
249 pr_err(PREFIX "Failed to get DAC power GPIO\n");
250 return ret;
251 }
252
253 ret = gpio_direction_output(OMAP3_PANDORA_DAC_POWER_GPIO, 0);
254 if (ret) {
255 pr_err(PREFIX "Failed to set DAC power GPIO direction\n");
256 goto fail0;
257 }
258
259 ret = gpio_request(OMAP3_PANDORA_AMP_POWER_GPIO, "amp_power");
260 if (ret) {
261 pr_err(PREFIX "Failed to get amp power GPIO\n");
262 goto fail0;
263 }
264
265 ret = gpio_direction_output(OMAP3_PANDORA_AMP_POWER_GPIO, 0);
266 if (ret) {
267 pr_err(PREFIX "Failed to set amp power GPIO direction\n");
268 goto fail1;
269 }
270
271 omap3pandora_snd_device = platform_device_alloc("soc-audio", -1);
272 if (omap3pandora_snd_device == NULL) {
273 pr_err(PREFIX "Platform device allocation failed\n");
274 ret = -ENOMEM;
275 goto fail1;
276 }
277
278 platform_set_drvdata(omap3pandora_snd_device, &omap3pandora_snd_data);
279 omap3pandora_snd_data.dev = &omap3pandora_snd_device->dev;
280 *(unsigned int *)omap_mcbsp_dai[0].private_data = 1; /* McBSP2 */
281 *(unsigned int *)omap_mcbsp_dai[1].private_data = 3; /* McBSP4 */
282
283 ret = platform_device_add(omap3pandora_snd_device);
284 if (ret) {
285 pr_err(PREFIX "Unable to add platform device\n");
286 goto fail2;
287 }
288
289 return 0;
290
291fail2:
292 platform_device_put(omap3pandora_snd_device);
293fail1:
294 gpio_free(OMAP3_PANDORA_AMP_POWER_GPIO);
295fail0:
296 gpio_free(OMAP3_PANDORA_DAC_POWER_GPIO);
297 return ret;
298}
299module_init(omap3pandora_soc_init);
300
301static void __exit omap3pandora_soc_exit(void)
302{
303 platform_device_unregister(omap3pandora_snd_device);
304 gpio_free(OMAP3_PANDORA_AMP_POWER_GPIO);
305 gpio_free(OMAP3_PANDORA_DAC_POWER_GPIO);
306}
307module_exit(omap3pandora_soc_exit);
308
309MODULE_AUTHOR("Grazvydas Ignotas <notasas@gmail.com>");
310MODULE_DESCRIPTION("ALSA SoC OMAP3 Pandora");
311MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/osk5912.c b/sound/soc/omap/osk5912.c
index 0fe733796898..cd41a948df7b 100644
--- a/sound/soc/omap/osk5912.c
+++ b/sound/soc/omap/osk5912.c
@@ -61,7 +61,7 @@ static int osk_hw_params(struct snd_pcm_substream *substream,
61 61
62 /* Set codec DAI configuration */ 62 /* Set codec DAI configuration */
63 err = snd_soc_dai_set_fmt(codec_dai, 63 err = snd_soc_dai_set_fmt(codec_dai,
64 SND_SOC_DAIFMT_DSP_A | 64 SND_SOC_DAIFMT_DSP_B |
65 SND_SOC_DAIFMT_NB_IF | 65 SND_SOC_DAIFMT_NB_IF |
66 SND_SOC_DAIFMT_CBM_CFM); 66 SND_SOC_DAIFMT_CBM_CFM);
67 if (err < 0) { 67 if (err < 0) {
@@ -71,7 +71,7 @@ static int osk_hw_params(struct snd_pcm_substream *substream,
71 71
72 /* Set cpu DAI configuration */ 72 /* Set cpu DAI configuration */
73 err = snd_soc_dai_set_fmt(cpu_dai, 73 err = snd_soc_dai_set_fmt(cpu_dai,
74 SND_SOC_DAIFMT_DSP_A | 74 SND_SOC_DAIFMT_DSP_B |
75 SND_SOC_DAIFMT_NB_IF | 75 SND_SOC_DAIFMT_NB_IF |
76 SND_SOC_DAIFMT_CBM_CFM); 76 SND_SOC_DAIFMT_CBM_CFM);
77 if (err < 0) { 77 if (err < 0) {
@@ -143,16 +143,16 @@ static struct snd_soc_dai_link osk_dai = {
143}; 143};
144 144
145/* Audio machine driver */ 145/* Audio machine driver */
146static struct snd_soc_machine snd_soc_machine_osk = { 146static struct snd_soc_card snd_soc_card_osk = {
147 .name = "OSK5912", 147 .name = "OSK5912",
148 .platform = &omap_soc_platform,
148 .dai_link = &osk_dai, 149 .dai_link = &osk_dai,
149 .num_links = 1, 150 .num_links = 1,
150}; 151};
151 152
152/* Audio subsystem */ 153/* Audio subsystem */
153static struct snd_soc_device osk_snd_devdata = { 154static struct snd_soc_device osk_snd_devdata = {
154 .machine = &snd_soc_machine_osk, 155 .card = &snd_soc_card_osk,
155 .platform = &omap_soc_platform,
156 .codec_dev = &soc_codec_dev_tlv320aic23, 156 .codec_dev = &soc_codec_dev_tlv320aic23,
157}; 157};
158 158
diff --git a/sound/soc/omap/overo.c b/sound/soc/omap/overo.c
new file mode 100644
index 000000000000..a72dc4e159e5
--- /dev/null
+++ b/sound/soc/omap/overo.c
@@ -0,0 +1,148 @@
1/*
2 * overo.c -- SoC audio for Gumstix Overo
3 *
4 * Author: Steve Sakoman <steve@sakoman.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21
22#include <linux/clk.h>
23#include <linux/platform_device.h>
24#include <sound/core.h>
25#include <sound/pcm.h>
26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28
29#include <asm/mach-types.h>
30#include <mach/hardware.h>
31#include <mach/gpio.h>
32#include <mach/mcbsp.h>
33
34#include "omap-mcbsp.h"
35#include "omap-pcm.h"
36#include "../codecs/twl4030.h"
37
38static int overo_hw_params(struct snd_pcm_substream *substream,
39 struct snd_pcm_hw_params *params)
40{
41 struct snd_soc_pcm_runtime *rtd = substream->private_data;
42 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
43 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
44 int ret;
45
46 /* Set codec DAI configuration */
47 ret = snd_soc_dai_set_fmt(codec_dai,
48 SND_SOC_DAIFMT_I2S |
49 SND_SOC_DAIFMT_NB_NF |
50 SND_SOC_DAIFMT_CBM_CFM);
51 if (ret < 0) {
52 printk(KERN_ERR "can't set codec DAI configuration\n");
53 return ret;
54 }
55
56 /* Set cpu DAI configuration */
57 ret = snd_soc_dai_set_fmt(cpu_dai,
58 SND_SOC_DAIFMT_I2S |
59 SND_SOC_DAIFMT_NB_NF |
60 SND_SOC_DAIFMT_CBM_CFM);
61 if (ret < 0) {
62 printk(KERN_ERR "can't set cpu DAI configuration\n");
63 return ret;
64 }
65
66 /* Set the codec system clock for DAC and ADC */
67 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
68 SND_SOC_CLOCK_IN);
69 if (ret < 0) {
70 printk(KERN_ERR "can't set codec system clock\n");
71 return ret;
72 }
73
74 return 0;
75}
76
77static struct snd_soc_ops overo_ops = {
78 .hw_params = overo_hw_params,
79};
80
81/* Digital audio interface glue - connects codec <--> CPU */
82static struct snd_soc_dai_link overo_dai = {
83 .name = "TWL4030",
84 .stream_name = "TWL4030",
85 .cpu_dai = &omap_mcbsp_dai[0],
86 .codec_dai = &twl4030_dai,
87 .ops = &overo_ops,
88};
89
90/* Audio machine driver */
91static struct snd_soc_card snd_soc_card_overo = {
92 .name = "overo",
93 .platform = &omap_soc_platform,
94 .dai_link = &overo_dai,
95 .num_links = 1,
96};
97
98/* Audio subsystem */
99static struct snd_soc_device overo_snd_devdata = {
100 .card = &snd_soc_card_overo,
101 .codec_dev = &soc_codec_dev_twl4030,
102};
103
104static struct platform_device *overo_snd_device;
105
106static int __init overo_soc_init(void)
107{
108 int ret;
109
110 if (!machine_is_overo()) {
111 pr_debug("Not Overo!\n");
112 return -ENODEV;
113 }
114 printk(KERN_INFO "overo SoC init\n");
115
116 overo_snd_device = platform_device_alloc("soc-audio", -1);
117 if (!overo_snd_device) {
118 printk(KERN_ERR "Platform device allocation failed\n");
119 return -ENOMEM;
120 }
121
122 platform_set_drvdata(overo_snd_device, &overo_snd_devdata);
123 overo_snd_devdata.dev = &overo_snd_device->dev;
124 *(unsigned int *)overo_dai.cpu_dai->private_data = 1; /* McBSP2 */
125
126 ret = platform_device_add(overo_snd_device);
127 if (ret)
128 goto err1;
129
130 return 0;
131
132err1:
133 printk(KERN_ERR "Unable to add platform device\n");
134 platform_device_put(overo_snd_device);
135
136 return ret;
137}
138module_init(overo_soc_init);
139
140static void __exit overo_soc_exit(void)
141{
142 platform_device_unregister(overo_snd_device);
143}
144module_exit(overo_soc_exit);
145
146MODULE_AUTHOR("Steve Sakoman <steve@sakoman.com>");
147MODULE_DESCRIPTION("ALSA SoC overo");
148MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/sdp3430.c b/sound/soc/omap/sdp3430.c
new file mode 100644
index 000000000000..ad97836818b1
--- /dev/null
+++ b/sound/soc/omap/sdp3430.c
@@ -0,0 +1,152 @@
1/*
2 * sdp3430.c -- SoC audio for TI OMAP3430 SDP
3 *
4 * Author: Misael Lopez Cruz <x0052729@ti.com>
5 *
6 * Based on:
7 * Author: Steve Sakoman <steve@sakoman.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * version 2 as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * 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., 51 Franklin St, Fifth Floor, Boston, MA
21 * 02110-1301 USA
22 *
23 */
24
25#include <linux/clk.h>
26#include <linux/platform_device.h>
27#include <sound/core.h>
28#include <sound/pcm.h>
29#include <sound/soc.h>
30#include <sound/soc-dapm.h>
31
32#include <asm/mach-types.h>
33#include <mach/hardware.h>
34#include <mach/gpio.h>
35#include <mach/mcbsp.h>
36
37#include "omap-mcbsp.h"
38#include "omap-pcm.h"
39#include "../codecs/twl4030.h"
40
41static int sdp3430_hw_params(struct snd_pcm_substream *substream,
42 struct snd_pcm_hw_params *params)
43{
44 struct snd_soc_pcm_runtime *rtd = substream->private_data;
45 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
46 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
47 int ret;
48
49 /* Set codec DAI configuration */
50 ret = snd_soc_dai_set_fmt(codec_dai,
51 SND_SOC_DAIFMT_I2S |
52 SND_SOC_DAIFMT_NB_NF |
53 SND_SOC_DAIFMT_CBM_CFM);
54 if (ret < 0) {
55 printk(KERN_ERR "can't set codec DAI configuration\n");
56 return ret;
57 }
58
59 /* Set cpu DAI configuration */
60 ret = snd_soc_dai_set_fmt(cpu_dai,
61 SND_SOC_DAIFMT_I2S |
62 SND_SOC_DAIFMT_NB_NF |
63 SND_SOC_DAIFMT_CBM_CFM);
64 if (ret < 0) {
65 printk(KERN_ERR "can't set cpu DAI configuration\n");
66 return ret;
67 }
68
69 /* Set the codec system clock for DAC and ADC */
70 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
71 SND_SOC_CLOCK_IN);
72 if (ret < 0) {
73 printk(KERN_ERR "can't set codec system clock\n");
74 return ret;
75 }
76
77 return 0;
78}
79
80static struct snd_soc_ops sdp3430_ops = {
81 .hw_params = sdp3430_hw_params,
82};
83
84/* Digital audio interface glue - connects codec <--> CPU */
85static struct snd_soc_dai_link sdp3430_dai = {
86 .name = "TWL4030",
87 .stream_name = "TWL4030",
88 .cpu_dai = &omap_mcbsp_dai[0],
89 .codec_dai = &twl4030_dai,
90 .ops = &sdp3430_ops,
91};
92
93/* Audio machine driver */
94static struct snd_soc_machine snd_soc_machine_sdp3430 = {
95 .name = "SDP3430",
96 .platform = &omap_soc_platform,
97 .dai_link = &sdp3430_dai,
98 .num_links = 1,
99};
100
101/* Audio subsystem */
102static struct snd_soc_device sdp3430_snd_devdata = {
103 .machine = &snd_soc_machine_sdp3430,
104 .codec_dev = &soc_codec_dev_twl4030,
105};
106
107static struct platform_device *sdp3430_snd_device;
108
109static int __init sdp3430_soc_init(void)
110{
111 int ret;
112
113 if (!machine_is_omap_3430sdp()) {
114 pr_debug("Not SDP3430!\n");
115 return -ENODEV;
116 }
117 printk(KERN_INFO "SDP3430 SoC init\n");
118
119 sdp3430_snd_device = platform_device_alloc("soc-audio", -1);
120 if (!sdp3430_snd_device) {
121 printk(KERN_ERR "Platform device allocation failed\n");
122 return -ENOMEM;
123 }
124
125 platform_set_drvdata(sdp3430_snd_device, &sdp3430_snd_devdata);
126 sdp3430_snd_devdata.dev = &sdp3430_snd_device->dev;
127 *(unsigned int *)sdp3430_dai.cpu_dai->private_data = 1; /* McBSP2 */
128
129 ret = platform_device_add(sdp3430_snd_device);
130 if (ret)
131 goto err1;
132
133 return 0;
134
135err1:
136 printk(KERN_ERR "Unable to add platform device\n");
137 platform_device_put(sdp3430_snd_device);
138
139 return ret;
140}
141module_init(sdp3430_soc_init);
142
143static void __exit sdp3430_soc_exit(void)
144{
145 platform_device_unregister(sdp3430_snd_device);
146}
147module_exit(sdp3430_soc_exit);
148
149MODULE_AUTHOR("Misael Lopez Cruz <x0052729@ti.com>");
150MODULE_DESCRIPTION("ALSA SoC SDP3430");
151MODULE_LICENSE("GPL");
152
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index f8c1cdd940ac..f82e10699471 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -21,6 +21,9 @@ config SND_PXA2XX_SOC_AC97
21config SND_PXA2XX_SOC_I2S 21config SND_PXA2XX_SOC_I2S
22 tristate 22 tristate
23 23
24config SND_PXA_SOC_SSP
25 tristate
26
24config SND_PXA2XX_SOC_CORGI 27config SND_PXA2XX_SOC_CORGI
25 tristate "SoC Audio support for Sharp Zaurus SL-C7x0" 28 tristate "SoC Audio support for Sharp Zaurus SL-C7x0"
26 depends on SND_PXA2XX_SOC && PXA_SHARP_C7xx 29 depends on SND_PXA2XX_SOC && PXA_SHARP_C7xx
@@ -75,3 +78,22 @@ config SND_PXA2XX_SOC_EM_X270
75 help 78 help
76 Say Y if you want to add support for SoC audio on 79 Say Y if you want to add support for SoC audio on
77 CompuLab EM-x270. 80 CompuLab EM-x270.
81
82config SND_PXA2XX_SOC_PALM27X
83 bool "SoC Audio support for Palm T|X, T5 and LifeDrive"
84 depends on SND_PXA2XX_SOC && (MACH_PALMLD || MACH_PALMTX || MACH_PALMT5)
85 select SND_PXA2XX_SOC_AC97
86 select SND_SOC_WM9712
87 help
88 Say Y if you want to add support for SoC audio on
89 Palm T|X, T5 or LifeDrive handheld computer.
90
91config SND_SOC_ZYLONITE
92 tristate "SoC Audio support for Marvell Zylonite"
93 depends on SND_PXA2XX_SOC && MACH_ZYLONITE
94 select SND_PXA2XX_SOC_AC97
95 select SND_PXA_SOC_SSP
96 select SND_SOC_WM9713
97 help
98 Say Y if you want to add support for SoC audio on the
99 Marvell Zylonite reference platform.
diff --git a/sound/soc/pxa/Makefile b/sound/soc/pxa/Makefile
index 5bc8edf9dca9..08a9f2797729 100644
--- a/sound/soc/pxa/Makefile
+++ b/sound/soc/pxa/Makefile
@@ -2,10 +2,12 @@
2snd-soc-pxa2xx-objs := pxa2xx-pcm.o 2snd-soc-pxa2xx-objs := pxa2xx-pcm.o
3snd-soc-pxa2xx-ac97-objs := pxa2xx-ac97.o 3snd-soc-pxa2xx-ac97-objs := pxa2xx-ac97.o
4snd-soc-pxa2xx-i2s-objs := pxa2xx-i2s.o 4snd-soc-pxa2xx-i2s-objs := pxa2xx-i2s.o
5snd-soc-pxa-ssp-objs := pxa-ssp.o
5 6
6obj-$(CONFIG_SND_PXA2XX_SOC) += snd-soc-pxa2xx.o 7obj-$(CONFIG_SND_PXA2XX_SOC) += snd-soc-pxa2xx.o
7obj-$(CONFIG_SND_PXA2XX_SOC_AC97) += snd-soc-pxa2xx-ac97.o 8obj-$(CONFIG_SND_PXA2XX_SOC_AC97) += snd-soc-pxa2xx-ac97.o
8obj-$(CONFIG_SND_PXA2XX_SOC_I2S) += snd-soc-pxa2xx-i2s.o 9obj-$(CONFIG_SND_PXA2XX_SOC_I2S) += snd-soc-pxa2xx-i2s.o
10obj-$(CONFIG_SND_PXA_SOC_SSP) += snd-soc-pxa-ssp.o
9 11
10# PXA Machine Support 12# PXA Machine Support
11snd-soc-corgi-objs := corgi.o 13snd-soc-corgi-objs := corgi.o
@@ -14,6 +16,8 @@ snd-soc-tosa-objs := tosa.o
14snd-soc-e800-objs := e800_wm9712.o 16snd-soc-e800-objs := e800_wm9712.o
15snd-soc-spitz-objs := spitz.o 17snd-soc-spitz-objs := spitz.o
16snd-soc-em-x270-objs := em-x270.o 18snd-soc-em-x270-objs := em-x270.o
19snd-soc-palm27x-objs := palm27x.o
20snd-soc-zylonite-objs := zylonite.o
17 21
18obj-$(CONFIG_SND_PXA2XX_SOC_CORGI) += snd-soc-corgi.o 22obj-$(CONFIG_SND_PXA2XX_SOC_CORGI) += snd-soc-corgi.o
19obj-$(CONFIG_SND_PXA2XX_SOC_POODLE) += snd-soc-poodle.o 23obj-$(CONFIG_SND_PXA2XX_SOC_POODLE) += snd-soc-poodle.o
@@ -21,3 +25,5 @@ obj-$(CONFIG_SND_PXA2XX_SOC_TOSA) += snd-soc-tosa.o
21obj-$(CONFIG_SND_PXA2XX_SOC_E800) += snd-soc-e800.o 25obj-$(CONFIG_SND_PXA2XX_SOC_E800) += snd-soc-e800.o
22obj-$(CONFIG_SND_PXA2XX_SOC_SPITZ) += snd-soc-spitz.o 26obj-$(CONFIG_SND_PXA2XX_SOC_SPITZ) += snd-soc-spitz.o
23obj-$(CONFIG_SND_PXA2XX_SOC_EM_X270) += snd-soc-em-x270.o 27obj-$(CONFIG_SND_PXA2XX_SOC_EM_X270) += snd-soc-em-x270.o
28obj-$(CONFIG_SND_PXA2XX_SOC_PALM27X) += snd-soc-palm27x.o
29obj-$(CONFIG_SND_SOC_ZYLONITE) += snd-soc-zylonite.o
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c
index 2718eaf7895f..1ba25a559524 100644
--- a/sound/soc/pxa/corgi.c
+++ b/sound/soc/pxa/corgi.c
@@ -108,15 +108,11 @@ static int corgi_startup(struct snd_pcm_substream *substream)
108} 108}
109 109
110/* we need to unmute the HP at shutdown as the mute burns power on corgi */ 110/* we need to unmute the HP at shutdown as the mute burns power on corgi */
111static int corgi_shutdown(struct snd_pcm_substream *substream) 111static void corgi_shutdown(struct snd_pcm_substream *substream)
112{ 112{
113 struct snd_soc_pcm_runtime *rtd = substream->private_data;
114 struct snd_soc_codec *codec = rtd->socdev->codec;
115
116 /* set = unmute headphone */ 113 /* set = unmute headphone */
117 gpio_set_value(CORGI_GPIO_MUTE_L, 1); 114 gpio_set_value(CORGI_GPIO_MUTE_L, 1);
118 gpio_set_value(CORGI_GPIO_MUTE_R, 1); 115 gpio_set_value(CORGI_GPIO_MUTE_R, 1);
119 return 0;
120} 116}
121 117
122static int corgi_hw_params(struct snd_pcm_substream *substream, 118static int corgi_hw_params(struct snd_pcm_substream *substream,
@@ -314,8 +310,9 @@ static struct snd_soc_dai_link corgi_dai = {
314}; 310};
315 311
316/* corgi audio machine driver */ 312/* corgi audio machine driver */
317static struct snd_soc_machine snd_soc_machine_corgi = { 313static struct snd_soc_card snd_soc_corgi = {
318 .name = "Corgi", 314 .name = "Corgi",
315 .platform = &pxa2xx_soc_platform,
319 .dai_link = &corgi_dai, 316 .dai_link = &corgi_dai,
320 .num_links = 1, 317 .num_links = 1,
321}; 318};
@@ -328,8 +325,7 @@ static struct wm8731_setup_data corgi_wm8731_setup = {
328 325
329/* corgi audio subsystem */ 326/* corgi audio subsystem */
330static struct snd_soc_device corgi_snd_devdata = { 327static struct snd_soc_device corgi_snd_devdata = {
331 .machine = &snd_soc_machine_corgi, 328 .card = &snd_soc_corgi,
332 .platform = &pxa2xx_soc_platform,
333 .codec_dev = &soc_codec_dev_wm8731, 329 .codec_dev = &soc_codec_dev_wm8731,
334 .codec_data = &corgi_wm8731_setup, 330 .codec_data = &corgi_wm8731_setup,
335}; 331};
diff --git a/sound/soc/pxa/e800_wm9712.c b/sound/soc/pxa/e800_wm9712.c
index 6781c5be242f..2e3386dfa0f0 100644
--- a/sound/soc/pxa/e800_wm9712.c
+++ b/sound/soc/pxa/e800_wm9712.c
@@ -29,7 +29,7 @@
29#include "pxa2xx-pcm.h" 29#include "pxa2xx-pcm.h"
30#include "pxa2xx-ac97.h" 30#include "pxa2xx-ac97.h"
31 31
32static struct snd_soc_machine e800; 32static struct snd_soc_card e800;
33 33
34static struct snd_soc_dai_link e800_dai[] = { 34static struct snd_soc_dai_link e800_dai[] = {
35{ 35{
@@ -40,15 +40,15 @@ static struct snd_soc_dai_link e800_dai[] = {
40}, 40},
41}; 41};
42 42
43static struct snd_soc_machine e800 = { 43static struct snd_soc_card e800 = {
44 .name = "Toshiba e800", 44 .name = "Toshiba e800",
45 .platform = &pxa2xx_soc_platform,
45 .dai_link = e800_dai, 46 .dai_link = e800_dai,
46 .num_links = ARRAY_SIZE(e800_dai), 47 .num_links = ARRAY_SIZE(e800_dai),
47}; 48};
48 49
49static struct snd_soc_device e800_snd_devdata = { 50static struct snd_soc_device e800_snd_devdata = {
50 .machine = &e800, 51 .card = &e800,
51 .platform = &pxa2xx_soc_platform,
52 .codec_dev = &soc_codec_dev_wm9712, 52 .codec_dev = &soc_codec_dev_wm9712,
53}; 53};
54 54
diff --git a/sound/soc/pxa/em-x270.c b/sound/soc/pxa/em-x270.c
index e6ff6929ab4b..fe4a729ea648 100644
--- a/sound/soc/pxa/em-x270.c
+++ b/sound/soc/pxa/em-x270.c
@@ -23,7 +23,6 @@
23#include <linux/moduleparam.h> 23#include <linux/moduleparam.h>
24#include <linux/device.h> 24#include <linux/device.h>
25 25
26#include <sound/driver.h>
27#include <sound/core.h> 26#include <sound/core.h>
28#include <sound/pcm.h> 27#include <sound/pcm.h>
29#include <sound/soc.h> 28#include <sound/soc.h>
@@ -53,15 +52,15 @@ static struct snd_soc_dai_link em_x270_dai[] = {
53 }, 52 },
54}; 53};
55 54
56static struct snd_soc_machine em_x270 = { 55static struct snd_soc_card em_x270 = {
57 .name = "EM-X270", 56 .name = "EM-X270",
57 .platform = &pxa2xx_soc_platform,
58 .dai_link = em_x270_dai, 58 .dai_link = em_x270_dai,
59 .num_links = ARRAY_SIZE(em_x270_dai), 59 .num_links = ARRAY_SIZE(em_x270_dai),
60}; 60};
61 61
62static struct snd_soc_device em_x270_snd_devdata = { 62static struct snd_soc_device em_x270_snd_devdata = {
63 .machine = &em_x270, 63 .card = &em_x270,
64 .platform = &pxa2xx_soc_platform,
65 .codec_dev = &soc_codec_dev_wm9712, 64 .codec_dev = &soc_codec_dev_wm9712,
66}; 65};
67 66
diff --git a/sound/soc/pxa/palm27x.c b/sound/soc/pxa/palm27x.c
new file mode 100644
index 000000000000..4a9cf3083af0
--- /dev/null
+++ b/sound/soc/pxa/palm27x.c
@@ -0,0 +1,269 @@
1/*
2 * linux/sound/soc/pxa/palm27x.c
3 *
4 * SoC Audio driver for Palm T|X, T5 and LifeDrive
5 *
6 * based on tosa.c
7 *
8 * Copyright (C) 2008 Marek Vasut <marek.vasut@gmail.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 */
15
16#include <linux/module.h>
17#include <linux/moduleparam.h>
18#include <linux/device.h>
19#include <linux/gpio.h>
20#include <linux/interrupt.h>
21#include <linux/irq.h>
22
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/soc.h>
26#include <sound/soc-dapm.h>
27
28#include <asm/mach-types.h>
29#include <mach/audio.h>
30#include <mach/palmasoc.h>
31
32#include "../codecs/wm9712.h"
33#include "pxa2xx-pcm.h"
34#include "pxa2xx-ac97.h"
35
36static int palm27x_jack_func = 1;
37static int palm27x_spk_func = 1;
38static int palm27x_ep_gpio = -1;
39
40static void palm27x_ext_control(struct snd_soc_codec *codec)
41{
42 if (!palm27x_spk_func)
43 snd_soc_dapm_enable_pin(codec, "Speaker");
44 else
45 snd_soc_dapm_disable_pin(codec, "Speaker");
46
47 if (!palm27x_jack_func)
48 snd_soc_dapm_enable_pin(codec, "Headphone Jack");
49 else
50 snd_soc_dapm_disable_pin(codec, "Headphone Jack");
51
52 snd_soc_dapm_sync(codec);
53}
54
55static int palm27x_startup(struct snd_pcm_substream *substream)
56{
57 struct snd_soc_pcm_runtime *rtd = substream->private_data;
58 struct snd_soc_codec *codec = rtd->socdev->codec;
59
60 /* check the jack status at stream startup */
61 palm27x_ext_control(codec);
62 return 0;
63}
64
65static struct snd_soc_ops palm27x_ops = {
66 .startup = palm27x_startup,
67};
68
69static irqreturn_t palm27x_interrupt(int irq, void *v)
70{
71 palm27x_spk_func = gpio_get_value(palm27x_ep_gpio);
72 palm27x_jack_func = !palm27x_spk_func;
73 return IRQ_HANDLED;
74}
75
76static int palm27x_get_jack(struct snd_kcontrol *kcontrol,
77 struct snd_ctl_elem_value *ucontrol)
78{
79 ucontrol->value.integer.value[0] = palm27x_jack_func;
80 return 0;
81}
82
83static int palm27x_set_jack(struct snd_kcontrol *kcontrol,
84 struct snd_ctl_elem_value *ucontrol)
85{
86 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
87
88 if (palm27x_jack_func == ucontrol->value.integer.value[0])
89 return 0;
90
91 palm27x_jack_func = ucontrol->value.integer.value[0];
92 palm27x_ext_control(codec);
93 return 1;
94}
95
96static int palm27x_get_spk(struct snd_kcontrol *kcontrol,
97 struct snd_ctl_elem_value *ucontrol)
98{
99 ucontrol->value.integer.value[0] = palm27x_spk_func;
100 return 0;
101}
102
103static int palm27x_set_spk(struct snd_kcontrol *kcontrol,
104 struct snd_ctl_elem_value *ucontrol)
105{
106 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
107
108 if (palm27x_spk_func == ucontrol->value.integer.value[0])
109 return 0;
110
111 palm27x_spk_func = ucontrol->value.integer.value[0];
112 palm27x_ext_control(codec);
113 return 1;
114}
115
116/* PalmTX machine dapm widgets */
117static const struct snd_soc_dapm_widget palm27x_dapm_widgets[] = {
118 SND_SOC_DAPM_HP("Headphone Jack", NULL),
119 SND_SOC_DAPM_SPK("Speaker", NULL),
120};
121
122/* PalmTX audio map */
123static const struct snd_soc_dapm_route audio_map[] = {
124 /* headphone connected to HPOUTL, HPOUTR */
125 {"Headphone Jack", NULL, "HPOUTL"},
126 {"Headphone Jack", NULL, "HPOUTR"},
127
128 /* ext speaker connected to ROUT2, LOUT2 */
129 {"Speaker", NULL, "LOUT2"},
130 {"Speaker", NULL, "ROUT2"},
131};
132
133static const char *jack_function[] = {"Headphone", "Off"};
134static const char *spk_function[] = {"On", "Off"};
135static const struct soc_enum palm27x_enum[] = {
136 SOC_ENUM_SINGLE_EXT(2, jack_function),
137 SOC_ENUM_SINGLE_EXT(2, spk_function),
138};
139
140static const struct snd_kcontrol_new palm27x_controls[] = {
141 SOC_ENUM_EXT("Jack Function", palm27x_enum[0], palm27x_get_jack,
142 palm27x_set_jack),
143 SOC_ENUM_EXT("Speaker Function", palm27x_enum[1], palm27x_get_spk,
144 palm27x_set_spk),
145};
146
147static int palm27x_ac97_init(struct snd_soc_codec *codec)
148{
149 int i, err;
150
151 snd_soc_dapm_nc_pin(codec, "OUT3");
152 snd_soc_dapm_nc_pin(codec, "MONOOUT");
153
154 /* add palm27x specific controls */
155 for (i = 0; i < ARRAY_SIZE(palm27x_controls); i++) {
156 err = snd_ctl_add(codec->card,
157 snd_soc_cnew(&palm27x_controls[i],
158 codec, NULL));
159 if (err < 0)
160 return err;
161 }
162
163 /* add palm27x specific widgets */
164 snd_soc_dapm_new_controls(codec, palm27x_dapm_widgets,
165 ARRAY_SIZE(palm27x_dapm_widgets));
166
167 /* set up palm27x specific audio path audio_map */
168 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
169
170 snd_soc_dapm_sync(codec);
171 return 0;
172}
173
174static struct snd_soc_dai_link palm27x_dai[] = {
175{
176 .name = "AC97 HiFi",
177 .stream_name = "AC97 HiFi",
178 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI],
179 .codec_dai = &wm9712_dai[WM9712_DAI_AC97_HIFI],
180 .init = palm27x_ac97_init,
181 .ops = &palm27x_ops,
182},
183{
184 .name = "AC97 Aux",
185 .stream_name = "AC97 Aux",
186 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX],
187 .codec_dai = &wm9712_dai[WM9712_DAI_AC97_AUX],
188 .ops = &palm27x_ops,
189},
190};
191
192static struct snd_soc_card palm27x_asoc = {
193 .name = "Palm/PXA27x",
194 .platform = &pxa2xx_soc_platform,
195 .dai_link = palm27x_dai,
196 .num_links = ARRAY_SIZE(palm27x_dai),
197};
198
199static struct snd_soc_device palm27x_snd_devdata = {
200 .card = &palm27x_asoc,
201 .codec_dev = &soc_codec_dev_wm9712,
202};
203
204static struct platform_device *palm27x_snd_device;
205
206static int __init palm27x_asoc_init(void)
207{
208 int ret;
209
210 if (!(machine_is_palmtx() || machine_is_palmt5() ||
211 machine_is_palmld()))
212 return -ENODEV;
213
214 ret = gpio_request(palm27x_ep_gpio, "Headphone Jack");
215 if (ret)
216 return ret;
217 ret = gpio_direction_input(palm27x_ep_gpio);
218 if (ret)
219 goto err_alloc;
220
221 if (request_irq(gpio_to_irq(palm27x_ep_gpio), palm27x_interrupt,
222 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
223 "Headphone jack", NULL))
224 goto err_alloc;
225
226 palm27x_snd_device = platform_device_alloc("soc-audio", -1);
227 if (!palm27x_snd_device) {
228 ret = -ENOMEM;
229 goto err_dev;
230 }
231
232 platform_set_drvdata(palm27x_snd_device, &palm27x_snd_devdata);
233 palm27x_snd_devdata.dev = &palm27x_snd_device->dev;
234 ret = platform_device_add(palm27x_snd_device);
235
236 if (ret != 0)
237 goto put_device;
238
239 return 0;
240
241put_device:
242 platform_device_put(palm27x_snd_device);
243err_dev:
244 free_irq(gpio_to_irq(palm27x_ep_gpio), NULL);
245err_alloc:
246 gpio_free(palm27x_ep_gpio);
247
248 return ret;
249}
250
251static void __exit palm27x_asoc_exit(void)
252{
253 free_irq(gpio_to_irq(palm27x_ep_gpio), NULL);
254 gpio_free(palm27x_ep_gpio);
255 platform_device_unregister(palm27x_snd_device);
256}
257
258void __init palm27x_asoc_set_pdata(struct palm27x_asoc_info *data)
259{
260 palm27x_ep_gpio = data->jack_gpio;
261}
262
263module_init(palm27x_asoc_init);
264module_exit(palm27x_asoc_exit);
265
266/* Module information */
267MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
268MODULE_DESCRIPTION("ALSA SoC Palm T|X, T5 and LifeDrive");
269MODULE_LICENSE("GPL");
diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c
index 4d9930c52789..6e9827189fff 100644
--- a/sound/soc/pxa/poodle.c
+++ b/sound/soc/pxa/poodle.c
@@ -276,8 +276,9 @@ static struct snd_soc_dai_link poodle_dai = {
276}; 276};
277 277
278/* poodle audio machine driver */ 278/* poodle audio machine driver */
279static struct snd_soc_machine snd_soc_machine_poodle = { 279static struct snd_soc_card snd_soc_poodle = {
280 .name = "Poodle", 280 .name = "Poodle",
281 .platform = &pxa2xx_soc_platform,
281 .dai_link = &poodle_dai, 282 .dai_link = &poodle_dai,
282 .num_links = 1, 283 .num_links = 1,
283}; 284};
@@ -290,8 +291,7 @@ static struct wm8731_setup_data poodle_wm8731_setup = {
290 291
291/* poodle audio subsystem */ 292/* poodle audio subsystem */
292static struct snd_soc_device poodle_snd_devdata = { 293static struct snd_soc_device poodle_snd_devdata = {
293 .machine = &snd_soc_machine_poodle, 294 .card = &snd_soc_poodle,
294 .platform = &pxa2xx_soc_platform,
295 .codec_dev = &soc_codec_dev_wm8731, 295 .codec_dev = &soc_codec_dev_wm8731,
296 .codec_data = &poodle_wm8731_setup, 296 .codec_data = &poodle_wm8731_setup,
297}; 297};
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
new file mode 100644
index 000000000000..73cb6b4c2f2d
--- /dev/null
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -0,0 +1,931 @@
1#define DEBUG
2/*
3 * pxa-ssp.c -- ALSA Soc Audio Layer
4 *
5 * Copyright 2005,2008 Wolfson Microelectronics PLC.
6 * Author: Liam Girdwood
7 * Mark Brown <broonie@opensource.wolfsonmicro.com>
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 *
14 * TODO:
15 * o Test network mode for > 16bit sample size
16 */
17
18#include <linux/init.h>
19#include <linux/module.h>
20#include <linux/platform_device.h>
21#include <linux/clk.h>
22#include <linux/io.h>
23
24#include <sound/core.h>
25#include <sound/pcm.h>
26#include <sound/initval.h>
27#include <sound/pcm_params.h>
28#include <sound/soc.h>
29#include <sound/pxa2xx-lib.h>
30
31#include <mach/hardware.h>
32#include <mach/pxa-regs.h>
33#include <mach/regs-ssp.h>
34#include <mach/audio.h>
35#include <mach/ssp.h>
36
37#include "pxa2xx-pcm.h"
38#include "pxa-ssp.h"
39
40/*
41 * SSP audio private data
42 */
43struct ssp_priv {
44 struct ssp_dev dev;
45 unsigned int sysclk;
46 int dai_fmt;
47#ifdef CONFIG_PM
48 struct ssp_state state;
49#endif
50};
51
52#define PXA2xx_SSP1_BASE 0x41000000
53#define PXA27x_SSP2_BASE 0x41700000
54#define PXA27x_SSP3_BASE 0x41900000
55#define PXA3xx_SSP4_BASE 0x41a00000
56
57static struct pxa2xx_pcm_dma_params pxa_ssp1_pcm_mono_out = {
58 .name = "SSP1 PCM Mono out",
59 .dev_addr = PXA2xx_SSP1_BASE + SSDR,
60 .drcmr = &DRCMR(14),
61 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
62 DCMD_BURST16 | DCMD_WIDTH2,
63};
64
65static struct pxa2xx_pcm_dma_params pxa_ssp1_pcm_mono_in = {
66 .name = "SSP1 PCM Mono in",
67 .dev_addr = PXA2xx_SSP1_BASE + SSDR,
68 .drcmr = &DRCMR(13),
69 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
70 DCMD_BURST16 | DCMD_WIDTH2,
71};
72
73static struct pxa2xx_pcm_dma_params pxa_ssp1_pcm_stereo_out = {
74 .name = "SSP1 PCM Stereo out",
75 .dev_addr = PXA2xx_SSP1_BASE + SSDR,
76 .drcmr = &DRCMR(14),
77 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
78 DCMD_BURST16 | DCMD_WIDTH4,
79};
80
81static struct pxa2xx_pcm_dma_params pxa_ssp1_pcm_stereo_in = {
82 .name = "SSP1 PCM Stereo in",
83 .dev_addr = PXA2xx_SSP1_BASE + SSDR,
84 .drcmr = &DRCMR(13),
85 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
86 DCMD_BURST16 | DCMD_WIDTH4,
87};
88
89static struct pxa2xx_pcm_dma_params pxa_ssp2_pcm_mono_out = {
90 .name = "SSP2 PCM Mono out",
91 .dev_addr = PXA27x_SSP2_BASE + SSDR,
92 .drcmr = &DRCMR(16),
93 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
94 DCMD_BURST16 | DCMD_WIDTH2,
95};
96
97static struct pxa2xx_pcm_dma_params pxa_ssp2_pcm_mono_in = {
98 .name = "SSP2 PCM Mono in",
99 .dev_addr = PXA27x_SSP2_BASE + SSDR,
100 .drcmr = &DRCMR(15),
101 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
102 DCMD_BURST16 | DCMD_WIDTH2,
103};
104
105static struct pxa2xx_pcm_dma_params pxa_ssp2_pcm_stereo_out = {
106 .name = "SSP2 PCM Stereo out",
107 .dev_addr = PXA27x_SSP2_BASE + SSDR,
108 .drcmr = &DRCMR(16),
109 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
110 DCMD_BURST16 | DCMD_WIDTH4,
111};
112
113static struct pxa2xx_pcm_dma_params pxa_ssp2_pcm_stereo_in = {
114 .name = "SSP2 PCM Stereo in",
115 .dev_addr = PXA27x_SSP2_BASE + SSDR,
116 .drcmr = &DRCMR(15),
117 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
118 DCMD_BURST16 | DCMD_WIDTH4,
119};
120
121static struct pxa2xx_pcm_dma_params pxa_ssp3_pcm_mono_out = {
122 .name = "SSP3 PCM Mono out",
123 .dev_addr = PXA27x_SSP3_BASE + SSDR,
124 .drcmr = &DRCMR(67),
125 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
126 DCMD_BURST16 | DCMD_WIDTH2,
127};
128
129static struct pxa2xx_pcm_dma_params pxa_ssp3_pcm_mono_in = {
130 .name = "SSP3 PCM Mono in",
131 .dev_addr = PXA27x_SSP3_BASE + SSDR,
132 .drcmr = &DRCMR(66),
133 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
134 DCMD_BURST16 | DCMD_WIDTH2,
135};
136
137static struct pxa2xx_pcm_dma_params pxa_ssp3_pcm_stereo_out = {
138 .name = "SSP3 PCM Stereo out",
139 .dev_addr = PXA27x_SSP3_BASE + SSDR,
140 .drcmr = &DRCMR(67),
141 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
142 DCMD_BURST16 | DCMD_WIDTH4,
143};
144
145static struct pxa2xx_pcm_dma_params pxa_ssp3_pcm_stereo_in = {
146 .name = "SSP3 PCM Stereo in",
147 .dev_addr = PXA27x_SSP3_BASE + SSDR,
148 .drcmr = &DRCMR(66),
149 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
150 DCMD_BURST16 | DCMD_WIDTH4,
151};
152
153static struct pxa2xx_pcm_dma_params pxa_ssp4_pcm_mono_out = {
154 .name = "SSP4 PCM Mono out",
155 .dev_addr = PXA3xx_SSP4_BASE + SSDR,
156 .drcmr = &DRCMR(67),
157 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
158 DCMD_BURST16 | DCMD_WIDTH2,
159};
160
161static struct pxa2xx_pcm_dma_params pxa_ssp4_pcm_mono_in = {
162 .name = "SSP4 PCM Mono in",
163 .dev_addr = PXA3xx_SSP4_BASE + SSDR,
164 .drcmr = &DRCMR(66),
165 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
166 DCMD_BURST16 | DCMD_WIDTH2,
167};
168
169static struct pxa2xx_pcm_dma_params pxa_ssp4_pcm_stereo_out = {
170 .name = "SSP4 PCM Stereo out",
171 .dev_addr = PXA3xx_SSP4_BASE + SSDR,
172 .drcmr = &DRCMR(67),
173 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
174 DCMD_BURST16 | DCMD_WIDTH4,
175};
176
177static struct pxa2xx_pcm_dma_params pxa_ssp4_pcm_stereo_in = {
178 .name = "SSP4 PCM Stereo in",
179 .dev_addr = PXA3xx_SSP4_BASE + SSDR,
180 .drcmr = &DRCMR(66),
181 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
182 DCMD_BURST16 | DCMD_WIDTH4,
183};
184
185static void dump_registers(struct ssp_device *ssp)
186{
187 dev_dbg(&ssp->pdev->dev, "SSCR0 0x%08x SSCR1 0x%08x SSTO 0x%08x\n",
188 ssp_read_reg(ssp, SSCR0), ssp_read_reg(ssp, SSCR1),
189 ssp_read_reg(ssp, SSTO));
190
191 dev_dbg(&ssp->pdev->dev, "SSPSP 0x%08x SSSR 0x%08x SSACD 0x%08x\n",
192 ssp_read_reg(ssp, SSPSP), ssp_read_reg(ssp, SSSR),
193 ssp_read_reg(ssp, SSACD));
194}
195
196static struct pxa2xx_pcm_dma_params *ssp_dma_params[4][4] = {
197 {
198 &pxa_ssp1_pcm_mono_out, &pxa_ssp1_pcm_mono_in,
199 &pxa_ssp1_pcm_stereo_out, &pxa_ssp1_pcm_stereo_in,
200 },
201 {
202 &pxa_ssp2_pcm_mono_out, &pxa_ssp2_pcm_mono_in,
203 &pxa_ssp2_pcm_stereo_out, &pxa_ssp2_pcm_stereo_in,
204 },
205 {
206 &pxa_ssp3_pcm_mono_out, &pxa_ssp3_pcm_mono_in,
207 &pxa_ssp3_pcm_stereo_out, &pxa_ssp3_pcm_stereo_in,
208 },
209 {
210 &pxa_ssp4_pcm_mono_out, &pxa_ssp4_pcm_mono_in,
211 &pxa_ssp4_pcm_stereo_out, &pxa_ssp4_pcm_stereo_in,
212 },
213};
214
215static int pxa_ssp_startup(struct snd_pcm_substream *substream,
216 struct snd_soc_dai *dai)
217{
218 struct snd_soc_pcm_runtime *rtd = substream->private_data;
219 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
220 struct ssp_priv *priv = cpu_dai->private_data;
221 int ret = 0;
222
223 if (!cpu_dai->active) {
224 ret = ssp_init(&priv->dev, cpu_dai->id + 1, SSP_NO_IRQ);
225 if (ret < 0)
226 return ret;
227 ssp_disable(&priv->dev);
228 }
229 return ret;
230}
231
232static void pxa_ssp_shutdown(struct snd_pcm_substream *substream,
233 struct snd_soc_dai *dai)
234{
235 struct snd_soc_pcm_runtime *rtd = substream->private_data;
236 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
237 struct ssp_priv *priv = cpu_dai->private_data;
238
239 if (!cpu_dai->active) {
240 ssp_disable(&priv->dev);
241 ssp_exit(&priv->dev);
242 }
243}
244
245#ifdef CONFIG_PM
246
247static int pxa_ssp_suspend(struct snd_soc_dai *cpu_dai)
248{
249 struct ssp_priv *priv = cpu_dai->private_data;
250
251 if (!cpu_dai->active)
252 return 0;
253
254 ssp_save_state(&priv->dev, &priv->state);
255 clk_disable(priv->dev.ssp->clk);
256 return 0;
257}
258
259static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai)
260{
261 struct ssp_priv *priv = cpu_dai->private_data;
262
263 if (!cpu_dai->active)
264 return 0;
265
266 clk_enable(priv->dev.ssp->clk);
267 ssp_restore_state(&priv->dev, &priv->state);
268 ssp_enable(&priv->dev);
269
270 return 0;
271}
272
273#else
274#define pxa_ssp_suspend NULL
275#define pxa_ssp_resume NULL
276#endif
277
278/**
279 * ssp_set_clkdiv - set SSP clock divider
280 * @div: serial clock rate divider
281 */
282static void ssp_set_scr(struct ssp_dev *dev, u32 div)
283{
284 struct ssp_device *ssp = dev->ssp;
285 u32 sscr0 = ssp_read_reg(dev->ssp, SSCR0) & ~SSCR0_SCR;
286
287 ssp_write_reg(ssp, SSCR0, (sscr0 | SSCR0_SerClkDiv(div)));
288}
289
290/*
291 * Set the SSP ports SYSCLK.
292 */
293static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
294 int clk_id, unsigned int freq, int dir)
295{
296 struct ssp_priv *priv = cpu_dai->private_data;
297 struct ssp_device *ssp = priv->dev.ssp;
298 int val;
299
300 u32 sscr0 = ssp_read_reg(ssp, SSCR0) &
301 ~(SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ADC);
302
303 dev_dbg(&ssp->pdev->dev,
304 "pxa_ssp_set_dai_sysclk id: %d, clk_id %d, freq %d\n",
305 cpu_dai->id, clk_id, freq);
306
307 switch (clk_id) {
308 case PXA_SSP_CLK_NET_PLL:
309 sscr0 |= SSCR0_MOD;
310 break;
311 case PXA_SSP_CLK_PLL:
312 /* Internal PLL is fixed */
313 if (cpu_is_pxa25x())
314 priv->sysclk = 1843200;
315 else
316 priv->sysclk = 13000000;
317 break;
318 case PXA_SSP_CLK_EXT:
319 priv->sysclk = freq;
320 sscr0 |= SSCR0_ECS;
321 break;
322 case PXA_SSP_CLK_NET:
323 priv->sysclk = freq;
324 sscr0 |= SSCR0_NCS | SSCR0_MOD;
325 break;
326 case PXA_SSP_CLK_AUDIO:
327 priv->sysclk = 0;
328 ssp_set_scr(&priv->dev, 1);
329 sscr0 |= SSCR0_ADC;
330 break;
331 default:
332 return -ENODEV;
333 }
334
335 /* The SSP clock must be disabled when changing SSP clock mode
336 * on PXA2xx. On PXA3xx it must be enabled when doing so. */
337 if (!cpu_is_pxa3xx())
338 clk_disable(priv->dev.ssp->clk);
339 val = ssp_read_reg(ssp, SSCR0) | sscr0;
340 ssp_write_reg(ssp, SSCR0, val);
341 if (!cpu_is_pxa3xx())
342 clk_enable(priv->dev.ssp->clk);
343
344 return 0;
345}
346
347/*
348 * Set the SSP clock dividers.
349 */
350static int pxa_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
351 int div_id, int div)
352{
353 struct ssp_priv *priv = cpu_dai->private_data;
354 struct ssp_device *ssp = priv->dev.ssp;
355 int val;
356
357 switch (div_id) {
358 case PXA_SSP_AUDIO_DIV_ACDS:
359 val = (ssp_read_reg(ssp, SSACD) & ~0x7) | SSACD_ACDS(div);
360 ssp_write_reg(ssp, SSACD, val);
361 break;
362 case PXA_SSP_AUDIO_DIV_SCDB:
363 val = ssp_read_reg(ssp, SSACD);
364 val &= ~SSACD_SCDB;
365#if defined(CONFIG_PXA3xx)
366 if (cpu_is_pxa3xx())
367 val &= ~SSACD_SCDX8;
368#endif
369 switch (div) {
370 case PXA_SSP_CLK_SCDB_1:
371 val |= SSACD_SCDB;
372 break;
373 case PXA_SSP_CLK_SCDB_4:
374 break;
375#if defined(CONFIG_PXA3xx)
376 case PXA_SSP_CLK_SCDB_8:
377 if (cpu_is_pxa3xx())
378 val |= SSACD_SCDX8;
379 else
380 return -EINVAL;
381 break;
382#endif
383 default:
384 return -EINVAL;
385 }
386 ssp_write_reg(ssp, SSACD, val);
387 break;
388 case PXA_SSP_DIV_SCR:
389 ssp_set_scr(&priv->dev, div);
390 break;
391 default:
392 return -ENODEV;
393 }
394
395 return 0;
396}
397
398/*
399 * Configure the PLL frequency pxa27x and (afaik - pxa320 only)
400 */
401static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai,
402 int pll_id, unsigned int freq_in, unsigned int freq_out)
403{
404 struct ssp_priv *priv = cpu_dai->private_data;
405 struct ssp_device *ssp = priv->dev.ssp;
406 u32 ssacd = ssp_read_reg(ssp, SSACD) & ~0x70;
407
408#if defined(CONFIG_PXA3xx)
409 if (cpu_is_pxa3xx())
410 ssp_write_reg(ssp, SSACDD, 0);
411#endif
412
413 switch (freq_out) {
414 case 5622000:
415 break;
416 case 11345000:
417 ssacd |= (0x1 << 4);
418 break;
419 case 12235000:
420 ssacd |= (0x2 << 4);
421 break;
422 case 14857000:
423 ssacd |= (0x3 << 4);
424 break;
425 case 32842000:
426 ssacd |= (0x4 << 4);
427 break;
428 case 48000000:
429 ssacd |= (0x5 << 4);
430 break;
431 case 0:
432 /* Disable */
433 break;
434
435 default:
436#ifdef CONFIG_PXA3xx
437 /* PXA3xx has a clock ditherer which can be used to generate
438 * a wider range of frequencies - calculate a value for it.
439 */
440 if (cpu_is_pxa3xx()) {
441 u32 val;
442 u64 tmp = 19968;
443 tmp *= 1000000;
444 do_div(tmp, freq_out);
445 val = tmp;
446
447 val = (val << 16) | 64;;
448 ssp_write_reg(ssp, SSACDD, val);
449
450 ssacd |= (0x6 << 4);
451
452 dev_dbg(&ssp->pdev->dev,
453 "Using SSACDD %x to supply %dHz\n",
454 val, freq_out);
455 break;
456 }
457#endif
458
459 return -EINVAL;
460 }
461
462 ssp_write_reg(ssp, SSACD, ssacd);
463
464 return 0;
465}
466
467/*
468 * Set the active slots in TDM/Network mode
469 */
470static int pxa_ssp_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai,
471 unsigned int mask, int slots)
472{
473 struct ssp_priv *priv = cpu_dai->private_data;
474 struct ssp_device *ssp = priv->dev.ssp;
475 u32 sscr0;
476
477 sscr0 = ssp_read_reg(ssp, SSCR0) & ~SSCR0_SlotsPerFrm(7);
478
479 /* set number of active slots */
480 sscr0 |= SSCR0_SlotsPerFrm(slots);
481 ssp_write_reg(ssp, SSCR0, sscr0);
482
483 /* set active slot mask */
484 ssp_write_reg(ssp, SSTSA, mask);
485 ssp_write_reg(ssp, SSRSA, mask);
486 return 0;
487}
488
489/*
490 * Tristate the SSP DAI lines
491 */
492static int pxa_ssp_set_dai_tristate(struct snd_soc_dai *cpu_dai,
493 int tristate)
494{
495 struct ssp_priv *priv = cpu_dai->private_data;
496 struct ssp_device *ssp = priv->dev.ssp;
497 u32 sscr1;
498
499 sscr1 = ssp_read_reg(ssp, SSCR1);
500 if (tristate)
501 sscr1 &= ~SSCR1_TTE;
502 else
503 sscr1 |= SSCR1_TTE;
504 ssp_write_reg(ssp, SSCR1, sscr1);
505
506 return 0;
507}
508
509/*
510 * Set up the SSP DAI format.
511 * The SSP Port must be inactive before calling this function as the
512 * physical interface format is changed.
513 */
514static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
515 unsigned int fmt)
516{
517 struct ssp_priv *priv = cpu_dai->private_data;
518 struct ssp_device *ssp = priv->dev.ssp;
519 u32 sscr0;
520 u32 sscr1;
521 u32 sspsp;
522
523 /* reset port settings */
524 sscr0 = ssp_read_reg(ssp, SSCR0) &
525 (SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ADC);
526 sscr1 = SSCR1_RxTresh(8) | SSCR1_TxTresh(7);
527 sspsp = 0;
528
529 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
530 case SND_SOC_DAIFMT_CBM_CFM:
531 sscr1 |= SSCR1_SCLKDIR | SSCR1_SFRMDIR;
532 break;
533 case SND_SOC_DAIFMT_CBM_CFS:
534 sscr1 |= SSCR1_SCLKDIR;
535 break;
536 case SND_SOC_DAIFMT_CBS_CFS:
537 break;
538 default:
539 return -EINVAL;
540 }
541
542 ssp_write_reg(ssp, SSCR0, sscr0);
543 ssp_write_reg(ssp, SSCR1, sscr1);
544 ssp_write_reg(ssp, SSPSP, sspsp);
545
546 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
547 case SND_SOC_DAIFMT_I2S:
548 sscr0 |= SSCR0_MOD | SSCR0_PSP;
549 sscr1 |= SSCR1_RWOT | SSCR1_TRAIL;
550
551 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
552 case SND_SOC_DAIFMT_NB_NF:
553 sspsp |= SSPSP_FSRT;
554 break;
555 case SND_SOC_DAIFMT_NB_IF:
556 sspsp |= SSPSP_SFRMP | SSPSP_FSRT;
557 break;
558 case SND_SOC_DAIFMT_IB_IF:
559 sspsp |= SSPSP_SFRMP;
560 break;
561 default:
562 return -EINVAL;
563 }
564 break;
565
566 case SND_SOC_DAIFMT_DSP_A:
567 sspsp |= SSPSP_FSRT;
568 case SND_SOC_DAIFMT_DSP_B:
569 sscr0 |= SSCR0_MOD | SSCR0_PSP;
570 sscr1 |= SSCR1_TRAIL | SSCR1_RWOT;
571
572 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
573 case SND_SOC_DAIFMT_NB_NF:
574 sspsp |= SSPSP_SFRMP;
575 break;
576 case SND_SOC_DAIFMT_IB_IF:
577 break;
578 default:
579 return -EINVAL;
580 }
581 break;
582
583 default:
584 return -EINVAL;
585 }
586
587 ssp_write_reg(ssp, SSCR0, sscr0);
588 ssp_write_reg(ssp, SSCR1, sscr1);
589 ssp_write_reg(ssp, SSPSP, sspsp);
590
591 dump_registers(ssp);
592
593 /* Since we are configuring the timings for the format by hand
594 * we have to defer some things until hw_params() where we
595 * know parameters like the sample size.
596 */
597 priv->dai_fmt = fmt;
598
599 return 0;
600}
601
602/*
603 * Set the SSP audio DMA parameters and sample size.
604 * Can be called multiple times by oss emulation.
605 */
606static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
607 struct snd_pcm_hw_params *params,
608 struct snd_soc_dai *dai)
609{
610 struct snd_soc_pcm_runtime *rtd = substream->private_data;
611 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
612 struct ssp_priv *priv = cpu_dai->private_data;
613 struct ssp_device *ssp = priv->dev.ssp;
614 int dma = 0, chn = params_channels(params);
615 u32 sscr0;
616 u32 sspsp;
617 int width = snd_pcm_format_physical_width(params_format(params));
618
619 /* select correct DMA params */
620 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
621 dma = 1; /* capture DMA offset is 1,3 */
622 if (chn == 2)
623 dma += 2; /* stereo DMA offset is 2, mono is 0 */
624 cpu_dai->dma_data = ssp_dma_params[cpu_dai->id][dma];
625
626 dev_dbg(&ssp->pdev->dev, "pxa_ssp_hw_params: dma %d\n", dma);
627
628 /* we can only change the settings if the port is not in use */
629 if (ssp_read_reg(ssp, SSCR0) & SSCR0_SSE)
630 return 0;
631
632 /* clear selected SSP bits */
633 sscr0 = ssp_read_reg(ssp, SSCR0) & ~(SSCR0_DSS | SSCR0_EDSS);
634 ssp_write_reg(ssp, SSCR0, sscr0);
635
636 /* bit size */
637 sscr0 = ssp_read_reg(ssp, SSCR0);
638 switch (params_format(params)) {
639 case SNDRV_PCM_FORMAT_S16_LE:
640#ifdef CONFIG_PXA3xx
641 if (cpu_is_pxa3xx())
642 sscr0 |= SSCR0_FPCKE;
643#endif
644 sscr0 |= SSCR0_DataSize(16);
645 if (params_channels(params) > 1)
646 sscr0 |= SSCR0_EDSS;
647 break;
648 case SNDRV_PCM_FORMAT_S24_LE:
649 sscr0 |= (SSCR0_EDSS | SSCR0_DataSize(8));
650 /* we must be in network mode (2 slots) for 24 bit stereo */
651 break;
652 case SNDRV_PCM_FORMAT_S32_LE:
653 sscr0 |= (SSCR0_EDSS | SSCR0_DataSize(16));
654 /* we must be in network mode (2 slots) for 32 bit stereo */
655 break;
656 }
657 ssp_write_reg(ssp, SSCR0, sscr0);
658
659 switch (priv->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
660 case SND_SOC_DAIFMT_I2S:
661 /* Cleared when the DAI format is set */
662 sspsp = ssp_read_reg(ssp, SSPSP) | SSPSP_SFRMWDTH(width);
663 ssp_write_reg(ssp, SSPSP, sspsp);
664 break;
665 default:
666 break;
667 }
668
669 /* We always use a network mode so we always require TDM slots
670 * - complain loudly and fail if they've not been set up yet.
671 */
672 if (!(ssp_read_reg(ssp, SSTSA) & 0xf)) {
673 dev_err(&ssp->pdev->dev, "No TDM timeslot configured\n");
674 return -EINVAL;
675 }
676
677 dump_registers(ssp);
678
679 return 0;
680}
681
682static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd,
683 struct snd_soc_dai *dai)
684{
685 struct snd_soc_pcm_runtime *rtd = substream->private_data;
686 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
687 int ret = 0;
688 struct ssp_priv *priv = cpu_dai->private_data;
689 struct ssp_device *ssp = priv->dev.ssp;
690 int val;
691
692 switch (cmd) {
693 case SNDRV_PCM_TRIGGER_RESUME:
694 ssp_enable(&priv->dev);
695 break;
696 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
697 val = ssp_read_reg(ssp, SSCR1);
698 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
699 val |= SSCR1_TSRE;
700 else
701 val |= SSCR1_RSRE;
702 ssp_write_reg(ssp, SSCR1, val);
703 val = ssp_read_reg(ssp, SSSR);
704 ssp_write_reg(ssp, SSSR, val);
705 break;
706 case SNDRV_PCM_TRIGGER_START:
707 val = ssp_read_reg(ssp, SSCR1);
708 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
709 val |= SSCR1_TSRE;
710 else
711 val |= SSCR1_RSRE;
712 ssp_write_reg(ssp, SSCR1, val);
713 ssp_enable(&priv->dev);
714 break;
715 case SNDRV_PCM_TRIGGER_STOP:
716 val = ssp_read_reg(ssp, SSCR1);
717 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
718 val &= ~SSCR1_TSRE;
719 else
720 val &= ~SSCR1_RSRE;
721 ssp_write_reg(ssp, SSCR1, val);
722 break;
723 case SNDRV_PCM_TRIGGER_SUSPEND:
724 ssp_disable(&priv->dev);
725 break;
726 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
727 val = ssp_read_reg(ssp, SSCR1);
728 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
729 val &= ~SSCR1_TSRE;
730 else
731 val &= ~SSCR1_RSRE;
732 ssp_write_reg(ssp, SSCR1, val);
733 break;
734
735 default:
736 ret = -EINVAL;
737 }
738
739 dump_registers(ssp);
740
741 return ret;
742}
743
744static int pxa_ssp_probe(struct platform_device *pdev,
745 struct snd_soc_dai *dai)
746{
747 struct ssp_priv *priv;
748 int ret;
749
750 priv = kzalloc(sizeof(struct ssp_priv), GFP_KERNEL);
751 if (!priv)
752 return -ENOMEM;
753
754 priv->dev.ssp = ssp_request(dai->id, "SoC audio");
755 if (priv->dev.ssp == NULL) {
756 ret = -ENODEV;
757 goto err_priv;
758 }
759
760 dai->private_data = priv;
761
762 return 0;
763
764err_priv:
765 kfree(priv);
766 return ret;
767}
768
769static void pxa_ssp_remove(struct platform_device *pdev,
770 struct snd_soc_dai *dai)
771{
772 struct ssp_priv *priv = dai->private_data;
773 ssp_free(priv->dev.ssp);
774}
775
776#define PXA_SSP_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
777 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \
778 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | \
779 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
780
781#define PXA_SSP_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
782 SNDRV_PCM_FMTBIT_S24_LE | \
783 SNDRV_PCM_FMTBIT_S32_LE)
784
785struct snd_soc_dai pxa_ssp_dai[] = {
786 {
787 .name = "pxa2xx-ssp1",
788 .id = 0,
789 .probe = pxa_ssp_probe,
790 .remove = pxa_ssp_remove,
791 .suspend = pxa_ssp_suspend,
792 .resume = pxa_ssp_resume,
793 .playback = {
794 .channels_min = 1,
795 .channels_max = 2,
796 .rates = PXA_SSP_RATES,
797 .formats = PXA_SSP_FORMATS,
798 },
799 .capture = {
800 .channels_min = 1,
801 .channels_max = 2,
802 .rates = PXA_SSP_RATES,
803 .formats = PXA_SSP_FORMATS,
804 },
805 .ops = {
806 .startup = pxa_ssp_startup,
807 .shutdown = pxa_ssp_shutdown,
808 .trigger = pxa_ssp_trigger,
809 .hw_params = pxa_ssp_hw_params,
810 .set_sysclk = pxa_ssp_set_dai_sysclk,
811 .set_clkdiv = pxa_ssp_set_dai_clkdiv,
812 .set_pll = pxa_ssp_set_dai_pll,
813 .set_fmt = pxa_ssp_set_dai_fmt,
814 .set_tdm_slot = pxa_ssp_set_dai_tdm_slot,
815 .set_tristate = pxa_ssp_set_dai_tristate,
816 },
817 },
818 { .name = "pxa2xx-ssp2",
819 .id = 1,
820 .probe = pxa_ssp_probe,
821 .remove = pxa_ssp_remove,
822 .suspend = pxa_ssp_suspend,
823 .resume = pxa_ssp_resume,
824 .playback = {
825 .channels_min = 1,
826 .channels_max = 2,
827 .rates = PXA_SSP_RATES,
828 .formats = PXA_SSP_FORMATS,
829 },
830 .capture = {
831 .channels_min = 1,
832 .channels_max = 2,
833 .rates = PXA_SSP_RATES,
834 .formats = PXA_SSP_FORMATS,
835 },
836 .ops = {
837 .startup = pxa_ssp_startup,
838 .shutdown = pxa_ssp_shutdown,
839 .trigger = pxa_ssp_trigger,
840 .hw_params = pxa_ssp_hw_params,
841 .set_sysclk = pxa_ssp_set_dai_sysclk,
842 .set_clkdiv = pxa_ssp_set_dai_clkdiv,
843 .set_pll = pxa_ssp_set_dai_pll,
844 .set_fmt = pxa_ssp_set_dai_fmt,
845 .set_tdm_slot = pxa_ssp_set_dai_tdm_slot,
846 .set_tristate = pxa_ssp_set_dai_tristate,
847 },
848 },
849 {
850 .name = "pxa2xx-ssp3",
851 .id = 2,
852 .probe = pxa_ssp_probe,
853 .remove = pxa_ssp_remove,
854 .suspend = pxa_ssp_suspend,
855 .resume = pxa_ssp_resume,
856 .playback = {
857 .channels_min = 1,
858 .channels_max = 2,
859 .rates = PXA_SSP_RATES,
860 .formats = PXA_SSP_FORMATS,
861 },
862 .capture = {
863 .channels_min = 1,
864 .channels_max = 2,
865 .rates = PXA_SSP_RATES,
866 .formats = PXA_SSP_FORMATS,
867 },
868 .ops = {
869 .startup = pxa_ssp_startup,
870 .shutdown = pxa_ssp_shutdown,
871 .trigger = pxa_ssp_trigger,
872 .hw_params = pxa_ssp_hw_params,
873 .set_sysclk = pxa_ssp_set_dai_sysclk,
874 .set_clkdiv = pxa_ssp_set_dai_clkdiv,
875 .set_pll = pxa_ssp_set_dai_pll,
876 .set_fmt = pxa_ssp_set_dai_fmt,
877 .set_tdm_slot = pxa_ssp_set_dai_tdm_slot,
878 .set_tristate = pxa_ssp_set_dai_tristate,
879 },
880 },
881 {
882 .name = "pxa2xx-ssp4",
883 .id = 3,
884 .probe = pxa_ssp_probe,
885 .remove = pxa_ssp_remove,
886 .suspend = pxa_ssp_suspend,
887 .resume = pxa_ssp_resume,
888 .playback = {
889 .channels_min = 1,
890 .channels_max = 2,
891 .rates = PXA_SSP_RATES,
892 .formats = PXA_SSP_FORMATS,
893 },
894 .capture = {
895 .channels_min = 1,
896 .channels_max = 2,
897 .rates = PXA_SSP_RATES,
898 .formats = PXA_SSP_FORMATS,
899 },
900 .ops = {
901 .startup = pxa_ssp_startup,
902 .shutdown = pxa_ssp_shutdown,
903 .trigger = pxa_ssp_trigger,
904 .hw_params = pxa_ssp_hw_params,
905 .set_sysclk = pxa_ssp_set_dai_sysclk,
906 .set_clkdiv = pxa_ssp_set_dai_clkdiv,
907 .set_pll = pxa_ssp_set_dai_pll,
908 .set_fmt = pxa_ssp_set_dai_fmt,
909 .set_tdm_slot = pxa_ssp_set_dai_tdm_slot,
910 .set_tristate = pxa_ssp_set_dai_tristate,
911 },
912 },
913};
914EXPORT_SYMBOL_GPL(pxa_ssp_dai);
915
916static int __init pxa_ssp_init(void)
917{
918 return snd_soc_register_dais(pxa_ssp_dai, ARRAY_SIZE(pxa_ssp_dai));
919}
920module_init(pxa_ssp_init);
921
922static void __exit pxa_ssp_exit(void)
923{
924 snd_soc_unregister_dais(pxa_ssp_dai, ARRAY_SIZE(pxa_ssp_dai));
925}
926module_exit(pxa_ssp_exit);
927
928/* Module information */
929MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
930MODULE_DESCRIPTION("PXA SSP/PCM SoC Interface");
931MODULE_LICENSE("GPL");
diff --git a/sound/soc/pxa/pxa-ssp.h b/sound/soc/pxa/pxa-ssp.h
new file mode 100644
index 000000000000..91deadd55675
--- /dev/null
+++ b/sound/soc/pxa/pxa-ssp.h
@@ -0,0 +1,47 @@
1/*
2 * ASoC PXA SSP port support
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 _PXA_SSP_H
10#define _PXA_SSP_H
11
12/* pxa DAI SSP IDs */
13#define PXA_DAI_SSP1 0
14#define PXA_DAI_SSP2 1
15#define PXA_DAI_SSP3 2
16#define PXA_DAI_SSP4 3
17
18/* SSP clock sources */
19#define PXA_SSP_CLK_PLL 0
20#define PXA_SSP_CLK_EXT 1
21#define PXA_SSP_CLK_NET 2
22#define PXA_SSP_CLK_AUDIO 3
23#define PXA_SSP_CLK_NET_PLL 4
24
25/* SSP audio dividers */
26#define PXA_SSP_AUDIO_DIV_ACDS 0
27#define PXA_SSP_AUDIO_DIV_SCDB 1
28#define PXA_SSP_DIV_SCR 2
29
30/* SSP ACDS audio dividers values */
31#define PXA_SSP_CLK_AUDIO_DIV_1 0
32#define PXA_SSP_CLK_AUDIO_DIV_2 1
33#define PXA_SSP_CLK_AUDIO_DIV_4 2
34#define PXA_SSP_CLK_AUDIO_DIV_8 3
35#define PXA_SSP_CLK_AUDIO_DIV_16 4
36#define PXA_SSP_CLK_AUDIO_DIV_32 5
37
38/* SSP divider bypass */
39#define PXA_SSP_CLK_SCDB_4 0
40#define PXA_SSP_CLK_SCDB_1 1
41#define PXA_SSP_CLK_SCDB_8 2
42
43#define PXA_SSP_PLL_OUT 0
44
45extern struct snd_soc_dai pxa_ssp_dai[4];
46
47#endif
diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c
index a7a3a9c5c6ff..780db6757ad2 100644
--- a/sound/soc/pxa/pxa2xx-ac97.c
+++ b/sound/soc/pxa/pxa2xx-ac97.c
@@ -87,14 +87,12 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_mic_mono_in = {
87}; 87};
88 88
89#ifdef CONFIG_PM 89#ifdef CONFIG_PM
90static int pxa2xx_ac97_suspend(struct platform_device *pdev, 90static int pxa2xx_ac97_suspend(struct snd_soc_dai *dai)
91 struct snd_soc_dai *dai)
92{ 91{
93 return pxa2xx_ac97_hw_suspend(); 92 return pxa2xx_ac97_hw_suspend();
94} 93}
95 94
96static int pxa2xx_ac97_resume(struct platform_device *pdev, 95static int pxa2xx_ac97_resume(struct snd_soc_dai *dai)
97 struct snd_soc_dai *dai)
98{ 96{
99 return pxa2xx_ac97_hw_resume(); 97 return pxa2xx_ac97_hw_resume();
100} 98}
@@ -117,7 +115,8 @@ static void pxa2xx_ac97_remove(struct platform_device *pdev,
117} 115}
118 116
119static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream, 117static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream,
120 struct snd_pcm_hw_params *params) 118 struct snd_pcm_hw_params *params,
119 struct snd_soc_dai *dai)
121{ 120{
122 struct snd_soc_pcm_runtime *rtd = substream->private_data; 121 struct snd_soc_pcm_runtime *rtd = substream->private_data;
123 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 122 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -131,7 +130,8 @@ static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream,
131} 130}
132 131
133static int pxa2xx_ac97_hw_aux_params(struct snd_pcm_substream *substream, 132static int pxa2xx_ac97_hw_aux_params(struct snd_pcm_substream *substream,
134 struct snd_pcm_hw_params *params) 133 struct snd_pcm_hw_params *params,
134 struct snd_soc_dai *dai)
135{ 135{
136 struct snd_soc_pcm_runtime *rtd = substream->private_data; 136 struct snd_soc_pcm_runtime *rtd = substream->private_data;
137 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 137 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -145,7 +145,8 @@ static int pxa2xx_ac97_hw_aux_params(struct snd_pcm_substream *substream,
145} 145}
146 146
147static int pxa2xx_ac97_hw_mic_params(struct snd_pcm_substream *substream, 147static int pxa2xx_ac97_hw_mic_params(struct snd_pcm_substream *substream,
148 struct snd_pcm_hw_params *params) 148 struct snd_pcm_hw_params *params,
149 struct snd_soc_dai *dai)
149{ 150{
150 struct snd_soc_pcm_runtime *rtd = substream->private_data; 151 struct snd_soc_pcm_runtime *rtd = substream->private_data;
151 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 152 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -170,7 +171,7 @@ struct snd_soc_dai pxa_ac97_dai[] = {
170{ 171{
171 .name = "pxa2xx-ac97", 172 .name = "pxa2xx-ac97",
172 .id = 0, 173 .id = 0,
173 .type = SND_SOC_DAI_AC97, 174 .ac97_control = 1,
174 .probe = pxa2xx_ac97_probe, 175 .probe = pxa2xx_ac97_probe,
175 .remove = pxa2xx_ac97_remove, 176 .remove = pxa2xx_ac97_remove,
176 .suspend = pxa2xx_ac97_suspend, 177 .suspend = pxa2xx_ac97_suspend,
@@ -193,7 +194,7 @@ struct snd_soc_dai pxa_ac97_dai[] = {
193{ 194{
194 .name = "pxa2xx-ac97-aux", 195 .name = "pxa2xx-ac97-aux",
195 .id = 1, 196 .id = 1,
196 .type = SND_SOC_DAI_AC97, 197 .ac97_control = 1,
197 .playback = { 198 .playback = {
198 .stream_name = "AC97 Aux Playback", 199 .stream_name = "AC97 Aux Playback",
199 .channels_min = 1, 200 .channels_min = 1,
@@ -212,7 +213,7 @@ struct snd_soc_dai pxa_ac97_dai[] = {
212{ 213{
213 .name = "pxa2xx-ac97-mic", 214 .name = "pxa2xx-ac97-mic",
214 .id = 2, 215 .id = 2,
215 .type = SND_SOC_DAI_AC97, 216 .ac97_control = 1,
216 .capture = { 217 .capture = {
217 .stream_name = "AC97 Mic Capture", 218 .stream_name = "AC97 Mic Capture",
218 .channels_min = 1, 219 .channels_min = 1,
@@ -227,6 +228,18 @@ struct snd_soc_dai pxa_ac97_dai[] = {
227EXPORT_SYMBOL_GPL(pxa_ac97_dai); 228EXPORT_SYMBOL_GPL(pxa_ac97_dai);
228EXPORT_SYMBOL_GPL(soc_ac97_ops); 229EXPORT_SYMBOL_GPL(soc_ac97_ops);
229 230
231static int __init pxa_ac97_init(void)
232{
233 return snd_soc_register_dais(pxa_ac97_dai, ARRAY_SIZE(pxa_ac97_dai));
234}
235module_init(pxa_ac97_init);
236
237static void __exit pxa_ac97_exit(void)
238{
239 snd_soc_unregister_dais(pxa_ac97_dai, ARRAY_SIZE(pxa_ac97_dai));
240}
241module_exit(pxa_ac97_exit);
242
230MODULE_AUTHOR("Nicolas Pitre"); 243MODULE_AUTHOR("Nicolas Pitre");
231MODULE_DESCRIPTION("AC97 driver for the Intel PXA2xx chip"); 244MODULE_DESCRIPTION("AC97 driver for the Intel PXA2xx chip");
232MODULE_LICENSE("GPL"); 245MODULE_LICENSE("GPL");
diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c
index e758034db5c3..517991fb1099 100644
--- a/sound/soc/pxa/pxa2xx-i2s.c
+++ b/sound/soc/pxa/pxa2xx-i2s.c
@@ -121,7 +121,8 @@ static struct pxa2xx_gpio gpio_bus[] = {
121 }, 121 },
122}; 122};
123 123
124static int pxa2xx_i2s_startup(struct snd_pcm_substream *substream) 124static int pxa2xx_i2s_startup(struct snd_pcm_substream *substream,
125 struct snd_soc_dai *dai)
125{ 126{
126 struct snd_soc_pcm_runtime *rtd = substream->private_data; 127 struct snd_soc_pcm_runtime *rtd = substream->private_data;
127 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 128 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -187,7 +188,8 @@ static int pxa2xx_i2s_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
187} 188}
188 189
189static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream, 190static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream,
190 struct snd_pcm_hw_params *params) 191 struct snd_pcm_hw_params *params,
192 struct snd_soc_dai *dai)
191{ 193{
192 struct snd_soc_pcm_runtime *rtd = substream->private_data; 194 struct snd_soc_pcm_runtime *rtd = substream->private_data;
193 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 195 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -248,7 +250,8 @@ static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream,
248 return 0; 250 return 0;
249} 251}
250 252
251static int pxa2xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd) 253static int pxa2xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
254 struct snd_soc_dai *dai)
252{ 255{
253 int ret = 0; 256 int ret = 0;
254 257
@@ -269,7 +272,8 @@ static int pxa2xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd)
269 return ret; 272 return ret;
270} 273}
271 274
272static void pxa2xx_i2s_shutdown(struct snd_pcm_substream *substream) 275static void pxa2xx_i2s_shutdown(struct snd_pcm_substream *substream,
276 struct snd_soc_dai *dai)
273{ 277{
274 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 278 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
275 SACR1 |= SACR1_DRPL; 279 SACR1 |= SACR1_DRPL;
@@ -289,8 +293,7 @@ static void pxa2xx_i2s_shutdown(struct snd_pcm_substream *substream)
289} 293}
290 294
291#ifdef CONFIG_PM 295#ifdef CONFIG_PM
292static int pxa2xx_i2s_suspend(struct platform_device *dev, 296static int pxa2xx_i2s_suspend(struct snd_soc_dai *dai)
293 struct snd_soc_dai *dai)
294{ 297{
295 if (!dai->active) 298 if (!dai->active)
296 return 0; 299 return 0;
@@ -307,8 +310,7 @@ static int pxa2xx_i2s_suspend(struct platform_device *dev,
307 return 0; 310 return 0;
308} 311}
309 312
310static int pxa2xx_i2s_resume(struct platform_device *pdev, 313static int pxa2xx_i2s_resume(struct snd_soc_dai *dai)
311 struct snd_soc_dai *dai)
312{ 314{
313 if (!dai->active) 315 if (!dai->active)
314 return 0; 316 return 0;
@@ -336,7 +338,6 @@ static int pxa2xx_i2s_resume(struct platform_device *pdev,
336struct snd_soc_dai pxa_i2s_dai = { 338struct snd_soc_dai pxa_i2s_dai = {
337 .name = "pxa2xx-i2s", 339 .name = "pxa2xx-i2s",
338 .id = 0, 340 .id = 0,
339 .type = SND_SOC_DAI_I2S,
340 .suspend = pxa2xx_i2s_suspend, 341 .suspend = pxa2xx_i2s_suspend,
341 .resume = pxa2xx_i2s_resume, 342 .resume = pxa2xx_i2s_resume,
342 .playback = { 343 .playback = {
@@ -353,8 +354,7 @@ struct snd_soc_dai pxa_i2s_dai = {
353 .startup = pxa2xx_i2s_startup, 354 .startup = pxa2xx_i2s_startup,
354 .shutdown = pxa2xx_i2s_shutdown, 355 .shutdown = pxa2xx_i2s_shutdown,
355 .trigger = pxa2xx_i2s_trigger, 356 .trigger = pxa2xx_i2s_trigger,
356 .hw_params = pxa2xx_i2s_hw_params,}, 357 .hw_params = pxa2xx_i2s_hw_params,
357 .dai_ops = {
358 .set_fmt = pxa2xx_i2s_set_dai_fmt, 358 .set_fmt = pxa2xx_i2s_set_dai_fmt,
359 .set_sysclk = pxa2xx_i2s_set_dai_sysclk, 359 .set_sysclk = pxa2xx_i2s_set_dai_sysclk,
360 }, 360 },
@@ -364,12 +364,23 @@ EXPORT_SYMBOL_GPL(pxa_i2s_dai);
364 364
365static int pxa2xx_i2s_probe(struct platform_device *dev) 365static int pxa2xx_i2s_probe(struct platform_device *dev)
366{ 366{
367 int ret;
368
367 clk_i2s = clk_get(&dev->dev, "I2SCLK"); 369 clk_i2s = clk_get(&dev->dev, "I2SCLK");
368 return IS_ERR(clk_i2s) ? PTR_ERR(clk_i2s) : 0; 370 if (IS_ERR(clk_i2s))
371 return PTR_ERR(clk_i2s);
372
373 pxa_i2s_dai.dev = &dev->dev;
374 ret = snd_soc_register_dai(&pxa_i2s_dai);
375 if (ret != 0)
376 clk_put(clk_i2s);
377
378 return ret;
369} 379}
370 380
371static int __devexit pxa2xx_i2s_remove(struct platform_device *dev) 381static int __devexit pxa2xx_i2s_remove(struct platform_device *dev)
372{ 382{
383 snd_soc_unregister_dai(&pxa_i2s_dai);
373 clk_put(clk_i2s); 384 clk_put(clk_i2s);
374 clk_i2s = ERR_PTR(-ENOENT); 385 clk_i2s = ERR_PTR(-ENOENT);
375 return 0; 386 return 0;
diff --git a/sound/soc/pxa/pxa2xx-pcm.c b/sound/soc/pxa/pxa2xx-pcm.c
index afcd892cd2fa..c670d08e7c9e 100644
--- a/sound/soc/pxa/pxa2xx-pcm.c
+++ b/sound/soc/pxa/pxa2xx-pcm.c
@@ -69,7 +69,7 @@ static int pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream)
69 return 0; 69 return 0;
70} 70}
71 71
72struct snd_pcm_ops pxa2xx_pcm_ops = { 72static struct snd_pcm_ops pxa2xx_pcm_ops = {
73 .open = __pxa2xx_pcm_open, 73 .open = __pxa2xx_pcm_open,
74 .close = __pxa2xx_pcm_close, 74 .close = __pxa2xx_pcm_close,
75 .ioctl = snd_pcm_lib_ioctl, 75 .ioctl = snd_pcm_lib_ioctl,
@@ -118,6 +118,18 @@ struct snd_soc_platform pxa2xx_soc_platform = {
118}; 118};
119EXPORT_SYMBOL_GPL(pxa2xx_soc_platform); 119EXPORT_SYMBOL_GPL(pxa2xx_soc_platform);
120 120
121static int __init pxa2xx_soc_platform_init(void)
122{
123 return snd_soc_register_platform(&pxa2xx_soc_platform);
124}
125module_init(pxa2xx_soc_platform_init);
126
127static void __exit pxa2xx_soc_platform_exit(void)
128{
129 snd_soc_unregister_platform(&pxa2xx_soc_platform);
130}
131module_exit(pxa2xx_soc_platform_exit);
132
121MODULE_AUTHOR("Nicolas Pitre"); 133MODULE_AUTHOR("Nicolas Pitre");
122MODULE_DESCRIPTION("Intel PXA2xx PCM DMA module"); 134MODULE_DESCRIPTION("Intel PXA2xx PCM DMA module");
123MODULE_LICENSE("GPL"); 135MODULE_LICENSE("GPL");
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c
index d307b6757e95..a3b9e6bdf979 100644
--- a/sound/soc/pxa/spitz.c
+++ b/sound/soc/pxa/spitz.c
@@ -319,8 +319,9 @@ static struct snd_soc_dai_link spitz_dai = {
319}; 319};
320 320
321/* spitz audio machine driver */ 321/* spitz audio machine driver */
322static struct snd_soc_machine snd_soc_machine_spitz = { 322static struct snd_soc_card snd_soc_spitz = {
323 .name = "Spitz", 323 .name = "Spitz",
324 .platform = &pxa2xx_soc_platform,
324 .dai_link = &spitz_dai, 325 .dai_link = &spitz_dai,
325 .num_links = 1, 326 .num_links = 1,
326}; 327};
@@ -333,8 +334,7 @@ static struct wm8750_setup_data spitz_wm8750_setup = {
333 334
334/* spitz audio subsystem */ 335/* spitz audio subsystem */
335static struct snd_soc_device spitz_snd_devdata = { 336static struct snd_soc_device spitz_snd_devdata = {
336 .machine = &snd_soc_machine_spitz, 337 .card = &snd_soc_spitz,
337 .platform = &pxa2xx_soc_platform,
338 .codec_dev = &soc_codec_dev_wm8750, 338 .codec_dev = &soc_codec_dev_wm8750,
339 .codec_data = &spitz_wm8750_setup, 339 .codec_data = &spitz_wm8750_setup,
340}; 340};
diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c
index afefe41b8c46..c77194f74c9b 100644
--- a/sound/soc/pxa/tosa.c
+++ b/sound/soc/pxa/tosa.c
@@ -38,7 +38,7 @@
38#include "pxa2xx-pcm.h" 38#include "pxa2xx-pcm.h"
39#include "pxa2xx-ac97.h" 39#include "pxa2xx-ac97.h"
40 40
41static struct snd_soc_machine tosa; 41static struct snd_soc_card tosa;
42 42
43#define TOSA_HP 0 43#define TOSA_HP 0
44#define TOSA_MIC_INT 1 44#define TOSA_MIC_INT 1
@@ -230,15 +230,37 @@ static struct snd_soc_dai_link tosa_dai[] = {
230}, 230},
231}; 231};
232 232
233static struct snd_soc_machine tosa = { 233static int tosa_probe(struct platform_device *dev)
234{
235 int ret;
236
237 ret = gpio_request(TOSA_GPIO_L_MUTE, "Headphone Jack");
238 if (ret)
239 return ret;
240 ret = gpio_direction_output(TOSA_GPIO_L_MUTE, 0);
241 if (ret)
242 gpio_free(TOSA_GPIO_L_MUTE);
243
244 return ret;
245}
246
247static int tosa_remove(struct platform_device *dev)
248{
249 gpio_free(TOSA_GPIO_L_MUTE);
250 return 0;
251}
252
253static struct snd_soc_card tosa = {
234 .name = "Tosa", 254 .name = "Tosa",
255 .platform = &pxa2xx_soc_platform,
235 .dai_link = tosa_dai, 256 .dai_link = tosa_dai,
236 .num_links = ARRAY_SIZE(tosa_dai), 257 .num_links = ARRAY_SIZE(tosa_dai),
258 .probe = tosa_probe,
259 .remove = tosa_remove,
237}; 260};
238 261
239static struct snd_soc_device tosa_snd_devdata = { 262static struct snd_soc_device tosa_snd_devdata = {
240 .machine = &tosa, 263 .card = &tosa,
241 .platform = &pxa2xx_soc_platform,
242 .codec_dev = &soc_codec_dev_wm9712, 264 .codec_dev = &soc_codec_dev_wm9712,
243}; 265};
244 266
@@ -251,11 +273,6 @@ static int __init tosa_init(void)
251 if (!machine_is_tosa()) 273 if (!machine_is_tosa())
252 return -ENODEV; 274 return -ENODEV;
253 275
254 ret = gpio_request(TOSA_GPIO_L_MUTE, "Headphone Jack");
255 if (ret)
256 return ret;
257 gpio_direction_output(TOSA_GPIO_L_MUTE, 0);
258
259 tosa_snd_device = platform_device_alloc("soc-audio", -1); 276 tosa_snd_device = platform_device_alloc("soc-audio", -1);
260 if (!tosa_snd_device) { 277 if (!tosa_snd_device) {
261 ret = -ENOMEM; 278 ret = -ENOMEM;
@@ -272,15 +289,12 @@ static int __init tosa_init(void)
272 platform_device_put(tosa_snd_device); 289 platform_device_put(tosa_snd_device);
273 290
274err_alloc: 291err_alloc:
275 gpio_free(TOSA_GPIO_L_MUTE);
276
277 return ret; 292 return ret;
278} 293}
279 294
280static void __exit tosa_exit(void) 295static void __exit tosa_exit(void)
281{ 296{
282 platform_device_unregister(tosa_snd_device); 297 platform_device_unregister(tosa_snd_device);
283 gpio_free(TOSA_GPIO_L_MUTE);
284} 298}
285 299
286module_init(tosa_init); 300module_init(tosa_init);
diff --git a/sound/soc/pxa/zylonite.c b/sound/soc/pxa/zylonite.c
new file mode 100644
index 000000000000..f8e9ecd589d3
--- /dev/null
+++ b/sound/soc/pxa/zylonite.c
@@ -0,0 +1,219 @@
1/*
2 * zylonite.c -- SoC audio for Zylonite
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
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of the
10 * License, or (at your option) any later version.
11 *
12 */
13
14#include <linux/module.h>
15#include <linux/moduleparam.h>
16#include <linux/device.h>
17#include <linux/i2c.h>
18#include <sound/core.h>
19#include <sound/pcm.h>
20#include <sound/pcm_params.h>
21#include <sound/soc.h>
22#include <sound/soc-dapm.h>
23
24#include "../codecs/wm9713.h"
25#include "pxa2xx-pcm.h"
26#include "pxa2xx-ac97.h"
27#include "pxa-ssp.h"
28
29static struct snd_soc_card zylonite;
30
31static const struct snd_soc_dapm_widget zylonite_dapm_widgets[] = {
32 SND_SOC_DAPM_HP("Headphone", NULL),
33 SND_SOC_DAPM_MIC("Headset Microphone", NULL),
34 SND_SOC_DAPM_MIC("Handset Microphone", NULL),
35 SND_SOC_DAPM_SPK("Multiactor", NULL),
36 SND_SOC_DAPM_SPK("Headset Earpiece", NULL),
37};
38
39/* Currently supported audio map */
40static const struct snd_soc_dapm_route audio_map[] = {
41
42 /* Headphone output connected to HPL/HPR */
43 { "Headphone", NULL, "HPL" },
44 { "Headphone", NULL, "HPR" },
45
46 /* On-board earpiece */
47 { "Headset Earpiece", NULL, "OUT3" },
48
49 /* Headphone mic */
50 { "MIC2A", NULL, "Mic Bias" },
51 { "Mic Bias", NULL, "Headset Microphone" },
52
53 /* On-board mic */
54 { "MIC1", NULL, "Mic Bias" },
55 { "Mic Bias", NULL, "Handset Microphone" },
56
57 /* Multiactor differentially connected over SPKL/SPKR */
58 { "Multiactor", NULL, "SPKL" },
59 { "Multiactor", NULL, "SPKR" },
60};
61
62static int zylonite_wm9713_init(struct snd_soc_codec *codec)
63{
64 /* Currently we only support use of the AC97 clock here. If
65 * CLK_POUT is selected by SW15 then the clock API will need
66 * to be used to request and enable it here.
67 */
68
69 snd_soc_dapm_new_controls(codec, zylonite_dapm_widgets,
70 ARRAY_SIZE(zylonite_dapm_widgets));
71
72 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
73
74 /* Static setup for now */
75 snd_soc_dapm_enable_pin(codec, "Headphone");
76 snd_soc_dapm_enable_pin(codec, "Headset Earpiece");
77
78 snd_soc_dapm_sync(codec);
79 return 0;
80}
81
82static int zylonite_voice_hw_params(struct snd_pcm_substream *substream,
83 struct snd_pcm_hw_params *params)
84{
85 struct snd_soc_pcm_runtime *rtd = substream->private_data;
86 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
87 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
88 unsigned int pll_out = 0;
89 unsigned int acds = 0;
90 unsigned int wm9713_div = 0;
91 int ret = 0;
92
93 switch (params_rate(params)) {
94 case 8000:
95 wm9713_div = 12;
96 pll_out = 2048000;
97 break;
98 case 16000:
99 wm9713_div = 6;
100 pll_out = 4096000;
101 break;
102 case 48000:
103 default:
104 wm9713_div = 2;
105 pll_out = 12288000;
106 acds = 1;
107 break;
108 }
109
110 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
111 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
112 if (ret < 0)
113 return ret;
114
115 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
116 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
117 if (ret < 0)
118 return ret;
119
120 ret = snd_soc_dai_set_tdm_slot(cpu_dai,
121 params_channels(params),
122 params_channels(params));
123 if (ret < 0)
124 return ret;
125
126 ret = snd_soc_dai_set_pll(cpu_dai, 0, 0, pll_out);
127 if (ret < 0)
128 return ret;
129
130 ret = snd_soc_dai_set_clkdiv(cpu_dai, PXA_SSP_AUDIO_DIV_ACDS, acds);
131 if (ret < 0)
132 return ret;
133
134 ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_AUDIO, 0, 1);
135 if (ret < 0)
136 return ret;
137
138 /* Note that if the PLL is in use the WM9713_PCMCLK_PLL_DIV needs
139 * to be set instead.
140 */
141 ret = snd_soc_dai_set_clkdiv(codec_dai, WM9713_PCMCLK_DIV,
142 WM9713_PCMDIV(wm9713_div));
143 if (ret < 0)
144 return ret;
145
146 return 0;
147}
148
149static struct snd_soc_ops zylonite_voice_ops = {
150 .hw_params = zylonite_voice_hw_params,
151};
152
153static struct snd_soc_dai_link zylonite_dai[] = {
154{
155 .name = "AC97",
156 .stream_name = "AC97 HiFi",
157 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI],
158 .codec_dai = &wm9713_dai[WM9713_DAI_AC97_HIFI],
159 .init = zylonite_wm9713_init,
160},
161{
162 .name = "AC97 Aux",
163 .stream_name = "AC97 Aux",
164 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX],
165 .codec_dai = &wm9713_dai[WM9713_DAI_AC97_AUX],
166},
167{
168 .name = "WM9713 Voice",
169 .stream_name = "WM9713 Voice",
170 .cpu_dai = &pxa_ssp_dai[PXA_DAI_SSP3],
171 .codec_dai = &wm9713_dai[WM9713_DAI_PCM_VOICE],
172 .ops = &zylonite_voice_ops,
173},
174};
175
176static struct snd_soc_card zylonite = {
177 .name = "Zylonite",
178 .platform = &pxa2xx_soc_platform,
179 .dai_link = zylonite_dai,
180 .num_links = ARRAY_SIZE(zylonite_dai),
181};
182
183static struct snd_soc_device zylonite_snd_ac97_devdata = {
184 .card = &zylonite,
185 .codec_dev = &soc_codec_dev_wm9713,
186};
187
188static struct platform_device *zylonite_snd_ac97_device;
189
190static int __init zylonite_init(void)
191{
192 int ret;
193
194 zylonite_snd_ac97_device = platform_device_alloc("soc-audio", -1);
195 if (!zylonite_snd_ac97_device)
196 return -ENOMEM;
197
198 platform_set_drvdata(zylonite_snd_ac97_device,
199 &zylonite_snd_ac97_devdata);
200 zylonite_snd_ac97_devdata.dev = &zylonite_snd_ac97_device->dev;
201
202 ret = platform_device_add(zylonite_snd_ac97_device);
203 if (ret != 0)
204 platform_device_put(zylonite_snd_ac97_device);
205
206 return ret;
207}
208
209static void __exit zylonite_exit(void)
210{
211 platform_device_unregister(zylonite_snd_ac97_device);
212}
213
214module_init(zylonite_init);
215module_exit(zylonite_exit);
216
217MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
218MODULE_DESCRIPTION("ALSA SoC WM9713 Zylonite");
219MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig
index b9f2353effeb..fcd03acf10f6 100644
--- a/sound/soc/s3c24xx/Kconfig
+++ b/sound/soc/s3c24xx/Kconfig
@@ -44,3 +44,8 @@ config SND_S3C24XX_SOC_LN2440SBC_ALC650
44 Say Y if you want to add support for SoC audio on ln2440sbc 44 Say Y if you want to add support for SoC audio on ln2440sbc
45 with the ALC650. 45 with the ALC650.
46 46
47config SND_S3C24XX_SOC_S3C24XX_UDA134X
48 tristate "SoC I2S Audio support UDA134X wired to a S3C24XX"
49 depends on SND_S3C24XX_SOC
50 select SND_S3C24XX_SOC_I2S
51 select SND_SOC_UDA134X
diff --git a/sound/soc/s3c24xx/Makefile b/sound/soc/s3c24xx/Makefile
index 0aa5fb0b9700..96b3f3f617d4 100644
--- a/sound/soc/s3c24xx/Makefile
+++ b/sound/soc/s3c24xx/Makefile
@@ -13,7 +13,9 @@ obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o
13snd-soc-neo1973-wm8753-objs := neo1973_wm8753.o 13snd-soc-neo1973-wm8753-objs := neo1973_wm8753.o
14snd-soc-smdk2443-wm9710-objs := smdk2443_wm9710.o 14snd-soc-smdk2443-wm9710-objs := smdk2443_wm9710.o
15snd-soc-ln2440sbc-alc650-objs := ln2440sbc_alc650.o 15snd-soc-ln2440sbc-alc650-objs := ln2440sbc_alc650.o
16snd-soc-s3c24xx-uda134x-objs := s3c24xx_uda134x.o
16 17
17obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o 18obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o
18obj-$(CONFIG_SND_S3C24XX_SOC_SMDK2443_WM9710) += snd-soc-smdk2443-wm9710.o 19obj-$(CONFIG_SND_S3C24XX_SOC_SMDK2443_WM9710) += snd-soc-smdk2443-wm9710.o
19obj-$(CONFIG_SND_S3C24XX_SOC_LN2440SBC_ALC650) += snd-soc-ln2440sbc-alc650.o 20obj-$(CONFIG_SND_S3C24XX_SOC_LN2440SBC_ALC650) += snd-soc-ln2440sbc-alc650.o
21obj-$(CONFIG_SND_S3C24XX_SOC_S3C24XX_UDA134X) += snd-soc-s3c24xx-uda134x.o
diff --git a/sound/soc/s3c24xx/ln2440sbc_alc650.c b/sound/soc/s3c24xx/ln2440sbc_alc650.c
index 4eab2c19c454..12c71482d258 100644
--- a/sound/soc/s3c24xx/ln2440sbc_alc650.c
+++ b/sound/soc/s3c24xx/ln2440sbc_alc650.c
@@ -27,7 +27,7 @@
27#include "s3c24xx-pcm.h" 27#include "s3c24xx-pcm.h"
28#include "s3c24xx-ac97.h" 28#include "s3c24xx-ac97.h"
29 29
30static struct snd_soc_machine ln2440sbc; 30static struct snd_soc_card ln2440sbc;
31 31
32static struct snd_soc_dai_link ln2440sbc_dai[] = { 32static struct snd_soc_dai_link ln2440sbc_dai[] = {
33{ 33{
@@ -38,15 +38,15 @@ static struct snd_soc_dai_link ln2440sbc_dai[] = {
38}, 38},
39}; 39};
40 40
41static struct snd_soc_machine ln2440sbc = { 41static struct snd_soc_card ln2440sbc = {
42 .name = "LN2440SBC", 42 .name = "LN2440SBC",
43 .platform = &s3c24xx_soc_platform,
43 .dai_link = ln2440sbc_dai, 44 .dai_link = ln2440sbc_dai,
44 .num_links = ARRAY_SIZE(ln2440sbc_dai), 45 .num_links = ARRAY_SIZE(ln2440sbc_dai),
45}; 46};
46 47
47static struct snd_soc_device ln2440sbc_snd_ac97_devdata = { 48static struct snd_soc_device ln2440sbc_snd_ac97_devdata = {
48 .machine = &ln2440sbc, 49 .card = &ln2440sbc,
49 .platform = &s3c24xx_soc_platform,
50 .codec_dev = &soc_codec_dev_ac97, 50 .codec_dev = &soc_codec_dev_ac97,
51}; 51};
52 52
diff --git a/sound/soc/s3c24xx/neo1973_wm8753.c b/sound/soc/s3c24xx/neo1973_wm8753.c
index 87ddfefcc2fb..45bb12e8ea44 100644
--- a/sound/soc/s3c24xx/neo1973_wm8753.c
+++ b/sound/soc/s3c24xx/neo1973_wm8753.c
@@ -59,7 +59,7 @@
59#define NEO_CAPTURE_HEADSET 7 59#define NEO_CAPTURE_HEADSET 7
60#define NEO_CAPTURE_BLUETOOTH 8 60#define NEO_CAPTURE_BLUETOOTH 8
61 61
62static struct snd_soc_machine neo1973; 62static struct snd_soc_card neo1973;
63static struct i2c_client *i2c; 63static struct i2c_client *i2c;
64 64
65static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream, 65static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream,
@@ -548,7 +548,6 @@ static int neo1973_wm8753_init(struct snd_soc_codec *codec)
548static struct snd_soc_dai bt_dai = { 548static struct snd_soc_dai bt_dai = {
549 .name = "Bluetooth", 549 .name = "Bluetooth",
550 .id = 0, 550 .id = 0,
551 .type = SND_SOC_DAI_PCM,
552 .playback = { 551 .playback = {
553 .channels_min = 1, 552 .channels_min = 1,
554 .channels_max = 1, 553 .channels_max = 1,
@@ -579,8 +578,9 @@ static struct snd_soc_dai_link neo1973_dai[] = {
579}, 578},
580}; 579};
581 580
582static struct snd_soc_machine neo1973 = { 581static struct snd_soc_card neo1973 = {
583 .name = "neo1973", 582 .name = "neo1973",
583 .platform = &s3c24xx_soc_platform,
584 .dai_link = neo1973_dai, 584 .dai_link = neo1973_dai,
585 .num_links = ARRAY_SIZE(neo1973_dai), 585 .num_links = ARRAY_SIZE(neo1973_dai),
586}; 586};
@@ -591,8 +591,7 @@ static struct wm8753_setup_data neo1973_wm8753_setup = {
591}; 591};
592 592
593static struct snd_soc_device neo1973_snd_devdata = { 593static struct snd_soc_device neo1973_snd_devdata = {
594 .machine = &neo1973, 594 .card = &neo1973,
595 .platform = &s3c24xx_soc_platform,
596 .codec_dev = &soc_codec_dev_wm8753, 595 .codec_dev = &soc_codec_dev_wm8753,
597 .codec_data = &neo1973_wm8753_setup, 596 .codec_data = &neo1973_wm8753_setup,
598}; 597};
diff --git a/sound/soc/s3c24xx/s3c2412-i2s.c b/sound/soc/s3c24xx/s3c2412-i2s.c
index ded7d995a922..f3fc0aba0aaf 100644
--- a/sound/soc/s3c24xx/s3c2412-i2s.c
+++ b/sound/soc/s3c24xx/s3c2412-i2s.c
@@ -343,7 +343,8 @@ static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
343} 343}
344 344
345static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream, 345static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream,
346 struct snd_pcm_hw_params *params) 346 struct snd_pcm_hw_params *params,
347 struct snd_soc_dai *dai)
347{ 348{
348 struct snd_soc_pcm_runtime *rtd = substream->private_data; 349 struct snd_soc_pcm_runtime *rtd = substream->private_data;
349 u32 iismod; 350 u32 iismod;
@@ -373,7 +374,8 @@ static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream,
373 return 0; 374 return 0;
374} 375}
375 376
376static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd) 377static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
378 struct snd_soc_dai *dai)
377{ 379{
378 int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); 380 int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
379 unsigned long irqs; 381 unsigned long irqs;
@@ -647,8 +649,7 @@ static int s3c2412_i2s_probe(struct platform_device *pdev,
647} 649}
648 650
649#ifdef CONFIG_PM 651#ifdef CONFIG_PM
650static int s3c2412_i2s_suspend(struct platform_device *dev, 652static int s3c2412_i2s_suspend(struct snd_soc_dai *dai)
651 struct snd_soc_dai *dai)
652{ 653{
653 struct s3c2412_i2s_info *i2s = &s3c2412_i2s; 654 struct s3c2412_i2s_info *i2s = &s3c2412_i2s;
654 u32 iismod; 655 u32 iismod;
@@ -663,25 +664,24 @@ static int s3c2412_i2s_suspend(struct platform_device *dev,
663 iismod = readl(i2s->regs + S3C2412_IISMOD); 664 iismod = readl(i2s->regs + S3C2412_IISMOD);
664 665
665 if (iismod & S3C2412_IISCON_RXDMA_ACTIVE) 666 if (iismod & S3C2412_IISCON_RXDMA_ACTIVE)
666 dev_warn(&dev->dev, "%s: RXDMA active?\n", __func__); 667 pr_warning("%s: RXDMA active?\n", __func__);
667 668
668 if (iismod & S3C2412_IISCON_TXDMA_ACTIVE) 669 if (iismod & S3C2412_IISCON_TXDMA_ACTIVE)
669 dev_warn(&dev->dev, "%s: TXDMA active?\n", __func__); 670 pr_warning("%s: TXDMA active?\n", __func__);
670 671
671 if (iismod & S3C2412_IISCON_IIS_ACTIVE) 672 if (iismod & S3C2412_IISCON_IIS_ACTIVE)
672 dev_warn(&dev->dev, "%s: IIS active\n", __func__); 673 pr_warning("%s: IIS active\n", __func__);
673 } 674 }
674 675
675 return 0; 676 return 0;
676} 677}
677 678
678static int s3c2412_i2s_resume(struct platform_device *pdev, 679static int s3c2412_i2s_resume(struct snd_soc_dai *dai)
679 struct snd_soc_dai *dai)
680{ 680{
681 struct s3c2412_i2s_info *i2s = &s3c2412_i2s; 681 struct s3c2412_i2s_info *i2s = &s3c2412_i2s;
682 682
683 dev_info(&pdev->dev, "dai_active %d, IISMOD %08x, IISCON %08x\n", 683 pr_info("dai_active %d, IISMOD %08x, IISCON %08x\n",
684 dai->active, i2s->suspend_iismod, i2s->suspend_iiscon); 684 dai->active, i2s->suspend_iismod, i2s->suspend_iiscon);
685 685
686 if (dai->active) { 686 if (dai->active) {
687 writel(i2s->suspend_iiscon, i2s->regs + S3C2412_IISCON); 687 writel(i2s->suspend_iiscon, i2s->regs + S3C2412_IISCON);
@@ -711,7 +711,6 @@ static int s3c2412_i2s_resume(struct platform_device *pdev,
711struct snd_soc_dai s3c2412_i2s_dai = { 711struct snd_soc_dai s3c2412_i2s_dai = {
712 .name = "s3c2412-i2s", 712 .name = "s3c2412-i2s",
713 .id = 0, 713 .id = 0,
714 .type = SND_SOC_DAI_I2S,
715 .probe = s3c2412_i2s_probe, 714 .probe = s3c2412_i2s_probe,
716 .suspend = s3c2412_i2s_suspend, 715 .suspend = s3c2412_i2s_suspend,
717 .resume = s3c2412_i2s_resume, 716 .resume = s3c2412_i2s_resume,
@@ -730,8 +729,6 @@ struct snd_soc_dai s3c2412_i2s_dai = {
730 .ops = { 729 .ops = {
731 .trigger = s3c2412_i2s_trigger, 730 .trigger = s3c2412_i2s_trigger,
732 .hw_params = s3c2412_i2s_hw_params, 731 .hw_params = s3c2412_i2s_hw_params,
733 },
734 .dai_ops = {
735 .set_fmt = s3c2412_i2s_set_fmt, 732 .set_fmt = s3c2412_i2s_set_fmt,
736 .set_clkdiv = s3c2412_i2s_set_clkdiv, 733 .set_clkdiv = s3c2412_i2s_set_clkdiv,
737 .set_sysclk = s3c2412_i2s_set_sysclk, 734 .set_sysclk = s3c2412_i2s_set_sysclk,
@@ -739,6 +736,19 @@ struct snd_soc_dai s3c2412_i2s_dai = {
739}; 736};
740EXPORT_SYMBOL_GPL(s3c2412_i2s_dai); 737EXPORT_SYMBOL_GPL(s3c2412_i2s_dai);
741 738
739static int __init s3c2412_i2s_init(void)
740{
741 return snd_soc_register_dai(&s3c2412_i2s_dai);
742}
743module_init(s3c2412_i2s_init);
744
745static void __exit s3c2412_i2s_exit(void)
746{
747 snd_soc_unregister_dai(&s3c2412_i2s_dai);
748}
749module_exit(s3c2412_i2s_exit);
750
751
742/* Module information */ 752/* Module information */
743MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); 753MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
744MODULE_DESCRIPTION("S3C2412 I2S SoC Interface"); 754MODULE_DESCRIPTION("S3C2412 I2S SoC Interface");
diff --git a/sound/soc/s3c24xx/s3c2443-ac97.c b/sound/soc/s3c24xx/s3c2443-ac97.c
index 19c5c3cf5d8c..1bfce40bb2e4 100644
--- a/sound/soc/s3c24xx/s3c2443-ac97.c
+++ b/sound/soc/s3c24xx/s3c2443-ac97.c
@@ -271,7 +271,8 @@ static void s3c2443_ac97_remove(struct platform_device *pdev,
271} 271}
272 272
273static int s3c2443_ac97_hw_params(struct snd_pcm_substream *substream, 273static int s3c2443_ac97_hw_params(struct snd_pcm_substream *substream,
274 struct snd_pcm_hw_params *params) 274 struct snd_pcm_hw_params *params,
275 struct snd_soc_dai *dai)
275{ 276{
276 struct snd_soc_pcm_runtime *rtd = substream->private_data; 277 struct snd_soc_pcm_runtime *rtd = substream->private_data;
277 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 278 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -284,7 +285,8 @@ static int s3c2443_ac97_hw_params(struct snd_pcm_substream *substream,
284 return 0; 285 return 0;
285} 286}
286 287
287static int s3c2443_ac97_trigger(struct snd_pcm_substream *substream, int cmd) 288static int s3c2443_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
289 struct snd_soc_dai *dai)
288{ 290{
289 u32 ac_glbctrl; 291 u32 ac_glbctrl;
290 292
@@ -313,7 +315,8 @@ static int s3c2443_ac97_trigger(struct snd_pcm_substream *substream, int cmd)
313} 315}
314 316
315static int s3c2443_ac97_hw_mic_params(struct snd_pcm_substream *substream, 317static int s3c2443_ac97_hw_mic_params(struct snd_pcm_substream *substream,
316 struct snd_pcm_hw_params *params) 318 struct snd_pcm_hw_params *params,
319 struct snd_soc_dai *dai)
317{ 320{
318 struct snd_soc_pcm_runtime *rtd = substream->private_data; 321 struct snd_soc_pcm_runtime *rtd = substream->private_data;
319 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 322 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -327,7 +330,7 @@ static int s3c2443_ac97_hw_mic_params(struct snd_pcm_substream *substream,
327} 330}
328 331
329static int s3c2443_ac97_mic_trigger(struct snd_pcm_substream *substream, 332static int s3c2443_ac97_mic_trigger(struct snd_pcm_substream *substream,
330 int cmd) 333 int cmd, struct snd_soc_dai *dai)
331{ 334{
332 u32 ac_glbctrl; 335 u32 ac_glbctrl;
333 336
@@ -356,7 +359,7 @@ struct snd_soc_dai s3c2443_ac97_dai[] = {
356{ 359{
357 .name = "s3c2443-ac97", 360 .name = "s3c2443-ac97",
358 .id = 0, 361 .id = 0,
359 .type = SND_SOC_DAI_AC97, 362 .ac97_control = 1,
360 .probe = s3c2443_ac97_probe, 363 .probe = s3c2443_ac97_probe,
361 .remove = s3c2443_ac97_remove, 364 .remove = s3c2443_ac97_remove,
362 .playback = { 365 .playback = {
@@ -378,7 +381,7 @@ struct snd_soc_dai s3c2443_ac97_dai[] = {
378{ 381{
379 .name = "pxa2xx-ac97-mic", 382 .name = "pxa2xx-ac97-mic",
380 .id = 1, 383 .id = 1,
381 .type = SND_SOC_DAI_AC97, 384 .ac97_control = 1,
382 .capture = { 385 .capture = {
383 .stream_name = "AC97 Mic Capture", 386 .stream_name = "AC97 Mic Capture",
384 .channels_min = 1, 387 .channels_min = 1,
@@ -393,6 +396,21 @@ struct snd_soc_dai s3c2443_ac97_dai[] = {
393EXPORT_SYMBOL_GPL(s3c2443_ac97_dai); 396EXPORT_SYMBOL_GPL(s3c2443_ac97_dai);
394EXPORT_SYMBOL_GPL(soc_ac97_ops); 397EXPORT_SYMBOL_GPL(soc_ac97_ops);
395 398
399static int __init s3c2443_ac97_init(void)
400{
401 return snd_soc_register_dais(s3c2443_ac97_dai,
402 ARRAY_SIZE(s3c2443_ac97_dai));
403}
404module_init(s3c2443_ac97_init);
405
406static void __exit s3c2443_ac97_exit(void)
407{
408 snd_soc_unregister_dais(s3c2443_ac97_dai,
409 ARRAY_SIZE(s3c2443_ac97_dai));
410}
411module_exit(s3c2443_ac97_exit);
412
413
396MODULE_AUTHOR("Graeme Gregory"); 414MODULE_AUTHOR("Graeme Gregory");
397MODULE_DESCRIPTION("AC97 driver for the Samsung s3c2443 chip"); 415MODULE_DESCRIPTION("AC97 driver for the Samsung s3c2443 chip");
398MODULE_LICENSE("GPL"); 416MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.c b/sound/soc/s3c24xx/s3c24xx-i2s.c
index ba4476b55fbc..6f4d439b57aa 100644
--- a/sound/soc/s3c24xx/s3c24xx-i2s.c
+++ b/sound/soc/s3c24xx/s3c24xx-i2s.c
@@ -243,7 +243,8 @@ static int s3c24xx_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
243} 243}
244 244
245static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream, 245static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream,
246 struct snd_pcm_hw_params *params) 246 struct snd_pcm_hw_params *params,
247 struct snd_soc_dai *dai)
247{ 248{
248 struct snd_soc_pcm_runtime *rtd = substream->private_data; 249 struct snd_soc_pcm_runtime *rtd = substream->private_data;
249 u32 iismod; 250 u32 iismod;
@@ -261,10 +262,17 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream,
261 262
262 switch (params_format(params)) { 263 switch (params_format(params)) {
263 case SNDRV_PCM_FORMAT_S8: 264 case SNDRV_PCM_FORMAT_S8:
265 iismod &= ~S3C2410_IISMOD_16BIT;
266 ((struct s3c24xx_pcm_dma_params *)
267 rtd->dai->cpu_dai->dma_data)->dma_size = 1;
264 break; 268 break;
265 case SNDRV_PCM_FORMAT_S16_LE: 269 case SNDRV_PCM_FORMAT_S16_LE:
266 iismod |= S3C2410_IISMOD_16BIT; 270 iismod |= S3C2410_IISMOD_16BIT;
271 ((struct s3c24xx_pcm_dma_params *)
272 rtd->dai->cpu_dai->dma_data)->dma_size = 2;
267 break; 273 break;
274 default:
275 return -EINVAL;
268 } 276 }
269 277
270 writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); 278 writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD);
@@ -272,7 +280,8 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream,
272 return 0; 280 return 0;
273} 281}
274 282
275static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd) 283static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
284 struct snd_soc_dai *dai)
276{ 285{
277 int ret = 0; 286 int ret = 0;
278 287
@@ -410,8 +419,7 @@ static int s3c24xx_i2s_probe(struct platform_device *pdev,
410} 419}
411 420
412#ifdef CONFIG_PM 421#ifdef CONFIG_PM
413static int s3c24xx_i2s_suspend(struct platform_device *pdev, 422static int s3c24xx_i2s_suspend(struct snd_soc_dai *cpu_dai)
414 struct snd_soc_dai *cpu_dai)
415{ 423{
416 DBG("Entered %s\n", __func__); 424 DBG("Entered %s\n", __func__);
417 425
@@ -425,8 +433,7 @@ static int s3c24xx_i2s_suspend(struct platform_device *pdev,
425 return 0; 433 return 0;
426} 434}
427 435
428static int s3c24xx_i2s_resume(struct platform_device *pdev, 436static int s3c24xx_i2s_resume(struct snd_soc_dai *cpu_dai)
429 struct snd_soc_dai *cpu_dai)
430{ 437{
431 DBG("Entered %s\n", __func__); 438 DBG("Entered %s\n", __func__);
432 clk_enable(s3c24xx_i2s.iis_clk); 439 clk_enable(s3c24xx_i2s.iis_clk);
@@ -452,7 +459,6 @@ static int s3c24xx_i2s_resume(struct platform_device *pdev,
452struct snd_soc_dai s3c24xx_i2s_dai = { 459struct snd_soc_dai s3c24xx_i2s_dai = {
453 .name = "s3c24xx-i2s", 460 .name = "s3c24xx-i2s",
454 .id = 0, 461 .id = 0,
455 .type = SND_SOC_DAI_I2S,
456 .probe = s3c24xx_i2s_probe, 462 .probe = s3c24xx_i2s_probe,
457 .suspend = s3c24xx_i2s_suspend, 463 .suspend = s3c24xx_i2s_suspend,
458 .resume = s3c24xx_i2s_resume, 464 .resume = s3c24xx_i2s_resume,
@@ -468,8 +474,7 @@ struct snd_soc_dai s3c24xx_i2s_dai = {
468 .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE,}, 474 .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE,},
469 .ops = { 475 .ops = {
470 .trigger = s3c24xx_i2s_trigger, 476 .trigger = s3c24xx_i2s_trigger,
471 .hw_params = s3c24xx_i2s_hw_params,}, 477 .hw_params = s3c24xx_i2s_hw_params,
472 .dai_ops = {
473 .set_fmt = s3c24xx_i2s_set_fmt, 478 .set_fmt = s3c24xx_i2s_set_fmt,
474 .set_clkdiv = s3c24xx_i2s_set_clkdiv, 479 .set_clkdiv = s3c24xx_i2s_set_clkdiv,
475 .set_sysclk = s3c24xx_i2s_set_sysclk, 480 .set_sysclk = s3c24xx_i2s_set_sysclk,
@@ -477,6 +482,18 @@ struct snd_soc_dai s3c24xx_i2s_dai = {
477}; 482};
478EXPORT_SYMBOL_GPL(s3c24xx_i2s_dai); 483EXPORT_SYMBOL_GPL(s3c24xx_i2s_dai);
479 484
485static int __init s3c24xx_i2s_init(void)
486{
487 return snd_soc_register_dai(&s3c24xx_i2s_dai);
488}
489module_init(s3c24xx_i2s_init);
490
491static void __exit s3c24xx_i2s_exit(void)
492{
493 snd_soc_unregister_dai(&s3c24xx_i2s_dai);
494}
495module_exit(s3c24xx_i2s_exit);
496
480/* Module information */ 497/* Module information */
481MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); 498MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
482MODULE_DESCRIPTION("s3c24xx I2S SoC Interface"); 499MODULE_DESCRIPTION("s3c24xx I2S SoC Interface");
diff --git a/sound/soc/s3c24xx/s3c24xx-pcm.c b/sound/soc/s3c24xx/s3c24xx-pcm.c
index e13e614bada9..7c64d31d067e 100644
--- a/sound/soc/s3c24xx/s3c24xx-pcm.c
+++ b/sound/soc/s3c24xx/s3c24xx-pcm.c
@@ -465,6 +465,18 @@ struct snd_soc_platform s3c24xx_soc_platform = {
465}; 465};
466EXPORT_SYMBOL_GPL(s3c24xx_soc_platform); 466EXPORT_SYMBOL_GPL(s3c24xx_soc_platform);
467 467
468static int __init s3c24xx_soc_platform_init(void)
469{
470 return snd_soc_register_platform(&s3c24xx_soc_platform);
471}
472module_init(s3c24xx_soc_platform_init);
473
474static void __exit s3c24xx_soc_platform_exit(void)
475{
476 snd_soc_unregister_platform(&s3c24xx_soc_platform);
477}
478module_exit(s3c24xx_soc_platform_exit);
479
468MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); 480MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
469MODULE_DESCRIPTION("Samsung S3C24XX PCM DMA module"); 481MODULE_DESCRIPTION("Samsung S3C24XX PCM DMA module");
470MODULE_LICENSE("GPL"); 482MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/s3c24xx_uda134x.c b/sound/soc/s3c24xx/s3c24xx_uda134x.c
new file mode 100644
index 000000000000..a0a4d1832a14
--- /dev/null
+++ b/sound/soc/s3c24xx/s3c24xx_uda134x.c
@@ -0,0 +1,373 @@
1/*
2 * Modifications by Christian Pellegrin <chripell@evolware.org>
3 *
4 * s3c24xx_uda134x.c -- S3C24XX_UDA134X ALSA SoC Audio board driver
5 *
6 * Copyright 2007 Dension Audio Systems Ltd.
7 * Author: Zoltan Devai
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/module.h>
15#include <linux/clk.h>
16#include <linux/mutex.h>
17#include <linux/gpio.h>
18#include <sound/pcm.h>
19#include <sound/pcm_params.h>
20#include <sound/soc.h>
21#include <sound/soc-dapm.h>
22#include <sound/s3c24xx_uda134x.h>
23#include <sound/uda134x.h>
24
25#include <asm/plat-s3c24xx/regs-iis.h>
26
27#include "s3c24xx-pcm.h"
28#include "s3c24xx-i2s.h"
29#include "../codecs/uda134x.h"
30
31
32/* #define ENFORCE_RATES 1 */
33/*
34 Unfortunately the S3C24XX in master mode has a limited capacity of
35 generating the clock for the codec. If you define this only rates
36 that are really available will be enforced. But be careful, most
37 user level application just want the usual sampling frequencies (8,
38 11.025, 22.050, 44.1 kHz) and anyway resampling is a costly
39 operation for embedded systems. So if you aren't very lucky or your
40 hardware engineer wasn't very forward-looking it's better to leave
41 this undefined. If you do so an approximate value for the requested
42 sampling rate in the range -/+ 5% will be chosen. If this in not
43 possible an error will be returned.
44*/
45
46static struct clk *xtal;
47static struct clk *pclk;
48/* this is need because we don't have a place where to keep the
49 * pointers to the clocks in each substream. We get the clocks only
50 * when we are actually using them so we don't block stuff like
51 * frequency change or oscillator power-off */
52static int clk_users;
53static DEFINE_MUTEX(clk_lock);
54
55static unsigned int rates[33 * 2];
56#ifdef ENFORCE_RATES
57static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
58 .count = ARRAY_SIZE(rates),
59 .list = rates,
60 .mask = 0,
61};
62#endif
63
64static struct platform_device *s3c24xx_uda134x_snd_device;
65
66static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream)
67{
68 int ret = 0;
69#ifdef ENFORCE_RATES
70 struct snd_pcm_runtime *runtime = substream->runtime;;
71#endif
72
73 mutex_lock(&clk_lock);
74 pr_debug("%s %d\n", __func__, clk_users);
75 if (clk_users == 0) {
76 xtal = clk_get(&s3c24xx_uda134x_snd_device->dev, "xtal");
77 if (!xtal) {
78 printk(KERN_ERR "%s cannot get xtal\n", __func__);
79 ret = -EBUSY;
80 } else {
81 pclk = clk_get(&s3c24xx_uda134x_snd_device->dev,
82 "pclk");
83 if (!pclk) {
84 printk(KERN_ERR "%s cannot get pclk\n",
85 __func__);
86 clk_put(xtal);
87 ret = -EBUSY;
88 }
89 }
90 if (!ret) {
91 int i, j;
92
93 for (i = 0; i < 2; i++) {
94 int fs = i ? 256 : 384;
95
96 rates[i*33] = clk_get_rate(xtal) / fs;
97 for (j = 1; j < 33; j++)
98 rates[i*33 + j] = clk_get_rate(pclk) /
99 (j * fs);
100 }
101 }
102 }
103 clk_users += 1;
104 mutex_unlock(&clk_lock);
105 if (!ret) {
106#ifdef ENFORCE_RATES
107 ret = snd_pcm_hw_constraint_list(runtime, 0,
108 SNDRV_PCM_HW_PARAM_RATE,
109 &hw_constraints_rates);
110 if (ret < 0)
111 printk(KERN_ERR "%s cannot set constraints\n",
112 __func__);
113#endif
114 }
115 return ret;
116}
117
118static void s3c24xx_uda134x_shutdown(struct snd_pcm_substream *substream)
119{
120 mutex_lock(&clk_lock);
121 pr_debug("%s %d\n", __func__, clk_users);
122 clk_users -= 1;
123 if (clk_users == 0) {
124 clk_put(xtal);
125 xtal = NULL;
126 clk_put(pclk);
127 pclk = NULL;
128 }
129 mutex_unlock(&clk_lock);
130}
131
132static int s3c24xx_uda134x_hw_params(struct snd_pcm_substream *substream,
133 struct snd_pcm_hw_params *params)
134{
135 struct snd_soc_pcm_runtime *rtd = substream->private_data;
136 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
137 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
138 unsigned int clk = 0;
139 int ret = 0;
140 int clk_source, fs_mode;
141 unsigned long rate = params_rate(params);
142 long err, cerr;
143 unsigned int div;
144 int i, bi;
145
146 err = 999999;
147 bi = 0;
148 for (i = 0; i < 2*33; i++) {
149 cerr = rates[i] - rate;
150 if (cerr < 0)
151 cerr = -cerr;
152 if (cerr < err) {
153 err = cerr;
154 bi = i;
155 }
156 }
157 if (bi / 33 == 1)
158 fs_mode = S3C2410_IISMOD_256FS;
159 else
160 fs_mode = S3C2410_IISMOD_384FS;
161 if (bi % 33 == 0) {
162 clk_source = S3C24XX_CLKSRC_MPLL;
163 div = 1;
164 } else {
165 clk_source = S3C24XX_CLKSRC_PCLK;
166 div = bi % 33;
167 }
168 pr_debug("%s desired rate %lu, %d\n", __func__, rate, bi);
169
170 clk = (fs_mode == S3C2410_IISMOD_384FS ? 384 : 256) * rate;
171 pr_debug("%s will use: %s %s %d sysclk %d err %ld\n", __func__,
172 fs_mode == S3C2410_IISMOD_384FS ? "384FS" : "256FS",
173 clk_source == S3C24XX_CLKSRC_MPLL ? "MPLLin" : "PCLK",
174 div, clk, err);
175
176 if ((err * 100 / rate) > 5) {
177 printk(KERN_ERR "S3C24XX_UDA134X: effective frequency "
178 "too different from desired (%ld%%)\n",
179 err * 100 / rate);
180 return -EINVAL;
181 }
182
183 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
184 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
185 if (ret < 0)
186 return ret;
187
188 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
189 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
190 if (ret < 0)
191 return ret;
192
193 ret = snd_soc_dai_set_sysclk(cpu_dai, clk_source , clk,
194 SND_SOC_CLOCK_IN);
195 if (ret < 0)
196 return ret;
197
198 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK, fs_mode);
199 if (ret < 0)
200 return ret;
201
202 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_BCLK,
203 S3C2410_IISMOD_32FS);
204 if (ret < 0)
205 return ret;
206
207 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER,
208 S3C24XX_PRESCALE(div, div));
209 if (ret < 0)
210 return ret;
211
212 /* set the codec system clock for DAC and ADC */
213 ret = snd_soc_dai_set_sysclk(codec_dai, 0, clk,
214 SND_SOC_CLOCK_OUT);
215 if (ret < 0)
216 return ret;
217
218 return 0;
219}
220
221static struct snd_soc_ops s3c24xx_uda134x_ops = {
222 .startup = s3c24xx_uda134x_startup,
223 .shutdown = s3c24xx_uda134x_shutdown,
224 .hw_params = s3c24xx_uda134x_hw_params,
225};
226
227static struct snd_soc_dai_link s3c24xx_uda134x_dai_link = {
228 .name = "UDA134X",
229 .stream_name = "UDA134X",
230 .codec_dai = &uda134x_dai,
231 .cpu_dai = &s3c24xx_i2s_dai,
232 .ops = &s3c24xx_uda134x_ops,
233};
234
235static struct snd_soc_card snd_soc_s3c24xx_uda134x = {
236 .name = "S3C24XX_UDA134X",
237 .platform = &s3c24xx_soc_platform,
238 .dai_link = &s3c24xx_uda134x_dai_link,
239 .num_links = 1,
240};
241
242static struct s3c24xx_uda134x_platform_data *s3c24xx_uda134x_l3_pins;
243
244static void setdat(int v)
245{
246 gpio_set_value(s3c24xx_uda134x_l3_pins->l3_data, v > 0);
247}
248
249static void setclk(int v)
250{
251 gpio_set_value(s3c24xx_uda134x_l3_pins->l3_clk, v > 0);
252}
253
254static void setmode(int v)
255{
256 gpio_set_value(s3c24xx_uda134x_l3_pins->l3_mode, v > 0);
257}
258
259static struct uda134x_platform_data s3c24xx_uda134x = {
260 .l3 = {
261 .setdat = setdat,
262 .setclk = setclk,
263 .setmode = setmode,
264 .data_hold = 1,
265 .data_setup = 1,
266 .clock_high = 1,
267 .mode_hold = 1,
268 .mode = 1,
269 .mode_setup = 1,
270 },
271};
272
273static struct snd_soc_device s3c24xx_uda134x_snd_devdata = {
274 .card = &snd_soc_s3c24xx_uda134x,
275 .codec_dev = &soc_codec_dev_uda134x,
276 .codec_data = &s3c24xx_uda134x,
277};
278
279static int s3c24xx_uda134x_setup_pin(int pin, char *fun)
280{
281 if (gpio_request(pin, "s3c24xx_uda134x") < 0) {
282 printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: "
283 "l3 %s pin already in use", fun);
284 return -EBUSY;
285 }
286 gpio_direction_output(pin, 0);
287 return 0;
288}
289
290static int s3c24xx_uda134x_probe(struct platform_device *pdev)
291{
292 int ret;
293
294 printk(KERN_INFO "S3C24XX_UDA134X SoC Audio driver\n");
295
296 s3c24xx_uda134x_l3_pins = pdev->dev.platform_data;
297 if (s3c24xx_uda134x_l3_pins == NULL) {
298 printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: "
299 "unable to find platform data\n");
300 return -ENODEV;
301 }
302 s3c24xx_uda134x.power = s3c24xx_uda134x_l3_pins->power;
303 s3c24xx_uda134x.model = s3c24xx_uda134x_l3_pins->model;
304
305 if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_data,
306 "data") < 0)
307 return -EBUSY;
308 if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_clk,
309 "clk") < 0) {
310 gpio_free(s3c24xx_uda134x_l3_pins->l3_data);
311 return -EBUSY;
312 }
313 if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_mode,
314 "mode") < 0) {
315 gpio_free(s3c24xx_uda134x_l3_pins->l3_data);
316 gpio_free(s3c24xx_uda134x_l3_pins->l3_clk);
317 return -EBUSY;
318 }
319
320 s3c24xx_uda134x_snd_device = platform_device_alloc("soc-audio", -1);
321 if (!s3c24xx_uda134x_snd_device) {
322 printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: "
323 "Unable to register\n");
324 return -ENOMEM;
325 }
326
327 platform_set_drvdata(s3c24xx_uda134x_snd_device,
328 &s3c24xx_uda134x_snd_devdata);
329 s3c24xx_uda134x_snd_devdata.dev = &s3c24xx_uda134x_snd_device->dev;
330 ret = platform_device_add(s3c24xx_uda134x_snd_device);
331 if (ret) {
332 printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: Unable to add\n");
333 platform_device_put(s3c24xx_uda134x_snd_device);
334 }
335
336 return ret;
337}
338
339static int s3c24xx_uda134x_remove(struct platform_device *pdev)
340{
341 platform_device_unregister(s3c24xx_uda134x_snd_device);
342 gpio_free(s3c24xx_uda134x_l3_pins->l3_data);
343 gpio_free(s3c24xx_uda134x_l3_pins->l3_clk);
344 gpio_free(s3c24xx_uda134x_l3_pins->l3_mode);
345 return 0;
346}
347
348static struct platform_driver s3c24xx_uda134x_driver = {
349 .probe = s3c24xx_uda134x_probe,
350 .remove = s3c24xx_uda134x_remove,
351 .driver = {
352 .name = "s3c24xx_uda134x",
353 .owner = THIS_MODULE,
354 },
355};
356
357static int __init s3c24xx_uda134x_init(void)
358{
359 return platform_driver_register(&s3c24xx_uda134x_driver);
360}
361
362static void __exit s3c24xx_uda134x_exit(void)
363{
364 platform_driver_unregister(&s3c24xx_uda134x_driver);
365}
366
367
368module_init(s3c24xx_uda134x_init);
369module_exit(s3c24xx_uda134x_exit);
370
371MODULE_AUTHOR("Zoltan Devai, Christian Pellegrin <chripell@evolware.org>");
372MODULE_DESCRIPTION("S3C24XX_UDA134X ALSA SoC audio driver");
373MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/smdk2443_wm9710.c b/sound/soc/s3c24xx/smdk2443_wm9710.c
index 8515d6ff03f2..a2a4f5323c17 100644
--- a/sound/soc/s3c24xx/smdk2443_wm9710.c
+++ b/sound/soc/s3c24xx/smdk2443_wm9710.c
@@ -23,7 +23,7 @@
23#include "s3c24xx-pcm.h" 23#include "s3c24xx-pcm.h"
24#include "s3c24xx-ac97.h" 24#include "s3c24xx-ac97.h"
25 25
26static struct snd_soc_machine smdk2443; 26static struct snd_soc_card smdk2443;
27 27
28static struct snd_soc_dai_link smdk2443_dai[] = { 28static struct snd_soc_dai_link smdk2443_dai[] = {
29{ 29{
@@ -34,15 +34,15 @@ static struct snd_soc_dai_link smdk2443_dai[] = {
34}, 34},
35}; 35};
36 36
37static struct snd_soc_machine smdk2443 = { 37static struct snd_soc_card smdk2443 = {
38 .name = "SMDK2443", 38 .name = "SMDK2443",
39 .platform = &s3c24xx_soc_platform,
39 .dai_link = smdk2443_dai, 40 .dai_link = smdk2443_dai,
40 .num_links = ARRAY_SIZE(smdk2443_dai), 41 .num_links = ARRAY_SIZE(smdk2443_dai),
41}; 42};
42 43
43static struct snd_soc_device smdk2443_snd_ac97_devdata = { 44static struct snd_soc_device smdk2443_snd_ac97_devdata = {
44 .machine = &smdk2443, 45 .card = &smdk2443,
45 .platform = &s3c24xx_soc_platform,
46 .codec_dev = &soc_codec_dev_ac97, 46 .codec_dev = &soc_codec_dev_ac97,
47}; 47};
48 48
diff --git a/sound/soc/sh/dma-sh7760.c b/sound/soc/sh/dma-sh7760.c
index 9faa12622d09..0dad3a0bb920 100644
--- a/sound/soc/sh/dma-sh7760.c
+++ b/sound/soc/sh/dma-sh7760.c
@@ -348,6 +348,18 @@ struct snd_soc_platform sh7760_soc_platform = {
348}; 348};
349EXPORT_SYMBOL_GPL(sh7760_soc_platform); 349EXPORT_SYMBOL_GPL(sh7760_soc_platform);
350 350
351static int __init sh7760_soc_platform_init(void)
352{
353 return snd_soc_register_platform(&sh7760_soc_platform);
354}
355module_init(sh7760_soc_platform_init);
356
357static void __exit sh7760_soc_platform_exit(void)
358{
359 snd_soc_unregister_platform(&sh7760_soc_platform);
360}
361module_exit(sh7760_soc_platform_exit);
362
351MODULE_LICENSE("GPL"); 363MODULE_LICENSE("GPL");
352MODULE_DESCRIPTION("SH7760 Audio DMA (DMABRG) driver"); 364MODULE_DESCRIPTION("SH7760 Audio DMA (DMABRG) driver");
353MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>"); 365MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>");
diff --git a/sound/soc/sh/hac.c b/sound/soc/sh/hac.c
index df7bc345c320..eab31838badf 100644
--- a/sound/soc/sh/hac.c
+++ b/sound/soc/sh/hac.c
@@ -236,7 +236,8 @@ struct snd_ac97_bus_ops soc_ac97_ops = {
236EXPORT_SYMBOL_GPL(soc_ac97_ops); 236EXPORT_SYMBOL_GPL(soc_ac97_ops);
237 237
238static int hac_hw_params(struct snd_pcm_substream *substream, 238static int hac_hw_params(struct snd_pcm_substream *substream,
239 struct snd_pcm_hw_params *params) 239 struct snd_pcm_hw_params *params,
240 struct snd_soc_dai *dai)
240{ 241{
241 struct snd_soc_pcm_runtime *rtd = substream->private_data; 242 struct snd_soc_pcm_runtime *rtd = substream->private_data;
242 struct hac_priv *hac = &hac_cpu_data[rtd->dai->cpu_dai->id]; 243 struct hac_priv *hac = &hac_cpu_data[rtd->dai->cpu_dai->id];
@@ -270,7 +271,7 @@ struct snd_soc_dai sh4_hac_dai[] = {
270{ 271{
271 .name = "HAC0", 272 .name = "HAC0",
272 .id = 0, 273 .id = 0,
273 .type = SND_SOC_DAI_AC97, 274 .ac97_control = 1,
274 .playback = { 275 .playback = {
275 .rates = AC97_RATES, 276 .rates = AC97_RATES,
276 .formats = AC97_FMTS, 277 .formats = AC97_FMTS,
@@ -290,8 +291,8 @@ struct snd_soc_dai sh4_hac_dai[] = {
290#ifdef CONFIG_CPU_SUBTYPE_SH7760 291#ifdef CONFIG_CPU_SUBTYPE_SH7760
291{ 292{
292 .name = "HAC1", 293 .name = "HAC1",
294 .ac97_control = 1,
293 .id = 1, 295 .id = 1,
294 .type = SND_SOC_DAI_AC97,
295 .playback = { 296 .playback = {
296 .rates = AC97_RATES, 297 .rates = AC97_RATES,
297 .formats = AC97_FMTS, 298 .formats = AC97_FMTS,
@@ -313,6 +314,18 @@ struct snd_soc_dai sh4_hac_dai[] = {
313}; 314};
314EXPORT_SYMBOL_GPL(sh4_hac_dai); 315EXPORT_SYMBOL_GPL(sh4_hac_dai);
315 316
317static int __init sh4_hac_init(void)
318{
319 return snd_soc_register_dais(sh4_hac_dai, ARRAY_SIZE(sh4_hac_dai));
320}
321module_init(sh4_hac_init);
322
323static void __exit sh4_hac_exit(void)
324{
325 snd_soc_unregister_dais(sh4_hac_dai, ARRAY_SIZE(sh4_hac_dai));
326}
327module_exit(sh4_hac_exit);
328
316MODULE_LICENSE("GPL"); 329MODULE_LICENSE("GPL");
317MODULE_DESCRIPTION("SuperH onchip HAC (AC97) audio driver"); 330MODULE_DESCRIPTION("SuperH onchip HAC (AC97) audio driver");
318MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>"); 331MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>");
diff --git a/sound/soc/sh/sh7760-ac97.c b/sound/soc/sh/sh7760-ac97.c
index 92bfaf4774a7..ce7f95b59de3 100644
--- a/sound/soc/sh/sh7760-ac97.c
+++ b/sound/soc/sh/sh7760-ac97.c
@@ -38,15 +38,15 @@ static struct snd_soc_dai_link sh7760_ac97_dai = {
38 .ops = NULL, 38 .ops = NULL,
39}; 39};
40 40
41static struct snd_soc_machine sh7760_ac97_soc_machine = { 41static struct snd_soc_card sh7760_ac97_soc_machine = {
42 .name = "SH7760 AC97", 42 .name = "SH7760 AC97",
43 .platform = &sh7760_soc_platform,
43 .dai_link = &sh7760_ac97_dai, 44 .dai_link = &sh7760_ac97_dai,
44 .num_links = 1, 45 .num_links = 1,
45}; 46};
46 47
47static struct snd_soc_device sh7760_ac97_snd_devdata = { 48static struct snd_soc_device sh7760_ac97_snd_devdata = {
48 .machine = &sh7760_ac97_soc_machine, 49 .card = &sh7760_ac97_soc_machine,
49 .platform = &sh7760_soc_platform,
50 .codec_dev = &soc_codec_dev_ac97, 50 .codec_dev = &soc_codec_dev_ac97,
51}; 51};
52 52
diff --git a/sound/soc/sh/ssi.c b/sound/soc/sh/ssi.c
index 55c3464163ab..d1e5390fddeb 100644
--- a/sound/soc/sh/ssi.c
+++ b/sound/soc/sh/ssi.c
@@ -89,7 +89,8 @@ struct ssi_priv {
89 * track usage of the SSI; it is simplex-only so prevent attempts of 89 * track usage of the SSI; it is simplex-only so prevent attempts of
90 * concurrent playback + capture. FIXME: any locking required? 90 * concurrent playback + capture. FIXME: any locking required?
91 */ 91 */
92static int ssi_startup(struct snd_pcm_substream *substream) 92static int ssi_startup(struct snd_pcm_substream *substream,
93 struct snd_soc_dai *dai)
93{ 94{
94 struct snd_soc_pcm_runtime *rtd = substream->private_data; 95 struct snd_soc_pcm_runtime *rtd = substream->private_data;
95 struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id]; 96 struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id];
@@ -101,7 +102,8 @@ static int ssi_startup(struct snd_pcm_substream *substream)
101 return 0; 102 return 0;
102} 103}
103 104
104static void ssi_shutdown(struct snd_pcm_substream *substream) 105static void ssi_shutdown(struct snd_pcm_substream *substream,
106 struct snd_soc_dai *dai)
105{ 107{
106 struct snd_soc_pcm_runtime *rtd = substream->private_data; 108 struct snd_soc_pcm_runtime *rtd = substream->private_data;
107 struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id]; 109 struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id];
@@ -109,7 +111,8 @@ static void ssi_shutdown(struct snd_pcm_substream *substream)
109 ssi->inuse = 0; 111 ssi->inuse = 0;
110} 112}
111 113
112static int ssi_trigger(struct snd_pcm_substream *substream, int cmd) 114static int ssi_trigger(struct snd_pcm_substream *substream, int cmd,
115 struct snd_soc_dai *dai)
113{ 116{
114 struct snd_soc_pcm_runtime *rtd = substream->private_data; 117 struct snd_soc_pcm_runtime *rtd = substream->private_data;
115 struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id]; 118 struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id];
@@ -129,7 +132,8 @@ static int ssi_trigger(struct snd_pcm_substream *substream, int cmd)
129} 132}
130 133
131static int ssi_hw_params(struct snd_pcm_substream *substream, 134static int ssi_hw_params(struct snd_pcm_substream *substream,
132 struct snd_pcm_hw_params *params) 135 struct snd_pcm_hw_params *params,
136 struct snd_soc_dai *dai)
133{ 137{
134 struct snd_soc_pcm_runtime *rtd = substream->private_data; 138 struct snd_soc_pcm_runtime *rtd = substream->private_data;
135 struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id]; 139 struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id];
@@ -336,7 +340,6 @@ struct snd_soc_dai sh4_ssi_dai[] = {
336{ 340{
337 .name = "SSI0", 341 .name = "SSI0",
338 .id = 0, 342 .id = 0,
339 .type = SND_SOC_DAI_I2S,
340 .playback = { 343 .playback = {
341 .rates = SSI_RATES, 344 .rates = SSI_RATES,
342 .formats = SSI_FMTS, 345 .formats = SSI_FMTS,
@@ -354,8 +357,6 @@ struct snd_soc_dai sh4_ssi_dai[] = {
354 .shutdown = ssi_shutdown, 357 .shutdown = ssi_shutdown,
355 .trigger = ssi_trigger, 358 .trigger = ssi_trigger,
356 .hw_params = ssi_hw_params, 359 .hw_params = ssi_hw_params,
357 },
358 .dai_ops = {
359 .set_sysclk = ssi_set_sysclk, 360 .set_sysclk = ssi_set_sysclk,
360 .set_clkdiv = ssi_set_clkdiv, 361 .set_clkdiv = ssi_set_clkdiv,
361 .set_fmt = ssi_set_fmt, 362 .set_fmt = ssi_set_fmt,
@@ -365,7 +366,6 @@ struct snd_soc_dai sh4_ssi_dai[] = {
365{ 366{
366 .name = "SSI1", 367 .name = "SSI1",
367 .id = 1, 368 .id = 1,
368 .type = SND_SOC_DAI_I2S,
369 .playback = { 369 .playback = {
370 .rates = SSI_RATES, 370 .rates = SSI_RATES,
371 .formats = SSI_FMTS, 371 .formats = SSI_FMTS,
@@ -383,8 +383,6 @@ struct snd_soc_dai sh4_ssi_dai[] = {
383 .shutdown = ssi_shutdown, 383 .shutdown = ssi_shutdown,
384 .trigger = ssi_trigger, 384 .trigger = ssi_trigger,
385 .hw_params = ssi_hw_params, 385 .hw_params = ssi_hw_params,
386 },
387 .dai_ops = {
388 .set_sysclk = ssi_set_sysclk, 386 .set_sysclk = ssi_set_sysclk,
389 .set_clkdiv = ssi_set_clkdiv, 387 .set_clkdiv = ssi_set_clkdiv,
390 .set_fmt = ssi_set_fmt, 388 .set_fmt = ssi_set_fmt,
@@ -394,6 +392,18 @@ struct snd_soc_dai sh4_ssi_dai[] = {
394}; 392};
395EXPORT_SYMBOL_GPL(sh4_ssi_dai); 393EXPORT_SYMBOL_GPL(sh4_ssi_dai);
396 394
395static int __init sh4_ssi_init(void)
396{
397 return snd_soc_register_dais(sh4_ssi_dai, ARRAY_SIZE(sh4_ssi_dai));
398}
399module_init(sh4_ssi_init);
400
401static void __exit sh4_ssi_exit(void)
402{
403 snd_soc_unregister_dais(sh4_ssi_dai, ARRAY_SIZE(sh4_ssi_dai));
404}
405module_exit(sh4_ssi_exit);
406
397MODULE_LICENSE("GPL"); 407MODULE_LICENSE("GPL");
398MODULE_DESCRIPTION("SuperH onchip SSI (I2S) audio driver"); 408MODULE_DESCRIPTION("SuperH onchip SSI (I2S) audio driver");
399MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>"); 409MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>");
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 16c7453f4946..b098c0b4c584 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -26,6 +26,7 @@
26#include <linux/delay.h> 26#include <linux/delay.h>
27#include <linux/pm.h> 27#include <linux/pm.h>
28#include <linux/bitops.h> 28#include <linux/bitops.h>
29#include <linux/debugfs.h>
29#include <linux/platform_device.h> 30#include <linux/platform_device.h>
30#include <sound/core.h> 31#include <sound/core.h>
31#include <sound/pcm.h> 32#include <sound/pcm.h>
@@ -34,18 +35,23 @@
34#include <sound/soc-dapm.h> 35#include <sound/soc-dapm.h>
35#include <sound/initval.h> 36#include <sound/initval.h>
36 37
37/* debug */
38#define SOC_DEBUG 0
39#if SOC_DEBUG
40#define dbg(format, arg...) printk(format, ## arg)
41#else
42#define dbg(format, arg...)
43#endif
44
45static DEFINE_MUTEX(pcm_mutex); 38static DEFINE_MUTEX(pcm_mutex);
46static DEFINE_MUTEX(io_mutex); 39static DEFINE_MUTEX(io_mutex);
47static DECLARE_WAIT_QUEUE_HEAD(soc_pm_waitq); 40static DECLARE_WAIT_QUEUE_HEAD(soc_pm_waitq);
48 41
42#ifdef CONFIG_DEBUG_FS
43static struct dentry *debugfs_root;
44#endif
45
46static DEFINE_MUTEX(client_mutex);
47static LIST_HEAD(card_list);
48static LIST_HEAD(dai_list);
49static LIST_HEAD(platform_list);
50static LIST_HEAD(codec_list);
51
52static int snd_soc_register_card(struct snd_soc_card *card);
53static int snd_soc_unregister_card(struct snd_soc_card *card);
54
49/* 55/*
50 * This is a timeout to do a DAPM powerdown after a stream is closed(). 56 * This is a timeout to do a DAPM powerdown after a stream is closed().
51 * It can be used to eliminate pops between different playback streams, e.g. 57 * It can be used to eliminate pops between different playback streams, e.g.
@@ -107,20 +113,6 @@ static int soc_ac97_dev_register(struct snd_soc_codec *codec)
107} 113}
108#endif 114#endif
109 115
110static inline const char *get_dai_name(int type)
111{
112 switch (type) {
113 case SND_SOC_DAI_AC97_BUS:
114 case SND_SOC_DAI_AC97:
115 return "AC97";
116 case SND_SOC_DAI_I2S:
117 return "I2S";
118 case SND_SOC_DAI_PCM:
119 return "PCM";
120 }
121 return NULL;
122}
123
124/* 116/*
125 * Called by ALSA when a PCM substream is opened, the runtime->hw record is 117 * Called by ALSA when a PCM substream is opened, the runtime->hw record is
126 * then initialized and any private data can be allocated. This also calls 118 * then initialized and any private data can be allocated. This also calls
@@ -130,9 +122,10 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
130{ 122{
131 struct snd_soc_pcm_runtime *rtd = substream->private_data; 123 struct snd_soc_pcm_runtime *rtd = substream->private_data;
132 struct snd_soc_device *socdev = rtd->socdev; 124 struct snd_soc_device *socdev = rtd->socdev;
125 struct snd_soc_card *card = socdev->card;
133 struct snd_pcm_runtime *runtime = substream->runtime; 126 struct snd_pcm_runtime *runtime = substream->runtime;
134 struct snd_soc_dai_link *machine = rtd->dai; 127 struct snd_soc_dai_link *machine = rtd->dai;
135 struct snd_soc_platform *platform = socdev->platform; 128 struct snd_soc_platform *platform = card->platform;
136 struct snd_soc_dai *cpu_dai = machine->cpu_dai; 129 struct snd_soc_dai *cpu_dai = machine->cpu_dai;
137 struct snd_soc_dai *codec_dai = machine->codec_dai; 130 struct snd_soc_dai *codec_dai = machine->codec_dai;
138 int ret = 0; 131 int ret = 0;
@@ -141,7 +134,7 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
141 134
142 /* startup the audio subsystem */ 135 /* startup the audio subsystem */
143 if (cpu_dai->ops.startup) { 136 if (cpu_dai->ops.startup) {
144 ret = cpu_dai->ops.startup(substream); 137 ret = cpu_dai->ops.startup(substream, cpu_dai);
145 if (ret < 0) { 138 if (ret < 0) {
146 printk(KERN_ERR "asoc: can't open interface %s\n", 139 printk(KERN_ERR "asoc: can't open interface %s\n",
147 cpu_dai->name); 140 cpu_dai->name);
@@ -158,7 +151,7 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
158 } 151 }
159 152
160 if (codec_dai->ops.startup) { 153 if (codec_dai->ops.startup) {
161 ret = codec_dai->ops.startup(substream); 154 ret = codec_dai->ops.startup(substream, codec_dai);
162 if (ret < 0) { 155 if (ret < 0) {
163 printk(KERN_ERR "asoc: can't open codec %s\n", 156 printk(KERN_ERR "asoc: can't open codec %s\n",
164 codec_dai->name); 157 codec_dai->name);
@@ -228,12 +221,12 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
228 goto machine_err; 221 goto machine_err;
229 } 222 }
230 223
231 dbg("asoc: %s <-> %s info:\n", codec_dai->name, cpu_dai->name); 224 pr_debug("asoc: %s <-> %s info:\n", codec_dai->name, cpu_dai->name);
232 dbg("asoc: rate mask 0x%x\n", runtime->hw.rates); 225 pr_debug("asoc: rate mask 0x%x\n", runtime->hw.rates);
233 dbg("asoc: min ch %d max ch %d\n", runtime->hw.channels_min, 226 pr_debug("asoc: min ch %d max ch %d\n", runtime->hw.channels_min,
234 runtime->hw.channels_max); 227 runtime->hw.channels_max);
235 dbg("asoc: min rate %d max rate %d\n", runtime->hw.rate_min, 228 pr_debug("asoc: min rate %d max rate %d\n", runtime->hw.rate_min,
236 runtime->hw.rate_max); 229 runtime->hw.rate_max);
237 230
238 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 231 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
239 cpu_dai->playback.active = codec_dai->playback.active = 1; 232 cpu_dai->playback.active = codec_dai->playback.active = 1;
@@ -255,7 +248,7 @@ codec_dai_err:
255 248
256platform_err: 249platform_err:
257 if (cpu_dai->ops.shutdown) 250 if (cpu_dai->ops.shutdown)
258 cpu_dai->ops.shutdown(substream); 251 cpu_dai->ops.shutdown(substream, cpu_dai);
259out: 252out:
260 mutex_unlock(&pcm_mutex); 253 mutex_unlock(&pcm_mutex);
261 return ret; 254 return ret;
@@ -268,8 +261,9 @@ out:
268 */ 261 */
269static void close_delayed_work(struct work_struct *work) 262static void close_delayed_work(struct work_struct *work)
270{ 263{
271 struct snd_soc_device *socdev = 264 struct snd_soc_card *card = container_of(work, struct snd_soc_card,
272 container_of(work, struct snd_soc_device, delayed_work.work); 265 delayed_work.work);
266 struct snd_soc_device *socdev = card->socdev;
273 struct snd_soc_codec *codec = socdev->codec; 267 struct snd_soc_codec *codec = socdev->codec;
274 struct snd_soc_dai *codec_dai; 268 struct snd_soc_dai *codec_dai;
275 int i; 269 int i;
@@ -278,18 +272,18 @@ static void close_delayed_work(struct work_struct *work)
278 for (i = 0; i < codec->num_dai; i++) { 272 for (i = 0; i < codec->num_dai; i++) {
279 codec_dai = &codec->dai[i]; 273 codec_dai = &codec->dai[i];
280 274
281 dbg("pop wq checking: %s status: %s waiting: %s\n", 275 pr_debug("pop wq checking: %s status: %s waiting: %s\n",
282 codec_dai->playback.stream_name, 276 codec_dai->playback.stream_name,
283 codec_dai->playback.active ? "active" : "inactive", 277 codec_dai->playback.active ? "active" : "inactive",
284 codec_dai->pop_wait ? "yes" : "no"); 278 codec_dai->pop_wait ? "yes" : "no");
285 279
286 /* are we waiting on this codec DAI stream */ 280 /* are we waiting on this codec DAI stream */
287 if (codec_dai->pop_wait == 1) { 281 if (codec_dai->pop_wait == 1) {
288 282
289 /* Reduce power if no longer active */ 283 /* Reduce power if no longer active */
290 if (codec->active == 0) { 284 if (codec->active == 0) {
291 dbg("pop wq D1 %s %s\n", codec->name, 285 pr_debug("pop wq D1 %s %s\n", codec->name,
292 codec_dai->playback.stream_name); 286 codec_dai->playback.stream_name);
293 snd_soc_dapm_set_bias_level(socdev, 287 snd_soc_dapm_set_bias_level(socdev,
294 SND_SOC_BIAS_PREPARE); 288 SND_SOC_BIAS_PREPARE);
295 } 289 }
@@ -301,8 +295,8 @@ static void close_delayed_work(struct work_struct *work)
301 295
302 /* Fall into standby if no longer active */ 296 /* Fall into standby if no longer active */
303 if (codec->active == 0) { 297 if (codec->active == 0) {
304 dbg("pop wq D3 %s %s\n", codec->name, 298 pr_debug("pop wq D3 %s %s\n", codec->name,
305 codec_dai->playback.stream_name); 299 codec_dai->playback.stream_name);
306 snd_soc_dapm_set_bias_level(socdev, 300 snd_soc_dapm_set_bias_level(socdev,
307 SND_SOC_BIAS_STANDBY); 301 SND_SOC_BIAS_STANDBY);
308 } 302 }
@@ -320,8 +314,9 @@ static int soc_codec_close(struct snd_pcm_substream *substream)
320{ 314{
321 struct snd_soc_pcm_runtime *rtd = substream->private_data; 315 struct snd_soc_pcm_runtime *rtd = substream->private_data;
322 struct snd_soc_device *socdev = rtd->socdev; 316 struct snd_soc_device *socdev = rtd->socdev;
317 struct snd_soc_card *card = socdev->card;
323 struct snd_soc_dai_link *machine = rtd->dai; 318 struct snd_soc_dai_link *machine = rtd->dai;
324 struct snd_soc_platform *platform = socdev->platform; 319 struct snd_soc_platform *platform = card->platform;
325 struct snd_soc_dai *cpu_dai = machine->cpu_dai; 320 struct snd_soc_dai *cpu_dai = machine->cpu_dai;
326 struct snd_soc_dai *codec_dai = machine->codec_dai; 321 struct snd_soc_dai *codec_dai = machine->codec_dai;
327 struct snd_soc_codec *codec = socdev->codec; 322 struct snd_soc_codec *codec = socdev->codec;
@@ -346,10 +341,10 @@ static int soc_codec_close(struct snd_pcm_substream *substream)
346 snd_soc_dai_digital_mute(codec_dai, 1); 341 snd_soc_dai_digital_mute(codec_dai, 1);
347 342
348 if (cpu_dai->ops.shutdown) 343 if (cpu_dai->ops.shutdown)
349 cpu_dai->ops.shutdown(substream); 344 cpu_dai->ops.shutdown(substream, cpu_dai);
350 345
351 if (codec_dai->ops.shutdown) 346 if (codec_dai->ops.shutdown)
352 codec_dai->ops.shutdown(substream); 347 codec_dai->ops.shutdown(substream, codec_dai);
353 348
354 if (machine->ops && machine->ops->shutdown) 349 if (machine->ops && machine->ops->shutdown)
355 machine->ops->shutdown(substream); 350 machine->ops->shutdown(substream);
@@ -361,7 +356,7 @@ static int soc_codec_close(struct snd_pcm_substream *substream)
361 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 356 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
362 /* start delayed pop wq here for playback streams */ 357 /* start delayed pop wq here for playback streams */
363 codec_dai->pop_wait = 1; 358 codec_dai->pop_wait = 1;
364 schedule_delayed_work(&socdev->delayed_work, 359 schedule_delayed_work(&card->delayed_work,
365 msecs_to_jiffies(pmdown_time)); 360 msecs_to_jiffies(pmdown_time));
366 } else { 361 } else {
367 /* capture streams can be powered down now */ 362 /* capture streams can be powered down now */
@@ -387,8 +382,9 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
387{ 382{
388 struct snd_soc_pcm_runtime *rtd = substream->private_data; 383 struct snd_soc_pcm_runtime *rtd = substream->private_data;
389 struct snd_soc_device *socdev = rtd->socdev; 384 struct snd_soc_device *socdev = rtd->socdev;
385 struct snd_soc_card *card = socdev->card;
390 struct snd_soc_dai_link *machine = rtd->dai; 386 struct snd_soc_dai_link *machine = rtd->dai;
391 struct snd_soc_platform *platform = socdev->platform; 387 struct snd_soc_platform *platform = card->platform;
392 struct snd_soc_dai *cpu_dai = machine->cpu_dai; 388 struct snd_soc_dai *cpu_dai = machine->cpu_dai;
393 struct snd_soc_dai *codec_dai = machine->codec_dai; 389 struct snd_soc_dai *codec_dai = machine->codec_dai;
394 struct snd_soc_codec *codec = socdev->codec; 390 struct snd_soc_codec *codec = socdev->codec;
@@ -413,7 +409,7 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
413 } 409 }
414 410
415 if (codec_dai->ops.prepare) { 411 if (codec_dai->ops.prepare) {
416 ret = codec_dai->ops.prepare(substream); 412 ret = codec_dai->ops.prepare(substream, codec_dai);
417 if (ret < 0) { 413 if (ret < 0) {
418 printk(KERN_ERR "asoc: codec DAI prepare error\n"); 414 printk(KERN_ERR "asoc: codec DAI prepare error\n");
419 goto out; 415 goto out;
@@ -421,58 +417,49 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
421 } 417 }
422 418
423 if (cpu_dai->ops.prepare) { 419 if (cpu_dai->ops.prepare) {
424 ret = cpu_dai->ops.prepare(substream); 420 ret = cpu_dai->ops.prepare(substream, cpu_dai);
425 if (ret < 0) { 421 if (ret < 0) {
426 printk(KERN_ERR "asoc: cpu DAI prepare error\n"); 422 printk(KERN_ERR "asoc: cpu DAI prepare error\n");
427 goto out; 423 goto out;
428 } 424 }
429 } 425 }
430 426
431 /* we only want to start a DAPM playback stream if we are not waiting 427 /* cancel any delayed stream shutdown that is pending */
432 * on an existing one stopping */ 428 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
433 if (codec_dai->pop_wait) { 429 codec_dai->pop_wait) {
434 /* we are waiting for the delayed work to start */ 430 codec_dai->pop_wait = 0;
435 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) 431 cancel_delayed_work(&card->delayed_work);
436 snd_soc_dapm_stream_event(socdev->codec, 432 }
437 codec_dai->capture.stream_name,
438 SND_SOC_DAPM_STREAM_START);
439 else {
440 codec_dai->pop_wait = 0;
441 cancel_delayed_work(&socdev->delayed_work);
442 snd_soc_dai_digital_mute(codec_dai, 0);
443 }
444 } else {
445 /* no delayed work - do we need to power up codec */
446 if (codec->bias_level != SND_SOC_BIAS_ON) {
447 433
448 snd_soc_dapm_set_bias_level(socdev, 434 /* do we need to power up codec */
449 SND_SOC_BIAS_PREPARE); 435 if (codec->bias_level != SND_SOC_BIAS_ON) {
436 snd_soc_dapm_set_bias_level(socdev,
437 SND_SOC_BIAS_PREPARE);
450 438
451 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 439 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
452 snd_soc_dapm_stream_event(codec, 440 snd_soc_dapm_stream_event(codec,
453 codec_dai->playback.stream_name, 441 codec_dai->playback.stream_name,
454 SND_SOC_DAPM_STREAM_START); 442 SND_SOC_DAPM_STREAM_START);
455 else 443 else
456 snd_soc_dapm_stream_event(codec, 444 snd_soc_dapm_stream_event(codec,
457 codec_dai->capture.stream_name, 445 codec_dai->capture.stream_name,
458 SND_SOC_DAPM_STREAM_START); 446 SND_SOC_DAPM_STREAM_START);
459 447
460 snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_ON); 448 snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_ON);
461 snd_soc_dai_digital_mute(codec_dai, 0); 449 snd_soc_dai_digital_mute(codec_dai, 0);
462 450
463 } else { 451 } else {
464 /* codec already powered - power on widgets */ 452 /* codec already powered - power on widgets */
465 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 453 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
466 snd_soc_dapm_stream_event(codec, 454 snd_soc_dapm_stream_event(codec,
467 codec_dai->playback.stream_name, 455 codec_dai->playback.stream_name,
468 SND_SOC_DAPM_STREAM_START); 456 SND_SOC_DAPM_STREAM_START);
469 else 457 else
470 snd_soc_dapm_stream_event(codec, 458 snd_soc_dapm_stream_event(codec,
471 codec_dai->capture.stream_name, 459 codec_dai->capture.stream_name,
472 SND_SOC_DAPM_STREAM_START); 460 SND_SOC_DAPM_STREAM_START);
473 461
474 snd_soc_dai_digital_mute(codec_dai, 0); 462 snd_soc_dai_digital_mute(codec_dai, 0);
475 }
476 } 463 }
477 464
478out: 465out:
@@ -491,7 +478,8 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
491 struct snd_soc_pcm_runtime *rtd = substream->private_data; 478 struct snd_soc_pcm_runtime *rtd = substream->private_data;
492 struct snd_soc_device *socdev = rtd->socdev; 479 struct snd_soc_device *socdev = rtd->socdev;
493 struct snd_soc_dai_link *machine = rtd->dai; 480 struct snd_soc_dai_link *machine = rtd->dai;
494 struct snd_soc_platform *platform = socdev->platform; 481 struct snd_soc_card *card = socdev->card;
482 struct snd_soc_platform *platform = card->platform;
495 struct snd_soc_dai *cpu_dai = machine->cpu_dai; 483 struct snd_soc_dai *cpu_dai = machine->cpu_dai;
496 struct snd_soc_dai *codec_dai = machine->codec_dai; 484 struct snd_soc_dai *codec_dai = machine->codec_dai;
497 int ret = 0; 485 int ret = 0;
@@ -507,7 +495,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
507 } 495 }
508 496
509 if (codec_dai->ops.hw_params) { 497 if (codec_dai->ops.hw_params) {
510 ret = codec_dai->ops.hw_params(substream, params); 498 ret = codec_dai->ops.hw_params(substream, params, codec_dai);
511 if (ret < 0) { 499 if (ret < 0) {
512 printk(KERN_ERR "asoc: can't set codec %s hw params\n", 500 printk(KERN_ERR "asoc: can't set codec %s hw params\n",
513 codec_dai->name); 501 codec_dai->name);
@@ -516,7 +504,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
516 } 504 }
517 505
518 if (cpu_dai->ops.hw_params) { 506 if (cpu_dai->ops.hw_params) {
519 ret = cpu_dai->ops.hw_params(substream, params); 507 ret = cpu_dai->ops.hw_params(substream, params, cpu_dai);
520 if (ret < 0) { 508 if (ret < 0) {
521 printk(KERN_ERR "asoc: interface %s hw params failed\n", 509 printk(KERN_ERR "asoc: interface %s hw params failed\n",
522 cpu_dai->name); 510 cpu_dai->name);
@@ -539,11 +527,11 @@ out:
539 527
540platform_err: 528platform_err:
541 if (cpu_dai->ops.hw_free) 529 if (cpu_dai->ops.hw_free)
542 cpu_dai->ops.hw_free(substream); 530 cpu_dai->ops.hw_free(substream, cpu_dai);
543 531
544interface_err: 532interface_err:
545 if (codec_dai->ops.hw_free) 533 if (codec_dai->ops.hw_free)
546 codec_dai->ops.hw_free(substream); 534 codec_dai->ops.hw_free(substream, codec_dai);
547 535
548codec_err: 536codec_err:
549 if (machine->ops && machine->ops->hw_free) 537 if (machine->ops && machine->ops->hw_free)
@@ -561,7 +549,8 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
561 struct snd_soc_pcm_runtime *rtd = substream->private_data; 549 struct snd_soc_pcm_runtime *rtd = substream->private_data;
562 struct snd_soc_device *socdev = rtd->socdev; 550 struct snd_soc_device *socdev = rtd->socdev;
563 struct snd_soc_dai_link *machine = rtd->dai; 551 struct snd_soc_dai_link *machine = rtd->dai;
564 struct snd_soc_platform *platform = socdev->platform; 552 struct snd_soc_card *card = socdev->card;
553 struct snd_soc_platform *platform = card->platform;
565 struct snd_soc_dai *cpu_dai = machine->cpu_dai; 554 struct snd_soc_dai *cpu_dai = machine->cpu_dai;
566 struct snd_soc_dai *codec_dai = machine->codec_dai; 555 struct snd_soc_dai *codec_dai = machine->codec_dai;
567 struct snd_soc_codec *codec = socdev->codec; 556 struct snd_soc_codec *codec = socdev->codec;
@@ -582,10 +571,10 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
582 571
583 /* now free hw params for the DAI's */ 572 /* now free hw params for the DAI's */
584 if (codec_dai->ops.hw_free) 573 if (codec_dai->ops.hw_free)
585 codec_dai->ops.hw_free(substream); 574 codec_dai->ops.hw_free(substream, codec_dai);
586 575
587 if (cpu_dai->ops.hw_free) 576 if (cpu_dai->ops.hw_free)
588 cpu_dai->ops.hw_free(substream); 577 cpu_dai->ops.hw_free(substream, cpu_dai);
589 578
590 mutex_unlock(&pcm_mutex); 579 mutex_unlock(&pcm_mutex);
591 return 0; 580 return 0;
@@ -595,14 +584,15 @@ static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
595{ 584{
596 struct snd_soc_pcm_runtime *rtd = substream->private_data; 585 struct snd_soc_pcm_runtime *rtd = substream->private_data;
597 struct snd_soc_device *socdev = rtd->socdev; 586 struct snd_soc_device *socdev = rtd->socdev;
587 struct snd_soc_card *card= socdev->card;
598 struct snd_soc_dai_link *machine = rtd->dai; 588 struct snd_soc_dai_link *machine = rtd->dai;
599 struct snd_soc_platform *platform = socdev->platform; 589 struct snd_soc_platform *platform = card->platform;
600 struct snd_soc_dai *cpu_dai = machine->cpu_dai; 590 struct snd_soc_dai *cpu_dai = machine->cpu_dai;
601 struct snd_soc_dai *codec_dai = machine->codec_dai; 591 struct snd_soc_dai *codec_dai = machine->codec_dai;
602 int ret; 592 int ret;
603 593
604 if (codec_dai->ops.trigger) { 594 if (codec_dai->ops.trigger) {
605 ret = codec_dai->ops.trigger(substream, cmd); 595 ret = codec_dai->ops.trigger(substream, cmd, codec_dai);
606 if (ret < 0) 596 if (ret < 0)
607 return ret; 597 return ret;
608 } 598 }
@@ -614,7 +604,7 @@ static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
614 } 604 }
615 605
616 if (cpu_dai->ops.trigger) { 606 if (cpu_dai->ops.trigger) {
617 ret = cpu_dai->ops.trigger(substream, cmd); 607 ret = cpu_dai->ops.trigger(substream, cmd, cpu_dai);
618 if (ret < 0) 608 if (ret < 0)
619 return ret; 609 return ret;
620 } 610 }
@@ -636,8 +626,8 @@ static struct snd_pcm_ops soc_pcm_ops = {
636static int soc_suspend(struct platform_device *pdev, pm_message_t state) 626static int soc_suspend(struct platform_device *pdev, pm_message_t state)
637{ 627{
638 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 628 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
639 struct snd_soc_machine *machine = socdev->machine; 629 struct snd_soc_card *card = socdev->card;
640 struct snd_soc_platform *platform = socdev->platform; 630 struct snd_soc_platform *platform = card->platform;
641 struct snd_soc_codec_device *codec_dev = socdev->codec_dev; 631 struct snd_soc_codec_device *codec_dev = socdev->codec_dev;
642 struct snd_soc_codec *codec = socdev->codec; 632 struct snd_soc_codec *codec = socdev->codec;
643 int i; 633 int i;
@@ -653,29 +643,29 @@ static int soc_suspend(struct platform_device *pdev, pm_message_t state)
653 snd_power_change_state(codec->card, SNDRV_CTL_POWER_D3hot); 643 snd_power_change_state(codec->card, SNDRV_CTL_POWER_D3hot);
654 644
655 /* mute any active DAC's */ 645 /* mute any active DAC's */
656 for (i = 0; i < machine->num_links; i++) { 646 for (i = 0; i < card->num_links; i++) {
657 struct snd_soc_dai *dai = machine->dai_link[i].codec_dai; 647 struct snd_soc_dai *dai = card->dai_link[i].codec_dai;
658 if (dai->dai_ops.digital_mute && dai->playback.active) 648 if (dai->ops.digital_mute && dai->playback.active)
659 dai->dai_ops.digital_mute(dai, 1); 649 dai->ops.digital_mute(dai, 1);
660 } 650 }
661 651
662 /* suspend all pcms */ 652 /* suspend all pcms */
663 for (i = 0; i < machine->num_links; i++) 653 for (i = 0; i < card->num_links; i++)
664 snd_pcm_suspend_all(machine->dai_link[i].pcm); 654 snd_pcm_suspend_all(card->dai_link[i].pcm);
665 655
666 if (machine->suspend_pre) 656 if (card->suspend_pre)
667 machine->suspend_pre(pdev, state); 657 card->suspend_pre(pdev, state);
668 658
669 for (i = 0; i < machine->num_links; i++) { 659 for (i = 0; i < card->num_links; i++) {
670 struct snd_soc_dai *cpu_dai = machine->dai_link[i].cpu_dai; 660 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;
671 if (cpu_dai->suspend && cpu_dai->type != SND_SOC_DAI_AC97) 661 if (cpu_dai->suspend && !cpu_dai->ac97_control)
672 cpu_dai->suspend(pdev, cpu_dai); 662 cpu_dai->suspend(cpu_dai);
673 if (platform->suspend) 663 if (platform->suspend)
674 platform->suspend(pdev, cpu_dai); 664 platform->suspend(cpu_dai);
675 } 665 }
676 666
677 /* close any waiting streams and save state */ 667 /* close any waiting streams and save state */
678 run_delayed_work(&socdev->delayed_work); 668 run_delayed_work(&card->delayed_work);
679 codec->suspend_bias_level = codec->bias_level; 669 codec->suspend_bias_level = codec->bias_level;
680 670
681 for (i = 0; i < codec->num_dai; i++) { 671 for (i = 0; i < codec->num_dai; i++) {
@@ -692,14 +682,14 @@ static int soc_suspend(struct platform_device *pdev, pm_message_t state)
692 if (codec_dev->suspend) 682 if (codec_dev->suspend)
693 codec_dev->suspend(pdev, state); 683 codec_dev->suspend(pdev, state);
694 684
695 for (i = 0; i < machine->num_links; i++) { 685 for (i = 0; i < card->num_links; i++) {
696 struct snd_soc_dai *cpu_dai = machine->dai_link[i].cpu_dai; 686 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;
697 if (cpu_dai->suspend && cpu_dai->type == SND_SOC_DAI_AC97) 687 if (cpu_dai->suspend && cpu_dai->ac97_control)
698 cpu_dai->suspend(pdev, cpu_dai); 688 cpu_dai->suspend(cpu_dai);
699 } 689 }
700 690
701 if (machine->suspend_post) 691 if (card->suspend_post)
702 machine->suspend_post(pdev, state); 692 card->suspend_post(pdev, state);
703 693
704 return 0; 694 return 0;
705} 695}
@@ -709,11 +699,11 @@ static int soc_suspend(struct platform_device *pdev, pm_message_t state)
709 */ 699 */
710static void soc_resume_deferred(struct work_struct *work) 700static void soc_resume_deferred(struct work_struct *work)
711{ 701{
712 struct snd_soc_device *socdev = container_of(work, 702 struct snd_soc_card *card = container_of(work,
713 struct snd_soc_device, 703 struct snd_soc_card,
714 deferred_resume_work); 704 deferred_resume_work);
715 struct snd_soc_machine *machine = socdev->machine; 705 struct snd_soc_device *socdev = card->socdev;
716 struct snd_soc_platform *platform = socdev->platform; 706 struct snd_soc_platform *platform = card->platform;
717 struct snd_soc_codec_device *codec_dev = socdev->codec_dev; 707 struct snd_soc_codec_device *codec_dev = socdev->codec_dev;
718 struct snd_soc_codec *codec = socdev->codec; 708 struct snd_soc_codec *codec = socdev->codec;
719 struct platform_device *pdev = to_platform_device(socdev->dev); 709 struct platform_device *pdev = to_platform_device(socdev->dev);
@@ -723,15 +713,15 @@ static void soc_resume_deferred(struct work_struct *work)
723 * so userspace apps are blocked from touching us 713 * so userspace apps are blocked from touching us
724 */ 714 */
725 715
726 dev_info(socdev->dev, "starting resume work\n"); 716 dev_dbg(socdev->dev, "starting resume work\n");
727 717
728 if (machine->resume_pre) 718 if (card->resume_pre)
729 machine->resume_pre(pdev); 719 card->resume_pre(pdev);
730 720
731 for (i = 0; i < machine->num_links; i++) { 721 for (i = 0; i < card->num_links; i++) {
732 struct snd_soc_dai *cpu_dai = machine->dai_link[i].cpu_dai; 722 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;
733 if (cpu_dai->resume && cpu_dai->type == SND_SOC_DAI_AC97) 723 if (cpu_dai->resume && cpu_dai->ac97_control)
734 cpu_dai->resume(pdev, cpu_dai); 724 cpu_dai->resume(cpu_dai);
735 } 725 }
736 726
737 if (codec_dev->resume) 727 if (codec_dev->resume)
@@ -749,24 +739,24 @@ static void soc_resume_deferred(struct work_struct *work)
749 } 739 }
750 740
751 /* unmute any active DACs */ 741 /* unmute any active DACs */
752 for (i = 0; i < machine->num_links; i++) { 742 for (i = 0; i < card->num_links; i++) {
753 struct snd_soc_dai *dai = machine->dai_link[i].codec_dai; 743 struct snd_soc_dai *dai = card->dai_link[i].codec_dai;
754 if (dai->dai_ops.digital_mute && dai->playback.active) 744 if (dai->ops.digital_mute && dai->playback.active)
755 dai->dai_ops.digital_mute(dai, 0); 745 dai->ops.digital_mute(dai, 0);
756 } 746 }
757 747
758 for (i = 0; i < machine->num_links; i++) { 748 for (i = 0; i < card->num_links; i++) {
759 struct snd_soc_dai *cpu_dai = machine->dai_link[i].cpu_dai; 749 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;
760 if (cpu_dai->resume && cpu_dai->type != SND_SOC_DAI_AC97) 750 if (cpu_dai->resume && !cpu_dai->ac97_control)
761 cpu_dai->resume(pdev, cpu_dai); 751 cpu_dai->resume(cpu_dai);
762 if (platform->resume) 752 if (platform->resume)
763 platform->resume(pdev, cpu_dai); 753 platform->resume(cpu_dai);
764 } 754 }
765 755
766 if (machine->resume_post) 756 if (card->resume_post)
767 machine->resume_post(pdev); 757 card->resume_post(pdev);
768 758
769 dev_info(socdev->dev, "resume work completed\n"); 759 dev_dbg(socdev->dev, "resume work completed\n");
770 760
771 /* userspace can access us now we are back as we were before */ 761 /* userspace can access us now we are back as we were before */
772 snd_power_change_state(codec->card, SNDRV_CTL_POWER_D0); 762 snd_power_change_state(codec->card, SNDRV_CTL_POWER_D0);
@@ -776,11 +766,12 @@ static void soc_resume_deferred(struct work_struct *work)
776static int soc_resume(struct platform_device *pdev) 766static int soc_resume(struct platform_device *pdev)
777{ 767{
778 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 768 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
769 struct snd_soc_card *card = socdev->card;
779 770
780 dev_info(socdev->dev, "scheduling resume work\n"); 771 dev_dbg(socdev->dev, "scheduling resume work\n");
781 772
782 if (!schedule_work(&socdev->deferred_resume_work)) 773 if (!schedule_work(&card->deferred_resume_work))
783 dev_err(socdev->dev, "work item may be lost\n"); 774 dev_err(socdev->dev, "resume work item may be lost\n");
784 775
785 return 0; 776 return 0;
786} 777}
@@ -790,23 +781,83 @@ static int soc_resume(struct platform_device *pdev)
790#define soc_resume NULL 781#define soc_resume NULL
791#endif 782#endif
792 783
793/* probes a new socdev */ 784static void snd_soc_instantiate_card(struct snd_soc_card *card)
794static int soc_probe(struct platform_device *pdev)
795{ 785{
796 int ret = 0, i; 786 struct platform_device *pdev = container_of(card->dev,
797 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 787 struct platform_device,
798 struct snd_soc_machine *machine = socdev->machine; 788 dev);
799 struct snd_soc_platform *platform = socdev->platform; 789 struct snd_soc_codec_device *codec_dev = card->socdev->codec_dev;
800 struct snd_soc_codec_device *codec_dev = socdev->codec_dev; 790 struct snd_soc_platform *platform;
791 struct snd_soc_dai *dai;
792 int i, found, ret, ac97;
793
794 if (card->instantiated)
795 return;
796
797 found = 0;
798 list_for_each_entry(platform, &platform_list, list)
799 if (card->platform == platform) {
800 found = 1;
801 break;
802 }
803 if (!found) {
804 dev_dbg(card->dev, "Platform %s not registered\n",
805 card->platform->name);
806 return;
807 }
808
809 ac97 = 0;
810 for (i = 0; i < card->num_links; i++) {
811 found = 0;
812 list_for_each_entry(dai, &dai_list, list)
813 if (card->dai_link[i].cpu_dai == dai) {
814 found = 1;
815 break;
816 }
817 if (!found) {
818 dev_dbg(card->dev, "DAI %s not registered\n",
819 card->dai_link[i].cpu_dai->name);
820 return;
821 }
801 822
802 if (machine->probe) { 823 if (card->dai_link[i].cpu_dai->ac97_control)
803 ret = machine->probe(pdev); 824 ac97 = 1;
825 }
826
827 /* If we have AC97 in the system then don't wait for the
828 * codec. This will need revisiting if we have to handle
829 * systems with mixed AC97 and non-AC97 parts. Only check for
830 * DAIs currently; we can't do this per link since some AC97
831 * codecs have non-AC97 DAIs.
832 */
833 if (!ac97)
834 for (i = 0; i < card->num_links; i++) {
835 found = 0;
836 list_for_each_entry(dai, &dai_list, list)
837 if (card->dai_link[i].codec_dai == dai) {
838 found = 1;
839 break;
840 }
841 if (!found) {
842 dev_dbg(card->dev, "DAI %s not registered\n",
843 card->dai_link[i].codec_dai->name);
844 return;
845 }
846 }
847
848 /* Note that we do not current check for codec components */
849
850 dev_dbg(card->dev, "All components present, instantiating\n");
851
852 /* Found everything, bring it up */
853 if (card->probe) {
854 ret = card->probe(pdev);
804 if (ret < 0) 855 if (ret < 0)
805 return ret; 856 return;
806 } 857 }
807 858
808 for (i = 0; i < machine->num_links; i++) { 859 for (i = 0; i < card->num_links; i++) {
809 struct snd_soc_dai *cpu_dai = machine->dai_link[i].cpu_dai; 860 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;
810 if (cpu_dai->probe) { 861 if (cpu_dai->probe) {
811 ret = cpu_dai->probe(pdev, cpu_dai); 862 ret = cpu_dai->probe(pdev, cpu_dai);
812 if (ret < 0) 863 if (ret < 0)
@@ -827,13 +878,15 @@ static int soc_probe(struct platform_device *pdev)
827 } 878 }
828 879
829 /* DAPM stream work */ 880 /* DAPM stream work */
830 INIT_DELAYED_WORK(&socdev->delayed_work, close_delayed_work); 881 INIT_DELAYED_WORK(&card->delayed_work, close_delayed_work);
831#ifdef CONFIG_PM 882#ifdef CONFIG_PM
832 /* deferred resume work */ 883 /* deferred resume work */
833 INIT_WORK(&socdev->deferred_resume_work, soc_resume_deferred); 884 INIT_WORK(&card->deferred_resume_work, soc_resume_deferred);
834#endif 885#endif
835 886
836 return 0; 887 card->instantiated = 1;
888
889 return;
837 890
838platform_err: 891platform_err:
839 if (codec_dev->remove) 892 if (codec_dev->remove)
@@ -841,15 +894,45 @@ platform_err:
841 894
842cpu_dai_err: 895cpu_dai_err:
843 for (i--; i >= 0; i--) { 896 for (i--; i >= 0; i--) {
844 struct snd_soc_dai *cpu_dai = machine->dai_link[i].cpu_dai; 897 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;
845 if (cpu_dai->remove) 898 if (cpu_dai->remove)
846 cpu_dai->remove(pdev, cpu_dai); 899 cpu_dai->remove(pdev, cpu_dai);
847 } 900 }
848 901
849 if (machine->remove) 902 if (card->remove)
850 machine->remove(pdev); 903 card->remove(pdev);
904}
851 905
852 return ret; 906/*
907 * Attempt to initialise any uninitalised cards. Must be called with
908 * client_mutex.
909 */
910static void snd_soc_instantiate_cards(void)
911{
912 struct snd_soc_card *card;
913 list_for_each_entry(card, &card_list, list)
914 snd_soc_instantiate_card(card);
915}
916
917/* probes a new socdev */
918static int soc_probe(struct platform_device *pdev)
919{
920 int ret = 0;
921 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
922 struct snd_soc_card *card = socdev->card;
923
924 /* Bodge while we push things out of socdev */
925 card->socdev = socdev;
926
927 /* Bodge while we unpick instantiation */
928 card->dev = &pdev->dev;
929 ret = snd_soc_register_card(card);
930 if (ret != 0) {
931 dev_err(&pdev->dev, "Failed to register card\n");
932 return ret;
933 }
934
935 return 0;
853} 936}
854 937
855/* removes a socdev */ 938/* removes a socdev */
@@ -857,11 +940,11 @@ static int soc_remove(struct platform_device *pdev)
857{ 940{
858 int i; 941 int i;
859 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 942 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
860 struct snd_soc_machine *machine = socdev->machine; 943 struct snd_soc_card *card = socdev->card;
861 struct snd_soc_platform *platform = socdev->platform; 944 struct snd_soc_platform *platform = card->platform;
862 struct snd_soc_codec_device *codec_dev = socdev->codec_dev; 945 struct snd_soc_codec_device *codec_dev = socdev->codec_dev;
863 946
864 run_delayed_work(&socdev->delayed_work); 947 run_delayed_work(&card->delayed_work);
865 948
866 if (platform->remove) 949 if (platform->remove)
867 platform->remove(pdev); 950 platform->remove(pdev);
@@ -869,14 +952,16 @@ static int soc_remove(struct platform_device *pdev)
869 if (codec_dev->remove) 952 if (codec_dev->remove)
870 codec_dev->remove(pdev); 953 codec_dev->remove(pdev);
871 954
872 for (i = 0; i < machine->num_links; i++) { 955 for (i = 0; i < card->num_links; i++) {
873 struct snd_soc_dai *cpu_dai = machine->dai_link[i].cpu_dai; 956 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;
874 if (cpu_dai->remove) 957 if (cpu_dai->remove)
875 cpu_dai->remove(pdev, cpu_dai); 958 cpu_dai->remove(pdev, cpu_dai);
876 } 959 }
877 960
878 if (machine->remove) 961 if (card->remove)
879 machine->remove(pdev); 962 card->remove(pdev);
963
964 snd_soc_unregister_card(card);
880 965
881 return 0; 966 return 0;
882} 967}
@@ -898,6 +983,8 @@ static int soc_new_pcm(struct snd_soc_device *socdev,
898 struct snd_soc_dai_link *dai_link, int num) 983 struct snd_soc_dai_link *dai_link, int num)
899{ 984{
900 struct snd_soc_codec *codec = socdev->codec; 985 struct snd_soc_codec *codec = socdev->codec;
986 struct snd_soc_card *card = socdev->card;
987 struct snd_soc_platform *platform = card->platform;
901 struct snd_soc_dai *codec_dai = dai_link->codec_dai; 988 struct snd_soc_dai *codec_dai = dai_link->codec_dai;
902 struct snd_soc_dai *cpu_dai = dai_link->cpu_dai; 989 struct snd_soc_dai *cpu_dai = dai_link->cpu_dai;
903 struct snd_soc_pcm_runtime *rtd; 990 struct snd_soc_pcm_runtime *rtd;
@@ -914,8 +1001,8 @@ static int soc_new_pcm(struct snd_soc_device *socdev,
914 codec_dai->codec = socdev->codec; 1001 codec_dai->codec = socdev->codec;
915 1002
916 /* check client and interface hw capabilities */ 1003 /* check client and interface hw capabilities */
917 sprintf(new_name, "%s %s-%s-%d", dai_link->stream_name, codec_dai->name, 1004 sprintf(new_name, "%s %s-%d", dai_link->stream_name, codec_dai->name,
918 get_dai_name(cpu_dai->type), num); 1005 num);
919 1006
920 if (codec_dai->playback.channels_min) 1007 if (codec_dai->playback.channels_min)
921 playback = 1; 1008 playback = 1;
@@ -933,13 +1020,13 @@ static int soc_new_pcm(struct snd_soc_device *socdev,
933 1020
934 dai_link->pcm = pcm; 1021 dai_link->pcm = pcm;
935 pcm->private_data = rtd; 1022 pcm->private_data = rtd;
936 soc_pcm_ops.mmap = socdev->platform->pcm_ops->mmap; 1023 soc_pcm_ops.mmap = platform->pcm_ops->mmap;
937 soc_pcm_ops.pointer = socdev->platform->pcm_ops->pointer; 1024 soc_pcm_ops.pointer = platform->pcm_ops->pointer;
938 soc_pcm_ops.ioctl = socdev->platform->pcm_ops->ioctl; 1025 soc_pcm_ops.ioctl = platform->pcm_ops->ioctl;
939 soc_pcm_ops.copy = socdev->platform->pcm_ops->copy; 1026 soc_pcm_ops.copy = platform->pcm_ops->copy;
940 soc_pcm_ops.silence = socdev->platform->pcm_ops->silence; 1027 soc_pcm_ops.silence = platform->pcm_ops->silence;
941 soc_pcm_ops.ack = socdev->platform->pcm_ops->ack; 1028 soc_pcm_ops.ack = platform->pcm_ops->ack;
942 soc_pcm_ops.page = socdev->platform->pcm_ops->page; 1029 soc_pcm_ops.page = platform->pcm_ops->page;
943 1030
944 if (playback) 1031 if (playback)
945 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &soc_pcm_ops); 1032 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &soc_pcm_ops);
@@ -947,24 +1034,22 @@ static int soc_new_pcm(struct snd_soc_device *socdev,
947 if (capture) 1034 if (capture)
948 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &soc_pcm_ops); 1035 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &soc_pcm_ops);
949 1036
950 ret = socdev->platform->pcm_new(codec->card, codec_dai, pcm); 1037 ret = platform->pcm_new(codec->card, codec_dai, pcm);
951 if (ret < 0) { 1038 if (ret < 0) {
952 printk(KERN_ERR "asoc: platform pcm constructor failed\n"); 1039 printk(KERN_ERR "asoc: platform pcm constructor failed\n");
953 kfree(rtd); 1040 kfree(rtd);
954 return ret; 1041 return ret;
955 } 1042 }
956 1043
957 pcm->private_free = socdev->platform->pcm_free; 1044 pcm->private_free = platform->pcm_free;
958 printk(KERN_INFO "asoc: %s <-> %s mapping ok\n", codec_dai->name, 1045 printk(KERN_INFO "asoc: %s <-> %s mapping ok\n", codec_dai->name,
959 cpu_dai->name); 1046 cpu_dai->name);
960 return ret; 1047 return ret;
961} 1048}
962 1049
963/* codec register dump */ 1050/* codec register dump */
964static ssize_t codec_reg_show(struct device *dev, 1051static ssize_t soc_codec_reg_show(struct snd_soc_device *devdata, char *buf)
965 struct device_attribute *attr, char *buf)
966{ 1052{
967 struct snd_soc_device *devdata = dev_get_drvdata(dev);
968 struct snd_soc_codec *codec = devdata->codec; 1053 struct snd_soc_codec *codec = devdata->codec;
969 int i, step = 1, count = 0; 1054 int i, step = 1, count = 0;
970 1055
@@ -1001,8 +1086,110 @@ static ssize_t codec_reg_show(struct device *dev,
1001 1086
1002 return count; 1087 return count;
1003} 1088}
1089static ssize_t codec_reg_show(struct device *dev,
1090 struct device_attribute *attr, char *buf)
1091{
1092 struct snd_soc_device *devdata = dev_get_drvdata(dev);
1093 return soc_codec_reg_show(devdata, buf);
1094}
1095
1004static DEVICE_ATTR(codec_reg, 0444, codec_reg_show, NULL); 1096static DEVICE_ATTR(codec_reg, 0444, codec_reg_show, NULL);
1005 1097
1098#ifdef CONFIG_DEBUG_FS
1099static int codec_reg_open_file(struct inode *inode, struct file *file)
1100{
1101 file->private_data = inode->i_private;
1102 return 0;
1103}
1104
1105static ssize_t codec_reg_read_file(struct file *file, char __user *user_buf,
1106 size_t count, loff_t *ppos)
1107{
1108 ssize_t ret;
1109 struct snd_soc_codec *codec = file->private_data;
1110 struct device *card_dev = codec->card->dev;
1111 struct snd_soc_device *devdata = card_dev->driver_data;
1112 char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
1113 if (!buf)
1114 return -ENOMEM;
1115 ret = soc_codec_reg_show(devdata, buf);
1116 if (ret >= 0)
1117 ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
1118 kfree(buf);
1119 return ret;
1120}
1121
1122static ssize_t codec_reg_write_file(struct file *file,
1123 const char __user *user_buf, size_t count, loff_t *ppos)
1124{
1125 char buf[32];
1126 int buf_size;
1127 char *start = buf;
1128 unsigned long reg, value;
1129 int step = 1;
1130 struct snd_soc_codec *codec = file->private_data;
1131
1132 buf_size = min(count, (sizeof(buf)-1));
1133 if (copy_from_user(buf, user_buf, buf_size))
1134 return -EFAULT;
1135 buf[buf_size] = 0;
1136
1137 if (codec->reg_cache_step)
1138 step = codec->reg_cache_step;
1139
1140 while (*start == ' ')
1141 start++;
1142 reg = simple_strtoul(start, &start, 16);
1143 if ((reg >= codec->reg_cache_size) || (reg % step))
1144 return -EINVAL;
1145 while (*start == ' ')
1146 start++;
1147 if (strict_strtoul(start, 16, &value))
1148 return -EINVAL;
1149 codec->write(codec, reg, value);
1150 return buf_size;
1151}
1152
1153static const struct file_operations codec_reg_fops = {
1154 .open = codec_reg_open_file,
1155 .read = codec_reg_read_file,
1156 .write = codec_reg_write_file,
1157};
1158
1159static void soc_init_codec_debugfs(struct snd_soc_codec *codec)
1160{
1161 codec->debugfs_reg = debugfs_create_file("codec_reg", 0644,
1162 debugfs_root, codec,
1163 &codec_reg_fops);
1164 if (!codec->debugfs_reg)
1165 printk(KERN_WARNING
1166 "ASoC: Failed to create codec register debugfs file\n");
1167
1168 codec->debugfs_pop_time = debugfs_create_u32("dapm_pop_time", 0744,
1169 debugfs_root,
1170 &codec->pop_time);
1171 if (!codec->debugfs_pop_time)
1172 printk(KERN_WARNING
1173 "Failed to create pop time debugfs file\n");
1174}
1175
1176static void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
1177{
1178 debugfs_remove(codec->debugfs_pop_time);
1179 debugfs_remove(codec->debugfs_reg);
1180}
1181
1182#else
1183
1184static inline void soc_init_codec_debugfs(struct snd_soc_codec *codec)
1185{
1186}
1187
1188static inline void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
1189{
1190}
1191#endif
1192
1006/** 1193/**
1007 * snd_soc_new_ac97_codec - initailise AC97 device 1194 * snd_soc_new_ac97_codec - initailise AC97 device
1008 * @codec: audio codec 1195 * @codec: audio codec
@@ -1121,7 +1308,7 @@ EXPORT_SYMBOL_GPL(snd_soc_test_bits);
1121int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid) 1308int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid)
1122{ 1309{
1123 struct snd_soc_codec *codec = socdev->codec; 1310 struct snd_soc_codec *codec = socdev->codec;
1124 struct snd_soc_machine *machine = socdev->machine; 1311 struct snd_soc_card *card = socdev->card;
1125 int ret = 0, i; 1312 int ret = 0, i;
1126 1313
1127 mutex_lock(&codec->mutex); 1314 mutex_lock(&codec->mutex);
@@ -1140,11 +1327,11 @@ int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid)
1140 strncpy(codec->card->driver, codec->name, sizeof(codec->card->driver)); 1327 strncpy(codec->card->driver, codec->name, sizeof(codec->card->driver));
1141 1328
1142 /* create the pcms */ 1329 /* create the pcms */
1143 for (i = 0; i < machine->num_links; i++) { 1330 for (i = 0; i < card->num_links; i++) {
1144 ret = soc_new_pcm(socdev, &machine->dai_link[i], i); 1331 ret = soc_new_pcm(socdev, &card->dai_link[i], i);
1145 if (ret < 0) { 1332 if (ret < 0) {
1146 printk(KERN_ERR "asoc: can't create pcm %s\n", 1333 printk(KERN_ERR "asoc: can't create pcm %s\n",
1147 machine->dai_link[i].stream_name); 1334 card->dai_link[i].stream_name);
1148 mutex_unlock(&codec->mutex); 1335 mutex_unlock(&codec->mutex);
1149 return ret; 1336 return ret;
1150 } 1337 }
@@ -1156,7 +1343,7 @@ int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid)
1156EXPORT_SYMBOL_GPL(snd_soc_new_pcms); 1343EXPORT_SYMBOL_GPL(snd_soc_new_pcms);
1157 1344
1158/** 1345/**
1159 * snd_soc_register_card - register sound card 1346 * snd_soc_init_card - register sound card
1160 * @socdev: the SoC audio device 1347 * @socdev: the SoC audio device
1161 * 1348 *
1162 * Register a SoC sound card. Also registers an AC97 device if the 1349 * Register a SoC sound card. Also registers an AC97 device if the
@@ -1164,29 +1351,28 @@ EXPORT_SYMBOL_GPL(snd_soc_new_pcms);
1164 * 1351 *
1165 * Returns 0 for success, else error. 1352 * Returns 0 for success, else error.
1166 */ 1353 */
1167int snd_soc_register_card(struct snd_soc_device *socdev) 1354int snd_soc_init_card(struct snd_soc_device *socdev)
1168{ 1355{
1169 struct snd_soc_codec *codec = socdev->codec; 1356 struct snd_soc_codec *codec = socdev->codec;
1170 struct snd_soc_machine *machine = socdev->machine; 1357 struct snd_soc_card *card = socdev->card;
1171 int ret = 0, i, ac97 = 0, err = 0; 1358 int ret = 0, i, ac97 = 0, err = 0;
1172 1359
1173 for (i = 0; i < machine->num_links; i++) { 1360 for (i = 0; i < card->num_links; i++) {
1174 if (socdev->machine->dai_link[i].init) { 1361 if (card->dai_link[i].init) {
1175 err = socdev->machine->dai_link[i].init(codec); 1362 err = card->dai_link[i].init(codec);
1176 if (err < 0) { 1363 if (err < 0) {
1177 printk(KERN_ERR "asoc: failed to init %s\n", 1364 printk(KERN_ERR "asoc: failed to init %s\n",
1178 socdev->machine->dai_link[i].stream_name); 1365 card->dai_link[i].stream_name);
1179 continue; 1366 continue;
1180 } 1367 }
1181 } 1368 }
1182 if (socdev->machine->dai_link[i].codec_dai->type == 1369 if (card->dai_link[i].codec_dai->ac97_control)
1183 SND_SOC_DAI_AC97_BUS)
1184 ac97 = 1; 1370 ac97 = 1;
1185 } 1371 }
1186 snprintf(codec->card->shortname, sizeof(codec->card->shortname), 1372 snprintf(codec->card->shortname, sizeof(codec->card->shortname),
1187 "%s", machine->name); 1373 "%s", card->name);
1188 snprintf(codec->card->longname, sizeof(codec->card->longname), 1374 snprintf(codec->card->longname, sizeof(codec->card->longname),
1189 "%s (%s)", machine->name, codec->name); 1375 "%s (%s)", card->name, codec->name);
1190 1376
1191 ret = snd_card_register(codec->card); 1377 ret = snd_card_register(codec->card);
1192 if (ret < 0) { 1378 if (ret < 0) {
@@ -1216,12 +1402,13 @@ int snd_soc_register_card(struct snd_soc_device *socdev)
1216 if (err < 0) 1402 if (err < 0)
1217 printk(KERN_WARNING "asoc: failed to add codec sysfs files\n"); 1403 printk(KERN_WARNING "asoc: failed to add codec sysfs files\n");
1218 1404
1405 soc_init_codec_debugfs(socdev->codec);
1219 mutex_unlock(&codec->mutex); 1406 mutex_unlock(&codec->mutex);
1220 1407
1221out: 1408out:
1222 return ret; 1409 return ret;
1223} 1410}
1224EXPORT_SYMBOL_GPL(snd_soc_register_card); 1411EXPORT_SYMBOL_GPL(snd_soc_init_card);
1225 1412
1226/** 1413/**
1227 * snd_soc_free_pcms - free sound card and pcms 1414 * snd_soc_free_pcms - free sound card and pcms
@@ -1239,10 +1426,11 @@ void snd_soc_free_pcms(struct snd_soc_device *socdev)
1239#endif 1426#endif
1240 1427
1241 mutex_lock(&codec->mutex); 1428 mutex_lock(&codec->mutex);
1429 soc_cleanup_codec_debugfs(socdev->codec);
1242#ifdef CONFIG_SND_SOC_AC97_BUS 1430#ifdef CONFIG_SND_SOC_AC97_BUS
1243 for (i = 0; i < codec->num_dai; i++) { 1431 for (i = 0; i < codec->num_dai; i++) {
1244 codec_dai = &codec->dai[i]; 1432 codec_dai = &codec->dai[i];
1245 if (codec_dai->type == SND_SOC_DAI_AC97_BUS && codec->ac97) { 1433 if (codec_dai->ac97_control && codec->ac97) {
1246 soc_ac97_dev_unregister(codec); 1434 soc_ac97_dev_unregister(codec);
1247 goto free_card; 1435 goto free_card;
1248 } 1436 }
@@ -1756,8 +1944,8 @@ EXPORT_SYMBOL_GPL(snd_soc_put_volsw_s8);
1756int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id, 1944int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
1757 unsigned int freq, int dir) 1945 unsigned int freq, int dir)
1758{ 1946{
1759 if (dai->dai_ops.set_sysclk) 1947 if (dai->ops.set_sysclk)
1760 return dai->dai_ops.set_sysclk(dai, clk_id, freq, dir); 1948 return dai->ops.set_sysclk(dai, clk_id, freq, dir);
1761 else 1949 else
1762 return -EINVAL; 1950 return -EINVAL;
1763} 1951}
@@ -1776,8 +1964,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_sysclk);
1776int snd_soc_dai_set_clkdiv(struct snd_soc_dai *dai, 1964int snd_soc_dai_set_clkdiv(struct snd_soc_dai *dai,
1777 int div_id, int div) 1965 int div_id, int div)
1778{ 1966{
1779 if (dai->dai_ops.set_clkdiv) 1967 if (dai->ops.set_clkdiv)
1780 return dai->dai_ops.set_clkdiv(dai, div_id, div); 1968 return dai->ops.set_clkdiv(dai, div_id, div);
1781 else 1969 else
1782 return -EINVAL; 1970 return -EINVAL;
1783} 1971}
@@ -1795,8 +1983,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_clkdiv);
1795int snd_soc_dai_set_pll(struct snd_soc_dai *dai, 1983int snd_soc_dai_set_pll(struct snd_soc_dai *dai,
1796 int pll_id, unsigned int freq_in, unsigned int freq_out) 1984 int pll_id, unsigned int freq_in, unsigned int freq_out)
1797{ 1985{
1798 if (dai->dai_ops.set_pll) 1986 if (dai->ops.set_pll)
1799 return dai->dai_ops.set_pll(dai, pll_id, freq_in, freq_out); 1987 return dai->ops.set_pll(dai, pll_id, freq_in, freq_out);
1800 else 1988 else
1801 return -EINVAL; 1989 return -EINVAL;
1802} 1990}
@@ -1805,15 +1993,14 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_pll);
1805/** 1993/**
1806 * snd_soc_dai_set_fmt - configure DAI hardware audio format. 1994 * snd_soc_dai_set_fmt - configure DAI hardware audio format.
1807 * @dai: DAI 1995 * @dai: DAI
1808 * @clk_id: DAI specific clock ID
1809 * @fmt: SND_SOC_DAIFMT_ format value. 1996 * @fmt: SND_SOC_DAIFMT_ format value.
1810 * 1997 *
1811 * Configures the DAI hardware format and clocking. 1998 * Configures the DAI hardware format and clocking.
1812 */ 1999 */
1813int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 2000int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1814{ 2001{
1815 if (dai->dai_ops.set_fmt) 2002 if (dai->ops.set_fmt)
1816 return dai->dai_ops.set_fmt(dai, fmt); 2003 return dai->ops.set_fmt(dai, fmt);
1817 else 2004 else
1818 return -EINVAL; 2005 return -EINVAL;
1819} 2006}
@@ -1831,8 +2018,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_fmt);
1831int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai, 2018int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
1832 unsigned int mask, int slots) 2019 unsigned int mask, int slots)
1833{ 2020{
1834 if (dai->dai_ops.set_sysclk) 2021 if (dai->ops.set_sysclk)
1835 return dai->dai_ops.set_tdm_slot(dai, mask, slots); 2022 return dai->ops.set_tdm_slot(dai, mask, slots);
1836 else 2023 else
1837 return -EINVAL; 2024 return -EINVAL;
1838} 2025}
@@ -1847,8 +2034,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_tdm_slot);
1847 */ 2034 */
1848int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate) 2035int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate)
1849{ 2036{
1850 if (dai->dai_ops.set_sysclk) 2037 if (dai->ops.set_sysclk)
1851 return dai->dai_ops.set_tristate(dai, tristate); 2038 return dai->ops.set_tristate(dai, tristate);
1852 else 2039 else
1853 return -EINVAL; 2040 return -EINVAL;
1854} 2041}
@@ -1863,21 +2050,242 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_tristate);
1863 */ 2050 */
1864int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute) 2051int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute)
1865{ 2052{
1866 if (dai->dai_ops.digital_mute) 2053 if (dai->ops.digital_mute)
1867 return dai->dai_ops.digital_mute(dai, mute); 2054 return dai->ops.digital_mute(dai, mute);
1868 else 2055 else
1869 return -EINVAL; 2056 return -EINVAL;
1870} 2057}
1871EXPORT_SYMBOL_GPL(snd_soc_dai_digital_mute); 2058EXPORT_SYMBOL_GPL(snd_soc_dai_digital_mute);
1872 2059
1873static int __devinit snd_soc_init(void) 2060/**
2061 * snd_soc_register_card - Register a card with the ASoC core
2062 *
2063 * @param card Card to register
2064 *
2065 * Note that currently this is an internal only function: it will be
2066 * exposed to machine drivers after further backporting of ASoC v2
2067 * registration APIs.
2068 */
2069static int snd_soc_register_card(struct snd_soc_card *card)
2070{
2071 if (!card->name || !card->dev)
2072 return -EINVAL;
2073
2074 INIT_LIST_HEAD(&card->list);
2075 card->instantiated = 0;
2076
2077 mutex_lock(&client_mutex);
2078 list_add(&card->list, &card_list);
2079 snd_soc_instantiate_cards();
2080 mutex_unlock(&client_mutex);
2081
2082 dev_dbg(card->dev, "Registered card '%s'\n", card->name);
2083
2084 return 0;
2085}
2086
2087/**
2088 * snd_soc_unregister_card - Unregister a card with the ASoC core
2089 *
2090 * @param card Card to unregister
2091 *
2092 * Note that currently this is an internal only function: it will be
2093 * exposed to machine drivers after further backporting of ASoC v2
2094 * registration APIs.
2095 */
2096static int snd_soc_unregister_card(struct snd_soc_card *card)
2097{
2098 mutex_lock(&client_mutex);
2099 list_del(&card->list);
2100 mutex_unlock(&client_mutex);
2101
2102 dev_dbg(card->dev, "Unregistered card '%s'\n", card->name);
2103
2104 return 0;
2105}
2106
2107/**
2108 * snd_soc_register_dai - Register a DAI with the ASoC core
2109 *
2110 * @param dai DAI to register
2111 */
2112int snd_soc_register_dai(struct snd_soc_dai *dai)
2113{
2114 if (!dai->name)
2115 return -EINVAL;
2116
2117 /* The device should become mandatory over time */
2118 if (!dai->dev)
2119 printk(KERN_WARNING "No device for DAI %s\n", dai->name);
2120
2121 INIT_LIST_HEAD(&dai->list);
2122
2123 mutex_lock(&client_mutex);
2124 list_add(&dai->list, &dai_list);
2125 snd_soc_instantiate_cards();
2126 mutex_unlock(&client_mutex);
2127
2128 pr_debug("Registered DAI '%s'\n", dai->name);
2129
2130 return 0;
2131}
2132EXPORT_SYMBOL_GPL(snd_soc_register_dai);
2133
2134/**
2135 * snd_soc_unregister_dai - Unregister a DAI from the ASoC core
2136 *
2137 * @param dai DAI to unregister
2138 */
2139void snd_soc_unregister_dai(struct snd_soc_dai *dai)
2140{
2141 mutex_lock(&client_mutex);
2142 list_del(&dai->list);
2143 mutex_unlock(&client_mutex);
2144
2145 pr_debug("Unregistered DAI '%s'\n", dai->name);
2146}
2147EXPORT_SYMBOL_GPL(snd_soc_unregister_dai);
2148
2149/**
2150 * snd_soc_register_dais - Register multiple DAIs with the ASoC core
2151 *
2152 * @param dai Array of DAIs to register
2153 * @param count Number of DAIs
2154 */
2155int snd_soc_register_dais(struct snd_soc_dai *dai, size_t count)
2156{
2157 int i, ret;
2158
2159 for (i = 0; i < count; i++) {
2160 ret = snd_soc_register_dai(&dai[i]);
2161 if (ret != 0)
2162 goto err;
2163 }
2164
2165 return 0;
2166
2167err:
2168 for (i--; i >= 0; i--)
2169 snd_soc_unregister_dai(&dai[i]);
2170
2171 return ret;
2172}
2173EXPORT_SYMBOL_GPL(snd_soc_register_dais);
2174
2175/**
2176 * snd_soc_unregister_dais - Unregister multiple DAIs from the ASoC core
2177 *
2178 * @param dai Array of DAIs to unregister
2179 * @param count Number of DAIs
2180 */
2181void snd_soc_unregister_dais(struct snd_soc_dai *dai, size_t count)
2182{
2183 int i;
2184
2185 for (i = 0; i < count; i++)
2186 snd_soc_unregister_dai(&dai[i]);
2187}
2188EXPORT_SYMBOL_GPL(snd_soc_unregister_dais);
2189
2190/**
2191 * snd_soc_register_platform - Register a platform with the ASoC core
2192 *
2193 * @param platform platform to register
2194 */
2195int snd_soc_register_platform(struct snd_soc_platform *platform)
2196{
2197 if (!platform->name)
2198 return -EINVAL;
2199
2200 INIT_LIST_HEAD(&platform->list);
2201
2202 mutex_lock(&client_mutex);
2203 list_add(&platform->list, &platform_list);
2204 snd_soc_instantiate_cards();
2205 mutex_unlock(&client_mutex);
2206
2207 pr_debug("Registered platform '%s'\n", platform->name);
2208
2209 return 0;
2210}
2211EXPORT_SYMBOL_GPL(snd_soc_register_platform);
2212
2213/**
2214 * snd_soc_unregister_platform - Unregister a platform from the ASoC core
2215 *
2216 * @param platform platform to unregister
2217 */
2218void snd_soc_unregister_platform(struct snd_soc_platform *platform)
1874{ 2219{
1875 printk(KERN_INFO "ASoC version %s\n", SND_SOC_VERSION); 2220 mutex_lock(&client_mutex);
2221 list_del(&platform->list);
2222 mutex_unlock(&client_mutex);
2223
2224 pr_debug("Unregistered platform '%s'\n", platform->name);
2225}
2226EXPORT_SYMBOL_GPL(snd_soc_unregister_platform);
2227
2228/**
2229 * snd_soc_register_codec - Register a codec with the ASoC core
2230 *
2231 * @param codec codec to register
2232 */
2233int snd_soc_register_codec(struct snd_soc_codec *codec)
2234{
2235 if (!codec->name)
2236 return -EINVAL;
2237
2238 /* The device should become mandatory over time */
2239 if (!codec->dev)
2240 printk(KERN_WARNING "No device for codec %s\n", codec->name);
2241
2242 INIT_LIST_HEAD(&codec->list);
2243
2244 mutex_lock(&client_mutex);
2245 list_add(&codec->list, &codec_list);
2246 snd_soc_instantiate_cards();
2247 mutex_unlock(&client_mutex);
2248
2249 pr_debug("Registered codec '%s'\n", codec->name);
2250
2251 return 0;
2252}
2253EXPORT_SYMBOL_GPL(snd_soc_register_codec);
2254
2255/**
2256 * snd_soc_unregister_codec - Unregister a codec from the ASoC core
2257 *
2258 * @param codec codec to unregister
2259 */
2260void snd_soc_unregister_codec(struct snd_soc_codec *codec)
2261{
2262 mutex_lock(&client_mutex);
2263 list_del(&codec->list);
2264 mutex_unlock(&client_mutex);
2265
2266 pr_debug("Unregistered codec '%s'\n", codec->name);
2267}
2268EXPORT_SYMBOL_GPL(snd_soc_unregister_codec);
2269
2270static int __init snd_soc_init(void)
2271{
2272#ifdef CONFIG_DEBUG_FS
2273 debugfs_root = debugfs_create_dir("asoc", NULL);
2274 if (IS_ERR(debugfs_root) || !debugfs_root) {
2275 printk(KERN_WARNING
2276 "ASoC: Failed to create debugfs directory\n");
2277 debugfs_root = NULL;
2278 }
2279#endif
2280
1876 return platform_driver_register(&soc_driver); 2281 return platform_driver_register(&soc_driver);
1877} 2282}
1878 2283
1879static void snd_soc_exit(void) 2284static void __exit snd_soc_exit(void)
1880{ 2285{
2286#ifdef CONFIG_DEBUG_FS
2287 debugfs_remove_recursive(debugfs_root);
2288#endif
1881 platform_driver_unregister(&soc_driver); 2289 platform_driver_unregister(&soc_driver);
1882} 2290}
1883 2291
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 7351db9606e4..8863eddbac02 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -37,7 +37,6 @@
37#include <linux/bitops.h> 37#include <linux/bitops.h>
38#include <linux/platform_device.h> 38#include <linux/platform_device.h>
39#include <linux/jiffies.h> 39#include <linux/jiffies.h>
40#include <linux/debugfs.h>
41#include <sound/core.h> 40#include <sound/core.h>
42#include <sound/pcm.h> 41#include <sound/pcm.h>
43#include <sound/pcm_params.h> 42#include <sound/pcm_params.h>
@@ -67,17 +66,13 @@ static int dapm_status = 1;
67module_param(dapm_status, int, 0); 66module_param(dapm_status, int, 0);
68MODULE_PARM_DESC(dapm_status, "enable DPM sysfs entries"); 67MODULE_PARM_DESC(dapm_status, "enable DPM sysfs entries");
69 68
70static struct dentry *asoc_debugfs; 69static void pop_wait(u32 pop_time)
71
72static u32 pop_time;
73
74static void pop_wait(void)
75{ 70{
76 if (pop_time) 71 if (pop_time)
77 schedule_timeout_uninterruptible(msecs_to_jiffies(pop_time)); 72 schedule_timeout_uninterruptible(msecs_to_jiffies(pop_time));
78} 73}
79 74
80static void pop_dbg(const char *fmt, ...) 75static void pop_dbg(u32 pop_time, const char *fmt, ...)
81{ 76{
82 va_list args; 77 va_list args;
83 78
@@ -85,7 +80,7 @@ static void pop_dbg(const char *fmt, ...)
85 80
86 if (pop_time) { 81 if (pop_time) {
87 vprintk(fmt, args); 82 vprintk(fmt, args);
88 pop_wait(); 83 pop_wait(pop_time);
89 } 84 }
90 85
91 va_end(args); 86 va_end(args);
@@ -230,10 +225,11 @@ static int dapm_update_bits(struct snd_soc_dapm_widget *widget)
230 225
231 change = old != new; 226 change = old != new;
232 if (change) { 227 if (change) {
233 pop_dbg("pop test %s : %s in %d ms\n", widget->name, 228 pop_dbg(codec->pop_time, "pop test %s : %s in %d ms\n",
234 widget->power ? "on" : "off", pop_time); 229 widget->name, widget->power ? "on" : "off",
230 codec->pop_time);
235 snd_soc_write(codec, widget->reg, new); 231 snd_soc_write(codec, widget->reg, new);
236 pop_wait(); 232 pop_wait(codec->pop_time);
237 } 233 }
238 pr_debug("reg %x old %x new %x change %d\n", widget->reg, 234 pr_debug("reg %x old %x new %x change %d\n", widget->reg,
239 old, new, change); 235 old, new, change);
@@ -293,7 +289,7 @@ static int dapm_new_mixer(struct snd_soc_codec *codec,
293 struct snd_soc_dapm_widget *w) 289 struct snd_soc_dapm_widget *w)
294{ 290{
295 int i, ret = 0; 291 int i, ret = 0;
296 char name[32]; 292 size_t name_len;
297 struct snd_soc_dapm_path *path; 293 struct snd_soc_dapm_path *path;
298 294
299 /* add kcontrol */ 295 /* add kcontrol */
@@ -307,11 +303,16 @@ static int dapm_new_mixer(struct snd_soc_codec *codec,
307 continue; 303 continue;
308 304
309 /* add dapm control with long name */ 305 /* add dapm control with long name */
310 snprintf(name, 32, "%s %s", w->name, w->kcontrols[i].name); 306 name_len = 2 + strlen(w->name)
311 path->long_name = kstrdup (name, GFP_KERNEL); 307 + strlen(w->kcontrols[i].name);
308 path->long_name = kmalloc(name_len, GFP_KERNEL);
312 if (path->long_name == NULL) 309 if (path->long_name == NULL)
313 return -ENOMEM; 310 return -ENOMEM;
314 311
312 snprintf(path->long_name, name_len, "%s %s",
313 w->name, w->kcontrols[i].name);
314 path->long_name[name_len - 1] = '\0';
315
315 path->kcontrol = snd_soc_cnew(&w->kcontrols[i], w, 316 path->kcontrol = snd_soc_cnew(&w->kcontrols[i], w,
316 path->long_name); 317 path->long_name);
317 ret = snd_ctl_add(codec->card, path->kcontrol); 318 ret = snd_ctl_add(codec->card, path->kcontrol);
@@ -821,23 +822,9 @@ static DEVICE_ATTR(dapm_widget, 0444, dapm_widget_show, NULL);
821 822
822int snd_soc_dapm_sys_add(struct device *dev) 823int snd_soc_dapm_sys_add(struct device *dev)
823{ 824{
824 int ret = 0;
825
826 if (!dapm_status) 825 if (!dapm_status)
827 return 0; 826 return 0;
828 827 return device_create_file(dev, &dev_attr_dapm_widget);
829 ret = device_create_file(dev, &dev_attr_dapm_widget);
830 if (ret != 0)
831 return ret;
832
833 asoc_debugfs = debugfs_create_dir("asoc", NULL);
834 if (!IS_ERR(asoc_debugfs) && 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;
841} 828}
842 829
843static void snd_soc_dapm_sys_remove(struct device *dev) 830static void snd_soc_dapm_sys_remove(struct device *dev)
@@ -845,9 +832,6 @@ static void snd_soc_dapm_sys_remove(struct device *dev)
845 if (dapm_status) { 832 if (dapm_status) {
846 device_remove_file(dev, &dev_attr_dapm_widget); 833 device_remove_file(dev, &dev_attr_dapm_widget);
847 } 834 }
848
849 if (asoc_debugfs)
850 debugfs_remove_recursive(asoc_debugfs);
851} 835}
852 836
853/* free all dapm widgets and resources */ 837/* free all dapm widgets and resources */
@@ -1007,28 +991,6 @@ err:
1007} 991}
1008 992
1009/** 993/**
1010 * snd_soc_dapm_connect_input - connect dapm widgets
1011 * @codec: audio codec
1012 * @sink: name of target widget
1013 * @control: mixer control name
1014 * @source: name of source name
1015 *
1016 * Connects 2 dapm widgets together via a named audio path. The sink is
1017 * the widget receiving the audio signal, whilst the source is the sender
1018 * of the audio signal.
1019 *
1020 * This function has been deprecated in favour of snd_soc_dapm_add_routes().
1021 *
1022 * Returns 0 for success else error.
1023 */
1024int snd_soc_dapm_connect_input(struct snd_soc_codec *codec, const char *sink,
1025 const char *control, const char *source)
1026{
1027 return snd_soc_dapm_add_route(codec, sink, control, source);
1028}
1029EXPORT_SYMBOL_GPL(snd_soc_dapm_connect_input);
1030
1031/**
1032 * snd_soc_dapm_add_routes - Add routes between DAPM widgets 994 * snd_soc_dapm_add_routes - Add routes between DAPM widgets
1033 * @codec: codec 995 * @codec: codec
1034 * @route: audio routes 996 * @route: audio routes
@@ -1358,8 +1320,12 @@ int snd_soc_dapm_new_controls(struct snd_soc_codec *codec,
1358 1320
1359 for (i = 0; i < num; i++) { 1321 for (i = 0; i < num; i++) {
1360 ret = snd_soc_dapm_new_control(codec, widget); 1322 ret = snd_soc_dapm_new_control(codec, widget);
1361 if (ret < 0) 1323 if (ret < 0) {
1324 printk(KERN_ERR
1325 "ASoC: Failed to create DAPM control %s: %d\n",
1326 widget->name, ret);
1362 return ret; 1327 return ret;
1328 }
1363 widget++; 1329 widget++;
1364 } 1330 }
1365 return 0; 1331 return 0;
@@ -1440,11 +1406,11 @@ int snd_soc_dapm_set_bias_level(struct snd_soc_device *socdev,
1440 enum snd_soc_bias_level level) 1406 enum snd_soc_bias_level level)
1441{ 1407{
1442 struct snd_soc_codec *codec = socdev->codec; 1408 struct snd_soc_codec *codec = socdev->codec;
1443 struct snd_soc_machine *machine = socdev->machine; 1409 struct snd_soc_card *card = socdev->card;
1444 int ret = 0; 1410 int ret = 0;
1445 1411
1446 if (machine->set_bias_level) 1412 if (card->set_bias_level)
1447 ret = machine->set_bias_level(machine, level); 1413 ret = card->set_bias_level(card, level);
1448 if (ret == 0 && codec->set_bias_level) 1414 if (ret == 0 && codec->set_bias_level)
1449 ret = codec->set_bias_level(codec, level); 1415 ret = codec->set_bias_level(codec, level);
1450 1416
diff --git a/sound/sound_core.c b/sound/sound_core.c
index 10ba4218161b..2b302bbffe73 100644
--- a/sound/sound_core.c
+++ b/sound/sound_core.c
@@ -10,6 +10,7 @@
10#include <linux/module.h> 10#include <linux/module.h>
11#include <linux/device.h> 11#include <linux/device.h>
12#include <linux/err.h> 12#include <linux/err.h>
13#include <sound/core.h>
13 14
14#ifdef CONFIG_SOUND_OSS_CORE 15#ifdef CONFIG_SOUND_OSS_CORE
15static int __init init_oss_soundcore(void); 16static int __init init_oss_soundcore(void);
diff --git a/sound/usb/caiaq/caiaq-control.c b/sound/usb/caiaq/caiaq-control.c
index 798ca124da58..ccd763dd7167 100644
--- a/sound/usb/caiaq/caiaq-control.c
+++ b/sound/usb/caiaq/caiaq-control.c
@@ -247,69 +247,56 @@ static struct caiaq_controller a8dj_controller[] = {
247 { "Software lock", 40 } 247 { "Software lock", 40 }
248}; 248};
249 249
250int __devinit snd_usb_caiaq_control_init(struct snd_usb_caiaqdev *dev) 250static int __devinit add_controls(struct caiaq_controller *c, int num,
251 struct snd_usb_caiaqdev *dev)
251{ 252{
252 int i; 253 int i, ret;
253 struct snd_kcontrol *kc; 254 struct snd_kcontrol *kc;
254 255
256 for (i = 0; i < num; i++, c++) {
257 kcontrol_template.name = c->name;
258 kcontrol_template.private_value = c->index;
259 kc = snd_ctl_new1(&kcontrol_template, dev);
260 ret = snd_ctl_add(dev->chip.card, kc);
261 if (ret < 0)
262 return ret;
263 }
264
265 return 0;
266}
267
268int __devinit snd_usb_caiaq_control_init(struct snd_usb_caiaqdev *dev)
269{
270 int ret = 0;
271
255 switch (dev->chip.usb_id) { 272 switch (dev->chip.usb_id) {
256 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1): 273 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1):
257 for (i = 0; i < ARRAY_SIZE(ak1_controller); i++) { 274 ret = add_controls(ak1_controller,
258 struct caiaq_controller *c = ak1_controller + i; 275 ARRAY_SIZE(ak1_controller), dev);
259 kcontrol_template.name = c->name;
260 kcontrol_template.private_value = c->index;
261 kc = snd_ctl_new1(&kcontrol_template, dev);
262 snd_ctl_add(dev->chip.card, kc);
263 }
264
265 break; 276 break;
266 277
267 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2): 278 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2):
268 for (i = 0; i < ARRAY_SIZE(rk2_controller); i++) { 279 ret = add_controls(rk2_controller,
269 struct caiaq_controller *c = rk2_controller + i; 280 ARRAY_SIZE(rk2_controller), dev);
270 kcontrol_template.name = c->name;
271 kcontrol_template.private_value = c->index;
272 kc = snd_ctl_new1(&kcontrol_template, dev);
273 snd_ctl_add(dev->chip.card, kc);
274 }
275
276 break; 281 break;
277 282
278 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3): 283 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3):
279 for (i = 0; i < ARRAY_SIZE(rk3_controller); i++) { 284 ret = add_controls(rk3_controller,
280 struct caiaq_controller *c = rk3_controller + i; 285 ARRAY_SIZE(rk3_controller), dev);
281 kcontrol_template.name = c->name;
282 kcontrol_template.private_value = c->index;
283 kc = snd_ctl_new1(&kcontrol_template, dev);
284 snd_ctl_add(dev->chip.card, kc);
285 }
286
287 break; 286 break;
288 287
289 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER): 288 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER):
290 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2): 289 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2):
291 for (i = 0; i < ARRAY_SIZE(kore_controller); i++) { 290 ret = add_controls(kore_controller,
292 struct caiaq_controller *c = kore_controller + i; 291 ARRAY_SIZE(kore_controller), dev);
293 kcontrol_template.name = c->name;
294 kcontrol_template.private_value = c->index;
295 kc = snd_ctl_new1(&kcontrol_template, dev);
296 snd_ctl_add(dev->chip.card, kc);
297 }
298
299 break; 292 break;
300 293
301 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ): 294 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ):
302 for (i = 0; i < ARRAY_SIZE(a8dj_controller); i++) { 295 ret = add_controls(a8dj_controller,
303 struct caiaq_controller *c = a8dj_controller + i; 296 ARRAY_SIZE(a8dj_controller), dev);
304 kcontrol_template.name = c->name;
305 kcontrol_template.private_value = c->index;
306 kc = snd_ctl_new1(&kcontrol_template, dev);
307 snd_ctl_add(dev->chip.card, kc);
308 }
309
310 break; 297 break;
311 } 298 }
312 299
313 return 0; 300 return ret;
314} 301}
315 302
diff --git a/sound/usb/caiaq/caiaq-device.c b/sound/usb/caiaq/caiaq-device.c
index 83175083e50f..b143ef7152f7 100644
--- a/sound/usb/caiaq/caiaq-device.c
+++ b/sound/usb/caiaq/caiaq-device.c
@@ -42,7 +42,7 @@
42#endif 42#endif
43 43
44MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>"); 44MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
45MODULE_DESCRIPTION("caiaq USB audio, version 1.3.8"); 45MODULE_DESCRIPTION("caiaq USB audio, version 1.3.9");
46MODULE_LICENSE("GPL"); 46MODULE_LICENSE("GPL");
47MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2}," 47MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2},"
48 "{Native Instruments, RigKontrol3}," 48 "{Native Instruments, RigKontrol3},"
diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c
index 5962e4b84423..6d9f9b135c62 100644
--- a/sound/usb/usbmidi.c
+++ b/sound/usb/usbmidi.c
@@ -880,7 +880,7 @@ static void snd_usbmidi_output_trigger(struct snd_rawmidi_substream *substream,
880 snd_rawmidi_transmit_ack(substream, 1); 880 snd_rawmidi_transmit_ack(substream, 1);
881 return; 881 return;
882 } 882 }
883 tasklet_hi_schedule(&port->ep->tasklet); 883 tasklet_schedule(&port->ep->tasklet);
884 } 884 }
885} 885}
886 886
diff --git a/sound/usb/usx2y/usb_stream.c b/sound/usb/usx2y/usb_stream.c
index ff23cc1ce3b9..70b96355ca4c 100644
--- a/sound/usb/usx2y/usb_stream.c
+++ b/sound/usb/usx2y/usb_stream.c
@@ -276,7 +276,8 @@ static void subs_set_complete(struct urb **urbs, void (*complete)(struct urb *))
276 } 276 }
277} 277}
278 278
279int usb_stream_prepare_playback(struct usb_stream_kernel *sk, struct urb *inurb) 279static int usb_stream_prepare_playback(struct usb_stream_kernel *sk,
280 struct urb *inurb)
280{ 281{
281 struct usb_stream *s = sk->s; 282 struct usb_stream *s = sk->s;
282 struct urb *io; 283 struct urb *io;